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 Addr pc
= tc
->readPC();
172 if (pc
& (ULL(1) << PcJBitShift
))
182 if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
183 misc_reg
< MISCREG_CP15_END
) {
184 panic("Unimplemented CP15 register %s read.\n",
185 miscRegName
[misc_reg
]);
189 warn("The clidr register always reports 0 caches.\n");
192 warn("The ccsidr register isn't implemented and "
193 "always reads as 0.\n");
195 case MISCREG_ID_PFR0
:
196 warn("Returning thumbEE disabled for now since we don't support CP14"
197 "config registers and jumping to ThumbEE vectors\n");
198 return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
199 case MISCREG_ID_MMFR0
:
200 return 0x03; //VMSAz7
202 return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
204 warn("Not doing anything for miscreg ACTLR\n");
207 case MISCREG_PMCCNTR
:
209 warn("Not doing anyhting for read to miscreg %s\n",
210 miscRegName
[misc_reg
]);
214 return readMiscRegNoEffect(misc_reg
);
218 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
)
220 assert(misc_reg
< NumMiscRegs
);
223 if (misc_reg
== MISCREG_SPSR
)
224 flat_idx
= flattenMiscIndex(misc_reg
);
227 miscRegs
[flat_idx
] = val
;
229 DPRINTF(MiscRegs
, "Writing to misc reg %d (%d) : %#x\n", misc_reg
,
234 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
, ThreadContext
*tc
)
236 MiscReg newVal
= val
;
237 if (misc_reg
== MISCREG_CPSR
) {
240 DPRINTF(Arm
, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
241 miscRegs
[misc_reg
], cpsr
, cpsr
.f
, cpsr
.i
, cpsr
.a
, cpsr
.mode
);
242 Addr npc
= tc
->readNextPC() & ~PcModeMask
;
249 } else if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
250 misc_reg
< MISCREG_CP15_END
) {
251 panic("Unimplemented CP15 register %s wrote with %#x.\n",
252 miscRegName
[misc_reg
], val
);
255 case MISCREG_ITSTATE
:
257 ITSTATE itstate
= newVal
;
258 CPSR cpsr
= miscRegs
[MISCREG_CPSR
];
259 cpsr
.it1
= itstate
.bottom2
;
260 cpsr
.it2
= itstate
.top6
;
261 miscRegs
[MISCREG_CPSR
] = cpsr
;
263 "Updating ITSTATE -> %#x in CPSR -> %#x.\n",
264 (uint8_t)itstate
, (uint32_t)cpsr
);
270 CPACR valCpacr
= val
;
271 newCpacr
.cp10
= valCpacr
.cp10
;
272 newCpacr
.cp11
= valCpacr
.cp11
;
273 //XXX d32dis isn't implemented. The manual says whether or not
274 //it works is implementation defined.
275 newCpacr
.asedis
= valCpacr
.asedis
;
280 warn("The csselr register isn't implemented.\n");
284 const uint32_t ones
= (uint32_t)(-1);
286 fpscrMask
.ioc
= ones
;
287 fpscrMask
.dzc
= ones
;
288 fpscrMask
.ofc
= ones
;
289 fpscrMask
.ufc
= ones
;
290 fpscrMask
.ixc
= ones
;
291 fpscrMask
.idc
= ones
;
292 fpscrMask
.len
= ones
;
293 fpscrMask
.stride
= ones
;
294 fpscrMask
.rMode
= ones
;
297 fpscrMask
.ahp
= ones
;
303 newVal
= (newVal
& (uint32_t)fpscrMask
) |
304 (miscRegs
[MISCREG_FPSCR
] & ~(uint32_t)fpscrMask
);
309 const uint32_t fpexcMask
= 0x60000000;
310 newVal
= (newVal
& fpexcMask
) |
311 (miscRegs
[MISCREG_FPEXC
] & ~fpexcMask
);
316 DPRINTF(MiscRegs
, "Writing SCTLR: %#x\n", newVal
);
317 SCTLR sctlr
= miscRegs
[MISCREG_SCTLR
];
318 SCTLR new_sctlr
= newVal
;
319 new_sctlr
.nmfi
= (bool)sctlr
.nmfi
;
320 miscRegs
[MISCREG_SCTLR
] = (MiscReg
)new_sctlr
;
329 case MISCREG_TLBIALLIS
:
330 case MISCREG_TLBIALL
:
331 warn("Need to flush all TLBs in MP\n");
332 tc
->getITBPtr()->flushAll();
333 tc
->getDTBPtr()->flushAll();
335 case MISCREG_ITLBIALL
:
336 tc
->getITBPtr()->flushAll();
338 case MISCREG_DTLBIALL
:
339 tc
->getDTBPtr()->flushAll();
341 case MISCREG_TLBIMVAIS
:
342 case MISCREG_TLBIMVA
:
343 warn("Need to flush all TLBs in MP\n");
344 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
346 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
349 case MISCREG_TLBIASIDIS
:
350 case MISCREG_TLBIASID
:
351 warn("Need to flush all TLBs in MP\n");
352 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
353 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
355 case MISCREG_TLBIMVAAIS
:
356 case MISCREG_TLBIMVAA
:
357 warn("Need to flush all TLBs in MP\n");
358 tc
->getITBPtr()->flushMva(mbits(newVal
, 31,12));
359 tc
->getDTBPtr()->flushMva(mbits(newVal
, 31,12));
361 case MISCREG_ITLBIMVA
:
362 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
365 case MISCREG_DTLBIMVA
:
366 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
369 case MISCREG_ITLBIASID
:
370 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
372 case MISCREG_DTLBIASID
:
373 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
376 warn("Not doing anything for write of miscreg ACTLR\n");
379 case MISCREG_PMCCNTR
:
381 warn("Not doing anything for write to miscreg %s\n",
382 miscRegName
[misc_reg
]);
384 case MISCREG_V2PCWPR
:
385 case MISCREG_V2PCWPW
:
386 case MISCREG_V2PCWUR
:
387 case MISCREG_V2PCWUW
:
388 case MISCREG_V2POWPR
:
389 case MISCREG_V2POWPW
:
390 case MISCREG_V2POWUR
:
391 case MISCREG_V2POWUW
:
393 RequestPtr req
= new Request
;
398 case MISCREG_V2PCWPR
:
399 flags
= TLB::MustBeOne
;
400 mode
= BaseTLB::Read
;
402 case MISCREG_V2PCWPW
:
403 flags
= TLB::MustBeOne
;
404 mode
= BaseTLB::Write
;
406 case MISCREG_V2PCWUR
:
407 flags
= TLB::MustBeOne
| TLB::UserMode
;
408 mode
= BaseTLB::Read
;
410 case MISCREG_V2PCWUW
:
411 flags
= TLB::MustBeOne
| TLB::UserMode
;
412 mode
= BaseTLB::Write
;
415 panic("Security Extensions not implemented!");
417 req
->setVirt(0, val
, 1, flags
, tc
->readPC());
418 fault
= tc
->getDTBPtr()->translateAtomic(req
, tc
, mode
);
419 if (fault
== NoFault
) {
420 miscRegs
[MISCREG_PAR
] =
421 (req
->getPaddr() & 0xfffff000) |
422 (tc
->getDTBPtr()->getAttr() );
424 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
425 val
, miscRegs
[MISCREG_PAR
]);
428 // Set fault bit and FSR
429 FSR fsr
= miscRegs
[MISCREG_DFSR
];
430 miscRegs
[MISCREG_PAR
] =
440 setMiscRegNoEffect(misc_reg
, newVal
);