diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-07-23 10:57:04 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-07-23 10:57:04 -0500 |
commit | 3988982c82ad4173dea376fea30e5432d36146db (patch) | |
tree | a4f72b53b9db680859ecc16b43dae4f113e1b744 /include | |
parent | 931f0adf64261bf7eb3efaafb4430c04a6a3e6f6 (diff) | |
parent | 6f152e9bc80aed81ea89aa8ad345cd71326b71fb (diff) |
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
QOM CPUState refactorings
* Fix NULL pointer dereference in gdbstub
* Introduce vaddr type
* Introduce CPUClass::set_pc()
* Introduce CPUClass::synchronize_from_tb()
* Introduce CPUClass::get_phys_page_debug()
* Introduce CPUClass::memory_rw_debug()
* Move singlestep_enabled and gdb_regs fields out of CPU_COMMON
* Adopt CPUState in more APIs
* Propagate CPUState in gdbstub
# gpg: Signature made Mon 22 Jul 2013 07:50:17 PM CDT using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found
# By Andreas Färber (21) and others
# Via Andreas Färber
* afaerber/tags/qom-cpu-for-anthony: (24 commits)
linux-user: Use X86CPU property to retrieve CPUID family
gdbstub: Change gdb_register_coprocessor() argument to CPUState
cpu: Move gdb_regs field from CPU_COMMON to CPUState
gdbstub: Change GDBState::{c,g}_cpu and find_cpu() to CPUState
cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug()
exec: Change cpu_memory_rw_debug() argument to CPUState
cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
gdbstub: Change gdb_{read,write}_register() argument to CPUState
gdbstub: Change gdb_handlesig() argument to CPUState
gdbstub: Change syscall callback argument to CPUState
kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState
cpu: Change cpu_single_step() argument to CPUState
gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
target-alpha: Copy implver to DisasContext
target-alpha: Copy singlestep_enabled to DisasContext
cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb()
target-unicore32: Implement CPUClass::set_pc()
target-moxie: Implement CPUClass::set_pc()
target-m68k: Implement CPUClass::set_pc()
...
Diffstat (limited to 'include')
-rw-r--r-- | include/exec/cpu-all.h | 14 | ||||
-rw-r--r-- | include/exec/cpu-defs.h | 3 | ||||
-rw-r--r-- | include/exec/gdbstub.h | 6 | ||||
-rw-r--r-- | include/exec/softmmu-semi.h | 18 | ||||
-rw-r--r-- | include/qom/cpu.h | 113 | ||||
-rw-r--r-- | include/sysemu/kvm.h | 4 |
6 files changed, 77 insertions, 81 deletions
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 5084202217..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: * @@ -428,19 +429,8 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint); void cpu_watchpoint_remove_all(CPUArchState *env, int mask); -#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ -#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ -#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ - -void cpu_single_step(CPUArchState *env, int enabled); - #if !defined(CONFIG_USER_ONLY) -/* Return the physical page corresponding to a virtual one. Use it - only for debugging because no protection checks are done. Return -1 - if no page found. */ -hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr); - /* memory API */ extern ram_addr_t ram_size; @@ -494,7 +484,7 @@ void qemu_mutex_lock_ramlist(void); void qemu_mutex_unlock_ramlist(void); #endif /* !CONFIG_USER_ONLY */ -int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, +int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write); #endif /* CPU_ALL_H */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 39094b3f48..b5b93db842 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -170,13 +170,10 @@ typedef struct CPUWatchpoint { /* from this point: preserved by CPU reset */ \ /* ice debug support */ \ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \ - int singlestep_enabled; \ \ QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \ CPUWatchpoint *watchpoint_hit; \ \ - struct GDBRegisterState *gdb_regs; \ - \ /* Core interrupt code */ \ sigjmp_buf jmp_env; \ int exception_index; \ diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index ded4160e57..1bd00aea23 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, ...); @@ -20,13 +20,13 @@ void gdb_set_stop_cpu(CPUState *cpu); void gdb_exit(CPUArchState *, int); #ifdef CONFIG_USER_ONLY int gdb_queuesig (void); -int gdb_handlesig (CPUArchState *, int); +int gdb_handlesig(CPUState *, int); void gdb_signalled(CPUArchState *, int); void gdbserver_fork(CPUArchState *); #endif /* Get or set a register. Returns the size of the register. */ typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); -void gdb_register_coprocessor(CPUArchState *env, +void gdb_register_coprocessor(CPUState *cpu, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos); 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/include/qom/cpu.h b/include/qom/cpu.h index dfd81a1d2f..daf1835c1a 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -30,6 +30,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 * @title: CPU Class @@ -48,6 +60,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, bool is_write, bool is_exec, int opaque, unsigned size); +struct TranslationBlock; + /** * CPUClass: * @class_by_name: Callback to map -cpu command line model name to an @@ -56,11 +70,16 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, * @reset_dump_flags: #CPUDumpFlags to use for reset logging. * @do_interrupt: Callback for interrupt handling. * @do_unassigned_access: Callback for unassigned access handling. + * @memory_rw_debug: Callback for GDB memory access. * @dump_state: Callback for dumping state. * @dump_statistics: Callback for dumping statistics. * @get_arch_id: Callback for getting architecture-dependent CPU ID. * @get_paging_enabled: Callback for inquiring whether paging is enabled. * @get_memory_mapping: Callback for obtaining the memory mappings. + * @set_pc: Callback for setting the Program Counter register. + * @synchronize_from_tb: Callback for synchronizing state from a TCG + * #TranslationBlock. + * @get_phys_page_debug: Callback for obtaining a physical address. * @vmsd: State description for migration. * * Represents a CPU family or model. @@ -76,6 +95,8 @@ typedef struct CPUClass { int reset_dump_flags; void (*do_interrupt)(CPUState *cpu); CPUUnassignedAccess do_unassigned_access; + int (*memory_rw_debug)(CPUState *cpu, vaddr addr, + uint8_t *buf, int len, bool is_write); void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); void (*dump_statistics)(CPUState *cpu, FILE *f, @@ -84,6 +105,9 @@ typedef struct CPUClass { bool (*get_paging_enabled)(const CPUState *cpu); void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); + void (*set_pc)(CPUState *cpu, vaddr value); + void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); + hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, @@ -114,8 +138,10 @@ struct kvm_run; * @stopped: Indicates the CPU has been artificially stopped. * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this * CPU and return to its top level loop. + * @singlestep_enabled: Flags for single-stepping. * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. + * @gdb_regs: Additional GDB registers. * @next_cpu: Next CPU sharing TB cache. * @kvm_fd: vCPU file descriptor for KVM. * @@ -146,9 +172,11 @@ struct CPUState { volatile sig_atomic_t exit_request; volatile sig_atomic_t tcg_exit_req; uint32_t interrupt_request; + int singlestep_enabled; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; + struct GDBRegisterState *gdb_regs; CPUState *next_cpu; int kvm_fd; @@ -259,6 +287,25 @@ void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +#ifndef CONFIG_USER_ONLY +/** + * cpu_get_phys_page_debug: + * @cpu: The CPU to obtain the physical page address for. + * @addr: The virtual address. + * + * Obtains the physical page corresponding to a virtual one. + * Use it only for debugging because no protection checks are done. + * + * Returns: Corresponding physical page address or -1 if no page found. + */ +static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return cc->get_phys_page_debug(cpu, addr); +} +#endif + /** * cpu_reset: * @cpu: The CPU whose state is to be reset. @@ -277,59 +324,6 @@ void cpu_reset(CPUState *cpu); ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); /** - * cpu_class_set_vmsd: - * @cc: CPU class - * @value: Value to set. Unused for %CONFIG_USER_ONLY. - * - * Sets #VMStateDescription for @cc. - * - * The @value argument is intentionally discarded for the non-softmmu targets - * to avoid linker errors or excessive preprocessor usage. If this behavior - * is undesired, you should assign #CPUClass.vmsd directly instead. - */ -#ifndef CONFIG_USER_ONLY -static inline void cpu_class_set_vmsd(CPUClass *cc, - const struct VMStateDescription *value) -{ - cc->vmsd = value; -} -#else -#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL) -#endif - -#ifndef CONFIG_USER_ONLY -static inline void cpu_class_set_do_unassigned_access(CPUClass *cc, - CPUUnassignedAccess value) -{ - cc->do_unassigned_access = value; -} -#else -#define cpu_class_set_do_unassigned_access(cc, value) \ - ((cc)->do_unassigned_access = NULL) -#endif - -/** - * device_class_set_vmsd: - * @dc: Device class - * @value: Value to set. Unused for %CONFIG_USER_ONLY. - * - * Sets #VMStateDescription for @dc. - * - * The @value argument is intentionally discarded for the non-softmmu targets - * to avoid linker errors or excessive preprocessor usage. If this behavior - * is undesired, you should assign #DeviceClass.vmsd directly instead. - */ -#ifndef CONFIG_USER_ONLY -static inline void device_class_set_vmsd(DeviceClass *dc, - const struct VMStateDescription *value) -{ - dc->vmsd = value; -} -#else -#define device_class_set_vmsd(dc, value) ((dc)->vmsd = NULL) -#endif - -/** * qemu_cpu_has_work: * @cpu: The vCPU to check. * @@ -489,6 +483,19 @@ void cpu_resume(CPUState *cpu); */ void qemu_init_vcpu(CPUState *cpu); +#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ +#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ +#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ + +/** + * cpu_single_step: + * @cpu: CPU to the flags for. + * @enabled: Flags to enable. + * + * Enables or disables single-stepping for @cpu. + */ +void cpu_single_step(CPUState *cpu, int enabled); + #ifdef CONFIG_SOFTMMU extern const struct VMStateDescription vmstate_cpu_common; #else 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); |