mirror of https://github.com/xemu-project/xemu.git
Merge branch 'qom-cpu-rest.v1' of git://github.com/afaerber/qemu-cpu
* 'qom-cpu-rest.v1' of git://github.com/afaerber/qemu-cpu: Makefile: Simplify compilation of target-*/cpu.c target-mips: Start QOM'ifying CPU init target-mips: QOM'ify CPU target-m68k: Add QOM CPU subclasses target-m68k: Start QOM'ifying CPU init target-m68k: QOM'ify CPU reset target-m68k: QOM'ify CPU target-sh4: Start QOM'ifying CPU init target-sh4: QOM'ify CPU reset target-sh4: QOM'ify CPU MAINTAINERS: Downgrade target-mips and target-sh4 to Odd Fixes MAINTAINERS: Downgrade target-m68k to Odd Fixes
This commit is contained in:
commit
61d25e1548
|
@ -78,7 +78,7 @@ F: target-lm32/
|
||||||
|
|
||||||
M68K
|
M68K
|
||||||
M: Paul Brook <paul@codesourcery.com>
|
M: Paul Brook <paul@codesourcery.com>
|
||||||
S: Maintained
|
S: Odd Fixes
|
||||||
F: target-m68k/
|
F: target-m68k/
|
||||||
|
|
||||||
MicroBlaze
|
MicroBlaze
|
||||||
|
@ -88,7 +88,7 @@ F: target-microblaze/
|
||||||
|
|
||||||
MIPS
|
MIPS
|
||||||
M: Aurelien Jarno <aurelien@aurel32.net>
|
M: Aurelien Jarno <aurelien@aurel32.net>
|
||||||
S: Maintained
|
S: Odd Fixes
|
||||||
F: target-mips/
|
F: target-mips/
|
||||||
|
|
||||||
PowerPC
|
PowerPC
|
||||||
|
@ -104,7 +104,7 @@ F: target-s390x/
|
||||||
|
|
||||||
SH4
|
SH4
|
||||||
M: Aurelien Jarno <aurelien@aurel32.net>
|
M: Aurelien Jarno <aurelien@aurel32.net>
|
||||||
S: Maintained
|
S: Odd Fixes
|
||||||
F: target-sh4/
|
F: target-sh4/
|
||||||
|
|
||||||
SPARC
|
SPARC
|
||||||
|
|
|
@ -87,27 +87,18 @@ libobj-y += op_helper.o
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
libobj-y += helper.o
|
libobj-y += helper.o
|
||||||
ifeq ($(TARGET_BASE_ARCH), i386)
|
ifneq ($(TARGET_BASE_ARCH), ppc)
|
||||||
libobj-y += cpu.o
|
libobj-y += cpu.o
|
||||||
endif
|
endif
|
||||||
libobj-$(TARGET_SPARC64) += vis_helper.o
|
libobj-$(TARGET_SPARC64) += vis_helper.o
|
||||||
libobj-$(CONFIG_NEED_MMU) += mmu.o
|
libobj-$(CONFIG_NEED_MMU) += mmu.o
|
||||||
libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
|
libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
|
||||||
libobj-$(TARGET_ARM) += cpu.o
|
|
||||||
libobj-$(TARGET_CRIS) += cpu.o
|
|
||||||
libobj-$(TARGET_LM32) += cpu.o
|
|
||||||
libobj-$(TARGET_MICROBLAZE) += cpu.o
|
|
||||||
libobj-$(TARGET_S390X) += cpu.o
|
|
||||||
ifeq ($(TARGET_BASE_ARCH), sparc)
|
ifeq ($(TARGET_BASE_ARCH), sparc)
|
||||||
libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
|
libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
|
||||||
libobj-y += cpu.o
|
|
||||||
endif
|
endif
|
||||||
libobj-$(TARGET_SPARC) += int32_helper.o
|
libobj-$(TARGET_SPARC) += int32_helper.o
|
||||||
libobj-$(TARGET_SPARC64) += int64_helper.o
|
libobj-$(TARGET_SPARC64) += int64_helper.o
|
||||||
libobj-$(TARGET_UNICORE32) += cpu.o
|
|
||||||
libobj-$(TARGET_XTENSA) += cpu.o
|
|
||||||
libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
|
libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
|
||||||
libobj-$(TARGET_ALPHA) += cpu.o
|
|
||||||
|
|
||||||
libobj-y += disas.o
|
libobj-y += disas.o
|
||||||
libobj-$(CONFIG_TCI_DIS) += tci-dis.o
|
libobj-$(CONFIG_TCI_DIS) += tci-dis.o
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* QEMU Motorola 68k CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||||
|
*/
|
||||||
|
#ifndef QEMU_M68K_CPU_QOM_H
|
||||||
|
#define QEMU_M68K_CPU_QOM_H
|
||||||
|
|
||||||
|
#include "qemu/cpu.h"
|
||||||
|
|
||||||
|
#define TYPE_M68K_CPU "m68k-cpu"
|
||||||
|
|
||||||
|
#define M68K_CPU_CLASS(klass) \
|
||||||
|
OBJECT_CLASS_CHECK(M68kCPUClass, (klass), TYPE_M68K_CPU)
|
||||||
|
#define M68K_CPU(obj) \
|
||||||
|
OBJECT_CHECK(M68kCPU, (obj), TYPE_M68K_CPU)
|
||||||
|
#define M68K_CPU_GET_CLASS(obj) \
|
||||||
|
OBJECT_GET_CLASS(M68kCPUClass, (obj), TYPE_M68K_CPU)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* M68kCPUClass:
|
||||||
|
* @parent_reset: The parent class' reset handler.
|
||||||
|
*
|
||||||
|
* A Motorola 68k CPU model.
|
||||||
|
*/
|
||||||
|
typedef struct M68kCPUClass {
|
||||||
|
/*< private >*/
|
||||||
|
CPUClass parent_class;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
void (*parent_reset)(CPUState *cpu);
|
||||||
|
} M68kCPUClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* M68kCPU:
|
||||||
|
* @env: #CPUM68KState
|
||||||
|
*
|
||||||
|
* A Motorola 68k CPU.
|
||||||
|
*/
|
||||||
|
typedef struct M68kCPU {
|
||||||
|
/*< private >*/
|
||||||
|
CPUState parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
CPUM68KState env;
|
||||||
|
} M68kCPU;
|
||||||
|
|
||||||
|
static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
|
||||||
|
{
|
||||||
|
return M68K_CPU(container_of(env, M68kCPU, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ENV_GET_CPU(e) CPU(m68k_env_get_cpu(e))
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* QEMU Motorola 68k CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void m68k_set_feature(CPUM68KState *env, int feature)
|
||||||
|
{
|
||||||
|
env->features |= (1u << feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CPUClass::reset() */
|
||||||
|
static void m68k_cpu_reset(CPUState *s)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(s);
|
||||||
|
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
|
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||||
|
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
||||||
|
log_cpu_state(env, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mcc->parent_reset(s);
|
||||||
|
|
||||||
|
memset(env, 0, offsetof(CPUM68KState, breakpoints));
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
env->sr = 0x2700;
|
||||||
|
#endif
|
||||||
|
m68k_switch_sp(env);
|
||||||
|
/* ??? FP regs should be initialized to NaN. */
|
||||||
|
env->cc_op = CC_OP_FLAGS;
|
||||||
|
/* TODO: We should set PC from the interrupt vector. */
|
||||||
|
env->pc = 0;
|
||||||
|
tlb_flush(env, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CPU models */
|
||||||
|
|
||||||
|
static void m5206_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(obj);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void m5208_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(obj);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_BRAL);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_USP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cfv4e_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(obj);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_BRAL);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_FPU);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_USP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void any_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(obj);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_BRAL);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_FPU);
|
||||||
|
/* MAC and EMAC are mututally exclusive, so pick EMAC.
|
||||||
|
It's mostly backwards compatible. */
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_USP);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
|
||||||
|
m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct M68kCPUInfo {
|
||||||
|
const char *name;
|
||||||
|
void (*instance_init)(Object *obj);
|
||||||
|
} M68kCPUInfo;
|
||||||
|
|
||||||
|
static const M68kCPUInfo m68k_cpus[] = {
|
||||||
|
{ .name = "m5206", .instance_init = m5206_cpu_initfn },
|
||||||
|
{ .name = "m5208", .instance_init = m5208_cpu_initfn },
|
||||||
|
{ .name = "cfv4e", .instance_init = cfv4e_cpu_initfn },
|
||||||
|
{ .name = "any", .instance_init = any_cpu_initfn },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void m68k_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(obj);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
|
cpu_exec_init(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void m68k_cpu_class_init(ObjectClass *c, void *data)
|
||||||
|
{
|
||||||
|
M68kCPUClass *mcc = M68K_CPU_CLASS(c);
|
||||||
|
CPUClass *cc = CPU_CLASS(c);
|
||||||
|
|
||||||
|
mcc->parent_reset = cc->reset;
|
||||||
|
cc->reset = m68k_cpu_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_cpu_type(const M68kCPUInfo *info)
|
||||||
|
{
|
||||||
|
TypeInfo type_info = {
|
||||||
|
.name = info->name,
|
||||||
|
.parent = TYPE_M68K_CPU,
|
||||||
|
.instance_init = info->instance_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
type_register_static(&type_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo m68k_cpu_type_info = {
|
||||||
|
.name = TYPE_M68K_CPU,
|
||||||
|
.parent = TYPE_CPU,
|
||||||
|
.instance_size = sizeof(M68kCPU),
|
||||||
|
.instance_init = m68k_cpu_initfn,
|
||||||
|
.abstract = true,
|
||||||
|
.class_size = sizeof(M68kCPUClass),
|
||||||
|
.class_init = m68k_cpu_class_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void m68k_cpu_register_types(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
type_register_static(&m68k_cpu_type_info);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(m68k_cpus); i++) {
|
||||||
|
register_cpu_type(&m68k_cpus[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type_init(m68k_cpu_register_types)
|
|
@ -116,10 +116,11 @@ typedef struct CPUM68KState {
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
} CPUM68KState;
|
} CPUM68KState;
|
||||||
|
|
||||||
|
#include "cpu-qom.h"
|
||||||
|
|
||||||
void m68k_tcg_init(void);
|
void m68k_tcg_init(void);
|
||||||
CPUM68KState *cpu_m68k_init(const char *cpu_model);
|
CPUM68KState *cpu_m68k_init(const char *cpu_model);
|
||||||
int cpu_m68k_exec(CPUM68KState *s);
|
int cpu_m68k_exec(CPUM68KState *s);
|
||||||
void cpu_m68k_close(CPUM68KState *s);
|
|
||||||
void do_interrupt(CPUM68KState *env1);
|
void do_interrupt(CPUM68KState *env1);
|
||||||
void do_interrupt_m68k_hardirq(CPUM68KState *env1);
|
void do_interrupt_m68k_hardirq(CPUM68KState *env1);
|
||||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
|
/* you can call this signal handler from your SIGBUS and SIGSEGV
|
||||||
|
|
|
@ -25,35 +25,50 @@
|
||||||
|
|
||||||
#define SIGNBIT (1u << 31)
|
#define SIGNBIT (1u << 31)
|
||||||
|
|
||||||
enum m68k_cpuid {
|
typedef struct M68kCPUListState {
|
||||||
M68K_CPUID_M5206,
|
fprintf_function cpu_fprintf;
|
||||||
M68K_CPUID_M5208,
|
FILE *file;
|
||||||
M68K_CPUID_CFV4E,
|
} M68kCPUListState;
|
||||||
M68K_CPUID_ANY,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct m68k_def_t m68k_def_t;
|
/* Sort alphabetically, except for "any". */
|
||||||
|
static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
ObjectClass *class_a = (ObjectClass *)a;
|
||||||
|
ObjectClass *class_b = (ObjectClass *)b;
|
||||||
|
const char *name_a, *name_b;
|
||||||
|
|
||||||
struct m68k_def_t {
|
name_a = object_class_get_name(class_a);
|
||||||
const char * name;
|
name_b = object_class_get_name(class_b);
|
||||||
enum m68k_cpuid id;
|
if (strcmp(name_a, "any") == 0) {
|
||||||
};
|
return 1;
|
||||||
|
} else if (strcmp(name_b, "any") == 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return strcasecmp(name_a, name_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static m68k_def_t m68k_cpu_defs[] = {
|
static void m68k_cpu_list_entry(gpointer data, gpointer user_data)
|
||||||
{"m5206", M68K_CPUID_M5206},
|
{
|
||||||
{"m5208", M68K_CPUID_M5208},
|
ObjectClass *c = data;
|
||||||
{"cfv4e", M68K_CPUID_CFV4E},
|
M68kCPUListState *s = user_data;
|
||||||
{"any", M68K_CPUID_ANY},
|
|
||||||
{NULL, 0},
|
(*s->cpu_fprintf)(s->file, "%s\n",
|
||||||
};
|
object_class_get_name(c));
|
||||||
|
}
|
||||||
|
|
||||||
void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
M68kCPUListState s = {
|
||||||
|
.file = f,
|
||||||
|
.cpu_fprintf = cpu_fprintf,
|
||||||
|
};
|
||||||
|
GSList *list;
|
||||||
|
|
||||||
for (i = 0; m68k_cpu_defs[i].name; i++) {
|
list = object_class_get_list(TYPE_M68K_CPU, false);
|
||||||
(*cpu_fprintf)(f, "%s\n", m68k_cpu_defs[i].name);
|
list = g_slist_sort(list, m68k_cpu_list_compare);
|
||||||
}
|
g_slist_foreach(list, m68k_cpu_list_entry, &s);
|
||||||
|
g_slist_free(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
|
static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
|
||||||
|
@ -83,92 +98,23 @@ static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m68k_set_feature(CPUM68KState *env, int feature)
|
|
||||||
{
|
|
||||||
env->features |= (1u << feature);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cpu_m68k_set_model(CPUM68KState *env, const char *name)
|
|
||||||
{
|
|
||||||
m68k_def_t *def;
|
|
||||||
|
|
||||||
for (def = m68k_cpu_defs; def->name; def++) {
|
|
||||||
if (strcmp(def->name, name) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!def->name)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
switch (def->id) {
|
|
||||||
case M68K_CPUID_M5206:
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
|
||||||
break;
|
|
||||||
case M68K_CPUID_M5208:
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_BRAL);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_USP);
|
|
||||||
break;
|
|
||||||
case M68K_CPUID_CFV4E:
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_BRAL);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_FPU);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_USP);
|
|
||||||
break;
|
|
||||||
case M68K_CPUID_ANY:
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_BRAL);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_FPU);
|
|
||||||
/* MAC and EMAC are mututally exclusive, so pick EMAC.
|
|
||||||
It's mostly backwards compatible. */
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_USP);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
|
|
||||||
m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
register_m68k_insns(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. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpu_state_reset(CPUM68KState *env)
|
void cpu_state_reset(CPUM68KState *env)
|
||||||
{
|
{
|
||||||
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
cpu_reset(ENV_GET_CPU(env));
|
||||||
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
|
||||||
log_cpu_state(env, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(env, 0, offsetof(CPUM68KState, breakpoints));
|
|
||||||
#if !defined (CONFIG_USER_ONLY)
|
|
||||||
env->sr = 0x2700;
|
|
||||||
#endif
|
|
||||||
m68k_switch_sp(env);
|
|
||||||
/* ??? FP regs should be initialized to NaN. */
|
|
||||||
env->cc_op = CC_OP_FLAGS;
|
|
||||||
/* TODO: We should set PC from the interrupt vector. */
|
|
||||||
env->pc = 0;
|
|
||||||
tlb_flush(env, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUM68KState *cpu_m68k_init(const char *cpu_model)
|
CPUM68KState *cpu_m68k_init(const char *cpu_model)
|
||||||
{
|
{
|
||||||
|
M68kCPU *cpu;
|
||||||
CPUM68KState *env;
|
CPUM68KState *env;
|
||||||
static int inited;
|
static int inited;
|
||||||
|
|
||||||
env = g_malloc0(sizeof(CPUM68KState));
|
if (object_class_by_name(cpu_model) == NULL) {
|
||||||
cpu_exec_init(env);
|
return NULL;
|
||||||
|
}
|
||||||
|
cpu = M68K_CPU(object_new(cpu_model));
|
||||||
|
env = &cpu->env;
|
||||||
|
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
inited = 1;
|
inited = 1;
|
||||||
m68k_tcg_init();
|
m68k_tcg_init();
|
||||||
|
@ -176,21 +122,18 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model)
|
||||||
|
|
||||||
env->cpu_model_str = cpu_model;
|
env->cpu_model_str = cpu_model;
|
||||||
|
|
||||||
if (cpu_m68k_set_model(env, cpu_model) < 0) {
|
register_m68k_insns(env);
|
||||||
cpu_m68k_close(env);
|
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
|
||||||
return NULL;
|
gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
|
||||||
|
11, "cf-fp.xml", 18);
|
||||||
}
|
}
|
||||||
|
/* TODO: Add [E]MAC registers. */
|
||||||
|
|
||||||
cpu_state_reset(env);
|
cpu_reset(ENV_GET_CPU(env));
|
||||||
qemu_init_vcpu(env);
|
qemu_init_vcpu(env);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_m68k_close(CPUM68KState *env)
|
|
||||||
{
|
|
||||||
g_free(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
|
void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* QEMU MIPS CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||||
|
*/
|
||||||
|
#ifndef QEMU_MIPS_CPU_QOM_H
|
||||||
|
#define QEMU_MIPS_CPU_QOM_H
|
||||||
|
|
||||||
|
#include "qemu/cpu.h"
|
||||||
|
|
||||||
|
#ifdef TARGET_MIPS64
|
||||||
|
#define TYPE_MIPS_CPU "mips64-cpu"
|
||||||
|
#else
|
||||||
|
#define TYPE_MIPS_CPU "mips-cpu"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MIPS_CPU_CLASS(klass) \
|
||||||
|
OBJECT_CLASS_CHECK(MIPSCPUClass, (klass), TYPE_MIPS_CPU)
|
||||||
|
#define MIPS_CPU(obj) \
|
||||||
|
OBJECT_CHECK(MIPSCPU, (obj), TYPE_MIPS_CPU)
|
||||||
|
#define MIPS_CPU_GET_CLASS(obj) \
|
||||||
|
OBJECT_GET_CLASS(MIPSCPUClass, (obj), TYPE_MIPS_CPU)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIPSCPUClass:
|
||||||
|
* @parent_reset: The parent class' reset handler.
|
||||||
|
*
|
||||||
|
* A MIPS CPU model.
|
||||||
|
*/
|
||||||
|
typedef struct MIPSCPUClass {
|
||||||
|
/*< private >*/
|
||||||
|
CPUClass parent_class;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
void (*parent_reset)(CPUState *cpu);
|
||||||
|
} MIPSCPUClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIPSCPU:
|
||||||
|
* @env: #CPUMIPSState
|
||||||
|
*
|
||||||
|
* A MIPS CPU.
|
||||||
|
*/
|
||||||
|
typedef struct MIPSCPU {
|
||||||
|
/*< private >*/
|
||||||
|
CPUState parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
CPUMIPSState env;
|
||||||
|
} MIPSCPU;
|
||||||
|
|
||||||
|
static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
|
||||||
|
{
|
||||||
|
return MIPS_CPU(container_of(env, MIPSCPU, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ENV_GET_CPU(e) CPU(mips_env_get_cpu(e))
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* QEMU MIPS CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* CPUClass::reset() */
|
||||||
|
static void mips_cpu_reset(CPUState *s)
|
||||||
|
{
|
||||||
|
MIPSCPU *cpu = MIPS_CPU(s);
|
||||||
|
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
|
||||||
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
|
||||||
|
mcc->parent_reset(s);
|
||||||
|
|
||||||
|
cpu_state_reset(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mips_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
MIPSCPU *cpu = MIPS_CPU(obj);
|
||||||
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
|
||||||
|
cpu_exec_init(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mips_cpu_class_init(ObjectClass *c, void *data)
|
||||||
|
{
|
||||||
|
MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
|
||||||
|
CPUClass *cc = CPU_CLASS(c);
|
||||||
|
|
||||||
|
mcc->parent_reset = cc->reset;
|
||||||
|
cc->reset = mips_cpu_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo mips_cpu_type_info = {
|
||||||
|
.name = TYPE_MIPS_CPU,
|
||||||
|
.parent = TYPE_CPU,
|
||||||
|
.instance_size = sizeof(MIPSCPU),
|
||||||
|
.instance_init = mips_cpu_initfn,
|
||||||
|
.abstract = false,
|
||||||
|
.class_size = sizeof(MIPSCPUClass),
|
||||||
|
.class_init = mips_cpu_class_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mips_cpu_register_types(void)
|
||||||
|
{
|
||||||
|
type_register_static(&mips_cpu_type_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_init(mips_cpu_register_types)
|
|
@ -476,6 +476,8 @@ struct CPUMIPSState {
|
||||||
struct QEMUTimer *timer; /* Internal timer */
|
struct QEMUTimer *timer; /* Internal timer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "cpu-qom.h"
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
int no_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot,
|
int no_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot,
|
||||||
target_ulong address, int rw, int access_type);
|
target_ulong address, int rw, int access_type);
|
||||||
|
|
|
@ -12691,17 +12691,18 @@ static void mips_tcg_init(void)
|
||||||
|
|
||||||
CPUMIPSState *cpu_mips_init (const char *cpu_model)
|
CPUMIPSState *cpu_mips_init (const char *cpu_model)
|
||||||
{
|
{
|
||||||
|
MIPSCPU *cpu;
|
||||||
CPUMIPSState *env;
|
CPUMIPSState *env;
|
||||||
const mips_def_t *def;
|
const mips_def_t *def;
|
||||||
|
|
||||||
def = cpu_mips_find_by_name(cpu_model);
|
def = cpu_mips_find_by_name(cpu_model);
|
||||||
if (!def)
|
if (!def)
|
||||||
return NULL;
|
return NULL;
|
||||||
env = g_malloc0(sizeof(CPUMIPSState));
|
cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
|
||||||
|
env = &cpu->env;
|
||||||
env->cpu_model = def;
|
env->cpu_model = def;
|
||||||
env->cpu_model_str = cpu_model;
|
env->cpu_model_str = cpu_model;
|
||||||
|
|
||||||
cpu_exec_init(env);
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
mmu_init(env, def);
|
mmu_init(env, def);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* QEMU SuperH CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||||
|
*/
|
||||||
|
#ifndef QEMU_SUPERH_CPU_QOM_H
|
||||||
|
#define QEMU_SUPERH_CPU_QOM_H
|
||||||
|
|
||||||
|
#include "qemu/cpu.h"
|
||||||
|
|
||||||
|
#define TYPE_SUPERH_CPU "superh-cpu"
|
||||||
|
|
||||||
|
#define SUPERH_CPU_CLASS(klass) \
|
||||||
|
OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU)
|
||||||
|
#define SUPERH_CPU(obj) \
|
||||||
|
OBJECT_CHECK(SuperHCPU, (obj), TYPE_SUPERH_CPU)
|
||||||
|
#define SUPERH_CPU_GET_CLASS(obj) \
|
||||||
|
OBJECT_GET_CLASS(SuperHCPUClass, (obj), TYPE_SUPERH_CPU)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SuperHCPUClass:
|
||||||
|
* @parent_reset: The parent class' reset handler.
|
||||||
|
*
|
||||||
|
* A SuperH CPU model.
|
||||||
|
*/
|
||||||
|
typedef struct SuperHCPUClass {
|
||||||
|
/*< private >*/
|
||||||
|
CPUClass parent_class;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
void (*parent_reset)(CPUState *cpu);
|
||||||
|
} SuperHCPUClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SuperHCPU:
|
||||||
|
* @env: #CPUSH4State
|
||||||
|
*
|
||||||
|
* A SuperH CPU.
|
||||||
|
*/
|
||||||
|
typedef struct SuperHCPU {
|
||||||
|
/*< private >*/
|
||||||
|
CPUState parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
CPUSH4State env;
|
||||||
|
} SuperHCPU;
|
||||||
|
|
||||||
|
static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
|
||||||
|
{
|
||||||
|
return SUPERH_CPU(container_of(env, SuperHCPU, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ENV_GET_CPU(e) CPU(sh_env_get_cpu(e))
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* QEMU SuperH CPU
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Samuel Tardieu
|
||||||
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* CPUClass::reset() */
|
||||||
|
static void superh_cpu_reset(CPUState *s)
|
||||||
|
{
|
||||||
|
SuperHCPU *cpu = SUPERH_CPU(s);
|
||||||
|
SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(cpu);
|
||||||
|
CPUSH4State *env = &cpu->env;
|
||||||
|
|
||||||
|
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||||
|
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
||||||
|
log_cpu_state(env, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
scc->parent_reset(s);
|
||||||
|
|
||||||
|
memset(env, 0, offsetof(CPUSH4State, breakpoints));
|
||||||
|
tlb_flush(env, 1);
|
||||||
|
|
||||||
|
env->pc = 0xA0000000;
|
||||||
|
#if defined(CONFIG_USER_ONLY)
|
||||||
|
env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
|
||||||
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
|
||||||
|
#else
|
||||||
|
env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0;
|
||||||
|
env->fpscr = FPSCR_DN | FPSCR_RM_ZERO; /* CPU reset value according to SH4 manual */
|
||||||
|
set_float_rounding_mode(float_round_to_zero, &env->fp_status);
|
||||||
|
set_flush_to_zero(1, &env->fp_status);
|
||||||
|
#endif
|
||||||
|
set_default_nan_mode(1, &env->fp_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void superh_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
SuperHCPU *cpu = SUPERH_CPU(obj);
|
||||||
|
CPUSH4State *env = &cpu->env;
|
||||||
|
|
||||||
|
cpu_exec_init(env);
|
||||||
|
|
||||||
|
env->movcal_backup_tail = &(env->movcal_backup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void superh_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
{
|
||||||
|
CPUClass *cc = CPU_CLASS(oc);
|
||||||
|
SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
|
||||||
|
|
||||||
|
scc->parent_reset = cc->reset;
|
||||||
|
cc->reset = superh_cpu_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo superh_cpu_type_info = {
|
||||||
|
.name = TYPE_SUPERH_CPU,
|
||||||
|
.parent = TYPE_CPU,
|
||||||
|
.instance_size = sizeof(SuperHCPU),
|
||||||
|
.instance_init = superh_cpu_initfn,
|
||||||
|
.abstract = false,
|
||||||
|
.class_size = sizeof(SuperHCPUClass),
|
||||||
|
.class_init = superh_cpu_class_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void superh_cpu_register_types(void)
|
||||||
|
{
|
||||||
|
type_register_static(&superh_cpu_type_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_init(superh_cpu_register_types)
|
|
@ -189,6 +189,8 @@ typedef struct CPUSH4State {
|
||||||
memory_content **movcal_backup_tail;
|
memory_content **movcal_backup_tail;
|
||||||
} CPUSH4State;
|
} CPUSH4State;
|
||||||
|
|
||||||
|
#include "cpu-qom.h"
|
||||||
|
|
||||||
CPUSH4State *cpu_sh4_init(const char *cpu_model);
|
CPUSH4State *cpu_sh4_init(const char *cpu_model);
|
||||||
int cpu_sh4_exec(CPUSH4State * s);
|
int cpu_sh4_exec(CPUSH4State * s);
|
||||||
int cpu_sh4_signal_handler(int host_signum, void *pinfo,
|
int cpu_sh4_signal_handler(int host_signum, void *pinfo,
|
||||||
|
|
|
@ -180,25 +180,7 @@ void cpu_dump_state(CPUSH4State * env, FILE * f,
|
||||||
|
|
||||||
void cpu_state_reset(CPUSH4State *env)
|
void cpu_state_reset(CPUSH4State *env)
|
||||||
{
|
{
|
||||||
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
cpu_reset(ENV_GET_CPU(env));
|
||||||
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
|
||||||
log_cpu_state(env, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(env, 0, offsetof(CPUSH4State, breakpoints));
|
|
||||||
tlb_flush(env, 1);
|
|
||||||
|
|
||||||
env->pc = 0xA0000000;
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
|
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
|
|
||||||
#else
|
|
||||||
env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0;
|
|
||||||
env->fpscr = FPSCR_DN | FPSCR_RM_ZERO; /* CPU reset value according to SH4 manual */
|
|
||||||
set_float_rounding_mode(float_round_to_zero, &env->fp_status);
|
|
||||||
set_flush_to_zero(1, &env->fp_status);
|
|
||||||
#endif
|
|
||||||
set_default_nan_mode(1, &env->fp_status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -267,19 +249,19 @@ static void cpu_register(CPUSH4State *env, const sh4_def_t *def)
|
||||||
|
|
||||||
CPUSH4State *cpu_sh4_init(const char *cpu_model)
|
CPUSH4State *cpu_sh4_init(const char *cpu_model)
|
||||||
{
|
{
|
||||||
|
SuperHCPU *cpu;
|
||||||
CPUSH4State *env;
|
CPUSH4State *env;
|
||||||
const sh4_def_t *def;
|
const sh4_def_t *def;
|
||||||
|
|
||||||
def = cpu_sh4_find_by_name(cpu_model);
|
def = cpu_sh4_find_by_name(cpu_model);
|
||||||
if (!def)
|
if (!def)
|
||||||
return NULL;
|
return NULL;
|
||||||
env = g_malloc0(sizeof(CPUSH4State));
|
cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU));
|
||||||
|
env = &cpu->env;
|
||||||
env->features = def->features;
|
env->features = def->features;
|
||||||
cpu_exec_init(env);
|
|
||||||
env->movcal_backup_tail = &(env->movcal_backup);
|
|
||||||
sh4_translate_init();
|
sh4_translate_init();
|
||||||
env->cpu_model_str = cpu_model;
|
env->cpu_model_str = cpu_model;
|
||||||
cpu_state_reset(env);
|
cpu_reset(CPU(cpu));
|
||||||
cpu_register(env, def);
|
cpu_register(env, def);
|
||||||
qemu_init_vcpu(env);
|
qemu_init_vcpu(env);
|
||||||
return env;
|
return env;
|
||||||
|
|
Loading…
Reference in New Issue