Statistics
| Branch: | Revision:

root / target-mips / translate_init.c @ fcb4a419

History | View | Annotate | Download (6.4 kB)

1 33d68b5f ths
/*
2 33d68b5f ths
 *  MIPS emulation for qemu: CPU initialisation routines.
3 33d68b5f ths
 *
4 33d68b5f ths
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5 33d68b5f ths
 *  Copyright (c) 2007 Herve Poussineau
6 33d68b5f ths
 *
7 33d68b5f ths
 * This library is free software; you can redistribute it and/or
8 33d68b5f ths
 * modify it under the terms of the GNU Lesser General Public
9 33d68b5f ths
 * License as published by the Free Software Foundation; either
10 33d68b5f ths
 * version 2 of the License, or (at your option) any later version.
11 33d68b5f ths
 *
12 33d68b5f ths
 * This library is distributed in the hope that it will be useful,
13 33d68b5f ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 33d68b5f ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 33d68b5f ths
 * Lesser General Public License for more details.
16 33d68b5f ths
 *
17 33d68b5f ths
 * You should have received a copy of the GNU Lesser General Public
18 33d68b5f ths
 * License along with this library; if not, write to the Free Software
19 33d68b5f ths
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 33d68b5f ths
 */
21 33d68b5f ths
22 3953d786 ths
/* CPU / CPU family specific config register values. */
23 3953d786 ths
24 3953d786 ths
/* Have config1, is MIPS32R1, uses TLB, no virtual icache,
25 3953d786 ths
   uncached coherency */
26 3953d786 ths
#define MIPS_CONFIG0                                              \
27 3953d786 ths
  ((1 << CP0C0_M) | (0x0 << CP0C0_K23) | (0x0 << CP0C0_KU) |      \
28 3953d786 ths
   (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) |    \
29 3953d786 ths
   (0x2 << CP0C0_K0))
30 3953d786 ths
31 fcb4a419 ths
/* Have config2, 64 sets Icache, 16 bytes Icache line,
32 3953d786 ths
   2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
33 3953d786 ths
   no coprocessor2 attached, no MDMX support attached,
34 3953d786 ths
   no performance counters, watch registers present,
35 3953d786 ths
   no code compression, EJTAG present, no FPU */
36 3953d786 ths
#define MIPS_CONFIG1                                              \
37 fcb4a419 ths
((1 << CP0C1_M) |                                                 \
38 3953d786 ths
 (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) |      \
39 3953d786 ths
 (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) |      \
40 3953d786 ths
 (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) |            \
41 3953d786 ths
 (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) |            \
42 3953d786 ths
 (0 << CP0C1_FP))
43 3953d786 ths
44 3953d786 ths
/* Have config3, no tertiary/secondary caches implemented */
45 3953d786 ths
#define MIPS_CONFIG2                                              \
46 3953d786 ths
((1 << CP0C2_M))
47 3953d786 ths
48 3953d786 ths
/* No config4, no DSP ASE, no large physaddr,
49 3953d786 ths
   no external interrupt controller, no vectored interupts,
50 3953d786 ths
   no 1kb pages, no MT ASE, no SmartMIPS ASE, no trace logic */
51 3953d786 ths
#define MIPS_CONFIG3                                              \
52 3953d786 ths
((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) |          \
53 3953d786 ths
 (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) |        \
54 3953d786 ths
 (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL))
55 3953d786 ths
56 3953d786 ths
/* Define a implementation number of 1.
57 3953d786 ths
   Define a major version 1, minor version 0. */
58 3953d786 ths
#define MIPS_FCR0 ((0 << 16) | (1 << 8) | (1 << 4) | 0)
59 3953d786 ths
60 3953d786 ths
61 33d68b5f ths
struct mips_def_t {
62 33d68b5f ths
    const unsigned char *name;
63 33d68b5f ths
    int32_t CP0_PRid;
64 33d68b5f ths
    int32_t CP0_Config0;
65 33d68b5f ths
    int32_t CP0_Config1;
66 3953d786 ths
    int32_t CP0_Config2;
67 3953d786 ths
    int32_t CP0_Config3;
68 34ee2ede ths
    int32_t CP0_Config6;
69 34ee2ede ths
    int32_t CP0_Config7;
70 2f644545 ths
    int32_t SYNCI_Step;
71 2f644545 ths
    int32_t CCRes;
72 3953d786 ths
    int32_t CP1_fcr0;
73 33d68b5f ths
};
74 33d68b5f ths
75 33d68b5f ths
/*****************************************************************************/
76 33d68b5f ths
/* MIPS CPU definitions */
77 33d68b5f ths
static mips_def_t mips_defs[] =
78 33d68b5f ths
{
79 60aa19ab ths
#ifndef TARGET_MIPS64
80 33d68b5f ths
    {
81 33d68b5f ths
        .name = "4Kc",
82 33d68b5f ths
        .CP0_PRid = 0x00018000,
83 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0,
84 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
85 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
86 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
87 2f644545 ths
        .SYNCI_Step = 32,
88 2f644545 ths
        .CCRes = 2,
89 3953d786 ths
        .CP1_fcr0 = MIPS_FCR0,
90 33d68b5f ths
    },
91 33d68b5f ths
    {
92 34ee2ede ths
        .name = "4KEcR1",
93 33d68b5f ths
        .CP0_PRid = 0x00018400,
94 34ee2ede ths
        .CP0_Config0 = MIPS_CONFIG0,
95 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
96 34ee2ede ths
        .CP0_Config2 = MIPS_CONFIG2,
97 34ee2ede ths
        .CP0_Config3 = MIPS_CONFIG3,
98 2f644545 ths
        .SYNCI_Step = 32,
99 2f644545 ths
        .CCRes = 2,
100 34ee2ede ths
        .CP1_fcr0 = MIPS_FCR0,
101 34ee2ede ths
    },
102 34ee2ede ths
    {
103 34ee2ede ths
        .name = "4KEc",
104 34ee2ede ths
        .CP0_PRid = 0x00019000,
105 34ee2ede ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
106 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
107 34ee2ede ths
        .CP0_Config2 = MIPS_CONFIG2,
108 34ee2ede ths
        .CP0_Config3 = MIPS_CONFIG3,
109 2f644545 ths
        .SYNCI_Step = 32,
110 2f644545 ths
        .CCRes = 2,
111 34ee2ede ths
        .CP1_fcr0 = MIPS_FCR0,
112 34ee2ede ths
    },
113 34ee2ede ths
    {
114 34ee2ede ths
        .name = "24Kc",
115 34ee2ede ths
        .CP0_PRid = 0x00019300,
116 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
117 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
118 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
119 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
120 2f644545 ths
        .SYNCI_Step = 32,
121 2f644545 ths
        .CCRes = 2,
122 3953d786 ths
        .CP1_fcr0 = MIPS_FCR0,
123 33d68b5f ths
    },
124 33d68b5f ths
    {
125 33d68b5f ths
        .name = "24Kf",
126 33d68b5f ths
        .CP0_PRid = 0x00019300,
127 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
128 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU),
129 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
130 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
131 2f644545 ths
        .SYNCI_Step = 32,
132 2f644545 ths
        .CCRes = 2,
133 3953d786 ths
        .CP1_fcr0 = MIPS_FCR0,
134 33d68b5f ths
    },
135 33d68b5f ths
#else
136 33d68b5f ths
    {
137 33d68b5f ths
        .name = "R4000",
138 33d68b5f ths
        .CP0_PRid = 0x00000400,
139 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
140 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU),
141 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
142 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
143 2f644545 ths
        .SYNCI_Step = 16,
144 2f644545 ths
        .CCRes = 2,
145 3953d786 ths
        .CP1_fcr0 = MIPS_FCR0,
146 33d68b5f ths
    },
147 33d68b5f ths
#endif
148 33d68b5f ths
};
149 33d68b5f ths
150 33d68b5f ths
int mips_find_by_name (const unsigned char *name, mips_def_t **def)
151 33d68b5f ths
{
152 33d68b5f ths
    int i, ret;
153 33d68b5f ths
154 33d68b5f ths
    ret = -1;
155 33d68b5f ths
    *def = NULL;
156 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
157 33d68b5f ths
        if (strcasecmp(name, mips_defs[i].name) == 0) {
158 33d68b5f ths
            *def = &mips_defs[i];
159 33d68b5f ths
            ret = 0;
160 33d68b5f ths
            break;
161 33d68b5f ths
        }
162 33d68b5f ths
    }
163 33d68b5f ths
164 33d68b5f ths
    return ret;
165 33d68b5f ths
}
166 33d68b5f ths
167 33d68b5f ths
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
168 33d68b5f ths
{
169 33d68b5f ths
    int i;
170 33d68b5f ths
171 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
172 33d68b5f ths
        (*cpu_fprintf)(f, "MIPS '%s'\n",
173 33d68b5f ths
                       mips_defs[i].name);
174 33d68b5f ths
    }
175 33d68b5f ths
}
176 33d68b5f ths
177 33d68b5f ths
int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
178 33d68b5f ths
{
179 33d68b5f ths
    if (!def)
180 33d68b5f ths
        cpu_abort(env, "Unable to find MIPS CPU definition\n");
181 33d68b5f ths
    env->CP0_PRid = def->CP0_PRid;
182 3953d786 ths
#ifdef TARGET_WORDS_BIGENDIAN
183 3953d786 ths
    env->CP0_Config0 = def->CP0_Config0 | (1 << CP0C0_BE);
184 3953d786 ths
#else
185 33d68b5f ths
    env->CP0_Config0 = def->CP0_Config0;
186 3953d786 ths
#endif
187 33d68b5f ths
    env->CP0_Config1 = def->CP0_Config1;
188 3953d786 ths
    env->CP0_Config2 = def->CP0_Config2;
189 3953d786 ths
    env->CP0_Config3 = def->CP0_Config3;
190 34ee2ede ths
    env->CP0_Config6 = def->CP0_Config6;
191 34ee2ede ths
    env->CP0_Config7 = def->CP0_Config7;
192 2f644545 ths
    env->SYNCI_Step = def->SYNCI_Step;
193 2f644545 ths
    env->CCRes = def->CCRes;
194 3953d786 ths
    env->fcr0 = def->CP1_fcr0;
195 fcb4a419 ths
#if defined (MIPS_USES_R4K_TLB)
196 fcb4a419 ths
    env->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
197 fcb4a419 ths
    env->CP0_Random = env->nb_tlb - 1;
198 fcb4a419 ths
    env->tlb_in_use = env->nb_tlb;
199 fcb4a419 ths
#endif
200 33d68b5f ths
    return 0;
201 33d68b5f ths
}