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
) || !mde
)
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
|| HaveSecureEL2Ext(tc
)) && enableTdeTge
;
170 ExceptionLevel target_el
= route_to_el2
? EL2
: EL1
;
171 if (oslk
|| (sdd
&& secure
&& ArmSystem::haveEL(tc
, EL3
))) {
175 if (el
== target_el
) {
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 (EL2Enabled(tc
) && !ELIsInHost(tc
, el
)) {
273 v
= testVMIDMatch(tc
);
278 if (from_link
&& EL2Enabled(tc
) && !ELIsInHost(tc
, el
)) {
279 v
= testVMIDMatch(tc
);
284 if (EL2Enabled(tc
) && !ELIsInHost(tc
, el
)) {
285 v
= testContextMatch(tc
, true);
287 v
= v
&& testVMIDMatch(tc
);
291 if (from_link
&& EL2Enabled(tc
) && !ELIsInHost(tc
, el
)) {
292 v
= testContextMatch(tc
, true);
293 v
= v
&& testVMIDMatch(tc
);
298 if (HaveVirtHostExt(tc
) && (!isSecure(tc
)|| HaveSecureEL2Ext(tc
)))
299 v
= testContextMatch(tc
, false);
303 if (HaveVirtHostExt(tc
) && from_link
&&
304 (!isSecure(tc
)|| HaveSecureEL2Ext(tc
))) {
305 v
= testContextMatch(tc
, false);
310 if (HaveVirtHostExt(tc
) && !ELIsInHost(tc
, el
) &&
311 (!isSecure(tc
)|| HaveSecureEL2Ext(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 (!isSecure(tc
)|| HaveSecureEL2Ext(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
,
649 bool enabled_src
= false;
651 enabled_src
= conf
->isDebugEnabled(tc
);
653 bool enabled_dst
= false;
654 bool secure
= isSecureBelowEL3(tc
) || dest
== EL3
;
656 enabled_dst
= conf
->isDebugEnabledForEL32(tc
, dest
, secure
,
659 enabled_dst
= conf
->isDebugEnabledForEL64(tc
, dest
, secure
,
662 ExceptionLevel ELd
= debugTargetFrom(tc
, secure
);
664 if (!ELIs32(tc
, ELd
) && !enabled_src
&& enabled_dst
) {
667 stateSS
= ACTIVE_PENDING_STATE
;
669 stateSS
= ACTIVE_NOT_PENDING_STATE
;
677 SoftwareStep::advanceSS(ThreadContext
* tc
)
680 PCState pc
= tc
->pcState();
687 case ACTIVE_NOT_PENDING_STATE
:
689 if (cpsrD
== 1 || !bSS
) {
690 stateSS
= INACTIVE_STATE
;
693 stateSS
= ACTIVE_PENDING_STATE
;
698 case ACTIVE_PENDING_STATE
:
704 stateSS
= INACTIVE_STATE
;
715 SelfDebug::testVectorCatch(ThreadContext
*tc
, Addr addr
,
720 to32
= targetAArch32(tc
);
723 if (!isDebugEnabled(tc
) || !mde
|| !aarch32
)
726 ExceptionLevel el
= (ExceptionLevel
) currEL(tc
);
728 if (fault
== nullptr)
729 debug
= vcExcpt
->addressMatching(tc
, addr
, el
);
731 debug
= vcExcpt
->exceptionTrapping(tc
, el
, fault
);
734 return std::make_shared
<HypervisorTrap
>(0, 0x22,
735 EC_PREFETCH_ABORT_TO_HYP
);
737 return std::make_shared
<PrefetchAbort
>(addr
,
738 ArmFault::DebugEvent
, false,
739 ArmFault::UnknownTran
,
740 ArmFault::VECTORCATCH
);
748 VectorCatch::addressMatching(ThreadContext
*tc
, Addr addr
, ExceptionLevel el
)
750 // Each bit position in this string corresponds to a bit in DBGVCR
751 // and an exception vector.
753 if (conf
->isAArch32() && ELIs32(tc
, EL1
) &&
754 (addr
& 0x3) == 0 && el
!= EL2
) {
756 DBGVCR match_word
= 0x0;
758 Addr vbase
= getVectorBase(tc
, false);
759 Addr vaddress
= addr
& ~ 0x1f;
760 Addr low_addr
= bits(addr
, 5, 2);
761 if (vaddress
== vbase
) {
762 if (ArmSystem::haveEL(tc
, EL3
) && !isSecure(tc
)) {
763 uint32_t bmask
= 1UL << (low_addr
+ 24);
764 match_word
= match_word
| (DBGVCR
) bmask
;
765 // Non-secure vectors
767 uint32_t bmask
= 1UL << (low_addr
);
768 match_word
= match_word
| (DBGVCR
) bmask
;
769 // Secure vectors (or no EL3)
772 uint32_t mvbase
= getVectorBase(tc
, true);
773 if (ArmSystem::haveEL(tc
, EL3
) && ELIs32(tc
, EL3
) &&
774 isSecure(tc
) && (vaddress
== mvbase
)) {
775 uint32_t bmask
= 1UL << (low_addr
+ 8);
776 match_word
= match_word
| (DBGVCR
) bmask
;
782 // Mask out bits not corresponding to vectors.
783 if (!ArmSystem::haveEL(tc
, EL3
)) {
784 mask
= (DBGVCR
) 0xDE;
785 } else if (!ELIs32(tc
, EL3
)) {
786 mask
= (DBGVCR
) 0xDE0000DE;
788 mask
= (DBGVCR
) 0xDE00DEDE;
790 DBGVCR dbgvcr
= tc
->readMiscReg(MISCREG_DBGVCR
);
791 match_word
= match_word
& dbgvcr
& mask
;
792 enabled
= match_word
!= 0x0;
793 // Check for UNPREDICTABLE case - match on Prefetch Abort and
794 // Data Abort vectors
795 ExceptionLevel ELd
= debugTargetFrom(tc
, isSecure(tc
));
796 if (((match_word
& 0x18001818) != 0x0) && ELd
== el
) {
806 VectorCatch::exceptionTrapping(ThreadContext
*tc
, ExceptionLevel el
,
809 if (conf
->isAArch32() && ELIs32(tc
, EL1
) && el
!= EL2
) {
811 DBGVCR dbgvcr
= tc
->readMiscReg(MISCREG_DBGVCR
);
812 DBGVCR match_type
= fault
->vectorCatchFlag();
815 if (!ArmSystem::haveEL(tc
, EL3
)) {
816 mask
= (DBGVCR
) 0xDE;
817 } else if (ELIs32(tc
, EL3
) && fault
->getToMode() == MODE_MON
) {
818 mask
= (DBGVCR
) 0x0000DE00;
821 mask
= (DBGVCR
) 0x000000DE;
823 mask
= (DBGVCR
) 0xDE000000;
825 match_type
= match_type
& mask
& dbgvcr
;
827 if (match_type
!= 0x0) {