2 * Copyright (c) 2019 Metempsy Technology LSC
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/self_debug.hh"
40 #include "arch/arm/faults.hh"
41 #include "arch/arm/miscregs_types.hh"
42 #include "base/bitfield.hh"
44 using namespace ArmISA
;
48 SelfDebug::testDebug(ThreadContext
*tc
, const RequestPtr
&req
,
51 Fault fault
= NoFault
;
53 if (mode
== BaseTLB::Execute
) {
54 const bool d_step
= softStep
->advanceSS(tc
);
56 fault
= testVectorCatch(tc
, req
->getVaddr(), nullptr);
58 fault
= testBreakPoints(tc
, req
->getVaddr());
60 } else if (!req
->isCacheMaintenance() ||
61 (req
->isCacheInvalidate() && !req
->isCacheClean())) {
62 bool md
= mode
== BaseTLB::Write
? true: false;
63 fault
= testWatchPoints(tc
, req
->getVaddr(), md
,
66 req
->isCacheMaintenance());
73 SelfDebug::testBreakPoints(ThreadContext
*tc
, Addr vaddr
)
80 to32
= targetAArch32(tc
);
84 if (!isDebugEnabled(tc
))
87 ExceptionLevel el
= (ExceptionLevel
) currEL(tc
);
88 for (auto &p
: arBrkPoints
){
89 PCState pcst
= tc
->pcState();
91 if (pcst
.itstate() != 0x0)
93 if (p
.enable
&& p
.isActive(pc
) &&(!to32
|| !p
.onUse
)) {
94 const DBGBCR ctr
= p
.getControlReg(tc
);
95 if (p
.isEnabled(tc
, el
, ctr
.hmc
, ctr
.ssc
, ctr
.pmc
)) {
96 bool debug
= p
.test(tc
, pc
, el
, ctr
, false);
100 return triggerException(tc
, pc
);
110 SelfDebug::triggerException(ThreadContext
*tc
, Addr vaddr
)
113 return std::make_shared
<PrefetchAbort
>(vaddr
,
114 ArmFault::DebugEvent
, false,
115 ArmFault::UnknownTran
,
118 return std::make_shared
<HardwareBreakpoint
>(vaddr
, 0x22);
123 SelfDebug::testWatchPoints(ThreadContext
*tc
, Addr vaddr
, bool write
,
124 bool atomic
, unsigned size
, bool cm
)
127 to32
= targetAArch32(tc
);
130 if (!isDebugEnabled(tc
) || !enableFlag
)
133 ExceptionLevel el
= (ExceptionLevel
) currEL(tc
);
135 for (auto &p
: arWatchPoints
){
138 bool debug
= p
.test(tc
, vaddr
, el
, write
, atomic
, size
);
140 return triggerWatchpointException(tc
, vaddr
, write
, cm
);
148 SelfDebug::triggerWatchpointException(ThreadContext
*tc
, Addr vaddr
,
152 ArmFault::DebugType d
= cm
? ArmFault::WPOINT_CM
:
153 ArmFault::WPOINT_NOCM
;
154 return std::make_shared
<DataAbort
>(vaddr
,
155 TlbEntry::DomainType::NoAccess
,
156 write
, ArmFault::DebugEvent
, cm
,
157 ArmFault::UnknownTran
, d
);
159 return std::make_shared
<Watchpoint
>(0, vaddr
, write
, cm
);
164 SelfDebug::isDebugEnabledForEL64(ThreadContext
*tc
, ExceptionLevel el
,
165 bool secure
, bool mask
)
167 bool route_to_el2
= ArmSystem::haveEL(tc
, EL2
) &&
168 !secure
&& enableTdeTge
;
170 ExceptionLevel target_el
= route_to_el2
? EL2
: EL1
;
171 if (oslk
|| (bSDD
&& secure
&& ArmSystem::haveEL(tc
, EL3
))) {
175 if (el
== target_el
) {
176 return bKDE
&& !mask
;
178 return target_el
> el
;
183 SelfDebug::isDebugEnabledForEL32(ThreadContext
*tc
, ExceptionLevel el
,
184 bool secure
, bool mask
)
186 if (el
== EL0
&& !ELStateUsingAArch32(tc
, EL1
, secure
)) {
187 return isDebugEnabledForEL64(tc
, el
, secure
, mask
);
195 if (secure
&& ArmSystem::haveEL(tc
, EL3
)) {
196 // We ignore the check for invasive External debug checking SPIDEN
197 // and DBGEN signals. They are not implemented
198 bool spd32
= bits(tc
->readMiscReg(MISCREG_MDCR_EL3
), 14);
201 bool suiden
= bits(tc
->readMiscReg(MISCREG_SDER
), 0);
202 enabled
= el
== EL0
? (enabled
|| suiden
) : enabled
;
210 BrkPoint::testLinkedBk(ThreadContext
*tc
, Addr vaddr
, ExceptionLevel el
)
213 const DBGBCR ctr
= getControlReg(tc
);
214 if ((ctr
.bt
& 0x1) && enable
) {
215 debug
= test(tc
, vaddr
, el
, ctr
, true);
221 BrkPoint::test(ThreadContext
*tc
, Addr pc
, ExceptionLevel el
, DBGBCR ctr
,
227 v
= testAddrMatch(tc
, pc
, ctr
.bas
);
231 v
= testAddrMatch(tc
, pc
, ctr
.bas
); // linked
233 v
= (conf
->getBrkPoint(ctr
.lbn
))->testLinkedBk(tc
, pc
, el
);
239 bool host
= ELIsInHost(tc
, el
);
240 v
= testContextMatch(tc
, !host
, true);
246 bool host
= ELIsInHost(tc
, el
);
247 v
= testContextMatch(tc
, !host
, true);
252 v
= testAddrMissMatch(tc
, pc
, ctr
.bas
);
256 v
= testAddrMissMatch(tc
, pc
, ctr
.bas
); // linked
258 v
= v
&& (conf
->getBrkPoint(ctr
.lbn
))->testLinkedBk(tc
, pc
, el
);
262 if (HaveVirtHostExt(tc
) && !ELIsInHost(tc
, el
))
263 v
= testContextMatch(tc
, true);
267 if (HaveVirtHostExt(tc
) && !ELIsInHost(tc
, el
) && from_link
)
268 v
= testContextMatch(tc
, true);
272 if (ArmSystem::haveEL(tc
, EL2
) && !ELIsInHost(tc
, el
)) {
273 v
= testVMIDMatch(tc
);
278 if (from_link
&& ArmSystem::haveEL(tc
, EL2
) &&
279 !ELIsInHost(tc
, el
)) {
280 v
= testVMIDMatch(tc
);
285 if (ArmSystem::haveEL(tc
, EL2
) && !ELIsInHost(tc
, el
)) {
286 v
= testContextMatch(tc
, true);
288 v
= v
&& testVMIDMatch(tc
);
292 if (from_link
&& ArmSystem::haveEL(tc
, EL2
) &&
293 !ELIsInHost(tc
, el
)) {
294 v
= testContextMatch(tc
, true);
295 v
= v
&& testVMIDMatch(tc
);
300 if (HaveVirtHostExt(tc
) && !inSecureState(tc
))
301 v
= testContextMatch(tc
, false);
305 if (HaveVirtHostExt(tc
) && from_link
&& !inSecureState(tc
))
306 v
= testContextMatch(tc
, false);
310 if (HaveVirtHostExt(tc
) && !ELIsInHost(tc
, el
)
311 && !inSecureState(tc
) ) {
312 v
= testContextMatch(tc
, true); // CONTEXTIDR_EL1
313 v
= v
&& testContextMatch(tc
, false); // CONTEXTIDR_EL2
317 if (HaveVirtHostExt(tc
) && !ELIsInHost(tc
, el
) && from_link
318 && !inSecureState(tc
) ) {
319 v
= testContextMatch(tc
, true); // CONTEXTIDR_EL1
320 v
= v
&& testContextMatch(tc
, false); // CONTEXTIDR_EL2
330 SelfDebug::init(ThreadContext
*tc
)
334 CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
335 aarch32
= cpsr
.width
== 1;
337 const AA64DFR0 dfr
= tc
->readMiscReg(MISCREG_ID_AA64DFR0_EL1
);
338 const AA64MMFR2 mm_fr2
= tc
->readMiscReg(MISCREG_ID_AA64MMFR2_EL1
);
339 const AA64MMFR1 mm_fr1
= tc
->readMiscReg(MISCREG_ID_AA64MMFR1_EL1
);
341 for (int i
= 0; i
<= dfr
.brps
; i
++) {
342 const bool isctxaw
= i
>= (dfr
.brps
- dfr
.ctx_cmps
);
344 BrkPoint bkp
= BrkPoint((MiscRegIndex
)(MISCREG_DBGBCR0_EL1
+ i
),
345 (MiscRegIndex
)(MISCREG_DBGBVR0_EL1
+ i
),
346 this, isctxaw
, (bool)mm_fr2
.varange
,
347 mm_fr1
.vmidbits
, aarch32
);
348 const DBGBCR ctr
= tc
->readMiscReg(MISCREG_DBGBCR0_EL1
+ i
);
350 bkp
.updateControl(ctr
);
351 arBrkPoints
.push_back(bkp
);
354 for (int i
= 0; i
<= dfr
.wrps
; i
++) {
355 WatchPoint wtp
= WatchPoint((MiscRegIndex
)(MISCREG_DBGWCR0
+ i
),
356 (MiscRegIndex
)(MISCREG_DBGWVR0
+ i
),
357 this, (bool)mm_fr2
.varange
, aarch32
);
358 const DBGWCR ctr
= tc
->readMiscReg(MISCREG_DBGWCR0
+ i
);
360 wtp
.updateControl(ctr
);
361 arWatchPoints
.push_back(wtp
);
366 RegVal oslar_el1
= tc
->readMiscReg(MISCREG_OSLAR_EL1
);
367 updateOSLock(oslar_el1
);
368 // Initialize preloaded control booleans
369 uint64_t mdscr_el1
= tc
->readMiscReg(MISCREG_MDSCR_EL1
);
370 setMDSCRvals(mdscr_el1
);
372 const uint64_t mdcr_el3
= tc
->readMiscReg(MISCREG_MDCR_EL3
);
375 const HCR hcr
= tc
->readMiscReg(MISCREG_HCR_EL2
);
376 const HDCR mdcr
= tc
->readMiscRegNoEffect(MISCREG_MDCR_EL2
);
377 setenableTDETGE(hcr
, mdcr
);
379 // Enable Vector Catch Exceptions
380 const DEVID dvid
= tc
->readMiscReg(MISCREG_DBGDEVID0
);
381 vcExcpt
= new VectorCatch(dvid
.vectorcatch
==0x0, this);
385 BrkPoint::testAddrMatch(ThreadContext
*tc
, Addr in_pc
, uint8_t bas
)
387 Addr pc_tocmp
= getAddrfromReg(tc
);
388 Addr pc
= bits(in_pc
, maxAddrSize
, 2);
391 CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
396 prs
= bits(in_pc
, 1, 0) == 0x2;
398 prs
= bits(in_pc
, 1, 0) == 0x0;
400 return (pc
== pc_tocmp
) && prs
;
404 BrkPoint::testAddrMissMatch(ThreadContext
*tc
, Addr in_pc
, uint8_t bas
)
408 Addr pc_tocmp
= getAddrfromReg(tc
);
409 Addr pc
= bits(in_pc
, maxAddrSize
, 2);
411 CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
416 prs
= bits(in_pc
, 1, 0) == 0x2;
418 prs
= bits(in_pc
, 1, 0) == 0x0;
420 return (pc
!= pc_tocmp
) && !prs
;
424 BrkPoint::testContextMatch(ThreadContext
*tc
, bool ctx1
)
426 return testContextMatch(tc
, ctx1
, ctx1
);
430 BrkPoint::testContextMatch(ThreadContext
*tc
, bool ctx1
, bool low_ctx
)
434 MiscRegIndex miscridx
;
435 ExceptionLevel el
= currEL(tc
);
436 bool a32
= conf
->isAArch32();
439 miscridx
= a32
? MISCREG_CONTEXTIDR
: MISCREG_CONTEXTIDR_EL1
;
440 if ((el
== EL3
&& !a32
) || el
== EL2
)
443 miscridx
= MISCREG_CONTEXTIDR_EL2
;
444 if (el
== EL2
&& a32
)
448 RegVal ctxid
= bits(tc
->readMiscReg(miscridx
), 31, 0);
449 RegVal v
= getContextfromReg(tc
, low_ctx
);
454 BrkPoint::testVMIDMatch(ThreadContext
*tc
)
456 uint32_t vmid_index
= 55;
459 ExceptionLevel el
= currEL(tc
);
463 uint32_t vmid
= bits(tc
->readMiscReg(MISCREG_VTTBR_EL2
), vmid_index
, 48);
464 uint32_t v
= getVMIDfromReg(tc
);
470 BrkPoint::isEnabled(ThreadContext
*tc
, ExceptionLevel el
,
471 uint8_t hmc
, uint8_t ssc
, uint8_t pmc
)
474 bool aarch32
= conf
->isAArch32();
475 bool no_el2
= !ArmSystem::haveEL(tc
, EL2
);
476 bool no_el3
= !ArmSystem::haveEL(tc
, EL3
);
478 if (no_el3
&& !no_el2
&& (ssc
== 0x1 || ssc
== 0x2) &&
479 !(hmc
&& ssc
== 0x1 && pmc
== 0x0)) {
481 } else if (no_el3
&& no_el2
&& (hmc
!= 0x0 || ssc
!= 0x0) &&
482 !(!aarch32
&& ((hmc
&& ssc
== 0x1 && pmc
== 0x0) || ssc
== 0x3))) {
484 } else if (no_el2
&& hmc
&& ssc
== 0x3 && pmc
== 0x0) {
486 } else if (ssc
== 0x11 && pmc
== 0x1 &&
487 !(!aarch32
&& hmc
&& ssc
== 0x3 && pmc
== 0x0)) {
488 // AND secureEL2 not implemented
490 } else if (hmc
&& ssc
== 0x1 && pmc
== 0x0) {
491 //AND secureEL2 not implemented
496 v
= (pmc
== 0x3) || (pmc
== 0x2 && hmc
== 0x0);
498 v
= v
|| (pmc
== 0x0 && ssc
!= 0x3 && hmc
== 0x0);
500 panic("Unexpected EL in SelfDebug::isDebugEnabled.\n");
503 v
= (pmc
== 0x3) || (pmc
== 0x1);
505 v
= v
|| (pmc
== 0x0 && hmc
== 0x0 && ssc
!=0x3);
509 ((hmc
== 0x1) && !((ssc
== 0x2) && (pmc
== 0x0)));
511 panic("Unexpected EL in SelfDebug::isDebugEnabled.\n");
515 panic("Unexpected EL in SelfDebug::isDebugEnabled.\n");
516 v
= (hmc
== 0x1) & (ssc
!= 0x3);
519 panic("Unexpected EL %d in BrkPoint::isEnabled.\n", el
);
521 return v
&& SelfDebug::securityStateMatch(tc
, ssc
, hmc
|| !aarch32
);
525 BrkPoint::getVMIDfromReg(ThreadContext
*tc
)
527 uint32_t vmid_index
= 39;
530 return bits(tc
->readMiscReg(valRegIndex
), vmid_index
, 32);
535 WatchPoint::isEnabled(ThreadContext
* tc
, ExceptionLevel el
,
536 bool hmc
, uint8_t ssc
, uint8_t pac
)
540 bool aarch32
= conf
->isAArch32();
541 bool no_el2
= !ArmSystem::haveEL(tc
, EL2
);
542 bool no_el3
= !ArmSystem::haveEL(tc
, EL3
);
545 // WatchPoint PL2 using aarch32 is disabled except for
546 // debug state. Check G2-5395 table G2-15.
550 if (ssc
== 0x01 || ssc
== 0x02 ){
553 ((!hmc
&& ssc
== 0x3) || (hmc
&& ssc
== 0x0))) {
557 if (no_el2
&& hmc
&& ssc
== 0x03 && pac
== 0)
562 v
= (pac
== 0x3 || (pac
== 0x2 && !hmc
&& ssc
!= 0x3));
565 v
= (pac
== 0x1 || pac
== 0x3);
568 v
= (hmc
&& (ssc
!= 0x2 || pac
!= 0x0));
571 v
= (hmc
&& (ssc
== 0x2 ||
572 (ssc
== 0x1 && (pac
== 0x1 || pac
== 0x3))));
575 panic("Unexpected EL in WatchPoint::isEnabled.\n");
577 return v
&& SelfDebug::securityStateMatch(tc
, ssc
, hmc
);
581 WatchPoint::test(ThreadContext
*tc
, Addr addr
, ExceptionLevel el
, bool& wrt
,
582 bool atomic
, unsigned size
)
586 const DBGWCR ctr
= tc
->readMiscReg(ctrlRegIndex
);
587 if (isEnabled(tc
, el
, ctr
.hmc
, ctr
.ssc
, ctr
.pac
) &&
588 ((wrt
&& (ctr
.lsv
& 0x2)) || (!wrt
&& (ctr
.lsv
& 0x1)) || atomic
)) {
589 v
= compareAddress(tc
, addr
, ctr
.bas
, ctr
.mask
, size
);
591 v
= v
&& (conf
->getBrkPoint(ctr
.lbn
))->testLinkedBk(tc
, addr
, el
);
594 if (atomic
&& (ctr
.lsv
& 0x1)) {
601 WatchPoint::compareAddress(ThreadContext
*tc
, Addr in_addr
, uint8_t bas
,
602 uint8_t mask
, unsigned size
)
604 Addr addr_tocmp
= getAddrfromReg(tc
);
605 int maxbits
= isDoubleAligned(addr_tocmp
) ? 4: 8;
606 int bottom
= isDoubleAligned(addr_tocmp
) ? 2: 3;
607 Addr addr
= bits(in_addr
, maxAddrSize
, 0);
613 for (int i
= 0; i
< maxbits
; i
++) {
614 uint8_t bas_m
= 0x1 << i
;
615 uint8_t masked_bas
= bas
& bas_m
;
616 if (masked_bas
== bas_m
) {
617 uint8_t off
= log2(masked_bas
);
618 Addr cmpaddr
= addr_tocmp
| off
;
619 for (int j
= 0; j
< size
; j
++) {
620 if ((addr
+ j
) == cmpaddr
) {
629 for (int j
= 0; j
< size
; j
++) {
632 addr
= bits((in_addr
+j
), maxAddrSize
, mask
);
633 compaddr
= bits(addr_tocmp
, maxAddrSize
, mask
);
635 addr
= bits((in_addr
+j
), maxAddrSize
, bottom
);
636 compaddr
= bits(addr_tocmp
, maxAddrSize
, bottom
);
638 v
= v
|| (addr
== compaddr
);
645 SoftwareStep::debugExceptionReturnSS(ThreadContext
*tc
, CPSR spsr
,
646 ExceptionLevel dest
, bool aarch32
)
649 bool enabled_src
= false;
651 enabled_src
= conf
->isDebugEnabled(tc
);
653 bool enabled_dst
= false;
654 bool secure
= isSecureBelowEL3(tc
) || dest
== EL3
;
655 CPSR cpsr
= tc
->readMiscReg(MISCREG_CPSR
);
657 enabled_dst
= conf
->isDebugEnabledForEL32(tc
, dest
, secure
,
660 enabled_dst
= conf
->isDebugEnabledForEL64(tc
, dest
, secure
,
663 ExceptionLevel ELd
= debugTargetFrom(tc
, secure
);
665 if (!ELIs32(tc
, ELd
) && !enabled_src
&& enabled_dst
) {
668 stateSS
= ACTIVE_PENDING_STATE
;
670 stateSS
= ACTIVE_NOT_PENDING_STATE
;
678 SoftwareStep::advanceSS(ThreadContext
* tc
)
681 PCState pc
= tc
->pcState();
688 case ACTIVE_NOT_PENDING_STATE
:
690 if (cpsrD
== 1 || !bSS
) {
691 stateSS
= INACTIVE_STATE
;
694 stateSS
= ACTIVE_PENDING_STATE
;
699 case ACTIVE_PENDING_STATE
:
705 stateSS
= INACTIVE_STATE
;
716 SelfDebug::testVectorCatch(ThreadContext
*tc
, Addr addr
,
721 to32
= targetAArch32(tc
);
724 if (!isDebugEnabled(tc
) || !enableFlag
|| !aarch32
)
727 ExceptionLevel el
= (ExceptionLevel
) currEL(tc
);
729 if (fault
== nullptr)
730 debug
= vcExcpt
->addressMatching(tc
, addr
, el
);
732 debug
= vcExcpt
->exceptionTrapping(tc
, el
, fault
);
735 return std::make_shared
<HypervisorTrap
>(0, 0x22,
736 EC_PREFETCH_ABORT_TO_HYP
);
738 return std::make_shared
<PrefetchAbort
>(addr
,
739 ArmFault::DebugEvent
, false,
740 ArmFault::UnknownTran
,
741 ArmFault::VECTORCATCH
);
749 VectorCatch::addressMatching(ThreadContext
*tc
, Addr addr
, ExceptionLevel el
)
751 // Each bit position in this string corresponds to a bit in DBGVCR
752 // and an exception vector.
754 if (conf
->isAArch32() && ELIs32(tc
, EL1
) &&
755 (addr
& 0x3) == 0 && el
!= EL2
) {
757 DBGVCR match_word
= 0x0;
759 Addr vbase
= getVectorBase(tc
, false);
760 Addr vaddress
= addr
& ~ 0x1f;
761 Addr low_addr
= bits(addr
, 5, 2);
762 if (vaddress
== vbase
) {
763 if (ArmSystem::haveEL(tc
, EL3
) && !inSecureState(tc
)) {
764 uint32_t bmask
= 1UL << (low_addr
+ 24);
765 match_word
= match_word
| (DBGVCR
) bmask
;
766 // Non-secure vectors
768 uint32_t bmask
= 1UL << (low_addr
);
769 match_word
= match_word
| (DBGVCR
) bmask
;
770 // Secure vectors (or no EL3)
773 uint32_t mvbase
= getVectorBase(tc
, true);
774 if (ArmSystem::haveEL(tc
, EL3
) && ELIs32(tc
, EL3
) &&
775 inSecureState(tc
) && (vaddress
== mvbase
)) {
776 uint32_t bmask
= 1UL << (low_addr
+ 8);
777 match_word
= match_word
| (DBGVCR
) bmask
;
783 // Mask out bits not corresponding to vectors.
784 if (!ArmSystem::haveEL(tc
, EL3
)) {
785 mask
= (DBGVCR
) 0xDE;
786 } else if (!ELIs32(tc
, EL3
)) {
787 mask
= (DBGVCR
) 0xDE0000DE;
789 mask
= (DBGVCR
) 0xDE00DEDE;
791 DBGVCR dbgvcr
= tc
->readMiscReg(MISCREG_DBGVCR
);
792 match_word
= match_word
& dbgvcr
& mask
;
793 enabled
= match_word
!= 0x0;
794 // Check for UNPREDICTABLE case - match on Prefetch Abort and
795 // Data Abort vectors
796 ExceptionLevel ELd
= debugTargetFrom(tc
, inSecureState(tc
));
797 if (((match_word
& 0x18001818) != 0x0) && ELd
== el
) {
807 VectorCatch::exceptionTrapping(ThreadContext
*tc
, ExceptionLevel el
,
810 if (conf
->isAArch32() && ELIs32(tc
, EL1
) && el
!= EL2
) {
812 DBGVCR dbgvcr
= tc
->readMiscReg(MISCREG_DBGVCR
);
813 DBGVCR match_type
= fault
->vectorCatchFlag();
816 if (!ArmSystem::haveEL(tc
, EL3
)) {
817 mask
= (DBGVCR
) 0xDE;
818 } else if (ELIs32(tc
, EL3
) && fault
->getToMode() == MODE_MON
) {
819 mask
= (DBGVCR
) 0x0000DE00;
821 if (inSecureState(tc
))
822 mask
= (DBGVCR
) 0x000000DE;
824 mask
= (DBGVCR
) 0xDE000000;
826 match_type
= match_type
& mask
& dbgvcr
;
828 if (match_type
!= 0x0) {