32
32
# define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
33
# define LOG_PCALL_STATE(env) \
34
log_cpu_state_mask(CPU_LOG_PCALL, (env), CPU_DUMP_CCOP)
33
# define LOG_PCALL_STATE(cpu) \
34
log_cpu_state_mask(CPU_LOG_PCALL, (cpu), CPU_DUMP_CCOP)
36
36
# define LOG_PCALL(...) do { } while (0)
37
# define LOG_PCALL_STATE(env) do { } while (0)
37
# define LOG_PCALL_STATE(cpu) do { } while (0)
40
40
/* return non zero if error */
325
325
cpu_stl_kernel(env, env->tr.base + 0x20, next_eip);
326
326
cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags);
327
cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), EAX);
328
cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), ECX);
329
cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX);
330
cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), EBX);
331
cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
332
cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), EBP);
333
cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
334
cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
327
cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
328
cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
329
cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
330
cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
331
cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
332
cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
333
cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]);
334
cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]);
335
335
for (i = 0; i < 6; i++) {
336
336
cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4),
337
337
env->segs[i].selector);
341
341
cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip);
342
342
cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags);
343
cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), EAX);
344
cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), ECX);
345
cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX);
346
cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), EBX);
347
cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
348
cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), EBP);
349
cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
350
cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
343
cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
344
cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
345
cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
346
cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
347
cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
348
cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
349
cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]);
350
cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]);
351
351
for (i = 0; i < 4; i++) {
352
352
cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4),
353
353
env->segs[i].selector);
397
397
cpu_load_eflags(env, new_eflags, eflags_mask);
398
398
/* XXX: what to do in 16 bit case? */
399
env->regs[R_EAX] = new_regs[0];
400
env->regs[R_ECX] = new_regs[1];
401
env->regs[R_EDX] = new_regs[2];
402
env->regs[R_EBX] = new_regs[3];
403
env->regs[R_ESP] = new_regs[4];
404
env->regs[R_EBP] = new_regs[5];
405
env->regs[R_ESI] = new_regs[6];
406
env->regs[R_EDI] = new_regs[7];
407
407
if (new_eflags & VM_MASK) {
408
408
for (i = 0; i < 6; i++) {
409
409
load_seg_vm(env, i, new_segs[i]);
457
457
tss_load_seg(env, R_GS, new_segs[R_GS]);
460
/* check that EIP is in the CS segment limits */
460
/* check that env->eip is in the CS segment limits */
461
461
if (new_eip > env->segs[R_CS].limit) {
462
462
/* XXX: different exception if CALL? */
463
463
raise_exception_err(env, EXCP0D_GPF, 0);
504
504
#ifdef TARGET_X86_64
505
#define SET_ESP(val, sp_mask) \
507
if ((sp_mask) == 0xffff) { \
508
ESP = (ESP & ~0xffff) | ((val) & 0xffff); \
509
} else if ((sp_mask) == 0xffffffffLL) { \
510
ESP = (uint32_t)(val); \
505
#define SET_ESP(val, sp_mask) \
507
if ((sp_mask) == 0xffff) { \
508
env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | \
510
} else if ((sp_mask) == 0xffffffffLL) { \
511
env->regs[R_ESP] = (uint32_t)(val); \
513
env->regs[R_ESP] = (val); \
516
#define SET_ESP(val, sp_mask) \
518
ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask)); \
517
#define SET_ESP(val, sp_mask) \
519
env->regs[R_ESP] = (env->regs[R_ESP] & ~(sp_mask)) | \
520
((val) & (sp_mask)); \
601
esp = (ESP - (2 << shift)) & mask;
603
esp = (env->regs[R_ESP] - (2 << shift)) & mask;
602
604
ssp = env->segs[R_SS].base + esp;
604
606
cpu_stl_kernel(env, ssp, error_code);
709
711
PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);
711
713
PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);
712
PUSHL(ssp, esp, sp_mask, ESP);
714
PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]);
714
716
PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(env));
715
717
PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);
726
728
PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector);
728
730
PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);
729
PUSHW(ssp, esp, sp_mask, ESP);
731
PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]);
731
733
PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env));
732
734
PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);
901
903
PUSHQ(esp, env->segs[R_SS].selector);
904
PUSHQ(esp, env->regs[R_ESP]);
903
905
PUSHQ(esp, cpu_compute_eflags(env));
904
906
PUSHQ(esp, env->segs[R_CS].selector);
905
907
PUSHQ(esp, old_eip);
912
914
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
916
env->regs[R_ESP] = esp;
916
918
selector = (selector & ~3) | dpl;
917
919
cpu_x86_load_seg_cache(env, R_CS, selector,
949
951
if (env->hflags & HF_LMA_MASK) {
952
ECX = env->eip + next_eip_addend;
954
env->regs[R_ECX] = env->eip + next_eip_addend;
953
955
env->regs[11] = cpu_compute_eflags(env);
955
957
code64 = env->hflags & HF_CS64_MASK;
974
976
env->eip = env->cstar;
977
ECX = (uint32_t)(env->eip + next_eip_addend);
979
env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
979
981
cpu_x86_set_cpl(env, 0);
980
982
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
1015
1017
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1016
1018
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
1020
env->eip = env->regs[R_ECX];
1020
1022
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
1022
1024
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1023
1025
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1024
1026
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
1025
env->eip = (uint32_t)ECX;
1027
env->eip = (uint32_t)env->regs[R_ECX];
1027
1029
cpu_x86_load_seg_cache(env, R_SS, selector + 8,
1039
1041
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1040
1042
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1041
1043
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
1042
env->eip = (uint32_t)ECX;
1044
env->eip = (uint32_t)env->regs[R_ECX];
1043
1045
cpu_x86_load_seg_cache(env, R_SS, selector + 8,
1045
1047
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1069
1071
ptr = dt->base + intno * 4;
1070
1072
offset = cpu_lduw_kernel(env, ptr);
1071
1073
selector = cpu_lduw_kernel(env, ptr + 2);
1074
esp = env->regs[R_ESP];
1073
1075
ssp = env->segs[R_SS].base;
1075
1077
old_eip = next_eip;
1083
1085
PUSHW(ssp, esp, 0xffff, old_eip);
1085
1087
/* update processor state */
1086
ESP = (ESP & ~0xffff) | (esp & 0xffff);
1088
env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff);
1087
1089
env->eip = offset;
1088
1090
env->segs[R_CS].selector = selector;
1089
1091
env->segs[R_CS].base = (selector << 4);
1157
1159
* Begin execution of an interruption. is_int is TRUE if coming from
1158
* the int instruction. next_eip is the EIP value AFTER the interrupt
1160
* the int instruction. next_eip is the env->eip value AFTER the interrupt
1159
1161
* instruction. It is only relevant if is_int is TRUE.
1161
static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
1163
static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
1162
1164
int error_code, target_ulong next_eip, int is_hw)
1166
CPUX86State *env = &cpu->env;
1164
1168
if (qemu_loglevel_mask(CPU_LOG_INT)) {
1165
1169
if ((env->cr[0] & CR0_PE_MASK)) {
1166
1170
static int count;
1169
1173
" pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
1170
1174
count, intno, error_code, is_int,
1171
1175
env->hflags & HF_CPL_MASK,
1172
env->segs[R_CS].selector, EIP,
1173
(int)env->segs[R_CS].base + EIP,
1174
env->segs[R_SS].selector, ESP);
1176
env->segs[R_CS].selector, env->eip,
1177
(int)env->segs[R_CS].base + env->eip,
1178
env->segs[R_SS].selector, env->regs[R_ESP]);
1175
1179
if (intno == 0x0e) {
1176
1180
qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
1178
qemu_log(" EAX=" TARGET_FMT_lx, EAX);
1182
qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]);
1180
1184
qemu_log("\n");
1181
log_cpu_state(env, CPU_DUMP_CCOP);
1185
log_cpu_state(CPU(cpu), CPU_DUMP_CCOP);
1250
1254
/* simulate a real cpu exception. On i386, it can
1251
1255
trigger new exceptions, but we do not handle
1252
1256
double or triple faults yet. */
1253
do_interrupt_all(env, env->exception_index,
1257
do_interrupt_all(cpu, env->exception_index,
1254
1258
env->exception_is_int,
1255
1259
env->error_code,
1256
1260
env->exception_next_eip, 0);
1262
1266
void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
1264
do_interrupt_all(env, intno, 0, 0, 0, is_hw);
1268
do_interrupt_all(x86_env_get_cpu(env), intno, 0, 0, 0, is_hw);
1267
1271
void helper_enter_level(CPUX86State *env, int level, int data32,
1583
1587
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
1584
1588
get_seg_base(e1, e2), limit, e2);
1587
1591
/* jump to call or task gate */
1588
1592
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1636
1640
cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl,
1637
1641
get_seg_base(e1, e2), limit, e2);
1641
1645
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
1683
1687
next_eip = env->eip + next_eip_addend;
1684
1688
LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift);
1685
LOG_PCALL_STATE(env);
1689
LOG_PCALL_STATE(CPU(x86_env_get_cpu(env)));
1686
1690
if ((new_cs & 0xfffc) == 0) {
1687
1691
raise_exception_err(env, EXCP0D_GPF, 0);
1721
1725
target_ulong rsp;
1723
1727
/* 64 bit case */
1728
rsp = env->regs[R_ESP];
1725
1729
PUSHQ(rsp, env->segs[R_CS].selector);
1726
1730
PUSHQ(rsp, next_eip);
1727
1731
/* from this point, not restartable */
1732
env->regs[R_ESP] = rsp;
1729
1733
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
1730
1734
get_seg_base(e1, e2),
1731
1735
get_seg_limit(e1, e2), e2);
1740
sp = env->regs[R_ESP];
1737
1741
sp_mask = get_sp_mask(env->segs[R_SS].flags);
1738
1742
ssp = env->segs[R_SS].base;
1752
1756
SET_ESP(sp, sp_mask);
1753
1757
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
1754
1758
get_seg_base(e1, e2), limit, e2);
1758
1762
/* check gate type */
1809
1813
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
1810
1814
/* to inner privilege */
1811
1815
get_ss_esp_from_tss(env, &ss, &sp, dpl);
1812
LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx
1814
ss, sp, param_count, ESP);
1816
LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]="
1817
TARGET_FMT_lx "\n", ss, sp, param_count,
1815
1819
if ((ss & 0xfffc) == 0) {
1816
1820
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
1843
1847
ssp = get_seg_base(ss_e1, ss_e2);
1845
1849
PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
1846
PUSHL(ssp, sp, sp_mask, ESP);
1850
PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]);
1847
1851
for (i = param_count - 1; i >= 0; i--) {
1848
val = cpu_ldl_kernel(env, old_ssp + ((ESP + i * 4) &
1852
val = cpu_ldl_kernel(env, old_ssp +
1853
((env->regs[R_ESP] + i * 4) &
1850
1855
PUSHL(ssp, sp, sp_mask, val);
1853
1858
PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
1854
PUSHW(ssp, sp, sp_mask, ESP);
1859
PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]);
1855
1860
for (i = param_count - 1; i >= 0; i--) {
1856
val = cpu_lduw_kernel(env, old_ssp + ((ESP + i * 2) &
1861
val = cpu_lduw_kernel(env, old_ssp +
1862
((env->regs[R_ESP] + i * 2) &
1858
1864
PUSHW(ssp, sp, sp_mask, val);
1863
1869
/* to same privilege */
1870
sp = env->regs[R_ESP];
1865
1871
sp_mask = get_sp_mask(env->segs[R_SS].flags);
1866
1872
ssp = env->segs[R_SS].base;
1867
1873
/* push_size = (4 << shift); */
1919
1925
POPW(ssp, sp, sp_mask, new_cs);
1920
1926
POPW(ssp, sp, sp_mask, new_eflags);
1922
ESP = (ESP & ~sp_mask) | (sp & sp_mask);
1928
env->regs[R_ESP] = (env->regs[R_ESP] & ~sp_mask) | (sp & sp_mask);
1923
1929
env->segs[R_CS].selector = new_cs;
1924
1930
env->segs[R_CS].base = (new_cs << 4);
1925
1931
env->eip = new_eip;
2015
2021
LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
2016
2022
new_cs, new_eip, shift, addend);
2017
LOG_PCALL_STATE(env);
2023
LOG_PCALL_STATE(CPU(x86_env_get_cpu(env)));
2018
2024
if ((new_cs & 0xfffc) == 0) {
2019
2025
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
2179
2185
load_seg_vm(env, R_GS, new_gs & 0xffff);
2181
2187
env->eip = new_eip & 0xffff;
2188
env->regs[R_ESP] = new_esp;
2185
2191
void helper_iret_protected(CPUX86State *env, int shift, int next_eip)
2248
2254
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
2250
2256
DESC_W_MASK | DESC_A_MASK);
2251
ESP = env->sysenter_esp;
2252
EIP = env->sysenter_eip;
2257
env->regs[R_ESP] = env->sysenter_esp;
2258
env->eip = env->sysenter_eip;
2255
2261
void helper_sysexit(CPUX86State *env, int dflag)
2288
2294
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
2289
2295
DESC_W_MASK | DESC_A_MASK);
2297
env->regs[R_ESP] = env->regs[R_ECX];
2298
env->eip = env->regs[R_EDX];
2295
2301
target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)