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 | } | ... | ... |