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,6 +2,7 @@ | ||
| 2 | - Tap device emulation for Solaris (Sittichai Palanisong) | 2 | - Tap device emulation for Solaris (Sittichai Palanisong) |
| 3 | - Monitor multiplexing to several I/O channels (Jason Wessel) | 3 | - Monitor multiplexing to several I/O channels (Jason Wessel) |
| 4 | - ds1225y nvram support (Herve Poussineau) | 4 | - ds1225y nvram support (Herve Poussineau) |
| 5 | + - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau) | ||
| 5 | 6 | ||
| 6 | version 0.9.0: | 7 | version 0.9.0: |
| 7 | 8 |
Makefile.target
| @@ -551,6 +551,7 @@ endif | @@ -551,6 +551,7 @@ endif | ||
| 551 | ifeq ($(TARGET_ARCH), mips) | 551 | ifeq ($(TARGET_ARCH), mips) |
| 552 | op.o: op.c op_template.c fop_template.c op_mem.c | 552 | op.o: op.c op_template.c fop_template.c op_mem.c |
| 553 | op_helper.o: op_helper_mem.c | 553 | op_helper.o: op_helper_mem.c |
| 554 | +translate.o: translate.c translate_init.c | ||
| 554 | endif | 555 | endif |
| 555 | 556 | ||
| 556 | loader.o: loader.c elf_ops.h | 557 | loader.o: loader.c elf_ops.h |
hw/mips_malta.c
| @@ -626,8 +626,20 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, | @@ -626,8 +626,20 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device, | ||
| 626 | /* fdctrl_t *floppy_controller; */ | 626 | /* fdctrl_t *floppy_controller; */ |
| 627 | MaltaFPGAState *malta_fpga; | 627 | MaltaFPGAState *malta_fpga; |
| 628 | int ret; | 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 | env = cpu_init(); | 641 | env = cpu_init(); |
| 642 | + cpu_mips_register(env, def); | ||
| 631 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); | 643 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
| 632 | qemu_register_reset(main_cpu_reset, env); | 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,8 +138,20 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, | ||
| 138 | CPUState *env; | 138 | CPUState *env; |
| 139 | RTCState *rtc_state; | 139 | RTCState *rtc_state; |
| 140 | int i; | 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 | env = cpu_init(); | 153 | env = cpu_init(); |
| 154 | + cpu_mips_register(env, def); | ||
| 143 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); | 155 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
| 144 | qemu_register_reset(main_cpu_reset, env); | 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,7 +160,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, | ||
| 148 | 160 | ||
| 149 | if (!mips_qemu_iomemtype) { | 161 | if (!mips_qemu_iomemtype) { |
| 150 | mips_qemu_iomemtype = cpu_register_io_memory(0, mips_qemu_read, | 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 | cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype); | 165 | cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype); |
| 154 | 166 |
target-mips/cpu.h
| @@ -282,6 +282,11 @@ struct CPUMIPSState { | @@ -282,6 +282,11 @@ struct CPUMIPSState { | ||
| 282 | struct QEMUTimer *timer; /* Internal timer */ | 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 | #include "cpu-all.h" | 290 | #include "cpu-all.h" |
| 286 | 291 | ||
| 287 | /* Memory access type : | 292 | /* Memory access type : |
target-mips/mips-defs.h
| @@ -6,26 +6,15 @@ | @@ -6,26 +6,15 @@ | ||
| 6 | /* If we want to use host float regs... */ | 6 | /* If we want to use host float regs... */ |
| 7 | //#define USE_HOST_FLOAT_REGS | 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 | /* 32 bits target */ | 9 | /* 32 bits target */ |
| 17 | #undef MIPS_HAS_MIPS64 | 10 | #undef MIPS_HAS_MIPS64 |
| 18 | //#define MIPS_HAS_MIPS64 1 | 11 | //#define MIPS_HAS_MIPS64 1 |
| 19 | /* real pages are variable size... */ | 12 | /* real pages are variable size... */ |
| 20 | #define TARGET_PAGE_BITS 12 | 13 | #define TARGET_PAGE_BITS 12 |
| 21 | -/* Uses MIPS R4Kx enhancements to MIPS32 architecture */ | ||
| 22 | -#define MIPS_USES_R4K_EXT | ||
| 23 | /* Uses MIPS R4Kc TLB model */ | 14 | /* Uses MIPS R4Kc TLB model */ |
| 24 | #define MIPS_USES_R4K_TLB | 15 | #define MIPS_USES_R4K_TLB |
| 25 | #define MIPS_TLB_NB 16 | 16 | #define MIPS_TLB_NB 16 |
| 26 | #define MIPS_TLB_MAX 128 | 17 | #define MIPS_TLB_MAX 128 |
| 27 | -/* basic FPU register support */ | ||
| 28 | -#define MIPS_USES_FPU 1 | ||
| 29 | /* Define a implementation number of 1. | 18 | /* Define a implementation number of 1. |
| 30 | * Define a major version 1, minor version 0. | 19 | * Define a major version 1, minor version 0. |
| 31 | */ | 20 | */ |
| @@ -63,21 +52,6 @@ | @@ -63,21 +52,6 @@ | ||
| 63 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ | 52 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ |
| 64 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ | 53 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ |
| 65 | (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL)) | 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 | #ifdef MIPS_HAS_MIPS64 | 56 | #ifdef MIPS_HAS_MIPS64 |
| 83 | #define TARGET_LONG_BITS 64 | 57 | #define TARGET_LONG_BITS 64 |
target-mips/translate.c
| @@ -5283,12 +5283,6 @@ void cpu_reset (CPUMIPSState *env) | @@ -5283,12 +5283,6 @@ void cpu_reset (CPUMIPSState *env) | ||
| 5283 | env->CP0_Wired = 0; | 5283 | env->CP0_Wired = 0; |
| 5284 | /* SMP not implemented */ | 5284 | /* SMP not implemented */ |
| 5285 | env->CP0_EBase = 0x80000000; | 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 | env->CP0_Config2 = MIPS_CONFIG2; | 5286 | env->CP0_Config2 = MIPS_CONFIG2; |
| 5293 | env->CP0_Config3 = MIPS_CONFIG3; | 5287 | env->CP0_Config3 = MIPS_CONFIG3; |
| 5294 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); | 5288 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
| @@ -5296,7 +5290,6 @@ void cpu_reset (CPUMIPSState *env) | @@ -5296,7 +5290,6 @@ void cpu_reset (CPUMIPSState *env) | ||
| 5296 | env->hflags = MIPS_HFLAG_ERL; | 5290 | env->hflags = MIPS_HFLAG_ERL; |
| 5297 | /* Count register increments in debug mode, EJTAG version 1 */ | 5291 | /* Count register increments in debug mode, EJTAG version 1 */ |
| 5298 | env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); | 5292 | env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); |
| 5299 | - env->CP0_PRid = MIPS_CPU; | ||
| 5300 | #endif | 5293 | #endif |
| 5301 | env->exception_index = EXCP_NONE; | 5294 | env->exception_index = EXCP_NONE; |
| 5302 | #if defined(CONFIG_USER_ONLY) | 5295 | #if defined(CONFIG_USER_ONLY) |
| @@ -5308,3 +5301,5 @@ void cpu_reset (CPUMIPSState *env) | @@ -5308,3 +5301,5 @@ void cpu_reset (CPUMIPSState *env) | ||
| 5308 | env->SYNCI_Step = 16; | 5301 | env->SYNCI_Step = 16; |
| 5309 | env->CCRes = 2; | 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,6 +7009,8 @@ int main(int argc, char **argv) | ||
| 7009 | ppc_cpu_list(stdout, &fprintf); | 7009 | ppc_cpu_list(stdout, &fprintf); |
| 7010 | #elif defined(TARGET_ARM) | 7010 | #elif defined(TARGET_ARM) |
| 7011 | arm_cpu_list(); | 7011 | arm_cpu_list(); |
| 7012 | +#elif defined(TARGET_MIPS) | ||
| 7013 | + mips_cpu_list(stdout, &fprintf); | ||
| 7012 | #endif | 7014 | #endif |
| 7013 | exit(1); | 7015 | exit(1); |
| 7014 | } else { | 7016 | } else { |
vl.h
| @@ -713,6 +713,10 @@ typedef void IRQRequestFunc(void *opaque, int level); | @@ -713,6 +713,10 @@ typedef void IRQRequestFunc(void *opaque, int level); | ||
| 713 | void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | 713 | void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
| 714 | #endif | 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 | /* ISA bus */ | 720 | /* ISA bus */ |
| 717 | 721 | ||
| 718 | extern target_phys_addr_t isa_mem_base; | 722 | extern target_phys_addr_t isa_mem_base; |