Statistics
| Branch: | Revision:

root / target-mips / translate_init.c @ 4e9f8537

History | View | Annotate | Download (16.6 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 ae5d8053 ths
/* Have config2, no coprocessor2 attached, no MDMX support attached,
32 3953d786 ths
   no performance counters, watch registers present,
33 3953d786 ths
   no code compression, EJTAG present, no FPU */
34 3953d786 ths
#define MIPS_CONFIG1                                              \
35 fcb4a419 ths
((1 << CP0C1_M) |                                                 \
36 3953d786 ths
 (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) |            \
37 3953d786 ths
 (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) |            \
38 3953d786 ths
 (0 << CP0C1_FP))
39 3953d786 ths
40 3953d786 ths
/* Have config3, no tertiary/secondary caches implemented */
41 3953d786 ths
#define MIPS_CONFIG2                                              \
42 3953d786 ths
((1 << CP0C2_M))
43 3953d786 ths
44 3953d786 ths
/* No config4, no DSP ASE, no large physaddr,
45 3953d786 ths
   no external interrupt controller, no vectored interupts,
46 ead9360e ths
   no 1kb pages, no SmartMIPS ASE, no trace logic */
47 3953d786 ths
#define MIPS_CONFIG3                                              \
48 3953d786 ths
((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) |          \
49 3953d786 ths
 (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) |        \
50 ead9360e ths
 (0 << CP0C3_SM) | (0 << CP0C3_TL))
51 3953d786 ths
52 3953d786 ths
/* Define a implementation number of 1.
53 3953d786 ths
   Define a major version 1, minor version 0. */
54 5a5012ec ths
#define MIPS_FCR0 ((0 << FCR0_S) | (0x1 << FCR0_PRID) | (0x10 << FCR0_REV))
55 3953d786 ths
56 3953d786 ths
57 33d68b5f ths
struct mips_def_t {
58 33d68b5f ths
    const unsigned char *name;
59 33d68b5f ths
    int32_t CP0_PRid;
60 33d68b5f ths
    int32_t CP0_Config0;
61 33d68b5f ths
    int32_t CP0_Config1;
62 3953d786 ths
    int32_t CP0_Config2;
63 3953d786 ths
    int32_t CP0_Config3;
64 34ee2ede ths
    int32_t CP0_Config6;
65 34ee2ede ths
    int32_t CP0_Config7;
66 2f644545 ths
    int32_t SYNCI_Step;
67 2f644545 ths
    int32_t CCRes;
68 ead9360e ths
    int32_t CP0_Status_rw_bitmask;
69 ead9360e ths
    int32_t CP0_TCStatus_rw_bitmask;
70 ead9360e ths
    int32_t CP0_SRSCtl;
71 3953d786 ths
    int32_t CP1_fcr0;
72 e034e2c3 ths
    int32_t SEGBITS;
73 ead9360e ths
    int32_t CP0_SRSConf0_rw_bitmask;
74 ead9360e ths
    int32_t CP0_SRSConf0;
75 ead9360e ths
    int32_t CP0_SRSConf1_rw_bitmask;
76 ead9360e ths
    int32_t CP0_SRSConf1;
77 ead9360e ths
    int32_t CP0_SRSConf2_rw_bitmask;
78 ead9360e ths
    int32_t CP0_SRSConf2;
79 ead9360e ths
    int32_t CP0_SRSConf3_rw_bitmask;
80 ead9360e ths
    int32_t CP0_SRSConf3;
81 ead9360e ths
    int32_t CP0_SRSConf4_rw_bitmask;
82 ead9360e ths
    int32_t CP0_SRSConf4;
83 e189e748 ths
    int insn_flags;
84 33d68b5f ths
};
85 33d68b5f ths
86 33d68b5f ths
/*****************************************************************************/
87 33d68b5f ths
/* MIPS CPU definitions */
88 33d68b5f ths
static mips_def_t mips_defs[] =
89 33d68b5f ths
{
90 33d68b5f ths
    {
91 33d68b5f ths
        .name = "4Kc",
92 33d68b5f ths
        .CP0_PRid = 0x00018000,
93 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0,
94 ae5d8053 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
95 ae5d8053 ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
96 ae5d8053 ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
97 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
98 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
99 2f644545 ths
        .SYNCI_Step = 32,
100 2f644545 ths
        .CCRes = 2,
101 ead9360e ths
        .CP0_Status_rw_bitmask = 0x1278FF17,
102 e189e748 ths
        .insn_flags = CPU_MIPS32 | ASE_MIPS16,
103 33d68b5f ths
    },
104 33d68b5f ths
    {
105 34ee2ede ths
        .name = "4KEcR1",
106 33d68b5f ths
        .CP0_PRid = 0x00018400,
107 34ee2ede ths
        .CP0_Config0 = MIPS_CONFIG0,
108 ae5d8053 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
109 ae5d8053 ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
110 ae5d8053 ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
111 34ee2ede ths
        .CP0_Config2 = MIPS_CONFIG2,
112 34ee2ede ths
        .CP0_Config3 = MIPS_CONFIG3,
113 2f644545 ths
        .SYNCI_Step = 32,
114 2f644545 ths
        .CCRes = 2,
115 ead9360e ths
        .CP0_Status_rw_bitmask = 0x1278FF17,
116 e189e748 ths
        .insn_flags = CPU_MIPS32 | ASE_MIPS16,
117 34ee2ede ths
    },
118 34ee2ede ths
    {
119 34ee2ede ths
        .name = "4KEc",
120 34ee2ede ths
        .CP0_PRid = 0x00019000,
121 34ee2ede ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
122 ae5d8053 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
123 ae5d8053 ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
124 ae5d8053 ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
125 34ee2ede ths
        .CP0_Config2 = MIPS_CONFIG2,
126 ead9360e ths
        .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
127 2f644545 ths
        .SYNCI_Step = 32,
128 2f644545 ths
        .CCRes = 2,
129 ead9360e ths
        .CP0_Status_rw_bitmask = 0x1278FF17,
130 e189e748 ths
        .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
131 34ee2ede ths
    },
132 34ee2ede ths
    {
133 34ee2ede ths
        .name = "24Kc",
134 34ee2ede ths
        .CP0_PRid = 0x00019300,
135 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
136 ae5d8053 ths
        .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
137 ae5d8053 ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
138 ae5d8053 ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
139 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
140 ead9360e ths
        .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
141 2f644545 ths
        .SYNCI_Step = 32,
142 2f644545 ths
        .CCRes = 2,
143 ead9360e ths
        /* No DSP implemented. */
144 671880e6 ths
        .CP0_Status_rw_bitmask = 0x1278FF1F,
145 e189e748 ths
        .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
146 33d68b5f ths
    },
147 33d68b5f ths
    {
148 33d68b5f ths
        .name = "24Kf",
149 33d68b5f ths
        .CP0_PRid = 0x00019300,
150 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
151 ae5d8053 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
152 ae5d8053 ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
153 ae5d8053 ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
154 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
155 ead9360e ths
        .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
156 2f644545 ths
        .SYNCI_Step = 32,
157 2f644545 ths
        .CCRes = 2,
158 ead9360e ths
        /* No DSP implemented. */
159 671880e6 ths
        .CP0_Status_rw_bitmask = 0x3678FF1F,
160 5a5012ec ths
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
161 5a5012ec ths
                    (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
162 e189e748 ths
        .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
163 33d68b5f ths
    },
164 ead9360e ths
    {
165 ead9360e ths
        .name = "34Kf",
166 ead9360e ths
        .CP0_PRid = 0x00019500,
167 ead9360e ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
168 ead9360e ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
169 ead9360e ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
170 ead9360e ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
171 ead9360e ths
        .CP0_Config2 = MIPS_CONFIG2,
172 ead9360e ths
        .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
173 ead9360e ths
        .SYNCI_Step = 32,
174 ead9360e ths
        .CCRes = 2,
175 ead9360e ths
        /* No DSP implemented. */
176 671880e6 ths
        .CP0_Status_rw_bitmask = 0x3678FF1F,
177 ead9360e ths
        /* No DSP implemented. */
178 ead9360e ths
        .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) |
179 ead9360e ths
                    (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) |
180 ead9360e ths
                    (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) |
181 ead9360e ths
                    (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) |
182 ead9360e ths
                    (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) |
183 ead9360e ths
                    (0xff << CP0TCSt_TASID),
184 ead9360e ths
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
185 ead9360e ths
                    (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID),
186 ead9360e ths
        .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS),
187 ead9360e ths
        .CP0_SRSConf0_rw_bitmask = 0x3fffffff,
188 ead9360e ths
        .CP0_SRSConf0 = (1 << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) |
189 ead9360e ths
                    (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1),
190 ead9360e ths
        .CP0_SRSConf1_rw_bitmask = 0x3fffffff,
191 ead9360e ths
        .CP0_SRSConf1 = (1 << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) |
192 ead9360e ths
                    (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4),
193 ead9360e ths
        .CP0_SRSConf2_rw_bitmask = 0x3fffffff,
194 ead9360e ths
        .CP0_SRSConf2 = (1 << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) |
195 ead9360e ths
                    (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7),
196 ead9360e ths
        .CP0_SRSConf3_rw_bitmask = 0x3fffffff,
197 ead9360e ths
        .CP0_SRSConf3 = (1 << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) |
198 ead9360e ths
                    (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10),
199 ead9360e ths
        .CP0_SRSConf4_rw_bitmask = 0x3fffffff,
200 ead9360e ths
        .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
201 ead9360e ths
                    (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
202 e189e748 ths
        .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
203 ead9360e ths
    },
204 540635ba ths
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
205 33d68b5f ths
    {
206 33d68b5f ths
        .name = "R4000",
207 33d68b5f ths
        .CP0_PRid = 0x00000400,
208 33d68b5f ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
209 ae5d8053 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) |
210 ae5d8053 ths
                    (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
211 ae5d8053 ths
                    (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
212 3953d786 ths
        .CP0_Config2 = MIPS_CONFIG2,
213 3953d786 ths
        .CP0_Config3 = MIPS_CONFIG3,
214 2f644545 ths
        .SYNCI_Step = 16,
215 2f644545 ths
        .CCRes = 2,
216 ead9360e ths
        .CP0_Status_rw_bitmask = 0x3678FFFF,
217 1e3d0552 ths
        /* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
218 c9c1a064 ths
        .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
219 e034e2c3 ths
        .SEGBITS = 40,
220 e189e748 ths
        .insn_flags = CPU_MIPS3,
221 c9c1a064 ths
    },
222 c9c1a064 ths
    {
223 c9c1a064 ths
        .name = "5Kc",
224 c9c1a064 ths
        .CP0_PRid = 0x00018100,
225 c9c1a064 ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
226 c9c1a064 ths
        .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) |
227 c9c1a064 ths
                    (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
228 c9c1a064 ths
                    (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
229 c9c1a064 ths
                    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
230 c9c1a064 ths
        .CP0_Config2 = MIPS_CONFIG2,
231 c9c1a064 ths
        .CP0_Config3 = MIPS_CONFIG3,
232 c9c1a064 ths
        .SYNCI_Step = 32,
233 c9c1a064 ths
        .CCRes = 2,
234 ead9360e ths
        .CP0_Status_rw_bitmask = 0x32F8FFFF,
235 e034e2c3 ths
        .SEGBITS = 42,
236 e189e748 ths
        .insn_flags = CPU_MIPS64,
237 c9c1a064 ths
    },
238 c9c1a064 ths
    {
239 c9c1a064 ths
        .name = "5Kf",
240 c9c1a064 ths
        .CP0_PRid = 0x00018100,
241 c9c1a064 ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
242 c9c1a064 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
243 c9c1a064 ths
                    (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
244 c9c1a064 ths
                    (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
245 c9c1a064 ths
                    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
246 c9c1a064 ths
        .CP0_Config2 = MIPS_CONFIG2,
247 c9c1a064 ths
        .CP0_Config3 = MIPS_CONFIG3,
248 c9c1a064 ths
        .SYNCI_Step = 32,
249 c9c1a064 ths
        .CCRes = 2,
250 ead9360e ths
        .CP0_Status_rw_bitmask = 0x36F8FFFF,
251 1e3d0552 ths
        /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
252 c9c1a064 ths
        .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
253 c9c1a064 ths
                    (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
254 e034e2c3 ths
        .SEGBITS = 42,
255 e189e748 ths
        .insn_flags = CPU_MIPS64,
256 c9c1a064 ths
    },
257 c9c1a064 ths
    {
258 c9c1a064 ths
        .name = "20Kc",
259 bd04c6fe ths
        /* We emulate a later version of the 20Kc, earlier ones had a broken
260 bd04c6fe ths
           WAIT instruction. */
261 bd04c6fe ths
        .CP0_PRid = 0x000182a0,
262 c9c1a064 ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | (1 << CP0C0_VI),
263 c9c1a064 ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) |
264 c9c1a064 ths
                    (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
265 c9c1a064 ths
                    (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
266 c9c1a064 ths
                    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
267 c9c1a064 ths
        .CP0_Config2 = MIPS_CONFIG2,
268 c9c1a064 ths
        .CP0_Config3 = MIPS_CONFIG3,
269 c9c1a064 ths
        .SYNCI_Step = 32,
270 c9c1a064 ths
        .CCRes = 2,
271 ead9360e ths
        .CP0_Status_rw_bitmask = 0x36FBFFFF,
272 1e3d0552 ths
        /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
273 c9c1a064 ths
        .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
274 5a5012ec ths
                    (1 << FCR0_D) | (1 << FCR0_S) |
275 c9c1a064 ths
                    (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
276 e034e2c3 ths
        .SEGBITS = 40,
277 e189e748 ths
        .insn_flags = CPU_MIPS64 | ASE_MIPS3D,
278 33d68b5f ths
    },
279 33d68b5f ths
#endif
280 33d68b5f ths
};
281 33d68b5f ths
282 33d68b5f ths
int mips_find_by_name (const unsigned char *name, mips_def_t **def)
283 33d68b5f ths
{
284 33d68b5f ths
    int i, ret;
285 33d68b5f ths
286 33d68b5f ths
    ret = -1;
287 33d68b5f ths
    *def = NULL;
288 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
289 33d68b5f ths
        if (strcasecmp(name, mips_defs[i].name) == 0) {
290 33d68b5f ths
            *def = &mips_defs[i];
291 33d68b5f ths
            ret = 0;
292 33d68b5f ths
            break;
293 33d68b5f ths
        }
294 33d68b5f ths
    }
295 33d68b5f ths
296 33d68b5f ths
    return ret;
297 33d68b5f ths
}
298 33d68b5f ths
299 33d68b5f ths
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
300 33d68b5f ths
{
301 33d68b5f ths
    int i;
302 33d68b5f ths
303 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
304 33d68b5f ths
        (*cpu_fprintf)(f, "MIPS '%s'\n",
305 33d68b5f ths
                       mips_defs[i].name);
306 33d68b5f ths
    }
307 33d68b5f ths
}
308 33d68b5f ths
309 29929e34 ths
#ifndef CONFIG_USER_ONLY
310 29929e34 ths
static void no_mmu_init (CPUMIPSState *env, mips_def_t *def)
311 29929e34 ths
{
312 ead9360e ths
    env->tlb->nb_tlb = 1;
313 ead9360e ths
    env->tlb->map_address = &no_mmu_map_address;
314 29929e34 ths
}
315 29929e34 ths
316 29929e34 ths
static void fixed_mmu_init (CPUMIPSState *env, mips_def_t *def)
317 29929e34 ths
{
318 ead9360e ths
    env->tlb->nb_tlb = 1;
319 ead9360e ths
    env->tlb->map_address = &fixed_mmu_map_address;
320 29929e34 ths
}
321 29929e34 ths
322 29929e34 ths
static void r4k_mmu_init (CPUMIPSState *env, mips_def_t *def)
323 29929e34 ths
{
324 ead9360e ths
    env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
325 ead9360e ths
    env->tlb->map_address = &r4k_map_address;
326 ead9360e ths
    env->tlb->do_tlbwi = r4k_do_tlbwi;
327 ead9360e ths
    env->tlb->do_tlbwr = r4k_do_tlbwr;
328 ead9360e ths
    env->tlb->do_tlbp = r4k_do_tlbp;
329 ead9360e ths
    env->tlb->do_tlbr = r4k_do_tlbr;
330 ead9360e ths
}
331 ead9360e ths
332 ead9360e ths
static void mmu_init (CPUMIPSState *env, mips_def_t *def)
333 ead9360e ths
{
334 ead9360e ths
    env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext));
335 ead9360e ths
336 ead9360e ths
    /* There are more full-featured MMU variants in older MIPS CPUs,
337 ead9360e ths
       R3000, R6000 and R8000 come to mind. If we ever support them,
338 ead9360e ths
       this check will need to look up a different place than those
339 ead9360e ths
       newfangled config registers. */
340 ead9360e ths
    switch ((env->CP0_Config0 >> CP0C0_MT) & 3) {
341 ead9360e ths
        case 0:
342 ead9360e ths
            no_mmu_init(env, def);
343 ead9360e ths
            break;
344 ead9360e ths
        case 1:
345 ead9360e ths
            r4k_mmu_init(env, def);
346 ead9360e ths
            break;
347 ead9360e ths
        case 3:
348 ead9360e ths
            fixed_mmu_init(env, def);
349 ead9360e ths
            break;
350 ead9360e ths
        default:
351 ead9360e ths
            cpu_abort(env, "MMU type not supported\n");
352 ead9360e ths
    }
353 ead9360e ths
    env->CP0_Random = env->tlb->nb_tlb - 1;
354 ead9360e ths
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
355 29929e34 ths
}
356 29929e34 ths
#endif /* CONFIG_USER_ONLY */
357 29929e34 ths
358 ead9360e ths
static void fpu_init (CPUMIPSState *env, mips_def_t *def)
359 ead9360e ths
{
360 ead9360e ths
    env->fpu = qemu_mallocz(sizeof(CPUMIPSFPUContext));
361 ead9360e ths
362 ead9360e ths
    env->fpu->fcr0 = def->CP1_fcr0;
363 ead9360e ths
#ifdef CONFIG_USER_ONLY
364 ead9360e ths
    if (env->CP0_Config1 & (1 << CP0C1_FP))
365 ead9360e ths
        env->hflags |= MIPS_HFLAG_FPU;
366 ead9360e ths
    if (env->fpu->fcr0 & (1 << FCR0_F64))
367 ead9360e ths
        env->hflags |= MIPS_HFLAG_F64;
368 ead9360e ths
#endif
369 ead9360e ths
}
370 ead9360e ths
371 ead9360e ths
static void mvp_init (CPUMIPSState *env, mips_def_t *def)
372 ead9360e ths
{
373 ead9360e ths
    env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext));
374 ead9360e ths
375 ead9360e ths
    /* MVPConf1 implemented, TLB sharable, no gating storage support,
376 ead9360e ths
       programmable cache partitioning implemented, number of allocatable
377 ead9360e ths
       and sharable TLB entries, MVP has allocatable TCs, 2 VPEs
378 ead9360e ths
       implemented, 5 TCs implemented. */
379 ead9360e ths
    env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) |
380 ead9360e ths
                             (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) |
381 2337fdc2 ths
#ifndef CONFIG_USER_ONLY
382 2337fdc2 ths
                             /* Usermode has no TLB support */
383 ead9360e ths
                             (env->tlb->nb_tlb << CP0MVPC0_PTLBE) |
384 2337fdc2 ths
#endif
385 ead9360e ths
// TODO: actually do 2 VPEs.
386 ead9360e ths
//                             (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
387 ead9360e ths
//                             (0x04 << CP0MVPC0_PTC);
388 ead9360e ths
                             (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
389 ead9360e ths
                             (0x04 << CP0MVPC0_PTC);
390 ead9360e ths
    /* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
391 ead9360e ths
       no UDI implemented, no CP2 implemented, 1 CP1 implemented. */
392 ead9360e ths
    env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) |
393 ead9360e ths
                             (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
394 ead9360e ths
                             (0x1 << CP0MVPC1_PCP1);
395 ead9360e ths
}
396 ead9360e ths
397 33d68b5f ths
int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
398 33d68b5f ths
{
399 33d68b5f ths
    if (!def)
400 51b2772f ths
        def = env->cpu_model;
401 51b2772f ths
    if (!def)
402 33d68b5f ths
        cpu_abort(env, "Unable to find MIPS CPU definition\n");
403 51b2772f ths
    env->cpu_model = def;
404 33d68b5f ths
    env->CP0_PRid = def->CP0_PRid;
405 33d68b5f ths
    env->CP0_Config0 = def->CP0_Config0;
406 51b2772f ths
#ifdef TARGET_WORDS_BIGENDIAN
407 51b2772f ths
    env->CP0_Config0 |= (1 << CP0C0_BE);
408 3953d786 ths
#endif
409 33d68b5f ths
    env->CP0_Config1 = def->CP0_Config1;
410 3953d786 ths
    env->CP0_Config2 = def->CP0_Config2;
411 3953d786 ths
    env->CP0_Config3 = def->CP0_Config3;
412 34ee2ede ths
    env->CP0_Config6 = def->CP0_Config6;
413 34ee2ede ths
    env->CP0_Config7 = def->CP0_Config7;
414 2f644545 ths
    env->SYNCI_Step = def->SYNCI_Step;
415 2f644545 ths
    env->CCRes = def->CCRes;
416 ead9360e ths
    env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask;
417 ead9360e ths
    env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
418 ead9360e ths
    env->CP0_SRSCtl = def->CP0_SRSCtl;
419 540635ba ths
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
420 e189e748 ths
    if (def->insn_flags & ISA_MIPS3)
421 3ddf0b5c ths
    {
422 3ddf0b5c ths
        env->hflags |= MIPS_HFLAG_64;
423 3ddf0b5c ths
        env->SEGBITS = def->SEGBITS;
424 3ddf0b5c ths
        env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
425 3ddf0b5c ths
    } else {
426 3ddf0b5c ths
        env->SEGBITS = 32;
427 3ddf0b5c ths
        env->SEGMask = 0xFFFFFFFF;
428 3ddf0b5c ths
    }
429 e034e2c3 ths
#endif
430 ead9360e ths
    env->CP0_SRSConf0_rw_bitmask = def->CP0_SRSConf0_rw_bitmask;
431 ead9360e ths
    env->CP0_SRSConf0 = def->CP0_SRSConf0;
432 ead9360e ths
    env->CP0_SRSConf1_rw_bitmask = def->CP0_SRSConf1_rw_bitmask;
433 ead9360e ths
    env->CP0_SRSConf1 = def->CP0_SRSConf1;
434 ead9360e ths
    env->CP0_SRSConf2_rw_bitmask = def->CP0_SRSConf2_rw_bitmask;
435 ead9360e ths
    env->CP0_SRSConf2 = def->CP0_SRSConf2;
436 ead9360e ths
    env->CP0_SRSConf3_rw_bitmask = def->CP0_SRSConf3_rw_bitmask;
437 ead9360e ths
    env->CP0_SRSConf3 = def->CP0_SRSConf3;
438 ead9360e ths
    env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask;
439 ead9360e ths
    env->CP0_SRSConf4 = def->CP0_SRSConf4;
440 e189e748 ths
    env->insn_flags = def->insn_flags;
441 ead9360e ths
442 ead9360e ths
#ifndef CONFIG_USER_ONLY
443 ead9360e ths
    mmu_init(env, def);
444 ead9360e ths
#endif
445 ead9360e ths
    fpu_init(env, def);
446 ead9360e ths
    mvp_init(env, def);
447 33d68b5f ths
    return 0;
448 33d68b5f ths
}