Changeset 36175 in vbox for trunk/src/recompiler/cpu-exec.c
- Timestamp:
- Mar 4, 2011 4:21:09 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler/cpu-exec.c
r36171 r36175 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 18 */ 20 19 … … 29 28 30 29 #include "config.h" 31 #define CPU_NO_GLOBAL_REGS32 30 #include "exec.h" 33 31 #include "disas.h" … … 61 59 //#define DEBUG_EXEC 62 60 //#define DEBUG_SIGNAL 61 62 int qemu_cpu_has_work(CPUState *env) 63 { 64 return cpu_has_work(env); 65 } 63 66 64 67 void cpu_loop_exit(void) … … 389 392 } 390 393 RAWEx_ProfileStop(env, STATS_IRQ_HANDLING); 391 if (interrupt_request & CPU_INTERRUPT_EXIT)392 {393 env->exception_index = EXCP_INTERRUPT;394 ASMAtomicAndS32((int32_t volatile *)&env->interrupt_request, ~CPU_INTERRUPT_EXIT);395 ret = env->exception_index;396 cpu_loop_exit();397 }398 394 if (interrupt_request & CPU_INTERRUPT_RC) 399 395 { … … 518 514 gcc-4.4/amd64 anymore, see #3883. */ 519 515 env->current_tb = NULL; 520 if ( !(env->interrupt_request & ( CPU_INTERRUPT_ EXIT | CPU_INTERRUPT_DEBUG | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_RC516 if ( !(env->interrupt_request & ( CPU_INTERRUPT_DEBUG | CPU_INTERRUPT_EXTERNAL_EXIT | CPU_INTERRUPT_RC 521 517 | CPU_INTERRUPT_SINGLE_INSTR | CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT)) 522 518 && ( (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_TIMER) … … 575 571 #elif defined(TARGET_ARM) 576 572 #elif defined(TARGET_PPC) 573 #elif defined(TARGET_MICROBLAZE) 577 574 #elif defined(TARGET_MIPS) 578 575 #elif defined(TARGET_SH4) … … 587 584 for(;;) { 588 585 if (setjmp(env->jmp_env) == 0) { 586 #if defined(__sparc__) && !defined(HOST_SOLARIS) 587 #undef env 588 env = cpu_single_env; 589 #define env cpu_single_env 590 #endif 589 591 env->current_tb = NULL; 590 592 /* if an exception is pending, we execute it here */ … … 624 626 #elif defined(TARGET_PPC) 625 627 do_interrupt(env); 628 #elif defined(TARGET_MICROBLAZE) 629 do_interrupt(env); 626 630 #elif defined(TARGET_MIPS) 627 631 do_interrupt(env); … … 643 647 env->exception_index = -1; 644 648 } 645 #ifdef USE_KQEMU649 #ifdef CONFIG_KQEMU 646 650 if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) { 647 651 int ret; … … 691 695 } 692 696 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ 693 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) 697 defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ 698 defined(TARGET_MICROBLAZE) 694 699 if (interrupt_request & CPU_INTERRUPT_HALT) { 695 700 env->interrupt_request &= ~CPU_INTERRUPT_HALT; … … 700 705 #endif 701 706 #if defined(TARGET_I386) 702 if (env->hflags2 & HF2_GIF_MASK) { 707 if (interrupt_request & CPU_INTERRUPT_INIT) { 708 svm_check_intercept(SVM_EXIT_INIT); 709 do_cpu_init(env); 710 env->exception_index = EXCP_HALTED; 711 cpu_loop_exit(); 712 } else if (interrupt_request & CPU_INTERRUPT_SIPI) { 713 do_cpu_sipi(env); 714 } else if (env->hflags2 & HF2_GIF_MASK) { 703 715 if ((interrupt_request & CPU_INTERRUPT_SMI) && 704 716 !(env->hflags & HF_SMM_MASK)) { … … 713 725 do_interrupt(EXCP02_NMI, 0, 0, 0, 1); 714 726 next_tb = 0; 727 } else if (interrupt_request & CPU_INTERRUPT_MCE) { 728 env->interrupt_request &= ~CPU_INTERRUPT_MCE; 729 do_interrupt(EXCP12_MCHK, 0, 0, 0, 0); 730 next_tb = 0; 715 731 } else if ((interrupt_request & CPU_INTERRUPT_HARD) && 716 732 (((env->hflags2 & HF2_VINTR_MASK) && … … 724 740 intno = cpu_get_pic_interrupt(env); 725 741 qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); 742 #if defined(__sparc__) && !defined(HOST_SOLARIS) 743 #undef env 744 env = cpu_single_env; 745 #define env cpu_single_env 746 #endif 726 747 do_interrupt(intno, 0, 0, 0, 1); 727 748 /* ensure that no TB jump will be modified as … … 755 776 next_tb = 0; 756 777 } 778 #elif defined(TARGET_MICROBLAZE) 779 if ((interrupt_request & CPU_INTERRUPT_HARD) 780 && (env->sregs[SR_MSR] & MSR_IE) 781 && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)) 782 && !(env->iflags & (D_FLAG | IMM_FLAG))) { 783 env->exception_index = EXCP_IRQ; 784 do_interrupt(env); 785 next_tb = 0; 786 } 757 787 #elif defined(TARGET_MIPS) 758 788 if ((interrupt_request & CPU_INTERRUPT_HARD) && … … 770 800 #elif defined(TARGET_SPARC) 771 801 if ((interrupt_request & CPU_INTERRUPT_HARD) && 772 (env->psret != 0)) {802 cpu_interrupts_enabled(env)) { 773 803 int pil = env->interrupt_index & 15; 774 804 int type = env->interrupt_index & 0xf0; … … 781 811 do_interrupt(env); 782 812 env->interrupt_index = 0; 783 #if !defined( TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)813 #if !defined(CONFIG_USER_ONLY) 784 814 cpu_check_irqs(env); 785 815 #endif … … 884 914 | env->cc_dest | (env->cc_x << 4); 885 915 log_cpu_state(env, 0); 916 #elif defined(TARGET_MICROBLAZE) 917 log_cpu_state(env, 0); 886 918 #elif defined(TARGET_MIPS) 887 919 log_cpu_state(env, 0); … … 918 950 { 919 951 if (next_tb != 0 && 920 #ifdef USE_KQEMU952 #ifdef CONFIG_KQEMU 921 953 (env->kqemu_enabled != 2) && 922 954 #endif … … 975 1007 /* reset soft MMU for next block (it can currently 976 1008 only be set by a memory fault) */ 977 #if defined( USE_KQEMU)1009 #if defined(CONFIG_KQEMU) 978 1010 #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000) 979 1011 if (kqemu_is_ok(env) && … … 1001 1033 env->sr = (env->sr & 0xffe0) 1002 1034 | env->cc_dest | (env->cc_x << 4); 1035 #elif defined(TARGET_MICROBLAZE) 1003 1036 #elif defined(TARGET_MIPS) 1004 1037 #elif defined(TARGET_SH4) … … 1118 1151 if (ret == 1) { 1119 1152 #if 0 1120 printf("PF exception: EIP=0x% RGv CR2=0x%RGverror=0x%x\n",1153 printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", 1121 1154 env->eip, env->cr[2], env->error_code); 1122 1155 #endif … … 1349 1382 } 1350 1383 1384 #elif defined (TARGET_MICROBLAZE) 1385 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, 1386 int is_write, sigset_t *old_set, 1387 void *puc) 1388 { 1389 TranslationBlock *tb; 1390 int ret; 1391 1392 if (cpu_single_env) 1393 env = cpu_single_env; /* XXX: find a correct solution for multithread */ 1394 #if defined(DEBUG_SIGNAL) 1395 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 1396 pc, address, is_write, *(unsigned long *)old_set); 1397 #endif 1398 /* XXX: locking issue */ 1399 if (is_write && page_unprotect(h2g(address), pc, puc)) { 1400 return 1; 1401 } 1402 1403 /* see if it is an MMU fault */ 1404 ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); 1405 if (ret < 0) 1406 return 0; /* not an MMU fault */ 1407 if (ret == 0) 1408 return 1; /* the MMU fault was handled without causing real CPU fault */ 1409 1410 /* now we have a real cpu fault */ 1411 tb = tb_find_pc(pc); 1412 if (tb) { 1413 /* the PC is inside the translated code. It means that we have 1414 a virtual CPU fault */ 1415 cpu_restore_state(tb, env, pc, puc); 1416 } 1417 if (ret == 1) { 1418 #if 0 1419 printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n", 1420 env->PC, env->error_code, tb); 1421 #endif 1422 /* we restore the process signal mask as the sigreturn should 1423 do it (XXX: use sigsetjmp) */ 1424 sigprocmask(SIG_SETMASK, old_set, NULL); 1425 cpu_loop_exit(); 1426 } else { 1427 /* activate soft MMU for this block */ 1428 cpu_resume_from_signal(env, puc); 1429 } 1430 /* never comes here */ 1431 return 1; 1432 } 1433 1351 1434 #elif defined (TARGET_SH4) 1352 1435 static inline int handle_cpu_signal(unsigned long pc, unsigned long address, … … 1491 1574 # define TRAP_sig(context) ((context)->uc_mcontext->es.trapno) 1492 1575 # define ERROR_sig(context) ((context)->uc_mcontext->es.err) 1576 # define MASK_sig(context) ((context)->uc_sigmask) 1577 #elif defined(__OpenBSD__) 1578 # define EIP_sig(context) ((context)->sc_eip) 1579 # define TRAP_sig(context) ((context)->sc_trapno) 1580 # define ERROR_sig(context) ((context)->sc_err) 1581 # define MASK_sig(context) ((context)->sc_mask) 1493 1582 #else 1494 1583 # define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP]) 1495 1584 # define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) 1496 1585 # define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) 1586 # define MASK_sig(context) ((context)->uc_sigmask) 1497 1587 #endif 1498 1588 … … 1501 1591 { 1502 1592 siginfo_t *info = pinfo; 1593 #if defined(__OpenBSD__) 1594 struct sigcontext *uc = puc; 1595 #else 1503 1596 struct ucontext *uc = puc; 1597 #endif 1504 1598 unsigned long pc; 1505 1599 int trapno; … … 1516 1610 trapno == 0xe ? 1517 1611 (ERROR_sig(uc) >> 1) & 1 : 0, 1518 & uc->uc_sigmask, puc);1612 &MASK_sig(uc), puc); 1519 1613 } 1520 1614 … … 1522 1616 1523 1617 #ifdef __NetBSD__ 1524 #define REG_ERR _REG_ERR 1525 #define REG_TRAPNO _REG_TRAPNO 1526 1527 #define QEMU_UC_MCONTEXT_GREGS(uc, reg) (uc)->uc_mcontext.__gregs[(reg)] 1528 #define QEMU_UC_MACHINE_PC(uc) _UC_MACHINE_PC(uc) 1618 #define PC_sig(context) _UC_MACHINE_PC(context) 1619 #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) 1620 #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) 1621 #define MASK_sig(context) ((context)->uc_sigmask) 1622 #elif defined(__OpenBSD__) 1623 #define PC_sig(context) ((context)->sc_rip) 1624 #define TRAP_sig(context) ((context)->sc_trapno) 1625 #define ERROR_sig(context) ((context)->sc_err) 1626 #define MASK_sig(context) ((context)->sc_mask) 1529 1627 #else 1530 #define QEMU_UC_MCONTEXT_GREGS(uc, reg) (uc)->uc_mcontext.gregs[(reg)] 1531 #define QEMU_UC_MACHINE_PC(uc) QEMU_UC_MCONTEXT_GREGS(uc, REG_RIP) 1628 #define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP]) 1629 #define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) 1630 #define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) 1631 #define MASK_sig(context) ((context)->uc_sigmask) 1532 1632 #endif 1533 1633 … … 1539 1639 #ifdef __NetBSD__ 1540 1640 ucontext_t *uc = puc; 1641 #elif defined(__OpenBSD__) 1642 struct sigcontext *uc = puc; 1541 1643 #else 1542 1644 struct ucontext *uc = puc; 1543 1645 #endif 1544 1646 1545 pc = QEMU_UC_MACHINE_PC(uc);1647 pc = PC_sig(uc); 1546 1648 return handle_cpu_signal(pc, (unsigned long)info->si_addr, 1547 QEMU_UC_MCONTEXT_GREGS(uc, REG_TRAPNO) == 0xe ?1548 ( QEMU_UC_MCONTEXT_GREGS(uc, REG_ERR) >> 1) & 1 : 0,1549 & uc->uc_sigmask, puc);1649 TRAP_sig(uc) == 0xe ? 1650 (ERROR_sig(uc) >> 1) & 1 : 0, 1651 &MASK_sig(uc), puc); 1550 1652 } 1551 1653 … … 1684 1786 switch((insn >> 19) & 0x3f) { 1685 1787 case 0x05: // stb 1788 case 0x15: // stba 1686 1789 case 0x06: // sth 1790 case 0x16: // stha 1687 1791 case 0x04: // st 1792 case 0x14: // sta 1688 1793 case 0x07: // std 1794 case 0x17: // stda 1795 case 0x0e: // stx 1796 case 0x1e: // stxa 1689 1797 case 0x24: // stf 1798 case 0x34: // stfa 1690 1799 case 0x27: // stdf 1800 case 0x37: // stdfa 1801 case 0x26: // stqf 1802 case 0x36: // stqfa 1691 1803 case 0x25: // stfsr 1804 case 0x3c: // casa 1805 case 0x3e: // casxa 1692 1806 is_write = 1; 1693 1807 break;
Note:
See TracChangeset
for help on using the changeset viewer.