328 |
328 |
cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
|
329 |
329 |
cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
|
330 |
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), ESP);
|
|
331 |
cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
|
332 |
332 |
cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
|
333 |
333 |
cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
|
334 |
334 |
cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
|
... | ... | |
344 |
344 |
cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
|
345 |
345 |
cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
|
346 |
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), ESP);
|
|
347 |
cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
|
348 |
348 |
cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
|
349 |
349 |
cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
|
350 |
350 |
cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
|
... | ... | |
400 |
400 |
env->regs[R_ECX] = new_regs[1];
|
401 |
401 |
env->regs[R_EDX] = new_regs[2];
|
402 |
402 |
env->regs[R_EBX] = new_regs[3];
|
403 |
|
ESP = new_regs[4];
|
|
403 |
env->regs[R_ESP] = new_regs[4];
|
404 |
404 |
env->regs[R_EBP] = new_regs[5];
|
405 |
405 |
ESI = new_regs[6];
|
406 |
406 |
EDI = new_regs[7];
|
... | ... | |
502 |
502 |
}
|
503 |
503 |
|
504 |
504 |
#ifdef TARGET_X86_64
|
505 |
|
#define SET_ESP(val, sp_mask) \
|
506 |
|
do { \
|
507 |
|
if ((sp_mask) == 0xffff) { \
|
508 |
|
ESP = (ESP & ~0xffff) | ((val) & 0xffff); \
|
509 |
|
} else if ((sp_mask) == 0xffffffffLL) { \
|
510 |
|
ESP = (uint32_t)(val); \
|
511 |
|
} else { \
|
512 |
|
ESP = (val); \
|
513 |
|
} \
|
|
505 |
#define SET_ESP(val, sp_mask) \
|
|
506 |
do { \
|
|
507 |
if ((sp_mask) == 0xffff) { \
|
|
508 |
env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | \
|
|
509 |
((val) & 0xffff); \
|
|
510 |
} else if ((sp_mask) == 0xffffffffLL) { \
|
|
511 |
env->regs[R_ESP] = (uint32_t)(val); \
|
|
512 |
} else { \
|
|
513 |
env->regs[R_ESP] = (val); \
|
|
514 |
} \
|
514 |
515 |
} while (0)
|
515 |
516 |
#else
|
516 |
|
#define SET_ESP(val, sp_mask) \
|
517 |
|
do { \
|
518 |
|
ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask)); \
|
|
517 |
#define SET_ESP(val, sp_mask) \
|
|
518 |
do { \
|
|
519 |
env->regs[R_ESP] = (env->regs[R_ESP] & ~(sp_mask)) | \
|
|
520 |
((val) & (sp_mask)); \
|
519 |
521 |
} while (0)
|
520 |
522 |
#endif
|
521 |
523 |
|
... | ... | |
598 |
600 |
} else {
|
599 |
601 |
mask = 0xffff;
|
600 |
602 |
}
|
601 |
|
esp = (ESP - (2 << shift)) & mask;
|
|
603 |
esp = (env->regs[R_ESP] - (2 << shift)) & mask;
|
602 |
604 |
ssp = env->segs[R_SS].base + esp;
|
603 |
605 |
if (shift) {
|
604 |
606 |
cpu_stl_kernel(env, ssp, error_code);
|
... | ... | |
680 |
682 |
new_stack = 0;
|
681 |
683 |
sp_mask = get_sp_mask(env->segs[R_SS].flags);
|
682 |
684 |
ssp = env->segs[R_SS].base;
|
683 |
|
esp = ESP;
|
|
685 |
esp = env->regs[R_ESP];
|
684 |
686 |
dpl = cpl;
|
685 |
687 |
} else {
|
686 |
688 |
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
|
... | ... | |
709 |
711 |
PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);
|
710 |
712 |
}
|
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]);
|
713 |
715 |
}
|
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);
|
727 |
729 |
}
|
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]);
|
730 |
732 |
}
|
731 |
733 |
PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env));
|
732 |
734 |
PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);
|
... | ... | |
888 |
890 |
if (ist != 0) {
|
889 |
891 |
esp = get_rsp_from_tss(env, ist + 3);
|
890 |
892 |
} else {
|
891 |
|
esp = ESP;
|
|
893 |
esp = env->regs[R_ESP];
|
892 |
894 |
}
|
893 |
895 |
esp &= ~0xfLL; /* align stack */
|
894 |
896 |
dpl = cpl;
|
... | ... | |
899 |
901 |
}
|
900 |
902 |
|
901 |
903 |
PUSHQ(esp, env->segs[R_SS].selector);
|
902 |
|
PUSHQ(esp, ESP);
|
|
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);
|
... | ... | |
911 |
913 |
ss = 0 | dpl;
|
912 |
914 |
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
|
913 |
915 |
}
|
914 |
|
ESP = esp;
|
|
916 |
env->regs[R_ESP] = esp;
|
915 |
917 |
|
916 |
918 |
selector = (selector & ~3) | dpl;
|
917 |
919 |
cpu_x86_load_seg_cache(env, R_CS, selector,
|
... | ... | |
1069 |
1071 |
ptr = dt->base + intno * 4;
|
1070 |
1072 |
offset = cpu_lduw_kernel(env, ptr);
|
1071 |
1073 |
selector = cpu_lduw_kernel(env, ptr + 2);
|
1072 |
|
esp = ESP;
|
|
1074 |
esp = env->regs[R_ESP];
|
1073 |
1075 |
ssp = env->segs[R_SS].base;
|
1074 |
1076 |
if (is_int) {
|
1075 |
1077 |
old_eip = next_eip;
|
... | ... | |
1083 |
1085 |
PUSHW(ssp, esp, 0xffff, old_eip);
|
1084 |
1086 |
|
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);
|
... | ... | |
1171 |
1173 |
env->hflags & HF_CPL_MASK,
|
1172 |
1174 |
env->segs[R_CS].selector, EIP,
|
1173 |
1175 |
(int)env->segs[R_CS].base + EIP,
|
1174 |
|
env->segs[R_SS].selector, ESP);
|
|
1176 |
env->segs[R_SS].selector, env->regs[R_ESP]);
|
1175 |
1177 |
if (intno == 0x0e) {
|
1176 |
1178 |
qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
|
1177 |
1179 |
} else {
|
... | ... | |
1273 |
1275 |
esp_mask = get_sp_mask(env->segs[R_SS].flags);
|
1274 |
1276 |
ssp = env->segs[R_SS].base;
|
1275 |
1277 |
ebp = env->regs[R_EBP];
|
1276 |
|
esp = ESP;
|
|
1278 |
esp = env->regs[R_ESP];
|
1277 |
1279 |
if (data32) {
|
1278 |
1280 |
/* 32 bit */
|
1279 |
1281 |
esp -= 4;
|
... | ... | |
1306 |
1308 |
target_ulong esp, ebp;
|
1307 |
1309 |
|
1308 |
1310 |
ebp = env->regs[R_EBP];
|
1309 |
|
esp = ESP;
|
|
1311 |
esp = env->regs[R_ESP];
|
1310 |
1312 |
|
1311 |
1313 |
if (data64) {
|
1312 |
1314 |
/* 64 bit */
|
... | ... | |
1653 |
1655 |
target_ulong ssp;
|
1654 |
1656 |
|
1655 |
1657 |
new_eip = new_eip1;
|
1656 |
|
esp = ESP;
|
|
1658 |
esp = env->regs[R_ESP];
|
1657 |
1659 |
esp_mask = get_sp_mask(env->segs[R_SS].flags);
|
1658 |
1660 |
ssp = env->segs[R_SS].base;
|
1659 |
1661 |
if (shift) {
|
... | ... | |
1721 |
1723 |
target_ulong rsp;
|
1722 |
1724 |
|
1723 |
1725 |
/* 64 bit case */
|
1724 |
|
rsp = ESP;
|
|
1726 |
rsp = env->regs[R_ESP];
|
1725 |
1727 |
PUSHQ(rsp, env->segs[R_CS].selector);
|
1726 |
1728 |
PUSHQ(rsp, next_eip);
|
1727 |
1729 |
/* from this point, not restartable */
|
1728 |
|
ESP = rsp;
|
|
1730 |
env->regs[R_ESP] = rsp;
|
1729 |
1731 |
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
|
1730 |
1732 |
get_seg_base(e1, e2),
|
1731 |
1733 |
get_seg_limit(e1, e2), e2);
|
... | ... | |
1733 |
1735 |
} else
|
1734 |
1736 |
#endif
|
1735 |
1737 |
{
|
1736 |
|
sp = ESP;
|
|
1738 |
sp = env->regs[R_ESP];
|
1737 |
1739 |
sp_mask = get_sp_mask(env->segs[R_SS].flags);
|
1738 |
1740 |
ssp = env->segs[R_SS].base;
|
1739 |
1741 |
if (shift) {
|
... | ... | |
1809 |
1811 |
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
|
1810 |
1812 |
/* to inner privilege */
|
1811 |
1813 |
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 |
LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]=" TARGET_FMT_lx
|
1813 |
1815 |
"\n",
|
1814 |
|
ss, sp, param_count, ESP);
|
|
1816 |
ss, sp, param_count, env->regs[R_ESP]);
|
1815 |
1817 |
if ((ss & 0xfffc) == 0) {
|
1816 |
1818 |
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
|
1817 |
1819 |
}
|
... | ... | |
1843 |
1845 |
ssp = get_seg_base(ss_e1, ss_e2);
|
1844 |
1846 |
if (shift) {
|
1845 |
1847 |
PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
|
1846 |
|
PUSHL(ssp, sp, sp_mask, ESP);
|
|
1848 |
PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]);
|
1847 |
1849 |
for (i = param_count - 1; i >= 0; i--) {
|
1848 |
|
val = cpu_ldl_kernel(env, old_ssp + ((ESP + i * 4) &
|
|
1850 |
val = cpu_ldl_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 4) &
|
1849 |
1851 |
old_sp_mask));
|
1850 |
1852 |
PUSHL(ssp, sp, sp_mask, val);
|
1851 |
1853 |
}
|
1852 |
1854 |
} else {
|
1853 |
1855 |
PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
|
1854 |
|
PUSHW(ssp, sp, sp_mask, ESP);
|
|
1856 |
PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]);
|
1855 |
1857 |
for (i = param_count - 1; i >= 0; i--) {
|
1856 |
|
val = cpu_lduw_kernel(env, old_ssp + ((ESP + i * 2) &
|
|
1858 |
val = cpu_lduw_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 2) &
|
1857 |
1859 |
old_sp_mask));
|
1858 |
1860 |
PUSHW(ssp, sp, sp_mask, val);
|
1859 |
1861 |
}
|
... | ... | |
1861 |
1863 |
new_stack = 1;
|
1862 |
1864 |
} else {
|
1863 |
1865 |
/* to same privilege */
|
1864 |
|
sp = ESP;
|
|
1866 |
sp = env->regs[R_ESP];
|
1865 |
1867 |
sp_mask = get_sp_mask(env->segs[R_SS].flags);
|
1866 |
1868 |
ssp = env->segs[R_SS].base;
|
1867 |
1869 |
/* push_size = (4 << shift); */
|
... | ... | |
1905 |
1907 |
int eflags_mask;
|
1906 |
1908 |
|
1907 |
1909 |
sp_mask = 0xffff; /* XXXX: use SS segment size? */
|
1908 |
|
sp = ESP;
|
|
1910 |
sp = env->regs[R_ESP];
|
1909 |
1911 |
ssp = env->segs[R_SS].base;
|
1910 |
1912 |
if (shift == 1) {
|
1911 |
1913 |
/* 32 bits */
|
... | ... | |
1919 |
1921 |
POPW(ssp, sp, sp_mask, new_cs);
|
1920 |
1922 |
POPW(ssp, sp, sp_mask, new_eflags);
|
1921 |
1923 |
}
|
1922 |
|
ESP = (ESP & ~sp_mask) | (sp & sp_mask);
|
|
1924 |
env->regs[R_ESP] = (env->regs[R_ESP] & ~sp_mask) | (sp & sp_mask);
|
1923 |
1925 |
env->segs[R_CS].selector = new_cs;
|
1924 |
1926 |
env->segs[R_CS].base = (new_cs << 4);
|
1925 |
1927 |
env->eip = new_eip;
|
... | ... | |
1978 |
1980 |
{
|
1979 |
1981 |
sp_mask = get_sp_mask(env->segs[R_SS].flags);
|
1980 |
1982 |
}
|
1981 |
|
sp = ESP;
|
|
1983 |
sp = env->regs[R_ESP];
|
1982 |
1984 |
ssp = env->segs[R_SS].base;
|
1983 |
1985 |
new_eflags = 0; /* avoid warning */
|
1984 |
1986 |
#ifdef TARGET_X86_64
|
... | ... | |
2179 |
2181 |
load_seg_vm(env, R_GS, new_gs & 0xffff);
|
2180 |
2182 |
|
2181 |
2183 |
env->eip = new_eip & 0xffff;
|
2182 |
|
ESP = new_esp;
|
|
2184 |
env->regs[R_ESP] = new_esp;
|
2183 |
2185 |
}
|
2184 |
2186 |
|
2185 |
2187 |
void helper_iret_protected(CPUX86State *env, int shift, int next_eip)
|
... | ... | |
2248 |
2250 |
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
|
2249 |
2251 |
DESC_S_MASK |
|
2250 |
2252 |
DESC_W_MASK | DESC_A_MASK);
|
2251 |
|
ESP = env->sysenter_esp;
|
|
2253 |
env->regs[R_ESP] = env->sysenter_esp;
|
2252 |
2254 |
EIP = env->sysenter_eip;
|
2253 |
2255 |
}
|
2254 |
2256 |
|
... | ... | |
2288 |
2290 |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
|
2289 |
2291 |
DESC_W_MASK | DESC_A_MASK);
|
2290 |
2292 |
}
|
2291 |
|
ESP = env->regs[R_ECX];
|
|
2293 |
env->regs[R_ESP] = env->regs[R_ECX];
|
2292 |
2294 |
EIP = env->regs[R_EDX];
|
2293 |
2295 |
}
|
2294 |
2296 |
|