mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-03 19:18:09 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cd2940669 | |||
| 21ca1564fd | |||
| e6e1bd374b | |||
| d049d5cd66 |
@@ -160,16 +160,26 @@ bool ArmNce::HandleGuestAlignmentFault(GuestContext* guest_ctx, void* raw_info,
|
|||||||
bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) {
|
bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) {
|
||||||
auto* info = static_cast<siginfo_t*>(raw_info);
|
auto* info = static_cast<siginfo_t*>(raw_info);
|
||||||
|
|
||||||
// Try to handle an invalid access.
|
|
||||||
// TODO: handle accesses which split a page?
|
|
||||||
const Common::ProcessAddress addr =
|
|
||||||
(reinterpret_cast<u64>(info->si_addr) & ~Memory::YUZU_PAGEMASK);
|
|
||||||
auto& memory = guest_ctx->parent->m_running_thread->GetOwnerProcess()->GetMemory();
|
auto& memory = guest_ctx->parent->m_running_thread->GetOwnerProcess()->GetMemory();
|
||||||
if (memory.InvalidateNCE(addr, Memory::YUZU_PAGESIZE)) {
|
|
||||||
// We handled the access successfully and are returning to guest code.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Try to handle an invalid access.
|
||||||
|
auto const acc_size = 16; // Max architectural access size
|
||||||
|
// Please note accesses can be wider than 16-bytes
|
||||||
|
// This should handle **most** of the fragant issues with cases like 128-bit vector
|
||||||
|
// ld/st or GPU writes.
|
||||||
|
// This computes the addr for the (first) page corresponding to the access (if not crossing)
|
||||||
|
auto const addr_c1 = Common::ProcessAddress(u64(info->si_addr) & ~Memory::YUZU_PAGEMASK);
|
||||||
|
if (!(acc_size > 1 && (addr_c1 & Memory::YUZU_PAGEMASK) + acc_size > Memory::YUZU_PAGESIZE)) {
|
||||||
|
if (memory.InvalidateNCE(addr_c1, Memory::YUZU_PAGESIZE))
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Corresponds to the 2nd page, this means the access is split between two pages
|
||||||
|
auto const addr_c2 = (addr_c1 & ~Memory::YUZU_PAGEMASK) + Memory::YUZU_PAGESIZE;
|
||||||
|
// Always invalidate 2nd page, but only account if 1st page was invalidated properly
|
||||||
|
memory.InvalidateNCE(addr_c2, Memory::YUZU_PAGESIZE);
|
||||||
|
if (memory.InvalidateNCE(addr_c1, Memory::YUZU_PAGESIZE))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// We couldn't handle the access.
|
// We couldn't handle the access.
|
||||||
return HandleFailedGuestFault(guest_ctx, raw_info, raw_context);
|
return HandleFailedGuestFault(guest_ctx, raw_info, raw_context);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user