Statistics
| Branch: | Revision:

root / target-mips / translate_init.c @ 273af660

History | View | Annotate | Download (17.5 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 7385ac0b ths
        .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT,
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 d2123ead ths
    {
280 d2123ead ths
        /* A generic CPU providing MIPS64 Release 2 features.
281 d2123ead ths
           FIXME: Eventually this should be replaced by a real CPU model. */
282 d2123ead ths
        .name = "MIPS64R2-generic",
283 d2123ead ths
        .CP0_PRid = 0x00000000,
284 d2123ead ths
        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | (0x1 << CP0C0_AR),
285 d2123ead ths
        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
286 d2123ead ths
                    (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
287 d2123ead ths
                    (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
288 d2123ead ths
                    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
289 d2123ead ths
        .CP0_Config2 = MIPS_CONFIG2,
290 d2123ead ths
        .CP0_Config3 = MIPS_CONFIG3,
291 d2123ead ths
        .SYNCI_Step = 32,
292 d2123ead ths
        .CCRes = 2,
293 d2123ead ths
        .CP0_Status_rw_bitmask = 0x36FBFFFF,
294 d2123ead ths
        .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) | (1 << FCR0_L) |
295 d2123ead ths
                    (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
296 d2123ead ths
                    (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
297 d2123ead ths
        .SEGBITS = 40,
298 d2123ead ths
        .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
299 d2123ead ths
    },
300 33d68b5f ths
#endif
301 33d68b5f ths
};
302 33d68b5f ths
303 33d68b5f ths
int mips_find_by_name (const unsigned char *name, mips_def_t **def)
304 33d68b5f ths
{
305 33d68b5f ths
    int i, ret;
306 33d68b5f ths
307 33d68b5f ths
    ret = -1;
308 33d68b5f ths
    *def = NULL;
309 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
310 33d68b5f ths
        if (strcasecmp(name, mips_defs[i].name) == 0) {
311 33d68b5f ths
            *def = &mips_defs[i];
312 33d68b5f ths
            ret = 0;
313 33d68b5f ths
            break;
314 33d68b5f ths
        }
315 33d68b5f ths
    }
316 33d68b5f ths
317 33d68b5f ths
    return ret;
318 33d68b5f ths
}
319 33d68b5f ths
320 33d68b5f ths
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
321 33d68b5f ths
{
322 33d68b5f ths
    int i;
323 33d68b5f ths
324 33d68b5f ths
    for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); i++) {
325 33d68b5f ths
        (*cpu_fprintf)(f, "MIPS '%s'\n",
326 33d68b5f ths
                       mips_defs[i].name);
327 33d68b5f ths
    }
328 33d68b5f ths
}
329 33d68b5f ths
330 29929e34 ths
#ifndef CONFIG_USER_ONLY
331 29929e34 ths
static void no_mmu_init (CPUMIPSState *env, mips_def_t *def)
332 29929e34 ths
{
333 ead9360e ths
    env->tlb->nb_tlb = 1;
334 ead9360e ths
    env->tlb->map_address = &no_mmu_map_address;
335 29929e34 ths
}
336 29929e34 ths
337 29929e34 ths
static void fixed_mmu_init (CPUMIPSState *env, mips_def_t *def)
338 29929e34 ths
{
339 ead9360e ths
    env->tlb->nb_tlb = 1;
340 ead9360e ths
    env->tlb->map_address = &fixed_mmu_map_address;
341 29929e34 ths
}
342 29929e34 ths
343 29929e34 ths
static void r4k_mmu_init (CPUMIPSState *env, mips_def_t *def)
344 29929e34 ths
{
345 ead9360e ths
    env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
346 ead9360e ths
    env->tlb->map_address = &r4k_map_address;
347 ead9360e ths
    env->tlb->do_tlbwi = r4k_do_tlbwi;
348 ead9360e ths
    env->tlb->do_tlbwr = r4k_do_tlbwr;
349 ead9360e ths
    env->tlb->do_tlbp = r4k_do_tlbp;
350 ead9360e ths
    env->tlb->do_tlbr = r4k_do_tlbr;
351 ead9360e ths
}
352 ead9360e ths
353 ead9360e ths
static void mmu_init (CPUMIPSState *env, mips_def_t *def)
354 ead9360e ths
{
355 ead9360e ths
    env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext));
356 ead9360e ths
357 ead9360e ths
    /* There are more full-featured MMU variants in older MIPS CPUs,
358 ead9360e ths
       R3000, R6000 and R8000 come to mind. If we ever support them,
359 ead9360e ths
       this check will need to look up a different place than those
360 ead9360e ths
       newfangled config registers. */
361 ead9360e ths
    switch ((env->CP0_Config0 >> CP0C0_MT) & 3) {
362 ead9360e ths
        case 0:
363 ead9360e ths
            no_mmu_init(env, def);
364 ead9360e ths
            break;
365 ead9360e ths
        case 1:
366 ead9360e ths
            r4k_mmu_init(env, def);
367 ead9360e ths
            break;
368 ead9360e ths
        case 3:
369 ead9360e ths
            fixed_mmu_init(env, def);
370 ead9360e ths
            break;
371 ead9360e ths
        default:
372 ead9360e ths
            cpu_abort(env, "MMU type not supported\n");
373 ead9360e ths
    }
374 ead9360e ths
    env->CP0_Random = env->tlb->nb_tlb - 1;
375 ead9360e ths
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
376 29929e34 ths
}
377 29929e34 ths
#endif /* CONFIG_USER_ONLY */
378 29929e34 ths
379 ead9360e ths
static void fpu_init (CPUMIPSState *env, mips_def_t *def)
380 ead9360e ths
{
381 ead9360e ths
    env->fpu = qemu_mallocz(sizeof(CPUMIPSFPUContext));
382 ead9360e ths
383 ead9360e ths
    env->fpu->fcr0 = def->CP1_fcr0;
384 ead9360e ths
#ifdef CONFIG_USER_ONLY
385 ead9360e ths
    if (env->CP0_Config1 & (1 << CP0C1_FP))
386 ead9360e ths
        env->hflags |= MIPS_HFLAG_FPU;
387 ead9360e ths
    if (env->fpu->fcr0 & (1 << FCR0_F64))
388 ead9360e ths
        env->hflags |= MIPS_HFLAG_F64;
389 ead9360e ths
#endif
390 ead9360e ths
}
391 ead9360e ths
392 ead9360e ths
static void mvp_init (CPUMIPSState *env, mips_def_t *def)
393 ead9360e ths
{
394 ead9360e ths
    env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext));
395 ead9360e ths
396 ead9360e ths
    /* MVPConf1 implemented, TLB sharable, no gating storage support,
397 ead9360e ths
       programmable cache partitioning implemented, number of allocatable
398 ead9360e ths
       and sharable TLB entries, MVP has allocatable TCs, 2 VPEs
399 ead9360e ths
       implemented, 5 TCs implemented. */
400 ead9360e ths
    env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) |
401 ead9360e ths
                             (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) |
402 2337fdc2 ths
#ifndef CONFIG_USER_ONLY
403 2337fdc2 ths
                             /* Usermode has no TLB support */
404 ead9360e ths
                             (env->tlb->nb_tlb << CP0MVPC0_PTLBE) |
405 2337fdc2 ths
#endif
406 ead9360e ths
// TODO: actually do 2 VPEs.
407 ead9360e ths
//                             (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
408 ead9360e ths
//                             (0x04 << CP0MVPC0_PTC);
409 ead9360e ths
                             (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
410 ead9360e ths
                             (0x04 << CP0MVPC0_PTC);
411 ead9360e ths
    /* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
412 ead9360e ths
       no UDI implemented, no CP2 implemented, 1 CP1 implemented. */
413 ead9360e ths
    env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) |
414 ead9360e ths
                             (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
415 ead9360e ths
                             (0x1 << CP0MVPC1_PCP1);
416 ead9360e ths
}
417 ead9360e ths
418 33d68b5f ths
int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
419 33d68b5f ths
{
420 33d68b5f ths
    if (!def)
421 51b2772f ths
        def = env->cpu_model;
422 51b2772f ths
    if (!def)
423 33d68b5f ths
        cpu_abort(env, "Unable to find MIPS CPU definition\n");
424 51b2772f ths
    env->cpu_model = def;
425 33d68b5f ths
    env->CP0_PRid = def->CP0_PRid;
426 33d68b5f ths
    env->CP0_Config0 = def->CP0_Config0;
427 51b2772f ths
#ifdef TARGET_WORDS_BIGENDIAN
428 51b2772f ths
    env->CP0_Config0 |= (1 << CP0C0_BE);
429 3953d786 ths
#endif
430 33d68b5f ths
    env->CP0_Config1 = def->CP0_Config1;
431 3953d786 ths
    env->CP0_Config2 = def->CP0_Config2;
432 3953d786 ths
    env->CP0_Config3 = def->CP0_Config3;
433 34ee2ede ths
    env->CP0_Config6 = def->CP0_Config6;
434 34ee2ede ths
    env->CP0_Config7 = def->CP0_Config7;
435 2f644545 ths
    env->SYNCI_Step = def->SYNCI_Step;
436 2f644545 ths
    env->CCRes = def->CCRes;
437 ead9360e ths
    env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask;
438 ead9360e ths
    env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
439 ead9360e ths
    env->CP0_SRSCtl = def->CP0_SRSCtl;
440 540635ba ths
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
441 e189e748 ths
    if (def->insn_flags & ISA_MIPS3)
442 3ddf0b5c ths
    {
443 3ddf0b5c ths
        env->hflags |= MIPS_HFLAG_64;
444 3ddf0b5c ths
        env->SEGBITS = def->SEGBITS;
445 3ddf0b5c ths
        env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
446 3ddf0b5c ths
    } else {
447 3ddf0b5c ths
        env->SEGBITS = 32;
448 3ddf0b5c ths
        env->SEGMask = 0xFFFFFFFF;
449 3ddf0b5c ths
    }
450 e034e2c3 ths
#endif
451 ead9360e ths
    env->CP0_SRSConf0_rw_bitmask = def->CP0_SRSConf0_rw_bitmask;
452 ead9360e ths
    env->CP0_SRSConf0 = def->CP0_SRSConf0;
453 ead9360e ths
    env->CP0_SRSConf1_rw_bitmask = def->CP0_SRSConf1_rw_bitmask;
454 ead9360e ths
    env->CP0_SRSConf1 = def->CP0_SRSConf1;
455 ead9360e ths
    env->CP0_SRSConf2_rw_bitmask = def->CP0_SRSConf2_rw_bitmask;
456 ead9360e ths
    env->CP0_SRSConf2 = def->CP0_SRSConf2;
457 ead9360e ths
    env->CP0_SRSConf3_rw_bitmask = def->CP0_SRSConf3_rw_bitmask;
458 ead9360e ths
    env->CP0_SRSConf3 = def->CP0_SRSConf3;
459 ead9360e ths
    env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask;
460 ead9360e ths
    env->CP0_SRSConf4 = def->CP0_SRSConf4;
461 e189e748 ths
    env->insn_flags = def->insn_flags;
462 ead9360e ths
463 ead9360e ths
#ifndef CONFIG_USER_ONLY
464 ead9360e ths
    mmu_init(env, def);
465 ead9360e ths
#endif
466 ead9360e ths
    fpu_init(env, def);
467 ead9360e ths
    mvp_init(env, def);
468 33d68b5f ths
    return 0;
469 33d68b5f ths
}