File:  [Qemu by Fabrice Bellard] / qemu / softmmu_header.h
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:20:45 2018 UTC (2 years, 2 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, qemu0111, qemu0110, HEAD
qemu 0.11.0

    1: /*
    2:  *  Software MMU support
    3:  *
    4:  *  Copyright (c) 2003 Fabrice Bellard
    5:  *
    6:  * This library is free software; you can redistribute it and/or
    7:  * modify it under the terms of the GNU Lesser General Public
    8:  * License as published by the Free Software Foundation; either
    9:  * version 2 of the License, or (at your option) any later version.
   10:  *
   11:  * This library is distributed in the hope that it will be useful,
   12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * Lesser General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU Lesser General Public
   17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
   18:  */
   19: #if DATA_SIZE == 8
   20: #define SUFFIX q
   21: #define USUFFIX q
   22: #define DATA_TYPE uint64_t
   23: #elif DATA_SIZE == 4
   24: #define SUFFIX l
   25: #define USUFFIX l
   26: #define DATA_TYPE uint32_t
   27: #elif DATA_SIZE == 2
   28: #define SUFFIX w
   29: #define USUFFIX uw
   30: #define DATA_TYPE uint16_t
   31: #define DATA_STYPE int16_t
   32: #elif DATA_SIZE == 1
   33: #define SUFFIX b
   34: #define USUFFIX ub
   35: #define DATA_TYPE uint8_t
   36: #define DATA_STYPE int8_t
   37: #else
   38: #error unsupported data size
   39: #endif
   40: 
   41: #if ACCESS_TYPE < (NB_MMU_MODES)
   42: 
   43: #define CPU_MMU_INDEX ACCESS_TYPE
   44: #define MMUSUFFIX _mmu
   45: 
   46: #elif ACCESS_TYPE == (NB_MMU_MODES)
   47: 
   48: #define CPU_MMU_INDEX (cpu_mmu_index(env))
   49: #define MMUSUFFIX _mmu
   50: 
   51: #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
   52: 
   53: #define CPU_MMU_INDEX (cpu_mmu_index(env))
   54: #define MMUSUFFIX _cmmu
   55: 
   56: #else
   57: #error invalid ACCESS_TYPE
   58: #endif
   59: 
   60: #if DATA_SIZE == 8
   61: #define RES_TYPE uint64_t
   62: #else
   63: #define RES_TYPE int
   64: #endif
   65: 
   66: #if ACCESS_TYPE == (NB_MMU_MODES + 1)
   67: #define ADDR_READ addr_code
   68: #else
   69: #define ADDR_READ addr_read
   70: #endif
   71: 
   72: /* generic load/store macros */
   73: 
   74: static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
   75: {
   76:     int page_index;
   77:     RES_TYPE res;
   78:     target_ulong addr;
   79:     unsigned long physaddr;
   80:     int mmu_idx;
   81: 
   82:     addr = ptr;
   83:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
   84:     mmu_idx = CPU_MMU_INDEX;
   85:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
   86:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
   87:         res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
   88:     } else {
   89:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
   90:         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
   91:     }
   92:     return res;
   93: }
   94: 
   95: #if DATA_SIZE <= 2
   96: static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
   97: {
   98:     int res, page_index;
   99:     target_ulong addr;
  100:     unsigned long physaddr;
  101:     int mmu_idx;
  102: 
  103:     addr = ptr;
  104:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  105:     mmu_idx = CPU_MMU_INDEX;
  106:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
  107:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
  108:         res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
  109:     } else {
  110:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
  111:         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
  112:     }
  113:     return res;
  114: }
  115: #endif
  116: 
  117: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
  118: 
  119: /* generic store macro */
  120: 
  121: static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
  122: {
  123:     int page_index;
  124:     target_ulong addr;
  125:     unsigned long physaddr;
  126:     int mmu_idx;
  127: 
  128:     addr = ptr;
  129:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  130:     mmu_idx = CPU_MMU_INDEX;
  131:     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
  132:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
  133:         glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
  134:     } else {
  135:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
  136:         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
  137:     }
  138: }
  139: 
  140: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
  141: 
  142: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
  143: 
  144: #if DATA_SIZE == 8
  145: static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
  146: {
  147:     union {
  148:         float64 d;
  149:         uint64_t i;
  150:     } u;
  151:     u.i = glue(ldq, MEMSUFFIX)(ptr);
  152:     return u.d;
  153: }
  154: 
  155: static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
  156: {
  157:     union {
  158:         float64 d;
  159:         uint64_t i;
  160:     } u;
  161:     u.d = v;
  162:     glue(stq, MEMSUFFIX)(ptr, u.i);
  163: }
  164: #endif /* DATA_SIZE == 8 */
  165: 
  166: #if DATA_SIZE == 4
  167: static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
  168: {
  169:     union {
  170:         float32 f;
  171:         uint32_t i;
  172:     } u;
  173:     u.i = glue(ldl, MEMSUFFIX)(ptr);
  174:     return u.f;
  175: }
  176: 
  177: static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
  178: {
  179:     union {
  180:         float32 f;
  181:         uint32_t i;
  182:     } u;
  183:     u.f = v;
  184:     glue(stl, MEMSUFFIX)(ptr, u.i);
  185: }
  186: #endif /* DATA_SIZE == 4 */
  187: 
  188: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
  189: 
  190: #undef RES_TYPE
  191: #undef DATA_TYPE
  192: #undef DATA_STYPE
  193: #undef SUFFIX
  194: #undef USUFFIX
  195: #undef DATA_SIZE
  196: #undef CPU_MMU_INDEX
  197: #undef MMUSUFFIX
  198: #undef ADDR_READ

unix.superglobalmegacorp.com