From: Dirk Behme <dirk.behme@googlemail.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] MIPS instruction set configuration
Date: Sat, 08 Jul 2006 08:15:59 +0200 [thread overview]
Message-ID: <44AF4D9F.2090000@gmail.com> (raw)
In-Reply-To: <44A92F87.6030408@bellard.org>
[-- Attachment #1: Type: text/plain, Size: 879 bytes --]
Fabrice Bellard wrote:
> Dirk Behme wrote:
>
>> Fabrice Bellard wrote:
>>
>>> Each machine can add specific support for that (for example a -cpu
>>> option). It is likely to come at least for the PC machines.
>>
>>> I add suggest one more parameter to cpu_mips_set_model() to specify
>>> optional features. A function converting a CPU "string id" into an id
>>> + features would be interesting too.
>>
>> Fabrice, do you will accept the patch if I remove the
>> MIPS_FEATURE_ISAx options and convert MIPS_FEATURE_NEC_EXT to
>> MIPS_FEATURE_NEC_VR5400 as described in my previous mail?
>
> Yes. Even without I can accept it as it is better than what we
> previously had.
Please find as promised in attachment the updated version of
this patch. It removes MIPS_FEATURE_ISAx for the moment and
renames MIPS_FEATURE_NEC_EXT to MIPS_FEATURE_NEC_VR5400.
Best regards
Dirk
[-- Attachment #2: mips_isa_config_patch.txt --]
[-- Type: text/plain, Size: 13498 bytes --]
--- ./hw/mips_r4k.c_orig 2006-07-08 07:16:50.000000000 +0200
+++ ./hw/mips_r4k.c 2006-07-08 07:16:45.000000000 +0200
@@ -189,10 +189,10 @@ CPUReadMemoryFunc *io_read[] = {
&io_readl,
};
-void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
+void mips_r4kc_init (int ram_size, int vga_ram_size, int boot_device,
+ DisplayState *ds, const char **fd_filename, int snapshot,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename)
{
char buf[1024];
int64_t entry = 0;
@@ -203,6 +203,7 @@ void mips_r4k_init (int ram_size, int vg
long kernel_size;
env = cpu_init();
+ cpu_mips_set_model(env, MIPS_R4Kc);
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
/* allocate RAM */
@@ -284,8 +285,8 @@ void mips_r4k_init (int ram_size, int vg
}
}
-QEMUMachine mips_machine = {
- "mips",
- "mips r4k platform",
- mips_r4k_init,
+QEMUMachine mips_r4kc_machine = {
+ "r4kc",
+ "mips r4kc platform",
+ mips_r4kc_init,
};
--- ./vl.h_orig 2006-07-08 07:16:51.000000000 +0200
+++ ./vl.h 2006-07-08 07:16:45.000000000 +0200
@@ -917,7 +917,7 @@ extern QEMUMachine core99_machine;
extern QEMUMachine heathrow_machine;
/* mips_r4k.c */
-extern QEMUMachine mips_machine;
+extern QEMUMachine mips_r4kc_machine;
/* shix.c */
extern QEMUMachine shix_machine;
--- ./target-mips/cpu.h_orig 2006-07-08 07:16:50.000000000 +0200
+++ ./target-mips/cpu.h 2006-07-08 07:23:52.000000000 +0200
@@ -210,6 +210,8 @@ struct CPUMIPSState {
int bcond; /* Branch condition (if needed) */
int halted; /* TRUE if the CPU is in suspend state */
+
+ uint32_t features; /* Internal CPU feature flags */
CPU_COMMON
};
@@ -275,5 +277,30 @@ enum {
int cpu_mips_exec(CPUMIPSState *s);
CPUMIPSState *cpu_mips_init(void);
uint32_t cpu_mips_get_clock (void);
+void cpu_mips_set_model(CPUMIPSState *env, uint32_t id);
+
+enum mips_features {
+ MIPS_FEATURE_R4K_EXT = 0x1, /* instruction set extension for MIPS R4K */
+ MIPS_FEATURE_NEC_VR5400 = 0x2, /* instruction set extension for NEC VR5400 CPUs */
+ MIPS_FEATURE_FPU = 0x4, /* floating point instruction set */
+};
+
+#ifdef MIPS_USES_R4K_EXT
+#define mips_uses_r4k_ext() (env->features & MIPS_FEATURE_R4K_EXT)
+#else
+#define mips_uses_r4k_ext() 0
+#endif
+
+#ifdef MIPS_USES_NEC_VR5400
+#define mips_uses_nec_vr5400() (env->features & MIPS_FEATURE_NEC_VR5400)
+#else
+#define mips_uses_nec_vr5400() 0
+#endif
+
+#ifdef MIPS_USES_FPU
+#define mips_uses_fpu() (env->features & MIPS_FEATURE_FPU)
+#else
+#define mips_uses_fpu() 0
+#endif
#endif /* !defined (__MIPS_CPU_H__) */
--- ./target-mips/translate.c_orig 2006-07-08 07:16:50.000000000 +0200
+++ ./target-mips/translate.c 2006-07-08 07:22:48.000000000 +0200
@@ -1887,7 +1887,7 @@ static void gen_blikely(DisasContext *ct
gen_set_label(l1);
}
-static void decode_opc (DisasContext *ctx)
+static void decode_opc (CPUState *env, DisasContext *ctx)
{
int32_t offset;
int rs, rt, rd, sa;
@@ -1927,7 +1927,17 @@ static void decode_opc (DisasContext *ct
gen_arith(ctx, op1 | EXT_SPECIAL, rd, rs, rt);
break;
case 0x18 ... 0x1B: /* MULT / DIV */
- gen_muldiv(ctx, op1 | EXT_SPECIAL, rs, rt);
+ if(!sa) {
+ gen_muldiv(ctx, op1 | EXT_SPECIAL, rs, rt);
+ } else {
+ if(mips_uses_nec_vr5400()) {
+ op1 = ctx->opcode & 0x7FF;
+ /* tbd: call handler for special NEC instructions */
+ } else {
+ MIPS_INVAL("NEC extension");
+ generate_exception(ctx, EXCP_RI);
+ }
+ }
break;
case 0x08 ... 0x09: /* Jumps */
gen_compute_branch(ctx, op1 | EXT_SPECIAL, rs, rd, sa);
@@ -1985,19 +1995,32 @@ static void decode_opc (DisasContext *ct
case 0x1C: /* Special2 opcode */
op1 = ctx->opcode & 0x3F;
switch (op1) {
-#if defined (MIPS_USES_R4K_EXT)
/* Those instructions are not part of MIPS32 core */
case 0x00 ... 0x01: /* Multiply and add/sub */
case 0x04 ... 0x05:
- gen_muldiv(ctx, op1 | EXT_SPECIAL2, rs, rt);
+ if(mips_uses_r4k_ext()) {
+ gen_muldiv(ctx, op1 | EXT_SPECIAL2, rs, rt);
+ } else {
+ MIPS_INVAL("r4k extension");
+ generate_exception(ctx, EXCP_RI);
+ }
break;
case 0x02: /* MUL */
- gen_arith(ctx, op1 | EXT_SPECIAL2, rd, rs, rt);
+ if(mips_uses_r4k_ext()) {
+ gen_arith(ctx, op1 | EXT_SPECIAL2, rd, rs, rt);
+ } else {
+ MIPS_INVAL("r4k extension");
+ generate_exception(ctx, EXCP_RI);
+ }
break;
case 0x20 ... 0x21: /* CLO / CLZ */
- gen_cl(ctx, op1 | EXT_SPECIAL2, rd, rs);
+ if(mips_uses_r4k_ext()) {
+ gen_cl(ctx, op1 | EXT_SPECIAL2, rd, rs);
+ } else {
+ MIPS_INVAL("r4k extension");
+ generate_exception(ctx, EXCP_RI);
+ }
break;
-#endif
case 0x3F: /* SDBBP */
/* XXX: not clear which exception should be raised
* when in debug mode...
@@ -2074,43 +2097,43 @@ static void decode_opc (DisasContext *ct
case 0x35: /* LDC1 */
case 0x39: /* SWC1 */
case 0x3D: /* SDC1 */
-#if defined(MIPS_USES_FPU)
- gen_op_cp1_enabled();
- gen_flt_ldst(ctx, op, rt, rs, imm);
-#else
- generate_exception_err(ctx, EXCP_CpU, 1);
-#endif
+ if(mips_uses_fpu()) {
+ gen_op_cp1_enabled();
+ gen_flt_ldst(ctx, op, rt, rs, imm);
+ } else {
+ generate_exception_err(ctx, EXCP_CpU, 1);
+ }
break;
case 0x11: /* CP1 opcode */
-#if defined(MIPS_USES_FPU)
- gen_op_cp1_enabled();
- op1 = ((ctx->opcode >> 21) & 0x1F);
- switch (op1) {
- case 0x00: /* mfc1 */
- case 0x02: /* cfc1 */
- case 0x04: /* mtc1 */
- case 0x06: /* ctc1 */
- gen_cp1(ctx, op1 | EXT_CP1, rt, rd);
- break;
- case 0x08: /* bc */
- gen_compute_branch1(ctx, rt, imm << 2);
- return;
- case 0x10: /* 16: fmt=single fp */
- case 0x11: /* 17: fmt=double fp */
- case 0x14: /* 20: fmt=32bit fixed */
- case 0x15: /* 21: fmt=64bit fixed */
- gen_farith(ctx, op1, rt, rd, sa, ctx->opcode & 0x3f);
- break;
- default:
- generate_exception_err(ctx, EXCP_RI, 1);
+ if(mips_uses_fpu()) {
+ gen_op_cp1_enabled();
+ op1 = ((ctx->opcode >> 21) & 0x1F);
+ switch (op1) {
+ case 0x00: /* mfc1 */
+ case 0x02: /* cfc1 */
+ case 0x04: /* mtc1 */
+ case 0x06: /* ctc1 */
+ gen_cp1(ctx, op1 | EXT_CP1, rt, rd);
+ break;
+ case 0x08: /* bc */
+ gen_compute_branch1(ctx, rt, imm << 2);
+ return;
+ case 0x10: /* 16: fmt=single fp */
+ case 0x11: /* 17: fmt=double fp */
+ case 0x14: /* 20: fmt=32bit fixed */
+ case 0x15: /* 21: fmt=64bit fixed */
+ gen_farith(ctx, op1, rt, rd, sa, ctx->opcode & 0x3f);
+ break;
+ default:
+ generate_exception_err(ctx, EXCP_RI, 1);
+ break;
+ }
break;
+ } else {
+ generate_exception_err(ctx, EXCP_CpU, 1);
}
break;
-#else
- generate_exception_err(ctx, EXCP_CpU, 1);
-#endif
- break;
/* COP2. */
case 0x32: /* LWC2 */
@@ -2262,7 +2285,7 @@ int gen_intermediate_code_internal (CPUS
gen_opc_instr_start[lj] = 1;
}
ctx.opcode = ldl_code(ctx.pc);
- decode_opc(&ctx);
+ decode_opc(env, &ctx);
ctx.pc += 4;
if (env->singlestep_enabled)
@@ -2400,44 +2423,3 @@ void cpu_dump_state (CPUState *env, FILE
fpu_dump_state(env, f, cpu_fprintf, flags);
#endif
}
-
-CPUMIPSState *cpu_mips_init (void)
-{
- CPUMIPSState *env;
-
- env = qemu_mallocz(sizeof(CPUMIPSState));
- if (!env)
- return NULL;
- cpu_exec_init(env);
- tlb_flush(env, 1);
- /* Minimal init */
- env->PC = 0xBFC00000;
-#if defined (MIPS_USES_R4K_TLB)
- env->CP0_random = MIPS_TLB_NB - 1;
-#endif
- env->CP0_Wired = 0;
- env->CP0_Config0 = MIPS_CONFIG0;
-#if defined (MIPS_CONFIG1)
- env->CP0_Config1 = MIPS_CONFIG1;
-#endif
-#if defined (MIPS_CONFIG2)
- env->CP0_Config2 = MIPS_CONFIG2;
-#endif
-#if defined (MIPS_CONFIG3)
- env->CP0_Config3 = MIPS_CONFIG3;
-#endif
- env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
- env->CP0_WatchLo = 0;
- 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;
- env->exception_index = EXCP_NONE;
-#if defined(CONFIG_USER_ONLY)
- env->hflags |= MIPS_HFLAG_UM;
-#endif
-#ifdef MIPS_USES_FPU
- env->fcr0 = MIPS_FCR0;
-#endif
- return env;
-}
--- ./target-mips/helper.c_orig 2006-07-08 07:16:50.000000000 +0200
+++ ./target-mips/helper.c 2006-07-08 07:22:04.000000000 +0200
@@ -430,3 +430,68 @@ void do_interrupt (CPUState *env)
}
env->exception_index = EXCP_NONE;
}
+
+CPUMIPSState *cpu_mips_init (void)
+{
+ CPUMIPSState *env;
+
+ env = qemu_mallocz(sizeof(CPUMIPSState));
+ if (!env)
+ return NULL;
+ cpu_exec_init(env);
+ tlb_flush(env, 1);
+ /* Minimal init */
+ env->PC = 0xBFC00000;
+#if defined (MIPS_USES_R4K_TLB)
+ env->CP0_random = MIPS_TLB_NB - 1;
+#endif
+ env->CP0_Wired = 0;
+ env->CP0_Config0 = MIPS_CONFIG0;
+#if defined (MIPS_CONFIG1)
+ env->CP0_Config1 = MIPS_CONFIG1;
+#endif
+#if defined (MIPS_CONFIG2)
+ env->CP0_Config2 = MIPS_CONFIG2;
+#endif
+#if defined (MIPS_CONFIG3)
+ env->CP0_Config3 = MIPS_CONFIG3;
+#endif
+ env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
+ env->CP0_WatchLo = 0;
+ env->hflags = MIPS_HFLAG_ERL;
+ /* Count register increments in debug mode, EJTAG version 1 */
+ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
+ env->exception_index = EXCP_NONE;
+#if defined(CONFIG_USER_ONLY)
+ env->hflags |= MIPS_HFLAG_UM;
+#endif
+ return env;
+}
+
+static inline void set_feature(CPUMIPSState *env, int feature)
+{
+ env->features |= feature;
+}
+
+void cpu_mips_set_model(CPUMIPSState *env, uint32_t id)
+{
+ env->CP0_PRid = id;
+ env->features = 0;
+ switch (id) {
+ case MIPS_R4Kc:
+ set_feature(env, MIPS_FEATURE_R4K_EXT);
+ set_feature(env, MIPS_FEATURE_FPU);
+ break;
+ default:
+ cpu_abort(env, "Bad CPU ID: %x\n", id);
+ break;
+ }
+
+ if(mips_uses_fpu()) {
+ env->fcr0 = MIPS_FCR0;
+#if defined (MIPS_CONFIG1)
+ env->CP0_Config1 |= (1 << CP0C1_FP);
+#endif
+ }
+}
+
--- ./target-mips/mips-defs.h_orig 2006-07-08 07:16:50.000000000 +0200
+++ ./target-mips/mips-defs.h 2006-07-08 07:16:45.000000000 +0200
@@ -9,10 +9,6 @@
#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 */
#define TARGET_LONG_BITS 32
/* real pages are variable size... */
@@ -40,28 +36,13 @@
/* 16 TLBs, 64 sets Icache, 16 bytes Icache line, 2-way Icache,
* 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
* no performance counters, watch registers present, no code compression,
- * EJTAG present, FPU enable bit depending on MIPS_USES_FPU
+ * EJTAG present, FPU bit is set depending on runtime FPU selection
*/
#define MIPS_CONFIG1 \
((15 << CP0C1_MMU) | \
(0x000 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x01 << CP0C1_IA) | \
(0x000 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x01 << CP0C1_DA) | \
(0 << CP0C1_PC) | (1 << CP0C1_WR) | (0 << CP0C1_CA) | \
- (1 << CP0C1_EP) | (MIPS_USES_FPU << CP0C1_FP))
-#elif (MIPS_CPU == MIPS_R4Kp)
-/* 32 bits target */
-#define TARGET_LONG_BITS 32
-/* 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"
-/* Remainder for other flags */
-//#define TARGET_MIPS64
-//#define MIPS_USES_FPU
-#endif
+ (1 << CP0C1_EP))
#endif /* !defined (__QEMU_MIPS_DEFS_H__) */
--- ./vl.c_orig 2006-07-08 07:16:50.000000000 +0200
+++ ./vl.c 2006-07-08 07:16:45.000000000 +0200
@@ -5455,7 +5455,7 @@ void register_machines(void)
qemu_register_machine(&core99_machine);
qemu_register_machine(&prep_machine);
#elif defined(TARGET_MIPS)
- qemu_register_machine(&mips_machine);
+ qemu_register_machine(&mips_r4kc_machine);
#elif defined(TARGET_SPARC)
#ifdef TARGET_SPARC64
qemu_register_machine(&sun4u_machine);
next prev parent reply other threads:[~2006-07-08 6:15 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-06-25 16:12 [Qemu-devel] Pending MIPS patches Dirk Behme
2006-06-25 16:39 ` Fabrice Bellard
2006-06-26 9:35 ` Marius Groeger
2006-06-26 15:35 ` Dirk Behme
2006-06-26 20:17 ` Fabrice Bellard
2006-06-27 15:45 ` MIPS instruction set configuration, was: " Dirk Behme
2006-06-27 15:55 ` [Qemu-devel] Re: MIPS instruction set configuration Marius Groeger
2006-06-27 20:57 ` Fabrice Bellard
2006-07-02 16:27 ` [Qemu-devel] [PATCH] " Dirk Behme
2006-07-02 23:16 ` Thiemo Seufer
2006-07-03 8:32 ` Fabrice Bellard
2006-07-03 9:50 ` Thiemo Seufer
2006-07-03 14:32 ` Dirk Behme
2006-07-03 14:53 ` Fabrice Bellard
2006-07-08 6:15 ` Dirk Behme [this message]
2006-07-03 14:20 ` Dirk Behme
2006-07-03 17:02 ` Thiemo Seufer
2006-07-03 18:41 ` Stefan Weil
2006-07-03 19:58 ` Thiemo Seufer
2006-07-08 6:19 ` Dirk Behme
2006-07-08 12:47 ` Thiemo Seufer
[not found] ` <44A001C7.8040303@gmail.com>
2006-06-26 17:27 ` [Qemu-devel] Pending MIPS patches Raphaël Rigo
2006-06-27 21:08 ` Fabrice Bellard
2006-06-27 21:15 ` Fabrice Bellard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44AF4D9F.2090000@gmail.com \
--to=dirk.behme@googlemail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).