mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-03 16:35:46 +00:00
handle some errors properly so avoid exit() during initialization. this fixes issue #237
This commit is contained in:
parent
116d96692d
commit
2f297bdd3a
|
@ -58,6 +58,7 @@ module Common =
|
|||
let UC_ERR_WRITE_UNALIGNED = 17
|
||||
let UC_ERR_FETCH_UNALIGNED = 18
|
||||
let UC_ERR_HOOK_EXIST = 19
|
||||
let UC_ERR_RESOURCE = 20
|
||||
let UC_MEM_READ = 16
|
||||
let UC_MEM_WRITE = 17
|
||||
let UC_MEM_FETCH = 18
|
||||
|
|
|
@ -53,6 +53,7 @@ const (
|
|||
ERR_WRITE_UNALIGNED = 17
|
||||
ERR_FETCH_UNALIGNED = 18
|
||||
ERR_HOOK_EXIST = 19
|
||||
ERR_RESOURCE = 20
|
||||
MEM_READ = 16
|
||||
MEM_WRITE = 17
|
||||
MEM_FETCH = 18
|
||||
|
|
|
@ -55,6 +55,7 @@ public interface UnicornConst {
|
|||
public static final int UC_ERR_WRITE_UNALIGNED = 17;
|
||||
public static final int UC_ERR_FETCH_UNALIGNED = 18;
|
||||
public static final int UC_ERR_HOOK_EXIST = 19;
|
||||
public static final int UC_ERR_RESOURCE = 20;
|
||||
public static final int UC_MEM_READ = 16;
|
||||
public static final int UC_MEM_WRITE = 17;
|
||||
public static final int UC_MEM_FETCH = 18;
|
||||
|
|
|
@ -51,6 +51,7 @@ UC_ERR_READ_UNALIGNED = 16
|
|||
UC_ERR_WRITE_UNALIGNED = 17
|
||||
UC_ERR_FETCH_UNALIGNED = 18
|
||||
UC_ERR_HOOK_EXIST = 19
|
||||
UC_ERR_RESOURCE = 20
|
||||
UC_MEM_READ = 16
|
||||
UC_MEM_WRITE = 17
|
||||
UC_MEM_FETCH = 18
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf, int l
|
|||
typedef void (*uc_args_void_t)(void*);
|
||||
|
||||
typedef void (*uc_args_uc_t)(struct uc_struct*);
|
||||
typedef int (*uc_args_int_uc_t)(struct uc_struct*);
|
||||
|
||||
typedef bool (*uc_args_tcg_enable_t)(struct uc_struct*);
|
||||
|
||||
|
@ -91,7 +92,8 @@ struct uc_struct {
|
|||
uc_args_uc_u64_t set_pc; // set PC for tracecode
|
||||
uc_args_int_t stop_interrupt; // check if the interrupt should stop emulation
|
||||
|
||||
uc_args_uc_t init_arch, pause_all_vcpus, vm_start, cpu_exec_init_all;
|
||||
uc_args_uc_t init_arch, pause_all_vcpus, cpu_exec_init_all;
|
||||
uc_args_int_uc_t vm_start;
|
||||
uc_args_tcg_enable_t tcg_enabled;
|
||||
uc_args_uc_long_t tcg_exec_init;
|
||||
uc_args_uc_ram_size_t memory_map;
|
||||
|
|
|
@ -125,6 +125,7 @@ typedef enum uc_err {
|
|||
UC_ERR_WRITE_UNALIGNED, // Unaligned write
|
||||
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
|
||||
UC_ERR_HOOK_EXIST, // hook for this event already existed
|
||||
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
|
||||
} uc_err;
|
||||
|
||||
|
||||
|
|
37
qemu/cpus.c
37
qemu/cpus.c
|
@ -37,16 +37,19 @@ static bool cpu_can_run(CPUState *cpu);
|
|||
static void cpu_handle_guest_debug(CPUState *cpu);
|
||||
static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env);
|
||||
static bool tcg_exec_all(struct uc_struct* uc);
|
||||
static void qemu_tcg_init_vcpu(CPUState *cpu);
|
||||
static int qemu_tcg_init_vcpu(CPUState *cpu);
|
||||
static void *qemu_tcg_cpu_thread_fn(void *arg);
|
||||
|
||||
void vm_start(struct uc_struct* uc)
|
||||
int vm_start(struct uc_struct* uc)
|
||||
{
|
||||
resume_all_vcpus(uc);
|
||||
if (resume_all_vcpus(uc)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//sleep(3);
|
||||
// kick off TCG thread
|
||||
qemu_mutex_unlock_iothread(uc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cpu_is_stopped(CPUState *cpu)
|
||||
|
@ -78,7 +81,7 @@ void pause_all_vcpus(struct uc_struct *uc)
|
|||
}
|
||||
|
||||
|
||||
void resume_all_vcpus(struct uc_struct *uc)
|
||||
int resume_all_vcpus(struct uc_struct *uc)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
|
@ -93,7 +96,8 @@ void resume_all_vcpus(struct uc_struct *uc)
|
|||
CPU_FOREACH(cpu) {
|
||||
cpu->created = true;
|
||||
cpu->halted = 0;
|
||||
qemu_init_vcpu(cpu);
|
||||
if (qemu_init_vcpu(cpu))
|
||||
return -1;
|
||||
}
|
||||
qemu_mutex_lock_iothread(uc);
|
||||
}
|
||||
|
@ -103,18 +107,21 @@ void resume_all_vcpus(struct uc_struct *uc)
|
|||
CPU_FOREACH(cpu) {
|
||||
cpu_resume(cpu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qemu_init_vcpu(CPUState *cpu)
|
||||
int qemu_init_vcpu(CPUState *cpu)
|
||||
{
|
||||
cpu->nr_cores = smp_cores;
|
||||
cpu->nr_threads = smp_threads;
|
||||
cpu->stopped = true;
|
||||
cpu->uc->tcg_cpu_thread = NULL;
|
||||
|
||||
if (tcg_enabled(cpu->uc)) {
|
||||
qemu_tcg_init_vcpu(cpu);
|
||||
}
|
||||
if (tcg_enabled(cpu->uc))
|
||||
return qemu_tcg_init_vcpu(cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,7 +140,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
|||
}
|
||||
qemu_cond_signal(&uc->qemu_cpu_cond);
|
||||
|
||||
|
||||
/* wait for initial kick-off after machine start */
|
||||
while (QTAILQ_FIRST(&uc->cpus)->stopped) {
|
||||
qemu_cond_wait(uc->tcg_halt_cond, &uc->qemu_global_mutex);
|
||||
|
@ -170,7 +176,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
|||
/* For temporary buffers for forming a name */
|
||||
#define VCPU_THREAD_NAME_SIZE 16
|
||||
|
||||
static void qemu_tcg_init_vcpu(CPUState *cpu)
|
||||
static int qemu_tcg_init_vcpu(CPUState *cpu)
|
||||
{
|
||||
struct uc_struct *uc = cpu->uc;
|
||||
char thread_name[VCPU_THREAD_NAME_SIZE];
|
||||
|
@ -185,8 +191,9 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
|
|||
uc->tcg_halt_cond = cpu->halt_cond;
|
||||
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
|
||||
cpu->cpu_index);
|
||||
qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn,
|
||||
cpu, QEMU_THREAD_JOINABLE);
|
||||
if (qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn,
|
||||
cpu, QEMU_THREAD_JOINABLE))
|
||||
return -1;
|
||||
#ifdef _WIN32
|
||||
cpu->hThread = qemu_thread_get_handle(cpu->thread);
|
||||
#endif
|
||||
|
@ -198,6 +205,8 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
|
|||
cpu->thread = uc->tcg_cpu_thread;
|
||||
cpu->halt_cond = uc->tcg_halt_cond;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env)
|
||||
|
|
|
@ -17,10 +17,12 @@
|
|||
#include "exec/address-spaces.h"
|
||||
|
||||
|
||||
static void tosa_init(struct uc_struct *uc, MachineState *machine)
|
||||
static int tosa_init(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
//cpu_arm_init(uc, "pxa255");
|
||||
cpu_arm_init(uc, "cortex-a15"); // FIXME
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tosa_machine_init(struct uc_struct *uc)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "exec/address-spaces.h"
|
||||
|
||||
|
||||
static void machvirt_init(struct uc_struct *uc, MachineState *machine)
|
||||
static int machvirt_init(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
const char *cpu_model = machine->cpu_model;
|
||||
int n;
|
||||
|
@ -51,12 +51,14 @@ static void machvirt_init(struct uc_struct *uc, MachineState *machine)
|
|||
|
||||
if (!oc) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpuobj = object_new(uc, object_class_get_name(oc));
|
||||
object_property_set_bool(uc, cpuobj, true, "realized", NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void machvirt_machine_init(struct uc_struct *uc)
|
||||
|
|
|
@ -155,7 +155,7 @@ static bool device_get_realized(struct uc_struct *uc, Object *obj, Error **errp)
|
|||
return dev->realized;
|
||||
}
|
||||
|
||||
static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, Error **errp)
|
||||
static int device_set_realized(struct uc_struct *uc, Object *obj, bool value, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(uc, obj);
|
||||
DeviceClass *dc = DEVICE_GET_CLASS(uc, dev);
|
||||
|
@ -164,7 +164,7 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
|
|||
|
||||
if (dev->hotplugged && !dc->hotpluggable) {
|
||||
error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (value && !dev->realized) {
|
||||
|
@ -181,7 +181,8 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
|
|||
#endif
|
||||
|
||||
if (dc->realize) {
|
||||
dc->realize(uc, dev, &local_err);
|
||||
if (dc->realize(uc, dev, &local_err))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (local_err != NULL) {
|
||||
|
@ -222,7 +223,7 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
|
|||
}
|
||||
|
||||
dev->realized = value;
|
||||
return;
|
||||
return 0;
|
||||
|
||||
child_realize_fail:
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
|
@ -237,7 +238,7 @@ post_realize_fail:
|
|||
|
||||
fail:
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void device_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||
|
|
|
@ -104,7 +104,7 @@ static X86CPU *pc_new_cpu(struct uc_struct *uc, const char *cpu_model, int64_t a
|
|||
}
|
||||
|
||||
object_property_set_int(uc, OBJECT(cpu), apic_id, "apic-id", &local_err);
|
||||
object_property_set_bool(uc, OBJECT(cpu), true, "realized", &local_err);
|
||||
object_property_set_bool(uc, OBJECT(cpu), true, "realized", &local_err); // qq
|
||||
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -114,7 +114,7 @@ static X86CPU *pc_new_cpu(struct uc_struct *uc, const char *cpu_model, int64_t a
|
|||
return cpu;
|
||||
}
|
||||
|
||||
void pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
|
||||
int pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
|
||||
{
|
||||
int i;
|
||||
Error *error = NULL;
|
||||
|
@ -129,13 +129,15 @@ void pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
|
|||
}
|
||||
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
uc->cpu = pc_new_cpu(uc, cpu_model, x86_cpu_apic_id_from_index(i), &error);
|
||||
uc->cpu = pc_new_cpu(uc, cpu_model, x86_cpu_apic_id_from_index(i), &error); // qq
|
||||
if (error) {
|
||||
//error_report("%s", error_get_pretty(error));
|
||||
error_free(error);
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pc_machine_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||
|
|
|
@ -36,14 +36,14 @@
|
|||
#define GIGABYTE_ALIGN true
|
||||
|
||||
/* PC hardware initialisation */
|
||||
static void pc_init1(struct uc_struct *uc, MachineState *machine)
|
||||
static int pc_init1(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
pc_cpus_init(uc, machine->cpu_model);
|
||||
return pc_cpus_init(uc, machine->cpu_model);
|
||||
}
|
||||
|
||||
static void pc_init_pci(struct uc_struct *uc, MachineState *machine)
|
||||
static int pc_init_pci(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
pc_init1(uc, machine);
|
||||
return pc_init1(uc, machine);
|
||||
}
|
||||
|
||||
#define PC_I440FX_MACHINE_OPTIONS \
|
||||
|
|
|
@ -186,8 +186,9 @@ static void apic_post_load(APICCommonState *s)
|
|||
}
|
||||
}
|
||||
|
||||
static void apic_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int apic_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apic_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)
|
||||
|
|
|
@ -196,7 +196,7 @@ static void apic_reset_common(struct uc_struct *uc, DeviceState *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(uc, dev);
|
||||
APICCommonClass *info;
|
||||
|
@ -204,7 +204,7 @@ static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **
|
|||
if (uc->apic_no >= MAX_APICS) {
|
||||
error_setg(errp, "%s initialization failed.",
|
||||
object_get_typename(OBJECT(dev)));
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
s->idx = uc->apic_no++;
|
||||
|
||||
|
@ -225,6 +225,8 @@ static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **
|
|||
if (uc->apic_report_tpr_access && info->enable_tpr_reporting) {
|
||||
info->enable_tpr_reporting(s, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apic_common_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
|
||||
/* Board init. */
|
||||
static void dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
|
||||
static int dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
const char *cpu_model = machine->cpu_model;
|
||||
CPUM68KState *env;
|
||||
|
@ -27,12 +27,14 @@ static void dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
|
|||
env = cpu_init(uc, cpu_model);
|
||||
if (!env) {
|
||||
fprintf(stderr, "Unable to find m68k CPU definition\n");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize CPU registers. */
|
||||
env->vbr = 0;
|
||||
env->pc = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dummy_m68k_machine_init(struct uc_struct *uc)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "exec/address-spaces.h"
|
||||
|
||||
|
||||
static void mips_r4k_init(struct uc_struct *uc, MachineState *machine)
|
||||
static int mips_r4k_init(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
const char *cpu_model = machine->cpu_model;
|
||||
MIPSCPU *cpu;
|
||||
|
@ -38,8 +38,10 @@ static void mips_r4k_init(struct uc_struct *uc, MachineState *machine)
|
|||
cpu = cpu_mips_init(uc, cpu_model);
|
||||
if (cpu == NULL) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mips_machine_init(struct uc_struct *uc)
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "exec/address-spaces.h"
|
||||
|
||||
|
||||
static void leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
|
||||
static int leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
const char *cpu_model = machine->cpu_model;
|
||||
SPARCCPU *cpu;
|
||||
|
@ -46,10 +46,12 @@ static void leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
|
|||
cpu = cpu_sparc_init(uc, cpu_model);
|
||||
if (cpu == NULL) {
|
||||
fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpu_sparc_set_id(&cpu->env, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void leon3_machine_init(struct uc_struct *uc)
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
|
||||
/* Sun4u hardware initialisation */
|
||||
static void sun4u_init(struct uc_struct *uc, MachineState *machine)
|
||||
static int sun4u_init(struct uc_struct *uc, MachineState *machine)
|
||||
{
|
||||
const char *cpu_model = machine->cpu_model;
|
||||
SPARCCPU *cpu;
|
||||
|
@ -41,8 +41,10 @@ static void sun4u_init(struct uc_struct *uc, MachineState *machine)
|
|||
cpu = cpu_sparc_init(uc, cpu_model);
|
||||
if (cpu == NULL) {
|
||||
fprintf(stderr, "Unable to find Sparc CPU definition\n");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sun4u_machine_init(struct uc_struct *uc)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "qom/object.h"
|
||||
#include "uc_priv.h"
|
||||
|
||||
typedef void QEMUMachineInitFunc(struct uc_struct *uc, MachineState *ms);
|
||||
typedef int QEMUMachineInitFunc(struct uc_struct *uc, MachineState *ms);
|
||||
|
||||
typedef void QEMUMachineResetFunc(void);
|
||||
|
||||
|
@ -54,7 +54,7 @@ struct MachineClass {
|
|||
const char *family; /* NULL iff @name identifies a standalone machtype */
|
||||
const char *name;
|
||||
|
||||
void (*init)(struct uc_struct *uc, MachineState *state);
|
||||
int (*init)(struct uc_struct *uc, MachineState *state);
|
||||
void (*reset)(void);
|
||||
|
||||
int max_cpus;
|
||||
|
|
|
@ -34,7 +34,7 @@ typedef struct PCMachineClass PCMachineClass;
|
|||
#define PC_MACHINE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
|
||||
|
||||
void pc_cpus_init(struct uc_struct *uc, const char *cpu_model);
|
||||
int pc_cpus_init(struct uc_struct *uc, const char *cpu_model);
|
||||
|
||||
FWCfgState *pc_memory_init(MachineState *machine,
|
||||
MemoryRegion *system_memory,
|
||||
|
|
|
@ -32,7 +32,7 @@ typedef enum DeviceCategory {
|
|||
typedef int (*qdev_initfn)(DeviceState *dev);
|
||||
typedef int (*qdev_event)(DeviceState *dev);
|
||||
typedef void (*qdev_resetfn)(DeviceState *dev);
|
||||
typedef void (*DeviceRealize)(struct uc_struct *uc, DeviceState *dev, Error **errp);
|
||||
typedef int (*DeviceRealize)(struct uc_struct *uc, DeviceState *dev, Error **errp);
|
||||
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
|
||||
typedef void (*BusRealize)(BusState *bus, Error **errp);
|
||||
typedef void (*BusUnrealize)(BusState *bus, Error **errp);
|
||||
|
|
|
@ -53,7 +53,8 @@ void qemu_event_wait(QemuEvent *ev);
|
|||
void qemu_event_destroy(QemuEvent *ev);
|
||||
|
||||
struct uc_struct;
|
||||
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
|
||||
// return -1 on error, 0 on success
|
||||
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
|
||||
void *(*start_routine)(void *),
|
||||
void *arg, int mode);
|
||||
void *qemu_thread_join(QemuThread *thread);
|
||||
|
|
|
@ -582,7 +582,7 @@ void cpu_resume(CPUState *cpu);
|
|||
*
|
||||
* Initializes a vCPU.
|
||||
*/
|
||||
void qemu_init_vcpu(CPUState *cpu);
|
||||
int 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 */
|
||||
|
|
|
@ -304,6 +304,11 @@ typedef void (ObjectPropertyAccessor)(struct uc_struct *uc, Object *obj,
|
|||
void *opaque,
|
||||
const char *name,
|
||||
Error **errp);
|
||||
typedef int (ObjectPropertySetAccessor)(struct uc_struct *uc, Object *obj,
|
||||
struct Visitor *v,
|
||||
void *opaque,
|
||||
const char *name,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* ObjectPropertyResolve:
|
||||
|
@ -342,7 +347,7 @@ typedef struct ObjectProperty
|
|||
gchar *type;
|
||||
gchar *description;
|
||||
ObjectPropertyAccessor *get;
|
||||
ObjectPropertyAccessor *set;
|
||||
ObjectPropertySetAccessor *set;
|
||||
ObjectPropertyResolve *resolve;
|
||||
ObjectPropertyRelease *release;
|
||||
void *opaque;
|
||||
|
@ -799,7 +804,7 @@ void object_unref(struct uc_struct *uc, Object *obj);
|
|||
ObjectProperty *object_property_add(Object *obj, const char *name,
|
||||
const char *type,
|
||||
ObjectPropertyAccessor *get,
|
||||
ObjectPropertyAccessor *set,
|
||||
ObjectPropertySetAccessor *set,
|
||||
ObjectPropertyRelease *release,
|
||||
void *opaque, Error **errp);
|
||||
|
||||
|
@ -1168,7 +1173,7 @@ void object_property_add_link(Object *obj, const char *name,
|
|||
*/
|
||||
void object_property_add_str(Object *obj, const char *name,
|
||||
char *(*get)(struct uc_struct *uc, Object *, Error **),
|
||||
void (*set)(struct uc_struct *uc, Object *, const char *, Error **),
|
||||
int (*set)(struct uc_struct *uc, Object *, const char *, Error **),
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
|
@ -1184,7 +1189,7 @@ void object_property_add_str(Object *obj, const char *name,
|
|||
*/
|
||||
void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name,
|
||||
bool (*get)(struct uc_struct *uc, Object *, Error **),
|
||||
void (*set)(struct uc_struct *uc, Object *, bool, Error **),
|
||||
int (*set)(struct uc_struct *uc, Object *, bool, Error **),
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@ struct uc_struct;
|
|||
|
||||
/* cpus.c */
|
||||
void qemu_init_cpu_loop(struct uc_struct*);
|
||||
void resume_all_vcpus(struct uc_struct*);
|
||||
int resume_all_vcpus(struct uc_struct*);
|
||||
void pause_all_vcpus(struct uc_struct*);
|
||||
void cpu_stop_current(struct uc_struct*);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef struct vm_change_state_entry VMChangeStateEntry;
|
|||
#define VMRESET_SILENT false
|
||||
#define VMRESET_REPORT true
|
||||
|
||||
void vm_start(struct uc_struct*);
|
||||
int vm_start(struct uc_struct*);
|
||||
|
||||
void qemu_system_reset_request(struct uc_struct*);
|
||||
void qemu_system_shutdown_request(void);
|
||||
|
|
|
@ -216,13 +216,15 @@ static void cpu_common_parse_features(CPUState *cpu, char *features,
|
|||
}
|
||||
}
|
||||
|
||||
static void cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cpu = CPU(dev);
|
||||
|
||||
if (dev->hotplugged) {
|
||||
cpu_resume(cpu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpu_common_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||
|
|
|
@ -716,7 +716,7 @@ void object_unref(struct uc_struct *uc, Object *obj)
|
|||
ObjectProperty *
|
||||
object_property_add(Object *obj, const char *name, const char *type,
|
||||
ObjectPropertyAccessor *get,
|
||||
ObjectPropertyAccessor *set,
|
||||
ObjectPropertySetAccessor *set,
|
||||
ObjectPropertyRelease *release,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
|
@ -826,7 +826,8 @@ void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, const ch
|
|||
if (!prop->set) {
|
||||
error_set(errp, QERR_PERMISSION_DENIED);
|
||||
} else {
|
||||
prop->set(uc, obj, v, prop->opaque, name, errp);
|
||||
if (prop->set(uc, obj, v, prop->opaque, name, errp))
|
||||
error_set(errp, QERR_UNDEFINED_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1169,7 +1170,7 @@ static Object *object_resolve_link(struct uc_struct *uc, Object *obj, const char
|
|||
return target;
|
||||
}
|
||||
|
||||
static void object_set_link_property(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int object_set_link_property(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
|
@ -1188,18 +1189,20 @@ static void object_set_link_property(struct uc_struct *uc, Object *obj, Visitor
|
|||
g_free(path);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop->check(obj, name, new_target, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
object_ref(new_target);
|
||||
*child = new_target;
|
||||
object_unref(uc, old_target);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Object *object_resolve_link_property(struct uc_struct *uc, Object *parent, void *opaque, const gchar *part)
|
||||
|
@ -1410,7 +1413,7 @@ Object *object_resolve_path(struct uc_struct *uc, const char *path, bool *ambigu
|
|||
typedef struct StringProperty
|
||||
{
|
||||
char *(*get)(struct uc_struct *uc, Object *, Error **);
|
||||
void (*set)(struct uc_struct *uc, Object *, const char *, Error **);
|
||||
int (*set)(struct uc_struct *uc, Object *, const char *, Error **);
|
||||
} StringProperty;
|
||||
|
||||
static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1426,7 +1429,7 @@ static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void
|
|||
}
|
||||
}
|
||||
|
||||
static void property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
StringProperty *prop = opaque;
|
||||
|
@ -1436,11 +1439,13 @@ static void property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void
|
|||
visit_type_str(v, &value, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop->set(uc, obj, value, errp);
|
||||
g_free(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void property_release_str(struct uc_struct *uc, Object *obj, const char *name,
|
||||
|
@ -1452,7 +1457,7 @@ static void property_release_str(struct uc_struct *uc, Object *obj, const char *
|
|||
|
||||
void object_property_add_str(Object *obj, const char *name,
|
||||
char *(*get)(struct uc_struct *uc, Object *, Error **),
|
||||
void (*set)(struct uc_struct *uc, Object *, const char *, Error **),
|
||||
int (*set)(struct uc_struct *uc, Object *, const char *, Error **),
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
|
@ -1475,7 +1480,7 @@ void object_property_add_str(Object *obj, const char *name,
|
|||
typedef struct BoolProperty
|
||||
{
|
||||
bool (*get)(struct uc_struct *uc, Object *, Error **);
|
||||
void (*set)(struct uc_struct *uc, Object *, bool, Error **);
|
||||
int (*set)(struct uc_struct *uc, Object *, bool, Error **);
|
||||
} BoolProperty;
|
||||
|
||||
static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1488,7 +1493,7 @@ static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, voi
|
|||
visit_type_bool(v, &value, name, errp);
|
||||
}
|
||||
|
||||
static void property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
BoolProperty *prop = opaque;
|
||||
|
@ -1498,10 +1503,10 @@ static void property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, voi
|
|||
visit_type_bool(v, &value, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prop->set(uc, obj, value, errp);
|
||||
return prop->set(uc, obj, value, errp);
|
||||
}
|
||||
|
||||
static void property_release_bool(struct uc_struct *uc, Object *obj, const char *name,
|
||||
|
@ -1513,7 +1518,7 @@ static void property_release_bool(struct uc_struct *uc, Object *obj, const char
|
|||
|
||||
void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name,
|
||||
bool (*get)(struct uc_struct *uc, Object *, Error **),
|
||||
void (*set)(struct uc_struct *uc, Object *, bool, Error **),
|
||||
int (*set)(struct uc_struct *uc, Object *, bool, Error **),
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
|
@ -1611,12 +1616,14 @@ static void property_get_alias(struct uc_struct *uc, Object *obj, struct Visitor
|
|||
object_property_get(uc, prop->target_obj, v, prop->target_name, errp);
|
||||
}
|
||||
|
||||
static void property_set_alias(struct uc_struct *uc, Object *obj, struct Visitor *v, void *opaque,
|
||||
static int property_set_alias(struct uc_struct *uc, Object *obj, struct Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
AliasProperty *prop = opaque;
|
||||
|
||||
object_property_set(uc, prop->target_obj, v, prop->target_name, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Object *property_resolve_alias(struct uc_struct *uc, Object *obj, void *opaque,
|
||||
|
|
|
@ -21,7 +21,7 @@ void object_property_set_qobject(struct uc_struct *uc, Object *obj, QObject *val
|
|||
{
|
||||
QmpInputVisitor *mi;
|
||||
mi = qmp_input_visitor_new(value);
|
||||
object_property_set(uc, obj, qmp_input_get_visitor(mi), name, errp);
|
||||
object_property_set(uc, obj, qmp_input_get_visitor(mi), name, errp); // qq
|
||||
|
||||
qmp_input_visitor_cleanup(mi);
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ static void arm_cpu_finalizefn(struct uc_struct *uc, Object *obj, void *opaque)
|
|||
g_hash_table_destroy(cpu->cp_regs);
|
||||
}
|
||||
|
||||
static void arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
ARMCPU *cpu = ARM_CPU(uc, dev);
|
||||
|
@ -399,6 +399,8 @@ static void arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
|
|||
cpu_reset(cs);
|
||||
|
||||
acc->parent_realize(uc, dev, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ObjectClass *arm_cpu_class_by_name(struct uc_struct *uc, const char *cpu_model)
|
||||
|
|
|
@ -1162,7 +1162,7 @@ static void x86_cpuid_version_get_family(struct uc_struct *uc, Object *obj, Visi
|
|||
visit_type_int(v, &value, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
@ -1175,12 +1175,12 @@ static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visi
|
|||
visit_type_int(v, &value, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
if (value < min || value > max) {
|
||||
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
|
||||
name ? name : "null", value, min, max);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
env->cpuid_version &= ~0xff00f00;
|
||||
|
@ -1189,6 +1189,8 @@ static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visi
|
|||
} else {
|
||||
env->cpuid_version |= value << 8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1203,7 +1205,7 @@ static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visit
|
|||
visit_type_int(v, &value, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
@ -1216,16 +1218,18 @@ static void x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visit
|
|||
visit_type_int(v, &value, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
if (value < min || value > max) {
|
||||
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
|
||||
name ? name : "null", value, min, max);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
env->cpuid_version &= ~0xf00f0;
|
||||
env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
|
||||
|
@ -1240,7 +1244,7 @@ static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Vi
|
|||
visit_type_int(v, &value, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
|
||||
static int x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
|
||||
void *opaque, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
|
@ -1254,16 +1258,18 @@ static void x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Vi
|
|||
visit_type_int(v, &value, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
if (value < min || value > max) {
|
||||
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
|
||||
name ? name : "null", value, min, max);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
env->cpuid_version &= ~0xf;
|
||||
env->cpuid_version |= value & 0xf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1274,12 +1280,14 @@ static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, v
|
|||
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_set_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int x86_cpuid_set_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
||||
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1290,12 +1298,14 @@ static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v,
|
|||
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_set_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int x86_cpuid_set_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
||||
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **errp)
|
||||
|
@ -1310,7 +1320,7 @@ static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **err
|
|||
return value;
|
||||
}
|
||||
|
||||
static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *value,
|
||||
static int x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *value,
|
||||
Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
@ -1320,7 +1330,7 @@ static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *
|
|||
if (strlen(value) != CPUID_VENDOR_SZ) {
|
||||
error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
|
||||
"vendor", value);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
env->cpuid_vendor1 = 0;
|
||||
|
@ -1331,6 +1341,8 @@ static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *
|
|||
env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
|
||||
env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **errp)
|
||||
|
@ -1348,7 +1360,7 @@ static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **e
|
|||
return value;
|
||||
}
|
||||
|
||||
static void x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char *model_id,
|
||||
static int x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char *model_id,
|
||||
Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
@ -1368,6 +1380,8 @@ static void x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char
|
|||
}
|
||||
env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1380,7 +1394,7 @@ static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v
|
|||
visit_type_int(v, &value, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
@ -1392,15 +1406,17 @@ static void x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v
|
|||
visit_type_int(v, &value, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
if (value < min || value > max) {
|
||||
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
|
||||
name ? name : "null", value, min, max);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpu->env.tsc_khz = value / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -1412,7 +1428,7 @@ static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v,
|
|||
visit_type_int(v, &value, name, errp);
|
||||
}
|
||||
|
||||
static void x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
static int x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(uc, obj);
|
||||
|
@ -1425,26 +1441,28 @@ static void x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v,
|
|||
if (dev->realized) {
|
||||
error_setg(errp, "Attempt to set property '%s' on '%s' after "
|
||||
"it was realized", name, object_get_typename(obj));
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
visit_type_int(v, &value, name, &error);
|
||||
if (error) {
|
||||
error_propagate(errp, error);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
if (value < min || value > max) {
|
||||
error_setg(errp, "Property %s.%s doesn't take value %" PRId64
|
||||
" (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
|
||||
object_get_typename(obj), name, value, min, max);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((value != cpu->env.cpuid_apic_id) && cpu_exists(uc, value)) {
|
||||
error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
cpu->env.cpuid_apic_id = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generic getter for "feature-words" and "filtered-features" properties */
|
||||
|
@ -2249,7 +2267,7 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
|
|||
#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
|
||||
(env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
|
||||
(env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
|
||||
static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
X86CPU *cpu = X86_CPU(uc, dev);
|
||||
|
@ -2270,7 +2288,6 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
|
|||
& CPUID_EXT2_AMD_ALIASES);
|
||||
}
|
||||
|
||||
|
||||
if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) {
|
||||
error_setg(&local_err,
|
||||
"TCG doesn't support requested features");
|
||||
|
@ -2289,7 +2306,8 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
|
|||
#endif
|
||||
|
||||
mce_init(cpu);
|
||||
qemu_init_vcpu(cs);
|
||||
if (qemu_init_vcpu(cs))
|
||||
return -1;
|
||||
|
||||
x86_cpu_apic_realize(cpu, &local_err);
|
||||
if (local_err != NULL) {
|
||||
|
@ -2301,8 +2319,10 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
|
|||
out:
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enables contiguous-apic-ID mode, for compatibility */
|
||||
|
|
|
@ -146,7 +146,7 @@ static const M68kCPUInfo m68k_cpus[] = {
|
|||
{ .name = "any", .instance_init = any_cpu_initfn },
|
||||
};
|
||||
|
||||
static void m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(uc, dev);
|
||||
|
@ -155,6 +155,8 @@ static void m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **e
|
|||
qemu_init_vcpu(cs);
|
||||
|
||||
mcc->parent_realize(cs->uc, dev, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void m68k_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||
|
|
|
@ -92,7 +92,7 @@ static void mips_cpu_reset(CPUState *s)
|
|||
cpu_state_reset(env);
|
||||
}
|
||||
|
||||
static void mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(uc, dev);
|
||||
|
@ -101,6 +101,8 @@ static void mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **e
|
|||
qemu_init_vcpu(cs);
|
||||
|
||||
mcc->parent_realize(uc, dev, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mips_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||
|
|
|
@ -783,7 +783,7 @@ static bool sparc_cpu_has_work(CPUState *cs)
|
|||
cpu_interrupts_enabled(env);
|
||||
}
|
||||
|
||||
static void sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
static int sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
|
||||
{
|
||||
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(uc, dev);
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
@ -798,6 +798,8 @@ static void sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **
|
|||
qemu_init_vcpu(CPU(dev));
|
||||
|
||||
scc->parent_realize(uc, dev, errp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sparc_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
static void error_exit(int err, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
|
||||
abort();
|
||||
// fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
|
||||
// abort();
|
||||
}
|
||||
|
||||
void qemu_mutex_init(QemuMutex *mutex)
|
||||
|
@ -389,7 +389,7 @@ void qemu_event_wait(QemuEvent *ev)
|
|||
}
|
||||
}
|
||||
|
||||
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
|
||||
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
|
||||
void *(*start_routine)(void*),
|
||||
void *arg, int mode)
|
||||
{
|
||||
|
@ -397,20 +397,16 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
|
|||
int err;
|
||||
pthread_attr_t attr;
|
||||
|
||||
#if 0
|
||||
static int count = 0;
|
||||
count++;
|
||||
printf(">>> create thread %u\n", count);
|
||||
#endif
|
||||
|
||||
err = pthread_attr_init(&attr);
|
||||
if (err) {
|
||||
error_exit(err, __func__);
|
||||
return -1;
|
||||
}
|
||||
if (mode == QEMU_THREAD_DETACHED) {
|
||||
err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
if (err) {
|
||||
error_exit(err, __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,12 +414,16 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
|
|||
sigfillset(&set);
|
||||
pthread_sigmask(SIG_SETMASK, &set, &oldset);
|
||||
err = pthread_create(&thread->thread, &attr, start_routine, arg);
|
||||
if (err)
|
||||
if (err) {
|
||||
error_exit(err, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread)
|
||||
|
|
|
@ -27,7 +27,7 @@ static void error_exit(int err, const char *msg)
|
|||
NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
|
||||
fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
|
||||
LocalFree(pstr);
|
||||
abort();
|
||||
//abort();
|
||||
}
|
||||
|
||||
void qemu_mutex_init(QemuMutex *mutex)
|
||||
|
@ -326,7 +326,7 @@ void *qemu_thread_join(QemuThread *thread)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
|
||||
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
|
||||
void *(*start_routine)(void *),
|
||||
void *arg, int mode)
|
||||
{
|
||||
|
@ -350,9 +350,13 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
|
|||
data, 0, &thread->tid);
|
||||
if (!hThread) {
|
||||
error_exit(GetLastError(), __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CloseHandle(hThread);
|
||||
thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread)
|
||||
|
|
11
qemu/vl.c
11
qemu/vl.c
|
@ -94,8 +94,6 @@ int machine_initialize(struct uc_struct *uc)
|
|||
MachineClass *machine_class;
|
||||
MachineState *current_machine;
|
||||
|
||||
//printf(">>> starting machine initialize\n");
|
||||
|
||||
module_call_init(uc, MODULE_INIT_QOM);
|
||||
register_types_object(uc);
|
||||
machine_register_types(uc);
|
||||
|
@ -115,11 +113,8 @@ int machine_initialize(struct uc_struct *uc)
|
|||
return -2;
|
||||
}
|
||||
|
||||
// printf("222\n");
|
||||
current_machine = MACHINE(uc, object_new(uc, object_class_get_name(
|
||||
OBJECT_CLASS(machine_class))));
|
||||
//object_property_add_child(object_get_root(), "machine",
|
||||
// OBJECT(current_machine), &error_abort);
|
||||
|
||||
current_machine->uc = uc;
|
||||
uc->cpu_exec_init_all(uc);
|
||||
|
@ -129,14 +124,10 @@ int machine_initialize(struct uc_struct *uc)
|
|||
|
||||
qemu_init_cpu_loop(uc);
|
||||
qemu_mutex_lock_iothread(uc);
|
||||
//cpu_ticks_init();
|
||||
// printf("333\n");
|
||||
|
||||
current_machine->cpu_model = NULL;
|
||||
machine_class->init(uc, current_machine);
|
||||
|
||||
//printf(">>> ending machine initialize\n");
|
||||
return 0;
|
||||
return machine_class->init(uc, current_machine);
|
||||
}
|
||||
|
||||
void qemu_system_reset_request(struct uc_struct* uc)
|
||||
|
|
10
uc.c
10
uc.c
|
@ -97,6 +97,8 @@ const char *uc_strerror(uc_err code)
|
|||
return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)";
|
||||
case UC_ERR_HOOK_EXIST:
|
||||
return "Hook for this type event already exists (UC_ERR_HOOK_EXIST)";
|
||||
case UC_ERR_RESOURCE:
|
||||
return "Insufficient resource (UC_ERR_RESOURCE)";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +237,8 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
|
|||
return UC_ERR_ARCH;
|
||||
}
|
||||
|
||||
machine_initialize(uc);
|
||||
if (machine_initialize(uc))
|
||||
return UC_ERR_RESOURCE;
|
||||
|
||||
*result = uc;
|
||||
|
||||
|
@ -502,7 +505,10 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
|
|||
|
||||
uc->addr_end = until;
|
||||
|
||||
uc->vm_start(uc);
|
||||
if (uc->vm_start(uc)) {
|
||||
return UC_ERR_RESOURCE;
|
||||
}
|
||||
|
||||
if (timeout)
|
||||
enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds
|
||||
uc->pause_all_vcpus(uc);
|
||||
|
|
Loading…
Reference in a new issue