summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/nce/arm_nce.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp
index bb1f6d2e6..6eb6299cc 100644
--- a/src/core/arm/nce/arm_nce.cpp
+++ b/src/core/arm/nce/arm_nce.cpp
@@ -116,10 +116,18 @@ bool ARM_NCE::HandleGuestFault(GuestContext* guest_ctx, void* raw_info, void* ra
116 return true; 116 return true;
117 } 117 }
118 118
119 // We can't handle the access, so trigger an exception. 119 // We can't handle the access, so determine why we crashed.
120 const bool is_prefetch_abort = host_ctx.pc == reinterpret_cast<u64>(info->si_addr); 120 const bool is_prefetch_abort = host_ctx.pc == reinterpret_cast<u64>(info->si_addr);
121 guest_ctx->esr_el1.fetch_or( 121
122 static_cast<u64>(is_prefetch_abort ? HaltReason::PrefetchAbort : HaltReason::DataAbort)); 122 // For data aborts, skip the instruction and return to guest code.
123 // This will allow games to continue in many scenarios where they would otherwise crash.
124 if (!is_prefetch_abort) {
125 host_ctx.pc += 4;
126 return true;
127 }
128
129 // This is a prefetch abort.
130 guest_ctx->esr_el1.fetch_or(static_cast<u64>(HaltReason::PrefetchAbort));
123 131
124 // Forcibly mark the context as locked. We are still running. 132 // Forcibly mark the context as locked. We are still running.
125 // We may race with SignalInterrupt here: 133 // We may race with SignalInterrupt here: