MIPS -cpu selection support, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2491 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e24ad6f140
commit
33d68b5f00
@ -2,6 +2,7 @@
|
|||||||
- Tap device emulation for Solaris (Sittichai Palanisong)
|
- Tap device emulation for Solaris (Sittichai Palanisong)
|
||||||
- Monitor multiplexing to several I/O channels (Jason Wessel)
|
- Monitor multiplexing to several I/O channels (Jason Wessel)
|
||||||
- ds1225y nvram support (Herve Poussineau)
|
- ds1225y nvram support (Herve Poussineau)
|
||||||
|
- CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
|
||||||
|
|
||||||
version 0.9.0:
|
version 0.9.0:
|
||||||
|
|
||||||
|
@ -551,6 +551,7 @@ endif
|
|||||||
ifeq ($(TARGET_ARCH), mips)
|
ifeq ($(TARGET_ARCH), mips)
|
||||||
op.o: op.c op_template.c fop_template.c op_mem.c
|
op.o: op.c op_template.c fop_template.c op_mem.c
|
||||||
op_helper.o: op_helper_mem.c
|
op_helper.o: op_helper_mem.c
|
||||||
|
translate.o: translate.c translate_init.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
loader.o: loader.c elf_ops.h
|
loader.o: loader.c elf_ops.h
|
||||||
|
@ -626,8 +626,20 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
|
|||||||
/* fdctrl_t *floppy_controller; */
|
/* fdctrl_t *floppy_controller; */
|
||||||
MaltaFPGAState *malta_fpga;
|
MaltaFPGAState *malta_fpga;
|
||||||
int ret;
|
int ret;
|
||||||
|
mips_def_t *def;
|
||||||
|
|
||||||
|
/* init CPUs */
|
||||||
|
if (cpu_model == NULL) {
|
||||||
|
#ifdef MIPS_HAS_MIPS64
|
||||||
|
cpu_model = "R4000";
|
||||||
|
#else
|
||||||
|
cpu_model = "4KEc";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (mips_find_by_name(cpu_model, &def) != 0)
|
||||||
|
def = NULL;
|
||||||
env = cpu_init();
|
env = cpu_init();
|
||||||
|
cpu_mips_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);
|
||||||
|
|
||||||
|
@ -138,8 +138,20 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
|
|||||||
CPUState *env;
|
CPUState *env;
|
||||||
RTCState *rtc_state;
|
RTCState *rtc_state;
|
||||||
int i;
|
int i;
|
||||||
|
mips_def_t *def;
|
||||||
|
|
||||||
|
/* init CPUs */
|
||||||
|
if (cpu_model == NULL) {
|
||||||
|
#ifdef MIPS_HAS_MIPS64
|
||||||
|
cpu_model = "R4000";
|
||||||
|
#else
|
||||||
|
cpu_model = "4KEc";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (mips_find_by_name(cpu_model, &def) != 0)
|
||||||
|
def = NULL;
|
||||||
env = cpu_init();
|
env = cpu_init();
|
||||||
|
cpu_mips_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);
|
||||||
|
|
||||||
@ -148,7 +160,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
|
|||||||
|
|
||||||
if (!mips_qemu_iomemtype) {
|
if (!mips_qemu_iomemtype) {
|
||||||
mips_qemu_iomemtype = cpu_register_io_memory(0, mips_qemu_read,
|
mips_qemu_iomemtype = cpu_register_io_memory(0, mips_qemu_read,
|
||||||
mips_qemu_write, NULL);
|
mips_qemu_write, NULL);
|
||||||
}
|
}
|
||||||
cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype);
|
cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype);
|
||||||
|
|
||||||
|
@ -282,6 +282,11 @@ struct CPUMIPSState {
|
|||||||
struct QEMUTimer *timer; /* Internal timer */
|
struct QEMUTimer *timer; /* Internal timer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct mips_def_t mips_def_t;
|
||||||
|
int mips_find_by_name (const unsigned char *name, mips_def_t **def);
|
||||||
|
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
|
||||||
|
int cpu_mips_register (CPUMIPSState *env, mips_def_t *def);
|
||||||
|
|
||||||
#include "cpu-all.h"
|
#include "cpu-all.h"
|
||||||
|
|
||||||
/* Memory access type :
|
/* Memory access type :
|
||||||
|
@ -6,26 +6,15 @@
|
|||||||
/* If we want to use host float regs... */
|
/* If we want to use host float regs... */
|
||||||
//#define USE_HOST_FLOAT_REGS
|
//#define USE_HOST_FLOAT_REGS
|
||||||
|
|
||||||
#define MIPS_R4Kc 0x00018000
|
|
||||||
#define MIPS_R4Kp 0x00018300
|
|
||||||
|
|
||||||
/* Emulate MIPS R4Kc for now */
|
|
||||||
#define MIPS_CPU MIPS_R4Kc
|
|
||||||
|
|
||||||
#if (MIPS_CPU == MIPS_R4Kc)
|
|
||||||
/* 32 bits target */
|
/* 32 bits target */
|
||||||
#undef MIPS_HAS_MIPS64
|
#undef MIPS_HAS_MIPS64
|
||||||
//#define MIPS_HAS_MIPS64 1
|
//#define MIPS_HAS_MIPS64 1
|
||||||
/* real pages are variable size... */
|
/* real pages are variable size... */
|
||||||
#define TARGET_PAGE_BITS 12
|
#define TARGET_PAGE_BITS 12
|
||||||
/* Uses MIPS R4Kx enhancements to MIPS32 architecture */
|
|
||||||
#define MIPS_USES_R4K_EXT
|
|
||||||
/* Uses MIPS R4Kc TLB model */
|
/* Uses MIPS R4Kc TLB model */
|
||||||
#define MIPS_USES_R4K_TLB
|
#define MIPS_USES_R4K_TLB
|
||||||
#define MIPS_TLB_NB 16
|
#define MIPS_TLB_NB 16
|
||||||
#define MIPS_TLB_MAX 128
|
#define MIPS_TLB_MAX 128
|
||||||
/* basic FPU register support */
|
|
||||||
#define MIPS_USES_FPU 1
|
|
||||||
/* Define a implementation number of 1.
|
/* Define a implementation number of 1.
|
||||||
* Define a major version 1, minor version 0.
|
* Define a major version 1, minor version 0.
|
||||||
*/
|
*/
|
||||||
@ -63,21 +52,6 @@
|
|||||||
((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
|
((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
|
||||||
(0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
|
(0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
|
||||||
(0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL))
|
(0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL))
|
||||||
#elif (MIPS_CPU == MIPS_R4Kp)
|
|
||||||
/* 32 bits target */
|
|
||||||
#undef MIPS_HAS_MIPS64
|
|
||||||
/* real pages are variable size... */
|
|
||||||
#define TARGET_PAGE_BITS 12
|
|
||||||
/* Uses MIPS R4Kx enhancements to MIPS32 architecture */
|
|
||||||
#define MIPS_USES_R4K_EXT
|
|
||||||
/* Uses MIPS R4Km FPM MMU model */
|
|
||||||
#define MIPS_USES_R4K_FPM
|
|
||||||
#else
|
|
||||||
#error "MIPS CPU not defined"
|
|
||||||
/* Reminder for other flags */
|
|
||||||
//#undef MIPS_HAS_MIPS64
|
|
||||||
//#define MIPS_USES_FPU
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MIPS_HAS_MIPS64
|
#ifdef MIPS_HAS_MIPS64
|
||||||
#define TARGET_LONG_BITS 64
|
#define TARGET_LONG_BITS 64
|
||||||
|
@ -5283,12 +5283,6 @@ void cpu_reset (CPUMIPSState *env)
|
|||||||
env->CP0_Wired = 0;
|
env->CP0_Wired = 0;
|
||||||
/* SMP not implemented */
|
/* SMP not implemented */
|
||||||
env->CP0_EBase = 0x80000000;
|
env->CP0_EBase = 0x80000000;
|
||||||
env->CP0_Config0 = MIPS_CONFIG0;
|
|
||||||
env->CP0_Config1 = MIPS_CONFIG1;
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
/* basic FPU register support */
|
|
||||||
env->CP0_Config1 |= (1 << CP0C1_FP);
|
|
||||||
#endif
|
|
||||||
env->CP0_Config2 = MIPS_CONFIG2;
|
env->CP0_Config2 = MIPS_CONFIG2;
|
||||||
env->CP0_Config3 = MIPS_CONFIG3;
|
env->CP0_Config3 = MIPS_CONFIG3;
|
||||||
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
|
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
|
||||||
@ -5296,7 +5290,6 @@ void cpu_reset (CPUMIPSState *env)
|
|||||||
env->hflags = MIPS_HFLAG_ERL;
|
env->hflags = MIPS_HFLAG_ERL;
|
||||||
/* Count register increments in debug mode, EJTAG version 1 */
|
/* Count register increments in debug mode, EJTAG version 1 */
|
||||||
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
|
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
|
||||||
env->CP0_PRid = MIPS_CPU;
|
|
||||||
#endif
|
#endif
|
||||||
env->exception_index = EXCP_NONE;
|
env->exception_index = EXCP_NONE;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
@ -5308,3 +5301,5 @@ void cpu_reset (CPUMIPSState *env)
|
|||||||
env->SYNCI_Step = 16;
|
env->SYNCI_Step = 16;
|
||||||
env->CCRes = 2;
|
env->CCRes = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "translate_init.c"
|
||||||
|
97
target-mips/translate_init.c
Normal file
97
target-mips/translate_init.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* MIPS emulation for qemu: CPU initialisation routines.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2005 Jocelyn Mayer
|
||||||
|
* Copyright (c) 2007 Herve Poussineau
|
||||||
|
*
|
||||||
|
* 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 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct mips_def_t {
|
||||||
|
const unsigned char *name;
|
||||||
|
int32_t CP0_PRid;
|
||||||
|
int32_t CP0_Config0;
|
||||||
|
int32_t CP0_Config1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* MIPS CPU definitions */
|
||||||
|
static mips_def_t mips_defs[] =
|
||||||
|
{
|
||||||
|
#ifndef MIPS_HAS_MIPS64
|
||||||
|
{
|
||||||
|
.name = "4Kc",
|
||||||
|
.CP0_PRid = 0x00018000,
|
||||||
|
.CP0_Config0 = MIPS_CONFIG0,
|
||||||
|
.CP0_Config1 = MIPS_CONFIG1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "4KEc",
|
||||||
|
.CP0_PRid = 0x00018400,
|
||||||
|
.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
|
||||||
|
.CP0_Config1 = MIPS_CONFIG1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "24Kf",
|
||||||
|
.CP0_PRid = 0x00019300,
|
||||||
|
.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
|
||||||
|
.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP),
|
||||||
|
},
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
.name = "R4000",
|
||||||
|
.CP0_PRid = 0x00000400,
|
||||||
|
.CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
|
||||||
|
.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP),
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int mips_find_by_name (const unsigned char *name, mips_def_t **def)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
ret = -1;
|
||||||
|
*def = NULL;
|
||||||
|
for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
|
||||||
|
if (strcasecmp(name, mips_defs[i].name) == 0) {
|
||||||
|
*def = &mips_defs[i];
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
|
||||||
|
(*cpu_fprintf)(f, "MIPS '%s'\n",
|
||||||
|
mips_defs[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
|
||||||
|
{
|
||||||
|
if (!def)
|
||||||
|
cpu_abort(env, "Unable to find MIPS CPU definition\n");
|
||||||
|
env->CP0_PRid = def->CP0_PRid;
|
||||||
|
env->CP0_Config0 = def->CP0_Config0;
|
||||||
|
env->CP0_Config1 = def->CP0_Config1;
|
||||||
|
return 0;
|
||||||
|
}
|
2
vl.c
2
vl.c
@ -7009,6 +7009,8 @@ int main(int argc, char **argv)
|
|||||||
ppc_cpu_list(stdout, &fprintf);
|
ppc_cpu_list(stdout, &fprintf);
|
||||||
#elif defined(TARGET_ARM)
|
#elif defined(TARGET_ARM)
|
||||||
arm_cpu_list();
|
arm_cpu_list();
|
||||||
|
#elif defined(TARGET_MIPS)
|
||||||
|
mips_cpu_list(stdout, &fprintf);
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
4
vl.h
4
vl.h
@ -713,6 +713,10 @@ typedef void IRQRequestFunc(void *opaque, int level);
|
|||||||
void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
|
void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TARGET_MIPS)
|
||||||
|
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ISA bus */
|
/* ISA bus */
|
||||||
|
|
||||||
extern target_phys_addr_t isa_mem_base;
|
extern target_phys_addr_t isa_mem_base;
|
||||||
|
Loading…
Reference in New Issue
Block a user