Merge remote-tracking branch 'afaerber/qom-cpu' into staging

# By Andreas Färber
# Via Andreas Färber
* afaerber/qom-cpu: (47 commits)
  target-i386: Split command line parsing out of cpu_x86_register()
  target-i386: Move cpu_x86_init()
  target-lm32: Drop unused cpu_lm32_close() prototype
  target-s390x: Drop unused cpu_s390x_close() prototype
  spapr_hcall: Replace open-coded CPU loop with qemu_get_cpu()
  ppce500_spin: Replace open-coded CPU loop with qemu_get_cpu()
  e500: Replace open-coded loop with qemu_get_cpu()
  cpu: Add CPUArchState pointer to CPUState
  cputlb: Pass CPUState to cpu_unlink_tb()
  cpu: Move current_tb field to CPUState
  cpu: Move exit_request field to CPUState
  cpu: Move running field to CPUState
  cpu: Move host_tid field to CPUState
  target-cris: Introduce CRISCPU subclasses
  target-m68k: Pass M68kCPU to m68k_set_irq_level()
  mcf_intc: Pass M68kCPU to mcf_intc_init()
  mcf5206: Pass M68kCPU to mcf5206_init()
  target-m68k: Return M68kCPU from cpu_m68k_init()
  ppc405_uc: Pass PowerPCCPU to ppc40x_{core,chip,system}_reset()
  target-xtensa: Move TCG initialization to XtensaCPU initfn
  ...
This commit is contained in:
Anthony Liguori 2013-02-18 08:37:29 -06:00
commit 3c3adde005
83 changed files with 791 additions and 374 deletions

View File

@ -32,7 +32,9 @@ bool qemu_cpu_has_work(CPUState *cpu)
void cpu_loop_exit(CPUArchState *env)
{
env->current_tb = NULL;
CPUState *cpu = ENV_GET_CPU(env);
cpu->current_tb = NULL;
longjmp(env->jmp_env, 1);
}
@ -54,6 +56,7 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc)
static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
TranslationBlock *orig_tb)
{
CPUState *cpu = ENV_GET_CPU(env);
tcg_target_ulong next_tb;
TranslationBlock *tb;
@ -64,10 +67,10 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
max_cycles);
env->current_tb = tb;
cpu->current_tb = tb;
/* execute the generated code */
next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
env->current_tb = NULL;
cpu->current_tb = NULL;
if ((next_tb & 3) == 2) {
/* Restore PC. This may happen if async event occurs before
@ -196,7 +199,7 @@ int cpu_exec(CPUArchState *env)
cpu_single_env = env;
if (unlikely(exit_request)) {
env->exit_request = 1;
cpu->exit_request = 1;
}
#if defined(TARGET_I386)
@ -537,8 +540,8 @@ int cpu_exec(CPUArchState *env)
next_tb = 0;
}
}
if (unlikely(env->exit_request)) {
env->exit_request = 0;
if (unlikely(cpu->exit_request)) {
cpu->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(env);
}
@ -589,9 +592,9 @@ int cpu_exec(CPUArchState *env)
TB, but before it is linked into a potentially
infinite loop and becomes env->current_tb. Avoid
starting execution if there is a pending interrupt. */
env->current_tb = tb;
cpu->current_tb = tb;
barrier();
if (likely(!env->exit_request)) {
if (likely(!cpu->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
next_tb = tcg_qemu_tb_exec(env, tc_ptr);
@ -623,7 +626,7 @@ int cpu_exec(CPUArchState *env)
}
}
}
env->current_tb = NULL;
cpu->current_tb = NULL;
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
} /* for(;;) */

View File

@ -54,6 +54,7 @@ static const CPUTLBEntry s_cputlb_empty_entry = {
*/
void tlb_flush(CPUArchState *env, int flush_global)
{
CPUState *cpu = ENV_GET_CPU(env);
int i;
#if defined(DEBUG_TLB)
@ -61,7 +62,7 @@ void tlb_flush(CPUArchState *env, int flush_global)
#endif
/* must reset current TB so that interrupts cannot modify the
links while we are modifying them */
env->current_tb = NULL;
cpu->current_tb = NULL;
for (i = 0; i < CPU_TLB_SIZE; i++) {
int mmu_idx;
@ -92,6 +93,7 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
void tlb_flush_page(CPUArchState *env, target_ulong addr)
{
CPUState *cpu = ENV_GET_CPU(env);
int i;
int mmu_idx;
@ -110,7 +112,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr)
}
/* must reset current TB so that interrupts cannot modify the
links while we are modifying them */
env->current_tb = NULL;
cpu->current_tb = NULL;
addr &= TARGET_PAGE_MASK;
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);

8
dump.c
View File

@ -271,11 +271,13 @@ static int write_elf64_note(DumpState *s)
static int write_elf64_notes(DumpState *s)
{
CPUArchState *env;
CPUState *cpu;
int ret;
int id;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
id = cpu_index(env);
cpu = ENV_GET_CPU(env);
id = cpu_index(cpu);
ret = cpu_write_elf64_note(fd_write_vmcore, env, id, s);
if (ret < 0) {
dump_error(s, "dump: failed to write elf notes.\n");
@ -321,11 +323,13 @@ static int write_elf32_note(DumpState *s)
static int write_elf32_notes(DumpState *s)
{
CPUArchState *env;
CPUState *cpu;
int ret;
int id;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
id = cpu_index(env);
cpu = ENV_GET_CPU(env);
id = cpu_index(cpu);
ret = cpu_write_elf32_note(fd_write_vmcore, env, id, s);
if (ret < 0) {
dump_error(s, "dump: failed to write elf notes.\n");

6
exec.c
View File

@ -492,8 +492,10 @@ void cpu_reset_interrupt(CPUArchState *env, int mask)
void cpu_exit(CPUArchState *env)
{
env->exit_request = 1;
cpu_unlink_tb(env);
CPUState *cpu = ENV_GET_CPU(env);
cpu->exit_request = 1;
cpu_unlink_tb(cpu);
}
void cpu_abort(CPUArchState *env, const char *fmt, ...)

View File

@ -2066,9 +2066,11 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
static CPUArchState *find_cpu(uint32_t thread_id)
{
CPUArchState *env;
CPUState *cpu;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
if (cpu_index(env) == thread_id) {
cpu = ENV_GET_CPU(env);
if (cpu_index(cpu) == thread_id) {
return env;
}
}
@ -2096,7 +2098,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(s->c_cpu));
cpu_index(ENV_GET_CPU(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
@ -2391,7 +2393,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
} else if (strcmp(p,"sThreadInfo") == 0) {
report_cpuinfo:
if (s->query_cpu) {
snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
snprintf(buf, sizeof(buf), "m%x",
cpu_index(ENV_GET_CPU(s->query_cpu)));
put_packet(s, buf);
s->query_cpu = s->query_cpu->next_cpu;
} else
@ -2512,6 +2515,7 @@ 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);
char buf[256];
const char *type;
int ret;
@ -2540,7 +2544,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
}
snprintf(buf, sizeof(buf),
"T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
GDB_SIGNAL_TRAP, cpu_index(env), type,
GDB_SIGNAL_TRAP, cpu_index(cpu), type,
env->watchpoint_hit->vaddr);
env->watchpoint_hit = NULL;
goto send_packet;
@ -2573,7 +2577,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
ret = GDB_SIGNAL_UNKNOWN;
break;
}
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(env));
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
send_packet:
put_packet(s, buf);

View File

@ -24,6 +24,7 @@ static void an5206_init(QEMUMachineInitArgs *args)
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
M68kCPU *cpu;
CPUM68KState *env;
int kernel_size;
uint64_t elf_entry;
@ -32,12 +33,14 @@ static void an5206_init(QEMUMachineInitArgs *args)
MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *sram = g_new(MemoryRegion, 1);
if (!cpu_model)
if (!cpu_model) {
cpu_model = "m5206";
env = cpu_init(cpu_model);
if (!env) {
}
cpu = cpu_m68k_init(cpu_model);
if (!cpu) {
hw_error("Unable to find m68k CPU definition\n");
}
env = &cpu->env;
/* Initialize CPU registers. */
env->vbr = 0;
@ -55,7 +58,7 @@ static void an5206_init(QEMUMachineInitArgs *args)
vmstate_register_ram_global(sram);
memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, env);
mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu);
/* Load kernel. */
if (!kernel_filename) {

View File

@ -103,7 +103,7 @@ void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
{
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
vapic_report_tpr_access(s->vapic, &s->cpu->env, ip, access);
vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access);
}
void apic_report_irq_delivered(int delivered)

View File

@ -143,7 +143,7 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time);
void apic_enable_tpr_access_reporting(DeviceState *d, bool enable);
void apic_enable_vapic(DeviceState *d, hwaddr paddr);
void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,
void vapic_report_tpr_access(DeviceState *dev, CPUState *cpu, target_ulong ip,
TPRAccess access);
#endif /* !QEMU_APIC_INTERNAL_H */

View File

@ -382,8 +382,10 @@ static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
}
static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong ip)
static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
{
CPUState *cs = CPU(cpu);
CPUX86State *env = &cpu->env;
VAPICHandlers *handlers;
uint8_t opcode[2];
uint32_t imm32;
@ -439,17 +441,18 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i
resume_all_vcpus();
if (!kvm_enabled()) {
env->current_tb = NULL;
cs->current_tb = NULL;
tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
cpu_resume_from_signal(env, NULL);
}
}
void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,
void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
TPRAccess access)
{
VAPICROMState *s = DO_UPCAST(VAPICROMState, busdev.qdev, dev);
CPUX86State *env = cpu;
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
cpu_synchronize_state(env);
@ -465,7 +468,7 @@ void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,
if (vapic_enable(s, env) < 0) {
return;
}
patch_instruction(s, env, ip);
patch_instruction(s, cpu, ip);
}
typedef struct VAPICEnableTPRReporting {

View File

@ -17,7 +17,7 @@ void mcf_uart_mm_init(struct MemoryRegion *sysmem,
/* mcf_intc.c */
qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem,
hwaddr base,
CPUM68KState *env);
M68kCPU *cpu);
/* mcf_fec.c */
void mcf_fec_init(struct MemoryRegion *sysmem, NICInfo *nd,
@ -25,6 +25,6 @@ void mcf_fec_init(struct MemoryRegion *sysmem, NICInfo *nd,
/* mcf5206.c */
qemu_irq *mcf5206_init(struct MemoryRegion *sysmem,
uint32_t base, CPUM68KState *env);
uint32_t base, M68kCPU *cpu);
#endif

View File

@ -145,7 +145,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
/* System Integration Module. */
typedef struct {
CPUM68KState *env;
M68kCPU *cpu;
MemoryRegion iomem;
m5206_timer_state *timer[2];
void *uart[2];
@ -226,7 +226,7 @@ static void m5206_mbar_update(m5206_mbar_state *s)
level = 0;
vector = 0;
}
m68k_set_irq_level(s->env, level, vector);
m68k_set_irq_level(s->cpu, level, vector);
}
static void m5206_mbar_set_irq(void *opaque, int irq, int level)
@ -525,7 +525,7 @@ static const MemoryRegionOps m5206_mbar_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, CPUM68KState *env)
qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, M68kCPU *cpu)
{
m5206_mbar_state *s;
qemu_irq *pic;
@ -541,7 +541,7 @@ qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, CPUM68KState *env)
s->timer[1] = m5206_timer_init(pic[10]);
s->uart[0] = mcf_uart_init(pic[12], serial_hds[0]);
s->uart[1] = mcf_uart_init(pic[13], serial_hds[1]);
s->env = env;
s->cpu = cpu;
m5206_mbar_reset(s);
return pic;

View File

@ -192,6 +192,7 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args)
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
M68kCPU *cpu;
CPUM68KState *env;
int kernel_size;
uint64_t elf_entry;
@ -201,13 +202,15 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args)
MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *sram = g_new(MemoryRegion, 1);
if (!cpu_model)
if (!cpu_model) {
cpu_model = "m5208";
env = cpu_init(cpu_model);
if (!env) {
}
cpu = cpu_m68k_init(cpu_model);
if (!cpu) {
fprintf(stderr, "Unable to find m68k CPU definition\n");
exit(1);
}
env = &cpu->env;
/* Initialize CPU registers. */
env->vbr = 0;
@ -224,7 +227,7 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args)
memory_region_add_subregion(address_space_mem, 0x80000000, sram);
/* Internal peripherals. */
pic = mcf_intc_init(address_space_mem, 0xfc048000, env);
pic = mcf_intc_init(address_space_mem, 0xfc048000, cpu);
mcf_uart_mm_init(address_space_mem, 0xfc060000, pic[26], serial_hds[0]);
mcf_uart_mm_init(address_space_mem, 0xfc064000, pic[27], serial_hds[1]);

View File

@ -16,7 +16,7 @@ typedef struct {
uint64_t ifr;
uint64_t enabled;
uint8_t icr[64];
CPUM68KState *env;
M68kCPU *cpu;
int active_vector;
} mcf_intc_state;
@ -40,7 +40,7 @@ static void mcf_intc_update(mcf_intc_state *s)
}
}
s->active_vector = ((best == 64) ? 24 : (best + 64));
m68k_set_irq_level(s->env, best_level, s->active_vector);
m68k_set_irq_level(s->cpu, best_level, s->active_vector);
}
static uint64_t mcf_intc_read(void *opaque, hwaddr addr,
@ -139,12 +139,12 @@ static const MemoryRegionOps mcf_intc_ops = {
qemu_irq *mcf_intc_init(MemoryRegion *sysmem,
hwaddr base,
CPUM68KState *env)
M68kCPU *cpu)
{
mcf_intc_state *s;
s = g_malloc0(sizeof(mcf_intc_state));
s->env = env;
s->cpu = cpu;
mcf_intc_reset(s);
memory_region_init_io(&s->iomem, &mcf_intc_ops, s, "mcf", 0x100);

View File

@ -876,7 +876,6 @@ void pc_cpus_init(const char *cpu_model)
for (i = 0; i < smp_cpus; i++) {
if (!cpu_x86_init(cpu_model)) {
fprintf(stderr, "Unable to find x86 CPU definition\n");
exit(1);
}
}

View File

@ -300,20 +300,20 @@ static void ppc40x_set_irq(void *opaque, int pin, int level)
if (level) {
LOG_IRQ("%s: reset the PowerPC system\n",
__func__);
ppc40x_system_reset(env);
ppc40x_system_reset(cpu);
}
break;
case PPC40x_INPUT_RESET_CHIP:
if (level) {
LOG_IRQ("%s: reset the PowerPC chip\n", __func__);
ppc40x_chip_reset(env);
ppc40x_chip_reset(cpu);
}
break;
case PPC40x_INPUT_RESET_CORE:
/* XXX: TODO: update DBSR[MRR] */
if (level) {
LOG_IRQ("%s: reset the PowerPC core\n", __func__);
ppc40x_core_reset(env);
ppc40x_core_reset(cpu);
}
break;
case PPC40x_INPUT_CINT:
@ -1011,13 +1011,13 @@ static void cpu_4xx_wdt_cb (void *opaque)
/* No reset */
break;
case 0x1: /* Core reset */
ppc40x_core_reset(env);
ppc40x_core_reset(cpu);
break;
case 0x2: /* Chip reset */
ppc40x_chip_reset(env);
ppc40x_chip_reset(cpu);
break;
case 0x3: /* System reset */
ppc40x_system_reset(env);
ppc40x_system_reset(cpu);
break;
}
}

View File

@ -58,9 +58,9 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
unsigned int decr_excp);
/* Embedded PowerPC reset */
void ppc40x_core_reset (CPUPPCState *env);
void ppc40x_chip_reset (CPUPPCState *env);
void ppc40x_system_reset (CPUPPCState *env);
void ppc40x_core_reset(PowerPCCPU *cpu);
void ppc40x_chip_reset(PowerPCCPU *cpu);
void ppc40x_system_reset(PowerPCCPU *cpu);
void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
extern CPUWriteMemoryFunc * const PPC_io_write[];

View File

@ -240,20 +240,15 @@ static int ppce500_load_device_tree(CPUPPCState *env,
/* We need to generate the cpu nodes in reverse order, so Linux can pick
the first node as boot node and be happy */
for (i = smp_cpus - 1; i >= 0; i--) {
CPUState *cpu = NULL;
CPUState *cpu;
char cpu_name[128];
uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);
for (env = first_cpu; env != NULL; env = env->next_cpu) {
cpu = ENV_GET_CPU(env);
if (cpu->cpu_index == i) {
break;
}
}
cpu = qemu_get_cpu(i);
if (cpu == NULL) {
continue;
}
env = cpu->env_ptr;
snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
cpu->cpu_index);

View File

@ -1770,8 +1770,9 @@ static void ppc405_mal_init(CPUPPCState *env, qemu_irq irqs[4])
/*****************************************************************************/
/* SPR */
void ppc40x_core_reset (CPUPPCState *env)
void ppc40x_core_reset(PowerPCCPU *cpu)
{
CPUPPCState *env = &cpu->env;
target_ulong dbsr;
printf("Reset PowerPC core\n");
@ -1782,8 +1783,9 @@ void ppc40x_core_reset (CPUPPCState *env)
env->spr[SPR_40x_DBSR] = dbsr;
}
void ppc40x_chip_reset (CPUPPCState *env)
void ppc40x_chip_reset(PowerPCCPU *cpu)
{
CPUPPCState *env = &cpu->env;
target_ulong dbsr;
printf("Reset PowerPC chip\n");
@ -1795,7 +1797,7 @@ void ppc40x_chip_reset (CPUPPCState *env)
env->spr[SPR_40x_DBSR] = dbsr;
}
void ppc40x_system_reset (CPUPPCState *env)
void ppc40x_system_reset(PowerPCCPU *cpu)
{
printf("Reset PowerPC system\n");
qemu_system_reset_request();
@ -1803,21 +1805,23 @@ void ppc40x_system_reset (CPUPPCState *env)
void store_40x_dbcr0 (CPUPPCState *env, uint32_t val)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
switch ((val >> 28) & 0x3) {
case 0x0:
/* No action */
break;
case 0x1:
/* Core reset */
ppc40x_core_reset(env);
ppc40x_core_reset(cpu);
break;
case 0x2:
/* Chip reset */
ppc40x_chip_reset(env);
ppc40x_chip_reset(cpu);
break;
case 0x3:
/* System reset */
ppc40x_system_reset(env);
ppc40x_system_reset(cpu);
break;
}
}

View File

@ -123,18 +123,11 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value,
{
SpinState *s = opaque;
int env_idx = addr / sizeof(SpinInfo);
CPUPPCState *env;
CPUState *cpu = NULL;
CPUState *cpu;
SpinInfo *curspin = &s->spin[env_idx];
uint8_t *curspin_p = (uint8_t*)curspin;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
cpu = CPU(ppc_env_get_cpu(env));
if (cpu->cpu_index == env_idx) {
break;
}
}
cpu = qemu_get_cpu(env_idx);
if (cpu == NULL) {
/* Unknown CPU */
return;
@ -161,11 +154,11 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value,
if (!(ldq_p(&curspin->addr) & 1)) {
/* run CPU */
SpinKick kick = {
.cpu = ppc_env_get_cpu(env),
.cpu = POWERPC_CPU(cpu),
.spin = curspin,
};
run_on_cpu(CPU(kick.cpu), spin_kick, &kick);
run_on_cpu(cpu, spin_kick, &kick);
}
}

View File

@ -469,16 +469,11 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr,
CPUPPCState *tenv;
CPUState *tcpu;
for (tenv = first_cpu; tenv; tenv = tenv->next_cpu) {
tcpu = CPU(ppc_env_get_cpu(tenv));
if (tcpu->cpu_index == procno) {
break;
}
}
if (!tenv) {
tcpu = qemu_get_cpu(procno);
if (!tcpu) {
return H_PARAMETER;
}
tenv = tcpu->env_ptr;
switch (flags) {
case FLAGS_REGISTER_VPA:
@ -513,13 +508,14 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
target_ulong opcode, target_ulong *args)
{
CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
env->msr |= (1ULL << MSR_EE);
hreg_compute_hflags(env);
if (!cpu_has_work(CPU(cpu))) {
if (!cpu_has_work(cs)) {
env->halted = 1;
env->exception_index = EXCP_HLT;
env->exit_request = 1;
cs->exit_request = 1;
}
return H_SUCCESS;
}

View File

@ -26,7 +26,6 @@
#include "config.h"
#include <setjmp.h>
#include <inttypes.h>
#include <signal.h>
#include "qemu/osdep.h"
#include "qemu/queue.h"
#include "exec/hwaddr.h"
@ -149,7 +148,6 @@ typedef struct CPUWatchpoint {
#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
struct TranslationBlock *current_tb; /* currently executing TB */ \
/* soft mmu support */ \
/* in order to avoid passing too many arguments to the MMIO \
helpers, we store some rarely used information in the CPU \
@ -160,7 +158,6 @@ typedef struct CPUWatchpoint {
memory was accessed */ \
uint32_t halted; /* Nonzero if the CPU is in suspend state */ \
uint32_t interrupt_request; \
volatile sig_atomic_t exit_request; \
CPU_COMMON_TLB \
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
/* buffer for temporaries in the code generator */ \
@ -191,8 +188,6 @@ typedef struct CPUWatchpoint {
int exception_index; \
\
CPUArchState *next_cpu; /* next CPU sharing TB cache */ \
uint32_t host_tid; /* host thread ID */ \
int running; /* Nonzero if cpu is currently running(usermode). */ \
/* user data */ \
void *opaque; \
\

View File

@ -404,11 +404,13 @@ extern volatile sig_atomic_t exit_request;
instruction of a TB so that interrupts take effect immediately. */
static inline int can_do_io(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
if (!use_icount) {
return 1;
}
/* If not executing code then assume we are ok. */
if (!env->current_tb) {
if (cpu->current_tb == NULL) {
return 1;
}
return env->can_do_io != 0;

View File

@ -30,12 +30,11 @@ 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);
static inline int cpu_index(CPUArchState *env)
static inline int cpu_index(CPUState *cpu)
{
#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL)
return env->host_tid;
return cpu->host_tid;
#else
CPUState *cpu = ENV_GET_CPU(env);
return cpu->cpu_index + 1;
#endif
}

View File

@ -20,6 +20,7 @@
#ifndef QEMU_CPU_H
#define QEMU_CPU_H
#include <signal.h>
#include "hw/qdev-core.h"
#include "qemu/thread.h"
@ -65,9 +66,13 @@ struct kvm_run;
* @nr_cores: Number of cores within this CPU package.
* @nr_threads: Number of threads within this CPU.
* @numa_node: NUMA node this CPU is belonging to.
* @host_tid: Host thread ID.
* @running: #true if CPU is currently running (usermode).
* @created: Indicates whether the CPU thread has been successfully created.
* @stop: Indicates a pending stop request.
* @stopped: Indicates the CPU has been artificially stopped.
* @env_ptr: Pointer to subclass-specific CPUArchState field.
* @current_tb: Currently executing TB.
* @kvm_fd: vCPU file descriptor for KVM.
*
* State of one CPU core or thread.
@ -86,12 +91,18 @@ struct CPUState {
HANDLE hThread;
#endif
int thread_id;
uint32_t host_tid;
bool running;
struct QemuCond *halt_cond;
struct qemu_work_item *queued_work_first, *queued_work_last;
bool thread_kicked;
bool created;
bool stop;
bool stopped;
volatile sig_atomic_t exit_request;
void *env_ptr; /* CPUArchState */
struct TranslationBlock *current_tb;
int kvm_fd;
bool kvm_vcpu_dirty;

View File

@ -1537,7 +1537,7 @@ int kvm_cpu_exec(CPUArchState *env)
DPRINTF("kvm_cpu_exec()\n");
if (kvm_arch_process_async_events(cpu)) {
env->exit_request = 0;
cpu->exit_request = 0;
return EXCP_HLT;
}
@ -1548,7 +1548,7 @@ int kvm_cpu_exec(CPUArchState *env)
}
kvm_arch_pre_run(cpu, run);
if (env->exit_request) {
if (cpu->exit_request) {
DPRINTF("interrupt exit requested\n");
/*
* KVM requires us to reenter the kernel after IO exits to complete
@ -1622,7 +1622,7 @@ int kvm_cpu_exec(CPUArchState *env)
vm_stop(RUN_STATE_INTERNAL_ERROR);
}
env->exit_request = 0;
cpu->exit_request = 0;
return ret;
}

View File

@ -151,13 +151,16 @@ static inline void exclusive_idle(void)
static inline void start_exclusive(void)
{
CPUArchState *other;
CPUState *other_cpu;
pthread_mutex_lock(&exclusive_lock);
exclusive_idle();
pending_cpus = 1;
/* Make all other cpus stop executing. */
for (other = first_cpu; other; other = other->next_cpu) {
if (other->running) {
other_cpu = ENV_GET_CPU(other);
if (other_cpu->running) {
pending_cpus++;
cpu_exit(other);
}
@ -176,19 +179,19 @@ static inline void end_exclusive(void)
}
/* Wait for exclusive ops to finish, and begin cpu execution. */
static inline void cpu_exec_start(CPUArchState *env)
static inline void cpu_exec_start(CPUState *cpu)
{
pthread_mutex_lock(&exclusive_lock);
exclusive_idle();
env->running = 1;
cpu->running = true;
pthread_mutex_unlock(&exclusive_lock);
}
/* Mark cpu as not executing, and release pending exclusive ops. */
static inline void cpu_exec_end(CPUArchState *env)
static inline void cpu_exec_end(CPUState *cpu)
{
pthread_mutex_lock(&exclusive_lock);
env->running = 0;
cpu->running = false;
if (pending_cpus > 1) {
pending_cpus--;
if (pending_cpus == 1) {
@ -210,11 +213,11 @@ void cpu_list_unlock(void)
}
#else /* if !CONFIG_USE_NPTL */
/* These are no-ops because we are not threadsafe. */
static inline void cpu_exec_start(CPUArchState *env)
static inline void cpu_exec_start(CPUState *cpu)
{
}
static inline void cpu_exec_end(CPUArchState *env)
static inline void cpu_exec_end(CPUState *cpu)
{
}
@ -697,15 +700,16 @@ done:
void cpu_loop(CPUARMState *env)
{
CPUState *cs = CPU(arm_env_get_cpu(env));
int trapnr;
unsigned int n, insn;
target_siginfo_t info;
uint32_t addr;
for(;;) {
cpu_exec_start(env);
cpu_exec_start(cs);
trapnr = cpu_arm_exec(env);
cpu_exec_end(env);
cpu_exec_end(cs);
switch(trapnr) {
case EXCP_UDEF:
{
@ -912,14 +916,15 @@ void cpu_loop(CPUARMState *env)
void cpu_loop(CPUUniCore32State *env)
{
CPUState *cs = CPU(uc32_env_get_cpu(env));
int trapnr;
unsigned int n, insn;
target_siginfo_t info;
for (;;) {
cpu_exec_start(env);
cpu_exec_start(cs);
trapnr = uc32_cpu_exec(env);
cpu_exec_end(env);
cpu_exec_end(cs);
switch (trapnr) {
case UC32_EXCP_PRIV:
{
@ -1367,14 +1372,15 @@ static int do_store_exclusive(CPUPPCState *env)
void cpu_loop(CPUPPCState *env)
{
CPUState *cs = CPU(ppc_env_get_cpu(env));
target_siginfo_t info;
int trapnr;
target_ulong ret;
for(;;) {
cpu_exec_start(env);
cpu_exec_start(cs);
trapnr = cpu_ppc_exec(env);
cpu_exec_end(env);
cpu_exec_end(cs);
switch(trapnr) {
case POWERPC_EXCP_NONE:
/* Just go on */
@ -2184,14 +2190,15 @@ static int do_store_exclusive(CPUMIPSState *env)
void cpu_loop(CPUMIPSState *env)
{
CPUState *cs = CPU(mips_env_get_cpu(env));
target_siginfo_t info;
int trapnr, ret;
unsigned int syscall_num;
for(;;) {
cpu_exec_start(env);
cpu_exec_start(cs);
trapnr = cpu_mips_exec(env);
cpu_exec_end(env);
cpu_exec_end(cs);
switch(trapnr) {
case EXCP_SYSCALL:
syscall_num = env->active_tc.gpr[2] - 4000;

View File

@ -4312,13 +4312,15 @@ static void *clone_func(void *arg)
{
new_thread_info *info = arg;
CPUArchState *env;
CPUState *cpu;
TaskState *ts;
env = info->env;
cpu = ENV_GET_CPU(env);
thread_env = env;
ts = (TaskState *)thread_env->opaque;
info->tid = gettid();
env->host_tid = info->tid;
cpu->host_tid = info->tid;
task_settid(ts);
if (info->child_tidptr)
put_user_u32(info->tid, info->child_tidptr);

View File

@ -32,6 +32,8 @@ void cpu_reset(CPUState *cpu)
static void cpu_common_reset(CPUState *cpu)
{
cpu->exit_request = 0;
cpu->current_tb = NULL;
}
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
@ -46,6 +48,10 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model)
return NULL;
}
static void cpu_common_realizefn(DeviceState *dev, Error **errp)
{
}
static void cpu_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@ -53,6 +59,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->class_by_name = cpu_common_class_by_name;
k->reset = cpu_common_reset;
dc->realize = cpu_common_realizefn;
dc->no_user = 1;
}

View File

@ -34,6 +34,7 @@
/**
* AlphaCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* An Alpha CPU model.
@ -43,6 +44,7 @@ typedef struct AlphaCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} AlphaCPUClass;

View File

@ -21,14 +21,16 @@
#include "cpu.h"
#include "qemu-common.h"
#include "qapi/error.h"
static void alpha_cpu_realize(Object *obj, Error **errp)
static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
{
AlphaCPU *cpu = ALPHA_CPU(obj);
AlphaCPU *cpu = ALPHA_CPU(dev);
AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev);
qemu_init_vcpu(&cpu->env);
acc->parent_realize(dev, errp);
}
/* Sort alphabetically by type name. */
@ -134,7 +136,8 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model)
env->cpu_model_str = cpu_model;
alpha_cpu_realize(OBJECT(cpu), NULL);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}
@ -230,9 +233,11 @@ static const TypeInfo ev68_cpu_type_info = {
static void alpha_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
AlphaCPU *cpu = ALPHA_CPU(obj);
CPUAlphaState *env = &cpu->env;
cs->env_ptr = env;
cpu_exec_init(env);
tlb_flush(env, 1);
@ -250,7 +255,12 @@ static void alpha_cpu_initfn(Object *obj)
static void alpha_cpu_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
AlphaCPUClass *acc = ALPHA_CPU_CLASS(oc);
acc->parent_realize = dc->realize;
dc->realize = alpha_cpu_realizefn;
cc->class_by_name = alpha_cpu_class_by_name;
}

View File

@ -33,6 +33,7 @@
/**
* ARMCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* An ARM CPU model.
@ -42,6 +43,7 @@ typedef struct ARMCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} ARMCPUClass;
@ -107,7 +109,6 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
#define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
void arm_cpu_realize(ARMCPU *cpu);
void register_cp_regs_for_features(ARMCPU *cpu);
#endif

View File

@ -134,11 +134,19 @@ static inline void set_feature(CPUARMState *env, int feature)
static void arm_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
ARMCPU *cpu = ARM_CPU(obj);
static bool inited;
cs->env_ptr = &cpu->env;
cpu_exec_init(&cpu->env);
cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
g_free, g_free);
if (tcg_enabled() && !inited) {
inited = true;
arm_translate_init();
}
}
static void arm_cpu_finalizefn(Object *obj)
@ -147,15 +155,12 @@ static void arm_cpu_finalizefn(Object *obj)
g_hash_table_destroy(cpu->cp_regs);
}
void arm_cpu_realize(ARMCPU *cpu)
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
{
/* This function is called by cpu_arm_init() because it
* needs to do common actions based on feature bits, etc
* that have been set by the subclass init functions.
* When we have QOM realize support it should become
* a true realize function instead.
*/
ARMCPU *cpu = ARM_CPU(dev);
ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
CPUARMState *env = &cpu->env;
/* Some features automatically imply others: */
if (arm_feature(env, ARM_FEATURE_V7)) {
set_feature(env, ARM_FEATURE_VAPA);
@ -197,6 +202,12 @@ void arm_cpu_realize(ARMCPU *cpu)
}
register_cp_regs_for_features(cpu);
arm_cpu_register_gdb_regs_for_features(cpu);
cpu_reset(CPU(cpu));
qemu_init_vcpu(env);
acc->parent_realize(dev, errp);
}
/* CPU models */
@ -782,6 +793,10 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(acc);
DeviceClass *dc = DEVICE_CLASS(oc);
acc->parent_realize = dc->realize;
dc->realize = arm_cpu_realizefn;
acc->parent_reset = cc->reset;
cc->reset = arm_cpu_reset;

View File

@ -234,6 +234,7 @@ typedef struct CPUARMState {
ARMCPU *cpu_arm_init(const char *cpu_model);
void arm_translate_init(void);
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
int cpu_arm_exec(CPUARMState *s);
void do_interrupt(CPUARMState *);
void switch_mode(CPUARMState *, int);

View File

@ -1263,7 +1263,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
ARMCPU *cpu;
CPUARMState *env;
ObjectClass *oc;
static int inited = 0;
oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
if (!oc) {
@ -1272,14 +1271,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
cpu = ARM_CPU(object_new(object_class_get_name(oc)));
env = &cpu->env;
env->cpu_model_str = cpu_model;
arm_cpu_realize(cpu);
if (tcg_enabled() && !inited) {
inited = 1;
arm_translate_init();
}
/* TODO this should be set centrally, once possible */
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
{
CPUARMState *env = &cpu->env;
cpu_reset(CPU(cpu));
if (arm_feature(env, ARM_FEATURE_NEON)) {
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
51, "arm-neon.xml", 0);
@ -1290,8 +1292,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
19, "arm-vfp.xml", 0);
}
qemu_init_vcpu(env);
return cpu;
}
/* Sort alphabetically by type name, except for "any". */

View File

@ -33,7 +33,9 @@
/**
* CRISCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
* @vr: Version Register value.
*
* A CRIS CPU model.
*/
@ -42,7 +44,10 @@ typedef struct CRISCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
uint32_t vr;
} CRISCPUClass;
/**

View File

@ -55,21 +55,194 @@ static void cris_cpu_reset(CPUState *s)
#endif
}
static ObjectClass *cris_cpu_class_by_name(const char *cpu_model)
{
ObjectClass *oc;
char *typename;
if (cpu_model == NULL) {
return NULL;
}
typename = g_strdup_printf("%s-" TYPE_CRIS_CPU, cpu_model);
oc = object_class_by_name(typename);
g_free(typename);
if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_CRIS_CPU) ||
object_class_is_abstract(oc))) {
oc = NULL;
}
return oc;
}
CRISCPU *cpu_cris_init(const char *cpu_model)
{
CRISCPU *cpu;
ObjectClass *oc;
oc = cris_cpu_class_by_name(cpu_model);
if (oc == NULL) {
return NULL;
}
cpu = CRIS_CPU(object_new(object_class_get_name(oc)));
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}
/* Sort alphabetically by VR. */
static gint cris_cpu_list_compare(gconstpointer a, gconstpointer b)
{
CRISCPUClass *ccc_a = CRIS_CPU_CLASS(a);
CRISCPUClass *ccc_b = CRIS_CPU_CLASS(b);
/* */
if (ccc_a->vr > ccc_b->vr) {
return 1;
} else if (ccc_a->vr < ccc_b->vr) {
return -1;
} else {
return 0;
}
}
static void cris_cpu_list_entry(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
CPUListState *s = user_data;
const char *typename = object_class_get_name(oc);
char *name;
name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_CRIS_CPU));
(*s->cpu_fprintf)(s->file, " %s\n", name);
g_free(name);
}
void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
CPUListState s = {
.file = f,
.cpu_fprintf = cpu_fprintf,
};
GSList *list;
list = object_class_get_list(TYPE_CRIS_CPU, false);
list = g_slist_sort(list, cris_cpu_list_compare);
(*cpu_fprintf)(f, "Available CPUs:\n");
g_slist_foreach(list, cris_cpu_list_entry, &s);
g_slist_free(list);
}
static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
{
CRISCPU *cpu = CRIS_CPU(dev);
CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(dev);
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
ccc->parent_realize(dev, errp);
}
static void cris_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
CRISCPU *cpu = CRIS_CPU(obj);
CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj);
CPUCRISState *env = &cpu->env;
static bool tcg_initialized;
cs->env_ptr = env;
cpu_exec_init(env);
env->pregs[PR_VR] = ccc->vr;
if (tcg_enabled() && !tcg_initialized) {
tcg_initialized = true;
if (env->pregs[PR_VR] < 32) {
cris_initialize_crisv10_tcg();
} else {
cris_initialize_tcg();
}
}
}
static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
{
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 8;
}
static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
{
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 9;
}
static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
{
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 10;
}
static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
{
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 11;
}
static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
{
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 32;
}
#define TYPE(model) model "-" TYPE_CRIS_CPU
static const TypeInfo cris_cpu_model_type_infos[] = {
{
.name = TYPE("crisv8"),
.parent = TYPE_CRIS_CPU,
.class_init = crisv8_cpu_class_init,
}, {
.name = TYPE("crisv9"),
.parent = TYPE_CRIS_CPU,
.class_init = crisv9_cpu_class_init,
}, {
.name = TYPE("crisv10"),
.parent = TYPE_CRIS_CPU,
.class_init = crisv10_cpu_class_init,
}, {
.name = TYPE("crisv11"),
.parent = TYPE_CRIS_CPU,
.class_init = crisv11_cpu_class_init,
}, {
.name = TYPE("crisv32"),
.parent = TYPE_CRIS_CPU,
.class_init = crisv32_cpu_class_init,
}
};
#undef TYPE
static void cris_cpu_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->parent_realize = dc->realize;
dc->realize = cris_cpu_realizefn;
ccc->parent_reset = cc->reset;
cc->reset = cris_cpu_reset;
cc->class_by_name = cris_cpu_class_by_name;
}
static const TypeInfo cris_cpu_type_info = {
@ -77,14 +250,19 @@ static const TypeInfo cris_cpu_type_info = {
.parent = TYPE_CPU,
.instance_size = sizeof(CRISCPU),
.instance_init = cris_cpu_initfn,
.abstract = false,
.abstract = true,
.class_size = sizeof(CRISCPUClass),
.class_init = cris_cpu_class_init,
};
static void cris_cpu_register_types(void)
{
int i;
type_register_static(&cris_cpu_type_info);
for (i = 0; i < ARRAY_SIZE(cris_cpu_model_type_infos); i++) {
type_register_static(&cris_cpu_model_type_infos[i]);
}
}
type_init(cris_cpu_register_types)

View File

@ -182,6 +182,9 @@ void do_interrupt(CPUCRISState *env);
int cpu_cris_signal_handler(int host_signum, void *pinfo,
void *puc);
void cris_initialize_tcg(void);
void cris_initialize_crisv10_tcg(void);
enum {
CC_OP_DYNAMIC, /* Use env->cc_op */
CC_OP_FLAGS,

View File

@ -3513,69 +3513,13 @@ void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
}
struct
void cris_initialize_tcg(void)
{
uint32_t vr;
const char *name;
} cris_cores[] = {
{8, "crisv8"},
{9, "crisv9"},
{10, "crisv10"},
{11, "crisv11"},
{32, "crisv32"},
};
void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
unsigned int i;
(*cpu_fprintf)(f, "Available CPUs:\n");
for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
(*cpu_fprintf)(f, " %s\n", cris_cores[i].name);
}
}
static uint32_t vr_by_name(const char *name)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
if (strcmp(name, cris_cores[i].name) == 0) {
return cris_cores[i].vr;
}
}
return 32;
}
CRISCPU *cpu_cris_init(const char *cpu_model)
{
CRISCPU *cpu;
CPUCRISState *env;
static int tcg_initialized = 0;
int i;
cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU));
env = &cpu->env;
env->pregs[PR_VR] = vr_by_name(cpu_model);
cpu_reset(CPU(cpu));
qemu_init_vcpu(env);
if (tcg_initialized) {
return cpu;
}
tcg_initialized = 1;
#define GEN_HELPER 2
#include "helper.h"
if (env->pregs[PR_VR] < 32) {
cpu_crisv10_init(env);
return cpu;
}
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
cc_x = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUCRISState, cc_x), "cc_x");
@ -3615,8 +3559,6 @@ CRISCPU *cpu_cris_init(const char *cpu_model)
offsetof(CPUCRISState, pregs[i]),
pregnames[i]);
}
return cpu;
}
void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)

View File

@ -1257,7 +1257,7 @@ static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc)
return insn_len;
}
static CPUCRISState *cpu_crisv10_init (CPUCRISState *env)
void cris_initialize_crisv10_tcg(void)
{
int i;
@ -1300,7 +1300,4 @@ static CPUCRISState *cpu_crisv10_init (CPUCRISState *env)
offsetof(CPUCRISState, pregs[i]),
pregnames_v10[i]);
}
return env;
}

View File

@ -39,6 +39,7 @@
/**
* X86CPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* An x86 CPU model or family.
@ -48,6 +49,7 @@ typedef struct X86CPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} X86CPUClass;
@ -72,8 +74,5 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
#define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
/* TODO Drop once ObjectClass::realize is available */
void x86_cpu_realize(Object *obj, Error **errp);
#endif

View File

@ -1516,16 +1516,50 @@ static void filter_features_for_kvm(X86CPU *cpu)
}
#endif
int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
{
CPUX86State *env = &cpu->env;
x86_def_t def1, *def = &def1;
Error *error = NULL;
char *name, *features;
gchar **model_pieces;
memset(def, 0, sizeof(*def));
if (cpu_x86_find_by_name(def, name) < 0) {
error_setg(errp, "Unable to find CPU definition: %s", name);
return;
}
if (kvm_enabled()) {
def->kvm_features |= kvm_default_features;
}
def->ext_features |= CPUID_EXT_HYPERVISOR;
object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
object_property_set_int(OBJECT(cpu), def->level, "level", errp);
object_property_set_int(OBJECT(cpu), def->family, "family", errp);
object_property_set_int(OBJECT(cpu), def->model, "model", errp);
object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
env->cpuid_features = def->features;
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
env->cpuid_ext3_features = def->ext3_features;
object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
env->cpuid_kvm_features = def->kvm_features;
env->cpuid_svm_features = def->svm_features;
env->cpuid_ext4_features = def->ext4_features;
env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
env->cpuid_xlevel2 = def->xlevel2;
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
}
X86CPU *cpu_x86_init(const char *cpu_model)
{
X86CPU *cpu = NULL;
CPUX86State *env;
gchar **model_pieces;
char *name, *features;
Error *error = NULL;
model_pieces = g_strsplit(cpu_model, ",", 2);
if (!model_pieces[0]) {
error_setg(&error, "Invalid/empty CPU model name");
@ -1534,46 +1568,36 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
name = model_pieces[0];
features = model_pieces[1];
if (cpu_x86_find_by_name(def, name) < 0) {
error_setg(&error, "Unable to find CPU definition: %s", name);
goto out;
}
cpu = X86_CPU(object_new(TYPE_X86_CPU));
env = &cpu->env;
env->cpu_model_str = cpu_model;
if (kvm_enabled()) {
def->kvm_features |= kvm_default_features;
}
def->ext_features |= CPUID_EXT_HYPERVISOR;
object_property_set_str(OBJECT(cpu), def->vendor, "vendor", &error);
object_property_set_int(OBJECT(cpu), def->level, "level", &error);
object_property_set_int(OBJECT(cpu), def->family, "family", &error);
object_property_set_int(OBJECT(cpu), def->model, "model", &error);
object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
env->cpuid_features = def->features;
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
env->cpuid_ext3_features = def->ext3_features;
object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
env->cpuid_kvm_features = def->kvm_features;
env->cpuid_svm_features = def->svm_features;
env->cpuid_ext4_features = def->ext4_features;
env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
env->cpuid_xlevel2 = def->xlevel2;
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
cpu_x86_register(cpu, name, &error);
if (error) {
goto out;
}
cpu_x86_parse_featurestr(cpu, features, &error);
if (error) {
goto out;
}
object_property_set_bool(OBJECT(cpu), true, "realized", &error);
if (error) {
goto out;
}
out:
g_strfreev(model_pieces);
if (error) {
fprintf(stderr, "%s\n", error_get_pretty(error));
error_free(error);
return -1;
if (cpu != NULL) {
object_unref(OBJECT(cpu));
cpu = NULL;
}
return 0;
}
return cpu;
}
#if !defined(CONFIG_USER_ONLY)
@ -2060,10 +2084,14 @@ static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
}
#endif
void x86_cpu_realize(Object *obj, Error **errp)
static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
{
X86CPU *cpu = X86_CPU(obj);
X86CPU *cpu = X86_CPU(dev);
X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
CPUX86State *env = &cpu->env;
#ifndef CONFIG_USER_ONLY
Error *local_err = NULL;
#endif
if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) {
env->cpuid_level = 7;
@ -2105,8 +2133,9 @@ void x86_cpu_realize(Object *obj, Error **errp)
qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) {
x86_cpu_apic_init(cpu, errp);
if (error_is_set(errp)) {
x86_cpu_apic_init(cpu, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
}
}
@ -2115,6 +2144,8 @@ void x86_cpu_realize(Object *obj, Error **errp)
mce_init(cpu);
qemu_init_vcpu(&cpu->env);
cpu_reset(CPU(cpu));
xcc->parent_realize(dev, errp);
}
/* Enables contiguous-apic-ID mode, for compatibility */
@ -2157,6 +2188,7 @@ static void x86_cpu_initfn(Object *obj)
CPUX86State *env = &cpu->env;
static int inited;
cs->env_ptr = env;
cpu_exec_init(env);
object_property_add(obj, "family", "int",
@ -2200,6 +2232,10 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
{
X86CPUClass *xcc = X86_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
xcc->parent_realize = dc->realize;
dc->realize = x86_cpu_realizefn;
xcc->parent_reset = cc->reset;
cc->reset = x86_cpu_reset;

View File

@ -1002,7 +1002,6 @@ int cpu_x86_signal_handler(int host_signum, void *pinfo,
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx);
int cpu_x86_register(X86CPU *cpu, const char *cpu_model);
void cpu_clear_apic_feature(CPUX86State *env);
void host_cpuid(uint32_t function, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);

View File

@ -1267,30 +1267,6 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
return 1;
}
X86CPU *cpu_x86_init(const char *cpu_model)
{
X86CPU *cpu;
CPUX86State *env;
Error *error = NULL;
cpu = X86_CPU(object_new(TYPE_X86_CPU));
env = &cpu->env;
env->cpu_model_str = cpu_model;
if (cpu_x86_register(cpu, cpu_model) < 0) {
object_unref(OBJECT(cpu));
return NULL;
}
x86_cpu_realize(OBJECT(cpu), &error);
if (error) {
error_free(error);
object_unref(OBJECT(cpu));
return NULL;
}
return cpu;
}
#if !defined(CONFIG_USER_ONLY)
void do_cpu_init(X86CPU *cpu)
{

View File

@ -1777,7 +1777,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
* or pending TPR access reports. */
if (env->interrupt_request &
(CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
env->exit_request = 1;
cpu->exit_request = 1;
}
/* Try to inject an interrupt if the guest can accept it */
@ -1847,7 +1847,7 @@ int kvm_arch_process_async_events(CPUState *cs)
if (env->exception_injected == EXCP08_DBLE) {
/* this means triple fault */
qemu_system_reset_request();
env->exit_request = 1;
cs->exit_request = 1;
return 0;
}
env->exception_injected = EXCP12_MCHK;

View File

@ -34,6 +34,7 @@
/**
* LM32CPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A LatticeMico32 CPU model.
@ -43,6 +44,7 @@ typedef struct LM32CPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} LM32CPUClass;

View File

@ -42,22 +42,44 @@ static void lm32_cpu_reset(CPUState *s)
memset(env, 0, offsetof(CPULM32State, breakpoints));
}
static void lm32_cpu_realizefn(DeviceState *dev, Error **errp)
{
LM32CPU *cpu = LM32_CPU(dev);
LM32CPUClass *lcc = LM32_CPU_GET_CLASS(dev);
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
lcc->parent_realize(dev, errp);
}
static void lm32_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
LM32CPU *cpu = LM32_CPU(obj);
CPULM32State *env = &cpu->env;
static bool tcg_initialized;
cs->env_ptr = env;
cpu_exec_init(env);
env->flags = 0;
cpu_reset(CPU(cpu));
if (tcg_enabled() && !tcg_initialized) {
tcg_initialized = true;
lm32_translate_init();
}
}
static void lm32_cpu_class_init(ObjectClass *oc, void *data)
{
LM32CPUClass *lcc = LM32_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
lcc->parent_realize = dc->realize;
dc->realize = lm32_cpu_realizefn;
lcc->parent_reset = cc->reset;
cc->reset = lm32_cpu_reset;

View File

@ -189,7 +189,6 @@ struct CPULM32State {
LM32CPU *cpu_lm32_init(const char *cpu_model);
void cpu_lm32_list(FILE *f, fprintf_function cpu_fprintf);
int cpu_lm32_exec(CPULM32State *s);
void cpu_lm32_close(CPULM32State *s);
void do_interrupt(CPULM32State *env);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero

View File

@ -197,7 +197,6 @@ LM32CPU *cpu_lm32_init(const char *cpu_model)
LM32CPU *cpu;
CPULM32State *env;
const LM32Def *def;
static int tcg_initialized;
def = cpu_lm32_find_by_name(cpu_model);
if (!def) {
@ -212,12 +211,7 @@ LM32CPU *cpu_lm32_init(const char *cpu_model)
env->num_wps = def->num_watchpoints;
env->cfg = cfg_by_def(def);
qemu_init_vcpu(env);
if (tcg_enabled() && !tcg_initialized) {
tcg_initialized = 1;
lm32_translate_init();
}
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}

View File

@ -33,6 +33,7 @@
/**
* M68kCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A Motorola 68k CPU model.
@ -42,6 +43,7 @@ typedef struct M68kCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} M68kCPUClass;

View File

@ -139,12 +139,33 @@ static const M68kCPUInfo m68k_cpus[] = {
{ .name = "any", .instance_init = any_cpu_initfn },
};
static void m68k_cpu_realizefn(DeviceState *dev, Error **errp)
{
M68kCPU *cpu = M68K_CPU(dev);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(dev);
m68k_cpu_init_gdb(cpu);
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
mcc->parent_realize(dev, errp);
}
static void m68k_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
M68kCPU *cpu = M68K_CPU(obj);
CPUM68KState *env = &cpu->env;
static bool inited;
cs->env_ptr = env;
cpu_exec_init(env);
if (tcg_enabled() && !inited) {
inited = true;
m68k_tcg_init();
}
}
static const VMStateDescription vmstate_m68k_cpu = {
@ -158,6 +179,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
CPUClass *cc = CPU_CLASS(c);
DeviceClass *dc = DEVICE_CLASS(c);
mcc->parent_realize = dc->realize;
dc->realize = m68k_cpu_realizefn;
mcc->parent_reset = cc->reset;
cc->reset = m68k_cpu_reset;

View File

@ -116,7 +116,8 @@ typedef struct CPUM68KState {
#include "cpu-qom.h"
void m68k_tcg_init(void);
CPUM68KState *cpu_m68k_init(const char *cpu_model);
void m68k_cpu_init_gdb(M68kCPU *cpu);
M68kCPU *cpu_m68k_init(const char *cpu_model);
int cpu_m68k_exec(CPUM68KState *s);
void do_interrupt(CPUM68KState *env1);
void do_interrupt_m68k_hardirq(CPUM68KState *env1);
@ -168,7 +169,7 @@ enum {
#define MACSR_V 0x002
#define MACSR_EV 0x001
void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector);
void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector);
void m68k_set_macsr(CPUM68KState *env, uint32_t val);
void m68k_switch_sp(CPUM68KState *env);
@ -214,7 +215,15 @@ void register_m68k_insns (CPUM68KState *env);
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32
#define cpu_init cpu_m68k_init
static inline CPUM68KState *cpu_init(const char *cpu_model)
{
M68kCPU *cpu = cpu_m68k_init(cpu_model);
if (cpu == NULL) {
return NULL;
}
return &cpu->env;
}
#define cpu_exec cpu_m68k_exec
#define cpu_gen_code cpu_m68k_gen_code
#define cpu_signal_handler cpu_m68k_signal_handler

View File

@ -98,12 +98,11 @@ static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
return 0;
}
CPUM68KState *cpu_m68k_init(const char *cpu_model)
M68kCPU *cpu_m68k_init(const char *cpu_model)
{
M68kCPU *cpu;
CPUM68KState *env;
ObjectClass *oc;
static int inited;
oc = cpu_class_by_name(TYPE_M68K_CPU, cpu_model);
if (oc == NULL) {
@ -111,24 +110,24 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model)
}
cpu = M68K_CPU(object_new(object_class_get_name(oc)));
env = &cpu->env;
if (!inited) {
inited = 1;
m68k_tcg_init();
}
env->cpu_model_str = cpu_model;
register_m68k_insns(env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}
void m68k_cpu_init_gdb(M68kCPU *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,
11, "cf-fp.xml", 18);
}
/* TODO: Add [E]MAC registers. */
cpu_reset(ENV_GET_CPU(env));
qemu_init_vcpu(env);
return env;
}
void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
@ -311,8 +310,10 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
be handled by the interrupt controller. Real hardware only requests
the vector when the interrupt is acknowledged by the CPU. For
simplicitly we calculate it when the interrupt is signalled. */
void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
{
CPUM68KState *env = &cpu->env;
env->pending_level = level;
env->pending_vector = vector;
if (level)

View File

@ -33,6 +33,7 @@
/**
* MicroBlazeCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A MicroBlaze CPU model.
@ -42,6 +43,7 @@ typedef struct MicroBlazeCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} MicroBlazeCPUClass;

View File

@ -85,14 +85,33 @@ static void mb_cpu_reset(CPUState *s)
#endif
}
static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(dev);
MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev);
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
mcc->parent_realize(dev, errp);
}
static void mb_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
MicroBlazeCPU *cpu = MICROBLAZE_CPU(obj);
CPUMBState *env = &cpu->env;
static bool tcg_initialized;
cs->env_ptr = env;
cpu_exec_init(env);
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
if (tcg_enabled() && !tcg_initialized) {
tcg_initialized = true;
mb_tcg_init();
}
}
static const VMStateDescription vmstate_mb_cpu = {
@ -106,6 +125,9 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
CPUClass *cc = CPU_CLASS(oc);
MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_CLASS(oc);
mcc->parent_realize = dc->realize;
dc->realize = mb_cpu_realizefn;
mcc->parent_reset = cc->reset;
cc->reset = mb_cpu_reset;

View File

@ -272,6 +272,7 @@ struct CPUMBState {
#include "cpu-qom.h"
void mb_tcg_init(void);
MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
int cpu_mb_exec(CPUMBState *s);
void do_interrupt(CPUMBState *env);

View File

@ -1965,19 +1965,17 @@ void cpu_dump_state (CPUMBState *env, FILE *f, fprintf_function cpu_fprintf,
MicroBlazeCPU *cpu_mb_init(const char *cpu_model)
{
MicroBlazeCPU *cpu;
static int tcg_initialized = 0;
int i;
cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
if (tcg_initialized) {
return cpu;
}
}
tcg_initialized = 1;
void mb_tcg_init(void)
{
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
@ -2008,8 +2006,6 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model)
}
#define GEN_HELPER 2
#include "helper.h"
return cpu;
}
void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos)

View File

@ -37,6 +37,7 @@
/**
* MIPSCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A MIPS CPU model.
@ -46,6 +47,7 @@ typedef struct MIPSCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} MIPSCPUClass;

View File

@ -42,18 +42,39 @@ static void mips_cpu_reset(CPUState *s)
cpu_state_reset(env);
}
static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
{
MIPSCPU *cpu = MIPS_CPU(dev);
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
mcc->parent_realize(dev, errp);
}
static void mips_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
MIPSCPU *cpu = MIPS_CPU(obj);
CPUMIPSState *env = &cpu->env;
cs->env_ptr = env;
cpu_exec_init(env);
if (tcg_enabled()) {
mips_tcg_init();
}
}
static void mips_cpu_class_init(ObjectClass *c, void *data)
{
MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
CPUClass *cc = CPU_CLASS(c);
DeviceClass *dc = DEVICE_CLASS(c);
mcc->parent_realize = dc->realize;
dc->realize = mips_cpu_realizefn;
mcc->parent_reset = cc->reset;
cc->reset = mips_cpu_reset;

View File

@ -629,6 +629,7 @@ enum {
#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
int cpu_mips_exec(CPUMIPSState *s);
void mips_tcg_init(void);
MIPSCPU *cpu_mips_init(const char *cpu_model);
int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);

View File

@ -15836,7 +15836,7 @@ void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
#endif
}
static void mips_tcg_init(void)
void mips_tcg_init(void)
{
int i;
static int inited;
@ -15915,9 +15915,9 @@ MIPSCPU *cpu_mips_init(const char *cpu_model)
#endif
fpu_init(env, def);
mvp_init(env, def);
mips_tcg_init();
cpu_reset(CPU(cpu));
qemu_init_vcpu(env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}

View File

@ -62,19 +62,24 @@ static inline void set_feature(OpenRISCCPU *cpu, int feature)
cpu->env.cpucfgr = cpu->feature;
}
void openrisc_cpu_realize(Object *obj, Error **errp)
static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
{
OpenRISCCPU *cpu = OPENRISC_CPU(obj);
OpenRISCCPU *cpu = OPENRISC_CPU(dev);
OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(dev);
qemu_init_vcpu(&cpu->env);
cpu_reset(CPU(cpu));
occ->parent_realize(dev, errp);
}
static void openrisc_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
OpenRISCCPU *cpu = OPENRISC_CPU(obj);
static int inited;
cs->env_ptr = &cpu->env;
cpu_exec_init(&cpu->env);
#ifndef CONFIG_USER_ONLY
@ -134,6 +139,10 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
{
OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(occ);
DeviceClass *dc = DEVICE_CLASS(oc);
occ->parent_realize = dc->realize;
dc->realize = openrisc_cpu_realizefn;
occ->parent_reset = cc->reset;
cc->reset = openrisc_cpu_reset;
@ -187,7 +196,7 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model)
cpu = OPENRISC_CPU(object_new(object_class_get_name(oc)));
cpu->env.cpu_model_str = cpu_model;
openrisc_cpu_realize(OBJECT(cpu), NULL);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}

View File

@ -33,7 +33,6 @@ struct OpenRISCCPU;
#include "exec/cpu-defs.h"
#include "fpu/softfloat.h"
#include "qom/cpu.h"
#include "qapi/error.h"
#define TYPE_OPENRISC_CPU "or32-cpu"
@ -46,6 +45,7 @@ struct OpenRISCCPU;
/**
* OpenRISCCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A OpenRISC CPU model.
@ -55,6 +55,7 @@ typedef struct OpenRISCCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} OpenRISCCPUClass;
@ -340,7 +341,6 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
void openrisc_cpu_realize(Object *obj, Error **errp);
void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
int cpu_openrisc_exec(CPUOpenRISCState *s);

View File

@ -40,6 +40,7 @@
/**
* PowerPCCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A PowerPC CPU model.
@ -49,6 +50,7 @@ typedef struct PowerPCCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
/* TODO inline fields here */

View File

@ -10030,9 +10030,9 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu)
return 0;
}
static void ppc_cpu_realize(Object *obj, Error **errp)
static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(obj);
PowerPCCPU *cpu = POWERPC_CPU(dev);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
ppc_def_t *def = pcc->info;
@ -10083,6 +10083,8 @@ static void ppc_cpu_realize(Object *obj, Error **errp)
qemu_init_vcpu(env);
pcc->parent_realize(dev, errp);
#if defined(PPC_DUMP_CPU)
{
const char *mmu_model, *excp_model, *bus_model;
@ -10347,14 +10349,9 @@ PowerPCCPU *cpu_ppc_init(const char *cpu_model)
cpu = POWERPC_CPU(object_new(object_class_get_name(oc)));
env = &cpu->env;
if (tcg_enabled()) {
ppc_translate_init();
}
env->cpu_model_str = cpu_model;
ppc_cpu_realize(OBJECT(cpu), &err);
object_property_set_bool(OBJECT(cpu), true, "realized", &err);
if (err != NULL) {
fprintf(stderr, "%s\n", error_get_pretty(err));
error_free(err);
@ -10532,11 +10529,13 @@ static void ppc_cpu_reset(CPUState *s)
static void ppc_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
PowerPCCPU *cpu = POWERPC_CPU(obj);
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
CPUPPCState *env = &cpu->env;
ppc_def_t *def = pcc->info;
cs->env_ptr = env;
cpu_exec_init(env);
env->msr_mask = def->msr_mask;
@ -10569,12 +10568,20 @@ static void ppc_cpu_initfn(Object *obj)
env->sps = defsps;
}
#endif /* defined(TARGET_PPC64) */
if (tcg_enabled()) {
ppc_translate_init();
}
}
static void ppc_cpu_class_init(ObjectClass *oc, void *data)
{
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
pcc->parent_realize = dc->realize;
dc->realize = ppc_cpu_realizefn;
pcc->parent_reset = cc->reset;
cc->reset = ppc_cpu_reset;

View File

@ -34,6 +34,7 @@
/**
* S390CPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* An S/390 CPU model.
@ -43,6 +44,7 @@ typedef struct S390CPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} S390CPUClass;

View File

@ -97,15 +97,29 @@ static void s390_cpu_machine_reset_cb(void *opaque)
}
#endif
static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
{
S390CPU *cpu = S390_CPU(dev);
S390CPUClass *scc = S390_CPU_GET_CLASS(dev);
qemu_init_vcpu(&cpu->env);
cpu_reset(CPU(cpu));
scc->parent_realize(dev, errp);
}
static void s390_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
S390CPU *cpu = S390_CPU(obj);
CPUS390XState *env = &cpu->env;
static bool inited;
static int cpu_num = 0;
#if !defined(CONFIG_USER_ONLY)
struct tm tm;
#endif
cs->env_ptr = env;
cpu_exec_init(env);
#if !defined(CONFIG_USER_ONLY)
qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
@ -123,7 +137,10 @@ static void s390_cpu_initfn(Object *obj)
env->cpu_num = cpu_num++;
env->ext_index = -1;
cpu_reset(CPU(cpu));
if (tcg_enabled() && !inited) {
inited = true;
s390x_translate_init();
}
}
static void s390_cpu_finalize(Object *obj)
@ -146,6 +163,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
CPUClass *cc = CPU_CLASS(scc);
DeviceClass *dc = DEVICE_CLASS(oc);
scc->parent_realize = dc->realize;
dc->realize = s390_cpu_realizefn;
scc->parent_reset = cc->reset;
cc->reset = s390_cpu_reset;

View File

@ -315,7 +315,6 @@ static inline int get_ilen(uint8_t opc)
S390CPU *cpu_s390x_init(const char *cpu_model);
void s390x_translate_init(void);
int cpu_s390x_exec(CPUS390XState *s);
void cpu_s390x_close(CPUS390XState *s);
void do_interrupt (CPUS390XState *env);
/* you can call this signal handler from your SIGBUS and SIGSEGV

View File

@ -74,18 +74,13 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
{
S390CPU *cpu;
CPUS390XState *env;
static int inited;
cpu = S390_CPU(object_new(TYPE_S390_CPU));
env = &cpu->env;
if (tcg_enabled() && !inited) {
inited = 1;
s390x_translate_init();
}
env->cpu_model_str = cpu_model;
qemu_init_vcpu(env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}

View File

@ -33,6 +33,7 @@
/**
* SuperHCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A SuperH CPU model.
@ -42,6 +43,7 @@ typedef struct SuperHCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} SuperHCPUClass;

View File

@ -54,14 +54,31 @@ static void superh_cpu_reset(CPUState *s)
set_default_nan_mode(1, &env->fp_status);
}
static void superh_cpu_realizefn(DeviceState *dev, Error **errp)
{
SuperHCPU *cpu = SUPERH_CPU(dev);
SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(dev);
cpu_reset(CPU(cpu));
qemu_init_vcpu(&cpu->env);
scc->parent_realize(dev, errp);
}
static void superh_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
SuperHCPU *cpu = SUPERH_CPU(obj);
CPUSH4State *env = &cpu->env;
cs->env_ptr = env;
cpu_exec_init(env);
env->movcal_backup_tail = &(env->movcal_backup);
if (tcg_enabled()) {
sh4_translate_init();
}
}
static const VMStateDescription vmstate_sh_cpu = {
@ -75,6 +92,9 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
CPUClass *cc = CPU_CLASS(oc);
SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
scc->parent_realize = dc->realize;
dc->realize = superh_cpu_realizefn;
scc->parent_reset = cc->reset;
cc->reset = superh_cpu_reset;

View File

@ -191,6 +191,7 @@ typedef struct CPUSH4State {
#include "cpu-qom.h"
void sh4_translate_init(void);
SuperHCPU *cpu_sh4_init(const char *cpu_model);
int cpu_sh4_exec(CPUSH4State * s);
int cpu_sh4_signal_handler(int host_signum, void *pinfo,

View File

@ -71,7 +71,7 @@ static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
#include "exec/gen-icount.h"
static void sh4_translate_init(void)
void sh4_translate_init(void)
{
int i;
static int done_init = 0;
@ -251,11 +251,11 @@ SuperHCPU *cpu_sh4_init(const char *cpu_model)
cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU));
env = &cpu->env;
env->features = def->features;
sh4_translate_init();
env->cpu_model_str = cpu_model;
cpu_reset(CPU(cpu));
cpu_register(env, def);
qemu_init_vcpu(env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}

View File

@ -38,6 +38,7 @@
/**
* SPARCCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A SPARC CPU model.
@ -47,6 +48,7 @@ typedef struct SPARCCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} SPARCCPUClass;

View File

@ -114,15 +114,12 @@ SPARCCPU *cpu_sparc_init(const char *cpu_model)
cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
env = &cpu->env;
if (tcg_enabled()) {
gen_intermediate_code_init(env);
}
if (cpu_sparc_register(env, cpu_model) < 0) {
object_unref(OBJECT(cpu));
return NULL;
}
qemu_init_vcpu(env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}
@ -851,12 +848,28 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "\n");
}
static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
{
SPARCCPU *cpu = SPARC_CPU(dev);
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
qemu_init_vcpu(&cpu->env);
scc->parent_realize(dev, errp);
}
static void sparc_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
SPARCCPU *cpu = SPARC_CPU(obj);
CPUSPARCState *env = &cpu->env;
cs->env_ptr = env;
cpu_exec_init(env);
if (tcg_enabled()) {
gen_intermediate_code_init(env);
}
}
static void sparc_cpu_uninitfn(Object *obj)
@ -871,6 +884,10 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
{
SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
scc->parent_realize = dc->realize;
dc->realize = sparc_cpu_realizefn;
scc->parent_reset = cc->reset;
cc->reset = sparc_cpu_reset;

View File

@ -25,6 +25,7 @@
/**
* UniCore32CPUClass:
* @parent_realize: The parent class' realize handler.
*
* A UniCore32 CPU model.
*/
@ -32,6 +33,8 @@ typedef struct UniCore32CPUClass {
/*< private >*/
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
} UniCore32CPUClass;
/**

View File

@ -81,11 +81,24 @@ static const UniCore32CPUInfo uc32_cpus[] = {
{ .name = "any", .instance_init = uc32_any_cpu_initfn },
};
static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)
{
UniCore32CPU *cpu = UNICORE32_CPU(dev);
UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev);
qemu_init_vcpu(&cpu->env);
ucc->parent_realize(dev, errp);
}
static void uc32_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
UniCore32CPU *cpu = UNICORE32_CPU(obj);
CPUUniCore32State *env = &cpu->env;
static bool inited;
cs->env_ptr = env;
cpu_exec_init(env);
#ifdef CONFIG_USER_ONLY
@ -97,6 +110,11 @@ static void uc32_cpu_initfn(Object *obj)
#endif
tlb_flush(env, 1);
if (tcg_enabled() && !inited) {
inited = true;
uc32_translate_init();
}
}
static const VMStateDescription vmstate_uc32_cpu = {
@ -108,6 +126,10 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc);
ucc->parent_realize = dc->realize;
dc->realize = uc32_cpu_realizefn;
cc->class_by_name = uc32_cpu_class_by_name;
dc->vmsd = &vmstate_uc32_cpu;

View File

@ -30,7 +30,6 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model)
UniCore32CPU *cpu;
CPUUniCore32State *env;
ObjectClass *oc;
static int inited = 1;
oc = cpu_class_by_name(TYPE_UNICORE32_CPU, cpu_model);
if (oc == NULL) {
@ -40,12 +39,8 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model)
env = &cpu->env;
env->cpu_model_str = cpu_model;
if (inited) {
inited = 0;
uc32_translate_init();
}
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
qemu_init_vcpu(env);
return env;
}

View File

@ -43,6 +43,7 @@
/**
* XtensaCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* An Xtensa CPU model.
@ -52,6 +53,7 @@ typedef struct XtensaCPUClass {
CPUClass parent_class;
/*< public >*/
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} XtensaCPUClass;

View File

@ -57,12 +57,31 @@ static void xtensa_cpu_reset(CPUState *s)
reset_mmu(env);
}
static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
{
XtensaCPU *cpu = XTENSA_CPU(dev);
XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
qemu_init_vcpu(&cpu->env);
xcc->parent_realize(dev, errp);
}
static void xtensa_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
XtensaCPU *cpu = XTENSA_CPU(obj);
CPUXtensaState *env = &cpu->env;
static bool tcg_inited;
cs->env_ptr = env;
cpu_exec_init(env);
if (tcg_enabled() && !tcg_inited) {
tcg_inited = true;
xtensa_translate_init();
cpu_set_debug_excp_handler(xtensa_breakpoint_handler);
}
}
static const VMStateDescription vmstate_xtensa_cpu = {
@ -76,6 +95,9 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
CPUClass *cc = CPU_CLASS(oc);
XtensaCPUClass *xcc = XTENSA_CPU_CLASS(cc);
xcc->parent_realize = dc->realize;
dc->realize = xtensa_cpu_realizefn;
xcc->parent_reset = cc->reset;
cc->reset = xtensa_cpu_reset;

View File

@ -385,6 +385,7 @@ static inline CPUXtensaState *cpu_init(const char *cpu_model)
}
void xtensa_translate_init(void);
void xtensa_breakpoint_handler(CPUXtensaState *env);
int cpu_xtensa_exec(CPUXtensaState *s);
void xtensa_register_core(XtensaConfigList *node);
void do_interrupt(CPUXtensaState *s);

View File

@ -54,7 +54,7 @@ static uint32_t check_hw_breakpoints(CPUXtensaState *env)
return 0;
}
static void breakpoint_handler(CPUXtensaState *env)
void xtensa_breakpoint_handler(CPUXtensaState *env)
{
if (env->watchpoint_hit) {
if (env->watchpoint_hit->flags & BP_CPU) {
@ -72,8 +72,6 @@ static void breakpoint_handler(CPUXtensaState *env)
XtensaCPU *cpu_xtensa_init(const char *cpu_model)
{
static int tcg_inited;
static int debug_handler_inited;
XtensaCPU *cpu;
CPUXtensaState *env;
const XtensaConfig *config = NULL;
@ -93,18 +91,10 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model)
env = &cpu->env;
env->config = config;
if (!tcg_inited) {
tcg_inited = 1;
xtensa_translate_init();
}
if (!debug_handler_inited && tcg_enabled()) {
debug_handler_inited = 1;
cpu_set_debug_excp_handler(breakpoint_handler);
}
xtensa_irq_init(env);
qemu_init_vcpu(env);
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
return cpu;
}

View File

@ -998,6 +998,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
{
TranslationBlock *tb, *tb_next, *saved_tb;
CPUArchState *env = cpu_single_env;
CPUState *cpu = NULL;
tb_page_addr_t tb_start, tb_end;
PageDesc *p;
int n;
@ -1020,6 +1021,9 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
/* build code bitmap */
build_page_bitmap(p);
}
if (env != NULL) {
cpu = ENV_GET_CPU(env);
}
/* we remove all the TBs in the range [start, end[ */
/* XXX: see if in some cases it could be faster to invalidate all
@ -1066,14 +1070,14 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
/* we need to do that to handle the case where a signal
occurs while doing tb_phys_invalidate() */
saved_tb = NULL;
if (env) {
saved_tb = env->current_tb;
env->current_tb = NULL;
if (cpu != NULL) {
saved_tb = cpu->current_tb;
cpu->current_tb = NULL;
}
tb_phys_invalidate(tb, -1);
if (env) {
env->current_tb = saved_tb;
if (env->interrupt_request && env->current_tb) {
if (cpu != NULL) {
cpu->current_tb = saved_tb;
if (env && env->interrupt_request && cpu->current_tb) {
cpu_interrupt(env, env->interrupt_request);
}
}
@ -1094,7 +1098,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
/* we generate a block containing just the instruction
modifying the memory. It will ensure that it cannot modify
itself */
env->current_tb = NULL;
cpu->current_tb = NULL;
tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
cpu_resume_from_signal(env, NULL);
}
@ -1142,6 +1146,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
#ifdef TARGET_HAS_PRECISE_SMC
TranslationBlock *current_tb = NULL;
CPUArchState *env = cpu_single_env;
CPUState *cpu = NULL;
int current_tb_modified = 0;
target_ulong current_pc = 0;
target_ulong current_cs_base = 0;
@ -1158,6 +1163,9 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
if (tb && pc != 0) {
current_tb = tb_find_pc(pc);
}
if (env != NULL) {
cpu = ENV_GET_CPU(env);
}
#endif
while (tb != NULL) {
n = (uintptr_t)tb & 3;
@ -1186,7 +1194,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
/* we generate a block containing just the instruction
modifying the memory. It will ensure that it cannot modify
itself */
env->current_tb = NULL;
cpu->current_tb = NULL;
tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
cpu_resume_from_signal(env, puc);
}
@ -1408,7 +1416,7 @@ void tb_invalidate_phys_addr(hwaddr addr)
}
#endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */
void cpu_unlink_tb(CPUArchState *env)
void cpu_unlink_tb(CPUState *cpu)
{
/* FIXME: TB unchaining isn't SMP safe. For now just ignore the
problem and hope the cpu will stop of its own accord. For userspace
@ -1418,11 +1426,11 @@ void cpu_unlink_tb(CPUArchState *env)
static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
spin_lock(&interrupt_lock);
tb = env->current_tb;
tb = cpu->current_tb;
/* if the cpu is currently executing code, we must unlink it and
all the potentially executing TB */
if (tb) {
env->current_tb = NULL;
cpu->current_tb = NULL;
tb_reset_jump_recursive(tb);
}
spin_unlock(&interrupt_lock);
@ -1467,7 +1475,7 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask)
cpu_abort(env, "Raised interrupt while not in I/O function");
}
} else {
cpu_unlink_tb(env);
cpu_unlink_tb(cpu);
}
}
@ -1615,8 +1623,10 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
void cpu_interrupt(CPUArchState *env, int mask)
{
CPUState *cpu = ENV_GET_CPU(env);
env->interrupt_request |= mask;
cpu_unlink_tb(env);
cpu_unlink_tb(cpu);
}
/*

View File

@ -28,7 +28,7 @@
/* translate-all.c */
void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
void cpu_unlink_tb(CPUArchState *env);
void cpu_unlink_tb(CPUState *cpu);
void tb_check_watchpoint(CPUArchState *env);
#endif /* TRANSLATE_ALL_H */