|
|
@ -247,10 +247,7 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size |
|
|
} |
|
|
} |
|
|
impl->multi_dev_address.Register(new_dev, start_id); |
|
|
impl->multi_dev_address.Register(new_dev, start_id); |
|
|
} |
|
|
} |
|
|
t_slot0 = {}; |
|
|
|
|
|
t_slot1 = {}; |
|
|
|
|
|
t_slot2 = {}; |
|
|
|
|
|
t_slot3 = {}; |
|
|
|
|
|
|
|
|
t_slot = {}; |
|
|
if (track) { |
|
|
if (track) { |
|
|
TrackContinuityImpl(address, virtual_address, size, asid); |
|
|
TrackContinuityImpl(address, virtual_address, size, asid); |
|
|
} |
|
|
} |
|
|
@ -282,10 +279,7 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) { |
|
|
compressed_device_addr[phys_addr - 1] = new_start | MULTI_FLAG; |
|
|
compressed_device_addr[phys_addr - 1] = new_start | MULTI_FLAG; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
t_slot0 = {}; |
|
|
|
|
|
t_slot1 = {}; |
|
|
|
|
|
t_slot2 = {}; |
|
|
|
|
|
t_slot3 = {}; |
|
|
|
|
|
|
|
|
t_slot = {}; |
|
|
} |
|
|
} |
|
|
template <typename Traits> |
|
|
template <typename Traits> |
|
|
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address, |
|
|
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address, |
|
|
@ -428,42 +422,18 @@ void DeviceMemoryManager<Traits>::ReadBlock(DAddr address, void* dest_pointer, s |
|
|
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK; |
|
|
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK; |
|
|
if (size <= Memory::YUZU_PAGESIZE - page_offset) { |
|
|
if (size <= Memory::YUZU_PAGESIZE - page_offset) { |
|
|
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK); |
|
|
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK); |
|
|
if (t_slot0.guest_page == guest_page && t_slot0.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot0.host_ptr + page_offset, size); |
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 4; ++i) { |
|
|
|
|
|
if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
if (t_slot1.guest_page == guest_page && t_slot1.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot1.host_ptr + page_offset, size); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (t_slot2.guest_page == guest_page && t_slot2.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot2.host_ptr + page_offset, size); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (t_slot3.guest_page == guest_page && t_slot3.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot3.host_ptr + page_offset, size); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; |
|
|
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; |
|
|
const auto phys_addr = compressed_physical_ptr[page_index]; |
|
|
const auto phys_addr = compressed_physical_ptr[page_index]; |
|
|
if (phys_addr != 0) { |
|
|
if (phys_addr != 0) { |
|
|
auto* const mem_ptr = GetPointerFromRaw<u8>( |
|
|
|
|
|
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS)); |
|
|
|
|
|
switch (cache_cursor & 3U) { |
|
|
|
|
|
case 0: |
|
|
|
|
|
t_slot0 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
case 1: |
|
|
|
|
|
t_slot1 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
case 2: |
|
|
|
|
|
t_slot2 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
t_slot3 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS)); |
|
|
|
|
|
t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
cache_cursor = (cache_cursor + 1) & 3U; |
|
|
cache_cursor = (cache_cursor + 1) & 3U; |
|
|
std::memcpy(dest_pointer, mem_ptr + page_offset, size); |
|
|
std::memcpy(dest_pointer, mem_ptr + page_offset, size); |
|
|
return; |
|
|
return; |
|
|
@ -510,42 +480,18 @@ void DeviceMemoryManager<Traits>::ReadBlockUnsafe(DAddr address, void* dest_poin |
|
|
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK; |
|
|
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK; |
|
|
if (size <= Memory::YUZU_PAGESIZE - page_offset) { |
|
|
if (size <= Memory::YUZU_PAGESIZE - page_offset) { |
|
|
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK); |
|
|
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK); |
|
|
if (t_slot0.guest_page == guest_page && t_slot0.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot0.host_ptr + page_offset, size); |
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 4; ++i) { |
|
|
|
|
|
if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
if (t_slot1.guest_page == guest_page && t_slot1.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot1.host_ptr + page_offset, size); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (t_slot2.guest_page == guest_page && t_slot2.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot2.host_ptr + page_offset, size); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (t_slot3.guest_page == guest_page && t_slot3.host_ptr != nullptr) { |
|
|
|
|
|
std::memcpy(dest_pointer, t_slot3.host_ptr + page_offset, size); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; |
|
|
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; |
|
|
const auto phys_addr = compressed_physical_ptr[page_index]; |
|
|
const auto phys_addr = compressed_physical_ptr[page_index]; |
|
|
if (phys_addr != 0) { |
|
|
if (phys_addr != 0) { |
|
|
auto* const mem_ptr = GetPointerFromRaw<u8>( |
|
|
|
|
|
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS)); |
|
|
|
|
|
switch (cache_cursor & 3U) { |
|
|
|
|
|
case 0: |
|
|
|
|
|
t_slot0 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
case 1: |
|
|
|
|
|
t_slot1 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
case 2: |
|
|
|
|
|
t_slot2 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
t_slot3 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS)); |
|
|
|
|
|
t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
|
|
cache_cursor = (cache_cursor + 1) & 3U; |
|
|
cache_cursor = (cache_cursor + 1) & 3U; |
|
|
std::memcpy(dest_pointer, mem_ptr + page_offset, size); |
|
|
std::memcpy(dest_pointer, mem_ptr + page_offset, size); |
|
|
return; |
|
|
return; |
|
|
|