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
;
69 /* Start with an event in the mailbox */
70 miscRegs
[MISCREG_SEV_MAILBOX
] = 1;
73 * Implemented = '5' from "M5",
76 miscRegs
[MISCREG_MIDR
] =
77 (0x35 << 24) | // Implementor is '5' from "M5"
78 (0 << 20) | // Variant
79 (0xf << 16) | // Architecture from CPUID scheme
80 (0xf00 << 4) | // Primary part number
81 (0 << 0) | // Revision
84 // Separate Instruction and Data TLBs.
85 miscRegs
[MISCREG_TLBTR
] = 1;
88 mvfr0
.advSimdRegisters
= 2;
89 mvfr0
.singlePrecision
= 2;
90 mvfr0
.doublePrecision
= 2;
91 mvfr0
.vfpExceptionTrapping
= 0;
94 mvfr0
.shortVectors
= 1;
95 mvfr0
.roundingModes
= 1;
96 miscRegs
[MISCREG_MVFR0
] = mvfr0
;
99 mvfr1
.flushToZero
= 1;
100 mvfr1
.defaultNaN
= 1;
101 mvfr1
.advSimdLoadStore
= 1;
102 mvfr1
.advSimdInteger
= 1;
103 mvfr1
.advSimdSinglePrecision
= 1;
104 mvfr1
.advSimdHalfPrecision
= 1;
105 mvfr1
.vfpHalfPrecision
= 1;
106 miscRegs
[MISCREG_MVFR1
] = mvfr1
;
108 miscRegs
[MISCREG_MPIDR
] = 0;
110 // Reset values of PRRR and NMRR are implementation dependent
112 miscRegs
[MISCREG_PRRR
] =
125 miscRegs
[MISCREG_NMRR
] =
142 miscRegs
[MISCREG_CPACR
] = 0;
143 miscRegs
[MISCREG_FPSID
] = 0x410430A0;
144 //XXX We need to initialize the rest of the state.
148 ISA::readMiscRegNoEffect(int misc_reg
)
150 assert(misc_reg
< NumMiscRegs
);
153 if (misc_reg
== MISCREG_SPSR
)
154 flat_idx
= flattenMiscIndex(misc_reg
);
157 MiscReg val
= miscRegs
[flat_idx
];
159 DPRINTF(MiscRegs
, "Reading From misc reg %d (%d) : %#x\n",
160 misc_reg
, flat_idx
, val
);
166 ISA::readMiscReg(int misc_reg
, ThreadContext
*tc
)
168 if (misc_reg
== MISCREG_CPSR
) {
169 CPSR cpsr
= miscRegs
[misc_reg
];
170 Addr pc
= tc
->readPC();
171 if (pc
& (ULL(1) << PcJBitShift
))
175 if (pc
& (ULL(1) << PcTBitShift
))
181 if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
182 misc_reg
< MISCREG_CP15_END
) {
183 panic("Unimplemented CP15 register %s read.\n",
184 miscRegName
[misc_reg
]);
188 warn("The clidr register always reports 0 caches.\n");
191 warn("The ccsidr register isn't implemented and "
192 "always reads as 0.\n");
194 case MISCREG_ID_PFR0
:
195 warn("Returning thumbEE disabled for now since we don't support CP14"
196 "config registers and jumping to ThumbEE vectors\n");
197 return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
198 case MISCREG_ID_MMFR0
:
199 return 0x03; //VMSAz7
201 return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
203 warn("Not doing anything for miscreg ACTLR\n");
206 case MISCREG_PMCCNTR
:
208 warn("Not doing anyhting for read to miscreg %s\n",
209 miscRegName
[misc_reg
]);
213 return readMiscRegNoEffect(misc_reg
);
217 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
)
219 assert(misc_reg
< NumMiscRegs
);
222 if (misc_reg
== MISCREG_SPSR
)
223 flat_idx
= flattenMiscIndex(misc_reg
);
226 miscRegs
[flat_idx
] = val
;
228 DPRINTF(MiscRegs
, "Writing to misc reg %d (%d) : %#x\n", misc_reg
,
233 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
, ThreadContext
*tc
)
235 MiscReg newVal
= val
;
236 if (misc_reg
== MISCREG_CPSR
) {
239 DPRINTF(Arm
, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
240 miscRegs
[misc_reg
], cpsr
, cpsr
.f
, cpsr
.i
, cpsr
.a
, cpsr
.mode
);
241 Addr npc
= tc
->readNextPC() & ~PcModeMask
;
243 npc
= npc
| (ULL(1) << PcJBitShift
);
245 npc
= npc
| (ULL(1) << PcTBitShift
);
248 } else if (misc_reg
>= MISCREG_CP15_UNIMP_START
&&
249 misc_reg
< MISCREG_CP15_END
) {
250 panic("Unimplemented CP15 register %s wrote with %#x.\n",
251 miscRegName
[misc_reg
], val
);
254 case MISCREG_ITSTATE
:
256 ITSTATE itstate
= newVal
;
257 CPSR cpsr
= miscRegs
[MISCREG_CPSR
];
258 cpsr
.it1
= itstate
.bottom2
;
259 cpsr
.it2
= itstate
.top6
;
260 miscRegs
[MISCREG_CPSR
] = cpsr
;
262 "Updating ITSTATE -> %#x in CPSR -> %#x.\n",
263 (uint8_t)itstate
, (uint32_t)cpsr
);
269 CPACR valCpacr
= val
;
270 newCpacr
.cp10
= valCpacr
.cp10
;
271 newCpacr
.cp11
= valCpacr
.cp11
;
272 //XXX d32dis isn't implemented. The manual says whether or not
273 //it works is implementation defined.
274 newCpacr
.asedis
= valCpacr
.asedis
;
279 warn("The csselr register isn't implemented.\n");
283 const uint32_t ones
= (uint32_t)(-1);
285 fpscrMask
.ioc
= ones
;
286 fpscrMask
.dzc
= ones
;
287 fpscrMask
.ofc
= ones
;
288 fpscrMask
.ufc
= ones
;
289 fpscrMask
.ixc
= ones
;
290 fpscrMask
.idc
= ones
;
291 fpscrMask
.len
= ones
;
292 fpscrMask
.stride
= ones
;
293 fpscrMask
.rMode
= ones
;
296 fpscrMask
.ahp
= ones
;
302 newVal
= (newVal
& (uint32_t)fpscrMask
) |
303 (miscRegs
[MISCREG_FPSCR
] & ~(uint32_t)fpscrMask
);
308 const uint32_t fpexcMask
= 0x60000000;
309 newVal
= (newVal
& fpexcMask
) |
310 (miscRegs
[MISCREG_FPEXC
] & ~fpexcMask
);
315 DPRINTF(MiscRegs
, "Writing SCTLR: %#x\n", newVal
);
316 SCTLR sctlr
= miscRegs
[MISCREG_SCTLR
];
317 SCTLR new_sctlr
= newVal
;
318 new_sctlr
.nmfi
= (bool)sctlr
.nmfi
;
319 miscRegs
[MISCREG_SCTLR
] = (MiscReg
)new_sctlr
;
328 case MISCREG_TLBIALLIS
:
329 case MISCREG_TLBIALL
:
330 warn("Need to flush all TLBs in MP\n");
331 tc
->getITBPtr()->flushAll();
332 tc
->getDTBPtr()->flushAll();
334 case MISCREG_ITLBIALL
:
335 tc
->getITBPtr()->flushAll();
337 case MISCREG_DTLBIALL
:
338 tc
->getDTBPtr()->flushAll();
340 case MISCREG_TLBIMVAIS
:
341 case MISCREG_TLBIMVA
:
342 warn("Need to flush all TLBs in MP\n");
343 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
345 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
348 case MISCREG_TLBIASIDIS
:
349 case MISCREG_TLBIASID
:
350 warn("Need to flush all TLBs in MP\n");
351 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
352 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
354 case MISCREG_TLBIMVAAIS
:
355 case MISCREG_TLBIMVAA
:
356 warn("Need to flush all TLBs in MP\n");
357 tc
->getITBPtr()->flushMva(mbits(newVal
, 31,12));
358 tc
->getDTBPtr()->flushMva(mbits(newVal
, 31,12));
360 case MISCREG_ITLBIMVA
:
361 tc
->getITBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
364 case MISCREG_DTLBIMVA
:
365 tc
->getDTBPtr()->flushMvaAsid(mbits(newVal
, 31, 12),
368 case MISCREG_ITLBIASID
:
369 tc
->getITBPtr()->flushAsid(bits(newVal
, 7,0));
371 case MISCREG_DTLBIASID
:
372 tc
->getDTBPtr()->flushAsid(bits(newVal
, 7,0));
375 warn("Not doing anything for write of miscreg ACTLR\n");
378 case MISCREG_PMCCNTR
:
380 warn("Not doing anything for write to miscreg %s\n",
381 miscRegName
[misc_reg
]);
383 case MISCREG_V2PCWPR
:
384 case MISCREG_V2PCWPW
:
385 case MISCREG_V2PCWUR
:
386 case MISCREG_V2PCWUW
:
387 case MISCREG_V2POWPR
:
388 case MISCREG_V2POWPW
:
389 case MISCREG_V2POWUR
:
390 case MISCREG_V2POWUW
:
392 RequestPtr req
= new Request
;
397 case MISCREG_V2PCWPR
:
398 flags
= TLB::MustBeOne
;
399 mode
= BaseTLB::Read
;
401 case MISCREG_V2PCWPW
:
402 flags
= TLB::MustBeOne
;
403 mode
= BaseTLB::Write
;
405 case MISCREG_V2PCWUR
:
406 flags
= TLB::MustBeOne
| TLB::UserMode
;
407 mode
= BaseTLB::Read
;
409 case MISCREG_V2PCWUW
:
410 flags
= TLB::MustBeOne
| TLB::UserMode
;
411 mode
= BaseTLB::Write
;
414 panic("Security Extensions not implemented!");
416 req
->setVirt(0, val
, 1, flags
, tc
->readPC());
417 fault
= tc
->getDTBPtr()->translateAtomic(req
, tc
, mode
);
418 if (fault
== NoFault
) {
419 miscRegs
[MISCREG_PAR
] =
420 (req
->getPaddr() & 0xfffff000) |
421 (tc
->getDTBPtr()->getAttr() );
423 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
424 val
, miscRegs
[MISCREG_PAR
]);
427 // Set fault bit and FSR
428 FSR fsr
= miscRegs
[MISCREG_DFSR
];
429 miscRegs
[MISCREG_PAR
] =
439 setMiscRegNoEffect(misc_reg
, newVal
);