2003-08-11 01:35:13 +04:00
|
|
|
/*
|
|
|
|
* common defines for all CPUs
|
2007-09-17 01:08:06 +04:00
|
|
|
*
|
2003-08-11 01:35:13 +04:00
|
|
|
* Copyright (c) 2003 Fabrice Bellard
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2009-07-17 00:47:01 +04:00
|
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
2003-08-11 01:35:13 +04:00
|
|
|
*/
|
|
|
|
#ifndef CPU_DEFS_H
|
|
|
|
#define CPU_DEFS_H
|
|
|
|
|
2007-11-17 20:14:51 +03:00
|
|
|
#ifndef NEED_CPU_H
|
|
|
|
#error cpu.h included from common code
|
|
|
|
#endif
|
|
|
|
|
2003-08-11 01:35:13 +04:00
|
|
|
#include "config.h"
|
|
|
|
#include <setjmp.h>
|
2004-02-17 01:17:43 +03:00
|
|
|
#include <inttypes.h>
|
2009-03-07 00:48:00 +03:00
|
|
|
#include <signal.h>
|
2004-02-17 01:17:43 +03:00
|
|
|
#include "osdep.h"
|
2009-09-12 11:36:22 +04:00
|
|
|
#include "qemu-queue.h"
|
2009-05-19 19:17:58 +04:00
|
|
|
#include "targphys.h"
|
2003-08-11 01:35:13 +04:00
|
|
|
|
2004-01-24 18:26:06 +03:00
|
|
|
#ifndef TARGET_LONG_BITS
|
|
|
|
#error TARGET_LONG_BITS must be defined before including this header
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
|
|
|
|
|
2004-04-26 01:25:15 +04:00
|
|
|
/* target_ulong is the type of a virtual address */
|
2004-01-24 18:26:06 +03:00
|
|
|
#if TARGET_LONG_SIZE == 4
|
|
|
|
typedef int32_t target_long;
|
|
|
|
typedef uint32_t target_ulong;
|
2005-01-04 02:35:10 +03:00
|
|
|
#define TARGET_FMT_lx "%08x"
|
2007-04-04 11:58:14 +04:00
|
|
|
#define TARGET_FMT_ld "%d"
|
2007-09-19 09:46:03 +04:00
|
|
|
#define TARGET_FMT_lu "%u"
|
2004-01-24 18:26:06 +03:00
|
|
|
#elif TARGET_LONG_SIZE == 8
|
|
|
|
typedef int64_t target_long;
|
|
|
|
typedef uint64_t target_ulong;
|
2006-06-25 22:15:32 +04:00
|
|
|
#define TARGET_FMT_lx "%016" PRIx64
|
2007-04-04 11:58:14 +04:00
|
|
|
#define TARGET_FMT_ld "%" PRId64
|
2007-09-19 09:46:03 +04:00
|
|
|
#define TARGET_FMT_lu "%" PRIu64
|
2004-01-24 18:26:06 +03:00
|
|
|
#else
|
|
|
|
#error TARGET_LONG_SIZE undefined
|
|
|
|
#endif
|
|
|
|
|
2004-03-21 20:06:25 +03:00
|
|
|
#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
|
|
|
|
|
2005-07-03 02:09:27 +04:00
|
|
|
#define EXCP_INTERRUPT 0x10000 /* async interruption */
|
|
|
|
#define EXCP_HLT 0x10001 /* hlt instruction reached */
|
|
|
|
#define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */
|
2005-11-24 00:02:53 +03:00
|
|
|
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
|
2003-08-11 01:35:13 +04:00
|
|
|
|
2005-11-20 13:32:34 +03:00
|
|
|
#define TB_JMP_CACHE_BITS 12
|
|
|
|
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
|
|
|
|
|
2006-11-12 23:40:55 +03:00
|
|
|
/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
|
|
|
|
addresses on the same page. The top bits are the same. This allows
|
|
|
|
TLB invalidation to quickly clear a subset of the hash table. */
|
|
|
|
#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2)
|
|
|
|
#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS)
|
|
|
|
#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
|
|
|
|
#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
|
|
|
|
|
2005-11-29 00:19:04 +03:00
|
|
|
#define CPU_TLB_BITS 8
|
|
|
|
#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
|
2003-08-11 01:35:13 +04:00
|
|
|
|
2008-01-31 12:22:27 +03:00
|
|
|
#if TARGET_PHYS_ADDR_BITS == 32 && TARGET_LONG_BITS == 32
|
|
|
|
#define CPU_TLB_ENTRY_BITS 4
|
|
|
|
#else
|
|
|
|
#define CPU_TLB_ENTRY_BITS 5
|
|
|
|
#endif
|
|
|
|
|
2003-08-11 01:35:13 +04:00
|
|
|
typedef struct CPUTLBEntry {
|
2008-06-09 04:20:13 +04:00
|
|
|
/* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
|
|
|
|
bit TARGET_PAGE_BITS-1..4 : Nonzero for accesses that should not
|
|
|
|
go directly to ram.
|
2003-10-28 00:12:17 +03:00
|
|
|
bit 3 : indicates that the entry is invalid
|
|
|
|
bit 2..0 : zero
|
|
|
|
*/
|
2007-09-17 01:08:06 +04:00
|
|
|
target_ulong addr_read;
|
|
|
|
target_ulong addr_write;
|
|
|
|
target_ulong addr_code;
|
2008-06-09 04:20:13 +04:00
|
|
|
/* Addend to virtual address to get physical address. IO accesses
|
2008-11-29 16:33:23 +03:00
|
|
|
use the corresponding iotlb value. */
|
2008-01-31 12:22:27 +03:00
|
|
|
#if TARGET_PHYS_ADDR_BITS == 64
|
|
|
|
/* on i386 Linux make sure it is aligned */
|
2009-10-02 01:12:16 +04:00
|
|
|
target_phys_addr_t addend __attribute__((aligned(8)));
|
2008-01-31 12:22:27 +03:00
|
|
|
#else
|
2009-10-02 01:12:16 +04:00
|
|
|
target_phys_addr_t addend;
|
2008-01-31 12:22:27 +03:00
|
|
|
#endif
|
|
|
|
/* padding to get a power of two size */
|
|
|
|
uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -
|
|
|
|
(sizeof(target_ulong) * 3 +
|
2009-10-02 01:12:16 +04:00
|
|
|
((-sizeof(target_ulong) * 3) & (sizeof(target_phys_addr_t) - 1)) +
|
|
|
|
sizeof(target_phys_addr_t))];
|
2003-08-11 01:35:13 +04:00
|
|
|
} CPUTLBEntry;
|
|
|
|
|
2009-07-27 18:13:06 +04:00
|
|
|
#ifdef HOST_WORDS_BIGENDIAN
|
2008-06-29 05:03:05 +04:00
|
|
|
typedef struct icount_decr_u16 {
|
|
|
|
uint16_t high;
|
|
|
|
uint16_t low;
|
|
|
|
} icount_decr_u16;
|
|
|
|
#else
|
|
|
|
typedef struct icount_decr_u16 {
|
|
|
|
uint16_t low;
|
|
|
|
uint16_t high;
|
|
|
|
} icount_decr_u16;
|
|
|
|
#endif
|
|
|
|
|
2008-11-05 19:04:33 +03:00
|
|
|
struct kvm_run;
|
|
|
|
struct KVMState;
|
|
|
|
|
2008-11-18 23:07:32 +03:00
|
|
|
typedef struct CPUBreakpoint {
|
|
|
|
target_ulong pc;
|
|
|
|
int flags; /* BP_* */
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_ENTRY(CPUBreakpoint) entry;
|
2008-11-18 23:07:32 +03:00
|
|
|
} CPUBreakpoint;
|
|
|
|
|
|
|
|
typedef struct CPUWatchpoint {
|
|
|
|
target_ulong vaddr;
|
|
|
|
target_ulong len_mask;
|
|
|
|
int flags; /* BP_* */
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_ENTRY(CPUWatchpoint) entry;
|
2008-11-18 23:07:32 +03:00
|
|
|
} CPUWatchpoint;
|
|
|
|
|
2008-04-08 23:29:54 +04:00
|
|
|
#define CPU_TEMP_BUF_NLONGS 128
|
2005-11-20 13:32:34 +03:00
|
|
|
#define CPU_COMMON \
|
|
|
|
struct TranslationBlock *current_tb; /* currently executing TB */ \
|
|
|
|
/* soft mmu support */ \
|
2008-06-29 05:03:05 +04:00
|
|
|
/* in order to avoid passing too many arguments to the MMIO \
|
|
|
|
helpers, we store some rarely used information in the CPU \
|
2005-11-20 13:32:34 +03:00
|
|
|
context) */ \
|
2008-06-29 05:03:05 +04:00
|
|
|
unsigned long mem_io_pc; /* host pc at which the memory was \
|
|
|
|
accessed */ \
|
|
|
|
target_ulong mem_io_vaddr; /* target virtual addr at which the \
|
|
|
|
memory was accessed */ \
|
2008-07-02 00:01:19 +04:00
|
|
|
uint32_t halted; /* Nonzero if the CPU is in suspend state */ \
|
2009-04-24 22:04:07 +04:00
|
|
|
uint32_t stop; /* Stop request */ \
|
|
|
|
uint32_t stopped; /* Artificially stopped */ \
|
2008-07-02 00:01:19 +04:00
|
|
|
uint32_t interrupt_request; \
|
2009-03-07 00:48:00 +03:00
|
|
|
volatile sig_atomic_t exit_request; \
|
2007-10-28 22:45:05 +03:00
|
|
|
/* The meaning of the MMU modes is defined in the target code. */ \
|
2007-04-05 10:43:27 +04:00
|
|
|
CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
|
2009-10-02 01:12:16 +04:00
|
|
|
target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \
|
2005-11-20 13:32:34 +03:00
|
|
|
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
|
2008-04-08 23:29:54 +04:00
|
|
|
/* buffer for temporaries in the code generator */ \
|
|
|
|
long temp_buf[CPU_TEMP_BUF_NLONGS]; \
|
2005-11-20 13:32:34 +03:00
|
|
|
\
|
2008-06-29 05:03:05 +04:00
|
|
|
int64_t icount_extra; /* Instructions until next timer event. */ \
|
|
|
|
/* Number of cycles left, with interrupt flag in high bit. \
|
|
|
|
This allows a single read-compare-cbranch-write sequence to test \
|
|
|
|
for both decrementer underflow and exceptions. */ \
|
|
|
|
union { \
|
|
|
|
uint32_t u32; \
|
|
|
|
icount_decr_u16 u16; \
|
|
|
|
} icount_decr; \
|
|
|
|
uint32_t can_do_io; /* nonzero if memory mapped IO is safe. */ \
|
|
|
|
\
|
2005-11-20 13:32:34 +03:00
|
|
|
/* from this point: preserved by CPU reset */ \
|
|
|
|
/* ice debug support */ \
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
|
2005-11-20 13:32:34 +03:00
|
|
|
int singlestep_enabled; \
|
|
|
|
\
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
|
2008-11-18 23:07:32 +03:00
|
|
|
CPUWatchpoint *watchpoint_hit; \
|
2008-10-11 21:55:29 +04:00
|
|
|
\
|
|
|
|
struct GDBRegisterState *gdb_regs; \
|
2007-03-17 02:58:11 +03:00
|
|
|
\
|
2008-05-29 14:08:06 +04:00
|
|
|
/* Core interrupt code */ \
|
|
|
|
jmp_buf jmp_env; \
|
2009-12-08 19:54:55 +03:00
|
|
|
int32_t exception_index; \
|
2008-05-29 14:08:06 +04:00
|
|
|
\
|
2009-03-07 18:24:59 +03:00
|
|
|
CPUState *next_cpu; /* next CPU sharing TB cache */ \
|
2005-11-22 02:25:50 +03:00
|
|
|
int cpu_index; /* CPU index (informative) */ \
|
2009-06-03 22:33:08 +04:00
|
|
|
uint32_t host_tid; /* host thread ID */ \
|
2009-04-22 02:30:27 +04:00
|
|
|
int numa_node; /* NUMA node this cpu is belonging to */ \
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 17:42:40 +04:00
|
|
|
int nr_cores; /* number of cores within this CPU package */ \
|
|
|
|
int nr_threads;/* number of threads within this CPU */ \
|
2008-06-08 00:50:51 +04:00
|
|
|
int running; /* Nonzero if cpu is currently running(usermode). */ \
|
2005-11-20 13:32:34 +03:00
|
|
|
/* user data */ \
|
2007-12-09 05:22:57 +03:00
|
|
|
void *opaque; \
|
|
|
|
\
|
2009-04-24 22:04:07 +04:00
|
|
|
uint32_t created; \
|
|
|
|
struct QemuThread *thread; \
|
|
|
|
struct QemuCond *halt_cond; \
|
2008-11-05 19:04:33 +03:00
|
|
|
const char *cpu_model_str; \
|
|
|
|
struct KVMState *kvm_state; \
|
|
|
|
struct kvm_run *kvm_run; \
|
|
|
|
int kvm_fd;
|
2005-11-20 13:32:34 +03:00
|
|
|
|
2003-08-11 01:35:13 +04:00
|
|
|
#endif
|