Commit 33d68b5f00011c8101aec93ba1bb2b470e35151d
1 parent
e24ad6f1
MIPS -cpu selection support, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2491 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
10 changed files
with
137 additions
and
34 deletions
Changelog
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | - Tap device emulation for Solaris (Sittichai Palanisong) |
| 3 | 3 | - Monitor multiplexing to several I/O channels (Jason Wessel) |
| 4 | 4 | - ds1225y nvram support (Herve Poussineau) |
| 5 | + - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau) | |
| 5 | 6 | |
| 6 | 7 | version 0.9.0: |
| 7 | 8 | ... | ... |
Makefile.target
hw/mips_malta.c
| ... | ... | @@ -626,8 +626,20 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, |
| 626 | 626 | /* fdctrl_t *floppy_controller; */ |
| 627 | 627 | MaltaFPGAState *malta_fpga; |
| 628 | 628 | int ret; |
| 629 | + mips_def_t *def; | |
| 629 | 630 | |
| 631 | + /* init CPUs */ | |
| 632 | + if (cpu_model == NULL) { | |
| 633 | +#ifdef MIPS_HAS_MIPS64 | |
| 634 | + cpu_model = "R4000"; | |
| 635 | +#else | |
| 636 | + cpu_model = "4KEc"; | |
| 637 | +#endif | |
| 638 | + } | |
| 639 | + if (mips_find_by_name(cpu_model, &def) != 0) | |
| 640 | + def = NULL; | |
| 630 | 641 | env = cpu_init(); |
| 642 | + cpu_mips_register(env, def); | |
| 631 | 643 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
| 632 | 644 | qemu_register_reset(main_cpu_reset, env); |
| 633 | 645 | ... | ... |
hw/mips_r4k.c
| ... | ... | @@ -138,8 +138,20 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, |
| 138 | 138 | CPUState *env; |
| 139 | 139 | RTCState *rtc_state; |
| 140 | 140 | int i; |
| 141 | + mips_def_t *def; | |
| 141 | 142 | |
| 143 | + /* init CPUs */ | |
| 144 | + if (cpu_model == NULL) { | |
| 145 | +#ifdef MIPS_HAS_MIPS64 | |
| 146 | + cpu_model = "R4000"; | |
| 147 | +#else | |
| 148 | + cpu_model = "4KEc"; | |
| 149 | +#endif | |
| 150 | + } | |
| 151 | + if (mips_find_by_name(cpu_model, &def) != 0) | |
| 152 | + def = NULL; | |
| 142 | 153 | env = cpu_init(); |
| 154 | + cpu_mips_register(env, def); | |
| 143 | 155 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
| 144 | 156 | qemu_register_reset(main_cpu_reset, env); |
| 145 | 157 | |
| ... | ... | @@ -148,7 +160,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, |
| 148 | 160 | |
| 149 | 161 | if (!mips_qemu_iomemtype) { |
| 150 | 162 | mips_qemu_iomemtype = cpu_register_io_memory(0, mips_qemu_read, |
| 151 | - mips_qemu_write, NULL); | |
| 163 | + mips_qemu_write, NULL); | |
| 152 | 164 | } |
| 153 | 165 | cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype); |
| 154 | 166 | ... | ... |
target-mips/cpu.h
| ... | ... | @@ -282,6 +282,11 @@ struct CPUMIPSState { |
| 282 | 282 | struct QEMUTimer *timer; /* Internal timer */ |
| 283 | 283 | }; |
| 284 | 284 | |
| 285 | +typedef struct mips_def_t mips_def_t; | |
| 286 | +int mips_find_by_name (const unsigned char *name, mips_def_t **def); | |
| 287 | +void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | |
| 288 | +int cpu_mips_register (CPUMIPSState *env, mips_def_t *def); | |
| 289 | + | |
| 285 | 290 | #include "cpu-all.h" |
| 286 | 291 | |
| 287 | 292 | /* Memory access type : | ... | ... |
target-mips/mips-defs.h
| ... | ... | @@ -6,26 +6,15 @@ |
| 6 | 6 | /* If we want to use host float regs... */ |
| 7 | 7 | //#define USE_HOST_FLOAT_REGS |
| 8 | 8 | |
| 9 | -#define MIPS_R4Kc 0x00018000 | |
| 10 | -#define MIPS_R4Kp 0x00018300 | |
| 11 | - | |
| 12 | -/* Emulate MIPS R4Kc for now */ | |
| 13 | -#define MIPS_CPU MIPS_R4Kc | |
| 14 | - | |
| 15 | -#if (MIPS_CPU == MIPS_R4Kc) | |
| 16 | 9 | /* 32 bits target */ |
| 17 | 10 | #undef MIPS_HAS_MIPS64 |
| 18 | 11 | //#define MIPS_HAS_MIPS64 1 |
| 19 | 12 | /* real pages are variable size... */ |
| 20 | 13 | #define TARGET_PAGE_BITS 12 |
| 21 | -/* Uses MIPS R4Kx enhancements to MIPS32 architecture */ | |
| 22 | -#define MIPS_USES_R4K_EXT | |
| 23 | 14 | /* Uses MIPS R4Kc TLB model */ |
| 24 | 15 | #define MIPS_USES_R4K_TLB |
| 25 | 16 | #define MIPS_TLB_NB 16 |
| 26 | 17 | #define MIPS_TLB_MAX 128 |
| 27 | -/* basic FPU register support */ | |
| 28 | -#define MIPS_USES_FPU 1 | |
| 29 | 18 | /* Define a implementation number of 1. |
| 30 | 19 | * Define a major version 1, minor version 0. |
| 31 | 20 | */ |
| ... | ... | @@ -63,21 +52,6 @@ |
| 63 | 52 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ |
| 64 | 53 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ |
| 65 | 54 | (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL)) |
| 66 | -#elif (MIPS_CPU == MIPS_R4Kp) | |
| 67 | -/* 32 bits target */ | |
| 68 | -#undef MIPS_HAS_MIPS64 | |
| 69 | -/* real pages are variable size... */ | |
| 70 | -#define TARGET_PAGE_BITS 12 | |
| 71 | -/* Uses MIPS R4Kx enhancements to MIPS32 architecture */ | |
| 72 | -#define MIPS_USES_R4K_EXT | |
| 73 | -/* Uses MIPS R4Km FPM MMU model */ | |
| 74 | -#define MIPS_USES_R4K_FPM | |
| 75 | -#else | |
| 76 | -#error "MIPS CPU not defined" | |
| 77 | -/* Reminder for other flags */ | |
| 78 | -//#undef MIPS_HAS_MIPS64 | |
| 79 | -//#define MIPS_USES_FPU | |
| 80 | -#endif | |
| 81 | 55 | |
| 82 | 56 | #ifdef MIPS_HAS_MIPS64 |
| 83 | 57 | #define TARGET_LONG_BITS 64 | ... | ... |
target-mips/translate.c
| ... | ... | @@ -5283,12 +5283,6 @@ void cpu_reset (CPUMIPSState *env) |
| 5283 | 5283 | env->CP0_Wired = 0; |
| 5284 | 5284 | /* SMP not implemented */ |
| 5285 | 5285 | env->CP0_EBase = 0x80000000; |
| 5286 | - env->CP0_Config0 = MIPS_CONFIG0; | |
| 5287 | - env->CP0_Config1 = MIPS_CONFIG1; | |
| 5288 | -#ifdef MIPS_USES_FPU | |
| 5289 | - /* basic FPU register support */ | |
| 5290 | - env->CP0_Config1 |= (1 << CP0C1_FP); | |
| 5291 | -#endif | |
| 5292 | 5286 | env->CP0_Config2 = MIPS_CONFIG2; |
| 5293 | 5287 | env->CP0_Config3 = MIPS_CONFIG3; |
| 5294 | 5288 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
| ... | ... | @@ -5296,7 +5290,6 @@ void cpu_reset (CPUMIPSState *env) |
| 5296 | 5290 | env->hflags = MIPS_HFLAG_ERL; |
| 5297 | 5291 | /* Count register increments in debug mode, EJTAG version 1 */ |
| 5298 | 5292 | env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); |
| 5299 | - env->CP0_PRid = MIPS_CPU; | |
| 5300 | 5293 | #endif |
| 5301 | 5294 | env->exception_index = EXCP_NONE; |
| 5302 | 5295 | #if defined(CONFIG_USER_ONLY) |
| ... | ... | @@ -5308,3 +5301,5 @@ void cpu_reset (CPUMIPSState *env) |
| 5308 | 5301 | env->SYNCI_Step = 16; |
| 5309 | 5302 | env->CCRes = 2; |
| 5310 | 5303 | } |
| 5304 | + | |
| 5305 | +#include "translate_init.c" | ... | ... |
target-mips/translate_init.c
0 โ 100644
| 1 | +/* | |
| 2 | + * MIPS emulation for qemu: CPU initialisation routines. | |
| 3 | + * | |
| 4 | + * Copyright (c) 2004-2005 Jocelyn Mayer | |
| 5 | + * Copyright (c) 2007 Herve Poussineau | |
| 6 | + * | |
| 7 | + * This library is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU Lesser General Public | |
| 9 | + * License as published by the Free Software Foundation; either | |
| 10 | + * version 2 of the License, or (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This library is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * Lesser General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU Lesser General Public | |
| 18 | + * License along with this library; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 20 | + */ | |
| 21 | + | |
| 22 | +struct mips_def_t { | |
| 23 | + const unsigned char *name; | |
| 24 | + int32_t CP0_PRid; | |
| 25 | + int32_t CP0_Config0; | |
| 26 | + int32_t CP0_Config1; | |
| 27 | +}; | |
| 28 | + | |
| 29 | +/*****************************************************************************/ | |
| 30 | +/* MIPS CPU definitions */ | |
| 31 | +static mips_def_t mips_defs[] = | |
| 32 | +{ | |
| 33 | +#ifndef MIPS_HAS_MIPS64 | |
| 34 | + { | |
| 35 | + .name = "4Kc", | |
| 36 | + .CP0_PRid = 0x00018000, | |
| 37 | + .CP0_Config0 = MIPS_CONFIG0, | |
| 38 | + .CP0_Config1 = MIPS_CONFIG1, | |
| 39 | + }, | |
| 40 | + { | |
| 41 | + .name = "4KEc", | |
| 42 | + .CP0_PRid = 0x00018400, | |
| 43 | + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), | |
| 44 | + .CP0_Config1 = MIPS_CONFIG1, | |
| 45 | + }, | |
| 46 | + { | |
| 47 | + .name = "24Kf", | |
| 48 | + .CP0_PRid = 0x00019300, | |
| 49 | + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), | |
| 50 | + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP), | |
| 51 | + }, | |
| 52 | +#else | |
| 53 | + { | |
| 54 | + .name = "R4000", | |
| 55 | + .CP0_PRid = 0x00000400, | |
| 56 | + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT), | |
| 57 | + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP), | |
| 58 | + }, | |
| 59 | +#endif | |
| 60 | +}; | |
| 61 | + | |
| 62 | +int mips_find_by_name (const unsigned char *name, mips_def_t **def) | |
| 63 | +{ | |
| 64 | + int i, ret; | |
| 65 | + | |
| 66 | + ret = -1; | |
| 67 | + *def = NULL; | |
| 68 | + for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) { | |
| 69 | + if (strcasecmp(name, mips_defs[i].name) == 0) { | |
| 70 | + *def = &mips_defs[i]; | |
| 71 | + ret = 0; | |
| 72 | + break; | |
| 73 | + } | |
| 74 | + } | |
| 75 | + | |
| 76 | + return ret; | |
| 77 | +} | |
| 78 | + | |
| 79 | +void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) | |
| 80 | +{ | |
| 81 | + int i; | |
| 82 | + | |
| 83 | + for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) { | |
| 84 | + (*cpu_fprintf)(f, "MIPS '%s'\n", | |
| 85 | + mips_defs[i].name); | |
| 86 | + } | |
| 87 | +} | |
| 88 | + | |
| 89 | +int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) | |
| 90 | +{ | |
| 91 | + if (!def) | |
| 92 | + cpu_abort(env, "Unable to find MIPS CPU definition\n"); | |
| 93 | + env->CP0_PRid = def->CP0_PRid; | |
| 94 | + env->CP0_Config0 = def->CP0_Config0; | |
| 95 | + env->CP0_Config1 = def->CP0_Config1; | |
| 96 | + return 0; | |
| 97 | +} | ... | ... |
vl.c
| ... | ... | @@ -7009,6 +7009,8 @@ int main(int argc, char **argv) |
| 7009 | 7009 | ppc_cpu_list(stdout, &fprintf); |
| 7010 | 7010 | #elif defined(TARGET_ARM) |
| 7011 | 7011 | arm_cpu_list(); |
| 7012 | +#elif defined(TARGET_MIPS) | |
| 7013 | + mips_cpu_list(stdout, &fprintf); | |
| 7012 | 7014 | #endif |
| 7013 | 7015 | exit(1); |
| 7014 | 7016 | } else { | ... | ... |
vl.h
| ... | ... | @@ -713,6 +713,10 @@ typedef void IRQRequestFunc(void *opaque, int level); |
| 713 | 713 | void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
| 714 | 714 | #endif |
| 715 | 715 | |
| 716 | +#if defined(TARGET_MIPS) | |
| 717 | +void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | |
| 718 | +#endif | |
| 719 | + | |
| 716 | 720 | /* ISA bus */ |
| 717 | 721 | |
| 718 | 722 | extern target_phys_addr_t isa_mem_base; | ... | ... |