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,6 +169,8 @@ int cpu_exec(CPUState *env1) | ||
169 | env->exception_is_int, | 169 | env->exception_is_int, |
170 | env->error_code, | 170 | env->error_code, |
171 | env->exception_next_eip, 0); | 171 | env->exception_next_eip, 0); |
172 | +#elif defined(TARGET_PPC) | ||
173 | + do_interrupt(env); | ||
172 | #endif | 174 | #endif |
173 | } | 175 | } |
174 | env->exception_index = -1; | 176 | env->exception_index = -1; |
@@ -201,6 +203,13 @@ int cpu_exec(CPUState *env1) | @@ -201,6 +203,13 @@ int cpu_exec(CPUState *env1) | ||
201 | T0 = 0; | 203 | T0 = 0; |
202 | #endif | 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 | #endif | 213 | #endif |
205 | if (interrupt_request & CPU_INTERRUPT_EXIT) { | 214 | if (interrupt_request & CPU_INTERRUPT_EXIT) { |
206 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; | 215 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; |
@@ -250,7 +259,7 @@ int cpu_exec(CPUState *env1) | @@ -250,7 +259,7 @@ int cpu_exec(CPUState *env1) | ||
250 | pc = (uint8_t *)env->regs[15]; | 259 | pc = (uint8_t *)env->regs[15]; |
251 | #elif defined(TARGET_SPARC) | 260 | #elif defined(TARGET_SPARC) |
252 | flags = 0; | 261 | flags = 0; |
253 | - cs_base = env->npc; | 262 | + cs_base = (uint8_t *)env->npc; |
254 | pc = (uint8_t *) env->pc; | 263 | pc = (uint8_t *) env->pc; |
255 | #elif defined(TARGET_PPC) | 264 | #elif defined(TARGET_PPC) |
256 | flags = 0; | 265 | flags = 0; |
@@ -571,8 +580,9 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -571,8 +580,9 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
571 | int is_write, sigset_t *old_set) | 580 | int is_write, sigset_t *old_set) |
572 | { | 581 | { |
573 | TranslationBlock *tb; | 582 | TranslationBlock *tb; |
583 | + int ret; | ||
574 | 584 | ||
575 | -#if 0 | 585 | +#if 1 |
576 | if (cpu_single_env) | 586 | if (cpu_single_env) |
577 | env = cpu_single_env; /* XXX: find a correct solution for multithread */ | 587 | env = cpu_single_env; /* XXX: find a correct solution for multithread */ |
578 | #endif | 588 | #endif |
@@ -585,6 +595,13 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -585,6 +595,13 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
585 | return 1; | 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 | /* now we have a real cpu fault */ | 605 | /* now we have a real cpu fault */ |
589 | tb = tb_find_pc(pc); | 606 | tb = tb_find_pc(pc); |
590 | if (tb) { | 607 | if (tb) { |
@@ -592,14 +609,20 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -592,14 +609,20 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
592 | a virtual CPU fault */ | 609 | a virtual CPU fault */ |
593 | cpu_restore_state(tb, env, pc); | 610 | cpu_restore_state(tb, env, pc); |
594 | } | 611 | } |
612 | + if (ret == 1) { | ||
595 | #if 0 | 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 | #endif | 616 | #endif |
599 | /* we restore the process signal mask as the sigreturn should | 617 | /* we restore the process signal mask as the sigreturn should |
600 | do it (XXX: use sigsetjmp) */ | 618 | do it (XXX: use sigsetjmp) */ |
601 | sigprocmask(SIG_SETMASK, old_set, NULL); | 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 | /* never comes here */ | 626 | /* never comes here */ |
604 | return 1; | 627 | return 1; |
605 | } | 628 | } |