VirtualBox

Changeset 60750 in vbox


Ignore:
Timestamp:
Apr 28, 2016 8:11:10 PM (9 years ago)
Author:
vboxsync
Message:

bs3kit: cleanups

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
4 edited
1 copied

Legend:

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

    r60657 r60750  
    240240        bs3kit/bs3-first-rm.asm \
    241241        bs3-cpu-basic-2.c \
     242        bs3-cpu-basic-2-x0.c \
    242243        bs3-cpu-basic-2-asm.asm \
    243244       bs3kit/bs3-cmn-instantiate-x0.c16 \
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c

    r60749 r60750  
    4444    } while (0)
    4545
    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 /** Worker requires 386 or later. */
    51 # define BS3CB2SIDTSGDT_F_386PLUS   UINT8_C(0x02)
    52 #endif
    5346
    5447#ifdef BS3_INSTANTIATING_MODE
     
    9184    uint8_t u1DescType;
    9285} BS3CB2INVLDESCTYPE;
    93 
    94 typedef struct BS3CB2SIDTSGDT
    95 {
    96     const char *pszDesc;
    97     FPFNBS3FAR  fpfnWorker;
    98     uint8_t     cbInstr;
    99     bool        fSs;
    100     uint8_t     bMode;
    101     uint8_t     fFlags;
    102 } BS3CB2SIDTSGDT;
    10386#endif
    10487
     
    11598# define            g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr)
    11699extern uint32_t     g_bs3CpuBasic2_ud2_FlatAddr;
    117 
    118 extern FNBS3FAR     bs3CpuBasic2_sidt_bx_ud2_c16;
    119 extern FNBS3FAR     bs3CpuBasic2_sidt_bx_ud2_c32;
    120 extern FNBS3FAR     bs3CpuBasic2_sidt_bx_ud2_c64;
    121 extern FNBS3FAR     bs3CpuBasic2_sidt_ss_bx_ud2_c16;
    122 extern FNBS3FAR     bs3CpuBasic2_sidt_ss_bx_ud2_c32;
    123 extern FNBS3FAR     bs3CpuBasic2_sidt_rexw_bx_ud2_c64;
    124 extern FNBS3FAR     bs3CpuBasic2_sidt_opsize_bx_ud2_c16;
    125 extern FNBS3FAR     bs3CpuBasic2_sidt_opsize_bx_ud2_c32;
    126 extern FNBS3FAR     bs3CpuBasic2_sidt_opsize_bx_ud2_c64;
    127 extern FNBS3FAR     bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16;
    128 extern FNBS3FAR     bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32;
    129 extern FNBS3FAR     bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64;
    130 
    131 extern FNBS3FAR     bs3CpuBasic2_sgdt_bx_ud2_c16;
    132 extern FNBS3FAR     bs3CpuBasic2_sgdt_bx_ud2_c32;
    133 extern FNBS3FAR     bs3CpuBasic2_sgdt_bx_ud2_c64;
    134 extern FNBS3FAR     bs3CpuBasic2_sgdt_ss_bx_ud2_c16;
    135 extern FNBS3FAR     bs3CpuBasic2_sgdt_ss_bx_ud2_c32;
    136 extern FNBS3FAR     bs3CpuBasic2_sgdt_rexw_bx_ud2_c64;
    137 extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_bx_ud2_c16;
    138 extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_bx_ud2_c32;
    139 extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_bx_ud2_c64;
    140 extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16;
    141 extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32;
    142 extern FNBS3FAR     bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64;
    143 
    144 extern FNBS3FAR     bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16;
    145 extern FNBS3FAR     bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32;
    146 extern FNBS3FAR     bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64;
    147 extern FNBS3FAR     bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16;
    148 extern FNBS3FAR     bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32;
    149 extern FNBS3FAR     bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64;
    150 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16;
    151 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2_c16;
    152 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32;
    153 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64;
    154 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16;
    155 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32;
    156 extern FNBS3FAR     bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64;
    157 
    158 extern FNBS3FAR     bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c16;
    159 extern FNBS3FAR     bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c32;
    160 extern FNBS3FAR     bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c64;
    161 extern FNBS3FAR     bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16;
    162 extern FNBS3FAR     bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32;
    163 extern FNBS3FAR     bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64;
    164 extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c16;
    165 extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c32;
    166 extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c64;
    167 extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16;
    168 extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32;
    169 extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64;
    170 
    171100#endif
    172101
     
    182111# define                    g_f16BitSys     BS3_CMN_NM(g_f16BitSys)
    183112static bool                 g_f16BitSys = 1;
    184 
    185 
    186 /** SIDT test workers. */
    187 static BS3CB2SIDTSGDT const g_aSidtWorkers[] =
    188 {
    189     { "", bs3CpuBasic2_sidt_bx_ud2_c16,             3, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    190     { "", bs3CpuBasic2_sidt_ss_bx_ud2_c16,          4, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    191     { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c16,      4, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    192     { "", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16,   5, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    193     { "", bs3CpuBasic2_sidt_bx_ud2_c32,             3, false,   BS3_MODE_CODE_32, 0 },
    194     { "", bs3CpuBasic2_sidt_ss_bx_ud2_c32,          4, true,    BS3_MODE_CODE_32, 0 },
    195     { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c32,      4, false,   BS3_MODE_CODE_32, 0 },
    196     { "", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32,   5, true,    BS3_MODE_CODE_32, 0 },
    197     { "", bs3CpuBasic2_sidt_bx_ud2_c64,             3, false,   BS3_MODE_CODE_64, 0 },
    198     { "", bs3CpuBasic2_sidt_rexw_bx_ud2_c64,        4, false,   BS3_MODE_CODE_64, 0 },
    199     { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c64,      4, false,   BS3_MODE_CODE_64, 0 },
    200     { "", bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64, 0 },
    201 };
    202 
    203 /** SGDT test workers. */
    204 static BS3CB2SIDTSGDT const g_aSgdtWorkers[] =
    205 {
    206     { "", bs3CpuBasic2_sgdt_bx_ud2_c16,             3, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    207     { "", bs3CpuBasic2_sgdt_ss_bx_ud2_c16,          4, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    208     { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c16,      4, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    209     { "", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16,   5, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    210     { "", bs3CpuBasic2_sgdt_bx_ud2_c32,             3, false,   BS3_MODE_CODE_32, 0 },
    211     { "", bs3CpuBasic2_sgdt_ss_bx_ud2_c32,          4, true,    BS3_MODE_CODE_32, 0 },
    212     { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c32,      4, false,   BS3_MODE_CODE_32, 0 },
    213     { "", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32,   5, true,    BS3_MODE_CODE_32, 0 },
    214     { "", bs3CpuBasic2_sgdt_bx_ud2_c64,             3, false,   BS3_MODE_CODE_64, 0 },
    215     { "", bs3CpuBasic2_sgdt_rexw_bx_ud2_c64,        4, false,   BS3_MODE_CODE_64, 0 },
    216     { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c64,      4, false,   BS3_MODE_CODE_64, 0 },
    217     { "", bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64, 0 },
    218 };
    219 
    220 /** LIDT test workers. */
    221 static BS3CB2SIDTSGDT const g_aLidtWorkers[] =
    222 {
    223     { "lidt [bx]",              bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16,             11, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    224     { "lidt [ss:bx]",           bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16,          12, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    225     { "o32 lidt [bx]",          bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16,      12, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },
    226     { "o32 lidt [bx]; sidt32",  bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2_c16,    27, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },
    227     { "o32 lidt [ss:bx]",       bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16,   13, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },
    228     { "lidt [ebx]",             bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32,             11, false,   BS3_MODE_CODE_32, 0 },
    229     { "lidt [ss:ebx]",          bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32,          12, true,    BS3_MODE_CODE_32, 0 },
    230     { "o16 lidt [ebx]",         bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32,      12, false,   BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },
    231     { "o16 lidt [ss:ebx]",      bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32,   13, true,    BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },
    232     { "lidt [rbx]",             bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64,              9, false,   BS3_MODE_CODE_64, 0 },
    233     { "o64 lidt [rbx]",         bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64,        10, false,   BS3_MODE_CODE_64, 0 },
    234     { "o32 lidt [rbx]",         bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64,      10, false,   BS3_MODE_CODE_64, 0 },
    235     { "o32 o64 lidt [rbx]",     bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64, 11, false,   BS3_MODE_CODE_64, 0 },
    236 };
    237 
    238 /** LGDT test workers. */
    239 static BS3CB2SIDTSGDT const g_aLgdtWorkers[] =
    240 {
    241     { "lgdt [bx]",              bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c16,             11, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    242     { "lgdt [ss:bx]",           bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16,          12, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    243     { "o32 lgdt [bx]",          bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c16,      12, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },
    244     { "o32 lgdt [ss:bx]",       bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16,   13, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },
    245     { "lgdt [ebx]",             bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c32,             11, false,   BS3_MODE_CODE_32, 0 },
    246     { "lgdt [ss:ebx]",          bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32,          12, true,    BS3_MODE_CODE_32, 0 },
    247     { "o16 lgdt [ebx]",         bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c32,      12, false,   BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },
    248     { "o16 lgdt [ss:ebx]",      bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32,   13, true,    BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },
    249     { "lgdt [rbx]",             bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c64,              9, false,   BS3_MODE_CODE_64, 0 },
    250     { "o64 lgdt [rbx]",         bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64,        10, false,   BS3_MODE_CODE_64, 0 },
    251     { "o32 lgdt [rbx]",         bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c64,      10, false,   BS3_MODE_CODE_64, 0 },
    252     { "o32 o64 lgdt [rbx]",     bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64, 11, false,   BS3_MODE_CODE_64, 0 },
    253 };
    254 
    255113
    256114
     
    14451303}
    14461304
    1447 #if TMPL_BITS == 16
    1448 
    1449 /**
    1450  * Executes one round of SIDT and SGDT tests using one assembly worker.
    1451  *
    1452  * This is written with driving everything from the 16-bit or 32-bit worker in
    1453  * mind, i.e. not assuming the test bitcount is the same as the current.
    1454  */
    1455 # define bs3CpuBasic2_sidt_sgdt_One BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_One)
    1456 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
    1457                                                uint8_t const *pbExpected)
    1458 {
    1459     BS3TRAPFRAME        TrapCtx;
    1460     BS3REGCTX           Ctx;
    1461     BS3REGCTX           CtxUdExpected;
    1462     BS3REGCTX           TmpCtx;
    1463     uint8_t const       cbBuf = 8*2;         /* test buffer area  */
    1464     uint8_t             abBuf[8*2 + 8 + 8];  /* test buffer w/ misalignment test space and some extra guard. */
    1465     uint8_t BS3_FAR    *pbBuf  = abBuf;
    1466     uint8_t const       cbIdtr = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 2+8 : 2+4;
    1467     bool const          f286   = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286;
    1468     uint8_t             bFiller;
    1469     int                 off;
    1470     int                 off2;
    1471     unsigned            cb;
    1472     uint8_t BS3_FAR    *pbTest;
    1473 
    1474     /* make sure they're allocated  */
    1475     Bs3MemZero(&Ctx, sizeof(Ctx));
    1476     Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected));
    1477     Bs3MemZero(&TmpCtx, sizeof(TmpCtx));
    1478     Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
    1479     Bs3MemZero(&abBuf, sizeof(abBuf));
    1480 
    1481     /* Create a context, give this routine some more stack space, point the context
    1482        at our SIDT [xBX] + UD2 combo, and point DS:xBX at abBuf. */
    1483     Bs3RegCtxSaveEx(&Ctx, bTestMode, 256 /*cbExtraStack*/);
    1484     Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);
    1485     Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pWorker->fpfnWorker);
    1486     if (BS3_MODE_IS_16BIT_SYS(bTestMode))
    1487         g_uBs3TrapEipHint = Ctx.rip.u32;
    1488     if (!BS3_MODE_IS_RM_OR_V86(bTestMode))
    1489         Bs3RegCtxConvertToRingX(&Ctx, bRing);
    1490 
    1491     /* For successful SIDT attempts, we'll stop at the UD2. */
    1492     Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx));
    1493     CtxUdExpected.rip.u += pWorker->cbInstr;
    1494 
    1495     /*
    1496      * Check that it works at all and that only bytes we expect gets written to.
    1497      */
    1498     /* First with zero buffer. */
    1499     Bs3MemZero(abBuf, sizeof(abBuf));
    1500     if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), 0))
    1501         Bs3TestFailedF("ASMMemIsAllU8 or Bs3MemZero is busted: abBuf=%.*Rhxs\n", sizeof(abBuf), pbBuf);
    1502     if (!ASMMemIsZero(abBuf, sizeof(abBuf)))
    1503         Bs3TestFailedF("ASMMemIsZero or Bs3MemZero is busted: abBuf=%.*Rhxs\n", sizeof(abBuf), pbBuf);
    1504     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1505     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1506     if (f286 && abBuf[cbIdtr - 1] != 0xff)
    1507         Bs3TestFailedF("286: Top base byte isn't 0xff (#1): %#x\n", abBuf[cbIdtr - 1]);
    1508     if (!ASMMemIsZero(&abBuf[cbIdtr], cbBuf - cbIdtr))
    1509         Bs3TestFailedF("Unexpected buffer bytes set (#1): cbIdtr=%u abBuf=%.*Rhxs\n", cbIdtr, cbBuf, pbBuf);
    1510     if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)
    1511         Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);
    1512     g_usBs3TestStep++;
    1513 
    1514     /* Again with a buffer filled with a byte not occuring in the previous result. */
    1515     bFiller = 0x55;
    1516     while (Bs3MemChr(abBuf, bFiller, cbBuf) != NULL)
    1517         bFiller++;
    1518     Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
    1519     if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))
    1520         Bs3TestFailedF("ASMMemIsAllU8 or Bs3MemSet is busted: bFiller=%#x abBuf=%.*Rhxs\n", bFiller, sizeof(abBuf), pbBuf);
    1521 
    1522     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1523     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1524     if (f286 && abBuf[cbIdtr - 1] != 0xff)
    1525         Bs3TestFailedF("286: Top base byte isn't 0xff (#2): %#x\n", abBuf[cbIdtr - 1]);
    1526     if (!ASMMemIsAllU8(&abBuf[cbIdtr], cbBuf - cbIdtr, bFiller))
    1527         Bs3TestFailedF("Unexpected buffer bytes set (#2): cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf);
    1528     if (Bs3MemChr(abBuf, bFiller, cbIdtr) != NULL)
    1529         Bs3TestFailedF("Not all bytes touched: cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf);
    1530     if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)
    1531         Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);
    1532     g_usBs3TestStep++;
    1533 
    1534     /*
    1535      * Slide the buffer along 8 bytes to cover misalignment.
    1536      */
    1537     for (off = 0; off < 8; off++)
    1538     {
    1539         pbBuf = &abBuf[off];
    1540         Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &abBuf[off]);
    1541         CtxUdExpected.rbx.u = Ctx.rbx.u;
    1542 
    1543         /* First with zero buffer. */
    1544         Bs3MemZero(abBuf, sizeof(abBuf));
    1545         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1546         bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1547         if (off > 0 && !ASMMemIsZero(abBuf, off))
    1548             Bs3TestFailedF("Unexpected buffer bytes set before (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n",
    1549                            cbIdtr, off, off + cbBuf, abBuf);
    1550         if (!ASMMemIsZero(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off))
    1551             Bs3TestFailedF("Unexpected buffer bytes set after (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n",
    1552                            cbIdtr, off, off + cbBuf, abBuf);
    1553         if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    1554             Bs3TestFailedF("286: Top base byte isn't 0xff (#3): %#x\n", abBuf[off + cbIdtr - 1]);
    1555         if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
    1556             Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    1557         g_usBs3TestStep++;
    1558 
    1559         /* Again with a buffer filled with a byte not occuring in the previous result. */
    1560         Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
    1561         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1562         bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1563         if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))
    1564             Bs3TestFailedF("Unexpected buffer bytes set before (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1565                            cbIdtr, off, bFiller, off + cbBuf, abBuf);
    1566         if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off, bFiller))
    1567             Bs3TestFailedF("Unexpected buffer bytes set after (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1568                            cbIdtr, off, bFiller, off + cbBuf, abBuf);
    1569         if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)
    1570             Bs3TestFailedF("Not all bytes touched (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1571                            cbIdtr, off, bFiller, off + cbBuf, abBuf);
    1572         if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    1573             Bs3TestFailedF("286: Top base byte isn't 0xff (#4): %#x\n", abBuf[off + cbIdtr - 1]);
    1574         if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
    1575             Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    1576         g_usBs3TestStep++;
    1577     }
    1578     pbBuf = abBuf;
    1579     Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);
    1580     CtxUdExpected.rbx.u = Ctx.rbx.u;
    1581 
    1582     /*
    1583      * Play with the selector limit if the target mode supports limit checking
    1584      * We use BS3_SEL_TEST_PAGE_00 for this
    1585      */
    1586     if (   !BS3_MODE_IS_RM_OR_V86(bTestMode)
    1587         && !BS3_MODE_IS_64BIT_CODE(bTestMode))
    1588     {
    1589         uint16_t cbLimit;
    1590         uint32_t uFlatBuf = Bs3SelPtrToFlat(abBuf);
    1591         Bs3GdteTestPage00 = Bs3Gdte_DATA16;
    1592         Bs3GdteTestPage00.Gen.u2Dpl       = bRing;
    1593         Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatBuf;
    1594         Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatBuf >> 16);
    1595         Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatBuf >> 24);
    1596 
    1597         if (pWorker->fSs)
    1598             CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;
    1599         else
    1600             CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
    1601 
    1602         /* Expand up (normal). */
    1603         for (off = 0; off < 8; off++)
    1604         {
    1605             CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    1606             for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)
    1607             {
    1608                 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    1609                 Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
    1610                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1611                 if (off + cbIdtr <= cbLimit + 1)
    1612                 {
    1613                     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1614                     if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)
    1615                         Bs3TestFailedF("Not all bytes touched (#5): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1616                                        cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1617                     if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
    1618                         Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    1619                     if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    1620                         Bs3TestFailedF("286: Top base byte isn't 0xff (#5): %#x\n", abBuf[off + cbIdtr - 1]);
    1621                 }
    1622                 else
    1623                 {
    1624                     if (pWorker->fSs)
    1625                         bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    1626                     else
    1627                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1628                     if (off + 2 <= cbLimit + 1)
    1629                     {
    1630                         if (Bs3MemChr(&abBuf[off], bFiller, 2) != NULL)
    1631                             Bs3TestFailedF("Limit bytes not touched (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1632                                            cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1633                         if (Bs3MemCmp(&abBuf[off], pbExpected, 2) != 0)
    1634                             Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pbExpected, &abBuf[off]);
    1635                         if (!ASMMemIsAllU8(&abBuf[off + 2], cbIdtr - 2, bFiller))
    1636                             Bs3TestFailedF("Base bytes touched on #GP (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1637                                            cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1638                     }
    1639                     else if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))
    1640                         Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1641                                        cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1642                 }
    1643 
    1644                 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))
    1645                     Bs3TestFailedF("Leading bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1646                                    cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1647                 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller))
    1648                     Bs3TestFailedF("Trailing bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1649                                    cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1650 
    1651                 g_usBs3TestStep++;
    1652             }
    1653         }
    1654 
    1655         /* Expand down (weird).  Inverted valid area compared to expand up,
    1656            so a limit of zero give us a valid range for 0001..0ffffh (instead of
    1657            a segment with one valid byte at 0000h).  Whereas a limit of 0fffeh
    1658            means one valid byte at 0ffffh, and a limit of 0ffffh means none
    1659            (because in a normal expand up the 0ffffh means all 64KB are
    1660            accessible). */
    1661         Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;
    1662         for (off = 0; off < 8; off++)
    1663         {
    1664             CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    1665             for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)
    1666             {
    1667                 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    1668                 Bs3MemSet(abBuf, bFiller, sizeof(abBuf));
    1669                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1670 
    1671                 if (off > cbLimit)
    1672                 {
    1673                     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1674                     if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)
    1675                         Bs3TestFailedF("Not all bytes touched (#8): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1676                                        cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1677                     if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)
    1678                         Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);
    1679                     if (f286 && abBuf[off + cbIdtr - 1] != 0xff)
    1680                         Bs3TestFailedF("286: Top base byte isn't 0xff (#8): %#x\n", abBuf[off + cbIdtr - 1]);
    1681                 }
    1682                 else
    1683                 {
    1684                     if (pWorker->fSs)
    1685                         bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    1686                     else
    1687                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1688                     if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))
    1689                         Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1690                                        cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1691                 }
    1692 
    1693                 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))
    1694                     Bs3TestFailedF("Leading bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1695                                    cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1696                 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller))
    1697                     Bs3TestFailedF("Trailing bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",
    1698                                    cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);
    1699 
    1700                 g_usBs3TestStep++;
    1701             }
    1702         }
    1703 
    1704         Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);
    1705         CtxUdExpected.rbx.u = Ctx.rbx.u;
    1706         CtxUdExpected.ss = Ctx.ss;
    1707         CtxUdExpected.ds = Ctx.ds;
    1708     }
    1709 
    1710     /*
    1711      * Play with the paging.
    1712      */
    1713     if (   BS3_MODE_IS_PAGED(bTestMode)
    1714         && (!pWorker->fSs || bRing == 3) /* SS.DPL == CPL, we'll get some tiled ring-3 selector here.  */
    1715         && (pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED)) != NULL)
    1716     {
    1717         RTCCUINTXREG uFlatTest = Bs3SelPtrToFlat(pbTest);
    1718 
    1719         /*
    1720          * Slide the buffer towards the trailing guard page.  We'll observe the
    1721          * first word being written entirely separately from the 2nd dword/qword.
    1722          */
    1723         for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
    1724         {
    1725             Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2);
    1726             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);
    1727             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1728             if (off + cbIdtr <= X86_PAGE_SIZE)
    1729             {
    1730                 CtxUdExpected.rbx = Ctx.rbx;
    1731                 CtxUdExpected.ss  = Ctx.ss;
    1732                 CtxUdExpected.ds  = Ctx.ds;
    1733                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1734                 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    1735                     Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    1736             }
    1737             else
    1738             {
    1739                 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
    1740                                           uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    1741                 if (   off <= X86_PAGE_SIZE - 2
    1742                     && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    1743                     Bs3TestPrintf("Mismatch (#10): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
    1744                                   pbExpected, &pbTest[off], off);
    1745                 if (   off < X86_PAGE_SIZE - 2
    1746                     && !ASMMemIsAllU8(&pbTest[off + 2], X86_PAGE_SIZE - off - 2, bFiller))
    1747                     Bs3TestPrintf("Wrote partial base on #PF (#10): bFiller=%#x, got %.*Rhxs; off=%#x\n",
    1748                                   bFiller, X86_PAGE_SIZE - off - 2, &pbTest[off + 2], off);
    1749                 if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller)
    1750                     Bs3TestPrintf("Wrote partial limit on #PF (#10): Expected %02x, got %02x\n", bFiller, pbTest[off]);
    1751             }
    1752             g_usBs3TestStep++;
    1753         }
    1754 
    1755         /*
    1756          * Now, do it the other way around. It should look normal now since writing
    1757          * the limit will #PF first and nothing should be written.
    1758          */
    1759         for (off = cbIdtr + 4; off >= -cbIdtr - 4; off--)
    1760         {
    1761             Bs3MemSet(pbTest, bFiller, 48);
    1762             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);
    1763             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1764             if (off >= 0)
    1765             {
    1766                 CtxUdExpected.rbx = Ctx.rbx;
    1767                 CtxUdExpected.ss  = Ctx.ss;
    1768                 CtxUdExpected.ds  = Ctx.ds;
    1769                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1770                 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    1771                     Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    1772             }
    1773             else
    1774             {
    1775                 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), uFlatTest + off);
    1776                 if (   -off < cbIdtr
    1777                     && !ASMMemIsAllU8(pbTest, cbIdtr + off, bFiller))
    1778                     Bs3TestPrintf("Wrote partial content on #PF (#12): bFiller=%#x, found %.*Rhxs; off=%d\n",
    1779                                   bFiller, cbIdtr + off, pbTest, off);
    1780             }
    1781             if (!ASMMemIsAllU8(&pbTest[RT_MAX(cbIdtr + off, 0)], 16, bFiller))
    1782                 Bs3TestPrintf("Wrote beyond expected area (#13): bFiller=%#x, found %.16Rhxs; off=%d\n",
    1783                               bFiller, &pbTest[RT_MAX(cbIdtr + off, 0)], off);
    1784             g_usBs3TestStep++;
    1785         }
    1786 
    1787         /*
    1788          * Combine paging and segment limit and check ordering.
    1789          * This is kind of interesting here since it the instruction seems to
    1790          * be doing two separate writes.
    1791          */
    1792         if (   !BS3_MODE_IS_RM_OR_V86(bTestMode)
    1793             && !BS3_MODE_IS_64BIT_CODE(bTestMode))
    1794         {
    1795             uint16_t cbLimit;
    1796 
    1797             Bs3GdteTestPage00 = Bs3Gdte_DATA16;
    1798             Bs3GdteTestPage00.Gen.u2Dpl       = bRing;
    1799             Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatTest;
    1800             Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);
    1801             Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);
    1802 
    1803             if (pWorker->fSs)
    1804                 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;
    1805             else
    1806                 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
    1807 
    1808             /* Expand up (normal), approaching tail guard page. */
    1809             for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
    1810             {
    1811                 CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    1812                 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)
    1813                 {
    1814                     Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    1815                     Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2);
    1816                     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1817                     if (off + cbIdtr <= cbLimit + 1)
    1818                     {
    1819                         /* No #GP, but maybe #PF. */
    1820                         if (off + cbIdtr <= X86_PAGE_SIZE)
    1821                         {
    1822                             bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1823                             if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    1824                                 Bs3TestFailedF("Mismatch (#14): expected %.*Rhxs, got %.*Rhxs\n",
    1825                                                cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    1826                         }
    1827                         else
    1828                         {
    1829                             bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
    1830                                                       uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    1831                             if (   off <= X86_PAGE_SIZE - 2
    1832                                 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    1833                                 Bs3TestPrintf("Mismatch (#15): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
    1834                                               pbExpected, &pbTest[off], off);
    1835                             cb = X86_PAGE_SIZE - off - 2;
    1836                             if (   off < X86_PAGE_SIZE - 2
    1837                                 && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller))
    1838                                 Bs3TestPrintf("Wrote partial base on #PF (#15): bFiller=%#x, got %.*Rhxs; off=%#x\n",
    1839                                               bFiller, cb, &pbTest[off + 2], off);
    1840                             if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller)
    1841                                 Bs3TestPrintf("Wrote partial limit on #PF (#15): Expected %02x, got %02x\n", bFiller, pbTest[off]);
    1842                         }
    1843                     }
    1844                     else if (off + 2 <= cbLimit + 1)
    1845                     {
    1846                         /* [ig]tr.limit writing does not cause #GP, but may cause #PG, if not writing the base causes #GP. */
    1847                         if (off <= X86_PAGE_SIZE - 2)
    1848                         {
    1849                             if (pWorker->fSs)
    1850                                 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    1851                             else
    1852                                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1853                             if (Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    1854                                 Bs3TestPrintf("Mismatch (#16): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",
    1855                                               pbExpected, &pbTest[off], off);
    1856                             cb = X86_PAGE_SIZE - off - 2;
    1857                             if (   off < X86_PAGE_SIZE - 2
    1858                                 && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller))
    1859                                 Bs3TestPrintf("Wrote partial base with limit (#16): bFiller=%#x, got %.*Rhxs; off=%#x\n",
    1860                                               bFiller, cb, &pbTest[off + 2], off);
    1861                         }
    1862                         else
    1863                         {
    1864                             bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
    1865                                                       uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    1866                             if (   off < X86_PAGE_SIZE
    1867                                 && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller))
    1868                                 Bs3TestPrintf("Mismatch (#16): Partial limit write on #PF: bFiller=%#x, got %.*Rhxs\n",
    1869                                               bFiller, X86_PAGE_SIZE - off, &pbTest[off]);
    1870                         }
    1871                     }
    1872                     else
    1873                     {
    1874                         /* #GP/#SS on limit. */
    1875                         if (pWorker->fSs)
    1876                             bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    1877                         else
    1878                             bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1879                         if (   off < X86_PAGE_SIZE
    1880                             && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller))
    1881                             Bs3TestPrintf("Mismatch (#17): Partial write on #GP: bFiller=%#x, got %.*Rhxs\n",
    1882                                           bFiller, X86_PAGE_SIZE - off, &pbTest[off]);
    1883                     }
    1884 
    1885                     cb = RT_MIN(cbIdtr * 2, off - (X86_PAGE_SIZE - cbIdtr*2));
    1886                     if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], cb, bFiller))
    1887                         Bs3TestFailedF("Leading bytes touched (#18): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",
    1888                                        cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE - cbIdtr * 2]);
    1889 
    1890                     g_usBs3TestStep++;
    1891 
    1892                     /* Set DS to 0 and check that we get #GP(0). */
    1893                     if (!pWorker->fSs)
    1894                     {
    1895                         Ctx.ds = 0;
    1896                         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1897                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1898                         Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
    1899                         g_usBs3TestStep++;
    1900                     }
    1901                 }
    1902             }
    1903 
    1904             /* Expand down. */
    1905             pbTest    -= X86_PAGE_SIZE; /* Note! we're backing up a page to simplify things */
    1906             uFlatTest -= X86_PAGE_SIZE;
    1907 
    1908             Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;
    1909             Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatTest;
    1910             Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);
    1911             Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);
    1912 
    1913             for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
    1914             {
    1915                 CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    1916                 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)
    1917                 {
    1918                     Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    1919                     Bs3MemSet(&pbTest[X86_PAGE_SIZE], bFiller, cbIdtr * 2);
    1920                     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1921                     if (cbLimit < off && off >= X86_PAGE_SIZE)
    1922                     {
    1923                         bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1924                         if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    1925                             Bs3TestFailedF("Mismatch (#19): expected %.*Rhxs, got %.*Rhxs\n",
    1926                                            cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    1927                         cb = X86_PAGE_SIZE + cbIdtr*2 - off;
    1928                         if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], cb, bFiller))
    1929                             Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",
    1930                                            cbIdtr, off, cbLimit, bFiller, cb, pbTest[off + cbIdtr]);
    1931                     }
    1932                     else
    1933                     {
    1934                         if (cbLimit < off && off < X86_PAGE_SIZE)
    1935                             bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),
    1936                                                       uFlatTest + off);
    1937                         else if (pWorker->fSs)
    1938                             bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    1939                         else
    1940                             bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1941                         cb = cbIdtr*2;
    1942                         if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE], cb, bFiller))
    1943                             Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",
    1944                                            cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE]);
    1945                     }
    1946                     g_usBs3TestStep++;
    1947                 }
    1948             }
    1949 
    1950             pbTest    += X86_PAGE_SIZE;
    1951             uFlatTest += X86_PAGE_SIZE;
    1952         }
    1953 
    1954         Bs3MemGuardedTestPageFree(pbTest);
    1955     }
    1956 
    1957     /*
    1958      * Check non-canonical 64-bit space.
    1959      */
    1960     if (   BS3_MODE_IS_64BIT_CODE(bTestMode)
    1961         && (pbTest = (uint8_t BS3_FAR *)Bs3PagingSetupCanonicalTraps()) != NULL)
    1962     {
    1963         /* Make our references relative to the gap. */
    1964         pbTest += g_cbBs3PagingOneCanonicalTrap;
    1965 
    1966         /* Hit it from below. */
    1967         for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)
    1968         {
    1969             Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0x0000800000000000) + off;
    1970             Bs3MemSet(&pbTest[-64], bFiller, 64*2);
    1971             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    1972             if (off + cbIdtr <= 0)
    1973             {
    1974                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    1975                 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    1976                     Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    1977             }
    1978             else
    1979             {
    1980                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    1981                 if (off <= -2 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)
    1982                     Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pbExpected, &pbTest[off]);
    1983                 off2 = off <= -2 ? 2 : 0;
    1984                 cb   = cbIdtr - off2;
    1985                 if (!ASMMemIsAllU8(&pbTest[off + off2], cb, bFiller))
    1986                     Bs3TestFailedF("Mismatch (#21): touched base %.*Rhxs, got %.*Rhxs\n",
    1987                                    cb, &pbExpected[off], cb, &pbTest[off + off2]);
    1988             }
    1989             if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))
    1990                 Bs3TestFailedF("Leading bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]);
    1991             if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller))
    1992                 Bs3TestFailedF("Trailing bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]);
    1993         }
    1994 
    1995         /* Hit it from above. */
    1996         for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)
    1997         {
    1998             Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0xffff800000000000) + off;
    1999             Bs3MemSet(&pbTest[-64], bFiller, 64*2);
    2000             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2001             if (off >= 0)
    2002             {
    2003                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2004                 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)
    2005                     Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);
    2006             }
    2007             else
    2008             {
    2009                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2010                 if (!ASMMemIsAllU8(&pbTest[off], cbIdtr, bFiller))
    2011                     Bs3TestFailedF("Mismatch (#22): touched base %.*Rhxs, got %.*Rhxs\n",
    2012                                    cbIdtr, &pbExpected[off], cbIdtr, &pbTest[off]);
    2013             }
    2014             if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))
    2015                 Bs3TestFailedF("Leading bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]);
    2016             if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller))
    2017                 Bs3TestFailedF("Trailing bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]);
    2018         }
    2019 
    2020     }
    2021 }
    2022 
    2023 
    2024 # define bs3CpuBasic2_sidt_sgdt_Common BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_Common)
    2025 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
    2026                                                   uint8_t const *pbExpected)
    2027 {
    2028     unsigned idx;
    2029     unsigned bRing;
    2030     unsigned iStep = 0;
    2031 
    2032     /* Note! We skip the SS checks for ring-0 since we badly mess up SS in the
    2033              test and don't want to bother with double faults. */
    2034     for (bRing = 0; bRing <= 3; bRing++)
    2035     {
    2036         for (idx = 0; idx < cWorkers; idx++)
    2037             if (    (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK))
    2038                 && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ ))
    2039             {
    2040                 g_usBs3TestStep = iStep;
    2041                 bs3CpuBasic2_sidt_sgdt_One(&paWorkers[idx], bTestMode, bRing, pbExpected);
    2042                 iStep += 1000;
    2043             }
    2044         if (BS3_MODE_IS_RM_OR_V86(bTestMode))
    2045             break;
    2046     }
    2047 }
    2048 
    2049 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
    2050 {
    2051     union
    2052     {
    2053         RTIDTR  Idtr;
    2054         uint8_t ab[16];
    2055     } Expected;
    2056 
    2057     g_pszTestMode = Bs3GetModeName(bMode);
    2058     g_bTestMode   = bMode;
    2059     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
    2060 
    2061 
    2062     /*
    2063      * Pass to common worker which is only compiled once per mode.
    2064      */
    2065     Bs3MemZero(&Expected, sizeof(Expected));
    2066     ASMGetIDTR(&Expected.Idtr);
    2067     bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSidtWorkers, RT_ELEMENTS(g_aSidtWorkers), Expected.ab);
    2068 
    2069     /*
    2070      * Re-initialize the IDT.
    2071      */
    2072     Bs3TrapReInit();
    2073     return 0;
    2074 }
    2075 
    2076 
    2077 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
    2078 {
    2079     uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;
    2080     uint64_t       uNew     = 0;
    2081     union
    2082     {
    2083         RTGDTR  Gdtr;
    2084         uint8_t ab[16];
    2085     } Expected;
    2086 
    2087     g_pszTestMode = Bs3GetModeName(bMode);
    2088     g_bTestMode   = bMode;
    2089     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
    2090 
    2091     /*
    2092      * If paged mode, try push the GDT way up.
    2093      */
    2094     if (BS3_MODE_IS_PAGED(bMode))
    2095     {
    2096 /** @todo loading non-canonical base addresses.   */
    2097         int rc;
    2098         uNew  = BS3_MODE_IS_64BIT_SYS(bMode) ? UINT64_C(0xffff80fedcb70000) : UINT64_C(0xc2d28000);
    2099         uNew |= uOrgAddr & X86_PAGE_OFFSET_MASK;
    2100         rc = Bs3PagingAlias(uNew, uOrgAddr, Bs3Lgdt_Gdt.cb, X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_D | X86_PTE_A);
    2101         if (RT_SUCCESS(rc))
    2102         {
    2103             Bs3Lgdt_Gdt.uAddr = uNew;
    2104             Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uNew);
    2105         }
    2106     }
    2107 
    2108     /*
    2109      * Pass to common worker which is only compiled once per mode.
    2110      */
    2111     Bs3MemZero(&Expected, sizeof(Expected));
    2112     ASMGetGDTR(&Expected.Gdtr);
    2113     bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab);
    2114 
    2115     /*
    2116      * Unalias the GDT.
    2117      */
    2118     if (uNew != 0)
    2119     {
    2120         Bs3Lgdt_Gdt.uAddr = uOrgAddr;
    2121         Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uOrgAddr);
    2122         Bs3PagingUnalias(uNew, Bs3Lgdt_Gdt.cb);
    2123     }
    2124 
    2125     /*
    2126      * Re-initialize the IDT.
    2127      */
    2128     Bs3TrapReInit();
    2129     return 0;
    2130 }
    2131 
    2132 
    2133 
    2134 /*
    2135  * LIDT & LGDT
    2136  */
    2137 
    2138 /**
    2139  * Executes one round of LIDT and LGDT tests using one assembly worker.
    2140  *
    2141  * This is written with driving everything from the 16-bit or 32-bit worker in
    2142  * mind, i.e. not assuming the test bitcount is the same as the current.
    2143  */
    2144 # define bs3CpuBasic2_lidt_lgdt_One BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_One)
    2145 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
    2146                                                uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected)
    2147 {
    2148     static const struct
    2149     {
    2150         bool        fGP;
    2151         uint16_t    cbLimit;
    2152         uint64_t    u64Base;
    2153     } s_aValues64[] =
    2154     {
    2155         { false, 0x0000, UINT64_C(0x0000000000000000) },
    2156         { false, 0x0001, UINT64_C(0x0000000000000001) },
    2157         { false, 0x0002, UINT64_C(0x0000000000000010) },
    2158         { false, 0x0003, UINT64_C(0x0000000000000123) },
    2159         { false, 0x0004, UINT64_C(0x0000000000001234) },
    2160         { false, 0x0005, UINT64_C(0x0000000000012345) },
    2161         { false, 0x0006, UINT64_C(0x0000000000123456) },
    2162         { false, 0x0007, UINT64_C(0x0000000001234567) },
    2163         { false, 0x0008, UINT64_C(0x0000000012345678) },
    2164         { false, 0x0009, UINT64_C(0x0000000123456789) },
    2165         { false, 0x000a, UINT64_C(0x000000123456789a) },
    2166         { false, 0x000b, UINT64_C(0x00000123456789ab) },
    2167         { false, 0x000c, UINT64_C(0x0000123456789abc) },
    2168         { false, 0x001c, UINT64_C(0x00007ffffeefefef) },
    2169         { false, 0xffff, UINT64_C(0x00007fffffffffff) },
    2170         {  true, 0xf3f1, UINT64_C(0x0000800000000000) },
    2171         {  true, 0x0000, UINT64_C(0x0000800000000000) },
    2172         {  true, 0x0000, UINT64_C(0x0000800000000333) },
    2173         {  true, 0x00f0, UINT64_C(0x0001000000000000) },
    2174         {  true, 0x0ff0, UINT64_C(0x0012000000000000) },
    2175         {  true, 0x0eff, UINT64_C(0x0123000000000000) },
    2176         {  true, 0xe0fe, UINT64_C(0x1234000000000000) },
    2177         {  true, 0x00ad, UINT64_C(0xffff300000000000) },
    2178         {  true, 0x0000, UINT64_C(0xffff7fffffffffff) },
    2179         {  true, 0x00f0, UINT64_C(0xffff7fffffffffff) },
    2180         { false, 0x5678, UINT64_C(0xffff800000000000) },
    2181         { false, 0x2969, UINT64_C(0xffffffffffeefefe) },
    2182         { false, 0x1221, UINT64_C(0xffffffffffffffff) },
    2183         { false, 0x1221, UINT64_C(0xffffffffffffffff) },
    2184     };
    2185     static const struct
    2186     {
    2187         uint16_t    cbLimit;
    2188         uint32_t    u32Base;
    2189     } s_aValues32[] =
    2190     {
    2191         { 0xdfdf, UINT32_C(0xefefefef) },
    2192         { 0x0000, UINT32_C(0x00000000) },
    2193         { 0x0001, UINT32_C(0x00000001) },
    2194         { 0x0002, UINT32_C(0x00000012) },
    2195         { 0x0003, UINT32_C(0x00000123) },
    2196         { 0x0004, UINT32_C(0x00001234) },
    2197         { 0x0005, UINT32_C(0x00012345) },
    2198         { 0x0006, UINT32_C(0x00123456) },
    2199         { 0x0007, UINT32_C(0x01234567) },
    2200         { 0x0008, UINT32_C(0x12345678) },
    2201         { 0x0009, UINT32_C(0x80204060) },
    2202         { 0x000a, UINT32_C(0xddeeffaa) },
    2203         { 0x000b, UINT32_C(0xfdecdbca) },
    2204         { 0x000c, UINT32_C(0x6098456b) },
    2205         { 0x000d, UINT32_C(0x98506099) },
    2206         { 0x000e, UINT32_C(0x206950bc) },
    2207         { 0x000f, UINT32_C(0x9740395d) },
    2208         { 0x0334, UINT32_C(0x64a9455e) },
    2209         { 0xb423, UINT32_C(0xd20b6eff) },
    2210         { 0x4955, UINT32_C(0x85296d46) },
    2211         { 0xffff, UINT32_C(0x07000039) },
    2212         { 0xefe1, UINT32_C(0x0007fe00) },
    2213     };
    2214 
    2215     BS3TRAPFRAME        TrapCtx;
    2216     BS3REGCTX           Ctx;
    2217     BS3REGCTX           CtxUdExpected;
    2218     BS3REGCTX           TmpCtx;
    2219     uint8_t             abBufLoad[40];          /* Test buffer w/ misalignment test space and some (cbIdtr) extra guard. */
    2220     uint8_t             abBufSave[32];          /* For saving the result after loading. */
    2221     uint8_t             abBufRestore[24];       /* For restoring sane value (same seg as abBufSave!). */
    2222     uint8_t             abExpectedFilled[32];   /* Same as pbExpected, except it's filled with bFiller2 instead of zeros. */
    2223     uint8_t BS3_FAR    *pbBufSave;              /* Correctly aligned pointer into abBufSave. */
    2224     uint8_t BS3_FAR    *pbBufRestore;           /* Correctly aligned pointer into abBufRestore. */
    2225     uint8_t const       cbIdtr        = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 2+8 : 2+4;
    2226     uint8_t const       cbBaseLoaded  = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 8
    2227                                       : BS3_MODE_IS_16BIT_CODE(bTestMode) == !(pWorker->fFlags & BS3CB2SIDTSGDT_F_OPSIZE)
    2228                                       ? 3 : 4;
    2229     bool const          f286          = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286;
    2230     uint8_t const       bTop16BitBase = f286 ? 0xff : 0x00;
    2231     uint8_t             bFiller1;               /* For filling abBufLoad.  */
    2232     uint8_t             bFiller2;               /* For filling abBufSave and expectations. */
    2233     int                 off;
    2234     uint8_t BS3_FAR    *pbTest;
    2235     unsigned            i;
    2236 
    2237     /* make sure they're allocated  */
    2238     Bs3MemZero(&Ctx, sizeof(Ctx));
    2239     Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected));
    2240     Bs3MemZero(&TmpCtx, sizeof(TmpCtx));
    2241     Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
    2242     Bs3MemZero(abBufSave, sizeof(abBufSave));
    2243     Bs3MemZero(abBufLoad, sizeof(abBufLoad));
    2244     Bs3MemZero(abBufRestore, sizeof(abBufRestore));
    2245 
    2246     /*
    2247      * Create a context, giving this routine some more stack space.
    2248      *  - Point the context at our LIDT [xBX] + SIDT [xDI] + LIDT [xSI] + UD2 combo.
    2249      *  - Point DS/SS:xBX at abBufLoad.
    2250      *  - Point ES:xDI at abBufSave.
    2251      *  - Point ES:xSI at abBufRestore.
    2252      */
    2253     Bs3RegCtxSaveEx(&Ctx, bTestMode, 256 /*cbExtraStack*/);
    2254     Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pWorker->fpfnWorker);
    2255     if (BS3_MODE_IS_16BIT_SYS(bTestMode))
    2256         g_uBs3TrapEipHint = Ctx.rip.u32;
    2257     Ctx.rflags.u16 &= ~X86_EFL_IF;
    2258     Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);
    2259 
    2260     pbBufSave = abBufSave;
    2261     if ((BS3_FP_OFF(pbBufSave) + 2) & 7)
    2262         pbBufSave += 8 - ((BS3_FP_OFF(pbBufSave) + 2) & 7);
    2263     Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.es, pbBufSave);
    2264 
    2265     pbBufRestore = abBufRestore;
    2266     if ((BS3_FP_OFF(pbBufRestore) + 2) & 7)
    2267         pbBufRestore += 8 - ((BS3_FP_OFF(pbBufRestore) + 2) & 7);
    2268     Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsi, &Ctx.es, pbBufRestore);
    2269     Bs3MemCpy(pbBufRestore, pbRestore, cbRestore);
    2270 
    2271     if (!BS3_MODE_IS_RM_OR_V86(bTestMode))
    2272         Bs3RegCtxConvertToRingX(&Ctx, bRing);
    2273 
    2274     /* For successful SIDT attempts, we'll stop at the UD2. */
    2275     Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx));
    2276     CtxUdExpected.rip.u += pWorker->cbInstr;
    2277 
    2278     /*
    2279      * Check that it works at all.
    2280      */
    2281     Bs3MemZero(abBufLoad, sizeof(abBufLoad));
    2282     Bs3MemCpy(abBufLoad, pbBufRestore, cbIdtr);
    2283     Bs3MemZero(abBufSave, sizeof(abBufSave));
    2284     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2285     if (bRing != 0)
    2286         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2287     else
    2288     {
    2289         bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2290         if (Bs3MemCmp(pbBufSave, pbExpected, cbIdtr * 2) != 0)
    2291             Bs3TestFailedF("Mismatch (%s, #1): expected %.*Rhxs, got %.*Rhxs\n",
    2292                            pWorker->pszDesc, cbIdtr*2, pbExpected, cbIdtr*2, pbBufSave);
    2293     }
    2294     g_usBs3TestStep++;
    2295 
    2296     /* Determine two filler bytes that doesn't appear in the previous result or our expectations. */
    2297     bFiller1 = ~0x55;
    2298     while (   Bs3MemChr(pbBufSave, bFiller1, cbIdtr) != NULL
    2299            || Bs3MemChr(pbRestore, bFiller1, cbRestore) != NULL
    2300            || bFiller1 == 0xff)
    2301         bFiller1++;
    2302     bFiller2 = 0x33;
    2303     while (   Bs3MemChr(pbBufSave, bFiller2, cbIdtr) != NULL
    2304            || Bs3MemChr(pbRestore, bFiller2, cbRestore) != NULL
    2305            || bFiller2 == 0xff
    2306            || bFiller2 == bFiller1)
    2307         bFiller2++;
    2308     Bs3MemSet(abExpectedFilled, bFiller2, sizeof(abExpectedFilled));
    2309     Bs3MemCpy(abExpectedFilled, pbExpected, cbIdtr);
    2310 
    2311     /* Again with a buffer filled with a byte not occuring in the previous result. */
    2312     Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
    2313     Bs3MemCpy(abBufLoad, pbBufRestore, cbIdtr);
    2314     Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2315     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2316     if (bRing != 0)
    2317         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2318     else
    2319     {
    2320         bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2321         if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2322             Bs3TestFailedF("Mismatch (%s, #2): expected %.*Rhxs, got %.*Rhxs\n",
    2323                            pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2324     }
    2325     g_usBs3TestStep++;
    2326 
    2327     /*
    2328      * Try loading a bunch of different limit+base value to check what happens,
    2329      * especially what happens wrt the top part of the base in 16-bit mode.
    2330      */
    2331     if (BS3_MODE_IS_64BIT_CODE(bTestMode))
    2332     {
    2333         for (i = 0; i < RT_ELEMENTS(s_aValues64); i++)
    2334         {
    2335             Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
    2336             Bs3MemCpy(&abBufLoad[0], &s_aValues64[i].cbLimit, 2);
    2337             Bs3MemCpy(&abBufLoad[2], &s_aValues64[i].u64Base, 8);
    2338             Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2339             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2340             if (bRing != 0 || s_aValues64[i].fGP)
    2341                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2342             else
    2343             {
    2344                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2345                 if (   Bs3MemCmp(&pbBufSave[0], &s_aValues64[i].cbLimit, 2) != 0
    2346                     || Bs3MemCmp(&pbBufSave[2], &s_aValues64[i].u64Base, 8) != 0
    2347                     || !ASMMemIsAllU8(&pbBufSave[10], cbIdtr, bFiller2))
    2348                     Bs3TestFailedF("Mismatch (%s, #2): expected %04RX16:%016RX64, fillers %#x %#x, got %.*Rhxs\n",
    2349                                    pWorker->pszDesc, s_aValues64[i].cbLimit, s_aValues64[i].u64Base,
    2350                                    bFiller1, bFiller2, cbIdtr*2, pbBufSave);
    2351             }
    2352             g_usBs3TestStep++;
    2353         }
    2354     }
    2355     else
    2356     {
    2357         for (i = 0; i < RT_ELEMENTS(s_aValues32); i++)
    2358         {
    2359             Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
    2360             Bs3MemCpy(&abBufLoad[0], &s_aValues32[i].cbLimit, 2);
    2361             Bs3MemCpy(&abBufLoad[2], &s_aValues32[i].u32Base, cbBaseLoaded);
    2362             Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2363             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2364             if (bRing != 0)
    2365                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2366             else
    2367             {
    2368                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2369                 if (   Bs3MemCmp(&pbBufSave[0], &s_aValues32[i].cbLimit, 2) != 0
    2370                     || Bs3MemCmp(&pbBufSave[2], &s_aValues32[i].u32Base, cbBaseLoaded) != 0
    2371                     || (   cbBaseLoaded != 4
    2372                         && pbBufSave[2+3] != bTop16BitBase)
    2373                     || !ASMMemIsAllU8(&pbBufSave[8], cbIdtr, bFiller2))
    2374                     Bs3TestFailedF("Mismatch (%s,#3): loaded %04RX16:%08RX32, fillers %#x %#x%s, got %.*Rhxs\n",
    2375                                    pWorker->pszDesc, s_aValues32[i].cbLimit, s_aValues32[i].u32Base, bFiller1, bFiller2,
    2376                                    f286 ? ", 286" : "", cbIdtr*2, pbBufSave);
    2377             }
    2378             g_usBs3TestStep++;
    2379         }
    2380     }
    2381 
    2382     /*
    2383      * Slide the buffer along 8 bytes to cover misalignment.
    2384      */
    2385     for (off = 0; off < 8; off++)
    2386     {
    2387         Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &abBufLoad[off]);
    2388         CtxUdExpected.rbx.u = Ctx.rbx.u;
    2389 
    2390         Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
    2391         Bs3MemCpy(&abBufLoad[off], pbBufRestore, cbIdtr);
    2392         Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2393         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2394         if (bRing != 0)
    2395             bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2396         else
    2397         {
    2398             bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2399             if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2400                 Bs3TestFailedF("Mismatch (%s, #4): expected %.*Rhxs, got %.*Rhxs\n",
    2401                                pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2402         }
    2403         g_usBs3TestStep++;
    2404     }
    2405     Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);
    2406     CtxUdExpected.rbx.u = Ctx.rbx.u;
    2407 
    2408     /*
    2409      * Play with the selector limit if the target mode supports limit checking
    2410      * We use BS3_SEL_TEST_PAGE_00 for this
    2411      */
    2412     if (   !BS3_MODE_IS_RM_OR_V86(bTestMode)
    2413         && !BS3_MODE_IS_64BIT_CODE(bTestMode))
    2414     {
    2415         uint16_t cbLimit;
    2416         uint32_t uFlatBuf = Bs3SelPtrToFlat(abBufLoad);
    2417         Bs3GdteTestPage00 = Bs3Gdte_DATA16;
    2418         Bs3GdteTestPage00.Gen.u2Dpl       = bRing;
    2419         Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatBuf;
    2420         Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatBuf >> 16);
    2421         Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatBuf >> 24);
    2422 
    2423         if (pWorker->fSs)
    2424             CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;
    2425         else
    2426             CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
    2427 
    2428         /* Expand up (normal). */
    2429         for (off = 0; off < 8; off++)
    2430         {
    2431             CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    2432             for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)
    2433             {
    2434                 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    2435 
    2436                 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
    2437                 Bs3MemCpy(&abBufLoad[off], pbBufRestore, cbIdtr);
    2438                 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2439                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2440                 if (bRing != 0)
    2441                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2442                 else if (off + cbIdtr <= cbLimit + 1)
    2443                 {
    2444                     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2445                     if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2446                         Bs3TestFailedF("Mismatch (%s, #5): expected %.*Rhxs, got %.*Rhxs\n",
    2447                                        pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2448                 }
    2449                 else if (pWorker->fSs)
    2450                     bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    2451                 else
    2452                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2453                 g_usBs3TestStep++;
    2454 
    2455                 /* Again with zero limit and messed up base (should trigger tripple fault if partially loaded). */
    2456                 abBufLoad[off] = abBufLoad[off + 1] = 0;
    2457                 abBufLoad[off + 2] |= 1;
    2458                 abBufLoad[off + cbIdtr - 2] ^= 0x5a;
    2459                 abBufLoad[off + cbIdtr - 1] ^= 0xa5;
    2460                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2461                 if (bRing != 0)
    2462                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2463                 else if (off + cbIdtr <= cbLimit + 1)
    2464                     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2465                 else if (pWorker->fSs)
    2466                     bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    2467                 else
    2468                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2469             }
    2470         }
    2471 
    2472         /* Expand down (weird).  Inverted valid area compared to expand up,
    2473            so a limit of zero give us a valid range for 0001..0ffffh (instead of
    2474            a segment with one valid byte at 0000h).  Whereas a limit of 0fffeh
    2475            means one valid byte at 0ffffh, and a limit of 0ffffh means none
    2476            (because in a normal expand up the 0ffffh means all 64KB are
    2477            accessible). */
    2478         Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;
    2479         for (off = 0; off < 8; off++)
    2480         {
    2481             CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    2482             for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)
    2483             {
    2484                 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    2485 
    2486                 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));
    2487                 Bs3MemCpy(&abBufLoad[off], pbBufRestore, cbIdtr);
    2488                 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2489                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2490                 if (bRing != 0)
    2491                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2492                 else if (off > cbLimit)
    2493                 {
    2494                     bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2495                     if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2496                         Bs3TestFailedF("Mismatch (%s, #6): expected %.*Rhxs, got %.*Rhxs\n",
    2497                                        pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2498                 }
    2499                 else if (pWorker->fSs)
    2500                     bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    2501                 else
    2502                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2503                g_usBs3TestStep++;
    2504 
    2505                /* Again with zero limit and messed up base (should trigger triple fault if partially loaded). */
    2506                abBufLoad[off] = abBufLoad[off + 1] = 0;
    2507                abBufLoad[off + 2] |= 3;
    2508                abBufLoad[off + cbIdtr - 2] ^= 0x55;
    2509                abBufLoad[off + cbIdtr - 1] ^= 0xaa;
    2510                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2511                if (bRing != 0)
    2512                    bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2513                else if (off > cbLimit)
    2514                    bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2515                else if (pWorker->fSs)
    2516                    bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    2517                else
    2518                    bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2519             }
    2520         }
    2521 
    2522         Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);
    2523         CtxUdExpected.rbx.u = Ctx.rbx.u;
    2524         CtxUdExpected.ss = Ctx.ss;
    2525         CtxUdExpected.ds = Ctx.ds;
    2526     }
    2527 
    2528     /*
    2529      * Play with the paging.
    2530      */
    2531     if (   BS3_MODE_IS_PAGED(bTestMode)
    2532         && (!pWorker->fSs || bRing == 3) /* SS.DPL == CPL, we'll get some tiled ring-3 selector here.  */
    2533         && (pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED)) != NULL)
    2534     {
    2535         RTCCUINTXREG uFlatTest = Bs3SelPtrToFlat(pbTest);
    2536 
    2537         /*
    2538          * Slide the load buffer towards the trailing guard page.
    2539          */
    2540         Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[X86_PAGE_SIZE]);
    2541         CtxUdExpected.ss = Ctx.ss;
    2542         CtxUdExpected.ds = Ctx.ds;
    2543         for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
    2544         {
    2545             Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller1, cbIdtr*2);
    2546             if (off < X86_PAGE_SIZE)
    2547                 Bs3MemCpy(&pbTest[off], pbBufRestore, RT_MIN(X86_PAGE_SIZE - off, cbIdtr));
    2548             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);
    2549             Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2550             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2551             if (bRing != 0)
    2552                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2553             else if (off + cbIdtr <= X86_PAGE_SIZE)
    2554             {
    2555                 CtxUdExpected.rbx = Ctx.rbx;
    2556                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2557                 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr*2) != 0)
    2558                     Bs3TestFailedF("Mismatch (%s, #7): expected %.*Rhxs, got %.*Rhxs\n",
    2559                                    pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2560             }
    2561             else
    2562                 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    2563             g_usBs3TestStep++;
    2564 
    2565             /* Again with zero limit and maybe messed up base as well (triple fault if buggy).
    2566                The 386DX-40 here triple faults (or something) with off == 0xffe, nothing else. */
    2567             if (   off < X86_PAGE_SIZE && off + cbIdtr > X86_PAGE_SIZE
    2568                 && (   off != X86_PAGE_SIZE - 2
    2569                     || (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) != BS3CPU_80386)
    2570                 )
    2571             {
    2572                 pbTest[off] = 0;
    2573                 if (off + 1 < X86_PAGE_SIZE)
    2574                     pbTest[off + 1] = 0;
    2575                 if (off + 2 < X86_PAGE_SIZE)
    2576                     pbTest[off + 2] |= 7;
    2577                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2578                 if (bRing != 0)
    2579                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2580                 else
    2581                     bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    2582                 g_usBs3TestStep++;
    2583             }
    2584         }
    2585 
    2586         /*
    2587          * Now, do it the other way around. It should look normal now since writing
    2588          * the limit will #PF first and nothing should be written.
    2589          */
    2590         for (off = cbIdtr + 4; off >= -cbIdtr - 4; off--)
    2591         {
    2592             Bs3MemSet(pbTest, bFiller1, 48);
    2593             if (off >= 0)
    2594                 Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);
    2595             else if (off + cbIdtr > 0)
    2596                 Bs3MemCpy(pbTest, &pbBufRestore[-off], cbIdtr + off);
    2597             Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);
    2598             Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2599             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2600             if (bRing != 0)
    2601                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2602             else if (off >= 0)
    2603             {
    2604                 CtxUdExpected.rbx = Ctx.rbx;
    2605                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2606                 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr*2) != 0)
    2607                     Bs3TestFailedF("Mismatch (%s, #8): expected %.*Rhxs, got %.*Rhxs\n",
    2608                                    pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2609             }
    2610             else
    2611                 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + off);
    2612             g_usBs3TestStep++;
    2613 
    2614             /* Again with messed up base as well (triple fault if buggy). */
    2615             if (off < 0 && off > -cbIdtr)
    2616             {
    2617                 if (off + 2 >= 0)
    2618                     pbTest[off + 2] |= 15;
    2619                 pbTest[off + cbIdtr - 1] ^= 0xaa;
    2620                 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2621                 if (bRing != 0)
    2622                     bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2623                 else
    2624                     bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + off);
    2625                 g_usBs3TestStep++;
    2626             }
    2627         }
    2628 
    2629         /*
    2630          * Combine paging and segment limit and check ordering.
    2631          * This is kind of interesting here since it the instruction seems to
    2632          * actually be doing two separate read, just like it's S[IG]DT counterpart.
    2633          *
    2634          * Note! My 486DX4 does a DWORD limit read when the operand size is 32-bit,
    2635          *       that's what f486Weirdness deals with.
    2636          */
    2637         if (   !BS3_MODE_IS_RM_OR_V86(bTestMode)
    2638             && !BS3_MODE_IS_64BIT_CODE(bTestMode))
    2639         {
    2640             bool const f486Weirdness = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80486
    2641                                     && BS3_MODE_IS_32BIT_CODE(bTestMode) == !(pWorker->fFlags & BS3CB2SIDTSGDT_F_OPSIZE);
    2642             uint16_t   cbLimit;
    2643 
    2644             Bs3GdteTestPage00 = Bs3Gdte_DATA16;
    2645             Bs3GdteTestPage00.Gen.u2Dpl       = bRing;
    2646             Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatTest;
    2647             Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);
    2648             Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);
    2649 
    2650             if (pWorker->fSs)
    2651                 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;
    2652             else
    2653                 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
    2654 
    2655             /* Expand up (normal), approaching tail guard page. */
    2656             for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
    2657             {
    2658                 CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    2659                 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)
    2660                 {
    2661                     Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    2662                     Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller1, cbIdtr * 2);
    2663                     if (off < X86_PAGE_SIZE)
    2664                         Bs3MemCpy(&pbTest[off], pbBufRestore, RT_MIN(cbIdtr, X86_PAGE_SIZE - off));
    2665                     Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2666                     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2667                     if (bRing != 0)
    2668                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2669                     else if (off + cbIdtr <= cbLimit + 1)
    2670                     {
    2671                         /* No #GP, but maybe #PF. */
    2672                         if (off + cbIdtr <= X86_PAGE_SIZE)
    2673                         {
    2674                             bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2675                             if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2676                                 Bs3TestFailedF("Mismatch (%s, #9): expected %.*Rhxs, got %.*Rhxs\n",
    2677                                                pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2678                         }
    2679                         else
    2680                             bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    2681                     }
    2682                     /* No #GP/#SS on limit, but instead #PF? */
    2683                     else if (  !f486Weirdness
    2684                              ? off     < cbLimit && off >= 0xfff
    2685                              : off + 2 < cbLimit && off >= 0xffd)
    2686                         bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));
    2687                     /* #GP/#SS on limit or base. */
    2688                     else if (pWorker->fSs)
    2689                         bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    2690                     else
    2691                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2692 
    2693                     g_usBs3TestStep++;
    2694 
    2695                     /* Set DS to 0 and check that we get #GP(0). */
    2696                     if (!pWorker->fSs)
    2697                     {
    2698                         Ctx.ds = 0;
    2699                         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2700                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2701                         Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;
    2702                         g_usBs3TestStep++;
    2703                     }
    2704                 }
    2705             }
    2706 
    2707             /* Expand down. */
    2708             pbTest    -= X86_PAGE_SIZE; /* Note! we're backing up a page to simplify things */
    2709             uFlatTest -= X86_PAGE_SIZE;
    2710 
    2711             Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;
    2712             Bs3GdteTestPage00.Gen.u16BaseLow  = (uint16_t)uFlatTest;
    2713             Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);
    2714             Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);
    2715 
    2716             for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)
    2717             {
    2718                 CtxUdExpected.rbx.u = Ctx.rbx.u = off;
    2719                 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)
    2720                 {
    2721                     Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;
    2722                     Bs3MemSet(&pbTest[X86_PAGE_SIZE], bFiller1, cbIdtr * 2);
    2723                     if (off >= X86_PAGE_SIZE)
    2724                         Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);
    2725                     else if (off > X86_PAGE_SIZE - cbIdtr)
    2726                         Bs3MemCpy(&pbTest[X86_PAGE_SIZE], &pbBufRestore[X86_PAGE_SIZE - off], cbIdtr - (X86_PAGE_SIZE - off));
    2727                     Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2728                     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2729                     if (bRing != 0)
    2730                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2731                     else if (cbLimit < off && off >= X86_PAGE_SIZE)
    2732                     {
    2733                         bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2734                         if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2735                             Bs3TestFailedF("Mismatch (%s, #10): expected %.*Rhxs, got %.*Rhxs\n",
    2736                                            pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2737                     }
    2738                     else if (cbLimit < off && off < X86_PAGE_SIZE)
    2739                         bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + off);
    2740                     else if (pWorker->fSs)
    2741                         bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);
    2742                     else
    2743                         bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2744                     g_usBs3TestStep++;
    2745                 }
    2746             }
    2747 
    2748             pbTest    += X86_PAGE_SIZE;
    2749             uFlatTest += X86_PAGE_SIZE;
    2750         }
    2751 
    2752         Bs3MemGuardedTestPageFree(pbTest);
    2753     }
    2754 
    2755     /*
    2756      * Check non-canonical 64-bit space.
    2757      */
    2758     if (   BS3_MODE_IS_64BIT_CODE(bTestMode)
    2759         && (pbTest = (uint8_t BS3_FAR *)Bs3PagingSetupCanonicalTraps()) != NULL)
    2760     {
    2761         /* Make our references relative to the gap. */
    2762         pbTest += g_cbBs3PagingOneCanonicalTrap;
    2763 
    2764         /* Hit it from below. */
    2765         for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)
    2766         {
    2767             Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0x0000800000000000) + off;
    2768             Bs3MemSet(&pbTest[-64], bFiller1, 64*2);
    2769             Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);
    2770             Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2771             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2772             if (off + cbIdtr > 0 || bRing != 0)
    2773                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2774             else
    2775             {
    2776                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2777                 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2778                     Bs3TestFailedF("Mismatch (%s, #11): expected %.*Rhxs, got %.*Rhxs\n",
    2779                                    pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2780             }
    2781         }
    2782 
    2783         /* Hit it from above. */
    2784         for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)
    2785         {
    2786             Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0xffff800000000000) + off;
    2787             Bs3MemSet(&pbTest[-64], bFiller1, 64*2);
    2788             Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);
    2789             Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));
    2790             Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2791             if (off < 0 || bRing != 0)
    2792                 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);
    2793             else
    2794             {
    2795                 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);
    2796                 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)
    2797                     Bs3TestFailedF("Mismatch (%s, #19): expected %.*Rhxs, got %.*Rhxs\n",
    2798                                    pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);
    2799             }
    2800         }
    2801 
    2802     }
    2803 }
    2804 
    2805 
    2806 # define bs3CpuBasic2_lidt_lgdt_Common BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_Common)
    2807 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
    2808                                                   void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected)
    2809 {
    2810     unsigned idx;
    2811     unsigned bRing;
    2812     unsigned iStep = 0;
    2813 
    2814     /* Note! We skip the SS checks for ring-0 since we badly mess up SS in the
    2815              test and don't want to bother with double faults. */
    2816     for (bRing = BS3_MODE_IS_V86(bTestMode) ? 3 : 0; bRing <= 3; bRing++)
    2817     {
    2818         for (idx = 0; idx < cWorkers; idx++)
    2819             if (    (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK))
    2820                 && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ )
    2821                 && (   !(paWorkers[idx].fFlags & BS3CB2SIDTSGDT_F_386PLUS)
    2822                     || (   bTestMode > BS3_MODE_PE16
    2823                         || (   bTestMode == BS3_MODE_PE16
    2824                             && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)) ) )
    2825             {
    2826                 //Bs3TestPrintf("idx=%-2d fpfnWorker=%p fSs=%d cbInstr=%d\n",
    2827                 //              idx, paWorkers[idx].fpfnWorker, paWorkers[idx].fSs, paWorkers[idx].cbInstr);
    2828                 g_usBs3TestStep = iStep;
    2829                 bs3CpuBasic2_lidt_lgdt_One(&paWorkers[idx], bTestMode, bRing, pvRestore, cbRestore, pbExpected);
    2830                 iStep += 1000;
    2831             }
    2832         if (BS3_MODE_IS_RM_SYS(bTestMode))
    2833             break;
    2834     }
    2835 }
    2836 
    2837 
    2838 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(uint8_t bMode)
    2839 {
    2840     union
    2841     {
    2842         RTIDTR  Idtr;
    2843         uint8_t ab[32]; /* At least cbIdtr*2! */
    2844     } Expected;
    2845 
    2846     g_pszTestMode = Bs3GetModeName(bMode);
    2847     g_bTestMode   = bMode;
    2848     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
    2849 
    2850     /*
    2851      * Pass to common worker which is only compiled once per mode.
    2852      */
    2853     Bs3MemZero(&Expected, sizeof(Expected));
    2854     ASMGetIDTR(&Expected.Idtr);
    2855 
    2856     if (BS3_MODE_IS_RM_SYS(bMode))
    2857         bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
    2858                                       &Bs3Lidt_Ivt, sizeof(Bs3Lidt_Ivt), Expected.ab);
    2859     else if (BS3_MODE_IS_16BIT_SYS(bMode))
    2860         bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
    2861                                       &Bs3Lidt_Idt16, sizeof(Bs3Lidt_Idt16), Expected.ab);
    2862     else if (BS3_MODE_IS_32BIT_SYS(bMode))
    2863         bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
    2864                                       &Bs3Lidt_Idt32, sizeof(Bs3Lidt_Idt32), Expected.ab);
    2865     else
    2866         bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
    2867                                       &Bs3Lidt_Idt64, sizeof(Bs3Lidt_Idt64), Expected.ab);
    2868 
    2869     /*
    2870      * Re-initialize the IDT.
    2871      */
    2872     Bs3TrapReInit();
    2873     return 0;
    2874 }
    2875 
    2876 
    2877 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)
    2878 {
    2879     union
    2880     {
    2881         RTGDTR  Gdtr;
    2882         uint8_t ab[32]; /* At least cbIdtr*2! */
    2883     } Expected;
    2884 
    2885     g_pszTestMode = Bs3GetModeName(bMode);
    2886     g_bTestMode   = bMode;
    2887     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
    2888 
    2889     /*
    2890      * Pass to common worker which is only compiled once per mode.
    2891      */
    2892     if (BS3_MODE_IS_RM_SYS(bMode))
    2893         ASMSetGDTR((PRTGDTR)&Bs3LgdtDef_Gdt);
    2894     Bs3MemZero(&Expected, sizeof(Expected));
    2895     ASMGetGDTR(&Expected.Gdtr);
    2896 
    2897     bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLgdtWorkers, RT_ELEMENTS(g_aLgdtWorkers),
    2898                                   &Bs3LgdtDef_Gdt, sizeof(Bs3LgdtDef_Gdt), Expected.ab);
    2899 
    2900     /*
    2901      * Re-initialize the IDT.
    2902      */
    2903     Bs3TrapReInit();
    2904     return 0;
    2905 }
    2906 #endif /* TMPL_BITS == 16 */
    2907 
    2908 
    29091305# if ARCH_BITS != 64
    29101306
     
    31521548}
    31531549
    3154 
    3155 # if 0
    3156 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
    3157 {
    3158     BS3_ASSERT(bMode == TMPL_MODE);
    3159     return BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(bMode);
    3160 }
    3161 
    3162 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
    3163 {
    3164     BS3_ASSERT(bMode == TMPL_MODE);
    3165     return BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(bMode);
    3166 }
    3167 
    3168 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode)
    3169 {
    3170     BS3_ASSERT(bMode == TMPL_MODE);
    3171     return BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(bMode);
    3172 }
    3173 
    3174 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)
    3175 {
    3176     BS3_ASSERT(bMode == TMPL_MODE);
    3177     return BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(bMode);
    3178 }
    3179 # endif
    3180 
    31811550#endif /* BS3_INSTANTIATING_MODE */
    31821551
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-x0.c

    r60749 r60750  
    11/* $Id$ */
    22/** @file
    3  * BS3Kit - bs3-cpu-basic-2, C code template.
     3 * BS3Kit - bs3-cpu-basic-2, C test driver code (16-bit).
    44 */
    55
     
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
     31#define BS3_USE_X0_TEXT_SEG
     32#include <bs3kit.h>
    3133#include <iprt/asm.h>
    3234#include <iprt/asm-amd64-x86.h>
     
    4547
    4648
    47 #ifdef BS3_INSTANTIATING_CMN
    4849/** Indicating that we've got operand size prefix and that it matters. */
    49 # define BS3CB2SIDTSGDT_F_OPSIZE    UINT8_C(0x01)
     50#define BS3CB2SIDTSGDT_F_OPSIZE    UINT8_C(0x01)
    5051/** Worker requires 386 or later. */
    51 # define BS3CB2SIDTSGDT_F_386PLUS   UINT8_C(0x02)
    52 #endif
    53 
    54 #ifdef BS3_INSTANTIATING_MODE
    55 # undef MyBs3Idt
    56 # undef MY_SYS_SEL_R0_CS
    57 # undef MY_SYS_SEL_R0_CS_CNF
    58 # undef MY_SYS_SEL_R0_DS
    59 # undef MY_SYS_SEL_R0_SS
    60 # if BS3_MODE_IS_16BIT_SYS(TMPL_MODE)
    61 #  define MyBs3Idt              Bs3Idt16
    62 #  define MY_SYS_SEL_R0_CS      BS3_SEL_R0_CS16
    63 #  define MY_SYS_SEL_R0_CS_CNF  BS3_SEL_R0_CS16_CNF
    64 #  define MY_SYS_SEL_R0_DS      BS3_SEL_R0_DS16
    65 #  define MY_SYS_SEL_R0_SS      BS3_SEL_R0_SS16
    66 # elif BS3_MODE_IS_32BIT_SYS(TMPL_MODE)
    67 #  define MyBs3Idt              Bs3Idt32
    68 #  define MY_SYS_SEL_R0_CS      BS3_SEL_R0_CS32
    69 #  define MY_SYS_SEL_R0_CS_CNF  BS3_SEL_R0_CS32_CNF
    70 #  define MY_SYS_SEL_R0_DS      BS3_SEL_R0_DS32
    71 #  define MY_SYS_SEL_R0_SS      BS3_SEL_R0_SS32
    72 # elif BS3_MODE_IS_64BIT_SYS(TMPL_MODE)
    73 #  define MyBs3Idt              Bs3Idt64
    74 #  define MY_SYS_SEL_R0_CS      BS3_SEL_R0_CS64
    75 #  define MY_SYS_SEL_R0_CS_CNF  BS3_SEL_R0_CS64_CNF
    76 #  define MY_SYS_SEL_R0_DS      BS3_SEL_R0_DS64
    77 #  define MY_SYS_SEL_R0_SS      BS3_SEL_R0_DS64
    78 # else
    79 #  error "TMPL_MODE"
    80 # endif
    81 #endif
     52#define BS3CB2SIDTSGDT_F_386PLUS   UINT8_C(0x02)
    8253
    8354
     
    8556*   Structures and Typedefs                                                                                                      *
    8657*********************************************************************************************************************************/
    87 #ifdef BS3_INSTANTIATING_CMN
    8858typedef struct BS3CB2INVLDESCTYPE
    8959{
     
    10171    uint8_t     fFlags;
    10272} BS3CB2SIDTSGDT;
    103 #endif
    10473
    10574
     
    10776*   External Symbols                                                                                                             *
    10877*********************************************************************************************************************************/
    109 #ifdef BS3_INSTANTIATING_CMN
    11078extern FNBS3FAR     bs3CpuBasic2_Int80;
    11179extern FNBS3FAR     bs3CpuBasic2_Int81;
     
    11381extern FNBS3FAR     bs3CpuBasic2_Int83;
    11482extern FNBS3FAR     bs3CpuBasic2_ud2;
    115 # define            g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr)
     83#define             g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr)
    11684extern uint32_t     g_bs3CpuBasic2_ud2_FlatAddr;
    11785
     
    169137extern FNBS3FAR     bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64;
    170138
    171 #endif
    172139
    173140
     
    175142*   Global Variables                                                                                                             *
    176143*********************************************************************************************************************************/
    177 #ifdef BS3_INSTANTIATING_CMN
    178 # define                    g_pszTestMode   BS3_CMN_NM(g_pszTestMode)
     144#define                     g_pszTestMode   BS3_CMN_NM(g_pszTestMode)
    179145static const char BS3_FAR  *g_pszTestMode = (const char *)1;
    180 # define                    g_bTestMode     BS3_CMN_NM(g_bTestMode)
     146#define                     g_bTestMode     BS3_CMN_NM(g_bTestMode)
    181147static uint8_t              g_bTestMode = 1;
    182 # define                    g_f16BitSys     BS3_CMN_NM(g_f16BitSys)
     148#define                     g_f16BitSys     BS3_CMN_NM(g_f16BitSys)
    183149static bool                 g_f16BitSys = 1;
    184150
     
    187153static BS3CB2SIDTSGDT const g_aSidtWorkers[] =
    188154{
    189     { "", bs3CpuBasic2_sidt_bx_ud2_c16,             3, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    190     { "", bs3CpuBasic2_sidt_ss_bx_ud2_c16,          4, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    191     { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c16,      4, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    192     { "", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16,   5, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    193     { "", bs3CpuBasic2_sidt_bx_ud2_c32,             3, false,   BS3_MODE_CODE_32, 0 },
    194     { "", bs3CpuBasic2_sidt_ss_bx_ud2_c32,          4, true,    BS3_MODE_CODE_32, 0 },
    195     { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c32,      4, false,   BS3_MODE_CODE_32, 0 },
    196     { "", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32,   5, true,    BS3_MODE_CODE_32, 0 },
    197     { "", bs3CpuBasic2_sidt_bx_ud2_c64,             3, false,   BS3_MODE_CODE_64, 0 },
    198     { "", bs3CpuBasic2_sidt_rexw_bx_ud2_c64,        4, false,   BS3_MODE_CODE_64, 0 },
    199     { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c64,      4, false,   BS3_MODE_CODE_64, 0 },
    200     { "", bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64, 0 },
     155    { "sidt [bx]",              bs3CpuBasic2_sidt_bx_ud2_c16,             3, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     156    { "sidt [ss:bx]",          bs3CpuBasic2_sidt_ss_bx_ud2_c16,          4, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     157    { "o32 sidt [bx]",          bs3CpuBasic2_sidt_opsize_bx_ud2_c16,      4, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
     158    { "o32 sidt [ss:bx]",      bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16,   5, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
     159    { "sidt [ebx]",            bs3CpuBasic2_sidt_bx_ud2_c32,             3, false,   BS3_MODE_CODE_32, 0 },
     160    { "sidt [ss:ebx]",          bs3CpuBasic2_sidt_ss_bx_ud2_c32,          4, true,    BS3_MODE_CODE_32, 0 },
     161    { "o16 sidt [ebx]",        bs3CpuBasic2_sidt_opsize_bx_ud2_c32,      4, false,   BS3_MODE_CODE_32, 0 },
     162    { "o16 sidt [ss:ebx]",      bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32,   5, true,    BS3_MODE_CODE_32, 0 },
     163    { "sidt [rbx]",            bs3CpuBasic2_sidt_bx_ud2_c64,             3, false,   BS3_MODE_CODE_64, 0 },
     164    { "o64 sidt [rbx]",        bs3CpuBasic2_sidt_rexw_bx_ud2_c64,        4, false,   BS3_MODE_CODE_64, 0 },
     165    { "o32 sidt [rbx]",        bs3CpuBasic2_sidt_opsize_bx_ud2_c64,      4, false,   BS3_MODE_CODE_64, 0 },
     166    { "o32 o64 sidt [rbx]",    bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64, 0 },
    201167};
    202168
     
    204170static BS3CB2SIDTSGDT const g_aSgdtWorkers[] =
    205171{
    206     { "", bs3CpuBasic2_sgdt_bx_ud2_c16,             3, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    207     { "", bs3CpuBasic2_sgdt_ss_bx_ud2_c16,          4, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
    208     { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c16,      4, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    209     { "", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16,   5, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
    210     { "", bs3CpuBasic2_sgdt_bx_ud2_c32,             3, false,   BS3_MODE_CODE_32, 0 },
    211     { "", bs3CpuBasic2_sgdt_ss_bx_ud2_c32,          4, true,    BS3_MODE_CODE_32, 0 },
    212     { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c32,      4, false,   BS3_MODE_CODE_32, 0 },
    213     { "", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32,   5, true,    BS3_MODE_CODE_32, 0 },
    214     { "", bs3CpuBasic2_sgdt_bx_ud2_c64,             3, false,   BS3_MODE_CODE_64, 0 },
    215     { "", bs3CpuBasic2_sgdt_rexw_bx_ud2_c64,        4, false,   BS3_MODE_CODE_64, 0 },
    216     { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c64,      4, false,   BS3_MODE_CODE_64, 0 },
    217     { "", bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64, 0 },
     172    { "sgdt [bx]",              bs3CpuBasic2_sgdt_bx_ud2_c16,             3, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     173    { "sgdt [ss:bx]",          bs3CpuBasic2_sgdt_ss_bx_ud2_c16,          4, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },
     174    { "o32 sgdt [bx]",          bs3CpuBasic2_sgdt_opsize_bx_ud2_c16,      4, false,   BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
     175    { "o32 sgdt [ss:bx]",      bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16,   5, true,    BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },
     176    { "sgdt [ebx]",            bs3CpuBasic2_sgdt_bx_ud2_c32,             3, false,   BS3_MODE_CODE_32, 0 },
     177    { "sgdt [ss:ebx]",          bs3CpuBasic2_sgdt_ss_bx_ud2_c32,          4, true,    BS3_MODE_CODE_32, 0 },
     178    { "o16 sgdt [ebx]",        bs3CpuBasic2_sgdt_opsize_bx_ud2_c32,      4, false,   BS3_MODE_CODE_32, 0 },
     179    { "o16 sgdt [ss:ebx]",      bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32,   5, true,    BS3_MODE_CODE_32, 0 },
     180    { "sgdt [rbx]",            bs3CpuBasic2_sgdt_bx_ud2_c64,             3, false,   BS3_MODE_CODE_64, 0 },
     181    { "o64 sgdt [rbx]",        bs3CpuBasic2_sgdt_rexw_bx_ud2_c64,        4, false,   BS3_MODE_CODE_64, 0 },
     182    { "o32 sgdt [rbx]",        bs3CpuBasic2_sgdt_opsize_bx_ud2_c64,      4, false,   BS3_MODE_CODE_64, 0 },
     183    { "o32 o64 sgdt [rbx]",    bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false,   BS3_MODE_CODE_64, 0 },
    218184};
    219185
     
    255221
    256222
     223#if 0
    257224/** Table containing invalid CS selector types. */
    258225static const BS3CB2INVLDESCTYPE g_aInvalidCsTypes[] =
     
    312279    {   15,                         0 },
    313280};
    314 
    315 #endif /* BS3_INSTANTIATING_CMN - global */
    316 
    317 #ifdef BS3_INSTANTIATING_CMN
     281#endif
     282
     283
    318284
    319285/**
     
    321287 * and g_pszTestMode.
    322288 */
    323 # define bs3CpuBasic2_FailedF BS3_CMN_NM(bs3CpuBasic2_FailedF)
    324 BS3_DECL_NEAR(void) bs3CpuBasic2_FailedF(const char *pszFormat, ...)
     289static void bs3CpuBasic2_FailedF(const char *pszFormat, ...)
    325290{
    326291    va_list va;
     
    335300
    336301
     302#if 0
    337303/**
    338304 * Compares trap stuff.
    339305 */
    340 # define bs3CpuBasic2_CompareIntCtx1 BS3_CMN_NM(bs3CpuBasic2_CompareIntCtx1)
    341 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareIntCtx1(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint8_t bXcpt)
     306static void bs3CpuBasic2_CompareIntCtx1(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint8_t bXcpt)
    342307{
    343308    uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
     
    355320    }
    356321}
    357 
    358 
     322#endif
     323
     324
     325#if 0
    359326/**
    360327 * Compares trap stuff.
    361328 */
    362 # define bs3CpuBasic2_CompareTrapCtx2 BS3_CMN_NM(bs3CpuBasic2_CompareTrapCtx2)
    363 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareTrapCtx2(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t cbIpAdjust,
    364                                                  uint8_t bXcpt, uint16_t uHandlerCs)
     329static void bs3CpuBasic2_CompareTrapCtx2(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t cbIpAdjust,
     330                                         uint8_t bXcpt, uint16_t uHandlerCs)
    365331{
    366332    uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
     
    379345    }
    380346}
     347#endif
    381348
    382349/**
    383350 * Compares a CPU trap.
    384351 */
    385 # define bs3CpuBasic2_CompareCpuTrapCtx BS3_CMN_NM(bs3CpuBasic2_CompareCpuTrapCtx)
    386 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareCpuTrapCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd,
    387                                                    uint8_t bXcpt, bool f486ResumeFlagHint)
     352static void bs3CpuBasic2_CompareCpuTrapCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd,
     353                                           uint8_t bXcpt, bool f486ResumeFlagHint)
    388354{
    389355    uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
     
    419385 * Compares \#GP trap.
    420386 */
    421 # define bs3CpuBasic2_CompareGpCtx BS3_CMN_NM(bs3CpuBasic2_CompareGpCtx)
    422 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareGpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd)
     387static void bs3CpuBasic2_CompareGpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd)
    423388{
    424389    bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_GP, true /*f486ResumeFlagHint*/);
    425390}
    426391
     392#if 0
    427393/**
    428394 * Compares \#NP trap.
    429395 */
    430 # define bs3CpuBasic2_CompareNpCtx BS3_CMN_NM(bs3CpuBasic2_CompareNpCtx)
    431 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareNpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd)
     396static void bs3CpuBasic2_CompareNpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd)
    432397{
    433398    bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_NP, true /*f486ResumeFlagHint*/);
    434399}
     400#endif
    435401
    436402/**
    437403 * Compares \#SS trap.
    438404 */
    439 # define bs3CpuBasic2_CompareSsCtx BS3_CMN_NM(bs3CpuBasic2_CompareSsCtx)
    440 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareSsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd, bool f486ResumeFlagHint)
     405static void bs3CpuBasic2_CompareSsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd, bool f486ResumeFlagHint)
    441406{
    442407    bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_SS, f486ResumeFlagHint);
    443408}
    444409
     410#if 0
    445411/**
    446412 * Compares \#TS trap.
    447413 */
    448 # define bs3CpuBasic2_CompareTsCtx BS3_CMN_NM(bs3CpuBasic2_CompareTsCtx)
    449 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareTsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd)
     414static void bs3CpuBasic2_CompareTsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd)
    450415{
    451416    bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_TS, false /*f486ResumeFlagHint*/);
    452417}
     418#endif
    453419
    454420/**
    455421 * Compares \#PF trap.
    456422 */
    457 # define bs3CpuBasic2_ComparePfCtx BS3_CMN_NM(bs3CpuBasic2_ComparePfCtx)
    458 BS3_DECL_NEAR(void) bs3CpuBasic2_ComparePfCtx(PCBS3TRAPFRAME pTrapCtx, PBS3REGCTX pStartCtx, uint16_t uErrCd, uint64_t uCr2Expected)
     423static void bs3CpuBasic2_ComparePfCtx(PCBS3TRAPFRAME pTrapCtx, PBS3REGCTX pStartCtx, uint16_t uErrCd, uint64_t uCr2Expected)
    459424{
    460425    uint64_t const uCr2Saved     = pStartCtx->cr2.u;
     
    467432 * Compares \#UD trap.
    468433 */
    469 # define bs3CpuBasic2_CompareUdCtx BS3_CMN_NM(bs3CpuBasic2_CompareUdCtx)
    470 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareUdCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx)
     434static void bs3CpuBasic2_CompareUdCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx)
    471435{
    472436    bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, 0 /*no error code*/, X86_XCPT_UD, true /*f486ResumeFlagHint*/);
     
    474438
    475439
    476 # define bs3CpuBasic2_RaiseXcpt1Common BS3_CMN_NM(bs3CpuBasic2_RaiseXcpt1Common)
    477 BS3_DECL_NEAR(void) bs3CpuBasic2_RaiseXcpt1Common(uint16_t const uSysR0Cs, uint16_t const uSysR0CsConf, uint16_t const uSysR0Ss,
    478                                                   PX86DESC const paIdt, unsigned const cIdteShift)
     440#if 0 /* convert me */
     441static void bs3CpuBasic2_RaiseXcpt1Common(uint16_t const uSysR0Cs, uint16_t const uSysR0CsConf, uint16_t const uSysR0Ss,
     442                                          PX86DESC const paIdt, unsigned const cIdteShift)
    479443{
    480444    BS3TRAPFRAME    TrapCtx;
     
    14441408# endif
    14451409}
    1446 
    1447 #if TMPL_BITS == 16
     1410#endif /* convert me */
     1411
    14481412
    14491413/**
     
    14531417 * mind, i.e. not assuming the test bitcount is the same as the current.
    14541418 */
    1455 # define bs3CpuBasic2_sidt_sgdt_One BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_One)
    1456 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
    1457                                                uint8_t const *pbExpected)
     1419static void bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
     1420                                       uint8_t const *pbExpected)
    14581421{
    14591422    BS3TRAPFRAME        TrapCtx;
     
    15091472        Bs3TestFailedF("Unexpected buffer bytes set (#1): cbIdtr=%u abBuf=%.*Rhxs\n", cbIdtr, cbBuf, pbBuf);
    15101473    if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)
    1511         Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);
     1474        Bs3TestFailedF("Mismatch (%s,#1): expected %.*Rhxs, got %.*Rhxs\n", pWorker->pszDesc, cbIdtr, pbExpected, cbIdtr, abBuf);
    15121475    g_usBs3TestStep++;
    15131476
     
    15291492        Bs3TestFailedF("Not all bytes touched: cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf);
    15301493    if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)
    1531         Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);
     1494        Bs3TestFailedF("Mismatch (%s,#2): expected %.*Rhxs, got %.*Rhxs\n", pWorker->pszDesc, cbIdtr, pbExpected, cbIdtr, abBuf);
    15321495    g_usBs3TestStep++;
    15331496
     
    20221985
    20231986
    2024 # define bs3CpuBasic2_sidt_sgdt_Common BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_Common)
    2025 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
    2026                                                   uint8_t const *pbExpected)
     1987static void bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
     1988                                          uint8_t const *pbExpected)
    20271989{
    20281990    unsigned idx;
     
    20462008    }
    20472009}
     2010
    20482011
    20492012BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
     
    20922055     * If paged mode, try push the GDT way up.
    20932056     */
     2057    Bs3MemZero(&Expected, sizeof(Expected));
     2058    ASMGetGDTR(&Expected.Gdtr);
    20942059    if (BS3_MODE_IS_PAGED(bMode))
    20952060    {
     
    21032068            Bs3Lgdt_Gdt.uAddr = uNew;
    21042069            Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uNew);
     2070            ASMGetGDTR(&Expected.Gdtr);
     2071            if (BS3_MODE_IS_64BIT_SYS(bMode) && ARCH_BITS != 64)
     2072                *(uint32_t *)&Expected.ab[6] = (uint32_t)(uNew >> 32);
    21052073        }
    21062074    }
     
    21092077     * Pass to common worker which is only compiled once per mode.
    21102078     */
    2111     Bs3MemZero(&Expected, sizeof(Expected));
    2112     ASMGetGDTR(&Expected.Gdtr);
    21132079    bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab);
    21142080
     
    21422108 * mind, i.e. not assuming the test bitcount is the same as the current.
    21432109 */
    2144 # define bs3CpuBasic2_lidt_lgdt_One BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_One)
    2145 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
    2146                                                uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected)
     2110static void bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,
     2111                                       uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected)
    21472112{
    21482113    static const struct
     
    28042769
    28052770
    2806 # define bs3CpuBasic2_lidt_lgdt_Common BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_Common)
    2807 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
    2808                                                   void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected)
     2771static void bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,
     2772                                          void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected)
    28092773{
    28102774    unsigned idx;
     
    29042868    return 0;
    29052869}
    2906 #endif /* TMPL_BITS == 16 */
    2907 
    2908 
    2909 # if ARCH_BITS != 64
    2910 
    2911 /**
    2912  * Worker for bs3CpuBasic2_TssGateEsp that tests the INT 80 from outer rings.
    2913  */
    2914 #  define bs3CpuBasic2_TssGateEsp_AltStackOuterRing BS3_CMN_NM(bs3CpuBasic2_TssGateEsp_AltStackOuterRing)
    2915 BS3_DECL_NEAR(void) bs3CpuBasic2_TssGateEsp_AltStackOuterRing(PCBS3REGCTX pCtx, uint8_t bRing, uint8_t *pbAltStack,
    2916                                                               size_t cbAltStack, bool f16BitStack, bool f16BitTss,
    2917                                                               bool f16BitHandler, unsigned uLine)
    2918 {
    2919     uint8_t const   cbIretFrame = f16BitHandler ? 5*2 : 5*4;
    2920     BS3REGCTX       Ctx2;
    2921     BS3TRAPFRAME    TrapCtx;
    2922     uint8_t        *pbTmp;
    2923     g_usBs3TestStep = uLine;
    2924 
    2925     Bs3MemCpy(&Ctx2, pCtx, sizeof(Ctx2));
    2926     Bs3RegCtxConvertToRingX(&Ctx2, bRing);
    2927 
    2928     if (pbAltStack)
    2929     {
    2930         Ctx2.rsp.u = Bs3SelPtrToFlat(pbAltStack + 0x1980);
    2931         Bs3MemZero(pbAltStack, cbAltStack);
    2932     }
    2933 
    2934     Bs3TrapSetJmpAndRestore(&Ctx2, &TrapCtx);
    2935 
    2936     if (!f16BitStack && f16BitTss)
    2937         Ctx2.rsp.u &= UINT16_MAX;
    2938 
    2939     bs3CpuBasic2_CompareIntCtx1(&TrapCtx, &Ctx2, 0x80 /*bXcpt*/);
    2940     CHECK_MEMBER("bCpl", "%u", TrapCtx.Ctx.bCpl, bRing);
    2941     CHECK_MEMBER("cbIretFrame", "%#x", TrapCtx.cbIretFrame, cbIretFrame);
    2942 
    2943     if (pbAltStack)
    2944     {
    2945         uint64_t uExpectedRsp = (f16BitTss ? Bs3Tss16.sp0 : Bs3Tss32.esp0) - cbIretFrame;
    2946         if (f16BitStack)
    2947         {
    2948             uExpectedRsp &= UINT16_MAX;
    2949             uExpectedRsp |= Ctx2.rsp.u & ~(uint64_t)UINT16_MAX;
    2950         }
    2951         if (   TrapCtx.uHandlerRsp != uExpectedRsp
    2952             || TrapCtx.uHandlerSs  != (f16BitTss ? Bs3Tss16.ss0 : Bs3Tss32.ss0))
    2953             bs3CpuBasic2_FailedF("handler SS:ESP=%04x:%08RX64, expected %04x:%08RX16",
    2954                                  TrapCtx.uHandlerSs, TrapCtx.uHandlerRsp, Bs3Tss16.ss0, uExpectedRsp);
    2955 
    2956         pbTmp = (uint8_t *)ASMMemFirstNonZero(pbAltStack, cbAltStack);
    2957         if ((f16BitStack || TrapCtx.uHandlerRsp <= UINT16_MAX) && pbTmp != NULL)
    2958             bs3CpuBasic2_FailedF("someone touched the alt stack (%p) with SS:ESP=%04x:%#RX32: %p=%02x",
    2959                                  pbAltStack, Ctx2.ss, Ctx2.rsp.u32, pbTmp, *pbTmp);
    2960         else if (!f16BitStack && TrapCtx.uHandlerRsp > UINT16_MAX && pbTmp == NULL)
    2961             bs3CpuBasic2_FailedF("the alt stack (%p) was not used SS:ESP=%04x:%#RX32\n", pbAltStack, Ctx2.ss, Ctx2.rsp.u32);
    2962     }
    2963 }
    2964 
    2965 #  define bs3CpuBasic2_TssGateEspCommon BS3_CMN_NM(bs3CpuBasic2_TssGateEspCommon)
    2966 BS3_DECL_NEAR(void) bs3CpuBasic2_TssGateEspCommon(bool const g_f16BitSys, PX86DESC const paIdt, unsigned const cIdteShift)
    2967 {
    2968     BS3TRAPFRAME    TrapCtx;
    2969     BS3REGCTX       Ctx;
    2970     BS3REGCTX       Ctx2;
    2971 #  if TMPL_BITS == 16
    2972     uint8_t        *pbTmp;
    2973 #  endif
    2974 
    2975     /* make sure they're allocated  */
    2976     Bs3MemZero(&Ctx, sizeof(Ctx));
    2977     Bs3MemZero(&Ctx2, sizeof(Ctx2));
    2978     Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
    2979 
    2980     Bs3RegCtxSave(&Ctx);
    2981     Ctx.rsp.u -= 0x80;
    2982     Ctx.rip.u  = (uintptr_t)BS3_FP_OFF(&bs3CpuBasic2_Int80);
    2983 #  if TMPL_BITS == 32
    2984     g_uBs3TrapEipHint = Ctx.rip.u32;
    2985 #  endif
    2986 
    2987     /*
    2988      * We'll be using IDT entry 80 and 81 here. The first one will be
    2989      * accessible from all DPLs, the latter not. So, start with setting
    2990      * the DPLs.
    2991      */
    2992     paIdt[0x80 << cIdteShift].Gate.u2Dpl = 3;
    2993     paIdt[0x81 << cIdteShift].Gate.u2Dpl = 0;
    2994 
    2995     /*
    2996      * Check that the basic stuff works first.
    2997      */
    2998     Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    2999     g_usBs3TestStep = __LINE__;
    3000     bs3CpuBasic2_CompareIntCtx1(&TrapCtx, &Ctx, 0x80 /*bXcpt*/);
    3001 
    3002     bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, NULL, 0, g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__);
    3003     bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 2, NULL, 0, g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__);
    3004     bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 3, NULL, 0, g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__);
    3005 
    3006     /*
    3007      * Check that the upper part of ESP is preserved when doing .
    3008      */
    3009     if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
    3010     {
    3011         size_t const cbAltStack = _8K;
    3012         uint8_t *pbAltStack = Bs3MemAllocZ(BS3MEMKIND_TILED, cbAltStack);
    3013         if (pbAltStack)
    3014         {
    3015             /* same ring */
    3016             g_usBs3TestStep = __LINE__;
    3017             Bs3MemCpy(&Ctx2, &Ctx, sizeof(Ctx2));
    3018             Ctx2.rsp.u = Bs3SelPtrToFlat(pbAltStack + 0x1980);
    3019             if (Bs3TrapSetJmp(&TrapCtx))
    3020                 Bs3RegCtxRestore(&Ctx2, 0); /* (does not return) */
    3021             bs3CpuBasic2_CompareIntCtx1(&TrapCtx, &Ctx2, 0x80 /*bXcpt*/);
    3022 #  if TMPL_BITS == 16
    3023             if ((pbTmp = (uint8_t *)ASMMemFirstNonZero(pbAltStack, cbAltStack)) != NULL)
    3024                 bs3CpuBasic2_FailedF("someone touched the alt stack (%p) with SS:ESP=%04x:%#RX32: %p=%02x\n",
    3025                                      pbAltStack, Ctx2.ss, Ctx2.rsp.u32, pbTmp, *pbTmp);
    3026 #  else
    3027             if (ASMMemIsZero(pbAltStack, cbAltStack))
    3028                 bs3CpuBasic2_FailedF("alt stack wasn't used despite SS:ESP=%04x:%#RX32\n", Ctx2.ss, Ctx2.rsp.u32);
    3029 #  endif
    3030 
    3031             /* Different rings (load SS0:SP0 from TSS). */
    3032             bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, pbAltStack, cbAltStack,
    3033                                                       g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__);
    3034             bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 2, pbAltStack, cbAltStack,
    3035                                                       g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__);
    3036             bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 3, pbAltStack, cbAltStack,
    3037                                                       g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__);
    3038 
    3039             /* Different rings but switch the SS bitness in the TSS. */
    3040             if (g_f16BitSys)
    3041             {
    3042                 Bs3Tss16.ss0 = BS3_SEL_R0_SS32;
    3043                 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, pbAltStack, cbAltStack,
    3044                                                           false, g_f16BitSys, g_f16BitSys, __LINE__);
    3045                 Bs3Tss16.ss0 = BS3_SEL_R0_SS16;
    3046             }
    3047             else
    3048             {
    3049                 Bs3Tss32.ss0 = BS3_SEL_R0_SS16;
    3050                 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, pbAltStack, cbAltStack,
    3051                                                           true,  g_f16BitSys, g_f16BitSys, __LINE__);
    3052                 Bs3Tss32.ss0 = BS3_SEL_R0_SS32;
    3053             }
    3054 
    3055             Bs3MemFree(pbAltStack, cbAltStack);
    3056         }
    3057         else
    3058             Bs3TestPrintf("%s: Skipping ESP check, alloc failed\n", g_pszTestMode);
    3059     }
    3060     else
    3061         Bs3TestPrintf("%s: Skipping ESP check, CPU too old\n", g_pszTestMode);
    3062 }
    3063 
    3064 # endif /* ARCH_BITS != 64 */
    3065 #endif /* BS3_INSTANTIATING_CMN */
    3066 
    3067 
    3068 /*
    3069  * Mode specific code.
    3070  * Mode specific code.
    3071  * Mode specific code.
    3072  */
    3073 #ifdef BS3_INSTANTIATING_MODE
    3074 
    3075 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_TssGateEsp)(uint8_t bMode)
    3076 {
    3077     uint8_t bRet = 0;
    3078 
    3079     g_pszTestMode = TMPL_NM(g_szBs3ModeName);
    3080     g_bTestMode   = bMode;
    3081     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
    3082 
    3083 # if TMPL_MODE == BS3_MODE_PE16 \
    3084  || TMPL_MODE == BS3_MODE_PE16_32 \
    3085  || TMPL_MODE == BS3_MODE_PP16 \
    3086  || TMPL_MODE == BS3_MODE_PP16_32 \
    3087  || TMPL_MODE == BS3_MODE_PAE16 \
    3088  || TMPL_MODE == BS3_MODE_PAE16_32 \
    3089  || TMPL_MODE == BS3_MODE_PE32
    3090     bs3CpuBasic2_TssGateEspCommon(BS3_MODE_IS_16BIT_SYS(TMPL_MODE),
    3091                                   (PX86DESC)MyBs3Idt,
    3092                                   BS3_MODE_IS_64BIT_SYS(TMPL_MODE) ? 1 : 0);
    3093 # else
    3094     bRet = BS3TESTDOMODE_SKIPPED;
    3095 # endif
    3096 
    3097     /*
    3098      * Re-initialize the IDT.
    3099      */
    3100     Bs3TrapInit();
    3101     return bRet;
    3102 }
    3103 
    3104 
    3105 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_RaiseXcpt1)(uint8_t bMode)
    3106 {
    3107     g_pszTestMode = TMPL_NM(g_szBs3ModeName);
    3108     g_bTestMode   = bMode;
    3109     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
    3110 
    3111 # if !BS3_MODE_IS_RM_OR_V86(TMPL_MODE)
    3112 
    3113     /*
    3114      * Pass to common worker which is only compiled once per mode.
    3115      */
    3116     bs3CpuBasic2_RaiseXcpt1Common(MY_SYS_SEL_R0_CS,
    3117                                   MY_SYS_SEL_R0_CS_CNF,
    3118                                   MY_SYS_SEL_R0_SS,
    3119                                   (PX86DESC)MyBs3Idt,
    3120                                   BS3_MODE_IS_64BIT_SYS(TMPL_MODE) ? 1 : 0);
    3121 
    3122     /*
    3123      * Re-initialize the IDT.
    3124      */
    3125     Bs3TrapInit();
    3126     return 0;
    3127 # elif TMPL_MODE == BS3_MODE_RM
    3128 
    3129     /*
    3130      * Check
    3131      */
    3132     /** @todo check    */
    3133     return BS3TESTDOMODE_SKIPPED;
    3134 
    3135 # else
    3136     return BS3TESTDOMODE_SKIPPED;
    3137 # endif
    3138 }
    3139 
    3140 
    3141 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_iret)(uint8_t bMode)
    3142 {
    3143     g_pszTestMode = TMPL_NM(g_szBs3ModeName);
    3144     g_bTestMode   = bMode;
    3145     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
    3146 
    3147     Bs3PrintStrN(RT_STR_TUPLE("Hello world!\n"));
    3148 # if !BS3_MODE_IS_V86(TMPL_MODE)
    3149     Bs3TestPrintf(RT_STR_TUPLE("Hi there!\n"));
    3150 # endif
    3151     return BS3TESTDOMODE_SKIPPED;
    3152 }
    3153 
    3154 
    3155 # if 0
    3156 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
    3157 {
    3158     BS3_ASSERT(bMode == TMPL_MODE);
    3159     return BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(bMode);
    3160 }
    3161 
    3162 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
    3163 {
    3164     BS3_ASSERT(bMode == TMPL_MODE);
    3165     return BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(bMode);
    3166 }
    3167 
    3168 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode)
    3169 {
    3170     BS3_ASSERT(bMode == TMPL_MODE);
    3171     return BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(bMode);
    3172 }
    3173 
    3174 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)
    3175 {
    3176     BS3_ASSERT(bMode == TMPL_MODE);
    3177     return BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(bMode);
    3178 }
    3179 # endif
    3180 
    3181 #endif /* BS3_INSTANTIATING_MODE */
    3182 
     2870
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c

    r60749 r60750  
    3838BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_TssGateEsp);
    3939BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_RaiseXcpt1);
    40 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_iret);
    41 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sidt);
    42 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sgdt);
    43 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lidt);
    44 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lgdt);
    4540
    4641FNBS3TESTDOMODE             bs3CpuBasic2_sidt_f16;
     
    5449*   Global Variables                                                                                                             *
    5550*********************************************************************************************************************************/
    56 #if 0
    5751static const BS3TESTMODEENTRY g_aModeTest[] =
    5852{
    59 #if 0
    60     BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
     53    //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
    6154    BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),
    62 //    BS3TESTMODEENTRY_MODE("sidt", bs3CpuBasic2_sidt),
    63 //    BS3TESTMODEENTRY_MODE("sgdt", bs3CpuBasic2_sgdt),
    64 //    BS3TESTMODEENTRY_MODE("lidt", bs3CpuBasic2_lidt),
    65 //    BS3TESTMODEENTRY_MODE("lgdt", bs3CpuBasic2_lgdt),
    66 #endif
    67 //    BS3TESTMODEENTRY_MODE("iret", bs3CpuBasic2_iret),
    6855};
    69 #endif
    7056
    7157static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] =
    7258{
    7359    //{ "iret", bs3CpuBasic2_iret_f16, 0 },
     60    { "sidt", bs3CpuBasic2_sidt_f16, 0 },
     61    { "sgdt", bs3CpuBasic2_sgdt_f16, 0 },
     62    { "lidt", bs3CpuBasic2_lidt_f16, 0 },
    7463    { "lgdt", bs3CpuBasic2_lgdt_f16, 0 },
    7564};
     
    8271    Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
    8372
    84     //Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest));
     73    Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest));
    8574    Bs3TestDoModesByOne_rm(g_aModeByOneTests, RT_ELEMENTS(g_aModeByOneTests), 0);
    8675
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestDoModesByOneHlp.asm

    r60749 r60750  
    141141
    142142.return:
    143 hlt
    144143        ; Switch back to 64-bit mode.
    145144        extern  _Bs3SwitchTo64Bit_c16
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