From 52f34623b499cb0273118b1f637c2c6ebaf5d5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 13:44:40 +0200 Subject: [PATCH 01/24] gdbstub: Change GDBState::query_cpu to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since first_cpu/next_cpu are CPUState, CPUArchState is no longer needed. This resolves a NULL pointer dereference of query_cpu, introduced with commit 182735efaf956ccab50b6d74a4fed163e0f35660 and reported by TeLeMan and Max Filippov. Reviewed-by: Richard Henderson Signed-off-by: Andreas Färber --- gdbstub.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 0ee82a944f..bdba19b404 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -289,7 +289,7 @@ enum RSState { typedef struct GDBState { CPUArchState *c_cpu; /* current CPU for step/continue ops */ CPUArchState *g_cpu; /* current CPU for other ops */ - CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */ + CPUState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ char line_buf[MAX_PACKET_LENGTH]; int line_buf_index; @@ -2401,15 +2401,14 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "QC1"); break; } else if (strcmp(p,"fThreadInfo") == 0) { - s->query_cpu = first_cpu->env_ptr; + s->query_cpu = first_cpu; goto report_cpuinfo; } else if (strcmp(p,"sThreadInfo") == 0) { report_cpuinfo: if (s->query_cpu) { - snprintf(buf, sizeof(buf), "m%x", - cpu_index(ENV_GET_CPU(s->query_cpu))); + snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu)); put_packet(s, buf); - s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr; + s->query_cpu = s->query_cpu->next_cpu; } else put_packet(s, "l"); break; From 577f42c0e11a5bfb462ff3a217701cd5c4356fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 6 Jul 2013 03:14:52 +0200 Subject: [PATCH 02/24] cpu: Introduce vaddr type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vaddr is to target_ulong what uintmax_t is to unsigned int. Its purpose is to allow turning per-target functions with target_ulong arguments into CPUClass hooks. Suggested-by: Peter Maydell Signed-off-by: Andreas Färber --- include/qom/cpu.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index dfd81a1d2f..829fd4554f 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -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 From 2be8d4509896116dae7b3b9dffc0fccef480126d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 22 Jul 2013 18:34:35 +0200 Subject: [PATCH 03/24] HACKING: Document vaddr type usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also extend documentation of target_ulong and abi_ulong. Signed-off-by: Peter Maydell Signed-off-by: Andreas Färber --- HACKING | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/HACKING b/HACKING index e73ac79fe9..12fbc8afe4 100644 --- a/HACKING +++ b/HACKING @@ -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 From f45748f10eda61d6262153fadf3910cb63e17ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 21 Jun 2013 19:09:18 +0200 Subject: [PATCH 04/24] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves setting the Program Counter from gdbstub into target code. Use vaddr type as upper-bound replacement for target_ulong. Signed-off-by: Andreas Färber --- gdbstub.c | 39 ++++++------------------------------- include/qom/cpu.h | 2 ++ target-alpha/cpu.c | 8 ++++++++ target-arm/cpu.c | 8 ++++++++ target-cris/cpu.c | 8 ++++++++ target-i386/cpu.c | 8 ++++++++ target-lm32/cpu.c | 8 ++++++++ target-microblaze/cpu.c | 8 ++++++++ target-mips/cpu.c | 14 +++++++++++++ target-openrisc/cpu.c | 8 ++++++++ target-ppc/translate_init.c | 8 ++++++++ target-s390x/cpu.c | 8 ++++++++ target-sh4/cpu.c | 8 ++++++++ target-sparc/cpu.c | 9 +++++++++ target-xtensa/cpu.c | 8 ++++++++ 15 files changed, 119 insertions(+), 33 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index bdba19b404..55d4756da7 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2042,40 +2042,13 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { - cpu_synchronize_state(ENV_GET_CPU(s->c_cpu)); -#if defined(TARGET_I386) - s->c_cpu->eip = pc; -#elif defined (TARGET_PPC) - s->c_cpu->nip = pc; -#elif defined (TARGET_SPARC) - s->c_cpu->pc = pc; - s->c_cpu->npc = pc + 4; -#elif defined (TARGET_ARM) - s->c_cpu->regs[15] = pc; -#elif defined (TARGET_SH4) - s->c_cpu->pc = pc; -#elif defined (TARGET_MIPS) - s->c_cpu->active_tc.PC = pc & ~(target_ulong)1; - if (pc & 1) { - s->c_cpu->hflags |= MIPS_HFLAG_M16; - } else { - s->c_cpu->hflags &= ~(MIPS_HFLAG_M16); + CPUState *cpu = ENV_GET_CPU(s->c_cpu); + CPUClass *cc = CPU_GET_CLASS(cpu); + + cpu_synchronize_state(cpu); + if (cc->set_pc) { + cc->set_pc(cpu, pc); } -#elif defined (TARGET_MICROBLAZE) - s->c_cpu->sregs[SR_PC] = pc; -#elif defined(TARGET_OPENRISC) - s->c_cpu->pc = pc; -#elif defined (TARGET_CRIS) - s->c_cpu->pc = pc; -#elif defined (TARGET_ALPHA) - s->c_cpu->pc = pc; -#elif defined (TARGET_S390X) - s->c_cpu->psw.addr = pc; -#elif defined (TARGET_LM32) - s->c_cpu->pc = pc; -#elif defined(TARGET_XTENSA) - s->c_cpu->pc = pc; -#endif } static CPUArchState *find_cpu(uint32_t thread_id) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 829fd4554f..4620fee540 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -73,6 +73,7 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, * @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. * @vmsd: State description for migration. * * Represents a CPU family or model. @@ -96,6 +97,7 @@ 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); const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 26708055d9..09bb7a8876 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -24,6 +24,13 @@ #include "migration/vmstate.h" +static void alpha_cpu_set_pc(CPUState *cs, vaddr value) +{ + AlphaCPU *cpu = ALPHA_CPU(cs); + + cpu->env.pc = value; +} + static void alpha_cpu_realizefn(DeviceState *dev, Error **errp) { AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev); @@ -264,6 +271,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = alpha_cpu_do_interrupt; cc->dump_state = alpha_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access); + cc->set_pc = alpha_cpu_set_pc; device_class_set_vmsd(dc, &vmstate_alpha_cpu); } diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 9f1696f933..082bc12831 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -25,6 +25,13 @@ #endif #include "sysemu/sysemu.h" +static void arm_cpu_set_pc(CPUState *cs, vaddr value) +{ + ARMCPU *cpu = ARM_CPU(cs); + + cpu->env.regs[15] = value; +} + static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) { /* Reset a single ARMCPRegInfo register */ @@ -816,6 +823,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = arm_cpu_class_by_name; cc->do_interrupt = arm_cpu_do_interrupt; cc->dump_state = arm_cpu_dump_state; + cc->set_pc = arm_cpu_set_pc; cpu_class_set_vmsd(cc, &vmstate_arm_cpu); } diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 2abb57fc23..b72fd98ab8 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -26,6 +26,13 @@ #include "mmu.h" +static void cris_cpu_set_pc(CPUState *cs, vaddr value) +{ + CRISCPU *cpu = CRIS_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void cris_cpu_reset(CPUState *s) { @@ -247,6 +254,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = cris_cpu_class_by_name; cc->do_interrupt = cris_cpu_do_interrupt; cc->dump_state = cris_cpu_dump_state; + cc->set_pc = cris_cpu_set_pc; } static const TypeInfo cris_cpu_type_info = { diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e3f75a81a7..67b095d17f 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2506,6 +2506,13 @@ static bool x86_cpu_get_paging_enabled(const CPUState *cs) return cpu->env.cr[0] & CR0_PG_MASK; } +static void x86_cpu_set_pc(CPUState *cs, vaddr value) +{ + X86CPU *cpu = X86_CPU(cs); + + cpu->env.eip = value; +} + static void x86_cpu_common_class_init(ObjectClass *oc, void *data) { X86CPUClass *xcc = X86_CPU_CLASS(oc); @@ -2522,6 +2529,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->do_interrupt = x86_cpu_do_interrupt; cc->dump_state = x86_cpu_dump_state; + cc->set_pc = x86_cpu_set_pc; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifndef CONFIG_USER_ONLY diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 04327acc05..8aa28b59d4 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -22,6 +22,13 @@ #include "qemu-common.h" +static void lm32_cpu_set_pc(CPUState *cs, vaddr value) +{ + LM32CPU *cpu = LM32_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void lm32_cpu_reset(CPUState *s) { @@ -79,6 +86,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = lm32_cpu_do_interrupt; cc->dump_state = lm32_cpu_dump_state; + cc->set_pc = lm32_cpu_set_pc; cpu_class_set_vmsd(cc, &vmstate_lm32_cpu); } diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index dce1c7ea67..0a9bcfa556 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -26,6 +26,13 @@ #include "migration/vmstate.h" +static void mb_cpu_set_pc(CPUState *cs, vaddr value) +{ + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + + cpu->env.sregs[SR_PC] = value; +} + /* CPUClass::reset() */ static void mb_cpu_reset(CPUState *s) { @@ -134,6 +141,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = mb_cpu_do_interrupt; cc->dump_state = mb_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access); + cc->set_pc = mb_cpu_set_pc; dc->vmsd = &vmstate_mb_cpu; dc->props = mb_properties; } diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 60a3faf2f8..6ec3d252e5 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -22,6 +22,19 @@ #include "qemu-common.h" +static void mips_cpu_set_pc(CPUState *cs, vaddr value) +{ + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + + env->active_tc.PC = value & ~(target_ulong)1; + if (value & 1) { + env->hflags |= MIPS_HFLAG_M16; + } else { + env->hflags &= ~(MIPS_HFLAG_M16); + } +} + /* CPUClass::reset() */ static void mips_cpu_reset(CPUState *s) { @@ -76,6 +89,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->do_interrupt = mips_cpu_do_interrupt; cc->dump_state = mips_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access); + cc->set_pc = mips_cpu_set_pc; } static const TypeInfo mips_cpu_type_info = { diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 6d40f1b85e..27ee9f415c 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -20,6 +20,13 @@ #include "cpu.h" #include "qemu-common.h" +static void openrisc_cpu_set_pc(CPUState *cs, vaddr value) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void openrisc_cpu_reset(CPUState *s) { @@ -146,6 +153,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = openrisc_cpu_class_by_name; cc->do_interrupt = openrisc_cpu_do_interrupt; cc->dump_state = openrisc_cpu_dump_state; + cc->set_pc = openrisc_cpu_set_pc; device_class_set_vmsd(dc, &vmstate_openrisc_cpu); } diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 79bfcd8df9..9ed7736b8a 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8322,6 +8322,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) return cpu_list; } +static void ppc_cpu_set_pc(CPUState *cs, vaddr value) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + cpu->env.nip = value; +} + /* CPUClass::reset() */ static void ppc_cpu_reset(CPUState *s) { @@ -8449,6 +8456,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = ppc_cpu_do_interrupt; cc->dump_state = ppc_cpu_dump_state; cc->dump_statistics = ppc_cpu_dump_statistics; + cc->set_pc = ppc_cpu_set_pc; } static const TypeInfo ppc_cpu_type_info = { diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 1ef2fc0e86..fe3cd8ed15 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -58,6 +58,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) } #endif +static void s390_cpu_set_pc(CPUState *cs, vaddr value) +{ + S390CPU *cpu = S390_CPU(cs); + + cpu->env.psw.addr = value; +} + /* CPUClass::reset() */ static void s390_cpu_reset(CPUState *s) { @@ -165,6 +172,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = s390_cpu_do_interrupt; cc->dump_state = s390_cpu_dump_state; + cc->set_pc = s390_cpu_set_pc; dc->vmsd = &vmstate_s390_cpu; } diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 03487eb32e..facbd18d55 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -24,6 +24,13 @@ #include "migration/vmstate.h" +static void superh_cpu_set_pc(CPUState *cs, vaddr value) +{ + SuperHCPU *cpu = SUPERH_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void superh_cpu_reset(CPUState *s) { @@ -269,6 +276,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = superh_cpu_class_by_name; cc->do_interrupt = superh_cpu_do_interrupt; cc->dump_state = superh_cpu_dump_state; + cc->set_pc = superh_cpu_set_pc; dc->vmsd = &vmstate_sh_cpu; } diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 87c3a50c00..88582c6a9b 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -723,6 +723,14 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "\n"); } +static void sparc_cpu_set_pc(CPUState *cs, vaddr value) +{ + SPARCCPU *cpu = SPARC_CPU(cs); + + cpu->env.pc = value; + cpu->env.npc = value + 4; +} + static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) { SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); @@ -767,6 +775,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = sparc_cpu_do_interrupt; cc->dump_state = sparc_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access); + cc->set_pc = sparc_cpu_set_pc; } static const TypeInfo sparc_cpu_type_info = { diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 0488984d4a..e3d742a911 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -33,6 +33,13 @@ #include "migration/vmstate.h" +static void xtensa_cpu_set_pc(CPUState *cs, vaddr value) +{ + XtensaCPU *cpu = XTENSA_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void xtensa_cpu_reset(CPUState *s) { @@ -100,6 +107,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = xtensa_cpu_do_interrupt; cc->dump_state = xtensa_cpu_dump_state; + cc->set_pc = xtensa_cpu_set_pc; dc->vmsd = &vmstate_xtensa_cpu; } From e700604df024ec5028f476b133ca337c4d7ee518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 20:35:01 +0200 Subject: [PATCH 05/24] target-m68k: Implement CPUClass::set_pc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for GDB's c addr (Continue) and s addr (Single Step). Prepares for dropping cpu_pc_from_tb(). Signed-off-by: Andreas Färber --- target-m68k/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 1b6ef664f5..43011e7fe5 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -23,6 +23,13 @@ #include "migration/vmstate.h" +static void m68k_cpu_set_pc(CPUState *cs, vaddr value) +{ + M68kCPU *cpu = M68K_CPU(cs); + + cpu->env.pc = value; +} + static void m68k_set_feature(CPUM68KState *env, int feature) { env->features |= (1u << feature); @@ -182,6 +189,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->class_by_name = m68k_cpu_class_by_name; cc->do_interrupt = m68k_cpu_do_interrupt; cc->dump_state = m68k_cpu_dump_state; + cc->set_pc = m68k_cpu_set_pc; dc->vmsd = &vmstate_m68k_cpu; } From a10b978c4246bf9af0e34505aba500d3e7f6c6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 20:43:26 +0200 Subject: [PATCH 06/24] target-moxie: Implement CPUClass::set_pc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for GDB's c addr (Continue) and s addr (Single Step). Prepares for dropping cpu_pc_from_tb(). Signed-off-by: Andreas Färber --- target-moxie/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 92ca5946bf..91f61973ab 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -22,6 +22,13 @@ #include "migration/vmstate.h" #include "machine.h" +static void moxie_cpu_set_pc(CPUState *cs, vaddr value) +{ + MoxieCPU *cpu = MOXIE_CPU(cs); + + cpu->env.pc = value; +} + static void moxie_cpu_reset(CPUState *s) { MoxieCPU *cpu = MOXIE_CPU(s); @@ -93,6 +100,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = moxie_cpu_do_interrupt; cc->dump_state = moxie_cpu_dump_state; + cc->set_pc = moxie_cpu_set_pc; cpu_class_set_vmsd(cc, &vmstate_moxie_cpu); } From b42eab27beaefd5c9bf9353383d6403e0628c014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 19:41:07 +0200 Subject: [PATCH 07/24] target-unicore32: Implement CPUClass::set_pc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for GDB's c addr (Continue) and s addr (Single Step). Prepares for dropping cpu_pc_from_tb(). Signed-off-by: Andreas Färber --- target-unicore32/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 6572f0199b..79f22922f2 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -16,6 +16,13 @@ #include "qemu-common.h" #include "migration/vmstate.h" +static void uc32_cpu_set_pc(CPUState *cs, vaddr value) +{ + UniCore32CPU *cpu = UNICORE32_CPU(cs); + + cpu->env.regs[31] = value; +} + static inline void set_feature(CPUUniCore32State *env, int feature) { env->features |= feature; @@ -131,6 +138,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = uc32_cpu_class_by_name; cc->do_interrupt = uc32_cpu_do_interrupt; cc->dump_state = uc32_cpu_dump_state; + cc->set_pc = uc32_cpu_set_pc; dc->vmsd = &vmstate_uc32_cpu; } From bdf7ae5bbdb3f050d97862b2ba0261fa902ebc53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 19:31:32 +0200 Subject: [PATCH 08/24] cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Where no extra implementation is needed, fall back to CPUClass::set_pc(). Acked-by: Michael Walle (for lm32) Signed-off-by: Andreas Färber --- cpu-exec.c | 8 +++++++- include/qom/cpu.h | 5 +++++ target-alpha/cpu.h | 5 ----- target-arm/cpu.h | 5 ----- target-cris/cpu.h | 4 ---- target-i386/cpu.c | 8 ++++++++ target-i386/cpu.h | 5 ----- target-lm32/cpu.h | 5 ----- target-m68k/cpu.h | 5 ----- target-microblaze/cpu.h | 5 ----- target-mips/cpu.c | 11 +++++++++++ target-mips/cpu.h | 7 ------- target-moxie/cpu.h | 5 ----- target-openrisc/cpu.h | 5 ----- target-ppc/cpu.h | 5 ----- target-s390x/cpu.h | 5 ----- target-sh4/cpu.c | 9 +++++++++ target-sh4/cpu.h | 6 ------ target-sparc/cpu.c | 9 +++++++++ target-sparc/cpu.h | 6 ------ target-unicore32/cpu.h | 5 ----- target-xtensa/cpu.h | 5 ----- 22 files changed, 49 insertions(+), 84 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 6c784a7e09..3fccb8617e 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -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 diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 4620fee540..4e5ec77919 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -60,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 @@ -74,6 +76,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, * @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. * @vmsd: State description for migration. * * Represents a CPU family or model. @@ -98,6 +102,7 @@ typedef struct CPUClass { 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); const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 066f0324e2..c85dc6e575 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif /* !defined (__CPU_ALPHA_H__) */ diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c798b272a0..b2dc49413c 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -797,11 +797,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb) -{ - env->regs[15] = tb->pc; -} - /* Load an instruction and return it in the standard little-endian order */ static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr, bool do_swap) diff --git a/target-cris/cpu.h b/target-cris/cpu.h index c12a8caea1..4b9fc4cb45 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 67b095d17f..b57ea4b6f2 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2513,6 +2513,13 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.eip = value; } +static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + X86CPU *cpu = X86_CPU(cs); + + cpu->env.eip = tb->pc - tb->cs_base; +} + static void x86_cpu_common_class_init(ObjectClass *oc, void *data) { X86CPUClass *xcc = X86_CPU_CLASS(oc); @@ -2530,6 +2537,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->do_interrupt = x86_cpu_do_interrupt; cc->dump_state = x86_cpu_dump_state; cc->set_pc = x86_cpu_set_pc; + cc->synchronize_from_tb = x86_cpu_synchronize_from_tb; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifndef CONFIG_USER_ONLY diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2d005b3ce9..cedefdc423 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1148,11 +1148,6 @@ static inline bool cpu_has_work(CPUState *cs) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb) -{ - env->eip = tb->pc - tb->cs_base; -} - static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc, target_ulong *cs_base, int *flags) { diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 856bdc745c..dbfe043551 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -232,9 +232,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPULM32State *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 9fdf89ef91..cfd6846347 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -260,9 +260,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 6c35475fd6..7508cf5a06 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -365,9 +365,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUMBState *env, TranslationBlock *tb) -{ - env->sregs[SR_PC] = tb->pc; -} - #endif diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 6ec3d252e5..1581cd976e 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -35,6 +35,16 @@ static void mips_cpu_set_pc(CPUState *cs, vaddr value) } } +static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + + env->active_tc.PC = tb->pc; + env->hflags &= ~MIPS_HFLAG_BMASK; + env->hflags |= tb->flags & MIPS_HFLAG_BMASK; +} + /* CPUClass::reset() */ static void mips_cpu_reset(CPUState *s) { @@ -90,6 +100,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->dump_state = mips_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access); cc->set_pc = mips_cpu_set_pc; + cc->synchronize_from_tb = mips_cpu_synchronize_from_tb; } static const TypeInfo mips_cpu_type_info = { diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 7ffd2e36bd..a29c82faf1 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -732,13 +732,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb) -{ - env->active_tc.PC = tb->pc; - env->hflags &= ~MIPS_HFLAG_BMASK; - env->hflags |= tb->flags & MIPS_HFLAG_BMASK; -} - static inline void compute_hflags(CPUMIPSState *env) { env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h index 72d02c20c1..d5030a4c34 100644 --- a/target-moxie/cpu.h +++ b/target-moxie/cpu.h @@ -143,11 +143,6 @@ static inline int cpu_mmu_index(CPUMoxieState *env) #include "exec/cpu-all.h" #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUMoxieState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 0aff8f20c7..82bfd03ec1 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -428,9 +428,4 @@ static inline target_ulong cpu_get_pc(CPUOpenRISCState *env) return env->pc; } -static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif /* CPU_OPENRISC_H */ diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 7a7b1bf35a..6f51e1f526 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2144,11 +2144,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb) -{ - env->nip = tb->pc; -} - void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env); #endif /* !defined (__CPU_PPC_H__) */ diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 646268858b..65bef8625f 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -1041,11 +1041,6 @@ static inline bool cpu_has_work(CPUState *cpu) (env->psw.mask & PSW_MASK_EXT); } -static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb) -{ - env->psw.addr = tb->pc; -} - /* fpu_helper.c */ uint32_t set_cc_nz_f32(float32 v); uint32_t set_cc_nz_f64(float64 v); diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index facbd18d55..03dedc179e 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -31,6 +31,14 @@ static void superh_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.pc = value; } +static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + SuperHCPU *cpu = SUPERH_CPU(cs); + + cpu->env.pc = tb->pc; + cpu->env.flags = tb->flags; +} + /* CPUClass::reset() */ static void superh_cpu_reset(CPUState *s) { @@ -277,6 +285,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = superh_cpu_do_interrupt; cc->dump_state = superh_cpu_dump_state; cc->set_pc = superh_cpu_set_pc; + cc->synchronize_from_tb = superh_cpu_synchronize_from_tb; dc->vmsd = &vmstate_sh_cpu; } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index c8df18bab1..276d2955c3 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -359,10 +359,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUSH4State *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->flags = tb->flags; -} - #endif /* _CPU_SH4_H */ diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 88582c6a9b..a2deba5a06 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -731,6 +731,14 @@ static void sparc_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.npc = value + 4; } +static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + SPARCCPU *cpu = SPARC_CPU(cs); + + cpu->env.pc = tb->pc; + cpu->env.npc = tb->cs_base; +} + static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) { SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); @@ -776,6 +784,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->dump_state = sparc_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access); cc->set_pc = sparc_cpu_set_pc; + cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; } static const TypeInfo sparc_cpu_type_info = { diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 41b014a0b3..0f35a2216f 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -759,10 +759,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUSPARCState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->npc = tb->cs_base; -} - #endif diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index d4be5252f3..967511e3f6 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -146,11 +146,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env) #include "cpu-qom.h" #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock *tb) -{ - env->regs[31] = tb->pc; -} - static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc, target_ulong *cs_base, int *flags) { diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 6c9fc35dcc..a8f02f6e4b 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -522,9 +522,4 @@ static inline int cpu_has_work(CPUState *cpu) return env->pending_irq_level; } -static inline void cpu_pc_from_tb(CPUXtensaState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif From ca6862a67f3c03e5efe26cf45b54c6176e4db5c3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Jul 2013 13:19:29 -0700 Subject: [PATCH 09/24] target-alpha: Copy singlestep_enabled to DisasContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepare for removing env from DisasContext. Signed-off-by: Richard Henderson Signed-off-by: Andreas Färber --- target-alpha/translate.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 5558b728dd..6a1aad6fec 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -46,6 +46,8 @@ struct DisasContext { int tb_rm; /* Current flush-to-zero setting for this TB. */ int tb_ftz; + + bool singlestep_enabled; }; /* Return values from translate_one, indicating the state of the TB. @@ -380,7 +382,7 @@ static int use_goto_tb(DisasContext *ctx, uint64_t dest) /* Check for the dest on the same page as the start of the TB. We also want to suppress goto_tb in the case of single-steping and IO. */ return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0 - && !ctx->env->singlestep_enabled + && !ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)); } @@ -3401,6 +3403,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, ctx.env = env; ctx.pc = pc_start; ctx.mem_idx = cpu_mmu_index(env); + ctx.singlestep_enabled = env->singlestep_enabled; /* ??? Every TB begins with unset rounding mode, to be initialized on the first fp insn of the TB. Alternately we could define a proper @@ -3457,7 +3460,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, || tcg_ctx.gen_opc_ptr >= gen_opc_end || num_insns >= max_insns || singlestep - || env->singlestep_enabled)) { + || ctx.singlestep_enabled)) { ret = EXIT_PC_STALE; } } while (ret == NO_EXIT); @@ -3474,7 +3477,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, tcg_gen_movi_i64(cpu_pc, ctx.pc); /* FALLTHRU */ case EXIT_PC_UPDATED: - if (env->singlestep_enabled) { + if (ctx.singlestep_enabled) { gen_excp_1(EXCP_DEBUG, 0); } else { tcg_gen_exit_tb(0); From 801c4c287b7d85fe8447900f78a9a6ab89d00271 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Jul 2013 13:19:30 -0700 Subject: [PATCH 10/24] target-alpha: Copy implver to DisasContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Which allows removing env from DisasContext. Signed-off-by: Richard Henderson Signed-off-by: Andreas Färber --- target-alpha/translate.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 6a1aad6fec..c298c06e8e 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -38,7 +38,6 @@ typedef struct DisasContext DisasContext; struct DisasContext { struct TranslationBlock *tb; - CPUAlphaState *env; uint64_t pc; int mem_idx; @@ -47,6 +46,9 @@ struct DisasContext { /* Current flush-to-zero setting for this TB. */ int tb_ftz; + /* implver value for this CPU. */ + int implver; + bool singlestep_enabled; }; @@ -2250,8 +2252,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x6C: /* IMPLVER */ - if (rc != 31) - tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver); + if (rc != 31) { + tcg_gen_movi_i64(cpu_ir[rc], ctx->implver); + } break; default: goto invalid_opc; @@ -3400,9 +3403,9 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.tb = tb; - ctx.env = env; ctx.pc = pc_start; ctx.mem_idx = cpu_mmu_index(env); + ctx.implver = env->implver; ctx.singlestep_enabled = env->singlestep_enabled; /* ??? Every TB begins with unset rounding mode, to be initialized on From ed2803da58355413447f8c7c681a76873168114f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 21 Jun 2013 20:20:45 +0200 Subject: [PATCH 11/24] cpu: Move singlestep_enabled field from CPU_COMMON to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepares for changing cpu_single_step() argument to CPUState. Acked-by: Michael Walle (for lm32) Signed-off-by: Andreas Färber --- cpu-exec.c | 2 +- cpus.c | 2 +- exec.c | 10 ++++++---- include/exec/cpu-defs.h | 1 - include/qom/cpu.h | 2 ++ kvm-all.c | 2 +- target-alpha/translate.c | 3 ++- target-arm/translate.c | 7 ++++--- target-cris/translate.c | 7 ++++--- target-i386/kvm.c | 6 ++++-- target-i386/translate.c | 5 +++-- target-lm32/translate.c | 7 ++++--- target-m68k/translate.c | 7 ++++--- target-microblaze/translate.c | 8 +++++--- target-mips/translate.c | 11 +++++++---- target-moxie/translate.c | 5 +++-- target-openrisc/translate.c | 7 ++++--- target-ppc/translate.c | 8 +++++--- target-s390x/translate.c | 5 +++-- target-sh4/translate.c | 8 +++++--- target-sparc/translate.c | 3 ++- target-unicore32/translate.c | 7 ++++--- target-xtensa/translate.c | 7 ++++--- 23 files changed, 78 insertions(+), 52 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 3fccb8617e..301be28bf7 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -297,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; } diff --git a/cpus.c b/cpus.c index 2509eb5af3..4549b7a01a 100644 --- a/cpus.c +++ b/cpus.c @@ -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); diff --git a/exec.c b/exec.c index c8658c6f9d..30b676d7e5 100644 --- a/exec.c +++ b/exec.c @@ -588,11 +588,13 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask) void cpu_single_step(CPUArchState *env, int enabled) { #if defined(TARGET_HAS_ICE) - if (env->singlestep_enabled != enabled) { - env->singlestep_enabled = enabled; - if (kvm_enabled()) + CPUState *cpu = ENV_GET_CPU(env); + + 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); diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 39094b3f48..12b1ca7426 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -170,7 +170,6 @@ 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; \ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 4e5ec77919..94302a415e 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -133,6 +133,7 @@ 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. * @next_cpu: Next CPU sharing TB cache. @@ -165,6 +166,7 @@ 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; diff --git a/kvm-all.c b/kvm-all.c index 232c39a610..a210389320 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -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); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index c298c06e8e..0efd5595e6 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -3388,6 +3388,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUAlphaState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; target_ulong pc_start; @@ -3406,7 +3407,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, ctx.pc = pc_start; ctx.mem_idx = cpu_mmu_index(env); ctx.implver = env->implver; - ctx.singlestep_enabled = env->singlestep_enabled; + ctx.singlestep_enabled = cs->singlestep_enabled; /* ??? Every TB begins with unset rounding mode, to be initialized on the first fp insn of the TB. Alternately we could define a proper diff --git a/target-arm/translate.c b/target-arm/translate.c index 7b50c8c308..6db4c50df4 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -9911,6 +9911,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; @@ -9930,7 +9931,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->condjmp = 0; dc->thumb = ARM_TBFLAG_THUMB(tb->flags); dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags); @@ -10080,7 +10081,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, * ensures prefetch aborts occur at the right place. */ num_insns ++; } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !cs->singlestep_enabled && !singlestep && dc->pc < next_page_start && num_insns < max_insns); @@ -10097,7 +10098,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, /* At this stage dc->condjmp will only be set when the skipped instruction was a conditional branch or trap, and the PC has already been written. */ - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (dc->condjmp) { gen_set_condexec(dc); diff --git a/target-cris/translate.c b/target-cris/translate.c index 1de9743953..2a4beeb869 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3165,6 +3165,7 @@ static inline void gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUCRISState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; @@ -3197,7 +3198,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, dc->is_jmp = DISAS_NEXT; dc->ppc = pc_start; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->flags_uptodate = 1; dc->flagx_known = 1; dc->flags_x = tb->flags & X_FLAG; @@ -3337,7 +3338,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, /* If we are rexecuting a branch due to exceptions on delay slots dont break. */ - if (!(tb->pc & 1) && env->singlestep_enabled) { + if (!(tb->pc & 1) && cs->singlestep_enabled) { break; } } while (!dc->is_jmp && !dc->cpustate_changed @@ -3370,7 +3371,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, cris_evaluate_flags(dc); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(env_pc, npc); } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 8315489989..513888267e 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1594,6 +1594,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu) static int kvm_guest_debug_workarounds(X86CPU *cpu) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; int ret = 0; unsigned long reinject_trap = 0; @@ -1616,7 +1617,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu) * reinject them via SET_GUEST_DEBUG. */ if (reinject_trap || - (!kvm_has_robust_singlestep() && env->singlestep_enabled)) { + (!kvm_has_robust_singlestep() && cs->singlestep_enabled)) { ret = kvm_update_guest_debug(env, reinject_trap); } return ret; @@ -2042,13 +2043,14 @@ static CPUWatchpoint hw_watchpoint; static int kvm_handle_debug(X86CPU *cpu, struct kvm_debug_exit_arch *arch_info) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; int ret = 0; int n; if (arch_info->exception == 1) { if (arch_info->dr6 & (1 << 14)) { - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { ret = EXCP_DEBUG; } } else { diff --git a/target-i386/translate.c b/target-i386/translate.c index 6550c27798..065a9d320e 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8255,6 +8255,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; DisasContext dc1, *dc = &dc1; target_ulong pc_ptr; @@ -8281,7 +8282,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, dc->cpl = (flags >> HF_CPL_SHIFT) & 3; dc->iopl = (flags >> IOPL_SHIFT) & 3; dc->tf = (flags >> TF_SHIFT) & 1; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->cc_op = CC_OP_DYNAMIC; dc->cc_op_dirty = false; dc->cs_base = cs_base; @@ -8302,7 +8303,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, dc->code64 = (flags >> HF_CS64_SHIFT) & 1; #endif dc->flags = flags; - dc->jmp_opt = !(dc->tf || env->singlestep_enabled || + dc->jmp_opt = !(dc->tf || cs->singlestep_enabled || (flags & HF_INHIBIT_IRQ_MASK) #ifndef CONFIG_SOFTMMU || (flags & HF_SOFTMMU_MASK) diff --git a/target-lm32/translate.c b/target-lm32/translate.c index ed12f50740..1247287050 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1015,6 +1015,7 @@ static inline void gen_intermediate_code_internal(LM32CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPULM32State *env = &cpu->env; struct DisasContext ctx, *dc = &ctx; uint16_t *gen_opc_end; @@ -1032,7 +1033,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->nr_nops = 0; if (pc_start & 3) { @@ -1077,7 +1078,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu, } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end - && !env->singlestep_enabled + && !cs->singlestep_enabled && !singlestep && (dc->pc < next_page_start) && num_insns < max_insns); @@ -1086,7 +1087,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu, gen_io_end(); } - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(cpu_pc, dc->pc); } diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 2d73af50c3..d562eebef3 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -2974,6 +2974,7 @@ static inline void gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUM68KState *env = &cpu->env; DisasContext dc1, *dc = &dc1; uint16_t *gen_opc_end; @@ -2995,7 +2996,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; dc->cc_op = CC_OP_DYNAMIC; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->fpcr = env->fpcr; dc->user = (env->sr & SR_S) == 0; dc->is_mem = 0; @@ -3038,14 +3039,14 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, disas_m68k_insn(env, dc); num_insns++; } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !cs->singlestep_enabled && !singlestep && (pc_offset) < (TARGET_PAGE_SIZE - 32) && num_insns < max_insns); if (tb->cflags & CF_LAST_IO) gen_io_end(); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (!dc->is_jmp) { gen_flush_cc_op(dc); diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index eba255b7c6..cd4357703f 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1741,6 +1741,7 @@ static inline void gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUMBState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; @@ -1766,7 +1767,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, dc->jmp = JMP_INDIRECT; } dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->cpustate_changed = 0; dc->abort_at_next_insn = 0; dc->nr_nops = 0; @@ -1859,8 +1860,9 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, break; } } - if (env->singlestep_enabled) + if (cs->singlestep_enabled) { break; + } } while (!dc->is_jmp && !dc->cpustate_changed && tcg_ctx.gen_opc_ptr < gen_opc_end && !singlestep @@ -1887,7 +1889,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, } t_sync_flags(dc); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG); if (dc->is_jmp != DISAS_JUMP) { diff --git a/target-mips/translate.c b/target-mips/translate.c index 8246c200a1..877f8dfe88 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -15543,6 +15543,7 @@ static inline void gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUMIPSState *env = &cpu->env; DisasContext ctx; target_ulong pc_start; @@ -15561,7 +15562,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.pc = pc_start; ctx.saved_pc = -1; - ctx.singlestep_enabled = env->singlestep_enabled; + ctx.singlestep_enabled = cs->singlestep_enabled; ctx.insn_flags = env->insn_flags; ctx.tb = tb; ctx.bstate = BS_NONE; @@ -15637,8 +15638,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, This is what GDB expects and is consistent with what the hardware does (e.g. if a delay slot instruction faults, the reported PC is the PC of the branch). */ - if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) + if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) { break; + } if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; @@ -15653,9 +15655,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, if (singlestep) break; } - if (tb->cflags & CF_LAST_IO) + if (tb->cflags & CF_LAST_IO) { gen_io_end(); - if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) { + } + if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) { save_cpu_state(&ctx, ctx.bstate == BS_NONE); gen_helper_0e0i(raise_exception, EXCP_DEBUG); } else { diff --git a/target-moxie/translate.c b/target-moxie/translate.c index 664d359438..8cc0bb7bfb 100644 --- a/target-moxie/translate.c +++ b/target-moxie/translate.c @@ -824,6 +824,7 @@ static inline void gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); DisasContext ctx; target_ulong pc_start; uint16_t *gen_opc_end; @@ -871,7 +872,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, ctx.pc += decode_opc(cpu, &ctx); num_insns++; - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { break; } @@ -880,7 +881,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, } } while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end); - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { tcg_gen_movi_tl(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); } else { diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index f222834fc3..a6050ba6d8 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -1662,6 +1662,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, TranslationBlock *tb, int search_pc) { + CPUState *cs = CPU(cpu); struct DisasContext ctx, *dc = &ctx; uint16_t *gen_opc_end; uint32_t pc_start; @@ -1681,7 +1682,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, dc->mem_idx = cpu_mmu_index(&cpu->env); dc->synced_flags = dc->tb_flags = tb->flags; dc->delayed_branch = !!(dc->tb_flags & D_FLAG); - dc->singlestep_enabled = cpu->env.singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("-----------------------------------------\n"); log_cpu_state(CPU(cpu), 0); @@ -1743,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, } } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end - && !cpu->env.singlestep_enabled + && !cs->singlestep_enabled && !singlestep && (dc->pc < next_page_start) && num_insns < max_insns); @@ -1755,7 +1756,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, dc->is_jmp = DISAS_UPDATE; tcg_gen_movi_tl(cpu_pc, dc->pc); } - if (unlikely(cpu->env.singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(cpu_pc, dc->pc); } diff --git a/target-ppc/translate.c b/target-ppc/translate.c index eb96272b0e..f07d70d866 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -9730,6 +9730,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; opc_handler_t **table, *handler; @@ -9770,8 +9771,9 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, ctx.singlestep_enabled = 0; if ((env->flags & POWERPC_FLAG_BE) && msr_be) ctx.singlestep_enabled |= CPU_BRANCH_STEP; - if (unlikely(env->singlestep_enabled)) + if (unlikely(cs->singlestep_enabled)) { ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP; + } #if defined (DO_SINGLE_STEP) && 0 /* Single step trace mode */ msr_se = 1; @@ -9873,7 +9875,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, ctx.exception != POWERPC_EXCP_BRANCH)) { gen_exception(ctxp, POWERPC_EXCP_TRACE); } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || - (env->singlestep_enabled) || + (cs->singlestep_enabled) || singlestep || num_insns >= max_insns)) { /* if we reach a page boundary or are single stepping, stop @@ -9887,7 +9889,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, if (ctx.exception == POWERPC_EXCP_NONE) { gen_goto_tb(&ctx, 0, ctx.nip); } else if (ctx.exception != POWERPC_EXCP_BRANCH) { - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { gen_debug_exception(ctxp); } /* Generate the return instruction */ diff --git a/target-s390x/translate.c b/target-s390x/translate.c index cba7b87527..1fb76c5264 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -4740,6 +4740,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUS390XState *env = &cpu->env; DisasContext dc; target_ulong pc_start; @@ -4761,7 +4762,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu, dc.tb = tb; dc.pc = pc_start; dc.cc_op = CC_OP_DYNAMIC; - do_debug = dc.singlestep_enabled = env->singlestep_enabled; + do_debug = dc.singlestep_enabled = cs->singlestep_enabled; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; @@ -4818,7 +4819,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu, || tcg_ctx.gen_opc_ptr >= gen_opc_end || num_insns >= max_insns || singlestep - || env->singlestep_enabled)) { + || cs->singlestep_enabled)) { status = EXIT_PC_STALE; } } while (status == NO_EXIT); diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 2fbe6685b0..59f3d47023 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -1849,6 +1849,7 @@ static inline void gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUSH4State *env = &cpu->env; DisasContext ctx; target_ulong pc_start; @@ -1868,7 +1869,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, so assume it is a dynamic branch. */ ctx.delayed_pc = -1; /* use delayed pc from env pointer */ ctx.tb = tb; - ctx.singlestep_enabled = env->singlestep_enabled; + ctx.singlestep_enabled = cs->singlestep_enabled; ctx.features = env->features; ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA); @@ -1914,8 +1915,9 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, ctx.pc += 2; if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; - if (env->singlestep_enabled) + if (cs->singlestep_enabled) { break; + } if (num_insns >= max_insns) break; if (singlestep) @@ -1923,7 +1925,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, } if (tb->cflags & CF_LAST_IO) gen_io_end(); - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); } else { diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 5e771e5da7..093e0e2c78 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -5223,6 +5223,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, TranslationBlock *tb, bool spc) { + CPUState *cs = CPU(cpu); CPUSPARCState *env = &cpu->env; target_ulong pc_start, last_pc; uint16_t *gen_opc_end; @@ -5244,7 +5245,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, dc->def = env->def; dc->fpu_enabled = tb_fpu_enabled(tb->flags); dc->address_mask_32bit = tb_am_enabled(tb->flags); - dc->singlestep = (env->singlestep_enabled || singlestep); + dc->singlestep = (cs->singlestep_enabled || singlestep); gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; num_insns = 0; diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index d85185df36..68be1c64e0 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -1879,6 +1879,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUUniCore32State *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; @@ -1900,7 +1901,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->condjmp = 0; cpu_F0s = tcg_temp_new_i32(); cpu_F1s = tcg_temp_new_i32(); @@ -1971,7 +1972,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, * ensures prefetch aborts occur at the right place. */ num_insns++; } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !cs->singlestep_enabled && !singlestep && dc->pc < next_page_start && num_insns < max_insns); @@ -1988,7 +1989,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, /* At this stage dc->condjmp will only be set when the skipped instruction was a conditional branch or trap, and the PC has already been written. */ - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (dc->condjmp) { if (dc->is_jmp == DISAS_SYSCALL) { diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index e4cf828630..e692329157 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -2879,6 +2879,7 @@ static inline void gen_intermediate_code_internal(XtensaCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUXtensaState *env = &cpu->env; DisasContext dc; int insn_count = 0; @@ -2894,7 +2895,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, } dc.config = env->config; - dc.singlestep_enabled = env->singlestep_enabled; + dc.singlestep_enabled = cs->singlestep_enabled; dc.tb = tb; dc.pc = pc_start; dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK; @@ -2917,7 +2918,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, gen_tb_start(); - if (env->singlestep_enabled && env->exception_taken) { + if (cs->singlestep_enabled && env->exception_taken) { env->exception_taken = 0; tcg_gen_movi_i32(cpu_pc, dc.pc); gen_exception(&dc, EXCP_DEBUG); @@ -2970,7 +2971,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, if (dc.icount) { tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount); } - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, dc.pc); gen_exception(&dc, EXCP_DEBUG); break; From 5ca666c765e9e92217a87669365b212abae6f9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 24 Jun 2013 19:20:57 +0200 Subject: [PATCH 12/24] gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In particular reindent to 4 instead of 2 spaces. Prepares for changing cpu_single_step() argument in gdb_handlesig(). Signed-off-by: Andreas Färber --- gdbstub.c | 94 +++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 55d4756da7..6ddff91f14 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2761,66 +2761,66 @@ gdb_queuesig (void) } int -gdb_handlesig (CPUArchState *env, int sig) +gdb_handlesig(CPUArchState *env, int sig) { - GDBState *s; - char buf[256]; - int n; + GDBState *s; + char buf[256]; + int n; - s = gdbserver_state; - if (gdbserver_fd < 0 || s->fd < 0) - return sig; - - /* disable single step if it was enabled */ - cpu_single_step(env, 0); - tb_flush(env); - - if (sig != 0) - { - snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig)); - put_packet(s, buf); + s = gdbserver_state; + if (gdbserver_fd < 0 || s->fd < 0) { + return sig; } - /* put_packet() might have detected that the peer terminated the - connection. */ - if (s->fd < 0) - return sig; - sig = 0; - s->state = RS_IDLE; - s->running_state = 0; - while (s->running_state == 0) { - n = read (s->fd, buf, 256); - if (n > 0) - { - int i; + /* disable single step if it was enabled */ + cpu_single_step(env, 0); + tb_flush(env); - for (i = 0; i < n; i++) - gdb_read_byte (s, buf[i]); + if (sig != 0) { + snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig)); + put_packet(s, buf); + } + /* put_packet() might have detected that the peer terminated the + connection. */ + if (s->fd < 0) { + return sig; + } + + sig = 0; + s->state = RS_IDLE; + s->running_state = 0; + while (s->running_state == 0) { + n = read(s->fd, buf, 256); + if (n > 0) { + int i; + + for (i = 0; i < n; i++) { + gdb_read_byte(s, buf[i]); + } + } else if (n == 0 || errno != EAGAIN) { + /* XXX: Connection closed. Should probably wait for another + connection before continuing. */ + return sig; } - else if (n == 0 || errno != EAGAIN) - { - /* XXX: Connection closed. Should probably wait for another - connection before continuing. */ - return sig; - } - } - sig = s->signal; - s->signal = 0; - return sig; + } + sig = s->signal; + s->signal = 0; + return sig; } /* Tell the remote gdb that the process has exited due to SIG. */ void gdb_signalled(CPUArchState *env, int sig) { - GDBState *s; - char buf[4]; + GDBState *s; + char buf[4]; - s = gdbserver_state; - if (gdbserver_fd < 0 || s->fd < 0) - return; + s = gdbserver_state; + if (gdbserver_fd < 0 || s->fd < 0) { + return; + } - snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig)); - put_packet(s, buf); + snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig)); + put_packet(s, buf); } static void gdb_accept(void) From 3825b28ff128e2bd3cb0a338c21923c926b1f38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 24 Jun 2013 18:41:06 +0200 Subject: [PATCH 13/24] cpu: Change cpu_single_step() argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use CPUState::env_ptr for now. Needed for GdbState::c_cpu. Signed-off-by: Andreas Färber --- exec.c | 4 ++-- gdbstub.c | 9 +++++---- include/exec/cpu-all.h | 6 ------ include/qom/cpu.h | 13 +++++++++++++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/exec.c b/exec.c index 30b676d7e5..9cd936c5df 100644 --- a/exec.c +++ b/exec.c @@ -585,10 +585,10 @@ 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) - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = cpu->env_ptr; if (cpu->singlestep_enabled != enabled) { cpu->singlestep_enabled = enabled; diff --git a/gdbstub.c b/gdbstub.c index 6ddff91f14..8e23509d3f 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2154,7 +2154,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) s->c_cpu = env; } if (res == 's') { - cpu_single_step(s->c_cpu, sstep_flags); + cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); } s->signal = res_signal; gdb_continue(s); @@ -2182,7 +2182,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) addr = strtoull(p, (char **)&p, 16); gdb_set_cpu_pc(s, addr); } - cpu_single_step(s->c_cpu, sstep_flags); + cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); gdb_continue(s); return RS_IDLE; case 'F': @@ -2570,7 +2570,7 @@ send_packet: put_packet(s, buf); /* disable single step if it was enabled */ - cpu_single_step(env, 0); + cpu_single_step(cpu, 0); } #endif @@ -2763,6 +2763,7 @@ gdb_queuesig (void) int gdb_handlesig(CPUArchState *env, int sig) { + CPUState *cpu = ENV_GET_CPU(env); GDBState *s; char buf[256]; int n; @@ -2773,7 +2774,7 @@ gdb_handlesig(CPUArchState *env, int sig) } /* disable single step if it was enabled */ - cpu_single_step(env, 0); + cpu_single_step(cpu, 0); tb_flush(env); if (sig != 0) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 5084202217..b48db0317b 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -428,12 +428,6 @@ 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 diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 94302a415e..43a52e459f 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -510,6 +510,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 From 6227881415e0e0117d56aef90cf6e72f24187ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 17:12:06 +0200 Subject: [PATCH 14/24] kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPUArchState is no longer directly used since converting CPU loops to CPUState. Prepares for changing GDBState::c_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 12 ++++++++---- include/sysemu/kvm.h | 4 ++-- kvm-all.c | 10 ++++------ kvm-stub.c | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 8e23509d3f..b5e6778c80 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1954,8 +1954,10 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) CPUArchState *env; int err = 0; - if (kvm_enabled()) - return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); + if (kvm_enabled()) { + return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), + addr, len, type); + } switch (type) { case GDB_BREAKPOINT_SW: @@ -1991,8 +1993,10 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) CPUArchState *env; int err = 0; - if (kvm_enabled()) - return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type); + if (kvm_enabled()) { + return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), + addr, len, type); + } switch (type) { case GDB_BREAKPOINT_SW: diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 1e08a85116..f8ac448e0b 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -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); diff --git a/kvm-all.c b/kvm-all.c index a210389320..4fb4ccbeca 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -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; diff --git a/kvm-stub.c b/kvm-stub.c index 370c8371d5..7b2233ae82 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -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; From 9e0c5422cfbed78990e2edc9d68928647829f5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 17:45:01 +0200 Subject: [PATCH 15/24] gdbstub: Change syscall callback argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Callback implementations were specific to arm and m68k, so can easily cast to ARMCPU and M68kCPU respectively. Prepares for changing GDBState::c_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 2 +- include/exec/gdbstub.h | 2 +- target-arm/arm-semi.c | 8 ++++++-- target-m68k/m68k-semi.c | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index b5e6778c80..bb44ef2f18 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2205,7 +2205,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; type = *p; if (s->current_syscall_cb) { - s->current_syscall_cb(s->c_cpu, ret, err); + s->current_syscall_cb(ENV_GET_CPU(s->c_cpu), ret, err); s->current_syscall_cb = NULL; } if (type == 'C') { diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index ded4160e57..de0f4fb5b4 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -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, ...); diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c index 5f01bca119..4ecea65f62 100644 --- a/target-arm/arm-semi.c +++ b/target-arm/arm-semi.c @@ -122,8 +122,10 @@ static target_ulong arm_semi_syscall_len; static target_ulong syscall_err; #endif -static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) +static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; #ifdef CONFIG_USER_ONLY TaskState *ts = env->opaque; #endif @@ -152,8 +154,10 @@ static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) } } -static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err) +static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; /* The size is always stored in big-endian order, extract the value. We assume the size always fit in 32 bits. */ uint32_t size; diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c index 239fadbad5..94c4983813 100644 --- a/target-m68k/m68k-semi.c +++ b/target-m68k/m68k-semi.c @@ -161,8 +161,11 @@ static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, uint32_t err) static int m68k_semi_is_fseek; -static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) +static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + if (m68k_semi_is_fseek) { /* FIXME: We've already lost the high bits of the fseek return value. */ From db6b81d43693cec86d62df79dd7402fc045427ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 19:49:31 +0200 Subject: [PATCH 16/24] gdbstub: Change gdb_handlesig() argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepares for changing GDBState::c_cpu to CPUState. Signed-off-by: Andreas Färber --- bsd-user/main.c | 10 ++++++---- gdbstub.c | 6 +++--- include/exec/gdbstub.h | 2 +- linux-user/main.c | 35 +++++++++++++++++++---------------- linux-user/signal.c | 3 ++- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index 1e9255242c..f9246aa102 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -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 */ diff --git a/gdbstub.c b/gdbstub.c index bb44ef2f18..b65682f496 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2636,7 +2636,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) va_end(va); #ifdef CONFIG_USER_ONLY put_packet(s, s->syscall_buf); - gdb_handlesig(s->c_cpu, 0); + gdb_handlesig(ENV_GET_CPU(s->c_cpu), 0); #else /* In this case wait to send the syscall packet until notification that the CPU has stopped. This must be done because if the packet is sent @@ -2765,9 +2765,9 @@ gdb_queuesig (void) } int -gdb_handlesig(CPUArchState *env, int sig) +gdb_handlesig(CPUState *cpu, int sig) { - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = cpu->env_ptr; GDBState *s; char buf[256]; int n; diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index de0f4fb5b4..0f1ad9a64e 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -20,7 +20,7 @@ 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 diff --git a/linux-user/main.c b/linux-user/main.c index 99c3b3f5ef..f6a3aad9e5 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -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 */ diff --git a/linux-user/signal.c b/linux-user/signal.c index d0727becc2..a5e8906c4d 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -5386,6 +5386,7 @@ long do_rt_sigreturn(CPUArchState *env) void process_pending_signals(CPUArchState *cpu_env) { + CPUState *cpu = ENV_GET_CPU(cpu_env); int sig; abi_ulong handler; sigset_t set, old_set; @@ -5419,7 +5420,7 @@ void process_pending_signals(CPUArchState *cpu_env) if (!k->first) k->pending = 0; - sig = gdb_handlesig (cpu_env, sig); + sig = gdb_handlesig(cpu, sig); if (!sig) { sa = NULL; handler = TARGET_SIG_IGN; From 385b9f0e4d8c60037c937edd7a3735fff7570429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 18:25:36 +0200 Subject: [PATCH 17/24] gdbstub: Change gdb_{read,write}_register() argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use CPUState::env_ptr for now. Prepares for changing GDBState::g_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index b65682f496..848754d0d5 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1866,8 +1866,9 @@ static const char *get_feature_xml(const char *p, const char **newp) } #endif -static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) +static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) { + CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < NUM_CORE_REGS) @@ -1881,8 +1882,9 @@ static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) return 0; } -static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg) +static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) { + CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < NUM_CORE_REGS) @@ -2220,7 +2222,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) env = s->g_cpu; len = 0; for (addr = 0; addr < num_g_regs; addr++) { - reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); + reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), + mem_buf + len, addr); len += reg_size; } memtohex(buf, mem_buf, len); @@ -2233,7 +2236,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); for (addr = 0; addr < num_g_regs && len > 0; addr++) { - reg_size = gdb_write_register(s->g_cpu, registers, addr); + reg_size = gdb_write_register(ENV_GET_CPU(s->g_cpu), registers, + addr); len -= reg_size; registers += reg_size; } @@ -2272,7 +2276,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (!gdb_has_xml) goto unknown_command; addr = strtoull(p, (char **)&p, 16); - reg_size = gdb_read_register(s->g_cpu, mem_buf, addr); + reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); if (reg_size) { memtohex(buf, mem_buf, reg_size); put_packet(s, buf); @@ -2288,7 +2292,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; reg_size = strlen(p) / 2; hextomem(mem_buf, p, reg_size); - gdb_write_register(s->g_cpu, mem_buf, addr); + gdb_write_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); put_packet(s, "OK"); break; case 'Z': From 00b941e581b5c42645f836ef530705bb76a3e6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 29 Jun 2013 18:55:54 +0200 Subject: [PATCH 18/24] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change breakpoint_invalidate() argument to CPUState alongside. Since all targets now assign a softmmu-only field, we can drop helpers cpu_class_set_{do_unassigned_access,vmsd}() and device_class_set_vmsd(). Prepares for changing cpu_memory_rw_debug() argument to CPUState. Acked-by: Max Filippov (for xtensa) Signed-off-by: Andreas Färber --- exec.c | 20 +++++----- hw/i386/kvmvapic.c | 6 ++- hw/xtensa/xtensa_lx60.c | 8 ++-- hw/xtensa/xtensa_sim.c | 10 +++-- include/exec/cpu-all.h | 5 --- include/qom/cpu.h | 74 +++++++++++-------------------------- target-alpha/cpu-qom.h | 1 + target-alpha/cpu.c | 7 +++- target-alpha/helper.c | 5 ++- target-arm/cpu-qom.h | 2 + target-arm/cpu.c | 5 ++- target-arm/helper.c | 8 ++-- target-cris/cpu-qom.h | 2 + target-cris/cpu.c | 3 ++ target-cris/helper.c | 7 ++-- target-i386/cpu-qom.h | 2 + target-i386/cpu.c | 3 +- target-i386/helper.c | 4 +- target-lm32/cpu-qom.h | 1 + target-lm32/cpu.c | 5 ++- target-lm32/helper.c | 6 ++- target-m68k/cpu-qom.h | 1 + target-m68k/cpu.c | 3 ++ target-m68k/helper.c | 2 +- target-microblaze/cpu-qom.h | 1 + target-microblaze/cpu.c | 5 ++- target-microblaze/helper.c | 4 +- target-mips/cpu-qom.h | 1 + target-mips/cpu.c | 5 ++- target-mips/helper.c | 7 +++- target-moxie/cpu.c | 5 ++- target-moxie/cpu.h | 1 + target-moxie/helper.c | 11 ++---- target-openrisc/cpu.c | 5 ++- target-openrisc/cpu.h | 1 + target-openrisc/mmu.c | 5 +-- target-ppc/cpu-qom.h | 1 + target-ppc/mmu_helper.c | 4 +- target-ppc/translate_init.c | 3 ++ target-s390x/cpu-qom.h | 1 + target-s390x/cpu.c | 3 ++ target-s390x/helper.c | 5 ++- target-sh4/cpu-qom.h | 1 + target-sh4/cpu.c | 3 ++ target-sh4/helper.c | 5 ++- target-sparc/cpu-qom.h | 1 + target-sparc/cpu.c | 5 ++- target-sparc/mmu_helper.c | 11 ++++-- target-unicore32/cpu-qom.h | 1 + target-unicore32/cpu.c | 3 ++ target-unicore32/softmmu.c | 7 ++-- target-xtensa/cpu-qom.h | 1 + target-xtensa/cpu.c | 3 ++ target-xtensa/helper.c | 7 ++-- target-xtensa/xtensa-semi.c | 4 +- 55 files changed, 182 insertions(+), 128 deletions(-) diff --git a/exec.c b/exec.c index 9cd936c5df..a491af7f0f 100644 --- a/exec.c +++ b/exec.c @@ -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 @@ -2613,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(ENV_GET_CPU(env), page); /* if no physical page mapped, return an error */ if (phys_addr == -1) return -1; diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index ccd089a40e..224601fedd 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -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; } @@ -271,6 +272,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 +289,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; } diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c index 075daf1893..1138666ca5 100644 --- a/hw/xtensa/xtensa_lx60.c +++ b/hw/xtensa/xtensa_lx60.c @@ -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; diff --git a/hw/xtensa/xtensa_sim.c b/hw/xtensa/xtensa_sim.c index a88707e161..ea91162b63 100644 --- a/hw/xtensa/xtensa_sim.c +++ b/hw/xtensa/xtensa_sim.c @@ -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) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index b48db0317b..ef16cbd477 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -430,11 +430,6 @@ void cpu_watchpoint_remove_all(CPUArchState *env, int mask); #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; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 43a52e459f..63666464de 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -78,6 +78,7 @@ struct TranslationBlock; * @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. @@ -103,6 +104,7 @@ typedef struct CPUClass { 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, @@ -280,6 +282,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. @@ -297,59 +318,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. diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index 60125b19d5..b2eeba36f3 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -81,5 +81,6 @@ extern const struct VMStateDescription vmstate_alpha_cpu; void alpha_cpu_do_interrupt(CPUState *cpu); void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 09bb7a8876..c8c8c2c861 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -270,9 +270,12 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = alpha_cpu_class_by_name; cc->do_interrupt = alpha_cpu_do_interrupt; cc->dump_state = alpha_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access); cc->set_pc = alpha_cpu_set_pc; - device_class_set_vmsd(dc, &vmstate_alpha_cpu); +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = alpha_cpu_unassigned_access; + cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug; + dc->vmsd = &vmstate_alpha_cpu; +#endif } static const TypeInfo alpha_cpu_type_info = { diff --git a/target-alpha/helper.c b/target-alpha/helper.c index ff57dd6c18..fc61bb02f7 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -315,12 +315,13 @@ static int get_physical_address(CPUAlphaState *env, target_ulong addr, return ret; } -hwaddr cpu_get_phys_page_debug(CPUAlphaState *env, target_ulong addr) +hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + AlphaCPU *cpu = ALPHA_CPU(cs); target_ulong phys; int prot, fail; - fail = get_physical_address(env, addr, 0, 0, &phys, &prot); + fail = get_physical_address(&cpu->env, addr, 0, 0, &phys, &prot); return (fail >= 0 ? -1 : phys); } diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 48ba6054ec..02162c9aba 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -147,4 +147,6 @@ void arm_v7m_cpu_do_interrupt(CPUState *cpu); void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 082bc12831..d3906a4829 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -824,7 +824,10 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = arm_cpu_do_interrupt; cc->dump_state = arm_cpu_dump_state; cc->set_pc = arm_cpu_set_pc; - cpu_class_set_vmsd(cc, &vmstate_arm_cpu); +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_arm_cpu; +#endif } static void cpu_register(const ARMCPUInfo *info) diff --git a/target-arm/helper.c b/target-arm/helper.c index aeae024165..9105ad98c0 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2762,17 +2762,19 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, return 1; } -hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr) +hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + ARMCPU *cpu = ARM_CPU(cs); hwaddr phys_addr; target_ulong page_size; int prot; int ret; - ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size); + ret = get_phys_addr(&cpu->env, addr, 0, 0, &phys_addr, &prot, &page_size); - if (ret != 0) + if (ret != 0) { return -1; + } return phys_addr; } diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index af7d14de4b..d7baf0746a 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -79,4 +79,6 @@ void crisv10_cpu_do_interrupt(CPUState *cpu); void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + #endif diff --git a/target-cris/cpu.c b/target-cris/cpu.c index b72fd98ab8..ba095e75a5 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -255,6 +255,9 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = cris_cpu_do_interrupt; cc->dump_state = cris_cpu_dump_state; cc->set_pc = cris_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = cris_cpu_get_phys_page_debug; +#endif } static const TypeInfo cris_cpu_type_info = { diff --git a/target-cris/helper.c b/target-cris/helper.c index aba7537265..d274b388b8 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -255,16 +255,17 @@ void cris_cpu_do_interrupt(CPUState *cs) env->pregs[PR_ERP]); } -hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr) +hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + CRISCPU *cpu = CRIS_CPU(cs); uint32_t phy = addr; struct cris_mmu_result res; int miss; - miss = cris_mmu_translate(&res, env, addr, 0, 0, 1); + miss = cris_mmu_translate(&res, &cpu->env, addr, 0, 0, 1); /* If D TLB misses, try I TLB. */ if (miss) { - miss = cris_mmu_translate(&res, env, addr, 2, 0, 1); + miss = cris_mmu_translate(&res, &cpu->env, addr, 2, 0, 1); } if (!miss) { diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 7e55e5fd2e..d928562c53 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -104,4 +104,6 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index b57ea4b6f2..cd350cb8e4 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2542,12 +2542,13 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifndef CONFIG_USER_ONLY cc->get_memory_mapping = x86_cpu_get_memory_mapping; + cc->get_phys_page_debug = x86_cpu_get_phys_page_debug; cc->write_elf64_note = x86_cpu_write_elf64_note; cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote; cc->write_elf32_note = x86_cpu_write_elf32_note; cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote; + cc->vmsd = &vmstate_x86_cpu; #endif - cpu_class_set_vmsd(cc, &vmstate_x86_cpu); } static const TypeInfo x86_cpu_type_info = { diff --git a/target-i386/helper.c b/target-i386/helper.c index d6f43d7a21..2745292d1d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -884,8 +884,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, return 1; } -hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr) +hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; target_ulong pde_addr, pte_addr; uint64_t pte; hwaddr paddr; diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h index e3bb619dc3..9e2732919d 100644 --- a/target-lm32/cpu-qom.h +++ b/target-lm32/cpu-qom.h @@ -78,5 +78,6 @@ extern const struct VMStateDescription vmstate_lm32_cpu; void lm32_cpu_do_interrupt(CPUState *cpu); void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 8aa28b59d4..ce55e4807d 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -87,7 +87,10 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = lm32_cpu_do_interrupt; cc->dump_state = lm32_cpu_dump_state; cc->set_pc = lm32_cpu_set_pc; - cpu_class_set_vmsd(cc, &vmstate_lm32_cpu); +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_lm32_cpu; +#endif } static const TypeInfo lm32_cpu_type_info = { diff --git a/target-lm32/helper.c b/target-lm32/helper.c index 615b44e5be..15bc61554d 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -37,10 +37,12 @@ int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, return 0; } -hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr) +hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + LM32CPU *cpu = LM32_CPU(cs); + addr &= TARGET_PAGE_MASK; - if (env->flags & LM32_FLAG_IGNORE_MSB) { + if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) { return addr & 0x7fffffff; } else { return addr; diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h index 858bf30088..7115707e91 100644 --- a/target-m68k/cpu-qom.h +++ b/target-m68k/cpu-qom.h @@ -73,5 +73,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env) void m68k_cpu_do_interrupt(CPUState *cpu); void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 43011e7fe5..988f476257 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -190,6 +190,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->do_interrupt = m68k_cpu_do_interrupt; cc->dump_state = m68k_cpu_dump_state; cc->set_pc = m68k_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_m68k_cpu; } diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 54fa419ace..dcadfabeaa 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -290,7 +290,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, /* MMU */ /* TODO: This will need fixing once the MMU is implemented. */ -hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr) +hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { return addr; } diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h index ec2b989a23..1318a36676 100644 --- a/target-microblaze/cpu-qom.h +++ b/target-microblaze/cpu-qom.h @@ -74,5 +74,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env) void mb_cpu_do_interrupt(CPUState *cs); void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 0a9bcfa556..9f10c8c778 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -140,8 +140,11 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = mb_cpu_do_interrupt; cc->dump_state = mb_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access); cc->set_pc = mb_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = mb_cpu_unassigned_access; + cc->get_phys_page_debug = mb_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_mb_cpu; dc->props = mb_properties; } diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index c6c96d4488..4fa9ce9cb5 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -265,8 +265,10 @@ void mb_cpu_do_interrupt(CPUState *cs) } } -hwaddr cpu_get_phys_page_debug(CPUMBState * env, target_ulong addr) +hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUMBState *env = &cpu->env; target_ulong vaddr, paddr = 0; struct microblaze_mmu_lookup lu; unsigned int hit; diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index 654744a45b..7c8e616392 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -77,5 +77,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env) void mips_cpu_do_interrupt(CPUState *cpu); void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 1581cd976e..4834c86d02 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -98,9 +98,12 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->do_interrupt = mips_cpu_do_interrupt; cc->dump_state = mips_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access); cc->set_pc = mips_cpu_set_pc; cc->synchronize_from_tb = mips_cpu_synchronize_from_tb; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = mips_cpu_unassigned_access; + cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; +#endif } static const TypeInfo mips_cpu_type_info = { diff --git a/target-mips/helper.c b/target-mips/helper.c index 6983b92a11..6feef7bcd6 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -254,13 +254,16 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, } #if !defined(CONFIG_USER_ONLY) -hwaddr cpu_get_phys_page_debug(CPUMIPSState *env, target_ulong addr) +hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + MIPSCPU *cpu = MIPS_CPU(cs); hwaddr phys_addr; int prot; - if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) + if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, + ACCESS_INT) != 0) { return -1; + } return phys_addr; } #endif diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 91f61973ab..6550be5b35 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -101,7 +101,10 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = moxie_cpu_do_interrupt; cc->dump_state = moxie_cpu_dump_state; cc->set_pc = moxie_cpu_set_pc; - cpu_class_set_vmsd(cc, &vmstate_moxie_cpu); +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_moxie_cpu; +#endif } static void moxielite_initfn(Object *obj) diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h index d5030a4c34..5ce14b5fd3 100644 --- a/target-moxie/cpu.h +++ b/target-moxie/cpu.h @@ -118,6 +118,7 @@ int cpu_moxie_exec(CPUMoxieState *s); void moxie_cpu_do_interrupt(CPUState *cs); void moxie_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); void moxie_translate_init(void); int cpu_moxie_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target-moxie/helper.c b/target-moxie/helper.c index ea0788fcea..b12e4ffcaf 100644 --- a/target-moxie/helper.c +++ b/target-moxie/helper.c @@ -118,11 +118,6 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, return 1; } -hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr) -{ - return addr; -} - #else /* !CONFIG_USER_ONLY */ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, @@ -162,12 +157,14 @@ void moxie_cpu_do_interrupt(CPUState *cs) } } -hwaddr cpu_get_phys_page_debug(CPUMoxieState *env, target_ulong addr) +hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + MoxieCPU *cpu = MOXIE_CPU(cs); uint32_t phy = addr; MoxieMMUResult res; int miss; - miss = moxie_mmu_translate(&res, env, addr, 0, 0); + + miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0); if (!miss) { phy = res.phy; } diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 27ee9f415c..3da5a7a8b1 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -154,7 +154,10 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = openrisc_cpu_do_interrupt; cc->dump_state = openrisc_cpu_dump_state; cc->set_pc = openrisc_cpu_set_pc; - device_class_set_vmsd(dc, &vmstate_openrisc_cpu); +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug; + dc->vmsd = &vmstate_openrisc_cpu; +#endif } static void cpu_register(const OpenRISCCPUInfo *info) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 82bfd03ec1..3ddb7674c7 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -349,6 +349,7 @@ int cpu_openrisc_exec(CPUOpenRISCState *s); void openrisc_cpu_do_interrupt(CPUState *cpu); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); void openrisc_translate_init(void); int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address, diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index d354e1f8b2..57f5616e9c 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -219,12 +219,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, #endif #ifndef CONFIG_USER_ONLY -hwaddr cpu_get_phys_page_debug(CPUOpenRISCState *env, - target_ulong addr) +hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); hwaddr phys_addr; int prot; - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) { return -1; diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 7132599516..3341c5151d 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -105,5 +105,6 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 77102c4b65..5dd4e05f78 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -1409,8 +1409,10 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, return ret; } -hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr) +hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; mmu_ctx_t ctx; switch (env->mmu_model) { diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 9ed7736b8a..0fc9014f56 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8457,6 +8457,9 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->dump_state = ppc_cpu_dump_state; cc->dump_statistics = ppc_cpu_dump_statistics; cc->set_pc = ppc_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; +#endif } static const TypeInfo ppc_cpu_type_info = { diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h index 4c091e3ea0..a4fe8fb5fc 100644 --- a/target-s390x/cpu-qom.h +++ b/target-s390x/cpu-qom.h @@ -74,5 +74,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env) void s390_cpu_do_interrupt(CPUState *cpu); void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index fe3cd8ed15..cb89d1a46b 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -173,6 +173,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = s390_cpu_do_interrupt; cc->dump_state = s390_cpu_dump_state; cc->set_pc = s390_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = s390_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_s390_cpu; } diff --git a/target-s390x/helper.c b/target-s390x/helper.c index b425054be8..61abfd7d9e 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -417,9 +417,10 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr, return 0; } -hwaddr cpu_get_phys_page_debug(CPUS390XState *env, - target_ulong vaddr) +hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; target_ulong raddr; int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; int old_exc = env->exception_index; diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index c229a9a29b..7c9160bab8 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -86,5 +86,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env) void superh_cpu_do_interrupt(CPUState *cpu); void superh_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 03dedc179e..51a77576fb 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -286,6 +286,9 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->dump_state = superh_cpu_dump_state; cc->set_pc = superh_cpu_set_pc; cc->synchronize_from_tb = superh_cpu_synchronize_from_tb; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = superh_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_sh_cpu; } diff --git a/target-sh4/helper.c b/target-sh4/helper.c index cb6a2d28bd..9ac28250e0 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -508,12 +508,13 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, return 0; } -hwaddr cpu_get_phys_page_debug(CPUSH4State * env, target_ulong addr) +hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + SuperHCPU *cpu = SUPERH_CPU(cs); target_ulong physical; int prot; - get_physical_address(env, &physical, &prot, addr, 0, 0); + get_physical_address(&cpu->env, &physical, &prot, addr, 0, 0); return physical; } diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h index 033a5b5219..39d975b5fc 100644 --- a/target-sparc/cpu-qom.h +++ b/target-sparc/cpu-qom.h @@ -78,5 +78,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env) void sparc_cpu_do_interrupt(CPUState *cpu); void sparc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index a2deba5a06..12494ccaa4 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -782,9 +782,12 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = sparc_cpu_do_interrupt; cc->dump_state = sparc_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access); cc->set_pc = sparc_cpu_set_pc; cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = sparc_cpu_unassigned_access; + cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; +#endif } static const TypeInfo sparc_cpu_type_info = { diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index 740cbe8f2c..846d129353 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -310,6 +310,7 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev) void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) { + CPUState *cs = CPU(sparc_env_get_cpu(env)); target_ulong va, va1, va2; unsigned int n, m, o; hwaddr pde_ptr, pa; @@ -322,20 +323,20 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { pde = mmu_probe(env, va, 2); if (pde) { - pa = cpu_get_phys_page_debug(env, va); + pa = cpu_get_phys_page_debug(cs, va); (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n", va, pa, pde); for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { pde = mmu_probe(env, va1, 1); if (pde) { - pa = cpu_get_phys_page_debug(env, va1); + pa = cpu_get_phys_page_debug(cs, va1); (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde); for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { pde = mmu_probe(env, va2, 0); if (pde) { - pa = cpu_get_phys_page_debug(env, va2); + pa = cpu_get_phys_page_debug(cs, va2); (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n", @@ -833,8 +834,10 @@ hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr, } #endif -hwaddr cpu_get_phys_page_debug(CPUSPARCState *env, target_ulong addr) +hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; hwaddr phys_addr; int mmu_idx = cpu_mmu_index(env); MemoryRegionSection section; diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h index 350d48034c..f727760d9e 100644 --- a/target-unicore32/cpu-qom.h +++ b/target-unicore32/cpu-qom.h @@ -63,5 +63,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env) void uc32_cpu_do_interrupt(CPUState *cpu); void uc32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 79f22922f2..46813e52ae 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -139,6 +139,9 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = uc32_cpu_do_interrupt; cc->dump_state = uc32_cpu_dump_state; cc->set_pc = uc32_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_uc32_cpu; } diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c index eadaeb11ab..1e13a85d05 100644 --- a/target-unicore32/softmmu.c +++ b/target-unicore32/softmmu.c @@ -261,9 +261,10 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, return ret; } -hwaddr cpu_get_phys_page_debug(CPUUniCore32State *env, - target_ulong addr) +hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { - cpu_abort(env, "%s not supported yet\n", __func__); + UniCore32CPU *cpu = UNICORE32_CPU(cs); + + cpu_abort(&cpu->env, "%s not supported yet\n", __func__); return addr; } diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index 31e7498181..b9896f2647 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -83,5 +83,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env) void xtensa_cpu_do_interrupt(CPUState *cpu); void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index e3d742a911..d2bcfc69a2 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -108,6 +108,9 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = xtensa_cpu_do_interrupt; cc->dump_state = xtensa_cpu_dump_state; cc->set_pc = xtensa_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_xtensa_cpu; } diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 6f613c66a6..de6cc3b7c5 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -108,17 +108,18 @@ void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf) } } -hwaddr cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong addr) +hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + XtensaCPU *cpu = XTENSA_CPU(cs); uint32_t paddr; uint32_t page_size; unsigned access; - if (xtensa_get_physical_addr(env, false, addr, 0, 0, + if (xtensa_get_physical_addr(&cpu->env, false, addr, 0, 0, &paddr, &page_size, &access) == 0) { return paddr; } - if (xtensa_get_physical_addr(env, false, addr, 2, 0, + if (xtensa_get_physical_addr(&cpu->env, false, addr, 2, 0, &paddr, &page_size, &access) == 0) { return paddr; } diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c index 5fe0361c02..d9dd22244f 100644 --- a/target-xtensa/xtensa-semi.c +++ b/target-xtensa/xtensa-semi.c @@ -152,6 +152,7 @@ static uint32_t errno_h2g(int host_errno) void HELPER(simcall)(CPUXtensaState *env) { + CPUState *cs = CPU(xtensa_env_get_cpu(env)); uint32_t *regs = env->regs; switch (regs[2]) { @@ -169,8 +170,7 @@ void HELPER(simcall)(CPUXtensaState *env) uint32_t len = regs[5]; while (len > 0) { - hwaddr paddr = - cpu_get_phys_page_debug(env, vaddr); + hwaddr paddr = cpu_get_phys_page_debug(cs, vaddr); uint32_t page_left = TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1)); uint32_t io_sz = page_left < len ? page_left : len; From f17ec444c3d39f76bcd8b71c2c05d5754bfe333e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 29 Jun 2013 19:40:58 +0200 Subject: [PATCH 19/24] exec: Change cpu_memory_rw_debug() argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Propagate X86CPU in kvmvapic for simplicity. Signed-off-by: Andreas Färber --- cpus.c | 4 +-- disas.c | 4 +-- exec.c | 6 ++-- gdbstub.c | 2 +- hw/i386/kvmvapic.c | 72 +++++++++++++++++++------------------ include/exec/cpu-all.h | 3 +- include/exec/softmmu-semi.h | 18 +++++----- monitor.c | 2 +- target-arm/arm-semi.c | 2 +- target-i386/helper.c | 8 +++-- target-i386/kvm.c | 14 ++++---- target-sparc/mmu_helper.c | 5 +-- target-xtensa/xtensa-semi.c | 10 +++--- 13 files changed, 77 insertions(+), 73 deletions(-) diff --git a/cpus.c b/cpus.c index 4549b7a01a..ca6b886592 100644 --- a/cpus.c +++ b/cpus.c @@ -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; diff --git a/disas.c b/disas.c index e51127e540..71007fb6a1 100644 --- a/disas.c +++ b/disas.c @@ -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; } diff --git a/exec.c b/exec.c index a491af7f0f..7997002f14 100644 --- a/exec.c +++ b/exec.c @@ -1835,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; @@ -2606,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; @@ -2615,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_GET_CPU(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; diff --git a/gdbstub.c b/gdbstub.c index 848754d0d5..6cefb17ea8 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -46,7 +46,7 @@ static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, int is_write) { - return cpu_memory_rw_debug(env, addr, buf, len, is_write); + return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write); } #else /* target_memory_rw_debug() defined in cpu.h */ diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 224601fedd..035d0fe489 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -188,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]; @@ -211,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; } @@ -226,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; } @@ -237,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++) { @@ -254,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; @@ -334,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; @@ -343,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; @@ -351,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; @@ -364,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) @@ -411,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(); @@ -460,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); @@ -669,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(); } @@ -683,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: @@ -725,7 +727,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) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index ef16cbd477..f2800ec682 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -22,6 +22,7 @@ #include "qemu-common.h" #include "exec/cpu-common.h" #include "qemu/thread.h" +#include "qom/cpu.h" /* some important defines: * @@ -483,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 */ diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h index 93798b9614..8401f7d587 100644 --- a/include/exec/softmmu-semi.h +++ b/include/exec/softmmu-semi.h @@ -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) diff --git a/monitor.c b/monitor.c index 6db2ba4d7a..5dc0aa97f5 100644 --- a/monitor.c +++ b/monitor.c @@ -1164,7 +1164,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize, cpu_physical_memory_read(addr, buf, l); } else { env = mon_get_cpu(); - if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) { + if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) { monitor_printf(mon, " Cannot access memory\n"); break; } diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c index 4ecea65f62..ee469c49c5 100644 --- a/target-arm/arm-semi.c +++ b/target-arm/arm-semi.c @@ -161,7 +161,7 @@ static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err) /* The size is always stored in big-endian order, extract the value. We assume the size always fit in 32 bits. */ uint32_t size; - cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); + cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); env->regs[0] = be32_to_cpu(size); #ifdef CONFIG_USER_ONLY ((TaskState *)env->opaque)->swi_errno = err; diff --git a/target-i386/helper.c b/target-i386/helper.c index 2745292d1d..bf3e2ac73d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -363,7 +363,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "Code="); for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) { - if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) { + if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) { snprintf(codestr, sizeof(codestr), "%02x", code); } else { snprintf(codestr, sizeof(codestr), "??"); @@ -1260,6 +1260,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, target_ulong *base, unsigned int *limit, unsigned int *flags) { + X86CPU *cpu = x86_env_get_cpu(env); + CPUState *cs = CPU(cpu); SegmentCache *dt; target_ulong ptr; uint32_t e1, e2; @@ -1272,8 +1274,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, index = selector & ~7; ptr = dt->base + index; if ((index + 7) > dt->limit - || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 - || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0) + || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 + || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0) return 0; *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 513888267e..3c9d10a762 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1932,25 +1932,23 @@ static int kvm_handle_tpr_access(X86CPU *cpu) return 1; } -int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp) +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - CPUX86State *env = &X86_CPU(cpu)->env; static const uint8_t int3 = 0xcc; - if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || - cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&int3, 1, 1)) { + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) { return -EINVAL; } return 0; } -int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp) +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - CPUX86State *env = &X86_CPU(cpu)->env; uint8_t int3; - if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc || - cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { + if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { return -EINVAL; } return 0; diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index 846d129353..45d08e47a5 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -356,6 +356,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, uint8_t *buf, int len, int is_write) { + CPUState *cs = CPU(sparc_env_get_cpu(env)); int i; int len1; int cwp = env->cwp; @@ -390,7 +391,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, /* Handle access before this window. */ if (addr < fp) { len1 = fp - addr; - if (cpu_memory_rw_debug(env, addr, buf, len1, is_write) != 0) { + if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) { return -1; } addr += len1; @@ -426,7 +427,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, } } } - return cpu_memory_rw_debug(env, addr, buf, len, is_write); + return cpu_memory_rw_debug(cs, addr, buf, len, is_write); } #else /* !TARGET_SPARC64 */ diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c index d9dd22244f..424253d1f3 100644 --- a/target-xtensa/xtensa-semi.c +++ b/target-xtensa/xtensa-semi.c @@ -204,8 +204,8 @@ void HELPER(simcall)(CPUXtensaState *env) int i; for (i = 0; i < ARRAY_SIZE(name); ++i) { - rc = cpu_memory_rw_debug( - env, regs[3] + i, (uint8_t *)name + i, 1, 0); + rc = cpu_memory_rw_debug(cs, regs[3] + i, + (uint8_t *)name + i, 1, 0); if (rc != 0 || name[i] == 0) { break; } @@ -249,7 +249,7 @@ void HELPER(simcall)(CPUXtensaState *env) FD_SET(fd, &fdset); if (target_tv) { - cpu_memory_rw_debug(env, target_tv, + cpu_memory_rw_debug(cs, target_tv, (uint8_t *)target_tvv, sizeof(target_tvv), 0); tv.tv_sec = (int32_t)tswap32(target_tvv[0]); tv.tv_usec = (int32_t)tswap32(target_tvv[1]); @@ -284,8 +284,8 @@ void HELPER(simcall)(CPUXtensaState *env) }; argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text)); - cpu_memory_rw_debug( - env, regs[3], (uint8_t *)&argv, sizeof(argv), 1); + cpu_memory_rw_debug(cs, + regs[3], (uint8_t *)&argv, sizeof(argv), 1); } break; From f3659eee05793aede68b1791465fb2b0767bc1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 19:09:09 +0200 Subject: [PATCH 20/24] cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make inline target_memory_rw_debug() always available and change its argument to CPUState. Let it check if CPUClass::memory_rw_debug provides a specialized callback and fall back to cpu_memory_rw_debug() otherwise. The only overriding implementation is for 32-bit sparc. This prepares for changing GDBState::g_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 21 ++++++++++++--------- include/qom/cpu.h | 3 +++ target-sparc/cpu.c | 3 +++ target-sparc/cpu.h | 5 ++--- target-sparc/mmu_helper.c | 8 +++++--- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 6cefb17ea8..9e017edcf6 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -42,15 +42,16 @@ #include "sysemu/kvm.h" #include "qemu/bitops.h" -#ifndef TARGET_CPU_MEMORY_RW_DEBUG -static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, - uint8_t *buf, int len, int is_write) +static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr, + uint8_t *buf, int len, bool is_write) { - return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write); + CPUClass *cc = CPU_GET_CLASS(cpu); + + if (cc->memory_rw_debug) { + return cc->memory_rw_debug(cpu, addr, buf, len, is_write); + } + return cpu_memory_rw_debug(cpu, addr, buf, len, is_write); } -#else -/* target_memory_rw_debug() defined in cpu.h */ -#endif enum { GDB_SIGNAL_0 = 0, @@ -2248,7 +2249,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, NULL, 16); - if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) { + if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, + false) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); @@ -2263,7 +2265,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ':') p++; hextomem(mem_buf, p, len); - if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) { + if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, + true) != 0) { put_packet(s, "E14"); } else { put_packet(s, "OK"); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 63666464de..f71ec2d041 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -70,6 +70,7 @@ struct TranslationBlock; * @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. @@ -94,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, diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 12494ccaa4..d1d03396ef 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -782,6 +782,9 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = sparc_cpu_do_interrupt; cc->dump_state = sparc_cpu_dump_state; +#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) + cc->memory_rw_debug = sparc_cpu_memory_rw_debug; +#endif cc->set_pc = sparc_cpu_set_pc; cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; #ifndef CONFIG_USER_ONLY diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 0f35a2216f..41194ec06b 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -526,9 +526,8 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env); #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) -int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, - uint8_t *buf, int len, int is_write); -#define TARGET_CPU_MEMORY_RW_DEBUG +int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, + uint8_t *buf, int len, bool is_write); #endif diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index 45d08e47a5..ef12a0a8d0 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -353,10 +353,12 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) * reads (and only reads) in stack frames as if windows were flushed. We assume * that the sparc ABI is followed. */ -int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, - uint8_t *buf, int len, int is_write) +int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address, + uint8_t *buf, int len, bool is_write) { - CPUState *cs = CPU(sparc_env_get_cpu(env)); + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; + target_ulong addr = address; int i; int len1; int cwp = env->cwp; From 2e0f2cfba6c2169c07358e473841ec211009dd3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 27 Jun 2013 19:19:39 +0200 Subject: [PATCH 21/24] gdbstub: Change GDBState::{c,g}_cpu and find_cpu() to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use CPUState::env_ptr where still needed. Signed-off-by: Andreas Färber --- gdbstub.c | 104 +++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 9e017edcf6..ee31603c65 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -288,8 +288,8 @@ enum RSState { RS_CHKSUM2, }; typedef struct GDBState { - CPUArchState *c_cpu; /* current CPU for step/continue ops */ - CPUArchState *g_cpu; /* current CPU for other ops */ + CPUState *c_cpu; /* current CPU for step/continue ops */ + CPUState *g_cpu; /* current CPU for other ops */ CPUState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ char line_buf[MAX_PACKET_LENGTH]; @@ -1958,8 +1958,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) int err = 0; if (kvm_enabled()) { - return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), - addr, len, type); + return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); } switch (type) { @@ -1997,8 +1996,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) int err = 0; if (kvm_enabled()) { - return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), - addr, len, type); + return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type); } switch (type) { @@ -2034,7 +2032,7 @@ static void gdb_breakpoint_remove_all(void) CPUArchState *env; if (kvm_enabled()) { - kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu)); + kvm_remove_all_breakpoints(gdbserver_state->c_cpu); return; } @@ -2049,7 +2047,7 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { - CPUState *cpu = ENV_GET_CPU(s->c_cpu); + CPUState *cpu = s->c_cpu; CPUClass *cc = CPU_GET_CLASS(cpu); cpu_synchronize_state(cpu); @@ -2058,13 +2056,13 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) } } -static CPUArchState *find_cpu(uint32_t thread_id) +static CPUState *find_cpu(uint32_t thread_id) { CPUState *cpu; for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { if (cpu_index(cpu) == thread_id) { - return cpu->env_ptr; + return cpu; } } @@ -2073,7 +2071,10 @@ static CPUArchState *find_cpu(uint32_t thread_id) static int gdb_handle_packet(GDBState *s, const char *line_buf) { +#ifdef TARGET_XTENSA CPUArchState *env; +#endif + CPUState *cpu; const char *p; uint32_t thread; int ch, reg_size, type, res; @@ -2091,7 +2092,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) case '?': /* TODO: Make this return the correct value for user-mode. */ snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP, - cpu_index(ENV_GET_CPU(s->c_cpu))); + cpu_index(s->c_cpu)); put_packet(s, buf); /* Remove all the breakpoints when this query is issued, * because gdb is doing and initial connect and the state @@ -2153,15 +2154,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } if (res) { if (res_thread != -1 && res_thread != 0) { - env = find_cpu(res_thread); - if (env == NULL) { + cpu = find_cpu(res_thread); + if (cpu == NULL) { put_packet(s, "E22"); break; } - s->c_cpu = env; + s->c_cpu = cpu; } if (res == 's') { - cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); + cpu_single_step(s->c_cpu, sstep_flags); } s->signal = res_signal; gdb_continue(s); @@ -2189,7 +2190,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) addr = strtoull(p, (char **)&p, 16); gdb_set_cpu_pc(s, addr); } - cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); + cpu_single_step(s->c_cpu, sstep_flags); gdb_continue(s); return RS_IDLE; case 'F': @@ -2208,7 +2209,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; type = *p; if (s->current_syscall_cb) { - s->current_syscall_cb(ENV_GET_CPU(s->c_cpu), ret, err); + s->current_syscall_cb(s->c_cpu, ret, err); s->current_syscall_cb = NULL; } if (type == 'C') { @@ -2219,26 +2220,28 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } break; case 'g': - cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); - env = s->g_cpu; + cpu_synchronize_state(s->g_cpu); +#ifdef TARGET_XTENSA + env = s->g_cpu->env_ptr; +#endif len = 0; for (addr = 0; addr < num_g_regs; addr++) { - reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), - mem_buf + len, addr); + reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); len += reg_size; } memtohex(buf, mem_buf, len); put_packet(s, buf); break; case 'G': - cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); - env = s->g_cpu; + cpu_synchronize_state(s->g_cpu); +#ifdef TARGET_XTENSA + env = s->g_cpu->env_ptr; +#endif registers = mem_buf; len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); for (addr = 0; addr < num_g_regs && len > 0; addr++) { - reg_size = gdb_write_register(ENV_GET_CPU(s->g_cpu), registers, - addr); + reg_size = gdb_write_register(s->g_cpu, registers, addr); len -= reg_size; registers += reg_size; } @@ -2249,8 +2252,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, NULL, 16); - if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, - false) != 0) { + if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); @@ -2265,7 +2267,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ':') p++; hextomem(mem_buf, p, len); - if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, + if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, true) != 0) { put_packet(s, "E14"); } else { @@ -2279,7 +2281,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (!gdb_has_xml) goto unknown_command; addr = strtoull(p, (char **)&p, 16); - reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); + reg_size = gdb_read_register(s->g_cpu, mem_buf, addr); if (reg_size) { memtohex(buf, mem_buf, reg_size); put_packet(s, buf); @@ -2295,7 +2297,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; reg_size = strlen(p) / 2; hextomem(mem_buf, p, reg_size); - gdb_write_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); + gdb_write_register(s->g_cpu, mem_buf, addr); put_packet(s, "OK"); break; case 'Z': @@ -2325,18 +2327,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "OK"); break; } - env = find_cpu(thread); - if (env == NULL) { + cpu = find_cpu(thread); + if (cpu == NULL) { put_packet(s, "E22"); break; } switch (type) { case 'c': - s->c_cpu = env; + s->c_cpu = cpu; put_packet(s, "OK"); break; case 'g': - s->g_cpu = env; + s->g_cpu = cpu; put_packet(s, "OK"); break; default: @@ -2346,9 +2348,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'T': thread = strtoull(p, (char **)&p, 16); - env = find_cpu(thread); + cpu = find_cpu(thread); - if (env != NULL) { + if (cpu != NULL) { put_packet(s, "OK"); } else { put_packet(s, "E22"); @@ -2398,9 +2400,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) { thread = strtoull(p+16, (char **)&p, 16); - env = find_cpu(thread); - if (env != NULL) { - CPUState *cpu = ENV_GET_CPU(env); + cpu = find_cpu(thread); + if (cpu != NULL) { cpu_synchronize_state(cpu); len = snprintf((char *)mem_buf, sizeof(mem_buf), "CPU#%d [%s]", cpu->cpu_index, @@ -2412,7 +2413,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } #ifdef CONFIG_USER_ONLY else if (strncmp(p, "Offsets", 7) == 0) { - TaskState *ts = s->c_cpu->opaque; + CPUArchState *env = s->c_cpu->env_ptr; + TaskState *ts = env->opaque; snprintf(buf, sizeof(buf), "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx @@ -2502,18 +2504,16 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) void gdb_set_stop_cpu(CPUState *cpu) { - CPUArchState *env = cpu->env_ptr; - - gdbserver_state->c_cpu = env; - gdbserver_state->g_cpu = env; + gdbserver_state->c_cpu = cpu; + gdbserver_state->g_cpu = cpu; } #ifndef CONFIG_USER_ONLY static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; - CPUArchState *env = s->c_cpu; - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = s->c_cpu->env_ptr; + CPUState *cpu = s->c_cpu; char buf[256]; const char *type; int ret; @@ -2643,7 +2643,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) va_end(va); #ifdef CONFIG_USER_ONLY put_packet(s, s->syscall_buf); - gdb_handlesig(ENV_GET_CPU(s->c_cpu), 0); + gdb_handlesig(s->c_cpu, 0); #else /* In this case wait to send the syscall packet until notification that the CPU has stopped. This must be done because if the packet is sent @@ -2651,7 +2651,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) is still in the running state, which can cause packets to be dropped and state transition 'T' packets to be sent while the syscall is still being processed. */ - cpu_exit(ENV_GET_CPU(s->c_cpu)); + cpu_exit(s->c_cpu); #endif } @@ -2860,8 +2860,8 @@ static void gdb_accept(void) socket_set_nodelay(fd); s = g_malloc0(sizeof(GDBState)); - s->c_cpu = first_cpu->env_ptr; - s->g_cpu = first_cpu->env_ptr; + s->c_cpu = first_cpu; + s->g_cpu = first_cpu; s->fd = fd; gdb_has_xml = 0; @@ -3045,8 +3045,8 @@ int gdbserver_start(const char *device) mon_chr = s->mon_chr; memset(s, 0, sizeof(GDBState)); } - s->c_cpu = first_cpu->env_ptr; - s->g_cpu = first_cpu->env_ptr; + s->c_cpu = first_cpu; + s->g_cpu = first_cpu; s->chr = chr; s->state = chr ? RS_IDLE : RS_INACTIVE; s->mon_chr = mon_chr; From eac8b355f0015e44addce3e92030365b16d9da61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 21:11:37 +0200 Subject: [PATCH 22/24] cpu: Move gdb_regs field from CPU_COMMON to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepares for changing gdb_register_coprocessor() argument to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 11 ++++++----- include/exec/cpu-defs.h | 2 -- include/qom/cpu.h | 2 ++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index ee31603c65..e58d06ead9 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1840,7 +1840,7 @@ static const char *get_feature_xml(const char *p, const char **newp) /* Generate the XML description for this CPU. */ if (!target_xml[0]) { GDBRegisterState *r; - CPUArchState *env = first_cpu->env_ptr; + CPUState *cpu = first_cpu; snprintf(target_xml, sizeof(target_xml), "" @@ -1849,7 +1849,7 @@ static const char *get_feature_xml(const char *p, const char **newp) "", GDB_CORE_XML); - for (r = env->gdb_regs; r; r = r->next) { + for (r = cpu->gdb_regs; r; r = r->next) { pstrcat(target_xml, sizeof(target_xml), "xml); pstrcat(target_xml, sizeof(target_xml), "\"/>"); @@ -1875,7 +1875,7 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) if (reg < NUM_CORE_REGS) return cpu_gdb_read_register(env, mem_buf, reg); - for (r = env->gdb_regs; r; r = r->next) { + for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->get_reg(env, mem_buf, reg - r->base_reg); } @@ -1891,7 +1891,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) if (reg < NUM_CORE_REGS) return cpu_gdb_write_register(env, mem_buf, reg); - for (r = env->gdb_regs; r; r = r->next) { + for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->set_reg(env, mem_buf, reg - r->base_reg); } @@ -1910,11 +1910,12 @@ void gdb_register_coprocessor(CPUArchState * env, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos) { + CPUState *cpu = ENV_GET_CPU(env); GDBRegisterState *s; GDBRegisterState **p; static int last_reg = NUM_CORE_REGS; - p = &env->gdb_regs; + p = &cpu->gdb_regs; while (*p) { /* Check for duplicates. */ if (strcmp((*p)->xml, xml) == 0) diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 12b1ca7426..b5b93db842 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -174,8 +174,6 @@ typedef struct CPUWatchpoint { QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \ CPUWatchpoint *watchpoint_hit; \ \ - struct GDBRegisterState *gdb_regs; \ - \ /* Core interrupt code */ \ sigjmp_buf jmp_env; \ int exception_index; \ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index f71ec2d041..daf1835c1a 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -141,6 +141,7 @@ struct kvm_run; * @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. * @@ -175,6 +176,7 @@ struct CPUState { void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; + struct GDBRegisterState *gdb_regs; CPUState *next_cpu; int kvm_fd; From 22169d415a1d1706f66a4fd50a3573d3f296b24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 21:27:39 +0200 Subject: [PATCH 23/24] gdbstub: Change gdb_register_coprocessor() argument to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 7 +++---- include/exec/gdbstub.h | 2 +- target-arm/helper.c | 7 ++++--- target-m68k/helper.c | 3 ++- target-ppc/translate_init.c | 15 ++++++++------- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index e58d06ead9..35ca7c2c1e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1906,11 +1906,10 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) gdb reading a CPU register, and set_reg is gdb modifying a CPU register. */ -void gdb_register_coprocessor(CPUArchState * env, - gdb_reg_cb get_reg, gdb_reg_cb set_reg, - int num_regs, const char *xml, int g_pos) +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) { - CPUState *cpu = ENV_GET_CPU(env); GDBRegisterState *s; GDBRegisterState **p; static int last_reg = NUM_CORE_REGS; diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 0f1ad9a64e..1bd00aea23 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -26,7 +26,7 @@ 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); diff --git a/target-arm/helper.c b/target-arm/helper.c index 9105ad98c0..b0c3ca1fbe 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1513,16 +1513,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model) void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) { + CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; if (arm_feature(env, ARM_FEATURE_NEON)) { - gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 51, "arm-neon.xml", 0); } else if (arm_feature(env, ARM_FEATURE_VFP3)) { - gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 35, "arm-vfp3.xml", 0); } else if (arm_feature(env, ARM_FEATURE_VFP)) { - gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 19, "arm-vfp.xml", 0); } } diff --git a/target-m68k/helper.c b/target-m68k/helper.c index dcadfabeaa..00a7a08e83 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -121,10 +121,11 @@ M68kCPU *cpu_m68k_init(const char *cpu_model) void m68k_cpu_init_gdb(M68kCPU *cpu) { + CPUState *cs = CPU(cpu); CPUM68KState *env = &cpu->env; if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { - gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg, + gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg, 11, "cf-fp.xml", 18); } /* TODO: Add [E]MAC registers. */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 0fc9014f56..0b0844f467 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7804,8 +7804,8 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu) static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) { + CPUState *cs = CPU(dev); PowerPCCPU *cpu = POWERPC_CPU(dev); - CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); Error *local_err = NULL; #if !defined(CONFIG_USER_ONLY) @@ -7849,15 +7849,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) init_ppc_proc(cpu); if (pcc->insns_flags & PPC_FLOAT) { - gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg, + gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, 33, "power-fpu.xml", 0); } if (pcc->insns_flags & PPC_ALTIVEC) { - gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg, + gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, 34, "power-altivec.xml", 0); } if (pcc->insns_flags & PPC_SPE) { - gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg, + gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, 34, "power-spe.xml", 0); } @@ -7865,6 +7865,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) #if defined(PPC_DUMP_CPU) { + CPUPPCState *env = &cpu->env; const char *mmu_model, *excp_model, *bus_model; switch (env->mmu_model) { case POWERPC_MMU_32B: @@ -8016,10 +8017,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) printf(" none\n"); printf(" Time-base/decrementer clock source: %s\n", env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock"); + dump_ppc_insns(env); + dump_ppc_sprs(env); + fflush(stdout); } - dump_ppc_insns(env); - dump_ppc_sprs(env); - fflush(stdout); #endif } From 6f152e9bc80aed81ea89aa8ad345cd71326b71fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 May 2012 00:01:58 +0200 Subject: [PATCH 24/24] linux-user: Use X86CPU property to retrieve CPUID family MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids duplicating the calculation. Reviewed-by: Igor Mammedov Signed-off-by: Andreas Färber --- linux-user/cpu-uname.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/linux-user/cpu-uname.c b/linux-user/cpu-uname.c index 59cd6477d5..cc713e6553 100644 --- a/linux-user/cpu-uname.c +++ b/linux-user/cpu-uname.c @@ -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 */