Changeset 60724 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Apr 27, 2016 5:00:29 PM (9 years ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/Config.kmk
r60596 r60724 707 707 segment BS3TEXT32 \ 708 708 segment BS3TEXT32_END \ 709 clname BS3CLASSSEPARATE32AND64BITCODE \ 710 segment BS3SEPARATE32AND64BITCODE \ 711 segment BS3SEPARATE32AND64BITCODE_END \ 709 712 clname BS3CLASS64CODE \ 710 713 segment BS3TEXT64_START \ … … 921 924 segment BS3TEXT32 \ 922 925 segment BS3TEXT32_END \ 926 clname BS3CLASSSEPARATE32AND64BITCODE \ 927 segment BS3SEPARATE32AND64BITCODE \ 928 segment BS3SEPARATE32AND64BITCODE_END \ 923 929 clname BS3CLASS64CODE \ 924 930 segment BS3TEXT64 \ -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c
r60686 r60724 43 43 else bs3CpuBasic2_FailedF(a_szName "=" a_szFmt " expected " a_szFmt, (a_Actual), (a_Expected)); \ 44 44 } while (0) 45 46 47 #ifdef BS3_INSTANTIATING_CMN 48 /** Indicating that we've got operand size prefix and that it matters. */ 49 # define BS3CB2SIDTSGDT_F_OPSIZE UINT8_C(0x01) 50 #endif 45 51 46 52 #ifdef BS3_INSTANTIATING_MODE … … 90 96 bool fSs; 91 97 uint8_t bMode; 98 uint8_t fFlags; 92 99 } BS3CB2SIDTSGDT; 93 100 #endif … … 131 138 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32; 132 139 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64; 140 141 extern FNBS3FAR bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16; 142 extern FNBS3FAR bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32; 143 extern FNBS3FAR bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64; 144 extern FNBS3FAR bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16; 145 extern FNBS3FAR bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32; 146 extern FNBS3FAR bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64; 147 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16; 148 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32; 149 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64; 150 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16; 151 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32; 152 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64; 153 133 154 #endif 134 155 … … 146 167 147 168 169 /** SIDT test workers. */ 148 170 static BS3CB2SIDTSGDT const g_aSidtWorkers[] = 149 171 { … … 162 184 }; 163 185 164 186 /** SGDT test workers. */ 165 187 static BS3CB2SIDTSGDT const g_aSgdtWorkers[] = 166 188 { … … 178 200 { bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64 }, 179 201 }; 202 203 /** LIDT test workers. */ 204 static BS3CB2SIDTSGDT const g_aLidtWorkers[] = 205 { 206 { bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16, 11, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 207 { bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16, 12, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 208 { bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16, 12, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 209 { bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16, 13, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 210 { bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32, 11, false, BS3_MODE_CODE_32, 0 }, 211 { bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32, 12, true, BS3_MODE_CODE_32, 0 }, 212 { bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32, 12, false, BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE }, 213 { bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32, 13, true, BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE }, 214 { bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64, 9, false, BS3_MODE_CODE_64, 0 }, 215 { bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64, 10, false, BS3_MODE_CODE_64, 0 }, 216 { bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64, 10, false, BS3_MODE_CODE_64, 0 }, 217 { bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64, 11, false, BS3_MODE_CODE_64, 0 }, 218 }; 219 180 220 181 221 … … 1379 1419 # define bs3CpuBasic2_sidt_sgdt_One BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_One) 1380 1420 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing, 1381 uint8_t const *p abExpected)1421 uint8_t const *pbExpected) 1382 1422 { 1383 1423 BS3TRAPFRAME TrapCtx; … … 1432 1472 if (!ASMMemIsZero(&abBuf[cbIdtr], cbBuf - cbIdtr)) 1433 1473 Bs3TestFailedF("Unexpected buffer bytes set (#1): cbIdtr=%u abBuf=%.*Rhxs\n", cbIdtr, cbBuf, pbBuf); 1434 if (Bs3MemCmp(abBuf, p abExpected, cbIdtr) != 0)1435 Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, abBuf);1474 if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0) 1475 Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf); 1436 1476 g_usBs3TestStep++; 1437 1477 1438 /* Again with buffer filleda byte not occuring in the previous result. */1478 /* Again with a buffer filled with a byte not occuring in the previous result. */ 1439 1479 bFiller = 0x55; 1440 1480 while (Bs3MemChr(abBuf, bFiller, cbBuf) != NULL) … … 1452 1492 if (Bs3MemChr(abBuf, bFiller, cbIdtr) != NULL) 1453 1493 Bs3TestFailedF("Not all bytes touched: cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf); 1454 if (Bs3MemCmp(abBuf, p abExpected, cbIdtr) != 0)1455 Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, abBuf);1494 if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0) 1495 Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf); 1456 1496 g_usBs3TestStep++; 1457 1497 … … 1477 1517 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 1478 1518 Bs3TestFailedF("286: Top base byte isn't 0xff (#3): %#x\n", abBuf[off + cbIdtr - 1]); 1479 if (Bs3MemCmp(&abBuf[off], p abExpected, cbIdtr) != 0)1480 Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &abBuf[off]);1519 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 1520 Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 1481 1521 g_usBs3TestStep++; 1482 1522 1483 /* Again with buffer filleda byte not occuring in the previous result. */1523 /* Again with a buffer filled with a byte not occuring in the previous result. */ 1484 1524 Bs3MemSet(abBuf, bFiller, sizeof(abBuf)); 1485 1525 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); … … 1496 1536 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 1497 1537 Bs3TestFailedF("286: Top base byte isn't 0xff (#4): %#x\n", abBuf[off + cbIdtr - 1]); 1498 if (Bs3MemCmp(&abBuf[off], p abExpected, cbIdtr) != 0)1499 Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &abBuf[off]);1538 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 1539 Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 1500 1540 g_usBs3TestStep++; 1501 1541 } … … 1539 1579 Bs3TestFailedF("Not all bytes touched (#5): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 1540 1580 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 1541 if (Bs3MemCmp(&abBuf[off], p abExpected, cbIdtr) != 0)1542 Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &abBuf[off]);1581 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 1582 Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 1543 1583 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 1544 1584 Bs3TestFailedF("286: Top base byte isn't 0xff (#5): %#x\n", abBuf[off + cbIdtr - 1]); … … 1555 1595 Bs3TestFailedF("Limit bytes not touched (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 1556 1596 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 1557 if (Bs3MemCmp(&abBuf[off], p abExpected, 2) != 0)1558 Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", p abExpected, &abBuf[off]);1597 if (Bs3MemCmp(&abBuf[off], pbExpected, 2) != 0) 1598 Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pbExpected, &abBuf[off]); 1559 1599 if (!ASMMemIsAllU8(&abBuf[off + 2], cbIdtr - 2, bFiller)) 1560 1600 Bs3TestFailedF("Base bytes touched on #GP (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", … … 1599 1639 Bs3TestFailedF("Not all bytes touched (#8): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 1600 1640 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 1601 if (Bs3MemCmp(&abBuf[off], p abExpected, cbIdtr) != 0)1602 Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &abBuf[off]);1641 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 1642 Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 1603 1643 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 1604 1644 Bs3TestFailedF("286: Top base byte isn't 0xff (#8): %#x\n", abBuf[off + cbIdtr - 1]); … … 1656 1696 CtxUdExpected.ds = Ctx.ds; 1657 1697 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 1658 if (Bs3MemCmp(&pbTest[off], p abExpected, cbIdtr) != 0)1659 Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &pbTest[off]);1698 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 1699 Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 1660 1700 } 1661 1701 else … … 1664 1704 uFlatTest + RT_MAX(off, X86_PAGE_SIZE)); 1665 1705 if ( off <= X86_PAGE_SIZE - 2 1666 && Bs3MemCmp(&pbTest[off], p abExpected, 2) != 0)1706 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 1667 1707 Bs3TestPrintf("Mismatch (#10): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n", 1668 p abExpected, &pbTest[off], off);1708 pbExpected, &pbTest[off], off); 1669 1709 if ( off < X86_PAGE_SIZE - 2 1670 1710 && !ASMMemIsAllU8(&pbTest[off + 2], X86_PAGE_SIZE - off - 2, bFiller)) … … 1692 1732 CtxUdExpected.ds = Ctx.ds; 1693 1733 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 1694 if (Bs3MemCmp(&pbTest[off], p abExpected, cbIdtr) != 0)1695 Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &pbTest[off]);1734 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 1735 Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 1696 1736 } 1697 1737 else … … 1745 1785 { 1746 1786 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 1747 if (Bs3MemCmp(&pbTest[off], p abExpected, cbIdtr) != 0)1787 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 1748 1788 Bs3TestFailedF("Mismatch (#14): expected %.*Rhxs, got %.*Rhxs\n", 1749 cbIdtr, p abExpected, cbIdtr, &pbTest[off]);1789 cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 1750 1790 } 1751 1791 else … … 1754 1794 uFlatTest + RT_MAX(off, X86_PAGE_SIZE)); 1755 1795 if ( off <= X86_PAGE_SIZE - 2 1756 && Bs3MemCmp(&pbTest[off], p abExpected, 2) != 0)1796 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 1757 1797 Bs3TestPrintf("Mismatch (#15): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n", 1758 p abExpected, &pbTest[off], off);1798 pbExpected, &pbTest[off], off); 1759 1799 cb = X86_PAGE_SIZE - off - 2; 1760 1800 if ( off < X86_PAGE_SIZE - 2 … … 1775 1815 else 1776 1816 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 1777 if (Bs3MemCmp(&pbTest[off], p abExpected, 2) != 0)1817 if (Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 1778 1818 Bs3TestPrintf("Mismatch (#16): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n", 1779 p abExpected, &pbTest[off], off);1819 pbExpected, &pbTest[off], off); 1780 1820 cb = X86_PAGE_SIZE - off - 2; 1781 1821 if ( off < X86_PAGE_SIZE - 2 … … 1846 1886 { 1847 1887 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 1848 if (Bs3MemCmp(&pbTest[off], p abExpected, cbIdtr) != 0)1888 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 1849 1889 Bs3TestFailedF("Mismatch (#19): expected %.*Rhxs, got %.*Rhxs\n", 1850 cbIdtr, p abExpected, cbIdtr, &pbTest[off]);1890 cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 1851 1891 cb = X86_PAGE_SIZE + cbIdtr*2 - off; 1852 1892 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], cb, bFiller)) … … 1897 1937 { 1898 1938 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 1899 if (Bs3MemCmp(&pbTest[off], p abExpected, cbIdtr) != 0)1900 Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &pbTest[off]);1939 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 1940 Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 1901 1941 } 1902 1942 else 1903 1943 { 1904 1944 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 1905 if (off <= -2 && Bs3MemCmp(&pbTest[off], p abExpected, 2) != 0)1906 Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", p abExpected, &pbTest[off]);1945 if (off <= -2 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 1946 Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pbExpected, &pbTest[off]); 1907 1947 off2 = off <= -2 ? 2 : 0; 1908 1948 cb = cbIdtr - off2; 1909 1949 if (!ASMMemIsAllU8(&pbTest[off + off2], cb, bFiller)) 1910 1950 Bs3TestFailedF("Mismatch (#21): touched base %.*Rhxs, got %.*Rhxs\n", 1911 cb, &p abExpected[off], cb, &pbTest[off + off2]);1951 cb, &pbExpected[off], cb, &pbTest[off + off2]); 1912 1952 } 1913 1953 if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller)) … … 1926 1966 { 1927 1967 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 1928 if (Bs3MemCmp(&pbTest[off], p abExpected, cbIdtr) != 0)1929 Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, p abExpected, cbIdtr, &pbTest[off]);1968 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 1969 Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 1930 1970 } 1931 1971 else … … 1934 1974 if (!ASMMemIsAllU8(&pbTest[off], cbIdtr, bFiller)) 1935 1975 Bs3TestFailedF("Mismatch (#22): touched base %.*Rhxs, got %.*Rhxs\n", 1936 cbIdtr, &p abExpected[off], cbIdtr, &pbTest[off]);1976 cbIdtr, &pbExpected[off], cbIdtr, &pbTest[off]); 1937 1977 } 1938 1978 if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller)) … … 1943 1983 1944 1984 } 1945 1946 /*1947 * Move the table by setting up alias pages. Aim at areas above 2GB for 32-bit and in1948 * the 'negative' space of 64-bit addresses.1949 */1950 if (BS3_MODE_IS_PAGED(bTestMode))1951 {1952 1953 }1954 1955 1956 1985 } 1986 1957 1987 1958 1988 # define bs3CpuBasic2_sidt_sgdt_Common BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_Common) 1959 1989 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers, 1960 uint8_t const *p abExpected)1990 uint8_t const *pbExpected) 1961 1991 { 1962 1992 unsigned idx; … … 1973 2003 { 1974 2004 g_usBs3TestStep = iStep; 1975 bs3CpuBasic2_sidt_sgdt_One(&paWorkers[idx], bTestMode, bRing, p abExpected);2005 bs3CpuBasic2_sidt_sgdt_One(&paWorkers[idx], bTestMode, bRing, pbExpected); 1976 2006 iStep += 1000; 1977 2007 } 1978 2008 if (BS3_MODE_IS_RM_OR_V86(bTestMode)) 2009 break; 2010 } 2011 } 2012 2013 2014 /* 2015 * LIDT & LGDT 2016 */ 2017 2018 /** 2019 * Executes one round of LIDT and LGDT tests using one assembly worker. 2020 * 2021 * This is written with driving everything from the 16-bit or 32-bit worker in 2022 * mind, i.e. not assuming the test bitcount is the same as the current. 2023 */ 2024 # define bs3CpuBasic2_lidt_lgdt_One BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_One) 2025 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing, 2026 uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected) 2027 { 2028 BS3TRAPFRAME TrapCtx; 2029 BS3REGCTX Ctx; 2030 BS3REGCTX CtxUdExpected; 2031 BS3REGCTX TmpCtx; 2032 uint8_t abBufLoad[40]; /* Test buffer w/ misalignment test space and some (cbIdtr) extra guard. */ 2033 uint8_t abBufSave[32]; /* For saving the result after loading. */ 2034 uint8_t abBufRestore[24]; /* For restoring sane value (same seg as abBufSave!). */ 2035 uint8_t abExpectedFilled[32]; /* Same as pbExpected, except it's filled with bFiller2 instead of zeros. */ 2036 uint8_t BS3_FAR *pbBufSave; /* Correctly aligned pointer into abBufSave. */ 2037 uint8_t BS3_FAR *pbBufRestore; /* Correctly aligned pointer into abBufRestore. */ 2038 uint8_t const cbIdtr = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 2+8 : 2+4; 2039 uint8_t const cbBaseLoaded = BS3_MODE_IS_16BIT_CODE(bTestMode) || (pWorker->fFlags & BS3CB2SIDTSGDT_F_OPSIZE) 2040 ? 3 : cbIdtr - 2; 2041 bool const f286 = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286; 2042 uint8_t const bTop16BitBase = f286 ? 0xff : 0x00; 2043 uint8_t bFiller1; /* For filling abBufLoad. */ 2044 uint8_t bFiller2; /* For filling abBufSave and expectations. */ 2045 // int off; 2046 // int off2; 2047 // unsigned cb; 2048 // uint8_t BS3_FAR *pbTest; 2049 unsigned i; 2050 2051 /* make sure they're allocated */ 2052 Bs3MemZero(&Ctx, sizeof(Ctx)); 2053 Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected)); 2054 Bs3MemZero(&TmpCtx, sizeof(TmpCtx)); 2055 Bs3MemZero(&TrapCtx, sizeof(TrapCtx)); 2056 Bs3MemZero(abBufSave, sizeof(abBufSave)); 2057 Bs3MemZero(abBufLoad, sizeof(abBufLoad)); 2058 Bs3MemZero(abBufRestore, sizeof(abBufRestore)); 2059 2060 /* 2061 * Create a context, giving this routine some more stack space. 2062 * - Point the context at our LIDT [xBX] + SIDT [xDI] + LIDT [xSI] + UD2 combo. 2063 * - Point DS/SS:xBX at abBufLoad. 2064 * - Point ES:xDI at abBufSave. 2065 * - Point ES:xSI at abBufRestore. 2066 */ 2067 Bs3RegCtxSaveEx(&Ctx, bTestMode, 256 /*cbExtraStack*/); 2068 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pWorker->fpfnWorker); 2069 if (BS3_MODE_IS_16BIT_SYS(bTestMode)) 2070 g_uBs3TrapEipHint = Ctx.rip.u32; 2071 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad); 2072 2073 pbBufSave = abBufSave; 2074 if ((BS3_FP_OFF(pbBufSave) + 2) & 7) 2075 pbBufSave += 8 - ((BS3_FP_OFF(pbBufSave) + 2) & 7); 2076 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.es, pbBufSave); 2077 2078 pbBufRestore = abBufRestore; 2079 if ((BS3_FP_OFF(pbBufRestore) + 2) & 7) 2080 pbBufRestore += 8 - ((BS3_FP_OFF(pbBufRestore) + 2) & 7); 2081 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsi, &Ctx.es, pbBufRestore); 2082 Bs3MemCpy(pbBufRestore, pbRestore, cbRestore); 2083 2084 if (!BS3_MODE_IS_RM_OR_V86(bTestMode)) 2085 Bs3RegCtxConvertToRingX(&Ctx, bRing); 2086 2087 /* For successful SIDT attempts, we'll stop at the UD2. */ 2088 Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx)); 2089 CtxUdExpected.rip.u += pWorker->cbInstr; 2090 2091 /* 2092 * Check that it works at all. 2093 */ 2094 Bs3MemZero(abBufLoad, sizeof(abBufLoad)); 2095 Bs3MemCpy(abBufLoad, pbBufRestore, cbRestore); 2096 Bs3MemZero(abBufSave, sizeof(abBufSave)); 2097 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2098 if (bRing != 0) 2099 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2100 else 2101 { 2102 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2103 if (Bs3MemCmp(pbBufSave, pbExpected, cbIdtr * 2) != 0) 2104 Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr*2, pbExpected, cbIdtr*2, pbBufSave); 2105 } 2106 g_usBs3TestStep++; 2107 2108 /* Determine two filler bytes that doesn't appear in the previous result or our expectations. */ 2109 bFiller1 = ~0x55; 2110 while ( Bs3MemChr(pbBufSave, bFiller1, cbIdtr) != NULL 2111 || Bs3MemChr(pbRestore, bFiller1, cbRestore) != NULL 2112 || bFiller1 == 0xff) 2113 bFiller1++; 2114 bFiller2 = 0x33; 2115 while ( Bs3MemChr(pbBufSave, bFiller2, cbIdtr) != NULL 2116 || Bs3MemChr(pbRestore, bFiller2, cbRestore) != NULL 2117 || bFiller2 == 0xff 2118 || bFiller2 == bFiller1) 2119 bFiller2++; 2120 Bs3MemSet(abExpectedFilled, bFiller2, sizeof(abExpectedFilled)); 2121 Bs3MemCpy(abExpectedFilled, pbExpected, cbIdtr); 2122 2123 /* Again with a buffer filled with a byte not occuring in the previous result. */ 2124 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad)); 2125 Bs3MemCpy(abBufLoad, pbBufRestore, cbRestore); 2126 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave)); 2127 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2128 if (bRing != 0) 2129 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2130 else 2131 { 2132 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2133 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0) 2134 Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave); 2135 } 2136 g_usBs3TestStep++; 2137 2138 /* 2139 * Try loading a bunch of different limit+base value to check what happens, 2140 * especially what happens wrt the top part of the base in 16-bit mode. 2141 */ 2142 if (BS3_MODE_IS_64BIT_CODE(bTestMode)) 2143 { 2144 static const struct 2145 { 2146 bool fGP; 2147 uint16_t cbLimit; 2148 uint64_t u64Base; 2149 } s_aValues[] = 2150 { 2151 { false, 0x0000, UINT64_C(0x0000000000000000) }, 2152 { false, 0x0001, UINT64_C(0x0000000000000001) }, 2153 { false, 0x0002, UINT64_C(0x0000000000000010) }, 2154 { false, 0x0003, UINT64_C(0x0000000000000123) }, 2155 { false, 0x0004, UINT64_C(0x0000000000001234) }, 2156 { false, 0x0005, UINT64_C(0x0000000000012345) }, 2157 { false, 0x0006, UINT64_C(0x0000000000123456) }, 2158 { false, 0x0007, UINT64_C(0x0000000001234567) }, 2159 { false, 0x0008, UINT64_C(0x0000000012345678) }, 2160 { false, 0x0009, UINT64_C(0x0000000123456789) }, 2161 { false, 0x000a, UINT64_C(0x000000123456789a) }, 2162 { false, 0x000b, UINT64_C(0x00000123456789ab) }, 2163 { false, 0x000c, UINT64_C(0x0000123456789abc) }, 2164 { false, 0x001c, UINT64_C(0x00007ffffeefefef) }, 2165 { false, 0xffff, UINT64_C(0x00007fffffffffff) }, 2166 { true, 0xf3f1, UINT64_C(0x0000800000000000) }, 2167 { true, 0x0000, UINT64_C(0x0000800000000000) }, 2168 { true, 0x0000, UINT64_C(0x0000800000000333) }, 2169 { true, 0x00f0, UINT64_C(0x0001000000000000) }, 2170 { true, 0x0ff0, UINT64_C(0x0012000000000000) }, 2171 { true, 0x0eff, UINT64_C(0x0123000000000000) }, 2172 { true, 0xe0fe, UINT64_C(0x1234000000000000) }, 2173 { true, 0x00ad, UINT64_C(0xffff300000000000) }, 2174 { true, 0x0000, UINT64_C(0xffff7fffffffffff) }, 2175 { true, 0x00f0, UINT64_C(0xffff7fffffffffff) }, 2176 { false, 0x5678, UINT64_C(0xffff800000000000) }, 2177 { false, 0x2969, UINT64_C(0xffffffffffeefefe) }, 2178 { false, 0x1221, UINT64_C(0xffffffffffffffff) }, 2179 { false, 0x1221, UINT64_C(0xffffffffffffffff) }, 2180 }; 2181 for (i = 0; i < RT_ELEMENTS(s_aValues); i++) 2182 { 2183 Bs3MemSet(abBufSave, bFiller1, sizeof(abBufSave)); 2184 Bs3MemCpy(&abBufLoad[0], &s_aValues[i].cbLimit, 2); 2185 Bs3MemCpy(&abBufLoad[2], &s_aValues[i].u64Base, 8); 2186 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave)); 2187 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2188 if (bRing != 0 || s_aValues[i].fGP) 2189 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2190 else 2191 { 2192 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2193 if ( Bs3MemCmp(&pbBufSave[0], &s_aValues[i].cbLimit, 2) != 0 2194 || Bs3MemCmp(&pbBufSave[2], &s_aValues[i].u64Base, 8) != 0 2195 || !ASMMemIsAllU8(&pbBufSave[10], cbIdtr, bFiller2)) 2196 Bs3TestFailedF("Mismatch (#2): expected %04RX16:%016RX64, fillers %#x %#x, got %.*Rhxs\n", 2197 s_aValues[i].cbLimit, s_aValues[i].u64Base, bFiller1, bFiller2, cbIdtr*2, pbBufSave); 2198 } 2199 g_usBs3TestStep++; 2200 } 2201 } 2202 else 2203 { 2204 static const struct 2205 { 2206 uint16_t cbLimit; 2207 uint32_t u32Base; 2208 } s_aValues[] = 2209 { 2210 { 0x0000, UINT32_C(0x00000000) }, 2211 { 0x0001, UINT32_C(0x00000001) }, 2212 { 0x0002, UINT32_C(0x00000012) }, 2213 { 0x0003, UINT32_C(0x00000123) }, 2214 { 0x0004, UINT32_C(0x00001234) }, 2215 { 0x0005, UINT32_C(0x00012345) }, 2216 { 0x0006, UINT32_C(0x00123456) }, 2217 { 0x0007, UINT32_C(0x01234567) }, 2218 { 0x0008, UINT32_C(0x12345678) }, 2219 { 0x0009, UINT32_C(0x80204060) }, 2220 { 0x000a, UINT32_C(0xddeeffaa) }, 2221 { 0x000b, UINT32_C(0xfdecdbca) }, 2222 { 0x000c, UINT32_C(0x6098456b) }, 2223 { 0x000d, UINT32_C(0x98506099) }, 2224 { 0x000e, UINT32_C(0x206950bc) }, 2225 { 0x000f, UINT32_C(0x9740395d) }, 2226 { 0x0334, UINT32_C(0x64a9455e) }, 2227 { 0xb423, UINT32_C(0xd20b6eff) }, 2228 { 0x4955, UINT32_C(0x85296d46) }, 2229 { 0xffff, UINT32_C(0x07000039) }, 2230 { 0xefe1, UINT32_C(0x0007fe00) }, 2231 }; 2232 for (i = 0; i < RT_ELEMENTS(s_aValues); i++) 2233 { 2234 Bs3MemSet(abBufSave, bFiller1, sizeof(abBufSave)); 2235 Bs3MemCpy(&abBufLoad[0], &s_aValues[i].cbLimit, 2); 2236 Bs3MemCpy(&abBufLoad[2], &s_aValues[i].u32Base, cbBaseLoaded); 2237 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave)); 2238 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2239 if (bRing != 0) 2240 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2241 else 2242 { 2243 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2244 if ( Bs3MemCmp(&pbBufSave[0], &s_aValues[i].cbLimit, 2) != 0 2245 || Bs3MemCmp(&pbBufSave[2], &s_aValues[i].u32Base, cbBaseLoaded) != 0 2246 || ( cbBaseLoaded != 4 2247 && pbBufSave[2+3] != bTop16BitBase) 2248 || !ASMMemIsAllU8(&pbBufSave[8], cbIdtr, bFiller2)) 2249 Bs3TestFailedF("Mismatch (#3): loaded %04RX16:%08RX32, fillers %#x %#x%s%s (cbIns=%d), got %.*Rhxs\n", 2250 s_aValues[i].cbLimit, s_aValues[i].u32Base, bFiller1, bFiller2, f286 ? ", 286" : "", 2251 pWorker->fFlags ? ", opsize" : "", pWorker->cbInstr, cbIdtr*2, pbBufSave); 2252 } 2253 g_usBs3TestStep++; 2254 } 2255 2256 } 2257 2258 2259 2260 #if 0 2261 2262 /* 2263 * Slide the buffer along 8 bytes to cover misalignment. 2264 */ 2265 for (off = 0; off < 8; off++) 2266 { 2267 pbBuf = &abBuf[off]; 2268 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &abBuf[off]); 2269 CtxUdExpected.rbx.u = Ctx.rbx.u; 2270 2271 /* First with zero buffer. */ 2272 Bs3MemZero(abBuf, sizeof(abBuf)); 2273 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2274 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2275 if (off > 0 && !ASMMemIsZero(abBuf, off)) 2276 Bs3TestFailedF("Unexpected buffer bytes set before (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n", 2277 cbIdtr, off, off + cbBuf, abBuf); 2278 if (!ASMMemIsZero(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off)) 2279 Bs3TestFailedF("Unexpected buffer bytes set after (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n", 2280 cbIdtr, off, off + cbBuf, abBuf); 2281 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 2282 Bs3TestFailedF("286: Top base byte isn't 0xff (#3): %#x\n", abBuf[off + cbIdtr - 1]); 2283 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 2284 Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 2285 g_usBs3TestStep++; 2286 2287 /* Again with a buffer filled with a byte not occuring in the previous result. */ 2288 Bs3MemSet(abBuf, bFiller, sizeof(abBuf)); 2289 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2290 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2291 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller)) 2292 Bs3TestFailedF("Unexpected buffer bytes set before (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n", 2293 cbIdtr, off, bFiller, off + cbBuf, abBuf); 2294 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off, bFiller)) 2295 Bs3TestFailedF("Unexpected buffer bytes set after (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n", 2296 cbIdtr, off, bFiller, off + cbBuf, abBuf); 2297 if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL) 2298 Bs3TestFailedF("Not all bytes touched (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n", 2299 cbIdtr, off, bFiller, off + cbBuf, abBuf); 2300 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 2301 Bs3TestFailedF("286: Top base byte isn't 0xff (#4): %#x\n", abBuf[off + cbIdtr - 1]); 2302 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 2303 Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 2304 g_usBs3TestStep++; 2305 } 2306 pbBuf = abBuf; 2307 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf); 2308 CtxUdExpected.rbx.u = Ctx.rbx.u; 2309 2310 /* 2311 * Play with the selector limit if the target mode supports limit checking 2312 * We use BS3_SEL_TEST_PAGE_00 for this 2313 */ 2314 if ( !BS3_MODE_IS_RM_OR_V86(bTestMode) 2315 && !BS3_MODE_IS_64BIT_CODE(bTestMode)) 2316 { 2317 uint16_t cbLimit; 2318 uint32_t uFlatBuf = Bs3SelPtrToFlat(abBuf); 2319 Bs3GdteTestPage00 = Bs3Gdte_DATA16; 2320 Bs3GdteTestPage00.Gen.u2Dpl = bRing; 2321 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatBuf; 2322 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatBuf >> 16); 2323 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatBuf >> 24); 2324 2325 if (pWorker->fSs) 2326 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing; 2327 else 2328 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing; 2329 2330 /* Expand up (normal). */ 2331 for (off = 0; off < 8; off++) 2332 { 2333 CtxUdExpected.rbx.u = Ctx.rbx.u = off; 2334 for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++) 2335 { 2336 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit; 2337 Bs3MemSet(abBuf, bFiller, sizeof(abBuf)); 2338 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2339 if (off + cbIdtr <= cbLimit + 1) 2340 { 2341 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2342 if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL) 2343 Bs3TestFailedF("Not all bytes touched (#5): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2344 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2345 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 2346 Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 2347 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 2348 Bs3TestFailedF("286: Top base byte isn't 0xff (#5): %#x\n", abBuf[off + cbIdtr - 1]); 2349 } 2350 else 2351 { 2352 if (pWorker->fSs) 2353 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/); 2354 else 2355 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2356 if (off + 2 <= cbLimit + 1) 2357 { 2358 if (Bs3MemChr(&abBuf[off], bFiller, 2) != NULL) 2359 Bs3TestFailedF("Limit bytes not touched (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2360 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2361 if (Bs3MemCmp(&abBuf[off], pbExpected, 2) != 0) 2362 Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pbExpected, &abBuf[off]); 2363 if (!ASMMemIsAllU8(&abBuf[off + 2], cbIdtr - 2, bFiller)) 2364 Bs3TestFailedF("Base bytes touched on #GP (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2365 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2366 } 2367 else if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller)) 2368 Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2369 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2370 } 2371 2372 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller)) 2373 Bs3TestFailedF("Leading bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2374 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2375 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller)) 2376 Bs3TestFailedF("Trailing bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2377 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2378 2379 g_usBs3TestStep++; 2380 } 2381 } 2382 2383 /* Expand down (weird). Inverted valid area compared to expand up, 2384 so a limit of zero give us a valid range for 0001..0ffffh (instead of 2385 a segment with one valid byte at 0000h). Whereas a limit of 0fffeh 2386 means one valid byte at 0ffffh, and a limit of 0ffffh means none 2387 (because in a normal expand up the 0ffffh means all 64KB are 2388 accessible). */ 2389 Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC; 2390 for (off = 0; off < 8; off++) 2391 { 2392 CtxUdExpected.rbx.u = Ctx.rbx.u = off; 2393 for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++) 2394 { 2395 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit; 2396 Bs3MemSet(abBuf, bFiller, sizeof(abBuf)); 2397 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2398 2399 if (off > cbLimit) 2400 { 2401 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2402 if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL) 2403 Bs3TestFailedF("Not all bytes touched (#8): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2404 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2405 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0) 2406 Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]); 2407 if (f286 && abBuf[off + cbIdtr - 1] != 0xff) 2408 Bs3TestFailedF("286: Top base byte isn't 0xff (#8): %#x\n", abBuf[off + cbIdtr - 1]); 2409 } 2410 else 2411 { 2412 if (pWorker->fSs) 2413 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/); 2414 else 2415 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2416 if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller)) 2417 Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2418 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2419 } 2420 2421 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller)) 2422 Bs3TestFailedF("Leading bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2423 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2424 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller)) 2425 Bs3TestFailedF("Trailing bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n", 2426 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf); 2427 2428 g_usBs3TestStep++; 2429 } 2430 } 2431 2432 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf); 2433 CtxUdExpected.rbx.u = Ctx.rbx.u; 2434 CtxUdExpected.ss = Ctx.ss; 2435 CtxUdExpected.ds = Ctx.ds; 2436 } 2437 2438 /* 2439 * Play with the paging. 2440 */ 2441 if ( BS3_MODE_IS_PAGED(bTestMode) 2442 && (!pWorker->fSs || bRing == 3) /* SS.DPL == CPL, we'll get some tiled ring-3 selector here. */ 2443 && (pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED)) != NULL) 2444 { 2445 RTCCUINTXREG uFlatTest = Bs3SelPtrToFlat(pbTest); 2446 2447 /* 2448 * Slide the buffer towards the trailing guard page. We'll observe the 2449 * first word being written entirely separately from the 2nd dword/qword. 2450 */ 2451 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++) 2452 { 2453 Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2); 2454 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]); 2455 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2456 if (off + cbIdtr <= X86_PAGE_SIZE) 2457 { 2458 CtxUdExpected.rbx = Ctx.rbx; 2459 CtxUdExpected.ss = Ctx.ss; 2460 CtxUdExpected.ds = Ctx.ds; 2461 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2462 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 2463 Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 2464 } 2465 else 2466 { 2467 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), 2468 uFlatTest + RT_MAX(off, X86_PAGE_SIZE)); 2469 if ( off <= X86_PAGE_SIZE - 2 2470 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 2471 Bs3TestPrintf("Mismatch (#10): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n", 2472 pbExpected, &pbTest[off], off); 2473 if ( off < X86_PAGE_SIZE - 2 2474 && !ASMMemIsAllU8(&pbTest[off + 2], X86_PAGE_SIZE - off - 2, bFiller)) 2475 Bs3TestPrintf("Wrote partial base on #PF (#10): bFiller=%#x, got %.*Rhxs; off=%#x\n", 2476 bFiller, X86_PAGE_SIZE - off - 2, &pbTest[off + 2], off); 2477 if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller) 2478 Bs3TestPrintf("Wrote partial limit on #PF (#10): Expected %02x, got %02x\n", bFiller, pbTest[off]); 2479 } 2480 g_usBs3TestStep++; 2481 } 2482 2483 /* 2484 * Now, do it the other way around. It should look normal now since writing 2485 * the limit will #PF first and nothing should be written. 2486 */ 2487 for (off = cbIdtr + 4; off >= -cbIdtr - 4; off--) 2488 { 2489 Bs3MemSet(pbTest, bFiller, 48); 2490 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]); 2491 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2492 if (off >= 0) 2493 { 2494 CtxUdExpected.rbx = Ctx.rbx; 2495 CtxUdExpected.ss = Ctx.ss; 2496 CtxUdExpected.ds = Ctx.ds; 2497 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2498 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 2499 Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 2500 } 2501 else 2502 { 2503 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), uFlatTest + off); 2504 if ( -off < cbIdtr 2505 && !ASMMemIsAllU8(pbTest, cbIdtr + off, bFiller)) 2506 Bs3TestPrintf("Wrote partial content on #PF (#12): bFiller=%#x, found %.*Rhxs; off=%d\n", 2507 bFiller, cbIdtr + off, pbTest, off); 2508 } 2509 if (!ASMMemIsAllU8(&pbTest[RT_MAX(cbIdtr + off, 0)], 16, bFiller)) 2510 Bs3TestPrintf("Wrote beyond expected area (#13): bFiller=%#x, found %.16Rhxs; off=%d\n", 2511 bFiller, &pbTest[RT_MAX(cbIdtr + off, 0)], off); 2512 g_usBs3TestStep++; 2513 } 2514 2515 /* 2516 * Combine paging and segment limit and check ordering. 2517 * This is kind of interesting here since it the instruction seems to 2518 * be doing two separate writes. 2519 */ 2520 if ( !BS3_MODE_IS_RM_OR_V86(bTestMode) 2521 && !BS3_MODE_IS_64BIT_CODE(bTestMode)) 2522 { 2523 uint16_t cbLimit; 2524 2525 Bs3GdteTestPage00 = Bs3Gdte_DATA16; 2526 Bs3GdteTestPage00.Gen.u2Dpl = bRing; 2527 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatTest; 2528 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16); 2529 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24); 2530 2531 if (pWorker->fSs) 2532 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing; 2533 else 2534 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing; 2535 2536 /* Expand up (normal), approaching tail guard page. */ 2537 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++) 2538 { 2539 CtxUdExpected.rbx.u = Ctx.rbx.u = off; 2540 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++) 2541 { 2542 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit; 2543 Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2); 2544 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2545 if (off + cbIdtr <= cbLimit + 1) 2546 { 2547 /* No #GP, but maybe #PF. */ 2548 if (off + cbIdtr <= X86_PAGE_SIZE) 2549 { 2550 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2551 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 2552 Bs3TestFailedF("Mismatch (#14): expected %.*Rhxs, got %.*Rhxs\n", 2553 cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 2554 } 2555 else 2556 { 2557 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), 2558 uFlatTest + RT_MAX(off, X86_PAGE_SIZE)); 2559 if ( off <= X86_PAGE_SIZE - 2 2560 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 2561 Bs3TestPrintf("Mismatch (#15): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n", 2562 pbExpected, &pbTest[off], off); 2563 cb = X86_PAGE_SIZE - off - 2; 2564 if ( off < X86_PAGE_SIZE - 2 2565 && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller)) 2566 Bs3TestPrintf("Wrote partial base on #PF (#15): bFiller=%#x, got %.*Rhxs; off=%#x\n", 2567 bFiller, cb, &pbTest[off + 2], off); 2568 if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller) 2569 Bs3TestPrintf("Wrote partial limit on #PF (#15): Expected %02x, got %02x\n", bFiller, pbTest[off]); 2570 } 2571 } 2572 else if (off + 2 <= cbLimit + 1) 2573 { 2574 /* [ig]tr.limit writing does not cause #GP, but may cause #PG, if not writing the base causes #GP. */ 2575 if (off <= X86_PAGE_SIZE - 2) 2576 { 2577 if (pWorker->fSs) 2578 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/); 2579 else 2580 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2581 if (Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 2582 Bs3TestPrintf("Mismatch (#16): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n", 2583 pbExpected, &pbTest[off], off); 2584 cb = X86_PAGE_SIZE - off - 2; 2585 if ( off < X86_PAGE_SIZE - 2 2586 && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller)) 2587 Bs3TestPrintf("Wrote partial base with limit (#16): bFiller=%#x, got %.*Rhxs; off=%#x\n", 2588 bFiller, cb, &pbTest[off + 2], off); 2589 } 2590 else 2591 { 2592 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), 2593 uFlatTest + RT_MAX(off, X86_PAGE_SIZE)); 2594 if ( off < X86_PAGE_SIZE 2595 && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller)) 2596 Bs3TestPrintf("Mismatch (#16): Partial limit write on #PF: bFiller=%#x, got %.*Rhxs\n", 2597 bFiller, X86_PAGE_SIZE - off, &pbTest[off]); 2598 } 2599 } 2600 else 2601 { 2602 /* #GP/#SS on limit. */ 2603 if (pWorker->fSs) 2604 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/); 2605 else 2606 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2607 if ( off < X86_PAGE_SIZE 2608 && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller)) 2609 Bs3TestPrintf("Mismatch (#17): Partial write on #GP: bFiller=%#x, got %.*Rhxs\n", 2610 bFiller, X86_PAGE_SIZE - off, &pbTest[off]); 2611 } 2612 2613 cb = RT_MIN(cbIdtr * 2, off - (X86_PAGE_SIZE - cbIdtr*2)); 2614 if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], cb, bFiller)) 2615 Bs3TestFailedF("Leading bytes touched (#18): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n", 2616 cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE - cbIdtr * 2]); 2617 2618 g_usBs3TestStep++; 2619 2620 /* Set DS to 0 and check that we get #GP(0). */ 2621 if (!pWorker->fSs) 2622 { 2623 Ctx.ds = 0; 2624 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2625 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2626 Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing; 2627 g_usBs3TestStep++; 2628 } 2629 } 2630 } 2631 2632 /* Expand down. */ 2633 pbTest -= X86_PAGE_SIZE; /* Note! we're backing up a page to simplify things */ 2634 uFlatTest -= X86_PAGE_SIZE; 2635 2636 Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC; 2637 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatTest; 2638 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16); 2639 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24); 2640 2641 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++) 2642 { 2643 CtxUdExpected.rbx.u = Ctx.rbx.u = off; 2644 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++) 2645 { 2646 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit; 2647 Bs3MemSet(&pbTest[X86_PAGE_SIZE], bFiller, cbIdtr * 2); 2648 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2649 if (cbLimit < off && off >= X86_PAGE_SIZE) 2650 { 2651 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2652 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 2653 Bs3TestFailedF("Mismatch (#19): expected %.*Rhxs, got %.*Rhxs\n", 2654 cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 2655 cb = X86_PAGE_SIZE + cbIdtr*2 - off; 2656 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], cb, bFiller)) 2657 Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n", 2658 cbIdtr, off, cbLimit, bFiller, cb, pbTest[off + cbIdtr]); 2659 } 2660 else 2661 { 2662 if (cbLimit < off && off < X86_PAGE_SIZE) 2663 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), 2664 uFlatTest + off); 2665 else if (pWorker->fSs) 2666 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/); 2667 else 2668 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2669 cb = cbIdtr*2; 2670 if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE], cb, bFiller)) 2671 Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n", 2672 cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE]); 2673 } 2674 g_usBs3TestStep++; 2675 } 2676 } 2677 2678 pbTest += X86_PAGE_SIZE; 2679 uFlatTest += X86_PAGE_SIZE; 2680 } 2681 2682 Bs3MemGuardedTestPageFree(pbTest); 2683 } 2684 2685 /* 2686 * Check non-canonical 64-bit space. 2687 */ 2688 if ( BS3_MODE_IS_64BIT_CODE(bTestMode) 2689 && (pbTest = (uint8_t BS3_FAR *)Bs3PagingSetupCanonicalTraps()) != NULL) 2690 { 2691 /* Make our references relative to the gap. */ 2692 pbTest += g_cbBs3PagingOneCanonicalTrap; 2693 2694 /* Hit it from below. */ 2695 for (off = -cbIdtr - 8; off < cbIdtr + 8; off++) 2696 { 2697 Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0x0000800000000000) + off; 2698 Bs3MemSet(&pbTest[-64], bFiller, 64*2); 2699 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2700 if (off + cbIdtr <= 0) 2701 { 2702 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2703 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 2704 Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 2705 } 2706 else 2707 { 2708 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2709 if (off <= -2 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0) 2710 Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pbExpected, &pbTest[off]); 2711 off2 = off <= -2 ? 2 : 0; 2712 cb = cbIdtr - off2; 2713 if (!ASMMemIsAllU8(&pbTest[off + off2], cb, bFiller)) 2714 Bs3TestFailedF("Mismatch (#21): touched base %.*Rhxs, got %.*Rhxs\n", 2715 cb, &pbExpected[off], cb, &pbTest[off + off2]); 2716 } 2717 if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller)) 2718 Bs3TestFailedF("Leading bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]); 2719 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller)) 2720 Bs3TestFailedF("Trailing bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]); 2721 } 2722 2723 /* Hit it from above. */ 2724 for (off = -cbIdtr - 8; off < cbIdtr + 8; off++) 2725 { 2726 Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0xffff800000000000) + off; 2727 Bs3MemSet(&pbTest[-64], bFiller, 64*2); 2728 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2729 if (off >= 0) 2730 { 2731 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 2732 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0) 2733 Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]); 2734 } 2735 else 2736 { 2737 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 2738 if (!ASMMemIsAllU8(&pbTest[off], cbIdtr, bFiller)) 2739 Bs3TestFailedF("Mismatch (#22): touched base %.*Rhxs, got %.*Rhxs\n", 2740 cbIdtr, &pbExpected[off], cbIdtr, &pbTest[off]); 2741 } 2742 if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller)) 2743 Bs3TestFailedF("Leading bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]); 2744 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller)) 2745 Bs3TestFailedF("Trailing bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]); 2746 } 2747 2748 } 2749 #endif 2750 } 2751 2752 2753 # define bs3CpuBasic2_lidt_lgdt_Common BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_Common) 2754 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers, 2755 void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected) 2756 { 2757 unsigned idx; 2758 unsigned bRing; 2759 unsigned iStep = 0; 2760 2761 /* Note! We skip the SS checks for ring-0 since we badly mess up SS in the 2762 test and don't want to bother with double faults. */ 2763 for (bRing = BS3_MODE_IS_V86(bTestMode) ? 3 : 0; bRing <= 3; bRing++) 2764 { 2765 for (idx = 0; idx < cWorkers; idx++) 2766 if ( (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK)) 2767 && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ )) 2768 { 2769 //Bs3TestPrintf("idx=%-2d fpfnWorker=%p fSs=%d cbInstr=%d\n", 2770 // idx, paWorkers[idx].fpfnWorker, paWorkers[idx].fSs, paWorkers[idx].cbInstr); 2771 g_usBs3TestStep = iStep; 2772 bs3CpuBasic2_lidt_lgdt_One(&paWorkers[idx], bTestMode, bRing, pvRestore, cbRestore, pbExpected); 2773 iStep += 1000; 2774 } 2775 if (BS3_MODE_IS_RM_SYS(bTestMode)) 1979 2776 break; 1980 2777 } … … 2230 3027 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode) 2231 3028 { 2232 //if (bMode == BS3_MODE_LM64)2233 {2234 3029 union 2235 3030 { … … 2255 3050 */ 2256 3051 Bs3TrapInit(); 2257 }2258 2259 3052 return 0; 2260 3053 } … … 2262 3055 2263 3056 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode) 2264 {2265 //if (bMode >= BS3_MODE_LM16)2266 3057 { 2267 3058 uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr; … … 2316 3107 */ 2317 3108 Bs3TrapInit(); 2318 }2319 3109 return 0; 2320 3110 } 2321 3111 3112 3113 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode) 3114 { 3115 union 3116 { 3117 RTIDTR Idtr; 3118 uint8_t ab[32]; /* At least cbIdtr*2! */ 3119 } Expected; 3120 3121 g_pszTestMode = TMPL_NM(g_szBs3ModeName); 3122 g_bTestMode = bMode; 3123 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(TMPL_MODE); 3124 3125 BS3_ASSERT(bMode == TMPL_MODE); 3126 3127 /* 3128 * Pass to common worker which is only compiled once per mode. 3129 */ 3130 Bs3MemZero(&Expected, sizeof(Expected)); 3131 ASMGetIDTR(&Expected.Idtr); 3132 3133 if (BS3_MODE_IS_RM_SYS(bMode)) 3134 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers), 3135 &Bs3Lidt_Ivt, sizeof(Bs3Lidt_Ivt), Expected.ab); 3136 else if (BS3_MODE_IS_16BIT_SYS(bMode)) 3137 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers), 3138 &Bs3Lidt_Idt16, sizeof(Bs3Lidt_Idt16), Expected.ab); 3139 else if (BS3_MODE_IS_32BIT_SYS(bMode)) 3140 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers), 3141 &Bs3Lidt_Idt32, sizeof(Bs3Lidt_Idt32), Expected.ab); 3142 else 3143 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers), 3144 &Bs3Lidt_Idt64, sizeof(Bs3Lidt_Idt64), Expected.ab); 3145 3146 /* 3147 * Re-initialize the IDT. 3148 */ 3149 Bs3TrapInit(); 3150 return 0; 3151 } 3152 3153 #if 0 3154 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode) 3155 { 3156 uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr; 3157 uint64_t uNew = 0; 3158 union 3159 { 3160 RTGDTR Gdtr; 3161 uint8_t ab[16]; 3162 } Expected; 3163 3164 g_pszTestMode = TMPL_NM(g_szBs3ModeName); 3165 g_bTestMode = bMode; 3166 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(TMPL_MODE); 3167 BS3_ASSERT(bMode == TMPL_MODE); 3168 3169 /* 3170 * Pass to common worker which is only compiled once per mode. 3171 */ 3172 Bs3MemZero(&Expected, sizeof(Expected)); 3173 ASMGetGDTR(&Expected.Gdtr); 3174 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab); 3175 3176 /* 3177 * Unalias the GDT. 3178 */ 3179 if (uNew != 0) 3180 { 3181 Bs3Lgdt_Gdt.uAddr = uOrgAddr; 3182 Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uOrgAddr); 3183 Bs3PagingUnalias(uNew, Bs3Lgdt_Gdt.cb); 3184 } 3185 3186 /* 3187 * Re-initialize the IDT. 3188 */ 3189 Bs3TrapInit(); 3190 return 0; 3191 } 3192 #endif 3193 2322 3194 #endif /* BS3_INSTANTIATING_MODE */ 2323 3195 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.mac
r60679 r60724 26 26 27 27 28 ;********************************************************************************************************************************* 29 ;* Header Files * 30 ;********************************************************************************************************************************* 28 31 %include "bs3kit-template-header.mac" ; setup environment 29 32 30 33 31 34 ;********************************************************************************************************************************* 32 ;* External Symbols * 33 ;********************************************************************************************************************************* 34 %undef Bs3Printf 35 BS3_EXTERN_CMN Bs3Printf 36 37 38 35 ;* External Symbols * 36 ;********************************************************************************************************************************* 39 37 TMPL_BEGIN_TEXT 40 41 ;42 ; Code that is instantiated for every possible CPU mode43 ;44 %ifdef BS3_INSTANTIATING_MODE45 46 %if 0 ; Will be doing the testing in C, I think.47 BS3_PROC_BEGIN_MODE bs3CpuBasic2_iret, BS3_PBC_FAR48 BS3_CALL_CONV_PROLOG 149 push xBP50 mov xBP, xSP51 sub xSP, 20h52 53 %if TMPL_BITS == 6454 %if TMPL_BITS == 1655 xor ax, ax56 mov al, [xBP + xCB*2]57 push ax58 push cs59 push .szMsg wrt BS3TEXT1660 call Bs3Printf61 add sp, 662 %else63 movzx xDX, byte [xBP + xCB*2]64 push xDX65 push .szMsg wrt FLAT66 BS3_CALL Bs3Printf, 267 add xSP, xCB * 268 %endif69 %endif70 71 ; Return72 xor al, al73 ;mov al, TMPL_MODE ; remove me74 75 76 mov xSP, xBP77 pop xBP78 BS3_CALL_CONV_EPILOG 179 ret80 .szMsg: db 'hello world %#x!', 13, 10, 081 82 BS3_PROC_END_MODE bs3CpuBasic2_iret83 %endif84 85 %endif ; BS3_INSTANTIATING_MODE86 38 87 39 … … 110 62 BS3_PROC_END_CMN bs3CpuBasic2_sidt_opsize_bx_ud2 111 63 112 %if TMPL_BITS == 6464 %if TMPL_BITS == 64 113 65 BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_rexw_bx_ud2, BS3_PBC_NEAR 114 66 db X86_OP_REX_W … … 127 79 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_rexw_bx_ud2) == 5) 128 80 BS3_PROC_END_CMN bs3CpuBasic2_sidt_opsize_rexw_bx_ud2 129 %endif130 131 %if TMPL_BITS != 6481 %endif 82 83 %if TMPL_BITS != 64 132 84 BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_ss_bx_ud2, BS3_PBC_NEAR 133 85 sidt [ss:xBX] … … 144 96 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_ss_bx_ud2) == 5) 145 97 BS3_PROC_END_CMN bs3CpuBasic2_sidt_opsize_ss_bx_ud2 146 %endif 98 %endif 99 147 100 148 101 ; … … 164 117 BS3_PROC_END_CMN bs3CpuBasic2_sgdt_opsize_bx_ud2 165 118 166 %if TMPL_BITS == 64119 %if TMPL_BITS == 64 167 120 BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_rexw_bx_ud2, BS3_PBC_NEAR 168 121 db X86_OP_REX_W … … 181 134 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2) == 5) 182 135 BS3_PROC_END_CMN bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2 183 %endif184 185 %if TMPL_BITS != 64136 %endif 137 138 %if TMPL_BITS != 64 186 139 BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_ss_bx_ud2, BS3_PBC_NEAR 187 140 sgdt [ss:xBX] … … 198 151 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_ss_bx_ud2) == 5) 199 152 BS3_PROC_END_CMN bs3CpuBasic2_sgdt_opsize_ss_bx_ud2 200 %endif 201 202 203 ; 204 ; 205 ; 206 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_bx_ud2, BS3_PBC_NEAR 207 lidt [xBX] 208 .again: ud2 209 jmp .again 210 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_bx_ud2) == 3) 211 BS3_PROC_END_CMN bs3CpuBasic2_lidt_bx_ud2 153 %endif 154 155 156 ; 157 ; LIDT 158 ; 159 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR 160 lidt [xBX] 161 sidt [BS3_NOT_64BIT(es:) xDI] 162 lidt [BS3_NOT_64BIT(es:) xSI] 163 .again: 164 ud2 165 jmp .again 166 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(9,11)) 167 BS3_PROC_END_CMN bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2 168 169 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR 170 db X86_OP_PRF_SIZE_OP 171 lidt [xBX] 172 sidt [BS3_NOT_64BIT(es:) xDI] 173 lidt [BS3_NOT_64BIT(es:) xSI] 174 .again: 175 ud2 176 jmp .again 177 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(10,12)) 178 BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2 179 180 %if TMPL_BITS == 64 181 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR 182 db X86_OP_REX_W 183 lidt [xBX] 184 sidt [xDI] 185 lidt [xSI] 186 .again: 187 ud2 188 jmp .again 189 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2) == 10) 190 BS3_PROC_END_CMN bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2 191 192 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR 193 db X86_OP_PRF_SIZE_OP 194 db X86_OP_REX_W 195 lidt [xBX] 196 sidt [xDI] 197 lidt [xSI] 198 .again: 199 ud2 200 jmp .again 201 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2) == 11) 202 BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2 203 %endif 204 205 %if TMPL_BITS != 64 206 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR 207 lidt [ss:xBX] 208 sidt [BS3_NOT_64BIT(es:) xDI] 209 lidt [BS3_NOT_64BIT(es:) xSI] 210 .again: 211 ud2 212 jmp .again 213 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2) == 12) 214 BS3_PROC_END_CMN bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2 215 216 BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR 217 db X86_OP_PRF_SIZE_OP 218 lidt [ss:xBX] 219 sidt [BS3_NOT_64BIT(es:) xDI] 220 lidt [BS3_NOT_64BIT(es:) xSI] 221 .again: 222 ud2 223 jmp .again 224 AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2) == 13) 225 BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2 226 %endif 227 212 228 213 229 %endif ; BS3_INSTANTIATING_CMN -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c
r60680 r60724 42 42 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sidt); 43 43 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sgdt); 44 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lidt); 45 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lgdt); 44 46 45 47 … … 50 52 { 51 53 //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp), 52 // BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),53 54 //BS3TESTMODEENTRY_CMN("iret", bs3CpuBasic2_iret), 54 55 // BS3TESTMODEENTRY_MODE("iret", bs3CpuBasic2_iret), 56 #if 0 57 BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1), 55 58 BS3TESTMODEENTRY_MODE("sidt", bs3CpuBasic2_sidt), 56 59 BS3TESTMODEENTRY_MODE("sgdt", bs3CpuBasic2_sgdt), 60 #endif 61 BS3TESTMODEENTRY_MODE("lidt", bs3CpuBasic2_lidt), 57 62 }; 58 63 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac
r60557 r60724 198 198 section BS3TEXT32_END align=1 CLASS=BS3CLASS32CODE PUBLIC USE32 FLAT 199 199 BS3_GLOBAL_DATA Bs3Text32_EndOfSegment, 0 200 201 202 ; 203 ; This is a hack to separate the 32-bit and 64-bit text segments when linking, 204 ; such that they don't share the same base frame because they're both assigned 205 ; to the AUTO group by the linker. 206 ; 207 section BS3SEPARATE32AND64BITCODE align=16 CLASS=BS3CLASSSEPARATE32AND64BITCODE PUBLIC USE16 208 BS3_GLOBAL_DATA Bs3Separate32And64BitCode_StartOfSegment, 0 209 db 10,13,'eye-catcher: 32-64 wedge',10,13 210 section BS3SEPARATE32AND64BITCODE_END align=16 CLASS=BS3CLASSSEPARATE32AND64BITCODE PUBLIC USE16 211 BS3_GLOBAL_DATA Bs3Separate32And64BitCode_EndOfSegment, 0 212 GROUP BS3SEPARATE32AND64BITCODEGROUP BS3SEPARATE32AND64BITCODE BS3SEPARATE32AND64BITCODE_END 200 213 201 214 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm
r60686 r60724 997 997 ; LIDT structure for the real mode IVT at address 0x00000000 (8-byte aligned on offset). 998 998 BS3_GLOBAL_DATA Bs3Lidt_Ivt, 2+8 999 dw 256*4 - 1; limit999 dw 0ffffh ; limit 1000 1000 dw 0 ; low offset 1001 1001 dw 0 ; high offset -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac
r60676 r60724 228 228 229 229 %undef BS3_IF_64BIT_OTHERWISE 230 %if %1 == 32231 %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_ 32BitExpr230 %if %1 == 64 231 %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_64BitExpr 232 232 %else 233 233 %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_OtherwiseExpr
Note:
See TracChangeset
for help on using the changeset viewer.