Annotation of qemu/cpu-all.h, revision 1.1.1.10

1.1       root        1: /*
                      2:  * defines common to all virtual CPUs
1.1.1.6   root        3:  *
1.1       root        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
1.1.1.8   root       17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: #ifndef CPU_ALL_H
                     20: #define CPU_ALL_H
                     21: 
1.1.1.7   root       22: #include "qemu-common.h"
1.1.1.8   root       23: #include "cpu-common.h"
1.1       root       24: 
1.1.1.6   root       25: /* some important defines:
                     26:  *
1.1       root       27:  * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
                     28:  * memory accesses.
1.1.1.6   root       29:  *
1.1.1.9   root       30:  * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
1.1       root       31:  * otherwise little endian.
1.1.1.6   root       32:  *
1.1       root       33:  * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
1.1.1.6   root       34:  *
1.1       root       35:  * TARGET_WORDS_BIGENDIAN : same for target cpu
                     36:  */
                     37: 
1.1.1.7   root       38: #include "softfloat.h"
1.1       root       39: 
1.1.1.9   root       40: #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
1.1       root       41: #define BSWAP_NEEDED
                     42: #endif
                     43: 
                     44: #ifdef BSWAP_NEEDED
                     45: 
                     46: static inline uint16_t tswap16(uint16_t s)
                     47: {
                     48:     return bswap16(s);
                     49: }
                     50: 
                     51: static inline uint32_t tswap32(uint32_t s)
                     52: {
                     53:     return bswap32(s);
                     54: }
                     55: 
                     56: static inline uint64_t tswap64(uint64_t s)
                     57: {
                     58:     return bswap64(s);
                     59: }
                     60: 
                     61: static inline void tswap16s(uint16_t *s)
                     62: {
                     63:     *s = bswap16(*s);
                     64: }
                     65: 
                     66: static inline void tswap32s(uint32_t *s)
                     67: {
                     68:     *s = bswap32(*s);
                     69: }
                     70: 
                     71: static inline void tswap64s(uint64_t *s)
                     72: {
                     73:     *s = bswap64(*s);
                     74: }
                     75: 
                     76: #else
                     77: 
                     78: static inline uint16_t tswap16(uint16_t s)
                     79: {
                     80:     return s;
                     81: }
                     82: 
                     83: static inline uint32_t tswap32(uint32_t s)
                     84: {
                     85:     return s;
                     86: }
                     87: 
                     88: static inline uint64_t tswap64(uint64_t s)
                     89: {
                     90:     return s;
                     91: }
                     92: 
                     93: static inline void tswap16s(uint16_t *s)
                     94: {
                     95: }
                     96: 
                     97: static inline void tswap32s(uint32_t *s)
                     98: {
                     99: }
                    100: 
                    101: static inline void tswap64s(uint64_t *s)
                    102: {
                    103: }
                    104: 
                    105: #endif
                    106: 
                    107: #if TARGET_LONG_SIZE == 4
                    108: #define tswapl(s) tswap32(s)
                    109: #define tswapls(s) tswap32s((uint32_t *)(s))
                    110: #define bswaptls(s) bswap32s(s)
                    111: #else
                    112: #define tswapl(s) tswap64(s)
                    113: #define tswapls(s) tswap64s((uint64_t *)(s))
                    114: #define bswaptls(s) bswap64s(s)
                    115: #endif
                    116: 
1.1.1.7   root      117: typedef union {
                    118:     float32 f;
                    119:     uint32_t l;
                    120: } CPU_FloatU;
                    121: 
1.1       root      122: /* NOTE: arm FPA is horrible as double 32 bit words are stored in big
                    123:    endian ! */
                    124: typedef union {
                    125:     float64 d;
1.1.1.9   root      126: #if defined(HOST_WORDS_BIGENDIAN) \
1.1       root      127:     || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
                    128:     struct {
                    129:         uint32_t upper;
                    130:         uint32_t lower;
                    131:     } l;
                    132: #else
                    133:     struct {
                    134:         uint32_t lower;
                    135:         uint32_t upper;
                    136:     } l;
                    137: #endif
                    138:     uint64_t ll;
                    139: } CPU_DoubleU;
                    140: 
1.1.1.6   root      141: #ifdef TARGET_SPARC
                    142: typedef union {
                    143:     float128 q;
1.1.1.9   root      144: #if defined(HOST_WORDS_BIGENDIAN) \
1.1.1.6   root      145:     || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
                    146:     struct {
                    147:         uint32_t upmost;
                    148:         uint32_t upper;
                    149:         uint32_t lower;
                    150:         uint32_t lowest;
                    151:     } l;
                    152:     struct {
                    153:         uint64_t upper;
                    154:         uint64_t lower;
                    155:     } ll;
                    156: #else
                    157:     struct {
                    158:         uint32_t lowest;
                    159:         uint32_t lower;
                    160:         uint32_t upper;
                    161:         uint32_t upmost;
                    162:     } l;
                    163:     struct {
                    164:         uint64_t lower;
                    165:         uint64_t upper;
                    166:     } ll;
                    167: #endif
                    168: } CPU_QuadU;
                    169: #endif
                    170: 
1.1       root      171: /* CPU memory access without any memory or io remapping */
                    172: 
                    173: /*
                    174:  * the generic syntax for the memory accesses is:
                    175:  *
                    176:  * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
                    177:  *
                    178:  * store: st{type}{size}{endian}_{access_type}(ptr, val)
                    179:  *
                    180:  * type is:
                    181:  * (empty): integer access
                    182:  *   f    : float access
1.1.1.6   root      183:  *
1.1       root      184:  * sign is:
                    185:  * (empty): for floats or 32 bit size
                    186:  *   u    : unsigned
                    187:  *   s    : signed
                    188:  *
                    189:  * size is:
                    190:  *   b: 8 bits
                    191:  *   w: 16 bits
                    192:  *   l: 32 bits
                    193:  *   q: 64 bits
1.1.1.6   root      194:  *
1.1       root      195:  * endian is:
                    196:  * (empty): target cpu endianness or 8 bit access
                    197:  *   r    : reversed target cpu endianness (not implemented yet)
                    198:  *   be   : big endian (not implemented yet)
                    199:  *   le   : little endian (not implemented yet)
                    200:  *
                    201:  * access_type is:
                    202:  *   raw    : host memory access
                    203:  *   user   : user mode access using soft MMU
                    204:  *   kernel : kernel mode access using soft MMU
                    205:  */
1.1.1.7   root      206: static inline int ldub_p(const void *ptr)
1.1       root      207: {
                    208:     return *(uint8_t *)ptr;
                    209: }
                    210: 
1.1.1.7   root      211: static inline int ldsb_p(const void *ptr)
1.1       root      212: {
                    213:     return *(int8_t *)ptr;
                    214: }
                    215: 
                    216: static inline void stb_p(void *ptr, int v)
                    217: {
                    218:     *(uint8_t *)ptr = v;
                    219: }
                    220: 
                    221: /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
                    222:    kernel handles unaligned load/stores may give better results, but
                    223:    it is a system wide setting : bad */
1.1.1.9   root      224: #if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
1.1       root      225: 
                    226: /* conservative code for little endian unaligned accesses */
1.1.1.7   root      227: static inline int lduw_le_p(const void *ptr)
1.1       root      228: {
1.1.1.7   root      229: #ifdef _ARCH_PPC
1.1       root      230:     int val;
                    231:     __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
                    232:     return val;
                    233: #else
1.1.1.7   root      234:     const uint8_t *p = ptr;
1.1       root      235:     return p[0] | (p[1] << 8);
                    236: #endif
                    237: }
                    238: 
1.1.1.7   root      239: static inline int ldsw_le_p(const void *ptr)
1.1       root      240: {
1.1.1.7   root      241: #ifdef _ARCH_PPC
1.1       root      242:     int val;
                    243:     __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
                    244:     return (int16_t)val;
                    245: #else
1.1.1.7   root      246:     const uint8_t *p = ptr;
1.1       root      247:     return (int16_t)(p[0] | (p[1] << 8));
                    248: #endif
                    249: }
                    250: 
1.1.1.7   root      251: static inline int ldl_le_p(const void *ptr)
1.1       root      252: {
1.1.1.7   root      253: #ifdef _ARCH_PPC
1.1       root      254:     int val;
                    255:     __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
                    256:     return val;
                    257: #else
1.1.1.7   root      258:     const uint8_t *p = ptr;
1.1       root      259:     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
                    260: #endif
                    261: }
                    262: 
1.1.1.7   root      263: static inline uint64_t ldq_le_p(const void *ptr)
1.1       root      264: {
1.1.1.7   root      265:     const uint8_t *p = ptr;
1.1       root      266:     uint32_t v1, v2;
1.1.1.2   root      267:     v1 = ldl_le_p(p);
                    268:     v2 = ldl_le_p(p + 4);
1.1       root      269:     return v1 | ((uint64_t)v2 << 32);
                    270: }
                    271: 
1.1.1.2   root      272: static inline void stw_le_p(void *ptr, int v)
1.1       root      273: {
1.1.1.7   root      274: #ifdef _ARCH_PPC
1.1       root      275:     __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
                    276: #else
                    277:     uint8_t *p = ptr;
                    278:     p[0] = v;
                    279:     p[1] = v >> 8;
                    280: #endif
                    281: }
                    282: 
1.1.1.2   root      283: static inline void stl_le_p(void *ptr, int v)
1.1       root      284: {
1.1.1.7   root      285: #ifdef _ARCH_PPC
1.1       root      286:     __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
                    287: #else
                    288:     uint8_t *p = ptr;
                    289:     p[0] = v;
                    290:     p[1] = v >> 8;
                    291:     p[2] = v >> 16;
                    292:     p[3] = v >> 24;
                    293: #endif
                    294: }
                    295: 
1.1.1.2   root      296: static inline void stq_le_p(void *ptr, uint64_t v)
1.1       root      297: {
                    298:     uint8_t *p = ptr;
1.1.1.2   root      299:     stl_le_p(p, (uint32_t)v);
                    300:     stl_le_p(p + 4, v >> 32);
1.1       root      301: }
                    302: 
                    303: /* float access */
                    304: 
1.1.1.7   root      305: static inline float32 ldfl_le_p(const void *ptr)
1.1       root      306: {
                    307:     union {
                    308:         float32 f;
                    309:         uint32_t i;
                    310:     } u;
1.1.1.2   root      311:     u.i = ldl_le_p(ptr);
1.1       root      312:     return u.f;
                    313: }
                    314: 
1.1.1.2   root      315: static inline void stfl_le_p(void *ptr, float32 v)
1.1       root      316: {
                    317:     union {
                    318:         float32 f;
                    319:         uint32_t i;
                    320:     } u;
                    321:     u.f = v;
1.1.1.2   root      322:     stl_le_p(ptr, u.i);
1.1       root      323: }
                    324: 
1.1.1.7   root      325: static inline float64 ldfq_le_p(const void *ptr)
1.1       root      326: {
                    327:     CPU_DoubleU u;
1.1.1.2   root      328:     u.l.lower = ldl_le_p(ptr);
                    329:     u.l.upper = ldl_le_p(ptr + 4);
1.1       root      330:     return u.d;
                    331: }
                    332: 
1.1.1.2   root      333: static inline void stfq_le_p(void *ptr, float64 v)
1.1       root      334: {
                    335:     CPU_DoubleU u;
                    336:     u.d = v;
1.1.1.2   root      337:     stl_le_p(ptr, u.l.lower);
                    338:     stl_le_p(ptr + 4, u.l.upper);
1.1       root      339: }
                    340: 
1.1.1.2   root      341: #else
                    342: 
1.1.1.7   root      343: static inline int lduw_le_p(const void *ptr)
1.1.1.2   root      344: {
                    345:     return *(uint16_t *)ptr;
                    346: }
                    347: 
1.1.1.7   root      348: static inline int ldsw_le_p(const void *ptr)
1.1.1.2   root      349: {
                    350:     return *(int16_t *)ptr;
                    351: }
1.1       root      352: 
1.1.1.7   root      353: static inline int ldl_le_p(const void *ptr)
1.1.1.2   root      354: {
                    355:     return *(uint32_t *)ptr;
                    356: }
                    357: 
1.1.1.7   root      358: static inline uint64_t ldq_le_p(const void *ptr)
1.1.1.2   root      359: {
                    360:     return *(uint64_t *)ptr;
                    361: }
                    362: 
                    363: static inline void stw_le_p(void *ptr, int v)
                    364: {
                    365:     *(uint16_t *)ptr = v;
                    366: }
                    367: 
                    368: static inline void stl_le_p(void *ptr, int v)
                    369: {
                    370:     *(uint32_t *)ptr = v;
                    371: }
                    372: 
                    373: static inline void stq_le_p(void *ptr, uint64_t v)
                    374: {
                    375:     *(uint64_t *)ptr = v;
                    376: }
                    377: 
                    378: /* float access */
                    379: 
1.1.1.7   root      380: static inline float32 ldfl_le_p(const void *ptr)
1.1.1.2   root      381: {
                    382:     return *(float32 *)ptr;
                    383: }
                    384: 
1.1.1.7   root      385: static inline float64 ldfq_le_p(const void *ptr)
1.1.1.2   root      386: {
                    387:     return *(float64 *)ptr;
                    388: }
                    389: 
                    390: static inline void stfl_le_p(void *ptr, float32 v)
                    391: {
                    392:     *(float32 *)ptr = v;
                    393: }
                    394: 
                    395: static inline void stfq_le_p(void *ptr, float64 v)
                    396: {
                    397:     *(float64 *)ptr = v;
                    398: }
                    399: #endif
                    400: 
1.1.1.9   root      401: #if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
1.1.1.2   root      402: 
1.1.1.7   root      403: static inline int lduw_be_p(const void *ptr)
1.1       root      404: {
                    405: #if defined(__i386__)
                    406:     int val;
                    407:     asm volatile ("movzwl %1, %0\n"
                    408:                   "xchgb %b0, %h0\n"
                    409:                   : "=q" (val)
                    410:                   : "m" (*(uint16_t *)ptr));
                    411:     return val;
                    412: #else
1.1.1.7   root      413:     const uint8_t *b = ptr;
1.1       root      414:     return ((b[0] << 8) | b[1]);
                    415: #endif
                    416: }
                    417: 
1.1.1.7   root      418: static inline int ldsw_be_p(const void *ptr)
1.1       root      419: {
                    420: #if defined(__i386__)
                    421:     int val;
                    422:     asm volatile ("movzwl %1, %0\n"
                    423:                   "xchgb %b0, %h0\n"
                    424:                   : "=q" (val)
                    425:                   : "m" (*(uint16_t *)ptr));
                    426:     return (int16_t)val;
                    427: #else
1.1.1.7   root      428:     const uint8_t *b = ptr;
1.1       root      429:     return (int16_t)((b[0] << 8) | b[1]);
                    430: #endif
                    431: }
                    432: 
1.1.1.7   root      433: static inline int ldl_be_p(const void *ptr)
1.1       root      434: {
                    435: #if defined(__i386__) || defined(__x86_64__)
                    436:     int val;
                    437:     asm volatile ("movl %1, %0\n"
                    438:                   "bswap %0\n"
                    439:                   : "=r" (val)
                    440:                   : "m" (*(uint32_t *)ptr));
                    441:     return val;
                    442: #else
1.1.1.7   root      443:     const uint8_t *b = ptr;
1.1       root      444:     return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
                    445: #endif
                    446: }
                    447: 
1.1.1.7   root      448: static inline uint64_t ldq_be_p(const void *ptr)
1.1       root      449: {
                    450:     uint32_t a,b;
1.1.1.2   root      451:     a = ldl_be_p(ptr);
1.1.1.7   root      452:     b = ldl_be_p((uint8_t *)ptr + 4);
1.1       root      453:     return (((uint64_t)a<<32)|b);
                    454: }
                    455: 
1.1.1.2   root      456: static inline void stw_be_p(void *ptr, int v)
1.1       root      457: {
                    458: #if defined(__i386__)
                    459:     asm volatile ("xchgb %b0, %h0\n"
                    460:                   "movw %w0, %1\n"
                    461:                   : "=q" (v)
                    462:                   : "m" (*(uint16_t *)ptr), "0" (v));
                    463: #else
                    464:     uint8_t *d = (uint8_t *) ptr;
                    465:     d[0] = v >> 8;
                    466:     d[1] = v;
                    467: #endif
                    468: }
                    469: 
1.1.1.2   root      470: static inline void stl_be_p(void *ptr, int v)
1.1       root      471: {
                    472: #if defined(__i386__) || defined(__x86_64__)
                    473:     asm volatile ("bswap %0\n"
                    474:                   "movl %0, %1\n"
                    475:                   : "=r" (v)
                    476:                   : "m" (*(uint32_t *)ptr), "0" (v));
                    477: #else
                    478:     uint8_t *d = (uint8_t *) ptr;
                    479:     d[0] = v >> 24;
                    480:     d[1] = v >> 16;
                    481:     d[2] = v >> 8;
                    482:     d[3] = v;
                    483: #endif
                    484: }
                    485: 
1.1.1.2   root      486: static inline void stq_be_p(void *ptr, uint64_t v)
1.1       root      487: {
1.1.1.2   root      488:     stl_be_p(ptr, v >> 32);
1.1.1.7   root      489:     stl_be_p((uint8_t *)ptr + 4, v);
1.1       root      490: }
                    491: 
                    492: /* float access */
                    493: 
1.1.1.7   root      494: static inline float32 ldfl_be_p(const void *ptr)
1.1       root      495: {
                    496:     union {
                    497:         float32 f;
                    498:         uint32_t i;
                    499:     } u;
1.1.1.2   root      500:     u.i = ldl_be_p(ptr);
1.1       root      501:     return u.f;
                    502: }
                    503: 
1.1.1.2   root      504: static inline void stfl_be_p(void *ptr, float32 v)
1.1       root      505: {
                    506:     union {
                    507:         float32 f;
                    508:         uint32_t i;
                    509:     } u;
                    510:     u.f = v;
1.1.1.2   root      511:     stl_be_p(ptr, u.i);
1.1       root      512: }
                    513: 
1.1.1.7   root      514: static inline float64 ldfq_be_p(const void *ptr)
1.1       root      515: {
                    516:     CPU_DoubleU u;
1.1.1.2   root      517:     u.l.upper = ldl_be_p(ptr);
1.1.1.7   root      518:     u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
1.1       root      519:     return u.d;
                    520: }
                    521: 
1.1.1.2   root      522: static inline void stfq_be_p(void *ptr, float64 v)
1.1       root      523: {
                    524:     CPU_DoubleU u;
                    525:     u.d = v;
1.1.1.2   root      526:     stl_be_p(ptr, u.l.upper);
1.1.1.7   root      527:     stl_be_p((uint8_t *)ptr + 4, u.l.lower);
1.1       root      528: }
                    529: 
                    530: #else
                    531: 
1.1.1.7   root      532: static inline int lduw_be_p(const void *ptr)
1.1       root      533: {
                    534:     return *(uint16_t *)ptr;
                    535: }
                    536: 
1.1.1.7   root      537: static inline int ldsw_be_p(const void *ptr)
1.1       root      538: {
                    539:     return *(int16_t *)ptr;
                    540: }
                    541: 
1.1.1.7   root      542: static inline int ldl_be_p(const void *ptr)
1.1       root      543: {
                    544:     return *(uint32_t *)ptr;
                    545: }
                    546: 
1.1.1.7   root      547: static inline uint64_t ldq_be_p(const void *ptr)
1.1       root      548: {
                    549:     return *(uint64_t *)ptr;
                    550: }
                    551: 
1.1.1.2   root      552: static inline void stw_be_p(void *ptr, int v)
1.1       root      553: {
                    554:     *(uint16_t *)ptr = v;
                    555: }
                    556: 
1.1.1.2   root      557: static inline void stl_be_p(void *ptr, int v)
1.1       root      558: {
                    559:     *(uint32_t *)ptr = v;
                    560: }
                    561: 
1.1.1.2   root      562: static inline void stq_be_p(void *ptr, uint64_t v)
1.1       root      563: {
                    564:     *(uint64_t *)ptr = v;
                    565: }
                    566: 
                    567: /* float access */
                    568: 
1.1.1.7   root      569: static inline float32 ldfl_be_p(const void *ptr)
1.1       root      570: {
                    571:     return *(float32 *)ptr;
                    572: }
                    573: 
1.1.1.7   root      574: static inline float64 ldfq_be_p(const void *ptr)
1.1       root      575: {
                    576:     return *(float64 *)ptr;
                    577: }
                    578: 
1.1.1.2   root      579: static inline void stfl_be_p(void *ptr, float32 v)
1.1       root      580: {
                    581:     *(float32 *)ptr = v;
                    582: }
                    583: 
1.1.1.2   root      584: static inline void stfq_be_p(void *ptr, float64 v)
1.1       root      585: {
                    586:     *(float64 *)ptr = v;
                    587: }
1.1.1.2   root      588: 
                    589: #endif
                    590: 
                    591: /* target CPU memory access functions */
                    592: #if defined(TARGET_WORDS_BIGENDIAN)
                    593: #define lduw_p(p) lduw_be_p(p)
                    594: #define ldsw_p(p) ldsw_be_p(p)
                    595: #define ldl_p(p) ldl_be_p(p)
                    596: #define ldq_p(p) ldq_be_p(p)
                    597: #define ldfl_p(p) ldfl_be_p(p)
                    598: #define ldfq_p(p) ldfq_be_p(p)
                    599: #define stw_p(p, v) stw_be_p(p, v)
                    600: #define stl_p(p, v) stl_be_p(p, v)
                    601: #define stq_p(p, v) stq_be_p(p, v)
                    602: #define stfl_p(p, v) stfl_be_p(p, v)
                    603: #define stfq_p(p, v) stfq_be_p(p, v)
                    604: #else
                    605: #define lduw_p(p) lduw_le_p(p)
                    606: #define ldsw_p(p) ldsw_le_p(p)
                    607: #define ldl_p(p) ldl_le_p(p)
                    608: #define ldq_p(p) ldq_le_p(p)
                    609: #define ldfl_p(p) ldfl_le_p(p)
                    610: #define ldfq_p(p) ldfq_le_p(p)
                    611: #define stw_p(p, v) stw_le_p(p, v)
                    612: #define stl_p(p, v) stl_le_p(p, v)
                    613: #define stq_p(p, v) stq_le_p(p, v)
                    614: #define stfl_p(p, v) stfl_le_p(p, v)
                    615: #define stfq_p(p, v) stfq_le_p(p, v)
1.1       root      616: #endif
                    617: 
                    618: /* MMU memory access macros */
                    619: 
1.1.1.3   root      620: #if defined(CONFIG_USER_ONLY)
1.1.1.7   root      621: #include <assert.h>
                    622: #include "qemu-types.h"
                    623: 
1.1.1.3   root      624: /* On some host systems the guest address space is reserved on the host.
                    625:  * This allows the guest address space to be offset to a convenient location.
                    626:  */
1.1.1.9   root      627: #if defined(CONFIG_USE_GUEST_BASE)
                    628: extern unsigned long guest_base;
                    629: extern int have_guest_base;
                    630: #define GUEST_BASE guest_base
                    631: #else
                    632: #define GUEST_BASE 0ul
                    633: #endif
1.1.1.3   root      634: 
                    635: /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
                    636: #define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
1.1.1.7   root      637: #define h2g(x) ({ \
                    638:     unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
                    639:     /* Check if given address fits target address space */ \
                    640:     assert(__ret == (abi_ulong)__ret); \
                    641:     (abi_ulong)__ret; \
                    642: })
                    643: #define h2g_valid(x) ({ \
                    644:     unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
                    645:     (__guest == (abi_ulong)__guest); \
                    646: })
1.1.1.3   root      647: 
                    648: #define saddr(x) g2h(x)
                    649: #define laddr(x) g2h(x)
                    650: 
                    651: #else /* !CONFIG_USER_ONLY */
1.1       root      652: /* NOTE: we use double casts if pointers and target_ulong have
                    653:    different sizes */
1.1.1.3   root      654: #define saddr(x) (uint8_t *)(long)(x)
                    655: #define laddr(x) (uint8_t *)(long)(x)
                    656: #endif
                    657: 
                    658: #define ldub_raw(p) ldub_p(laddr((p)))
                    659: #define ldsb_raw(p) ldsb_p(laddr((p)))
                    660: #define lduw_raw(p) lduw_p(laddr((p)))
                    661: #define ldsw_raw(p) ldsw_p(laddr((p)))
                    662: #define ldl_raw(p) ldl_p(laddr((p)))
                    663: #define ldq_raw(p) ldq_p(laddr((p)))
                    664: #define ldfl_raw(p) ldfl_p(laddr((p)))
                    665: #define ldfq_raw(p) ldfq_p(laddr((p)))
                    666: #define stb_raw(p, v) stb_p(saddr((p)), v)
                    667: #define stw_raw(p, v) stw_p(saddr((p)), v)
                    668: #define stl_raw(p, v) stl_p(saddr((p)), v)
                    669: #define stq_raw(p, v) stq_p(saddr((p)), v)
                    670: #define stfl_raw(p, v) stfl_p(saddr((p)), v)
                    671: #define stfq_raw(p, v) stfq_p(saddr((p)), v)
1.1       root      672: 
                    673: 
1.1.1.6   root      674: #if defined(CONFIG_USER_ONLY)
1.1       root      675: 
                    676: /* if user mode, no other memory access functions */
                    677: #define ldub(p) ldub_raw(p)
                    678: #define ldsb(p) ldsb_raw(p)
                    679: #define lduw(p) lduw_raw(p)
                    680: #define ldsw(p) ldsw_raw(p)
                    681: #define ldl(p) ldl_raw(p)
                    682: #define ldq(p) ldq_raw(p)
                    683: #define ldfl(p) ldfl_raw(p)
                    684: #define ldfq(p) ldfq_raw(p)
                    685: #define stb(p, v) stb_raw(p, v)
                    686: #define stw(p, v) stw_raw(p, v)
                    687: #define stl(p, v) stl_raw(p, v)
                    688: #define stq(p, v) stq_raw(p, v)
                    689: #define stfl(p, v) stfl_raw(p, v)
                    690: #define stfq(p, v) stfq_raw(p, v)
                    691: 
                    692: #define ldub_code(p) ldub_raw(p)
                    693: #define ldsb_code(p) ldsb_raw(p)
                    694: #define lduw_code(p) lduw_raw(p)
                    695: #define ldsw_code(p) ldsw_raw(p)
                    696: #define ldl_code(p) ldl_raw(p)
1.1.1.6   root      697: #define ldq_code(p) ldq_raw(p)
1.1       root      698: 
                    699: #define ldub_kernel(p) ldub_raw(p)
                    700: #define ldsb_kernel(p) ldsb_raw(p)
                    701: #define lduw_kernel(p) lduw_raw(p)
                    702: #define ldsw_kernel(p) ldsw_raw(p)
                    703: #define ldl_kernel(p) ldl_raw(p)
1.1.1.6   root      704: #define ldq_kernel(p) ldq_raw(p)
1.1       root      705: #define ldfl_kernel(p) ldfl_raw(p)
                    706: #define ldfq_kernel(p) ldfq_raw(p)
                    707: #define stb_kernel(p, v) stb_raw(p, v)
                    708: #define stw_kernel(p, v) stw_raw(p, v)
                    709: #define stl_kernel(p, v) stl_raw(p, v)
                    710: #define stq_kernel(p, v) stq_raw(p, v)
                    711: #define stfl_kernel(p, v) stfl_raw(p, v)
                    712: #define stfq_kernel(p, vt) stfq_raw(p, v)
                    713: 
                    714: #endif /* defined(CONFIG_USER_ONLY) */
                    715: 
                    716: /* page related stuff */
                    717: 
                    718: #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
                    719: #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
                    720: #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
                    721: 
1.1.1.3   root      722: /* ??? These should be the larger of unsigned long and target_ulong.  */
1.1       root      723: extern unsigned long qemu_real_host_page_size;
                    724: extern unsigned long qemu_host_page_bits;
                    725: extern unsigned long qemu_host_page_size;
                    726: extern unsigned long qemu_host_page_mask;
                    727: 
                    728: #define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
                    729: 
                    730: /* same as PROT_xxx */
                    731: #define PAGE_READ      0x0001
                    732: #define PAGE_WRITE     0x0002
                    733: #define PAGE_EXEC      0x0004
                    734: #define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
                    735: #define PAGE_VALID     0x0008
                    736: /* original state of the write flag (used when tracking self-modifying
                    737:    code */
1.1.1.6   root      738: #define PAGE_WRITE_ORG 0x0010
                    739: #define PAGE_RESERVED  0x0020
1.1       root      740: 
                    741: void page_dump(FILE *f);
1.1.1.8   root      742: int walk_memory_regions(void *,
                    743:     int (*fn)(void *, unsigned long, unsigned long, unsigned long));
1.1.1.3   root      744: int page_get_flags(target_ulong address);
                    745: void page_set_flags(target_ulong start, target_ulong end, int flags);
1.1.1.6   root      746: int page_check_range(target_ulong start, target_ulong len, int flags);
1.1       root      747: 
1.1.1.7   root      748: void cpu_exec_init_all(unsigned long tb_size);
1.1.1.6   root      749: CPUState *cpu_copy(CPUState *env);
1.1.1.8   root      750: CPUState *qemu_get_cpu(int cpu);
1.1       root      751: 
1.1.1.6   root      752: void cpu_dump_state(CPUState *env, FILE *f,
1.1       root      753:                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                    754:                     int flags);
1.1.1.6   root      755: void cpu_dump_statistics (CPUState *env, FILE *f,
                    756:                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                    757:                           int flags);
                    758: 
1.1.1.7   root      759: void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
                    760:     __attribute__ ((__format__ (__printf__, 2, 3)));
1.1.1.2   root      761: extern CPUState *first_cpu;
1.1       root      762: extern CPUState *cpu_single_env;
1.1.1.7   root      763: extern int64_t qemu_icount;
                    764: extern int use_icount;
1.1       root      765: 
                    766: #define CPU_INTERRUPT_HARD   0x02 /* hardware interrupt pending */
                    767: #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
                    768: #define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
1.1.1.2   root      769: #define CPU_INTERRUPT_FIQ    0x10 /* Fast interrupt pending.  */
                    770: #define CPU_INTERRUPT_HALT   0x20 /* CPU halt wanted */
1.1.1.5   root      771: #define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */
1.1.1.6   root      772: #define CPU_INTERRUPT_DEBUG  0x80 /* Debug event occured.  */
                    773: #define CPU_INTERRUPT_VIRQ   0x100 /* virtual interrupt pending.  */
1.1.1.7   root      774: #define CPU_INTERRUPT_NMI    0x200 /* NMI pending. */
1.1.1.8   root      775: #define CPU_INTERRUPT_INIT   0x400 /* INIT pending. */
                    776: #define CPU_INTERRUPT_SIPI   0x800 /* SIPI pending. */
                    777: #define CPU_INTERRUPT_MCE    0x1000 /* (x86 only) MCE pending. */
1.1.1.2   root      778: 
1.1       root      779: void cpu_interrupt(CPUState *s, int mask);
                    780: void cpu_reset_interrupt(CPUState *env, int mask);
                    781: 
1.1.1.8   root      782: void cpu_exit(CPUState *s);
                    783: 
                    784: int qemu_cpu_has_work(CPUState *env);
                    785: 
1.1.1.7   root      786: /* Breakpoint/watchpoint flags */
                    787: #define BP_MEM_READ           0x01
                    788: #define BP_MEM_WRITE          0x02
                    789: #define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE)
                    790: #define BP_STOP_BEFORE_ACCESS 0x04
                    791: #define BP_WATCHPOINT_HIT     0x08
                    792: #define BP_GDB                0x10
                    793: #define BP_CPU                0x20
                    794: 
                    795: int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
                    796:                           CPUBreakpoint **breakpoint);
                    797: int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags);
                    798: void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint);
                    799: void cpu_breakpoint_remove_all(CPUState *env, int mask);
                    800: int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
                    801:                           int flags, CPUWatchpoint **watchpoint);
                    802: int cpu_watchpoint_remove(CPUState *env, target_ulong addr,
                    803:                           target_ulong len, int flags);
                    804: void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint);
                    805: void cpu_watchpoint_remove_all(CPUState *env, int mask);
                    806: 
                    807: #define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
                    808: #define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
                    809: #define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */
                    810: 
1.1       root      811: void cpu_single_step(CPUState *env, int enabled);
                    812: void cpu_reset(CPUState *s);
                    813: 
                    814: /* Return the physical page corresponding to a virtual one. Use it
                    815:    only for debugging because no protection checks are done. Return -1
                    816:    if no page found. */
1.1.1.6   root      817: target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
1.1       root      818: 
1.1.1.6   root      819: #define CPU_LOG_TB_OUT_ASM (1 << 0)
1.1       root      820: #define CPU_LOG_TB_IN_ASM  (1 << 1)
                    821: #define CPU_LOG_TB_OP      (1 << 2)
                    822: #define CPU_LOG_TB_OP_OPT  (1 << 3)
                    823: #define CPU_LOG_INT        (1 << 4)
                    824: #define CPU_LOG_EXEC       (1 << 5)
                    825: #define CPU_LOG_PCALL      (1 << 6)
                    826: #define CPU_LOG_IOPORT     (1 << 7)
                    827: #define CPU_LOG_TB_CPU     (1 << 8)
1.1.1.7   root      828: #define CPU_LOG_RESET      (1 << 9)
1.1       root      829: 
                    830: /* define log items */
                    831: typedef struct CPULogItem {
                    832:     int mask;
                    833:     const char *name;
                    834:     const char *help;
                    835: } CPULogItem;
                    836: 
1.1.1.7   root      837: extern const CPULogItem cpu_log_items[];
1.1       root      838: 
                    839: void cpu_set_log(int log_flags);
                    840: void cpu_set_log_filename(const char *filename);
                    841: int cpu_str_to_log_mask(const char *str);
                    842: 
                    843: /* IO ports API */
1.1.1.8   root      844: #include "ioport.h"
1.1.1.7   root      845: 
1.1       root      846: /* memory API */
                    847: 
                    848: extern int phys_ram_fd;
                    849: extern uint8_t *phys_ram_dirty;
1.1.1.7   root      850: extern ram_addr_t ram_size;
1.1.1.8   root      851: extern ram_addr_t last_ram_offset;
1.1       root      852: 
                    853: /* physical memory access */
1.1.1.7   root      854: 
                    855: /* MMIO pages are identified by a combination of an IO device index and
                    856:    3 flags.  The ROMD code stores the page ram offset in iotlb entry, 
                    857:    so only a limited number of ids are avaiable.  */
                    858: 
1.1.1.2   root      859: #define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
1.1       root      860: 
1.1.1.7   root      861: /* Flags stored in the low bits of the TLB virtual address.  These are
                    862:    defined so that fast path ram access is all zeros.  */
                    863: /* Zero if TLB entry is valid.  */
                    864: #define TLB_INVALID_MASK   (1 << 3)
                    865: /* Set if TLB entry references a clean RAM page.  The iotlb entry will
                    866:    contain the page physical address.  */
                    867: #define TLB_NOTDIRTY    (1 << 4)
                    868: /* Set if TLB entry is an IO callback.  */
                    869: #define TLB_MMIO        (1 << 5)
                    870: 
1.1.1.6   root      871: int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
1.1       root      872:                         uint8_t *buf, int len, int is_write);
                    873: 
1.1.1.7   root      874: #define VGA_DIRTY_FLAG       0x01
                    875: #define CODE_DIRTY_FLAG      0x02
                    876: #define MIGRATION_DIRTY_FLAG 0x08
1.1       root      877: 
                    878: /* read dirty bit (return 0 or 1) */
                    879: static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
                    880: {
                    881:     return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
                    882: }
                    883: 
1.1.1.6   root      884: static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
1.1       root      885:                                                 int dirty_flags)
                    886: {
                    887:     return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
                    888: }
                    889: 
                    890: static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
                    891: {
                    892:     phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
                    893: }
                    894: 
                    895: void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                    896:                                      int dirty_flags);
                    897: void cpu_tlb_update_dirty(CPUState *env);
                    898: 
1.1.1.7   root      899: int cpu_physical_memory_set_dirty_tracking(int enable);
                    900: 
                    901: int cpu_physical_memory_get_dirty_tracking(void);
                    902: 
1.1.1.8   root      903: int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
                    904:                                    target_phys_addr_t end_addr);
1.1.1.7   root      905: 
1.1       root      906: void dump_exec_info(FILE *f,
                    907:                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
                    908: 
1.1.1.7   root      909: /* Coalesced MMIO regions are areas where write operations can be reordered.
                    910:  * This usually implies that write operations are side-effect free.  This allows
                    911:  * batching which can make a major impact on performance when using
                    912:  * virtualization.
                    913:  */
                    914: void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
1.1.1.4   root      915: 
1.1.1.7   root      916: void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
1.1.1.4   root      917: 
1.1.1.7   root      918: /*******************************************/
                    919: /* host CPU ticks (if available) */
1.1.1.4   root      920: 
1.1.1.7   root      921: #if defined(_ARCH_PPC)
1.1.1.4   root      922: 
                    923: static inline int64_t cpu_get_real_ticks(void)
                    924: {
1.1.1.7   root      925:     int64_t retval;
                    926: #ifdef _ARCH_PPC64
                    927:     /* This reads timebase in one 64bit go and includes Cell workaround from:
                    928:        http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
                    929:      */
                    930:     __asm__ __volatile__ (
                    931:         "mftb    %0\n\t"
                    932:         "cmpwi   %0,0\n\t"
                    933:         "beq-    $-8"
                    934:         : "=r" (retval));
                    935: #else
                    936:     /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
                    937:     unsigned long junk;
                    938:     __asm__ __volatile__ (
                    939:         "mftbu   %1\n\t"
                    940:         "mftb    %L0\n\t"
                    941:         "mftbu   %0\n\t"
                    942:         "cmpw    %0,%1\n\t"
                    943:         "bne     $-16"
                    944:         : "=r" (retval), "=r" (junk));
                    945: #endif
                    946:     return retval;
1.1.1.4   root      947: }
                    948: 
                    949: #elif defined(__i386__)
                    950: 
                    951: static inline int64_t cpu_get_real_ticks(void)
1.1.1.3   root      952: {
                    953:     int64_t val;
                    954:     asm volatile ("rdtsc" : "=A" (val));
                    955:     return val;
                    956: }
                    957: 
1.1.1.4   root      958: #elif defined(__x86_64__)
                    959: 
                    960: static inline int64_t cpu_get_real_ticks(void)
                    961: {
                    962:     uint32_t low,high;
                    963:     int64_t val;
                    964:     asm volatile("rdtsc" : "=a" (low), "=d" (high));
                    965:     val = high;
                    966:     val <<= 32;
                    967:     val |= low;
                    968:     return val;
                    969: }
                    970: 
1.1.1.7   root      971: #elif defined(__hppa__)
                    972: 
                    973: static inline int64_t cpu_get_real_ticks(void)
                    974: {
                    975:     int val;
                    976:     asm volatile ("mfctl %%cr16, %0" : "=r"(val));
                    977:     return val;
                    978: }
                    979: 
1.1.1.4   root      980: #elif defined(__ia64)
                    981: 
                    982: static inline int64_t cpu_get_real_ticks(void)
                    983: {
                    984:        int64_t val;
                    985:        asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
                    986:        return val;
                    987: }
                    988: 
                    989: #elif defined(__s390__)
                    990: 
                    991: static inline int64_t cpu_get_real_ticks(void)
                    992: {
                    993:     int64_t val;
                    994:     asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
                    995:     return val;
                    996: }
                    997: 
1.1.1.6   root      998: #elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
1.1.1.4   root      999: 
                   1000: static inline int64_t cpu_get_real_ticks (void)
                   1001: {
                   1002: #if     defined(_LP64)
                   1003:         uint64_t        rval;
                   1004:         asm volatile("rd %%tick,%0" : "=r"(rval));
                   1005:         return rval;
                   1006: #else
                   1007:         union {
                   1008:                 uint64_t i64;
                   1009:                 struct {
                   1010:                         uint32_t high;
                   1011:                         uint32_t low;
                   1012:                 }       i32;
                   1013:         } rval;
                   1014:         asm volatile("rd %%tick,%1; srlx %1,32,%0"
                   1015:                 : "=r"(rval.i32.high), "=r"(rval.i32.low));
                   1016:         return rval.i64;
                   1017: #endif
                   1018: }
1.1.1.6   root     1019: 
1.1.1.10! root     1020: #elif defined(__mips__) && \
        !          1021:       ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
1.1.1.9   root     1022: /*
                   1023:  * binutils wants to use rdhwr only on mips32r2
                   1024:  * but as linux kernel emulate it, it's fine
                   1025:  * to use it.
                   1026:  *
                   1027:  */
                   1028: #define MIPS_RDHWR(rd, value) {                 \
                   1029:     __asm__ __volatile__ (                      \
                   1030:                           ".set   push\n\t"     \
                   1031:                           ".set mips32r2\n\t"   \
                   1032:                           "rdhwr  %0, "rd"\n\t" \
                   1033:                           ".set   pop"          \
                   1034:                           : "=r" (value));      \
                   1035: }
1.1.1.6   root     1036: 
                   1037: static inline int64_t cpu_get_real_ticks(void)
                   1038: {
1.1.1.9   root     1039: /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
1.1.1.6   root     1040:     uint32_t count;
                   1041:     static uint32_t cyc_per_count = 0;
                   1042: 
                   1043:     if (!cyc_per_count)
1.1.1.9   root     1044:         MIPS_RDHWR("$3", cyc_per_count);
1.1.1.6   root     1045: 
1.1.1.9   root     1046:     MIPS_RDHWR("$2", count);
1.1.1.6   root     1047:     return (int64_t)(count * cyc_per_count);
                   1048: }
                   1049: 
1.1.1.5   root     1050: #else
                   1051: /* The host CPU doesn't have an easily accessible cycle counter.
1.1.1.6   root     1052:    Just return a monotonically increasing value.  This will be
                   1053:    totally wrong, but hopefully better than nothing.  */
1.1.1.5   root     1054: static inline int64_t cpu_get_real_ticks (void)
                   1055: {
                   1056:     static int64_t ticks = 0;
                   1057:     return ticks++;
                   1058: }
1.1.1.4   root     1059: #endif
                   1060: 
                   1061: /* profiling */
                   1062: #ifdef CONFIG_PROFILER
                   1063: static inline int64_t profile_getclock(void)
                   1064: {
                   1065:     return cpu_get_real_ticks();
                   1066: }
                   1067: 
1.1.1.3   root     1068: extern int64_t qemu_time, qemu_time_start;
                   1069: extern int64_t tlb_flush_time;
                   1070: extern int64_t dev_time;
                   1071: #endif
                   1072: 
1.1.1.8   root     1073: void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
                   1074:                         uint64_t mcg_status, uint64_t addr, uint64_t misc);
                   1075: 
1.1       root     1076: #endif /* CPU_ALL_H */

unix.superglobalmegacorp.com