func: int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
  
                                int is_user, int is_softmmu)
  
  {
  
      uint32_t physical;
  
      int prot;
  
      int exception = 0, error_code = 0;
  
      int access_type;
  
      int ret = 0;
  
  
  
  //    printf("%s 0\n", __func__);
  
      access_type = env->access_type;
  
      if (env->user_mode_only) {
  
          /* user mode only emulation */
  
          ret = -2;
  
          goto do_fault;
  
      }
  
      /* NASTY BUG workaround */
  
      if (access_type == ACCESS_CODE && rw) {
  
  	printf("%s: ERROR WRITE CODE ACCESS\n", __func__);
  
  	access_type = ACCESS_INT;
  
      }
  
      ret = get_physical_address(env, &physical, &prot,
  
                                 address, rw, access_type);
  
      if (ret == 0) {
  
  	ret = tlb_set_page(env, address & ~0xFFF, physical, prot,
  
  			   is_user, is_softmmu);
  
      } else if (ret < 0) {
  
      do_fault:
  
  #if defined (DEBUG_MMU)
  
  	if (loglevel > 0)
  
  	    cpu_ppc_dump_state(env, logfile, 0);
  
  #endif
  
          if (access_type == ACCESS_CODE) {
  
              exception = EXCP_ISI;
  
              switch (ret) {
  
              case -1:
  
                  /* No matches in page tables */
  
                  error_code = EXCP_ISI_TRANSLATE;
  
                  break;
  
              case -2:
  
                  /* Access rights violation */
  
                  error_code = EXCP_ISI_PROT;
  
                  break;
  
              case -3:
  
  		/* No execute protection violation */
  
                  error_code = EXCP_ISI_NOEXEC;
  
                  break;
  
              case -4:
  
                  /* Direct store exception */
  
                  /* No code fetch is allowed in direct-store areas */
  
                  error_code = EXCP_ISI_DIRECT;
  
                  break;
  
              }
  
          } else {
  
              exception = EXCP_DSI;
  
              switch (ret) {
  
              case -1:
  
                  /* No matches in page tables */
  
                  error_code = EXCP_DSI_TRANSLATE;
  
                  break;
  
              case -2:
  
                  /* Access rights violation */
  
                  error_code = EXCP_DSI_PROT;
  
                  break;
  
              case -4:
  
                  /* Direct store exception */
  
                  switch (access_type) {
  
                  case ACCESS_FLOAT:
  
                      /* Floating point load/store */
  
                      exception = EXCP_ALIGN;
  
                      error_code = EXCP_ALIGN_FP;
  
                      break;
  
                  case ACCESS_RES:
  
                      /* lwarx, ldarx or srwcx. */
  
                      exception = EXCP_DSI;
  
                      error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT;
  
                      break;
  
                  case ACCESS_EXT:
  
                      /* eciwx or ecowx */
  
                      exception = EXCP_DSI;
  
                      error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT |
  
  			EXCP_DSI_ECXW;
  
                      break;
  
                  default:
  
  		    printf("DSI: invalid exception (%d)\n", ret);
  
                      exception = EXCP_PROGRAM;
  
                      error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
  
                      break;
  
                  }
  
              }
  
              if (rw)
  
                  error_code |= EXCP_DSI_STORE;
  
  	    /* Store fault address */
  
  	    env->spr[DAR] = address;
  
          }
  
  #if 0
  
          printf("%s: set exception to %d %02x\n",
  
                 __func__, exception, error_code);
  
  #endif
  
          env->exception_index = exception;
  
          env->error_code = error_code;
  
          ret = 1;
  
      }
  
  
  
      return ret;
  
  }
  