mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
QOM CPUState refactorings
* Fix NULL pointer dereference in gdbstub
* Introduce vaddr type
* Introduce CPUClass::set_pc()
* Introduce CPUClass::synchronize_from_tb()
* Introduce CPUClass::get_phys_page_debug()
* Introduce CPUClass::memory_rw_debug()
* Move singlestep_enabled and gdb_regs fields out of CPU_COMMON
* Adopt CPUState in more APIs
* Propagate CPUState in gdbstub
# gpg: Signature made Mon 22 Jul 2013 07:50:17 PM CDT using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found
# By Andreas Färber (21) and others
# Via Andreas Färber
* afaerber/tags/qom-cpu-for-anthony: (24 commits)
linux-user: Use X86CPU property to retrieve CPUID family
gdbstub: Change gdb_register_coprocessor() argument to CPUState
cpu: Move gdb_regs field from CPU_COMMON to CPUState
gdbstub: Change GDBState::{c,g}_cpu and find_cpu() to CPUState
cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug()
exec: Change cpu_memory_rw_debug() argument to CPUState
cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
gdbstub: Change gdb_{read,write}_register() argument to CPUState
gdbstub: Change gdb_handlesig() argument to CPUState
gdbstub: Change syscall callback argument to CPUState
kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState
cpu: Change cpu_single_step() argument to CPUState
gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
target-alpha: Copy implver to DisasContext
target-alpha: Copy singlestep_enabled to DisasContext
cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb()
target-unicore32: Implement CPUClass::set_pc()
target-moxie: Implement CPUClass::set_pc()
target-m68k: Implement CPUClass::set_pc()
...
This commit is contained in:
@@ -40,8 +40,23 @@ speaking, the size of guest memory can always fit into ram_addr_t but
|
||||
it would not be correct to store an actual guest physical address in a
|
||||
ram_addr_t.
|
||||
|
||||
Use target_ulong (or abi_ulong) for CPU virtual addresses, however
|
||||
devices should not need to use target_ulong.
|
||||
For CPU virtual addresses there are several possible types.
|
||||
vaddr is the best type to use to hold a CPU virtual address in
|
||||
target-independent code. It is guaranteed to be large enough to hold a
|
||||
virtual address for any target, and it does not change size from target
|
||||
to target. It is always unsigned.
|
||||
target_ulong is a type the size of a virtual address on the CPU; this means
|
||||
it may be 32 or 64 bits depending on which target is being built. It should
|
||||
therefore be used only in target-specific code, and in some
|
||||
performance-critical built-per-target core code such as the TLB code.
|
||||
There is also a signed version, target_long.
|
||||
abi_ulong is for the *-user targets, and represents a type the size of
|
||||
'void *' in that target's ABI. (This may not be the same as the size of a
|
||||
full CPU virtual address in the case of target ABIs which use 32 bit pointers
|
||||
on 64 bit CPUs, like sparc32plus.) Definitions of structures that must match
|
||||
the target's ABI must use this type for anything that on the target is defined
|
||||
to be an 'unsigned long' or a pointer type.
|
||||
There is also a signed version, abi_long.
|
||||
|
||||
Of course, take all of the above with a grain of salt. If you're about
|
||||
to use some system interface that requires a type like size_t, pid_t or
|
||||
|
||||
+6
-4
@@ -643,7 +643,7 @@ void cpu_loop(CPUSPARCState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
#if 0
|
||||
if (sig)
|
||||
{
|
||||
@@ -738,6 +738,7 @@ int main(int argc, char **argv)
|
||||
struct image_info info1, *info = &info1;
|
||||
TaskState ts1, *ts = &ts1;
|
||||
CPUArchState *env;
|
||||
CPUState *cpu;
|
||||
int optind;
|
||||
const char *r;
|
||||
int gdbstub_port = 0;
|
||||
@@ -912,10 +913,11 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu = ENV_GET_CPU(env);
|
||||
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
cpu_reset(ENV_GET_CPU(env));
|
||||
cpu_reset(cpu);
|
||||
#endif
|
||||
thread_cpu = ENV_GET_CPU(env);
|
||||
thread_cpu = cpu;
|
||||
|
||||
if (getenv("QEMU_STRACE")) {
|
||||
do_strace = 1;
|
||||
@@ -1134,7 +1136,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (gdbstub_port) {
|
||||
gdbserver_start (gdbstub_port);
|
||||
gdb_handlesig(env, 0);
|
||||
gdb_handlesig(cpu, 0);
|
||||
}
|
||||
cpu_loop(env);
|
||||
/* never exits */
|
||||
|
||||
+8
-2
@@ -59,8 +59,14 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
|
||||
* counter hit zero); we must restore the guest PC to the address
|
||||
* of the start of the TB.
|
||||
*/
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
|
||||
cpu_pc_from_tb(env, tb);
|
||||
if (cc->synchronize_from_tb) {
|
||||
cc->synchronize_from_tb(cpu, tb);
|
||||
} else {
|
||||
assert(cc->set_pc);
|
||||
cc->set_pc(cpu, tb->pc);
|
||||
}
|
||||
}
|
||||
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
|
||||
/* We were asked to stop executing TBs (probably a pending
|
||||
@@ -291,7 +297,7 @@ int cpu_exec(CPUArchState *env)
|
||||
for(;;) {
|
||||
interrupt_request = cpu->interrupt_request;
|
||||
if (unlikely(interrupt_request)) {
|
||||
if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
|
||||
if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
|
||||
/* Mask out external interrupts for this step. */
|
||||
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
|
||||
}
|
||||
|
||||
@@ -1186,7 +1186,7 @@ static void tcg_exec_all(void)
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
|
||||
qemu_clock_enable(vm_clock,
|
||||
(env->singlestep_enabled & SSTEP_NOTIMER) == 0);
|
||||
(cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
|
||||
|
||||
if (cpu_can_run(cpu)) {
|
||||
r = tcg_cpu_exec(env);
|
||||
@@ -1285,7 +1285,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
|
||||
{
|
||||
FILE *f;
|
||||
uint32_t l;
|
||||
CPUArchState *env;
|
||||
CPUState *cpu;
|
||||
uint8_t buf[1024];
|
||||
|
||||
@@ -1299,7 +1298,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
|
||||
"a CPU number");
|
||||
return;
|
||||
}
|
||||
env = cpu->env_ptr;
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
@@ -1311,7 +1309,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
|
||||
l = sizeof(buf);
|
||||
if (l > size)
|
||||
l = size;
|
||||
cpu_memory_rw_debug(env, addr, buf, l, 0);
|
||||
cpu_memory_rw_debug(cpu, addr, buf, l, 0);
|
||||
if (fwrite(buf, 1, l, f) != l) {
|
||||
error_set(errp, QERR_IO_ERROR);
|
||||
goto exit;
|
||||
|
||||
@@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr,
|
||||
{
|
||||
CPUDebug *s = container_of(info, CPUDebug, info);
|
||||
|
||||
cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||
if (monitor_disas_is_physical) {
|
||||
cpu_physical_memory_read(memaddr, myaddr, length);
|
||||
} else {
|
||||
cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -415,14 +415,14 @@ void cpu_exec_init(CPUArchState *env)
|
||||
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
|
||||
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||
{
|
||||
tb_invalidate_phys_page_range(pc, pc + 1, 0);
|
||||
}
|
||||
#else
|
||||
static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
|
||||
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||
{
|
||||
tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) |
|
||||
tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) |
|
||||
(pc & ~TARGET_PAGE_MASK));
|
||||
}
|
||||
#endif
|
||||
@@ -525,15 +525,17 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
|
||||
bp->flags = flags;
|
||||
|
||||
/* keep all GDB-injected breakpoints in front */
|
||||
if (flags & BP_GDB)
|
||||
if (flags & BP_GDB) {
|
||||
QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
|
||||
else
|
||||
} else {
|
||||
QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
|
||||
}
|
||||
|
||||
breakpoint_invalidate(env, pc);
|
||||
breakpoint_invalidate(ENV_GET_CPU(env), pc);
|
||||
|
||||
if (breakpoint)
|
||||
if (breakpoint) {
|
||||
*breakpoint = bp;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
@@ -564,7 +566,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
|
||||
|
||||
breakpoint_invalidate(env, breakpoint->pc);
|
||||
breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
|
||||
|
||||
g_free(breakpoint);
|
||||
#endif
|
||||
@@ -585,14 +587,16 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
|
||||
|
||||
/* enable or disable single step mode. EXCP_DEBUG is returned by the
|
||||
CPU loop after each instruction */
|
||||
void cpu_single_step(CPUArchState *env, int enabled)
|
||||
void cpu_single_step(CPUState *cpu, int enabled)
|
||||
{
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
if (env->singlestep_enabled != enabled) {
|
||||
env->singlestep_enabled = enabled;
|
||||
if (kvm_enabled())
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
|
||||
if (cpu->singlestep_enabled != enabled) {
|
||||
cpu->singlestep_enabled = enabled;
|
||||
if (kvm_enabled()) {
|
||||
kvm_update_guest_debug(env, 0);
|
||||
else {
|
||||
} else {
|
||||
/* must flush all the translated code to avoid inconsistencies */
|
||||
/* XXX: only flush what is necessary */
|
||||
tb_flush(env);
|
||||
@@ -1831,7 +1835,7 @@ MemoryRegion *get_system_io(void)
|
||||
|
||||
/* physical memory access (slow version, mainly for debug) */
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
||||
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
uint8_t *buf, int len, int is_write)
|
||||
{
|
||||
int l, flags;
|
||||
@@ -2602,7 +2606,7 @@ void stq_be_phys(hwaddr addr, uint64_t val)
|
||||
}
|
||||
|
||||
/* virtual memory access for debug (includes writing to ROM) */
|
||||
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
||||
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
uint8_t *buf, int len, int is_write)
|
||||
{
|
||||
int l;
|
||||
@@ -2611,7 +2615,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
||||
|
||||
while (len > 0) {
|
||||
page = addr & TARGET_PAGE_MASK;
|
||||
phys_addr = cpu_get_phys_page_debug(env, page);
|
||||
phys_addr = cpu_get_phys_page_debug(cpu, page);
|
||||
/* if no physical page mapped, return an error */
|
||||
if (phys_addr == -1)
|
||||
return -1;
|
||||
|
||||
+41
-37
@@ -146,6 +146,7 @@ static void update_guest_rom_state(VAPICROMState *s)
|
||||
|
||||
static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
|
||||
{
|
||||
CPUState *cs = CPU(x86_env_get_cpu(env));
|
||||
hwaddr paddr;
|
||||
target_ulong addr;
|
||||
|
||||
@@ -158,7 +159,7 @@ static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
|
||||
* virtual address space for the APIC mapping.
|
||||
*/
|
||||
for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
|
||||
paddr = cpu_get_phys_page_debug(env, addr);
|
||||
paddr = cpu_get_phys_page_debug(cs, addr);
|
||||
if (paddr != APIC_DEFAULT_ADDRESS) {
|
||||
continue;
|
||||
}
|
||||
@@ -187,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)
|
||||
modrm_reg(opcode[1]) == instr->modrm_reg);
|
||||
}
|
||||
|
||||
static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||
static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
|
||||
target_ulong *pip, TPRAccess access)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
const TPRInstruction *instr;
|
||||
target_ulong ip = *pip;
|
||||
uint8_t opcode[2];
|
||||
@@ -210,7 +212,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||
* RSP, used by the patched instruction, is zero, so the guest gets a
|
||||
* double fault and dies.
|
||||
*/
|
||||
if (env->regs[R_ESP] == 0) {
|
||||
if (cpu->env.regs[R_ESP] == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -225,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||
if (instr->access != access) {
|
||||
continue;
|
||||
}
|
||||
if (cpu_memory_rw_debug(env, ip - instr->length, opcode,
|
||||
if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,
|
||||
sizeof(opcode), 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -236,7 +238,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) {
|
||||
if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
|
||||
@@ -253,7 +255,7 @@ instruction_ok:
|
||||
* Grab the virtual TPR address from the instruction
|
||||
* and update the cached values.
|
||||
*/
|
||||
if (cpu_memory_rw_debug(env, ip + instr->addr_offset,
|
||||
if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,
|
||||
(void *)&real_tpr_addr,
|
||||
sizeof(real_tpr_addr), 0) < 0) {
|
||||
return -1;
|
||||
@@ -271,6 +273,7 @@ instruction_ok:
|
||||
|
||||
static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
|
||||
{
|
||||
CPUState *cs = CPU(x86_env_get_cpu(env));
|
||||
hwaddr paddr;
|
||||
uint32_t rom_state_vaddr;
|
||||
uint32_t pos, patch, offset;
|
||||
@@ -287,7 +290,7 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
|
||||
|
||||
/* find out virtual address of the ROM */
|
||||
rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
|
||||
paddr = cpu_get_phys_page_debug(env, rom_state_vaddr);
|
||||
paddr = cpu_get_phys_page_debug(cs, rom_state_vaddr);
|
||||
if (paddr == -1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -332,8 +335,9 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
|
||||
* cannot be accessed or is considered invalid. This also ensures that we are
|
||||
* not patching the wrong guest.
|
||||
*/
|
||||
static int get_kpcr_number(CPUX86State *env)
|
||||
static int get_kpcr_number(X86CPU *cpu)
|
||||
{
|
||||
CPUX86State *env = &cpu->env;
|
||||
struct kpcr {
|
||||
uint8_t fill1[0x1c];
|
||||
uint32_t self;
|
||||
@@ -341,7 +345,7 @@ static int get_kpcr_number(CPUX86State *env)
|
||||
uint8_t number;
|
||||
} QEMU_PACKED kpcr;
|
||||
|
||||
if (cpu_memory_rw_debug(env, env->segs[R_FS].base,
|
||||
if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base,
|
||||
(void *)&kpcr, sizeof(kpcr), 0) < 0 ||
|
||||
kpcr.self != env->segs[R_FS].base) {
|
||||
return -1;
|
||||
@@ -349,9 +353,9 @@ static int get_kpcr_number(CPUX86State *env)
|
||||
return kpcr.number;
|
||||
}
|
||||
|
||||
static int vapic_enable(VAPICROMState *s, CPUX86State *env)
|
||||
static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
|
||||
{
|
||||
int cpu_number = get_kpcr_number(env);
|
||||
int cpu_number = get_kpcr_number(cpu);
|
||||
hwaddr vapic_paddr;
|
||||
static const uint8_t enabled = 1;
|
||||
|
||||
@@ -362,26 +366,26 @@ static int vapic_enable(VAPICROMState *s, CPUX86State *env)
|
||||
(((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
|
||||
cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
|
||||
(void *)&enabled, sizeof(enabled), 1);
|
||||
apic_enable_vapic(env->apic_state, vapic_paddr);
|
||||
apic_enable_vapic(cpu->env.apic_state, vapic_paddr);
|
||||
|
||||
s->state = VAPIC_ACTIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte)
|
||||
static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
|
||||
{
|
||||
cpu_memory_rw_debug(env, addr, &byte, 1, 1);
|
||||
cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
|
||||
}
|
||||
|
||||
static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
|
||||
static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
|
||||
uint32_t target)
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
offset = cpu_to_le32(target - ip - 5);
|
||||
patch_byte(env, ip, 0xe8); /* call near */
|
||||
cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
|
||||
patch_byte(cpu, ip, 0xe8); /* call near */
|
||||
cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
|
||||
}
|
||||
|
||||
static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
||||
@@ -409,32 +413,32 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
||||
|
||||
pause_all_vcpus();
|
||||
|
||||
cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
|
||||
cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
|
||||
|
||||
switch (opcode[0]) {
|
||||
case 0x89: /* mov r32 to r/m32 */
|
||||
patch_byte(env, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
|
||||
patch_call(s, env, ip + 1, handlers->set_tpr);
|
||||
patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
|
||||
patch_call(s, cpu, ip + 1, handlers->set_tpr);
|
||||
break;
|
||||
case 0x8b: /* mov r/m32 to r32 */
|
||||
patch_byte(env, ip, 0x90);
|
||||
patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
|
||||
patch_byte(cpu, ip, 0x90);
|
||||
patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
|
||||
break;
|
||||
case 0xa1: /* mov abs to eax */
|
||||
patch_call(s, env, ip, handlers->get_tpr[0]);
|
||||
patch_call(s, cpu, ip, handlers->get_tpr[0]);
|
||||
break;
|
||||
case 0xa3: /* mov eax to abs */
|
||||
patch_call(s, env, ip, handlers->set_tpr_eax);
|
||||
patch_call(s, cpu, ip, handlers->set_tpr_eax);
|
||||
break;
|
||||
case 0xc7: /* mov imm32, r/m32 (c7/0) */
|
||||
patch_byte(env, ip, 0x68); /* push imm32 */
|
||||
cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0);
|
||||
cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1);
|
||||
patch_call(s, env, ip + 5, handlers->set_tpr);
|
||||
patch_byte(cpu, ip, 0x68); /* push imm32 */
|
||||
cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
|
||||
cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
|
||||
patch_call(s, cpu, ip + 5, handlers->set_tpr);
|
||||
break;
|
||||
case 0xff: /* push r/m32 */
|
||||
patch_byte(env, ip, 0x50); /* push eax */
|
||||
patch_call(s, env, ip + 1, handlers->get_tpr_stack);
|
||||
patch_byte(cpu, ip, 0x50); /* push eax */
|
||||
patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@@ -458,16 +462,16 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
|
||||
if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
|
||||
if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) {
|
||||
if (s->state == VAPIC_ACTIVE) {
|
||||
vapic_enable(s, env);
|
||||
vapic_enable(s, cpu);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (update_rom_mapping(s, env, ip) < 0) {
|
||||
return;
|
||||
}
|
||||
if (vapic_enable(s, env) < 0) {
|
||||
if (vapic_enable(s, cpu) < 0) {
|
||||
return;
|
||||
}
|
||||
patch_instruction(s, cpu, ip);
|
||||
@@ -667,8 +671,8 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
* accurate.
|
||||
*/
|
||||
pause_all_vcpus();
|
||||
patch_byte(env, env->eip - 2, 0x66);
|
||||
patch_byte(env, env->eip - 1, 0x90);
|
||||
patch_byte(cpu, env->eip - 2, 0x66);
|
||||
patch_byte(cpu, env->eip - 1, 0x90);
|
||||
resume_all_vcpus();
|
||||
}
|
||||
|
||||
@@ -681,7 +685,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
if (find_real_tpr_addr(s, env) < 0) {
|
||||
break;
|
||||
}
|
||||
vapic_enable(s, env);
|
||||
vapic_enable(s, cpu);
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
@@ -722,7 +726,7 @@ static void do_vapic_enable(void *data)
|
||||
VAPICROMState *s = data;
|
||||
X86CPU *cpu = X86_CPU(first_cpu);
|
||||
|
||||
vapic_enable(s, &cpu->env);
|
||||
vapic_enable(s, cpu);
|
||||
}
|
||||
|
||||
static int vapic_post_load(void *opaque, int version_id)
|
||||
|
||||
@@ -144,9 +144,11 @@ static void lx60_net_init(MemoryRegion *address_space,
|
||||
memory_region_add_subregion(address_space, buffers, ram);
|
||||
}
|
||||
|
||||
static uint64_t translate_phys_addr(void *env, uint64_t addr)
|
||||
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
|
||||
{
|
||||
return cpu_get_phys_page_debug(env, addr);
|
||||
XtensaCPU *cpu = opaque;
|
||||
|
||||
return cpu_get_phys_page_debug(CPU(cpu), addr);
|
||||
}
|
||||
|
||||
static void lx60_reset(void *opaque)
|
||||
@@ -252,7 +254,7 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
|
||||
}
|
||||
uint64_t elf_entry;
|
||||
uint64_t elf_lowaddr;
|
||||
int success = load_elf(kernel_filename, translate_phys_addr, env,
|
||||
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
|
||||
&elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
|
||||
if (success > 0) {
|
||||
env->pc = elf_entry;
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
#include "exec/memory.h"
|
||||
#include "exec/address-spaces.h"
|
||||
|
||||
static uint64_t translate_phys_addr(void *env, uint64_t addr)
|
||||
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
|
||||
{
|
||||
return cpu_get_phys_page_debug(env, addr);
|
||||
XtensaCPU *cpu = opaque;
|
||||
|
||||
return cpu_get_phys_page_debug(CPU(cpu), addr);
|
||||
}
|
||||
|
||||
static void sim_reset(void *opaque)
|
||||
@@ -88,10 +90,10 @@ static void xtensa_sim_init(QEMUMachineInitArgs *args)
|
||||
uint64_t elf_entry;
|
||||
uint64_t elf_lowaddr;
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
int success = load_elf(kernel_filename, translate_phys_addr, env,
|
||||
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
|
||||
&elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
|
||||
#else
|
||||
int success = load_elf(kernel_filename, translate_phys_addr, env,
|
||||
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
|
||||
&elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0);
|
||||
#endif
|
||||
if (success > 0) {
|
||||
|
||||
+2
-12
@@ -22,6 +22,7 @@
|
||||
#include "qemu-common.h"
|
||||
#include "exec/cpu-common.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "qom/cpu.h"
|
||||
|
||||
/* some important defines:
|
||||
*
|
||||
@@ -428,19 +429,8 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
|
||||
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
|
||||
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
|
||||
|
||||
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
|
||||
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
|
||||
#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
|
||||
|
||||
void cpu_single_step(CPUArchState *env, int enabled);
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
||||
/* Return the physical page corresponding to a virtual one. Use it
|
||||
only for debugging because no protection checks are done. Return -1
|
||||
if no page found. */
|
||||
hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
|
||||
|
||||
/* memory API */
|
||||
|
||||
extern ram_addr_t ram_size;
|
||||
@@ -494,7 +484,7 @@ void qemu_mutex_lock_ramlist(void);
|
||||
void qemu_mutex_unlock_ramlist(void);
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
||||
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
uint8_t *buf, int len, int is_write);
|
||||
|
||||
#endif /* CPU_ALL_H */
|
||||
|
||||
@@ -170,13 +170,10 @@ typedef struct CPUWatchpoint {
|
||||
/* from this point: preserved by CPU reset */ \
|
||||
/* ice debug support */ \
|
||||
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
|
||||
int singlestep_enabled; \
|
||||
\
|
||||
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
|
||||
CPUWatchpoint *watchpoint_hit; \
|
||||
\
|
||||
struct GDBRegisterState *gdb_regs; \
|
||||
\
|
||||
/* Core interrupt code */ \
|
||||
sigjmp_buf jmp_env; \
|
||||
int exception_index; \
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define GDB_WATCHPOINT_ACCESS 4
|
||||
|
||||
#ifdef NEED_CPU_H
|
||||
typedef void (*gdb_syscall_complete_cb)(CPUArchState *env,
|
||||
typedef void (*gdb_syscall_complete_cb)(CPUState *cpu,
|
||||
target_ulong ret, target_ulong err);
|
||||
|
||||
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
|
||||
@@ -20,13 +20,13 @@ void gdb_set_stop_cpu(CPUState *cpu);
|
||||
void gdb_exit(CPUArchState *, int);
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
int gdb_queuesig (void);
|
||||
int gdb_handlesig (CPUArchState *, int);
|
||||
int gdb_handlesig(CPUState *, int);
|
||||
void gdb_signalled(CPUArchState *, int);
|
||||
void gdbserver_fork(CPUArchState *);
|
||||
#endif
|
||||
/* Get or set a register. Returns the size of the register. */
|
||||
typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
|
||||
void gdb_register_coprocessor(CPUArchState *env,
|
||||
void gdb_register_coprocessor(CPUState *cpu,
|
||||
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
|
||||
int num_regs, const char *xml, int g_pos);
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
|
||||
return tswap32(val);
|
||||
}
|
||||
static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
cpu_memory_rw_debug(env, addr, &val, 1, 0);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
||||
static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
|
||||
{
|
||||
val = tswap32(val);
|
||||
cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
|
||||
}
|
||||
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
|
||||
#define put_user_ual(arg, p) put_user_u32(arg, p)
|
||||
@@ -42,8 +42,9 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
|
||||
uint8_t *p;
|
||||
/* TODO: Make this something that isn't fixed size. */
|
||||
p = malloc(len);
|
||||
if (p && copy)
|
||||
cpu_memory_rw_debug(env, addr, p, len, 0);
|
||||
if (p && copy) {
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
|
||||
@@ -58,7 +59,7 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
cpu_memory_rw_debug(env, addr, &c, 1, 0);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0);
|
||||
addr++;
|
||||
*(p++) = c;
|
||||
} while (c);
|
||||
@@ -68,8 +69,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
|
||||
static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
|
||||
target_ulong len)
|
||||
{
|
||||
if (len)
|
||||
cpu_memory_rw_debug(env, addr, p, len, 1);
|
||||
if (len) {
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
|
||||
|
||||
+60
-53
@@ -29,6 +29,18 @@
|
||||
|
||||
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
|
||||
|
||||
/**
|
||||
* vaddr:
|
||||
* Type wide enough to contain any #target_ulong virtual address.
|
||||
*/
|
||||
typedef uint64_t vaddr;
|
||||
#define VADDR_PRId PRId64
|
||||
#define VADDR_PRIu PRIu64
|
||||
#define VADDR_PRIo PRIo64
|
||||
#define VADDR_PRIx PRIx64
|
||||
#define VADDR_PRIX PRIX64
|
||||
#define VADDR_MAX UINT64_MAX
|
||||
|
||||
/**
|
||||
* SECTION:cpu
|
||||
* @section_id: QEMU-cpu
|
||||
@@ -48,6 +60,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
|
||||
bool is_write, bool is_exec, int opaque,
|
||||
unsigned size);
|
||||
|
||||
struct TranslationBlock;
|
||||
|
||||
/**
|
||||
* CPUClass:
|
||||
* @class_by_name: Callback to map -cpu command line model name to an
|
||||
@@ -56,11 +70,16 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
|
||||
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
||||
* @do_interrupt: Callback for interrupt handling.
|
||||
* @do_unassigned_access: Callback for unassigned access handling.
|
||||
* @memory_rw_debug: Callback for GDB memory access.
|
||||
* @dump_state: Callback for dumping state.
|
||||
* @dump_statistics: Callback for dumping statistics.
|
||||
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
|
||||
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
|
||||
* @get_memory_mapping: Callback for obtaining the memory mappings.
|
||||
* @set_pc: Callback for setting the Program Counter register.
|
||||
* @synchronize_from_tb: Callback for synchronizing state from a TCG
|
||||
* #TranslationBlock.
|
||||
* @get_phys_page_debug: Callback for obtaining a physical address.
|
||||
* @vmsd: State description for migration.
|
||||
*
|
||||
* Represents a CPU family or model.
|
||||
@@ -76,6 +95,8 @@ typedef struct CPUClass {
|
||||
int reset_dump_flags;
|
||||
void (*do_interrupt)(CPUState *cpu);
|
||||
CPUUnassignedAccess do_unassigned_access;
|
||||
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
|
||||
uint8_t *buf, int len, bool is_write);
|
||||
void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||
int flags);
|
||||
void (*dump_statistics)(CPUState *cpu, FILE *f,
|
||||
@@ -84,6 +105,9 @@ typedef struct CPUClass {
|
||||
bool (*get_paging_enabled)(const CPUState *cpu);
|
||||
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
|
||||
Error **errp);
|
||||
void (*set_pc)(CPUState *cpu, vaddr value);
|
||||
void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
|
||||
hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
|
||||
|
||||
const struct VMStateDescription *vmsd;
|
||||
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
@@ -114,8 +138,10 @@ struct kvm_run;
|
||||
* @stopped: Indicates the CPU has been artificially stopped.
|
||||
* @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
|
||||
* CPU and return to its top level loop.
|
||||
* @singlestep_enabled: Flags for single-stepping.
|
||||
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
||||
* @current_tb: Currently executing TB.
|
||||
* @gdb_regs: Additional GDB registers.
|
||||
* @next_cpu: Next CPU sharing TB cache.
|
||||
* @kvm_fd: vCPU file descriptor for KVM.
|
||||
*
|
||||
@@ -146,9 +172,11 @@ struct CPUState {
|
||||
volatile sig_atomic_t exit_request;
|
||||
volatile sig_atomic_t tcg_exit_req;
|
||||
uint32_t interrupt_request;
|
||||
int singlestep_enabled;
|
||||
|
||||
void *env_ptr; /* CPUArchState */
|
||||
struct TranslationBlock *current_tb;
|
||||
struct GDBRegisterState *gdb_regs;
|
||||
CPUState *next_cpu;
|
||||
|
||||
int kvm_fd;
|
||||
@@ -259,6 +287,25 @@ void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||
void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||
int flags);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/**
|
||||
* cpu_get_phys_page_debug:
|
||||
* @cpu: The CPU to obtain the physical page address for.
|
||||
* @addr: The virtual address.
|
||||
*
|
||||
* Obtains the physical page corresponding to a virtual one.
|
||||
* Use it only for debugging because no protection checks are done.
|
||||
*
|
||||
* Returns: Corresponding physical page address or -1 if no page found.
|
||||
*/
|
||||
static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
return cc->get_phys_page_debug(cpu, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpu_reset:
|
||||
* @cpu: The CPU whose state is to be reset.
|
||||
@@ -276,59 +323,6 @@ void cpu_reset(CPUState *cpu);
|
||||
*/
|
||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
|
||||
|
||||
/**
|
||||
* cpu_class_set_vmsd:
|
||||
* @cc: CPU class
|
||||
* @value: Value to set. Unused for %CONFIG_USER_ONLY.
|
||||
*
|
||||
* Sets #VMStateDescription for @cc.
|
||||
*
|
||||
* The @value argument is intentionally discarded for the non-softmmu targets
|
||||
* to avoid linker errors or excessive preprocessor usage. If this behavior
|
||||
* is undesired, you should assign #CPUClass.vmsd directly instead.
|
||||
*/
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static inline void cpu_class_set_vmsd(CPUClass *cc,
|
||||
const struct VMStateDescription *value)
|
||||
{
|
||||
cc->vmsd = value;
|
||||
}
|
||||
#else
|
||||
#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static inline void cpu_class_set_do_unassigned_access(CPUClass *cc,
|
||||
CPUUnassignedAccess value)
|
||||
{
|
||||
cc->do_unassigned_access = value;
|
||||
}
|
||||
#else
|
||||
#define cpu_class_set_do_unassigned_access(cc, value) \
|
||||
((cc)->do_unassigned_access = NULL)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* device_class_set_vmsd:
|
||||
* @dc: Device class
|
||||
* @value: Value to set. Unused for %CONFIG_USER_ONLY.
|
||||
*
|
||||
* Sets #VMStateDescription for @dc.
|
||||
*
|
||||
* The @value argument is intentionally discarded for the non-softmmu targets
|
||||
* to avoid linker errors or excessive preprocessor usage. If this behavior
|
||||
* is undesired, you should assign #DeviceClass.vmsd directly instead.
|
||||
*/
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static inline void device_class_set_vmsd(DeviceClass *dc,
|
||||
const struct VMStateDescription *value)
|
||||
{
|
||||
dc->vmsd = value;
|
||||
}
|
||||
#else
|
||||
#define device_class_set_vmsd(dc, value) ((dc)->vmsd = NULL)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* qemu_cpu_has_work:
|
||||
* @cpu: The vCPU to check.
|
||||
@@ -489,6 +483,19 @@ void cpu_resume(CPUState *cpu);
|
||||
*/
|
||||
void qemu_init_vcpu(CPUState *cpu);
|
||||
|
||||
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
|
||||
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
|
||||
#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
|
||||
|
||||
/**
|
||||
* cpu_single_step:
|
||||
* @cpu: CPU to the flags for.
|
||||
* @enabled: Flags to enable.
|
||||
*
|
||||
* Enables or disables single-stepping for @cpu.
|
||||
*/
|
||||
void cpu_single_step(CPUState *cpu, int enabled);
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
extern const struct VMStateDescription vmstate_cpu_common;
|
||||
#else
|
||||
|
||||
@@ -169,9 +169,9 @@ void *kvm_arch_ram_alloc(ram_addr_t size);
|
||||
void kvm_setup_guest_memory(void *start, size_t size);
|
||||
void kvm_flush_coalesced_mmio_buffer(void);
|
||||
|
||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type);
|
||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type);
|
||||
void kvm_remove_all_breakpoints(CPUState *cpu);
|
||||
int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
|
||||
|
||||
@@ -1890,7 +1890,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||
|
||||
data.dbg.control = reinject_trap;
|
||||
|
||||
if (env->singlestep_enabled) {
|
||||
if (cpu->singlestep_enabled) {
|
||||
data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
|
||||
}
|
||||
kvm_arch_update_guest_debug(cpu, &data.dbg);
|
||||
@@ -1900,10 +1900,9 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||
return data.err;
|
||||
}
|
||||
|
||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
struct kvm_sw_breakpoint *bp;
|
||||
int err;
|
||||
|
||||
@@ -1946,10 +1945,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
struct kvm_sw_breakpoint *bp;
|
||||
int err;
|
||||
|
||||
@@ -2022,13 +2020,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
||||
+2
-2
@@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
||||
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
target_ulong len, int type)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
||||
@@ -55,12 +55,14 @@ const char *cpu_to_uname_machine(void *cpu_env)
|
||||
return "x86-64";
|
||||
#elif defined(TARGET_I386)
|
||||
/* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */
|
||||
uint32_t cpuid_version = ((CPUX86State *)cpu_env)->cpuid_version;
|
||||
int family = ((cpuid_version >> 8) & 0x0f) + ((cpuid_version >> 20) & 0xff);
|
||||
if (family == 4)
|
||||
CPUState *cpu = ENV_GET_CPU((CPUX86State *)cpu_env);
|
||||
int family = object_property_get_int(OBJECT(cpu), "family", NULL);
|
||||
if (family == 4) {
|
||||
return "i486";
|
||||
if (family == 5)
|
||||
}
|
||||
if (family == 5) {
|
||||
return "i586";
|
||||
}
|
||||
return "i686";
|
||||
#else
|
||||
/* default is #define-d in each arch/ subdir */
|
||||
|
||||
+19
-16
@@ -312,6 +312,7 @@ static void set_idt(int n, unsigned int dpl)
|
||||
|
||||
void cpu_loop(CPUX86State *env)
|
||||
{
|
||||
CPUState *cs = CPU(x86_env_get_cpu(env));
|
||||
int trapnr;
|
||||
abi_ulong pc;
|
||||
target_siginfo_t info;
|
||||
@@ -443,7 +444,7 @@ void cpu_loop(CPUX86State *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -875,7 +876,7 @@ void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -966,7 +967,7 @@ void cpu_loop(CPUUniCore32State *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig(env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig) {
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
@@ -1233,7 +1234,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -1764,7 +1765,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig(env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig) {
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
@@ -2315,7 +2316,7 @@ done_syscall:
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -2475,7 +2476,7 @@ void cpu_loop(CPUOpenRISCState *env)
|
||||
break;
|
||||
}
|
||||
if (gdbsig) {
|
||||
gdb_handlesig(env, gdbsig);
|
||||
gdb_handlesig(cs, gdbsig);
|
||||
if (gdbsig != TARGET_SIGTRAP) {
|
||||
exit(1);
|
||||
}
|
||||
@@ -2518,7 +2519,7 @@ void cpu_loop(CPUSH4State *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -2586,7 +2587,7 @@ void cpu_loop(CPUCRISState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -2686,7 +2687,7 @@ void cpu_loop(CPUMBState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -2779,7 +2780,7 @@ void cpu_loop(CPUM68KState *env)
|
||||
{
|
||||
int sig;
|
||||
|
||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig)
|
||||
{
|
||||
info.si_signo = sig;
|
||||
@@ -3006,7 +3007,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||
}
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||
info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (info.si_signo) {
|
||||
env->lock_addr = -1;
|
||||
info.si_errno = 0;
|
||||
@@ -3059,7 +3060,7 @@ void cpu_loop(CPUS390XState *env)
|
||||
break;
|
||||
|
||||
case EXCP_DEBUG:
|
||||
sig = gdb_handlesig(env, TARGET_SIGTRAP);
|
||||
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||
if (sig) {
|
||||
n = TARGET_TRAP_BRKPT;
|
||||
goto do_signal_pc;
|
||||
@@ -3541,6 +3542,7 @@ int main(int argc, char **argv, char **envp)
|
||||
struct linux_binprm bprm;
|
||||
TaskState *ts;
|
||||
CPUArchState *env;
|
||||
CPUState *cpu;
|
||||
int optind;
|
||||
char **target_environ, **wrk;
|
||||
char **target_argv;
|
||||
@@ -3637,11 +3639,12 @@ int main(int argc, char **argv, char **envp)
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu = ENV_GET_CPU(env);
|
||||
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
cpu_reset(ENV_GET_CPU(env));
|
||||
cpu_reset(cpu);
|
||||
#endif
|
||||
|
||||
thread_cpu = ENV_GET_CPU(env);
|
||||
thread_cpu = cpu;
|
||||
|
||||
if (getenv("QEMU_STRACE")) {
|
||||
do_strace = 1;
|
||||
@@ -4076,7 +4079,7 @@ int main(int argc, char **argv, char **envp)
|
||||
gdbstub_port);
|
||||
exit(1);
|
||||
}
|
||||
gdb_handlesig(env, 0);
|
||||
gdb_handlesig(cpu, 0);
|
||||
}
|
||||
cpu_loop(env);
|
||||
/* never exits */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user