yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Add fallback for memory read/write in case the address goes over a 4K page

This commit is contained in:
Kelebek1 2023-02-11 16:27:43 +00:00
parent 19e1ea6a02
commit 2e02ed8bb5
1 changed files with 64 additions and 12 deletions

View File

@ -20,10 +20,24 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
return; return;
} }
auto info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(aux_info))}; AuxInfo::AuxInfoDsp info{};
info->read_offset = 0; auto info_ptr{&info};
info->write_offset = 0; bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <=
info->total_sample_count = 0; (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))};
if (host_safe) [[likely]] {
info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info);
} else {
memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
info_ptr->read_offset = 0;
info_ptr->write_offset = 0;
info_ptr->total_sample_count = 0;
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
} }
/** /**
@ -71,9 +85,18 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
return 0; return 0;
} }
auto send_info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(send_info_))}; AuxInfo::AuxInfoDsp send_info{};
auto send_ptr = &send_info;
bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
u32 target_write_offset{send_info->write_offset + write_offset}; if (host_safe) [[likely]] {
send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_);
} else {
memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
u32 target_write_offset{send_ptr->write_offset + write_offset};
if (target_write_offset > count_max) { if (target_write_offset > count_max) {
return 0; return 0;
} }
@ -82,7 +105,13 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
u32 read_pos{0}; u32 read_pos{0};
while (write_count > 0) { while (write_count > 0) {
u32 to_write{std::min(count_max - target_write_offset, write_count)}; u32 to_write{std::min(count_max - target_write_offset, write_count)};
if (to_write) { const auto write_addr = send_buffer + target_write_offset * sizeof(s32);
bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))};
if (write_safe) [[likely]] {
auto ptr = memory.GetPointer(write_addr);
std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32));
} else {
memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32), memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32),
&input[read_pos], to_write * sizeof(s32)); &input[read_pos], to_write * sizeof(s32));
} }
@ -92,7 +121,11 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
} }
if (update_count) { if (update_count) {
send_info->write_offset = (send_info->write_offset + update_count) % count_max; send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max;
}
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
} }
return write_count_; return write_count_;
@ -140,9 +173,18 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
return 0; return 0;
} }
auto return_info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(return_info_))}; AuxInfo::AuxInfoDsp return_info{};
auto return_ptr = &return_info;
bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
u32 target_read_offset{return_info->read_offset + read_offset}; if (host_safe) [[likely]] {
return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_);
} else {
memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
u32 target_read_offset{return_ptr->read_offset + read_offset};
if (target_read_offset > count_max) { if (target_read_offset > count_max) {
return 0; return 0;
} }
@ -151,7 +193,13 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
u32 write_pos{0}; u32 write_pos{0};
while (read_count > 0) { while (read_count > 0) {
u32 to_read{std::min(count_max - target_read_offset, read_count)}; u32 to_read{std::min(count_max - target_read_offset, read_count)};
if (to_read) { const auto read_addr = return_buffer + target_read_offset * sizeof(s32);
bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))};
if (read_safe) [[likely]] {
auto ptr = memory.GetPointer(read_addr);
std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32));
} else {
memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32), memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32),
&output[write_pos], to_read * sizeof(s32)); &output[write_pos], to_read * sizeof(s32));
} }
@ -161,7 +209,11 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
} }
if (update_count) { if (update_count) {
return_info->read_offset = (return_info->read_offset + update_count) % count_max; return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max;
}
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
} }
return read_count_; return read_count_;