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)
|
||||
- Monitor multiplexing to several I/O channels (Jason Wessel)
|
||||
- ds1225y nvram support (Herve Poussineau)
|
||||
- CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
|
||||
|
||||
version 0.9.0:
|
||||
|
||||
|
@ -551,6 +551,7 @@ endif
|
||||
ifeq ($(TARGET_ARCH), mips)
|
||||
op.o: op.c op_template.c fop_template.c op_mem.c
|
||||
op_helper.o: op_helper_mem.c
|
||||
translate.o: translate.c translate_init.c
|
||||
endif
|
||||
|
||||
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; */
|
||||
MaltaFPGAState *malta_fpga;
|
||||
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();
|
||||
cpu_mips_register(env, def);
|
||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, 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;
|
||||
RTCState *rtc_state;
|
||||
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();
|
||||
cpu_mips_register(env, def);
|
||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, 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) {
|
||||
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);
|
||||
|
||||
|
@ -282,6 +282,11 @@ struct CPUMIPSState {
|
||||
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"
|
||||
|
||||
/* Memory access type :
|
||||
|
@ -6,26 +6,15 @@
|
||||
/* If we want to 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 */
|
||||
#undef MIPS_HAS_MIPS64
|
||||
//#define MIPS_HAS_MIPS64 1
|
||||
/* real pages are variable size... */
|
||||
#define TARGET_PAGE_BITS 12
|
||||
/* Uses MIPS R4Kx enhancements to MIPS32 architecture */
|
||||
#define MIPS_USES_R4K_EXT
|
||||
/* Uses MIPS R4Kc TLB model */
|
||||
#define MIPS_USES_R4K_TLB
|
||||
#define MIPS_TLB_NB 16
|
||||
#define MIPS_TLB_MAX 128
|
||||
/* basic FPU register support */
|
||||
#define MIPS_USES_FPU 1
|
||||
/* Define a implementation number of 1.
|
||||
* Define a major version 1, minor version 0.
|
||||
*/
|
||||
@ -63,21 +52,6 @@
|
||||
((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
|
||||
(0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
|
||||
(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
|
||||
#define TARGET_LONG_BITS 64
|
||||
|
@ -5283,12 +5283,6 @@ void cpu_reset (CPUMIPSState *env)
|
||||
env->CP0_Wired = 0;
|
||||
/* SMP not implemented */
|
||||
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_Config3 = MIPS_CONFIG3;
|
||||
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
|
||||
@ -5296,7 +5290,6 @@ void cpu_reset (CPUMIPSState *env)
|
||||
env->hflags = MIPS_HFLAG_ERL;
|
||||
/* Count register increments in debug mode, EJTAG version 1 */
|
||||
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
|
||||
env->CP0_PRid = MIPS_CPU;
|
||||
#endif
|
||||
env->exception_index = EXCP_NONE;
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
@ -5308,3 +5301,5 @@ void cpu_reset (CPUMIPSState *env)
|
||||
env->SYNCI_Step = 16;
|
||||
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);
|
||||
#elif defined(TARGET_ARM)
|
||||
arm_cpu_list();
|
||||
#elif defined(TARGET_MIPS)
|
||||
mips_cpu_list(stdout, &fprintf);
|
||||
#endif
|
||||
exit(1);
|
||||
} 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, ...));
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_MIPS)
|
||||
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
|
||||
#endif
|
||||
|
||||
/* ISA bus */
|
||||
|
||||
extern target_phys_addr_t isa_mem_base;
|
||||
|
Loading…
Reference in New Issue
Block a user