qemu/include/exec/cpu-all.h
<<
>>
Prefs
   1/*
   2 * defines common to all virtual CPUs
   3 *
   4 *  Copyright (c) 2003 Fabrice Bellard
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19#ifndef CPU_ALL_H
  20#define CPU_ALL_H
  21
  22#include "qemu-common.h"
  23#include "exec/cpu-common.h"
  24#include "exec/memory.h"
  25#include "qemu/thread.h"
  26#include "qom/cpu.h"
  27#include "qemu/rcu.h"
  28
  29/* some important defines:
  30 *
  31 * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
  32 * memory accesses.
  33 *
  34 * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
  35 * otherwise little endian.
  36 *
  37 * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
  38 *
  39 * TARGET_WORDS_BIGENDIAN : same for target cpu
  40 */
  41
  42#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
  43#define BSWAP_NEEDED
  44#endif
  45
  46#ifdef BSWAP_NEEDED
  47
  48static inline uint16_t tswap16(uint16_t s)
  49{
  50    return bswap16(s);
  51}
  52
  53static inline uint32_t tswap32(uint32_t s)
  54{
  55    return bswap32(s);
  56}
  57
  58static inline uint64_t tswap64(uint64_t s)
  59{
  60    return bswap64(s);
  61}
  62
  63static inline void tswap16s(uint16_t *s)
  64{
  65    *s = bswap16(*s);
  66}
  67
  68static inline void tswap32s(uint32_t *s)
  69{
  70    *s = bswap32(*s);
  71}
  72
  73static inline void tswap64s(uint64_t *s)
  74{
  75    *s = bswap64(*s);
  76}
  77
  78#else
  79
  80static inline uint16_t tswap16(uint16_t s)
  81{
  82    return s;
  83}
  84
  85static inline uint32_t tswap32(uint32_t s)
  86{
  87    return s;
  88}
  89
  90static inline uint64_t tswap64(uint64_t s)
  91{
  92    return s;
  93}
  94
  95static inline void tswap16s(uint16_t *s)
  96{
  97}
  98
  99static inline void tswap32s(uint32_t *s)
 100{
 101}
 102
 103static inline void tswap64s(uint64_t *s)
 104{
 105}
 106
 107#endif
 108
 109#if TARGET_LONG_SIZE == 4
 110#define tswapl(s) tswap32(s)
 111#define tswapls(s) tswap32s((uint32_t *)(s))
 112#define bswaptls(s) bswap32s(s)
 113#else
 114#define tswapl(s) tswap64(s)
 115#define tswapls(s) tswap64s((uint64_t *)(s))
 116#define bswaptls(s) bswap64s(s)
 117#endif
 118
 119/* Target-endianness CPU memory access functions. These fit into the
 120 * {ld,st}{type}{sign}{size}{endian}_p naming scheme described in bswap.h.
 121 */
 122#if defined(TARGET_WORDS_BIGENDIAN)
 123#define lduw_p(p) lduw_be_p(p)
 124#define ldsw_p(p) ldsw_be_p(p)
 125#define ldl_p(p) ldl_be_p(p)
 126#define ldq_p(p) ldq_be_p(p)
 127#define ldfl_p(p) ldfl_be_p(p)
 128#define ldfq_p(p) ldfq_be_p(p)
 129#define stw_p(p, v) stw_be_p(p, v)
 130#define stl_p(p, v) stl_be_p(p, v)
 131#define stq_p(p, v) stq_be_p(p, v)
 132#define stfl_p(p, v) stfl_be_p(p, v)
 133#define stfq_p(p, v) stfq_be_p(p, v)
 134#else
 135#define lduw_p(p) lduw_le_p(p)
 136#define ldsw_p(p) ldsw_le_p(p)
 137#define ldl_p(p) ldl_le_p(p)
 138#define ldq_p(p) ldq_le_p(p)
 139#define ldfl_p(p) ldfl_le_p(p)
 140#define ldfq_p(p) ldfq_le_p(p)
 141#define stw_p(p, v) stw_le_p(p, v)
 142#define stl_p(p, v) stl_le_p(p, v)
 143#define stq_p(p, v) stq_le_p(p, v)
 144#define stfl_p(p, v) stfl_le_p(p, v)
 145#define stfq_p(p, v) stfq_le_p(p, v)
 146#endif
 147
 148/* MMU memory access macros */
 149
 150#if defined(CONFIG_USER_ONLY)
 151#include <assert.h>
 152#include "exec/user/abitypes.h"
 153
 154/* On some host systems the guest address space is reserved on the host.
 155 * This allows the guest address space to be offset to a convenient location.
 156 */
 157#if defined(CONFIG_USE_GUEST_BASE)
 158extern unsigned long guest_base;
 159extern int have_guest_base;
 160extern unsigned long reserved_va;
 161#define GUEST_BASE guest_base
 162#define RESERVED_VA reserved_va
 163#else
 164#define GUEST_BASE 0ul
 165#define RESERVED_VA 0ul
 166#endif
 167
 168#define GUEST_ADDR_MAX (RESERVED_VA ? RESERVED_VA : \
 169                                    (1ul << TARGET_VIRT_ADDR_SPACE_BITS) - 1)
 170#endif
 171
 172/* page related stuff */
 173
 174#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
 175#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
 176#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
 177
 178/* ??? These should be the larger of uintptr_t and target_ulong.  */
 179extern uintptr_t qemu_real_host_page_size;
 180extern uintptr_t qemu_host_page_size;
 181extern uintptr_t qemu_host_page_mask;
 182
 183#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
 184
 185/* same as PROT_xxx */
 186#define PAGE_READ      0x0001
 187#define PAGE_WRITE     0x0002
 188#define PAGE_EXEC      0x0004
 189#define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
 190#define PAGE_VALID     0x0008
 191/* original state of the write flag (used when tracking self-modifying
 192   code */
 193#define PAGE_WRITE_ORG 0x0010
 194#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 195/* FIXME: Code that sets/uses this is broken and needs to go away.  */
 196#define PAGE_RESERVED  0x0020
 197#endif
 198
 199#if defined(CONFIG_USER_ONLY)
 200void page_dump(FILE *f);
 201
 202typedef int (*walk_memory_regions_fn)(void *, target_ulong,
 203                                      target_ulong, unsigned long);
 204int walk_memory_regions(void *, walk_memory_regions_fn);
 205
 206int page_get_flags(target_ulong address);
 207void page_set_flags(target_ulong start, target_ulong end, int flags);
 208int page_check_range(target_ulong start, target_ulong len, int flags);
 209#endif
 210
 211CPUArchState *cpu_copy(CPUArchState *env);
 212
 213/* Flags for use in ENV->INTERRUPT_PENDING.
 214
 215   The numbers assigned here are non-sequential in order to preserve
 216   binary compatibility with the vmstate dump.  Bit 0 (0x0001) was
 217   previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
 218   the vmstate dump.  */
 219
 220/* External hardware interrupt pending.  This is typically used for
 221   interrupts from devices.  */
 222#define CPU_INTERRUPT_HARD        0x0002
 223
 224/* Exit the current TB.  This is typically used when some system-level device
 225   makes some change to the memory mapping.  E.g. the a20 line change.  */
 226#define CPU_INTERRUPT_EXITTB      0x0004
 227
 228/* Halt the CPU.  */
 229#define CPU_INTERRUPT_HALT        0x0020
 230
 231/* Debug event pending.  */
 232#define CPU_INTERRUPT_DEBUG       0x0080
 233
 234/* Reset signal.  */
 235#define CPU_INTERRUPT_RESET       0x0400
 236
 237/* Several target-specific external hardware interrupts.  Each target/cpu.h
 238   should define proper names based on these defines.  */
 239#define CPU_INTERRUPT_TGT_EXT_0   0x0008
 240#define CPU_INTERRUPT_TGT_EXT_1   0x0010
 241#define CPU_INTERRUPT_TGT_EXT_2   0x0040
 242#define CPU_INTERRUPT_TGT_EXT_3   0x0200
 243#define CPU_INTERRUPT_TGT_EXT_4   0x1000
 244
 245/* Several target-specific internal interrupts.  These differ from the
 246   preceding target-specific interrupts in that they are intended to
 247   originate from within the cpu itself, typically in response to some
 248   instruction being executed.  These, therefore, are not masked while
 249   single-stepping within the debugger.  */
 250#define CPU_INTERRUPT_TGT_INT_0   0x0100
 251#define CPU_INTERRUPT_TGT_INT_1   0x0800
 252#define CPU_INTERRUPT_TGT_INT_2   0x2000
 253
 254/* First unused bit: 0x4000.  */
 255
 256/* The set of all bits that should be masked when single-stepping.  */
 257#define CPU_INTERRUPT_SSTEP_MASK \
 258    (CPU_INTERRUPT_HARD          \
 259     | CPU_INTERRUPT_TGT_EXT_0   \
 260     | CPU_INTERRUPT_TGT_EXT_1   \
 261     | CPU_INTERRUPT_TGT_EXT_2   \
 262     | CPU_INTERRUPT_TGT_EXT_3   \
 263     | CPU_INTERRUPT_TGT_EXT_4)
 264
 265#if !defined(CONFIG_USER_ONLY)
 266
 267/* memory API */
 268
 269typedef struct RAMBlock RAMBlock;
 270
 271struct RAMBlock {
 272    struct rcu_head rcu;
 273    struct MemoryRegion *mr;
 274    uint8_t *host;
 275    ram_addr_t offset;
 276    ram_addr_t used_length;
 277    ram_addr_t max_length;
 278    void (*resized)(const char*, uint64_t length, void *host);
 279    uint32_t flags;
 280    /* Protected by iothread lock.  */
 281    char idstr[256];
 282    /* RCU-enabled, writes protected by the ramlist lock */
 283    QLIST_ENTRY(RAMBlock) next;
 284    int fd;
 285};
 286
 287static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset)
 288{
 289    assert(offset < block->used_length);
 290    assert(block->host);
 291    return (char *)block->host + offset;
 292}
 293
 294typedef struct RAMList {
 295    QemuMutex mutex;
 296    /* Protected by the iothread lock.  */
 297    unsigned long *dirty_memory[DIRTY_MEMORY_NUM];
 298    RAMBlock *mru_block;
 299    /* RCU-enabled, writes protected by the ramlist lock. */
 300    QLIST_HEAD(, RAMBlock) blocks;
 301    uint32_t version;
 302} RAMList;
 303extern RAMList ram_list;
 304
 305/* Flags stored in the low bits of the TLB virtual address.  These are
 306   defined so that fast path ram access is all zeros.  */
 307/* Zero if TLB entry is valid.  */
 308#define TLB_INVALID_MASK   (1 << 3)
 309/* Set if TLB entry references a clean RAM page.  The iotlb entry will
 310   contain the page physical address.  */
 311#define TLB_NOTDIRTY    (1 << 4)
 312/* Set if TLB entry is an IO callback.  */
 313#define TLB_MMIO        (1 << 5)
 314
 315void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 316void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
 317ram_addr_t last_ram_offset(void);
 318void qemu_mutex_lock_ramlist(void);
 319void qemu_mutex_unlock_ramlist(void);
 320#endif /* !CONFIG_USER_ONLY */
 321
 322int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
 323                        uint8_t *buf, int len, int is_write);
 324
 325#endif /* CPU_ALL_H */
 326