func: static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
  
  			    int is_user, uint32_t *phys_ptr, int *prot)
  
  {
  
      int code;
  
      uint32_t table;
  
      uint32_t desc;
  
      int type;
  
      int ap;
  
      int domain;
  
      uint32_t phys_addr;
  
  
  
      /* Pagetable walk.  */
  
      /* Lookup l1 descriptor.  */
  
      table = get_level1_table_address(env, address);
  
      desc = ldl_phys(table);
  
      type = (desc & 3);
  
      domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
  
      if (type == 0) {
  
          /* Section translation fault.  */
  
          code = 5;
  
          goto do_fault;
  
      }
  
      if (domain == 0 || domain == 2) {
  
          if (type == 2)
  
              code = 9; /* Section domain fault.  */
  
          else
  
              code = 11; /* Page domain fault.  */
  
          goto do_fault;
  
      }
  
      if (type == 2) {
  
          /* 1Mb section.  */
  
          phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
  
          ap = (desc >> 10) & 3;
  
          code = 13;
  
      } else {
  
          /* Lookup l2 entry.  */
  
  	if (type == 1) {
  
  	    /* Coarse pagetable.  */
  
  	    table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
  
  	} else {
  
  	    /* Fine pagetable.  */
  
  	    table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
  
  	}
  
          desc = ldl_phys(table);
  
          switch (desc & 3) {
  
          case 0: /* Page translation fault.  */
  
              code = 7;
  
              goto do_fault;
  
          case 1: /* 64k page.  */
  
              phys_addr = (desc & 0xffff0000) | (address & 0xffff);
  
              ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
  
              break;
  
          case 2: /* 4k page.  */
  
              phys_addr = (desc & 0xfffff000) | (address & 0xfff);
  
              ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
  
              break;
  
          case 3: /* 1k page.  */
  
  	    if (type == 1) {
  
  		if (arm_feature(env, ARM_FEATURE_XSCALE)) {
  
  		    phys_addr = (desc & 0xfffff000) | (address & 0xfff);
  
  		} else {
  
  		    /* Page translation fault.  */
  
  		    code = 7;
  
  		    goto do_fault;
  
  		}
  
  	    } else {
  
  		phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
  
  	    }
  
              ap = (desc >> 4) & 3;
  
              break;
  
          default:
  
              /* Never happens, but compiler isn't smart enough to tell.  */
  
              abort();
  
          }
  
          code = 15;
  
      }
  
      *prot = check_ap(env, ap, domain, access_type, is_user);
  
      if (!*prot) {
  
          /* Access permission fault.  */
  
          goto do_fault;
  
      }
  
      *phys_ptr = phys_addr;
  
      return 0;
  
  do_fault:
  
      return code | (domain << 4);
  
  }
  