Statistics
| Branch: | Revision:

root / target-mips / translate_init.c @ 51b2772f

History | View | Annotate | Download (7.9 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 5a5012ec ths
#define MIPS_FCR0 ((0 << FCR0_S) | (0x1 << FCR0_PRID) | (0x10 << FCR0_REV))
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 5a5012ec ths
    int32_t Status_rw_bitmask;
73 3953d786 ths
    int32_t CP1_fcr0;
74 33d68b5f ths
};
75 33d68b5f ths
76 33d68b5f ths
/*****************************************************************************/
77 33d68b5f ths
/* MIPS CPU definitions */
78 33d68b5f ths
static mips_def_t mips_defs[] =
79 33d68b5f ths
{
80 60aa19ab ths
#ifndef TARGET_MIPS64
81 33d68b5f ths
    {
82 33d68b5f ths
        .name = "4Kc",
83 33d68b5f ths
        .CP0_PRid = 0x00018000,
84 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0,
85 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
86 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
87 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
88 2f644545 ths
        .SYNCI_Step = 32,
89 2f644545 ths
        .CCRes = 2,
90 5a5012ec ths
        .Status_rw_bitmask = 0x3278FF17,
91 33d68b5f ths
    },
92 33d68b5f ths
    {
93 34ee2ede ths
        .name = "4KEcR1",
94 33d68b5f ths
        .CP0_PRid = 0x00018400,
95 34ee2ede ths
        .CP0_Config0 = MIPS_CONFIG0,
96 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
97 34ee2ede ths
        .CP0_Config2 = MIPS_CONFIG2,
98 34ee2ede ths
        .CP0_Config3 = MIPS_CONFIG3,
99 2f644545 ths
        .SYNCI_Step = 32,
100 2f644545 ths
        .CCRes = 2,
101 4759513b ths
        .Status_rw_bitmask = 0x3278FF17,
102 34ee2ede ths
    },
103 34ee2ede ths
    {
104 34ee2ede ths
        .name = "4KEc",
105 34ee2ede ths
        .CP0_PRid = 0x00019000,
106 34ee2ede ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
107 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
108 34ee2ede ths
        .CP0_Config2 = MIPS_CONFIG2,
109 34ee2ede ths
        .CP0_Config3 = MIPS_CONFIG3,
110 2f644545 ths
        .SYNCI_Step = 32,
111 2f644545 ths
        .CCRes = 2,
112 5a5012ec ths
        .Status_rw_bitmask = 0x3278FF17,
113 34ee2ede ths
    },
114 34ee2ede ths
    {
115 34ee2ede ths
        .name = "24Kc",
116 34ee2ede ths
        .CP0_PRid = 0x00019300,
117 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
118 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
119 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
120 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
121 2f644545 ths
        .SYNCI_Step = 32,
122 2f644545 ths
        .CCRes = 2,
123 5a5012ec ths
        .Status_rw_bitmask = 0x3278FF17,
124 33d68b5f ths
    },
125 33d68b5f ths
    {
126 33d68b5f ths
        .name = "24Kf",
127 33d68b5f ths
        .CP0_PRid = 0x00019300,
128 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
129 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU),
130 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
131 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
132 2f644545 ths
        .SYNCI_Step = 32,
133 2f644545 ths
        .CCRes = 2,
134 5a5012ec ths
        .Status_rw_bitmask = 0x3678FF17,
135 5a5012ec ths
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
136 5a5012ec ths
                    (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
137 33d68b5f ths
    },
138 33d68b5f ths
#else
139 33d68b5f ths
    {
140 33d68b5f ths
        .name = "R4000",
141 33d68b5f ths
        .CP0_PRid = 0x00000400,
142 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
143 fcb4a419 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU),
144 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
145 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
146 2f644545 ths
        .SYNCI_Step = 16,
147 2f644545 ths
        .CCRes = 2,
148 5a5012ec ths
        .Status_rw_bitmask = 0x3678FFFF,
149 5a5012ec ths
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
150 5a5012ec ths
                    (1 << FCR0_D) | (1 << FCR0_S) |
151 29929e34 ths
                    (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
152 33d68b5f ths
    },
153 33d68b5f ths
#endif
154 33d68b5f ths
};
155 33d68b5f ths
156 33d68b5f ths
int mips_find_by_name (const unsigned char *name, mips_def_t **def)
157 33d68b5f ths
{
158 33d68b5f ths
    int i, ret;
159 33d68b5f ths
160 33d68b5f ths
    ret = -1;
161 33d68b5f ths
    *def = NULL;
162 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
163 33d68b5f ths
        if (strcasecmp(name, mips_defs[i].name) == 0) {
164 33d68b5f ths
            *def = &mips_defs[i];
165 33d68b5f ths
            ret = 0;
166 33d68b5f ths
            break;
167 33d68b5f ths
        }
168 33d68b5f ths
    }
169 33d68b5f ths
170 33d68b5f ths
    return ret;
171 33d68b5f ths
}
172 33d68b5f ths
173 33d68b5f ths
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
174 33d68b5f ths
{
175 33d68b5f ths
    int i;
176 33d68b5f ths
177 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
178 33d68b5f ths
        (*cpu_fprintf)(f, "MIPS '%s'\n",
179 33d68b5f ths
                       mips_defs[i].name);
180 33d68b5f ths
    }
181 33d68b5f ths
}
182 33d68b5f ths
183 29929e34 ths
#ifndef CONFIG_USER_ONLY
184 29929e34 ths
static void no_mmu_init (CPUMIPSState *env, mips_def_t *def)
185 29929e34 ths
{
186 29929e34 ths
    env->nb_tlb = 1;
187 29929e34 ths
    env->map_address = &no_mmu_map_address;
188 29929e34 ths
}
189 29929e34 ths
190 29929e34 ths
static void fixed_mmu_init (CPUMIPSState *env, mips_def_t *def)
191 29929e34 ths
{
192 29929e34 ths
    env->nb_tlb = 1;
193 29929e34 ths
    env->map_address = &fixed_mmu_map_address;
194 29929e34 ths
}
195 29929e34 ths
196 29929e34 ths
static void r4k_mmu_init (CPUMIPSState *env, mips_def_t *def)
197 29929e34 ths
{
198 29929e34 ths
    env->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
199 29929e34 ths
    env->map_address = &r4k_map_address;
200 29929e34 ths
    env->do_tlbwi = r4k_do_tlbwi;
201 29929e34 ths
    env->do_tlbwr = r4k_do_tlbwr;
202 29929e34 ths
    env->do_tlbp = r4k_do_tlbp;
203 29929e34 ths
    env->do_tlbr = r4k_do_tlbr;
204 29929e34 ths
}
205 29929e34 ths
#endif /* CONFIG_USER_ONLY */
206 29929e34 ths
207 33d68b5f ths
int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
208 33d68b5f ths
{
209 33d68b5f ths
    if (!def)
210 51b2772f ths
        def = env->cpu_model;
211 51b2772f ths
    if (!def)
212 33d68b5f ths
        cpu_abort(env, "Unable to find MIPS CPU definition\n");
213 51b2772f ths
    env->cpu_model = def;
214 33d68b5f ths
    env->CP0_PRid = def->CP0_PRid;
215 33d68b5f ths
    env->CP0_Config0 = def->CP0_Config0;
216 51b2772f ths
#ifdef TARGET_WORDS_BIGENDIAN
217 51b2772f ths
    env->CP0_Config0 |= (1 << CP0C0_BE);
218 3953d786 ths
#endif
219 33d68b5f ths
    env->CP0_Config1 = def->CP0_Config1;
220 3953d786 ths
    env->CP0_Config2 = def->CP0_Config2;
221 3953d786 ths
    env->CP0_Config3 = def->CP0_Config3;
222 34ee2ede ths
    env->CP0_Config6 = def->CP0_Config6;
223 34ee2ede ths
    env->CP0_Config7 = def->CP0_Config7;
224 2f644545 ths
    env->SYNCI_Step = def->SYNCI_Step;
225 2f644545 ths
    env->CCRes = def->CCRes;
226 5a5012ec ths
    env->Status_rw_bitmask = def->Status_rw_bitmask;
227 3953d786 ths
    env->fcr0 = def->CP1_fcr0;
228 29929e34 ths
#ifndef CONFIG_USER_ONLY
229 29929e34 ths
    switch ((env->CP0_Config0 >> CP0C0_MT) & 3) {
230 29929e34 ths
        case 0:
231 29929e34 ths
            no_mmu_init(env, def);
232 29929e34 ths
            break;
233 29929e34 ths
        case 1:
234 29929e34 ths
            r4k_mmu_init(env, def);
235 29929e34 ths
            break;
236 29929e34 ths
        case 3:
237 29929e34 ths
            fixed_mmu_init(env, def);
238 29929e34 ths
            break;
239 29929e34 ths
        default:
240 29929e34 ths
            /* Older CPUs like the R3000 may need nonstandard handling here. */
241 29929e34 ths
            cpu_abort(env, "MMU type not supported\n");
242 29929e34 ths
    }
243 fcb4a419 ths
    env->CP0_Random = env->nb_tlb - 1;
244 fcb4a419 ths
    env->tlb_in_use = env->nb_tlb;
245 29929e34 ths
#endif /* CONFIG_USER_ONLY */
246 33d68b5f ths
    return 0;
247 33d68b5f ths
}