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