Commit ce09776be290b06562d3a6a7c262e880cbac666a
1 parent
5be1a8e0
PowerPC System emulation (Jocelyn Mayer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@534 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
28 additions
and
5 deletions
cpu-exec.c
| ... | ... | @@ -169,6 +169,8 @@ int cpu_exec(CPUState *env1) |
| 169 | 169 | env->exception_is_int, |
| 170 | 170 | env->error_code, |
| 171 | 171 | env->exception_next_eip, 0); |
| 172 | +#elif defined(TARGET_PPC) | |
| 173 | + do_interrupt(env); | |
| 172 | 174 | #endif |
| 173 | 175 | } |
| 174 | 176 | env->exception_index = -1; |
| ... | ... | @@ -201,6 +203,13 @@ int cpu_exec(CPUState *env1) |
| 201 | 203 | T0 = 0; |
| 202 | 204 | #endif |
| 203 | 205 | } |
| 206 | +#elif defined(TARGET_PPC) | |
| 207 | + if ((interrupt_request & CPU_INTERRUPT_HARD)) { | |
| 208 | + do_queue_exception(EXCP_EXTERNAL); | |
| 209 | + if (check_exception_state(env)) | |
| 210 | + do_interrupt(env); | |
| 211 | + env->interrupt_request &= ~CPU_INTERRUPT_HARD; | |
| 212 | + } | |
| 204 | 213 | #endif |
| 205 | 214 | if (interrupt_request & CPU_INTERRUPT_EXIT) { |
| 206 | 215 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; |
| ... | ... | @@ -250,7 +259,7 @@ int cpu_exec(CPUState *env1) |
| 250 | 259 | pc = (uint8_t *)env->regs[15]; |
| 251 | 260 | #elif defined(TARGET_SPARC) |
| 252 | 261 | flags = 0; |
| 253 | - cs_base = env->npc; | |
| 262 | + cs_base = (uint8_t *)env->npc; | |
| 254 | 263 | pc = (uint8_t *) env->pc; |
| 255 | 264 | #elif defined(TARGET_PPC) |
| 256 | 265 | flags = 0; |
| ... | ... | @@ -571,8 +580,9 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
| 571 | 580 | int is_write, sigset_t *old_set) |
| 572 | 581 | { |
| 573 | 582 | TranslationBlock *tb; |
| 583 | + int ret; | |
| 574 | 584 | |
| 575 | -#if 0 | |
| 585 | +#if 1 | |
| 576 | 586 | if (cpu_single_env) |
| 577 | 587 | env = cpu_single_env; /* XXX: find a correct solution for multithread */ |
| 578 | 588 | #endif |
| ... | ... | @@ -585,6 +595,13 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
| 585 | 595 | return 1; |
| 586 | 596 | } |
| 587 | 597 | |
| 598 | + /* see if it is an MMU fault */ | |
| 599 | + ret = cpu_ppc_handle_mmu_fault(env, address, is_write | ACCESS_INT, msr_pr, 0); | |
| 600 | + if (ret < 0) | |
| 601 | + return 0; /* not an MMU fault */ | |
| 602 | + if (ret == 0) | |
| 603 | + return 1; /* the MMU fault was handled without causing real CPU fault */ | |
| 604 | + | |
| 588 | 605 | /* now we have a real cpu fault */ |
| 589 | 606 | tb = tb_find_pc(pc); |
| 590 | 607 | if (tb) { |
| ... | ... | @@ -592,14 +609,20 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
| 592 | 609 | a virtual CPU fault */ |
| 593 | 610 | cpu_restore_state(tb, env, pc); |
| 594 | 611 | } |
| 612 | + if (ret == 1) { | |
| 595 | 613 | #if 0 |
| 596 | - printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", | |
| 597 | - env->eip, env->cr[2], env->error_code); | |
| 614 | + printf("PF exception: NIP=0x%08x error=0x%x %p\n", | |
| 615 | + env->nip, env->error_code, tb); | |
| 598 | 616 | #endif |
| 599 | 617 | /* we restore the process signal mask as the sigreturn should |
| 600 | 618 | do it (XXX: use sigsetjmp) */ |
| 601 | 619 | sigprocmask(SIG_SETMASK, old_set, NULL); |
| 602 | - raise_exception_err(EXCP_PROGRAM, env->error_code); | |
| 620 | + do_queue_exception_err(env->exception_index, env->error_code); | |
| 621 | + } else { | |
| 622 | + /* activate soft MMU for this block */ | |
| 623 | + sigprocmask(SIG_SETMASK, old_set, NULL); | |
| 624 | + cpu_loop_exit(); | |
| 625 | + } | |
| 603 | 626 | /* never comes here */ |
| 604 | 627 | return 1; |
| 605 | 628 | } | ... | ... |