VirtualBox

Changeset 108886 in vbox for trunk/src/VBox/VMM/testcase


Ignore:
Timestamp:
Apr 8, 2025 11:59:40 AM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168340
Message:

VMM/testcase/tstPGMAllGst-armv8: Updates to the testcase, add support for naming and setting individual bitfields for registers, bugref:10388

Location:
trunk/src/VBox/VMM/testcase
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/testcase/tstPGMAllGst-armv8.cpp

    r108879 r108886  
    6363
    6464/**
     65 * Named value.
     66 */
     67typedef struct TSTCFGNAMEDVALUE
     68{
     69    /** The name of the value. */
     70    const char *pszName;
     71    /** The integer value. */
     72    uint64_t   u64Val;
     73} TSTCFGNAMEDVALUE;
     74typedef TSTCFGNAMEDVALUE *PTSTCFGNAMEDVALUE;
     75typedef const TSTCFGNAMEDVALUE *PCTSTCFGNAMEDVALUE;
     76
     77
     78/**
     79 * A config bitfield.
     80 */
     81typedef struct TSTCFGBITFIELD
     82{
     83    /** The bitfield name. */
     84    const char          *pszName;
     85    /** The bitfield offset. */
     86    uint8_t             offBitfield;
     87    /** Number of bits for the bitfield. */
     88    uint8_t             cBits;
     89    /** Optional array of named values. */
     90    PCTSTCFGNAMEDVALUE  paNamedValues;
     91} TSTCFGBITFIELD;
     92typedef TSTCFGBITFIELD *PTSTCFGBITFIELD;
     93typedef const TSTCFGBITFIELD *PCTSTCFGBITFIELD;
     94
     95
     96/**
    6597 * Chunk of physical memory containing data.
    6698 */
     
    208240
    209241
     242static int tstMmuCfgReadBitfieldU64(RTTEST hTest, RTJSONVAL hObj, PCTSTCFGBITFIELD paBitfields, uint64_t *pu64Result)
     243{
     244    uint64_t u64 = 0;
     245
     246    uint32_t idx = 0;
     247    while (paBitfields[idx].pszName)
     248    {
     249        RTJSONVAL hValue = NIL_RTJSONVAL;
     250        int rc = RTJsonValueQueryByName(hObj, paBitfields[idx].pszName, &hValue);
     251        if (rc == VERR_NOT_FOUND)
     252        {
     253            idx++;
     254            continue;
     255        }
     256        if (RT_FAILURE(rc))
     257        {
     258            RTTestFailed(hTest, "Failed to query \"%s\" with %Rrc", paBitfields[idx].pszName, rc);
     259            return rc;
     260        }
     261
     262        RTJSONVALTYPE enmType = RTJsonValueGetType(hValue);
     263        switch (enmType)
     264        {
     265            case RTJSONVALTYPE_INTEGER:
     266            {
     267                int64_t i64Tmp = 0;
     268                rc = RTJsonValueQueryInteger(hValue, &i64Tmp);
     269                if (RT_FAILURE(rc))
     270                {
     271                    RTTestFailed(hTest, "Failed to query \"%s\" as an integer with %Rrc", paBitfields[idx].pszName, rc);
     272                    break;
     273                }
     274                else if (   i64Tmp < 0
     275                         || (uint64_t)i64Tmp > (RT_BIT_64(paBitfields[idx].cBits) - 1))
     276                {
     277                    RTTestFailed(hTest, "Value of \"%s\" is out of bounds, got %#RX64, maximum is %#RX64",
     278                                 paBitfields[idx].pszName, (uint64_t)i64Tmp, (RT_BIT_64(paBitfields[idx].cBits) - 1));
     279                    rc = VERR_INVALID_PARAMETER;
     280                }
     281                else
     282                    u64 |= ((uint64_t)i64Tmp) << paBitfields[idx].offBitfield;
     283                break;
     284            }
     285            case RTJSONVALTYPE_STRING:
     286            {
     287                if (paBitfields[idx].paNamedValues)
     288                {
     289                    const char *pszNamedValue = RTJsonValueGetString(hValue);
     290                    PCTSTCFGNAMEDVALUE pNamedValue = &paBitfields[idx].paNamedValues[0];
     291                    while (pNamedValue->pszName)
     292                    {
     293                        if (!RTStrICmp(pszNamedValue, pNamedValue->pszName))
     294                        {
     295                            u64 |= pNamedValue->u64Val << paBitfields[idx].offBitfield;
     296                            break;
     297                        }
     298                        pNamedValue++;
     299                    }
     300                    if (!pNamedValue->pszName)
     301                    {
     302                        RTTestFailed(hTest, "\"%s\" ist not a known named value for bitfield '%s'", pszNamedValue, paBitfields[idx].pszName);
     303                        rc = VERR_NOT_FOUND;
     304                    }
     305                }
     306                else
     307                {
     308                    RTTestFailed(hTest, "Bitfield \"%s\" doesn't support named values", paBitfields[idx].pszName);
     309                    rc = VERR_NOT_SUPPORTED;
     310                }
     311                break;
     312            }
     313            default:
     314                rc = VERR_NOT_SUPPORTED;
     315                RTTestFailed(hTest, "JSON value type %d is not supported\n", enmType);
     316                break;
     317        }
     318        RTJsonValueRelease(hValue);
     319
     320        if (RT_FAILURE(rc))
     321            return rc;
     322
     323        idx++;
     324    }
     325
     326    *pu64Result = u64;
     327    return VINF_SUCCESS;
     328}
     329
     330
     331static int tstMmuCfgReadU64(RTTEST hTest, RTJSONVAL hObj, const char *pszName, PCTSTCFGBITFIELD paBitfields, uint64_t *pu64Result)
     332{
     333    RTJSONVAL hValue = NIL_RTJSONVAL;
     334    int rc = RTJsonValueQueryByName(hObj, pszName, &hValue);
     335    if (RT_FAILURE(rc))
     336    {
     337        RTTestFailed(hTest, "Failed to query \"%s\" with %Rrc", pszName, rc);
     338        return rc;
     339    }
     340
     341    RTJSONVALTYPE enmType = RTJsonValueGetType(hValue);
     342    switch (enmType)
     343    {
     344        case RTJSONVALTYPE_INTEGER:
     345            rc = RTJsonValueQueryInteger(hValue, (int64_t *)pu64Result);
     346            break;
     347        case RTJSONVALTYPE_OBJECT:
     348            rc = tstMmuCfgReadBitfieldU64(hTest, hValue, paBitfields, pu64Result);
     349            break;
     350        default:
     351            rc = VERR_NOT_SUPPORTED;
     352            RTTestFailed(hTest, "JSON value type %d is not supported\n", enmType);
     353            break;
     354    }
     355
     356    RTJsonValueRelease(hValue);
     357    return rc;
     358}
     359
     360
    210361static DECLCALLBACK(int) tstZeroChunk(PAVLRU64NODECORE pCore, void *pvParam)
    211362{
     
    231382
    232383
    233 /**
    234  * Destroy the VM structure.
    235  *
    236  * @param   pVM     Pointer to the VM.
    237  */
    238384static void tstMmuCfgDestroy(PTSTPGMARMV8MMU pMmuCfg)
    239385{
     
    423569
    424570    /* Set MMU config (SCTLR, TCR, TTBR, etc.). */
    425     int64_t i64Tmp = 0;
    426     int rc = RTJsonValueQueryIntegerByName(hTestcase, "SCTLR_EL1", &i64Tmp);
     571    uint64_t u64RegSctlrEl1 = 0;
     572    int rc = tstMmuCfgReadU64(hTest, hTestcase, "SCTLR_EL1", NULL, &u64RegSctlrEl1);
    427573    if (RT_FAILURE(rc))
    428     {
    429         RTTestFailed(hTest, "Failed to query \"SCTLR_EL1\" with %Rrc", rc);
    430574        return rc;
    431     }
    432     uint64_t const u64RegSctlrEl1 = (uint64_t)i64Tmp;
    433 
    434     rc = RTJsonValueQueryIntegerByName(hTestcase, "TCR_EL1", &i64Tmp);
     575
     576    uint64_t u64RegTcrEl1 = 0;
     577    static const TSTCFGNAMEDVALUE s_aTgSizes[] =
     578    {
     579        { "4K",  0 },
     580        { "64K", 1 },
     581        { "16K", 2 },
     582        { NULL,  0 }
     583    };
     584    static const TSTCFGNAMEDVALUE s_aIpsSizes[] =
     585    {
     586        { "4G",   0 },
     587        { "64G",  1 },
     588        { "1T",   2 },
     589        { "4T",   3 },
     590        { "16T",  4 },
     591        { "256T", 5 },
     592        { "4P",   6 },
     593        { "64P",  7 },
     594
     595        { NULL,  0 }
     596    };
     597    static const TSTCFGBITFIELD s_aTcrEl1Bitfields[] =
     598    {
     599#define BITFIELD_CREATE_BOOL(a_Name, a_offBit) \
     600        { a_Name, a_offBit, 1, NULL }
     601
     602        BITFIELD_CREATE_BOOL("MTX1",   61),
     603        BITFIELD_CREATE_BOOL("MTX0",   60),
     604        BITFIELD_CREATE_BOOL("DS",     59),
     605        BITFIELD_CREATE_BOOL("TCMA1",  58),
     606        BITFIELD_CREATE_BOOL("TCMA0",  57),
     607        BITFIELD_CREATE_BOOL("E0PD1",  56),
     608        BITFIELD_CREATE_BOOL("E0PD0",  55),
     609        BITFIELD_CREATE_BOOL("NFD1",   54),
     610        BITFIELD_CREATE_BOOL("NFD0",   53),
     611        BITFIELD_CREATE_BOOL("TBID1",  52),
     612        BITFIELD_CREATE_BOOL("TBID0",  51),
     613        BITFIELD_CREATE_BOOL("HWU162", 50),
     614        BITFIELD_CREATE_BOOL("HWU161", 49),
     615        BITFIELD_CREATE_BOOL("HWU160", 48),
     616        BITFIELD_CREATE_BOOL("HWU159", 47),
     617        BITFIELD_CREATE_BOOL("HWU062", 46),
     618        BITFIELD_CREATE_BOOL("HWU061", 45),
     619        BITFIELD_CREATE_BOOL("HWU060", 44),
     620        BITFIELD_CREATE_BOOL("HWU059", 43),
     621        BITFIELD_CREATE_BOOL("HPD1",   42),
     622        BITFIELD_CREATE_BOOL("HPD0",   41),
     623        BITFIELD_CREATE_BOOL("HD",     40),
     624        BITFIELD_CREATE_BOOL("HA",     39),
     625        BITFIELD_CREATE_BOOL("TBI1",   38),
     626        BITFIELD_CREATE_BOOL("TBI0",   37),
     627        { "IPS",   32, 3, &s_aIpsSizes[0] },
     628        { "TG1",   30, 2, &s_aTgSizes[0]  },
     629        { "SH1",   28, 2, NULL },
     630        { "ORGN1", 26, 2, NULL },
     631        { "IRGN1", 24, 2, NULL },
     632        BITFIELD_CREATE_BOOL("EPD1",   33),
     633        BITFIELD_CREATE_BOOL("A1",     22),
     634        { "T1SZ",  16, 6, NULL },
     635
     636        { "TG0",   14, 2, &s_aTgSizes[0] },
     637        { "SH0",   12, 2, NULL },
     638        { "ORGN0", 10, 2, NULL },
     639        { "IRGN0",  8, 2, NULL },
     640        BITFIELD_CREATE_BOOL("EPD0",    7),
     641        { "T0SZ",   0, 6, NULL },
     642        { NULL,     0, 0, NULL }
     643
     644#undef BITFIELD_CREATE_BOOL
     645    };
     646    rc = tstMmuCfgReadU64(hTest, hTestcase, "TCR_EL1", &s_aTcrEl1Bitfields[0], &u64RegTcrEl1);
    435647    if (RT_FAILURE(rc))
    436     {
    437         RTTestFailed(hTest, "Failed to query \"TCR_EL1\" with %Rrc", rc);
    438648        return rc;
    439     }
    440     uint64_t const u64RegTcrEl1 = (uint64_t)i64Tmp;
    441 
    442     rc = RTJsonValueQueryIntegerByName(hTestcase, "TTBR0_EL1", &i64Tmp);
     649
     650    rc = tstMmuCfgReadU64(hTest, hTestcase, "TTBR0_EL1", NULL, &pVCpu->cpum.s.Guest.Ttbr0.u64);
    443651    if (RT_FAILURE(rc))
    444     {
    445         RTTestFailed(hTest, "Failed to query \"TTBR0_EL1\" with %Rrc", rc);
    446652        return rc;
    447     }
    448     pVCpu->cpum.s.Guest.Ttbr0.u64 = (uint64_t)i64Tmp;
    449 
    450     rc = RTJsonValueQueryIntegerByName(hTestcase, "TTBR1_EL1", &i64Tmp);
     653
     654    rc = tstMmuCfgReadU64(hTest, hTestcase, "TTBR1_EL1", NULL, &pVCpu->cpum.s.Guest.Ttbr1.u64);
    451655    if (RT_FAILURE(rc))
    452     {
    453         RTTestFailed(hTest, "Failed to query \"TTBR1_EL1\" with %Rrc", rc);
    454656        return rc;
    455     }
    456     pVCpu->cpum.s.Guest.Ttbr1.u64 = (uint64_t)i64Tmp;
    457 
    458657
    459658    uintptr_t const idxNewGstTtbr0 = pgmR3DeduceTypeFromTcr<ARMV8_TCR_EL1_AARCH64_T0SZ_SHIFT, ARMV8_TCR_EL1_AARCH64_TG0_SHIFT,
  • trunk/src/VBox/VMM/testcase/tstPGMAllGst-armv8.json

    r108879 r108886  
    4545        Name:      "4K Granules",
    4646        SCTLR_EL1: 0x1,
    47         TCR_EL1:   0,
     47        TCR_EL1:   { IPS: '64G', TG0: '4K', TG1: '4K' },
    4848        TTBR0_EL1: 0x0,
    4949        TTBR1_EL1: 0x1000,
Note: See TracChangeset for help on using the changeset viewer.

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