Miscallenious fixes to gl backend and qt frontend (#6834)
* renderer_gl: Make rasterizer normal class member * It doesn't need to be heap allocated anymore * gl_rasterizer: Remove default_texture * It's unused * gl_rasterizer: General cleanup * gl_rasterizer: Lower case lambdas * Match style with review comments from vulkan backend * rasterizer_cache: Prevent memory leak * Since the switch from shared_ptr these surfaces were no longer being destroyed properly. Use our garbage collector for that purpose to destroy it safely for both backends * rasterizer_cache: Make temp copy of old surface * The custom surface would override the memory region of the old region resulting in garbage data, this ensures the custom surface is constructed correctly * citra_qt: Manually create dialog tabs * Allows for custom constructors which is very useful. While at it, global state is now eliminated from configuration * citra_qt: Eliminate global system usage * core: Remove global system usage in memory and HIO * citra_qt: Use qOverload * tests: Run clang format * gl_texture_runtime: Fix surface scaling
This commit is contained in:
parent
970f2284d8
commit
88ea66053e
73 changed files with 594 additions and 555 deletions
|
@ -86,7 +86,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
|
|||
if (thread && running_core) {
|
||||
running_core->SaveContext(thread->context);
|
||||
}
|
||||
GDBStub::HandlePacket();
|
||||
GDBStub::HandlePacket(*this);
|
||||
|
||||
// If the loop is halted and we want to step, use a tiny (1) number of instructions to
|
||||
// execute. Otherwise, get out of the loop function.
|
||||
|
@ -368,7 +368,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
|||
const Kernel::New3dsHwCapabilities& n3ds_hw_caps, u32 num_cores) {
|
||||
LOG_DEBUG(HW_Memory, "initialized OK");
|
||||
|
||||
memory = std::make_unique<Memory::MemorySystem>();
|
||||
memory = std::make_unique<Memory::MemorySystem>(*this);
|
||||
|
||||
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue());
|
||||
|
||||
|
@ -632,9 +632,9 @@ void System::ApplySettings() {
|
|||
|
||||
if (IsPoweredOn()) {
|
||||
CoreTiming().UpdateClockSpeed(Settings::values.cpu_clock_percentage.GetValue());
|
||||
Core::DSP().SetSink(Settings::values.output_type.GetValue(),
|
||||
Settings::values.output_device.GetValue());
|
||||
Core::DSP().EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
||||
dsp_core->SetSink(Settings::values.output_type.GetValue(),
|
||||
Settings::values.output_device.GetValue());
|
||||
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
||||
|
||||
auto hid = Service::HID::GetModule(*this);
|
||||
if (hid) {
|
||||
|
|
|
@ -194,6 +194,10 @@ public:
|
|||
return *cpu_cores[core_id];
|
||||
};
|
||||
|
||||
[[nodiscard]] const ARM_Interface& GetCore(u32 core_id) const {
|
||||
return *cpu_cores[core_id];
|
||||
};
|
||||
|
||||
[[nodiscard]] u32 GetNumCores() const {
|
||||
return static_cast<u32>(cpu_cores.size());
|
||||
}
|
||||
|
@ -451,10 +455,6 @@ private:
|
|||
return System::GetInstance().GetNumCores();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline AudioCore::DspInterface& DSP() {
|
||||
return System::GetInstance().DSP();
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
||||
BOOST_CLASS_VERSION(Core::System, 1)
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/gdbstub/hio.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace GDBStub {
|
||||
|
@ -1035,7 +1034,7 @@ static void RemoveBreakpoint() {
|
|||
SendReply("OK");
|
||||
}
|
||||
|
||||
void HandlePacket() {
|
||||
void HandlePacket(Core::System& system) {
|
||||
if (!IsConnected()) {
|
||||
if (defer_start) {
|
||||
ToggleServer(true);
|
||||
|
@ -1076,7 +1075,7 @@ void HandlePacket() {
|
|||
Continue();
|
||||
return;
|
||||
case 'F':
|
||||
HandleHioReply(command_buffer, command_length);
|
||||
HandleHioReply(system, command_buffer, command_length);
|
||||
break;
|
||||
case 'g':
|
||||
ReadRegisters();
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
/// Breakpoint Method
|
||||
|
@ -70,7 +74,7 @@ void Break(bool is_memory_break = false);
|
|||
bool IsMemoryBreak();
|
||||
|
||||
/// Read and handle packet from gdb client.
|
||||
void HandlePacket();
|
||||
void HandlePacket(Core::System& system);
|
||||
|
||||
/**
|
||||
* Get the nearest breakpoint of the specified type at the given address.
|
||||
|
|
|
@ -54,7 +54,7 @@ static void SendErrorReply(int error_code, int retval = -1) {
|
|||
SendReply(packet.data());
|
||||
}
|
||||
|
||||
void SetHioRequest(const VAddr addr) {
|
||||
void SetHioRequest(Core::System& system, const VAddr addr) {
|
||||
if (!IsServerEnabled()) {
|
||||
LOG_WARNING(Debug_GDBStub, "HIO requested but GDB stub is not running");
|
||||
return;
|
||||
|
@ -69,15 +69,15 @@ void SetHioRequest(const VAddr addr) {
|
|||
LOG_INFO(Debug_GDBStub, "overwriting existing HIO request that was not sent yet");
|
||||
}
|
||||
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
auto& memory = system.Memory();
|
||||
const auto process = system.Kernel().GetCurrentProcess();
|
||||
|
||||
if (!memory.IsValidVirtualAddress(*process, addr)) {
|
||||
LOG_WARNING(Debug_GDBStub, "Invalid address for HIO request");
|
||||
return;
|
||||
}
|
||||
|
||||
memory.ReadBlock(*process, addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||
memory.ReadBlock(addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||
|
||||
if (current_hio_request.magic != std::array{'G', 'D', 'B', '\0'}) {
|
||||
std::string_view bad_magic{
|
||||
|
@ -105,10 +105,11 @@ void SetHioRequest(const VAddr addr) {
|
|||
Break();
|
||||
SetCpuHaltFlag(true);
|
||||
SetCpuStepFlag(false);
|
||||
Core::GetRunningCore().ClearInstructionCache();
|
||||
system.GetRunningCore().ClearInstructionCache();
|
||||
}
|
||||
|
||||
void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
||||
void HandleHioReply(Core::System& system, const u8* const command_buffer,
|
||||
const u32 command_length) {
|
||||
if (!IsWaitingForHioReply()) {
|
||||
LOG_WARNING(Debug_GDBStub, "Got HIO reply but never sent a request");
|
||||
return;
|
||||
|
@ -176,8 +177,8 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
|||
current_hio_request.retval, current_hio_request.gdb_errno,
|
||||
current_hio_request.ctrl_c);
|
||||
|
||||
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
const auto process = system.Kernel().GetCurrentProcess();
|
||||
auto& memory = system.Memory();
|
||||
|
||||
// should have been checked when we first initialized the request,
|
||||
// but just double check again before we write to memory
|
||||
|
@ -187,8 +188,7 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
|||
return;
|
||||
}
|
||||
|
||||
memory.WriteBlock(*process, current_hio_request_addr, ¤t_hio_request,
|
||||
sizeof(PackedGdbHioRequest));
|
||||
memory.WriteBlock(current_hio_request_addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||
|
||||
current_hio_request = {};
|
||||
current_hio_request_addr = 0;
|
||||
|
@ -197,7 +197,7 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
|||
// Restore state from before the request came in
|
||||
SetCpuStepFlag(was_stepping);
|
||||
SetCpuHaltFlag(was_halted);
|
||||
Core::GetRunningCore().ClearInstructionCache();
|
||||
system.GetRunningCore().ClearInstructionCache();
|
||||
}
|
||||
|
||||
bool HandlePendingHioRequestPacket() {
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
/**
|
||||
|
@ -47,7 +51,7 @@ static_assert(sizeof(PackedGdbHioRequest) == 152,
|
|||
*
|
||||
* @param address The memory address of the \ref PackedGdbHioRequest.
|
||||
*/
|
||||
void SetHioRequest(const VAddr address);
|
||||
void SetHioRequest(Core::System& system, const VAddr address);
|
||||
|
||||
/**
|
||||
* If there is a pending HIO request, send it to the client.
|
||||
|
@ -59,6 +63,6 @@ bool HandlePendingHioRequestPacket();
|
|||
/**
|
||||
* Process an HIO reply from the client.
|
||||
*/
|
||||
void HandleHioReply(const u8* const command_buffer, const u32 command_length);
|
||||
void HandleHioReply(Core::System& system, const u8* const command_buffer, const u32 command_length);
|
||||
|
||||
} // namespace GDBStub
|
||||
|
|
|
@ -1128,7 +1128,7 @@ void SVC::OutputDebugString(VAddr address, s32 len) {
|
|||
}
|
||||
|
||||
if (len == 0) {
|
||||
GDBStub::SetHioRequest(address);
|
||||
GDBStub::SetHioRequest(system, address);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1953,12 +1953,12 @@ ResultCode SVC::GetProcessList(s32* process_count, VAddr out_process_array,
|
|||
}
|
||||
|
||||
ResultCode SVC::InvalidateInstructionCacheRange(u32 addr, u32 size) {
|
||||
Core::GetRunningCore().InvalidateCacheRange(addr, size);
|
||||
system.GetRunningCore().InvalidateCacheRange(addr, size);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode SVC::InvalidateEntireInstructionCache() {
|
||||
Core::GetRunningCore().ClearInstructionCache();
|
||||
system.GetRunningCore().ClearInstructionCache();
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/global.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/hle/service/plgldr/plgldr.h"
|
||||
#include "core/hw/hw.h"
|
||||
#include "core/memory.h"
|
||||
|
@ -89,12 +87,13 @@ private:
|
|||
|
||||
class MemorySystem::Impl {
|
||||
public:
|
||||
// Visual Studio would try to allocate these on compile time if they are std::array, which would
|
||||
// exceed the memory limit.
|
||||
// Visual Studio would try to allocate these on compile time
|
||||
// if they are std::array which would exceed the memory limit.
|
||||
std::unique_ptr<u8[]> fcram = std::make_unique<u8[]>(Memory::FCRAM_N3DS_SIZE);
|
||||
std::unique_ptr<u8[]> vram = std::make_unique<u8[]>(Memory::VRAM_SIZE);
|
||||
std::unique_ptr<u8[]> n3ds_extra_ram = std::make_unique<u8[]>(Memory::N3DS_EXTRA_RAM_SIZE);
|
||||
|
||||
Core::System& system;
|
||||
std::shared_ptr<PageTable> current_page_table = nullptr;
|
||||
RasterizerCacheMarker cache_marker;
|
||||
std::vector<std::shared_ptr<PageTable>> page_table_list;
|
||||
|
@ -106,7 +105,7 @@ public:
|
|||
std::shared_ptr<BackingMem> n3ds_extra_ram_mem;
|
||||
std::shared_ptr<BackingMem> dsp_mem;
|
||||
|
||||
Impl();
|
||||
Impl(Core::System& system_);
|
||||
|
||||
const u8* GetPtr(Region r) const {
|
||||
switch (r) {
|
||||
|
@ -153,6 +152,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
u32 GetPC() const noexcept {
|
||||
return system.GetRunningCore().GetPC();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should only be called for virtual addreses with attribute `PageType::Special`.
|
||||
*/
|
||||
|
@ -187,7 +190,7 @@ public:
|
|||
HW_Memory,
|
||||
"unmapped ReadBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, src_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, src_addr, size, GetPC());
|
||||
std::memset(dest_buffer, 0, copy_amount);
|
||||
break;
|
||||
}
|
||||
|
@ -242,7 +245,7 @@ public:
|
|||
HW_Memory,
|
||||
"unmapped WriteBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, dest_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, dest_addr, size, GetPC());
|
||||
break;
|
||||
}
|
||||
case PageType::Memory: {
|
||||
|
@ -345,13 +348,13 @@ private:
|
|||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
MemorySystem::Impl::Impl()
|
||||
: fcram_mem(std::make_shared<BackingMemImpl<Region::FCRAM>>(*this)),
|
||||
MemorySystem::Impl::Impl(Core::System& system_)
|
||||
: system{system_}, fcram_mem(std::make_shared<BackingMemImpl<Region::FCRAM>>(*this)),
|
||||
vram_mem(std::make_shared<BackingMemImpl<Region::VRAM>>(*this)),
|
||||
n3ds_extra_ram_mem(std::make_shared<BackingMemImpl<Region::N3DS>>(*this)),
|
||||
dsp_mem(std::make_shared<BackingMemImpl<Region::DSP>>(*this)) {}
|
||||
|
||||
MemorySystem::MemorySystem() : impl(std::make_unique<Impl>()) {}
|
||||
MemorySystem::MemorySystem(Core::System& system) : impl(std::make_unique<Impl>(system)) {}
|
||||
MemorySystem::~MemorySystem() = default;
|
||||
|
||||
template <class Archive>
|
||||
|
@ -467,7 +470,7 @@ T MemorySystem::Read(const VAddr vaddr) {
|
|||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Read{} @ 0x{:08X} at PC 0x{:08X}", sizeof(T) * 8, vaddr,
|
||||
Core::GetRunningCore().GetPC());
|
||||
impl->GetPC());
|
||||
return 0;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
|
||||
|
@ -518,7 +521,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) {
|
|||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Write{} 0x{:08X} @ 0x{:08X} at PC 0x{:08X}",
|
||||
sizeof(data) * 8, (u32)data, vaddr, Core::GetRunningCore().GetPC());
|
||||
sizeof(data) * 8, (u32)data, vaddr, impl->GetPC());
|
||||
return;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
|
||||
|
@ -550,7 +553,7 @@ bool MemorySystem::WriteExclusive(const VAddr vaddr, const T data, const T expec
|
|||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Write{} 0x{:08X} @ 0x{:08X} at PC 0x{:08X}",
|
||||
sizeof(data) * 8, (u32)data, vaddr, Core::GetRunningCore().GetPC());
|
||||
sizeof(data) * 8, static_cast<u32>(data), vaddr, impl->GetPC());
|
||||
return true;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
|
||||
|
@ -606,8 +609,7 @@ u8* MemorySystem::GetPointer(const VAddr vaddr) {
|
|||
return GetPointerForRasterizerCache(vaddr);
|
||||
}
|
||||
|
||||
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x{:08x} at PC 0x{:08X}", vaddr,
|
||||
Core::GetRunningCore().GetPC());
|
||||
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x{:08x} at PC 0x{:08X}", vaddr, impl->GetPC());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -663,7 +665,7 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const {
|
|||
|
||||
if (area == memory_areas.end()) {
|
||||
LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#08X} at PC {:#08X}", address,
|
||||
Core::GetRunningCore().GetPC());
|
||||
impl->GetPC());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -693,8 +695,7 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const {
|
|||
return {target_mem, offset_into_region};
|
||||
}
|
||||
|
||||
/// For a rasterizer-accessible PAddr, gets a list of all possible VAddr
|
||||
static std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr) {
|
||||
std::vector<VAddr> MemorySystem::PhysicalToVirtualAddressForRasterizer(PAddr addr) {
|
||||
if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
|
||||
return {addr - VRAM_PADDR + VRAM_VADDR};
|
||||
}
|
||||
|
@ -714,7 +715,7 @@ static std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr) {
|
|||
// parts of the texture.
|
||||
LOG_ERROR(HW_Memory,
|
||||
"Trying to use invalid physical address for rasterizer: {:08X} at PC 0x{:08X}", addr,
|
||||
Core::GetRunningCore().GetPC());
|
||||
impl->GetPC());
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -729,7 +730,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached
|
|||
for (unsigned i = 0; i < num_pages; ++i, paddr += CITRA_PAGE_SIZE) {
|
||||
for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) {
|
||||
impl->cache_marker.Mark(vaddr, cached);
|
||||
for (auto page_table : impl->page_table_list) {
|
||||
for (auto& page_table : impl->page_table_list) {
|
||||
PageType& page_type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
|
||||
|
||||
if (cached) {
|
||||
|
@ -868,7 +869,7 @@ void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_add
|
|||
}
|
||||
|
||||
void MemorySystem::ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) {
|
||||
const auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
const auto& process = *impl->system.Kernel().GetCurrentProcess();
|
||||
return impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size);
|
||||
}
|
||||
|
||||
|
@ -911,7 +912,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a
|
|||
|
||||
void MemorySystem::WriteBlock(const VAddr dest_addr, const void* src_buffer,
|
||||
const std::size_t size) {
|
||||
auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
auto& process = *impl->system.Kernel().GetCurrentProcess();
|
||||
return impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size);
|
||||
}
|
||||
|
||||
|
@ -934,7 +935,7 @@ void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_ad
|
|||
LOG_ERROR(HW_Memory,
|
||||
"unmapped ZeroBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, dest_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, dest_addr, size, impl->GetPC());
|
||||
break;
|
||||
}
|
||||
case PageType::Memory: {
|
||||
|
@ -989,7 +990,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& dest_process,
|
|||
LOG_ERROR(HW_Memory,
|
||||
"unmapped CopyBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
|
||||
"0x{:08X}",
|
||||
current_vaddr, src_addr, size, Core::GetRunningCore().GetPC());
|
||||
current_vaddr, src_addr, size, impl->GetPC());
|
||||
ZeroBlock(dest_process, dest_addr, copy_amount);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ namespace Kernel {
|
|||
class Process;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace AudioCore {
|
||||
class DspInterface;
|
||||
}
|
||||
|
@ -287,7 +291,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode);
|
|||
|
||||
class MemorySystem {
|
||||
public:
|
||||
MemorySystem();
|
||||
explicit MemorySystem(Core::System& system);
|
||||
~MemorySystem();
|
||||
|
||||
/**
|
||||
|
@ -575,6 +579,9 @@ public:
|
|||
*/
|
||||
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached);
|
||||
|
||||
/// For a rasterizer-accessible PAddr, gets a list of all possible VAddr
|
||||
std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr);
|
||||
|
||||
/// Gets a pointer to the memory region beginning at the specified physical address.
|
||||
u8* GetPhysicalPointer(PAddr address) const;
|
||||
|
||||
|
@ -627,6 +634,7 @@ private:
|
|||
|
||||
void MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, PageType type);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue