]>
Commit | Line | Data |
---|---|---|
33d68b5f TS |
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 | |
8167ee88 | 18 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
33d68b5f TS |
19 | */ |
20 | ||
3953d786 TS |
21 | /* CPU / CPU family specific config register values. */ |
22 | ||
6d35524c | 23 | /* Have config1, uncached coherency */ |
3953d786 | 24 | #define MIPS_CONFIG0 \ |
6d35524c | 25 | ((1 << CP0C0_M) | (0x2 << CP0C0_K0)) |
3953d786 | 26 | |
ae5d8053 | 27 | /* Have config2, no coprocessor2 attached, no MDMX support attached, |
3953d786 TS |
28 | no performance counters, watch registers present, |
29 | no code compression, EJTAG present, no FPU */ | |
30 | #define MIPS_CONFIG1 \ | |
fcb4a419 | 31 | ((1 << CP0C1_M) | \ |
3953d786 TS |
32 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ |
33 | (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ | |
34 | (0 << CP0C1_FP)) | |
35 | ||
36 | /* Have config3, no tertiary/secondary caches implemented */ | |
37 | #define MIPS_CONFIG2 \ | |
38 | ((1 << CP0C2_M)) | |
39 | ||
6d35524c | 40 | /* No config4, no DSP ASE, no large physaddr (PABITS), |
3953d786 | 41 | no external interrupt controller, no vectored interupts, |
ead9360e | 42 | no 1kb pages, no SmartMIPS ASE, no trace logic */ |
3953d786 TS |
43 | #define MIPS_CONFIG3 \ |
44 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ | |
45 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ | |
ead9360e | 46 | (0 << CP0C3_SM) | (0 << CP0C3_TL)) |
3953d786 TS |
47 | |
48 | /* Define a implementation number of 1. | |
49 | Define a major version 1, minor version 0. */ | |
5a5012ec | 50 | #define MIPS_FCR0 ((0 << FCR0_S) | (0x1 << FCR0_PRID) | (0x10 << FCR0_REV)) |
3953d786 | 51 | |
6d35524c TS |
52 | /* MMU types, the first four entries have the same layout as the |
53 | CP0C0_MT field. */ | |
54 | enum mips_mmu_types { | |
55 | MMU_TYPE_NONE, | |
56 | MMU_TYPE_R4000, | |
57 | MMU_TYPE_RESERVED, | |
58 | MMU_TYPE_FMT, | |
59 | MMU_TYPE_R3000, | |
60 | MMU_TYPE_R6000, | |
61 | MMU_TYPE_R8000 | |
62 | }; | |
63 | ||
c227f099 | 64 | struct mips_def_t { |
50366fe9 | 65 | const char *name; |
33d68b5f TS |
66 | int32_t CP0_PRid; |
67 | int32_t CP0_Config0; | |
68 | int32_t CP0_Config1; | |
3953d786 TS |
69 | int32_t CP0_Config2; |
70 | int32_t CP0_Config3; | |
34ee2ede TS |
71 | int32_t CP0_Config6; |
72 | int32_t CP0_Config7; | |
2a6e32dd AJ |
73 | target_ulong CP0_LLAddr_rw_bitmask; |
74 | int CP0_LLAddr_shift; | |
2f644545 TS |
75 | int32_t SYNCI_Step; |
76 | int32_t CCRes; | |
ead9360e TS |
77 | int32_t CP0_Status_rw_bitmask; |
78 | int32_t CP0_TCStatus_rw_bitmask; | |
79 | int32_t CP0_SRSCtl; | |
3953d786 | 80 | int32_t CP1_fcr0; |
e034e2c3 | 81 | int32_t SEGBITS; |
6d35524c | 82 | int32_t PABITS; |
ead9360e TS |
83 | int32_t CP0_SRSConf0_rw_bitmask; |
84 | int32_t CP0_SRSConf0; | |
85 | int32_t CP0_SRSConf1_rw_bitmask; | |
86 | int32_t CP0_SRSConf1; | |
87 | int32_t CP0_SRSConf2_rw_bitmask; | |
88 | int32_t CP0_SRSConf2; | |
89 | int32_t CP0_SRSConf3_rw_bitmask; | |
90 | int32_t CP0_SRSConf3; | |
91 | int32_t CP0_SRSConf4_rw_bitmask; | |
92 | int32_t CP0_SRSConf4; | |
e189e748 | 93 | int insn_flags; |
6d35524c | 94 | enum mips_mmu_types mmu_type; |
33d68b5f TS |
95 | }; |
96 | ||
97 | /*****************************************************************************/ | |
98 | /* MIPS CPU definitions */ | |
c227f099 | 99 | static const mips_def_t mips_defs[] = |
33d68b5f | 100 | { |
33d68b5f TS |
101 | { |
102 | .name = "4Kc", | |
103 | .CP0_PRid = 0x00018000, | |
6d35524c | 104 | .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT), |
ae5d8053 | 105 | .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | |
6958549d | 106 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 | 107 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
ab3aee26 | 108 | (0 << CP0C1_CA), |
3953d786 TS |
109 | .CP0_Config2 = MIPS_CONFIG2, |
110 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
111 | .CP0_LLAddr_rw_bitmask = 0, |
112 | .CP0_LLAddr_shift = 4, | |
2f644545 TS |
113 | .SYNCI_Step = 32, |
114 | .CCRes = 2, | |
ead9360e | 115 | .CP0_Status_rw_bitmask = 0x1278FF17, |
6d35524c TS |
116 | .SEGBITS = 32, |
117 | .PABITS = 32, | |
73642f5b | 118 | .insn_flags = CPU_MIPS32, |
6d35524c | 119 | .mmu_type = MMU_TYPE_R4000, |
33d68b5f | 120 | }, |
8d162c2b TS |
121 | { |
122 | .name = "4Km", | |
123 | .CP0_PRid = 0x00018300, | |
124 | /* Config1 implemented, fixed mapping MMU, | |
125 | no virtual icache, uncached coherency. */ | |
6d35524c | 126 | .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT), |
8d162c2b | 127 | .CP0_Config1 = MIPS_CONFIG1 | |
6958549d | 128 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 NF |
129 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
130 | (1 << CP0C1_CA), | |
8d162c2b TS |
131 | .CP0_Config2 = MIPS_CONFIG2, |
132 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
133 | .CP0_LLAddr_rw_bitmask = 0, |
134 | .CP0_LLAddr_shift = 4, | |
8d162c2b TS |
135 | .SYNCI_Step = 32, |
136 | .CCRes = 2, | |
137 | .CP0_Status_rw_bitmask = 0x1258FF17, | |
6d35524c TS |
138 | .SEGBITS = 32, |
139 | .PABITS = 32, | |
8d162c2b | 140 | .insn_flags = CPU_MIPS32 | ASE_MIPS16, |
6d35524c | 141 | .mmu_type = MMU_TYPE_FMT, |
8d162c2b | 142 | }, |
33d68b5f | 143 | { |
34ee2ede | 144 | .name = "4KEcR1", |
33d68b5f | 145 | .CP0_PRid = 0x00018400, |
6d35524c | 146 | .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT), |
ae5d8053 | 147 | .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | |
6958549d | 148 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 | 149 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
ab3aee26 | 150 | (0 << CP0C1_CA), |
34ee2ede TS |
151 | .CP0_Config2 = MIPS_CONFIG2, |
152 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
153 | .CP0_LLAddr_rw_bitmask = 0, |
154 | .CP0_LLAddr_shift = 4, | |
2f644545 TS |
155 | .SYNCI_Step = 32, |
156 | .CCRes = 2, | |
ead9360e | 157 | .CP0_Status_rw_bitmask = 0x1278FF17, |
6d35524c TS |
158 | .SEGBITS = 32, |
159 | .PABITS = 32, | |
73642f5b | 160 | .insn_flags = CPU_MIPS32, |
6d35524c | 161 | .mmu_type = MMU_TYPE_R4000, |
34ee2ede | 162 | }, |
8d162c2b TS |
163 | { |
164 | .name = "4KEmR1", | |
165 | .CP0_PRid = 0x00018500, | |
6d35524c | 166 | .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT), |
8d162c2b | 167 | .CP0_Config1 = MIPS_CONFIG1 | |
6958549d | 168 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 NF |
169 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
170 | (1 << CP0C1_CA), | |
8d162c2b TS |
171 | .CP0_Config2 = MIPS_CONFIG2, |
172 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
173 | .CP0_LLAddr_rw_bitmask = 0, |
174 | .CP0_LLAddr_shift = 4, | |
8d162c2b TS |
175 | .SYNCI_Step = 32, |
176 | .CCRes = 2, | |
177 | .CP0_Status_rw_bitmask = 0x1258FF17, | |
6d35524c TS |
178 | .SEGBITS = 32, |
179 | .PABITS = 32, | |
8d162c2b | 180 | .insn_flags = CPU_MIPS32 | ASE_MIPS16, |
6d35524c | 181 | .mmu_type = MMU_TYPE_FMT, |
8d162c2b | 182 | }, |
34ee2ede TS |
183 | { |
184 | .name = "4KEc", | |
185 | .CP0_PRid = 0x00019000, | |
6d35524c TS |
186 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | |
187 | (MMU_TYPE_R4000 << CP0C0_MT), | |
ae5d8053 | 188 | .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | |
6958549d | 189 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 | 190 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
ab3aee26 | 191 | (0 << CP0C1_CA), |
34ee2ede | 192 | .CP0_Config2 = MIPS_CONFIG2, |
ead9360e | 193 | .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), |
2a6e32dd AJ |
194 | .CP0_LLAddr_rw_bitmask = 0, |
195 | .CP0_LLAddr_shift = 4, | |
2f644545 TS |
196 | .SYNCI_Step = 32, |
197 | .CCRes = 2, | |
ead9360e | 198 | .CP0_Status_rw_bitmask = 0x1278FF17, |
6d35524c TS |
199 | .SEGBITS = 32, |
200 | .PABITS = 32, | |
73642f5b | 201 | .insn_flags = CPU_MIPS32R2, |
6d35524c | 202 | .mmu_type = MMU_TYPE_R4000, |
34ee2ede | 203 | }, |
3e4587d5 TS |
204 | { |
205 | .name = "4KEm", | |
206 | .CP0_PRid = 0x00019100, | |
6d35524c | 207 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | |
6958549d | 208 | (MMU_TYPE_FMT << CP0C0_MT), |
3e4587d5 | 209 | .CP0_Config1 = MIPS_CONFIG1 | |
6958549d | 210 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 NF |
211 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
212 | (1 << CP0C1_CA), | |
3e4587d5 TS |
213 | .CP0_Config2 = MIPS_CONFIG2, |
214 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
215 | .CP0_LLAddr_rw_bitmask = 0, |
216 | .CP0_LLAddr_shift = 4, | |
3e4587d5 TS |
217 | .SYNCI_Step = 32, |
218 | .CCRes = 2, | |
219 | .CP0_Status_rw_bitmask = 0x1258FF17, | |
6d35524c TS |
220 | .SEGBITS = 32, |
221 | .PABITS = 32, | |
3e4587d5 | 222 | .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, |
6d35524c | 223 | .mmu_type = MMU_TYPE_FMT, |
3e4587d5 | 224 | }, |
34ee2ede TS |
225 | { |
226 | .name = "24Kc", | |
227 | .CP0_PRid = 0x00019300, | |
6d35524c | 228 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | |
6958549d | 229 | (MMU_TYPE_R4000 << CP0C0_MT), |
ae5d8053 | 230 | .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | |
6958549d | 231 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 NF |
232 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
233 | (1 << CP0C1_CA), | |
3953d786 | 234 | .CP0_Config2 = MIPS_CONFIG2, |
ead9360e | 235 | .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), |
2a6e32dd AJ |
236 | .CP0_LLAddr_rw_bitmask = 0, |
237 | .CP0_LLAddr_shift = 4, | |
2f644545 TS |
238 | .SYNCI_Step = 32, |
239 | .CCRes = 2, | |
ead9360e | 240 | /* No DSP implemented. */ |
671880e6 | 241 | .CP0_Status_rw_bitmask = 0x1278FF1F, |
6d35524c TS |
242 | .SEGBITS = 32, |
243 | .PABITS = 32, | |
3e4587d5 | 244 | .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, |
6d35524c | 245 | .mmu_type = MMU_TYPE_R4000, |
33d68b5f TS |
246 | }, |
247 | { | |
248 | .name = "24Kf", | |
249 | .CP0_PRid = 0x00019300, | |
6d35524c TS |
250 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | |
251 | (MMU_TYPE_R4000 << CP0C0_MT), | |
ae5d8053 | 252 | .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | |
6958549d | 253 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 NF |
254 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
255 | (1 << CP0C1_CA), | |
3953d786 | 256 | .CP0_Config2 = MIPS_CONFIG2, |
ead9360e | 257 | .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), |
2a6e32dd AJ |
258 | .CP0_LLAddr_rw_bitmask = 0, |
259 | .CP0_LLAddr_shift = 4, | |
2f644545 TS |
260 | .SYNCI_Step = 32, |
261 | .CCRes = 2, | |
ead9360e | 262 | /* No DSP implemented. */ |
671880e6 | 263 | .CP0_Status_rw_bitmask = 0x3678FF1F, |
5a5012ec TS |
264 | .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | |
265 | (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), | |
6d35524c TS |
266 | .SEGBITS = 32, |
267 | .PABITS = 32, | |
3e4587d5 | 268 | .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, |
6d35524c | 269 | .mmu_type = MMU_TYPE_R4000, |
33d68b5f | 270 | }, |
ead9360e TS |
271 | { |
272 | .name = "34Kf", | |
273 | .CP0_PRid = 0x00019500, | |
6d35524c | 274 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | |
6958549d | 275 | (MMU_TYPE_R4000 << CP0C0_MT), |
ead9360e | 276 | .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | |
6958549d | 277 | (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | |
d19954f4 NF |
278 | (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | |
279 | (1 << CP0C1_CA), | |
ead9360e TS |
280 | .CP0_Config2 = MIPS_CONFIG2, |
281 | .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT), | |
2a6e32dd AJ |
282 | .CP0_LLAddr_rw_bitmask = 0, |
283 | .CP0_LLAddr_shift = 0, | |
ead9360e TS |
284 | .SYNCI_Step = 32, |
285 | .CCRes = 2, | |
286 | /* No DSP implemented. */ | |
671880e6 | 287 | .CP0_Status_rw_bitmask = 0x3678FF1F, |
ead9360e TS |
288 | /* No DSP implemented. */ |
289 | .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) | | |
290 | (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) | | |
291 | (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) | | |
292 | (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) | | |
293 | (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) | | |
294 | (0xff << CP0TCSt_TASID), | |
295 | .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | | |
296 | (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID), | |
297 | .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS), | |
298 | .CP0_SRSConf0_rw_bitmask = 0x3fffffff, | |
299 | .CP0_SRSConf0 = (1 << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) | | |
300 | (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1), | |
301 | .CP0_SRSConf1_rw_bitmask = 0x3fffffff, | |
302 | .CP0_SRSConf1 = (1 << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) | | |
303 | (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4), | |
304 | .CP0_SRSConf2_rw_bitmask = 0x3fffffff, | |
305 | .CP0_SRSConf2 = (1 << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) | | |
306 | (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7), | |
307 | .CP0_SRSConf3_rw_bitmask = 0x3fffffff, | |
308 | .CP0_SRSConf3 = (1 << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) | | |
309 | (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10), | |
310 | .CP0_SRSConf4_rw_bitmask = 0x3fffffff, | |
311 | .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) | | |
312 | (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13), | |
6d35524c TS |
313 | .SEGBITS = 32, |
314 | .PABITS = 32, | |
7385ac0b | 315 | .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT, |
6d35524c | 316 | .mmu_type = MMU_TYPE_R4000, |
ead9360e | 317 | }, |
d26bc211 | 318 | #if defined(TARGET_MIPS64) |
33d68b5f TS |
319 | { |
320 | .name = "R4000", | |
321 | .CP0_PRid = 0x00000400, | |
6d35524c TS |
322 | /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */ |
323 | .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0), | |
6958549d | 324 | /* Note: Config1 is only used internally, the R4000 has only Config0. */ |
6d35524c | 325 | .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), |
2a6e32dd AJ |
326 | .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF, |
327 | .CP0_LLAddr_shift = 4, | |
2f644545 TS |
328 | .SYNCI_Step = 16, |
329 | .CCRes = 2, | |
ead9360e | 330 | .CP0_Status_rw_bitmask = 0x3678FFFF, |
6958549d | 331 | /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */ |
c9c1a064 | 332 | .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV), |
e034e2c3 | 333 | .SEGBITS = 40, |
6d35524c | 334 | .PABITS = 36, |
e189e748 | 335 | .insn_flags = CPU_MIPS3, |
6d35524c | 336 | .mmu_type = MMU_TYPE_R4000, |
c9c1a064 | 337 | }, |
e9c71dd1 TS |
338 | { |
339 | .name = "VR5432", | |
340 | .CP0_PRid = 0x00005400, | |
341 | /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */ | |
342 | .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0), | |
343 | .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), | |
2a6e32dd AJ |
344 | .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL, |
345 | .CP0_LLAddr_shift = 4, | |
e9c71dd1 TS |
346 | .SYNCI_Step = 16, |
347 | .CCRes = 2, | |
348 | .CP0_Status_rw_bitmask = 0x3678FFFF, | |
349 | /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */ | |
350 | .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV), | |
351 | .SEGBITS = 40, | |
352 | .PABITS = 32, | |
353 | .insn_flags = CPU_VR54XX, | |
354 | .mmu_type = MMU_TYPE_R4000, | |
355 | }, | |
c9c1a064 TS |
356 | { |
357 | .name = "5Kc", | |
358 | .CP0_PRid = 0x00018100, | |
29fe0e34 | 359 | .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | |
6958549d | 360 | (MMU_TYPE_R4000 << CP0C0_MT), |
c9c1a064 | 361 | .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) | |
6958549d AJ |
362 | (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | |
363 | (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | | |
364 | (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), | |
c9c1a064 TS |
365 | .CP0_Config2 = MIPS_CONFIG2, |
366 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
367 | .CP0_LLAddr_rw_bitmask = 0, |
368 | .CP0_LLAddr_shift = 4, | |
c9c1a064 TS |
369 | .SYNCI_Step = 32, |
370 | .CCRes = 2, | |
ead9360e | 371 | .CP0_Status_rw_bitmask = 0x32F8FFFF, |
e034e2c3 | 372 | .SEGBITS = 42, |
6d35524c | 373 | .PABITS = 36, |
e189e748 | 374 | .insn_flags = CPU_MIPS64, |
6d35524c | 375 | .mmu_type = MMU_TYPE_R4000, |
c9c1a064 TS |
376 | }, |
377 | { | |
378 | .name = "5Kf", | |
379 | .CP0_PRid = 0x00018100, | |
29fe0e34 | 380 | .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | |
6958549d | 381 | (MMU_TYPE_R4000 << CP0C0_MT), |
c9c1a064 | 382 | .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | |
6958549d AJ |
383 | (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | |
384 | (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | | |
385 | (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), | |
c9c1a064 TS |
386 | .CP0_Config2 = MIPS_CONFIG2, |
387 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
388 | .CP0_LLAddr_rw_bitmask = 0, |
389 | .CP0_LLAddr_shift = 4, | |
c9c1a064 TS |
390 | .SYNCI_Step = 32, |
391 | .CCRes = 2, | |
ead9360e | 392 | .CP0_Status_rw_bitmask = 0x36F8FFFF, |
6958549d | 393 | /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */ |
c9c1a064 TS |
394 | .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) | |
395 | (0x81 << FCR0_PRID) | (0x0 << FCR0_REV), | |
e034e2c3 | 396 | .SEGBITS = 42, |
6d35524c | 397 | .PABITS = 36, |
e189e748 | 398 | .insn_flags = CPU_MIPS64, |
6d35524c | 399 | .mmu_type = MMU_TYPE_R4000, |
c9c1a064 TS |
400 | }, |
401 | { | |
402 | .name = "20Kc", | |
6958549d | 403 | /* We emulate a later version of the 20Kc, earlier ones had a broken |
bd04c6fe TS |
404 | WAIT instruction. */ |
405 | .CP0_PRid = 0x000182a0, | |
29fe0e34 | 406 | .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | |
6d35524c | 407 | (MMU_TYPE_R4000 << CP0C0_MT) | (1 << CP0C0_VI), |
c9c1a064 | 408 | .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) | |
6958549d AJ |
409 | (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | |
410 | (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | | |
411 | (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), | |
c9c1a064 TS |
412 | .CP0_Config2 = MIPS_CONFIG2, |
413 | .CP0_Config3 = MIPS_CONFIG3, | |
2a6e32dd AJ |
414 | .CP0_LLAddr_rw_bitmask = 0, |
415 | .CP0_LLAddr_shift = 0, | |
c9c1a064 | 416 | .SYNCI_Step = 32, |
a1daafd8 | 417 | .CCRes = 1, |
ead9360e | 418 | .CP0_Status_rw_bitmask = 0x36FBFFFF, |
6958549d | 419 | /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */ |
c9c1a064 | 420 | .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) | |
5a5012ec | 421 | (1 << FCR0_D) | (1 << FCR0_S) | |
c9c1a064 | 422 | (0x82 << FCR0_PRID) | (0x0 << FCR0_REV), |
e034e2c3 | 423 | .SEGBITS = 40, |
6d35524c | 424 | .PABITS = 36, |
e189e748 | 425 | .insn_flags = CPU_MIPS64 | ASE_MIPS3D, |
6d35524c | 426 | .mmu_type = MMU_TYPE_R4000, |
33d68b5f | 427 | }, |
d2123ead | 428 | { |
6958549d | 429 | /* A generic CPU providing MIPS64 Release 2 features. |
d2123ead TS |
430 | FIXME: Eventually this should be replaced by a real CPU model. */ |
431 | .name = "MIPS64R2-generic", | |
8c89395e | 432 | .CP0_PRid = 0x00010000, |
6d35524c | 433 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | |
6958549d | 434 | (MMU_TYPE_R4000 << CP0C0_MT), |
d2123ead | 435 | .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | |
6958549d AJ |
436 | (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | |
437 | (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | | |
438 | (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), | |
d2123ead | 439 | .CP0_Config2 = MIPS_CONFIG2, |
6d35524c | 440 | .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), |
2a6e32dd AJ |
441 | .CP0_LLAddr_rw_bitmask = 0, |
442 | .CP0_LLAddr_shift = 0, | |
d2123ead TS |
443 | .SYNCI_Step = 32, |
444 | .CCRes = 2, | |
445 | .CP0_Status_rw_bitmask = 0x36FBFFFF, | |
ea4b07f7 TS |
446 | .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) | |
447 | (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | | |
448 | (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), | |
6d35524c TS |
449 | .SEGBITS = 42, |
450 | /* The architectural limit is 59, but we have hardcoded 36 bit | |
451 | in some places... | |
452 | .PABITS = 59, */ /* the architectural limit */ | |
453 | .PABITS = 36, | |
d2123ead | 454 | .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D, |
6d35524c | 455 | .mmu_type = MMU_TYPE_R4000, |
d2123ead | 456 | }, |
5bc6fba8 HC |
457 | { |
458 | .name = "Loongson-2E", | |
459 | .CP0_PRid = 0x6302, | |
460 | /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/ | |
461 | .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) | | |
462 | (0x1<<4) | (0x1<<1), | |
463 | /* Note: Config1 is only used internally, Loongson-2E has only Config0. */ | |
464 | .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), | |
465 | .SYNCI_Step = 16, | |
466 | .CCRes = 2, | |
467 | .CP0_Status_rw_bitmask = 0x35D0FFFF, | |
468 | .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), | |
469 | .SEGBITS = 40, | |
470 | .PABITS = 40, | |
471 | .insn_flags = CPU_LOONGSON2E, | |
472 | .mmu_type = MMU_TYPE_R4000, | |
473 | }, | |
474 | { | |
475 | .name = "Loongson-2F", | |
476 | .CP0_PRid = 0x6303, | |
477 | /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/ | |
478 | .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) | | |
479 | (0x1<<4) | (0x1<<1), | |
480 | /* Note: Config1 is only used internally, Loongson-2F has only Config0. */ | |
481 | .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), | |
482 | .SYNCI_Step = 16, | |
483 | .CCRes = 2, | |
484 | .CP0_Status_rw_bitmask = 0xF5D0FF1F, /*bit5:7 not writeable*/ | |
485 | .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), | |
486 | .SEGBITS = 40, | |
487 | .PABITS = 40, | |
488 | .insn_flags = CPU_LOONGSON2F, | |
489 | .mmu_type = MMU_TYPE_R4000, | |
490 | }, | |
491 | ||
33d68b5f TS |
492 | #endif |
493 | }; | |
494 | ||
c227f099 | 495 | static const mips_def_t *cpu_mips_find_by_name (const char *name) |
33d68b5f | 496 | { |
aaed909a | 497 | int i; |
33d68b5f | 498 | |
b1503cda | 499 | for (i = 0; i < ARRAY_SIZE(mips_defs); i++) { |
33d68b5f | 500 | if (strcasecmp(name, mips_defs[i].name) == 0) { |
aaed909a | 501 | return &mips_defs[i]; |
33d68b5f TS |
502 | } |
503 | } | |
aaed909a | 504 | return NULL; |
33d68b5f TS |
505 | } |
506 | ||
507 | void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) | |
508 | { | |
509 | int i; | |
510 | ||
b1503cda | 511 | for (i = 0; i < ARRAY_SIZE(mips_defs); i++) { |
33d68b5f TS |
512 | (*cpu_fprintf)(f, "MIPS '%s'\n", |
513 | mips_defs[i].name); | |
514 | } | |
515 | } | |
516 | ||
f8a6ec58 | 517 | #ifndef CONFIG_USER_ONLY |
c227f099 | 518 | static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def) |
29929e34 | 519 | { |
ead9360e TS |
520 | env->tlb->nb_tlb = 1; |
521 | env->tlb->map_address = &no_mmu_map_address; | |
29929e34 TS |
522 | } |
523 | ||
c227f099 | 524 | static void fixed_mmu_init (CPUMIPSState *env, const mips_def_t *def) |
29929e34 | 525 | { |
ead9360e TS |
526 | env->tlb->nb_tlb = 1; |
527 | env->tlb->map_address = &fixed_mmu_map_address; | |
29929e34 TS |
528 | } |
529 | ||
c227f099 | 530 | static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def) |
29929e34 | 531 | { |
ead9360e TS |
532 | env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63); |
533 | env->tlb->map_address = &r4k_map_address; | |
c01fccd2 AJ |
534 | env->tlb->helper_tlbwi = r4k_helper_tlbwi; |
535 | env->tlb->helper_tlbwr = r4k_helper_tlbwr; | |
536 | env->tlb->helper_tlbp = r4k_helper_tlbp; | |
537 | env->tlb->helper_tlbr = r4k_helper_tlbr; | |
ead9360e TS |
538 | } |
539 | ||
c227f099 | 540 | static void mmu_init (CPUMIPSState *env, const mips_def_t *def) |
ead9360e TS |
541 | { |
542 | env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext)); | |
543 | ||
6d35524c TS |
544 | switch (def->mmu_type) { |
545 | case MMU_TYPE_NONE: | |
ead9360e TS |
546 | no_mmu_init(env, def); |
547 | break; | |
6d35524c | 548 | case MMU_TYPE_R4000: |
ead9360e TS |
549 | r4k_mmu_init(env, def); |
550 | break; | |
6d35524c | 551 | case MMU_TYPE_FMT: |
ead9360e TS |
552 | fixed_mmu_init(env, def); |
553 | break; | |
6d35524c TS |
554 | case MMU_TYPE_R3000: |
555 | case MMU_TYPE_R6000: | |
556 | case MMU_TYPE_R8000: | |
ead9360e TS |
557 | default: |
558 | cpu_abort(env, "MMU type not supported\n"); | |
559 | } | |
29929e34 | 560 | } |
f8a6ec58 | 561 | #endif /* CONFIG_USER_ONLY */ |
29929e34 | 562 | |
c227f099 | 563 | static void fpu_init (CPUMIPSState *env, const mips_def_t *def) |
ead9360e | 564 | { |
f01be154 TS |
565 | int i; |
566 | ||
567 | for (i = 0; i < MIPS_FPU_MAX; i++) | |
568 | env->fpus[i].fcr0 = def->CP1_fcr0; | |
ead9360e | 569 | |
f01be154 | 570 | memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); |
ead9360e TS |
571 | } |
572 | ||
c227f099 | 573 | static void mvp_init (CPUMIPSState *env, const mips_def_t *def) |
ead9360e TS |
574 | { |
575 | env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext)); | |
576 | ||
577 | /* MVPConf1 implemented, TLB sharable, no gating storage support, | |
578 | programmable cache partitioning implemented, number of allocatable | |
579 | and sharable TLB entries, MVP has allocatable TCs, 2 VPEs | |
580 | implemented, 5 TCs implemented. */ | |
581 | env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) | | |
582 | (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) | | |
ead9360e TS |
583 | // TODO: actually do 2 VPEs. |
584 | // (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) | | |
585 | // (0x04 << CP0MVPC0_PTC); | |
586 | (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | | |
587 | (0x04 << CP0MVPC0_PTC); | |
932e71cd | 588 | #if !defined(CONFIG_USER_ONLY) |
0eaef5aa | 589 | /* Usermode has no TLB support */ |
932e71cd AJ |
590 | env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); |
591 | #endif | |
0eaef5aa | 592 | |
ead9360e TS |
593 | /* Allocatable CP1 have media extensions, allocatable CP1 have FP support, |
594 | no UDI implemented, no CP2 implemented, 1 CP1 implemented. */ | |
595 | env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) | | |
596 | (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) | | |
597 | (0x1 << CP0MVPC1_PCP1); | |
598 | } |