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