Commit ce09776be290b06562d3a6a7c262e880cbac666a

Authored by bellard
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 }
... ...