Revision 8f091a59

b/target-i386/cpu.h
214 214
#define MSR_IA32_SYSENTER_ESP           0x175
215 215
#define MSR_IA32_SYSENTER_EIP           0x176
216 216

  
217
#define MSR_MCG_CAP                     0x179
218
#define MSR_MCG_STATUS                  0x17a
219
#define MSR_MCG_CTL                     0x17b
220

  
221
#define MSR_PAT                         0x277
222

  
217 223
#define MSR_EFER                        0xc0000080
218 224

  
219 225
#define MSR_EFER_SCE   (1 << 0)
......
246 252
#define CPUID_PGE  (1 << 13)
247 253
#define CPUID_MCA  (1 << 14)
248 254
#define CPUID_CMOV (1 << 15)
255
#define CPUID_PAT  (1 << 16)
256
#define CPUID_CLFLUSH (1 << 19)
249 257
/* ... */
250 258
#define CPUID_MMX  (1 << 23)
251 259
#define CPUID_FXSR (1 << 24)
......
474 482
    target_ulong kernelgsbase;
475 483
#endif
476 484

  
485
    uint64_t pat;
486

  
477 487
    /* temporary data for USE_CODE_COPY mode */
478 488
#ifdef USE_CODE_COPY
479 489
    uint32_t tmp0;
b/target-i386/exec.h
157 157
void helper_ltr_T0(void);
158 158
void helper_movl_crN_T0(int reg);
159 159
void helper_movl_drN_T0(int reg);
160
void helper_invlpg(unsigned int addr);
160
void helper_invlpg(target_ulong addr);
161 161
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
162 162
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
163 163
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
164
void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
164
void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
165 165
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 
166 166
                             int is_write, int is_user, int is_softmmu);
167 167
void tlb_fill(target_ulong addr, int is_write, int is_user, 
......
190 190
void helper_cmpxchg8b(void);
191 191
void helper_cpuid(void);
192 192
void helper_enter_level(int level, int data32);
193
void helper_enter64_level(int level, int data64);
193 194
void helper_sysenter(void);
194 195
void helper_sysexit(void);
195 196
void helper_syscall(int next_eip_addend);
b/target-i386/helper.c
1334 1334
        ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1335 1335
        EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1336 1336
        break;
1337
    case 0x80000005:
1338
        /* cache info (L1 cache) */
1339
        EAX = 0x01ff01ff;
1340
        EBX = 0x01ff01ff;
1341
        ECX = 0x40020140;
1342
        EDX = 0x40020140;
1343
        break;
1344
    case 0x80000006:
1345
        /* cache info (L2 cache) */
1346
        EAX = 0;
1347
        EBX = 0x42004200;
1348
        ECX = 0x02008140;
1349
        EDX = 0;
1350
        break;
1337 1351
    case 0x80000008:
1338 1352
        /* virtual & phys address size in low 2 bytes. */
1339 1353
        EAX = 0x00003028;
......
1383 1397
    }
1384 1398
}
1385 1399

  
1400
#ifdef TARGET_X86_64
1401
void helper_enter64_level(int level, int data64)
1402
{
1403
    target_ulong esp, ebp;
1404
    ebp = EBP;
1405
    esp = ESP;
1406

  
1407
    if (data64) {
1408
        /* 64 bit */
1409
        esp -= 8;
1410
        while (--level) {
1411
            esp -= 8;
1412
            ebp -= 8;
1413
            stq(esp, ldq(ebp));
1414
        }
1415
        esp -= 8;
1416
        stq(esp, T1);
1417
    } else {
1418
        /* 16 bit */
1419
        esp -= 2;
1420
        while (--level) {
1421
            esp -= 2;
1422
            ebp -= 2;
1423
            stw(esp, lduw(ebp));
1424
        }
1425
        esp -= 2;
1426
        stw(esp, T1);
1427
    }
1428
}
1429
#endif
1430

  
1386 1431
void helper_lldt_T0(void)
1387 1432
{
1388 1433
    int selector;
......
1963 2008
#endif
1964 2009
        sp_mask = get_sp_mask(env->segs[R_SS].flags);
1965 2010
    sp = ESP;
2011
    /* XXX: ssp is zero in 64 bit ? */
1966 2012
    ssp = env->segs[R_SS].base;
1967 2013
    new_eflags = 0; /* avoid warning */
1968 2014
#ifdef TARGET_X86_64
......
2271 2317
    env->dr[reg] = T0;
2272 2318
}
2273 2319

  
2274
void helper_invlpg(unsigned int addr)
2320
void helper_invlpg(target_ulong addr)
2275 2321
{
2276 2322
    cpu_x86_flush_tlb(env, addr);
2277 2323
}
......
2332 2378
    case MSR_STAR:
2333 2379
        env->star = val;
2334 2380
        break;
2381
    case MSR_PAT:
2382
        env->pat = val;
2383
        break;
2335 2384
#ifdef TARGET_X86_64
2336 2385
    case MSR_LSTAR:
2337 2386
        env->lstar = val;
......
2380 2429
    case MSR_STAR:
2381 2430
        val = env->star;
2382 2431
        break;
2432
    case MSR_PAT:
2433
        val = env->pat;
2434
        break;
2383 2435
#ifdef TARGET_X86_64
2384 2436
    case MSR_LSTAR:
2385 2437
        val = env->lstar;
b/target-i386/helper2.c
106 106
        env->cpuid_version = (family << 8) | (model << 4) | stepping;
107 107
        env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
108 108
                               CPUID_TSC | CPUID_MSR | CPUID_MCE |
109
                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV);
109
                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
110
                               CPUID_PAT);
111
        env->pat = 0x0007040600070406ULL;
110 112
        env->cpuid_ext_features = 0;
111 113
        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
112 114
        env->cpuid_xlevel = 0;
......
128 130
        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
129 131
        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL;
130 132
        env->cpuid_xlevel = 0x80000008;
133

  
134
        /* these features are needed for Win64 and aren't fully implemented */
135
        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
131 136
#endif
132 137
    }
133 138
    cpu_single_env = env;
......
546 551
}
547 552

  
548 553
/* XXX: also flush 4MB pages */
549
void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
554
void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
550 555
{
551 556
    tlb_flush_page(env, addr);
552 557
}
b/target-i386/op.c
898 898
}
899 899

  
900 900
#ifdef TARGET_X86_64
901
void op_subq_A0_2(void)
902
{
903
    A0 -= 2;
904
}
905

  
901 906
void op_subq_A0_8(void)
902 907
{
903 908
    A0 -= 8;
......
929 934
    helper_enter_level(PARAM1, PARAM2);
930 935
}
931 936

  
937
#ifdef TARGET_X86_64
938
void OPPROTO op_enter64_level(void)
939
{
940
    helper_enter64_level(PARAM1, PARAM2);
941
}
942
#endif
943

  
932 944
void OPPROTO op_sysenter(void)
933 945
{
934 946
    helper_sysenter();
b/target-i386/translate.c
1627 1627
        override = R_DS;
1628 1628
    }
1629 1629
    if (must_add_seg) {
1630
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1630
#ifdef TARGET_X86_64
1631
        if (CODE64(s)) {
1632
            gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
1633
        } else 
1634
#endif
1635
        {
1636
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1637
        }
1631 1638
    }
1632 1639
}
1633 1640

  
......
1948 1955
{
1949 1956
#ifdef TARGET_X86_64
1950 1957
    if (CODE64(s)) {
1951
        /* XXX: check 16 bit behaviour */
1952 1958
        gen_op_movq_A0_reg[R_ESP]();
1953
        gen_op_subq_A0_8();
1954
        gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
1959
        if (s->dflag) {
1960
            gen_op_subq_A0_8();
1961
            gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
1962
        } else {
1963
            gen_op_subq_A0_2();
1964
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
1965
        }
1955 1966
        gen_op_movq_ESP_A0();
1956 1967
    } else 
1957 1968
#endif
......
1985 1996
{
1986 1997
#ifdef TARGET_X86_64
1987 1998
    if (CODE64(s)) {
1988
        /* XXX: check 16 bit behaviour */
1989 1999
        gen_op_movq_A0_reg[R_ESP]();
1990
        gen_op_subq_A0_8();
1991
        gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
2000
        if (s->dflag) {
2001
            gen_op_subq_A0_8();
2002
            gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
2003
        } else {
2004
            gen_op_subq_A0_2();
2005
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
2006
        }
1992 2007
        gen_op_movq_ESP_A0();
1993 2008
    } else 
1994 2009
#endif
......
2020 2035
{
2021 2036
#ifdef TARGET_X86_64
2022 2037
    if (CODE64(s)) {
2023
        /* XXX: check 16 bit behaviour */
2024 2038
        gen_op_movq_A0_reg[R_ESP]();
2025
        gen_op_ld_T0_A0[OT_QUAD + s->mem_index]();
2039
        gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
2026 2040
    } else 
2027 2041
#endif
2028 2042
    {
......
2041 2055
static void gen_pop_update(DisasContext *s)
2042 2056
{
2043 2057
#ifdef TARGET_X86_64
2044
    if (CODE64(s)) {
2058
    if (CODE64(s) && s->dflag) {
2045 2059
        gen_stack_update(s, 8);
2046 2060
    } else
2047 2061
#endif
......
2105 2119
{
2106 2120
    int ot, opsize;
2107 2121

  
2108
    ot = s->dflag + OT_WORD;
2109 2122
    level &= 0x1f;
2110
    opsize = 2 << s->dflag;
2111

  
2112
    gen_op_movl_A0_ESP();
2113
    gen_op_addl_A0_im(-opsize);
2114
    if (!s->ss32)
2115
        gen_op_andl_A0_ffff();
2116
    gen_op_movl_T1_A0();
2117
    if (s->addseg)
2118
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2119
    /* push bp */
2120
    gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2121
    gen_op_st_T0_A0[ot + s->mem_index]();
2122
    if (level) {
2123
        gen_op_enter_level(level, s->dflag);
2123
#ifdef TARGET_X86_64
2124
    if (CODE64(s)) {
2125
        ot = s->dflag ? OT_QUAD : OT_WORD;
2126
        opsize = 1 << ot;
2127
        
2128
        gen_op_movl_A0_ESP();
2129
        gen_op_addq_A0_im(-opsize);
2130
        gen_op_movl_T1_A0();
2131

  
2132
        /* push bp */
2133
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2134
        gen_op_st_T0_A0[ot + s->mem_index]();
2135
        if (level) {
2136
            gen_op_enter64_level(level, (ot == OT_QUAD));
2137
        }
2138
        gen_op_mov_reg_T1[ot][R_EBP]();
2139
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2140
        gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
2141
    } else 
2142
#endif
2143
    {
2144
        ot = s->dflag + OT_WORD;
2145
        opsize = 2 << s->dflag;
2146
        
2147
        gen_op_movl_A0_ESP();
2148
        gen_op_addl_A0_im(-opsize);
2149
        if (!s->ss32)
2150
            gen_op_andl_A0_ffff();
2151
        gen_op_movl_T1_A0();
2152
        if (s->addseg)
2153
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2154
        /* push bp */
2155
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2156
        gen_op_st_T0_A0[ot + s->mem_index]();
2157
        if (level) {
2158
            gen_op_enter_level(level, s->dflag);
2159
        }
2160
        gen_op_mov_reg_T1[ot][R_EBP]();
2161
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2162
        gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2124 2163
    }
2125
    gen_op_mov_reg_T1[ot][R_EBP]();
2126
    gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2127
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2128 2164
}
2129 2165

  
2130 2166
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
......
2901 2937
            if (mod != 3) 
2902 2938
                goto illegal_op;
2903 2939
#ifdef TARGET_X86_64
2904
            if (CODE64(s)) {
2940
            if (s->aflag == 2) {
2905 2941
                gen_op_movq_A0_reg[R_EDI]();
2906 2942
            } else 
2907 2943
#endif
......
3697 3733
        break;
3698 3734
    case 0xc8: /* enter */
3699 3735
        {
3700
            /* XXX: long mode support */
3701 3736
            int level;
3702 3737
            val = lduw_code(s->pc);
3703 3738
            s->pc += 2;
......
3707 3742
        break;
3708 3743
    case 0xc9: /* leave */
3709 3744
        /* XXX: exception not precise (ESP is updated before potential exception) */
3710
        /* XXX: may be invalid for 16 bit in long mode */
3711 3745
        if (CODE64(s)) {
3712 3746
            gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
3713 3747
            gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
......
3926 3960
            else
3927 3961
                ot = dflag + OT_WORD;
3928 3962
#ifdef TARGET_X86_64
3929
            if (CODE64(s)) {
3963
            if (s->aflag == 2) {
3930 3964
                offset_addr = ldq_code(s->pc);
3931 3965
                s->pc += 8;
3932 3966
                if (offset_addr == (int32_t)offset_addr)
......
3955 3989
        break;
3956 3990
    case 0xd7: /* xlat */
3957 3991
#ifdef TARGET_X86_64
3958
        if (CODE64(s)) {
3992
        if (s->aflag == 2) {
3959 3993
            gen_op_movq_A0_reg[R_EBX]();
3960 3994
            gen_op_addq_A0_AL();
3961 3995
        } else 
......
4779 4813
        val = ldsw_code(s->pc);
4780 4814
        s->pc += 2;
4781 4815
        gen_pop_T0(s);
4816
        if (CODE64(s) && s->dflag)
4817
            s->dflag = 2;
4782 4818
        gen_stack_update(s, val + (2 << s->dflag));
4783 4819
        if (s->dflag == 0)
4784 4820
            gen_op_andl_T0_ffff();
......
5782 5818
            break;
5783 5819
        case 5: /* lfence */
5784 5820
        case 6: /* mfence */
5785
        case 7: /* sfence */
5786 5821
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
5787 5822
                goto illegal_op;
5788 5823
            break;
5824
        case 7: /* sfence / clflush */
5825
            if ((modrm & 0xc7) == 0xc0) {
5826
                /* sfence */
5827
                if (!(s->cpuid_features & CPUID_SSE))
5828
                    goto illegal_op;
5829
            } else {
5830
                /* clflush */
5831
                if (!(s->cpuid_features & CPUID_CLFLUSH))
5832
                    goto illegal_op;
5833
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5834
            }
5835
            break;
5789 5836
        default:
5790 5837
            goto illegal_op;
5791 5838
        }
5792 5839
        break;
5840
    case 0x10d: /* prefetch */
5841
        modrm = ldub_code(s->pc++);
5842
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5843
        /* ignore for now */
5844
        break;
5793 5845
    case 0x110 ... 0x117:
5794 5846
    case 0x128 ... 0x12f:
5795 5847
    case 0x150 ... 0x177:

Also available in: Unified diff