VirtualBox

Changeset 35490 in vbox


Ignore:
Timestamp:
Jan 11, 2011 3:17:10 PM (14 years ago)
Author:
vboxsync
Message:

CPUM,Debugger: Registers, still some details left.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/dbgf.h

    r35468 r35490  
    13551355} DBGFREGDESC;
    13561356
     1357/** @name Macros for constructing DBGFREGDESC arrays.
     1358 * @{ */
     1359#define DBGFREGDESC_RW(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
     1360    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/,            a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
     1361#define DBGFREGDESC_RO(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
     1362    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
     1363#define DBGFREGDESC_RW_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
     1364    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/,            a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
     1365#define DBGFREGDESC_RO_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
     1366    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
     1367#define DBGFREGDESC_RW_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
     1368    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/,            a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
     1369#define DBGFREGDESC_RO_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
     1370    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
     1371#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
     1372    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/,            a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
     1373#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
     1374    { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
     1375#define DBGFREGDESC_TERMINATOR() \
     1376    { NULL, DBGFREG_END, DBGFREGVALTYPE_INVALID, 0, 0, NULL, NULL, NULL, NULL }
     1377/** @} */
     1378
     1379
    13571380/** @name DBGFREG_FLAGS_XXX
    13581381 * @{ */
     
    13601383#define DBGFREG_FLAGS_READ_ONLY         RT_BIT_32(0)
    13611384/** @} */
    1362 
    1363 
    1364 
    13651385
    13661386/**
     
    14001420
    14011421VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
     1422
     1423VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters);
     1424VMMR3DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, const char *pszPrefix, uint32_t iInstance);
    14021425
    14031426/**
  • trunk/include/iprt/uint128.h

    r35488 r35490  
    269269
    270270/**
     271 * Performs a bitwise AND of a 128-bit unsigned integer value and a mask made
     272 * up of the first N bits, assigning the result to the the 128-bit value.
     273 *
     274 * @returns pValueResult.
     275 * @param   pValueResult    The value and result.
     276 * @param   cBits           The number of bits to AND (counting from the first
     277 *                          bit).
     278 */
     279DECLINLINE(PRTUINT128U) RTUInt128AssignAndNFirstBits(PRTUINT128U pValueResult, unsigned cBits)
     280{
     281    if (cBits <= 64)
     282    {
     283        if (cBits != 64)
     284            pValueResult->s.Lo &= (RT_BIT_64(cBits) - 1);
     285        pValueResult->s.Hi = 0;
     286    }
     287    else if (cBits < 128)
     288        pValueResult->s.Hi &= (RT_BIT_64(cBits - 64) - 1);
     289/** @todo #if ARCH_BITS >= 64 */
     290    return pValueResult;
     291}
     292
     293
     294/**
    271295 * Performs a bitwise OR of two 128-bit unsigned integer values and assigned
    272296 * the result to the first one.
  • trunk/src/VBox/Debugger/DBGCOps.cpp

    r35439 r35490  
    494494     * Get the register.
    495495     */
    496     /// @todo DBGFR3RegByName();
    497     return VERR_NOT_IMPLEMENTED;
    498 
     496    DBGFREGVALTYPE  enmType;
     497    DBGFREGVAL      Value;
     498    int rc = DBGFR3RegNmQuery(pDbgc->pVM, pDbgc->idCpu, pArg->u.pszString, &Value, &enmType);
     499    if (RT_SUCCESS(rc))
     500    {
     501        rc = VERR_INTERNAL_ERROR_5;
     502        switch (enmType)
     503        {
     504            case DBGFREGVALTYPE_U8:
     505                DBGCVAR_INIT_NUMBER(pResult, Value.u8);
     506                return VINF_SUCCESS;
     507
     508            case DBGFREGVALTYPE_U16:
     509                DBGCVAR_INIT_NUMBER(pResult, Value.u16);
     510                return VINF_SUCCESS;
     511
     512            case DBGFREGVALTYPE_U32:
     513                DBGCVAR_INIT_NUMBER(pResult, Value.u32);
     514                return VINF_SUCCESS;
     515
     516            case DBGFREGVALTYPE_U64:
     517                DBGCVAR_INIT_NUMBER(pResult, Value.u64);
     518                return VINF_SUCCESS;
     519
     520            case DBGFREGVALTYPE_U128:
     521                DBGCVAR_INIT_NUMBER(pResult, Value.u128.s.Lo);
     522                return VINF_SUCCESS;
     523
     524            case DBGFREGVALTYPE_LRD:
     525                DBGCVAR_INIT_NUMBER(pResult, (uint64_t)Value.lrd);
     526                return VINF_SUCCESS;
     527
     528            case DBGFREGVALTYPE_DTR:
     529                DBGCVAR_INIT_NUMBER(pResult, Value.dtr.u64Base);
     530                return VINF_SUCCESS;
     531
     532            case DBGFREGVALTYPE_INVALID:
     533            case DBGFREGVALTYPE_END:
     534            case DBGFREGVALTYPE_32BIT_HACK:
     535                break;
     536        }
     537    }
     538    return rc;
    499539}
    500540
  • trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp

    r35410 r35490  
    206206    return VERR_INTERNAL_ERROR;
    207207}
     208VMMR3DECL(int) DBGFR3RegNmQuery(    PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
     209{
     210    return VERR_INTERNAL_ERROR;
     211}
     212
    208213VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr)
    209214{
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r35346 r35490  
    220220
    221221    /*
    222      * Register info handlers.
     222     * Register info handlers and registers with the debugger facility.
    223223     */
    224224    DBGFR3InfoRegisterInternal(pVM, "cpum",             "Displays the all the cpu states.",         &cpumR3InfoAll);
     
    228228    DBGFR3InfoRegisterInternal(pVM, "cpuid",            "Displays the guest cpuid leaves.",         &cpumR3CpuIdInfo);
    229229    DBGFR3InfoRegisterInternal(pVM, "cpumguestinstr",   "Displays the current guest instruction.",  &cpumR3InfoGuestInstr);
     230
     231    rc = cpumR3DbgInit(pVM);
     232    if (RT_FAILURE(rc))
     233        return rc;
    230234
    231235    /*
  • trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp

    r35468 r35490  
    2323#include <VBox/vmm/cpum.h>
    2424#include <VBox/vmm/dbgf.h>
     25#include <VBox/vmm/pdmapi.h>
    2526#include "CPUMInternal.h"
    2627#include <VBox/vmm/vm.h>
     
    2930#include <VBox/log.h>
    3031#include <iprt/thread.h>
    31 
    32 
    33 #if 0
     32#include <iprt/uint128.h>
     33
     34
    3435/**
    3536 * @interface_method_impl{DBGFREGDESC, pfnGet}
     
    8889
    8990        case DBGFREGVALTYPE_U128:
    90             ((PRTUINT128U)pv)->s.Hi &= ~pfMask->u128.s.Hi;
    91             ((PRTUINT128U)pv)->s.Lo &= ~pfMask->u128.s.Lo;
    92             ((PRTUINT128U)pv)->s.Hi |= pValue->u128.s.Hi & pfMask->u128.s.Hi;
    93             ((PRTUINT128U)pv)->s.Lo |= pValue->u128.s.Lo & pfMask->u128.s.Lo;
     91        {
     92            RTUINT128U Val;
     93            RTUInt128AssignAnd((PRTUINT128U)pv, RTUInt128AssignBitwiseNot(RTUInt128Assign(&Val, &pfMask->u128)));
     94            RTUInt128AssignOr((PRTUINT128U)pv, RTUInt128AssignAnd(RTUInt128Assign(&Val, &pValue->u128), &pfMask->u128));
    9495            return VINF_SUCCESS;
     96        }
    9597
    9698        default:
     
    110112
    111113
    112 static DECLCALLBACK(int) cpumR3RegGet_crX(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCCPUMCTX pCtx, PRTUINT128U puValue)
     114/**
     115 * @interface_method_impl{DBGFREGDESC, pfnGet}
     116 */
     117static DECLCALLBACK(int) cpumR3RegGet_crX(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
     118{
     119    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     120    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     121
     122    VMCPU_ASSERT_EMT(pVCpu);
     123
     124    uint64_t u64Value;
     125    int rc = CPUMGetGuestCRx(pVCpu, pDesc->offRegister, &u64Value);
     126    AssertRCReturn(rc, rc);
     127    switch (pDesc->enmType)
     128    {
     129        case DBGFREGVALTYPE_U64:    pValue->u64 = u64Value; break;
     130        case DBGFREGVALTYPE_U32:    pValue->u32 = (uint32_t)u64Value; break;
     131        default:
     132            AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     133    }
     134    return VINF_SUCCESS;
     135}
     136
     137
     138/**
     139 * @interface_method_impl{DBGFREGDESC, pfnGet}
     140 */
     141static DECLCALLBACK(int) cpumR3RegSet_crX(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
     142{
     143    int         rc;
     144    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     145    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     146
     147    VMCPU_ASSERT_EMT(pVCpu);
     148
     149    /*
     150     * Calculate the new value.
     151     */
     152    uint64_t u64Value;
     153    uint64_t fMask;
     154    uint64_t fMaskMax;
     155    switch (pDesc->enmType)
     156    {
     157        case DBGFREGVALTYPE_U64:
     158            u64Value = pValue->u64;
     159            fMask    = pfMask->u64;
     160            fMaskMax = UINT64_MAX;
     161            break;
     162        case DBGFREGVALTYPE_U32:
     163            u64Value = pValue->u32;
     164            fMask    = pfMask->u32;
     165            fMaskMax = UINT32_MAX;
     166            break;
     167        default:                    AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     168    }
     169    if (fMask != fMaskMax)
     170    {
     171        uint64_t u64FullValue;
     172        rc = CPUMGetGuestCRx(pVCpu, pDesc->offRegister, &u64FullValue);
     173        if (RT_FAILURE(rc))
     174            return rc;
     175        u64Value = (u64FullValue & ~fMask)
     176                 | (u64Value     &  fMask);
     177    }
     178
     179    /*
     180     * Perform the assignment.
     181     */
     182    switch (pDesc->offRegister)
     183    {
     184        case 0: rc = CPUMSetGuestCR0(pVCpu, u64Value); break;
     185        case 2: rc = CPUMSetGuestCR2(pVCpu, u64Value); break;
     186        case 3: rc = CPUMSetGuestCR3(pVCpu, u64Value); break;
     187        case 4: rc = CPUMSetGuestCR4(pVCpu, u64Value); break;
     188        case 8: rc = PDMApicSetTPR(pVCpu, (uint8_t)(u64Value << 4)); break;
     189        default:
     190            AssertFailedReturn(VERR_INTERNAL_ERROR_2);
     191    }
     192    return rc;
     193}
     194
     195
     196/**
     197 * @interface_method_impl{DBGFREGDESC, pfnGet}
     198 */
     199static DECLCALLBACK(int) cpumR3RegGet_drX(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
     200{
     201    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     202    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     203
     204    VMCPU_ASSERT_EMT(pVCpu);
     205
     206    uint64_t u64Value;
     207    int rc = CPUMGetGuestDRx(pVCpu, pDesc->offRegister, &u64Value);
     208    AssertRCReturn(rc, rc);
     209    switch (pDesc->enmType)
     210    {
     211        case DBGFREGVALTYPE_U64:    pValue->u64 = u64Value; break;
     212        case DBGFREGVALTYPE_U32:    pValue->u32 = (uint32_t)u64Value; break;
     213        default:
     214            AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     215    }
     216    return VINF_SUCCESS;
     217}
     218
     219
     220/**
     221 * @interface_method_impl{DBGFREGDESC, pfnGet}
     222 */
     223static DECLCALLBACK(int) cpumR3RegSet_drX(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
     224{
     225    int         rc;
     226    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     227    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     228
     229    VMCPU_ASSERT_EMT(pVCpu);
     230
     231    /*
     232     * Calculate the new value.
     233     */
     234    uint64_t u64Value;
     235    uint64_t fMask;
     236    uint64_t fMaskMax;
     237    switch (pDesc->enmType)
     238    {
     239        case DBGFREGVALTYPE_U64:
     240            u64Value = pValue->u64;
     241            fMask    = pfMask->u64;
     242            fMaskMax = UINT64_MAX;
     243            break;
     244        case DBGFREGVALTYPE_U32:
     245            u64Value = pValue->u32;
     246            fMask    = pfMask->u32;
     247            fMaskMax = UINT32_MAX;
     248            break;
     249        default:                    AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     250    }
     251    if (fMask != fMaskMax)
     252    {
     253        uint64_t u64FullValue;
     254        rc = CPUMGetGuestDRx(pVCpu, pDesc->offRegister, &u64FullValue);
     255        if (RT_FAILURE(rc))
     256            return rc;
     257        u64Value = (u64FullValue & ~fMask)
     258                 | (u64Value     &  fMask);
     259    }
     260
     261    /*
     262     * Perform the assignment.
     263     */
     264    return CPUMSetGuestDRx(pVCpu, pDesc->offRegister, u64Value);
     265}
     266
     267
     268/**
     269 * @interface_method_impl{DBGFREGDESC, pfnGet}
     270 */
     271static DECLCALLBACK(int) cpumR3RegGet_msr(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
     272{
     273    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     274    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     275
     276    VMCPU_ASSERT_EMT(pVCpu);
     277    uint64_t u64Value;
     278    int rc = CPUMQueryGuestMsr(pVCpu, pDesc->offRegister, &u64Value);
     279    if (RT_SUCCESS(rc))
     280    {
     281        switch (pDesc->enmType)
     282        {
     283            case DBGFREGVALTYPE_U64:    pValue->u64 = u64Value; break;
     284            case DBGFREGVALTYPE_U32:    pValue->u32 = (uint32_t)u64Value; break;
     285            case DBGFREGVALTYPE_U16:    pValue->u16 = (uint16_t)u64Value; break;
     286            default:
     287                AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     288        }
     289    }
     290    /** @todo what to do about errors? */
     291    return rc;
     292}
     293
     294
     295/**
     296 * @interface_method_impl{DBGFREGDESC, pfnGet}
     297 */
     298static DECLCALLBACK(int) cpumR3RegSet_msr(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
     299{
     300    int         rc;
     301    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     302    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     303
     304    VMCPU_ASSERT_EMT(pVCpu);
     305
     306    /*
     307     * Calculate the new value.
     308     */
     309    uint64_t u64Value;
     310    uint64_t fMask;
     311    uint64_t fMaskMax;
     312    switch (pDesc->enmType)
     313    {
     314        case DBGFREGVALTYPE_U64:
     315            u64Value = pValue->u64;
     316            fMask    = pfMask->u64;
     317            fMaskMax = UINT64_MAX;
     318            break;
     319        case DBGFREGVALTYPE_U32:
     320            u64Value = pValue->u32;
     321            fMask    = pfMask->u32;
     322            fMaskMax = UINT32_MAX;
     323            break;
     324        case DBGFREGVALTYPE_U16:
     325            u64Value = pValue->u16;
     326            fMask    = pfMask->u16;
     327            fMaskMax = UINT16_MAX;
     328            break;
     329        default:                    AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     330    }
     331    if (fMask != fMaskMax)
     332    {
     333        uint64_t u64FullValue;
     334        rc = CPUMQueryGuestMsr(pVCpu, pDesc->offRegister, &u64FullValue);
     335        if (RT_FAILURE(rc))
     336            return rc;
     337        u64Value = (u64FullValue & ~fMask)
     338                 | (u64Value     &  fMask);
     339    }
     340
     341    /*
     342     * Perform the assignment.
     343     */
     344    return CPUMSetGuestMsr(pVCpu, pDesc->offRegister, u64Value);
     345}
     346
     347
     348/**
     349 * @interface_method_impl{DBGFREGDESC, pfnGet}
     350 */
     351static DECLCALLBACK(int) cpumR3RegGet_gdtr(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
     352{
     353    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     354    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     355
     356    VMCPU_ASSERT_EMT(pVCpu);
     357    Assert(pDesc->enmType == DBGFREGVALTYPE_DTR);
     358
     359    pValue->dtr.u32Limit  = pVCpu->cpum.s.Guest.gdtr.cbGdt;
     360    pValue->dtr.u64Base   = pVCpu->cpum.s.Guest.gdtr.pGdt;
     361    return VINF_SUCCESS;
     362}
     363
     364
     365/**
     366 * @interface_method_impl{DBGFREGDESC, pfnGet}
     367 */
     368static DECLCALLBACK(int) cpumR3RegSet_gdtr(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
    113369{
    114370    return VERR_NOT_IMPLEMENTED;
    115371}
    116372
    117 static DECLCALLBACK(int) cpumR3RegSet_crX(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCPUMCTX pCtx, RTUINT128U uValue, RTUINT128U fMask)
     373
     374/**
     375 * @interface_method_impl{DBGFREGDESC, pfnGet}
     376 */
     377static DECLCALLBACK(int) cpumR3RegGet_idtr(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
     378{
     379    PVMCPU      pVCpu   = (PVMCPU)pvUser;
     380    void const *pv      = (uint8_t const *)&pVCpu->cpum.s.Guest + pDesc->offRegister;
     381
     382    VMCPU_ASSERT_EMT(pVCpu);
     383    Assert(pDesc->enmType == DBGFREGVALTYPE_DTR);
     384
     385    pValue->dtr.u32Limit  = pVCpu->cpum.s.Guest.idtr.cbIdt;
     386    pValue->dtr.u64Base   = pVCpu->cpum.s.Guest.idtr.pIdt;
     387    return VINF_SUCCESS;
     388}
     389
     390
     391/**
     392 * @interface_method_impl{DBGFREGDESC, pfnGet}
     393 */
     394static DECLCALLBACK(int) cpumR3RegSet_idtr(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
    118395{
    119396    return VERR_NOT_IMPLEMENTED;
    120397}
    121398
    122 static DECLCALLBACK(int) cpumR3RegGet_drX(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCCPUMCTX pCtx, PRTUINT128U puValue)
     399/**
     400 * @interface_method_impl{DBGFREGDESC, pfnGet}
     401 */
     402static DECLCALLBACK(int) cpumR3RegGet_ftw(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
    123403{
    124404    return VERR_NOT_IMPLEMENTED;
    125405}
    126406
    127 static DECLCALLBACK(int) cpumR3RegSet_drX(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCPUMCTX pCtx, RTUINT128U uValue, RTUINT128U fMask)
     407/**
     408 * @interface_method_impl{DBGFREGDESC, pfnGet}
     409 */
     410static DECLCALLBACK(int) cpumR3RegSet_ftw(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
    128411{
    129412    return VERR_NOT_IMPLEMENTED;
    130413}
    131414
    132 static DECLCALLBACK(int) cpumR3RegGet_msr(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCCPUMCTX pCtx, PRTUINT128U puValue)
    133 {
    134     return VERR_NOT_IMPLEMENTED;
    135 }
    136 
    137 static DECLCALLBACK(int) cpumR3RegSet_msr(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCPUMCTX pCtx, RTUINT128U uValue, RTUINT128U fMask)
    138 {
    139     return VERR_NOT_IMPLEMENTED;
    140 }
    141 
    142 static DECLCALLBACK(int) cpumR3RegGet_gdtr(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCCPUMCTX pCtx, PRTUINT128U puValue)
    143 {
    144     return VERR_NOT_IMPLEMENTED;
    145 }
    146 
    147 static DECLCALLBACK(int) cpumR3RegSet_gdtr(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCPUMCTX pCtx, RTUINT128U uValue, RTUINT128U fMask)
    148 {
    149     return VERR_NOT_IMPLEMENTED;
    150 }
    151 
    152 static DECLCALLBACK(int) cpumR3RegGet_idtr(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCCPUMCTX pCtx, PRTUINT128U puValue)
    153 {
    154     return VERR_NOT_IMPLEMENTED;
    155 }
    156 
    157 static DECLCALLBACK(int) cpumR3RegSet_idtr(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCPUMCTX pCtx, RTUINT128U uValue, RTUINT128U fMask)
    158 {
    159     return VERR_NOT_IMPLEMENTED;
    160 }
    161 
    162 static DECLCALLBACK(int) cpumR3RegGet_ftw(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCCPUMCTX pCtx, PRTUINT128U puValue)
    163 {
    164     return VERR_NOT_IMPLEMENTED;
    165 }
    166 
    167 static DECLCALLBACK(int) cpumR3RegSet_ftw(PVMCPU pVCpu, PCDBGFREGDESC pDesc, PCPUMCTX pCtx, RTUINT128U uValue, RTUINT128U fMask)
    168 {
    169     return VERR_NOT_IMPLEMENTED;
    170 }
    171 
    172 /**
    173  * @interface_method_impl{DBGFREGDESC, pfnGet}
    174  */
    175 static DECLCALLBACK(int) cpumR3RegGet_stN(void *pvUser, PCDBGFREGDESC pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask)
     415/**
     416 * @interface_method_impl{DBGFREGDESC, pfnGet}
     417 */
     418static DECLCALLBACK(int) cpumR3RegGet_stN(void *pvUser, PCDBGFREGDESC pDesc, PDBGFREGVAL pValue)
    176419{
    177420    return VERR_NOT_IMPLEMENTED;
     
    220463static DBGFREGALIAS const g_aCpumRegAliases_fpuip[] =
    221464{
    222     { "fpuip", DBGFREGVALTYPE_U16  },
     465    { "fpuip16", DBGFREGVALTYPE_U16  },
    223466    { NULL, DBGFREGVALTYPE_INVALID }
    224467};
     
    226469static DBGFREGALIAS const g_aCpumRegAliases_fpudp[] =
    227470{
    228     { "fpudp", DBGFREGVALTYPE_U16  },
     471    { "fpudp16", DBGFREGVALTYPE_U16  },
    229472    { NULL, DBGFREGVALTYPE_INVALID }
    230473};
     
    497740static DBGFREGDESC const g_aCpumRegDescs[] =
    498741{
     742#define CPUMREGDESC_RW_AS(a_szName, a_RegSuff, a_TypeSuff, a_CpumCtxMemb, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
     743    { a_szName, DBGFREG_##a_RegSuff, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/,            RT_OFFSETOF(CPUMCTX, a_CpumCtxMemb), a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
     744#define CPUMREGDESC_RO_AS(a_szName, a_RegSuff, a_TypeSuff, a_CpumCtxMemb, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
     745    { a_szName, DBGFREG_##a_RegSuff, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, RT_OFFSETOF(CPUMCTX, a_CpumCtxMemb), a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
     746#define CPUMREGDESC_EX_AS(a_szName, a_RegSuff, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
     747    { a_szName, DBGFREG_##a_RegSuff, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/,            a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
     748
    499749#define CPUMREGDESC_REG(UName, LName) \
    500     { #LName, DBGFREG_##UName, DBGFREGVALTYPE_U64, 0, RT_OFFSETOF(CPUMCTX, LName), cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_##LName, NULL }
     750    CPUMREGDESC_RW_AS(#LName,           UName,          U64, LName,                 cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_##LName,  NULL)
    501751    CPUMREGDESC_REG(RAX, rax),
    502752    CPUMREGDESC_REG(RCX, rcx),
    503753    CPUMREGDESC_REG(RDX, rdx),
     754    CPUMREGDESC_REG(RBX, rbx),
    504755    CPUMREGDESC_REG(RSP, rsp),
    505756    CPUMREGDESC_REG(RBP, rbp),
     
    515766    CPUMREGDESC_REG(R15, r15),
    516767#define CPUMREGDESC_SEG(UName, LName) \
    517     { #LName,         DBGFREG_##UName,        DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, LName),               cpumR3RegGet_Generic, cpumR3RegSet_seg,     NULL, NULL }, \
    518     { #LName "_attr", DBGFREG_##UName##_ATTR, DBGFREGVALTYPE_U32, 0, RT_OFFSETOF(CPUMCTX, LName##Hid.Attr.u),   cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_seg }, \
    519     { #LName "_base", DBGFREG_##UName##_ATTR, DBGFREGVALTYPE_U64, 0, RT_OFFSETOF(CPUMCTX, LName##Hid.u64Base),  cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL }, \
    520     { #LName "_lim",  DBGFREG_##UName##_ATTR, DBGFREGVALTYPE_U32, 0, RT_OFFSETOF(CPUMCTX, LName##Hid.u32Limit), cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL }
     768    CPUMREGDESC_RW_AS(#LName,           UName,          U16, LName,                 cpumR3RegGet_Generic, cpumR3RegSet_seg,     NULL,                       NULL                ), \
     769    CPUMREGDESC_RW_AS(#LName "_attr",   UName##_ATTR,   U32, LName##Hid.Attr.u,     cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_seg), \
     770    CPUMREGDESC_RW_AS(#LName "_base",   UName##_BASE,   U64, LName##Hid.u64Base,    cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       NULL                ), \
     771    CPUMREGDESC_RW_AS(#LName "_lim",    UName##_LIMIT,  U32, LName##Hid.u32Limit,   cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       NULL                )
    521772    CPUMREGDESC_SEG(CS, cs),
    522773    CPUMREGDESC_SEG(DS, ds),
     
    526777    CPUMREGDESC_SEG(SS, ss),
    527778    CPUMREGDESC_REG(RIP, rip),
    528     { "rflags",     DBGFREG_RFLAGS,     DBGFREGVALTYPE_U64, 0, RT_OFFSETOF(CPUMCTX, rflags),         cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_rflags, g_aCpumRegFields_rflags },
    529     { "fcw",        DBGFREG_FCW,        DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, fpu.FCW),        cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_fcw },
    530     { "fsw",        DBGFREG_FSW,        DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, fpu.FSW),        cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_fsw },
    531     { "ftw",        DBGFREG_FTW,        DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, fpu.FTW),        cpumR3RegGet_ftw,     cpumR3RegSet_ftw,     NULL, g_aCpumRegFields_ftw },
    532     { "fop",        DBGFREG_FOP,        DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, fpu.FOP),        cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
    533     { "fpuip",      DBGFREG_FPUIP,      DBGFREGVALTYPE_U32, 0, RT_OFFSETOF(CPUMCTX, fpu.FPUIP),      cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_fpuip, NULL },
    534     { "fpucs",      DBGFREG_FPUCS,      DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, fpu.CS),         cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
    535     { "fpudp",      DBGFREG_FPUDP,      DBGFREGVALTYPE_U32, 0, RT_OFFSETOF(CPUMCTX, fpu.FPUDP),      cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_fpudp, NULL },
    536     { "fpuds",      DBGFREG_FPUDS,      DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, fpu.DS),         cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
    537     { "mxcsr",      DBGFREG_MXCSR,      DBGFREGVALTYPE_U32, 0, RT_OFFSETOF(CPUMCTX, fpu.MXCSR),      cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_mxcsr },
    538     { "mxcsr_mask", DBGFREG_MXCSR_MASK, DBGFREGVALTYPE_U32, 0, RT_OFFSETOF(CPUMCTX, fpu.MXCSR_MASK), cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_mxcsr },
     779    CPUMREGDESC_RW_AS("rflags",         RFLAGS,         U64, rflags,                cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_rflags,   g_aCpumRegFields_rflags ),
     780    CPUMREGDESC_RW_AS("fcw",            FCW,            U16, fpu.FCW,               cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_fcw    ),
     781    CPUMREGDESC_RW_AS("fsw",            FSW,            U16, fpu.FSW,               cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_fsw    ),
     782    CPUMREGDESC_RW_AS("ftw",            FTW,            U16, fpu.FTW,               cpumR3RegGet_ftw,     cpumR3RegSet_ftw,     NULL,                       g_aCpumRegFields_ftw    ),
     783    CPUMREGDESC_RW_AS("fop",            FOP,            U16, fpu.FOP,               cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       NULL                    ),
     784    CPUMREGDESC_RW_AS("fpuip",          FPUIP,          U32, fpu.FPUIP,             cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_fpuip,    NULL                    ),
     785    CPUMREGDESC_RW_AS("fpucs",          FPUCS,          U16, fpu.CS,                cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       NULL                    ),
     786    CPUMREGDESC_RW_AS("fpudp",          FPUDP,          U32, fpu.FPUDP,             cpumR3RegGet_Generic, cpumR3RegSet_Generic, g_aCpumRegAliases_fpudp,    NULL                    ),
     787    CPUMREGDESC_RW_AS("fpuds",          FPUDS,          U16, fpu.DS,                cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       NULL                    ),
     788    CPUMREGDESC_RW_AS("mxcsr",          MXCSR,          U32, fpu.MXCSR,             cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_mxcsr  ),
     789    CPUMREGDESC_RW_AS("mxcsr_mask",     MXCSR_MASK,     U32, fpu.MXCSR_MASK,        cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_mxcsr  ),
    539790#define CPUMREGDESC_ST(n) \
    540     { "st" #n,      DBGFREG_ST##n,      DBGFREGVALTYPE_LRD, 0, ~(size_t)0, cpumR3RegGet_stN, cpumR3RegSet_stN, NULL, g_aCpumRegFields_stN }
     791    CPUMREGDESC_RW_AS("st" #n,          ST##n,          LRD, fpu.aRegs[n],          cpumR3RegGet_stN,     cpumR3RegSet_stN,     NULL,                       g_aCpumRegFields_stN    )
    541792    CPUMREGDESC_ST(0),
    542793    CPUMREGDESC_ST(1),
     
    548799    CPUMREGDESC_ST(7),
    549800#define CPUMREGDESC_MM(n) \
    550     { "mm" #n,      DBGFREG_MM##n,      DBGFREGVALTYPE_U64, 0, RT_OFFSETOF(CPUMCTX, fpu.aRegs[n].mmx), cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_mmN }
     801    CPUMREGDESC_RW_AS("mm" #n,          MM##n,          U64, fpu.aRegs[n].mmx,      cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_mmN    )
    551802    CPUMREGDESC_MM(0),
    552803    CPUMREGDESC_MM(1),
     
    558809    CPUMREGDESC_MM(7),
    559810#define CPUMREGDESC_XMM(n) \
    560     { "xmm" #n,     DBGFREG_XMM##n,     DBGFREGVALTYPE_U128, 0, RT_OFFSETOF(CPUMCTX, fpu.aXMM[n].xmm), cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, g_aCpumRegFields_xmmN }
     811    CPUMREGDESC_RW_AS("xmm" #n,         XMM##n,         U128, fpu.aXMM[n].xmm,      cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,                       g_aCpumRegFields_xmmN   )
    561812    CPUMREGDESC_XMM(0),
    562813    CPUMREGDESC_XMM(1),
     
    575826    CPUMREGDESC_XMM(14),
    576827    CPUMREGDESC_XMM(15),
    577     { "gdtr_base",  DBGFREG_GDTR_BASE,      DBGFREGVALTYPE_U64, 0, RT_OFFSETOF(CPUMCTX, gdtr.pGdt),  cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
    578     { "gdtr_limit", DBGFREG_GDTR_LIMIT,     DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, gdtr.cbGdt), cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
    579     { "idtr_base",  DBGFREG_IDTR_BASE,      DBGFREGVALTYPE_U64, 0, RT_OFFSETOF(CPUMCTX, idtr.pIdt),  cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
    580     { "idtr_limit", DBGFREG_IDTR_LIMIT,     DBGFREGVALTYPE_U16, 0, RT_OFFSETOF(CPUMCTX, idtr.cbIdt), cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL, NULL },
     828    CPUMREGDESC_RW_AS("gdtr_base",      GDTR_BASE,      U64, gdtr.pGdt,          cpumR3RegGet_Generic,    cpumR3RegSet_Generic, NULL,                       NULL                    ),
     829    CPUMREGDESC_RW_AS("gdtr_limit",     GDTR_LIMIT,     U16, gdtr.cbGdt,         cpumR3RegGet_Generic,    cpumR3RegSet_Generic, NULL,                       NULL                    ),
     830    CPUMREGDESC_RW_AS("idtr_base",      IDTR_BASE,      U64, idtr.pIdt,          cpumR3RegGet_Generic,    cpumR3RegSet_Generic, NULL,                       NULL                    ),
     831    CPUMREGDESC_RW_AS("idtr_limit",     IDTR_LIMIT,     U16, idtr.cbIdt,         cpumR3RegGet_Generic,    cpumR3RegSet_Generic, NULL,                       NULL                    ),
    581832    CPUMREGDESC_SEG(LDTR, ldtr),
    582833    CPUMREGDESC_SEG(TR, tr),
    583     { "cr0",        DBGFREG_CR0,       DBGFREGVALTYPE_U32, 0, 0, cpumR3RegGet_crX, cpumR3RegSet_crX, g_aCpumRegAliases_cr0, g_aCpumRegFields_cr0 },
    584     { "cr2",        DBGFREG_CR2,       DBGFREGVALTYPE_U64, 0, 2, cpumR3RegGet_crX, cpumR3RegSet_crX, NULL, NULL },
    585     { "cr3",        DBGFREG_CR3,       DBGFREGVALTYPE_U64, 0, 3, cpumR3RegGet_crX, cpumR3RegSet_crX, NULL, g_aCpumRegFields_cr3 },
    586     { "cr4",        DBGFREG_CR4,       DBGFREGVALTYPE_U32, 0, 4, cpumR3RegGet_crX, cpumR3RegSet_crX, NULL, g_aCpumRegFields_cr4 },
    587     { "cr8",        DBGFREG_CR8,       DBGFREGVALTYPE_U32, 0, 8, cpumR3RegGet_crX, cpumR3RegSet_crX, NULL, NULL },
    588     { "dr0",        DBGFREG_DR0,       DBGFREGVALTYPE_U64, 0, 0, cpumR3RegGet_drX, cpumR3RegSet_drX, NULL, NULL },
    589     { "dr1",        DBGFREG_DR1,       DBGFREGVALTYPE_U64, 0, 1, cpumR3RegGet_drX, cpumR3RegSet_drX, NULL, NULL },
    590     { "dr2",        DBGFREG_DR2,       DBGFREGVALTYPE_U64, 0, 2, cpumR3RegGet_drX, cpumR3RegSet_drX, NULL, NULL },
    591     { "dr3",        DBGFREG_DR3,       DBGFREGVALTYPE_U64, 0, 3, cpumR3RegGet_drX, cpumR3RegSet_drX, NULL, NULL },
    592     { "dr6",        DBGFREG_DR6,       DBGFREGVALTYPE_U32, 0, 6, cpumR3RegGet_drX, cpumR3RegSet_drX, NULL, g_aCpumRegFields_dr6 },
    593     { "dr7",        DBGFREG_DR7,       DBGFREGVALTYPE_U32, 0, 7, cpumR3RegGet_drX, cpumR3RegSet_drX, NULL, g_aCpumRegFields_dr7 },
    594     { "apic_base",    DBGFREG_MSR_IA32_APICBASE,      DBGFREGVALTYPE_U32, 0, MSR_IA32_APICBASE,      cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_apic_base },
    595     { "pat",          DBGFREG_MSR_IA32_CR_PAT,        DBGFREGVALTYPE_U64, 0, MSR_IA32_CR_PAT,        cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_cr_pat },
    596     { "perf_status",  DBGFREG_MSR_IA32_PERF_STATUS,   DBGFREGVALTYPE_U64, 0, MSR_IA32_PERF_STATUS,   cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_perf_status },
    597     { "sysenter_cs",  DBGFREG_MSR_IA32_SYSENTER_CS,   DBGFREGVALTYPE_U16, 0, MSR_IA32_SYSENTER_CS,   cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    598     { "sysenter_eip", DBGFREG_MSR_IA32_SYSENTER_EIP,  DBGFREGVALTYPE_U32, 0, MSR_IA32_SYSENTER_EIP,  cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    599     { "sysenter_esp", DBGFREG_MSR_IA32_SYSENTER_ESP,  DBGFREGVALTYPE_U32, 0, MSR_IA32_SYSENTER_ESP,  cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    600     { "tsc",          DBGFREG_MSR_IA32_TSC,           DBGFREGVALTYPE_U32, 0, MSR_IA32_TSC,           cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    601     { "efer",         DBGFREG_MSR_K6_EFER,            DBGFREGVALTYPE_U32, 0, MSR_K6_EFER,            cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_efer },
    602     { "star",         DBGFREG_MSR_K6_STAR,            DBGFREGVALTYPE_U64, 0, MSR_K6_STAR,            cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_star },
    603     { "cstar",        DBGFREG_MSR_K8_CSTAR,           DBGFREGVALTYPE_U64, 0, MSR_K8_CSTAR,           cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_cstar },
    604     { "msr_fs_base",  DBGFREG_MSR_K8_FS_BASE,         DBGFREGVALTYPE_U64, 0, MSR_K8_FS_BASE,         cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    605     { "msr_gs_base",  DBGFREG_MSR_K8_GS_BASE,         DBGFREGVALTYPE_U64, 0, MSR_K8_GS_BASE,         cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    606     { "krnl_gs_base", DBGFREG_MSR_K8_KERNEL_GS_BASE,  DBGFREGVALTYPE_U64, 0, MSR_K8_KERNEL_GS_BASE,  cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    607     { "lstar",        DBGFREG_MSR_K8_LSTAR,           DBGFREGVALTYPE_U64, 0, MSR_K8_LSTAR,           cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, g_aCpumRegFields_lstar },
    608     { "tsc_aux",      DBGFREG_MSR_K8_TSC_AUX,         DBGFREGVALTYPE_U64, 0, MSR_K8_TSC_AUX,         cpumR3RegGet_msr, cpumR3RegSet_msr, NULL, NULL },
    609     { "ah",           DBGFREG_AH,       DBGFREGVALTYPE_U8,  0, RT_OFFSETOF(CPUMCTX, rax) + 1,  NULL, NULL, NULL, NULL },
    610     { "ch",           DBGFREG_CH,       DBGFREGVALTYPE_U8,  0, RT_OFFSETOF(CPUMCTX, rcx) + 1,  NULL, NULL, NULL, NULL },
    611     { "dh",           DBGFREG_DH,       DBGFREGVALTYPE_U8,  0, RT_OFFSETOF(CPUMCTX, rdx) + 1,  NULL, NULL, NULL, NULL },
    612     { "bh",           DBGFREG_BH,       DBGFREGVALTYPE_U8,  0, RT_OFFSETOF(CPUMCTX, rbx) + 1,  NULL, NULL, NULL, NULL },
    613     { "gdtr",         DBGFREG_GDTR,     DBGFREGVALTYPE_DTR, 0, ~(size_t)0, cpumR3RegGet_gdtr, cpumR3RegSet_gdtr, NULL, NULL },
    614     { "idtr",         DBGFREG_IDTR,     DBGFREGVALTYPE_DTR, 0, ~(size_t)0, cpumR3RegGet_idtr, cpumR3RegSet_idtr, NULL, NULL },
     834    CPUMREGDESC_EX_AS("cr0",            CR0,            U32, 0,                  cpumR3RegGet_crX,        cpumR3RegSet_crX,     g_aCpumRegAliases_cr0,      g_aCpumRegFields_cr0    ),
     835    CPUMREGDESC_EX_AS("cr2",            CR2,            U64, 2,                  cpumR3RegGet_crX,        cpumR3RegSet_crX,     NULL,                       NULL                    ),
     836    CPUMREGDESC_EX_AS("cr3",            CR3,            U64, 3,                  cpumR3RegGet_crX,        cpumR3RegSet_crX,     NULL,                       g_aCpumRegFields_cr3    ),
     837    CPUMREGDESC_EX_AS("cr4",            CR4,            U32, 4,                  cpumR3RegGet_crX,        cpumR3RegSet_crX,     NULL,                       g_aCpumRegFields_cr4    ),
     838    CPUMREGDESC_EX_AS("cr8",            CR8,            U32, 8,                  cpumR3RegGet_crX,        cpumR3RegSet_crX,     NULL,                       NULL                    ),
     839    CPUMREGDESC_EX_AS("dr0",            DR0,            U64, 0,                  cpumR3RegGet_drX,        cpumR3RegSet_drX,     NULL,                       NULL                    ),
     840    CPUMREGDESC_EX_AS("dr1",            DR1,            U64, 1,                  cpumR3RegGet_drX,        cpumR3RegSet_drX,     NULL,                       NULL                    ),
     841    CPUMREGDESC_EX_AS("dr2",            DR2,            U64, 2,                  cpumR3RegGet_drX,        cpumR3RegSet_drX,     NULL,                       NULL                    ),
     842    CPUMREGDESC_EX_AS("dr3",            DR3,            U64, 3,                  cpumR3RegGet_drX,        cpumR3RegSet_drX,     NULL,                       NULL                    ),
     843    CPUMREGDESC_EX_AS("dr6",            DR6,            U32, 6,                  cpumR3RegGet_drX,        cpumR3RegSet_drX,     NULL,                       g_aCpumRegFields_dr6    ),
     844    CPUMREGDESC_EX_AS("dr7",            DR7,            U32, 7,                  cpumR3RegGet_drX,        cpumR3RegSet_drX,     NULL,                       g_aCpumRegFields_dr7    ),
     845#define CPUMREGDESC_MSR(a_szName, UName, a_TypeSuff, a_paSubFields) \
     846    CPUMREGDESC_EX_AS(a_szName,         MSR_##UName,    a_TypeSuff, MSR_##UName, cpumR3RegGet_msr,        cpumR3RegSet_msr,     NULL,                       a_paSubFields           )
     847    CPUMREGDESC_MSR("apic_base",     IA32_APICBASE,     U32, g_aCpumRegFields_apic_base  ),
     848    CPUMREGDESC_MSR("pat",           IA32_CR_PAT,       U64, g_aCpumRegFields_cr_pat     ),
     849    CPUMREGDESC_MSR("perf_status",   IA32_PERF_STATUS,  U64, g_aCpumRegFields_perf_status),
     850    CPUMREGDESC_MSR("sysenter_cs",   IA32_SYSENTER_CS,  U16, NULL                        ),
     851    CPUMREGDESC_MSR("sysenter_eip",  IA32_SYSENTER_EIP, U32, NULL                        ),
     852    CPUMREGDESC_MSR("sysenter_esp",  IA32_SYSENTER_ESP, U32, NULL                        ),
     853    CPUMREGDESC_MSR("tsc",           IA32_TSC,          U32, NULL                        ),
     854    CPUMREGDESC_MSR("efer",          K6_EFER,           U32, g_aCpumRegFields_efer       ),
     855    CPUMREGDESC_MSR("star",          K6_STAR,           U64, g_aCpumRegFields_star       ),
     856    CPUMREGDESC_MSR("cstar",         K8_CSTAR,          U64, g_aCpumRegFields_cstar      ),
     857    CPUMREGDESC_MSR("msr_fs_base",   K8_FS_BASE,        U64, NULL                        ),
     858    CPUMREGDESC_MSR("msr_gs_base",   K8_GS_BASE,        U64, NULL                        ),
     859    CPUMREGDESC_MSR("krnl_gs_base",  K8_KERNEL_GS_BASE, U64, NULL                        ),
     860    CPUMREGDESC_MSR("lstar",         K8_LSTAR,          U64, g_aCpumRegFields_lstar      ),
     861    CPUMREGDESC_MSR("sf_mask",       K8_SF_MASK,        U64, NULL                        ),
     862    CPUMREGDESC_MSR("tsc_aux",       K8_TSC_AUX,        U64, NULL                        ),
     863    CPUMREGDESC_EX_AS("ah",             AH,             U8,  RT_OFFSETOF(CPUMCTX, rax) + 1, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,               NULL                    ),
     864    CPUMREGDESC_EX_AS("ch",             CH,             U8,  RT_OFFSETOF(CPUMCTX, rcx) + 1, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,               NULL                    ),
     865    CPUMREGDESC_EX_AS("dh",             DH,             U8,  RT_OFFSETOF(CPUMCTX, rdx) + 1, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,               NULL                    ),
     866    CPUMREGDESC_EX_AS("bh",             BH,             U8,  RT_OFFSETOF(CPUMCTX, rbx) + 1, cpumR3RegGet_Generic, cpumR3RegSet_Generic, NULL,               NULL                    ),
     867    CPUMREGDESC_RW_AS("gdtr",           GDTR,           DTR, gdtr,              cpumR3RegGet_gdtr,        cpumR3RegSet_gdtr,    NULL,                       NULL                    ),
     868    CPUMREGDESC_RW_AS("idtr",           IDTR,           DTR, idtr,              cpumR3RegGet_idtr,        cpumR3RegSet_idtr,    NULL,                       NULL                    ),
     869    DBGFREGDESC_TERMINATOR()
    615870#undef CPUMREGDESC_REG
    616871#undef CPUMREGDESC_SEG
     
    618873#undef CPUMREGDESC_MM
    619874#undef CPUMREGDESC_XMM
    620 };
    621 
    622 #endif
     875#undef CPUMREGDESC_MSR
     876};
     877
     878
     879/**
     880 * Initializes the debugger related sides of the CPUM component.
     881 *
     882 * Called by CPUMR3Init.
     883 *
     884 * @returns VBox status code.
     885 * @param   pVM                 The VM handle.
     886 */
     887int cpumR3DbgInit(PVM pVM)
     888{
     889    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     890    {
     891        int rc = DBGFR3RegRegisterCpu(pVM, &pVM->aCpus[iCpu], g_aCpumRegDescs);
     892        AssertLogRelRCReturn(rc, rc);
     893    }
     894
     895    return VINF_SUCCESS;
     896}
     897
  • trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp

    r35470 r35490  
    3030#include <iprt/ctype.h>
    3131#include <iprt/string.h>
     32#include <iprt/uint128.h>
    3233
    3334
     
    156157int dbgfR3RegInit(PVM pVM)
    157158{
    158     return RTSemRWCreate(&pVM->dbgf.s.hRegDbLock);
     159    int rc = VINF_SUCCESS;
     160    if (!pVM->dbgf.s.fRegDbInitialized)
     161    {
     162        rc = RTSemRWCreate(&pVM->dbgf.s.hRegDbLock);
     163        pVM->dbgf.s.fRegDbInitialized = RT_SUCCESS(rc);
     164    }
     165    return rc;
    159166}
    160167
     
    169176    RTSemRWDestroy(pVM->dbgf.s.hRegDbLock);
    170177    pVM->dbgf.s.hRegDbLock = NIL_RTSEMRW;
     178    pVM->dbgf.s.fRegDbInitialized = false;
    171179}
    172180
     
    179187 * @returns true if valid, false if not.
    180188 * @param   pszName             The register name to validate.
    181  */
    182 static bool dbgfR3RegIsNameValid(const char *pszName)
     189 * @param   chDot               Set to '.' if accepted, otherwise 0.
     190 */
     191static bool dbgfR3RegIsNameValid(const char *pszName, char chDot)
    183192{
    184193    const char *psz = pszName;
     
    189198        if (   !RT_C_IS_LOWER(ch)
    190199            && !RT_C_IS_DIGIT(ch)
    191             && ch != '_')
     200            && ch != '_'
     201            && ch != chDot)
    192202            return false;
    193203    if (psz - pszName > DBGF_REG_MAX_NAME)
     
    215225     */
    216226    /* The name components. */
    217     AssertMsgReturn(dbgfR3RegIsNameValid(pszPrefix), ("%s\n", pszPrefix), VERR_INVALID_NAME);
     227    AssertMsgReturn(dbgfR3RegIsNameValid(pszPrefix, 0), ("%s\n", pszPrefix), VERR_INVALID_NAME);
    218228    const char  *psz             = RTStrEnd(pszPrefix, RTSTR_MAX);
    219229    bool const   fNeedUnderscore = RT_C_IS_DIGIT(psz[-1]);
     
    228238    for (iDesc = 0; paRegisters[iDesc].pszName != NULL; iDesc++)
    229239    {
    230         AssertMsgReturn(dbgfR3RegIsNameValid(paRegisters[iDesc].pszName), ("%s (#%u)\n", paRegisters[iDesc].pszName, iDesc), VERR_INVALID_NAME);
     240        AssertMsgReturn(dbgfR3RegIsNameValid(paRegisters[iDesc].pszName, 0), ("%s (#%u)\n", paRegisters[iDesc].pszName, iDesc), VERR_INVALID_NAME);
    231241
    232242        if (enmType == DBGFREGSETTYPE_CPU)
     
    238248        AssertReturn(   paRegisters[iDesc].enmType > DBGFREGVALTYPE_INVALID
    239249                     && paRegisters[iDesc].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);
    240         AssertMsgReturn(paRegisters[iDesc].fFlags & ~DBGFREG_FLAGS_READ_ONLY,
     250        AssertMsgReturn(!(paRegisters[iDesc].fFlags & ~DBGFREG_FLAGS_READ_ONLY),
    241251                        ("%#x (#%u)\n", paRegisters[iDesc].fFlags, iDesc),
    242252                        VERR_INVALID_PARAMETER);
     
    251261            for (; paAliases[iAlias].pszName; iAlias++)
    252262            {
    253                 AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[iAlias].pszName), ("%s (%s)\n", paAliases[iAlias].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
     263                AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[iAlias].pszName, 0), ("%s (%s)\n", paAliases[iAlias].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
    254264                AssertReturn(   paAliases[iAlias].enmType > DBGFREGVALTYPE_INVALID
    255265                             && paAliases[iAlias].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);
     
    264274            for (; paSubFields[iSubField].pszName; iSubField++)
    265275            {
    266                 AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[iSubField].pszName), ("%s (%s)\n", paSubFields[iSubField].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
     276                AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[iSubField].pszName, '.'), ("%s (%s)\n", paSubFields[iSubField].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
    267277                AssertReturn(paSubFields[iSubField].iFirstBit + paSubFields[iSubField].cBits <= 128, VERR_INVALID_PARAMETER);
    268278                AssertReturn(paSubFields[iSubField].cBits + paSubFields[iSubField].cShift <= 128, VERR_INVALID_PARAMETER);
     
    323333        while (RT_SUCCESS(rc))
    324334        {
    325             size_t cchReg = strlen(paRegisters[iDesc].pszName);
    326             memcpy(pszReg, paRegisters[iDesc].pszName, cchReg + 1);
     335            size_t cchReg = strlen(pszRegName);
     336            memcpy(pszReg, pszRegName, cchReg + 1);
    327337            pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
    328338            if (!pLookupRec->Core.pszString)
     
    332342            pLookupRec->pAlias    = pCurAlias;
    333343            pLookupRec->pSubField = NULL;
     344            pLookupRec++;
    334345
    335346            PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields;
     
    348359                    pLookupRec->pAlias    = pCurAlias;
    349360                    pLookupRec->pSubField = &paSubFields[iSubField];
     361                    pLookupRec++;
    350362                }
    351363            }
     
    353365            /* next */
    354366            pCurAlias = pNextAlias++;
    355             if (   !pCurAlias
    356                 || !pCurAlias->pszName)
     367            if (!pCurAlias)
    357368                break;
    358369            pszRegName = pCurAlias->pszName;
     370            if (!pszRegName)
     371                break;
    359372        }
    360373    }
     374    Assert(pLookupRec == &pRegSet->paLookupRecs[pRegSet->cLookupRecs]);
    361375
    362376    if (RT_SUCCESS(rc))
     
    406420 *
    407421 * @returns VBox status code.
     422 * @param   pVM             The VM handle.
    408423 * @param   pVCpu           The virtual CPU handle.
    409424 * @param   paRegisters     The register descriptors.
    410425 */
    411 VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVMCPU pVCpu, PCDBGFREGDESC paRegisters)
    412 {
    413     return dbgfR3RegRegisterCommon(pVCpu->pVMR3, paRegisters, DBGFREGSETTYPE_CPU, pVCpu, "cpu", pVCpu->idCpu);
     426VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters)
     427{
     428    if (!pVM->dbgf.s.fRegDbInitialized)
     429    {
     430        int rc = dbgfR3RegInit(pVM);
     431        if (RT_FAILURE(rc))
     432            return rc;
     433    }
     434
     435    return dbgfR3RegRegisterCommon(pVM, paRegisters, DBGFREGSETTYPE_CPU, pVCpu, "cpu", pVCpu->idCpu);
    414436}
    415437
     
    10651087
    10661088/**
    1067  * Performs a left shift on a RTUINT128U value.
    1068  *
    1069  * @returns pVal.
    1070  * @param   pVal                The value to shift (input/output).
    1071  * @param   cBits               The number of bits to shift it.  Negative
    1072  *                              numbers are treated as right shifts.
    1073  */
    1074 static PRTUINT128U dbgfR3RegU128_ShiftLeft(PRTUINT128U pVal, int cBits)
    1075 {
    1076     RTUINT128U const InVal = *pVal;
    1077 
    1078     if (cBits >= 0)
    1079     {
    1080         if (cBits >= 128)
    1081             pVal->s.Lo  = pVal->s.Hi = 0;
    1082         else if (cBits >= 64)
    1083         {
    1084             pVal->s.Lo  = 0;
    1085             pVal->s.Hi  = InVal.s.Lo << (cBits - 64);
    1086         }
    1087         else
    1088         {
    1089             pVal->s.Hi  = InVal.s.Hi << cBits;
    1090             pVal->s.Hi |= InVal.s.Lo >> (64 - cBits);
    1091             pVal->s.Lo  = InVal.s.Lo << cBits;
    1092         }
    1093     }
    1094     else
    1095     {
    1096         /* (right shift) */
    1097         cBits = -cBits;
    1098         if (cBits >= 128)
    1099             pVal->s.Lo  = pVal->s.Hi = 0;
    1100         else if (cBits >= 64)
    1101         {
    1102             pVal->s.Hi  = 0;
    1103             pVal->s.Lo  = InVal.s.Hi >> (cBits - 64);
    1104         }
    1105         else
    1106         {
    1107             pVal->s.Lo  = InVal.s.Lo >> cBits;
    1108             pVal->s.Lo |= InVal.s.Hi << (64 - cBits);
    1109             pVal->s.Hi  = InVal.s.Hi >> cBits;
    1110         }
    1111     }
    1112     return pVal;
    1113 }
    1114 
    1115 
    1116 /**
    1117  * ANDs the RTUINT128U value against a bitmask made up of the first @a cBits
    1118  * bits.
    1119  *
    1120  * @returns pVal.
    1121  * @param   pVal                The value to shift (input/output).
    1122  * @param   cBits               The number of bits in the AND mask.
    1123  */
    1124 static PRTUINT128U dbgfR3RegU128_AndNFirstBits(PRTUINT128U pVal, unsigned cBits)
    1125 {
    1126     if (cBits <= 64)
    1127     {
    1128         pVal->s.Hi  = 0;
    1129         pVal->s.Lo &= RT_BIT_64(cBits) - 1;
    1130     }
    1131     else if (cBits < 128)
    1132         pVal->s.Hi &= RT_BIT_64(cBits - 64) - 1;
    1133     return pVal;
    1134 }
    1135 
    1136 
    1137 /**
    11381089 * On CPU worker for the register queries, used by dbgfR3RegNmQueryWorker.
    11391090 *
     
    11771128                if (RT_SUCCESS(rc))
    11781129                {
    1179                     dbgfR3RegU128_ShiftLeft(&pValue->u128, -pSubField->iFirstBit);
    1180                     dbgfR3RegU128_AndNFirstBits(&pValue->u128, pSubField->cBits);
     1130                    RTUInt128AssignShiftLeft(&pValue->u128, -pSubField->iFirstBit);
     1131                    RTUInt128AssignAndNFirstBits(&pValue->u128, pSubField->cBits);
    11811132                    if (pSubField->cShift)
    1182                         dbgfR3RegU128_ShiftLeft(&pValue->u128, pSubField->cShift);
     1133                        RTUInt128AssignShiftLeft(&pValue->u128, pSubField->cShift);
    11831134                }
    11841135            }
  • trunk/src/VBox/VMM/include/CPUMInternal.h

    r35333 r35490  
    404404RT_C_DECLS_BEGIN
    405405
    406 DECLASM(int)      cpumHandleLazyFPUAsm(PCPUMCPU pCPUM);
     406#ifdef IN_RING3
     407int                 cpumR3DbgInit(PVM pVM);
     408#endif
     409
     410DECLASM(int)        cpumHandleLazyFPUAsm(PCPUMCPU pCPUM);
    407411
    408412#ifdef IN_RING0
    409 DECLASM(int)      cpumR0SaveHostRestoreGuestFPUState(PCPUMCPU pCPUM);
    410 DECLASM(int)      cpumR0SaveGuestRestoreHostFPUState(PCPUMCPU pCPUM);
    411 DECLASM(int)      cpumR0SaveHostFPUState(PCPUMCPU pCPUM);
    412 DECLASM(int)      cpumR0RestoreHostFPUState(PCPUMCPU pCPUM);
    413 DECLASM(void)     cpumR0LoadFPU(PCPUMCTX pCtx);
    414 DECLASM(void)     cpumR0SaveFPU(PCPUMCTX pCtx);
    415 DECLASM(void)     cpumR0LoadXMM(PCPUMCTX pCtx);
    416 DECLASM(void)     cpumR0SaveXMM(PCPUMCTX pCtx);
    417 DECLASM(void)     cpumR0SetFCW(uint16_t u16FCW);
    418 DECLASM(uint16_t) cpumR0GetFCW(void);
    419 DECLASM(void)     cpumR0SetMXCSR(uint32_t u32MXCSR);
    420 DECLASM(uint32_t) cpumR0GetMXCSR(void);
    421 DECLASM(void)     cpumR0LoadDRx(uint64_t const *pa4Regs);
    422 DECLASM(void)     cpumR0SaveDRx(uint64_t *pa4Regs);
     413DECLASM(int)        cpumR0SaveHostRestoreGuestFPUState(PCPUMCPU pCPUM);
     414DECLASM(int)        cpumR0SaveGuestRestoreHostFPUState(PCPUMCPU pCPUM);
     415DECLASM(int)        cpumR0SaveHostFPUState(PCPUMCPU pCPUM);
     416DECLASM(int)        cpumR0RestoreHostFPUState(PCPUMCPU pCPUM);
     417DECLASM(void)       cpumR0LoadFPU(PCPUMCTX pCtx);
     418DECLASM(void)       cpumR0SaveFPU(PCPUMCTX pCtx);
     419DECLASM(void)       cpumR0LoadXMM(PCPUMCTX pCtx);
     420DECLASM(void)       cpumR0SaveXMM(PCPUMCTX pCtx);
     421DECLASM(void)       cpumR0SetFCW(uint16_t u16FCW);
     422DECLASM(uint16_t)   cpumR0GetFCW(void);
     423DECLASM(void)       cpumR0SetMXCSR(uint32_t u32MXCSR);
     424DECLASM(uint32_t)   cpumR0GetMXCSR(void);
     425DECLASM(void)       cpumR0LoadDRx(uint64_t const *pa4Regs);
     426DECLASM(void)       cpumR0SaveDRx(uint64_t *pa4Regs);
    423427#endif
    424428
  • trunk/src/VBox/VMM/include/DBGFInternal.h

    r35466 r35490  
    271271    bool volatile               afAsAliasPopuplated[DBGF_AS_COUNT];
    272272    /** Alignment padding. */
    273     bool                        afAlignment[2];
     273    bool                        afAlignment1[2];
    274274
    275275    /** The register database lock. */
     
    281281    /** The number of registers (aliases and sub-fields not counted). */
    282282    uint32_t                    cRegs;
     283    /** For early initialization by . */
     284    bool volatile               fRegDbInitialized;
    283285    /** Alignment padding. */
    284     uint32_t                    Alignment2;
     286    bool                        afAlignment2[3];
    285287
    286288    /** The current Guest OS digger. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette