Commit 33d68b5f00011c8101aec93ba1bb2b470e35151d

Authored by ths
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
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
... ... @@ -551,6 +551,7 @@ endif
551 551 ifeq ($(TARGET_ARCH), mips)
552 552 op.o: op.c op_template.c fop_template.c op_mem.c
553 553 op_helper.o: op_helper_mem.c
  554 +translate.o: translate.c translate_init.c
554 555 endif
555 556  
556 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 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 +}
... ...
... ... @@ -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 {
... ...
... ... @@ -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;
... ...