Compare commits

..

1 Commits

Author SHA1 Message Date
ddc1badf48 Android #17 2023-07-23 00:58:29 +00:00
17 changed files with 96 additions and 210 deletions

View File

@ -136,22 +136,6 @@ if (YUZU_USE_BUNDLED_VCPKG)
endif() endif()
endif() endif()
if (MSVC)
set(VCPKG_DOWNLOADS_PATH ${PROJECT_SOURCE_DIR}/externals/vcpkg/downloads)
set(NASM_VERSION "2.16.01")
set(NASM_DESTINATION_PATH ${VCPKG_DOWNLOADS_PATH}/nasm-${NASM_VERSION}-win64.zip)
set(NASM_DOWNLOAD_URL "https://github.com/yuzu-emu/ext-windows-bin/raw/master/nasm/nasm-${NASM_VERSION}-win64.zip")
if (NOT EXISTS ${NASM_DESTINATION_PATH})
file(DOWNLOAD ${NASM_DOWNLOAD_URL} ${NASM_DESTINATION_PATH} SHOW_PROGRESS STATUS NASM_STATUS)
if (NOT NASM_STATUS EQUAL 0)
# Warn and not fail since vcpkg is supposed to download this package for us in the first place
message(WARNING "External nasm vcpkg package download from ${NASM_DOWNLOAD_URL} failed with status ${NASM_STATUS}")
endif()
endif()
endif()
if (YUZU_TESTS) if (YUZU_TESTS)
list(APPEND VCPKG_MANIFEST_FEATURES "yuzu-tests") list(APPEND VCPKG_MANIFEST_FEATURES "yuzu-tests")
endif() endif()

View File

@ -261,8 +261,10 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))};
const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))};
std::vector<u8> mem(size); if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
if (system.ApplicationMemory().ReadBlock(addr, mem.data(), size)) { std::vector<u8> mem(size);
system.ApplicationMemory().ReadBlock(addr, mem.data(), size);
SendReply(Common::HexToString(mem)); SendReply(Common::HexToString(mem));
} else { } else {
SendReply(GDB_STUB_REPLY_ERR); SendReply(GDB_STUB_REPLY_ERR);
@ -279,7 +281,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
const auto mem_substr{std::string_view(command).substr(mem_sep)}; const auto mem_substr{std::string_view(command).substr(mem_sep)};
const auto mem{Common::HexStringToVector(mem_substr, false)}; const auto mem{Common::HexStringToVector(mem_substr, false)};
if (system.ApplicationMemory().WriteBlock(addr, mem.data(), size)) { if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
system.ApplicationMemory().WriteBlock(addr, mem.data(), size);
system.InvalidateCpuInstructionCacheRange(addr, size); system.InvalidateCpuInstructionCacheRange(addr, size);
SendReply(GDB_STUB_REPLY_OK); SendReply(GDB_STUB_REPLY_OK);
} else { } else {

View File

@ -8,7 +8,6 @@
#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc { namespace Kernel::Svc {
@ -50,11 +49,15 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
// Copy user handles. // Copy user handles.
if (num_handles > 0) { if (num_handles > 0) {
// Get the handles. // Ensure we can try to get the handles.
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
sizeof(Handle) * num_handles), handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer); ResultInvalidPointer);
// Get the handles.
GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(),
sizeof(Handle) * num_handles);
// Convert the handles to objects. // Convert the handles to objects.
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
objs.data(), handles.data(), num_handles), objs.data(), handles.data(), num_handles),

View File

@ -7,7 +7,6 @@
#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc { namespace Kernel::Svc {
@ -65,11 +64,15 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
// Copy user handles. // Copy user handles.
if (num_handles > 0) { if (num_handles > 0) {
// Get the handles. // Ensure we can try to get the handles.
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(), R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
sizeof(Handle) * num_handles), user_handles, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer); ResultInvalidPointer);
// Get the handles.
GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
sizeof(Handle) * num_handles);
// Convert the handles to objects. // Convert the handles to objects.
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
objs.data(), handles.data(), num_handles), objs.data(), handles.data(), num_handles),

View File

@ -496,9 +496,8 @@ public:
void LoadIdTokenCache(HLERequestContext& ctx) { void LoadIdTokenCache(HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called"); LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push(0);
} }
protected: protected:

View File

@ -2,48 +2,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/glue/ectx.h" #include "core/hle/service/glue/ectx.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::Glue { namespace Service::Glue {
// This is nn::err::context::IContextRegistrar
class IContextRegistrar : public ServiceFramework<IContextRegistrar> {
public:
IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IContextRegistrar::Complete, "Complete"},
};
// clang-format on
RegisterHandlers(functions);
}
~IContextRegistrar() override = default;
private:
void Complete(HLERequestContext& ctx) {
struct InputParameters {
u32 unk;
};
struct OutputParameters {
u32 unk;
};
IPC::RequestParser rp{ctx};
[[maybe_unused]] auto input = rp.PopRaw<InputParameters>();
[[maybe_unused]] auto value = ctx.ReadBuffer();
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(0);
}
};
ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ECTX_AW::CreateContextRegistrar, "CreateContextRegistrar"}, {0, nullptr, "CreateContextRegistrar"},
{1, nullptr, "CommitContext"}, {1, nullptr, "CommitContext"},
}; };
// clang-format on // clang-format on
@ -53,10 +18,4 @@ ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
ECTX_AW::~ECTX_AW() = default; ECTX_AW::~ECTX_AW() = default;
void ECTX_AW::CreateContextRegistrar(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IContextRegistrar>(std::make_shared<IContextRegistrar>(system));
}
} // namespace Service::Glue } // namespace Service::Glue

View File

@ -15,9 +15,6 @@ class ECTX_AW final : public ServiceFramework<ECTX_AW> {
public: public:
explicit ECTX_AW(Core::System& system_); explicit ECTX_AW(Core::System& system_);
~ECTX_AW() override; ~ECTX_AW() override;
private:
void CreateContextRegistrar(HLERequestContext& ctx);
}; };
} // namespace Service::Glue } // namespace Service::Glue

View File

@ -559,7 +559,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd]; const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd];
if (!descriptor) { if (!descriptor) {
LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd); LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd);
pollfd.revents = PollEvents::Nval; pollfd.revents = PollEvents::Nval;
return {0, Errno::SUCCESS}; return {0, Errno::SUCCESS};
} }

View File

@ -24,7 +24,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{5, nullptr, "GetSettingUrl"}, {5, nullptr, "GetSettingUrl"},
{10, nullptr, "GetSettingName"}, {10, nullptr, "GetSettingName"},
{11, &NSD::GetEnvironmentIdentifier, "GetEnvironmentIdentifier"}, {11, nullptr, "GetEnvironmentIdentifier"},
{12, nullptr, "GetDeviceId"}, {12, nullptr, "GetDeviceId"},
{13, nullptr, "DeleteSettings"}, {13, nullptr, "DeleteSettings"},
{14, nullptr, "ImportSettings"}, {14, nullptr, "ImportSettings"},
@ -103,14 +103,6 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) {
const std::string environment_identifier = "lp1";
ctx.WriteBuffer(environment_identifier);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) { void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);

View File

@ -19,7 +19,6 @@ public:
private: private:
void Resolve(HLERequestContext& ctx); void Resolve(HLERequestContext& ctx);
void ResolveEx(HLERequestContext& ctx); void ResolveEx(HLERequestContext& ctx);
void GetEnvironmentIdentifier(HLERequestContext& ctx);
void GetApplicationServerEnvironmentType(HLERequestContext& ctx); void GetApplicationServerEnvironmentType(HLERequestContext& ctx);
}; };

View File

@ -24,7 +24,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"
{2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"}, {2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"},
{3, nullptr, "GetHostByAddrRequest"}, {3, nullptr, "GetHostByAddrRequest"},
{4, nullptr, "GetHostStringErrorRequest"}, {4, nullptr, "GetHostStringErrorRequest"},
{5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"}, {5, nullptr, "GetGaiStringErrorRequest"},
{6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"}, {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
{7, nullptr, "GetNameInfoRequest"}, {7, nullptr, "GetNameInfoRequest"},
{8, nullptr, "RequestCancelHandleRequest"}, {8, nullptr, "RequestCancelHandleRequest"},
@ -300,20 +300,6 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
}); });
} }
void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) {
struct InputParameters {
GetAddrInfoError gai_errno;
};
IPC::RequestParser rp{ctx};
auto input = rp.PopRaw<InputParameters>();
const std::string result = Translate(input.gai_errno);
ctx.WriteBuffer(result);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) { void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
// Additional options are ignored // Additional options are ignored
auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx); auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx);

View File

@ -18,7 +18,6 @@ public:
private: private:
void GetHostByNameRequest(HLERequestContext& ctx); void GetHostByNameRequest(HLERequestContext& ctx);
void GetGaiStringErrorRequest(HLERequestContext& ctx);
void GetHostByNameRequestWithOptions(HLERequestContext& ctx); void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
void GetAddrInfoRequest(HLERequestContext& ctx); void GetAddrInfoRequest(HLERequestContext& ctx);
void GetAddrInfoRequestWithOptions(HLERequestContext& ctx); void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);

View File

@ -81,44 +81,6 @@ GetAddrInfoError Translate(Network::GetAddrInfoError error) {
} }
} }
const char* Translate(GetAddrInfoError error) {
// https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254
switch (error) {
case GetAddrInfoError::SUCCESS:
return "Success";
case GetAddrInfoError::ADDRFAMILY:
return "Address family for hostname not supported";
case GetAddrInfoError::AGAIN:
return "Temporary failure in name resolution";
case GetAddrInfoError::BADFLAGS:
return "Invalid value for ai_flags";
case GetAddrInfoError::FAIL:
return "Non-recoverable failure in name resolution";
case GetAddrInfoError::FAMILY:
return "ai_family not supported";
case GetAddrInfoError::MEMORY:
return "Memory allocation failure";
case GetAddrInfoError::NODATA:
return "No address associated with hostname";
case GetAddrInfoError::NONAME:
return "hostname nor servname provided, or not known";
case GetAddrInfoError::SERVICE:
return "servname not supported for ai_socktype";
case GetAddrInfoError::SOCKTYPE:
return "ai_socktype not supported";
case GetAddrInfoError::SYSTEM:
return "System error returned in errno";
case GetAddrInfoError::BADHINTS:
return "Invalid value for hints";
case GetAddrInfoError::PROTOCOL:
return "Resolved protocol is unknown";
case GetAddrInfoError::OVERFLOW_:
return "Argument buffer overflow";
default:
return "Unknown error";
}
}
Network::Domain Translate(Domain domain) { Network::Domain Translate(Domain domain) {
switch (domain) { switch (domain) {
case Domain::Unspecified: case Domain::Unspecified:

View File

@ -20,9 +20,6 @@ std::pair<s32, Errno> Translate(std::pair<s32, Network::Errno> value);
/// Translate abstract getaddrinfo error to guest getaddrinfo error /// Translate abstract getaddrinfo error to guest getaddrinfo error
GetAddrInfoError Translate(Network::GetAddrInfoError value); GetAddrInfoError Translate(Network::GetAddrInfoError value);
/// Translate guest error to string
const char* Translate(GetAddrInfoError value);
/// Translate guest domain to abstract domain /// Translate guest domain to abstract domain
Network::Domain Translate(Domain domain); Network::Domain Translate(Domain domain);

View File

@ -183,13 +183,13 @@ struct Memory::Impl {
return string; return string;
} }
bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped, void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr,
auto on_memory, auto on_rasterizer, auto increment) { const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer,
const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl(); auto increment) {
const auto& page_table = process.GetPageTable().PageTableImpl();
std::size_t remaining_size = size; std::size_t remaining_size = size;
std::size_t page_index = addr >> YUZU_PAGEBITS; std::size_t page_index = addr >> YUZU_PAGEBITS;
std::size_t page_offset = addr & YUZU_PAGEMASK; std::size_t page_offset = addr & YUZU_PAGEMASK;
bool user_accessible = true;
while (remaining_size) { while (remaining_size) {
const std::size_t copy_amount = const std::size_t copy_amount =
@ -200,7 +200,6 @@ struct Memory::Impl {
const auto [pointer, type] = page_table.pointers[page_index].PointerType(); const auto [pointer, type] = page_table.pointers[page_index].PointerType();
switch (type) { switch (type) {
case Common::PageType::Unmapped: { case Common::PageType::Unmapped: {
user_accessible = false;
on_unmapped(copy_amount, current_vaddr); on_unmapped(copy_amount, current_vaddr);
break; break;
} }
@ -228,15 +227,13 @@ struct Memory::Impl {
increment(copy_amount); increment(copy_amount);
remaining_size -= copy_amount; remaining_size -= copy_amount;
} }
return user_accessible;
} }
template <bool UNSAFE> template <bool UNSAFE>
bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer, void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
const std::size_t size) { void* dest_buffer, const std::size_t size) {
return WalkBlock( WalkBlock(
src_addr, size, process, src_addr, size,
[src_addr, size, &dest_buffer](const std::size_t copy_amount, [src_addr, size, &dest_buffer](const std::size_t copy_amount,
const Common::ProcessAddress current_vaddr) { const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory, LOG_ERROR(HW_Memory,
@ -259,14 +256,14 @@ struct Memory::Impl {
}); });
} }
bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) { const std::size_t size) {
return ReadBlockImpl<false>(src_addr, dest_buffer, size); ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
} }
bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) { const std::size_t size) {
return ReadBlockImpl<true>(src_addr, dest_buffer, size); ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
} }
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const { const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
@ -286,10 +283,10 @@ struct Memory::Impl {
} }
template <bool UNSAFE> template <bool UNSAFE>
bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer, void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
const std::size_t size) { const void* src_buffer, const std::size_t size) {
return WalkBlock( WalkBlock(
dest_addr, size, process, dest_addr, size,
[dest_addr, size](const std::size_t copy_amount, [dest_addr, size](const std::size_t copy_amount,
const Common::ProcessAddress current_vaddr) { const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory, LOG_ERROR(HW_Memory,
@ -311,19 +308,20 @@ struct Memory::Impl {
}); });
} }
bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) { const std::size_t size) {
return WriteBlockImpl<false>(dest_addr, src_buffer, size); WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
} }
bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) { const std::size_t size) {
return WriteBlockImpl<true>(dest_addr, src_buffer, size); WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
} }
bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) { void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
return WalkBlock( const std::size_t size) {
dest_addr, size, WalkBlock(
process, dest_addr, size,
[dest_addr, size](const std::size_t copy_amount, [dest_addr, size](const std::size_t copy_amount,
const Common::ProcessAddress current_vaddr) { const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory, LOG_ERROR(HW_Memory,
@ -341,23 +339,23 @@ struct Memory::Impl {
[](const std::size_t copy_amount) {}); [](const std::size_t copy_amount) {});
} }
bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
const std::size_t size) { Common::ProcessAddress src_addr, const std::size_t size) {
return WalkBlock( WalkBlock(
dest_addr, size, process, dest_addr, size,
[&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory, LOG_ERROR(HW_Memory,
"Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
GetInteger(current_vaddr), GetInteger(src_addr), size); GetInteger(current_vaddr), GetInteger(src_addr), size);
ZeroBlock(dest_addr, copy_amount); ZeroBlock(process, dest_addr, copy_amount);
}, },
[&](const std::size_t copy_amount, const u8* const src_ptr) { [&](const std::size_t copy_amount, const u8* const src_ptr) {
WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount); WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount);
}, },
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) { u8* const host_ptr) {
HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount); WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount);
}, },
[&](const std::size_t copy_amount) { [&](const std::size_t copy_amount) {
dest_addr += copy_amount; dest_addr += copy_amount;
@ -366,13 +364,13 @@ struct Memory::Impl {
} }
template <typename Callback> template <typename Callback>
Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size, Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
Callback&& cb) { std::size_t size, Callback&& cb) {
class InvalidMemoryException : public std::exception {}; class InvalidMemoryException : public std::exception {};
try { try {
WalkBlock( WalkBlock(
dest_addr, size, process, dest_addr, size,
[&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) { [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
GetInteger(current_vaddr)); GetInteger(current_vaddr));
@ -389,34 +387,37 @@ struct Memory::Impl {
return ResultSuccess; return ResultSuccess;
} }
Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) { Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size) {
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
const std::size_t block_size) { const std::size_t block_size) {
// dc ivac: Invalidate to point of coherency // dc ivac: Invalidate to point of coherency
// GPU flush -> CPU invalidate // GPU flush -> CPU invalidate
HandleRasterizerDownload(GetInteger(current_vaddr), block_size); HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
}; };
return PerformCacheOperation(dest_addr, size, on_rasterizer); return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
} }
Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) { Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size) {
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
const std::size_t block_size) { const std::size_t block_size) {
// dc cvac: Store to point of coherency // dc cvac: Store to point of coherency
// CPU flush -> GPU invalidate // CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
}; };
return PerformCacheOperation(dest_addr, size, on_rasterizer); return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
} }
Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) { Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size) {
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
const std::size_t block_size) { const std::size_t block_size) {
// dc civac: Store to point of coherency, and invalidate from cache // dc civac: Store to point of coherency, and invalidate from cache
// CPU flush -> GPU invalidate // CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
}; };
return PerformCacheOperation(dest_addr, size, on_rasterizer); return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
} }
void MarkRegionDebug(u64 vaddr, u64 size, bool debug) { void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
@ -898,14 +899,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le
return impl->ReadCString(vaddr, max_length); return impl->ReadCString(vaddr, max_length);
} }
bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) { const std::size_t size) {
return impl->ReadBlock(src_addr, dest_buffer, size); impl->ReadBlock(src_addr, dest_buffer, size);
} }
bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) { const std::size_t size) {
return impl->ReadBlockUnsafe(src_addr, dest_buffer, size); impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
} }
const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const { const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
@ -916,23 +917,23 @@ u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
return impl->GetSpan(src_addr, size); return impl->GetSpan(src_addr, size);
} }
bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) { const std::size_t size) {
return impl->WriteBlock(dest_addr, src_buffer, size); impl->WriteBlock(dest_addr, src_buffer, size);
} }
bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) { const std::size_t size) {
return impl->WriteBlockUnsafe(dest_addr, src_buffer, size); impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
} }
bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
const std::size_t size) { const std::size_t size) {
return impl->CopyBlock(dest_addr, src_addr, size); impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size);
} }
bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->ZeroBlock(dest_addr, size); impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size);
} }
void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) { void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
@ -940,15 +941,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers
} }
Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->InvalidateDataCache(dest_addr, size); return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size);
} }
Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->StoreDataCache(dest_addr, size); return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size);
} }
Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->FlushDataCache(dest_addr, size); return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size);
} }
void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {

View File

@ -24,6 +24,7 @@ class GPUDirtyMemoryManager;
} // namespace Core } // namespace Core
namespace Kernel { namespace Kernel {
class PhysicalMemory;
class KProcess; class KProcess;
} // namespace Kernel } // namespace Kernel
@ -329,7 +330,7 @@ public:
* @post The range [dest_buffer, size) contains the read bytes from the * @post The range [dest_buffer, size) contains the read bytes from the
* current process' address space. * current process' address space.
*/ */
bool ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
/** /**
* Reads a contiguous block of bytes from the current process' address space. * Reads a contiguous block of bytes from the current process' address space.
@ -348,7 +349,7 @@ public:
* @post The range [dest_buffer, size) contains the read bytes from the * @post The range [dest_buffer, size) contains the read bytes from the
* current process' address space. * current process' address space.
*/ */
bool ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const; const u8* GetSpan(const VAddr src_addr, const std::size_t size) const;
u8* GetSpan(const VAddr src_addr, const std::size_t size); u8* GetSpan(const VAddr src_addr, const std::size_t size);
@ -372,7 +373,7 @@ public:
* and will mark that region as invalidated to caches that the active * and will mark that region as invalidated to caches that the active
* graphics backend may be maintaining over the course of execution. * graphics backend may be maintaining over the course of execution.
*/ */
bool WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size); void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
/** /**
* Writes a range of bytes into the current process' address space at the specified * Writes a range of bytes into the current process' address space at the specified
@ -390,7 +391,7 @@ public:
* will be ignored and an error will be logged. * will be ignored and an error will be logged.
* *
*/ */
bool WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer, void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
std::size_t size); std::size_t size);
/** /**
@ -404,7 +405,7 @@ public:
* @post The range [dest_addr, size) within the process' address space contains the * @post The range [dest_addr, size) within the process' address space contains the
* same data within the range [src_addr, size). * same data within the range [src_addr, size).
*/ */
bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
std::size_t size); std::size_t size);
/** /**
@ -417,7 +418,7 @@ public:
* @post The range [dest_addr, size) within the process' address space contains the * @post The range [dest_addr, size) within the process' address space contains the
* value 0. * value 0.
*/ */
bool ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size); void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
/** /**
* Invalidates a range of bytes within the current process' address space at the specified * Invalidates a range of bytes within the current process' address space at the specified

View File

@ -14,12 +14,12 @@
// //
#include <deque> #include <deque>
#include <map>
#include <span> #include <span>
#include <unordered_map>
#include <variant> #include <variant>
#include <vector> #include <vector>
#include <boost/container/flat_map.hpp>
#include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/frontend/ir/opcodes.h" #include "shader_recompiler/frontend/ir/opcodes.h"
#include "shader_recompiler/frontend/ir/pred.h" #include "shader_recompiler/frontend/ir/pred.h"
@ -52,7 +52,7 @@ struct IndirectBranchVariable {
using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
OverflowFlagTag, GotoVariable, IndirectBranchVariable>; OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
using ValueMap = std::unordered_map<IR::Block*, IR::Value>; using ValueMap = boost::container::flat_map<IR::Block*, IR::Value>;
struct DefTable { struct DefTable {
const IR::Value& Def(IR::Block* block, IR::Reg variable) { const IR::Value& Def(IR::Block* block, IR::Reg variable) {
@ -112,7 +112,7 @@ struct DefTable {
} }
std::array<ValueMap, IR::NUM_USER_PREDS> preds; std::array<ValueMap, IR::NUM_USER_PREDS> preds;
std::unordered_map<u32, ValueMap> goto_vars; boost::container::flat_map<u32, ValueMap> goto_vars;
ValueMap indirect_branch_var; ValueMap indirect_branch_var;
ValueMap zero_flag; ValueMap zero_flag;
ValueMap sign_flag; ValueMap sign_flag;
@ -295,7 +295,8 @@ private:
return same; return same;
} }
std::unordered_map<IR::Block*, std::map<Variant, IR::Inst*>> incomplete_phis; boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>>
incomplete_phis;
DefTable current_def; DefTable current_def;
}; };