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; |