Revision f419b321

b/target-i386/helper.c
933 933
    }
934 934
    env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
935 935
}
936
#endif
936 937

  
937 938
void helper_syscall(int next_eip_addend)
938 939
{
......
942 943
        raise_exception_err(EXCP06_ILLOP, 0);
943 944
    }
944 945
    selector = (env->star >> 32) & 0xffff;
946
#ifdef TARGET_X86_64
945 947
    if (env->hflags & HF_LMA_MASK) {
946 948
        ECX = env->eip + next_eip_addend;
947 949
        env->regs[11] = compute_eflags();
......
962 964
            env->eip = env->lstar;
963 965
        else
964 966
            env->eip = env->cstar;
965
    } else {
967
    } else 
968
#endif
969
    {
966 970
        ECX = (uint32_t)(env->eip + next_eip_addend);
967 971
        
968 972
        cpu_x86_set_cpl(env, 0);
......
985 989
{
986 990
    int cpl, selector;
987 991

  
992
    if (!(env->efer & MSR_EFER_SCE)) {
993
        raise_exception_err(EXCP06_ILLOP, 0);
994
    }
988 995
    cpl = env->hflags & HF_CPL_MASK;
989 996
    if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) {
990 997
        raise_exception_err(EXCP0D_GPF, 0);
991 998
    }
992 999
    selector = (env->star >> 48) & 0xffff;
1000
#ifdef TARGET_X86_64
993 1001
    if (env->hflags & HF_LMA_MASK) {
994 1002
        if (dflag == 2) {
995 1003
            cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3, 
......
1015 1023
        load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK | 
1016 1024
                    IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
1017 1025
        cpu_x86_set_cpl(env, 3);
1018
    } else {
1026
    } else 
1027
#endif
1028
    {
1019 1029
        cpu_x86_load_seg_cache(env, R_CS, selector | 3, 
1020 1030
                               0, 0xffffffff, 
1021 1031
                               DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
......
1030 1040
        env->eflags |= IF_MASK;
1031 1041
        cpu_x86_set_cpl(env, 3);
1032 1042
    }
1033
}
1043
#ifdef USE_KQEMU
1044
    if (kqemu_is_ok(env)) {
1045
        if (env->hflags & HF_LMA_MASK)
1046
            CC_OP = CC_OP_EFLAGS;
1047
        env->exception_index = -1;
1048
        cpu_loop_exit();
1049
    }
1034 1050
#endif
1051
}
1035 1052

  
1036 1053
/* real mode interrupt */
1037 1054
static void do_interrupt_real(int intno, int is_int, int error_code,
......
1265 1282

  
1266 1283
void helper_cpuid(void)
1267 1284
{
1268
    switch((uint32_t)EAX) {
1285
    uint32_t index;
1286
    index = (uint32_t)EAX;
1287
    
1288
    /* test if maximum index reached */
1289
    if (index & 0x80000000) {
1290
        if (index > env->cpuid_xlevel) 
1291
            index = env->cpuid_level;
1292
    } else {
1293
        if (index > env->cpuid_level) 
1294
            index = env->cpuid_level;
1295
    }
1296
        
1297
    switch(index) {
1269 1298
    case 0:
1270
        EAX = 2; /* max EAX index supported */
1299
        EAX = env->cpuid_level;
1271 1300
        EBX = env->cpuid_vendor1;
1272 1301
        EDX = env->cpuid_vendor2;
1273 1302
        ECX = env->cpuid_vendor3;
......
1278 1307
        ECX = env->cpuid_ext_features;
1279 1308
        EDX = env->cpuid_features;
1280 1309
        break;
1281
    default:
1310
    case 2:
1282 1311
        /* cache info: needed for Pentium Pro compatibility */
1283 1312
        EAX = 0x410601;
1284 1313
        EBX = 0;
1285 1314
        ECX = 0;
1286 1315
        EDX = 0;
1287 1316
        break;
1288
#ifdef TARGET_X86_64
1289 1317
    case 0x80000000:
1290
        EAX = 0x80000008;
1318
        EAX = env->cpuid_xlevel;
1291 1319
        EBX = env->cpuid_vendor1;
1292 1320
        EDX = env->cpuid_vendor2;
1293 1321
        ECX = env->cpuid_vendor3;
......
1296 1324
        EAX = env->cpuid_features;
1297 1325
        EBX = 0;
1298 1326
        ECX = 0;
1299
        /* long mode + syscall/sysret features */
1300
        EDX = (env->cpuid_features & 0x0183F3FF) | (1 << 29) | (1 << 11);
1327
        EDX = env->cpuid_ext2_features;
1328
        break;
1329
    case 0x80000002:
1330
    case 0x80000003:
1331
    case 0x80000004:
1332
        EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1333
        EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1334
        ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1335
        EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1301 1336
        break;
1302 1337
    case 0x80000008:
1303 1338
        /* virtual & phys address size in low 2 bytes. */
......
1306 1341
        ECX = 0;
1307 1342
        EDX = 0;
1308 1343
        break;
1309
#endif
1344
    default:
1345
        /* reserved values: zero */
1346
        EAX = 0;
1347
        EBX = 0;
1348
        ECX = 0;
1349
        EDX = 0;
1350
        break;
1310 1351
    }
1311 1352
}
1312 1353

  
......
1523 1564
}
1524 1565

  
1525 1566
/* protected mode jump */
1526
void helper_ljmp_protected_T0_T1(int next_eip)
1567
void helper_ljmp_protected_T0_T1(int next_eip_addend)
1527 1568
{
1528 1569
    int new_cs, gate_cs, type;
1529 1570
    uint32_t e1, e2, cpl, dpl, rpl, limit;
1530
    target_ulong new_eip;
1571
    target_ulong new_eip, next_eip;
1531 1572
    
1532 1573
    new_cs = T0;
1533 1574
    new_eip = T1;
......
1573 1614
        case 5: /* task gate */
1574 1615
            if (dpl < cpl || dpl < rpl)
1575 1616
                raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1617
            next_eip = env->eip + next_eip_addend;
1576 1618
            switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
1577 1619
            break;
1578 1620
        case 4: /* 286 call gate */
......
1638 1680
}
1639 1681

  
1640 1682
/* protected mode call */
1641
void helper_lcall_protected_T0_T1(int shift, int next_eip)
1683
void helper_lcall_protected_T0_T1(int shift, int next_eip_addend)
1642 1684
{
1643 1685
    int new_cs, new_eip, new_stack, i;
1644 1686
    uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
1645 1687
    uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
1646 1688
    uint32_t val, limit, old_sp_mask;
1647
    target_ulong ssp, old_ssp;
1689
    target_ulong ssp, old_ssp, next_eip;
1648 1690
    
1649 1691
    new_cs = T0;
1650 1692
    new_eip = T1;
1693
    next_eip = env->eip + next_eip_addend;
1651 1694
#ifdef DEBUG_PCALL
1652 1695
    if (loglevel & CPU_LOG_PCALL) {
1653 1696
        fprintf(logfile, "lcall %04x:%08x s=%d\n",
......
1684 1727
        if (!(e2 & DESC_P_MASK))
1685 1728
            raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
1686 1729

  
1687
        sp = ESP;
1688
        sp_mask = get_sp_mask(env->segs[R_SS].flags);
1689
        ssp = env->segs[R_SS].base;
1690
        if (shift) {
1691
            PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);
1692
            PUSHL(ssp, sp, sp_mask, next_eip);
1693
        } else {
1694
            PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
1695
            PUSHW(ssp, sp, sp_mask, next_eip);
1730
#ifdef TARGET_X86_64
1731
        /* XXX: check 16/32 bit cases in long mode */
1732
        if (shift == 2) {
1733
            target_ulong rsp;
1734
            /* 64 bit case */
1735
            rsp = ESP;
1736
            PUSHQ(rsp, env->segs[R_CS].selector);
1737
            PUSHQ(rsp, next_eip);
1738
            /* from this point, not restartable */
1739
            ESP = rsp;
1740
            cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
1741
                                   get_seg_base(e1, e2), 
1742
                                   get_seg_limit(e1, e2), e2);
1743
            EIP = new_eip;
1744
        } else 
1745
#endif
1746
        {
1747
            sp = ESP;
1748
            sp_mask = get_sp_mask(env->segs[R_SS].flags);
1749
            ssp = env->segs[R_SS].base;
1750
            if (shift) {
1751
                PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);
1752
                PUSHL(ssp, sp, sp_mask, next_eip);
1753
            } else {
1754
                PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
1755
                PUSHW(ssp, sp, sp_mask, next_eip);
1756
            }
1757
            
1758
            limit = get_seg_limit(e1, e2);
1759
            if (new_eip > limit)
1760
                raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1761
            /* from this point, not restartable */
1762
            ESP = (ESP & ~sp_mask) | (sp & sp_mask);
1763
            cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
1764
                                   get_seg_base(e1, e2), limit, e2);
1765
            EIP = new_eip;
1696 1766
        }
1697
        
1698
        limit = get_seg_limit(e1, e2);
1699
        if (new_eip > limit)
1700
            raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1701
        /* from this point, not restartable */
1702
        ESP = (ESP & ~sp_mask) | (sp & sp_mask);
1703
        cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
1704
                       get_seg_base(e1, e2), limit, e2);
1705
        EIP = new_eip;
1706 1767
    } else {
1707 1768
        /* check gate type */
1708 1769
        type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
......
2245 2306
    case MSR_IA32_APICBASE:
2246 2307
        cpu_set_apic_base(env, val);
2247 2308
        break;
2248
#ifdef TARGET_X86_64
2249 2309
    case MSR_EFER:
2250
#define MSR_EFER_UPDATE_MASK (MSR_EFER_SCE | MSR_EFER_LME | \
2251
                              MSR_EFER_NXE | MSR_EFER_FFXSR)
2252
        env->efer = (env->efer & ~MSR_EFER_UPDATE_MASK) | 
2253
            (val & MSR_EFER_UPDATE_MASK);
2310
        {
2311
            uint64_t update_mask;
2312
            update_mask = 0;
2313
            if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL)
2314
                update_mask |= MSR_EFER_SCE;
2315
            if (env->cpuid_ext2_features & CPUID_EXT2_LM)
2316
                update_mask |= MSR_EFER_LME;
2317
            if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
2318
                update_mask |= MSR_EFER_FFXSR;
2319
            if (env->cpuid_ext2_features & CPUID_EXT2_NX)
2320
                update_mask |= MSR_EFER_NXE;
2321
            env->efer = (env->efer & ~update_mask) | 
2322
            (val & update_mask);
2323
        }
2254 2324
        break;
2255 2325
    case MSR_STAR:
2256 2326
        env->star = val;
2257 2327
        break;
2328
#ifdef TARGET_X86_64
2258 2329
    case MSR_LSTAR:
2259 2330
        env->lstar = val;
2260 2331
        break;
......
2296 2367
    case MSR_IA32_APICBASE:
2297 2368
        val = cpu_get_apic_base(env);
2298 2369
        break;
2299
#ifdef TARGET_X86_64
2300 2370
    case MSR_EFER:
2301 2371
        val = env->efer;
2302 2372
        break;
2303 2373
    case MSR_STAR:
2304 2374
        val = env->star;
2305 2375
        break;
2376
#ifdef TARGET_X86_64
2306 2377
    case MSR_LSTAR:
2307 2378
        val = env->lstar;
2308 2379
        break;

Also available in: Unified diff