arm: Delete authors lists from the arm files.
[gem5.git] / src / arch / arm / insts / misc64.cc
1 /*
2 * Copyright (c) 2011-2013,2017-2019 ARM Limited
3 * All rights reserved
4 *
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.
13 *
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.
24 *
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.
36 */
37
38 #include "arch/arm/insts/misc64.hh"
39 #include "arch/arm/isa.hh"
40
41 std::string
42 ImmOp64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
43 {
44 std::stringstream ss;
45 printMnemonic(ss, "", false);
46 ccprintf(ss, "#0x%x", imm);
47 return ss.str();
48 }
49
50 std::string
51 RegRegImmImmOp64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
52 {
53 std::stringstream ss;
54 printMnemonic(ss, "", false);
55 printIntReg(ss, dest);
56 ss << ", ";
57 printIntReg(ss, op1);
58 ccprintf(ss, ", #%d, #%d", imm1, imm2);
59 return ss.str();
60 }
61
62 std::string
63 RegRegRegImmOp64::generateDisassembly(
64 Addr pc, const SymbolTable *symtab) const
65 {
66 std::stringstream ss;
67 printMnemonic(ss, "", false);
68 printIntReg(ss, dest);
69 ss << ", ";
70 printIntReg(ss, op1);
71 ss << ", ";
72 printIntReg(ss, op2);
73 ccprintf(ss, ", #%d", imm);
74 return ss.str();
75 }
76
77 std::string
78 UnknownOp64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
79 {
80 return csprintf("%-10s (inst %#08x)", "unknown", encoding());
81 }
82
83 Fault
84 MiscRegOp64::trap(ThreadContext *tc, MiscRegIndex misc_reg,
85 ExceptionLevel el, uint32_t immediate) const
86 {
87 ExceptionClass ec = EC_TRAPPED_MSR_MRS_64;
88
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);
92 }
93
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);
98 }
99
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);
104 }
105
106 return NoFault;
107 }
108
109 bool
110 MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
111 ExceptionLevel el, ExceptionClass &ec,
112 uint32_t &immediate) const
113 {
114 const CPACR cpacr = tc->readMiscReg(MISCREG_CPACR_EL1);
115
116 bool trap_to_sup = false;
117 switch (misc_reg) {
118 case MISCREG_FPCR:
119 case MISCREG_FPSR:
120 case MISCREG_FPEXC32_EL2:
121 if ((el == EL0 && cpacr.fpen != 0x3) ||
122 (el == EL1 && !(cpacr.fpen & 0x1))) {
123 trap_to_sup = true;
124 ec = EC_TRAPPED_SIMD_FP;
125 immediate = 0x1E00000;
126 }
127 break;
128 default:
129 break;
130 }
131 return trap_to_sup;
132 }
133
134 bool
135 MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
136 ExceptionLevel el, ExceptionClass &ec,
137 uint32_t &immediate) const
138 {
139 const CPTR cptr = tc->readMiscReg(MISCREG_CPTR_EL2);
140 const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
141 const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
142 const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
143
144 bool trap_to_hyp = false;
145
146 if (!inSecureState(scr, cpsr) && (el != EL2)) {
147 switch (misc_reg) {
148 // FP/SIMD regs
149 case MISCREG_FPCR:
150 case MISCREG_FPSR:
151 case MISCREG_FPEXC32_EL2:
152 trap_to_hyp = cptr.tfp;
153 ec = EC_TRAPPED_SIMD_FP;
154 immediate = 0x1E00000;
155 break;
156 // CPACR
157 case MISCREG_CPACR_EL1:
158 trap_to_hyp = cptr.tcpac && el == EL1;
159 break;
160 // Virtual memory control regs
161 case MISCREG_SCTLR_EL1:
162 case MISCREG_TTBR0_EL1:
163 case MISCREG_TTBR1_EL1:
164 case MISCREG_TCR_EL1:
165 case MISCREG_ESR_EL1:
166 case MISCREG_FAR_EL1:
167 case MISCREG_AFSR0_EL1:
168 case MISCREG_AFSR1_EL1:
169 case MISCREG_MAIR_EL1:
170 case MISCREG_AMAIR_EL1:
171 case MISCREG_CONTEXTIDR_EL1:
172 trap_to_hyp =
173 ((hcr.trvm && miscRead) || (hcr.tvm && !miscRead)) &&
174 el == EL1;
175 break;
176 // TLB maintenance instructions
177 case MISCREG_TLBI_VMALLE1:
178 case MISCREG_TLBI_VAE1_Xt:
179 case MISCREG_TLBI_ASIDE1_Xt:
180 case MISCREG_TLBI_VAAE1_Xt:
181 case MISCREG_TLBI_VALE1_Xt:
182 case MISCREG_TLBI_VAALE1_Xt:
183 case MISCREG_TLBI_VMALLE1IS:
184 case MISCREG_TLBI_VAE1IS_Xt:
185 case MISCREG_TLBI_ASIDE1IS_Xt:
186 case MISCREG_TLBI_VAAE1IS_Xt:
187 case MISCREG_TLBI_VALE1IS_Xt:
188 case MISCREG_TLBI_VAALE1IS_Xt:
189 trap_to_hyp = hcr.ttlb && el == EL1;
190 break;
191 // Cache maintenance instructions to the point of unification
192 case MISCREG_IC_IVAU_Xt:
193 case MISCREG_ICIALLU:
194 case MISCREG_ICIALLUIS:
195 case MISCREG_DC_CVAU_Xt:
196 trap_to_hyp = hcr.tpu && el <= EL1;
197 break;
198 // Data/Unified cache maintenance instructions to the
199 // point of coherency
200 case MISCREG_DC_IVAC_Xt:
201 case MISCREG_DC_CIVAC_Xt:
202 case MISCREG_DC_CVAC_Xt:
203 trap_to_hyp = hcr.tpc && el <= EL1;
204 break;
205 // Data/Unified cache maintenance instructions by set/way
206 case MISCREG_DC_ISW_Xt:
207 case MISCREG_DC_CSW_Xt:
208 case MISCREG_DC_CISW_Xt:
209 trap_to_hyp = hcr.tsw && el == EL1;
210 break;
211 // ACTLR
212 case MISCREG_ACTLR_EL1:
213 trap_to_hyp = hcr.tacr && el == EL1;
214 break;
215
216 case MISCREG_APDAKeyHi_EL1:
217 case MISCREG_APDAKeyLo_EL1:
218 case MISCREG_APDBKeyHi_EL1:
219 case MISCREG_APDBKeyLo_EL1:
220 case MISCREG_APGAKeyHi_EL1:
221 case MISCREG_APGAKeyLo_EL1:
222 case MISCREG_APIAKeyHi_EL1:
223 case MISCREG_APIAKeyLo_EL1:
224 case MISCREG_APIBKeyHi_EL1:
225 case MISCREG_APIBKeyLo_EL1:
226 trap_to_hyp = el==EL1 && hcr.apk == 0;
227 break;
228 // @todo: Trap implementation-dependent functionality based on
229 // hcr.tidcp
230
231 // ID regs, group 3
232 case MISCREG_ID_PFR0_EL1:
233 case MISCREG_ID_PFR1_EL1:
234 case MISCREG_ID_DFR0_EL1:
235 case MISCREG_ID_AFR0_EL1:
236 case MISCREG_ID_MMFR0_EL1:
237 case MISCREG_ID_MMFR1_EL1:
238 case MISCREG_ID_MMFR2_EL1:
239 case MISCREG_ID_MMFR3_EL1:
240 case MISCREG_ID_ISAR0_EL1:
241 case MISCREG_ID_ISAR1_EL1:
242 case MISCREG_ID_ISAR2_EL1:
243 case MISCREG_ID_ISAR3_EL1:
244 case MISCREG_ID_ISAR4_EL1:
245 case MISCREG_ID_ISAR5_EL1:
246 case MISCREG_MVFR0_EL1:
247 case MISCREG_MVFR1_EL1:
248 case MISCREG_MVFR2_EL1:
249 case MISCREG_ID_AA64PFR0_EL1:
250 case MISCREG_ID_AA64PFR1_EL1:
251 case MISCREG_ID_AA64DFR0_EL1:
252 case MISCREG_ID_AA64DFR1_EL1:
253 case MISCREG_ID_AA64ISAR0_EL1:
254 case MISCREG_ID_AA64ISAR1_EL1:
255 case MISCREG_ID_AA64MMFR0_EL1:
256 case MISCREG_ID_AA64MMFR1_EL1:
257 case MISCREG_ID_AA64MMFR2_EL1:
258 case MISCREG_ID_AA64AFR0_EL1:
259 case MISCREG_ID_AA64AFR1_EL1:
260 assert(miscRead);
261 trap_to_hyp = hcr.tid3 && el == EL1;
262 break;
263 // ID regs, group 2
264 case MISCREG_CTR_EL0:
265 case MISCREG_CCSIDR_EL1:
266 case MISCREG_CLIDR_EL1:
267 case MISCREG_CSSELR_EL1:
268 trap_to_hyp = hcr.tid2 && el <= EL1;
269 break;
270 // ID regs, group 1
271 case MISCREG_AIDR_EL1:
272 case MISCREG_REVIDR_EL1:
273 assert(miscRead);
274 trap_to_hyp = hcr.tid1 && el == EL1;
275 break;
276 case MISCREG_IMPDEF_UNIMPL:
277 trap_to_hyp = hcr.tidcp && el == EL1;
278 break;
279 // GICv3 regs
280 case MISCREG_ICC_SGI0R_EL1:
281 {
282 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
283 if (isa->haveGICv3CpuIfc())
284 trap_to_hyp = hcr.fmo && el == EL1;
285 }
286 break;
287 case MISCREG_ICC_SGI1R_EL1:
288 case MISCREG_ICC_ASGI1R_EL1:
289 {
290 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
291 if (isa->haveGICv3CpuIfc())
292 trap_to_hyp = hcr.imo && el == EL1;
293 }
294 break;
295 default:
296 break;
297 }
298 }
299 return trap_to_hyp;
300 }
301
302 bool
303 MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
304 ExceptionLevel el, ExceptionClass &ec,
305 uint32_t &immediate) const
306 {
307 const CPTR cptr = tc->readMiscReg(MISCREG_CPTR_EL3);
308 const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
309 bool trap_to_mon = false;
310
311 switch (misc_reg) {
312 // FP/SIMD regs
313 case MISCREG_FPCR:
314 case MISCREG_FPSR:
315 case MISCREG_FPEXC32_EL2:
316 trap_to_mon = cptr.tfp;
317 ec = EC_TRAPPED_SIMD_FP;
318 immediate = 0x1E00000;
319 break;
320 // CPACR, CPTR
321 case MISCREG_CPACR_EL1:
322 if (el == EL1 || el == EL2) {
323 trap_to_mon = cptr.tcpac;
324 }
325 break;
326 case MISCREG_CPTR_EL2:
327 if (el == EL2) {
328 trap_to_mon = cptr.tcpac;
329 }
330 break;
331 case MISCREG_APDAKeyHi_EL1:
332 case MISCREG_APDAKeyLo_EL1:
333 case MISCREG_APDBKeyHi_EL1:
334 case MISCREG_APDBKeyLo_EL1:
335 case MISCREG_APGAKeyHi_EL1:
336 case MISCREG_APGAKeyLo_EL1:
337 case MISCREG_APIAKeyHi_EL1:
338 case MISCREG_APIAKeyLo_EL1:
339 case MISCREG_APIBKeyHi_EL1:
340 case MISCREG_APIBKeyLo_EL1:
341 trap_to_mon = (el==EL1 || el==EL2) && scr.apk==0 && ELIs64(tc, EL3);
342 break;
343 default:
344 break;
345 }
346 return trap_to_mon;
347 }
348
349 RegVal
350 MiscRegImmOp64::miscRegImm() const
351 {
352 if (dest == MISCREG_SPSEL) {
353 return imm & 0x1;
354 } else if (dest == MISCREG_PAN) {
355 return (imm & 0x1) << 22;
356 } else {
357 panic("Not a valid PSTATE field register\n");
358 }
359 }
360
361 std::string
362 MiscRegImmOp64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
363 {
364 std::stringstream ss;
365 printMnemonic(ss);
366 printMiscReg(ss, dest);
367 ss << ", ";
368 ccprintf(ss, "#0x%x", imm);
369 return ss.str();
370 }
371
372 std::string
373 MiscRegRegImmOp64::generateDisassembly(
374 Addr pc, const SymbolTable *symtab) const
375 {
376 std::stringstream ss;
377 printMnemonic(ss);
378 printMiscReg(ss, dest);
379 ss << ", ";
380 printIntReg(ss, op1);
381 return ss.str();
382 }
383
384 std::string
385 RegMiscRegImmOp64::generateDisassembly(
386 Addr pc, const SymbolTable *symtab) const
387 {
388 std::stringstream ss;
389 printMnemonic(ss);
390 printIntReg(ss, dest);
391 ss << ", ";
392 printMiscReg(ss, op1);
393 return ss.str();
394 }
395
396 Fault
397 MiscRegImplDefined64::execute(ExecContext *xc,
398 Trace::InstRecord *traceData) const
399 {
400 auto tc = xc->tcBase();
401 const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
402 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
403
404 Fault fault = trap(tc, miscReg, el, imm);
405
406 if (fault != NoFault) {
407 return fault;
408
409 } else if (warning) {
410 warn_once("\tinstruction '%s' unimplemented\n", fullMnemonic.c_str());
411 return NoFault;
412
413 } else {
414 return std::make_shared<UndefinedInstruction>(machInst, false,
415 mnemonic);
416 }
417 }
418
419 std::string
420 MiscRegImplDefined64::generateDisassembly(Addr pc,
421 const SymbolTable *symtab) const
422 {
423 return csprintf("%-10s (implementation defined)", fullMnemonic.c_str());
424 }