VirtualBox

Changeset 60724 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
Apr 27, 2016 5:00:29 PM (9 years ago)
Author:
vboxsync
Message:

bs3kit: updates (started on lidt)

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/Config.kmk

    r60596 r60724  
    707707          segment BS3TEXT32 \
    708708          segment BS3TEXT32_END \
     709        clname BS3CLASSSEPARATE32AND64BITCODE \
     710          segment BS3SEPARATE32AND64BITCODE \
     711          segment BS3SEPARATE32AND64BITCODE_END \
    709712        clname BS3CLASS64CODE \
    710713          segment BS3TEXT64_START \
     
    921924          segment BS3TEXT32 \
    922925          segment BS3TEXT32_END \
     926        clname BS3CLASSSEPARATE32AND64BITCODE \
     927          segment BS3SEPARATE32AND64BITCODE \
     928          segment BS3SEPARATE32AND64BITCODE_END \
    923929        clname BS3CLASS64CODE \
    924930          segment BS3TEXT64 \
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c

    r60686 r60724  
    4343        else bs3CpuBasic2_FailedF(a_szName "=" a_szFmt " expected " a_szFmt, (a_Actual), (a_Expected)); \
    4444    } while (0)
     45
     46
     47#ifdef BS3_INSTANTIATING_CMN
     48/** Indicating that we've got operand size prefix and that it matters. */
     49# define BS3CB2SIDTSGDT_F_OPSIZE    UINT8_C(0x01)
     50#endif
    4551
    4652#ifdef BS3_INSTANTIATING_MODE
     
    9096    bool        fSs;
    9197    uint8_t     bMode;
     98    uint8_t     fFlags;
    9299} BS3CB2SIDTSGDT;
    93100#endif
     
    131138extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32;
    132139extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64;
     140
     141extern FNBS3FAR     bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16;
     142extern FNBS3FAR     bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32;
     143extern FNBS3FAR     bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64;
     144extern FNBS3FAR     bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16;
     145extern FNBS3FAR     bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32;
     146extern FNBS3FAR     bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64;
     147extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16;
     148extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32;
     149extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64;
     150extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16;
     151extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32;
     152extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64;
     153
    133154#endif
    134155
     
    146167
    147168
     169/** SIDT test workers. */
    148170static BS3CB2SIDTSGDT const g_aSidtWorkers[] =
    149171{
     
    162184};
    163185
    164 
     186/** SGDT test workers. */
    165187static BS3CB2SIDTSGDT const g_aSgdtWorkers[] =
    166188{
     
    178200    { bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64 },
    179201};
     202
     203/** LIDT test workers. */
     204static BS3CB2SIDTSGDT const g_aLidtWorkers[] =
     205{
     206    { bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16,             11, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     207    { bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16,          12, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     208    { bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16,      12, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     209    { bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16,   13, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     210    { bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32,             11, false,   BS3_MODE_CODE_32, 0 },
     211    { bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32,          12, true,    BS3_MODE_CODE_32, 0 },
     212    { bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32,      12, false,   BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },
     213    { bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32,   13, true,    BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },
     214    { bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64,              9, false,   BS3_MODE_CODE_64, 0 },
     215    { bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64,        10, false,   BS3_MODE_CODE_64, 0 },
     216    { bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64,      10, false,   BS3_MODE_CODE_64, 0 },
     217    { bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64, 11, false,   BS3_MODE_CODE_64, 0 },
     218};
     219
    180220
    181221
     
    13791419# define bs3CpuBasic2_sidt_sgdt_One BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_One)
    13801420BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
    1381                                                uint8_t const *pabExpected)
     1421                                               uint8_t const *pbExpected)
    13821422{
    13831423    BS3TRAPFRAME        TrapCtx;
     
    14321472    if (!ASMMemIsZero(&abBuf[cbIdtr], cbBuf - cbIdtr))
    14331473        Bs3TestFailedF("Unexpected buffer bytes set (#1): cbIdtr=%u abBuf=%.*Rhxs\n", cbIdtr, cbBuf, pbBuf);
    1434     if (Bs3MemCmp(abBuf, pabExpected, cbIdtr) != 0)
    1435         Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, abBuf);
     1474    if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)
     1475        Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);
    14361476    g_usBs3TestStep++;
    14371477
    1438     /* Again with buffer filled a byte not occuring in the previous result. */
     1478    /* Again with a buffer filled with a byte not occuring in the previous result. */
    14391479    bFiller = 0x55;
    14401480    while (Bs3MemChr(abBuf, bFiller, cbBuf) != NULL)
     
    14521492    if (Bs3MemChr(abBuf, bFiller, cbIdtr) != NULL)
    14531493        Bs3TestFailedF("Not all bytes touched: cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf);
    1454     if (Bs3MemCmp(abBuf, pabExpected, cbIdtr) != 0)
    1455         Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, abBuf);
     1494    if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)
     1495        Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);
    14561496    g_usBs3TestStep++;
    14571497
     
    14771517        if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    14781518            Bs3TestFailedF("286: Top base byte isn't 0xff (#3): %#x\n", abBuf[off + cbIdtr - 1]);
    1479         if (Bs3MemCmp(&abBuf[off], pabExpected, cbIdtr) != 0)
    1480             Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &abBuf[off]);
     1519        if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     1520            Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    14811521        g_usBs3TestStep++;
    14821522
    1483         /* Again with buffer filled a byte not occuring in the previous result. */
     1523        /* Again with a buffer filled with a byte not occuring in the previous result. */
    14841524        Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
    14851525        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     
    14961536        if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    14971537            Bs3TestFailedF("286: Top base byte isn't 0xff (#4): %#x\n", abBuf[off + cbIdtr - 1]);
    1498         if (Bs3MemCmp(&abBuf[off], pabExpected, cbIdtr) != 0)
    1499             Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &abBuf[off]);
     1538        if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     1539            Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    15001540        g_usBs3TestStep++;
    15011541    }
     
    15391579                        Bs3TestFailedF("Not all bytes touched (#5): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    15401580                                       cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1541                     if (Bs3MemCmp(&abBuf[off], pabExpected, cbIdtr) != 0)
    1542                         Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &abBuf[off]);
     1581                    if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     1582                        Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    15431583                    if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    15441584                        Bs3TestFailedF("286: Top base byte isn't 0xff (#5): %#x\n", abBuf[off + cbIdtr - 1]);
     
    15551595                            Bs3TestFailedF("Limit bytes not touched (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    15561596                                           cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1557                         if (Bs3MemCmp(&abBuf[off], pabExpected, 2) != 0)
    1558                             Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pabExpected, &abBuf[off]);
     1597                        if (Bs3MemCmp(&abBuf[off], pbExpected, 2) != 0)
     1598                            Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pbExpected, &abBuf[off]);
    15591599                        if (!ASMMemIsAllU8(&abBuf[off + 2], cbIdtr - 2, bFiller))
    15601600                            Bs3TestFailedF("Base bytes touched on #GP (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     
    15991639                        Bs3TestFailedF("Not all bytes touched (#8): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    16001640                                       cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1601                     if (Bs3MemCmp(&abBuf[off], pabExpected, cbIdtr) != 0)
    1602                         Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &abBuf[off]);
     1641                    if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     1642                        Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    16031643                    if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    16041644                        Bs3TestFailedF("286: Top base byte isn't 0xff (#8): %#x\n", abBuf[off + cbIdtr - 1]);
     
    16561696                CtxUdExpected.ds  = Ctx.ds;
    16571697                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1658                 if (Bs3MemCmp(&pbTest[off], pabExpected, cbIdtr) != 0)
    1659                     Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &pbTest[off]);
     1698                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     1699                    Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    16601700            }
    16611701            else
     
    16641704                                          uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    16651705                if (   off <= X86_PAGE_SIZE - 2
    1666                     && Bs3MemCmp(&pbTest[off], pabExpected, 2) != 0)
     1706                    && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    16671707                    Bs3TestPrintf("Mismatch (#10): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
    1668                                   pabExpected, &pbTest[off], off);
     1708                                  pbExpected, &pbTest[off], off);
    16691709                if (   off < X86_PAGE_SIZE - 2
    16701710                    && !ASMMemIsAllU8(&pbTest[off + 2], X86_PAGE_SIZE - off - 2, bFiller))
     
    16921732                CtxUdExpected.ds  = Ctx.ds;
    16931733                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1694                 if (Bs3MemCmp(&pbTest[off], pabExpected, cbIdtr) != 0)
    1695                     Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &pbTest[off]);
     1734                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     1735                    Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    16961736            }
    16971737            else
     
    17451785                        {
    17461786                            bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1747                             if (Bs3MemCmp(&pbTest[off], pabExpected, cbIdtr) != 0)
     1787                            if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    17481788                                Bs3TestFailedF("Mismatch (#14): expected %.*Rhxs, got %.*Rhxs\n",
    1749                                                cbIdtr, pabExpected, cbIdtr, &pbTest[off]);
     1789                                               cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    17501790                        }
    17511791                        else
     
    17541794                                                      uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    17551795                            if (   off <= X86_PAGE_SIZE - 2
    1756                                 && Bs3MemCmp(&pbTest[off], pabExpected, 2) != 0)
     1796                                && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    17571797                                Bs3TestPrintf("Mismatch (#15): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
    1758                                               pabExpected, &pbTest[off], off);
     1798                                              pbExpected, &pbTest[off], off);
    17591799                            cb = X86_PAGE_SIZE - off - 2;
    17601800                            if (   off < X86_PAGE_SIZE - 2
     
    17751815                            else
    17761816                                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1777                             if (Bs3MemCmp(&pbTest[off], pabExpected, 2) != 0)
     1817                            if (Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    17781818                                Bs3TestPrintf("Mismatch (#16): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
    1779                                               pabExpected, &pbTest[off], off);
     1819                                              pbExpected, &pbTest[off], off);
    17801820                            cb = X86_PAGE_SIZE - off - 2;
    17811821                            if (   off < X86_PAGE_SIZE - 2
     
    18461886                    {
    18471887                        bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1848                         if (Bs3MemCmp(&pbTest[off], pabExpected, cbIdtr) != 0)
     1888                        if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    18491889                            Bs3TestFailedF("Mismatch (#19): expected %.*Rhxs, got %.*Rhxs\n",
    1850                                            cbIdtr, pabExpected, cbIdtr, &pbTest[off]);
     1890                                           cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    18511891                        cb = X86_PAGE_SIZE + cbIdtr*2 - off;
    18521892                        if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], cb, bFiller))
     
    18971937            {
    18981938                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1899                 if (Bs3MemCmp(&pbTest[off], pabExpected, cbIdtr) != 0)
    1900                     Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &pbTest[off]);
     1939                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     1940                    Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    19011941            }
    19021942            else
    19031943            {
    19041944                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1905                 if (off <= -2 && Bs3MemCmp(&pbTest[off], pabExpected, 2) != 0)
    1906                     Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pabExpected, &pbTest[off]);
     1945                if (off <= -2 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
     1946                    Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pbExpected, &pbTest[off]);
    19071947                off2 = off <= -2 ? 2 : 0;
    19081948                cb   = cbIdtr - off2;
    19091949                if (!ASMMemIsAllU8(&pbTest[off + off2], cb, bFiller))
    19101950                    Bs3TestFailedF("Mismatch (#21): touched base %.*Rhxs, got %.*Rhxs\n",
    1911                                    cb, &pabExpected[off], cb, &pbTest[off + off2]);
     1951                                   cb, &pbExpected[off], cb, &pbTest[off + off2]);
    19121952            }
    19131953            if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))
     
    19261966            {
    19271967                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1928                 if (Bs3MemCmp(&pbTest[off], pabExpected, cbIdtr) != 0)
    1929                     Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pabExpected, cbIdtr, &pbTest[off]);
     1968                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     1969                    Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    19301970            }
    19311971            else
     
    19341974                if (!ASMMemIsAllU8(&pbTest[off], cbIdtr, bFiller))
    19351975                    Bs3TestFailedF("Mismatch (#22): touched base %.*Rhxs, got %.*Rhxs\n",
    1936                                    cbIdtr, &pabExpected[off], cbIdtr, &pbTest[off]);
     1976                                   cbIdtr, &pbExpected[off], cbIdtr, &pbTest[off]);
    19371977            }
    19381978            if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))
     
    19431983
    19441984    }
    1945 
    1946     /*
    1947      * Move the table by setting up alias pages.  Aim at areas above 2GB for 32-bit and in
    1948      * the 'negative' space of 64-bit addresses.
    1949      */
    1950     if (BS3_MODE_IS_PAGED(bTestMode))
    1951     {
    1952 
    1953     }
    1954 
    1955 
    19561985}
     1986
    19571987
    19581988# define bs3CpuBasic2_sidt_sgdt_Common BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_Common)
    19591989BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
    1960                                                   uint8_t const *pabExpected)
     1990                                                  uint8_t const *pbExpected)
    19611991{
    19621992    unsigned idx;
     
    19732003            {
    19742004                g_usBs3TestStep = iStep;
    1975                 bs3CpuBasic2_sidt_sgdt_One(&paWorkers[idx], bTestMode, bRing, pabExpected);
     2005                bs3CpuBasic2_sidt_sgdt_One(&paWorkers[idx], bTestMode, bRing, pbExpected);
    19762006                iStep += 1000;
    19772007            }
    19782008        if (BS3_MODE_IS_RM_OR_V86(bTestMode))
     2009            break;
     2010    }
     2011}
     2012
     2013
     2014/*
     2015 * LIDT & LGDT
     2016 */
     2017
     2018/**
     2019 * Executes one round of LIDT and LGDT tests using one assembly worker.
     2020 *
     2021 * This is written with driving everything from the 16-bit or 32-bit worker in
     2022 * mind, i.e. not assuming the test bitcount is the same as the current.
     2023 */
     2024# define bs3CpuBasic2_lidt_lgdt_One BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_One)
     2025BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
     2026                                               uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected)
     2027{
     2028    BS3TRAPFRAME        TrapCtx;
     2029    BS3REGCTX           Ctx;
     2030    BS3REGCTX           CtxUdExpected;
     2031    BS3REGCTX           TmpCtx;
     2032    uint8_t             abBufLoad[40];          /* Test buffer w/ misalignment test space and some (cbIdtr) extra guard. */
     2033    uint8_t             abBufSave[32];          /* For saving the result after loading. */
     2034    uint8_t             abBufRestore[24];       /* For restoring sane value (same seg as abBufSave!). */
     2035    uint8_t             abExpectedFilled[32];   /* Same as pbExpected, except it's filled with bFiller2 instead of zeros. */
     2036    uint8_t BS3_FAR    *pbBufSave;              /* Correctly aligned pointer into abBufSave. */
     2037    uint8_t BS3_FAR    *pbBufRestore;           /* Correctly aligned pointer into abBufRestore. */
     2038    uint8_t const       cbIdtr        = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 2+8 : 2+4;
     2039    uint8_t const       cbBaseLoaded  = BS3_MODE_IS_16BIT_CODE(bTestMode) || (pWorker->fFlags & BS3CB2SIDTSGDT_F_OPSIZE)
     2040                                      ? 3 : cbIdtr - 2;
     2041    bool const          f286          = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286;
     2042    uint8_t const       bTop16BitBase = f286 ? 0xff : 0x00;
     2043    uint8_t             bFiller1;               /* For filling abBufLoad.  */
     2044    uint8_t             bFiller2;               /* For filling abBufSave and expectations. */
     2045//    int                 off;
     2046//    int                 off2;
     2047//    unsigned            cb;
     2048//    uint8_t BS3_FAR    *pbTest;
     2049    unsigned            i;
     2050
     2051    /* make sure they're allocated  */
     2052    Bs3MemZero(&Ctx, sizeof(Ctx));
     2053    Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected));
     2054    Bs3MemZero(&TmpCtx, sizeof(TmpCtx));
     2055    Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
     2056    Bs3MemZero(abBufSave, sizeof(abBufSave));
     2057    Bs3MemZero(abBufLoad, sizeof(abBufLoad));
     2058    Bs3MemZero(abBufRestore, sizeof(abBufRestore));
     2059
     2060    /*
     2061     * Create a context, giving this routine some more stack space.
     2062     *  - Point the context at our LIDT [xBX] + SIDT [xDI] + LIDT [xSI] + UD2 combo.
     2063     *  - Point DS/SS:xBX at abBufLoad.
     2064     *  - Point ES:xDI at abBufSave.
     2065     *  - Point ES:xSI at abBufRestore.
     2066     */
     2067    Bs3RegCtxSaveEx(&Ctx, bTestMode, 256 /*cbExtraStack*/);
     2068    Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pWorker->fpfnWorker);
     2069    if (BS3_MODE_IS_16BIT_SYS(bTestMode))
     2070        g_uBs3TrapEipHint = Ctx.rip.u32;
     2071    Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);
     2072
     2073    pbBufSave = abBufSave;
     2074    if ((BS3_FP_OFF(pbBufSave) + 2) & 7)
     2075        pbBufSave += 8 - ((BS3_FP_OFF(pbBufSave) + 2) & 7);
     2076    Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.es, pbBufSave);
     2077
     2078    pbBufRestore = abBufRestore;
     2079    if ((BS3_FP_OFF(pbBufRestore) + 2) & 7)
     2080        pbBufRestore += 8 - ((BS3_FP_OFF(pbBufRestore) + 2) & 7);
     2081    Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsi, &Ctx.es, pbBufRestore);
     2082    Bs3MemCpy(pbBufRestore, pbRestore, cbRestore);
     2083
     2084    if (!BS3_MODE_IS_RM_OR_V86(bTestMode))
     2085        Bs3RegCtxConvertToRingX(&Ctx, bRing);
     2086
     2087    /* For successful SIDT attempts, we'll stop at the UD2. */
     2088    Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx));
     2089    CtxUdExpected.rip.u += pWorker->cbInstr;
     2090
     2091    /*
     2092     * Check that it works at all.
     2093     */
     2094    Bs3MemZero(abBufLoad, sizeof(abBufLoad));
     2095    Bs3MemCpy(abBufLoad, pbBufRestore, cbRestore);
     2096    Bs3MemZero(abBufSave, sizeof(abBufSave));
     2097    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2098    if (bRing != 0)
     2099        bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2100    else
     2101    {
     2102        bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2103        if (Bs3MemCmp(pbBufSave, pbExpected, cbIdtr * 2) != 0)
     2104            Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr*2, pbExpected, cbIdtr*2, pbBufSave);
     2105    }
     2106    g_usBs3TestStep++;
     2107
     2108    /* Determine two filler bytes that doesn't appear in the previous result or our expectations. */
     2109    bFiller1 = ~0x55;
     2110    while (   Bs3MemChr(pbBufSave, bFiller1, cbIdtr) != NULL
     2111           || Bs3MemChr(pbRestore, bFiller1, cbRestore) != NULL
     2112           || bFiller1 == 0xff)
     2113        bFiller1++;
     2114    bFiller2 = 0x33;
     2115    while (   Bs3MemChr(pbBufSave, bFiller2, cbIdtr) != NULL
     2116           || Bs3MemChr(pbRestore, bFiller2, cbRestore) != NULL
     2117           || bFiller2 == 0xff
     2118           || bFiller2 == bFiller1)
     2119        bFiller2++;
     2120    Bs3MemSet(abExpectedFilled, bFiller2, sizeof(abExpectedFilled));
     2121    Bs3MemCpy(abExpectedFilled, pbExpected, cbIdtr);
     2122
     2123    /* Again with a buffer filled with a byte not occuring in the previous result. */
     2124    Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
     2125    Bs3MemCpy(abBufLoad, pbBufRestore, cbRestore);
     2126    Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
     2127    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2128    if (bRing != 0)
     2129        bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2130    else
     2131    {
     2132        bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2133        if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
     2134            Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
     2135    }
     2136    g_usBs3TestStep++;
     2137
     2138    /*
     2139     * Try loading a bunch of different limit+base value to check what happens,
     2140     * especially what happens wrt the top part of the base in 16-bit mode.
     2141     */
     2142    if (BS3_MODE_IS_64BIT_CODE(bTestMode))
     2143    {
     2144        static const struct
     2145        {
     2146            bool        fGP;
     2147            uint16_t    cbLimit;
     2148            uint64_t    u64Base;
     2149        } s_aValues[] =
     2150        {
     2151            { false, 0x0000, UINT64_C(0x0000000000000000) },
     2152            { false, 0x0001, UINT64_C(0x0000000000000001) },
     2153            { false, 0x0002, UINT64_C(0x0000000000000010) },
     2154            { false, 0x0003, UINT64_C(0x0000000000000123) },
     2155            { false, 0x0004, UINT64_C(0x0000000000001234) },
     2156            { false, 0x0005, UINT64_C(0x0000000000012345) },
     2157            { false, 0x0006, UINT64_C(0x0000000000123456) },
     2158            { false, 0x0007, UINT64_C(0x0000000001234567) },
     2159            { false, 0x0008, UINT64_C(0x0000000012345678) },
     2160            { false, 0x0009, UINT64_C(0x0000000123456789) },
     2161            { false, 0x000a, UINT64_C(0x000000123456789a) },
     2162            { false, 0x000b, UINT64_C(0x00000123456789ab) },
     2163            { false, 0x000c, UINT64_C(0x0000123456789abc) },
     2164            { false, 0x001c, UINT64_C(0x00007ffffeefefef) },
     2165            { false, 0xffff, UINT64_C(0x00007fffffffffff) },
     2166            {  true, 0xf3f1, UINT64_C(0x0000800000000000) },
     2167            {  true, 0x0000, UINT64_C(0x0000800000000000) },
     2168            {  true, 0x0000, UINT64_C(0x0000800000000333) },
     2169            {  true, 0x00f0, UINT64_C(0x0001000000000000) },
     2170            {  true, 0x0ff0, UINT64_C(0x0012000000000000) },
     2171            {  true, 0x0eff, UINT64_C(0x0123000000000000) },
     2172            {  true, 0xe0fe, UINT64_C(0x1234000000000000) },
     2173            {  true, 0x00ad, UINT64_C(0xffff300000000000) },
     2174            {  true, 0x0000, UINT64_C(0xffff7fffffffffff) },
     2175            {  true, 0x00f0, UINT64_C(0xffff7fffffffffff) },
     2176            { false, 0x5678, UINT64_C(0xffff800000000000) },
     2177            { false, 0x2969, UINT64_C(0xffffffffffeefefe) },
     2178            { false, 0x1221, UINT64_C(0xffffffffffffffff) },
     2179            { false, 0x1221, UINT64_C(0xffffffffffffffff) },
     2180        };
     2181        for (i = 0; i < RT_ELEMENTS(s_aValues); i++)
     2182        {
     2183            Bs3MemSet(abBufSave, bFiller1, sizeof(abBufSave));
     2184            Bs3MemCpy(&abBufLoad[0], &s_aValues[i].cbLimit, 2);
     2185            Bs3MemCpy(&abBufLoad[2], &s_aValues[i].u64Base, 8);
     2186            Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
     2187            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2188            if (bRing != 0 || s_aValues[i].fGP)
     2189                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2190            else
     2191            {
     2192                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2193                if (   Bs3MemCmp(&pbBufSave[0], &s_aValues[i].cbLimit, 2) != 0
     2194                    || Bs3MemCmp(&pbBufSave[2], &s_aValues[i].u64Base, 8) != 0
     2195                    || !ASMMemIsAllU8(&pbBufSave[10], cbIdtr, bFiller2))
     2196                    Bs3TestFailedF("Mismatch (#2): expected %04RX16:%016RX64, fillers %#x %#x, got %.*Rhxs\n",
     2197                                   s_aValues[i].cbLimit, s_aValues[i].u64Base, bFiller1, bFiller2, cbIdtr*2, pbBufSave);
     2198            }
     2199            g_usBs3TestStep++;
     2200        }
     2201    }
     2202    else
     2203    {
     2204        static const struct
     2205        {
     2206            uint16_t    cbLimit;
     2207            uint32_t    u32Base;
     2208        } s_aValues[] =
     2209        {
     2210            { 0x0000, UINT32_C(0x00000000) },
     2211            { 0x0001, UINT32_C(0x00000001) },
     2212            { 0x0002, UINT32_C(0x00000012) },
     2213            { 0x0003, UINT32_C(0x00000123) },
     2214            { 0x0004, UINT32_C(0x00001234) },
     2215            { 0x0005, UINT32_C(0x00012345) },
     2216            { 0x0006, UINT32_C(0x00123456) },
     2217            { 0x0007, UINT32_C(0x01234567) },
     2218            { 0x0008, UINT32_C(0x12345678) },
     2219            { 0x0009, UINT32_C(0x80204060) },
     2220            { 0x000a, UINT32_C(0xddeeffaa) },
     2221            { 0x000b, UINT32_C(0xfdecdbca) },
     2222            { 0x000c, UINT32_C(0x6098456b) },
     2223            { 0x000d, UINT32_C(0x98506099) },
     2224            { 0x000e, UINT32_C(0x206950bc) },
     2225            { 0x000f, UINT32_C(0x9740395d) },
     2226            { 0x0334, UINT32_C(0x64a9455e) },
     2227            { 0xb423, UINT32_C(0xd20b6eff) },
     2228            { 0x4955, UINT32_C(0x85296d46) },
     2229            { 0xffff, UINT32_C(0x07000039) },
     2230            { 0xefe1, UINT32_C(0x0007fe00) },
     2231        };
     2232        for (i = 0; i < RT_ELEMENTS(s_aValues); i++)
     2233        {
     2234            Bs3MemSet(abBufSave, bFiller1, sizeof(abBufSave));
     2235            Bs3MemCpy(&abBufLoad[0], &s_aValues[i].cbLimit, 2);
     2236            Bs3MemCpy(&abBufLoad[2], &s_aValues[i].u32Base, cbBaseLoaded);
     2237            Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
     2238            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2239            if (bRing != 0)
     2240                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2241            else
     2242            {
     2243                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2244                if (   Bs3MemCmp(&pbBufSave[0], &s_aValues[i].cbLimit, 2) != 0
     2245                    || Bs3MemCmp(&pbBufSave[2], &s_aValues[i].u32Base, cbBaseLoaded) != 0
     2246                    || (   cbBaseLoaded != 4
     2247                        && pbBufSave[2+3] != bTop16BitBase)
     2248                    || !ASMMemIsAllU8(&pbBufSave[8], cbIdtr, bFiller2))
     2249                    Bs3TestFailedF("Mismatch (#3): loaded %04RX16:%08RX32, fillers %#x %#x%s%s (cbIns=%d), got %.*Rhxs\n",
     2250                                   s_aValues[i].cbLimit, s_aValues[i].u32Base, bFiller1, bFiller2, f286 ? ", 286" : "",
     2251                                   pWorker->fFlags ? ", opsize" : "", pWorker->cbInstr, cbIdtr*2, pbBufSave);
     2252            }
     2253            g_usBs3TestStep++;
     2254        }
     2255
     2256    }
     2257
     2258
     2259
     2260#if 0
     2261
     2262    /*
     2263     * Slide the buffer along 8 bytes to cover misalignment.
     2264     */
     2265    for (off = 0; off < 8; off++)
     2266    {
     2267        pbBuf = &abBuf[off];
     2268        Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &abBuf[off]);
     2269        CtxUdExpected.rbx.u = Ctx.rbx.u;
     2270
     2271        /* First with zero buffer. */
     2272        Bs3MemZero(abBuf, sizeof(abBuf));
     2273        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2274        bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2275        if (off > 0 && !ASMMemIsZero(abBuf, off))
     2276            Bs3TestFailedF("Unexpected buffer bytes set before (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n",
     2277                           cbIdtr, off, off + cbBuf, abBuf);
     2278        if (!ASMMemIsZero(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off))
     2279            Bs3TestFailedF("Unexpected buffer bytes set after (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n",
     2280                           cbIdtr, off, off + cbBuf, abBuf);
     2281        if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
     2282            Bs3TestFailedF("286: Top base byte isn't 0xff (#3): %#x\n", abBuf[off + cbIdtr - 1]);
     2283        if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     2284            Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
     2285        g_usBs3TestStep++;
     2286
     2287        /* Again with a buffer filled with a byte not occuring in the previous result. */
     2288        Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
     2289        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2290        bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2291        if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))
     2292            Bs3TestFailedF("Unexpected buffer bytes set before (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2293                           cbIdtr, off, bFiller, off + cbBuf, abBuf);
     2294        if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off, bFiller))
     2295            Bs3TestFailedF("Unexpected buffer bytes set after (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2296                           cbIdtr, off, bFiller, off + cbBuf, abBuf);
     2297        if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)
     2298            Bs3TestFailedF("Not all bytes touched (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2299                           cbIdtr, off, bFiller, off + cbBuf, abBuf);
     2300        if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
     2301            Bs3TestFailedF("286: Top base byte isn't 0xff (#4): %#x\n", abBuf[off + cbIdtr - 1]);
     2302        if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     2303            Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
     2304        g_usBs3TestStep++;
     2305    }
     2306    pbBuf = abBuf;
     2307    Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);
     2308    CtxUdExpected.rbx.u = Ctx.rbx.u;
     2309
     2310    /*
     2311     * Play with the selector limit if the target mode supports limit checking
     2312     * We use BS3_SEL_TEST_PAGE_00 for this
     2313     */
     2314    if (   !BS3_MODE_IS_RM_OR_V86(bTestMode)
     2315        && !BS3_MODE_IS_64BIT_CODE(bTestMode))
     2316    {
     2317        uint16_t cbLimit;
     2318        uint32_t uFlatBuf = Bs3SelPtrToFlat(abBuf);
     2319        Bs3GdteTestPage00 = Bs3Gdte_DATA16;
     2320        Bs3GdteTestPage00.Gen.u2Dpl       = bRing;
     2321        Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatBuf;
     2322        Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatBuf >> 16);
     2323        Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatBuf >> 24);
     2324
     2325        if (pWorker->fSs)
     2326            CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;
     2327        else
     2328            CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
     2329
     2330        /* Expand up (normal). */
     2331        for (off = 0; off < 8; off++)
     2332        {
     2333            CtxUdExpected.rbx.u = Ctx.rbx.u = off;
     2334            for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)
     2335            {
     2336                Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
     2337                Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
     2338                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2339                if (off + cbIdtr <= cbLimit + 1)
     2340                {
     2341                    bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2342                    if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)
     2343                        Bs3TestFailedF("Not all bytes touched (#5): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2344                                       cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2345                    if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     2346                        Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
     2347                    if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
     2348                        Bs3TestFailedF("286: Top base byte isn't 0xff (#5): %#x\n", abBuf[off + cbIdtr - 1]);
     2349                }
     2350                else
     2351                {
     2352                    if (pWorker->fSs)
     2353                        bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
     2354                    else
     2355                        bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2356                    if (off + 2 <= cbLimit + 1)
     2357                    {
     2358                        if (Bs3MemChr(&abBuf[off], bFiller, 2) != NULL)
     2359                            Bs3TestFailedF("Limit bytes not touched (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2360                                           cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2361                        if (Bs3MemCmp(&abBuf[off], pbExpected, 2) != 0)
     2362                            Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pbExpected, &abBuf[off]);
     2363                        if (!ASMMemIsAllU8(&abBuf[off + 2], cbIdtr - 2, bFiller))
     2364                            Bs3TestFailedF("Base bytes touched on #GP (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2365                                           cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2366                    }
     2367                    else if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))
     2368                        Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2369                                       cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2370                }
     2371
     2372                if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))
     2373                    Bs3TestFailedF("Leading bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2374                                   cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2375                if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller))
     2376                    Bs3TestFailedF("Trailing bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2377                                   cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2378
     2379                g_usBs3TestStep++;
     2380            }
     2381        }
     2382
     2383        /* Expand down (weird).  Inverted valid area compared to expand up,
     2384           so a limit of zero give us a valid range for 0001..0ffffh (instead of
     2385           a segment with one valid byte at 0000h).  Whereas a limit of 0fffeh
     2386           means one valid byte at 0ffffh, and a limit of 0ffffh means none
     2387           (because in a normal expand up the 0ffffh means all 64KB are
     2388           accessible). */
     2389        Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;
     2390        for (off = 0; off < 8; off++)
     2391        {
     2392            CtxUdExpected.rbx.u = Ctx.rbx.u = off;
     2393            for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)
     2394            {
     2395                Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
     2396                Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
     2397                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2398
     2399                if (off > cbLimit)
     2400                {
     2401                    bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2402                    if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)
     2403                        Bs3TestFailedF("Not all bytes touched (#8): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2404                                       cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2405                    if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
     2406                        Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
     2407                    if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
     2408                        Bs3TestFailedF("286: Top base byte isn't 0xff (#8): %#x\n", abBuf[off + cbIdtr - 1]);
     2409                }
     2410                else
     2411                {
     2412                    if (pWorker->fSs)
     2413                        bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
     2414                    else
     2415                        bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2416                    if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))
     2417                        Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2418                                       cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2419                }
     2420
     2421                if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))
     2422                    Bs3TestFailedF("Leading bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2423                                   cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2424                if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller))
     2425                    Bs3TestFailedF("Trailing bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
     2426                                   cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
     2427
     2428                g_usBs3TestStep++;
     2429            }
     2430        }
     2431
     2432        Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);
     2433        CtxUdExpected.rbx.u = Ctx.rbx.u;
     2434        CtxUdExpected.ss = Ctx.ss;
     2435        CtxUdExpected.ds = Ctx.ds;
     2436    }
     2437
     2438    /*
     2439     * Play with the paging.
     2440     */
     2441    if (   BS3_MODE_IS_PAGED(bTestMode)
     2442        && (!pWorker->fSs || bRing == 3) /* SS.DPL == CPL, we'll get some tiled ring-3 selector here.  */
     2443        && (pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED)) != NULL)
     2444    {
     2445        RTCCUINTXREG uFlatTest = Bs3SelPtrToFlat(pbTest);
     2446
     2447        /*
     2448         * Slide the buffer towards the trailing guard page.  We'll observe the
     2449         * first word being written entirely separately from the 2nd dword/qword.
     2450         */
     2451        for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
     2452        {
     2453            Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2);
     2454            Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);
     2455            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2456            if (off + cbIdtr <= X86_PAGE_SIZE)
     2457            {
     2458                CtxUdExpected.rbx = Ctx.rbx;
     2459                CtxUdExpected.ss  = Ctx.ss;
     2460                CtxUdExpected.ds  = Ctx.ds;
     2461                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2462                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     2463                    Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
     2464            }
     2465            else
     2466            {
     2467                bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
     2468                                          uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
     2469                if (   off <= X86_PAGE_SIZE - 2
     2470                    && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
     2471                    Bs3TestPrintf("Mismatch (#10): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
     2472                                  pbExpected, &pbTest[off], off);
     2473                if (   off < X86_PAGE_SIZE - 2
     2474                    && !ASMMemIsAllU8(&pbTest[off + 2], X86_PAGE_SIZE - off - 2, bFiller))
     2475                    Bs3TestPrintf("Wrote partial base on #PF (#10): bFiller=%#x, got %.*Rhxs; off=%#x\n",
     2476                                  bFiller, X86_PAGE_SIZE - off - 2, &pbTest[off + 2], off);
     2477                if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller)
     2478                    Bs3TestPrintf("Wrote partial limit on #PF (#10): Expected %02x, got %02x\n", bFiller, pbTest[off]);
     2479            }
     2480            g_usBs3TestStep++;
     2481        }
     2482
     2483        /*
     2484         * Now, do it the other way around. It should look normal now since writing
     2485         * the limit will #PF first and nothing should be written.
     2486         */
     2487        for (off = cbIdtr + 4; off >= -cbIdtr - 4; off--)
     2488        {
     2489            Bs3MemSet(pbTest, bFiller, 48);
     2490            Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);
     2491            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2492            if (off >= 0)
     2493            {
     2494                CtxUdExpected.rbx = Ctx.rbx;
     2495                CtxUdExpected.ss  = Ctx.ss;
     2496                CtxUdExpected.ds  = Ctx.ds;
     2497                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2498                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     2499                    Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
     2500            }
     2501            else
     2502            {
     2503                bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), uFlatTest + off);
     2504                if (   -off < cbIdtr
     2505                    && !ASMMemIsAllU8(pbTest, cbIdtr + off, bFiller))
     2506                    Bs3TestPrintf("Wrote partial content on #PF (#12): bFiller=%#x, found %.*Rhxs; off=%d\n",
     2507                                  bFiller, cbIdtr + off, pbTest, off);
     2508            }
     2509            if (!ASMMemIsAllU8(&pbTest[RT_MAX(cbIdtr + off, 0)], 16, bFiller))
     2510                Bs3TestPrintf("Wrote beyond expected area (#13): bFiller=%#x, found %.16Rhxs; off=%d\n",
     2511                              bFiller, &pbTest[RT_MAX(cbIdtr + off, 0)], off);
     2512            g_usBs3TestStep++;
     2513        }
     2514
     2515        /*
     2516         * Combine paging and segment limit and check ordering.
     2517         * This is kind of interesting here since it the instruction seems to
     2518         * be doing two separate writes.
     2519         */
     2520        if (   !BS3_MODE_IS_RM_OR_V86(bTestMode)
     2521            && !BS3_MODE_IS_64BIT_CODE(bTestMode))
     2522        {
     2523            uint16_t cbLimit;
     2524
     2525            Bs3GdteTestPage00 = Bs3Gdte_DATA16;
     2526            Bs3GdteTestPage00.Gen.u2Dpl       = bRing;
     2527            Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatTest;
     2528            Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);
     2529            Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);
     2530
     2531            if (pWorker->fSs)
     2532                CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;
     2533            else
     2534                CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
     2535
     2536            /* Expand up (normal), approaching tail guard page. */
     2537            for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
     2538            {
     2539                CtxUdExpected.rbx.u = Ctx.rbx.u = off;
     2540                for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)
     2541                {
     2542                    Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
     2543                    Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2);
     2544                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2545                    if (off + cbIdtr <= cbLimit + 1)
     2546                    {
     2547                        /* No #GP, but maybe #PF. */
     2548                        if (off + cbIdtr <= X86_PAGE_SIZE)
     2549                        {
     2550                            bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2551                            if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     2552                                Bs3TestFailedF("Mismatch (#14): expected %.*Rhxs, got %.*Rhxs\n",
     2553                                               cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
     2554                        }
     2555                        else
     2556                        {
     2557                            bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
     2558                                                      uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
     2559                            if (   off <= X86_PAGE_SIZE - 2
     2560                                && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
     2561                                Bs3TestPrintf("Mismatch (#15): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
     2562                                              pbExpected, &pbTest[off], off);
     2563                            cb = X86_PAGE_SIZE - off - 2;
     2564                            if (   off < X86_PAGE_SIZE - 2
     2565                                && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller))
     2566                                Bs3TestPrintf("Wrote partial base on #PF (#15): bFiller=%#x, got %.*Rhxs; off=%#x\n",
     2567                                              bFiller, cb, &pbTest[off + 2], off);
     2568                            if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller)
     2569                                Bs3TestPrintf("Wrote partial limit on #PF (#15): Expected %02x, got %02x\n", bFiller, pbTest[off]);
     2570                        }
     2571                    }
     2572                    else if (off + 2 <= cbLimit + 1)
     2573                    {
     2574                        /* [ig]tr.limit writing does not cause #GP, but may cause #PG, if not writing the base causes #GP. */
     2575                        if (off <= X86_PAGE_SIZE - 2)
     2576                        {
     2577                            if (pWorker->fSs)
     2578                                bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
     2579                            else
     2580                                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2581                            if (Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
     2582                                Bs3TestPrintf("Mismatch (#16): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
     2583                                              pbExpected, &pbTest[off], off);
     2584                            cb = X86_PAGE_SIZE - off - 2;
     2585                            if (   off < X86_PAGE_SIZE - 2
     2586                                && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller))
     2587                                Bs3TestPrintf("Wrote partial base with limit (#16): bFiller=%#x, got %.*Rhxs; off=%#x\n",
     2588                                              bFiller, cb, &pbTest[off + 2], off);
     2589                        }
     2590                        else
     2591                        {
     2592                            bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
     2593                                                      uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
     2594                            if (   off < X86_PAGE_SIZE
     2595                                && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller))
     2596                                Bs3TestPrintf("Mismatch (#16): Partial limit write on #PF: bFiller=%#x, got %.*Rhxs\n",
     2597                                              bFiller, X86_PAGE_SIZE - off, &pbTest[off]);
     2598                        }
     2599                    }
     2600                    else
     2601                    {
     2602                        /* #GP/#SS on limit. */
     2603                        if (pWorker->fSs)
     2604                            bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
     2605                        else
     2606                            bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2607                        if (   off < X86_PAGE_SIZE
     2608                            && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller))
     2609                            Bs3TestPrintf("Mismatch (#17): Partial write on #GP: bFiller=%#x, got %.*Rhxs\n",
     2610                                          bFiller, X86_PAGE_SIZE - off, &pbTest[off]);
     2611                    }
     2612
     2613                    cb = RT_MIN(cbIdtr * 2, off - (X86_PAGE_SIZE - cbIdtr*2));
     2614                    if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], cb, bFiller))
     2615                        Bs3TestFailedF("Leading bytes touched (#18): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",
     2616                                       cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE - cbIdtr * 2]);
     2617
     2618                    g_usBs3TestStep++;
     2619
     2620                    /* Set DS to 0 and check that we get #GP(0). */
     2621                    if (!pWorker->fSs)
     2622                    {
     2623                        Ctx.ds = 0;
     2624                        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2625                        bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2626                        Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
     2627                        g_usBs3TestStep++;
     2628                    }
     2629                }
     2630            }
     2631
     2632            /* Expand down. */
     2633            pbTest    -= X86_PAGE_SIZE; /* Note! we're backing up a page to simplify things */
     2634            uFlatTest -= X86_PAGE_SIZE;
     2635
     2636            Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;
     2637            Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatTest;
     2638            Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);
     2639            Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);
     2640
     2641            for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
     2642            {
     2643                CtxUdExpected.rbx.u = Ctx.rbx.u = off;
     2644                for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)
     2645                {
     2646                    Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
     2647                    Bs3MemSet(&pbTest[X86_PAGE_SIZE], bFiller, cbIdtr * 2);
     2648                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2649                    if (cbLimit < off && off >= X86_PAGE_SIZE)
     2650                    {
     2651                        bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2652                        if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     2653                            Bs3TestFailedF("Mismatch (#19): expected %.*Rhxs, got %.*Rhxs\n",
     2654                                           cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
     2655                        cb = X86_PAGE_SIZE + cbIdtr*2 - off;
     2656                        if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], cb, bFiller))
     2657                            Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",
     2658                                           cbIdtr, off, cbLimit, bFiller, cb, pbTest[off + cbIdtr]);
     2659                    }
     2660                    else
     2661                    {
     2662                        if (cbLimit < off && off < X86_PAGE_SIZE)
     2663                            bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
     2664                                                      uFlatTest + off);
     2665                        else if (pWorker->fSs)
     2666                            bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
     2667                        else
     2668                            bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2669                        cb = cbIdtr*2;
     2670                        if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE], cb, bFiller))
     2671                            Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",
     2672                                           cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE]);
     2673                    }
     2674                    g_usBs3TestStep++;
     2675                }
     2676            }
     2677
     2678            pbTest    += X86_PAGE_SIZE;
     2679            uFlatTest += X86_PAGE_SIZE;
     2680        }
     2681
     2682        Bs3MemGuardedTestPageFree(pbTest);
     2683    }
     2684
     2685    /*
     2686     * Check non-canonical 64-bit space.
     2687     */
     2688    if (   BS3_MODE_IS_64BIT_CODE(bTestMode)
     2689        && (pbTest = (uint8_t BS3_FAR *)Bs3PagingSetupCanonicalTraps()) != NULL)
     2690    {
     2691        /* Make our references relative to the gap. */
     2692        pbTest += g_cbBs3PagingOneCanonicalTrap;
     2693
     2694        /* Hit it from below. */
     2695        for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)
     2696        {
     2697            Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0x0000800000000000) + off;
     2698            Bs3MemSet(&pbTest[-64], bFiller, 64*2);
     2699            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2700            if (off + cbIdtr <= 0)
     2701            {
     2702                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2703                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     2704                    Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
     2705            }
     2706            else
     2707            {
     2708                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2709                if (off <= -2 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
     2710                    Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pbExpected, &pbTest[off]);
     2711                off2 = off <= -2 ? 2 : 0;
     2712                cb   = cbIdtr - off2;
     2713                if (!ASMMemIsAllU8(&pbTest[off + off2], cb, bFiller))
     2714                    Bs3TestFailedF("Mismatch (#21): touched base %.*Rhxs, got %.*Rhxs\n",
     2715                                   cb, &pbExpected[off], cb, &pbTest[off + off2]);
     2716            }
     2717            if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))
     2718                Bs3TestFailedF("Leading bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]);
     2719            if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller))
     2720                Bs3TestFailedF("Trailing bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]);
     2721        }
     2722
     2723        /* Hit it from above. */
     2724        for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)
     2725        {
     2726            Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0xffff800000000000) + off;
     2727            Bs3MemSet(&pbTest[-64], bFiller, 64*2);
     2728            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2729            if (off >= 0)
     2730            {
     2731                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
     2732                if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
     2733                    Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
     2734            }
     2735            else
     2736            {
     2737                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
     2738                if (!ASMMemIsAllU8(&pbTest[off], cbIdtr, bFiller))
     2739                    Bs3TestFailedF("Mismatch (#22): touched base %.*Rhxs, got %.*Rhxs\n",
     2740                                   cbIdtr, &pbExpected[off], cbIdtr, &pbTest[off]);
     2741            }
     2742            if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))
     2743                Bs3TestFailedF("Leading bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]);
     2744            if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller))
     2745                Bs3TestFailedF("Trailing bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]);
     2746        }
     2747
     2748    }
     2749#endif
     2750}
     2751
     2752
     2753# define bs3CpuBasic2_lidt_lgdt_Common BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_Common)
     2754BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
     2755                                                  void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected)
     2756{
     2757    unsigned idx;
     2758    unsigned bRing;
     2759    unsigned iStep = 0;
     2760
     2761    /* Note! We skip the SS checks for ring-0 since we badly mess up SS in the
     2762             test and don't want to bother with double faults. */
     2763    for (bRing = BS3_MODE_IS_V86(bTestMode) ? 3 : 0; bRing <= 3; bRing++)
     2764    {
     2765        for (idx = 0; idx < cWorkers; idx++)
     2766            if (    (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK))
     2767                && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ ))
     2768            {
     2769                //Bs3TestPrintf("idx=%-2d fpfnWorker=%p fSs=%d cbInstr=%d\n",
     2770                //              idx, paWorkers[idx].fpfnWorker, paWorkers[idx].fSs, paWorkers[idx].cbInstr);
     2771                g_usBs3TestStep = iStep;
     2772                bs3CpuBasic2_lidt_lgdt_One(&paWorkers[idx], bTestMode, bRing, pvRestore, cbRestore, pbExpected);
     2773                iStep += 1000;
     2774            }
     2775        if (BS3_MODE_IS_RM_SYS(bTestMode))
    19792776            break;
    19802777    }
     
    22303027BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
    22313028{
    2232 //if (bMode == BS3_MODE_LM64)
    2233 {
    22343029    union
    22353030    {
     
    22553050     */
    22563051    Bs3TrapInit();
    2257 }
    2258 
    22593052    return 0;
    22603053}
     
    22623055
    22633056BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
    2264 {
    2265 //if (bMode >= BS3_MODE_LM16)
    22663057{
    22673058    uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;
     
    23163107     */
    23173108    Bs3TrapInit();
    2318 }
    23193109    return 0;
    23203110}
    23213111
     3112
     3113BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode)
     3114{
     3115    union
     3116    {
     3117        RTIDTR  Idtr;
     3118        uint8_t ab[32]; /* At least cbIdtr*2! */
     3119    } Expected;
     3120
     3121    g_pszTestMode = TMPL_NM(g_szBs3ModeName);
     3122    g_bTestMode   = bMode;
     3123    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
     3124
     3125    BS3_ASSERT(bMode == TMPL_MODE);
     3126
     3127    /*
     3128     * Pass to common worker which is only compiled once per mode.
     3129     */
     3130    Bs3MemZero(&Expected, sizeof(Expected));
     3131    ASMGetIDTR(&Expected.Idtr);
     3132
     3133    if (BS3_MODE_IS_RM_SYS(bMode))
     3134        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
     3135                                      &Bs3Lidt_Ivt, sizeof(Bs3Lidt_Ivt), Expected.ab);
     3136    else if (BS3_MODE_IS_16BIT_SYS(bMode))
     3137        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
     3138                                      &Bs3Lidt_Idt16, sizeof(Bs3Lidt_Idt16), Expected.ab);
     3139    else if (BS3_MODE_IS_32BIT_SYS(bMode))
     3140        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
     3141                                      &Bs3Lidt_Idt32, sizeof(Bs3Lidt_Idt32), Expected.ab);
     3142    else
     3143        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
     3144                                      &Bs3Lidt_Idt64, sizeof(Bs3Lidt_Idt64), Expected.ab);
     3145
     3146    /*
     3147     * Re-initialize the IDT.
     3148     */
     3149    Bs3TrapInit();
     3150    return 0;
     3151}
     3152
     3153#if 0
     3154BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)
     3155{
     3156    uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;
     3157    uint64_t       uNew     = 0;
     3158    union
     3159    {
     3160        RTGDTR  Gdtr;
     3161        uint8_t ab[16];
     3162    } Expected;
     3163
     3164    g_pszTestMode = TMPL_NM(g_szBs3ModeName);
     3165    g_bTestMode   = bMode;
     3166    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
     3167    BS3_ASSERT(bMode == TMPL_MODE);
     3168
     3169    /*
     3170     * Pass to common worker which is only compiled once per mode.
     3171     */
     3172    Bs3MemZero(&Expected, sizeof(Expected));
     3173    ASMGetGDTR(&Expected.Gdtr);
     3174    bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab);
     3175
     3176    /*
     3177     * Unalias the GDT.
     3178     */
     3179    if (uNew != 0)
     3180    {
     3181        Bs3Lgdt_Gdt.uAddr = uOrgAddr;
     3182        Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uOrgAddr);
     3183        Bs3PagingUnalias(uNew, Bs3Lgdt_Gdt.cb);
     3184    }
     3185
     3186    /*
     3187     * Re-initialize the IDT.
     3188     */
     3189    Bs3TrapInit();
     3190    return 0;
     3191}
     3192#endif
     3193
    23223194#endif /* BS3_INSTANTIATING_MODE */
    23233195
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.mac

    r60679 r60724  
    2626
    2727
     28;*********************************************************************************************************************************
     29;*  Header Files                                                                                                                 *
     30;*********************************************************************************************************************************
    2831%include "bs3kit-template-header.mac"   ; setup environment
    2932
    3033
    3134;*********************************************************************************************************************************
    32 ;*      External Symbols                                                                                                         *
    33 ;*********************************************************************************************************************************
    34 %undef Bs3Printf
    35 BS3_EXTERN_CMN Bs3Printf
    36 
    37 
    38 
     35;*  External Symbols                                                                                                             *
     36;*********************************************************************************************************************************
    3937TMPL_BEGIN_TEXT
    40 
    41 ;
    42 ; Code that is instantiated for every possible CPU mode
    43 ;
    44 %ifdef BS3_INSTANTIATING_MODE
    45 
    46  %if 0 ; Will be doing the testing in C, I think.
    47 BS3_PROC_BEGIN_MODE bs3CpuBasic2_iret, BS3_PBC_FAR
    48         BS3_CALL_CONV_PROLOG 1
    49         push    xBP
    50         mov     xBP, xSP
    51         sub     xSP, 20h
    52 
    53  %if TMPL_BITS == 64
    54   %if TMPL_BITS == 16
    55         xor     ax, ax
    56         mov     al, [xBP + xCB*2]
    57         push    ax
    58         push    cs
    59         push    .szMsg wrt BS3TEXT16
    60         call    Bs3Printf
    61         add     sp, 6
    62   %else
    63         movzx   xDX, byte [xBP + xCB*2]
    64         push    xDX
    65         push    .szMsg wrt FLAT
    66         BS3_CALL Bs3Printf, 2
    67         add     xSP, xCB * 2
    68   %endif
    69  %endif
    70 
    71         ; Return
    72         xor     al, al
    73 ;mov al, TMPL_MODE                       ; remove me
    74 
    75 
    76         mov     xSP, xBP
    77         pop     xBP
    78         BS3_CALL_CONV_EPILOG 1
    79         ret
    80 .szMsg: db 'hello world %#x!', 13, 10, 0
    81 
    82 BS3_PROC_END_MODE   bs3CpuBasic2_iret
    83  %endif
    84 
    85 %endif ; BS3_INSTANTIATING_MODE
    8638
    8739
     
    11062BS3_PROC_END_CMN   bs3CpuBasic2_sidt_opsize_bx_ud2
    11163
    112 %if TMPL_BITS == 64
     64 %if TMPL_BITS == 64
    11365BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_rexw_bx_ud2, BS3_PBC_NEAR
    11466        db      X86_OP_REX_W
     
    12779AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_rexw_bx_ud2) == 5)
    12880BS3_PROC_END_CMN   bs3CpuBasic2_sidt_opsize_rexw_bx_ud2
    129 %endif
    130 
    131 %if TMPL_BITS != 64
     81 %endif
     82
     83 %if TMPL_BITS != 64
    13284BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_ss_bx_ud2, BS3_PBC_NEAR
    13385        sidt    [ss:xBX]
     
    14496AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_ss_bx_ud2) == 5)
    14597BS3_PROC_END_CMN   bs3CpuBasic2_sidt_opsize_ss_bx_ud2
    146 %endif
     98 %endif
     99
    147100
    148101;
     
    164117BS3_PROC_END_CMN   bs3CpuBasic2_sgdt_opsize_bx_ud2
    165118
    166 %if TMPL_BITS == 64
     119 %if TMPL_BITS == 64
    167120BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_rexw_bx_ud2, BS3_PBC_NEAR
    168121        db      X86_OP_REX_W
     
    181134AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2) == 5)
    182135BS3_PROC_END_CMN   bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2
    183 %endif
    184 
    185 %if TMPL_BITS != 64
     136 %endif
     137
     138 %if TMPL_BITS != 64
    186139BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_ss_bx_ud2, BS3_PBC_NEAR
    187140        sgdt    [ss:xBX]
     
    198151AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_ss_bx_ud2) == 5)
    199152BS3_PROC_END_CMN   bs3CpuBasic2_sgdt_opsize_ss_bx_ud2
    200 %endif
    201 
    202 
    203 ;
    204 ;
    205 ;
    206 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_bx_ud2, BS3_PBC_NEAR
    207         lidt    [xBX]
    208 .again: ud2
    209         jmp     .again
    210 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_bx_ud2) == 3)
    211 BS3_PROC_END_CMN   bs3CpuBasic2_lidt_bx_ud2
     153 %endif
     154
     155
     156;
     157; LIDT
     158;
     159BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
     160        lidt    [xBX]
     161        sidt    [BS3_NOT_64BIT(es:) xDI]
     162        lidt    [BS3_NOT_64BIT(es:) xSI]
     163.again:
     164        ud2
     165        jmp     .again
     166AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(9,11))
     167BS3_PROC_END_CMN   bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2
     168
     169BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
     170        db      X86_OP_PRF_SIZE_OP
     171        lidt    [xBX]
     172        sidt    [BS3_NOT_64BIT(es:) xDI]
     173        lidt    [BS3_NOT_64BIT(es:) xSI]
     174.again:
     175        ud2
     176        jmp     .again
     177AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(10,12))
     178BS3_PROC_END_CMN   bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2
     179
     180 %if TMPL_BITS == 64
     181BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
     182        db      X86_OP_REX_W
     183        lidt    [xBX]
     184        sidt    [xDI]
     185        lidt    [xSI]
     186.again:
     187        ud2
     188        jmp     .again
     189AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2) == 10)
     190BS3_PROC_END_CMN   bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2
     191
     192BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
     193        db      X86_OP_PRF_SIZE_OP
     194        db      X86_OP_REX_W
     195        lidt    [xBX]
     196        sidt    [xDI]
     197        lidt    [xSI]
     198.again:
     199        ud2
     200        jmp     .again
     201AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2) == 11)
     202BS3_PROC_END_CMN   bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2
     203 %endif
     204
     205 %if TMPL_BITS != 64
     206BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
     207        lidt    [ss:xBX]
     208        sidt    [BS3_NOT_64BIT(es:) xDI]
     209        lidt    [BS3_NOT_64BIT(es:) xSI]
     210.again:
     211        ud2
     212        jmp     .again
     213AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2) == 12)
     214BS3_PROC_END_CMN   bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2
     215
     216BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
     217        db      X86_OP_PRF_SIZE_OP
     218        lidt    [ss:xBX]
     219        sidt    [BS3_NOT_64BIT(es:) xDI]
     220        lidt    [BS3_NOT_64BIT(es:) xSI]
     221.again:
     222        ud2
     223        jmp     .again
     224AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2) == 13)
     225BS3_PROC_END_CMN   bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2
     226 %endif
     227
    212228
    213229%endif ; BS3_INSTANTIATING_CMN
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c

    r60680 r60724  
    4242BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sidt);
    4343BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sgdt);
     44BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lidt);
     45BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lgdt);
    4446
    4547
     
    5052{
    5153    //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
    52 //    BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),
    5354    //BS3TESTMODEENTRY_CMN("iret", bs3CpuBasic2_iret),
    5455//    BS3TESTMODEENTRY_MODE("iret", bs3CpuBasic2_iret),
     56#if 0
     57    BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),
    5558    BS3TESTMODEENTRY_MODE("sidt", bs3CpuBasic2_sidt),
    5659    BS3TESTMODEENTRY_MODE("sgdt", bs3CpuBasic2_sgdt),
     60#endif
     61    BS3TESTMODEENTRY_MODE("lidt", bs3CpuBasic2_lidt),
    5762};
    5863
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac

    r60557 r60724  
    198198section BS3TEXT32_END   align=1 CLASS=BS3CLASS32CODE PUBLIC USE32 FLAT
    199199BS3_GLOBAL_DATA Bs3Text32_EndOfSegment, 0
     200
     201
     202;
     203; This is a hack to separate the 32-bit and 64-bit text segments when linking,
     204; such that they don't share the same base frame because they're both assigned
     205; to the AUTO group by the linker.
     206;
     207section BS3SEPARATE32AND64BITCODE     align=16   CLASS=BS3CLASSSEPARATE32AND64BITCODE PUBLIC USE16
     208BS3_GLOBAL_DATA Bs3Separate32And64BitCode_StartOfSegment, 0
     209    db      10,13,'eye-catcher: 32-64 wedge',10,13
     210section BS3SEPARATE32AND64BITCODE_END align=16   CLASS=BS3CLASSSEPARATE32AND64BITCODE PUBLIC USE16
     211BS3_GLOBAL_DATA Bs3Separate32And64BitCode_EndOfSegment, 0
     212GROUP BS3SEPARATE32AND64BITCODEGROUP BS3SEPARATE32AND64BITCODE BS3SEPARATE32AND64BITCODE_END
    200213
    201214
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm

    r60686 r60724  
    997997; LIDT structure for the real mode IVT at address 0x00000000 (8-byte aligned on offset).
    998998BS3_GLOBAL_DATA Bs3Lidt_Ivt, 2+8
    999         dw      256*4 - 1                       ; limit
     999        dw      0ffffh                          ; limit
    10001000        dw      0                               ; low offset
    10011001        dw      0                               ; high offset
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac

    r60676 r60724  
    228228
    229229 %undef   BS3_IF_64BIT_OTHERWISE
    230  %if %1 == 32
    231   %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_32BitExpr
     230 %if %1 == 64
     231  %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_64BitExpr
    232232 %else
    233233  %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_OtherwiseExpr
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