2 * Copyright (c) 2011-2013,2017-2020 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.
38 #include "arch/arm/insts/misc64.hh"
39 #include "arch/arm/isa.hh"
42 ImmOp64::generateDisassembly(Addr pc
, const SymbolTable
*symtab
) const
45 printMnemonic(ss
, "", false);
46 ccprintf(ss
, "#0x%x", imm
);
51 RegRegImmImmOp64::generateDisassembly(Addr pc
, const SymbolTable
*symtab
) const
54 printMnemonic(ss
, "", false);
55 printIntReg(ss
, dest
);
58 ccprintf(ss
, ", #%d, #%d", imm1
, imm2
);
63 RegRegRegImmOp64::generateDisassembly(
64 Addr pc
, const SymbolTable
*symtab
) const
67 printMnemonic(ss
, "", false);
68 printIntReg(ss
, dest
);
73 ccprintf(ss
, ", #%d", imm
);
78 UnknownOp64::generateDisassembly(Addr pc
, const SymbolTable
*symtab
) const
80 return csprintf("%-10s (inst %#08x)", "unknown", encoding());
84 MiscRegOp64::trap(ThreadContext
*tc
, MiscRegIndex misc_reg
,
85 ExceptionLevel el
, uint32_t immediate
) const
87 ExceptionClass ec
= EC_TRAPPED_MSR_MRS_64
;
89 // Check for traps to supervisor (FP/SIMD regs)
90 if (el
<= EL1
&& checkEL1Trap(tc
, misc_reg
, el
, ec
, immediate
)) {
91 return std::make_shared
<SupervisorTrap
>(machInst
, immediate
, ec
);
94 // Check for traps to hypervisor
95 if ((ArmSystem::haveVirtualization(tc
) && el
<= EL2
) &&
96 checkEL2Trap(tc
, misc_reg
, el
, ec
, immediate
)) {
97 return std::make_shared
<HypervisorTrap
>(machInst
, immediate
, ec
);
100 // Check for traps to secure monitor
101 if ((ArmSystem::haveSecurity(tc
) && el
<= EL3
) &&
102 checkEL3Trap(tc
, misc_reg
, el
, ec
, immediate
)) {
103 return std::make_shared
<SecureMonitorTrap
>(machInst
, immediate
, ec
);
110 MiscRegOp64::checkEL1Trap(ThreadContext
*tc
, const MiscRegIndex misc_reg
,
111 ExceptionLevel el
, ExceptionClass
&ec
,
112 uint32_t &immediate
) const
114 const CPACR cpacr
= tc
->readMiscReg(MISCREG_CPACR_EL1
);
116 bool trap_to_sup
= false;
120 case MISCREG_FPEXC32_EL2
:
121 if ((el
== EL0
&& cpacr
.fpen
!= 0x3) ||
122 (el
== EL1
&& !(cpacr
.fpen
& 0x1))) {
124 ec
= EC_TRAPPED_SIMD_FP
;
125 immediate
= 0x1E00000;
129 case MISCREG_CNTFRQ_EL0
... MISCREG_CNTVOFF_EL2
:
130 trap_to_sup
= el
== EL0
&&
131 isGenericTimerSystemAccessTrapEL1(misc_reg
, tc
);
140 MiscRegOp64::checkEL2Trap(ThreadContext
*tc
, const MiscRegIndex misc_reg
,
141 ExceptionLevel el
, ExceptionClass
&ec
,
142 uint32_t &immediate
) const
144 const CPTR cptr
= tc
->readMiscReg(MISCREG_CPTR_EL2
);
145 const HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
146 const SCR scr
= tc
->readMiscReg(MISCREG_SCR_EL3
);
147 const CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
149 bool trap_to_hyp
= false;
151 if (!inSecureState(scr
, cpsr
) && (el
!= EL2
)) {
156 case MISCREG_FPEXC32_EL2
:
157 trap_to_hyp
= cptr
.tfp
;
158 ec
= EC_TRAPPED_SIMD_FP
;
159 immediate
= 0x1E00000;
162 case MISCREG_CPACR_EL1
:
163 trap_to_hyp
= cptr
.tcpac
&& el
== EL1
;
165 // Virtual memory control regs
166 case MISCREG_SCTLR_EL1
:
167 case MISCREG_TTBR0_EL1
:
168 case MISCREG_TTBR1_EL1
:
169 case MISCREG_TCR_EL1
:
170 case MISCREG_ESR_EL1
:
171 case MISCREG_FAR_EL1
:
172 case MISCREG_AFSR0_EL1
:
173 case MISCREG_AFSR1_EL1
:
174 case MISCREG_MAIR_EL1
:
175 case MISCREG_AMAIR_EL1
:
176 case MISCREG_CONTEXTIDR_EL1
:
178 ((hcr
.trvm
&& miscRead
) || (hcr
.tvm
&& !miscRead
)) &&
181 // TLB maintenance instructions
182 case MISCREG_TLBI_VMALLE1
:
183 case MISCREG_TLBI_VAE1_Xt
:
184 case MISCREG_TLBI_ASIDE1_Xt
:
185 case MISCREG_TLBI_VAAE1_Xt
:
186 case MISCREG_TLBI_VALE1_Xt
:
187 case MISCREG_TLBI_VAALE1_Xt
:
188 case MISCREG_TLBI_VMALLE1IS
:
189 case MISCREG_TLBI_VAE1IS_Xt
:
190 case MISCREG_TLBI_ASIDE1IS_Xt
:
191 case MISCREG_TLBI_VAAE1IS_Xt
:
192 case MISCREG_TLBI_VALE1IS_Xt
:
193 case MISCREG_TLBI_VAALE1IS_Xt
:
194 trap_to_hyp
= hcr
.ttlb
&& el
== EL1
;
196 // Cache maintenance instructions to the point of unification
197 case MISCREG_IC_IVAU_Xt
:
198 case MISCREG_ICIALLU
:
199 case MISCREG_ICIALLUIS
:
200 case MISCREG_DC_CVAU_Xt
:
201 trap_to_hyp
= hcr
.tpu
&& el
<= EL1
;
203 // Data/Unified cache maintenance instructions to the
204 // point of coherency
205 case MISCREG_DC_IVAC_Xt
:
206 case MISCREG_DC_CIVAC_Xt
:
207 case MISCREG_DC_CVAC_Xt
:
208 trap_to_hyp
= hcr
.tpc
&& el
<= EL1
;
210 // Data/Unified cache maintenance instructions by set/way
211 case MISCREG_DC_ISW_Xt
:
212 case MISCREG_DC_CSW_Xt
:
213 case MISCREG_DC_CISW_Xt
:
214 trap_to_hyp
= hcr
.tsw
&& el
== EL1
;
217 case MISCREG_ACTLR_EL1
:
218 trap_to_hyp
= hcr
.tacr
&& el
== EL1
;
221 case MISCREG_APDAKeyHi_EL1
:
222 case MISCREG_APDAKeyLo_EL1
:
223 case MISCREG_APDBKeyHi_EL1
:
224 case MISCREG_APDBKeyLo_EL1
:
225 case MISCREG_APGAKeyHi_EL1
:
226 case MISCREG_APGAKeyLo_EL1
:
227 case MISCREG_APIAKeyHi_EL1
:
228 case MISCREG_APIAKeyLo_EL1
:
229 case MISCREG_APIBKeyHi_EL1
:
230 case MISCREG_APIBKeyLo_EL1
:
231 trap_to_hyp
= el
==EL1
&& hcr
.apk
== 0;
233 // @todo: Trap implementation-dependent functionality based on
237 case MISCREG_ID_PFR0_EL1
:
238 case MISCREG_ID_PFR1_EL1
:
239 case MISCREG_ID_DFR0_EL1
:
240 case MISCREG_ID_AFR0_EL1
:
241 case MISCREG_ID_MMFR0_EL1
:
242 case MISCREG_ID_MMFR1_EL1
:
243 case MISCREG_ID_MMFR2_EL1
:
244 case MISCREG_ID_MMFR3_EL1
:
245 case MISCREG_ID_ISAR0_EL1
:
246 case MISCREG_ID_ISAR1_EL1
:
247 case MISCREG_ID_ISAR2_EL1
:
248 case MISCREG_ID_ISAR3_EL1
:
249 case MISCREG_ID_ISAR4_EL1
:
250 case MISCREG_ID_ISAR5_EL1
:
251 case MISCREG_MVFR0_EL1
:
252 case MISCREG_MVFR1_EL1
:
253 case MISCREG_MVFR2_EL1
:
254 case MISCREG_ID_AA64PFR0_EL1
:
255 case MISCREG_ID_AA64PFR1_EL1
:
256 case MISCREG_ID_AA64DFR0_EL1
:
257 case MISCREG_ID_AA64DFR1_EL1
:
258 case MISCREG_ID_AA64ISAR0_EL1
:
259 case MISCREG_ID_AA64ISAR1_EL1
:
260 case MISCREG_ID_AA64MMFR0_EL1
:
261 case MISCREG_ID_AA64MMFR1_EL1
:
262 case MISCREG_ID_AA64MMFR2_EL1
:
263 case MISCREG_ID_AA64AFR0_EL1
:
264 case MISCREG_ID_AA64AFR1_EL1
:
266 trap_to_hyp
= hcr
.tid3
&& el
== EL1
;
269 case MISCREG_CTR_EL0
:
270 case MISCREG_CCSIDR_EL1
:
271 case MISCREG_CLIDR_EL1
:
272 case MISCREG_CSSELR_EL1
:
273 trap_to_hyp
= hcr
.tid2
&& el
<= EL1
;
276 case MISCREG_AIDR_EL1
:
277 case MISCREG_REVIDR_EL1
:
279 trap_to_hyp
= hcr
.tid1
&& el
== EL1
;
281 case MISCREG_IMPDEF_UNIMPL
:
282 trap_to_hyp
= hcr
.tidcp
&& el
== EL1
;
285 case MISCREG_ICC_SGI0R_EL1
:
287 auto *isa
= static_cast<ArmISA::ISA
*>(tc
->getIsaPtr());
288 if (isa
->haveGICv3CpuIfc())
289 trap_to_hyp
= hcr
.fmo
&& el
== EL1
;
292 case MISCREG_ICC_SGI1R_EL1
:
293 case MISCREG_ICC_ASGI1R_EL1
:
295 auto *isa
= static_cast<ArmISA::ISA
*>(tc
->getIsaPtr());
296 if (isa
->haveGICv3CpuIfc())
297 trap_to_hyp
= hcr
.imo
&& el
== EL1
;
301 case MISCREG_CNTFRQ_EL0
... MISCREG_CNTVOFF_EL2
:
302 trap_to_hyp
= el
<= EL1
&&
303 isGenericTimerSystemAccessTrapEL2(misc_reg
, tc
);
313 MiscRegOp64::checkEL3Trap(ThreadContext
*tc
, const MiscRegIndex misc_reg
,
314 ExceptionLevel el
, ExceptionClass
&ec
,
315 uint32_t &immediate
) const
317 const CPTR cptr
= tc
->readMiscReg(MISCREG_CPTR_EL3
);
318 const SCR scr
= tc
->readMiscReg(MISCREG_SCR_EL3
);
319 bool trap_to_mon
= false;
325 case MISCREG_FPEXC32_EL2
:
326 trap_to_mon
= cptr
.tfp
;
327 ec
= EC_TRAPPED_SIMD_FP
;
328 immediate
= 0x1E00000;
331 case MISCREG_CPACR_EL1
:
332 if (el
== EL1
|| el
== EL2
) {
333 trap_to_mon
= cptr
.tcpac
;
336 case MISCREG_CPTR_EL2
:
338 trap_to_mon
= cptr
.tcpac
;
341 case MISCREG_APDAKeyHi_EL1
:
342 case MISCREG_APDAKeyLo_EL1
:
343 case MISCREG_APDBKeyHi_EL1
:
344 case MISCREG_APDBKeyLo_EL1
:
345 case MISCREG_APGAKeyHi_EL1
:
346 case MISCREG_APGAKeyLo_EL1
:
347 case MISCREG_APIAKeyHi_EL1
:
348 case MISCREG_APIAKeyLo_EL1
:
349 case MISCREG_APIBKeyHi_EL1
:
350 case MISCREG_APIBKeyLo_EL1
:
351 trap_to_mon
= (el
==EL1
|| el
==EL2
) && scr
.apk
==0 && ELIs64(tc
, EL3
);
354 case MISCREG_CNTFRQ_EL0
... MISCREG_CNTVOFF_EL2
:
355 trap_to_mon
= el
== EL1
&&
356 isGenericTimerSystemAccessTrapEL3(misc_reg
, tc
);
365 MiscRegImmOp64::miscRegImm() const
367 if (dest
== MISCREG_SPSEL
) {
369 } else if (dest
== MISCREG_PAN
) {
370 return (imm
& 0x1) << 22;
372 panic("Not a valid PSTATE field register\n");
377 MiscRegImmOp64::generateDisassembly(Addr pc
, const SymbolTable
*symtab
) const
379 std::stringstream ss
;
381 printMiscReg(ss
, dest
);
383 ccprintf(ss
, "#0x%x", imm
);
388 MiscRegRegImmOp64::generateDisassembly(
389 Addr pc
, const SymbolTable
*symtab
) const
391 std::stringstream ss
;
393 printMiscReg(ss
, dest
);
395 printIntReg(ss
, op1
);
400 RegMiscRegImmOp64::generateDisassembly(
401 Addr pc
, const SymbolTable
*symtab
) const
403 std::stringstream ss
;
405 printIntReg(ss
, dest
);
407 printMiscReg(ss
, op1
);
412 MiscRegImplDefined64::execute(ExecContext
*xc
,
413 Trace::InstRecord
*traceData
) const
415 auto tc
= xc
->tcBase();
416 const CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
417 const ExceptionLevel el
= (ExceptionLevel
) (uint8_t) cpsr
.el
;
419 Fault fault
= trap(tc
, miscReg
, el
, imm
);
421 if (fault
!= NoFault
) {
424 } else if (warning
) {
425 warn_once("\tinstruction '%s' unimplemented\n", fullMnemonic
.c_str());
429 return std::make_shared
<UndefinedInstruction
>(machInst
, false,
435 MiscRegImplDefined64::generateDisassembly(Addr pc
,
436 const SymbolTable
*symtab
) const
438 return csprintf("%-10s (implementation defined)", fullMnemonic
.c_str());