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 19 */
20 20 #include "exec.h"
21 21  
  22 +//#define DEBUG_PCALL
  23 +
22 24 const uint8_t parity_table[256] = {
23 25 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
24 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 542 uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2, push_size;
541 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 566 has_error_code = 0;
544 567 if (!is_int && !is_hw) {
545 568 switch(intno) {
... ... @@ -1260,11 +1283,22 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1260 1283  
1261 1284 new_cs = T0;
1262 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 1292 if ((new_cs & 0xfffc) == 0)
1264 1293 raise_exception_err(EXCP0D_GPF, 0);
1265 1294 if (load_segment(&e1, &e2, new_cs) != 0)
1266 1295 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1267 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 1302 if (e2 & DESC_S_MASK) {
1269 1303 if (!(e2 & DESC_CS_MASK))
1270 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 1375 raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
1342 1376 selector = e1 >> 16;
1343 1377 offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
  1378 + param_count = e2 & 0x1f;
1344 1379 if ((selector & 0xfffc) == 0)
1345 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 1392 if (!(e2 & DESC_C_MASK) && dpl < cpl) {
1358 1393 /* to inner priviledge */
1359 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 1400 if ((ss & 0xfffc) == 0)
1361 1401 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
1362 1402 if ((ss & 3) != dpl)
... ... @@ -1373,7 +1413,6 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1373 1413 if (!(ss_e2 & DESC_P_MASK))
1374 1414 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
1375 1415  
1376   - param_count = e2 & 0x1f;
1377 1416 push_size = ((param_count * 2) + 8) << shift;
1378 1417  
1379 1418 old_esp = ESP;
... ... @@ -1389,7 +1428,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1389 1428 get_seg_limit(ss_e1, ss_e2),
1390 1429 ss_e2);
1391 1430  
1392   - if (!(env->segs[R_SS].flags & DESC_B_MASK))
  1431 + if (!(ss_e2 & DESC_B_MASK))
1393 1432 sp &= 0xffff;
1394 1433 ssp = env->segs[R_SS].base + sp;
1395 1434 if (shift) {
... ... @@ -1441,7 +1480,6 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
1441 1480 e2);
1442 1481 cpu_x86_set_cpl(env, dpl);
1443 1482  
1444   - /* from this point, not restartable if same priviledge */
1445 1483 if (!(env->segs[R_SS].flags & DESC_B_MASK))
1446 1484 ESP = (ESP & 0xffff0000) | (sp & 0xffff);
1447 1485 else
... ... @@ -1838,7 +1876,7 @@ void helper_verr(void)
1838 1876 if (dpl < cpl || dpl < rpl)
1839 1877 return;
1840 1878 }
1841   - /* ok */
  1879 + CC_SRC |= CC_Z;
1842 1880 }
1843 1881  
1844 1882 void helper_verw(void)
... ... @@ -1866,7 +1904,7 @@ void helper_verw(void)
1866 1904 if (!(e2 & DESC_W_MASK))
1867 1905 return;
1868 1906 }
1869   - /* ok */
  1907 + CC_SRC |= CC_Z;
1870 1908 }
1871 1909  
1872 1910 /* FPU helpers */
... ...