2 * Copyright (c) 2010 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include "arch/arm/isa.hh"
49 SCTLR sctlr_rst
= miscRegs
[MISCREG_SCTLR_RST
];
51 memset(miscRegs
, 0, sizeof(miscRegs
));
53 cpsr
.mode
= MODE_USER
;
54 miscRegs
[MISCREG_CPSR
] = cpsr
;
58 sctlr
.te
= (bool)sctlr_rst
.te
;
59 sctlr
.nmfi
= (bool)sctlr_rst
.nmfi
;
60 sctlr
.v
= (bool)sctlr_rst
.v
;
66 miscRegs
[MISCREG_SCTLR
] = sctlr
;
67 miscRegs
[MISCREG_SCTLR_RST
] = sctlr_rst
;
71 * Technically this should be 0, but we don't support those
78 miscRegs
[MISCREG_CPACR
] = cpacr
;
80 /* Start with an event in the mailbox */
81 miscRegs
[MISCREG_SEV_MAILBOX
] = 1;
84 * Implemented = '5' from "M5",
87 miscRegs
[MISCREG_MIDR
] =
88 (0x35 << 24) | //Implementor is '5' from "M5"
90 (0xf << 16) | //Architecture from CPUID scheme
91 (0 << 4) | //Primary part number
95 // Separate Instruction and Data TLBs.
96 miscRegs
[MISCREG_TLBTR
] = 1;
99 mvfr0
.advSimdRegisters
= 2;
100 mvfr0
.singlePrecision
= 2;
101 mvfr0
.doublePrecision
= 2;
102 mvfr0
.vfpExceptionTrapping
= 0;
104 mvfr0
.squareRoot
= 1;
105 mvfr0
.shortVectors
= 1;
106 mvfr0
.roundingModes
= 1;
107 miscRegs
[MISCREG_MVFR0
] = mvfr0
;
110 mvfr1
.flushToZero
= 1;
111 mvfr1
.defaultNaN
= 1;
112 mvfr1
.advSimdLoadStore
= 1;
113 mvfr1
.advSimdInteger
= 1;
114 mvfr1
.advSimdSinglePrecision
= 1;
115 mvfr1
.advSimdHalfPrecision
= 1;
116 mvfr1
.vfpHalfPrecision
= 1;
117 miscRegs
[MISCREG_MVFR1
] = mvfr1
;
119 miscRegs
[MISCREG_MPIDR
] = 0;
121 // Reset values of PRRR and NMRR are implementation dependent
123 miscRegs
[MISCREG_PRRR
] =
136 miscRegs
[MISCREG_NMRR
] =
153 //XXX We need to initialize the rest of the state.
157 ISA::readMiscRegNoEffect(int misc_reg
)
159 assert(misc_reg
< NumMiscRegs
);
162 if (misc_reg
== MISCREG_SPSR
)
163 flat_idx
= flattenMiscIndex(misc_reg
);
166 MiscReg val
= miscRegs
[flat_idx
];
168 DPRINTF(MiscRegs
, "Reading From misc reg %d (%d) : %#x\n",
169 misc_reg
, flat_idx
, val
);
175 ISA::readMiscReg(int misc_reg
, ThreadContext
*tc
)
177 if (misc_reg
== MISCREG_CPSR
) {
178 CPSR cpsr
= miscRegs
[misc_reg
];
179 Addr pc
= tc
->readPC();
180 if (pc
& (ULL(1) << PcJBitShift
))
184 if (pc
& (ULL(1) << PcTBitShift
))
190 if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
191 misc_reg
< MISCREG_CP15_END
) {
192 panic("Unimplemented CP15 register %s read.\n",
193 miscRegName
[misc_reg
]);
197 warn("The clidr register always reports 0 caches.\n");
200 warn("The ccsidr register isn't implemented and "
201 "always reads as 0.\n");
203 case MISCREG_ID_PFR0
:
204 warn("Returning thumbEE disabled for now since we don't support CP14"
205 "config registers and jumping to ThumbEE vectors\n");
206 return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
207 case MISCREG_ID_MMFR0
:
208 return 0x03; //VMSAz7
210 return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
212 warn("Not doing anything for miscreg ACTLR\n");
215 case MISCREG_PMCCNTR
:
217 warn("Not doing anyhting for read to miscreg %s\n",
218 miscRegName
[misc_reg
]);
222 return readMiscRegNoEffect(misc_reg
);
226 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
)
228 assert(misc_reg
< NumMiscRegs
);
231 if (misc_reg
== MISCREG_SPSR
)
232 flat_idx
= flattenMiscIndex(misc_reg
);
235 miscRegs
[flat_idx
] = val
;
237 DPRINTF(MiscRegs
, "Writing to misc reg %d (%d) : %#x\n", misc_reg
,
242 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
, ThreadContext
*tc
)
244 MiscReg newVal
= val
;
245 if (misc_reg
== MISCREG_CPSR
) {
248 DPRINTF(Arm
, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
249 miscRegs
[misc_reg
], cpsr
, cpsr
.f
, cpsr
.i
, cpsr
.a
, cpsr
.mode
);
250 Addr npc
= tc
->readNextPC() & ~PcModeMask
;
252 npc
= npc
| (ULL(1) << PcJBitShift
);
254 npc
= npc
| (ULL(1) << PcTBitShift
);
257 } else if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
258 misc_reg
< MISCREG_CP15_END
) {
259 panic("Unimplemented CP15 register %s wrote with %#x.\n",
260 miscRegName
[misc_reg
], val
);
263 case MISCREG_ITSTATE
:
265 ITSTATE itstate
= newVal
;
266 CPSR cpsr
= miscRegs
[MISCREG_CPSR
];
267 cpsr
.it1
= itstate
.bottom2
;
268 cpsr
.it2
= itstate
.top6
;
269 miscRegs
[MISCREG_CPSR
] = cpsr
;
271 "Updating ITSTATE -> %#x in CPSR -> %#x.\n",
272 (uint8_t)itstate
, (uint32_t)cpsr
);
278 CPACR valCpacr
= val
;
279 newCpacr
.cp10
= valCpacr
.cp10
;
280 newCpacr
.cp11
= valCpacr
.cp11
;
281 if (newCpacr
.cp10
!= 0x3 || newCpacr
.cp11
!= 3) {
282 panic("Disabling coprocessors isn't implemented.\n");
288 warn("The csselr register isn't implemented.\n");
292 const uint32_t ones
= (uint32_t)(-1);
294 fpscrMask
.ioc
= ones
;
295 fpscrMask
.dzc
= ones
;
296 fpscrMask
.ofc
= ones
;
297 fpscrMask
.ufc
= ones
;
298 fpscrMask
.ixc
= ones
;
299 fpscrMask
.idc
= ones
;
300 fpscrMask
.len
= ones
;
301 fpscrMask
.stride
= ones
;
302 fpscrMask
.rMode
= ones
;
305 fpscrMask
.ahp
= ones
;
311 newVal
= (newVal
& (uint32_t)fpscrMask
) |
312 (miscRegs
[MISCREG_FPSCR
] & ~(uint32_t)fpscrMask
);
317 const uint32_t fpexcMask
= 0x60000000;
318 newVal
= (newVal
& fpexcMask
) |
319 (miscRegs
[MISCREG_FPEXC
] & ~fpexcMask
);
324 DPRINTF(MiscRegs
, "Writing SCTLR: %#x\n", newVal
);
325 SCTLR sctlr
= miscRegs
[MISCREG_SCTLR
];
326 SCTLR new_sctlr
= newVal
;
327 new_sctlr
.nmfi
= (bool)sctlr
.nmfi
;
328 miscRegs
[MISCREG_SCTLR
] = (MiscReg
)new_sctlr
;
337 case MISCREG_TLBIALLIS
:
338 case MISCREG_TLBIALL
:
339 warn("Need to flush all TLBs in MP\n");
340 tc
->getITBPtr()->flushAll();
341 tc
->getDTBPtr()->flushAll();
343 case MISCREG_ITLBIALL
:
344 tc
->getITBPtr()->flushAll();
346 case MISCREG_DTLBIALL
:
347 tc
->getDTBPtr()->flushAll();
349 case MISCREG_TLBIMVAIS
:
350 case MISCREG_TLBIMVA
:
351 warn("Need to flush all TLBs in MP\n");
352 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
354 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
357 case MISCREG_TLBIASIDIS
:
358 case MISCREG_TLBIASID
:
359 warn("Need to flush all TLBs in MP\n");
360 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
361 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
363 case MISCREG_TLBIMVAAIS
:
364 case MISCREG_TLBIMVAA
:
365 warn("Need to flush all TLBs in MP\n");
366 tc
->getITBPtr()->flushMva(mbits(newVal
, 31,12));
367 tc
->getDTBPtr()->flushMva(mbits(newVal
, 31,12));
369 case MISCREG_ITLBIMVA
:
370 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
373 case MISCREG_DTLBIMVA
:
374 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
377 case MISCREG_ITLBIASID
:
378 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
380 case MISCREG_DTLBIASID
:
381 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
384 warn("Not doing anything for write of miscreg ACTLR\n");
387 case MISCREG_PMCCNTR
:
389 warn("Not doing anything for write to miscreg %s\n",
390 miscRegName
[misc_reg
]);
392 case MISCREG_V2PCWPR
:
393 case MISCREG_V2PCWPW
:
394 case MISCREG_V2PCWUR
:
395 case MISCREG_V2PCWUW
:
396 case MISCREG_V2POWPR
:
397 case MISCREG_V2POWPW
:
398 case MISCREG_V2POWUR
:
399 case MISCREG_V2POWUW
:
401 RequestPtr req
= new Request
;
406 case MISCREG_V2PCWPR
:
407 flags
= TLB::MustBeOne
;
408 mode
= BaseTLB::Read
;
410 case MISCREG_V2PCWPW
:
411 flags
= TLB::MustBeOne
;
412 mode
= BaseTLB::Write
;
414 case MISCREG_V2PCWUR
:
415 flags
= TLB::MustBeOne
| TLB::UserMode
;
416 mode
= BaseTLB::Read
;
418 case MISCREG_V2PCWUW
:
419 flags
= TLB::MustBeOne
| TLB::UserMode
;
420 mode
= BaseTLB::Write
;
423 panic("Security Extensions not implemented!");
425 req
->setVirt(0, val
, 1, flags
, tc
->readPC());
426 fault
= tc
->getDTBPtr()->translateAtomic(req
, tc
, mode
);
427 if (fault
== NoFault
) {
428 miscRegs
[MISCREG_PAR
] =
429 (req
->getPaddr() & 0xfffff000) |
430 (tc
->getDTBPtr()->getAttr() );
432 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
433 val
, miscRegs
[MISCREG_PAR
]);
436 // Set fault bit and FSR
437 FSR fsr
= miscRegs
[MISCREG_DFSR
];
438 miscRegs
[MISCREG_PAR
] =
448 setMiscRegNoEffect(misc_reg
, newVal
);