utility.cc (10103:af1ec649e251) utility.cc (10190:fb83d025d1c3)
1/*
2 * Copyright (c) 2009-2013 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 * Authors: Ali Saidi
38 */
39
40
41#include "arch/arm/faults.hh"
42#include "arch/arm/isa_traits.hh"
43#include "arch/arm/system.hh"
44#include "arch/arm/tlb.hh"
45#include "arch/arm/utility.hh"
46#include "arch/arm/vtophys.hh"
47#include "cpu/checker/cpu.hh"
48#include "cpu/base.hh"
49#include "cpu/thread_context.hh"
50#include "mem/fs_translating_port_proxy.hh"
51#include "sim/full_system.hh"
52
53namespace ArmISA {
54
55void
56initCPU(ThreadContext *tc, int cpuId)
57{
58 // Reset CP15?? What does that mean -- ali
59
60 // FPEXC.EN = 0
61
62 static Fault reset = new Reset;
63 reset->invoke(tc);
64}
65
66uint64_t
67getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
68{
69 if (!FullSystem) {
70 panic("getArgument() only implemented for full system mode.\n");
71 M5_DUMMY_RETURN
72 }
73
74 if (fp)
75 panic("getArgument(): Floating point arguments not implemented\n");
76
77 if (inAArch64(tc)) {
78 if (size == (uint16_t)(-1))
79 size = sizeof(uint64_t);
80
81 if (number < 8 /*NumArgumentRegs64*/) {
82 return tc->readIntReg(number);
83 } else {
84 panic("getArgument(): No support reading stack args for AArch64\n");
85 }
86 } else {
87 if (size == (uint16_t)(-1))
88 size = ArmISA::MachineBytes;
89
90 if (number < NumArgumentRegs) {
91 // If the argument is 64 bits, it must be in an even regiser
92 // number. Increment the number here if it isn't even.
93 if (size == sizeof(uint64_t)) {
94 if ((number % 2) != 0)
95 number++;
96 // Read the two halves of the data. Number is inc here to
97 // get the second half of the 64 bit reg.
98 uint64_t tmp;
99 tmp = tc->readIntReg(number++);
100 tmp |= tc->readIntReg(number) << 32;
101 return tmp;
102 } else {
103 return tc->readIntReg(number);
104 }
105 } else {
106 Addr sp = tc->readIntReg(StackPointerReg);
107 FSTranslatingPortProxy &vp = tc->getVirtProxy();
108 uint64_t arg;
109 if (size == sizeof(uint64_t)) {
110 // If the argument is even it must be aligned
111 if ((number % 2) != 0)
112 number++;
113 arg = vp.read<uint64_t>(sp +
114 (number-NumArgumentRegs) * sizeof(uint32_t));
115 // since two 32 bit args == 1 64 bit arg, increment number
116 number++;
117 } else {
118 arg = vp.read<uint32_t>(sp +
119 (number-NumArgumentRegs) * sizeof(uint32_t));
120 }
121 return arg;
122 }
123 }
124 panic("getArgument() should always return\n");
125}
126
127void
128skipFunction(ThreadContext *tc)
129{
130 PCState newPC = tc->pcState();
131 if (inAArch64(tc)) {
132 newPC.set(tc->readIntReg(INTREG_X30));
133 } else {
134 newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
135 }
136
137 CheckerCPU *checker = tc->getCheckerCpuPtr();
138 if (checker) {
139 tc->pcStateNoRecord(newPC);
140 } else {
141 tc->pcState(newPC);
142 }
143}
144
145void
146copyRegs(ThreadContext *src, ThreadContext *dest)
147{
148 for (int i = 0; i < NumIntRegs; i++)
149 dest->setIntRegFlat(i, src->readIntRegFlat(i));
150
151 for (int i = 0; i < NumFloatRegs; i++)
152 dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
153
154 // Would need to add condition-code regs if implemented
155 assert(NumCCRegs == 0);
156
157 for (int i = 0; i < NumMiscRegs; i++)
158 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
159
160 // setMiscReg "with effect" will set the misc register mapping correctly.
161 // e.g. updateRegMap(val)
162 dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
163
164 // Copy over the PC State
165 dest->pcState(src->pcState());
166
167 // Invalidate the tlb misc register cache
168 dest->getITBPtr()->invalidateMiscReg();
169 dest->getDTBPtr()->invalidateMiscReg();
170}
171
172bool
173inSecureState(ThreadContext *tc)
174{
175 SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) :
176 tc->readMiscReg(MISCREG_SCR);
177 return ArmSystem::haveSecurity(tc) && inSecureState(
178 scr, tc->readMiscReg(MISCREG_CPSR));
179}
180
181bool
182inAArch64(ThreadContext *tc)
183{
184 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
185 return opModeIs64((OperatingMode) (uint8_t) cpsr.mode);
186}
187
188bool
189longDescFormatInUse(ThreadContext *tc)
190{
191 TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR);
192 return ArmSystem::haveLPAE(tc) && ttbcr.eae;
193}
194
195uint32_t
196getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
197{
1/*
2 * Copyright (c) 2009-2013 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 * Authors: Ali Saidi
38 */
39
40
41#include "arch/arm/faults.hh"
42#include "arch/arm/isa_traits.hh"
43#include "arch/arm/system.hh"
44#include "arch/arm/tlb.hh"
45#include "arch/arm/utility.hh"
46#include "arch/arm/vtophys.hh"
47#include "cpu/checker/cpu.hh"
48#include "cpu/base.hh"
49#include "cpu/thread_context.hh"
50#include "mem/fs_translating_port_proxy.hh"
51#include "sim/full_system.hh"
52
53namespace ArmISA {
54
55void
56initCPU(ThreadContext *tc, int cpuId)
57{
58 // Reset CP15?? What does that mean -- ali
59
60 // FPEXC.EN = 0
61
62 static Fault reset = new Reset;
63 reset->invoke(tc);
64}
65
66uint64_t
67getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
68{
69 if (!FullSystem) {
70 panic("getArgument() only implemented for full system mode.\n");
71 M5_DUMMY_RETURN
72 }
73
74 if (fp)
75 panic("getArgument(): Floating point arguments not implemented\n");
76
77 if (inAArch64(tc)) {
78 if (size == (uint16_t)(-1))
79 size = sizeof(uint64_t);
80
81 if (number < 8 /*NumArgumentRegs64*/) {
82 return tc->readIntReg(number);
83 } else {
84 panic("getArgument(): No support reading stack args for AArch64\n");
85 }
86 } else {
87 if (size == (uint16_t)(-1))
88 size = ArmISA::MachineBytes;
89
90 if (number < NumArgumentRegs) {
91 // If the argument is 64 bits, it must be in an even regiser
92 // number. Increment the number here if it isn't even.
93 if (size == sizeof(uint64_t)) {
94 if ((number % 2) != 0)
95 number++;
96 // Read the two halves of the data. Number is inc here to
97 // get the second half of the 64 bit reg.
98 uint64_t tmp;
99 tmp = tc->readIntReg(number++);
100 tmp |= tc->readIntReg(number) << 32;
101 return tmp;
102 } else {
103 return tc->readIntReg(number);
104 }
105 } else {
106 Addr sp = tc->readIntReg(StackPointerReg);
107 FSTranslatingPortProxy &vp = tc->getVirtProxy();
108 uint64_t arg;
109 if (size == sizeof(uint64_t)) {
110 // If the argument is even it must be aligned
111 if ((number % 2) != 0)
112 number++;
113 arg = vp.read<uint64_t>(sp +
114 (number-NumArgumentRegs) * sizeof(uint32_t));
115 // since two 32 bit args == 1 64 bit arg, increment number
116 number++;
117 } else {
118 arg = vp.read<uint32_t>(sp +
119 (number-NumArgumentRegs) * sizeof(uint32_t));
120 }
121 return arg;
122 }
123 }
124 panic("getArgument() should always return\n");
125}
126
127void
128skipFunction(ThreadContext *tc)
129{
130 PCState newPC = tc->pcState();
131 if (inAArch64(tc)) {
132 newPC.set(tc->readIntReg(INTREG_X30));
133 } else {
134 newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
135 }
136
137 CheckerCPU *checker = tc->getCheckerCpuPtr();
138 if (checker) {
139 tc->pcStateNoRecord(newPC);
140 } else {
141 tc->pcState(newPC);
142 }
143}
144
145void
146copyRegs(ThreadContext *src, ThreadContext *dest)
147{
148 for (int i = 0; i < NumIntRegs; i++)
149 dest->setIntRegFlat(i, src->readIntRegFlat(i));
150
151 for (int i = 0; i < NumFloatRegs; i++)
152 dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
153
154 // Would need to add condition-code regs if implemented
155 assert(NumCCRegs == 0);
156
157 for (int i = 0; i < NumMiscRegs; i++)
158 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
159
160 // setMiscReg "with effect" will set the misc register mapping correctly.
161 // e.g. updateRegMap(val)
162 dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
163
164 // Copy over the PC State
165 dest->pcState(src->pcState());
166
167 // Invalidate the tlb misc register cache
168 dest->getITBPtr()->invalidateMiscReg();
169 dest->getDTBPtr()->invalidateMiscReg();
170}
171
172bool
173inSecureState(ThreadContext *tc)
174{
175 SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) :
176 tc->readMiscReg(MISCREG_SCR);
177 return ArmSystem::haveSecurity(tc) && inSecureState(
178 scr, tc->readMiscReg(MISCREG_CPSR));
179}
180
181bool
182inAArch64(ThreadContext *tc)
183{
184 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
185 return opModeIs64((OperatingMode) (uint8_t) cpsr.mode);
186}
187
188bool
189longDescFormatInUse(ThreadContext *tc)
190{
191 TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR);
192 return ArmSystem::haveLPAE(tc) && ttbcr.eae;
193}
194
195uint32_t
196getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
197{
198 // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
199 // Reference Manual
200 //
201 // bit 31 - Multi-processor extensions available
202 // bit 30 - Uni-processor system
203 // bit 24 - Multi-threaded cores
204 // bit 11-8 - Cluster ID
205 // bit 1-0 - CPU ID
206 //
207 // We deliberately extend both the Cluster ID and CPU ID fields to allow
208 // for simulation of larger systems
209 assert((0 <= tc->cpuId()) && (tc->cpuId() < 256));
210 assert((0 <= tc->socketId()) && (tc->socketId() < 65536));
198 if (arm_sys->multiProc) {
199 return 0x80000000 | // multiprocessor extensions available
211 if (arm_sys->multiProc) {
212 return 0x80000000 | // multiprocessor extensions available
200 tc->cpuId();
213 tc->cpuId() | tc->socketId() << 8;
201 } else {
202 return 0x80000000 | // multiprocessor extensions available
203 0x40000000 | // in up system
214 } else {
215 return 0x80000000 | // multiprocessor extensions available
216 0x40000000 | // in up system
204 tc->cpuId();
217 tc->cpuId() | tc->socketId() << 8;
205 }
206}
207
208bool
209ELIs64(ThreadContext *tc, ExceptionLevel el)
210{
211 if (ArmSystem::highestEL(tc) == el)
212 // Register width is hard-wired
213 return ArmSystem::highestELIs64(tc);
214
215 switch (el) {
216 case EL0:
217 return opModeIs64(currOpMode(tc));
218 case EL1:
219 {
220 // @todo: uncomment this to enable Virtualization
221 // if (ArmSystem::haveVirtualization(tc)) {
222 // HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
223 // return hcr.rw;
224 // }
225 assert(ArmSystem::haveSecurity(tc));
226 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
227 return scr.rw;
228 }
229 case EL2:
230 {
231 assert(ArmSystem::haveSecurity(tc));
232 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
233 return scr.rw;
234 }
235 default:
236 panic("Invalid exception level");
237 break;
238 }
239}
240
241bool
242isBigEndian64(ThreadContext *tc)
243{
244 switch (opModeToEL(currOpMode(tc))) {
245 case EL3:
246 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee;
247 case EL2:
248 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee;
249 case EL1:
250 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee;
251 case EL0:
252 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e;
253 default:
254 panic("Invalid exception level");
255 break;
256 }
257}
258
259Addr
260purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el)
261{
262 TTBCR tcr;
263
264 switch (el) {
265 case EL0:
266 case EL1:
267 tcr = tc->readMiscReg(MISCREG_TCR_EL1);
268 if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
269 return addr | mask(63, 55);
270 else if (!bits(addr, 55, 48) && tcr.tbi0)
271 return bits(addr,55, 0);
272 break;
273 // @todo: uncomment this to enable Virtualization
274 // case EL2:
275 // assert(ArmSystem::haveVirtualization());
276 // tcr = tc->readMiscReg(MISCREG_TCR_EL2);
277 // if (tcr.tbi)
278 // return addr & mask(56);
279 // break;
280 case EL3:
281 assert(ArmSystem::haveSecurity(tc));
282 tcr = tc->readMiscReg(MISCREG_TCR_EL3);
283 if (tcr.tbi)
284 return addr & mask(56);
285 break;
286 default:
287 panic("Invalid exception level");
288 break;
289 }
290
291 return addr; // Nothing to do if this is not a tagged address
292}
293
294Addr
295truncPage(Addr addr)
296{
297 return addr & ~(PageBytes - 1);
298}
299
300Addr
301roundPage(Addr addr)
302{
303 return (addr + PageBytes - 1) & ~(PageBytes - 1);
304}
305
306bool
307mcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
308 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
309{
310 bool isRead;
311 uint32_t crm;
312 IntRegIndex rt;
313 uint32_t crn;
314 uint32_t opc1;
315 uint32_t opc2;
316 bool trapToHype = false;
317
318
319 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
320 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
321 trapToHype = ((uint32_t) hstr) & (1 << crn);
322 trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12);
323 trapToHype |= hcr.tidcp && (
324 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
325 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
326 ((crn == 11) && ((crm <= 8) || (crm == 15))) );
327
328 if (!trapToHype) {
329 switch (unflattenMiscReg(miscReg)) {
330 case MISCREG_CPACR:
331 trapToHype = hcptr.tcpac;
332 break;
333 case MISCREG_REVIDR:
334 case MISCREG_TCMTR:
335 case MISCREG_TLBTR:
336 case MISCREG_AIDR:
337 trapToHype = hcr.tid1;
338 break;
339 case MISCREG_CTR:
340 case MISCREG_CCSIDR:
341 case MISCREG_CLIDR:
342 case MISCREG_CSSELR:
343 trapToHype = hcr.tid2;
344 break;
345 case MISCREG_ID_PFR0:
346 case MISCREG_ID_PFR1:
347 case MISCREG_ID_DFR0:
348 case MISCREG_ID_AFR0:
349 case MISCREG_ID_MMFR0:
350 case MISCREG_ID_MMFR1:
351 case MISCREG_ID_MMFR2:
352 case MISCREG_ID_MMFR3:
353 case MISCREG_ID_ISAR0:
354 case MISCREG_ID_ISAR1:
355 case MISCREG_ID_ISAR2:
356 case MISCREG_ID_ISAR3:
357 case MISCREG_ID_ISAR4:
358 case MISCREG_ID_ISAR5:
359 trapToHype = hcr.tid3;
360 break;
361 case MISCREG_DCISW:
362 case MISCREG_DCCSW:
363 case MISCREG_DCCISW:
364 trapToHype = hcr.tsw;
365 break;
366 case MISCREG_DCIMVAC:
367 case MISCREG_DCCIMVAC:
368 case MISCREG_DCCMVAC:
369 trapToHype = hcr.tpc;
370 break;
371 case MISCREG_ICIMVAU:
372 case MISCREG_ICIALLU:
373 case MISCREG_ICIALLUIS:
374 case MISCREG_DCCMVAU:
375 trapToHype = hcr.tpu;
376 break;
377 case MISCREG_TLBIALLIS:
378 case MISCREG_TLBIMVAIS:
379 case MISCREG_TLBIASIDIS:
380 case MISCREG_TLBIMVAAIS:
381 case MISCREG_DTLBIALL:
382 case MISCREG_ITLBIALL:
383 case MISCREG_DTLBIMVA:
384 case MISCREG_ITLBIMVA:
385 case MISCREG_DTLBIASID:
386 case MISCREG_ITLBIASID:
387 case MISCREG_TLBIMVAA:
388 case MISCREG_TLBIALL:
389 case MISCREG_TLBIMVA:
390 case MISCREG_TLBIASID:
391 trapToHype = hcr.ttlb;
392 break;
393 case MISCREG_ACTLR:
394 trapToHype = hcr.tac;
395 break;
396 case MISCREG_SCTLR:
397 case MISCREG_TTBR0:
398 case MISCREG_TTBR1:
399 case MISCREG_TTBCR:
400 case MISCREG_DACR:
401 case MISCREG_DFSR:
402 case MISCREG_IFSR:
403 case MISCREG_DFAR:
404 case MISCREG_IFAR:
405 case MISCREG_ADFSR:
406 case MISCREG_AIFSR:
407 case MISCREG_PRRR:
408 case MISCREG_NMRR:
409 case MISCREG_MAIR0:
410 case MISCREG_MAIR1:
411 case MISCREG_CONTEXTIDR:
412 trapToHype = hcr.tvm & !isRead;
413 break;
414 case MISCREG_PMCR:
415 trapToHype = hdcr.tpmcr;
416 break;
417 // No default action needed
418 default:
419 break;
420 }
421 }
422 }
423 return trapToHype;
424}
425
426
427bool
428mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
429 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
430{
431 bool isRead;
432 uint32_t crm;
433 IntRegIndex rt;
434 uint32_t crn;
435 uint32_t opc1;
436 uint32_t opc2;
437 bool trapToHype = false;
438
439 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
440 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
441 inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
442 crm, crn, opc1, opc2, hdcr, hcptr, hstr);
443 trapToHype = hdcr.tda && (opc1 == 0);
444 trapToHype |= hcptr.tta && (opc1 == 1);
445 if (!trapToHype) {
446 switch (unflattenMiscReg(miscReg)) {
447 case MISCREG_DBGOSLSR:
448 case MISCREG_DBGOSLAR:
449 case MISCREG_DBGOSDLR:
450 case MISCREG_DBGPRCR:
451 trapToHype = hdcr.tdosa;
452 break;
453 case MISCREG_DBGDRAR:
454 case MISCREG_DBGDSAR:
455 trapToHype = hdcr.tdra;
456 break;
457 case MISCREG_JIDR:
458 trapToHype = hcr.tid0;
459 break;
460 case MISCREG_JOSCR:
461 case MISCREG_JMCR:
462 trapToHype = hstr.tjdbx;
463 break;
464 case MISCREG_TEECR:
465 case MISCREG_TEEHBR:
466 trapToHype = hstr.ttee;
467 break;
468 // No default action needed
469 default:
470 break;
471 }
472 }
473 }
474 return trapToHype;
475}
476
477bool
478mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
479 HCR hcr, uint32_t iss)
480{
481 uint32_t crm;
482 IntRegIndex rt;
483 uint32_t crn;
484 uint32_t opc1;
485 uint32_t opc2;
486 bool isRead;
487 bool trapToHype = false;
488
489 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
490 // This is technically the wrong function, but we can re-use it for
491 // the moment because we only need one field, which overlaps with the
492 // mcrmrc layout
493 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
494 trapToHype = ((uint32_t) hstr) & (1 << crm);
495
496 if (!trapToHype) {
497 switch (unflattenMiscReg(miscReg)) {
498 case MISCREG_SCTLR:
499 case MISCREG_TTBR0:
500 case MISCREG_TTBR1:
501 case MISCREG_TTBCR:
502 case MISCREG_DACR:
503 case MISCREG_DFSR:
504 case MISCREG_IFSR:
505 case MISCREG_DFAR:
506 case MISCREG_IFAR:
507 case MISCREG_ADFSR:
508 case MISCREG_AIFSR:
509 case MISCREG_PRRR:
510 case MISCREG_NMRR:
511 case MISCREG_MAIR0:
512 case MISCREG_MAIR1:
513 case MISCREG_CONTEXTIDR:
514 trapToHype = hcr.tvm & !isRead;
515 break;
516 // No default action needed
517 default:
518 break;
519 }
520 }
521 }
522 return trapToHype;
523}
524
525bool
526msrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el,
527 CPACR cpacr /* CPACR_EL1 */)
528{
529 bool trapToSup = false;
530 switch (miscReg) {
531 case MISCREG_FPCR:
532 case MISCREG_FPSR:
533 case MISCREG_FPEXC32_EL2:
534 if ((el == EL0 && cpacr.fpen != 0x3) ||
535 (el == EL1 && !(cpacr.fpen & 0x1)))
536 trapToSup = true;
537 break;
538 default:
539 break;
540 }
541 return trapToSup;
542}
543
544bool
545msrMrs64TrapToHyp(const MiscRegIndex miscReg, bool isRead,
546 CPTR cptr /* CPTR_EL2 */,
547 HCR hcr /* HCR_EL2 */,
548 bool * isVfpNeon)
549{
550 bool trapToHyp = false;
551 *isVfpNeon = false;
552
553 switch (miscReg) {
554 // FP/SIMD regs
555 case MISCREG_FPCR:
556 case MISCREG_FPSR:
557 case MISCREG_FPEXC32_EL2:
558 trapToHyp = cptr.tfp;
559 *isVfpNeon = true;
560 break;
561 // CPACR
562 case MISCREG_CPACR_EL1:
563 trapToHyp = cptr.tcpac;
564 break;
565 // Virtual memory control regs
566 case MISCREG_SCTLR_EL1:
567 case MISCREG_TTBR0_EL1:
568 case MISCREG_TTBR1_EL1:
569 case MISCREG_TCR_EL1:
570 case MISCREG_ESR_EL1:
571 case MISCREG_FAR_EL1:
572 case MISCREG_AFSR0_EL1:
573 case MISCREG_AFSR1_EL1:
574 case MISCREG_MAIR_EL1:
575 case MISCREG_AMAIR_EL1:
576 case MISCREG_CONTEXTIDR_EL1:
577 trapToHyp = (hcr.trvm && isRead) || (hcr.tvm && !isRead);
578 break;
579 // TLB maintenance instructions
580 case MISCREG_TLBI_VMALLE1:
581 case MISCREG_TLBI_VAE1_Xt:
582 case MISCREG_TLBI_ASIDE1_Xt:
583 case MISCREG_TLBI_VAAE1_Xt:
584 case MISCREG_TLBI_VALE1_Xt:
585 case MISCREG_TLBI_VAALE1_Xt:
586 case MISCREG_TLBI_VMALLE1IS:
587 case MISCREG_TLBI_VAE1IS_Xt:
588 case MISCREG_TLBI_ASIDE1IS_Xt:
589 case MISCREG_TLBI_VAAE1IS_Xt:
590 case MISCREG_TLBI_VALE1IS_Xt:
591 case MISCREG_TLBI_VAALE1IS_Xt:
592 trapToHyp = hcr.ttlb;
593 break;
594 // Cache maintenance instructions to the point of unification
595 case MISCREG_IC_IVAU_Xt:
596 case MISCREG_ICIALLU:
597 case MISCREG_ICIALLUIS:
598 case MISCREG_DC_CVAU_Xt:
599 trapToHyp = hcr.tpu;
600 break;
601 // Data/Unified cache maintenance instructions to the point of coherency
602 case MISCREG_DC_IVAC_Xt:
603 case MISCREG_DC_CIVAC_Xt:
604 case MISCREG_DC_CVAC_Xt:
605 trapToHyp = hcr.tpc;
606 break;
607 // Data/Unified cache maintenance instructions by set/way
608 case MISCREG_DC_ISW_Xt:
609 case MISCREG_DC_CSW_Xt:
610 case MISCREG_DC_CISW_Xt:
611 trapToHyp = hcr.tsw;
612 break;
613 // ACTLR
614 case MISCREG_ACTLR_EL1:
615 trapToHyp = hcr.tacr;
616 break;
617
618 // @todo: Trap implementation-dependent functionality based on
619 // hcr.tidcp
620
621 // ID regs, group 3
622 case MISCREG_ID_PFR0_EL1:
623 case MISCREG_ID_PFR1_EL1:
624 case MISCREG_ID_DFR0_EL1:
625 case MISCREG_ID_AFR0_EL1:
626 case MISCREG_ID_MMFR0_EL1:
627 case MISCREG_ID_MMFR1_EL1:
628 case MISCREG_ID_MMFR2_EL1:
629 case MISCREG_ID_MMFR3_EL1:
630 case MISCREG_ID_ISAR0_EL1:
631 case MISCREG_ID_ISAR1_EL1:
632 case MISCREG_ID_ISAR2_EL1:
633 case MISCREG_ID_ISAR3_EL1:
634 case MISCREG_ID_ISAR4_EL1:
635 case MISCREG_ID_ISAR5_EL1:
636 case MISCREG_MVFR0_EL1:
637 case MISCREG_MVFR1_EL1:
638 case MISCREG_MVFR2_EL1:
639 case MISCREG_ID_AA64PFR0_EL1:
640 case MISCREG_ID_AA64PFR1_EL1:
641 case MISCREG_ID_AA64DFR0_EL1:
642 case MISCREG_ID_AA64DFR1_EL1:
643 case MISCREG_ID_AA64ISAR0_EL1:
644 case MISCREG_ID_AA64ISAR1_EL1:
645 case MISCREG_ID_AA64MMFR0_EL1:
646 case MISCREG_ID_AA64MMFR1_EL1:
647 case MISCREG_ID_AA64AFR0_EL1:
648 case MISCREG_ID_AA64AFR1_EL1:
649 assert(isRead);
650 trapToHyp = hcr.tid3;
651 break;
652 // ID regs, group 2
653 case MISCREG_CTR_EL0:
654 case MISCREG_CCSIDR_EL1:
655 case MISCREG_CLIDR_EL1:
656 case MISCREG_CSSELR_EL1:
657 trapToHyp = hcr.tid2;
658 break;
659 // ID regs, group 1
660 case MISCREG_AIDR_EL1:
661 case MISCREG_REVIDR_EL1:
662 assert(isRead);
663 trapToHyp = hcr.tid1;
664 break;
665 default:
666 break;
667 }
668 return trapToHyp;
669}
670
671bool
672msrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */,
673 ExceptionLevel el, bool * isVfpNeon)
674{
675 bool trapToMon = false;
676 *isVfpNeon = false;
677
678 switch (miscReg) {
679 // FP/SIMD regs
680 case MISCREG_FPCR:
681 case MISCREG_FPSR:
682 case MISCREG_FPEXC32_EL2:
683 trapToMon = cptr.tfp;
684 *isVfpNeon = true;
685 break;
686 // CPACR, CPTR
687 case MISCREG_CPACR_EL1:
688 if (el == EL1) {
689 trapToMon = cptr.tcpac;
690 }
691 break;
692 case MISCREG_CPTR_EL2:
693 if (el == EL2) {
694 trapToMon = cptr.tcpac;
695 }
696 break;
697 default:
698 break;
699 }
700 return trapToMon;
701}
702
703bool
704decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
705 CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
706{
707 OperatingMode mode = MODE_UNDEFINED;
708 bool ok = true;
709
710 // R mostly indicates if its a int register or a misc reg, we override
711 // below if the few corner cases
712 isIntReg = !r;
713 // Loosely based on ARM ARM issue C section B9.3.10
714 if (r) {
715 switch (sysM)
716 {
717 case 0xE:
718 regIdx = MISCREG_SPSR_FIQ;
719 mode = MODE_FIQ;
720 break;
721 case 0x10:
722 regIdx = MISCREG_SPSR_IRQ;
723 mode = MODE_IRQ;
724 break;
725 case 0x12:
726 regIdx = MISCREG_SPSR_SVC;
727 mode = MODE_SVC;
728 break;
729 case 0x14:
730 regIdx = MISCREG_SPSR_ABT;
731 mode = MODE_ABORT;
732 break;
733 case 0x16:
734 regIdx = MISCREG_SPSR_UND;
735 mode = MODE_UNDEFINED;
736 break;
737 case 0x1C:
738 regIdx = MISCREG_SPSR_MON;
739 mode = MODE_MON;
740 break;
741 case 0x1E:
742 regIdx = MISCREG_SPSR_HYP;
743 mode = MODE_HYP;
744 break;
745 default:
746 ok = false;
747 break;
748 }
749 } else {
750 int sysM4To3 = bits(sysM, 4, 3);
751
752 if (sysM4To3 == 0) {
753 mode = MODE_USER;
754 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
755 } else if (sysM4To3 == 1) {
756 mode = MODE_FIQ;
757 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
758 } else if (sysM4To3 == 3) {
759 if (bits(sysM, 1) == 0) {
760 mode = MODE_MON;
761 regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
762 } else {
763 mode = MODE_HYP;
764 if (bits(sysM, 0) == 1) {
765 regIdx = intRegInMode(mode, 13); // R13 in HYP
766 } else {
767 isIntReg = false;
768 regIdx = MISCREG_ELR_HYP;
769 }
770 }
771 } else { // Other Banked registers
772 int sysM2 = bits(sysM, 2);
773 int sysM1 = bits(sysM, 1);
774
775 mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) |
776 (1 << 1) |
777 ((sysM2 && !sysM1) << 2) |
778 ((sysM2 && sysM1) << 3) |
779 (1 << 4) );
780 regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
781 // Don't flatten the register here. This is going to go through
782 // setIntReg() which will do the flattening
783 ok &= mode != cpsr.mode;
784 }
785 }
786
787 // Check that the requested register is accessable from the current mode
788 if (ok && checkSecurity && mode != cpsr.mode) {
789 switch (cpsr.mode)
790 {
791 case MODE_USER:
792 ok = false;
793 break;
794 case MODE_FIQ:
795 ok &= mode != MODE_HYP;
796 ok &= (mode != MODE_MON) || !scr.ns;
797 break;
798 case MODE_HYP:
799 ok &= mode != MODE_MON;
800 ok &= (mode != MODE_FIQ) || !nsacr.rfr;
801 break;
802 case MODE_IRQ:
803 case MODE_SVC:
804 case MODE_ABORT:
805 case MODE_UNDEFINED:
806 case MODE_SYSTEM:
807 ok &= mode != MODE_HYP;
808 ok &= (mode != MODE_MON) || !scr.ns;
809 ok &= (mode != MODE_FIQ) || !nsacr.rfr;
810 break;
811 // can access everything, no further checks required
812 case MODE_MON:
813 break;
814 default:
815 panic("unknown Mode 0x%x\n", cpsr.mode);
816 break;
817 }
818 }
819 return (ok);
820}
821
822bool
823vfpNeonEnabled(uint32_t &seq, HCPTR hcptr, NSACR nsacr, CPACR cpacr, CPSR cpsr,
824 uint32_t &iss, bool &trap, ThreadContext *tc, FPEXC fpexc,
825 bool isSIMD)
826{
827 iss = 0;
828 trap = false;
829 bool undefined = false;
830 bool haveSecurity = ArmSystem::haveSecurity(tc);
831 bool haveVirtualization = ArmSystem::haveVirtualization(tc);
832 bool isSecure = inSecureState(tc);
833
834 // Non-secure view of CPACR and HCPTR determines behavior
835 // Copy register values
836 uint8_t cpacr_cp10 = cpacr.cp10;
837 bool cpacr_asedis = cpacr.asedis;
838 bool hcptr_cp10 = false;
839 bool hcptr_tase = false;
840
841 bool cp10_enabled = cpacr.cp10 == 0x3
842 || (cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr));
843
844 bool cp11_enabled = cpacr.cp11 == 0x3
845 || (cpacr.cp11 == 0x1 && inPrivilegedMode(cpsr));
846
847 if (cp11_enabled) {
848 undefined |= !(fpexc.en && cp10_enabled);
849 } else {
850 undefined |= !(fpexc.en && cp10_enabled && (cpacr.cp11 == cpacr.cp10));
851 }
852
853 if (haveVirtualization) {
854 hcptr_cp10 = hcptr.tcp10;
855 undefined |= hcptr.tcp10 != hcptr.tcp11;
856 hcptr_tase = hcptr.tase;
857 }
858
859 if (haveSecurity) {
860 undefined |= nsacr.cp10 != nsacr.cp11;
861 if (!isSecure) {
862 // Modify register values to the Non-secure view
863 if (!nsacr.cp10) {
864 cpacr_cp10 = 0;
865 if (haveVirtualization) {
866 hcptr_cp10 = true;
867 }
868 }
869 if (nsacr.nsasedis) {
870 cpacr_asedis = true;
871 if (haveVirtualization) {
872 hcptr_tase = true;
873 }
874 }
875 }
876 }
877
878 // Check Coprocessor Access Control Register for permission to use CP10/11.
879 if (!haveVirtualization || (cpsr.mode != MODE_HYP)) {
880 switch (cpacr_cp10)
881 {
882 case 0:
883 undefined = true;
884 break;
885 case 1:
886 undefined |= inUserMode(cpsr);
887 break;
888 }
889
890 // Check if SIMD operations are disabled
891 if (isSIMD && cpacr_asedis) undefined = true;
892 }
893
894 // If required, check FPEXC enabled bit.
895 undefined |= !fpexc.en;
896
897 if (haveSecurity && haveVirtualization && !isSecure) {
898 if (hcptr_cp10 || (isSIMD && hcptr_tase)) {
899 iss = isSIMD ? (1 << 5) : 0xA;
900 trap = true;
901 }
902 }
903
904 return (!undefined);
905}
906
907bool
908SPAlignmentCheckEnabled(ThreadContext* tc)
909{
910 switch (opModeToEL(currOpMode(tc))) {
911 case EL3:
912 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa;
913 case EL2:
914 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa;
915 case EL1:
916 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa;
917 case EL0:
918 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0;
919 default:
920 panic("Invalid exception level");
921 break;
922 }
923}
924
925int
926decodePhysAddrRange64(uint8_t pa_enc)
927{
928 switch (pa_enc) {
929 case 0x0:
930 return 32;
931 case 0x1:
932 return 36;
933 case 0x2:
934 return 40;
935 case 0x3:
936 return 42;
937 case 0x4:
938 return 44;
939 case 0x5:
940 case 0x6:
941 case 0x7:
942 return 48;
943 default:
944 panic("Invalid phys. address range encoding");
945 }
946}
947
948uint8_t
949encodePhysAddrRange64(int pa_size)
950{
951 switch (pa_size) {
952 case 32:
953 return 0x0;
954 case 36:
955 return 0x1;
956 case 40:
957 return 0x2;
958 case 42:
959 return 0x3;
960 case 44:
961 return 0x4;
962 case 48:
963 return 0x5;
964 default:
965 panic("Invalid phys. address range");
966 }
967}
968
969} // namespace ArmISA
218 }
219}
220
221bool
222ELIs64(ThreadContext *tc, ExceptionLevel el)
223{
224 if (ArmSystem::highestEL(tc) == el)
225 // Register width is hard-wired
226 return ArmSystem::highestELIs64(tc);
227
228 switch (el) {
229 case EL0:
230 return opModeIs64(currOpMode(tc));
231 case EL1:
232 {
233 // @todo: uncomment this to enable Virtualization
234 // if (ArmSystem::haveVirtualization(tc)) {
235 // HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
236 // return hcr.rw;
237 // }
238 assert(ArmSystem::haveSecurity(tc));
239 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
240 return scr.rw;
241 }
242 case EL2:
243 {
244 assert(ArmSystem::haveSecurity(tc));
245 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
246 return scr.rw;
247 }
248 default:
249 panic("Invalid exception level");
250 break;
251 }
252}
253
254bool
255isBigEndian64(ThreadContext *tc)
256{
257 switch (opModeToEL(currOpMode(tc))) {
258 case EL3:
259 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee;
260 case EL2:
261 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee;
262 case EL1:
263 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee;
264 case EL0:
265 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e;
266 default:
267 panic("Invalid exception level");
268 break;
269 }
270}
271
272Addr
273purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el)
274{
275 TTBCR tcr;
276
277 switch (el) {
278 case EL0:
279 case EL1:
280 tcr = tc->readMiscReg(MISCREG_TCR_EL1);
281 if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
282 return addr | mask(63, 55);
283 else if (!bits(addr, 55, 48) && tcr.tbi0)
284 return bits(addr,55, 0);
285 break;
286 // @todo: uncomment this to enable Virtualization
287 // case EL2:
288 // assert(ArmSystem::haveVirtualization());
289 // tcr = tc->readMiscReg(MISCREG_TCR_EL2);
290 // if (tcr.tbi)
291 // return addr & mask(56);
292 // break;
293 case EL3:
294 assert(ArmSystem::haveSecurity(tc));
295 tcr = tc->readMiscReg(MISCREG_TCR_EL3);
296 if (tcr.tbi)
297 return addr & mask(56);
298 break;
299 default:
300 panic("Invalid exception level");
301 break;
302 }
303
304 return addr; // Nothing to do if this is not a tagged address
305}
306
307Addr
308truncPage(Addr addr)
309{
310 return addr & ~(PageBytes - 1);
311}
312
313Addr
314roundPage(Addr addr)
315{
316 return (addr + PageBytes - 1) & ~(PageBytes - 1);
317}
318
319bool
320mcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
321 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
322{
323 bool isRead;
324 uint32_t crm;
325 IntRegIndex rt;
326 uint32_t crn;
327 uint32_t opc1;
328 uint32_t opc2;
329 bool trapToHype = false;
330
331
332 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
333 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
334 trapToHype = ((uint32_t) hstr) & (1 << crn);
335 trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12);
336 trapToHype |= hcr.tidcp && (
337 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
338 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
339 ((crn == 11) && ((crm <= 8) || (crm == 15))) );
340
341 if (!trapToHype) {
342 switch (unflattenMiscReg(miscReg)) {
343 case MISCREG_CPACR:
344 trapToHype = hcptr.tcpac;
345 break;
346 case MISCREG_REVIDR:
347 case MISCREG_TCMTR:
348 case MISCREG_TLBTR:
349 case MISCREG_AIDR:
350 trapToHype = hcr.tid1;
351 break;
352 case MISCREG_CTR:
353 case MISCREG_CCSIDR:
354 case MISCREG_CLIDR:
355 case MISCREG_CSSELR:
356 trapToHype = hcr.tid2;
357 break;
358 case MISCREG_ID_PFR0:
359 case MISCREG_ID_PFR1:
360 case MISCREG_ID_DFR0:
361 case MISCREG_ID_AFR0:
362 case MISCREG_ID_MMFR0:
363 case MISCREG_ID_MMFR1:
364 case MISCREG_ID_MMFR2:
365 case MISCREG_ID_MMFR3:
366 case MISCREG_ID_ISAR0:
367 case MISCREG_ID_ISAR1:
368 case MISCREG_ID_ISAR2:
369 case MISCREG_ID_ISAR3:
370 case MISCREG_ID_ISAR4:
371 case MISCREG_ID_ISAR5:
372 trapToHype = hcr.tid3;
373 break;
374 case MISCREG_DCISW:
375 case MISCREG_DCCSW:
376 case MISCREG_DCCISW:
377 trapToHype = hcr.tsw;
378 break;
379 case MISCREG_DCIMVAC:
380 case MISCREG_DCCIMVAC:
381 case MISCREG_DCCMVAC:
382 trapToHype = hcr.tpc;
383 break;
384 case MISCREG_ICIMVAU:
385 case MISCREG_ICIALLU:
386 case MISCREG_ICIALLUIS:
387 case MISCREG_DCCMVAU:
388 trapToHype = hcr.tpu;
389 break;
390 case MISCREG_TLBIALLIS:
391 case MISCREG_TLBIMVAIS:
392 case MISCREG_TLBIASIDIS:
393 case MISCREG_TLBIMVAAIS:
394 case MISCREG_DTLBIALL:
395 case MISCREG_ITLBIALL:
396 case MISCREG_DTLBIMVA:
397 case MISCREG_ITLBIMVA:
398 case MISCREG_DTLBIASID:
399 case MISCREG_ITLBIASID:
400 case MISCREG_TLBIMVAA:
401 case MISCREG_TLBIALL:
402 case MISCREG_TLBIMVA:
403 case MISCREG_TLBIASID:
404 trapToHype = hcr.ttlb;
405 break;
406 case MISCREG_ACTLR:
407 trapToHype = hcr.tac;
408 break;
409 case MISCREG_SCTLR:
410 case MISCREG_TTBR0:
411 case MISCREG_TTBR1:
412 case MISCREG_TTBCR:
413 case MISCREG_DACR:
414 case MISCREG_DFSR:
415 case MISCREG_IFSR:
416 case MISCREG_DFAR:
417 case MISCREG_IFAR:
418 case MISCREG_ADFSR:
419 case MISCREG_AIFSR:
420 case MISCREG_PRRR:
421 case MISCREG_NMRR:
422 case MISCREG_MAIR0:
423 case MISCREG_MAIR1:
424 case MISCREG_CONTEXTIDR:
425 trapToHype = hcr.tvm & !isRead;
426 break;
427 case MISCREG_PMCR:
428 trapToHype = hdcr.tpmcr;
429 break;
430 // No default action needed
431 default:
432 break;
433 }
434 }
435 }
436 return trapToHype;
437}
438
439
440bool
441mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
442 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
443{
444 bool isRead;
445 uint32_t crm;
446 IntRegIndex rt;
447 uint32_t crn;
448 uint32_t opc1;
449 uint32_t opc2;
450 bool trapToHype = false;
451
452 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
453 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
454 inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
455 crm, crn, opc1, opc2, hdcr, hcptr, hstr);
456 trapToHype = hdcr.tda && (opc1 == 0);
457 trapToHype |= hcptr.tta && (opc1 == 1);
458 if (!trapToHype) {
459 switch (unflattenMiscReg(miscReg)) {
460 case MISCREG_DBGOSLSR:
461 case MISCREG_DBGOSLAR:
462 case MISCREG_DBGOSDLR:
463 case MISCREG_DBGPRCR:
464 trapToHype = hdcr.tdosa;
465 break;
466 case MISCREG_DBGDRAR:
467 case MISCREG_DBGDSAR:
468 trapToHype = hdcr.tdra;
469 break;
470 case MISCREG_JIDR:
471 trapToHype = hcr.tid0;
472 break;
473 case MISCREG_JOSCR:
474 case MISCREG_JMCR:
475 trapToHype = hstr.tjdbx;
476 break;
477 case MISCREG_TEECR:
478 case MISCREG_TEEHBR:
479 trapToHype = hstr.ttee;
480 break;
481 // No default action needed
482 default:
483 break;
484 }
485 }
486 }
487 return trapToHype;
488}
489
490bool
491mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
492 HCR hcr, uint32_t iss)
493{
494 uint32_t crm;
495 IntRegIndex rt;
496 uint32_t crn;
497 uint32_t opc1;
498 uint32_t opc2;
499 bool isRead;
500 bool trapToHype = false;
501
502 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
503 // This is technically the wrong function, but we can re-use it for
504 // the moment because we only need one field, which overlaps with the
505 // mcrmrc layout
506 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
507 trapToHype = ((uint32_t) hstr) & (1 << crm);
508
509 if (!trapToHype) {
510 switch (unflattenMiscReg(miscReg)) {
511 case MISCREG_SCTLR:
512 case MISCREG_TTBR0:
513 case MISCREG_TTBR1:
514 case MISCREG_TTBCR:
515 case MISCREG_DACR:
516 case MISCREG_DFSR:
517 case MISCREG_IFSR:
518 case MISCREG_DFAR:
519 case MISCREG_IFAR:
520 case MISCREG_ADFSR:
521 case MISCREG_AIFSR:
522 case MISCREG_PRRR:
523 case MISCREG_NMRR:
524 case MISCREG_MAIR0:
525 case MISCREG_MAIR1:
526 case MISCREG_CONTEXTIDR:
527 trapToHype = hcr.tvm & !isRead;
528 break;
529 // No default action needed
530 default:
531 break;
532 }
533 }
534 }
535 return trapToHype;
536}
537
538bool
539msrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el,
540 CPACR cpacr /* CPACR_EL1 */)
541{
542 bool trapToSup = false;
543 switch (miscReg) {
544 case MISCREG_FPCR:
545 case MISCREG_FPSR:
546 case MISCREG_FPEXC32_EL2:
547 if ((el == EL0 && cpacr.fpen != 0x3) ||
548 (el == EL1 && !(cpacr.fpen & 0x1)))
549 trapToSup = true;
550 break;
551 default:
552 break;
553 }
554 return trapToSup;
555}
556
557bool
558msrMrs64TrapToHyp(const MiscRegIndex miscReg, bool isRead,
559 CPTR cptr /* CPTR_EL2 */,
560 HCR hcr /* HCR_EL2 */,
561 bool * isVfpNeon)
562{
563 bool trapToHyp = false;
564 *isVfpNeon = false;
565
566 switch (miscReg) {
567 // FP/SIMD regs
568 case MISCREG_FPCR:
569 case MISCREG_FPSR:
570 case MISCREG_FPEXC32_EL2:
571 trapToHyp = cptr.tfp;
572 *isVfpNeon = true;
573 break;
574 // CPACR
575 case MISCREG_CPACR_EL1:
576 trapToHyp = cptr.tcpac;
577 break;
578 // Virtual memory control regs
579 case MISCREG_SCTLR_EL1:
580 case MISCREG_TTBR0_EL1:
581 case MISCREG_TTBR1_EL1:
582 case MISCREG_TCR_EL1:
583 case MISCREG_ESR_EL1:
584 case MISCREG_FAR_EL1:
585 case MISCREG_AFSR0_EL1:
586 case MISCREG_AFSR1_EL1:
587 case MISCREG_MAIR_EL1:
588 case MISCREG_AMAIR_EL1:
589 case MISCREG_CONTEXTIDR_EL1:
590 trapToHyp = (hcr.trvm && isRead) || (hcr.tvm && !isRead);
591 break;
592 // TLB maintenance instructions
593 case MISCREG_TLBI_VMALLE1:
594 case MISCREG_TLBI_VAE1_Xt:
595 case MISCREG_TLBI_ASIDE1_Xt:
596 case MISCREG_TLBI_VAAE1_Xt:
597 case MISCREG_TLBI_VALE1_Xt:
598 case MISCREG_TLBI_VAALE1_Xt:
599 case MISCREG_TLBI_VMALLE1IS:
600 case MISCREG_TLBI_VAE1IS_Xt:
601 case MISCREG_TLBI_ASIDE1IS_Xt:
602 case MISCREG_TLBI_VAAE1IS_Xt:
603 case MISCREG_TLBI_VALE1IS_Xt:
604 case MISCREG_TLBI_VAALE1IS_Xt:
605 trapToHyp = hcr.ttlb;
606 break;
607 // Cache maintenance instructions to the point of unification
608 case MISCREG_IC_IVAU_Xt:
609 case MISCREG_ICIALLU:
610 case MISCREG_ICIALLUIS:
611 case MISCREG_DC_CVAU_Xt:
612 trapToHyp = hcr.tpu;
613 break;
614 // Data/Unified cache maintenance instructions to the point of coherency
615 case MISCREG_DC_IVAC_Xt:
616 case MISCREG_DC_CIVAC_Xt:
617 case MISCREG_DC_CVAC_Xt:
618 trapToHyp = hcr.tpc;
619 break;
620 // Data/Unified cache maintenance instructions by set/way
621 case MISCREG_DC_ISW_Xt:
622 case MISCREG_DC_CSW_Xt:
623 case MISCREG_DC_CISW_Xt:
624 trapToHyp = hcr.tsw;
625 break;
626 // ACTLR
627 case MISCREG_ACTLR_EL1:
628 trapToHyp = hcr.tacr;
629 break;
630
631 // @todo: Trap implementation-dependent functionality based on
632 // hcr.tidcp
633
634 // ID regs, group 3
635 case MISCREG_ID_PFR0_EL1:
636 case MISCREG_ID_PFR1_EL1:
637 case MISCREG_ID_DFR0_EL1:
638 case MISCREG_ID_AFR0_EL1:
639 case MISCREG_ID_MMFR0_EL1:
640 case MISCREG_ID_MMFR1_EL1:
641 case MISCREG_ID_MMFR2_EL1:
642 case MISCREG_ID_MMFR3_EL1:
643 case MISCREG_ID_ISAR0_EL1:
644 case MISCREG_ID_ISAR1_EL1:
645 case MISCREG_ID_ISAR2_EL1:
646 case MISCREG_ID_ISAR3_EL1:
647 case MISCREG_ID_ISAR4_EL1:
648 case MISCREG_ID_ISAR5_EL1:
649 case MISCREG_MVFR0_EL1:
650 case MISCREG_MVFR1_EL1:
651 case MISCREG_MVFR2_EL1:
652 case MISCREG_ID_AA64PFR0_EL1:
653 case MISCREG_ID_AA64PFR1_EL1:
654 case MISCREG_ID_AA64DFR0_EL1:
655 case MISCREG_ID_AA64DFR1_EL1:
656 case MISCREG_ID_AA64ISAR0_EL1:
657 case MISCREG_ID_AA64ISAR1_EL1:
658 case MISCREG_ID_AA64MMFR0_EL1:
659 case MISCREG_ID_AA64MMFR1_EL1:
660 case MISCREG_ID_AA64AFR0_EL1:
661 case MISCREG_ID_AA64AFR1_EL1:
662 assert(isRead);
663 trapToHyp = hcr.tid3;
664 break;
665 // ID regs, group 2
666 case MISCREG_CTR_EL0:
667 case MISCREG_CCSIDR_EL1:
668 case MISCREG_CLIDR_EL1:
669 case MISCREG_CSSELR_EL1:
670 trapToHyp = hcr.tid2;
671 break;
672 // ID regs, group 1
673 case MISCREG_AIDR_EL1:
674 case MISCREG_REVIDR_EL1:
675 assert(isRead);
676 trapToHyp = hcr.tid1;
677 break;
678 default:
679 break;
680 }
681 return trapToHyp;
682}
683
684bool
685msrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */,
686 ExceptionLevel el, bool * isVfpNeon)
687{
688 bool trapToMon = false;
689 *isVfpNeon = false;
690
691 switch (miscReg) {
692 // FP/SIMD regs
693 case MISCREG_FPCR:
694 case MISCREG_FPSR:
695 case MISCREG_FPEXC32_EL2:
696 trapToMon = cptr.tfp;
697 *isVfpNeon = true;
698 break;
699 // CPACR, CPTR
700 case MISCREG_CPACR_EL1:
701 if (el == EL1) {
702 trapToMon = cptr.tcpac;
703 }
704 break;
705 case MISCREG_CPTR_EL2:
706 if (el == EL2) {
707 trapToMon = cptr.tcpac;
708 }
709 break;
710 default:
711 break;
712 }
713 return trapToMon;
714}
715
716bool
717decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
718 CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
719{
720 OperatingMode mode = MODE_UNDEFINED;
721 bool ok = true;
722
723 // R mostly indicates if its a int register or a misc reg, we override
724 // below if the few corner cases
725 isIntReg = !r;
726 // Loosely based on ARM ARM issue C section B9.3.10
727 if (r) {
728 switch (sysM)
729 {
730 case 0xE:
731 regIdx = MISCREG_SPSR_FIQ;
732 mode = MODE_FIQ;
733 break;
734 case 0x10:
735 regIdx = MISCREG_SPSR_IRQ;
736 mode = MODE_IRQ;
737 break;
738 case 0x12:
739 regIdx = MISCREG_SPSR_SVC;
740 mode = MODE_SVC;
741 break;
742 case 0x14:
743 regIdx = MISCREG_SPSR_ABT;
744 mode = MODE_ABORT;
745 break;
746 case 0x16:
747 regIdx = MISCREG_SPSR_UND;
748 mode = MODE_UNDEFINED;
749 break;
750 case 0x1C:
751 regIdx = MISCREG_SPSR_MON;
752 mode = MODE_MON;
753 break;
754 case 0x1E:
755 regIdx = MISCREG_SPSR_HYP;
756 mode = MODE_HYP;
757 break;
758 default:
759 ok = false;
760 break;
761 }
762 } else {
763 int sysM4To3 = bits(sysM, 4, 3);
764
765 if (sysM4To3 == 0) {
766 mode = MODE_USER;
767 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
768 } else if (sysM4To3 == 1) {
769 mode = MODE_FIQ;
770 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
771 } else if (sysM4To3 == 3) {
772 if (bits(sysM, 1) == 0) {
773 mode = MODE_MON;
774 regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
775 } else {
776 mode = MODE_HYP;
777 if (bits(sysM, 0) == 1) {
778 regIdx = intRegInMode(mode, 13); // R13 in HYP
779 } else {
780 isIntReg = false;
781 regIdx = MISCREG_ELR_HYP;
782 }
783 }
784 } else { // Other Banked registers
785 int sysM2 = bits(sysM, 2);
786 int sysM1 = bits(sysM, 1);
787
788 mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) |
789 (1 << 1) |
790 ((sysM2 && !sysM1) << 2) |
791 ((sysM2 && sysM1) << 3) |
792 (1 << 4) );
793 regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
794 // Don't flatten the register here. This is going to go through
795 // setIntReg() which will do the flattening
796 ok &= mode != cpsr.mode;
797 }
798 }
799
800 // Check that the requested register is accessable from the current mode
801 if (ok && checkSecurity && mode != cpsr.mode) {
802 switch (cpsr.mode)
803 {
804 case MODE_USER:
805 ok = false;
806 break;
807 case MODE_FIQ:
808 ok &= mode != MODE_HYP;
809 ok &= (mode != MODE_MON) || !scr.ns;
810 break;
811 case MODE_HYP:
812 ok &= mode != MODE_MON;
813 ok &= (mode != MODE_FIQ) || !nsacr.rfr;
814 break;
815 case MODE_IRQ:
816 case MODE_SVC:
817 case MODE_ABORT:
818 case MODE_UNDEFINED:
819 case MODE_SYSTEM:
820 ok &= mode != MODE_HYP;
821 ok &= (mode != MODE_MON) || !scr.ns;
822 ok &= (mode != MODE_FIQ) || !nsacr.rfr;
823 break;
824 // can access everything, no further checks required
825 case MODE_MON:
826 break;
827 default:
828 panic("unknown Mode 0x%x\n", cpsr.mode);
829 break;
830 }
831 }
832 return (ok);
833}
834
835bool
836vfpNeonEnabled(uint32_t &seq, HCPTR hcptr, NSACR nsacr, CPACR cpacr, CPSR cpsr,
837 uint32_t &iss, bool &trap, ThreadContext *tc, FPEXC fpexc,
838 bool isSIMD)
839{
840 iss = 0;
841 trap = false;
842 bool undefined = false;
843 bool haveSecurity = ArmSystem::haveSecurity(tc);
844 bool haveVirtualization = ArmSystem::haveVirtualization(tc);
845 bool isSecure = inSecureState(tc);
846
847 // Non-secure view of CPACR and HCPTR determines behavior
848 // Copy register values
849 uint8_t cpacr_cp10 = cpacr.cp10;
850 bool cpacr_asedis = cpacr.asedis;
851 bool hcptr_cp10 = false;
852 bool hcptr_tase = false;
853
854 bool cp10_enabled = cpacr.cp10 == 0x3
855 || (cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr));
856
857 bool cp11_enabled = cpacr.cp11 == 0x3
858 || (cpacr.cp11 == 0x1 && inPrivilegedMode(cpsr));
859
860 if (cp11_enabled) {
861 undefined |= !(fpexc.en && cp10_enabled);
862 } else {
863 undefined |= !(fpexc.en && cp10_enabled && (cpacr.cp11 == cpacr.cp10));
864 }
865
866 if (haveVirtualization) {
867 hcptr_cp10 = hcptr.tcp10;
868 undefined |= hcptr.tcp10 != hcptr.tcp11;
869 hcptr_tase = hcptr.tase;
870 }
871
872 if (haveSecurity) {
873 undefined |= nsacr.cp10 != nsacr.cp11;
874 if (!isSecure) {
875 // Modify register values to the Non-secure view
876 if (!nsacr.cp10) {
877 cpacr_cp10 = 0;
878 if (haveVirtualization) {
879 hcptr_cp10 = true;
880 }
881 }
882 if (nsacr.nsasedis) {
883 cpacr_asedis = true;
884 if (haveVirtualization) {
885 hcptr_tase = true;
886 }
887 }
888 }
889 }
890
891 // Check Coprocessor Access Control Register for permission to use CP10/11.
892 if (!haveVirtualization || (cpsr.mode != MODE_HYP)) {
893 switch (cpacr_cp10)
894 {
895 case 0:
896 undefined = true;
897 break;
898 case 1:
899 undefined |= inUserMode(cpsr);
900 break;
901 }
902
903 // Check if SIMD operations are disabled
904 if (isSIMD && cpacr_asedis) undefined = true;
905 }
906
907 // If required, check FPEXC enabled bit.
908 undefined |= !fpexc.en;
909
910 if (haveSecurity && haveVirtualization && !isSecure) {
911 if (hcptr_cp10 || (isSIMD && hcptr_tase)) {
912 iss = isSIMD ? (1 << 5) : 0xA;
913 trap = true;
914 }
915 }
916
917 return (!undefined);
918}
919
920bool
921SPAlignmentCheckEnabled(ThreadContext* tc)
922{
923 switch (opModeToEL(currOpMode(tc))) {
924 case EL3:
925 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa;
926 case EL2:
927 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa;
928 case EL1:
929 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa;
930 case EL0:
931 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0;
932 default:
933 panic("Invalid exception level");
934 break;
935 }
936}
937
938int
939decodePhysAddrRange64(uint8_t pa_enc)
940{
941 switch (pa_enc) {
942 case 0x0:
943 return 32;
944 case 0x1:
945 return 36;
946 case 0x2:
947 return 40;
948 case 0x3:
949 return 42;
950 case 0x4:
951 return 44;
952 case 0x5:
953 case 0x6:
954 case 0x7:
955 return 48;
956 default:
957 panic("Invalid phys. address range encoding");
958 }
959}
960
961uint8_t
962encodePhysAddrRange64(int pa_size)
963{
964 switch (pa_size) {
965 case 32:
966 return 0x0;
967 case 36:
968 return 0x1;
969 case 40:
970 return 0x2;
971 case 42:
972 return 0x3;
973 case 44:
974 return 0x4;
975 case 48:
976 return 0x5;
977 default:
978 panic("Invalid phys. address range");
979 }
980}
981
982} // namespace ArmISA