Sparc32/64 CPU selection
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2534 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
34ee2edebb
commit
62724a3773
@ -219,12 +219,21 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
|
long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
|
||||||
void *iommu, *dma, *main_esp, *main_lance = NULL;
|
void *iommu, *dma, *main_esp, *main_lance = NULL;
|
||||||
|
const sparc_def_t *def;
|
||||||
|
|
||||||
linux_boot = (kernel_filename != NULL);
|
linux_boot = (kernel_filename != NULL);
|
||||||
|
|
||||||
/* init CPUs */
|
/* init CPUs */
|
||||||
|
if (cpu_model == NULL)
|
||||||
|
cpu_model = "Fujitsu MB86904";
|
||||||
|
sparc_find_by_name(cpu_model, &def);
|
||||||
|
if (def == NULL) {
|
||||||
|
fprintf(stderr, "Unable to find Sparc CPU definition\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
for(i = 0; i < smp_cpus; i++) {
|
for(i = 0; i < smp_cpus; i++) {
|
||||||
env = cpu_init();
|
env = cpu_init();
|
||||||
|
cpu_sparc_register(env, def);
|
||||||
envs[i] = env;
|
envs[i] = env;
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
env->halted = 1;
|
env->halted = 1;
|
||||||
|
10
hw/sun4u.c
10
hw/sun4u.c
@ -266,10 +266,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
long prom_offset, initrd_size, kernel_size;
|
long prom_offset, initrd_size, kernel_size;
|
||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
|
const sparc_def_t *def;
|
||||||
|
|
||||||
linux_boot = (kernel_filename != NULL);
|
linux_boot = (kernel_filename != NULL);
|
||||||
|
|
||||||
|
/* init CPUs */
|
||||||
|
if (cpu_model == NULL)
|
||||||
|
cpu_model = "TI UltraSparc II";
|
||||||
|
sparc_find_by_name(cpu_model, &def);
|
||||||
|
if (def == NULL) {
|
||||||
|
fprintf(stderr, "Unable to find Sparc CPU definition\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
env = cpu_init();
|
env = cpu_init();
|
||||||
|
cpu_sparc_register(env, def);
|
||||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
||||||
qemu_register_reset(main_cpu_reset, env);
|
qemu_register_reset(main_cpu_reset, env);
|
||||||
|
|
||||||
|
@ -152,6 +152,8 @@
|
|||||||
/* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */
|
/* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */
|
||||||
#define NWINDOWS 8
|
#define NWINDOWS 8
|
||||||
|
|
||||||
|
typedef struct sparc_def_t sparc_def_t;
|
||||||
|
|
||||||
typedef struct CPUSPARCState {
|
typedef struct CPUSPARCState {
|
||||||
target_ulong gregs[8]; /* general registers */
|
target_ulong gregs[8]; /* general registers */
|
||||||
target_ulong *regwptr; /* pointer to current register window */
|
target_ulong *regwptr; /* pointer to current register window */
|
||||||
@ -170,6 +172,7 @@ typedef struct CPUSPARCState {
|
|||||||
int psret; /* enable traps */
|
int psret; /* enable traps */
|
||||||
uint32_t psrpil; /* interrupt level */
|
uint32_t psrpil; /* interrupt level */
|
||||||
int psref; /* enable fpu */
|
int psref; /* enable fpu */
|
||||||
|
target_ulong version;
|
||||||
jmp_buf jmp_env;
|
jmp_buf jmp_env;
|
||||||
int user_mode_only;
|
int user_mode_only;
|
||||||
int exception_index;
|
int exception_index;
|
||||||
@ -215,7 +218,6 @@ typedef struct CPUSPARCState {
|
|||||||
uint64_t bgregs[8]; /* backup for normal global registers */
|
uint64_t bgregs[8]; /* backup for normal global registers */
|
||||||
uint64_t igregs[8]; /* interrupt general registers */
|
uint64_t igregs[8]; /* interrupt general registers */
|
||||||
uint64_t mgregs[8]; /* mmu general registers */
|
uint64_t mgregs[8]; /* mmu general registers */
|
||||||
uint64_t version;
|
|
||||||
uint64_t fprs;
|
uint64_t fprs;
|
||||||
uint64_t tick_cmpr, stick_cmpr;
|
uint64_t tick_cmpr, stick_cmpr;
|
||||||
uint64_t gsr;
|
uint64_t gsr;
|
||||||
@ -233,9 +235,6 @@ typedef struct CPUSPARCState {
|
|||||||
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
|
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
|
||||||
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
|
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
// Manuf 0x17, version 0x11, mask 0 (UltraSparc-II)
|
|
||||||
#define GET_VER(env) ((0x17ULL << 48) | (0x11ULL << 32) | \
|
|
||||||
(0 << 24) | (MAXTL << 8) | (NWINDOWS - 1))
|
|
||||||
#else
|
#else
|
||||||
#define GET_FSR32(env) (env->fsr)
|
#define GET_FSR32(env) (env->fsr)
|
||||||
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
||||||
@ -246,9 +245,12 @@ typedef struct CPUSPARCState {
|
|||||||
CPUSPARCState *cpu_sparc_init(void);
|
CPUSPARCState *cpu_sparc_init(void);
|
||||||
int cpu_sparc_exec(CPUSPARCState *s);
|
int cpu_sparc_exec(CPUSPARCState *s);
|
||||||
int cpu_sparc_close(CPUSPARCState *s);
|
int cpu_sparc_close(CPUSPARCState *s);
|
||||||
|
int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
|
||||||
|
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
|
||||||
|
...));
|
||||||
|
int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
|
||||||
|
|
||||||
/* Fake impl 0, version 4 */
|
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
|
||||||
#define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) | \
|
|
||||||
(env->psref? PSR_EF : 0) | \
|
(env->psref? PSR_EF : 0) | \
|
||||||
(env->psrpil << 8) | \
|
(env->psrpil << 8) | \
|
||||||
(env->psrs? PSR_S : 0) | \
|
(env->psrs? PSR_S : 0) | \
|
||||||
|
@ -55,6 +55,13 @@ typedef struct DisasContext {
|
|||||||
struct TranslationBlock *tb;
|
struct TranslationBlock *tb;
|
||||||
} DisasContext;
|
} DisasContext;
|
||||||
|
|
||||||
|
struct sparc_def_t {
|
||||||
|
const unsigned char *name;
|
||||||
|
target_ulong iu_version;
|
||||||
|
uint32_t fpu_version;
|
||||||
|
uint32_t mmu_version;
|
||||||
|
};
|
||||||
|
|
||||||
static uint16_t *gen_opc_ptr;
|
static uint16_t *gen_opc_ptr;
|
||||||
static uint32_t *gen_opparam_ptr;
|
static uint32_t *gen_opparam_ptr;
|
||||||
extern FILE *logfile;
|
extern FILE *logfile;
|
||||||
@ -2751,11 +2758,8 @@ void cpu_reset(CPUSPARCState *env)
|
|||||||
env->gregs[1] = ram_size;
|
env->gregs[1] = ram_size;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
env->pstate = PS_PRIV;
|
env->pstate = PS_PRIV;
|
||||||
env->version = GET_VER(env);
|
|
||||||
env->pc = 0x1fff0000000ULL;
|
env->pc = 0x1fff0000000ULL;
|
||||||
#else
|
#else
|
||||||
env->fsr = 4 << 17; /* FPU version 4 (Meiko) */
|
|
||||||
env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
|
|
||||||
env->pc = 0xffd00000;
|
env->pc = 0xffd00000;
|
||||||
#endif
|
#endif
|
||||||
env->npc = env->pc + 4;
|
env->npc = env->pc + 4;
|
||||||
@ -2774,6 +2778,66 @@ CPUSPARCState *cpu_sparc_init(void)
|
|||||||
return (env);
|
return (env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const sparc_def_t sparc_defs[] = {
|
||||||
|
#ifdef TARGET_SPARC64
|
||||||
|
{
|
||||||
|
.name = "TI UltraSparc II",
|
||||||
|
.iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0 << 24)
|
||||||
|
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||||
|
.fpu_version = 0x00000000,
|
||||||
|
.mmu_version = 0,
|
||||||
|
},
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
.name = "Fujitsu MB86904",
|
||||||
|
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
|
||||||
|
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
|
||||||
|
.mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int sparc_find_by_name(const unsigned char *name, const sparc_def_t **def)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
ret = -1;
|
||||||
|
*def = NULL;
|
||||||
|
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
||||||
|
if (strcasecmp(name, sparc_defs[i].name) == 0) {
|
||||||
|
*def = &sparc_defs[i];
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
||||||
|
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
|
||||||
|
sparc_defs[i].name,
|
||||||
|
sparc_defs[i].iu_version,
|
||||||
|
sparc_defs[i].fpu_version,
|
||||||
|
sparc_defs[i].mmu_version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def)
|
||||||
|
{
|
||||||
|
env->version = def->iu_version;
|
||||||
|
env->fsr = def->fpu_version;
|
||||||
|
#if !defined(TARGET_SPARC64)
|
||||||
|
env->mmuregs[0] = def->mmu_version;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
|
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
|
||||||
|
|
||||||
void cpu_dump_state(CPUState *env, FILE *f,
|
void cpu_dump_state(CPUState *env, FILE *f,
|
||||||
|
2
vl.c
2
vl.c
@ -7007,6 +7007,8 @@ int main(int argc, char **argv)
|
|||||||
arm_cpu_list();
|
arm_cpu_list();
|
||||||
#elif defined(TARGET_MIPS)
|
#elif defined(TARGET_MIPS)
|
||||||
mips_cpu_list(stdout, &fprintf);
|
mips_cpu_list(stdout, &fprintf);
|
||||||
|
#elif defined(TARGET_SPARC)
|
||||||
|
sparc_cpu_list(stdout, &fprintf);
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user