Statistics
| Branch: | Revision:

root / cpu-all.h @ d4970b07

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

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