VirtualBox

Changeset 2426 in vbox for trunk/src/recompiler/target-i386


Ignore:
Timestamp:
Apr 30, 2007 12:36:15 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
20835
Message:

Removed the old recompiler code. (wonder why subversion didn't pick up these changes right way)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/target-i386/helper.c

    r1953 r2426  
    1818 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1919 */
     20#ifdef VBOX
     21# include <VBox/err.h>
     22#endif
    2023#include "exec.h"
    21 #ifdef VBOX
    22 #include <VBox/err.h>
    23 #endif
    2424
    2525//#define DEBUG_PCALL
     
    2828#define raise_exception_err(a, b)\
    2929do {\
    30     fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
     30    if (logfile)\
     31        fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
    3132    (raise_exception_err)(a, b);\
    3233} while (0)
     
    224225            if ((e2 & DESC_C_MASK) && dpl > rpl)
    225226                raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    226                
    227227        } else if (seg_reg == R_SS) {
    228228            /* SS must be writable data */
     
    380380        for(i = 0; i < 6; i++)
    381381            stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
    382 
    383382#if defined(VBOX) && defined(DEBUG)
    384383        printf("TSS 32 bits switch\n");
    385384        printf("Saving CS=%08X\n", env->segs[R_CS].selector);
    386385#endif
    387 
    388386    } else {
    389387        /* 16 bit */
     
    567565}
    568566
     567#ifdef TARGET_X86_64
     568#define SET_ESP(val, sp_mask)\
     569do {\
     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
    569581/* XXX: add a is_user flag to have proper security support */
    570582#define PUSHW(ssp, sp, sp_mask, val)\
     
    598610    SegmentCache *dt;
    599611    target_ulong ptr, ssp;
    600     int type, dpl, selector, ss_dpl, cpl, sp_mask;
     612    int type, dpl, selector, ss_dpl, cpl;
    601613    int has_error_code, new_stack, shift;
    602614    uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2;
    603     uint32_t old_eip;
     615    uint32_t old_eip, sp_mask;
    604616
    605617#ifdef VBOX
     
    642654        switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
    643655        if (has_error_code) {
    644             int mask, type;
     656            int type;
     657            uint32_t mask;
    645658            /* push the error code */
    646659            type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
     
    656669            else
    657670                stw_kernel(ssp, error_code);
    658             ESP = (esp & mask) | (ESP & ~mask);
     671            SET_ESP(esp, mask);
    659672        }
    660673        return;
     
    787800                               ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);
    788801    }
    789     ESP = (ESP & ~sp_mask) | (esp & sp_mask);
     802    SET_ESP(esp, sp_mask);
    790803
    791804    selector = (selector & ~3) | dpl;
     
    896909        env->eflags &= ~IF_MASK;
    897910}
    898 #endif
     911#endif /* VBOX */
    899912
    900913#ifdef TARGET_X86_64
     
    10781091        cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
    10791092                           0, 0xffffffff,
    1080                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
     1093                               DESC_G_MASK | DESC_P_MASK |
    10811094                               DESC_S_MASK |
    10821095                               DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
     
    11291142            cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
    11301143                                   0, 0xffffffff,
    1131                                    DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
     1144                                   DESC_G_MASK | DESC_P_MASK |
    11321145                                   DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
    11331146                                   DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
     
    11841197void helper_external_event(void)
    11851198{
     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
    11861209    if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD)
    11871210    {
     
    12781301                  target_ulong next_eip, int is_hw)
    12791302{
    1280 #ifdef DEBUG_PCALL
    1281     if (loglevel & (CPU_LOG_PCALL | CPU_LOG_INT)) {
     1303    if (loglevel & CPU_LOG_INT) {
    12821304        if ((env->cr[0] & CR0_PE_MASK)) {
    12831305            static int count;
     
    12941316            }
    12951317            fprintf(logfile, "\n");
     1318            cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
    12961319#if 0
    1297             cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
    12981320            {
    12991321                int i;
     
    13101332        }
    13111333    }
    1312 #endif
    13131334    if (env->cr[0] & CR0_PE_MASK) {
    13141335#if TARGET_X86_64
     
    13281349                do_soft_interrupt_vme(intno, error_code, next_eip);
    13291350            else
    1330 #endif
     1351#endif /* VBOX */
    13311352                do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
    13321353        }
     
    13761397    raise_interrupt(exception_index, 0, 0, 0);
    13771398}
     1399
     1400/* SMM support */
     1401
     1402#if defined(CONFIG_USER_ONLY)
     1403
     1404void do_smm_enter(void)
     1405{
     1406}
     1407
     1408void 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
     1420void 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
     1560void 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
    13781690
    13791691#ifdef BUGGY_GCC_DIV64
     
    14581770{
    14591771#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) {
    14611785    case 0:
    1462         EAX = 2; /* max EAX index supported */
     1786        EAX = env->cpuid_level;
    14631787        EBX = env->cpuid_vendor1;
    14641788        EDX = env->cpuid_vendor2;
     
    14671791    case 1:
    14681792        EAX = env->cpuid_version;
    1469         EBX = 0;
     1793        EBX = 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
    14701794        ECX = env->cpuid_ext_features;
    14711795        EDX = env->cpuid_features;
    14721796        break;
    1473 
    1474     default:
     1797    case 2:
    14751798        /* cache info: needed for Pentium Pro compatibility */
    14761799        EAX = 0x410601;
     
    14791802        EDX = 0;
    14801803        break;
    1481 
    1482 #ifdef TARGET_X86_64
    14831804    case 0x80000000:
    1484         EAX = 0x80000008;
     1805        EAX = env->cpuid_xlevel;
    14851806        EBX = env->cpuid_vendor1;
    14861807        EDX = env->cpuid_vendor2;
     
    14911812        EBX = 0;
    14921813        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;
    14951837        break;
    14961838    case 0x80000008:
     
    15011843        EDX = 0;
    15021844        break;
    1503 #endif
     1845    default:
     1846        /* reserved values: zero */
     1847        EAX = 0;
     1848        EBX = 0;
     1849        ECX = 0;
     1850        EDX = 0;
     1851        break;
    15041852    }
    15051853#else /* VBOX */
     
    16341982    int index, type, entry_limit;
    16351983    target_ulong ptr;
     1984   
    16361985#ifdef VBOX
    16371986    Log(("helper_ltr_T0: old tr=%RTsel {.base=%VGv, .limit=%VGv, .flags=%RX32} new=%RTsel\n",
     
    17502099            if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
    17512100                /* if not conforming code, test rights */
    1752                 if (dpl < cpl || dpl < rpl)
     2101                if (dpl < cpl || dpl < rpl) 
    17532102                    raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    17542103            }
     
    18902239    }
    18912240
    1892     ESP = (ESP & ~esp_mask) | (esp & esp_mask);
     2241    SET_ESP(esp, esp_mask);
    18932242    env->eip = new_eip;
    18942243    env->segs[R_CS].selector = new_cs;
     
    19762325                raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
    19772326            /* from this point, not restartable */
    1978             ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     2327            SET_ESP(sp, sp_mask);
    19792328            cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
    19802329                                   get_seg_base(e1, e2), limit, e2);
     
    21052454                       e2);
    21062455        cpu_x86_set_cpl(env, dpl);
    2107         ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     2456        SET_ESP(sp, sp_mask);
    21082457        EIP = offset;
    21092458    }
     
    21222471    target_ulong ssp;
    21232472    int eflags_mask;
    2124 
    21252473#ifdef VBOX
    21262474    bool fVME = false;
    21272475
    21282476    remR3TrapClear(env->pVM);
    2129 #endif
     2477#endif /* VBOX */
    21302478
    21312479    sp_mask = 0xffff; /* XXXX: use SS segment size ? */
     
    21542502        if (    ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK))
    21552503            ||  (new_eflags & TF_MASK))
    2156         {
    21572504            raise_exception(EXCP0D_GPF);
    2158         }
    2159     }
    2160 #endif
     2505    }
     2506#endif /* VBOX */
    21612507
    21622508    ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     
    21742520    if (shift == 0)
    21752521        eflags_mask &= 0xffff;
    2176 
    21772522    load_eflags(new_eflags, eflags_mask);
    21782523
     
    21852530            env->eflags &= ~VIF_MASK;
    21862531    }
    2187 #endif
     2532#endif /* VBOX */
    21882533}
    21892534
     
    21922537    int dpl;
    21932538    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
    21952547    e2 = env->segs[seg_reg].flags;
    21962548    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
     
    22172569    else
    22182570#endif
    2219     sp_mask = get_sp_mask(env->segs[R_SS].flags);
     2571        sp_mask = get_sp_mask(env->segs[R_SS].flags);
    22202572    sp = ESP;
    22212573    ssp = env->segs[R_SS].base;
     
    23632715#ifdef TARGET_X86_64
    23642716            /* NULL ss is allowed in long mode if cpl != 3*/
     2717            /* XXX: test CS64 ? */
    23652718            if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
    23662719                cpu_x86_load_seg_cache(env, R_SS, new_ss,
     
    23692722                                       DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
    23702723                                       DESC_W_MASK | DESC_A_MASK);
     2724                ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */
    23712725            } else
    23722726#endif
     
    24152769        sp += addend;
    24162770    }
    2417     ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     2771    SET_ESP(sp, sp_mask);
    24182772    env->eip = new_eip;
    24192773    if (is_iret) {
     
    24262780            eflags_mask |= IOPL_MASK;
    24272781#endif
    2428 
    24292782        iopl = (env->eflags >> IOPL_SHIFT) & 3;
    24302783        if (cpl <= iopl)
     
    24952848        helper_ret_protected(shift, 1, 0);
    24962849    }
     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
    24972857}
    24982858
     
    25002860{
    25012861    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
    25022868}
    25032869
     
    25442910    ESP = ECX;
    25452911    EIP = EDX;
     2912#ifdef USE_KQEMU
     2913    if (kqemu_is_ok(env)) {
     2914        env->exception_index = -1;
     2915        cpu_loop_exit();
     2916    }
     2917#endif
    25462918}
    25472919
     
    25752947}
    25762948
    2577 void helper_invlpg(unsigned int addr)
     2949void helper_invlpg(target_ulong addr)
    25782950{
    25792951    cpu_x86_flush_tlb(env, addr);
     
    25862958    if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
    25872959        raise_exception(EXCP0D_GPF);
    2588     }   
     2960    }
    25892961    val = cpu_get_tsc(env);
    25902962    EAX = (uint32_t)(val);
     
    26202992        cpu_set_apic_base(env, val);
    26212993        break;
    2622 #ifdef TARGET_X86_64
    26232994    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        }
    26283009        break;
    26293010    case MSR_STAR:
    26303011        env->star = val;
    26313012        break;
     3013    case MSR_PAT:
     3014        env->pat = val;
     3015        break;
     3016#ifdef TARGET_X86_64
    26323017    case MSR_LSTAR:
    26333018        env->lstar = val;
     
    26713056        val = cpu_get_apic_base(env);
    26723057        break;
    2673 #ifdef TARGET_X86_64
    26743058    case MSR_EFER:
    26753059        val = env->efer;
     
    26783062        val = env->star;
    26793063        break;
     3064    case MSR_PAT:
     3065        val = env->pat;
     3066        break;
     3067#ifdef TARGET_X86_64
    26803068    case MSR_LSTAR:
    26813069        val = env->lstar;
     
    29273315void helper_fbst_ST0_A0(void)
    29283316{
    2929     CPU86_LDouble tmp;
    29303317    int v;
    29313318    target_ulong mem_ref, mem_end;
    29323319    int64_t val;
    29333320
    2934     tmp = rint(ST0);
    2935     val = (int64_t)tmp;
     3321    val = floatx_to_int64(ST0, &env->fp_status);
    29363322    mem_ref = A0;
    29373323    mem_end = mem_ref + 9;
     
    31263512void helper_frndint(void)
    31273513{
    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);
    31513515}
    31523516
    31533517void helper_fscale(void)
    31543518{
    3155     CPU86_LDouble fpsrcop, fptemp;
    3156 
    3157     fpsrcop = 2.0;
    3158     fptemp = pow(fpsrcop,ST1);
    3159     ST0 *= fptemp;
     3519    ST0 = ldexp (ST0, (int)(ST1));
    31603520}
    31613521
     
    33953755
    33963756    if (env->cr[4] & CR4_OSFXSR_MASK) {
    3397         /* XXX: finish it, endianness */
     3757        /* XXX: finish it */
    33983758        env->mxcsr = ldl(ptr + 0x18);
    33993759        //ldl(ptr + 0x1c);
     
    35233883    *phigh += v;
    35243884#ifdef DEBUG_MULDIV
    3525     printf("mul: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
     3885    printf("mul: 0x%016" PRIx64 " * 0x%016" PRIx64 " = 0x%016" PRIx64 "%016" PRIx64 "\n",
    35263886           a, b, *phigh, *plow);
    35273887#endif
     
    35723932        }
    35733933#if defined(DEBUG_MULDIV)
    3574         printf("div: 0x%016llx%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",
    35753935               *phigh, *plow, b, a0, a1);
    35763936#endif
     
    36664026}
    36674027
    3668 #endif
    3669 
    3670 /* XXX: do it */
    3671 int fpu_isnan(double a)
    3672 {
    3673     return 0;
    3674 }
     4028void helper_bswapq_T0(void)
     4029{
     4030    T0 = bswap64(T0);
     4031}
     4032#endif
    36754033
    36764034void helper_hlt(void)
    36774035{
    36784036    env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
     4037    env->hflags |= HF_HALTED_MASK;
    36794038    env->exception_index = EXCP_HLT;
    36804039    cpu_loop_exit();
     
    36834042void helper_monitor(void)
    36844043{
    3685     if (ECX != 0)
     4044    if ((uint32_t)ECX != 0)
    36864045        raise_exception(EXCP0D_GPF);
    36874046    /* XXX: store address ? */
     
    36904049void helper_mwait(void)
    36914050{
    3692     if (ECX != 0)
     4051    if ((uint32_t)ECX != 0)
    36934052        raise_exception(EXCP0D_GPF);
    36944053#ifdef VBOX
     
    37154074}
    37164075
    3717 /* XXX: find a better solution */
    3718 double helper_sqrt(double a)
    3719 {
    3720     return sqrt(a);
     4076void 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
    37214112}
    37224113
     
    37694160        }
    37704161        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);
    37754165    }
    37764166    env = saved_env;
    37774167}
    37784168
    3779 #if defined(VBOX)
     4169#ifdef VBOX
    37804170
    37814171/**
     
    40294419    int csize;
    40304420    void (*gen_func)(void);
    4031     uint8_t *pvCode;
     4421    uint8_t *tc_ptr;
    40324422    uint32_t old_eip;
    40334423
     
    40384428    RAWEx_ProfileStart(env, STATS_EMULATE_SINGLE_INSTR);
    40394429
    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;
    40474449    tb_temp.page_addr[0] = 0;
    40484450    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 
    40534451    tb_temp.tb_next_offset[0] = 0xffff;
    40544452    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;
    40624458
    40634459    current = env->current_tb;
    40644460    env->current_tb = NULL;
    40654461
    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);
    40684466    if (cpu_gen_code(env, &tb_temp, env->cbCodeBuffer, &csize) < 0)
    40694467    {
    40704468        AssertFailed();
    40714469        RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    4072         ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4470        ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    40734471        env = savedenv;
    40744472        return -1;
     
    40794477        RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    40804478        AssertFailed();
    4081         ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4479        ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    40824480        env = savedenv;
    40834481        return -1;
    40844482    }
    4085     if (tb_temp.tc_ptr != pvCode)
     4483    if (tb_temp.tc_ptr != tc_ptr)
    40864484    {
    40874485        RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    40884486        AssertFailed();
    4089         ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4487        ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    40904488        env = savedenv;
    40914489        return -1;
    40924490    }
    40934491#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     */
    40984505    old_eip = env->eip;
    4099     // Execute it using emulation
    41004506    gen_func = (void *)tb_temp.tc_ptr;
    41014507    env->current_tb = &tb_temp;
     
    41194525    env->current_tb = current;
    41204526
     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   
    41214541    RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    41224542
     4543    /*                                                             
     4544     * Execute the next instruction when we encounter instruction fusing.
     4545     */
    41234546    if (env->hflags & HF_INHIBIT_IRQ_MASK)
    41244547    {
Note: See TracChangeset for help on using the changeset viewer.

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