From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Fz66V-00033I-Sh for qemu-devel@nongnu.org; Sat, 08 Jul 2006 02:15:47 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Fz66U-000336-SG for qemu-devel@nongnu.org; Sat, 08 Jul 2006 02:15:47 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Fz66U-000332-LP for qemu-devel@nongnu.org; Sat, 08 Jul 2006 02:15:46 -0400 Received: from [64.233.182.188] (helo=nf-out-0910.google.com) by monty-python.gnu.org with esmtp (Exim 4.52) id 1Fz674-0003tA-Ak for qemu-devel@nongnu.org; Sat, 08 Jul 2006 02:16:22 -0400 Received: by nf-out-0910.google.com with SMTP id b2so144813nfe for ; Fri, 07 Jul 2006 23:15:44 -0700 (PDT) Message-ID: <44AF4D9F.2090000@gmail.com> Date: Sat, 08 Jul 2006 08:15:59 +0200 MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH] MIPS instruction set configuration References: <449EB5FA.6070405@gmail.com> <449EBC39.3050701@bellard.org> <449FFEB2.1070305@gmail.com> <44A040DA.2050108@bellard.org> <44A1529D.1070306@gmail.com> <44A19BC3.1030607@bellard.org> <44A7F3F1.5020909@gmail.com> <20060702231636.GB18996@networkno.de> <44A8D615.9060004@bellard.org> <44A92A8A.8010200@gmail.com> <44A92F87.6030408@bellard.org> In-Reply-To: <44A92F87.6030408@bellard.org> Content-Type: multipart/mixed; boundary="------------080500000303050108040709" From: Dirk Behme Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------080500000303050108040709 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 --------------080500000303050108040709 Content-Type: text/plain; name="mips_isa_config_patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mips_isa_config_patch.txt" --- ./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); --------------080500000303050108040709--