diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/arm/arm_interface.h | 4 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 4 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 4 | ||||
-rw-r--r-- | src/core/arm/exclusive_monitor.cpp | 4 | ||||
-rw-r--r-- | src/core/arm/exclusive_monitor.h | 4 | ||||
-rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 8 | ||||
-rw-r--r-- | src/core/arm/unicorn/arm_unicorn.h | 4 | ||||
-rw-r--r-- | src/core/core.cpp | 11 | ||||
-rw-r--r-- | src/core/core.h | 5 | ||||
-rw-r--r-- | src/core/core_cpu.h | 4 | ||||
-rw-r--r-- | src/core/file_sys/registered_cache.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.h | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.h | 4 | ||||
-rw-r--r-- | src/core/hle/service/ns/pl_u.cpp | 56 | ||||
-rw-r--r-- | src/core/hle/service/set/set.cpp | 51 | ||||
-rw-r--r-- | src/core/hle/service/set/set.h | 2 |
21 files changed, 151 insertions, 38 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index b0d7ced7f..c368745b1 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -8,6 +8,8 @@ #include "common/common_types.h" #include "core/hle/kernel/vm_manager.h" +namespace Core { + /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: @@ -122,3 +124,5 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; }; + +} // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 2c817d7d1..f96e08212 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -14,6 +14,8 @@ #include "core/hle/kernel/svc.h" #include "core/memory.h" +namespace Core { + using Vector = Dynarmic::A64::Vector; class ARM_Dynarmic_Callbacks : public Dynarmic::A64::UserCallbacks { @@ -300,3 +302,5 @@ bool DynarmicExclusiveMonitor::ExclusiveWrite128(size_t core_index, VAddr vaddr, Memory::Write64(vaddr, value[1]); }); } + +} // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 14c072601..3bdfd8cd9 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -12,6 +12,8 @@ #include "core/arm/exclusive_monitor.h" #include "core/arm/unicorn/arm_unicorn.h" +namespace Core { + class ARM_Dynarmic_Callbacks; class DynarmicExclusiveMonitor; @@ -81,3 +83,5 @@ private: friend class ARM_Dynarmic; Dynarmic::A64::ExclusiveMonitor monitor; }; + +} // namespace Core diff --git a/src/core/arm/exclusive_monitor.cpp b/src/core/arm/exclusive_monitor.cpp index cb8c81d80..abd59ff4b 100644 --- a/src/core/arm/exclusive_monitor.cpp +++ b/src/core/arm/exclusive_monitor.cpp @@ -4,4 +4,8 @@ #include "core/arm/exclusive_monitor.h" +namespace Core { + ExclusiveMonitor::~ExclusiveMonitor() = default; + +} // namespace Core diff --git a/src/core/arm/exclusive_monitor.h b/src/core/arm/exclusive_monitor.h index 13671ed7a..6f9b51573 100644 --- a/src/core/arm/exclusive_monitor.h +++ b/src/core/arm/exclusive_monitor.h @@ -6,6 +6,8 @@ #include "common/common_types.h" +namespace Core { + class ExclusiveMonitor { public: virtual ~ExclusiveMonitor(); @@ -19,3 +21,5 @@ public: virtual bool ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) = 0; virtual bool ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) = 0; }; + +} // namespace Core diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 6bc349460..307f12198 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -11,6 +11,8 @@ #include "core/core_timing.h" #include "core/hle/kernel/svc.h" +namespace Core { + // Load Unicorn DLL once on Windows using RAII #ifdef _MSC_VER #include <unicorn_dynload.h> @@ -211,7 +213,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) { } } -void ARM_Unicorn::SaveContext(ARM_Interface::ThreadContext& ctx) { +void ARM_Unicorn::SaveContext(ThreadContext& ctx) { int uregs[32]; void* tregs[32]; @@ -238,7 +240,7 @@ void ARM_Unicorn::SaveContext(ARM_Interface::ThreadContext& ctx) { CHECKED(uc_reg_read_batch(uc, uregs, tregs, 32)); } -void ARM_Unicorn::LoadContext(const ARM_Interface::ThreadContext& ctx) { +void ARM_Unicorn::LoadContext(const ThreadContext& ctx) { int uregs[32]; void* tregs[32]; @@ -277,3 +279,5 @@ void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) { last_bkpt = bkpt; last_bkpt_hit = true; } + +} // namespace Core diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index af7943352..bd6b2f723 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h @@ -9,6 +9,8 @@ #include "core/arm/arm_interface.h" #include "core/gdbstub/gdbstub.h" +namespace Core { + class ARM_Unicorn final : public ARM_Interface { public: ARM_Unicorn(); @@ -46,3 +48,5 @@ private: GDBStub::BreakpointAddress last_bkpt{}; bool last_bkpt_hit; }; + +} // namespace Core diff --git a/src/core/core.cpp b/src/core/core.cpp index 28038ff6f..07da4c493 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -135,8 +135,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!", static_cast<int>(system_mode.second)); - if (system_mode.second != Loader::ResultStatus::Success) - return ResultStatus::ErrorSystemMode; + return ResultStatus::ErrorSystemMode; } ResultStatus init_result{Init(emu_window)}; @@ -148,14 +147,12 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st } const Loader::ResultStatus load_result{app_loader->Load(current_process)}; - if (Loader::ResultStatus::Success != load_result) { + if (load_result != Loader::ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); System::Shutdown(); - if (load_result != Loader::ResultStatus::Success) { - return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + - static_cast<u32>(load_result)); - } + return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + + static_cast<u32>(load_result)); } status = ResultStatus::Success; return status; diff --git a/src/core/core.h b/src/core/core.h index 7188dabdc..321104585 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -5,6 +5,7 @@ #pragma once #include <array> +#include <map> #include <memory> #include <string> #include <thread> @@ -22,8 +23,6 @@ #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu.h" -class ARM_Interface; - namespace Core::Frontend { class EmuWindow; } @@ -38,6 +37,8 @@ class RendererBase; namespace Core { +class ARM_Interface; + class System { public: System(const System&) = delete; diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h index 56cdae194..40ed34b47 100644 --- a/src/core/core_cpu.h +++ b/src/core/core_cpu.h @@ -12,14 +12,14 @@ #include "common/common_types.h" #include "core/arm/exclusive_monitor.h" -class ARM_Interface; - namespace Kernel { class Scheduler; } namespace Core { +class ARM_Interface; + constexpr unsigned NUM_CPU_CORES{4}; class CpuBarrier { diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index a02efc71e..dacf8568b 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -216,11 +216,11 @@ void RegisteredCache::ProcessFiles(const std::vector<NcaID>& ids) { const auto section0 = nca->GetSubdirectories()[0]; - for (const auto& file : section0->GetFiles()) { - if (file->GetExtension() != "cnmt") + for (const auto& section0_file : section0->GetFiles()) { + if (section0_file->GetExtension() != "cnmt") continue; - meta.insert_or_assign(nca->GetTitleId(), CNMT(file)); + meta.insert_or_assign(nca->GetTitleId(), CNMT(section0_file)); meta_id.insert_or_assign(nca->GetTitleId(), id); break; } diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index e770b9103..69c812f16 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -17,7 +17,7 @@ namespace Kernel { std::mutex Scheduler::scheduler_mutex; -Scheduler::Scheduler(ARM_Interface* cpu_core) : cpu_core(cpu_core) {} +Scheduler::Scheduler(Core::ARM_Interface* cpu_core) : cpu_core(cpu_core) {} Scheduler::~Scheduler() { for (auto& thread : thread_list) { diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 6a61ef64e..744990c9b 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -11,13 +11,15 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" +namespace Core { class ARM_Interface; +} namespace Kernel { class Scheduler final { public: - explicit Scheduler(ARM_Interface* cpu_core); + explicit Scheduler(Core::ARM_Interface* cpu_core); ~Scheduler(); /// Returns whether there are any threads that are ready to run. @@ -70,7 +72,7 @@ private: SharedPtr<Thread> current_thread = nullptr; - ARM_Interface* cpu_core; + Core::ARM_Interface* cpu_core; static std::mutex scheduler_mutex; }; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 6be5c474e..cb6253398 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -319,8 +319,7 @@ 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"); - *result = 0; + *result = Core::CurrentProcess()->program_id; break; case GetInfoType::PrivilegedProcessId: LOG_WARNING(Kernel_SVC, diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index cf4f94822..4ffd8d5cc 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -283,9 +283,9 @@ static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot( * @param entry_point Address of entry point for execution * @param arg User argument for thread */ -static void ResetThreadContext(ARM_Interface::ThreadContext& context, VAddr stack_top, +static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top, VAddr entry_point, u64 arg) { - memset(&context, 0, sizeof(ARM_Interface::ThreadContext)); + memset(&context, 0, sizeof(Core::ARM_Interface::ThreadContext)); context.cpu_registers[0] = arg; context.pc = entry_point; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index adc804248..06edc296d 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -204,7 +204,7 @@ public: return status == ThreadStatus::WaitSynchAll; } - ARM_Interface::ThreadContext context; + Core::ARM_Interface::ThreadContext context; u32 thread_id; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 970942d3f..c0ba330dc 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -17,6 +17,7 @@ #include "core/hle/service/hid/irs.h" #include "core/hle/service/hid/xcd.h" #include "core/hle/service/service.h" +#include "core/settings.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index e298f23a6..88d926808 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -4,8 +4,10 @@ #pragma once +#include <array> +#include "common/bit_field.h" +#include "common/common_types.h" #include "core/hle/service/service.h" -#include "core/settings.h" namespace Service::HID { diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 53cbf1a6e..923a52cc5 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -35,6 +35,14 @@ static constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONT std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"), std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf")}; +static constexpr std::array<const char*, 7> SHARED_FONTS_TTF{"FontStandard.ttf", + "FontChineseSimplified.ttf", + "FontExtendedChineseSimplified.ttf", + "FontChineseTraditional.ttf", + "FontKorean.ttf", + "FontNintendoExtended.ttf", + "FontNintendoExtended2.ttf"}; + // The below data is specific to shared font data dumped from Switch on f/w 2.2 // Virtual address and offsets/sizes likely will vary by dump static constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; @@ -76,6 +84,17 @@ void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s offset += transformed_font.size() * sizeof(u32); } +static void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output, + size_t& offset) { + ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!"); + const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT; + std::memcpy(output.data() + offset, &EXPECTED_RESULT, sizeof(u32)); // Magic header + const u32 ENC_SIZE = static_cast<u32>(input.size()) ^ KEY; + std::memcpy(output.data() + offset + sizeof(u32), &ENC_SIZE, sizeof(u32)); + std::memcpy(output.data() + offset + (sizeof(u32) * 2), input.data(), input.size()); + offset += input.size() + (sizeof(u32) * 2); +} + static u32 GetU32Swapped(const u8* data) { u32 value; std::memcpy(&value, data, sizeof(value)); @@ -109,10 +128,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") { RegisterHandlers(functions); // Attempt to load shared font data from disk const auto nand = FileSystem::GetSystemNANDContents(); + size_t offset = 0; // Rebuild shared fonts from data ncas if (nand->HasEntry(static_cast<u64>(FontArchives::Standard), FileSys::ContentRecordType::Data)) { - size_t offset = 0; shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE); for (auto font : SHARED_FONTS) { const auto nca = @@ -152,18 +171,45 @@ PL_U::PL_U() : ServiceFramework("pl:u") { DecryptSharedFont(font_data_u32, *shared_font, offset); SHARED_FONT_REGIONS.push_back(region); } + } else { - const std::string filepath{FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + - SHARED_FONT}; + shared_font = std::make_shared<std::vector<u8>>( + SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size + + const std::string user_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir); + const std::string filepath{user_path + SHARED_FONT}; + // Create path if not already created if (!FileUtil::CreateFullPath(filepath)) { LOG_ERROR(Service_NS, "Failed to create sharedfonts path \"{}\"!", filepath); return; } + + bool using_ttf = false; + for (const char* font_ttf : SHARED_FONTS_TTF) { + if (FileUtil::Exists(user_path + font_ttf)) { + using_ttf = true; + FileUtil::IOFile file(user_path + font_ttf, "rb"); + if (file.IsOpen()) { + std::vector<u8> ttf_bytes(file.GetSize()); + file.ReadBytes<u8>(ttf_bytes.data(), ttf_bytes.size()); + FontRegion region{ + static_cast<u32>(offset + 8), + static_cast<u32>(ttf_bytes.size())}; // Font offset and size do not account + // for the header + EncryptSharedFont(ttf_bytes, *shared_font, offset); + SHARED_FONT_REGIONS.push_back(region); + } else { + LOG_WARNING(Service_NS, "Unable to load font: {}", font_ttf); + } + } else if (using_ttf) { + LOG_WARNING(Service_NS, "Unable to find font: {}", font_ttf); + } + } + if (using_ttf) + return; FileUtil::IOFile file(filepath, "rb"); - shared_font = std::make_shared<std::vector<u8>>( - SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size if (file.IsOpen()) { // Read shared font data ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index a461e72ec..92b0640e8 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -32,24 +32,59 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{ LanguageCode::ZH_HANT, }}; +constexpr size_t pre4_0_0_max_entries = 0xF; +constexpr size_t post4_0_0_max_entries = 0x40; + LanguageCode GetLanguageCodeFromIndex(size_t index) { return available_language_codes.at(index); } -void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { - ctx.WriteBuffer(available_language_codes); +template <size_t size> +static std::array<LanguageCode, size> MakeLanguageCodeSubset() { + std::array<LanguageCode, size> arr; + std::copy_n(available_language_codes.begin(), size, arr.begin()); + return arr; +} +static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, size_t max_size) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast<u32>(available_language_codes.size())); + if (available_language_codes.size() > max_size) + rb.Push(static_cast<u32>(max_size)); + else + rb.Push(static_cast<u32>(available_language_codes.size())); +} + +void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { + if (available_language_codes.size() > pre4_0_0_max_entries) + ctx.WriteBuffer(MakeLanguageCodeSubset<pre4_0_0_max_entries>()); + else + ctx.WriteBuffer(available_language_codes); + + PushResponseLanguageCode(ctx, pre4_0_0_max_entries); + + LOG_DEBUG(Service_SET, "called"); +} + +void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) { + if (available_language_codes.size() > post4_0_0_max_entries) + ctx.WriteBuffer(MakeLanguageCodeSubset<post4_0_0_max_entries>()); + else + ctx.WriteBuffer(available_language_codes); + + PushResponseLanguageCode(ctx, post4_0_0_max_entries); LOG_DEBUG(Service_SET, "called"); } void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - rb.Push(static_cast<u32>(available_language_codes.size())); + PushResponseLanguageCode(ctx, pre4_0_0_max_entries); + + LOG_DEBUG(Service_SET, "called"); +} + +void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) { + PushResponseLanguageCode(ctx, post4_0_0_max_entries); LOG_DEBUG(Service_SET, "called"); } @@ -69,8 +104,8 @@ SET::SET() : ServiceFramework("set") { {2, nullptr, "MakeLanguageCode"}, {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, {4, nullptr, "GetRegionCode"}, - {5, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes2"}, - {6, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount2"}, + {5, &SET::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, + {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, {7, nullptr, "GetKeyCodeMap"}, {8, nullptr, "GetQuestFlag"}, }; diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index 4232b6162..669e740b7 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h @@ -38,7 +38,9 @@ public: private: void GetLanguageCode(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); + void GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); + void GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx); }; } // namespace Service::Set |