Statistics
| Branch: | Revision:

root / cpu-all.h @ 94d3f98a

History | View | Annotate | Download (25.2 kB)

1 5a9fdfec bellard
/*
2 5a9fdfec bellard
 * defines common to all virtual CPUs
3 5fafdf24 ths
 *
4 5a9fdfec bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 5a9fdfec bellard
 *
6 5a9fdfec bellard
 * This library is free software; you can redistribute it and/or
7 5a9fdfec bellard
 * modify it under the terms of the GNU Lesser General Public
8 5a9fdfec bellard
 * License as published by the Free Software Foundation; either
9 5a9fdfec bellard
 * version 2 of the License, or (at your option) any later version.
10 5a9fdfec bellard
 *
11 5a9fdfec bellard
 * This library is distributed in the hope that it will be useful,
12 5a9fdfec bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 5a9fdfec bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 5a9fdfec bellard
 * Lesser General Public License for more details.
15 5a9fdfec bellard
 *
16 5a9fdfec bellard
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 5a9fdfec bellard
 */
19 5a9fdfec bellard
#ifndef CPU_ALL_H
20 5a9fdfec bellard
#define CPU_ALL_H
21 5a9fdfec bellard
22 7d99a001 blueswir1
#include "qemu-common.h"
23 1ad2134f Paul Brook
#include "cpu-common.h"
24 0ac4bd56 bellard
25 5fafdf24 ths
/* some important defines:
26 5fafdf24 ths
 *
27 0ac4bd56 bellard
 * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
28 0ac4bd56 bellard
 * memory accesses.
29 5fafdf24 ths
 *
30 e2542fe2 Juan Quintela
 * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
31 0ac4bd56 bellard
 * otherwise little endian.
32 5fafdf24 ths
 *
33 0ac4bd56 bellard
 * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
34 5fafdf24 ths
 *
35 0ac4bd56 bellard
 * TARGET_WORDS_BIGENDIAN : same for target cpu
36 0ac4bd56 bellard
 */
37 0ac4bd56 bellard
38 939ef593 aurel32
#include "softfloat.h"
39 f193c797 bellard
40 e2542fe2 Juan Quintela
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
41 f193c797 bellard
#define BSWAP_NEEDED
42 f193c797 bellard
#endif
43 f193c797 bellard
44 f193c797 bellard
#ifdef BSWAP_NEEDED
45 f193c797 bellard
46 f193c797 bellard
static inline uint16_t tswap16(uint16_t s)
47 f193c797 bellard
{
48 f193c797 bellard
    return bswap16(s);
49 f193c797 bellard
}
50 f193c797 bellard
51 f193c797 bellard
static inline uint32_t tswap32(uint32_t s)
52 f193c797 bellard
{
53 f193c797 bellard
    return bswap32(s);
54 f193c797 bellard
}
55 f193c797 bellard
56 f193c797 bellard
static inline uint64_t tswap64(uint64_t s)
57 f193c797 bellard
{
58 f193c797 bellard
    return bswap64(s);
59 f193c797 bellard
}
60 f193c797 bellard
61 f193c797 bellard
static inline void tswap16s(uint16_t *s)
62 f193c797 bellard
{
63 f193c797 bellard
    *s = bswap16(*s);
64 f193c797 bellard
}
65 f193c797 bellard
66 f193c797 bellard
static inline void tswap32s(uint32_t *s)
67 f193c797 bellard
{
68 f193c797 bellard
    *s = bswap32(*s);
69 f193c797 bellard
}
70 f193c797 bellard
71 f193c797 bellard
static inline void tswap64s(uint64_t *s)
72 f193c797 bellard
{
73 f193c797 bellard
    *s = bswap64(*s);
74 f193c797 bellard
}
75 f193c797 bellard
76 f193c797 bellard
#else
77 f193c797 bellard
78 f193c797 bellard
static inline uint16_t tswap16(uint16_t s)
79 f193c797 bellard
{
80 f193c797 bellard
    return s;
81 f193c797 bellard
}
82 f193c797 bellard
83 f193c797 bellard
static inline uint32_t tswap32(uint32_t s)
84 f193c797 bellard
{
85 f193c797 bellard
    return s;
86 f193c797 bellard
}
87 f193c797 bellard
88 f193c797 bellard
static inline uint64_t tswap64(uint64_t s)
89 f193c797 bellard
{
90 f193c797 bellard
    return s;
91 f193c797 bellard
}
92 f193c797 bellard
93 f193c797 bellard
static inline void tswap16s(uint16_t *s)
94 f193c797 bellard
{
95 f193c797 bellard
}
96 f193c797 bellard
97 f193c797 bellard
static inline void tswap32s(uint32_t *s)
98 f193c797 bellard
{
99 f193c797 bellard
}
100 f193c797 bellard
101 f193c797 bellard
static inline void tswap64s(uint64_t *s)
102 f193c797 bellard
{
103 f193c797 bellard
}
104 f193c797 bellard
105 f193c797 bellard
#endif
106 f193c797 bellard
107 f193c797 bellard
#if TARGET_LONG_SIZE == 4
108 f193c797 bellard
#define tswapl(s) tswap32(s)
109 f193c797 bellard
#define tswapls(s) tswap32s((uint32_t *)(s))
110 0a962c02 bellard
#define bswaptls(s) bswap32s(s)
111 f193c797 bellard
#else
112 f193c797 bellard
#define tswapl(s) tswap64(s)
113 f193c797 bellard
#define tswapls(s) tswap64s((uint64_t *)(s))
114 0a962c02 bellard
#define bswaptls(s) bswap64s(s)
115 f193c797 bellard
#endif
116 f193c797 bellard
117 0ca9d380 aurel32
typedef union {
118 0ca9d380 aurel32
    float32 f;
119 0ca9d380 aurel32
    uint32_t l;
120 0ca9d380 aurel32
} CPU_FloatU;
121 0ca9d380 aurel32
122 832ed0fa bellard
/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
123 832ed0fa bellard
   endian ! */
124 0ac4bd56 bellard
typedef union {
125 53cd6637 bellard
    float64 d;
126 e2542fe2 Juan Quintela
#if defined(HOST_WORDS_BIGENDIAN) \
127 9d60cac0 bellard
    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
128 0ac4bd56 bellard
    struct {
129 0ac4bd56 bellard
        uint32_t upper;
130 832ed0fa bellard
        uint32_t lower;
131 0ac4bd56 bellard
    } l;
132 0ac4bd56 bellard
#else
133 0ac4bd56 bellard
    struct {
134 0ac4bd56 bellard
        uint32_t lower;
135 832ed0fa bellard
        uint32_t upper;
136 0ac4bd56 bellard
    } l;
137 0ac4bd56 bellard
#endif
138 0ac4bd56 bellard
    uint64_t ll;
139 0ac4bd56 bellard
} CPU_DoubleU;
140 0ac4bd56 bellard
141 602308f0 Aurelien Jarno
#if defined(FLOATX80)
142 602308f0 Aurelien Jarno
typedef union {
143 602308f0 Aurelien Jarno
     floatx80 d;
144 602308f0 Aurelien Jarno
     struct {
145 602308f0 Aurelien Jarno
         uint64_t lower;
146 602308f0 Aurelien Jarno
         uint16_t upper;
147 602308f0 Aurelien Jarno
     } l;
148 602308f0 Aurelien Jarno
} CPU_LDoubleU;
149 602308f0 Aurelien Jarno
#endif
150 602308f0 Aurelien Jarno
151 c8f930c0 Peter Maydell
#if defined(CONFIG_SOFTFLOAT)
152 1f587329 blueswir1
typedef union {
153 1f587329 blueswir1
    float128 q;
154 c8f930c0 Peter Maydell
#if defined(HOST_WORDS_BIGENDIAN)
155 1f587329 blueswir1
    struct {
156 1f587329 blueswir1
        uint32_t upmost;
157 1f587329 blueswir1
        uint32_t upper;
158 1f587329 blueswir1
        uint32_t lower;
159 1f587329 blueswir1
        uint32_t lowest;
160 1f587329 blueswir1
    } l;
161 1f587329 blueswir1
    struct {
162 1f587329 blueswir1
        uint64_t upper;
163 1f587329 blueswir1
        uint64_t lower;
164 1f587329 blueswir1
    } ll;
165 1f587329 blueswir1
#else
166 1f587329 blueswir1
    struct {
167 1f587329 blueswir1
        uint32_t lowest;
168 1f587329 blueswir1
        uint32_t lower;
169 1f587329 blueswir1
        uint32_t upper;
170 1f587329 blueswir1
        uint32_t upmost;
171 1f587329 blueswir1
    } l;
172 1f587329 blueswir1
    struct {
173 1f587329 blueswir1
        uint64_t lower;
174 1f587329 blueswir1
        uint64_t upper;
175 1f587329 blueswir1
    } ll;
176 1f587329 blueswir1
#endif
177 1f587329 blueswir1
} CPU_QuadU;
178 1f587329 blueswir1
#endif
179 1f587329 blueswir1
180 61382a50 bellard
/* CPU memory access without any memory or io remapping */
181 61382a50 bellard
182 83d73968 bellard
/*
183 83d73968 bellard
 * the generic syntax for the memory accesses is:
184 83d73968 bellard
 *
185 83d73968 bellard
 * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
186 83d73968 bellard
 *
187 83d73968 bellard
 * store: st{type}{size}{endian}_{access_type}(ptr, val)
188 83d73968 bellard
 *
189 83d73968 bellard
 * type is:
190 83d73968 bellard
 * (empty): integer access
191 83d73968 bellard
 *   f    : float access
192 5fafdf24 ths
 *
193 83d73968 bellard
 * sign is:
194 83d73968 bellard
 * (empty): for floats or 32 bit size
195 83d73968 bellard
 *   u    : unsigned
196 83d73968 bellard
 *   s    : signed
197 83d73968 bellard
 *
198 83d73968 bellard
 * size is:
199 83d73968 bellard
 *   b: 8 bits
200 83d73968 bellard
 *   w: 16 bits
201 83d73968 bellard
 *   l: 32 bits
202 83d73968 bellard
 *   q: 64 bits
203 5fafdf24 ths
 *
204 83d73968 bellard
 * endian is:
205 83d73968 bellard
 * (empty): target cpu endianness or 8 bit access
206 83d73968 bellard
 *   r    : reversed target cpu endianness (not implemented yet)
207 83d73968 bellard
 *   be   : big endian (not implemented yet)
208 83d73968 bellard
 *   le   : little endian (not implemented yet)
209 83d73968 bellard
 *
210 83d73968 bellard
 * access_type is:
211 83d73968 bellard
 *   raw    : host memory access
212 83d73968 bellard
 *   user   : user mode access using soft MMU
213 83d73968 bellard
 *   kernel : kernel mode access using soft MMU
214 83d73968 bellard
 */
215 8bba3ea1 balrog
static inline int ldub_p(const void *ptr)
216 5a9fdfec bellard
{
217 5a9fdfec bellard
    return *(uint8_t *)ptr;
218 5a9fdfec bellard
}
219 5a9fdfec bellard
220 8bba3ea1 balrog
static inline int ldsb_p(const void *ptr)
221 5a9fdfec bellard
{
222 5a9fdfec bellard
    return *(int8_t *)ptr;
223 5a9fdfec bellard
}
224 5a9fdfec bellard
225 c27004ec bellard
static inline void stb_p(void *ptr, int v)
226 5a9fdfec bellard
{
227 5a9fdfec bellard
    *(uint8_t *)ptr = v;
228 5a9fdfec bellard
}
229 5a9fdfec bellard
230 5a9fdfec bellard
/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
231 5a9fdfec bellard
   kernel handles unaligned load/stores may give better results, but
232 5a9fdfec bellard
   it is a system wide setting : bad */
233 e2542fe2 Juan Quintela
#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
234 5a9fdfec bellard
235 5a9fdfec bellard
/* conservative code for little endian unaligned accesses */
236 8bba3ea1 balrog
static inline int lduw_le_p(const void *ptr)
237 5a9fdfec bellard
{
238 e58ffeb3 malc
#ifdef _ARCH_PPC
239 5a9fdfec bellard
    int val;
240 5a9fdfec bellard
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
241 5a9fdfec bellard
    return val;
242 5a9fdfec bellard
#else
243 e01fe6d5 malc
    const uint8_t *p = ptr;
244 5a9fdfec bellard
    return p[0] | (p[1] << 8);
245 5a9fdfec bellard
#endif
246 5a9fdfec bellard
}
247 5a9fdfec bellard
248 8bba3ea1 balrog
static inline int ldsw_le_p(const void *ptr)
249 5a9fdfec bellard
{
250 e58ffeb3 malc
#ifdef _ARCH_PPC
251 5a9fdfec bellard
    int val;
252 5a9fdfec bellard
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
253 5a9fdfec bellard
    return (int16_t)val;
254 5a9fdfec bellard
#else
255 e01fe6d5 malc
    const uint8_t *p = ptr;
256 5a9fdfec bellard
    return (int16_t)(p[0] | (p[1] << 8));
257 5a9fdfec bellard
#endif
258 5a9fdfec bellard
}
259 5a9fdfec bellard
260 8bba3ea1 balrog
static inline int ldl_le_p(const void *ptr)
261 5a9fdfec bellard
{
262 e58ffeb3 malc
#ifdef _ARCH_PPC
263 5a9fdfec bellard
    int val;
264 5a9fdfec bellard
    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
265 5a9fdfec bellard
    return val;
266 5a9fdfec bellard
#else
267 e01fe6d5 malc
    const uint8_t *p = ptr;
268 5a9fdfec bellard
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
269 5a9fdfec bellard
#endif
270 5a9fdfec bellard
}
271 5a9fdfec bellard
272 8bba3ea1 balrog
static inline uint64_t ldq_le_p(const void *ptr)
273 5a9fdfec bellard
{
274 e01fe6d5 malc
    const uint8_t *p = ptr;
275 5a9fdfec bellard
    uint32_t v1, v2;
276 f0aca822 bellard
    v1 = ldl_le_p(p);
277 f0aca822 bellard
    v2 = ldl_le_p(p + 4);
278 5a9fdfec bellard
    return v1 | ((uint64_t)v2 << 32);
279 5a9fdfec bellard
}
280 5a9fdfec bellard
281 2df3b95d bellard
static inline void stw_le_p(void *ptr, int v)
282 5a9fdfec bellard
{
283 e58ffeb3 malc
#ifdef _ARCH_PPC
284 5a9fdfec bellard
    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
285 5a9fdfec bellard
#else
286 5a9fdfec bellard
    uint8_t *p = ptr;
287 5a9fdfec bellard
    p[0] = v;
288 5a9fdfec bellard
    p[1] = v >> 8;
289 5a9fdfec bellard
#endif
290 5a9fdfec bellard
}
291 5a9fdfec bellard
292 2df3b95d bellard
static inline void stl_le_p(void *ptr, int v)
293 5a9fdfec bellard
{
294 e58ffeb3 malc
#ifdef _ARCH_PPC
295 5a9fdfec bellard
    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
296 5a9fdfec bellard
#else
297 5a9fdfec bellard
    uint8_t *p = ptr;
298 5a9fdfec bellard
    p[0] = v;
299 5a9fdfec bellard
    p[1] = v >> 8;
300 5a9fdfec bellard
    p[2] = v >> 16;
301 5a9fdfec bellard
    p[3] = v >> 24;
302 5a9fdfec bellard
#endif
303 5a9fdfec bellard
}
304 5a9fdfec bellard
305 2df3b95d bellard
static inline void stq_le_p(void *ptr, uint64_t v)
306 5a9fdfec bellard
{
307 5a9fdfec bellard
    uint8_t *p = ptr;
308 f0aca822 bellard
    stl_le_p(p, (uint32_t)v);
309 f0aca822 bellard
    stl_le_p(p + 4, v >> 32);
310 5a9fdfec bellard
}
311 5a9fdfec bellard
312 5a9fdfec bellard
/* float access */
313 5a9fdfec bellard
314 8bba3ea1 balrog
static inline float32 ldfl_le_p(const void *ptr)
315 5a9fdfec bellard
{
316 5a9fdfec bellard
    union {
317 53cd6637 bellard
        float32 f;
318 5a9fdfec bellard
        uint32_t i;
319 5a9fdfec bellard
    } u;
320 2df3b95d bellard
    u.i = ldl_le_p(ptr);
321 5a9fdfec bellard
    return u.f;
322 5a9fdfec bellard
}
323 5a9fdfec bellard
324 2df3b95d bellard
static inline void stfl_le_p(void *ptr, float32 v)
325 5a9fdfec bellard
{
326 5a9fdfec bellard
    union {
327 53cd6637 bellard
        float32 f;
328 5a9fdfec bellard
        uint32_t i;
329 5a9fdfec bellard
    } u;
330 5a9fdfec bellard
    u.f = v;
331 2df3b95d bellard
    stl_le_p(ptr, u.i);
332 5a9fdfec bellard
}
333 5a9fdfec bellard
334 8bba3ea1 balrog
static inline float64 ldfq_le_p(const void *ptr)
335 5a9fdfec bellard
{
336 0ac4bd56 bellard
    CPU_DoubleU u;
337 2df3b95d bellard
    u.l.lower = ldl_le_p(ptr);
338 2df3b95d bellard
    u.l.upper = ldl_le_p(ptr + 4);
339 5a9fdfec bellard
    return u.d;
340 5a9fdfec bellard
}
341 5a9fdfec bellard
342 2df3b95d bellard
static inline void stfq_le_p(void *ptr, float64 v)
343 5a9fdfec bellard
{
344 0ac4bd56 bellard
    CPU_DoubleU u;
345 5a9fdfec bellard
    u.d = v;
346 2df3b95d bellard
    stl_le_p(ptr, u.l.lower);
347 2df3b95d bellard
    stl_le_p(ptr + 4, u.l.upper);
348 5a9fdfec bellard
}
349 5a9fdfec bellard
350 2df3b95d bellard
#else
351 2df3b95d bellard
352 8bba3ea1 balrog
static inline int lduw_le_p(const void *ptr)
353 2df3b95d bellard
{
354 2df3b95d bellard
    return *(uint16_t *)ptr;
355 2df3b95d bellard
}
356 2df3b95d bellard
357 8bba3ea1 balrog
static inline int ldsw_le_p(const void *ptr)
358 2df3b95d bellard
{
359 2df3b95d bellard
    return *(int16_t *)ptr;
360 2df3b95d bellard
}
361 93ac68bc bellard
362 8bba3ea1 balrog
static inline int ldl_le_p(const void *ptr)
363 2df3b95d bellard
{
364 2df3b95d bellard
    return *(uint32_t *)ptr;
365 2df3b95d bellard
}
366 2df3b95d bellard
367 8bba3ea1 balrog
static inline uint64_t ldq_le_p(const void *ptr)
368 2df3b95d bellard
{
369 2df3b95d bellard
    return *(uint64_t *)ptr;
370 2df3b95d bellard
}
371 2df3b95d bellard
372 2df3b95d bellard
static inline void stw_le_p(void *ptr, int v)
373 2df3b95d bellard
{
374 2df3b95d bellard
    *(uint16_t *)ptr = v;
375 2df3b95d bellard
}
376 2df3b95d bellard
377 2df3b95d bellard
static inline void stl_le_p(void *ptr, int v)
378 2df3b95d bellard
{
379 2df3b95d bellard
    *(uint32_t *)ptr = v;
380 2df3b95d bellard
}
381 2df3b95d bellard
382 2df3b95d bellard
static inline void stq_le_p(void *ptr, uint64_t v)
383 2df3b95d bellard
{
384 2df3b95d bellard
    *(uint64_t *)ptr = v;
385 2df3b95d bellard
}
386 2df3b95d bellard
387 2df3b95d bellard
/* float access */
388 2df3b95d bellard
389 8bba3ea1 balrog
static inline float32 ldfl_le_p(const void *ptr)
390 2df3b95d bellard
{
391 2df3b95d bellard
    return *(float32 *)ptr;
392 2df3b95d bellard
}
393 2df3b95d bellard
394 8bba3ea1 balrog
static inline float64 ldfq_le_p(const void *ptr)
395 2df3b95d bellard
{
396 2df3b95d bellard
    return *(float64 *)ptr;
397 2df3b95d bellard
}
398 2df3b95d bellard
399 2df3b95d bellard
static inline void stfl_le_p(void *ptr, float32 v)
400 2df3b95d bellard
{
401 2df3b95d bellard
    *(float32 *)ptr = v;
402 2df3b95d bellard
}
403 2df3b95d bellard
404 2df3b95d bellard
static inline void stfq_le_p(void *ptr, float64 v)
405 2df3b95d bellard
{
406 2df3b95d bellard
    *(float64 *)ptr = v;
407 2df3b95d bellard
}
408 2df3b95d bellard
#endif
409 2df3b95d bellard
410 e2542fe2 Juan Quintela
#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
411 2df3b95d bellard
412 8bba3ea1 balrog
static inline int lduw_be_p(const void *ptr)
413 93ac68bc bellard
{
414 83d73968 bellard
#if defined(__i386__)
415 83d73968 bellard
    int val;
416 83d73968 bellard
    asm volatile ("movzwl %1, %0\n"
417 83d73968 bellard
                  "xchgb %b0, %h0\n"
418 83d73968 bellard
                  : "=q" (val)
419 83d73968 bellard
                  : "m" (*(uint16_t *)ptr));
420 83d73968 bellard
    return val;
421 83d73968 bellard
#else
422 e01fe6d5 malc
    const uint8_t *b = ptr;
423 83d73968 bellard
    return ((b[0] << 8) | b[1]);
424 83d73968 bellard
#endif
425 93ac68bc bellard
}
426 93ac68bc bellard
427 8bba3ea1 balrog
static inline int ldsw_be_p(const void *ptr)
428 93ac68bc bellard
{
429 83d73968 bellard
#if defined(__i386__)
430 83d73968 bellard
    int val;
431 83d73968 bellard
    asm volatile ("movzwl %1, %0\n"
432 83d73968 bellard
                  "xchgb %b0, %h0\n"
433 83d73968 bellard
                  : "=q" (val)
434 83d73968 bellard
                  : "m" (*(uint16_t *)ptr));
435 83d73968 bellard
    return (int16_t)val;
436 83d73968 bellard
#else
437 e01fe6d5 malc
    const uint8_t *b = ptr;
438 83d73968 bellard
    return (int16_t)((b[0] << 8) | b[1]);
439 83d73968 bellard
#endif
440 93ac68bc bellard
}
441 93ac68bc bellard
442 8bba3ea1 balrog
static inline int ldl_be_p(const void *ptr)
443 93ac68bc bellard
{
444 4f2ac237 bellard
#if defined(__i386__) || defined(__x86_64__)
445 83d73968 bellard
    int val;
446 83d73968 bellard
    asm volatile ("movl %1, %0\n"
447 83d73968 bellard
                  "bswap %0\n"
448 83d73968 bellard
                  : "=r" (val)
449 83d73968 bellard
                  : "m" (*(uint32_t *)ptr));
450 83d73968 bellard
    return val;
451 83d73968 bellard
#else
452 e01fe6d5 malc
    const uint8_t *b = ptr;
453 83d73968 bellard
    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
454 83d73968 bellard
#endif
455 93ac68bc bellard
}
456 93ac68bc bellard
457 8bba3ea1 balrog
static inline uint64_t ldq_be_p(const void *ptr)
458 93ac68bc bellard
{
459 93ac68bc bellard
    uint32_t a,b;
460 2df3b95d bellard
    a = ldl_be_p(ptr);
461 4d7a0880 blueswir1
    b = ldl_be_p((uint8_t *)ptr + 4);
462 93ac68bc bellard
    return (((uint64_t)a<<32)|b);
463 93ac68bc bellard
}
464 93ac68bc bellard
465 2df3b95d bellard
static inline void stw_be_p(void *ptr, int v)
466 93ac68bc bellard
{
467 83d73968 bellard
#if defined(__i386__)
468 83d73968 bellard
    asm volatile ("xchgb %b0, %h0\n"
469 83d73968 bellard
                  "movw %w0, %1\n"
470 83d73968 bellard
                  : "=q" (v)
471 83d73968 bellard
                  : "m" (*(uint16_t *)ptr), "0" (v));
472 83d73968 bellard
#else
473 93ac68bc bellard
    uint8_t *d = (uint8_t *) ptr;
474 93ac68bc bellard
    d[0] = v >> 8;
475 93ac68bc bellard
    d[1] = v;
476 83d73968 bellard
#endif
477 93ac68bc bellard
}
478 93ac68bc bellard
479 2df3b95d bellard
static inline void stl_be_p(void *ptr, int v)
480 93ac68bc bellard
{
481 4f2ac237 bellard
#if defined(__i386__) || defined(__x86_64__)
482 83d73968 bellard
    asm volatile ("bswap %0\n"
483 83d73968 bellard
                  "movl %0, %1\n"
484 83d73968 bellard
                  : "=r" (v)
485 83d73968 bellard
                  : "m" (*(uint32_t *)ptr), "0" (v));
486 83d73968 bellard
#else
487 93ac68bc bellard
    uint8_t *d = (uint8_t *) ptr;
488 93ac68bc bellard
    d[0] = v >> 24;
489 93ac68bc bellard
    d[1] = v >> 16;
490 93ac68bc bellard
    d[2] = v >> 8;
491 93ac68bc bellard
    d[3] = v;
492 83d73968 bellard
#endif
493 93ac68bc bellard
}
494 93ac68bc bellard
495 2df3b95d bellard
static inline void stq_be_p(void *ptr, uint64_t v)
496 93ac68bc bellard
{
497 2df3b95d bellard
    stl_be_p(ptr, v >> 32);
498 4d7a0880 blueswir1
    stl_be_p((uint8_t *)ptr + 4, v);
499 0ac4bd56 bellard
}
500 0ac4bd56 bellard
501 0ac4bd56 bellard
/* float access */
502 0ac4bd56 bellard
503 8bba3ea1 balrog
static inline float32 ldfl_be_p(const void *ptr)
504 0ac4bd56 bellard
{
505 0ac4bd56 bellard
    union {
506 53cd6637 bellard
        float32 f;
507 0ac4bd56 bellard
        uint32_t i;
508 0ac4bd56 bellard
    } u;
509 2df3b95d bellard
    u.i = ldl_be_p(ptr);
510 0ac4bd56 bellard
    return u.f;
511 0ac4bd56 bellard
}
512 0ac4bd56 bellard
513 2df3b95d bellard
static inline void stfl_be_p(void *ptr, float32 v)
514 0ac4bd56 bellard
{
515 0ac4bd56 bellard
    union {
516 53cd6637 bellard
        float32 f;
517 0ac4bd56 bellard
        uint32_t i;
518 0ac4bd56 bellard
    } u;
519 0ac4bd56 bellard
    u.f = v;
520 2df3b95d bellard
    stl_be_p(ptr, u.i);
521 0ac4bd56 bellard
}
522 0ac4bd56 bellard
523 8bba3ea1 balrog
static inline float64 ldfq_be_p(const void *ptr)
524 0ac4bd56 bellard
{
525 0ac4bd56 bellard
    CPU_DoubleU u;
526 2df3b95d bellard
    u.l.upper = ldl_be_p(ptr);
527 4d7a0880 blueswir1
    u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
528 0ac4bd56 bellard
    return u.d;
529 0ac4bd56 bellard
}
530 0ac4bd56 bellard
531 2df3b95d bellard
static inline void stfq_be_p(void *ptr, float64 v)
532 0ac4bd56 bellard
{
533 0ac4bd56 bellard
    CPU_DoubleU u;
534 0ac4bd56 bellard
    u.d = v;
535 2df3b95d bellard
    stl_be_p(ptr, u.l.upper);
536 4d7a0880 blueswir1
    stl_be_p((uint8_t *)ptr + 4, u.l.lower);
537 93ac68bc bellard
}
538 93ac68bc bellard
539 5a9fdfec bellard
#else
540 5a9fdfec bellard
541 8bba3ea1 balrog
static inline int lduw_be_p(const void *ptr)
542 5a9fdfec bellard
{
543 5a9fdfec bellard
    return *(uint16_t *)ptr;
544 5a9fdfec bellard
}
545 5a9fdfec bellard
546 8bba3ea1 balrog
static inline int ldsw_be_p(const void *ptr)
547 5a9fdfec bellard
{
548 5a9fdfec bellard
    return *(int16_t *)ptr;
549 5a9fdfec bellard
}
550 5a9fdfec bellard
551 8bba3ea1 balrog
static inline int ldl_be_p(const void *ptr)
552 5a9fdfec bellard
{
553 5a9fdfec bellard
    return *(uint32_t *)ptr;
554 5a9fdfec bellard
}
555 5a9fdfec bellard
556 8bba3ea1 balrog
static inline uint64_t ldq_be_p(const void *ptr)
557 5a9fdfec bellard
{
558 5a9fdfec bellard
    return *(uint64_t *)ptr;
559 5a9fdfec bellard
}
560 5a9fdfec bellard
561 2df3b95d bellard
static inline void stw_be_p(void *ptr, int v)
562 5a9fdfec bellard
{
563 5a9fdfec bellard
    *(uint16_t *)ptr = v;
564 5a9fdfec bellard
}
565 5a9fdfec bellard
566 2df3b95d bellard
static inline void stl_be_p(void *ptr, int v)
567 5a9fdfec bellard
{
568 5a9fdfec bellard
    *(uint32_t *)ptr = v;
569 5a9fdfec bellard
}
570 5a9fdfec bellard
571 2df3b95d bellard
static inline void stq_be_p(void *ptr, uint64_t v)
572 5a9fdfec bellard
{
573 5a9fdfec bellard
    *(uint64_t *)ptr = v;
574 5a9fdfec bellard
}
575 5a9fdfec bellard
576 5a9fdfec bellard
/* float access */
577 5a9fdfec bellard
578 8bba3ea1 balrog
static inline float32 ldfl_be_p(const void *ptr)
579 5a9fdfec bellard
{
580 53cd6637 bellard
    return *(float32 *)ptr;
581 5a9fdfec bellard
}
582 5a9fdfec bellard
583 8bba3ea1 balrog
static inline float64 ldfq_be_p(const void *ptr)
584 5a9fdfec bellard
{
585 53cd6637 bellard
    return *(float64 *)ptr;
586 5a9fdfec bellard
}
587 5a9fdfec bellard
588 2df3b95d bellard
static inline void stfl_be_p(void *ptr, float32 v)
589 5a9fdfec bellard
{
590 53cd6637 bellard
    *(float32 *)ptr = v;
591 5a9fdfec bellard
}
592 5a9fdfec bellard
593 2df3b95d bellard
static inline void stfq_be_p(void *ptr, float64 v)
594 5a9fdfec bellard
{
595 53cd6637 bellard
    *(float64 *)ptr = v;
596 5a9fdfec bellard
}
597 2df3b95d bellard
598 2df3b95d bellard
#endif
599 2df3b95d bellard
600 2df3b95d bellard
/* target CPU memory access functions */
601 2df3b95d bellard
#if defined(TARGET_WORDS_BIGENDIAN)
602 2df3b95d bellard
#define lduw_p(p) lduw_be_p(p)
603 2df3b95d bellard
#define ldsw_p(p) ldsw_be_p(p)
604 2df3b95d bellard
#define ldl_p(p) ldl_be_p(p)
605 2df3b95d bellard
#define ldq_p(p) ldq_be_p(p)
606 2df3b95d bellard
#define ldfl_p(p) ldfl_be_p(p)
607 2df3b95d bellard
#define ldfq_p(p) ldfq_be_p(p)
608 2df3b95d bellard
#define stw_p(p, v) stw_be_p(p, v)
609 2df3b95d bellard
#define stl_p(p, v) stl_be_p(p, v)
610 2df3b95d bellard
#define stq_p(p, v) stq_be_p(p, v)
611 2df3b95d bellard
#define stfl_p(p, v) stfl_be_p(p, v)
612 2df3b95d bellard
#define stfq_p(p, v) stfq_be_p(p, v)
613 2df3b95d bellard
#else
614 2df3b95d bellard
#define lduw_p(p) lduw_le_p(p)
615 2df3b95d bellard
#define ldsw_p(p) ldsw_le_p(p)
616 2df3b95d bellard
#define ldl_p(p) ldl_le_p(p)
617 2df3b95d bellard
#define ldq_p(p) ldq_le_p(p)
618 2df3b95d bellard
#define ldfl_p(p) ldfl_le_p(p)
619 2df3b95d bellard
#define ldfq_p(p) ldfq_le_p(p)
620 2df3b95d bellard
#define stw_p(p, v) stw_le_p(p, v)
621 2df3b95d bellard
#define stl_p(p, v) stl_le_p(p, v)
622 2df3b95d bellard
#define stq_p(p, v) stq_le_p(p, v)
623 2df3b95d bellard
#define stfl_p(p, v) stfl_le_p(p, v)
624 2df3b95d bellard
#define stfq_p(p, v) stfq_le_p(p, v)
625 5a9fdfec bellard
#endif
626 5a9fdfec bellard
627 61382a50 bellard
/* MMU memory access macros */
628 61382a50 bellard
629 53a5960a pbrook
#if defined(CONFIG_USER_ONLY)
630 0e62fd79 aurel32
#include <assert.h>
631 0e62fd79 aurel32
#include "qemu-types.h"
632 0e62fd79 aurel32
633 53a5960a pbrook
/* On some host systems the guest address space is reserved on the host.
634 53a5960a pbrook
 * This allows the guest address space to be offset to a convenient location.
635 53a5960a pbrook
 */
636 379f6698 Paul Brook
#if defined(CONFIG_USE_GUEST_BASE)
637 379f6698 Paul Brook
extern unsigned long guest_base;
638 379f6698 Paul Brook
extern int have_guest_base;
639 68a1c816 Paul Brook
extern unsigned long reserved_va;
640 379f6698 Paul Brook
#define GUEST_BASE guest_base
641 18e9ea8a Aurelien Jarno
#define RESERVED_VA reserved_va
642 379f6698 Paul Brook
#else
643 379f6698 Paul Brook
#define GUEST_BASE 0ul
644 18e9ea8a Aurelien Jarno
#define RESERVED_VA 0ul
645 379f6698 Paul Brook
#endif
646 53a5960a pbrook
647 53a5960a pbrook
/* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
648 53a5960a pbrook
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
649 b9f83121 Richard Henderson
650 b9f83121 Richard Henderson
#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
651 b9f83121 Richard Henderson
#define h2g_valid(x) 1
652 b9f83121 Richard Henderson
#else
653 b9f83121 Richard Henderson
#define h2g_valid(x) ({ \
654 b9f83121 Richard Henderson
    unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
655 b9f83121 Richard Henderson
    __guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
656 b9f83121 Richard Henderson
})
657 b9f83121 Richard Henderson
#endif
658 b9f83121 Richard Henderson
659 0e62fd79 aurel32
#define h2g(x) ({ \
660 0e62fd79 aurel32
    unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
661 0e62fd79 aurel32
    /* Check if given address fits target address space */ \
662 b9f83121 Richard Henderson
    assert(h2g_valid(x)); \
663 0e62fd79 aurel32
    (abi_ulong)__ret; \
664 0e62fd79 aurel32
})
665 53a5960a pbrook
666 53a5960a pbrook
#define saddr(x) g2h(x)
667 53a5960a pbrook
#define laddr(x) g2h(x)
668 53a5960a pbrook
669 53a5960a pbrook
#else /* !CONFIG_USER_ONLY */
670 c27004ec bellard
/* NOTE: we use double casts if pointers and target_ulong have
671 c27004ec bellard
   different sizes */
672 53a5960a pbrook
#define saddr(x) (uint8_t *)(long)(x)
673 53a5960a pbrook
#define laddr(x) (uint8_t *)(long)(x)
674 53a5960a pbrook
#endif
675 53a5960a pbrook
676 53a5960a pbrook
#define ldub_raw(p) ldub_p(laddr((p)))
677 53a5960a pbrook
#define ldsb_raw(p) ldsb_p(laddr((p)))
678 53a5960a pbrook
#define lduw_raw(p) lduw_p(laddr((p)))
679 53a5960a pbrook
#define ldsw_raw(p) ldsw_p(laddr((p)))
680 53a5960a pbrook
#define ldl_raw(p) ldl_p(laddr((p)))
681 53a5960a pbrook
#define ldq_raw(p) ldq_p(laddr((p)))
682 53a5960a pbrook
#define ldfl_raw(p) ldfl_p(laddr((p)))
683 53a5960a pbrook
#define ldfq_raw(p) ldfq_p(laddr((p)))
684 53a5960a pbrook
#define stb_raw(p, v) stb_p(saddr((p)), v)
685 53a5960a pbrook
#define stw_raw(p, v) stw_p(saddr((p)), v)
686 53a5960a pbrook
#define stl_raw(p, v) stl_p(saddr((p)), v)
687 53a5960a pbrook
#define stq_raw(p, v) stq_p(saddr((p)), v)
688 53a5960a pbrook
#define stfl_raw(p, v) stfl_p(saddr((p)), v)
689 53a5960a pbrook
#define stfq_raw(p, v) stfq_p(saddr((p)), v)
690 c27004ec bellard
691 c27004ec bellard
692 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
693 61382a50 bellard
694 61382a50 bellard
/* if user mode, no other memory access functions */
695 61382a50 bellard
#define ldub(p) ldub_raw(p)
696 61382a50 bellard
#define ldsb(p) ldsb_raw(p)
697 61382a50 bellard
#define lduw(p) lduw_raw(p)
698 61382a50 bellard
#define ldsw(p) ldsw_raw(p)
699 61382a50 bellard
#define ldl(p) ldl_raw(p)
700 61382a50 bellard
#define ldq(p) ldq_raw(p)
701 61382a50 bellard
#define ldfl(p) ldfl_raw(p)
702 61382a50 bellard
#define ldfq(p) ldfq_raw(p)
703 61382a50 bellard
#define stb(p, v) stb_raw(p, v)
704 61382a50 bellard
#define stw(p, v) stw_raw(p, v)
705 61382a50 bellard
#define stl(p, v) stl_raw(p, v)
706 61382a50 bellard
#define stq(p, v) stq_raw(p, v)
707 61382a50 bellard
#define stfl(p, v) stfl_raw(p, v)
708 61382a50 bellard
#define stfq(p, v) stfq_raw(p, v)
709 61382a50 bellard
710 61382a50 bellard
#define ldub_code(p) ldub_raw(p)
711 61382a50 bellard
#define ldsb_code(p) ldsb_raw(p)
712 61382a50 bellard
#define lduw_code(p) lduw_raw(p)
713 61382a50 bellard
#define ldsw_code(p) ldsw_raw(p)
714 61382a50 bellard
#define ldl_code(p) ldl_raw(p)
715 bc98a7ef j_mayer
#define ldq_code(p) ldq_raw(p)
716 61382a50 bellard
717 61382a50 bellard
#define ldub_kernel(p) ldub_raw(p)
718 61382a50 bellard
#define ldsb_kernel(p) ldsb_raw(p)
719 61382a50 bellard
#define lduw_kernel(p) lduw_raw(p)
720 61382a50 bellard
#define ldsw_kernel(p) ldsw_raw(p)
721 61382a50 bellard
#define ldl_kernel(p) ldl_raw(p)
722 bc98a7ef j_mayer
#define ldq_kernel(p) ldq_raw(p)
723 0ac4bd56 bellard
#define ldfl_kernel(p) ldfl_raw(p)
724 0ac4bd56 bellard
#define ldfq_kernel(p) ldfq_raw(p)
725 61382a50 bellard
#define stb_kernel(p, v) stb_raw(p, v)
726 61382a50 bellard
#define stw_kernel(p, v) stw_raw(p, v)
727 61382a50 bellard
#define stl_kernel(p, v) stl_raw(p, v)
728 61382a50 bellard
#define stq_kernel(p, v) stq_raw(p, v)
729 0ac4bd56 bellard
#define stfl_kernel(p, v) stfl_raw(p, v)
730 0ac4bd56 bellard
#define stfq_kernel(p, vt) stfq_raw(p, v)
731 61382a50 bellard
732 61382a50 bellard
#endif /* defined(CONFIG_USER_ONLY) */
733 61382a50 bellard
734 5a9fdfec bellard
/* page related stuff */
735 5a9fdfec bellard
736 03875444 aurel32
#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
737 5a9fdfec bellard
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
738 5a9fdfec bellard
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
739 5a9fdfec bellard
740 53a5960a pbrook
/* ??? These should be the larger of unsigned long and target_ulong.  */
741 83fb7adf bellard
extern unsigned long qemu_real_host_page_size;
742 83fb7adf bellard
extern unsigned long qemu_host_page_bits;
743 83fb7adf bellard
extern unsigned long qemu_host_page_size;
744 83fb7adf bellard
extern unsigned long qemu_host_page_mask;
745 5a9fdfec bellard
746 83fb7adf bellard
#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
747 5a9fdfec bellard
748 5a9fdfec bellard
/* same as PROT_xxx */
749 5a9fdfec bellard
#define PAGE_READ      0x0001
750 5a9fdfec bellard
#define PAGE_WRITE     0x0002
751 5a9fdfec bellard
#define PAGE_EXEC      0x0004
752 5a9fdfec bellard
#define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
753 5a9fdfec bellard
#define PAGE_VALID     0x0008
754 5a9fdfec bellard
/* original state of the write flag (used when tracking self-modifying
755 5a9fdfec bellard
   code */
756 5fafdf24 ths
#define PAGE_WRITE_ORG 0x0010
757 2e9a5713 Paul Brook
#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
758 2e9a5713 Paul Brook
/* FIXME: Code that sets/uses this is broken and needs to go away.  */
759 50a9569b balrog
#define PAGE_RESERVED  0x0020
760 2e9a5713 Paul Brook
#endif
761 5a9fdfec bellard
762 b480d9b7 Paul Brook
#if defined(CONFIG_USER_ONLY)
763 5a9fdfec bellard
void page_dump(FILE *f);
764 5cd2c5b6 Richard Henderson
765 b480d9b7 Paul Brook
typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
766 b480d9b7 Paul Brook
                                      abi_ulong, unsigned long);
767 5cd2c5b6 Richard Henderson
int walk_memory_regions(void *, walk_memory_regions_fn);
768 5cd2c5b6 Richard Henderson
769 53a5960a pbrook
int page_get_flags(target_ulong address);
770 53a5960a pbrook
void page_set_flags(target_ulong start, target_ulong end, int flags);
771 3d97b40b ths
int page_check_range(target_ulong start, target_ulong len, int flags);
772 b480d9b7 Paul Brook
#endif
773 5a9fdfec bellard
774 c5be9f08 ths
CPUState *cpu_copy(CPUState *env);
775 950f1472 Glauber Costa
CPUState *qemu_get_cpu(int cpu);
776 c5be9f08 ths
777 f5c848ee Jan Kiszka
#define CPU_DUMP_CODE 0x00010000
778 f5c848ee Jan Kiszka
779 9a78eead Stefan Weil
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
780 7fe48483 bellard
                    int flags);
781 9a78eead Stefan Weil
void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
782 9a78eead Stefan Weil
                         int flags);
783 7fe48483 bellard
784 a5e50b26 malc
void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
785 2c80e423 Stefan Weil
    GCC_FMT_ATTR(2, 3);
786 f0aca822 bellard
extern CPUState *first_cpu;
787 e2f22898 bellard
extern CPUState *cpu_single_env;
788 db1a4972 Paolo Bonzini
789 9c76219e Richard Henderson
/* Flags for use in ENV->INTERRUPT_PENDING.
790 9c76219e Richard Henderson

791 9c76219e Richard Henderson
   The numbers assigned here are non-sequential in order to preserve
792 9c76219e Richard Henderson
   binary compatibility with the vmstate dump.  Bit 0 (0x0001) was
793 9c76219e Richard Henderson
   previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
794 9c76219e Richard Henderson
   the vmstate dump.  */
795 9c76219e Richard Henderson
796 9c76219e Richard Henderson
/* External hardware interrupt pending.  This is typically used for
797 9c76219e Richard Henderson
   interrupts from devices.  */
798 9c76219e Richard Henderson
#define CPU_INTERRUPT_HARD        0x0002
799 9c76219e Richard Henderson
800 9c76219e Richard Henderson
/* Exit the current TB.  This is typically used when some system-level device
801 9c76219e Richard Henderson
   makes some change to the memory mapping.  E.g. the a20 line change.  */
802 9c76219e Richard Henderson
#define CPU_INTERRUPT_EXITTB      0x0004
803 9c76219e Richard Henderson
804 9c76219e Richard Henderson
/* Halt the CPU.  */
805 9c76219e Richard Henderson
#define CPU_INTERRUPT_HALT        0x0020
806 9c76219e Richard Henderson
807 9c76219e Richard Henderson
/* Debug event pending.  */
808 9c76219e Richard Henderson
#define CPU_INTERRUPT_DEBUG       0x0080
809 9c76219e Richard Henderson
810 9c76219e Richard Henderson
/* Several target-specific external hardware interrupts.  Each target/cpu.h
811 9c76219e Richard Henderson
   should define proper names based on these defines.  */
812 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_EXT_0   0x0008
813 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_EXT_1   0x0010
814 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_EXT_2   0x0040
815 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_EXT_3   0x0200
816 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_EXT_4   0x1000
817 9c76219e Richard Henderson
818 9c76219e Richard Henderson
/* Several target-specific internal interrupts.  These differ from the
819 9c76219e Richard Henderson
   preceeding target-specific interrupts in that they are intended to
820 9c76219e Richard Henderson
   originate from within the cpu itself, typically in response to some
821 9c76219e Richard Henderson
   instruction being executed.  These, therefore, are not masked while
822 9c76219e Richard Henderson
   single-stepping within the debugger.  */
823 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_INT_0   0x0100
824 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_INT_1   0x0400
825 9c76219e Richard Henderson
#define CPU_INTERRUPT_TGT_INT_2   0x0800
826 9c76219e Richard Henderson
827 9c76219e Richard Henderson
/* First unused bit: 0x2000.  */
828 9c76219e Richard Henderson
829 3125f763 Richard Henderson
/* The set of all bits that should be masked when single-stepping.  */
830 3125f763 Richard Henderson
#define CPU_INTERRUPT_SSTEP_MASK \
831 3125f763 Richard Henderson
    (CPU_INTERRUPT_HARD          \
832 3125f763 Richard Henderson
     | CPU_INTERRUPT_TGT_EXT_0   \
833 3125f763 Richard Henderson
     | CPU_INTERRUPT_TGT_EXT_1   \
834 3125f763 Richard Henderson
     | CPU_INTERRUPT_TGT_EXT_2   \
835 3125f763 Richard Henderson
     | CPU_INTERRUPT_TGT_EXT_3   \
836 3125f763 Richard Henderson
     | CPU_INTERRUPT_TGT_EXT_4)
837 98699967 bellard
838 ec6959d0 Jan Kiszka
#ifndef CONFIG_USER_ONLY
839 ec6959d0 Jan Kiszka
typedef void (*CPUInterruptHandler)(CPUState *, int);
840 ec6959d0 Jan Kiszka
841 ec6959d0 Jan Kiszka
extern CPUInterruptHandler cpu_interrupt_handler;
842 ec6959d0 Jan Kiszka
843 ec6959d0 Jan Kiszka
static inline void cpu_interrupt(CPUState *s, int mask)
844 ec6959d0 Jan Kiszka
{
845 ec6959d0 Jan Kiszka
    cpu_interrupt_handler(s, mask);
846 ec6959d0 Jan Kiszka
}
847 ec6959d0 Jan Kiszka
#else /* USER_ONLY */
848 ec6959d0 Jan Kiszka
void cpu_interrupt(CPUState *env, int mask);
849 ec6959d0 Jan Kiszka
#endif /* USER_ONLY */
850 ec6959d0 Jan Kiszka
851 b54ad049 bellard
void cpu_reset_interrupt(CPUState *env, int mask);
852 68a79315 bellard
853 3098dba0 aurel32
void cpu_exit(CPUState *s);
854 3098dba0 aurel32
855 6a4955a8 aliguori
int qemu_cpu_has_work(CPUState *env);
856 6a4955a8 aliguori
857 a1d1bb31 aliguori
/* Breakpoint/watchpoint flags */
858 a1d1bb31 aliguori
#define BP_MEM_READ           0x01
859 a1d1bb31 aliguori
#define BP_MEM_WRITE          0x02
860 a1d1bb31 aliguori
#define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE)
861 06d55cc1 aliguori
#define BP_STOP_BEFORE_ACCESS 0x04
862 6e140f28 aliguori
#define BP_WATCHPOINT_HIT     0x08
863 a1d1bb31 aliguori
#define BP_GDB                0x10
864 2dc9f411 aliguori
#define BP_CPU                0x20
865 a1d1bb31 aliguori
866 a1d1bb31 aliguori
int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
867 a1d1bb31 aliguori
                          CPUBreakpoint **breakpoint);
868 a1d1bb31 aliguori
int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags);
869 a1d1bb31 aliguori
void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint);
870 a1d1bb31 aliguori
void cpu_breakpoint_remove_all(CPUState *env, int mask);
871 a1d1bb31 aliguori
int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
872 a1d1bb31 aliguori
                          int flags, CPUWatchpoint **watchpoint);
873 a1d1bb31 aliguori
int cpu_watchpoint_remove(CPUState *env, target_ulong addr,
874 a1d1bb31 aliguori
                          target_ulong len, int flags);
875 a1d1bb31 aliguori
void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint);
876 a1d1bb31 aliguori
void cpu_watchpoint_remove_all(CPUState *env, int mask);
877 60897d36 edgar_igl
878 60897d36 edgar_igl
#define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
879 60897d36 edgar_igl
#define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
880 60897d36 edgar_igl
#define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */
881 60897d36 edgar_igl
882 c33a346e bellard
void cpu_single_step(CPUState *env, int enabled);
883 d95dc32d bellard
void cpu_reset(CPUState *s);
884 3ae9501c Marcelo Tosatti
int cpu_is_stopped(CPUState *env);
885 e82bcec2 Marcelo Tosatti
void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
886 4c3a88a2 bellard
887 5fafdf24 ths
#define CPU_LOG_TB_OUT_ASM (1 << 0)
888 9fddaa0c bellard
#define CPU_LOG_TB_IN_ASM  (1 << 1)
889 f193c797 bellard
#define CPU_LOG_TB_OP      (1 << 2)
890 f193c797 bellard
#define CPU_LOG_TB_OP_OPT  (1 << 3)
891 f193c797 bellard
#define CPU_LOG_INT        (1 << 4)
892 f193c797 bellard
#define CPU_LOG_EXEC       (1 << 5)
893 f193c797 bellard
#define CPU_LOG_PCALL      (1 << 6)
894 fd872598 bellard
#define CPU_LOG_IOPORT     (1 << 7)
895 9fddaa0c bellard
#define CPU_LOG_TB_CPU     (1 << 8)
896 eca1bdf4 aliguori
#define CPU_LOG_RESET      (1 << 9)
897 f193c797 bellard
898 f193c797 bellard
/* define log items */
899 f193c797 bellard
typedef struct CPULogItem {
900 f193c797 bellard
    int mask;
901 f193c797 bellard
    const char *name;
902 f193c797 bellard
    const char *help;
903 f193c797 bellard
} CPULogItem;
904 f193c797 bellard
905 c7cd6a37 blueswir1
extern const CPULogItem cpu_log_items[];
906 f193c797 bellard
907 34865134 bellard
void cpu_set_log(int log_flags);
908 34865134 bellard
void cpu_set_log_filename(const char *filename);
909 f193c797 bellard
int cpu_str_to_log_mask(const char *str);
910 34865134 bellard
911 b3755a91 Paul Brook
#if !defined(CONFIG_USER_ONLY)
912 b3755a91 Paul Brook
913 4fcc562b Paul Brook
/* Return the physical page corresponding to a virtual one. Use it
914 4fcc562b Paul Brook
   only for debugging because no protection checks are done. Return -1
915 4fcc562b Paul Brook
   if no page found. */
916 4fcc562b Paul Brook
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
917 4fcc562b Paul Brook
918 33417e70 bellard
/* memory API */
919 33417e70 bellard
920 edf75d59 bellard
extern int phys_ram_fd;
921 c227f099 Anthony Liguori
extern ram_addr_t ram_size;
922 f471a17e Alex Williamson
923 cd19cfa2 Huang Ying
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
924 cd19cfa2 Huang Ying
#define RAM_PREALLOC_MASK   (1 << 0)
925 cd19cfa2 Huang Ying
926 f471a17e Alex Williamson
typedef struct RAMBlock {
927 f471a17e Alex Williamson
    uint8_t *host;
928 f471a17e Alex Williamson
    ram_addr_t offset;
929 f471a17e Alex Williamson
    ram_addr_t length;
930 cd19cfa2 Huang Ying
    uint32_t flags;
931 cc9e98cb Alex Williamson
    char idstr[256];
932 f471a17e Alex Williamson
    QLIST_ENTRY(RAMBlock) next;
933 04b16653 Alex Williamson
#if defined(__linux__) && !defined(TARGET_S390X)
934 04b16653 Alex Williamson
    int fd;
935 04b16653 Alex Williamson
#endif
936 f471a17e Alex Williamson
} RAMBlock;
937 f471a17e Alex Williamson
938 f471a17e Alex Williamson
typedef struct RAMList {
939 f471a17e Alex Williamson
    uint8_t *phys_dirty;
940 f471a17e Alex Williamson
    QLIST_HEAD(ram, RAMBlock) blocks;
941 f471a17e Alex Williamson
} RAMList;
942 f471a17e Alex Williamson
extern RAMList ram_list;
943 edf75d59 bellard
944 c902760f Marcelo Tosatti
extern const char *mem_path;
945 c902760f Marcelo Tosatti
extern int mem_prealloc;
946 c902760f Marcelo Tosatti
947 edf75d59 bellard
/* physical memory access */
948 0f459d16 pbrook
949 0f459d16 pbrook
/* MMIO pages are identified by a combination of an IO device index and
950 0f459d16 pbrook
   3 flags.  The ROMD code stores the page ram offset in iotlb entry, 
951 0f459d16 pbrook
   so only a limited number of ids are avaiable.  */
952 0f459d16 pbrook
953 98699967 bellard
#define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
954 edf75d59 bellard
955 0f459d16 pbrook
/* Flags stored in the low bits of the TLB virtual address.  These are
956 0f459d16 pbrook
   defined so that fast path ram access is all zeros.  */
957 0f459d16 pbrook
/* Zero if TLB entry is valid.  */
958 0f459d16 pbrook
#define TLB_INVALID_MASK   (1 << 3)
959 0f459d16 pbrook
/* Set if TLB entry references a clean RAM page.  The iotlb entry will
960 0f459d16 pbrook
   contain the page physical address.  */
961 0f459d16 pbrook
#define TLB_NOTDIRTY    (1 << 4)
962 0f459d16 pbrook
/* Set if TLB entry is an IO callback.  */
963 0f459d16 pbrook
#define TLB_MMIO        (1 << 5)
964 0f459d16 pbrook
965 74576198 aliguori
#define VGA_DIRTY_FLAG       0x01
966 74576198 aliguori
#define CODE_DIRTY_FLAG      0x02
967 74576198 aliguori
#define MIGRATION_DIRTY_FLAG 0x08
968 0a962c02 bellard
969 1ccde1cb bellard
/* read dirty bit (return 0 or 1) */
970 c227f099 Anthony Liguori
static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
971 1ccde1cb bellard
{
972 f471a17e Alex Williamson
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
973 0a962c02 bellard
}
974 0a962c02 bellard
975 ca39b46e Yoshiaki Tamura
static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
976 ca39b46e Yoshiaki Tamura
{
977 f471a17e Alex Williamson
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS];
978 ca39b46e Yoshiaki Tamura
}
979 ca39b46e Yoshiaki Tamura
980 c227f099 Anthony Liguori
static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
981 0a962c02 bellard
                                                int dirty_flags)
982 0a962c02 bellard
{
983 f471a17e Alex Williamson
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
984 1ccde1cb bellard
}
985 1ccde1cb bellard
986 c227f099 Anthony Liguori
static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
987 1ccde1cb bellard
{
988 f471a17e Alex Williamson
    ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
989 1ccde1cb bellard
}
990 1ccde1cb bellard
991 ca39b46e Yoshiaki Tamura
static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
992 ca39b46e Yoshiaki Tamura
                                                      int dirty_flags)
993 ca39b46e Yoshiaki Tamura
{
994 f471a17e Alex Williamson
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags;
995 ca39b46e Yoshiaki Tamura
}
996 ca39b46e Yoshiaki Tamura
997 ca39b46e Yoshiaki Tamura
static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
998 ca39b46e Yoshiaki Tamura
                                                        int length,
999 ca39b46e Yoshiaki Tamura
                                                        int dirty_flags)
1000 ca39b46e Yoshiaki Tamura
{
1001 ca39b46e Yoshiaki Tamura
    int i, mask, len;
1002 ca39b46e Yoshiaki Tamura
    uint8_t *p;
1003 ca39b46e Yoshiaki Tamura
1004 ca39b46e Yoshiaki Tamura
    len = length >> TARGET_PAGE_BITS;
1005 ca39b46e Yoshiaki Tamura
    mask = ~dirty_flags;
1006 f471a17e Alex Williamson
    p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS);
1007 ca39b46e Yoshiaki Tamura
    for (i = 0; i < len; i++) {
1008 ca39b46e Yoshiaki Tamura
        p[i] &= mask;
1009 ca39b46e Yoshiaki Tamura
    }
1010 ca39b46e Yoshiaki Tamura
}
1011 ca39b46e Yoshiaki Tamura
1012 c227f099 Anthony Liguori
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1013 0a962c02 bellard
                                     int dirty_flags);
1014 04c504cc bellard
void cpu_tlb_update_dirty(CPUState *env);
1015 1ccde1cb bellard
1016 74576198 aliguori
int cpu_physical_memory_set_dirty_tracking(int enable);
1017 74576198 aliguori
1018 74576198 aliguori
int cpu_physical_memory_get_dirty_tracking(void);
1019 74576198 aliguori
1020 c227f099 Anthony Liguori
int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
1021 c227f099 Anthony Liguori
                                   target_phys_addr_t end_addr);
1022 2bec46dc aliguori
1023 e5896b12 Anthony PERARD
int cpu_physical_log_start(target_phys_addr_t start_addr,
1024 e5896b12 Anthony PERARD
                           ram_addr_t size);
1025 e5896b12 Anthony PERARD
1026 e5896b12 Anthony PERARD
int cpu_physical_log_stop(target_phys_addr_t start_addr,
1027 e5896b12 Anthony PERARD
                          ram_addr_t size);
1028 e5896b12 Anthony PERARD
1029 055403b2 Stefan Weil
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
1030 b3755a91 Paul Brook
#endif /* !CONFIG_USER_ONLY */
1031 b3755a91 Paul Brook
1032 b3755a91 Paul Brook
int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
1033 b3755a91 Paul Brook
                        uint8_t *buf, int len, int is_write);
1034 b3755a91 Paul Brook
1035 5a9fdfec bellard
#endif /* CPU_ALL_H */