diff options
Diffstat (limited to 'src/core')
23 files changed, 192 insertions, 113 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 593e0eabd..426fc6474 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -63,16 +63,21 @@ extern void switch_mode(arm_core_t *core, uint32_t mode); typedef arm_core_t arm_processor; typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); +// Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. +// This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to +// support LDR/STREXD. +static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8; + // Exclusive memory access static int exclusive_detect(ARMul_State* state, ARMword addr){ - if(state->exclusive_tag == addr) + if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) return 0; else return -1; } static void add_exclusive_addr(ARMul_State* state, ARMword addr){ - state->exclusive_tag = addr; + state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; return; } @@ -80,7 +85,6 @@ static void remove_exclusive(ARMul_State* state, ARMword addr){ state->exclusive_tag = 0xFFFFFFFF; } - unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { unsigned int immed_8 = BITS(sht_oper, 0, 7); unsigned int rotate_imm = BITS(sht_oper, 8, 11); @@ -943,6 +947,15 @@ typedef struct _smla_inst { unsigned int Rn; } smla_inst; +typedef struct smlalxy_inst { + unsigned int x; + unsigned int y; + unsigned int RdLo; + unsigned int RdHi; + unsigned int Rm; + unsigned int Rn; +} smlalxy_inst; + typedef struct ssat_inst { unsigned int Rn; unsigned int Rd; @@ -2399,7 +2412,25 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlalxy_inst)); + smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); + inst_cream->RdLo = BITS(inst, 12, 15); + inst_cream->RdHi = BITS(inst, 16, 19); + inst_cream->Rn = BITS(inst, 0, 4); + inst_cream->Rm = BITS(inst, 8, 11); + + return inst_base; +} ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { @@ -4613,7 +4644,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { add_exclusive_addr(cpu, read_addr); cpu->exclusive_state = 1; - // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive? RD = Memory::Read32(read_addr); RD2 = Memory::Read32(read_addr + 4); @@ -5683,6 +5713,34 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SMLALXY_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component; + + u64 operand1 = RN; + u64 operand2 = RM; + + if (inst_cream->x != 0) + operand1 >>= 16; + if (inst_cream->y != 0) + operand2 >>= 16; + operand1 &= 0xFFFF; + if (operand1 & 0x8000) + operand1 -= 65536; + operand2 &= 0xFFFF; + if (operand2 & 0x8000) + operand2 -= 65536; + + u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2); + RDLO = (dest & 0xFFFFFFFF); + RDHI = ((dest >> 32) & 0xFFFFFFFF); + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smlalxy_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } SMLAW_INST: { @@ -6133,7 +6191,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { remove_exclusive(cpu, write_addr); cpu->exclusive_state = 0; - // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); @@ -6265,6 +6322,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { addr = RN; unsigned int value = Memory::Read8(addr); Memory::Write8(addr, (RM & 0xFF)); + RD = value; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(swp_inst)); diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 3100d7adc..1b2cef451 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -165,20 +165,20 @@ struct ARMul_State unsigned ErrorCode; /* type of illegal instruction */ /* Order of the following register should not be modified */ - ARMword Reg[16]; /* the current register file */ - ARMword Cpsr; /* the current psr */ + ARMword Reg[16]; /* the current register file */ + ARMword Cpsr; /* the current psr */ ARMword Spsr_copy; ARMword phys_pc; ARMword Reg_usr[2]; - ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ - ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ - ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ - ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ - ARMword Reg_firq[7]; /* R8---R14 FIRQ */ - ARMword Spsr[7]; /* the exception psr's */ - ARMword Mode; /* the current mode */ - ARMword Bank; /* the current register bank */ - ARMword exclusive_tag; + ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ + ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ + ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ + ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ + ARMword Reg_firq[7]; /* R8---R14 FIRQ */ + ARMword Spsr[7]; /* the exception psr's */ + ARMword Mode; /* the current mode */ + ARMword Bank; /* the current register bank */ + ARMword exclusive_tag; /* the address for which the local monitor is in exclusive access mode */ ARMword exclusive_state; ARMword exclusive_result; ARMword CP15[VFP_BASE - CP15_BASE]; diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 4759ef3ae..0805f42ae 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -9,6 +9,7 @@ #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/disk_archive.h" +#include "core/hle/service/fs/archive.h" #include "core/settings.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -19,15 +20,22 @@ namespace FileSys { static std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path) { std::vector<u8> vec_data = path.AsBinary(); const u32* data = reinterpret_cast<const u32*>(vec_data.data()); - u32 media_type = data[0]; u32 save_low = data[1]; u32 save_high = data[2]; - return Common::StringFromFormat("%s%s/%08X/%08X/", mount_point.c_str(), media_type == 0 ? "nand" : "sdmc", save_high, save_low); + return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_high, save_low); } -Archive_ExtSaveData::Archive_ExtSaveData(const std::string& mount_point) - : DiskArchive(mount_point), concrete_mount_point(mount_point) { - LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", this->mount_point.c_str()); +static std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) { + if (shared) + return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID.c_str()); + + return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(), + SYSTEM_ID.c_str(), SDCARD_ID.c_str()); +} + +Archive_ExtSaveData::Archive_ExtSaveData(const std::string& mount_location, bool shared) + : DiskArchive(GetExtDataContainerPath(mount_location, shared)) { + LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str()); } bool Archive_ExtSaveData::Initialize() { diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index a3a144799..fb7f209d2 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -17,7 +17,7 @@ namespace FileSys { /// File system interface to the ExtSaveData archive class Archive_ExtSaveData final : public DiskArchive { public: - Archive_ExtSaveData(const std::string& mount_point); + Archive_ExtSaveData(const std::string& mount_point, bool shared); /** * Initialize the archive. diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 280d4ff5d..3baee5294 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -9,6 +9,7 @@ #include "core/file_sys/archive_savedata.h" #include "core/file_sys/disk_archive.h" +#include "core/hle/service/fs/archive.h" #include "core/settings.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -16,14 +17,25 @@ namespace FileSys { -Archive_SaveData::Archive_SaveData(const std::string& mount_point) - : DiskArchive(mount_point) { +static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { + return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(), + SYSTEM_ID.c_str(), SDCARD_ID.c_str()); +} + +static std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) { + u32 high = program_id >> 32; + u32 low = program_id & 0xFFFFFFFF; + return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); +} + +Archive_SaveData::Archive_SaveData(const std::string& sdmc_directory) + : DiskArchive(GetSaveDataContainerPath(sdmc_directory)) { LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); } ResultCode Archive_SaveData::Open(const Path& path) { if (concrete_mount_point.empty()) - concrete_mount_point = Common::StringFromFormat("%s%016X", mount_point.c_str(), Kernel::g_program_id) + DIR_SEP; + concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); if (!FileUtil::Exists(concrete_mount_point)) { // When a SaveData archive is created for the first time, it is not yet formatted // and the save file/directory structure expected by the game has not yet been initialized. diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index 233158a0c..a7a507536 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -5,13 +5,24 @@ #include "common/file_util.h" #include "core/file_sys/archive_savedatacheck.h" +#include "core/hle/service/fs/archive.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace namespace FileSys { -Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) { +static std::string GetSaveDataCheckContainerPath(const std::string& nand_directory) { + return Common::StringFromFormat("%s%s/title/", nand_directory.c_str(), SYSTEM_ID.c_str()); +} + +static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high, u32 low) { + return Common::StringFromFormat("%s%08x/%08x/content/00000000.app.romfs", + mount_point.c_str(), high, low); +} + +Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& nand_directory) : + mount_point(GetSaveDataCheckContainerPath(nand_directory)) { } ResultCode Archive_SaveDataCheck::Open(const Path& path) { @@ -23,7 +34,7 @@ ResultCode Archive_SaveDataCheck::Open(const Path& path) { // this archive again with a different path, will corrupt the previously open file. auto vec = path.AsBinary(); const u32* data = reinterpret_cast<u32*>(vec.data()); - std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]); + std::string file_path = GetSaveDataCheckPath(mount_point, data[1], data[0]); FileUtil::IOFile file(file_path, "rb"); std::fill(raw_data.begin(), raw_data.end(), 0); diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 1c1c170b6..26b03e82f 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -16,8 +16,8 @@ namespace FileSys { -Archive_SDMC::Archive_SDMC(const std::string& mount_point) : DiskArchive(mount_point) { - LOG_INFO(Service_FS, "Directory %s set as SDMC.", mount_point.c_str()); +Archive_SDMC::Archive_SDMC(const std::string& sdmc_directory) : DiskArchive(sdmc_directory) { + LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str()); } bool Archive_SDMC::Initialize() { diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index 0da32d510..c2a5d641a 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -9,6 +9,7 @@ #include "core/file_sys/archive_systemsavedata.h" #include "core/file_sys/disk_archive.h" +#include "core/hle/service/fs/archive.h" #include "core/settings.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -22,8 +23,12 @@ static std::string GetSystemSaveDataPath(const std::string& mount_point, u64 sav return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_low, save_high); } +static std::string GetSystemSaveDataContainerPath(const std::string& mount_point) { + return Common::StringFromFormat("%sdata/%s/sysdata/", mount_point.c_str(), SYSTEM_ID.c_str()); +} + Archive_SystemSaveData::Archive_SystemSaveData(const std::string& mount_point, u64 save_id) - : DiskArchive(GetSystemSaveDataPath(mount_point, save_id)) { + : DiskArchive(GetSystemSaveDataPath(GetSystemSaveDataContainerPath(mount_point), save_id)) { LOG_INFO(Service_FS, "Directory %s set as SystemSaveData.", this->mount_point.c_str()); } diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index 55d85193c..c8f5845ca 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -15,8 +15,6 @@ namespace FileSys { /// File system interface to the SystemSaveData archive -/// TODO(Subv): This archive should point to a location in the NAND, -/// specifically nand:/data/<ID0>/sysdata/<SaveID-Low>/<SaveID-High> class Archive_SystemSaveData final : public DiskArchive { public: Archive_SystemSaveData(const std::string& mount_point, u64 save_id); diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp index 4b0f761d9..37be4b027 100644 --- a/src/core/hle/service/apt_a.cpp +++ b/src/core/hle/service/apt_a.cpp @@ -25,12 +25,12 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00040040, nullptr, "Finalize?"}, {0x00050040, nullptr, "GetAppletManInfo?"}, {0x00060040, nullptr, "GetAppletInfo?"}, + {0x000D0080, APT_U::ReceiveParameter, "ReceiveParameter?"}, + {0x000E0080, APT_U::GlanceParameter, "GlanceParameter?"}, {0x003B0040, nullptr, "CancelLibraryApplet?"}, {0x00430040, nullptr, "NotifyToWait?"}, {0x004B00C2, nullptr, "AppletUtility?"}, {0x00550040, nullptr, "WriteInputToNsState?"}, - {0x000D0080, APT_U::ReceiveParameter, "ReceiveParameter" }, - {0x000E0080, APT_U::GlanceParameter, "GlanceParameter" }, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 161aa8531..8812c49ef 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -161,9 +161,9 @@ ResultCode FormatConfig() { void CFGInit() { // TODO(Subv): In the future we should use the FS service to query this archive, // currently it is not possible because you can only have one open archive of the same type at any time - std::string syssavedata_directory = FileUtil::GetUserPath(D_SYSSAVEDATA_IDX); + std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); cfg_system_save_data = Common::make_unique<FileSys::Archive_SystemSaveData>( - syssavedata_directory, CFG_SAVE_ID); + nand_directory, CFG_SAVE_ID); if (!cfg_system_save_data->Initialize()) { LOG_CRITICAL(Service_CFG, "Could not initialize SystemSaveData archive for the CFG:U service"); return; diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 03c01cf90..835620909 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -172,12 +172,12 @@ static void GetModelNintendo2DS(Service::Interface* self) { const Interface::FunctionInfo FunctionTable[] = { {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, {0x00020000, nullptr, "SecureInfoGetRegion"}, - {0x00030000, nullptr, "GenHashConsoleUnique"}, + {0x00030040, nullptr, "GenHashConsoleUnique"}, {0x00040000, nullptr, "GetRegionCanadaUSA"}, {0x00050000, GetSystemModel, "GetSystemModel"}, {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, - {0x00070040, nullptr, "unknown"}, - {0x00080080, nullptr, "unknown"}, + {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, + {0x00080080, nullptr, "GoThroughTable"}, {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, }; diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index aef8cfbca..3a557efe1 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp @@ -14,16 +14,15 @@ namespace CSND_SND { const Interface::FunctionInfo FunctionTable[] = { {0x00010140, nullptr, "Initialize"}, {0x00020000, nullptr, "Shutdown"}, - {0x00030040, nullptr, "Unknown"}, - {0x00040080, nullptr, "Unknown"}, - {0x00050000, nullptr, "Unknown"}, - {0x00060000, nullptr, "Unknown"}, - {0x00070000, nullptr, "Unknown"}, - {0x00080040, nullptr, "Unknown"}, + {0x00030040, nullptr, "ExecuteType0Commands"}, + {0x00040080, nullptr, "ExecuteType1Commands"}, + {0x00050000, nullptr, "AcquireSoundChannels"}, + {0x00060000, nullptr, "ReleaseSoundChannels"}, + {0x00070000, nullptr, "AcquireCaptureDevice"}, + {0x00080040, nullptr, "ReleaseCaptureDevice"}, {0x00090082, nullptr, "FlushDCache"}, {0x000A0082, nullptr, "StoreDCache"}, {0x000B0082, nullptr, "InvalidateDCache"}, - {0x000C0000, nullptr, "Unknown"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index f761c6ab9..958dd9344 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -36,6 +36,10 @@ namespace std { }; } +/// TODO(Subv): Confirm length of these strings +const std::string SYSTEM_ID = "00000000000000000000000000000000"; +const std::string SDCARD_ID = "00000000000000000000000000000000"; + namespace Service { namespace FS { @@ -432,11 +436,11 @@ ResultCode FormatSaveData() { void ArchiveInit() { next_handle = 1; - // TODO(Link Mauve): Add the other archive types (see here for the known types: - // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). Currently the only half-finished - // archive type is SDMC, so it is the only one getting exposed. + // TODO(Subv): Add the other archive types (see here for the known types: + // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); + std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); auto sdmc_archive = Common::make_unique<FileSys::Archive_SDMC>(sdmc_directory); if (sdmc_archive->Initialize()) CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); @@ -444,28 +448,24 @@ void ArchiveInit() { LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); // Create the SaveData archive - std::string savedata_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX); - auto savedata_archive = Common::make_unique<FileSys::Archive_SaveData>(savedata_directory); + auto savedata_archive = Common::make_unique<FileSys::Archive_SaveData>(sdmc_directory); CreateArchive(std::move(savedata_archive), ArchiveIdCode::SaveData); - std::string extsavedata_directory = FileUtil::GetUserPath(D_EXTSAVEDATA); - auto extsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(extsavedata_directory); + auto extsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(sdmc_directory, false); if (extsavedata_archive->Initialize()) CreateArchive(std::move(extsavedata_archive), ArchiveIdCode::ExtSaveData); else - LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_directory.c_str()); + LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_archive->GetMountPoint().c_str()); - std::string sharedextsavedata_directory = FileUtil::GetUserPath(D_EXTSAVEDATA); - auto sharedextsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(sharedextsavedata_directory); + auto sharedextsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(nand_directory, true); if (sharedextsavedata_archive->Initialize()) CreateArchive(std::move(sharedextsavedata_archive), ArchiveIdCode::SharedExtSaveData); else LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", - sharedextsavedata_directory.c_str()); + sharedextsavedata_archive->GetMountPoint().c_str()); // Create the SaveDataCheck archive, basically a small variation of the RomFS archive - std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX); - auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory); + auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(nand_directory); CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck); } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 9e9efa019..b3f2134f2 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -10,6 +10,11 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/result.h" +/// The unique system identifier hash, also known as ID0 +extern const std::string SYSTEM_ID; +/// The scrambled SD card CID, also known as ID1 +extern const std::string SDCARD_ID; + namespace Service { namespace FS { diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp index b388afb15..d49bd5335 100644 --- a/src/core/hle/service/ir_rst.cpp +++ b/src/core/hle/service/ir_rst.cpp @@ -15,12 +15,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00010000, nullptr, "GetHandles"}, {0x00020080, nullptr, "Initialize"}, {0x00030000, nullptr, "Shutdown"}, - {0x00040000, nullptr, "Unknown"}, - {0x00050000, nullptr, "Unknown"}, - {0x00060000, nullptr, "Unknown"}, - {0x00070080, nullptr, "Unknown"}, - {0x00080000, nullptr, "Unknown"}, - {0x00090000, nullptr, "Unknown"}, + {0x00090000, nullptr, "WriteToTwoFields"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 9c9e90a40..7d6e2e8e8 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -13,10 +13,14 @@ namespace LDR_RO { const Interface::FunctionInfo FunctionTable[] = { {0x000100C2, nullptr, "Initialize"}, - {0x00020082, nullptr, "CRR_Load"}, - {0x00030042, nullptr, "CRR_Unload"}, - {0x000402C2, nullptr, "CRO_LoadAndFix"}, - {0x000500C2, nullptr, "CRO_ApplyRelocationPatchesAndLink"} + {0x00020082, nullptr, "LoadCRR"}, + {0x00030042, nullptr, "UnloadCCR"}, + {0x000402C2, nullptr, "LoadExeCRO"}, + {0x000500C2, nullptr, "LoadCROSymbols"}, + {0x00060042, nullptr, "CRO_Load?"}, + {0x00070042, nullptr, "LoadCROSymbols"}, + {0x00080042, nullptr, "Shutdown"}, + {0x000902C2, nullptr, "LoadExeCRO_New?"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp index 233b14f6d..0f03de6ae 100644 --- a/src/core/hle/service/ndm_u.cpp +++ b/src/core/hle/service/ndm_u.cpp @@ -11,10 +11,13 @@ namespace NDM_U { const Interface::FunctionInfo FunctionTable[] = { - {0x00060040, nullptr, "SuspendDaemons"}, - {0x00080040, nullptr, "DisableWifiUsage"}, - {0x00090000, nullptr, "EnableWifiUsage"}, - {0x00140040, nullptr, "OverrideDefaultDaemons"}, + {0x00010042, nullptr, "EnterExclusiveState"}, + {0x00020002, nullptr, "LeaveExclusiveState"}, + {0x00030000, nullptr, "QueryExclusiveMode"}, + {0x00060040, nullptr, "SuspendDaemons"}, + {0x00080040, nullptr, "DisableWifiUsage"}, + {0x00090000, nullptr, "EnableWifiUsage"}, + {0x00140040, nullptr, "OverrideDefaultDaemons"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 9cc700c46..fd79cd8ab 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -142,10 +142,10 @@ Interface::Interface() { Register(FunctionTable, ARRAY_SIZE(FunctionTable)); // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file // TODO(Subv): In the future we should use the FS service to query this archive - std::string extsavedata_directory = FileUtil::GetUserPath(D_EXTSAVEDATA); - ptm_shared_extsavedata = Common::make_unique<FileSys::Archive_ExtSaveData>(extsavedata_directory); + std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); + ptm_shared_extsavedata = Common::make_unique<FileSys::Archive_ExtSaveData>(nand_directory, true); if (!ptm_shared_extsavedata->Initialize()) { - LOG_CRITICAL(Service_PTM, "Could not initialize ExtSaveData archive for the PTM:U service"); + LOG_CRITICAL(Service_PTM, "Could not initialize SharedExtSaveData archive for the PTM:U service"); return; } FileSys::Path archive_path(ptm_shared_extdata_id); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index c5233e687..0c5597283 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -46,36 +46,22 @@ Manager* g_manager = nullptr; ///< Service manager //////////////////////////////////////////////////////////////////////////////////////////////////// // Service Manager class -Manager::Manager() { -} - -Manager::~Manager() { - for(Interface* service : m_services) { - DeleteService(service->GetPortName()); - } -} - -/// Add a service to the manager (does not create it though) void Manager::AddService(Interface* service) { // TOOD(yuriks): Fix error reporting m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); m_services.push_back(service); } -/// Removes a service from the manager, also frees memory void Manager::DeleteService(const std::string& port_name) { Interface* service = FetchFromPortName(port_name); m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); m_port_map.erase(port_name); - delete service; } -/// Get a Service Interface from its Handle Interface* Manager::FetchFromHandle(Handle handle) { return Kernel::g_handle_table.Get<Interface>(handle); } -/// Get a Service Interface from its port Interface* Manager::FetchFromPortName(const std::string& port_name) { auto itr = m_port_map.find(port_name); if (itr == m_port_map.end()) { diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 28b4ccd17..41ba1e554 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -114,29 +114,22 @@ private: /// Simple class to manage accessing services from ports and UID handles class Manager { - public: - Manager(); - - ~Manager(); - - /// Add a service to the manager (does not create it though) + /// Add a service to the manager void AddService(Interface* service); - /// Removes a service from the manager (does not delete it though) + /// Removes a service from the manager void DeleteService(const std::string& port_name); - /// Get a Service Interface from its UID - Interface* FetchFromHandle(u32 uid); + /// Get a Service Interface from its Handle + Interface* FetchFromHandle(Handle handle); /// Get a Service Interface from its port Interface* FetchFromPortName(const std::string& port_name); private: - std::vector<Interface*> m_services; std::map<std::string, u32> m_port_map; - }; /// Initialize ServiceManager diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 8e7abcf9c..f502c6afe 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -308,11 +308,11 @@ static void Socket(Service::Interface* self) { u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol)); - if (socket_handle != SOCKET_ERROR_VALUE) + if ((s32)socket_handle != SOCKET_ERROR_VALUE) open_sockets[socket_handle] = { socket_handle, true }; int result = 0; - if (socket_handle == SOCKET_ERROR_VALUE) + if ((s32)socket_handle == SOCKET_ERROR_VALUE) result = TranslateError(GET_ERRNO); cmd_buffer[1] = result; @@ -436,11 +436,11 @@ static void Accept(Service::Interface* self) { socklen_t addr_len = sizeof(addr); u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len)); - if (ret != SOCKET_ERROR_VALUE) + if ((s32)ret != SOCKET_ERROR_VALUE) open_sockets[ret] = { ret, true }; int result = 0; - if (ret == SOCKET_ERROR_VALUE) { + if ((s32)ret == SOCKET_ERROR_VALUE) { result = TranslateError(GET_ERRNO); } else { CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr); diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 25fab1a4f..912b52adf 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -52,13 +52,15 @@ static void GetServiceHandle(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010002, Initialize, "Initialize"}, - {0x00020000, GetProcSemaphore, "GetProcSemaphore"}, - {0x00030100, nullptr, "RegisterService"}, - {0x000400C0, nullptr, "UnregisterService"}, - {0x00050100, GetServiceHandle, "GetServiceHandle"}, - {0x000B0000, nullptr, "ReceiveNotification"}, - {0x000C0080, nullptr, "PublishToSubscriber"} + {0x00010002, Initialize, "Initialize"}, + {0x00020000, GetProcSemaphore, "GetProcSemaphore"}, + {0x00030100, nullptr, "RegisterService"}, + {0x000400C0, nullptr, "UnregisterService"}, + {0x00050100, GetServiceHandle, "GetServiceHandle"}, + {0x000600C2, nullptr, "RegisterHandle"}, + {0x00090040, nullptr, "Subscribe"}, + {0x000B0000, nullptr, "ReceiveNotification"}, + {0x000C0080, nullptr, "PublishToSubscriber"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// |