Statistics
| Branch: | Revision:

root / cpu-all.h @ cf67c6ba

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

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