diff options
author | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2017-12-01 13:24:29 +0000 |
---|---|---|
committer | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2017-12-21 13:25:24 +0000 |
commit | 0049df179f3b5f57218b91e98390c1aacaa27c2e (patch) | |
tree | 4830ffae7fe4f758e58ef7ad06a1f8d8853d2efb /src/arch/arm/faults.cc | |
parent | f9d6cf7eff123724a31e95195abcabc560481dda (diff) | |
download | gem5-0049df179f3b5f57218b91e98390c1aacaa27c2e.tar.xz |
arch-arm: Hyp routed undef fault need to change its syndrome
If undefined instruction has to be routed to EL2, the HSR register
must change the HSR.EC and HSR.ISS accordingly, which means not using
the EL1 exception syndrome, but the unknown reason one (EC=0, ISS=0)
Change-Id: I1540c713ab545bf307c1dad3ae305de4178443f4
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/6621
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/arm/faults.cc')
-rw-r--r-- | src/arch/arm/faults.cc | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 8d019d58a..d143056b1 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -391,6 +391,7 @@ ArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) uint32_t value; uint32_t exc_class = (uint32_t) ec(tc); uint32_t issVal = iss(); + assert(!from64 || ArmSystem::highestELIs64(tc)); value = exc_class << 26; @@ -438,12 +439,15 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) from64 = true; // Determine target exception level - if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) + if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) { toEL = EL3; - else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) + } else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) { toEL = EL2; - else + hypRouted = true; + } else { toEL = opModeToEL(nextMode()); + } + if (fromEL > toEL) toEL = fromEL; @@ -486,12 +490,14 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) armInst->annotateFault(this); } - if (have_security && routeToMonitor(tc)) + if (have_security && routeToMonitor(tc)) { cpsr.mode = MODE_MON; - else if (have_virtualization && routeToHyp(tc)) + } else if (have_virtualization && routeToHyp(tc)) { cpsr.mode = MODE_HYP; - else + hypRouted = true; + } else { cpsr.mode = nextMode(); + } // Ensure Secure state if initially in Monitor mode if (have_security && saved_cpsr.mode == MODE_MON) { @@ -747,6 +753,12 @@ UndefinedInstruction::routeToHyp(ThreadContext *tc) const uint32_t UndefinedInstruction::iss() const { + + // If UndefinedInstruction is routed to hypervisor, iss field is 0. + if (hypRouted) { + return 0; + } + if (overrideEc == EC_INVALID) return issRaw; @@ -836,7 +848,12 @@ SecureMonitorCall::iss() const ExceptionClass UndefinedInstruction::ec(ThreadContext *tc) const { - return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; + // If UndefinedInstruction is routed to hypervisor, + // HSR.EC field is 0. + if (hypRouted) + return EC_UNKNOWN; + else + return (overrideEc != EC_INVALID) ? overrideEc : vals.ec; } |