Commit f3f2d9be03816c991fff05ba30e6d9490005d282

Authored by bellard
1 parent 77729c24

call gate fix - verr and verw fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@459 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 43 additions and 5 deletions
target-i386/helper.c
@@ -19,6 +19,8 @@ @@ -19,6 +19,8 @@
19 */ 19 */
20 #include "exec.h" 20 #include "exec.h"
21 21
  22 +//#define DEBUG_PCALL
  23 +
22 const uint8_t parity_table[256] = { 24 const uint8_t parity_table[256] = {
23 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 25 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
24 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 26 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
@@ -540,6 +542,27 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, @@ -540,6 +542,27 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
540 uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2, push_size; 542 uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2, push_size;
541 uint32_t old_cs, old_ss, old_esp, old_eip; 543 uint32_t old_cs, old_ss, old_esp, old_eip;
542 544
  545 +#ifdef DEBUG_PCALL
  546 + if (loglevel) {
  547 + static int count;
  548 + fprintf(logfile, "%d: interrupt: vector=%02x error_code=%04x int=%d CS:IP=%04x:%08x CPL=%d\n",
  549 + count, intno, error_code, is_int, env->segs[R_CS].selector, env->eip, env->hflags & 3);
  550 +#if 0
  551 + {
  552 + int i;
  553 + uint8_t *ptr;
  554 + printf(" code=");
  555 + ptr = env->segs[R_CS].base + env->eip;
  556 + for(i = 0; i < 16; i++) {
  557 + printf(" %02x", ldub(ptr + i));
  558 + }
  559 + printf("\n");
  560 + }
  561 +#endif
  562 + count++;
  563 + }
  564 +#endif
  565 +
543 has_error_code = 0; 566 has_error_code = 0;
544 if (!is_int && !is_hw) { 567 if (!is_int && !is_hw) {
545 switch(intno) { 568 switch(intno) {
@@ -1260,11 +1283,22 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1260,11 +1283,22 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1260 1283
1261 new_cs = T0; 1284 new_cs = T0;
1262 new_eip = T1; 1285 new_eip = T1;
  1286 +#ifdef DEBUG_PCALL
  1287 + if (loglevel) {
  1288 + fprintf(logfile, "lcall %04x:%08x\n",
  1289 + new_cs, new_eip);
  1290 + }
  1291 +#endif
1263 if ((new_cs & 0xfffc) == 0) 1292 if ((new_cs & 0xfffc) == 0)
1264 raise_exception_err(EXCP0D_GPF, 0); 1293 raise_exception_err(EXCP0D_GPF, 0);
1265 if (load_segment(&e1, &e2, new_cs) != 0) 1294 if (load_segment(&e1, &e2, new_cs) != 0)
1266 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); 1295 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1267 cpl = env->hflags & HF_CPL_MASK; 1296 cpl = env->hflags & HF_CPL_MASK;
  1297 +#ifdef DEBUG_PCALL
  1298 + if (loglevel) {
  1299 + fprintf(logfile, "desc=%08x:%08x\n", e1, e2);
  1300 + }
  1301 +#endif
1268 if (e2 & DESC_S_MASK) { 1302 if (e2 & DESC_S_MASK) {
1269 if (!(e2 & DESC_CS_MASK)) 1303 if (!(e2 & DESC_CS_MASK))
1270 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); 1304 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
@@ -1341,6 +1375,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1341,6 +1375,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1341 raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); 1375 raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
1342 selector = e1 >> 16; 1376 selector = e1 >> 16;
1343 offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); 1377 offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
  1378 + param_count = e2 & 0x1f;
1344 if ((selector & 0xfffc) == 0) 1379 if ((selector & 0xfffc) == 0)
1345 raise_exception_err(EXCP0D_GPF, 0); 1380 raise_exception_err(EXCP0D_GPF, 0);
1346 1381
@@ -1357,6 +1392,11 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1357,6 +1392,11 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1357 if (!(e2 & DESC_C_MASK) && dpl < cpl) { 1392 if (!(e2 & DESC_C_MASK) && dpl < cpl) {
1358 /* to inner priviledge */ 1393 /* to inner priviledge */
1359 get_ss_esp_from_tss(&ss, &sp, dpl); 1394 get_ss_esp_from_tss(&ss, &sp, dpl);
  1395 +#ifdef DEBUG_PCALL
  1396 + if (loglevel)
  1397 + fprintf(logfile, "ss=%04x sp=%04x param_count=%d ESP=%x\n",
  1398 + ss, sp, param_count, ESP);
  1399 +#endif
1360 if ((ss & 0xfffc) == 0) 1400 if ((ss & 0xfffc) == 0)
1361 raise_exception_err(EXCP0A_TSS, ss & 0xfffc); 1401 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
1362 if ((ss & 3) != dpl) 1402 if ((ss & 3) != dpl)
@@ -1373,7 +1413,6 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1373,7 +1413,6 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1373 if (!(ss_e2 & DESC_P_MASK)) 1413 if (!(ss_e2 & DESC_P_MASK))
1374 raise_exception_err(EXCP0A_TSS, ss & 0xfffc); 1414 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
1375 1415
1376 - param_count = e2 & 0x1f;  
1377 push_size = ((param_count * 2) + 8) << shift; 1416 push_size = ((param_count * 2) + 8) << shift;
1378 1417
1379 old_esp = ESP; 1418 old_esp = ESP;
@@ -1389,7 +1428,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1389,7 +1428,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1389 get_seg_limit(ss_e1, ss_e2), 1428 get_seg_limit(ss_e1, ss_e2),
1390 ss_e2); 1429 ss_e2);
1391 1430
1392 - if (!(env->segs[R_SS].flags & DESC_B_MASK)) 1431 + if (!(ss_e2 & DESC_B_MASK))
1393 sp &= 0xffff; 1432 sp &= 0xffff;
1394 ssp = env->segs[R_SS].base + sp; 1433 ssp = env->segs[R_SS].base + sp;
1395 if (shift) { 1434 if (shift) {
@@ -1441,7 +1480,6 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) @@ -1441,7 +1480,6 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1441 e2); 1480 e2);
1442 cpu_x86_set_cpl(env, dpl); 1481 cpu_x86_set_cpl(env, dpl);
1443 1482
1444 - /* from this point, not restartable if same priviledge */  
1445 if (!(env->segs[R_SS].flags & DESC_B_MASK)) 1483 if (!(env->segs[R_SS].flags & DESC_B_MASK))
1446 ESP = (ESP & 0xffff0000) | (sp & 0xffff); 1484 ESP = (ESP & 0xffff0000) | (sp & 0xffff);
1447 else 1485 else
@@ -1838,7 +1876,7 @@ void helper_verr(void) @@ -1838,7 +1876,7 @@ void helper_verr(void)
1838 if (dpl < cpl || dpl < rpl) 1876 if (dpl < cpl || dpl < rpl)
1839 return; 1877 return;
1840 } 1878 }
1841 - /* ok */ 1879 + CC_SRC |= CC_Z;
1842 } 1880 }
1843 1881
1844 void helper_verw(void) 1882 void helper_verw(void)
@@ -1866,7 +1904,7 @@ void helper_verw(void) @@ -1866,7 +1904,7 @@ void helper_verw(void)
1866 if (!(e2 & DESC_W_MASK)) 1904 if (!(e2 & DESC_W_MASK))
1867 return; 1905 return;
1868 } 1906 }
1869 - /* ok */ 1907 + CC_SRC |= CC_Z;
1870 } 1908 }
1871 1909
1872 /* FPU helpers */ 1910 /* FPU helpers */