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"
42 #include "sim/faults.hh"
50 SCTLR sctlr_rst
= miscRegs
[MISCREG_SCTLR_RST
];
52 memset(miscRegs
, 0, sizeof(miscRegs
));
54 cpsr
.mode
= MODE_USER
;
55 miscRegs
[MISCREG_CPSR
] = cpsr
;
59 sctlr
.te
= (bool)sctlr_rst
.te
;
60 sctlr
.nmfi
= (bool)sctlr_rst
.nmfi
;
61 sctlr
.v
= (bool)sctlr_rst
.v
;
67 miscRegs
[MISCREG_SCTLR
] = sctlr
;
68 miscRegs
[MISCREG_SCTLR_RST
] = sctlr_rst
;
70 /* Start with an event in the mailbox */
71 miscRegs
[MISCREG_SEV_MAILBOX
] = 1;
74 * Implemented = '5' from "M5",
77 miscRegs
[MISCREG_MIDR
] =
78 (0x35 << 24) | // Implementor is '5' from "M5"
79 (0 << 20) | // Variant
80 (0xf << 16) | // Architecture from CPUID scheme
81 (0xf00 << 4) | // Primary part number
82 (0 << 0) | // Revision
85 // Separate Instruction and Data TLBs.
86 miscRegs
[MISCREG_TLBTR
] = 1;
89 mvfr0
.advSimdRegisters
= 2;
90 mvfr0
.singlePrecision
= 2;
91 mvfr0
.doublePrecision
= 2;
92 mvfr0
.vfpExceptionTrapping
= 0;
95 mvfr0
.shortVectors
= 1;
96 mvfr0
.roundingModes
= 1;
97 miscRegs
[MISCREG_MVFR0
] = mvfr0
;
100 mvfr1
.flushToZero
= 1;
101 mvfr1
.defaultNaN
= 1;
102 mvfr1
.advSimdLoadStore
= 1;
103 mvfr1
.advSimdInteger
= 1;
104 mvfr1
.advSimdSinglePrecision
= 1;
105 mvfr1
.advSimdHalfPrecision
= 1;
106 mvfr1
.vfpHalfPrecision
= 1;
107 miscRegs
[MISCREG_MVFR1
] = mvfr1
;
109 miscRegs
[MISCREG_MPIDR
] = 0;
111 // Reset values of PRRR and NMRR are implementation dependent
113 miscRegs
[MISCREG_PRRR
] =
126 miscRegs
[MISCREG_NMRR
] =
143 miscRegs
[MISCREG_CPACR
] = 0;
144 miscRegs
[MISCREG_FPSID
] = 0x410430A0;
145 //XXX We need to initialize the rest of the state.
149 ISA::readMiscRegNoEffect(int misc_reg
)
151 assert(misc_reg
< NumMiscRegs
);
154 if (misc_reg
== MISCREG_SPSR
)
155 flat_idx
= flattenMiscIndex(misc_reg
);
158 MiscReg val
= miscRegs
[flat_idx
];
160 DPRINTF(MiscRegs
, "Reading From misc reg %d (%d) : %#x\n",
161 misc_reg
, flat_idx
, val
);
167 ISA::readMiscReg(int misc_reg
, ThreadContext
*tc
)
169 if (misc_reg
== MISCREG_CPSR
) {
170 CPSR cpsr
= miscRegs
[misc_reg
];
171 PCState pc
= tc
->pcState();
172 cpsr
.j
= pc
.jazelle() ? 1 : 0;
173 cpsr
.t
= pc
.thumb() ? 1 : 0;
176 if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
177 misc_reg
< MISCREG_CP15_END
) {
178 panic("Unimplemented CP15 register %s read.\n",
179 miscRegName
[misc_reg
]);
183 warn_once("The clidr register always reports 0 caches.\n");
186 warn_once("The ccsidr register isn't implemented and "
187 "always reads as 0.\n");
189 case MISCREG_ID_PFR0
:
190 warn("Returning thumbEE disabled for now since we don't support CP14"
191 "config registers and jumping to ThumbEE vectors\n");
192 return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
193 case MISCREG_ID_MMFR0
:
194 return 0x03; //VMSAz7
196 return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
198 warn("Not doing anything for miscreg ACTLR\n");
201 case MISCREG_PMCCNTR
:
203 warn("Not doing anyhting for read to miscreg %s\n",
204 miscRegName
[misc_reg
]);
208 return readMiscRegNoEffect(misc_reg
);
212 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
)
214 assert(misc_reg
< NumMiscRegs
);
217 if (misc_reg
== MISCREG_SPSR
)
218 flat_idx
= flattenMiscIndex(misc_reg
);
221 miscRegs
[flat_idx
] = val
;
223 DPRINTF(MiscRegs
, "Writing to misc reg %d (%d) : %#x\n", misc_reg
,
228 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
, ThreadContext
*tc
)
231 MiscReg newVal
= val
;
232 if (misc_reg
== MISCREG_CPSR
) {
236 CPSR old_cpsr
= miscRegs
[MISCREG_CPSR
];
237 int old_mode
= old_cpsr
.mode
;
239 if (old_mode
!= cpsr
.mode
) {
240 tc
->getITBPtr()->invalidateMiscReg();
241 tc
->getDTBPtr()->invalidateMiscReg();
244 DPRINTF(Arm
, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
245 miscRegs
[misc_reg
], cpsr
, cpsr
.f
, cpsr
.i
, cpsr
.a
, cpsr
.mode
);
246 PCState pc
= tc
->pcState();
247 pc
.nextThumb(cpsr
.t
);
248 pc
.nextJazelle(cpsr
.j
);
250 } else if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
251 misc_reg
< MISCREG_CP15_END
) {
252 panic("Unimplemented CP15 register %s wrote with %#x.\n",
253 miscRegName
[misc_reg
], val
);
256 case MISCREG_ITSTATE
:
258 ITSTATE itstate
= newVal
;
259 CPSR cpsr
= miscRegs
[MISCREG_CPSR
];
260 cpsr
.it1
= itstate
.bottom2
;
261 cpsr
.it2
= itstate
.top6
;
262 miscRegs
[MISCREG_CPSR
] = cpsr
;
264 "Updating ITSTATE -> %#x in CPSR -> %#x.\n",
265 (uint8_t)itstate
, (uint32_t)cpsr
);
271 CPACR valCpacr
= val
;
272 newCpacr
.cp10
= valCpacr
.cp10
;
273 newCpacr
.cp11
= valCpacr
.cp11
;
274 //XXX d32dis isn't implemented. The manual says whether or not
275 //it works is implementation defined.
276 newCpacr
.asedis
= valCpacr
.asedis
;
281 warn_once("The csselr register isn't implemented.\n");
285 const uint32_t ones
= (uint32_t)(-1);
287 fpscrMask
.ioc
= ones
;
288 fpscrMask
.dzc
= ones
;
289 fpscrMask
.ofc
= ones
;
290 fpscrMask
.ufc
= ones
;
291 fpscrMask
.ixc
= ones
;
292 fpscrMask
.idc
= ones
;
293 fpscrMask
.len
= ones
;
294 fpscrMask
.stride
= ones
;
295 fpscrMask
.rMode
= ones
;
298 fpscrMask
.ahp
= ones
;
304 newVal
= (newVal
& (uint32_t)fpscrMask
) |
305 (miscRegs
[MISCREG_FPSCR
] & ~(uint32_t)fpscrMask
);
310 const uint32_t fpexcMask
= 0x60000000;
311 newVal
= (newVal
& fpexcMask
) |
312 (miscRegs
[MISCREG_FPEXC
] & ~fpexcMask
);
317 DPRINTF(MiscRegs
, "Writing SCTLR: %#x\n", newVal
);
318 SCTLR sctlr
= miscRegs
[MISCREG_SCTLR
];
319 SCTLR new_sctlr
= newVal
;
320 new_sctlr
.nmfi
= (bool)sctlr
.nmfi
;
321 miscRegs
[MISCREG_SCTLR
] = (MiscReg
)new_sctlr
;
322 tc
->getITBPtr()->invalidateMiscReg();
323 tc
->getDTBPtr()->invalidateMiscReg();
332 case MISCREG_TLBIALLIS
:
333 case MISCREG_TLBIALL
:
334 warn_once("Need to flush all TLBs in MP\n");
335 tc
->getITBPtr()->flushAll();
336 tc
->getDTBPtr()->flushAll();
338 case MISCREG_ITLBIALL
:
339 tc
->getITBPtr()->flushAll();
341 case MISCREG_DTLBIALL
:
342 tc
->getDTBPtr()->flushAll();
344 case MISCREG_TLBIMVAIS
:
345 case MISCREG_TLBIMVA
:
346 warn_once("Need to flush all TLBs in MP\n");
347 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
349 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
352 case MISCREG_TLBIASIDIS
:
353 case MISCREG_TLBIASID
:
354 warn_once("Need to flush all TLBs in MP\n");
355 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
356 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
358 case MISCREG_TLBIMVAAIS
:
359 case MISCREG_TLBIMVAA
:
360 warn_once("Need to flush all TLBs in MP\n");
361 tc
->getITBPtr()->flushMva(mbits(newVal
, 31,12));
362 tc
->getDTBPtr()->flushMva(mbits(newVal
, 31,12));
364 case MISCREG_ITLBIMVA
:
365 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
368 case MISCREG_DTLBIMVA
:
369 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
372 case MISCREG_ITLBIASID
:
373 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
375 case MISCREG_DTLBIASID
:
376 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
379 warn("Not doing anything for write of miscreg ACTLR\n");
382 case MISCREG_PMCCNTR
:
384 warn("Not doing anything for write to miscreg %s\n",
385 miscRegName
[misc_reg
]);
387 case MISCREG_V2PCWPR
:
388 case MISCREG_V2PCWPW
:
389 case MISCREG_V2PCWUR
:
390 case MISCREG_V2PCWUW
:
391 case MISCREG_V2POWPR
:
392 case MISCREG_V2POWPW
:
393 case MISCREG_V2POWUR
:
394 case MISCREG_V2POWUW
:
396 RequestPtr req
= new Request
;
401 case MISCREG_V2PCWPR
:
402 flags
= TLB::MustBeOne
;
403 mode
= BaseTLB::Read
;
405 case MISCREG_V2PCWPW
:
406 flags
= TLB::MustBeOne
;
407 mode
= BaseTLB::Write
;
409 case MISCREG_V2PCWUR
:
410 flags
= TLB::MustBeOne
| TLB::UserMode
;
411 mode
= BaseTLB::Read
;
413 case MISCREG_V2PCWUW
:
414 flags
= TLB::MustBeOne
| TLB::UserMode
;
415 mode
= BaseTLB::Write
;
418 panic("Security Extensions not implemented!");
420 req
->setVirt(0, val
, 1, flags
, tc
->pcState().pc());
421 fault
= tc
->getDTBPtr()->translateAtomic(req
, tc
, mode
);
422 if (fault
== NoFault
) {
423 miscRegs
[MISCREG_PAR
] =
424 (req
->getPaddr() & 0xfffff000) |
425 (tc
->getDTBPtr()->getAttr() );
427 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
428 val
, miscRegs
[MISCREG_PAR
]);
431 // Set fault bit and FSR
432 FSR fsr
= miscRegs
[MISCREG_DFSR
];
433 miscRegs
[MISCREG_PAR
] =
441 case MISCREG_CONTEXTIDR
:
445 tc
->getITBPtr()->invalidateMiscReg();
446 tc
->getDTBPtr()->invalidateMiscReg();
451 setMiscRegNoEffect(misc_reg
, newVal
);