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:
commit
3c3adde005
21
cpu-exec.c
21
cpu-exec.c
@ -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(;;) */
|
||||
|
6
cputlb.c
6
cputlb.c
@ -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
8
dump.c
@ -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
6
exec.c
@ -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, ...)
|
||||
|
14
gdbstub.c
14
gdbstub.c
@ -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);
|
||||
|
11
hw/an5206.c
11
hw/an5206.c
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
4
hw/mcf.h
4
hw/mcf.h
@ -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
|
||||
|
@ -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;
|
||||
|
11
hw/mcf5208.c
11
hw/mcf5208.c
@ -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]);
|
||||
|
@ -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);
|
||||
|
1
hw/pc.c
1
hw/pc.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
12
hw/ppc.c
12
hw/ppc.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
6
hw/ppc.h
6
hw/ppc.h
@ -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[];
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; \
|
||||
\
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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". */
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user