Changeset 2426 in vbox for trunk/src/recompiler/target-i386
- Timestamp:
- Apr 30, 2007 12:36:15 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 20835
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler/target-i386/helper.c
r1953 r2426 18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 #ifdef VBOX 21 # include <VBox/err.h> 22 #endif 20 23 #include "exec.h" 21 #ifdef VBOX22 #include <VBox/err.h>23 #endif24 24 25 25 //#define DEBUG_PCALL … … 28 28 #define raise_exception_err(a, b)\ 29 29 do {\ 30 fprintf(logfile, "raise_exception line=%d\n", __LINE__);\ 30 if (logfile)\ 31 fprintf(logfile, "raise_exception line=%d\n", __LINE__);\ 31 32 (raise_exception_err)(a, b);\ 32 33 } while (0) … … 224 225 if ((e2 & DESC_C_MASK) && dpl > rpl) 225 226 raise_exception_err(EXCP0A_TSS, selector & 0xfffc); 226 227 227 } else if (seg_reg == R_SS) { 228 228 /* SS must be writable data */ … … 380 380 for(i = 0; i < 6; i++) 381 381 stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector); 382 383 382 #if defined(VBOX) && defined(DEBUG) 384 383 printf("TSS 32 bits switch\n"); 385 384 printf("Saving CS=%08X\n", env->segs[R_CS].selector); 386 385 #endif 387 388 386 } else { 389 387 /* 16 bit */ … … 567 565 } 568 566 567 #ifdef TARGET_X86_64 568 #define SET_ESP(val, sp_mask)\ 569 do {\ 570 if ((sp_mask) == 0xffff)\ 571 ESP = (ESP & ~0xffff) | ((val) & 0xffff);\ 572 else if ((sp_mask) == 0xffffffffLL)\ 573 ESP = (uint32_t)(val);\ 574 else\ 575 ESP = (val);\ 576 } while (0) 577 #else 578 #define SET_ESP(val, sp_mask) ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask)) 579 #endif 580 569 581 /* XXX: add a is_user flag to have proper security support */ 570 582 #define PUSHW(ssp, sp, sp_mask, val)\ … … 598 610 SegmentCache *dt; 599 611 target_ulong ptr, ssp; 600 int type, dpl, selector, ss_dpl, cpl , sp_mask;612 int type, dpl, selector, ss_dpl, cpl; 601 613 int has_error_code, new_stack, shift; 602 614 uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2; 603 uint32_t old_eip ;615 uint32_t old_eip, sp_mask; 604 616 605 617 #ifdef VBOX … … 642 654 switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip); 643 655 if (has_error_code) { 644 int mask, type; 656 int type; 657 uint32_t mask; 645 658 /* push the error code */ 646 659 type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; … … 656 669 else 657 670 stw_kernel(ssp, error_code); 658 ESP = (esp & mask) | (ESP & ~mask);671 SET_ESP(esp, mask); 659 672 } 660 673 return; … … 787 800 ssp, get_seg_limit(ss_e1, ss_e2), ss_e2); 788 801 } 789 ESP = (ESP & ~sp_mask) | (esp &sp_mask);802 SET_ESP(esp, sp_mask); 790 803 791 804 selector = (selector & ~3) | dpl; … … 896 909 env->eflags &= ~IF_MASK; 897 910 } 898 #endif 911 #endif /* VBOX */ 899 912 900 913 #ifdef TARGET_X86_64 … … 1078 1091 cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, 1079 1092 0, 0xffffffff, 1080 DESC_G_MASK | DESC_ B_MASK | DESC_P_MASK |1093 DESC_G_MASK | DESC_P_MASK | 1081 1094 DESC_S_MASK | 1082 1095 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); … … 1129 1142 cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3, 1130 1143 0, 0xffffffff, 1131 DESC_G_MASK | DESC_ B_MASK | DESC_P_MASK |1144 DESC_G_MASK | DESC_P_MASK | 1132 1145 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 1133 1146 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | … … 1184 1197 void helper_external_event(void) 1185 1198 { 1199 #if defined(__DARWIN__) && defined(VBOX_STRICT) 1200 # if 0 1201 //uintptr_t uFrameAddr = (uintptr_t)__builtin_frame_address(0); - this is broken (uses %ebp) 1202 //AssertMsg(!( (uFrameAddr - sizeof(uintptr_t)) & 7 ), ("uFrameAddr=%#p\n", uFrameAddr)); 1203 # else 1204 uintptr_t uESP; 1205 __asm__ __volatile__("movl %%esp, %0" : "=r" (uESP)); 1206 AssertMsg(!(uESP & 15), ("esp=%#p\n", uESP)); 1207 # endif 1208 #endif 1186 1209 if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD) 1187 1210 { … … 1278 1301 target_ulong next_eip, int is_hw) 1279 1302 { 1280 #ifdef DEBUG_PCALL 1281 if (loglevel & (CPU_LOG_PCALL | CPU_LOG_INT)) { 1303 if (loglevel & CPU_LOG_INT) { 1282 1304 if ((env->cr[0] & CR0_PE_MASK)) { 1283 1305 static int count; … … 1294 1316 } 1295 1317 fprintf(logfile, "\n"); 1318 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); 1296 1319 #if 0 1297 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);1298 1320 { 1299 1321 int i; … … 1310 1332 } 1311 1333 } 1312 #endif1313 1334 if (env->cr[0] & CR0_PE_MASK) { 1314 1335 #if TARGET_X86_64 … … 1328 1349 do_soft_interrupt_vme(intno, error_code, next_eip); 1329 1350 else 1330 #endif 1351 #endif /* VBOX */ 1331 1352 do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw); 1332 1353 } … … 1376 1397 raise_interrupt(exception_index, 0, 0, 0); 1377 1398 } 1399 1400 /* SMM support */ 1401 1402 #if defined(CONFIG_USER_ONLY) 1403 1404 void do_smm_enter(void) 1405 { 1406 } 1407 1408 void helper_rsm(void) 1409 { 1410 } 1411 1412 #else 1413 1414 #ifdef TARGET_X86_64 1415 #define SMM_REVISION_ID 0x00020064 1416 #else 1417 #define SMM_REVISION_ID 0x00020000 1418 #endif 1419 1420 void do_smm_enter(void) 1421 { 1422 #ifdef VBOX 1423 cpu_abort(env, "do_ssm_enter"); 1424 #else /* !VBOX */ 1425 target_ulong sm_state; 1426 SegmentCache *dt; 1427 int i, offset; 1428 1429 if (loglevel & CPU_LOG_INT) { 1430 fprintf(logfile, "SMM: enter\n"); 1431 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); 1432 } 1433 1434 env->hflags |= HF_SMM_MASK; 1435 cpu_smm_update(env); 1436 1437 sm_state = env->smbase + 0x8000; 1438 1439 #ifdef TARGET_X86_64 1440 for(i = 0; i < 6; i++) { 1441 dt = &env->segs[i]; 1442 offset = 0x7e00 + i * 16; 1443 stw_phys(sm_state + offset, dt->selector); 1444 stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff); 1445 stl_phys(sm_state + offset + 4, dt->limit); 1446 stq_phys(sm_state + offset + 8, dt->base); 1447 } 1448 1449 stq_phys(sm_state + 0x7e68, env->gdt.base); 1450 stl_phys(sm_state + 0x7e64, env->gdt.limit); 1451 1452 stw_phys(sm_state + 0x7e70, env->ldt.selector); 1453 stq_phys(sm_state + 0x7e78, env->ldt.base); 1454 stl_phys(sm_state + 0x7e74, env->ldt.limit); 1455 stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff); 1456 1457 stq_phys(sm_state + 0x7e88, env->idt.base); 1458 stl_phys(sm_state + 0x7e84, env->idt.limit); 1459 1460 stw_phys(sm_state + 0x7e90, env->tr.selector); 1461 stq_phys(sm_state + 0x7e98, env->tr.base); 1462 stl_phys(sm_state + 0x7e94, env->tr.limit); 1463 stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff); 1464 1465 stq_phys(sm_state + 0x7ed0, env->efer); 1466 1467 stq_phys(sm_state + 0x7ff8, EAX); 1468 stq_phys(sm_state + 0x7ff0, ECX); 1469 stq_phys(sm_state + 0x7fe8, EDX); 1470 stq_phys(sm_state + 0x7fe0, EBX); 1471 stq_phys(sm_state + 0x7fd8, ESP); 1472 stq_phys(sm_state + 0x7fd0, EBP); 1473 stq_phys(sm_state + 0x7fc8, ESI); 1474 stq_phys(sm_state + 0x7fc0, EDI); 1475 for(i = 8; i < 16; i++) 1476 stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]); 1477 stq_phys(sm_state + 0x7f78, env->eip); 1478 stl_phys(sm_state + 0x7f70, compute_eflags()); 1479 stl_phys(sm_state + 0x7f68, env->dr[6]); 1480 stl_phys(sm_state + 0x7f60, env->dr[7]); 1481 1482 stl_phys(sm_state + 0x7f48, env->cr[4]); 1483 stl_phys(sm_state + 0x7f50, env->cr[3]); 1484 stl_phys(sm_state + 0x7f58, env->cr[0]); 1485 1486 stl_phys(sm_state + 0x7efc, SMM_REVISION_ID); 1487 stl_phys(sm_state + 0x7f00, env->smbase); 1488 #else 1489 stl_phys(sm_state + 0x7ffc, env->cr[0]); 1490 stl_phys(sm_state + 0x7ff8, env->cr[3]); 1491 stl_phys(sm_state + 0x7ff4, compute_eflags()); 1492 stl_phys(sm_state + 0x7ff0, env->eip); 1493 stl_phys(sm_state + 0x7fec, EDI); 1494 stl_phys(sm_state + 0x7fe8, ESI); 1495 stl_phys(sm_state + 0x7fe4, EBP); 1496 stl_phys(sm_state + 0x7fe0, ESP); 1497 stl_phys(sm_state + 0x7fdc, EBX); 1498 stl_phys(sm_state + 0x7fd8, EDX); 1499 stl_phys(sm_state + 0x7fd4, ECX); 1500 stl_phys(sm_state + 0x7fd0, EAX); 1501 stl_phys(sm_state + 0x7fcc, env->dr[6]); 1502 stl_phys(sm_state + 0x7fc8, env->dr[7]); 1503 1504 stl_phys(sm_state + 0x7fc4, env->tr.selector); 1505 stl_phys(sm_state + 0x7f64, env->tr.base); 1506 stl_phys(sm_state + 0x7f60, env->tr.limit); 1507 stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff); 1508 1509 stl_phys(sm_state + 0x7fc0, env->ldt.selector); 1510 stl_phys(sm_state + 0x7f80, env->ldt.base); 1511 stl_phys(sm_state + 0x7f7c, env->ldt.limit); 1512 stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff); 1513 1514 stl_phys(sm_state + 0x7f74, env->gdt.base); 1515 stl_phys(sm_state + 0x7f70, env->gdt.limit); 1516 1517 stl_phys(sm_state + 0x7f58, env->idt.base); 1518 stl_phys(sm_state + 0x7f54, env->idt.limit); 1519 1520 for(i = 0; i < 6; i++) { 1521 dt = &env->segs[i]; 1522 if (i < 3) 1523 offset = 0x7f84 + i * 12; 1524 else 1525 offset = 0x7f2c + (i - 3) * 12; 1526 stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector); 1527 stl_phys(sm_state + offset + 8, dt->base); 1528 stl_phys(sm_state + offset + 4, dt->limit); 1529 stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff); 1530 } 1531 stl_phys(sm_state + 0x7f14, env->cr[4]); 1532 1533 stl_phys(sm_state + 0x7efc, SMM_REVISION_ID); 1534 stl_phys(sm_state + 0x7ef8, env->smbase); 1535 #endif 1536 /* init SMM cpu state */ 1537 1538 #ifdef TARGET_X86_64 1539 env->efer = 0; 1540 env->hflags &= ~HF_LMA_MASK; 1541 #endif 1542 load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 1543 env->eip = 0x00008000; 1544 cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase, 1545 0xffffffff, 0); 1546 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0); 1547 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0); 1548 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0); 1549 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0); 1550 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0); 1551 1552 cpu_x86_update_cr0(env, 1553 env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK)); 1554 cpu_x86_update_cr4(env, 0); 1555 env->dr[7] = 0x00000400; 1556 CC_OP = CC_OP_EFLAGS; 1557 #endif /* VBOX */ 1558 } 1559 1560 void helper_rsm(void) 1561 { 1562 #ifdef VBOX 1563 cpu_abort(env, "helper_rsm"); 1564 #else /* !VBOX */ 1565 target_ulong sm_state; 1566 int i, offset; 1567 uint32_t val; 1568 1569 sm_state = env->smbase + 0x8000; 1570 #ifdef TARGET_X86_64 1571 env->efer = ldq_phys(sm_state + 0x7ed0); 1572 if (env->efer & MSR_EFER_LMA) 1573 env->hflags |= HF_LMA_MASK; 1574 else 1575 env->hflags &= ~HF_LMA_MASK; 1576 1577 for(i = 0; i < 6; i++) { 1578 offset = 0x7e00 + i * 16; 1579 cpu_x86_load_seg_cache(env, i, 1580 lduw_phys(sm_state + offset), 1581 ldq_phys(sm_state + offset + 8), 1582 ldl_phys(sm_state + offset + 4), 1583 (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8); 1584 } 1585 1586 env->gdt.base = ldq_phys(sm_state + 0x7e68); 1587 env->gdt.limit = ldl_phys(sm_state + 0x7e64); 1588 1589 env->ldt.selector = lduw_phys(sm_state + 0x7e70); 1590 env->ldt.base = ldq_phys(sm_state + 0x7e78); 1591 env->ldt.limit = ldl_phys(sm_state + 0x7e74); 1592 env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8; 1593 1594 env->idt.base = ldq_phys(sm_state + 0x7e88); 1595 env->idt.limit = ldl_phys(sm_state + 0x7e84); 1596 1597 env->tr.selector = lduw_phys(sm_state + 0x7e90); 1598 env->tr.base = ldq_phys(sm_state + 0x7e98); 1599 env->tr.limit = ldl_phys(sm_state + 0x7e94); 1600 env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; 1601 1602 EAX = ldq_phys(sm_state + 0x7ff8); 1603 ECX = ldq_phys(sm_state + 0x7ff0); 1604 EDX = ldq_phys(sm_state + 0x7fe8); 1605 EBX = ldq_phys(sm_state + 0x7fe0); 1606 ESP = ldq_phys(sm_state + 0x7fd8); 1607 EBP = ldq_phys(sm_state + 0x7fd0); 1608 ESI = ldq_phys(sm_state + 0x7fc8); 1609 EDI = ldq_phys(sm_state + 0x7fc0); 1610 for(i = 8; i < 16; i++) 1611 env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8); 1612 env->eip = ldq_phys(sm_state + 0x7f78); 1613 load_eflags(ldl_phys(sm_state + 0x7f70), 1614 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 1615 env->dr[6] = ldl_phys(sm_state + 0x7f68); 1616 env->dr[7] = ldl_phys(sm_state + 0x7f60); 1617 1618 cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48)); 1619 cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50)); 1620 cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58)); 1621 1622 val = ldl_phys(sm_state + 0x7efc); /* revision ID */ 1623 if (val & 0x20000) { 1624 env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff; 1625 } 1626 #else 1627 cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc)); 1628 cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8)); 1629 load_eflags(ldl_phys(sm_state + 0x7ff4), 1630 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 1631 env->eip = ldl_phys(sm_state + 0x7ff0); 1632 EDI = ldl_phys(sm_state + 0x7fec); 1633 ESI = ldl_phys(sm_state + 0x7fe8); 1634 EBP = ldl_phys(sm_state + 0x7fe4); 1635 ESP = ldl_phys(sm_state + 0x7fe0); 1636 EBX = ldl_phys(sm_state + 0x7fdc); 1637 EDX = ldl_phys(sm_state + 0x7fd8); 1638 ECX = ldl_phys(sm_state + 0x7fd4); 1639 EAX = ldl_phys(sm_state + 0x7fd0); 1640 env->dr[6] = ldl_phys(sm_state + 0x7fcc); 1641 env->dr[7] = ldl_phys(sm_state + 0x7fc8); 1642 1643 env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff; 1644 env->tr.base = ldl_phys(sm_state + 0x7f64); 1645 env->tr.limit = ldl_phys(sm_state + 0x7f60); 1646 env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8; 1647 1648 env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff; 1649 env->ldt.base = ldl_phys(sm_state + 0x7f80); 1650 env->ldt.limit = ldl_phys(sm_state + 0x7f7c); 1651 env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8; 1652 1653 env->gdt.base = ldl_phys(sm_state + 0x7f74); 1654 env->gdt.limit = ldl_phys(sm_state + 0x7f70); 1655 1656 env->idt.base = ldl_phys(sm_state + 0x7f58); 1657 env->idt.limit = ldl_phys(sm_state + 0x7f54); 1658 1659 for(i = 0; i < 6; i++) { 1660 if (i < 3) 1661 offset = 0x7f84 + i * 12; 1662 else 1663 offset = 0x7f2c + (i - 3) * 12; 1664 cpu_x86_load_seg_cache(env, i, 1665 ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff, 1666 ldl_phys(sm_state + offset + 8), 1667 ldl_phys(sm_state + offset + 4), 1668 (ldl_phys(sm_state + offset) & 0xf0ff) << 8); 1669 } 1670 cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14)); 1671 1672 val = ldl_phys(sm_state + 0x7efc); /* revision ID */ 1673 if (val & 0x20000) { 1674 env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff; 1675 } 1676 #endif 1677 CC_OP = CC_OP_EFLAGS; 1678 env->hflags &= ~HF_SMM_MASK; 1679 cpu_smm_update(env); 1680 1681 if (loglevel & CPU_LOG_INT) { 1682 fprintf(logfile, "SMM: after RSM\n"); 1683 cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP); 1684 } 1685 #endif /* !VBOX */ 1686 } 1687 1688 #endif /* !CONFIG_USER_ONLY */ 1689 1378 1690 1379 1691 #ifdef BUGGY_GCC_DIV64 … … 1458 1770 { 1459 1771 #ifndef VBOX 1460 switch((uint32_t)EAX) { 1772 uint32_t index; 1773 index = (uint32_t)EAX; 1774 1775 /* test if maximum index reached */ 1776 if (index & 0x80000000) { 1777 if (index > env->cpuid_xlevel) 1778 index = env->cpuid_level; 1779 } else { 1780 if (index > env->cpuid_level) 1781 index = env->cpuid_level; 1782 } 1783 1784 switch(index) { 1461 1785 case 0: 1462 EAX = 2; /* max EAX index supported */1786 EAX = env->cpuid_level; 1463 1787 EBX = env->cpuid_vendor1; 1464 1788 EDX = env->cpuid_vendor2; … … 1467 1791 case 1: 1468 1792 EAX = env->cpuid_version; 1469 EBX = 0;1793 EBX = 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */ 1470 1794 ECX = env->cpuid_ext_features; 1471 1795 EDX = env->cpuid_features; 1472 1796 break; 1473 1474 default: 1797 case 2: 1475 1798 /* cache info: needed for Pentium Pro compatibility */ 1476 1799 EAX = 0x410601; … … 1479 1802 EDX = 0; 1480 1803 break; 1481 1482 #ifdef TARGET_X86_641483 1804 case 0x80000000: 1484 EAX = 0x80000008;1805 EAX = env->cpuid_xlevel; 1485 1806 EBX = env->cpuid_vendor1; 1486 1807 EDX = env->cpuid_vendor2; … … 1491 1812 EBX = 0; 1492 1813 ECX = 0; 1493 /* long mode + syscall/sysret features */ 1494 EDX = (env->cpuid_features & 0x0183F3FF) | (1 << 29) | (1 << 11); 1814 EDX = env->cpuid_ext2_features; 1815 break; 1816 case 0x80000002: 1817 case 0x80000003: 1818 case 0x80000004: 1819 EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0]; 1820 EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1]; 1821 ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2]; 1822 EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3]; 1823 break; 1824 case 0x80000005: 1825 /* cache info (L1 cache) */ 1826 EAX = 0x01ff01ff; 1827 EBX = 0x01ff01ff; 1828 ECX = 0x40020140; 1829 EDX = 0x40020140; 1830 break; 1831 case 0x80000006: 1832 /* cache info (L2 cache) */ 1833 EAX = 0; 1834 EBX = 0x42004200; 1835 ECX = 0x02008140; 1836 EDX = 0; 1495 1837 break; 1496 1838 case 0x80000008: … … 1501 1843 EDX = 0; 1502 1844 break; 1503 #endif 1845 default: 1846 /* reserved values: zero */ 1847 EAX = 0; 1848 EBX = 0; 1849 ECX = 0; 1850 EDX = 0; 1851 break; 1504 1852 } 1505 1853 #else /* VBOX */ … … 1634 1982 int index, type, entry_limit; 1635 1983 target_ulong ptr; 1984 1636 1985 #ifdef VBOX 1637 1986 Log(("helper_ltr_T0: old tr=%RTsel {.base=%VGv, .limit=%VGv, .flags=%RX32} new=%RTsel\n", … … 1750 2099 if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { 1751 2100 /* if not conforming code, test rights */ 1752 if (dpl < cpl || dpl < rpl) 2101 if (dpl < cpl || dpl < rpl) 1753 2102 raise_exception_err(EXCP0D_GPF, selector & 0xfffc); 1754 2103 } … … 1890 2239 } 1891 2240 1892 ESP = (ESP & ~esp_mask) | (esp &esp_mask);2241 SET_ESP(esp, esp_mask); 1893 2242 env->eip = new_eip; 1894 2243 env->segs[R_CS].selector = new_cs; … … 1976 2325 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); 1977 2326 /* from this point, not restartable */ 1978 ESP = (ESP & ~sp_mask) | (sp &sp_mask);2327 SET_ESP(sp, sp_mask); 1979 2328 cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, 1980 2329 get_seg_base(e1, e2), limit, e2); … … 2105 2454 e2); 2106 2455 cpu_x86_set_cpl(env, dpl); 2107 ESP = (ESP & ~sp_mask) | (sp &sp_mask);2456 SET_ESP(sp, sp_mask); 2108 2457 EIP = offset; 2109 2458 } … … 2122 2471 target_ulong ssp; 2123 2472 int eflags_mask; 2124 2125 2473 #ifdef VBOX 2126 2474 bool fVME = false; 2127 2475 2128 2476 remR3TrapClear(env->pVM); 2129 #endif 2477 #endif /* VBOX */ 2130 2478 2131 2479 sp_mask = 0xffff; /* XXXX: use SS segment size ? */ … … 2154 2502 if ( ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK)) 2155 2503 || (new_eflags & TF_MASK)) 2156 {2157 2504 raise_exception(EXCP0D_GPF); 2158 } 2159 } 2160 #endif 2505 } 2506 #endif /* VBOX */ 2161 2507 2162 2508 ESP = (ESP & ~sp_mask) | (sp & sp_mask); … … 2174 2520 if (shift == 0) 2175 2521 eflags_mask &= 0xffff; 2176 2177 2522 load_eflags(new_eflags, eflags_mask); 2178 2523 … … 2185 2530 env->eflags &= ~VIF_MASK; 2186 2531 } 2187 #endif 2532 #endif /* VBOX */ 2188 2533 } 2189 2534 … … 2192 2537 int dpl; 2193 2538 uint32_t e2; 2194 2539 2540 /* XXX: on x86_64, we do not want to nullify FS and GS because 2541 they may still contain a valid base. I would be interested to 2542 know how a real x86_64 CPU behaves */ 2543 if ((seg_reg == R_FS || seg_reg == R_GS) && 2544 (env->segs[seg_reg].selector & 0xfffc) == 0) 2545 return; 2546 2195 2547 e2 = env->segs[seg_reg].flags; 2196 2548 dpl = (e2 >> DESC_DPL_SHIFT) & 3; … … 2217 2569 else 2218 2570 #endif 2219 sp_mask = get_sp_mask(env->segs[R_SS].flags);2571 sp_mask = get_sp_mask(env->segs[R_SS].flags); 2220 2572 sp = ESP; 2221 2573 ssp = env->segs[R_SS].base; … … 2363 2715 #ifdef TARGET_X86_64 2364 2716 /* NULL ss is allowed in long mode if cpl != 3*/ 2717 /* XXX: test CS64 ? */ 2365 2718 if ((env->hflags & HF_LMA_MASK) && rpl != 3) { 2366 2719 cpu_x86_load_seg_cache(env, R_SS, new_ss, … … 2369 2722 DESC_S_MASK | (rpl << DESC_DPL_SHIFT) | 2370 2723 DESC_W_MASK | DESC_A_MASK); 2724 ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */ 2371 2725 } else 2372 2726 #endif … … 2415 2769 sp += addend; 2416 2770 } 2417 ESP = (ESP & ~sp_mask) | (sp &sp_mask);2771 SET_ESP(sp, sp_mask); 2418 2772 env->eip = new_eip; 2419 2773 if (is_iret) { … … 2426 2780 eflags_mask |= IOPL_MASK; 2427 2781 #endif 2428 2429 2782 iopl = (env->eflags >> IOPL_SHIFT) & 3; 2430 2783 if (cpl <= iopl) … … 2495 2848 helper_ret_protected(shift, 1, 0); 2496 2849 } 2850 #ifdef USE_KQEMU 2851 if (kqemu_is_ok(env)) { 2852 CC_OP = CC_OP_EFLAGS; 2853 env->exception_index = -1; 2854 cpu_loop_exit(); 2855 } 2856 #endif 2497 2857 } 2498 2858 … … 2500 2860 { 2501 2861 helper_ret_protected(shift, 0, addend); 2862 #ifdef USE_KQEMU 2863 if (kqemu_is_ok(env)) { 2864 env->exception_index = -1; 2865 cpu_loop_exit(); 2866 } 2867 #endif 2502 2868 } 2503 2869 … … 2544 2910 ESP = ECX; 2545 2911 EIP = EDX; 2912 #ifdef USE_KQEMU 2913 if (kqemu_is_ok(env)) { 2914 env->exception_index = -1; 2915 cpu_loop_exit(); 2916 } 2917 #endif 2546 2918 } 2547 2919 … … 2575 2947 } 2576 2948 2577 void helper_invlpg( unsigned intaddr)2949 void helper_invlpg(target_ulong addr) 2578 2950 { 2579 2951 cpu_x86_flush_tlb(env, addr); … … 2586 2958 if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { 2587 2959 raise_exception(EXCP0D_GPF); 2588 } 2960 } 2589 2961 val = cpu_get_tsc(env); 2590 2962 EAX = (uint32_t)(val); … … 2620 2992 cpu_set_apic_base(env, val); 2621 2993 break; 2622 #ifdef TARGET_X86_642623 2994 case MSR_EFER: 2624 #define MSR_EFER_UPDATE_MASK (MSR_EFER_SCE | MSR_EFER_LME | \ 2625 MSR_EFER_NXE | MSR_EFER_FFXSR) 2626 env->efer = (env->efer & ~MSR_EFER_UPDATE_MASK) | 2627 (val & MSR_EFER_UPDATE_MASK); 2995 { 2996 uint64_t update_mask; 2997 update_mask = 0; 2998 if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) 2999 update_mask |= MSR_EFER_SCE; 3000 if (env->cpuid_ext2_features & CPUID_EXT2_LM) 3001 update_mask |= MSR_EFER_LME; 3002 if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) 3003 update_mask |= MSR_EFER_FFXSR; 3004 if (env->cpuid_ext2_features & CPUID_EXT2_NX) 3005 update_mask |= MSR_EFER_NXE; 3006 env->efer = (env->efer & ~update_mask) | 3007 (val & update_mask); 3008 } 2628 3009 break; 2629 3010 case MSR_STAR: 2630 3011 env->star = val; 2631 3012 break; 3013 case MSR_PAT: 3014 env->pat = val; 3015 break; 3016 #ifdef TARGET_X86_64 2632 3017 case MSR_LSTAR: 2633 3018 env->lstar = val; … … 2671 3056 val = cpu_get_apic_base(env); 2672 3057 break; 2673 #ifdef TARGET_X86_642674 3058 case MSR_EFER: 2675 3059 val = env->efer; … … 2678 3062 val = env->star; 2679 3063 break; 3064 case MSR_PAT: 3065 val = env->pat; 3066 break; 3067 #ifdef TARGET_X86_64 2680 3068 case MSR_LSTAR: 2681 3069 val = env->lstar; … … 2927 3315 void helper_fbst_ST0_A0(void) 2928 3316 { 2929 CPU86_LDouble tmp;2930 3317 int v; 2931 3318 target_ulong mem_ref, mem_end; 2932 3319 int64_t val; 2933 3320 2934 tmp = rint(ST0); 2935 val = (int64_t)tmp; 3321 val = floatx_to_int64(ST0, &env->fp_status); 2936 3322 mem_ref = A0; 2937 3323 mem_end = mem_ref + 9; … … 3126 3512 void helper_frndint(void) 3127 3513 { 3128 CPU86_LDouble a; 3129 3130 a = ST0; 3131 #ifdef __arm__ 3132 switch(env->fpuc & RC_MASK) { 3133 default: 3134 case RC_NEAR: 3135 asm("rndd %0, %1" : "=f" (a) : "f"(a)); 3136 break; 3137 case RC_DOWN: 3138 asm("rnddm %0, %1" : "=f" (a) : "f"(a)); 3139 break; 3140 case RC_UP: 3141 asm("rnddp %0, %1" : "=f" (a) : "f"(a)); 3142 break; 3143 case RC_CHOP: 3144 asm("rnddz %0, %1" : "=f" (a) : "f"(a)); 3145 break; 3146 } 3147 #else 3148 a = rint(a); 3149 #endif 3150 ST0 = a; 3514 ST0 = floatx_round_to_int(ST0, &env->fp_status); 3151 3515 } 3152 3516 3153 3517 void helper_fscale(void) 3154 3518 { 3155 CPU86_LDouble fpsrcop, fptemp; 3156 3157 fpsrcop = 2.0; 3158 fptemp = pow(fpsrcop,ST1); 3159 ST0 *= fptemp; 3519 ST0 = ldexp (ST0, (int)(ST1)); 3160 3520 } 3161 3521 … … 3395 3755 3396 3756 if (env->cr[4] & CR4_OSFXSR_MASK) { 3397 /* XXX: finish it , endianness*/3757 /* XXX: finish it */ 3398 3758 env->mxcsr = ldl(ptr + 0x18); 3399 3759 //ldl(ptr + 0x1c); … … 3523 3883 *phigh += v; 3524 3884 #ifdef DEBUG_MULDIV 3525 printf("mul: 0x%016 llx * 0x%016llx = 0x%016llx%016llx\n",3885 printf("mul: 0x%016" PRIx64 " * 0x%016" PRIx64 " = 0x%016" PRIx64 "%016" PRIx64 "\n", 3526 3886 a, b, *phigh, *plow); 3527 3887 #endif … … 3572 3932 } 3573 3933 #if defined(DEBUG_MULDIV) 3574 printf("div: 0x%016 llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n",3934 printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n", 3575 3935 *phigh, *plow, b, a0, a1); 3576 3936 #endif … … 3666 4026 } 3667 4027 3668 #endif 3669 3670 /* XXX: do it */ 3671 int fpu_isnan(double a) 3672 { 3673 return 0; 3674 } 4028 void helper_bswapq_T0(void) 4029 { 4030 T0 = bswap64(T0); 4031 } 4032 #endif 3675 4033 3676 4034 void helper_hlt(void) 3677 4035 { 3678 4036 env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ 4037 env->hflags |= HF_HALTED_MASK; 3679 4038 env->exception_index = EXCP_HLT; 3680 4039 cpu_loop_exit(); … … 3683 4042 void helper_monitor(void) 3684 4043 { 3685 if ( ECX != 0)4044 if ((uint32_t)ECX != 0) 3686 4045 raise_exception(EXCP0D_GPF); 3687 4046 /* XXX: store address ? */ … … 3690 4049 void helper_mwait(void) 3691 4050 { 3692 if ( ECX != 0)4051 if ((uint32_t)ECX != 0) 3693 4052 raise_exception(EXCP0D_GPF); 3694 4053 #ifdef VBOX … … 3715 4074 } 3716 4075 3717 /* XXX: find a better solution */ 3718 double helper_sqrt(double a) 3719 { 3720 return sqrt(a); 4076 void update_fp_status(void) 4077 { 4078 int rnd_type; 4079 4080 /* set rounding mode */ 4081 switch(env->fpuc & RC_MASK) { 4082 default: 4083 case RC_NEAR: 4084 rnd_type = float_round_nearest_even; 4085 break; 4086 case RC_DOWN: 4087 rnd_type = float_round_down; 4088 break; 4089 case RC_UP: 4090 rnd_type = float_round_up; 4091 break; 4092 case RC_CHOP: 4093 rnd_type = float_round_to_zero; 4094 break; 4095 } 4096 set_float_rounding_mode(rnd_type, &env->fp_status); 4097 #ifdef FLOATX80 4098 switch((env->fpuc >> 8) & 3) { 4099 case 0: 4100 rnd_type = 32; 4101 break; 4102 case 2: 4103 rnd_type = 64; 4104 break; 4105 case 3: 4106 default: 4107 rnd_type = 80; 4108 break; 4109 } 4110 set_floatx80_rounding_precision(rnd_type, &env->fp_status); 4111 #endif 3721 4112 } 3722 4113 … … 3769 4160 } 3770 4161 if (retaddr) 3771 raise_exception_err(EXCP0E_PAGE, env->error_code); 3772 else { 3773 raise_exception_err_norestore(EXCP0E_PAGE, env->error_code); 3774 } 4162 raise_exception_err(env->exception_index, env->error_code); 4163 else 4164 raise_exception_err_norestore(env->exception_index, env->error_code); 3775 4165 } 3776 4166 env = saved_env; 3777 4167 } 3778 4168 3779 #if defined(VBOX)4169 #ifdef VBOX 3780 4170 3781 4171 /** … … 4029 4419 int csize; 4030 4420 void (*gen_func)(void); 4031 uint8_t * pvCode;4421 uint8_t *tc_ptr; 4032 4422 uint32_t old_eip; 4033 4423 … … 4038 4428 RAWEx_ProfileStart(env, STATS_EMULATE_SINGLE_INSTR); 4039 4429 4040 pvCode = env->pvCodeBuffer; 4041 4042 // Setup temporary translation block 4043 tb_temp.hash_next = 0; 4044 tb_temp.jmp_first = 0; 4045 tb_temp.jmp_next[0] = 0; 4046 tb_temp.jmp_next[1] = 0; 4430 tc_ptr = env->pvCodeBuffer; 4431 4432 /* 4433 * Setup temporary translation block. 4434 */ 4435 /* tb_alloc: */ 4436 tb_temp.pc = env->segs[R_CS].base + env->eip; 4437 tb_temp.cflags = 0; 4438 4439 /* tb_find_slow: */ 4440 tb_temp.tc_ptr = tc_ptr; 4441 tb_temp.cs_base = env->segs[R_CS].base; 4442 tb_temp.flags = env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); 4443 4444 /* Initialize the rest with sensible values. */ 4445 tb_temp.size = 0; 4446 tb_temp.phys_hash_next = NULL; 4447 tb_temp.page_next[0] = NULL; 4448 tb_temp.page_next[1] = NULL; 4047 4449 tb_temp.page_addr[0] = 0; 4048 4450 tb_temp.page_addr[1] = 0; 4049 tb_temp.page_next[0] = 0;4050 tb_temp.page_next[1] = 0;4051 tb_temp.hash_next = 0;4052 4053 4451 tb_temp.tb_next_offset[0] = 0xffff; 4054 4452 tb_temp.tb_next_offset[1] = 0xffff; 4055 4056 tb_temp.cs_base = (unsigned long)env->segs[R_CS].base; 4057 tb_temp.pc = tb_temp.cs_base + env->eip; 4058 tb_temp.cflags = 0; 4059 tb_temp.flags = env->hflags; 4060 tb_temp.flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); 4061 tb_temp.tc_ptr = pvCode; 4453 tb_temp.tb_next[0] = 0xffff; 4454 tb_temp.tb_next[1] = 0xffff; 4455 tb_temp.jmp_next[0] = NULL; 4456 tb_temp.jmp_next[1] = NULL; 4457 tb_temp.jmp_first = NULL; 4062 4458 4063 4459 current = env->current_tb; 4064 4460 env->current_tb = NULL; 4065 4461 4066 // Translate only one instruction 4067 ASMAtomicOrS32(&env->state, CPU_EMULATE_SINGLE_INSTR); 4462 /* 4463 * Translate only one instruction. 4464 */ 4465 ASMAtomicOrU32(&env->state, CPU_EMULATE_SINGLE_INSTR); 4068 4466 if (cpu_gen_code(env, &tb_temp, env->cbCodeBuffer, &csize) < 0) 4069 4467 { 4070 4468 AssertFailed(); 4071 4469 RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR); 4072 ASMAtomicAnd S32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);4470 ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR); 4073 4471 env = savedenv; 4074 4472 return -1; … … 4079 4477 RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR); 4080 4478 AssertFailed(); 4081 ASMAtomicAnd S32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);4479 ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR); 4082 4480 env = savedenv; 4083 4481 return -1; 4084 4482 } 4085 if (tb_temp.tc_ptr != pvCode)4483 if (tb_temp.tc_ptr != tc_ptr) 4086 4484 { 4087 4485 RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR); 4088 4486 AssertFailed(); 4089 ASMAtomicAnd S32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);4487 ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR); 4090 4488 env = savedenv; 4091 4489 return -1; 4092 4490 } 4093 4491 #endif 4094 ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR); 4095 4096 tb_link(&tb_temp); 4097 4492 ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR); 4493 4494 /* tb_link_phys: */ 4495 tb_temp.jmp_first = (TranslationBlock *)((intptr_t)&tb_temp | 2); 4496 Assert(tb_temp.jmp_next[0] == NULL); Assert(tb_temp.jmp_next[1] == NULL); 4497 if (tb_temp.tb_next_offset[0] != 0xffff) 4498 tb_set_jmp_target(&tb_temp, 0, (uintptr_t)(tb_temp.tc_ptr + tb_temp.tb_next_offset[0])); 4499 if (tb_temp.tb_next_offset[1] != 0xffff) 4500 tb_set_jmp_target(&tb_temp, 1, (uintptr_t)(tb_temp.tc_ptr + tb_temp.tb_next_offset[1])); 4501 4502 /* 4503 * Execute it using emulation 4504 */ 4098 4505 old_eip = env->eip; 4099 // Execute it using emulation4100 4506 gen_func = (void *)tb_temp.tc_ptr; 4101 4507 env->current_tb = &tb_temp; … … 4119 4525 env->current_tb = current; 4120 4526 4527 Assert(tb_temp.phys_hash_next == NULL); 4528 Assert(tb_temp.page_next[0] == NULL); 4529 Assert(tb_temp.page_next[1] == NULL); 4530 Assert(tb_temp.page_addr[0] == 0); 4531 Assert(tb_temp.page_addr[1] == 0); 4532 /* 4533 Assert(tb_temp.tb_next_offset[0] == 0xffff); 4534 Assert(tb_temp.tb_next_offset[1] == 0xffff); 4535 Assert(tb_temp.tb_next[0] == 0xffff); 4536 Assert(tb_temp.tb_next[1] == 0xffff); 4537 Assert(tb_temp.jmp_next[0] == NULL); 4538 Assert(tb_temp.jmp_next[1] == NULL); 4539 Assert(tb_temp.jmp_first == NULL); */ 4540 4121 4541 RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR); 4122 4542 4543 /* 4544 * Execute the next instruction when we encounter instruction fusing. 4545 */ 4123 4546 if (env->hflags & HF_INHIBIT_IRQ_MASK) 4124 4547 {
Note:
See TracChangeset
for help on using the changeset viewer.