Commit 33d68b5f authored by ths's avatar ths
Browse files

MIPS -cpu selection support, by Herve Poussineau.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2491 c046a42c-6fe2-441c-8c8c-71466251a162
parent e24ad6f1
......@@ -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"
/*
* 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;
}
......@@ -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 {
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment