Compare commits
27 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08da0b7acc | ||
|
|
f81b915fd8 | ||
|
|
dd6c67c627 | ||
|
|
42d43ea741 | ||
|
|
d0825c9519 | ||
|
|
1913cf4783 | ||
|
|
40dee76c57 | ||
|
|
23d68a07dc | ||
|
|
60746e4e52 | ||
|
|
20d86d8a36 | ||
|
|
e9ad8e9185 | ||
|
|
1740aa5444 | ||
|
|
5ab597041f | ||
|
|
1dd4861d38 | ||
|
|
a6da2b93c1 | ||
|
|
378c881427 | ||
|
|
b1109931b9 | ||
|
|
c16cfbbc6c | ||
|
|
a994446b6e | ||
|
|
e2f2a49d2d | ||
|
|
3f78a61f09 | ||
|
|
5aafc83cc9 | ||
|
|
6d00780045 | ||
|
|
59dae03dbe | ||
|
|
22420612db | ||
|
|
2ba4e2263c | ||
|
|
0369ee7248 |
@@ -181,10 +181,10 @@ add_library(core STATIC
|
||||
hle/service/nvflinger/buffer_queue.h
|
||||
hle/service/nvflinger/nvflinger.cpp
|
||||
hle/service/nvflinger/nvflinger.h
|
||||
hle/service/pctl/module.cpp
|
||||
hle/service/pctl/module.h
|
||||
hle/service/pctl/pctl.cpp
|
||||
hle/service/pctl/pctl.h
|
||||
hle/service/pctl/pctl_a.cpp
|
||||
hle/service/pctl/pctl_a.h
|
||||
hle/service/service.cpp
|
||||
hle/service/service.h
|
||||
hle/service/set/set.cpp
|
||||
|
||||
@@ -80,19 +80,19 @@ ResultCode Disk_FileSystem::RenameFile(const std::string& src_path,
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
std::string full_path = base_directory + path;
|
||||
if (size == 0) {
|
||||
@@ -107,7 +107,7 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
LOG_ERROR(Service_FS, "Too large file");
|
||||
NGLOG_ERROR(Service_FS, "Too large file");
|
||||
// TODO(Subv): Find out the correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -120,13 +120,13 @@ ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const {
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", full_path.c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path);
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory(
|
||||
}
|
||||
|
||||
u64 Disk_FileSystem::GetFreeSpaceSize() const {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,14 +163,14 @@ ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& p
|
||||
}
|
||||
|
||||
ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
|
||||
LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
|
||||
NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||
file->Seek(offset, SEEK_SET);
|
||||
return MakeResult<size_t>(file->ReadBytes(buffer, length));
|
||||
}
|
||||
|
||||
ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush,
|
||||
const u8* buffer) const {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
file->Seek(offset, SEEK_SET);
|
||||
size_t written = file->WriteBytes(buffer, length);
|
||||
if (flush) {
|
||||
@@ -204,8 +204,7 @@ u64 Disk_Directory::Read(const u64 count, Entry* entries) {
|
||||
const std::string& filename = file.virtualName;
|
||||
Entry& entry = entries[entries_read];
|
||||
|
||||
LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size,
|
||||
file.isDirectory);
|
||||
NGLOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory);
|
||||
|
||||
// TODO(Link Mauve): use a proper conversion to UTF-16.
|
||||
for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
|
||||
|
||||
@@ -71,7 +71,7 @@ std::string Path::AsString() const {
|
||||
case Binary:
|
||||
default:
|
||||
// TODO(yuriks): Add assert
|
||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
|
||||
NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ std::u16string Path::AsU16Str() const {
|
||||
case Invalid:
|
||||
case Binary:
|
||||
// TODO(yuriks): Add assert
|
||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
|
||||
NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ std::vector<u8> Path::AsBinary() const {
|
||||
case Invalid:
|
||||
default:
|
||||
// TODO(yuriks): Add assert
|
||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
|
||||
NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <utility>
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
@@ -40,7 +39,7 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::string& file_path, siz
|
||||
|
||||
Loader::ResultStatus result = Load(file_data);
|
||||
if (result != Loader::ResultStatus::Success)
|
||||
LOG_ERROR(Service_FS, "Failed to load PFS from file %s!", file_path.c_str());
|
||||
NGLOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cinttypes>
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/file_sys/program_metadata.h"
|
||||
@@ -22,7 +21,7 @@ Loader::ResultStatus ProgramMetadata::Load(const std::string& file_path) {
|
||||
|
||||
Loader::ResultStatus result = Load(file_data);
|
||||
if (result != Loader::ResultStatus::Success)
|
||||
LOG_ERROR(Service_FS, "Failed to load NPDM from file %s!", file_path.c_str());
|
||||
NGLOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -77,14 +76,14 @@ u64 ProgramMetadata::GetFilesystemPermissions() const {
|
||||
}
|
||||
|
||||
void ProgramMetadata::Print() const {
|
||||
LOG_DEBUG(Service_FS, "Magic: %.4s", npdm_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Main thread priority: 0x%02x", npdm_header.main_thread_priority);
|
||||
LOG_DEBUG(Service_FS, "Main thread core: %u", npdm_header.main_thread_cpu);
|
||||
LOG_DEBUG(Service_FS, "Main thread stack size: 0x%x bytes", npdm_header.main_stack_size);
|
||||
LOG_DEBUG(Service_FS, "Process category: %u", npdm_header.process_category);
|
||||
LOG_DEBUG(Service_FS, "Flags: %02x", npdm_header.flags);
|
||||
LOG_DEBUG(Service_FS, " > 64-bit instructions: %s",
|
||||
npdm_header.has_64_bit_instructions ? "YES" : "NO");
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Main thread priority: {:#04X}", npdm_header.main_thread_priority);
|
||||
NGLOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu);
|
||||
NGLOG_DEBUG(Service_FS, "Main thread stack size: {:#X} bytes", npdm_header.main_stack_size);
|
||||
NGLOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category);
|
||||
NGLOG_DEBUG(Service_FS, "Flags: {:02X}", npdm_header.flags);
|
||||
NGLOG_DEBUG(Service_FS, " > 64-bit instructions: {}",
|
||||
npdm_header.has_64_bit_instructions ? "YES" : "NO");
|
||||
|
||||
auto address_space = "Unknown";
|
||||
switch (npdm_header.address_space_type) {
|
||||
@@ -96,19 +95,19 @@ void ProgramMetadata::Print() const {
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_DEBUG(Service_FS, " > Address space: %s\n", address_space);
|
||||
NGLOG_DEBUG(Service_FS, " > Address space: {}\n", address_space);
|
||||
|
||||
// Begin ACID printing (potential perms, signed)
|
||||
LOG_DEBUG(Service_FS, "Magic: %.4s", acid_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Flags: %02x", acid_header.flags);
|
||||
LOG_DEBUG(Service_FS, " > Is Retail: %s", acid_header.is_retail ? "YES" : "NO");
|
||||
LOG_DEBUG(Service_FS, "Title ID Min: %016" PRIX64, acid_header.title_id_min);
|
||||
LOG_DEBUG(Service_FS, "Title ID Max: %016" PRIX64, acid_header.title_id_max);
|
||||
LOG_DEBUG(Service_FS, "Filesystem Access: %016" PRIX64 "\n", acid_file_access.permissions);
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Flags: {:02X}", acid_header.flags);
|
||||
NGLOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
|
||||
NGLOG_DEBUG(Service_FS, "Title ID Min: {:016X}", acid_header.title_id_min);
|
||||
NGLOG_DEBUG(Service_FS, "Title ID Max: {:016X}", acid_header.title_id_max);
|
||||
NGLOG_DEBUG(Service_FS, "Filesystem Access: {:016X}\n", acid_file_access.permissions);
|
||||
|
||||
// Begin ACI0 printing (actual perms, unsigned)
|
||||
LOG_DEBUG(Service_FS, "Magic: %.4s", aci_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Title ID: %016" PRIX64, aci_header.title_id);
|
||||
LOG_DEBUG(Service_FS, "Filesystem Access: %016" PRIX64 "\n", aci_file_access.permissions);
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Title ID: {:016X}", aci_header.title_id);
|
||||
NGLOG_DEBUG(Service_FS, "Filesystem Access: {:016X}\n", aci_file_access.permissions);
|
||||
}
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace FileSys {
|
||||
RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) {
|
||||
// Load the RomFS from the app
|
||||
if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) {
|
||||
LOG_ERROR(Service_FS, "Unable to read RomFS!");
|
||||
NGLOG_ERROR(Service_FS, "Unable to read RomFS!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa
|
||||
}
|
||||
|
||||
ResultCode RomFS_Factory::Format(const Path& path) {
|
||||
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const {
|
||||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
@@ -21,74 +21,72 @@ ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const std:
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName());
|
||||
// TODO(bunnei): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path,
|
||||
const std::string& dest_path) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName());
|
||||
// TODO(bunnei): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
|
||||
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).",
|
||||
GetName().c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory(
|
||||
const std::string& path) const {
|
||||
LOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive");
|
||||
NGLOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive");
|
||||
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>());
|
||||
}
|
||||
|
||||
u64 RomFS_FileSystem::GetFreeSpaceSize() const {
|
||||
LOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive");
|
||||
NGLOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const {
|
||||
LOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path %s).", path.c_str());
|
||||
NGLOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path);
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
|
||||
LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
|
||||
NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||
romfs_file->Seek(data_offset + offset, SEEK_SET);
|
||||
size_t read_length = (size_t)std::min((u64)length, data_size - offset);
|
||||
|
||||
@@ -97,7 +95,7 @@ ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8*
|
||||
|
||||
ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush,
|
||||
const u8* buffer) const {
|
||||
LOG_ERROR(Service_FS, "Attempted to write to ROMFS file");
|
||||
NGLOG_ERROR(Service_FS, "Attempted to write to ROMFS file");
|
||||
// TODO(Subv): Find error code
|
||||
return MakeResult<size_t>(0);
|
||||
}
|
||||
@@ -107,7 +105,7 @@ u64 RomFS_Storage::GetSize() const {
|
||||
}
|
||||
|
||||
bool RomFS_Storage::SetSize(const u64 size) const {
|
||||
LOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file");
|
||||
NGLOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/disk_filesystem.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
@@ -30,7 +28,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path&
|
||||
}
|
||||
|
||||
ResultCode SaveData_Factory::Format(const Path& path) {
|
||||
LOG_WARNING(Service_FS, "Format archive %s", GetName().c_str());
|
||||
NGLOG_WARNING(Service_FS, "Format archive {}", GetName());
|
||||
// Create the save data directory.
|
||||
if (!FileUtil::CreateFullPath(GetFullPath())) {
|
||||
// TODO(Subv): Find the correct error code.
|
||||
@@ -41,7 +39,7 @@ ResultCode SaveData_Factory::Format(const Path& path) {
|
||||
}
|
||||
|
||||
ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const {
|
||||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -50,8 +48,7 @@ std::string SaveData_Factory::GetFullPath() const {
|
||||
u64 title_id = Core::CurrentProcess()->program_id;
|
||||
// TODO(Subv): Somehow obtain this value.
|
||||
u32 user = 0;
|
||||
return Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X/", nand_directory.c_str(), title_id,
|
||||
user);
|
||||
return fmt::format("{}save/{:016X}/{:08X}/", nand_directory, title_id, user);
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
@@ -26,13 +25,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& pat
|
||||
}
|
||||
|
||||
ResultCode SDMC_Factory::Format(const Path& path) {
|
||||
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
|
||||
// TODO(Subv): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const {
|
||||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
|
||||
|
||||
u16 slot = next_free_slot;
|
||||
if (slot >= generations.size()) {
|
||||
LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
|
||||
NGLOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
|
||||
return ERR_OUT_OF_HANDLES;
|
||||
}
|
||||
next_free_slot = generations[slot];
|
||||
@@ -48,7 +48,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
|
||||
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||
SharedPtr<Object> object = GetGeneric(handle);
|
||||
if (object == nullptr) {
|
||||
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle);
|
||||
NGLOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
return Create(std::move(object));
|
||||
|
||||
@@ -118,7 +118,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
|
||||
std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
|
||||
} else {
|
||||
if (Session()->IsDomain())
|
||||
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
|
||||
NGLOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +270,8 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const {
|
||||
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
|
||||
const size_t buffer_size{GetWriteBufferSize()};
|
||||
if (size > buffer_size) {
|
||||
LOG_CRITICAL(Core, "size (%016zx) is greater than buffer_size (%016zx)", size, buffer_size);
|
||||
NGLOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
|
||||
buffer_size);
|
||||
size = buffer_size; // TODO(bunnei): This needs to be HW tested
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
||||
continue;
|
||||
} else if ((type & 0xF00) == 0xE00) { // 0x0FFF
|
||||
// Allowed interrupts list
|
||||
LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
|
||||
NGLOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
|
||||
} else if ((type & 0xF80) == 0xF00) { // 0x07FF
|
||||
// Allowed syscalls mask
|
||||
unsigned int index = ((descriptor >> 24) & 7) * 24;
|
||||
@@ -74,7 +74,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
||||
} else if ((type & 0xFFE) == 0xFF8) { // 0x001F
|
||||
// Mapped memory range
|
||||
if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) {
|
||||
LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
|
||||
NGLOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
|
||||
continue;
|
||||
}
|
||||
u32 end_desc = kernel_caps[i + 1];
|
||||
@@ -109,9 +109,9 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
||||
|
||||
int minor = kernel_version & 0xFF;
|
||||
int major = (kernel_version >> 8) & 0xFF;
|
||||
LOG_INFO(Loader, "ExHeader kernel version: %d.%d", major, minor);
|
||||
NGLOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor);
|
||||
} else {
|
||||
LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor);
|
||||
NGLOG_ERROR(Loader, "Unhandled kernel caps descriptor: {:#010X}", descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory cat
|
||||
case ResourceLimitCategory::OTHER:
|
||||
return resource_limits[static_cast<u8>(category)];
|
||||
default:
|
||||
LOG_CRITICAL(Kernel, "Unknown resource limit category");
|
||||
NGLOG_CRITICAL(Kernel, "Unknown resource limit category");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
|
||||
case ResourceType::CPUTime:
|
||||
return current_cpu_time;
|
||||
default:
|
||||
LOG_ERROR(Kernel, "Unknown resource type=%08X", static_cast<u32>(resource));
|
||||
NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ u32 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
|
||||
case ResourceType::CPUTime:
|
||||
return max_cpu_time;
|
||||
default:
|
||||
LOG_ERROR(Kernel, "Unknown resource type=%08X", static_cast<u32>(resource));
|
||||
NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -94,11 +94,11 @@ void Scheduler::Reschedule() {
|
||||
Thread* next = PopNextReadyThread();
|
||||
|
||||
if (cur && next) {
|
||||
LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId());
|
||||
NGLOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId());
|
||||
} else if (cur) {
|
||||
LOG_TRACE(Kernel, "context switch %u -> idle", cur->GetObjectId());
|
||||
NGLOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId());
|
||||
} else if (next) {
|
||||
LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId());
|
||||
NGLOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId());
|
||||
}
|
||||
|
||||
SwitchContext(next);
|
||||
|
||||
@@ -68,7 +68,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||
return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||
|
||||
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
|
||||
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id);
|
||||
NGLOG_DEBUG(IPC, "CloseVirtualHandle, object_id={:#010X}", object_id);
|
||||
|
||||
domain_request_handlers[object_id - 1] = nullptr;
|
||||
|
||||
@@ -78,8 +78,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||
}
|
||||
}
|
||||
|
||||
LOG_CRITICAL(IPC, "Unknown domain command=%d",
|
||||
static_cast<int>(domain_message_header->command.Value()));
|
||||
NGLOG_CRITICAL(IPC, "Unknown domain command={}",
|
||||
static_cast<int>(domain_message_header->command.Value()));
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,16 +107,16 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
|
||||
// Error out if the requested permissions don't match what the creator process allows.
|
||||
if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
NGLOG_ERROR(Kernel, "cannot map id={}, address={:#X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
// Error out if the provided permissions are not compatible with what the creator process needs.
|
||||
if (other_permissions != MemoryPermission::DontCare &&
|
||||
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
NGLOG_ERROR(Kernel, "cannot map id={}, address={:#X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_WRONG_PERMISSION;
|
||||
}
|
||||
|
||||
@@ -131,9 +131,10 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
auto result = target_process->vm_manager.MapMemoryBlock(
|
||||
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
|
||||
if (result.Failed()) {
|
||||
LOG_ERROR(Kernel,
|
||||
"cannot map id=%u, target_address=0x%lx name=%s, error mapping to virtual memory",
|
||||
GetObjectId(), target_address, name.c_str());
|
||||
NGLOG_ERROR(
|
||||
Kernel,
|
||||
"cannot map id={}, target_address={:#X} name={}, error mapping to virtual memory",
|
||||
GetObjectId(), target_address, name);
|
||||
return result.Code();
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) {
|
||||
u32 masked_permissions =
|
||||
static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute);
|
||||
return static_cast<VMAPermission>(masked_permissions);
|
||||
};
|
||||
}
|
||||
|
||||
u8* SharedMemory::GetPointer(u32 offset) {
|
||||
return backing_block->data() + backing_block_offset + offset;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Kernel {
|
||||
|
||||
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
||||
static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, heap_size=0x%llx", heap_size);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, heap_size={:#X}", heap_size);
|
||||
auto& process = *Core::CurrentProcess();
|
||||
CASCADE_RESULT(*heap_addr,
|
||||
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
|
||||
@@ -39,21 +39,21 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
|
||||
}
|
||||
|
||||
static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%lx", addr);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, addr={:#X}", addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Maps a memory range into a different range.
|
||||
static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
|
||||
src_addr, size);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, dst_addr={:#X}, src_addr={:#X}, size={:#X}", dst_addr,
|
||||
src_addr, size);
|
||||
return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
|
||||
}
|
||||
|
||||
/// Unmaps a region that was previously mapped with svcMapMemory
|
||||
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
|
||||
src_addr, size);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, dst_addr={:#X}, src_addr={:#X}, size={:#X}", dst_addr,
|
||||
src_addr, size);
|
||||
return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
|
||||
if (port_name.size() > PortNameMaxLength)
|
||||
return ERR_PORT_NAME_TOO_LONG;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name.c_str());
|
||||
NGLOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
|
||||
|
||||
auto it = Service::g_kernel_named_ports.find(port_name);
|
||||
if (it == Service::g_kernel_named_ports.end()) {
|
||||
LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name.c_str());
|
||||
NGLOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
|
||||
return ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -90,11 +90,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
|
||||
static ResultCode SendSyncRequest(Handle handle) {
|
||||
SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle);
|
||||
if (!session) {
|
||||
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x%08X", handle);
|
||||
NGLOG_ERROR(Kernel_SVC, "called with invalid handle={:#010X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
|
||||
NGLOG_TRACE(Kernel_SVC, "called handle={:#010X}({})", handle, session->GetName());
|
||||
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
|
||||
@@ -105,7 +105,7 @@ static ResultCode SendSyncRequest(Handle handle) {
|
||||
|
||||
/// Get the ID for the specified thread.
|
||||
static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "called thread={:#010X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -118,7 +118,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
|
||||
|
||||
/// Get the ID of the specified process
|
||||
static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "called process={:#010X}", process_handle);
|
||||
|
||||
const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
|
||||
if (!process) {
|
||||
@@ -178,8 +178,8 @@ static ResultCode WaitSynchronization1(
|
||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
||||
static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count,
|
||||
s64 nano_seconds) {
|
||||
LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d",
|
||||
handles_address, handle_count, nano_seconds);
|
||||
NGLOG_TRACE(Kernel_SVC, "called handles_address={:#X}, handle_count={}, nano_seconds={}",
|
||||
handles_address, handle_count, nano_seconds);
|
||||
|
||||
if (!Memory::IsValidVirtualAddress(handles_address))
|
||||
return ERR_INVALID_POINTER;
|
||||
@@ -239,7 +239,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
|
||||
|
||||
/// Resumes a thread waiting on WaitSynchronization
|
||||
static ResultCode CancelSynchronization(Handle thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "called thread={:#X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -256,38 +256,38 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
|
||||
/// Attempts to locks a mutex, creating it if it does not already exist
|
||||
static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
Handle requesting_thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called holding_thread_handle=0x%08X, mutex_addr=0x%llx, "
|
||||
"requesting_current_thread_handle=0x%08X",
|
||||
holding_thread_handle, mutex_addr, requesting_thread_handle);
|
||||
NGLOG_TRACE(Kernel_SVC,
|
||||
"called holding_thread_handle={:#010X}, mutex_addr={:#X}, "
|
||||
"requesting_current_thread_handle={:#010X}",
|
||||
holding_thread_handle, mutex_addr, requesting_thread_handle);
|
||||
|
||||
return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle);
|
||||
}
|
||||
|
||||
/// Unlock a mutex
|
||||
static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
|
||||
LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr);
|
||||
NGLOG_TRACE(Kernel_SVC, "called mutex_addr={:#X}", mutex_addr);
|
||||
|
||||
return Mutex::Release(mutex_addr);
|
||||
}
|
||||
|
||||
/// Break program execution
|
||||
static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
|
||||
LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
|
||||
NGLOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
||||
static void OutputDebugString(VAddr address, s32 len) {
|
||||
std::vector<char> string(len);
|
||||
Memory::ReadBlock(address, string.data(), len);
|
||||
LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
|
||||
std::string str(len, '\0');
|
||||
Memory::ReadBlock(address, str.data(), str.size());
|
||||
NGLOG_DEBUG(Debug_Emulated, "{}", str);
|
||||
}
|
||||
|
||||
/// Gets system/memory information for the current process
|
||||
static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) {
|
||||
LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id,
|
||||
info_sub_id, handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "called info_id={:#X}, info_sub_id={:#X}, handle={:#010X}", info_id,
|
||||
info_sub_id, handle);
|
||||
|
||||
auto& vm_manager = Core::CurrentProcess()->vm_manager;
|
||||
|
||||
@@ -338,12 +338,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
*result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
|
||||
break;
|
||||
case GetInfoType::TitleId:
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
case GetInfoType::PrivilegedProcessId:
|
||||
LOG_WARNING(Kernel_SVC,
|
||||
"(STUBBED) Attempted to query priviledged process id bounds, returned 0");
|
||||
NGLOG_WARNING(Kernel_SVC,
|
||||
"(STUBBED) Attempted to query privileged process id bounds, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
default:
|
||||
@@ -355,13 +355,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
|
||||
/// Sets the thread activity
|
||||
static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, unknown=0x%08X", handle, unknown);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, unknown={:#010X}", handle,
|
||||
unknown);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Gets the thread context
|
||||
static ResultCode GetThreadContext(Handle handle, VAddr addr) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, addr=0x%" PRIx64, handle, addr);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, addr={:#X}", handle, addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -400,15 +401,15 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
||||
|
||||
/// Get which CPU core is executing the current thread
|
||||
static u32 GetCurrentProcessorNumber() {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, defaulting to processor 0");
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, defaulting to processor 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size,
|
||||
u32 permissions) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",
|
||||
shared_memory_handle, addr, size, permissions);
|
||||
NGLOG_TRACE(Kernel_SVC,
|
||||
"called, shared_memory_handle={:#X}, addr={:#X}, size={:#X}, permissions={:#010X}",
|
||||
shared_memory_handle, addr, size, permissions);
|
||||
|
||||
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
|
||||
if (!shared_memory) {
|
||||
@@ -428,16 +429,15 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
|
||||
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
|
||||
MemoryPermission::DontCare);
|
||||
default:
|
||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
|
||||
NGLOG_ERROR(Kernel_SVC, "unknown permissions={:#010X}", permissions);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
|
||||
LOG_WARNING(Kernel_SVC,
|
||||
"called, shared_memory_handle=0x%08X, addr=0x%" PRIx64 ", size=0x%" PRIx64 "",
|
||||
shared_memory_handle, addr, size);
|
||||
NGLOG_WARNING(Kernel_SVC, "called, shared_memory_handle={:#010X}, addr={:#X}, size={:#X}",
|
||||
shared_memory_handle, addr, size);
|
||||
|
||||
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
|
||||
|
||||
@@ -465,19 +465,19 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
|
||||
memory_info->type = static_cast<u32>(vma->second.meminfo_state);
|
||||
}
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x%08X addr=%llx", process_handle, addr);
|
||||
NGLOG_TRACE(Kernel_SVC, "called process={:#010X} addr={:X}", process_handle, addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Query memory
|
||||
static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) {
|
||||
LOG_TRACE(Kernel_SVC, "called, addr=%llx", addr);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, addr={:X}", addr);
|
||||
return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr);
|
||||
}
|
||||
|
||||
/// Exits the current process
|
||||
static void ExitProcess() {
|
||||
LOG_INFO(Kernel_SVC, "Process %u exiting", Core::CurrentProcess()->process_id);
|
||||
NGLOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id);
|
||||
|
||||
ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
|
||||
"Process has already exited");
|
||||
@@ -534,9 +534,9 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
|
||||
case THREADPROCESSORID_2:
|
||||
case THREADPROCESSORID_3:
|
||||
// TODO(bunnei): Implement support for other processor IDs
|
||||
LOG_ERROR(Kernel_SVC,
|
||||
"Newly created thread must run in another thread (%u), unimplemented.",
|
||||
processor_id);
|
||||
NGLOG_ERROR(Kernel_SVC,
|
||||
"Newly created thread must run in another thread ({}), unimplemented.",
|
||||
processor_id);
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(false, "Unsupported thread processor ID: %d", processor_id);
|
||||
@@ -551,17 +551,17 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
|
||||
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
|
||||
"threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
|
||||
entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle);
|
||||
NGLOG_TRACE(Kernel_SVC,
|
||||
"called entrypoint={:#010X} ({}), arg={:#010X}, stacktop={:#010X}, "
|
||||
"threadpriority={:#010X}, processorid={:#010X} : created handle={:#010X}",
|
||||
entry_point, name, arg, stack_top, priority, processor_id, *out_handle);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Starts the thread for the provided handle
|
||||
static ResultCode StartThread(Handle thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "called thread={:#010X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -575,7 +575,7 @@ static ResultCode StartThread(Handle thread_handle) {
|
||||
|
||||
/// Called when a thread exits
|
||||
static void ExitThread() {
|
||||
LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC());
|
||||
NGLOG_TRACE(Kernel_SVC, "called, pc={:#010X}", Core::CPU().GetPC());
|
||||
|
||||
ExitCurrentThread();
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
@@ -583,7 +583,7 @@ static void ExitThread() {
|
||||
|
||||
/// Sleep the current thread
|
||||
static void SleepThread(s64 nanoseconds) {
|
||||
LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds);
|
||||
NGLOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
|
||||
|
||||
// Don't attempt to yield execution if there are no available threads to run,
|
||||
// this way we avoid a useless reschedule to the idle thread.
|
||||
@@ -602,9 +602,9 @@ static void SleepThread(s64 nanoseconds) {
|
||||
/// Signal process wide key atomic
|
||||
static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr,
|
||||
Handle thread_handle, s64 nano_seconds) {
|
||||
LOG_TRACE(
|
||||
NGLOG_TRACE(
|
||||
Kernel_SVC,
|
||||
"called mutex_addr=%llx, condition_variable_addr=%llx, thread_handle=0x%08X, timeout=%d",
|
||||
"called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle={:#010X}, timeout={}",
|
||||
mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
|
||||
|
||||
SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
@@ -629,8 +629,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
|
||||
|
||||
/// Signal process wide key
|
||||
static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) {
|
||||
LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x",
|
||||
condition_variable_addr, target);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, condition_variable_addr={:#X}, target={:#010X}",
|
||||
condition_variable_addr, target);
|
||||
|
||||
u32 processed = 0;
|
||||
auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList();
|
||||
@@ -696,13 +696,13 @@ static u64 GetSystemTick() {
|
||||
|
||||
/// Close a handle
|
||||
static ResultCode CloseHandle(Handle handle) {
|
||||
LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "Closing handle {:#010X}", handle);
|
||||
return g_handle_table.Close(handle);
|
||||
}
|
||||
|
||||
/// Reset an event
|
||||
static ResultCode ResetSignal(Handle handle) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x%08X", handle);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called handle {:#010X}", handle);
|
||||
auto event = g_handle_table.Get<Event>(handle);
|
||||
ASSERT(event != nullptr);
|
||||
event->Clear();
|
||||
@@ -711,29 +711,29 @@ static ResultCode ResetSignal(Handle handle) {
|
||||
|
||||
/// Creates a TransferMemory object
|
||||
static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%lx, size=0x%lx, perms=%08X", addr, size,
|
||||
permissions);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called addr={:#X}, size={:#X}, perms={:010X}", addr, size,
|
||||
permissions);
|
||||
*handle = 0;
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode GetThreadCoreMask(Handle handle, u32* mask, u64* unknown) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X", handle);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:010X}", handle);
|
||||
*mask = 0x0;
|
||||
*unknown = 0xf;
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode SetThreadCoreMask(Handle handle, u32 mask, u64 unknown) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, mask=0x%08X, unknown=0x%lx", handle,
|
||||
mask, unknown);
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, mask={:#010X}, unknown={:#X}",
|
||||
handle, mask, unknown);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions,
|
||||
u32 remote_permissions) {
|
||||
LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size,
|
||||
local_permissions, remote_permissions);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, size={:#X}, localPerms={:#010X}, remotePerms={:#010X}", size,
|
||||
local_permissions, remote_permissions);
|
||||
auto sharedMemHandle =
|
||||
SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
|
||||
static_cast<MemoryPermission>(local_permissions),
|
||||
@@ -744,7 +744,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
|
||||
}
|
||||
|
||||
static ResultCode ClearEvent(Handle handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called, event=0xX", handle);
|
||||
NGLOG_TRACE(Kernel_SVC, "called, event={:010X}", handle);
|
||||
|
||||
SharedPtr<Event> evt = g_handle_table.Get<Event>(handle);
|
||||
if (evt == nullptr)
|
||||
@@ -896,7 +896,7 @@ static const FunctionDef SVC_Table[] = {
|
||||
|
||||
static const FunctionDef* GetSVCInfo(u32 func_num) {
|
||||
if (func_num >= std::size(SVC_Table)) {
|
||||
LOG_ERROR(Kernel_SVC, "unknown svc=0x%02X", func_num);
|
||||
NGLOG_ERROR(Kernel_SVC, "Unknown svc={:#04X}", func_num);
|
||||
return nullptr;
|
||||
}
|
||||
return &SVC_Table[func_num];
|
||||
@@ -915,10 +915,10 @@ void CallSVC(u32 immediate) {
|
||||
if (info->func) {
|
||||
info->func();
|
||||
} else {
|
||||
LOG_CRITICAL(Kernel_SVC, "unimplemented SVC function %s(..)", info->name);
|
||||
NGLOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
|
||||
}
|
||||
} else {
|
||||
LOG_CRITICAL(Kernel_SVC, "unknown SVC function 0x%x", immediate);
|
||||
NGLOG_CRITICAL(Kernel_SVC, "Unknown SVC function {:#X}", immediate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,9 +101,10 @@ void ExitCurrentThread() {
|
||||
* @param cycles_late The number of CPU cycles that have passed since the desired wakeup time
|
||||
*/
|
||||
static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
|
||||
SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>((Handle)thread_handle);
|
||||
const auto proper_handle = static_cast<Handle>(thread_handle);
|
||||
SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle);
|
||||
if (thread == nullptr) {
|
||||
LOG_CRITICAL(Kernel, "Callback fired for invalid thread %08X", (Handle)thread_handle);
|
||||
NGLOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,19 +239,19 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||
SharedPtr<Process> owner_process) {
|
||||
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
||||
if (priority > THREADPRIO_LOWEST) {
|
||||
LOG_ERROR(Kernel_SVC, "Invalid thread priority: %u", priority);
|
||||
NGLOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
|
||||
return ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (processor_id > THREADPROCESSORID_MAX) {
|
||||
LOG_ERROR(Kernel_SVC, "Invalid processor id: %d", processor_id);
|
||||
NGLOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id);
|
||||
return ERR_OUT_OF_RANGE_KERNEL;
|
||||
}
|
||||
|
||||
// TODO(yuriks): Other checks, returning 0xD9001BEA
|
||||
|
||||
if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) {
|
||||
LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %016" PRIx64, name.c_str(), entry_point);
|
||||
NGLOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
|
||||
// TODO (bunnei): Find the correct error code to use here
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -289,8 +290,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||
auto& linheap_memory = memory_region->linear_heap_memory;
|
||||
|
||||
if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
|
||||
LOG_ERROR(Kernel_SVC,
|
||||
"Not enough space in region to allocate a new TLS page for thread");
|
||||
NGLOG_ERROR(Kernel_SVC,
|
||||
"Not enough space in region to allocate a new TLS page for thread");
|
||||
return ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ void Timer::WakeupAllWaitingThreads() {
|
||||
}
|
||||
|
||||
void Timer::Signal(int cycles_late) {
|
||||
LOG_TRACE(Kernel, "Timer %u fired", GetObjectId());
|
||||
NGLOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
|
||||
|
||||
signaled = true;
|
||||
|
||||
@@ -97,7 +97,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
|
||||
timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
|
||||
|
||||
if (timer == nullptr) {
|
||||
LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle);
|
||||
NGLOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -379,22 +379,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
|
||||
}
|
||||
|
||||
u64 VMManager::GetTotalMemoryUsage() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0xF8000000;
|
||||
}
|
||||
|
||||
u64 VMManager::GetTotalHeapUsage() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetAddressSpaceBaseAddr() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x8000000;
|
||||
}
|
||||
|
||||
u64 VMManager::GetAddressSpaceSize() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return MAX_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/pctl/pctl_a.h"
|
||||
#include "core/hle/service/pctl/module.h"
|
||||
#include "core/hle/service/pctl/pctl.h"
|
||||
|
||||
namespace Service::PCTL {
|
||||
|
||||
@@ -12,7 +13,7 @@ class IParentalControlService final : public ServiceFramework<IParentalControlSe
|
||||
public:
|
||||
IParentalControlService() : ServiceFramework("IParentalControlService") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, nullptr, "Initialize"},
|
||||
{1, &IParentalControlService::Initialize, "Initialize"},
|
||||
{1001, nullptr, "CheckFreeCommunicationPermission"},
|
||||
{1002, nullptr, "ConfirmLaunchApplicationPermission"},
|
||||
{1003, nullptr, "ConfirmResumeApplicationPermission"},
|
||||
@@ -108,20 +109,38 @@ public:
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void Initialize(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_PCTL, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
};
|
||||
void PCTL_A::CreateService(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IParentalControlService>();
|
||||
NGLOG_DEBUG(Service_PCTL, "called");
|
||||
}
|
||||
|
||||
PCTL_A::PCTL_A() : ServiceFramework("pctl:a") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &PCTL_A::CreateService, "CreateService"},
|
||||
{1, nullptr, "CreateServiceWithoutInitialize"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IParentalControlService>();
|
||||
NGLOG_DEBUG(Service_PCTL, "called");
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
: ServiceFramework(name), module(std::move(module)) {}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
auto module = std::make_shared<Module>();
|
||||
std::make_shared<PCTL>(module, "pctl")->InstallAsService(service_manager);
|
||||
std::make_shared<PCTL>(module, "pctl:a")->InstallAsService(service_manager);
|
||||
std::make_shared<PCTL>(module, "pctl:r")->InstallAsService(service_manager);
|
||||
std::make_shared<PCTL>(module, "pctl:s")->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Service::PCTL
|
||||
28
src/core/hle/service/pctl/module.h
Normal file
28
src/core/hle/service/pctl/module.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::PCTL {
|
||||
|
||||
class Module final {
|
||||
public:
|
||||
class Interface : public ServiceFramework<Interface> {
|
||||
public:
|
||||
Interface(std::shared_ptr<Module> module, const char* name);
|
||||
|
||||
void CreateService(Kernel::HLERequestContext& ctx);
|
||||
void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Module> module;
|
||||
};
|
||||
};
|
||||
|
||||
/// Registers all PCTL services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Service::PCTL
|
||||
@@ -3,12 +3,15 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/pctl/pctl.h"
|
||||
#include "core/hle/service/pctl/pctl_a.h"
|
||||
|
||||
namespace Service::PCTL {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<PCTL_A>()->InstallAsService(service_manager);
|
||||
PCTL::PCTL(std::shared_ptr<Module> module, const char* name)
|
||||
: Module::Interface(std::move(module), name) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &PCTL::CreateService, "CreateService"},
|
||||
{1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Service::PCTL
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/pctl/module.h"
|
||||
|
||||
namespace Service::PCTL {
|
||||
|
||||
/// Registers all PCTL services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
class PCTL final : public Module::Interface {
|
||||
public:
|
||||
explicit PCTL(std::shared_ptr<Module> module, const char* name);
|
||||
};
|
||||
|
||||
} // namespace Service::PCTL
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::PCTL {
|
||||
|
||||
class PCTL_A final : public ServiceFramework<PCTL_A> {
|
||||
public:
|
||||
PCTL_A();
|
||||
~PCTL_A() = default;
|
||||
|
||||
private:
|
||||
void CreateService(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Service::PCTL
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "core/hle/service/nifm/nifm.h"
|
||||
#include "core/hle/service/ns/ns.h"
|
||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||
#include "core/hle/service/pctl/pctl.h"
|
||||
#include "core/hle/service/pctl/module.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/set/settings.h"
|
||||
#include "core/hle/service/sm/controller.h"
|
||||
|
||||
@@ -33,7 +33,8 @@ inline void Read(T& var, const u32 addr) {
|
||||
LCD::Read(var, addr);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr);
|
||||
NGLOG_ERROR(HW_Memory, "Unknown Read{} @ {:#010X}", sizeof(var) * 8, addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +62,8 @@ inline void Write(u32 addr, const T data) {
|
||||
LCD::Write(addr, data);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(HW_Memory, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr);
|
||||
NGLOG_ERROR(HW_Memory, "Unknown Write{} {:#010X} @ {:#010X}", sizeof(data) * 8, data, addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,12 +85,12 @@ void Update() {}
|
||||
/// Initialize hardware
|
||||
void Init() {
|
||||
LCD::Init();
|
||||
LOG_DEBUG(HW, "initialized OK");
|
||||
NGLOG_DEBUG(HW, "Initialized OK");
|
||||
}
|
||||
|
||||
/// Shutdown hardware
|
||||
void Shutdown() {
|
||||
LCD::Shutdown();
|
||||
LOG_DEBUG(HW, "shutdown OK");
|
||||
NGLOG_DEBUG(HW, "Shutdown OK");
|
||||
}
|
||||
} // namespace HW
|
||||
|
||||
@@ -20,7 +20,7 @@ inline void Read(T& var, const u32 raw_addr) {
|
||||
|
||||
// Reads other than u32 are untested, so I'd rather have them abort than silently fail
|
||||
if (index >= 0x400 || !std::is_same<T, u32>::value) {
|
||||
LOG_ERROR(HW_LCD, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr);
|
||||
NGLOG_ERROR(HW_LCD, "Unknown Read{} @ {:#010X}", sizeof(var) * 8, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ inline void Write(u32 addr, const T data) {
|
||||
|
||||
// Writes other than u32 are untested, so I'd rather have them abort than silently fail
|
||||
if (index >= 0x400 || !std::is_same<T, u32>::value) {
|
||||
LOG_ERROR(HW_LCD, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr);
|
||||
NGLOG_ERROR(HW_LCD, "Unknown Write{} {:#010X} @ {:#010X}", sizeof(data) * 8, data, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ template void Write<u8>(u32 addr, const u8 data);
|
||||
/// Initialize hardware
|
||||
void Init() {
|
||||
memset(&g_regs, 0, sizeof(g_regs));
|
||||
LOG_DEBUG(HW_LCD, "initialized OK");
|
||||
NGLOG_DEBUG(HW_LCD, "Initialized OK");
|
||||
}
|
||||
|
||||
/// Shutdown hardware
|
||||
void Shutdown() {
|
||||
LOG_DEBUG(HW_LCD, "shutdown OK");
|
||||
NGLOG_DEBUG(HW_LCD, "Shutdown OK");
|
||||
}
|
||||
|
||||
} // namespace LCD
|
||||
|
||||
@@ -39,8 +39,8 @@ PageTable* GetCurrentPageTable() {
|
||||
}
|
||||
|
||||
static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) {
|
||||
LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE,
|
||||
(base + size) * PAGE_SIZE);
|
||||
NGLOG_DEBUG(HW_Memory, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * PAGE_SIZE,
|
||||
(base + size) * PAGE_SIZE);
|
||||
|
||||
RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE,
|
||||
FlushMode::FlushAndInvalidate);
|
||||
@@ -169,10 +169,10 @@ T Read(const VAddr vaddr) {
|
||||
PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
|
||||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Read%lu @ 0x%08X", sizeof(T) * 8, vaddr);
|
||||
NGLOG_ERROR(HW_Memory, "Unmapped Read{} @ {:#010X}", sizeof(T) * 8, vaddr);
|
||||
return 0;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ %016" PRIX64, vaddr);
|
||||
break;
|
||||
case PageType::RasterizerCachedMemory: {
|
||||
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
|
||||
@@ -201,11 +201,11 @@ void Write(const VAddr vaddr, const T data) {
|
||||
PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
|
||||
switch (type) {
|
||||
case PageType::Unmapped:
|
||||
LOG_ERROR(HW_Memory, "unmapped Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data,
|
||||
vaddr);
|
||||
NGLOG_ERROR(HW_Memory, "Unmapped Write{} {:#010X} @ {:#018X}", sizeof(data) * 8, (u32)data,
|
||||
vaddr);
|
||||
return;
|
||||
case PageType::Memory:
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
|
||||
ASSERT_MSG(false, "Mapped memory page without a pointer @ %016" PRIX64, vaddr);
|
||||
break;
|
||||
case PageType::RasterizerCachedMemory: {
|
||||
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate);
|
||||
@@ -251,7 +251,7 @@ u8* GetPointer(const VAddr vaddr) {
|
||||
return GetPointerFromVMA(vaddr);
|
||||
}
|
||||
|
||||
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x%08x", vaddr);
|
||||
NGLOG_ERROR(HW_Memory, "Unknown GetPointer @ {:#018X}", vaddr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -288,13 +288,12 @@ u8* GetPhysicalPointer(PAddr address) {
|
||||
});
|
||||
|
||||
if (area == std::end(memory_areas)) {
|
||||
LOG_ERROR(HW_Memory, "unknown GetPhysicalPointer @ 0x%016" PRIX64, address);
|
||||
NGLOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#018X}", address);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (area->paddr_base == IO_AREA_PADDR) {
|
||||
LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr=0x%016" PRIX64,
|
||||
address);
|
||||
NGLOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:018X}", address);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -341,9 +340,9 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached)
|
||||
Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr);
|
||||
// The GPU <-> CPU virtual memory mapping is not 1:1
|
||||
if (!maybe_vaddr) {
|
||||
LOG_ERROR(HW_Memory,
|
||||
"Trying to flush a cached region to an invalid physical address %08X",
|
||||
gpu_addr);
|
||||
NGLOG_ERROR(HW_Memory,
|
||||
"Trying to flush a cached region to an invalid physical address {:016X}",
|
||||
gpu_addr);
|
||||
continue;
|
||||
}
|
||||
VAddr vaddr = *maybe_vaddr;
|
||||
@@ -477,8 +476,9 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_
|
||||
|
||||
switch (page_table.attributes[page_index]) {
|
||||
case PageType::Unmapped: {
|
||||
LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)",
|
||||
current_vaddr, src_addr, size);
|
||||
NGLOG_ERROR(HW_Memory,
|
||||
"Unmapped ReadBlock @ {:#018X} (start address = {:#018X}, size = {})",
|
||||
current_vaddr, src_addr, size);
|
||||
std::memset(dest_buffer, 0, copy_amount);
|
||||
break;
|
||||
}
|
||||
@@ -540,9 +540,9 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
|
||||
|
||||
switch (page_table.attributes[page_index]) {
|
||||
case PageType::Unmapped: {
|
||||
LOG_ERROR(HW_Memory,
|
||||
"unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)",
|
||||
current_vaddr, dest_addr, size);
|
||||
NGLOG_ERROR(HW_Memory,
|
||||
"Unmapped WriteBlock @ {:#018X} (start address = {:#018X}, size = {})",
|
||||
current_vaddr, dest_addr, size);
|
||||
break;
|
||||
}
|
||||
case PageType::Memory: {
|
||||
@@ -588,8 +588,9 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const size
|
||||
|
||||
switch (page_table.attributes[page_index]) {
|
||||
case PageType::Unmapped: {
|
||||
LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)",
|
||||
current_vaddr, dest_addr, size);
|
||||
NGLOG_ERROR(HW_Memory,
|
||||
"Unmapped ZeroBlock @ {:#018X} (start address = {#:018X}, size = {})",
|
||||
current_vaddr, dest_addr, size);
|
||||
break;
|
||||
}
|
||||
case PageType::Memory: {
|
||||
@@ -628,8 +629,9 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
||||
|
||||
switch (page_table.attributes[page_index]) {
|
||||
case PageType::Unmapped: {
|
||||
LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)",
|
||||
current_vaddr, src_addr, size);
|
||||
NGLOG_ERROR(HW_Memory,
|
||||
"Unmapped CopyBlock @ {:#018X} (start address = {:#018X}, size = {})",
|
||||
current_vaddr, src_addr, size);
|
||||
ZeroBlock(process, dest_addr, copy_amount);
|
||||
break;
|
||||
}
|
||||
@@ -657,6 +659,10 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
||||
}
|
||||
}
|
||||
|
||||
void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) {
|
||||
CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size);
|
||||
}
|
||||
|
||||
boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
|
||||
if (addr == 0) {
|
||||
return 0;
|
||||
@@ -678,7 +684,7 @@ boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
|
||||
PAddr VirtualToPhysicalAddress(const VAddr addr) {
|
||||
auto paddr = TryVirtualToPhysicalAddress(addr);
|
||||
if (!paddr) {
|
||||
LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%016" PRIX64, addr);
|
||||
NGLOG_ERROR(HW_Memory, "Unknown virtual address @ {:#018X}", addr);
|
||||
// To help with debugging, set bit on address so that it's obviously invalid.
|
||||
return addr | 0x80000000;
|
||||
}
|
||||
|
||||
@@ -24,10 +24,7 @@ namespace Tegra {
|
||||
|
||||
enum class BufferMethods {
|
||||
BindObject = 0,
|
||||
SetGraphMacroCode = 0x45,
|
||||
SetGraphMacroCodeArg = 0x46,
|
||||
SetGraphMacroEntry = 0x47,
|
||||
CountBufferMethods = 0x100,
|
||||
CountBufferMethods = 0x40,
|
||||
};
|
||||
|
||||
void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) {
|
||||
@@ -36,28 +33,6 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params)
|
||||
"{:08X} remaining params {}",
|
||||
method, subchannel, value, remaining_params);
|
||||
|
||||
if (method == static_cast<u32>(BufferMethods::SetGraphMacroEntry)) {
|
||||
// Prepare to upload a new macro, reset the upload counter.
|
||||
NGLOG_DEBUG(HW_GPU, "Uploading GPU macro {:08X}", value);
|
||||
current_macro_entry = value;
|
||||
current_macro_code.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (method == static_cast<u32>(BufferMethods::SetGraphMacroCodeArg)) {
|
||||
// Append a new code word to the current macro.
|
||||
current_macro_code.push_back(value);
|
||||
|
||||
// There are no more params remaining, submit the code to the 3D engine.
|
||||
if (remaining_params == 0) {
|
||||
maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code));
|
||||
current_macro_entry = InvalidGraphMacroEntry;
|
||||
current_macro_code.clear();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (method == static_cast<u32>(BufferMethods::BindObject)) {
|
||||
// Bind the current subchannel to the desired engine id.
|
||||
NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value);
|
||||
|
||||
@@ -2,12 +2,71 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/memory.h"
|
||||
#include "video_core/engines/fermi_2d.h"
|
||||
#include "video_core/textures/decoders.h"
|
||||
|
||||
namespace Tegra {
|
||||
namespace Engines {
|
||||
|
||||
void Fermi2D::WriteReg(u32 method, u32 value) {}
|
||||
Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
|
||||
|
||||
void Fermi2D::WriteReg(u32 method, u32 value) {
|
||||
ASSERT_MSG(method < Regs::NUM_REGS,
|
||||
"Invalid Fermi2D register, increase the size of the Regs structure");
|
||||
|
||||
regs.reg_array[method] = value;
|
||||
|
||||
switch (method) {
|
||||
case FERMI2D_REG_INDEX(trigger): {
|
||||
HandleSurfaceCopy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Fermi2D::HandleSurfaceCopy() {
|
||||
NGLOG_WARNING(HW_GPU, "Requested a surface copy with operation {}",
|
||||
static_cast<u32>(regs.operation));
|
||||
|
||||
const GPUVAddr source = regs.src.Address();
|
||||
const GPUVAddr dest = regs.dst.Address();
|
||||
|
||||
// TODO(Subv): Only same-format and same-size copies are allowed for now.
|
||||
ASSERT(regs.src.format == regs.dst.format);
|
||||
ASSERT(regs.src.width * regs.src.height == regs.dst.width * regs.dst.height);
|
||||
|
||||
// TODO(Subv): Only raw copies are implemented.
|
||||
ASSERT(regs.operation == Regs::Operation::SrcCopy);
|
||||
|
||||
const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source);
|
||||
const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest);
|
||||
|
||||
u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format);
|
||||
u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format);
|
||||
|
||||
if (regs.src.linear == regs.dst.linear) {
|
||||
// If the input layout and the output layout are the same, just perform a raw copy.
|
||||
Memory::CopyBlock(dest_cpu, source_cpu,
|
||||
src_bytes_per_pixel * regs.dst.width * regs.dst.height);
|
||||
return;
|
||||
}
|
||||
|
||||
u8* src_buffer = Memory::GetPointer(source_cpu);
|
||||
u8* dst_buffer = Memory::GetPointer(dest_cpu);
|
||||
|
||||
if (!regs.src.linear && regs.dst.linear) {
|
||||
// If the input is tiled and the output is linear, deswizzle the input and copy it over.
|
||||
Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel,
|
||||
dst_bytes_per_pixel, src_buffer, dst_buffer, true,
|
||||
regs.src.block_height);
|
||||
} else {
|
||||
// If the input is linear and the output is tiled, swizzle the input and copy it over.
|
||||
Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel,
|
||||
dst_bytes_per_pixel, dst_buffer, src_buffer, false,
|
||||
regs.dst.block_height);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Engines
|
||||
} // namespace Tegra
|
||||
|
||||
@@ -4,19 +4,106 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "common/assert.h"
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/memory_manager.h"
|
||||
|
||||
namespace Tegra {
|
||||
namespace Engines {
|
||||
|
||||
#define FERMI2D_REG_INDEX(field_name) \
|
||||
(offsetof(Tegra::Engines::Fermi2D::Regs, field_name) / sizeof(u32))
|
||||
|
||||
class Fermi2D final {
|
||||
public:
|
||||
Fermi2D() = default;
|
||||
explicit Fermi2D(MemoryManager& memory_manager);
|
||||
~Fermi2D() = default;
|
||||
|
||||
/// Write the value to the register identified by method.
|
||||
void WriteReg(u32 method, u32 value);
|
||||
|
||||
struct Regs {
|
||||
static constexpr size_t NUM_REGS = 0x258;
|
||||
|
||||
struct Surface {
|
||||
RenderTargetFormat format;
|
||||
BitField<0, 1, u32> linear;
|
||||
union {
|
||||
BitField<0, 4, u32> block_depth;
|
||||
BitField<4, 4, u32> block_height;
|
||||
BitField<8, 4, u32> block_width;
|
||||
};
|
||||
u32 depth;
|
||||
u32 layer;
|
||||
u32 pitch;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 address_high;
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size");
|
||||
|
||||
enum class Operation : u32 {
|
||||
SrcCopyAnd = 0,
|
||||
ROPAnd = 1,
|
||||
Blend = 2,
|
||||
SrcCopy = 3,
|
||||
ROP = 4,
|
||||
SrcCopyPremult = 5,
|
||||
BlendPremult = 6,
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(0x80);
|
||||
|
||||
Surface dst;
|
||||
|
||||
INSERT_PADDING_WORDS(2);
|
||||
|
||||
Surface src;
|
||||
|
||||
INSERT_PADDING_WORDS(0x15);
|
||||
|
||||
Operation operation;
|
||||
|
||||
INSERT_PADDING_WORDS(0x9);
|
||||
|
||||
// TODO(Subv): This is only a guess.
|
||||
u32 trigger;
|
||||
|
||||
INSERT_PADDING_WORDS(0x1A3);
|
||||
};
|
||||
std::array<u32, NUM_REGS> reg_array;
|
||||
};
|
||||
} regs{};
|
||||
|
||||
MemoryManager& memory_manager;
|
||||
|
||||
private:
|
||||
/// Performs the copy from the source surface to the destination surface as configured in the
|
||||
/// registers.
|
||||
void HandleSurfaceCopy();
|
||||
};
|
||||
|
||||
#define ASSERT_REG_POSITION(field_name, position) \
|
||||
static_assert(offsetof(Fermi2D::Regs, field_name) == position * 4, \
|
||||
"Field " #field_name " has invalid position")
|
||||
|
||||
ASSERT_REG_POSITION(dst, 0x80);
|
||||
ASSERT_REG_POSITION(src, 0x8C);
|
||||
ASSERT_REG_POSITION(operation, 0xAB);
|
||||
ASSERT_REG_POSITION(trigger, 0xB5);
|
||||
#undef ASSERT_REG_POSITION
|
||||
|
||||
} // namespace Engines
|
||||
} // namespace Tegra
|
||||
|
||||
@@ -22,10 +22,6 @@ constexpr u32 MacroRegistersStart = 0xE00;
|
||||
Maxwell3D::Maxwell3D(MemoryManager& memory_manager)
|
||||
: memory_manager(memory_manager), macro_interpreter(*this) {}
|
||||
|
||||
void Maxwell3D::SubmitMacroCode(u32 entry, std::vector<u32> code) {
|
||||
uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code);
|
||||
}
|
||||
|
||||
void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
|
||||
auto macro_code = uploaded_macros.find(method);
|
||||
// The requested macro must have been uploaded already.
|
||||
@@ -37,9 +33,6 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
|
||||
}
|
||||
|
||||
void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
||||
ASSERT_MSG(method < Regs::NUM_REGS,
|
||||
"Invalid Maxwell3D register, increase the size of the Regs structure");
|
||||
|
||||
auto debug_context = Core::System::GetInstance().GetGPUDebugContext();
|
||||
|
||||
// It is an error to write to a register other than the current macro's ARG register before it
|
||||
@@ -68,6 +61,9 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_MSG(method < Regs::NUM_REGS,
|
||||
"Invalid Maxwell3D register, increase the size of the Regs structure");
|
||||
|
||||
if (debug_context) {
|
||||
debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr);
|
||||
}
|
||||
@@ -75,6 +71,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
||||
regs.reg_array[method] = value;
|
||||
|
||||
switch (method) {
|
||||
case MAXWELL3D_REG_INDEX(macros.data): {
|
||||
ProcessMacroUpload(value);
|
||||
break;
|
||||
}
|
||||
case MAXWELL3D_REG_INDEX(code_address.code_address_high):
|
||||
case MAXWELL3D_REG_INDEX(code_address.code_address_low): {
|
||||
// Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS
|
||||
@@ -141,6 +141,12 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
||||
}
|
||||
}
|
||||
|
||||
void Maxwell3D::ProcessMacroUpload(u32 data) {
|
||||
// Store the uploaded macro code to interpret them when they're called.
|
||||
auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart];
|
||||
macro.push_back(data);
|
||||
}
|
||||
|
||||
void Maxwell3D::ProcessQueryGet() {
|
||||
GPUVAddr sequence_address = regs.query.QueryAddress();
|
||||
// Since the sequence address is given as a GPU VAddr, we have to convert it to an application
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
/// Register structure of the Maxwell3D engine.
|
||||
/// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
|
||||
struct Regs {
|
||||
static constexpr size_t NUM_REGS = 0xE36;
|
||||
static constexpr size_t NUM_REGS = 0xE00;
|
||||
|
||||
static constexpr size_t NumRenderTargets = 8;
|
||||
static constexpr size_t NumViewports = 16;
|
||||
@@ -322,7 +322,15 @@ public:
|
||||
|
||||
union {
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(0x200);
|
||||
INSERT_PADDING_WORDS(0x45);
|
||||
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(1);
|
||||
u32 data;
|
||||
u32 entry;
|
||||
} macros;
|
||||
|
||||
INSERT_PADDING_WORDS(0x1B8);
|
||||
|
||||
struct {
|
||||
u32 address_high;
|
||||
@@ -605,7 +613,7 @@ public:
|
||||
u32 size[MaxShaderStage];
|
||||
} tex_info_buffers;
|
||||
|
||||
INSERT_PADDING_WORDS(0x102);
|
||||
INSERT_PADDING_WORDS(0xCC);
|
||||
};
|
||||
std::array<u32, NUM_REGS> reg_array;
|
||||
};
|
||||
@@ -637,9 +645,6 @@ public:
|
||||
/// Write the value to the register identified by method.
|
||||
void WriteReg(u32 method, u32 value, u32 remaining_params);
|
||||
|
||||
/// Uploads the code for a GPU macro program associated with the specified entry.
|
||||
void SubmitMacroCode(u32 entry, std::vector<u32> code);
|
||||
|
||||
/// Returns a list of enabled textures for the specified shader stage.
|
||||
std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const;
|
||||
|
||||
@@ -670,6 +675,9 @@ private:
|
||||
*/
|
||||
void CallMacroMethod(u32 method, std::vector<u32> parameters);
|
||||
|
||||
/// Handles writes to the macro uploading registers.
|
||||
void ProcessMacroUpload(u32 data);
|
||||
|
||||
/// Handles a write to the QUERY_GET register.
|
||||
void ProcessQueryGet();
|
||||
|
||||
@@ -687,6 +695,7 @@ private:
|
||||
static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \
|
||||
"Field " #field_name " has invalid position")
|
||||
|
||||
ASSERT_REG_POSITION(macros, 0x45);
|
||||
ASSERT_REG_POSITION(rt, 0x200);
|
||||
ASSERT_REG_POSITION(viewport_transform[0], 0x280);
|
||||
ASSERT_REG_POSITION(viewport, 0x300);
|
||||
|
||||
@@ -214,6 +214,20 @@ union Instruction {
|
||||
BitField<56, 1, u64> neg_b;
|
||||
} fsetp;
|
||||
|
||||
union {
|
||||
BitField<39, 3, u64> pred39;
|
||||
BitField<42, 1, u64> neg_pred;
|
||||
BitField<43, 1, u64> neg_a;
|
||||
BitField<44, 1, u64> abs_b;
|
||||
BitField<45, 2, PredOperation> op;
|
||||
BitField<48, 4, PredCondition> cond;
|
||||
BitField<53, 1, u64> neg_b;
|
||||
BitField<54, 1, u64> abs_a;
|
||||
BitField<52, 1, u64> bf;
|
||||
BitField<55, 1, u64> ftz;
|
||||
BitField<56, 1, u64> neg_imm;
|
||||
} fset;
|
||||
|
||||
BitField<61, 1, u64> is_b_imm;
|
||||
BitField<60, 1, u64> is_b_gpr;
|
||||
BitField<59, 1, u64> is_c_gpr;
|
||||
@@ -261,6 +275,9 @@ public:
|
||||
I2F_C,
|
||||
I2F_R,
|
||||
I2F_IMM,
|
||||
I2I_C,
|
||||
I2I_R,
|
||||
I2I_IMM,
|
||||
LOP32I,
|
||||
MOV_C,
|
||||
MOV_R,
|
||||
@@ -272,6 +289,9 @@ public:
|
||||
FSETP_C, // Set Predicate
|
||||
FSETP_R,
|
||||
FSETP_IMM,
|
||||
FSET_C,
|
||||
FSET_R,
|
||||
FSET_IMM,
|
||||
ISETP_C,
|
||||
ISETP_IMM,
|
||||
ISETP_R,
|
||||
@@ -283,8 +303,9 @@ public:
|
||||
Ffma,
|
||||
Flow,
|
||||
Memory,
|
||||
FloatPredicate,
|
||||
IntegerPredicate,
|
||||
FloatSet,
|
||||
FloatSetPredicate,
|
||||
IntegerSetPredicate,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
@@ -409,6 +430,9 @@ private:
|
||||
INST("0100110010111---", Id::I2F_C, Type::Arithmetic, "I2F_C"),
|
||||
INST("0101110010111---", Id::I2F_R, Type::Arithmetic, "I2F_R"),
|
||||
INST("0011100-10111---", Id::I2F_IMM, Type::Arithmetic, "I2F_IMM"),
|
||||
INST("0100110011100---", Id::I2I_C, Type::Arithmetic, "I2I_C"),
|
||||
INST("0101110011100---", Id::I2I_R, Type::Arithmetic, "I2I_R"),
|
||||
INST("01110001-1000---", Id::I2I_IMM, Type::Arithmetic, "I2I_IMM"),
|
||||
INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"),
|
||||
INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"),
|
||||
INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"),
|
||||
@@ -417,12 +441,15 @@ private:
|
||||
INST("0100110000101---", Id::SHR_C, Type::Arithmetic, "SHR_C"),
|
||||
INST("0101110000101---", Id::SHR_R, Type::Arithmetic, "SHR_R"),
|
||||
INST("0011100-00101---", Id::SHR_IMM, Type::Arithmetic, "SHR_IMM"),
|
||||
INST("010010111011----", Id::FSETP_C, Type::FloatPredicate, "FSETP_C"),
|
||||
INST("010110111011----", Id::FSETP_R, Type::FloatPredicate, "FSETP_R"),
|
||||
INST("0011011-1011----", Id::FSETP_IMM, Type::FloatPredicate, "FSETP_IMM"),
|
||||
INST("010010110110----", Id::ISETP_C, Type::IntegerPredicate, "ISETP_C"),
|
||||
INST("010110110110----", Id::ISETP_R, Type::IntegerPredicate, "ISETP_R"),
|
||||
INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerPredicate, "ISETP_IMM"),
|
||||
INST("01011000--------", Id::FSET_R, Type::FloatSet, "FSET_R"),
|
||||
INST("0100100---------", Id::FSET_C, Type::FloatSet, "FSET_C"),
|
||||
INST("0011000---------", Id::FSET_IMM, Type::FloatSet, "FSET_IMM"),
|
||||
INST("010010111011----", Id::FSETP_C, Type::FloatSetPredicate, "FSETP_C"),
|
||||
INST("010110111011----", Id::FSETP_R, Type::FloatSetPredicate, "FSETP_R"),
|
||||
INST("0011011-1011----", Id::FSETP_IMM, Type::FloatSetPredicate, "FSETP_IMM"),
|
||||
INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"),
|
||||
INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"),
|
||||
INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"),
|
||||
};
|
||||
#undef INST
|
||||
std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) {
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Tegra {
|
||||
GPU::GPU() {
|
||||
memory_manager = std::make_unique<MemoryManager>();
|
||||
maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager);
|
||||
fermi_2d = std::make_unique<Engines::Fermi2D>();
|
||||
fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);
|
||||
maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
|
||||
}
|
||||
|
||||
@@ -22,4 +22,16 @@ const Tegra::Engines::Maxwell3D& GPU::Get3DEngine() const {
|
||||
return *maxwell_3d;
|
||||
}
|
||||
|
||||
u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
|
||||
ASSERT(format != RenderTargetFormat::NONE);
|
||||
|
||||
switch (format) {
|
||||
case RenderTargetFormat::RGBA8_UNORM:
|
||||
case RenderTargetFormat::RGB10_A2_UNORM:
|
||||
return 4;
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented render target format %u", static_cast<u32>(format));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Tegra
|
||||
|
||||
@@ -21,6 +21,9 @@ enum class RenderTargetFormat : u32 {
|
||||
RGBA8_SRGB = 0xD6,
|
||||
};
|
||||
|
||||
/// Returns the number of bytes per pixel of each rendertarget format.
|
||||
u32 RenderTargetBytesPerPixel(RenderTargetFormat format);
|
||||
|
||||
class DebugContext;
|
||||
|
||||
/**
|
||||
@@ -86,8 +89,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr u32 InvalidGraphMacroEntry = 0xFFFFFFFF;
|
||||
|
||||
/// Writes a single register in the engine bound to the specified subchannel
|
||||
void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params);
|
||||
|
||||
@@ -100,11 +101,6 @@ private:
|
||||
std::unique_ptr<Engines::Fermi2D> fermi_2d;
|
||||
/// Compute engine
|
||||
std::unique_ptr<Engines::MaxwellCompute> maxwell_compute;
|
||||
|
||||
/// Entry of the macro that is currently being uploaded
|
||||
u32 current_macro_entry = InvalidGraphMacroEntry;
|
||||
/// Code being uploaded for the current macro
|
||||
std::vector<u32> current_macro_code;
|
||||
};
|
||||
|
||||
} // namespace Tegra
|
||||
|
||||
@@ -519,7 +519,7 @@ private:
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::Type::FloatPredicate: {
|
||||
case OpCode::Type::FloatSetPredicate: {
|
||||
std::string op_a = instr.fsetp.neg_a ? "-" : "";
|
||||
op_a += GetRegister(instr.gpr8);
|
||||
|
||||
@@ -570,6 +570,59 @@ private:
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::Type::FloatSet: {
|
||||
std::string dest = GetRegister(instr.gpr0);
|
||||
std::string op_a = instr.fset.neg_a ? "-" : "";
|
||||
op_a += GetRegister(instr.gpr8);
|
||||
|
||||
if (instr.fset.abs_a) {
|
||||
op_a = "abs(" + op_a + ')';
|
||||
}
|
||||
|
||||
std::string op_b = instr.fset.neg_b ? "-" : "";
|
||||
|
||||
if (instr.is_b_imm) {
|
||||
std::string imm = GetImmediate19(instr);
|
||||
if (instr.fset.neg_imm)
|
||||
op_b += "(-" + imm + ')';
|
||||
else
|
||||
op_b += imm;
|
||||
} else {
|
||||
if (instr.is_b_gpr) {
|
||||
op_b += GetRegister(instr.gpr20);
|
||||
} else {
|
||||
op_b += GetUniform(instr.uniform);
|
||||
}
|
||||
}
|
||||
|
||||
if (instr.fset.abs_b) {
|
||||
op_b = "abs(" + op_b + ")";
|
||||
}
|
||||
|
||||
using Tegra::Shader::Pred;
|
||||
ASSERT_MSG(instr.fset.pred39 == static_cast<u64>(Pred::UnusedIndex),
|
||||
"Compound predicates are not implemented");
|
||||
|
||||
// The fset instruction sets a register to 1.0 if the condition is true, and to 0
|
||||
// otherwise.
|
||||
using Tegra::Shader::PredCondition;
|
||||
switch (instr.fset.cond) {
|
||||
case PredCondition::LessThan:
|
||||
SetDest(0, dest, "((" + op_a + ") < (" + op_b + ")) ? 1.0 : 0", 1, 1);
|
||||
break;
|
||||
case PredCondition::Equal:
|
||||
SetDest(0, dest, "((" + op_a + ") == (" + op_b + ")) ? 1.0 : 0", 1, 1);
|
||||
break;
|
||||
case PredCondition::GreaterThan:
|
||||
SetDest(0, dest, "((" + op_a + ") > (" + op_b + ")) ? 1.0 : 0", 1, 1);
|
||||
break;
|
||||
default:
|
||||
NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})",
|
||||
static_cast<unsigned>(instr.fset.cond.Value()), op_a, op_b);
|
||||
UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
switch (opcode->GetId()) {
|
||||
case OpCode::Id::EXIT: {
|
||||
|
||||
@@ -27,9 +27,8 @@ static u32 GetSwizzleOffset(u32 x, u32 y, u32 image_width, u32 bytes_per_pixel,
|
||||
return address;
|
||||
}
|
||||
|
||||
static void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel,
|
||||
u8* swizzled_data, u8* unswizzled_data, bool unswizzle,
|
||||
u32 block_height) {
|
||||
void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel,
|
||||
u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height) {
|
||||
u8* data_ptrs[2];
|
||||
for (unsigned y = 0; y < height; ++y) {
|
||||
for (unsigned x = 0; x < width; ++x) {
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace Texture {
|
||||
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
|
||||
u32 block_height = TICEntry::DefaultBlockHeight);
|
||||
|
||||
/// Copies texture data from a buffer and performs swizzling/unswizzling as necessary.
|
||||
void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel,
|
||||
u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height);
|
||||
|
||||
/**
|
||||
* Decodes an unswizzled texture into a A8R8G8B8 texture.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user