X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=include%2Fqom%2Fcpu.h;h=94302a415ecdfa85abd0b1e3944e48174e31577b;hb=ed2803da58355413447f8c7c681a76873168114f;hp=ac93dcec6639ddda8a44cc2ab87e97bc57e18871;hpb=2993683b0fde0f836777c945baaddcaa5937903f;p=qemu.git diff --git a/include/qom/cpu.h b/include/qom/cpu.h index ac93dcec6..94302a415 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -22,7 +22,24 @@ #include #include "hw/qdev-core.h" +#include "exec/hwaddr.h" #include "qemu/thread.h" +#include "qemu/tls.h" +#include "qemu/typedefs.h" + +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 @@ -39,12 +56,28 @@ typedef struct CPUState CPUState; +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 * instantiatable CPU type. * @reset: Callback to reset the #CPUState to its initial state. + * @reset_dump_flags: #CPUDumpFlags to use for reset logging. * @do_interrupt: Callback for interrupt handling. + * @do_unassigned_access: Callback for unassigned access handling. + * @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. * @vmsd: State description for migration. * * Represents a CPU family or model. @@ -57,9 +90,29 @@ typedef struct CPUClass { ObjectClass *(*class_by_name)(const char *cpu_model); void (*reset)(CPUState *cpu); + int reset_dump_flags; void (*do_interrupt)(CPUState *cpu); + CPUUnassignedAccess do_unassigned_access; + void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, + int flags); + void (*dump_statistics)(CPUState *cpu, FILE *f, + fprintf_function cpu_fprintf, int flags); + int64_t (*get_arch_id)(CPUState *cpu); + 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); const struct VMStateDescription *vmsd; + int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque); + int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque); + int (*write_elf32_note)(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque); + int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque); } CPUClass; struct KVMState; @@ -80,8 +133,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. + * @next_cpu: Next CPU sharing TB cache. * @kvm_fd: vCPU file descriptor for KVM. * * State of one CPU core or thread. @@ -111,9 +166,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; + CPUState *next_cpu; int kvm_fd; bool kvm_vcpu_dirty; @@ -125,6 +182,103 @@ struct CPUState { uint32_t halted; /* used by alpha, cris, ppc TCG */ }; +extern CPUState *first_cpu; + +DECLARE_TLS(CPUState *, current_cpu); +#define current_cpu tls_var(current_cpu) + +/** + * cpu_paging_enabled: + * @cpu: The CPU whose state is to be inspected. + * + * Returns: %true if paging is enabled, %false otherwise. + */ +bool cpu_paging_enabled(const CPUState *cpu); + +/** + * cpu_get_memory_mapping: + * @cpu: The CPU whose memory mappings are to be obtained. + * @list: Where to write the memory mappings to. + * @errp: Pointer for reporting an #Error. + */ +void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, + Error **errp); + +/** + * cpu_write_elf64_note: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque); + +/** + * cpu_write_elf64_qemunote: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque); + +/** + * cpu_write_elf32_note: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque); + +/** + * cpu_write_elf32_qemunote: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque); + +/** + * CPUDumpFlags: + * @CPU_DUMP_CODE: + * @CPU_DUMP_FPU: dump FPU register state, not just integer + * @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state + */ +enum CPUDumpFlags { + CPU_DUMP_CODE = 0x00010000, + CPU_DUMP_FPU = 0x00020000, + CPU_DUMP_CCOP = 0x00040000, +}; + +/** + * cpu_dump_state: + * @cpu: The CPU whose state is to be dumped. + * @f: File to dump to. + * @cpu_fprintf: Function to dump with. + * @flags: Flags what to dump. + * + * Dumps CPU state. + */ +void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, + int flags); + +/** + * cpu_dump_statistics: + * @cpu: The CPU whose state is to be dumped. + * @f: File to dump to. + * @cpu_fprintf: Function to dump with. + * @flags: Flags what to dump. + * + * Dumps CPU statistics. + */ +void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, + int flags); /** * cpu_reset: @@ -152,7 +306,7 @@ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); * * 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 #CPUState.vmsd directly instead. + * is undesired, you should assign #CPUClass.vmsd directly instead. */ #ifndef CONFIG_USER_ONLY static inline void cpu_class_set_vmsd(CPUClass *cc, @@ -164,6 +318,38 @@ static inline void cpu_class_set_vmsd(CPUClass *cc, #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. @@ -213,6 +399,25 @@ bool cpu_is_stopped(CPUState *cpu); */ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); +/** + * async_run_on_cpu: + * @cpu: The vCPU to run on. + * @func: The function to be executed. + * @data: Data to pass to the function. + * + * Schedules the function @func for execution on the vCPU @cpu asynchronously. + */ +void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); + +/** + * qemu_for_each_cpu: + * @func: The function to be executed. + * @data: Data to pass to the function. + * + * Executes @func for each CPU. + */ +void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data); + /** * qemu_get_cpu: * @index: The CPUState@cpu_index value of the CPU to obtain. @@ -223,6 +428,16 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); */ CPUState *qemu_get_cpu(int index); +/** + * cpu_exists: + * @id: Guest-exposed CPU ID to lookup. + * + * Search for CPU with specified ID. + * + * Returns: %true - CPU is found, %false - CPU isn't found. + */ +bool cpu_exists(int64_t id); + #ifndef CONFIG_USER_ONLY typedef void (*CPUInterruptHandler)(CPUState *, int); @@ -247,6 +462,21 @@ void cpu_interrupt(CPUState *cpu, int mask); #endif /* USER_ONLY */ +#ifndef CONFIG_USER_ONLY + +static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr, + bool is_write, bool is_exec, + int opaque, unsigned size) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + if (cc->do_unassigned_access) { + cc->do_unassigned_access(cpu, addr, is_write, is_exec, opaque, size); + } +} + +#endif + /** * cpu_reset_interrupt: * @cpu: The CPU to clear the interrupt on. @@ -256,6 +486,14 @@ void cpu_interrupt(CPUState *cpu, int mask); */ void cpu_reset_interrupt(CPUState *cpu, int mask); +/** + * cpu_exit: + * @cpu: The CPU to exit. + * + * Requests the CPU @cpu to exit execution. + */ +void cpu_exit(CPUState *cpu); + /** * cpu_resume: * @cpu: The CPU to resume. @@ -264,4 +502,26 @@ void cpu_reset_interrupt(CPUState *cpu, int mask); */ void cpu_resume(CPUState *cpu); +/** + * qemu_init_vcpu: + * @cpu: The vCPU to initialize. + * + * Initializes a vCPU. + */ +void qemu_init_vcpu(CPUState *cpu); + +#ifdef CONFIG_SOFTMMU +extern const struct VMStateDescription vmstate_cpu_common; +#else +#define vmstate_cpu_common vmstate_dummy +#endif + +#define VMSTATE_CPU() { \ + .name = "parent_obj", \ + .size = sizeof(CPUState), \ + .vmsd = &vmstate_cpu_common, \ + .flags = VMS_STRUCT, \ + .offset = 0, \ +} + #endif