Compare commits
7 Commits
access_log
...
sysupdater
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
838492c84c | ||
|
|
76fa4db2ed | ||
|
|
015537f9bf | ||
|
|
d47e9ec9fd | ||
|
|
4291d81642 | ||
|
|
dc9c9284e2 | ||
|
|
aa9ba17986 |
@@ -1,15 +1,15 @@
|
|||||||
# Planned Features
|
# Planned Features
|
||||||
atmosphère has a number of features that are either works-in-progress or planned. Please note that while time-estimates are given, they are loose, and things may be completed sooner or later than advertised.
|
atmosphère has a number of features that are either works-in-progress or planned. Please note that while time-estimates are given, they are loose, and things may be completed sooner or later than advertised.
|
||||||
|
|
||||||
The following descriptions were last updated on June 29th, 2020.
|
The following descriptions were last updated on June 15th, 2020.
|
||||||
|
|
||||||
## system updater homebrew
|
## system updater api
|
||||||
* **Description**: A user homebrew making use of the new system updater api, so that users can actually use the new api in practice.
|
* **Description**: A planned extension api for stratosphere (tenatively `ams:su`), this will provide an interface for homebrew to safely install system upgrades or downgrades. This will allow for much more easily transitioning safely between different versions of the operating system.
|
||||||
* **Development Status**: Initial revision complete, pending re-write by Adubbz.
|
* **Development Status**: Backend/implementation completed; final stages (user-facing ipc api) to be written by SciresM.
|
||||||
* **Completion Time**: June-July 2020
|
* **Estimated Time**: June 2020
|
||||||
|
|
||||||
## ams-on-mariko
|
## ams-on-mariko
|
||||||
* **Description**: Atmosphere cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although secure monitor support is complete in exosphere, additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; atmosphere's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
|
* **Description**: Atmosphere cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although exosphere's rewrite laid most groundwork on the secure monitor side, there is still work to do there -- and additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; atmosphere's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
|
||||||
* **Development Status**: Planned.
|
* **Development Status**: Planned.
|
||||||
* **Estimated Time**: Summer 2020
|
* **Estimated Time**: Summer 2020
|
||||||
|
|
||||||
@@ -47,17 +47,3 @@ The following descriptions were last updated on June 29th, 2020.
|
|||||||
* **Description**: General system stability improvements to enhance the user's experience.
|
* **Description**: General system stability improvements to enhance the user's experience.
|
||||||
* **Development Status**: Undergoing active development by all members of the atmosphère team.
|
* **Development Status**: Undergoing active development by all members of the atmosphère team.
|
||||||
* **Estimated Time**: June 15th.
|
* **Estimated Time**: June 15th.
|
||||||
|
|
||||||
# Completed features
|
|
||||||
|
|
||||||
The following features were previously included under the planned features section and are now complete.
|
|
||||||
|
|
||||||
Please note that this is not an exhaustive list of features present in atmosphère, and only serves to indicate what from the above has been completed.
|
|
||||||
|
|
||||||
## system updater api
|
|
||||||
* **Description**: A planned extension api for stratosphere (tenatively `ams:su`), this will provide an interface for homebrew to safely install system upgrades or downgrades. This will allow for much more easily transitioning safely between different versions of the operating system.
|
|
||||||
* **Completion Time**: June 2020
|
|
||||||
|
|
||||||
## exosphere re-write
|
|
||||||
* **Description**: exosphère, atmosphère's reimplementation of Horizon's Secure Monitor, was the first component authored for the project in early 2018. It is written in C, and in a style very different from the rest of atmosphère's code. In addition, exosphère was written to conform to constraints that no longer apply in an environment where it is not launched from the web browser, and where using a custom firmware image to orchestrate wake-from-sleep is possible. exosphère currently uses all but 1 KB of the space available to it, putting it at risk of breaking as future firmware updates are supported. A re-write will solve these issues.
|
|
||||||
* **Completion Time**: June 2020
|
|
||||||
@@ -68,59 +68,12 @@ namespace ams::secmon::boot {
|
|||||||
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
||||||
}
|
}
|
||||||
|
|
||||||
constinit const u8 DeviceMasterKeySourceKekSource[se::AesBlockSize] = {
|
|
||||||
0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This function derives the master kek and device keys using the tsec root key. */
|
/* This function derives the master kek and device keys using the tsec root key. */
|
||||||
void DeriveMasterKekAndDeviceKeyErista(bool is_prod) {
|
/* NOTE: Exosphere does not use this in practice, and expects the bootloader to set up keys already. */
|
||||||
/* NOTE: Exosphere does not use this in practice, and expects the bootloader to set up keys already. */
|
/* NOTE: This function is currently not implemented. If implemented, it will only be a reference implementation. */
|
||||||
/* NOTE: This function is currently not implemented. If implemented, it will only be a reference implementation. */
|
[[maybe_unused]]
|
||||||
if constexpr (false) {
|
void DeriveMasterKekAndDeviceKey() {
|
||||||
/* TODO: Consider implementing this as a reference. */
|
/* TODO: Decide whether to implement this. */
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: These are just latest-master-kek encrypted with BEK. */
|
|
||||||
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
|
|
||||||
/* TODO: Update on next change of keys. */
|
|
||||||
constinit const u8 MarikoMasterKekSourceProd[se::AesBlockSize] = {
|
|
||||||
0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82
|
|
||||||
};
|
|
||||||
|
|
||||||
constinit const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
|
||||||
0xF9, 0x37, 0xCF, 0x9A, 0xBD, 0x86, 0xBB, 0xA9, 0x9C, 0x9E, 0x03, 0xC4, 0xFC, 0xBC, 0x3B, 0xCE
|
|
||||||
};
|
|
||||||
|
|
||||||
void DeriveMasterKekAndDeviceKeyMariko(bool is_prod) {
|
|
||||||
/* Clear all keyslots other than KEK and SBK in SE1. */
|
|
||||||
for (int i = 0; i < pkg1::AesKeySlot_Count; ++i) {
|
|
||||||
if (i != pkg1::AesKeySlot_MarikoKek && i != pkg1::AesKeySlot_SecureBoot) {
|
|
||||||
se::ClearAesKeySlot(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear all keyslots in SE2. */
|
|
||||||
for (int i = 0; i < pkg1::AesKeySlot_Count; ++i) {
|
|
||||||
se::ClearAesKeySlot2(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the master kek. */
|
|
||||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_MasterKek, pkg1::AesKeySlot_MarikoKek, is_prod ? MarikoMasterKekSourceProd : MarikoMasterKekSourceDev, se::AesBlockSize);
|
|
||||||
|
|
||||||
/* Derive the device master key source kek. */
|
|
||||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko, pkg1::AesKeySlot_SecureBoot, DeviceMasterKeySourceKekSource, se::AesBlockSize);
|
|
||||||
|
|
||||||
/* Clear the KEK, now that we're done using it. */
|
|
||||||
se::ClearAesKeySlot(pkg1::AesKeySlot_MarikoKek);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeriveMasterKekAndDeviceKey(bool is_prod) {
|
|
||||||
if (GetSocType() == fuse::SocType_Mariko) {
|
|
||||||
DeriveMasterKekAndDeviceKeyMariko(is_prod);
|
|
||||||
} else /* if (GetSocType() == fuse::SocType_Erista) */ {
|
|
||||||
DeriveMasterKekAndDeviceKeyErista(is_prod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupRandomKey(int slot, se::KeySlotLockFlags flags) {
|
void SetupRandomKey(int slot, se::KeySlotLockFlags flags) {
|
||||||
@@ -265,9 +218,6 @@ namespace ams::secmon::boot {
|
|||||||
/* Get the current key generation. */
|
/* Get the current key generation. */
|
||||||
const int current_generation = secmon::GetKeyGeneration();
|
const int current_generation = secmon::GetKeyGeneration();
|
||||||
|
|
||||||
/* Get the kek slot. */
|
|
||||||
const int kek_slot = GetSocType() == fuse::SocType_Mariko ? pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko : pkg1::AesKeySlot_DeviceMasterKeySourceKekErista;
|
|
||||||
|
|
||||||
/* Iterate for all generations. */
|
/* Iterate for all generations. */
|
||||||
for (int i = 0; i < pkg1::OldDeviceMasterKeyCount; ++i) {
|
for (int i = 0; i < pkg1::OldDeviceMasterKeyCount; ++i) {
|
||||||
const int generation = pkg1::KeyGeneration_4_0_0 + i;
|
const int generation = pkg1::KeyGeneration_4_0_0 + i;
|
||||||
@@ -279,7 +229,7 @@ namespace ams::secmon::boot {
|
|||||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_Temporary, pkg1::AesKeySlot_Temporary, is_prod ? DeviceMasterKekSourcesProd[i] : DeviceMasterKekSourcesDev[i], se::AesBlockSize);
|
se::SetEncryptedAesKey128(pkg1::AesKeySlot_Temporary, pkg1::AesKeySlot_Temporary, is_prod ? DeviceMasterKekSourcesProd[i] : DeviceMasterKekSourcesDev[i], se::AesBlockSize);
|
||||||
|
|
||||||
/* Decrypt the device master key source into the work block. */
|
/* Decrypt the device master key source into the work block. */
|
||||||
se::DecryptAes128(work_block, se::AesBlockSize, kek_slot, DeviceMasterKeySourceSources[i], se::AesBlockSize);
|
se::DecryptAes128(work_block, se::AesBlockSize, pkg1::AesKeySlot_DeviceMasterKeySourceKek, DeviceMasterKeySourceSources[i], se::AesBlockSize);
|
||||||
|
|
||||||
/* If we're decrypting the current device master key, decrypt into the keyslot. */
|
/* If we're decrypting the current device master key, decrypt into the keyslot. */
|
||||||
if (generation == current_generation) {
|
if (generation == current_generation) {
|
||||||
@@ -294,11 +244,14 @@ namespace ams::secmon::boot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clear and lock the Device Master Key Source Kek. */
|
/* Clear and lock the Device Master Key Source Kek. */
|
||||||
se::ClearAesKeySlot(pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko);
|
se::ClearAesKeySlot(pkg1::AesKeySlot_DeviceMasterKeySourceKek);
|
||||||
se::LockAesKeySlot(pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko, se::KeySlotLockFlags_AllLockKek);
|
se::LockAesKeySlot(pkg1::AesKeySlot_DeviceMasterKeySourceKek, se::KeySlotLockFlags_AllLockKek);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeriveAllKeys(bool is_prod) {
|
void DeriveAllKeys() {
|
||||||
|
/* Determine whether we're prod. */
|
||||||
|
const bool is_prod = IsProduction();
|
||||||
|
|
||||||
/* Get the ephemeral work block. */
|
/* Get the ephemeral work block. */
|
||||||
u8 * const work_block = se::GetEphemeralWorkBlock();
|
u8 * const work_block = se::GetEphemeralWorkBlock();
|
||||||
ON_SCOPE_EXIT { util::ClearMemory(work_block, se::AesBlockSize); };
|
ON_SCOPE_EXIT { util::ClearMemory(work_block, se::AesBlockSize); };
|
||||||
@@ -347,18 +300,16 @@ namespace ams::secmon::boot {
|
|||||||
/* Initialize the rng. */
|
/* Initialize the rng. */
|
||||||
se::InitializeRandom();
|
se::InitializeRandom();
|
||||||
|
|
||||||
/* Determine whether we're production. */
|
|
||||||
const bool is_prod = IsProduction();
|
|
||||||
|
|
||||||
/* Derive the master kek and device key. */
|
/* Derive the master kek and device key. */
|
||||||
/* NOTE: This is a no-op on erista, because fusee will have set up keys. */
|
if constexpr (false) {
|
||||||
DeriveMasterKekAndDeviceKey(is_prod);
|
DeriveMasterKekAndDeviceKey();
|
||||||
|
}
|
||||||
|
|
||||||
/* Lock the device key as only usable as a kek. */
|
/* Lock the device key as only usable as a kek. */
|
||||||
se::LockAesKeySlot(pkg1::AesKeySlot_Device, se::KeySlotLockFlags_AllLockKek);
|
se::LockAesKeySlot(pkg1::AesKeySlot_Device, se::KeySlotLockFlags_AllLockKek);
|
||||||
|
|
||||||
/* Derive all keys. */
|
/* Derive all keys. */
|
||||||
DeriveAllKeys(is_prod);
|
DeriveAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -397,9 +348,6 @@ namespace ams::secmon::boot {
|
|||||||
/* Set the security engine to Per Key Secure. */
|
/* Set the security engine to Per Key Secure. */
|
||||||
se::SetPerKeySecure();
|
se::SetPerKeySecure();
|
||||||
|
|
||||||
/* Set the security engine to Context Save Secure. */
|
|
||||||
se::SetContextSaveSecure();
|
|
||||||
|
|
||||||
/* Setup the PMC registers. */
|
/* Setup the PMC registers. */
|
||||||
SetupPmcRegisters();
|
SetupPmcRegisters();
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace ams::secmon {
|
|||||||
i2c::SetRegisterAddress(i2c::Port_5, MemoryRegionVirtualDeviceI2c5.GetAddress());
|
i2c::SetRegisterAddress(i2c::Port_5, MemoryRegionVirtualDeviceI2c5.GetAddress());
|
||||||
pinmux::SetRegisterAddress(MemoryRegionVirtualDeviceApbMisc.GetAddress(), MemoryRegionVirtualDeviceGpio.GetAddress());
|
pinmux::SetRegisterAddress(MemoryRegionVirtualDeviceApbMisc.GetAddress(), MemoryRegionVirtualDeviceGpio.GetAddress());
|
||||||
pmc::SetRegisterAddress(MemoryRegionVirtualDevicePmc.GetAddress());
|
pmc::SetRegisterAddress(MemoryRegionVirtualDevicePmc.GetAddress());
|
||||||
se::SetRegisterAddress(MemoryRegionVirtualDeviceSecurityEngine.GetAddress(), MemoryRegionVirtualDeviceSecurityEngine2.GetAddress());
|
se::SetRegisterAddress(MemoryRegionVirtualDeviceSecurityEngine.GetAddress());
|
||||||
uart::SetRegisterAddress(MemoryRegionVirtualDeviceUart.GetAddress());
|
uart::SetRegisterAddress(MemoryRegionVirtualDeviceUart.GetAddress());
|
||||||
wdt::SetRegisterAddress(MemoryRegionVirtualDeviceTimer.GetAddress());
|
wdt::SetRegisterAddress(MemoryRegionVirtualDeviceTimer.GetAddress());
|
||||||
util::SetRegisterAddress(MemoryRegionVirtualDeviceTimer.GetAddress());
|
util::SetRegisterAddress(MemoryRegionVirtualDeviceTimer.GetAddress());
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ namespace ams::secmon {
|
|||||||
u32 mdcr_el2;
|
u32 mdcr_el2;
|
||||||
u32 mdcr_el3;
|
u32 mdcr_el3;
|
||||||
u32 spsr_el3;
|
u32 spsr_el3;
|
||||||
|
u64 dbgbvcr_el1[12];
|
||||||
|
u64 dbgwvcr_el1[ 8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CoreContext {
|
struct CoreContext {
|
||||||
@@ -59,6 +61,30 @@ namespace ams::secmon {
|
|||||||
HW_CPU_GET_MDCR_EL2 (dr.mdcr_el2);
|
HW_CPU_GET_MDCR_EL2 (dr.mdcr_el2);
|
||||||
HW_CPU_GET_MDCR_EL3 (dr.mdcr_el3);
|
HW_CPU_GET_MDCR_EL3 (dr.mdcr_el3);
|
||||||
HW_CPU_GET_SPSR_EL3 (dr.spsr_el3);
|
HW_CPU_GET_SPSR_EL3 (dr.spsr_el3);
|
||||||
|
|
||||||
|
/* Save debug breakpoints. */
|
||||||
|
HW_CPU_GET_DBGBVR0_EL1(dr.dbgbvcr_el1[ 0]);
|
||||||
|
HW_CPU_GET_DBGBCR0_EL1(dr.dbgbvcr_el1[ 1]);
|
||||||
|
HW_CPU_GET_DBGBVR1_EL1(dr.dbgbvcr_el1[ 2]);
|
||||||
|
HW_CPU_GET_DBGBCR1_EL1(dr.dbgbvcr_el1[ 3]);
|
||||||
|
HW_CPU_GET_DBGBVR2_EL1(dr.dbgbvcr_el1[ 4]);
|
||||||
|
HW_CPU_GET_DBGBCR2_EL1(dr.dbgbvcr_el1[ 5]);
|
||||||
|
HW_CPU_GET_DBGBVR3_EL1(dr.dbgbvcr_el1[ 6]);
|
||||||
|
HW_CPU_GET_DBGBCR3_EL1(dr.dbgbvcr_el1[ 7]);
|
||||||
|
HW_CPU_GET_DBGBVR4_EL1(dr.dbgbvcr_el1[ 8]);
|
||||||
|
HW_CPU_GET_DBGBCR4_EL1(dr.dbgbvcr_el1[ 9]);
|
||||||
|
HW_CPU_GET_DBGBVR5_EL1(dr.dbgbvcr_el1[10]);
|
||||||
|
HW_CPU_GET_DBGBCR5_EL1(dr.dbgbvcr_el1[11]);
|
||||||
|
|
||||||
|
/* Save debug watchpoints. */
|
||||||
|
HW_CPU_GET_DBGWVR0_EL1(dr.dbgwvcr_el1[0]);
|
||||||
|
HW_CPU_GET_DBGWCR0_EL1(dr.dbgwvcr_el1[1]);
|
||||||
|
HW_CPU_GET_DBGWVR1_EL1(dr.dbgwvcr_el1[2]);
|
||||||
|
HW_CPU_GET_DBGWCR1_EL1(dr.dbgwvcr_el1[3]);
|
||||||
|
HW_CPU_GET_DBGWVR2_EL1(dr.dbgwvcr_el1[4]);
|
||||||
|
HW_CPU_GET_DBGWCR2_EL1(dr.dbgwvcr_el1[5]);
|
||||||
|
HW_CPU_GET_DBGWVR3_EL1(dr.dbgwvcr_el1[6]);
|
||||||
|
HW_CPU_GET_DBGWCR3_EL1(dr.dbgwvcr_el1[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreDebugRegisters(const DebugRegisters &dr) {
|
void RestoreDebugRegisters(const DebugRegisters &dr) {
|
||||||
@@ -74,6 +100,30 @@ namespace ams::secmon {
|
|||||||
HW_CPU_SET_MDCR_EL2 (dr.mdcr_el2);
|
HW_CPU_SET_MDCR_EL2 (dr.mdcr_el2);
|
||||||
HW_CPU_SET_MDCR_EL3 (dr.mdcr_el3);
|
HW_CPU_SET_MDCR_EL3 (dr.mdcr_el3);
|
||||||
HW_CPU_SET_SPSR_EL3 (dr.spsr_el3);
|
HW_CPU_SET_SPSR_EL3 (dr.spsr_el3);
|
||||||
|
|
||||||
|
/* Restore debug breakpoints. */
|
||||||
|
HW_CPU_SET_DBGBVR0_EL1(dr.dbgbvcr_el1[ 0]);
|
||||||
|
HW_CPU_SET_DBGBCR0_EL1(dr.dbgbvcr_el1[ 1]);
|
||||||
|
HW_CPU_SET_DBGBVR1_EL1(dr.dbgbvcr_el1[ 2]);
|
||||||
|
HW_CPU_SET_DBGBCR1_EL1(dr.dbgbvcr_el1[ 3]);
|
||||||
|
HW_CPU_SET_DBGBVR2_EL1(dr.dbgbvcr_el1[ 4]);
|
||||||
|
HW_CPU_SET_DBGBCR2_EL1(dr.dbgbvcr_el1[ 5]);
|
||||||
|
HW_CPU_SET_DBGBVR3_EL1(dr.dbgbvcr_el1[ 6]);
|
||||||
|
HW_CPU_SET_DBGBCR3_EL1(dr.dbgbvcr_el1[ 7]);
|
||||||
|
HW_CPU_SET_DBGBVR4_EL1(dr.dbgbvcr_el1[ 8]);
|
||||||
|
HW_CPU_SET_DBGBCR4_EL1(dr.dbgbvcr_el1[ 9]);
|
||||||
|
HW_CPU_SET_DBGBVR5_EL1(dr.dbgbvcr_el1[10]);
|
||||||
|
HW_CPU_SET_DBGBCR5_EL1(dr.dbgbvcr_el1[11]);
|
||||||
|
|
||||||
|
/* Restore debug watchpoints. */
|
||||||
|
HW_CPU_SET_DBGWVR0_EL1(dr.dbgwvcr_el1[0]);
|
||||||
|
HW_CPU_SET_DBGWCR0_EL1(dr.dbgwvcr_el1[1]);
|
||||||
|
HW_CPU_SET_DBGWVR1_EL1(dr.dbgwvcr_el1[2]);
|
||||||
|
HW_CPU_SET_DBGWCR1_EL1(dr.dbgwvcr_el1[3]);
|
||||||
|
HW_CPU_SET_DBGWVR2_EL1(dr.dbgwvcr_el1[4]);
|
||||||
|
HW_CPU_SET_DBGWCR2_EL1(dr.dbgwvcr_el1[5]);
|
||||||
|
HW_CPU_SET_DBGWVR3_EL1(dr.dbgwvcr_el1[6]);
|
||||||
|
HW_CPU_SET_DBGWCR3_EL1(dr.dbgwvcr_el1[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
constinit CoreContext g_core_contexts[NumCores] = {};
|
constinit CoreContext g_core_contexts[NumCores] = {};
|
||||||
|
|||||||
@@ -264,13 +264,6 @@ namespace ams::secmon {
|
|||||||
{
|
{
|
||||||
reg::Write(AHB_ARBC(AHB_GIZMO_TZRAM), (1u << 7));
|
reg::Write(AHB_ARBC(AHB_GIZMO_TZRAM), (1u << 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: This is Mariko only in Nintendo's firmware. */
|
|
||||||
/* Still, it seems to have no adverse effects on Erista... */
|
|
||||||
/* TODO: Find a way to get access to SocType this early (fuse driver isn't alive yet), only write on mariko? */
|
|
||||||
{
|
|
||||||
reg::ReadWrite(AHB_ARBC(AHB_AHB_SPARE_REG), AHB_REG_BITS_VALUE(AHB_SPARE_REG_AHB_SPARE_REG, 0xE0000));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupSocDmaControllersCpuMemoryControllersEnableMmuWarmboot() {
|
void SetupSocDmaControllersCpuMemoryControllersEnableMmuWarmboot() {
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ namespace ams::secmon::smc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PrepareDeviceMasterKey(int generation) {
|
int PrepareDeviceMasterKey(int generation) {
|
||||||
if (generation == pkg1::KeyGeneration_1_0_0 && GetSocType() == fuse::SocType_Erista) {
|
if (generation == pkg1::KeyGeneration_1_0_0) {
|
||||||
return pkg1::AesKeySlot_Device;
|
return pkg1::AesKeySlot_Device;
|
||||||
}
|
}
|
||||||
if (generation == GetKeyGeneration()) {
|
if (generation == GetKeyGeneration()) {
|
||||||
|
|||||||
@@ -325,11 +325,7 @@ namespace ams::secmon::smc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SaveSecureContextForMariko() {
|
void SaveSecureContextForMariko() {
|
||||||
/* Save security engine context to TZRAM SE carveout (inaccessible to cpu). */
|
/* TODO: Implement this when adding ams-on-mariko support. */
|
||||||
se::SaveContextAutomatic();
|
|
||||||
|
|
||||||
/* Save TZRAM to shadow-TZRAM in always-on power domain. */
|
|
||||||
se::SaveTzramAutomatic();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSecureContext() {
|
void SaveSecureContext() {
|
||||||
|
|||||||
@@ -90,15 +90,12 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
|||||||
char filepath[0x40];
|
char filepath[0x40];
|
||||||
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
||||||
filepath[sizeof(filepath)-1] = 0;
|
filepath[sizeof(filepath)-1] = 0;
|
||||||
if (write_to_file(&ctx, sizeof(ctx), filepath) != sizeof(ctx)) {
|
write_to_file(&ctx, sizeof(ctx), filepath);
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Failed to save report to the SD card!\n");
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"Report saved to %s\n", filepath);
|
||||||
} else {
|
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Report saved to %s\n", filepath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display error. */
|
/* Display error. */
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nPress POWER to reboot\n");
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for button and reboot. */
|
/* Wait for button and reboot. */
|
||||||
|
|||||||
@@ -273,10 +273,7 @@ void derive_bis_key(void *dst, BisPartition partition_id, uint32_t target_firmwa
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t bis_key_generation = fuse_get_5x_key_generation();
|
const uint32_t bis_key_generation = fuse_get_5x_key_generation();
|
||||||
if (bis_key_generation > 0) {
|
|
||||||
bis_key_generation -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8_t AL16 bis_kek_source[0x10] = {0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F};
|
static const uint8_t AL16 bis_kek_source[0x10] = {0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F};
|
||||||
switch (partition_id) {
|
switch (partition_id) {
|
||||||
|
|||||||
@@ -838,7 +838,13 @@ uint32_t nxboot_main(void) {
|
|||||||
|
|
||||||
/* Derive new device keys. */
|
/* Derive new device keys. */
|
||||||
{
|
{
|
||||||
derive_new_device_keys(fuse_get_retail_type() != 0, KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, target_firmware);
|
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
|
||||||
|
derive_new_device_keys(fuse_get_retail_type() != 0, KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, target_firmware);
|
||||||
|
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
|
||||||
|
derive_new_device_keys(fuse_get_retail_type() != 0, KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY, target_firmware);
|
||||||
|
} else {
|
||||||
|
/* No new keys to derive */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the system partition's keys. */
|
/* Set the system partition's keys. */
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = 89f8944f8025c0557a18e64ceca7f65ab3090d82
|
commit = cf8f0c3c1f006e07c0b3976908220d3e7e83f7fa
|
||||||
parent = 29f1eb807066bdb551f8b1f7352c97e5ac62d436
|
parent = 033ae1dbe09ba354849caf90ca2a2f114d9b3b4b
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export ATMOSPHERE_DEFINES := -DATMOSPHERE
|
|||||||
export ATMOSPHERE_SETTINGS := -fPIE -g
|
export ATMOSPHERE_SETTINGS := -fPIE -g
|
||||||
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
|
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
|
||||||
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
|
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
|
||||||
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
|
-Wno-format-truncation
|
||||||
|
|
||||||
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20
|
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20
|
||||||
export ATMOSPHERE_ASFLAGS :=
|
export ATMOSPHERE_ASFLAGS :=
|
||||||
|
|||||||
@@ -19,40 +19,34 @@
|
|||||||
namespace ams::pkg1 {
|
namespace ams::pkg1 {
|
||||||
|
|
||||||
enum AesKeySlot {
|
enum AesKeySlot {
|
||||||
AesKeySlot_UserStart = 0,
|
AesKeySlot_UserStart = 0,
|
||||||
|
|
||||||
AesKeySlot_TzramSaveKek = 2,
|
AesKeySlot_TzramSaveKek = 2,
|
||||||
AesKeySlot_TzramSaveKey = 3,
|
AesKeySlot_TzramSaveKey = 3,
|
||||||
|
|
||||||
AesKeySlot_UserLast = 5,
|
AesKeySlot_UserLast = 5,
|
||||||
AesKeySlot_UserEnd = AesKeySlot_UserLast + 1,
|
AesKeySlot_UserEnd = AesKeySlot_UserLast + 1,
|
||||||
|
|
||||||
AesKeySlot_SecmonStart = 8,
|
AesKeySlot_SecmonStart = 8,
|
||||||
|
|
||||||
AesKeySlot_Temporary = 8,
|
AesKeySlot_Temporary = 8,
|
||||||
AesKeySlot_Smc = 9,
|
AesKeySlot_Smc = 9,
|
||||||
AesKeySlot_RandomForUserWrap = 10,
|
AesKeySlot_RandomForUserWrap = 10,
|
||||||
AesKeySlot_RandomForKeyStorageWrap = 11,
|
AesKeySlot_RandomForKeyStorageWrap = 11,
|
||||||
AesKeySlot_DeviceMaster = 12,
|
AesKeySlot_DeviceMaster = 12,
|
||||||
AesKeySlot_Master = 13,
|
AesKeySlot_Master = 13,
|
||||||
AesKeySlot_Device = 15,
|
AesKeySlot_Device = 15,
|
||||||
|
|
||||||
AesKeySlot_Count = 16,
|
AesKeySlot_SecmonEnd = 16,
|
||||||
AesKeySlot_SecmonEnd = AesKeySlot_Count,
|
|
||||||
|
|
||||||
/* Used only during boot. */
|
/* Used only during boot. */
|
||||||
AesKeySlot_Tsec = 12,
|
AesKeySlot_Tsec = 12,
|
||||||
AesKeySlot_TsecRoot = 13,
|
AesKeySlot_TsecRoot = 13,
|
||||||
AesKeySlot_SecureBoot = 14,
|
AesKeySlot_SecureBoot = 14,
|
||||||
AesKeySlot_SecureStorage = 15,
|
AesKeySlot_SecureStorage = 15,
|
||||||
|
|
||||||
AesKeySlot_DeviceMasterKeySourceKekErista = 10,
|
AesKeySlot_MasterKek = 13,
|
||||||
AesKeySlot_MasterKek = 13,
|
AesKeySlot_DeviceMasterKeySourceKek = 14,
|
||||||
AesKeySlot_DeviceMasterKeySourceKekMariko = 14,
|
|
||||||
|
|
||||||
/* Mariko only keyslots, used during boot. */
|
|
||||||
AesKeySlot_MarikoKek = 12,
|
|
||||||
AesKeySlot_MarikoBek = 13,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RsaKeySlot {
|
enum RsaKeySlot {
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ namespace ams::se {
|
|||||||
void ClearAesKeyIv(int slot);
|
void ClearAesKeyIv(int slot);
|
||||||
void LockAesKeySlot(int slot, u32 flags);
|
void LockAesKeySlot(int slot, u32 flags);
|
||||||
|
|
||||||
/* NOTE: This is Nintendo's API, but if we actually want to use SE2 we should use a different one. */
|
|
||||||
void ClearAesKeySlot2(int slot);
|
|
||||||
|
|
||||||
void SetAesKey(int slot, const void *key, size_t key_size);
|
void SetAesKey(int slot, const void *key, size_t key_size);
|
||||||
|
|
||||||
void SetEncryptedAesKey128(int dst_slot, int kek_slot, const void *key, size_t key_size);
|
void SetEncryptedAesKey128(int dst_slot, int kek_slot, const void *key, size_t key_size);
|
||||||
|
|||||||
@@ -18,14 +18,13 @@
|
|||||||
|
|
||||||
namespace ams::se {
|
namespace ams::se {
|
||||||
|
|
||||||
void SetRegisterAddress(uintptr_t address, uintptr_t address2);
|
void SetRegisterAddress(uintptr_t address);
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
void SetSecure(bool secure);
|
void SetSecure(bool secure);
|
||||||
void SetTzramSecure();
|
void SetTzramSecure();
|
||||||
void SetPerKeySecure();
|
void SetPerKeySecure();
|
||||||
void SetContextSaveSecure();
|
|
||||||
|
|
||||||
void Lockout();
|
void Lockout();
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,4 @@ namespace ams::se {
|
|||||||
bool ValidateStickyBits(const StickyBits &bits);
|
bool ValidateStickyBits(const StickyBits &bits);
|
||||||
void SaveContext(Context *dst);
|
void SaveContext(Context *dst);
|
||||||
|
|
||||||
void ConfigureAutomaticContextSave();
|
|
||||||
void SaveContextAutomatic();
|
|
||||||
void SaveTzramAutomatic();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#define AHB_MASTER_SWID (0x018)
|
#define AHB_MASTER_SWID (0x018)
|
||||||
#define AHB_MASTER_SWID_1 (0x038)
|
#define AHB_MASTER_SWID_1 (0x038)
|
||||||
#define AHB_GIZMO_TZRAM (0x054)
|
#define AHB_GIZMO_TZRAM (0x054)
|
||||||
#define AHB_AHB_SPARE_REG (0x110)
|
|
||||||
|
|
||||||
#define AHB_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (AHB_, NAME)
|
#define AHB_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (AHB_, NAME)
|
||||||
#define AHB_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (AHB_, NAME, VALUE)
|
#define AHB_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (AHB_, NAME, VALUE)
|
||||||
@@ -40,8 +39,3 @@ DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_COP, 1, ENABLE, DISABLE);
|
|||||||
DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_AHBDMA, 5, ENABLE, DISABLE);
|
DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_AHBDMA, 5, ENABLE, DISABLE);
|
||||||
DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_USB, 6, ENABLE, DISABLE);
|
DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_USB, 6, ENABLE, DISABLE);
|
||||||
DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_USB2, 18, ENABLE, DISABLE);
|
DEFINE_AHB_REG_BIT_ENUM(ARBITRATION_DISABLE_USB2, 18, ENABLE, DISABLE);
|
||||||
|
|
||||||
DEFINE_AHB_REG(AHB_SPARE_REG_CSITE_PADMACRO3_TRIM_SEL, 0, 5);
|
|
||||||
DEFINE_AHB_REG_BIT_ENUM(AHB_SPARE_REG_OBS_OVERRIDE_EN, 5, DISABLE, ENABLE);
|
|
||||||
DEFINE_AHB_REG_BIT_ENUM(AHB_SPARE_REG_APB2JTAG_OVERRIDE_EN, 6, DISABLE, ENABLE);
|
|
||||||
DEFINE_AHB_REG(AHB_SPARE_REG_AHB_SPARE_REG, 12, 32-12);
|
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ namespace ams::fuse {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static constexpr SocType SocType_CommonInternal = static_cast<SocType>(-1);
|
|
||||||
static_assert(SocType_CommonInternal != SocType_Erista);
|
|
||||||
static_assert(SocType_CommonInternal != SocType_Mariko);
|
|
||||||
|
|
||||||
struct BypassEntry {
|
struct BypassEntry {
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 value;
|
u32 value;
|
||||||
@@ -46,11 +42,6 @@ namespace ams::fuse {
|
|||||||
using HardwareType3 = util::BitPack32::Field<Reserved::Next, 4, int>;
|
using HardwareType3 = util::BitPack32::Field<Reserved::Next, 4, int>;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OdmWord28 {
|
|
||||||
using Regulator = util::BitPack32::Field<0, 1, int>;
|
|
||||||
using Reserved = util::BitPack32::Field<1, 31, int>;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE int GetHardwareStateValue(const util::BitPack32 odm_word4) {
|
constexpr ALWAYS_INLINE int GetHardwareStateValue(const util::BitPack32 odm_word4) {
|
||||||
constexpr auto HardwareState1Shift = 0;
|
constexpr auto HardwareState1Shift = 0;
|
||||||
constexpr auto HardwareState2Shift = OdmWord4::HardwareState1::Count + HardwareState1Shift;
|
constexpr auto HardwareState2Shift = OdmWord4::HardwareState1::Count + HardwareState1Shift;
|
||||||
@@ -82,16 +73,8 @@ namespace ams::fuse {
|
|||||||
return GetRegisterRegion()->fuse;
|
return GetRegisterRegion()->fuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE volatile FuseChipRegistersCommon &GetChipRegistersCommon() {
|
ALWAYS_INLINE volatile FuseChipRegisters &GetChipRegisters() {
|
||||||
return GetRegisterRegion()->chip_common;
|
return GetRegisterRegion()->chip;
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE volatile FuseChipRegistersErista &GetChipRegistersErista() {
|
|
||||||
return GetRegisterRegion()->chip_erista;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE volatile FuseChipRegistersMariko &GetChipRegistersMariko() {
|
|
||||||
return GetRegisterRegion()->chip_mariko;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsIdle() {
|
bool IsIdle() {
|
||||||
@@ -102,31 +85,6 @@ namespace ams::fuse {
|
|||||||
while (!IsIdle()) { /* ... */ }
|
while (!IsIdle()) { /* ... */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetOdmWordImpl(int index, fuse::SocType soc_type) {
|
|
||||||
if (index < 8) {
|
|
||||||
volatile auto &chip = GetChipRegistersCommon();
|
|
||||||
return chip.FUSE_RESERVED_ODM_0[index - 0];
|
|
||||||
} else if (soc_type == SocType_Mariko) {
|
|
||||||
volatile auto &chip = GetChipRegistersMariko();
|
|
||||||
if (index < 22) {
|
|
||||||
return chip.FUSE_RESERVED_ODM_8[index - 8];
|
|
||||||
} else if (index < 25) {
|
|
||||||
return chip.FUSE_RESERVED_ODM_22[index - 22];
|
|
||||||
} else if (index < 26) {
|
|
||||||
return chip.FUSE_RESERVED_ODM_25[index - 25];
|
|
||||||
} else if (index < 29) {
|
|
||||||
return chip.FUSE_RESERVED_ODM_26[index - 26];
|
|
||||||
} else if (index < 30) {
|
|
||||||
return chip.FUSE_RESERVED_ODM_29[index - 29];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AMS_ABORT("Invalid ODM fuse read");
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetCommonOdmWord(int index) {
|
|
||||||
return GetOdmWordImpl(index, SocType_CommonInternal);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsNewFuseFormat() {
|
bool IsNewFuseFormat() {
|
||||||
/* On mariko, this should always be true. */
|
/* On mariko, this should always be true. */
|
||||||
if (GetSocType() != SocType_Erista) {
|
if (GetSocType() != SocType_Erista) {
|
||||||
@@ -134,7 +92,7 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Require that the format version be non-zero in odm4. */
|
/* Require that the format version be non-zero in odm4. */
|
||||||
if (util::BitPack32{GetCommonOdmWord(4)}.Get<OdmWord4::FormatVersion>() == 0) {
|
if (util::BitPack32{GetOdmWord(4)}.Get<OdmWord4::FormatVersion>() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,8 +100,8 @@ namespace ams::fuse {
|
|||||||
constexpr u32 NewFuseFormatMagic0 = 0x8E61ECAE;
|
constexpr u32 NewFuseFormatMagic0 = 0x8E61ECAE;
|
||||||
constexpr u32 NewFuseFormatMagic1 = 0xF2BA3BB2;
|
constexpr u32 NewFuseFormatMagic1 = 0xF2BA3BB2;
|
||||||
|
|
||||||
const u32 w0 = GetCommonOdmWord(0);
|
const u32 w0 = GetOdmWord(0);
|
||||||
const u32 w1 = GetCommonOdmWord(1);
|
const u32 w1 = GetOdmWord(1);
|
||||||
|
|
||||||
return w0 == NewFuseFormatMagic0 && w1 == NewFuseFormatMagic1;
|
return w0 == NewFuseFormatMagic0 && w1 == NewFuseFormatMagic1;
|
||||||
}
|
}
|
||||||
@@ -248,12 +206,12 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 GetOdmWord(int index) {
|
u32 GetOdmWord(int index) {
|
||||||
return GetOdmWordImpl(index, GetSocType());
|
return GetChipRegisters().FUSE_RESERVED_ODM[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetEcid(br::BootEcid *out) {
|
void GetEcid(br::BootEcid *out) {
|
||||||
/* Get the registers. */
|
/* Get the registers. */
|
||||||
volatile auto &chip = GetChipRegistersCommon();
|
volatile auto &chip = GetChipRegisters();
|
||||||
|
|
||||||
/* Read the ecid components. */
|
/* Read the ecid components. */
|
||||||
const u32 vendor = reg::Read(chip.FUSE_OPT_VENDOR_CODE) & ((1u << 4) - 1);
|
const u32 vendor = reg::Read(chip.FUSE_OPT_VENDOR_CODE) & ((1u << 4) - 1);
|
||||||
@@ -277,7 +235,7 @@ namespace ams::fuse {
|
|||||||
|
|
||||||
u64 GetDeviceId() {
|
u64 GetDeviceId() {
|
||||||
/* Get the registers. */
|
/* Get the registers. */
|
||||||
volatile auto &chip = GetChipRegistersCommon();
|
volatile auto &chip = GetChipRegisters();
|
||||||
|
|
||||||
/* Read the device id components. */
|
/* Read the device id components. */
|
||||||
/* NOTE: Device ID is "basically" just an alternate encoding of Ecid. */
|
/* NOTE: Device ID is "basically" just an alternate encoding of Ecid. */
|
||||||
@@ -300,12 +258,12 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DramId GetDramId() {
|
DramId GetDramId() {
|
||||||
return static_cast<DramId>(util::BitPack32{GetCommonOdmWord(4)}.Get<OdmWord4::DramId>());
|
return static_cast<DramId>(util::BitPack32{GetOdmWord(4)}.Get<OdmWord4::DramId>());
|
||||||
}
|
}
|
||||||
|
|
||||||
HardwareType GetHardwareType() {
|
HardwareType GetHardwareType() {
|
||||||
/* Read the odm word. */
|
/* Read the odm word. */
|
||||||
const util::BitPack32 odm_word4 = { GetCommonOdmWord(4) };
|
const util::BitPack32 odm_word4 = { GetOdmWord(4) };
|
||||||
|
|
||||||
/* Get the value. */
|
/* Get the value. */
|
||||||
const auto value = GetHardwareTypeValue(odm_word4);
|
const auto value = GetHardwareTypeValue(odm_word4);
|
||||||
@@ -322,7 +280,7 @@ namespace ams::fuse {
|
|||||||
|
|
||||||
HardwareState GetHardwareState() {
|
HardwareState GetHardwareState() {
|
||||||
/* Read the odm word. */
|
/* Read the odm word. */
|
||||||
const util::BitPack32 odm_word4 = { GetCommonOdmWord(4) };
|
const util::BitPack32 odm_word4 = { GetOdmWord(4) };
|
||||||
|
|
||||||
/* Get the value. */
|
/* Get the value. */
|
||||||
const auto value = GetHardwareStateValue(odm_word4);
|
const auto value = GetHardwareStateValue(odm_word4);
|
||||||
@@ -335,28 +293,22 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PatchVersion GetPatchVersion() {
|
PatchVersion GetPatchVersion() {
|
||||||
const auto patch_version = reg::Read(GetChipRegistersCommon().FUSE_SOC_SPEEDO_1_CALIB);
|
const auto patch_version = reg::Read(GetChipRegisters().FUSE_SOC_SPEEDO_1_CALIB);
|
||||||
return static_cast<PatchVersion>(static_cast<int>(GetSocType() << 12) | patch_version);
|
return static_cast<PatchVersion>(static_cast<int>(GetSocType() << 12) | patch_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
QuestState GetQuestState() {
|
QuestState GetQuestState() {
|
||||||
return static_cast<QuestState>(util::BitPack32{GetCommonOdmWord(4)}.Get<OdmWord4::QuestState>());
|
return static_cast<QuestState>(util::BitPack32{GetOdmWord(4)}.Get<OdmWord4::QuestState>());
|
||||||
}
|
}
|
||||||
|
|
||||||
pmic::Regulator GetRegulator() {
|
pmic::Regulator GetRegulator() {
|
||||||
if (GetSocType() == SocType_Mariko) {
|
/* TODO: How should mariko be handled? This reads from ODM word 28 in fuses (not present in erista...). */
|
||||||
/* Read the odm word. */
|
return pmic::Regulator_Erista_Max77621;
|
||||||
const util::BitPack32 odm_word28 = { GetOdmWordImpl(28, SocType_Mariko) };
|
|
||||||
|
|
||||||
return static_cast<pmic::Regulator>(odm_word28.Get<OdmWord28::Regulator>() + 1);
|
|
||||||
} else /* if (GetSocType() == SocType_Erista) */ {
|
|
||||||
return pmic::Regulator_Erista_Max77621;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetDeviceUniqueKeyGeneration() {
|
int GetDeviceUniqueKeyGeneration() {
|
||||||
if (IsNewFuseFormat()) {
|
if (IsNewFuseFormat()) {
|
||||||
return util::BitPack32{GetCommonOdmWord(2)}.Get<OdmWord2::DeviceUniqueKeyGeneration>();
|
return util::BitPack32{GetOdmWord(2)}.Get<OdmWord2::DeviceUniqueKeyGeneration>();
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -392,13 +344,13 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Some patched units use XUSB in RCM. */
|
/* Some patched units use XUSB in RCM. */
|
||||||
if (reg::Read(GetChipRegistersCommon().FUSE_RESERVED_SW) & 0x80) {
|
if (reg::Read(GetChipRegisters().FUSE_RESERVED_SW) & 0x80) {
|
||||||
g_has_rcm_bug_patch = true;
|
g_has_rcm_bug_patch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Other units have a proper ipatch instead. */
|
/* Other units have a proper ipatch instead. */
|
||||||
u32 word_count = reg::Read(GetChipRegistersCommon().FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
u32 word_count = reg::Read(GetChipRegisters().FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
||||||
u32 word_addr = 191;
|
u32 word_addr = 191;
|
||||||
|
|
||||||
while (word_count && !g_has_rcm_bug_patch) {
|
while (word_count && !g_has_rcm_bug_patch) {
|
||||||
@@ -427,7 +379,7 @@ namespace ams::fuse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsOdmProductionMode() {
|
bool IsOdmProductionMode() {
|
||||||
return reg::HasValue(GetChipRegistersCommon().FUSE_SECURITY_MODE, FUSE_REG_BITS_ENUM(SECURITY_MODE_SECURITY_MODE, ENABLED));
|
return reg::HasValue(GetChipRegisters().FUSE_SECURITY_MODE, FUSE_REG_BITS_ENUM(SECURITY_MODE_SECURITY_MODE, ENABLED));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureFuseBypass() {
|
void ConfigureFuseBypass() {
|
||||||
|
|||||||
@@ -42,162 +42,12 @@ namespace ams::fuse {
|
|||||||
u32 FUSE_PRIVATE_KEY2_NONZERO;
|
u32 FUSE_PRIVATE_KEY2_NONZERO;
|
||||||
u32 FUSE_PRIVATE_KEY3_NONZERO;
|
u32 FUSE_PRIVATE_KEY3_NONZERO;
|
||||||
u32 FUSE_PRIVATE_KEY4_NONZERO;
|
u32 FUSE_PRIVATE_KEY4_NONZERO;
|
||||||
u32 _0x94;
|
u32 _0x94[0x1B];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<FuseRegisters>::value);
|
static_assert(util::is_pod<FuseRegisters>::value);
|
||||||
static_assert(sizeof(FuseRegisters) == 0x98);
|
static_assert(sizeof(FuseRegisters) == 0x100);
|
||||||
|
|
||||||
struct FuseChipRegistersCommon {
|
struct FuseChipRegisters {
|
||||||
u32 _0x98[0x1A];
|
|
||||||
u32 FUSE_PRODUCTION_MODE;
|
|
||||||
u32 FUSE_JTAG_SECUREID_VALID;
|
|
||||||
u32 FUSE_ODM_LOCK;
|
|
||||||
u32 FUSE_OPT_OPENGL_EN;
|
|
||||||
u32 FUSE_SKU_INFO;
|
|
||||||
u32 FUSE_CPU_SPEEDO_0_CALIB;
|
|
||||||
u32 FUSE_CPU_IDDQ_CALIB;
|
|
||||||
u32 _0x11C;
|
|
||||||
u32 _0x120;
|
|
||||||
u32 _0x124;
|
|
||||||
u32 FUSE_OPT_FT_REV;
|
|
||||||
u32 FUSE_CPU_SPEEDO_1_CALIB;
|
|
||||||
u32 FUSE_CPU_SPEEDO_2_CALIB;
|
|
||||||
u32 FUSE_SOC_SPEEDO_0_CALIB;
|
|
||||||
u32 FUSE_SOC_SPEEDO_1_CALIB;
|
|
||||||
u32 FUSE_SOC_SPEEDO_2_CALIB;
|
|
||||||
u32 FUSE_SOC_IDDQ_CALIB;
|
|
||||||
u32 _0x144;
|
|
||||||
u32 FUSE_FA;
|
|
||||||
u32 FUSE_RESERVED_PRODUCTION;
|
|
||||||
u32 FUSE_HDMI_LANE0_CALIB;
|
|
||||||
u32 FUSE_HDMI_LANE1_CALIB;
|
|
||||||
u32 FUSE_HDMI_LANE2_CALIB;
|
|
||||||
u32 FUSE_HDMI_LANE3_CALIB;
|
|
||||||
u32 FUSE_ENCRYPTION_RATE;
|
|
||||||
u32 FUSE_PUBLIC_KEY[0x8];
|
|
||||||
u32 FUSE_TSENSOR1_CALIB;
|
|
||||||
u32 FUSE_TSENSOR2_CALIB;
|
|
||||||
u32 _0x18C;
|
|
||||||
u32 FUSE_OPT_CP_REV;
|
|
||||||
u32 FUSE_OPT_PFG;
|
|
||||||
u32 FUSE_TSENSOR0_CALIB;
|
|
||||||
u32 FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
|
||||||
u32 FUSE_SECURITY_MODE;
|
|
||||||
u32 FUSE_PRIVATE_KEY[0x5];
|
|
||||||
u32 FUSE_ARM_JTAG_DIS;
|
|
||||||
u32 FUSE_BOOT_DEVICE_INFO;
|
|
||||||
u32 FUSE_RESERVED_SW;
|
|
||||||
u32 FUSE_OPT_VP9_DISABLE;
|
|
||||||
u32 FUSE_RESERVED_ODM_0[8 - 0];
|
|
||||||
u32 FUSE_OBS_DIS;
|
|
||||||
u32 _0x1EC;
|
|
||||||
u32 FUSE_USB_CALIB;
|
|
||||||
u32 FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
u32 FUSE_KFUSE_PRIVKEY_CTRL;
|
|
||||||
u32 FUSE_PACKAGE_INFO;
|
|
||||||
u32 FUSE_OPT_VENDOR_CODE;
|
|
||||||
u32 FUSE_OPT_FAB_CODE;
|
|
||||||
u32 FUSE_OPT_LOT_CODE_0;
|
|
||||||
u32 FUSE_OPT_LOT_CODE_1;
|
|
||||||
u32 FUSE_OPT_WAFER_ID;
|
|
||||||
u32 FUSE_OPT_X_COORDINATE;
|
|
||||||
u32 FUSE_OPT_Y_COORDINATE;
|
|
||||||
u32 FUSE_OPT_SEC_DEBUG_EN;
|
|
||||||
u32 FUSE_OPT_OPS_RESERVED;
|
|
||||||
u32 _0x224;
|
|
||||||
u32 FUSE_GPU_IDDQ_CALIB;
|
|
||||||
u32 FUSE_TSENSOR3_CALIB;
|
|
||||||
u32 _0x234;
|
|
||||||
u32 _0x238;
|
|
||||||
u32 _0x23C;
|
|
||||||
u32 _0x240;
|
|
||||||
u32 _0x244;
|
|
||||||
u32 FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
u32 FUSE_OPT_SUBREVISION;
|
|
||||||
u32 FUSE_OPT_SW_RESERVED_0;
|
|
||||||
u32 FUSE_OPT_SW_RESERVED_1;
|
|
||||||
u32 FUSE_TSENSOR4_CALIB;
|
|
||||||
u32 FUSE_TSENSOR5_CALIB;
|
|
||||||
u32 FUSE_TSENSOR6_CALIB;
|
|
||||||
u32 FUSE_TSENSOR7_CALIB;
|
|
||||||
u32 FUSE_OPT_PRIV_SEC_EN;
|
|
||||||
u32 _0x268;
|
|
||||||
u32 _0x26C;
|
|
||||||
u32 _0x270;
|
|
||||||
u32 _0x274;
|
|
||||||
u32 _0x278;
|
|
||||||
u32 FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
u32 FUSE_TSENSOR_COMMON;
|
|
||||||
u32 FUSE_OPT_CP_BIN;
|
|
||||||
u32 FUSE_OPT_GPU_DISABLE;
|
|
||||||
u32 FUSE_OPT_FT_BIN;
|
|
||||||
u32 FUSE_OPT_DONE_MAP;
|
|
||||||
u32 _0x294;
|
|
||||||
u32 FUSE_APB2JTAG_DISABLE;
|
|
||||||
u32 FUSE_ODM_INFO;
|
|
||||||
u32 _0x2A0;
|
|
||||||
u32 _0x2A4;
|
|
||||||
u32 FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
u32 _0x2AC;
|
|
||||||
u32 _0x2B0;
|
|
||||||
u32 _0x2B4;
|
|
||||||
u32 _0x2B8;
|
|
||||||
u32 _0x2BC;
|
|
||||||
u32 FUSE_WOA_SKU_FLAG;
|
|
||||||
u32 FUSE_ECO_RESERVE_1;
|
|
||||||
u32 FUSE_GCPLEX_CONFIG_FUSE;
|
|
||||||
u32 FUSE_PRODUCTION_MONTH;
|
|
||||||
u32 FUSE_RAM_REPAIR_INDICATOR;
|
|
||||||
u32 FUSE_TSENSOR9_CALIB;
|
|
||||||
u32 _0x2D8;
|
|
||||||
u32 FUSE_VMIN_CALIBRATION;
|
|
||||||
u32 FUSE_AGING_SENSOR_CALIBRATION;
|
|
||||||
u32 FUSE_DEBUG_AUTHENTICATION;
|
|
||||||
u32 FUSE_SECURE_PROVISION_INDEX;
|
|
||||||
u32 FUSE_SECURE_PROVISION_INFO;
|
|
||||||
u32 FUSE_OPT_GPU_DISABLE_CP1;
|
|
||||||
u32 FUSE_SPARE_ENDIS;
|
|
||||||
u32 FUSE_ECO_RESERVE_0;
|
|
||||||
u32 _0x2FC;
|
|
||||||
u32 _0x300;
|
|
||||||
u32 FUSE_RESERVED_CALIB0;
|
|
||||||
u32 FUSE_RESERVED_CALIB1;
|
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE;
|
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
|
||||||
u32 FUSE_OPT_CPU_DISABLE;
|
|
||||||
u32 FUSE_OPT_CPU_DISABLE_CP1;
|
|
||||||
u32 FUSE_TSENSOR10_CALIB;
|
|
||||||
u32 FUSE_TSENSOR10_CALIB_AUX;
|
|
||||||
u32 _0x324;
|
|
||||||
u32 _0x328;
|
|
||||||
u32 _0x32C;
|
|
||||||
u32 _0x330;
|
|
||||||
u32 _0x334;
|
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
|
||||||
u32 FUSE_OPT_GPU_TPC1_DISABLE;
|
|
||||||
u32 FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
|
||||||
u32 FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
|
||||||
u32 FUSE_OPT_CPU_DISABLE_CP2;
|
|
||||||
u32 FUSE_OPT_GPU_DISABLE_CP2;
|
|
||||||
u32 FUSE_USB_CALIB_EXT;
|
|
||||||
u32 FUSE_RESERVED_FIELD;
|
|
||||||
u32 _0x358;
|
|
||||||
u32 _0x35C;
|
|
||||||
u32 _0x360;
|
|
||||||
u32 _0x364;
|
|
||||||
u32 _0x368;
|
|
||||||
u32 _0x36C;
|
|
||||||
u32 _0x370;
|
|
||||||
u32 _0x374;
|
|
||||||
u32 _0x378;
|
|
||||||
u32 FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
u32 FUSE_SPARE_BIT[0x20];
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<FuseChipRegistersCommon>::value);
|
|
||||||
static_assert(sizeof(FuseChipRegistersCommon) == 0x400 - 0x98);
|
|
||||||
|
|
||||||
struct FuseChipRegistersErista {
|
|
||||||
u32 _0x98[0x1A];
|
|
||||||
u32 FUSE_PRODUCTION_MODE;
|
u32 FUSE_PRODUCTION_MODE;
|
||||||
u32 FUSE_JTAG_SECUREID_VALID;
|
u32 FUSE_JTAG_SECUREID_VALID;
|
||||||
u32 FUSE_ODM_LOCK;
|
u32 FUSE_ODM_LOCK;
|
||||||
@@ -237,7 +87,7 @@ namespace ams::fuse {
|
|||||||
u32 FUSE_BOOT_DEVICE_INFO;
|
u32 FUSE_BOOT_DEVICE_INFO;
|
||||||
u32 FUSE_RESERVED_SW;
|
u32 FUSE_RESERVED_SW;
|
||||||
u32 FUSE_OPT_VP9_DISABLE;
|
u32 FUSE_OPT_VP9_DISABLE;
|
||||||
u32 FUSE_RESERVED_ODM_0[8 - 0];
|
u32 FUSE_RESERVED_ODM[0x8];
|
||||||
u32 FUSE_OBS_DIS;
|
u32 FUSE_OBS_DIS;
|
||||||
u32 FUSE_NOR_INFO;
|
u32 FUSE_NOR_INFO;
|
||||||
u32 FUSE_USB_CALIB;
|
u32 FUSE_USB_CALIB;
|
||||||
@@ -271,34 +121,34 @@ namespace ams::fuse {
|
|||||||
u32 FUSE_TSENSOR7_CALIB;
|
u32 FUSE_TSENSOR7_CALIB;
|
||||||
u32 FUSE_OPT_PRIV_SEC_EN;
|
u32 FUSE_OPT_PRIV_SEC_EN;
|
||||||
u32 FUSE_PKC_DISABLE;
|
u32 FUSE_PKC_DISABLE;
|
||||||
u32 _0x26C;
|
u32 _0x16C;
|
||||||
u32 _0x270;
|
u32 _0x170;
|
||||||
u32 _0x274;
|
u32 _0x174;
|
||||||
u32 _0x278;
|
u32 _0x178;
|
||||||
u32 FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
u32 FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
||||||
u32 FUSE_TSENSOR_COMMON;
|
u32 FUSE_TSENSOR_COMMON;
|
||||||
u32 FUSE_OPT_CP_BIN;
|
u32 FUSE_OPT_CP_BIN;
|
||||||
u32 FUSE_OPT_GPU_DISABLE;
|
u32 FUSE_OPT_GPU_DISABLE;
|
||||||
u32 FUSE_OPT_FT_BIN;
|
u32 FUSE_OPT_FT_BIN;
|
||||||
u32 FUSE_OPT_DONE_MAP;
|
u32 FUSE_OPT_DONE_MAP;
|
||||||
u32 _0x294;
|
u32 _0x194;
|
||||||
u32 FUSE_APB2JTAG_DISABLE;
|
u32 FUSE_APB2JTAG_DISABLE;
|
||||||
u32 FUSE_ODM_INFO;
|
u32 FUSE_ODM_INFO;
|
||||||
u32 _0x2A0;
|
u32 _0x1A0;
|
||||||
u32 _0x2A4;
|
u32 _0x1A4;
|
||||||
u32 FUSE_ARM_CRYPT_DE_FEATURE;
|
u32 FUSE_ARM_CRYPT_DE_FEATURE;
|
||||||
u32 _0x2AC;
|
u32 _0x1AC;
|
||||||
u32 _0x2B0;
|
u32 _0x1B0;
|
||||||
u32 _0x2B4;
|
u32 _0x1B4;
|
||||||
u32 _0x2B8;
|
u32 _0x1B8;
|
||||||
u32 _0x2BC;
|
u32 _0x1BC;
|
||||||
u32 FUSE_WOA_SKU_FLAG;
|
u32 FUSE_WOA_SKU_FLAG;
|
||||||
u32 FUSE_ECO_RESERVE_1;
|
u32 FUSE_ECO_RESERVE_1;
|
||||||
u32 FUSE_GCPLEX_CONFIG_FUSE;
|
u32 FUSE_GCPLEX_CONFIG_FUSE;
|
||||||
u32 FUSE_PRODUCTION_MONTH;
|
u32 FUSE_PRODUCTION_MONTH;
|
||||||
u32 FUSE_RAM_REPAIR_INDICATOR;
|
u32 FUSE_RAM_REPAIR_INDICATOR;
|
||||||
u32 FUSE_TSENSOR9_CALIB;
|
u32 FUSE_TSENSOR9_CALIB;
|
||||||
u32 _0x2D8;
|
u32 _0x1D8;
|
||||||
u32 FUSE_VMIN_CALIBRATION;
|
u32 FUSE_VMIN_CALIBRATION;
|
||||||
u32 FUSE_AGING_SENSOR_CALIBRATION;
|
u32 FUSE_AGING_SENSOR_CALIBRATION;
|
||||||
u32 FUSE_DEBUG_AUTHENTICATION;
|
u32 FUSE_DEBUG_AUTHENTICATION;
|
||||||
@@ -307,8 +157,8 @@ namespace ams::fuse {
|
|||||||
u32 FUSE_OPT_GPU_DISABLE_CP1;
|
u32 FUSE_OPT_GPU_DISABLE_CP1;
|
||||||
u32 FUSE_SPARE_ENDIS;
|
u32 FUSE_SPARE_ENDIS;
|
||||||
u32 FUSE_ECO_RESERVE_0;
|
u32 FUSE_ECO_RESERVE_0;
|
||||||
u32 _0x2FC;
|
u32 _0x1FC;
|
||||||
u32 _0x300;
|
u32 _0x200;
|
||||||
u32 FUSE_RESERVED_CALIB0;
|
u32 FUSE_RESERVED_CALIB0;
|
||||||
u32 FUSE_RESERVED_CALIB1;
|
u32 FUSE_RESERVED_CALIB1;
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE;
|
u32 FUSE_OPT_GPU_TPC0_DISABLE;
|
||||||
@@ -331,175 +181,23 @@ namespace ams::fuse {
|
|||||||
u32 FUSE_USB_CALIB_EXT;
|
u32 FUSE_USB_CALIB_EXT;
|
||||||
u32 FUSE_RESERVED_FIELD;
|
u32 FUSE_RESERVED_FIELD;
|
||||||
u32 FUSE_OPT_ECC_EN;
|
u32 FUSE_OPT_ECC_EN;
|
||||||
u32 _0x35C;
|
u32 _0x25C;
|
||||||
u32 _0x360;
|
u32 _0x260;
|
||||||
u32 _0x364;
|
u32 _0x264;
|
||||||
u32 _0x368;
|
u32 _0x268;
|
||||||
u32 _0x36C;
|
|
||||||
u32 _0x370;
|
|
||||||
u32 _0x374;
|
|
||||||
u32 _0x378;
|
|
||||||
u32 FUSE_SPARE_REALIGNMENT_REG;
|
|
||||||
u32 FUSE_SPARE_BIT[0x20];
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<FuseChipRegistersErista>::value);
|
|
||||||
static_assert(sizeof(FuseChipRegistersErista) == 0x400 - 0x98);
|
|
||||||
|
|
||||||
struct FuseChipRegistersMariko {
|
|
||||||
u32 FUSE_RESERVED_ODM_8[22 - 8];
|
|
||||||
u32 FUSE_KEK[4];
|
|
||||||
u32 FUSE_BEK[4];
|
|
||||||
u32 _0xF0[4];
|
|
||||||
u32 FUSE_PRODUCTION_MODE;
|
|
||||||
u32 FUSE_JTAG_SECUREID_VALID;
|
|
||||||
u32 FUSE_ODM_LOCK;
|
|
||||||
u32 FUSE_OPT_OPENGL_EN;
|
|
||||||
u32 FUSE_SKU_INFO;
|
|
||||||
u32 FUSE_CPU_SPEEDO_0_CALIB;
|
|
||||||
u32 FUSE_CPU_IDDQ_CALIB;
|
|
||||||
u32 FUSE_RESERVED_ODM_22[25 - 22];
|
|
||||||
u32 FUSE_OPT_FT_REV;
|
|
||||||
u32 FUSE_CPU_SPEEDO_1_CALIB;
|
|
||||||
u32 FUSE_CPU_SPEEDO_2_CALIB;
|
|
||||||
u32 FUSE_SOC_SPEEDO_0_CALIB;
|
|
||||||
u32 FUSE_SOC_SPEEDO_1_CALIB;
|
|
||||||
u32 FUSE_SOC_SPEEDO_2_CALIB;
|
|
||||||
u32 FUSE_SOC_IDDQ_CALIB;
|
|
||||||
u32 FUSE_RESERVED_ODM_25[26 - 25];
|
|
||||||
u32 FUSE_FA;
|
|
||||||
u32 FUSE_RESERVED_PRODUCTION;
|
|
||||||
u32 FUSE_HDMI_LANE0_CALIB;
|
|
||||||
u32 FUSE_HDMI_LANE1_CALIB;
|
|
||||||
u32 FUSE_HDMI_LANE2_CALIB;
|
|
||||||
u32 FUSE_HDMI_LANE3_CALIB;
|
|
||||||
u32 FUSE_ENCRYPTION_RATE;
|
|
||||||
u32 FUSE_PUBLIC_KEY[0x8];
|
|
||||||
u32 FUSE_TSENSOR1_CALIB;
|
|
||||||
u32 FUSE_TSENSOR2_CALIB;
|
|
||||||
u32 FUSE_OPT_SECURE_SCC_DIS;
|
|
||||||
u32 FUSE_OPT_CP_REV;
|
|
||||||
u32 FUSE_OPT_PFG;
|
|
||||||
u32 FUSE_TSENSOR0_CALIB;
|
|
||||||
u32 FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
|
||||||
u32 FUSE_SECURITY_MODE;
|
|
||||||
u32 FUSE_PRIVATE_KEY[0x5];
|
|
||||||
u32 FUSE_ARM_JTAG_DIS;
|
|
||||||
u32 FUSE_BOOT_DEVICE_INFO;
|
|
||||||
u32 FUSE_RESERVED_SW;
|
|
||||||
u32 FUSE_OPT_VP9_DISABLE;
|
|
||||||
u32 FUSE_RESERVED_ODM_0[8 - 0];
|
|
||||||
u32 FUSE_OBS_DIS;
|
|
||||||
u32 _0x1EC;
|
|
||||||
u32 FUSE_USB_CALIB;
|
|
||||||
u32 FUSE_SKU_DIRECT_CONFIG;
|
|
||||||
u32 FUSE_KFUSE_PRIVKEY_CTRL;
|
|
||||||
u32 FUSE_PACKAGE_INFO;
|
|
||||||
u32 FUSE_OPT_VENDOR_CODE;
|
|
||||||
u32 FUSE_OPT_FAB_CODE;
|
|
||||||
u32 FUSE_OPT_LOT_CODE_0;
|
|
||||||
u32 FUSE_OPT_LOT_CODE_1;
|
|
||||||
u32 FUSE_OPT_WAFER_ID;
|
|
||||||
u32 FUSE_OPT_X_COORDINATE;
|
|
||||||
u32 FUSE_OPT_Y_COORDINATE;
|
|
||||||
u32 FUSE_OPT_SEC_DEBUG_EN;
|
|
||||||
u32 FUSE_OPT_OPS_RESERVED;
|
|
||||||
u32 _0x224;
|
|
||||||
u32 FUSE_GPU_IDDQ_CALIB;
|
|
||||||
u32 FUSE_TSENSOR3_CALIB;
|
|
||||||
u32 FUSE_CLOCK_BONDOUT0;
|
|
||||||
u32 FUSE_CLOCK_BONDOUT1;
|
|
||||||
u32 FUSE_RESERVED_ODM_26[29 - 26];
|
|
||||||
u32 FUSE_OPT_SAMPLE_TYPE;
|
|
||||||
u32 FUSE_OPT_SUBREVISION;
|
|
||||||
u32 FUSE_OPT_SW_RESERVED_0;
|
|
||||||
u32 FUSE_OPT_SW_RESERVED_1;
|
|
||||||
u32 FUSE_TSENSOR4_CALIB;
|
|
||||||
u32 FUSE_TSENSOR5_CALIB;
|
|
||||||
u32 FUSE_TSENSOR6_CALIB;
|
|
||||||
u32 FUSE_TSENSOR7_CALIB;
|
|
||||||
u32 FUSE_OPT_PRIV_SEC_EN;
|
|
||||||
u32 FUSE_BOOT_SECURITY_INFO;
|
|
||||||
u32 _0x26C;
|
u32 _0x26C;
|
||||||
u32 _0x270;
|
u32 _0x270;
|
||||||
u32 _0x274;
|
u32 _0x274;
|
||||||
u32 _0x278;
|
u32 _0x278;
|
||||||
u32 FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
|
||||||
u32 FUSE_TSENSOR_COMMON;
|
|
||||||
u32 FUSE_OPT_CP_BIN;
|
|
||||||
u32 FUSE_OPT_GPU_DISABLE;
|
|
||||||
u32 FUSE_OPT_FT_BIN;
|
|
||||||
u32 FUSE_OPT_DONE_MAP;
|
|
||||||
u32 FUSE_RESERVED_ODM_29[30 - 29];
|
|
||||||
u32 FUSE_APB2JTAG_DISABLE;
|
|
||||||
u32 FUSE_ODM_INFO;
|
|
||||||
u32 _0x2A0;
|
|
||||||
u32 _0x2A4;
|
|
||||||
u32 FUSE_ARM_CRYPT_DE_FEATURE;
|
|
||||||
u32 _0x2AC;
|
|
||||||
u32 _0x2B0;
|
|
||||||
u32 _0x2B4;
|
|
||||||
u32 _0x2B8;
|
|
||||||
u32 _0x2BC;
|
|
||||||
u32 FUSE_WOA_SKU_FLAG;
|
|
||||||
u32 FUSE_ECO_RESERVE_1;
|
|
||||||
u32 FUSE_GCPLEX_CONFIG_FUSE;
|
|
||||||
u32 FUSE_PRODUCTION_MONTH;
|
|
||||||
u32 FUSE_RAM_REPAIR_INDICATOR;
|
|
||||||
u32 FUSE_TSENSOR9_CALIB;
|
|
||||||
u32 _0x2D8;
|
|
||||||
u32 FUSE_VMIN_CALIBRATION;
|
|
||||||
u32 FUSE_AGING_SENSOR_CALIBRATION;
|
|
||||||
u32 FUSE_DEBUG_AUTHENTICATION;
|
|
||||||
u32 FUSE_SECURE_PROVISION_INDEX;
|
|
||||||
u32 FUSE_SECURE_PROVISION_INFO;
|
|
||||||
u32 FUSE_OPT_GPU_DISABLE_CP1;
|
|
||||||
u32 FUSE_SPARE_ENDIS;
|
|
||||||
u32 FUSE_ECO_RESERVE_0;
|
|
||||||
u32 _0x2FC;
|
|
||||||
u32 _0x300;
|
|
||||||
u32 FUSE_RESERVED_CALIB0;
|
|
||||||
u32 FUSE_RESERVED_CALIB1;
|
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE;
|
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
|
||||||
u32 FUSE_OPT_CPU_DISABLE;
|
|
||||||
u32 FUSE_OPT_CPU_DISABLE_CP1;
|
|
||||||
u32 FUSE_TSENSOR10_CALIB;
|
|
||||||
u32 FUSE_TSENSOR10_CALIB_AUX;
|
|
||||||
u32 _0x324;
|
|
||||||
u32 _0x328;
|
|
||||||
u32 _0x32C;
|
|
||||||
u32 _0x330;
|
|
||||||
u32 _0x334;
|
|
||||||
u32 FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
|
||||||
u32 FUSE_OPT_GPU_TPC1_DISABLE;
|
|
||||||
u32 FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
|
||||||
u32 FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
|
||||||
u32 FUSE_OPT_CPU_DISABLE_CP2;
|
|
||||||
u32 FUSE_OPT_GPU_DISABLE_CP2;
|
|
||||||
u32 FUSE_USB_CALIB_EXT;
|
|
||||||
u32 FUSE_RESERVED_FIELD;
|
|
||||||
u32 _0x358;
|
|
||||||
u32 _0x35C;
|
|
||||||
u32 _0x360;
|
|
||||||
u32 _0x364;
|
|
||||||
u32 _0x368;
|
|
||||||
u32 _0x36C;
|
|
||||||
u32 _0x370;
|
|
||||||
u32 _0x374;
|
|
||||||
u32 _0x378;
|
|
||||||
u32 FUSE_SPARE_REALIGNMENT_REG;
|
u32 FUSE_SPARE_REALIGNMENT_REG;
|
||||||
u32 FUSE_SPARE_BIT[0x20];
|
u32 FUSE_SPARE_BIT[0x20];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<FuseChipRegistersMariko>::value);
|
static_assert(util::is_pod<FuseChipRegisters>::value);
|
||||||
static_assert(sizeof(FuseChipRegistersMariko) == 0x400 - 0x98);
|
static_assert(sizeof(FuseChipRegisters) == 0x300);
|
||||||
|
|
||||||
struct FuseRegisterRegion {
|
struct FuseRegisterRegion {
|
||||||
FuseRegisters fuse;
|
FuseRegisters fuse;
|
||||||
union {
|
FuseChipRegisters chip;
|
||||||
FuseChipRegistersCommon chip_common;
|
|
||||||
FuseChipRegistersErista chip_erista;
|
|
||||||
FuseChipRegistersMariko chip_mariko;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<FuseRegisterRegion>::value);
|
static_assert(util::is_pod<FuseRegisterRegion>::value);
|
||||||
static_assert(sizeof(FuseRegisterRegion) == secmon::MemoryRegionPhysicalDeviceFuses.GetSize());
|
static_assert(sizeof(FuseRegisterRegion) == secmon::MemoryRegionPhysicalDeviceFuses.GetSize());
|
||||||
|
|||||||
@@ -362,29 +362,22 @@ namespace ams::se {
|
|||||||
StartOperationRaw(SE, SE_OPERATION_OP_START, out_ll_address, in_ll_address);
|
StartOperationRaw(SE, SE_OPERATION_OP_START, out_ll_address, in_ll_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearAesKeySlot(volatile SecurityEngineRegisters *SE, int slot) {
|
|
||||||
/* Validate the key slot. */
|
|
||||||
AMS_ABORT_UNLESS(0 <= slot && slot < AesKeySlotCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
/* Select the keyslot. */
|
|
||||||
reg::Write(SE->SE_CRYPTO_KEYTABLE_ADDR, SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_KEY_SLOT, slot), SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_WORD, i));
|
|
||||||
|
|
||||||
/* Write the data. */
|
|
||||||
SE->SE_CRYPTO_KEYTABLE_DATA = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearAesKeySlot(int slot) {
|
void ClearAesKeySlot(int slot) {
|
||||||
/* Clear the slot in SE1. */
|
/* Validate the key slot. */
|
||||||
ClearAesKeySlot(GetRegisters(), slot);
|
AMS_ABORT_UNLESS(0 <= slot && slot < AesKeySlotCount);
|
||||||
}
|
|
||||||
|
|
||||||
void ClearAesKeySlot2(int slot) {
|
/* Get the engine. */
|
||||||
/* Clear the slot in SE2. */
|
auto *SE = GetRegisters();
|
||||||
ClearAesKeySlot(GetRegisters2(), slot);
|
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
/* Select the keyslot. */
|
||||||
|
reg::Write(SE->SE_CRYPTO_KEYTABLE_ADDR, SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_KEY_SLOT, slot), SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_WORD, i));
|
||||||
|
|
||||||
|
/* Write the data. */
|
||||||
|
SE->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearAesKeyIv(int slot) {
|
void ClearAesKeyIv(int slot) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
namespace ams::se {
|
namespace ams::se {
|
||||||
|
|
||||||
volatile SecurityEngineRegisters *GetRegisters();
|
volatile SecurityEngineRegisters *GetRegisters();
|
||||||
volatile SecurityEngineRegisters *GetRegisters2();
|
|
||||||
|
|
||||||
void ExecuteOperation(volatile SecurityEngineRegisters *SE, SE_OPERATION_OP op, void *dst, size_t dst_size, const void *src, size_t src_size);
|
void ExecuteOperation(volatile SecurityEngineRegisters *SE, SE_OPERATION_OP op, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
void ExecuteOperationSingleBlock(volatile SecurityEngineRegisters *SE, void *dst, size_t dst_size, const void *src, size_t src_size);
|
void ExecuteOperationSingleBlock(volatile SecurityEngineRegisters *SE, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
|
|||||||
@@ -20,35 +20,17 @@ namespace ams::se {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constinit uintptr_t g_register_address = secmon::MemoryRegionPhysicalDeviceSecurityEngine.GetAddress();
|
constinit uintptr_t g_register_address = secmon::MemoryRegionPhysicalDeviceSecurityEngine.GetAddress();
|
||||||
constinit uintptr_t g_register2_address = secmon::MemoryRegionPhysicalDeviceSecurityEngine2.GetAddress();
|
|
||||||
constinit DoneHandler g_done_handler = nullptr;
|
constinit DoneHandler g_done_handler = nullptr;
|
||||||
|
|
||||||
void SetSecure(volatile SecurityEngineRegisters *SE, bool secure) {
|
|
||||||
/* Set the security software setting. */
|
|
||||||
if (secure) {
|
|
||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, SECURE));
|
|
||||||
} else {
|
|
||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, NONSECURE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the status register to force an update. */
|
|
||||||
reg::Read(SE->SE_SE_SECURITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile SecurityEngineRegisters *GetRegisters() {
|
volatile SecurityEngineRegisters *GetRegisters() {
|
||||||
return reinterpret_cast<volatile SecurityEngineRegisters *>(g_register_address);
|
return reinterpret_cast<volatile SecurityEngineRegisters *>(g_register_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile SecurityEngineRegisters *GetRegisters2() {
|
void SetRegisterAddress(uintptr_t address) {
|
||||||
return reinterpret_cast<volatile SecurityEngineRegisters *>(g_register2_address);
|
g_register_address = address;
|
||||||
}
|
|
||||||
|
|
||||||
void SetRegisterAddress(uintptr_t address, uintptr_t address2) {
|
|
||||||
g_register_address = address;
|
|
||||||
g_register2_address = address2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
@@ -57,13 +39,17 @@ namespace ams::se {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetSecure(bool secure) {
|
void SetSecure(bool secure) {
|
||||||
/* Set security for SE1. */
|
auto *SE = GetRegisters();
|
||||||
SetSecure(GetRegisters(), secure);
|
|
||||||
|
|
||||||
/* If SE2 is present, set security for SE2. */
|
/* Set the security software setting. */
|
||||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
if (secure) {
|
||||||
SetSecure(GetRegisters2(), secure);
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, SECURE));
|
||||||
|
} else {
|
||||||
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, NONSECURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read the status register to force an update. */
|
||||||
|
reg::Read(SE->SE_SE_SECURITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTzramSecure() {
|
void SetTzramSecure() {
|
||||||
@@ -80,18 +66,6 @@ namespace ams::se {
|
|||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_PERKEY_SETTING, SECURE));
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_PERKEY_SETTING, SECURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetContextSaveSecure() {
|
|
||||||
/* Context save lock to trustzone secure is only available on mariko. */
|
|
||||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
|
||||||
auto *SE = GetRegisters();
|
|
||||||
auto *SE2 = GetRegisters2();
|
|
||||||
|
|
||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_CTX_SAVE_TZ_LOCK, SECURE));
|
|
||||||
reg::ReadWrite(SE2->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_CTX_SAVE_TZ_LOCK, SECURE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lockout() {
|
void Lockout() {
|
||||||
auto *SE = GetRegisters();
|
auto *SE = GetRegisters();
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ namespace ams::se {
|
|||||||
u32 SE_OUT_CUR_LL_ID;
|
u32 SE_OUT_CUR_LL_ID;
|
||||||
u32 SE_HASH_RESULT[0x10];
|
u32 SE_HASH_RESULT[0x10];
|
||||||
u32 SE_CTX_SAVE_CONFIG;
|
u32 SE_CTX_SAVE_CONFIG;
|
||||||
u32 SE_CTX_SAVE_AUTO;
|
u32 _0x74[0x63];
|
||||||
u32 _0x78[0x62];
|
|
||||||
u32 SE_SHA_CONFIG;
|
u32 SE_SHA_CONFIG;
|
||||||
u32 SE_SHA_MSG_LENGTH[0x4];
|
u32 SE_SHA_MSG_LENGTH[0x4];
|
||||||
u32 SE_SHA_MSG_LEFT[0x4];
|
u32 SE_SHA_MSG_LEFT[0x4];
|
||||||
@@ -62,9 +61,7 @@ namespace ams::se {
|
|||||||
u32 SE_RSA_KEYTABLE_ADDR;
|
u32 SE_RSA_KEYTABLE_ADDR;
|
||||||
u32 SE_RSA_KEYTABLE_DATA;
|
u32 SE_RSA_KEYTABLE_DATA;
|
||||||
u32 SE_RSA_OUTPUT[0x40];
|
u32 SE_RSA_OUTPUT[0x40];
|
||||||
u32 _0x528[0x6];
|
u32 _0x528[0xB6];
|
||||||
u32 SE_TZRAM_OPERATION;
|
|
||||||
u32 _0x544[0xAF];
|
|
||||||
u32 SE_STATUS;
|
u32 SE_STATUS;
|
||||||
u32 SE_ERR_STATUS;
|
u32 SE_ERR_STATUS;
|
||||||
u32 SE_MISC;
|
u32 SE_MISC;
|
||||||
@@ -103,26 +100,17 @@ namespace ams::se {
|
|||||||
|
|
||||||
/* SE_STATUS. */
|
/* SE_STATUS. */
|
||||||
DEFINE_SE_REG_TWO_BIT_ENUM(STATUS_STATE, 0, IDLE, BUSY, WAIT_OUT, WAIT_IN);
|
DEFINE_SE_REG_TWO_BIT_ENUM(STATUS_STATE, 0, IDLE, BUSY, WAIT_OUT, WAIT_IN);
|
||||||
DEFINE_SE_REG_BIT_ENUM(STATUS_MEM_INTERFACE, 2, IDLE, BUSY);
|
|
||||||
|
|
||||||
/* SE_SECURITY */
|
/* SE_SECURITY */
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_HARD_SETTING, 0, SECURE, NONSECURE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_HARD_SETTING, 0, SECURE, NONSECURE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_ENG_DIS, 1, DISABLE, ENABLE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_ENG_DIS, 1, DISABLE, ENABLE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_PERKEY_SETTING, 2, SECURE, NONSECURE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_PERKEY_SETTING, 2, SECURE, NONSECURE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_CTX_SAVE_TZ_LOCK, 4, SECURE, NONSECURE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_SOFT_SETTING, 16, SECURE, NONSECURE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_CTX_TZ_LOCK_SOFT, 5, SECURE, NONSECURE);
|
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_SOFT_SETTING, 16, SECURE, NONSECURE);
|
|
||||||
|
|
||||||
/* SE_TZRAM_SECURITY */
|
/* SE_TZRAM_SECURITY */
|
||||||
DEFINE_SE_REG(TZRAM_SETTING, 0, BITSIZEOF(u32));
|
DEFINE_SE_REG(TZRAM_SETTING, 0, BITSIZEOF(u32));
|
||||||
constexpr inline u32 SE_TZRAM_SETTING_SECURE = 0;
|
constexpr inline u32 SE_TZRAM_SETTING_SECURE = 0;
|
||||||
|
|
||||||
/* SE_TZRAM_OPERATION */
|
|
||||||
DEFINE_SE_REG_BIT_ENUM(TZRAM_OPERATION_REQ, 0, IDLE, INITIATE);
|
|
||||||
DEFINE_SE_REG_BIT_ENUM(TZRAM_OPERATION_MODE, 1, SAVE, RESTORE);
|
|
||||||
DEFINE_SE_REG_BIT_ENUM(TZRAM_OPERATION_BUSY, 2, NO, YES);
|
|
||||||
DEFINE_SE_REG(TZRAM_OPERATION_CURR_ADDR, 16, 16);
|
|
||||||
|
|
||||||
/* SE_OPERATION */
|
/* SE_OPERATION */
|
||||||
DEFINE_SE_REG_THREE_BIT_ENUM(OPERATION_OP, 0, ABORT, START, RESTART_OUT, CTX_SAVE, RESTART_IN, RESERVED_5, RESERVED_6, RESERVED_7);
|
DEFINE_SE_REG_THREE_BIT_ENUM(OPERATION_OP, 0, ABORT, START, RESTART_OUT, CTX_SAVE, RESTART_IN, RESERVED_5, RESERVED_6, RESERVED_7);
|
||||||
|
|
||||||
@@ -180,11 +168,6 @@ namespace ams::se {
|
|||||||
DEFINE_SE_REG_BIT_ENUM(CTX_SAVE_CONFIG_STICKY_WORD_QUAD, 24, WORDS_0_3, WORDS_4_7);
|
DEFINE_SE_REG_BIT_ENUM(CTX_SAVE_CONFIG_STICKY_WORD_QUAD, 24, WORDS_0_3, WORDS_4_7);
|
||||||
DEFINE_SE_REG_THREE_BIT_ENUM(CTX_SAVE_CONFIG_SRC, 29, STICKY_BITS, RSA_KEYTABLE, AES_KEYTABLE, PKA1_STICKY_BITS, MEM, RESERVED5, SRK, PKA1_KEYTABLE);
|
DEFINE_SE_REG_THREE_BIT_ENUM(CTX_SAVE_CONFIG_SRC, 29, STICKY_BITS, RSA_KEYTABLE, AES_KEYTABLE, PKA1_STICKY_BITS, MEM, RESERVED5, SRK, PKA1_KEYTABLE);
|
||||||
|
|
||||||
/* SE_CTX_SAVE_AUTO */
|
|
||||||
DEFINE_SE_REG_BIT_ENUM(CTX_SAVE_AUTO_ENABLE, 0, NO, YES);
|
|
||||||
DEFINE_SE_REG_BIT_ENUM(CTX_SAVE_AUTO_LOCK, 8, NO, YES);
|
|
||||||
DEFINE_SE_REG(CTX_SAVE_AUTO_CURR_CNT, 16, 10);
|
|
||||||
|
|
||||||
/* SE_SHA_CONFIG */
|
/* SE_SHA_CONFIG */
|
||||||
DEFINE_SE_REG(SHA_CONFIG_HW_INIT_HASH, 0, 1);
|
DEFINE_SE_REG(SHA_CONFIG_HW_INIT_HASH, 0, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -44,50 +44,31 @@ namespace ams::se {
|
|||||||
reg::Write(SE->SE_RNG_CONFIG, SE_REG_BITS_ENUM(RNG_CONFIG_SRC, ENTROPY), SE_REG_BITS_VALUE(RNG_CONFIG_MODE, mode));
|
reg::Write(SE->SE_RNG_CONFIG, SE_REG_BITS_ENUM(RNG_CONFIG_SRC, ENTROPY), SE_REG_BITS_VALUE(RNG_CONFIG_MODE, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeRandom(volatile SecurityEngineRegisters *SE) {
|
|
||||||
/* Lock the entropy source. */
|
|
||||||
reg::Write(SE->SE_RNG_SRC_CONFIG, SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE, ENABLE),
|
|
||||||
SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE_LOCK, ENABLE));
|
|
||||||
|
|
||||||
/* Set the reseed interval to force a reseed every 70000 blocks. */
|
|
||||||
SE->SE_RNG_RESEED_INTERVAL = RngReseedInterval;
|
|
||||||
|
|
||||||
/* Initialize the DRBG. */
|
|
||||||
{
|
|
||||||
u8 dummy_buf[AesBlockSize];
|
|
||||||
|
|
||||||
/* Configure the engine to force drbg instantiation by writing random to memory. */
|
|
||||||
ConfigRng(SE, SE_CONFIG_DST_MEMORY, SE_RNG_CONFIG_MODE_FORCE_INSTANTIATION);
|
|
||||||
|
|
||||||
/* Configure to do a single RNG block operation to trigger DRBG init. */
|
|
||||||
SE->SE_CRYPTO_LAST_BLOCK = 0;
|
|
||||||
|
|
||||||
/* Execute the operation. */
|
|
||||||
ExecuteOperation(SE, SE_OPERATION_OP_START, dummy_buf, sizeof(dummy_buf), nullptr, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateSrk(volatile SecurityEngineRegisters *SE) {
|
|
||||||
/* Configure the RNG to output to SRK and force a reseed. */
|
|
||||||
ConfigRng(SE, SE_CONFIG_DST_SRK, SE_RNG_CONFIG_MODE_FORCE_RESEED);
|
|
||||||
|
|
||||||
/* Configure a single block operation. */
|
|
||||||
SE->SE_CRYPTO_LAST_BLOCK = 0;
|
|
||||||
|
|
||||||
/* Execute the operation. */
|
|
||||||
ExecuteOperation(SE, SE_OPERATION_OP_START, nullptr, 0, nullptr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeRandom() {
|
void InitializeRandom() {
|
||||||
/* Initialize random for SE1. */
|
/* Get the engine. */
|
||||||
InitializeRandom(GetRegisters());
|
auto *SE = GetRegisters();
|
||||||
|
|
||||||
/* If we have SE2, initialize random for SE2. */
|
/* Lock the entropy source. */
|
||||||
/* NOTE: Nintendo's implementation of this is incorrect. */
|
reg::Write(SE->SE_RNG_SRC_CONFIG, SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE, ENABLE),
|
||||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE_LOCK, ENABLE));
|
||||||
InitializeRandom(GetRegisters2());
|
|
||||||
|
/* Set the reseed interval to force a reseed every 70000 blocks. */
|
||||||
|
SE->SE_RNG_RESEED_INTERVAL = RngReseedInterval;
|
||||||
|
|
||||||
|
/* Initialize the DRBG. */
|
||||||
|
{
|
||||||
|
u8 dummy_buf[AesBlockSize];
|
||||||
|
|
||||||
|
/* Configure the engine to force drbg instantiation by writing random to memory. */
|
||||||
|
ConfigRng(SE, SE_CONFIG_DST_MEMORY, SE_RNG_CONFIG_MODE_FORCE_INSTANTIATION);
|
||||||
|
|
||||||
|
/* Configure to do a single RNG block operation to trigger DRBG init. */
|
||||||
|
SE->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
|
|
||||||
|
/* Execute the operation. */
|
||||||
|
ExecuteOperation(SE, SE_OPERATION_OP_START, dummy_buf, sizeof(dummy_buf), nullptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,14 +130,17 @@ namespace ams::se {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenerateSrk() {
|
void GenerateSrk() {
|
||||||
/* Generate SRK for SE1. */
|
/* Get the engine. */
|
||||||
GenerateSrk(GetRegisters());
|
auto *SE = GetRegisters();
|
||||||
|
|
||||||
/* If we have SE2, generate SRK for SE2. */
|
/* Configure the RNG to output to SRK and force a reseed. */
|
||||||
/* NOTE: Nintendo's implementation of this is incorrect. */
|
ConfigRng(SE, SE_CONFIG_DST_SRK, SE_RNG_CONFIG_MODE_FORCE_RESEED);
|
||||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
|
||||||
GenerateSrk(GetRegisters2());
|
/* Configure a single block operation. */
|
||||||
}
|
SE->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
|
|
||||||
|
/* Execute the operation. */
|
||||||
|
ExecuteOperation(SE, SE_OPERATION_OP_START, nullptr, 0, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ namespace ams::se {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr inline size_t SE1ContextSaveOperationCount = 133;
|
|
||||||
constexpr inline size_t SE2ContextSaveOperationCount = 646;
|
|
||||||
static_assert(((SE1ContextSaveOperationCount - 2) + 1) * se::AesBlockSize == sizeof(se::Context));
|
|
||||||
|
|
||||||
constinit const u8 FixedPattern[AesBlockSize] = {
|
constinit const u8 FixedPattern[AesBlockSize] = {
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||||
};
|
};
|
||||||
@@ -68,44 +64,6 @@ namespace ams::se {
|
|||||||
ExecuteContextSaveOperation(SE, dst, AesBlockSize, nullptr, 0);
|
ExecuteContextSaveOperation(SE, dst, AesBlockSize, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureForAutomaticContextSave(volatile SecurityEngineRegisters *SE) {
|
|
||||||
/* Configure the engine to do RNG encryption. */
|
|
||||||
reg::Write(SE->SE_CONFIG, SE_REG_BITS_ENUM(CONFIG_ENC_MODE, AESMODE_KEY128),
|
|
||||||
SE_REG_BITS_ENUM(CONFIG_DEC_MODE, AESMODE_KEY128),
|
|
||||||
SE_REG_BITS_ENUM(CONFIG_ENC_ALG, RNG),
|
|
||||||
SE_REG_BITS_ENUM(CONFIG_DEC_ALG, NOP),
|
|
||||||
SE_REG_BITS_ENUM(CONFIG_DST, MEMORY));
|
|
||||||
|
|
||||||
reg::Write(SE->SE_CRYPTO_CONFIG, SE_REG_BITS_ENUM (CRYPTO_CONFIG_MEMIF, AHB),
|
|
||||||
SE_REG_BITS_VALUE(CRYPTO_CONFIG_CTR_CNTN, 0),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_KEYSCH_BYPASS, DISABLE),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_CORE_SEL, ENCRYPT),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_IV_SELECT, ORIGINAL),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_VCTRAM_SEL, MEMORY),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_INPUT_SEL, RANDOM),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_XOR_POS, BYPASS),
|
|
||||||
SE_REG_BITS_ENUM (CRYPTO_CONFIG_HASH_ENB, DISABLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WaitAutomaticContextSaveDone(volatile SecurityEngineRegisters *SE) {
|
|
||||||
/* Wait for operation. */
|
|
||||||
while (!reg::HasValue(SE->SE_INT_STATUS, SE_REG_BITS_ENUM(INT_STATUS_SE_OP_DONE, ACTIVE))) { /* ... */ }
|
|
||||||
|
|
||||||
/* Wait for the engine to be idle. */
|
|
||||||
while (!reg::HasValue(SE->SE_STATUS, SE_REG_BITS_ENUM(STATUS_STATE, IDLE))) { /* ... */ }
|
|
||||||
|
|
||||||
/* Wait for the memory interface to be idle. */
|
|
||||||
while (!reg::HasValue(SE->SE_STATUS, SE_REG_BITS_ENUM(STATUS_MEM_INTERFACE, IDLE))) { /* ... */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValidateErrStatus(volatile SecurityEngineRegisters *SE) {
|
|
||||||
/* Ensure there is no error status. */
|
|
||||||
AMS_ABORT_UNLESS(reg::Read(SE->SE_ERR_STATUS) == 0);
|
|
||||||
|
|
||||||
/* Ensure no error occurred. */
|
|
||||||
AMS_ABORT_UNLESS(reg::HasValue(SE->SE_INT_STATUS, SE_REG_BITS_ENUM(INT_STATUS_ERR_STAT, CLEAR)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidateStickyBits(const StickyBits &bits) {
|
bool ValidateStickyBits(const StickyBits &bits) {
|
||||||
@@ -279,76 +237,15 @@ namespace ams::se {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAutomaticContextSave() {
|
|
||||||
/* Get registers. */
|
|
||||||
auto *SE = GetRegisters();
|
|
||||||
auto *SE2 = GetRegisters2();
|
|
||||||
|
|
||||||
/* Automatic context save is supported only on mariko. */
|
|
||||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
|
||||||
/* Configure SE1 to do automatic context save. */
|
|
||||||
reg::Write(SE->SE_CTX_SAVE_AUTO, SE_REG_BITS_ENUM(CTX_SAVE_AUTO_ENABLE, YES),
|
|
||||||
SE_REG_BITS_ENUM(CTX_SAVE_AUTO_LOCK, YES));
|
|
||||||
|
|
||||||
/* Configure SE2 to do automatic context save. */
|
|
||||||
reg::Write(SE2->SE_CTX_SAVE_AUTO, SE_REG_BITS_ENUM(CTX_SAVE_AUTO_ENABLE, YES),
|
|
||||||
SE_REG_BITS_ENUM(CTX_SAVE_AUTO_LOCK, YES));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveContextAutomatic() {
|
|
||||||
/* Get registers. */
|
|
||||||
auto *SE = GetRegisters();
|
|
||||||
auto *SE2 = GetRegisters2();
|
|
||||||
|
|
||||||
/* Ensure there's no error status before or after we save context. */
|
|
||||||
ValidateErrStatus();
|
|
||||||
ON_SCOPE_EXIT { ValidateErrStatus(); };
|
|
||||||
|
|
||||||
/* Perform atomic context save. */
|
|
||||||
{
|
|
||||||
/* Check that context save has not already been performed. */
|
|
||||||
AMS_ABORT_UNLESS(reg::HasValue(SE->SE_CTX_SAVE_AUTO, SE_REG_BITS_VALUE(CTX_SAVE_AUTO_CURR_CNT, 0)));
|
|
||||||
AMS_ABORT_UNLESS(reg::HasValue(SE2->SE_CTX_SAVE_AUTO, SE_REG_BITS_VALUE(CTX_SAVE_AUTO_CURR_CNT, 0)));
|
|
||||||
|
|
||||||
/* Configure SE1 to do context save. */
|
|
||||||
ConfigureForAutomaticContextSave(SE);
|
|
||||||
ConfigureForAutomaticContextSave(SE2);
|
|
||||||
|
|
||||||
/* Start the context save operation. */
|
|
||||||
reg::Write(SE->SE_OPERATION, SE_REG_BITS_ENUM(OPERATION_OP, CTX_SAVE));
|
|
||||||
reg::Write(SE2->SE_OPERATION, SE_REG_BITS_ENUM(OPERATION_OP, CTX_SAVE));
|
|
||||||
|
|
||||||
/* Wait for the context save operation to complete. */
|
|
||||||
WaitAutomaticContextSaveDone(SE);
|
|
||||||
WaitAutomaticContextSaveDone(SE2);
|
|
||||||
|
|
||||||
/* Check that the correct sizes were written. */
|
|
||||||
AMS_ABORT_UNLESS(reg::HasValue(SE->SE_CTX_SAVE_AUTO, SE_REG_BITS_VALUE(CTX_SAVE_AUTO_CURR_CNT, SE1ContextSaveOperationCount)));
|
|
||||||
AMS_ABORT_UNLESS(reg::HasValue(SE2->SE_CTX_SAVE_AUTO, SE_REG_BITS_VALUE(CTX_SAVE_AUTO_CURR_CNT, SE2ContextSaveOperationCount)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveTzramAutomatic() {
|
|
||||||
/* Get registers. */
|
|
||||||
auto *SE = GetRegisters();
|
|
||||||
|
|
||||||
/* Begin save-to-shadow-tzram operation. */
|
|
||||||
reg::Write(SE->SE_TZRAM_OPERATION, SE_REG_BITS_ENUM(TZRAM_OPERATION_MODE, SAVE),
|
|
||||||
SE_REG_BITS_ENUM(TZRAM_OPERATION_REQ, INITIATE));
|
|
||||||
|
|
||||||
/* Wait for operation to complete. */
|
|
||||||
while (reg::HasValue(SE->SE_TZRAM_OPERATION, SE_REG_BITS_ENUM(TZRAM_OPERATION_BUSY, YES))) { /* ... */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValidateErrStatus() {
|
void ValidateErrStatus() {
|
||||||
/* Ensure SE has no error status. */
|
/* Get the registers. */
|
||||||
ValidateErrStatus(GetRegisters());
|
auto *SE = GetRegisters();
|
||||||
|
|
||||||
/* If on mariko, ensure SE2 has no error status. */
|
/* Ensure there is no error status. */
|
||||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
AMS_ABORT_UNLESS(reg::Read(SE->SE_ERR_STATUS) == 0);
|
||||||
ValidateErrStatus(GetRegisters2());
|
|
||||||
}
|
/* Ensure no error occurred. */
|
||||||
|
AMS_ABORT_UNLESS(reg::HasValue(SE->SE_INT_STATUS, SE_REG_BITS_ENUM(INT_STATUS_ERR_STAT, CLEAR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ dist: dist-src dist-bin
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
@rm -fr release lib *.bz2 include/stratosphere.hpp.gch
|
@rm -fr release lib *.bz2
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
else
|
else
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d) $(GCH_FILES:.gch=.d)
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
# main targets
|
||||||
|
|||||||
@@ -16,13 +16,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere/fs/fs_common.hpp>
|
#include <stratosphere/fs/fs_common.hpp>
|
||||||
#include <stratosphere/fs/impl/fs_result_utils.hpp>
|
|
||||||
#include <stratosphere/fs/fs_context.hpp>
|
|
||||||
#include <stratosphere/fs/fs_result_config.hpp>
|
|
||||||
#include <stratosphere/fs/fs_storage_type.hpp>
|
#include <stratosphere/fs/fs_storage_type.hpp>
|
||||||
#include <stratosphere/fs/fs_priority.hpp>
|
|
||||||
#include <stratosphere/fs/impl/fs_priority_utils.hpp>
|
|
||||||
#include <stratosphere/fs/fs_access_log.hpp>
|
|
||||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||||
@@ -60,4 +54,3 @@
|
|||||||
#include <stratosphere/fs/fs_sd_card.hpp>
|
#include <stratosphere/fs/fs_sd_card.hpp>
|
||||||
#include <stratosphere/fs/fs_signed_system_partition.hpp>
|
#include <stratosphere/fs/fs_signed_system_partition.hpp>
|
||||||
#include <stratosphere/fs/fs_system_data.hpp>
|
#include <stratosphere/fs/fs_system_data.hpp>
|
||||||
#include <stratosphere/fs/impl/fs_access_log_impl.hpp>
|
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
enum AccessLogMode : u32 {
|
|
||||||
AccessLogMode_None = 0,
|
|
||||||
AccessLogMode_Log = 1,
|
|
||||||
AccessLogMode_SdCard = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
Result GetGlobalAccessLogMode(u32 *out);
|
|
||||||
Result SetGlobalAccessLogMode(u32 mode);
|
|
||||||
|
|
||||||
void SetLocalAccessLog(bool enabled);
|
|
||||||
void SetLocalSystemAccessLogForDebug(bool enabled);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
enum class AbortSpecifier {
|
|
||||||
Default,
|
|
||||||
Abort,
|
|
||||||
Return,
|
|
||||||
};
|
|
||||||
|
|
||||||
using ResultHandler = AbortSpecifier (*)(Result);
|
|
||||||
|
|
||||||
class FsContext {
|
|
||||||
private:
|
|
||||||
ResultHandler handler;
|
|
||||||
public:
|
|
||||||
constexpr explicit FsContext(ResultHandler h) : handler(h) { /* ... */ }
|
|
||||||
|
|
||||||
constexpr void SetHandler(ResultHandler h) { this->handler = h; }
|
|
||||||
|
|
||||||
constexpr AbortSpecifier HandleResult(Result result) const { return this->handler(result); }
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetDefaultFsContextResultHandler(const ResultHandler handler);
|
|
||||||
|
|
||||||
const FsContext *GetCurrentThreadFsContext();
|
|
||||||
void SetCurrentThreadFsContext(const FsContext *context);
|
|
||||||
|
|
||||||
class ScopedFsContext {
|
|
||||||
private:
|
|
||||||
const FsContext * const prev_context;
|
|
||||||
public:
|
|
||||||
ALWAYS_INLINE ScopedFsContext(const FsContext &ctx) : prev_context(GetCurrentThreadFsContext()) {
|
|
||||||
SetCurrentThreadFsContext(std::addressof(ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE ~ScopedFsContext() {
|
|
||||||
SetCurrentThreadFsContext(this->prev_context);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ScopedAutoAbortDisabler {
|
|
||||||
private:
|
|
||||||
const FsContext * const prev_context;
|
|
||||||
public:
|
|
||||||
ScopedAutoAbortDisabler();
|
|
||||||
ALWAYS_INLINE ~ScopedAutoAbortDisabler() {
|
|
||||||
SetCurrentThreadFsContext(this->prev_context);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -53,6 +53,8 @@ namespace ams::fs {
|
|||||||
CreateOption_BigFile = ::FsCreateOption_BigFile,
|
CreateOption_BigFile = ::FsCreateOption_BigFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using FileTimeStampRaw = ::FsTimeStampRaw;
|
||||||
|
|
||||||
struct FileHandle;
|
struct FileHandle;
|
||||||
struct DirectoryHandle;
|
struct DirectoryHandle;
|
||||||
|
|
||||||
@@ -72,6 +74,7 @@ namespace ams::fs {
|
|||||||
Result GetTotalSpaceSize(s64 *out, const char *path);
|
Result GetTotalSpaceSize(s64 *out, const char *path);
|
||||||
|
|
||||||
Result SetConcatenationFileAttribute(const char *path);
|
Result SetConcatenationFileAttribute(const char *path);
|
||||||
|
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path);
|
||||||
|
|
||||||
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode);
|
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode);
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/fs/fs_common.hpp>
|
|
||||||
#include <stratosphere/fs/fs_filesystem.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
using FileTimeStampRaw = ::FsTimeStampRaw;
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
Result GetFileTimeStampRawForDebug(FileTimeStampRaw *out, const char *path);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetFileTimeStampRawForDebug(FileTimeStampRaw *out, const char *path);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -14,9 +14,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere/fs/fs_common.hpp>
|
#include "fs_common.hpp"
|
||||||
#include <stratosphere/fs/fs_filesystem.hpp>
|
#include "fs_filesystem.hpp"
|
||||||
#include <stratosphere/fs/fs_filesystem_for_debug.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
enum Priority {
|
|
||||||
Priority_Realtime = 0,
|
|
||||||
Priority_Normal = 1,
|
|
||||||
Priority_Low = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PriorityRaw {
|
|
||||||
PriorityRaw_Realtime = 0,
|
|
||||||
PriorityRaw_Normal = 1,
|
|
||||||
PriorityRaw_Low = 2,
|
|
||||||
PriorityRaw_Background = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
Priority GetPriorityOnCurrentThread();
|
|
||||||
Priority GetPriority(os::ThreadType *thread);
|
|
||||||
PriorityRaw GetPriorityRawOnCurrentThread();
|
|
||||||
PriorityRaw GetPriorityRaw(os::ThreadType *thread);
|
|
||||||
|
|
||||||
void SetPriorityOnCurrentThread(Priority prio);
|
|
||||||
void SetPriority(os::ThreadType *thread, Priority prio);
|
|
||||||
void SetPriorityRawOnCurrentThread(PriorityRaw prio);
|
|
||||||
void SetPriorityRaw(os::ThreadType *thread, PriorityRaw prio);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
void SetEnabledAutoAbort(bool enabled);
|
|
||||||
void SetResultHandledByApplication(bool application);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../fs_common.hpp"
|
#include "../fs_common.hpp"
|
||||||
#include "../fs_filesystem.hpp"
|
#include "../fs_filesystem.hpp"
|
||||||
#include "../fs_filesystem_for_debug.hpp"
|
|
||||||
|
|
||||||
namespace ams::fs::fsa {
|
namespace ams::fs::fsa {
|
||||||
|
|
||||||
|
|||||||
@@ -1,206 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
#include <stratosphere/fs/fs_access_log.hpp>
|
|
||||||
#include <stratosphere/fs/fs_directory.hpp>
|
|
||||||
#include <stratosphere/fs/fs_file.hpp>
|
|
||||||
#include <stratosphere/fs/fs_priority.hpp>
|
|
||||||
#include <stratosphere/os/os_tick.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs::impl {
|
|
||||||
|
|
||||||
enum AccessLogTarget : u32 {
|
|
||||||
AccessLogTarget_None = (0 << 0),
|
|
||||||
AccessLogTarget_Application = (1 << 0),
|
|
||||||
AccessLogTarget_System = (1 << 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IdentifyAccessLogHandle {
|
|
||||||
void *handle;
|
|
||||||
public:
|
|
||||||
static constexpr IdentifyAccessLogHandle MakeHandle(void *h) {
|
|
||||||
return IdentifyAccessLogHandle{h};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool IsEnabledAccessLog(u32 target);
|
|
||||||
bool IsEnabledAccessLog();
|
|
||||||
|
|
||||||
bool IsEnabledHandleAccessLog(fs::FileHandle handle);
|
|
||||||
bool IsEnabledHandleAccessLog(fs::DirectoryHandle handle);
|
|
||||||
bool IsEnabledHandleAccessLog(fs::impl::IdentifyAccessLogHandle handle);
|
|
||||||
bool IsEnabledHandleAccessLog(const void *handle);
|
|
||||||
|
|
||||||
bool IsEnabledFileSystemAccessorAccessLog(const char *mount_name);
|
|
||||||
void EnableFileSystemAccessorAccessLog(const char *mount_name);
|
|
||||||
|
|
||||||
using AccessLogPrinterCallback = int (*)(char *buffer, size_t buffer_size);
|
|
||||||
void RegisterStartAccessLogPrinterCallback(AccessLogPrinterCallback callback);
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::impl::IdentifyAccessLogHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
void OutputAccessLog(Result result, fs::Priority priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 7, 8)));
|
|
||||||
void OutputAccessLog(Result result, fs::PriorityRaw priority_raw, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 7, 8)));
|
|
||||||
|
|
||||||
void OutputAccessLogToOnlySdCard(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
|
||||||
|
|
||||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
|
||||||
|
|
||||||
class IdString {
|
|
||||||
private:
|
|
||||||
char buffer[0x20];
|
|
||||||
private:
|
|
||||||
const char *ToValueString(int id);
|
|
||||||
public:
|
|
||||||
template<typename T>
|
|
||||||
const char *ToString(T id);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> requires (requires { T{}; })
|
|
||||||
inline T DereferenceOutValue(T *out_value, Result result) {
|
|
||||||
if (R_SUCCEEDED(result) && out_value != nullptr) {
|
|
||||||
return *out_value;
|
|
||||||
} else {
|
|
||||||
return T{};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Access log result name. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME __tmp_ams_fs_access_log_result
|
|
||||||
/* Access log utils. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__VALUE__) ::ams::fs::impl::DereferenceOutValue(__VALUE__, AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME)
|
|
||||||
|
|
||||||
/* Access log components. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE ", size: %" PRId64 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_SIZE ", read_size: %zu"
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE ", offset: %" PRId64 ", size: %zu"
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID ", thread_id: %" PRIu64 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT ", name: \"%s\""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_COUNT ", entry_count: %" PRId64 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_BUFFER_COUNT ", entry_buffer_count: %" PRId64 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_OPEN_MODE ", open_mode: 0x%" PRIX32 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH ", path: \"%s\""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_SIZE ", path: \"%s\", size: %" PRId64 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_OPEN_MODE ", path: \"%s\", open_mode: 0x%" PRIX32 ""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME ", path: \"%s\", new_path: \"%s\""
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_DIRECTORY_ENTRY_TYPE ", entry_type: %s"
|
|
||||||
|
|
||||||
/* Access log formats. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE ""
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_FILE(__OUT_READ_SIZE__, __OFFSET__, __SIZE__) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_SIZE, __OFFSET__, __SIZE__, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_READ_SIZE__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_FLUSH_OPTION AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION ", write_option: Flush"
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE(__OPTION__) ((__OPTION__).HasFlushFlag() ? AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_FLUSH_OPTION : AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_FILE_SIZE(__OUT_SIZE__) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_SIZE__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_DIRECTORY(__OUT_ENTRY_COUNT__, __ENTRY_BUFFER_COUNT__) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_BUFFER_COUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_COUNT, __ENTRY_BUFFER_COUNT__, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_ENTRY_COUNT__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_DIRECTORY_ENTRY_COUNT(__OUT_ENTRY_COUNT__) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_COUNT, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_ENTRY_COUNT__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_ENTRY_TYPE(__OUT_ENTRY_TYPE__, __PATH__) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_DIRECTORY_ENTRY_TYPE, __PATH__, ::ams::fs::impl::IdString().ToString(AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_ENTRY_TYPE__))
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(__OUT_SIZE__, __NAME__) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE, __NAME__, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_SIZE__)
|
|
||||||
|
|
||||||
/* Access log invocation lambdas. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_IMPL(__EXPR__, __HANDLE__, __ENABLED__, __NAME__, ...) \
|
|
||||||
[&](const char *name) { \
|
|
||||||
if (!(__ENABLED__)) { \
|
|
||||||
return (__EXPR__); \
|
|
||||||
} else { \
|
|
||||||
const ::ams::os::Tick start = ::ams::os::GetSystemTick(); \
|
|
||||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__EXPR__); \
|
|
||||||
const ::ams::os::Tick end = ::ams::os::GetSystemTick(); \
|
|
||||||
::ams::fs::impl::OutputAccessLog(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, start, end, name, __HANDLE__, __VA_ARGS__); \
|
|
||||||
return AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME; \
|
|
||||||
} \
|
|
||||||
}(__NAME__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_WITH_PRIORITY_IMPL(__EXPR__, __PRIORITY__, __HANDLE__, __ENABLED__, __NAME__, ...) \
|
|
||||||
[&](const char *name) { \
|
|
||||||
if (!(__ENABLED__)) { \
|
|
||||||
return (__EXPR__); \
|
|
||||||
} else { \
|
|
||||||
const ::ams::os::Tick start = ::ams::os::GetSystemTick(); \
|
|
||||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__EXPR__); \
|
|
||||||
const ::ams::os::Tick end = ::ams::os::GetSystemTick(); \
|
|
||||||
::ams::fs::impl::OutputAccessLog(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, __PRIORITY__, start, end, name, __HANDLE__, __VA_ARGS__); \
|
|
||||||
return AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME; \
|
|
||||||
} \
|
|
||||||
}(__NAME__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_EXPLICIT_IMPL(__RESULT__, __START__, __END__, __HANDLE__, __ENABLED__, __NAME__, ...) \
|
|
||||||
[&](const char *name) { \
|
|
||||||
if (!(__ENABLED__)) { \
|
|
||||||
return __RESULT__; \
|
|
||||||
} else { \
|
|
||||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__RESULT__); \
|
|
||||||
::ams::fs::impl::OutputAccessLog(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, __START__, __END__, name, __HANDLE__, __VA_ARGS__); \
|
|
||||||
return AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME; \
|
|
||||||
} \
|
|
||||||
}(__NAME__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL(__EXPR__, __ENABLED__, __NAME__, ...) \
|
|
||||||
[&](const char *name) { \
|
|
||||||
if (!(__ENABLED__)) { \
|
|
||||||
return (__EXPR__); \
|
|
||||||
} else { \
|
|
||||||
const ::ams::os::Tick start = ::ams::os::GetSystemTick(); \
|
|
||||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__EXPR__); \
|
|
||||||
const ::ams::os::Tick end = ::ams::os::GetSystemTick(); \
|
|
||||||
::ams::fs::impl::OutputAccessLogUnlessResultSuccess(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, start, end, name, nullptr, __VA_ARGS__); \
|
|
||||||
return AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME; \
|
|
||||||
} \
|
|
||||||
}(__NAME__)
|
|
||||||
|
|
||||||
|
|
||||||
/* Access log api. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG(__EXPR__, __HANDLE__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_WITH_NAME(__EXPR__, __HANDLE__, __NAME__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), __NAME__, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_EXPLICIT(__RESULT__, __START__, __END__, __HANDLE__, __NAME__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_EXPLICIT_IMPL((__RESULT__), __START__, __END__, __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), __NAME__, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(__EXPR__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL((__EXPR__), ::ams::fs::impl::IsEnabledAccessLog(), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
|
||||||
|
|
||||||
/* Specific utilities. */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(__EXPR__, __HANDLE__, __FILESYSTEM__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && (__FILESYSTEM__)->IsEnabledAccessLog(), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM_WITH_NAME(__EXPR__, __HANDLE__, __FILESYSTEM__, __NAME__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && (__FILESYSTEM__)->IsEnabledAccessLog(), __NAME__, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_UNMOUNT(__EXPR__, __MOUNT_NAME__, ...) \
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), nullptr, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledFileSystemAccessorAccessLog(__MOUNT_NAME__), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/fs/fs_common.hpp>
|
|
||||||
#include <stratosphere/sf/sf_fs_inline_context.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs::impl {
|
|
||||||
|
|
||||||
constexpr inline u8 TlsIoPriorityMask = 0x7;
|
|
||||||
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
|
|
||||||
|
|
||||||
struct TlsIoValueForInheritance {
|
|
||||||
u8 _tls_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void SetCurrentRequestRecursive() {
|
|
||||||
os::ThreadType * const cur_thread = os::GetCurrentThread();
|
|
||||||
sf::SetFsInlineContext(cur_thread, TlsIoRecursiveCallMask | sf::GetFsInlineContext(cur_thread));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsCurrentRequestRecursive() {
|
|
||||||
return (sf::GetFsInlineContext(os::GetCurrentThread()) & TlsIoRecursiveCallMask) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline TlsIoValueForInheritance GetTlsIoValueForInheritance() {
|
|
||||||
return TlsIoValueForInheritance { sf::GetFsInlineContext(os::GetCurrentThread()) };
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetTlsIoValueForInheritance(TlsIoValueForInheritance tls_io) {
|
|
||||||
sf::SetFsInlineContext(os::GetCurrentThread(), tls_io._tls_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/fs/fs_common.hpp>
|
|
||||||
#include <stratosphere/fs/fs_priority.hpp>
|
|
||||||
#include <stratosphere/fs/impl/fs_fs_inline_context_utils.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs::impl {
|
|
||||||
|
|
||||||
enum TlsIoPriority : u8 {
|
|
||||||
TlsIoPriority_Normal = 0,
|
|
||||||
TlsIoPriority_Realtime = 1,
|
|
||||||
TlsIoPriority_Low = 2,
|
|
||||||
TlsIoPriority_Background = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Ensure that TlsIo priority matches libnx priority. */
|
|
||||||
static_assert(TlsIoPriority_Normal == static_cast<TlsIoPriority>(::FsPriority_Normal));
|
|
||||||
static_assert(TlsIoPriority_Realtime == static_cast<TlsIoPriority>(::FsPriority_Realtime));
|
|
||||||
static_assert(TlsIoPriority_Low == static_cast<TlsIoPriority>(::FsPriority_Low));
|
|
||||||
static_assert(TlsIoPriority_Background == static_cast<TlsIoPriority>(::FsPriority_Background));
|
|
||||||
|
|
||||||
constexpr inline Result ConvertFsPriorityToTlsIoPriority(u8 *out, PriorityRaw priority) {
|
|
||||||
AMS_ASSERT(out != nullptr);
|
|
||||||
|
|
||||||
switch (priority) {
|
|
||||||
case PriorityRaw_Normal: *out = TlsIoPriority_Normal; break;
|
|
||||||
case PriorityRaw_Realtime: *out = TlsIoPriority_Realtime; break;
|
|
||||||
case PriorityRaw_Low: *out = TlsIoPriority_Low; break;
|
|
||||||
case PriorityRaw_Background: *out = TlsIoPriority_Background; break;
|
|
||||||
default: return fs::ResultInvalidArgument();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
|
|
||||||
AMS_ASSERT(out != nullptr);
|
|
||||||
|
|
||||||
switch (static_cast<TlsIoPriority>(tls_io)) {
|
|
||||||
case TlsIoPriority_Normal: *out = PriorityRaw_Normal; break;
|
|
||||||
case TlsIoPriority_Realtime: *out = PriorityRaw_Realtime; break;
|
|
||||||
case TlsIoPriority_Low: *out = PriorityRaw_Low; break;
|
|
||||||
case TlsIoPriority_Background: *out = PriorityRaw_Background; break;
|
|
||||||
default: return fs::ResultInvalidArgument();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u8 GetTlsIoPriority(os::ThreadType *thread) {
|
|
||||||
return sf::GetFsInlineContext(thread) & TlsIoPriorityMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs::impl {
|
|
||||||
|
|
||||||
bool IsAbortNeeded(Result result);
|
|
||||||
void LogErrorMessage(Result result, const char *function);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define AMS_FS_R_CHECK_ABORT_IMPL(__RESULT__, __FORCE__) \
|
|
||||||
({ \
|
|
||||||
if (::ams::fs::impl::IsAbortNeeded(__RESULT__) || (__FORCE__)) { \
|
|
||||||
::ams::fs::impl::LogErrorMessage(__RESULT__, AMS_CURRENT_FUNCTION_NAME); \
|
|
||||||
R_ABORT_UNLESS(__RESULT__); \
|
|
||||||
} \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_R_TRY(__RESULT__) \
|
|
||||||
({ \
|
|
||||||
const ::ams::Result __tmp_fs_result = (__RESULT__); \
|
|
||||||
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, false); \
|
|
||||||
R_TRY(__tmp_fs_result); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_R_ABORT_UNLESS(__RESULT__) \
|
|
||||||
({ \
|
|
||||||
const ::ams::Result __tmp_fs_result = (__RESULT__); \
|
|
||||||
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, true); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_ABORT_UNLESS_WITH_RESULT(__EXPR__, __RESULT__) \
|
|
||||||
({ \
|
|
||||||
if (!(__EXPR__)) { \
|
|
||||||
AMS_FS_R_ABORT_UNLESS((__RESULT__)); \
|
|
||||||
} \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_R_THROW(__RESULT__) \
|
|
||||||
({ \
|
|
||||||
const ::ams::Result __tmp_fs_result = (__RESULT__); \
|
|
||||||
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, false); \
|
|
||||||
return __tmp_fs_result; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_R_UNLESS(__EXPR__, __RESULT__) \
|
|
||||||
({ \
|
|
||||||
if (!(__EXPR__)) { \
|
|
||||||
AMS_FS_R_THROW((__RESULT__)); \
|
|
||||||
} \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_R_TRY_CATCH(__EXPR__) R_TRY_CATCH(__EXPR__)
|
|
||||||
|
|
||||||
#define AMS_FS_R_CATCH(...) R_CATCH(__VA_ARGS__)
|
|
||||||
|
|
||||||
#define AMS_FS_R_END_TRY_CATCH \
|
|
||||||
else if (R_FAILED(R_CURRENT_RESULT)) { \
|
|
||||||
AMS_FS_R_THROW(R_CURRENT_RESULT); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define AMS_FS_R_END_TRY_CATCH_WITH_ABORT_UNLESS \
|
|
||||||
else { \
|
|
||||||
AMS_FS_R_ABORT_UNLESS(R_CURRENT_RESULT); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
})
|
|
||||||
@@ -64,25 +64,10 @@ namespace ams::fssystem {
|
|||||||
|
|
||||||
/* Process a base storage entry. */
|
/* Process a base storage entry. */
|
||||||
if (cr_info.CanDo()) {
|
if (cr_info.CanDo()) {
|
||||||
/* Ensure that we can process. */
|
|
||||||
R_UNLESS(cur_entry.storage_index == 0, fs::ResultInvalidIndirectEntryStorageIndex());
|
R_UNLESS(cur_entry.storage_index == 0, fs::ResultInvalidIndirectEntryStorageIndex());
|
||||||
|
|
||||||
/* Get the current data storage's size. */
|
const auto data_offset = cur_offset - cur_entry_offset;
|
||||||
s64 cur_data_storage_size;
|
R_TRY(func(std::addressof(this->data_storage[0]), cur_entry.GetPhysicalOffset() + data_offset, cur_offset, static_cast<s64>(cr_info.GetReadSize())));
|
||||||
R_TRY(this->data_storage[0].GetSize(std::addressof(cur_data_storage_size)));
|
|
||||||
|
|
||||||
/* Ensure that we remain within range. */
|
|
||||||
const auto data_offset = cur_offset - cur_entry_offset;
|
|
||||||
const auto cur_entry_phys_offset = cur_entry.GetPhysicalOffset();
|
|
||||||
const auto cur_size = static_cast<s64>(cr_info.GetReadSize());
|
|
||||||
R_UNLESS(0 <= cur_entry_phys_offset && cur_entry_phys_offset <= cur_data_storage_size, fs::ResultInvalidIndirectEntryOffset());
|
|
||||||
R_UNLESS(cur_entry_phys_offset + data_offset + cur_size <= cur_data_storage_size, fs::ResultInvalidIndirectStorageSize());
|
|
||||||
|
|
||||||
/* Operate. */
|
|
||||||
R_TRY(func(std::addressof(this->data_storage[0]), cur_entry_phys_offset + data_offset, cur_offset, cur_size));
|
|
||||||
|
|
||||||
/* Mark as done. */
|
|
||||||
cr_info.Done();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,7 @@
|
|||||||
#include <stratosphere/os/os_system_event.hpp>
|
#include <stratosphere/os/os_system_event.hpp>
|
||||||
#include <stratosphere/os/os_interrupt_event.hpp>
|
#include <stratosphere/os/os_interrupt_event.hpp>
|
||||||
#include <stratosphere/os/os_timer_event.hpp>
|
#include <stratosphere/os/os_timer_event.hpp>
|
||||||
#include <stratosphere/os/os_thread_local_storage.hpp>
|
#include <stratosphere/os/os_thread_local_storage_api.hpp>
|
||||||
#include <stratosphere/os/os_sdk_thread_local_storage.hpp>
|
|
||||||
#include <stratosphere/os/os_thread.hpp>
|
#include <stratosphere/os/os_thread.hpp>
|
||||||
#include <stratosphere/os/os_message_queue.hpp>
|
#include <stratosphere/os/os_message_queue.hpp>
|
||||||
#include <stratosphere/os/os_waitable.hpp>
|
#include <stratosphere/os/os_waitable.hpp>
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/os/os_thread_local_storage.hpp>
|
|
||||||
#include <stratosphere/os/os_sdk_thread_local_storage_api.hpp>
|
|
||||||
|
|
||||||
namespace ams::os {
|
|
||||||
|
|
||||||
class SdkThreadLocalStorage {
|
|
||||||
NON_COPYABLE(SdkThreadLocalStorage);
|
|
||||||
NON_MOVEABLE(SdkThreadLocalStorage);
|
|
||||||
private:
|
|
||||||
TlsSlot tls_slot;
|
|
||||||
public:
|
|
||||||
SdkThreadLocalStorage() {
|
|
||||||
R_ABORT_UNLESS(os::SdkAllocateTlsSlot(std::addressof(this->tls_slot), nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SdkThreadLocalStorage(TlsDestructor destructor) {
|
|
||||||
R_ABORT_UNLESS(os::SdkAllocateTlsSlot(std::addressof(this->tls_slot), destructor));
|
|
||||||
}
|
|
||||||
|
|
||||||
~SdkThreadLocalStorage() {
|
|
||||||
os::FreeTlsSlot(this->tls_slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t GetValue() const { return os::GetTlsValue(this->tls_slot); }
|
|
||||||
void SetValue(uintptr_t value) { return os::SetTlsValue(this->tls_slot, value); }
|
|
||||||
|
|
||||||
TlsSlot GetTlsSlot() const { return this->tls_slot; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/os/os_common_types.hpp>
|
|
||||||
#include <stratosphere/os/os_memory_common.hpp>
|
|
||||||
#include <stratosphere/os/os_thread_local_storage_common.hpp>
|
|
||||||
|
|
||||||
namespace ams::os {
|
|
||||||
|
|
||||||
Result SdkAllocateTlsSlot(TlsSlot *out, TlsDestructor destructor);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/os/os_thread_local_storage_common.hpp>
|
|
||||||
#include <stratosphere/os/os_thread_local_storage_api.hpp>
|
|
||||||
|
|
||||||
namespace ams::os {
|
|
||||||
|
|
||||||
class ThreadLocalStorage {
|
|
||||||
NON_COPYABLE(ThreadLocalStorage);
|
|
||||||
NON_MOVEABLE(ThreadLocalStorage);
|
|
||||||
private:
|
|
||||||
TlsSlot tls_slot;
|
|
||||||
public:
|
|
||||||
ThreadLocalStorage() {
|
|
||||||
R_ABORT_UNLESS(os::AllocateTlsSlot(std::addressof(this->tls_slot), nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit ThreadLocalStorage(TlsDestructor destructor) {
|
|
||||||
R_ABORT_UNLESS(os::AllocateTlsSlot(std::addressof(this->tls_slot), destructor));
|
|
||||||
}
|
|
||||||
|
|
||||||
~ThreadLocalStorage() {
|
|
||||||
os::FreeTlsSlot(this->tls_slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t GetValue() const { return os::GetTlsValue(this->tls_slot); }
|
|
||||||
void SetValue(uintptr_t value) { return os::SetTlsValue(this->tls_slot, value); }
|
|
||||||
|
|
||||||
TlsSlot GetTlsSlot() const { return this->tls_slot; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -57,12 +57,6 @@ namespace ams::os {
|
|||||||
size_t stack_size;
|
size_t stack_size;
|
||||||
ThreadFunction function;
|
ThreadFunction function;
|
||||||
void *argument;
|
void *argument;
|
||||||
|
|
||||||
/* NOTE: Here, Nintendo stores the TLS array. This is handled by libnx in our case. */
|
|
||||||
/* However, we need to access certain values in other threads' TLS (Nintendo uses a hardcoded layout for SDK tls members...) */
|
|
||||||
/* These members are tls slot holders in sdk code, but just normal thread type members under our scheme. */
|
|
||||||
uintptr_t atomic_sf_inline_context;
|
|
||||||
|
|
||||||
mutable impl::InternalCriticalSectionStorage cs_thread;
|
mutable impl::InternalCriticalSectionStorage cs_thread;
|
||||||
mutable impl::InternalConditionVariableStorage cv_thread;
|
mutable impl::InternalConditionVariableStorage cv_thread;
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere/sf/sf_common.hpp>
|
#include <stratosphere/sf/sf_common.hpp>
|
||||||
|
|
||||||
namespace ams::os {
|
|
||||||
|
|
||||||
struct ThreadType;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ams::sf {
|
namespace ams::sf {
|
||||||
|
|
||||||
u8 GetFsInlineContext(os::ThreadType *thread);
|
u8 GetFsInlineContext();
|
||||||
u8 SetFsInlineContext(os::ThreadType *thread, u8 ctx);
|
u8 SetFsInlineContext(u8 ctx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace ams::erpt::srv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s64 JournalForReports::GetMaxReportSize() {
|
s64 JournalForReports::GetMaxReportSize() {
|
||||||
s64 max_size = 0;
|
s64 max_size;
|
||||||
for (auto it = s_record_list.begin(); it != s_record_list.end(); it++) {
|
for (auto it = s_record_list.begin(); it != s_record_list.end(); it++) {
|
||||||
max_size = std::max(max_size, it->info.report_size);
|
max_size = std::max(max_size, it->info.report_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ namespace ams::erpt::srv {
|
|||||||
auto file_guard = SCOPE_GUARD { if (mode == StreamMode_Write) { fs::CloseFile(this->file_handle); } };
|
auto file_guard = SCOPE_GUARD { if (mode == StreamMode_Write) { fs::CloseFile(this->file_handle); } };
|
||||||
|
|
||||||
std::strncpy(this->file_name, path, sizeof(this->file_name));
|
std::strncpy(this->file_name, path, sizeof(this->file_name));
|
||||||
this->file_name[sizeof(this->file_name) - 1] = '\x00';
|
|
||||||
|
|
||||||
this->buffer = reinterpret_cast<u8 *>(Allocate(buffer_size));
|
this->buffer = reinterpret_cast<u8 *>(Allocate(buffer_size));
|
||||||
R_UNLESS(this->buffer != nullptr, erpt::ResultOutOfMemory());
|
R_UNLESS(this->buffer != nullptr, erpt::ResultOutOfMemory());
|
||||||
|
|||||||
@@ -1,535 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
#include "fsa/fs_user_mount_table.hpp"
|
|
||||||
#include "fsa/fs_directory_accessor.hpp"
|
|
||||||
#include "fsa/fs_file_accessor.hpp"
|
|
||||||
#include "fsa/fs_filesystem_accessor.hpp"
|
|
||||||
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION "ams_version: " STRINGIZE(ATMOSPHERE_RELEASE_VERSION_MAJOR) "." STRINGIZE(ATMOSPHERE_RELEASE_VERSION_MINOR) "." STRINGIZE(ATMOSPHERE_RELEASE_VERSION_MICRO)
|
|
||||||
|
|
||||||
/* TODO: Other boards? */
|
|
||||||
#define AMS_FS_IMPL_ACCESS_LOG_SPEC "spec: NX"
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
/* Forward declare priority getter. */
|
|
||||||
fs::PriorityRaw GetPriorityRawOnCurrentThreadInternal();
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constinit u32 g_global_access_log_mode = fs::AccessLogMode_None;
|
|
||||||
constinit u32 g_local_access_log_target = fs::impl::AccessLogTarget_None;
|
|
||||||
|
|
||||||
constinit std::atomic_bool g_access_log_initialized = false;
|
|
||||||
constinit os::SdkMutex g_access_log_initialization_mutex;
|
|
||||||
|
|
||||||
void SetLocalAccessLogImpl(bool enabled) {
|
|
||||||
if (enabled) {
|
|
||||||
g_local_access_log_target |= fs::impl::AccessLogTarget_Application;
|
|
||||||
} else {
|
|
||||||
g_local_access_log_target &= ~fs::impl::AccessLogTarget_Application;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetGlobalAccessLogMode(u32 *out) {
|
|
||||||
/* Use libnx bindings. */
|
|
||||||
return ::fsGetGlobalAccessLogMode(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SetGlobalAccessLogMode(u32 mode) {
|
|
||||||
/* Use libnx bindings. */
|
|
||||||
return ::fsSetGlobalAccessLogMode(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetLocalAccessLog(bool enabled) {
|
|
||||||
SetLocalAccessLogImpl(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetLocalApplicationAccessLog(bool enabled) {
|
|
||||||
SetLocalAccessLogImpl(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetLocalSystemAccessLogForDebug(bool enabled) {
|
|
||||||
#if defined(AMS_BUILD_FOR_DEBUGGING)
|
|
||||||
if (enabled) {
|
|
||||||
g_local_access_log_target |= (fs::impl::AccessLogTarget_Application | fs::impl::AccessLogTarget_System);
|
|
||||||
} else {
|
|
||||||
g_local_access_log_target &= ~(fs::impl::AccessLogTarget_Application | fs::impl::AccessLogTarget_System);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ams::fs::impl {
|
|
||||||
|
|
||||||
const char *IdString::ToValueString(int id) {
|
|
||||||
const int len = std::snprintf(this->buffer, sizeof(this->buffer), "%d", id);
|
|
||||||
AMS_ASSERT(static_cast<size_t>(len) < sizeof(this->buffer));
|
|
||||||
return this->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char *IdString::ToString<fs::Priority>(fs::Priority id) {
|
|
||||||
switch (id) {
|
|
||||||
case fs::Priority_Realtime: return "Realtime";
|
|
||||||
case fs::Priority_Normal: return "Normal";
|
|
||||||
case fs::Priority_Low: return "Low";
|
|
||||||
default: return ToValueString(static_cast<int>(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char *IdString::ToString<fs::PriorityRaw>(fs::PriorityRaw id) {
|
|
||||||
switch (id) {
|
|
||||||
case fs::PriorityRaw_Realtime: return "Realtime";
|
|
||||||
case fs::PriorityRaw_Normal: return "Normal";
|
|
||||||
case fs::PriorityRaw_Low: return "Low";
|
|
||||||
case fs::PriorityRaw_Background: return "Realtime";
|
|
||||||
default: return ToValueString(static_cast<int>(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char *IdString::ToString<fs::ContentStorageId>(fs::ContentStorageId id) {
|
|
||||||
switch (id) {
|
|
||||||
case fs::ContentStorageId::User: return "User";
|
|
||||||
case fs::ContentStorageId::System: return "System";
|
|
||||||
case fs::ContentStorageId::SdCard: return "SdCard";
|
|
||||||
default: return ToValueString(static_cast<int>(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char *IdString::ToString<fs::SaveDataSpaceId>(fs::SaveDataSpaceId id) {
|
|
||||||
switch (id) {
|
|
||||||
case fs::SaveDataSpaceId::System: return "System";
|
|
||||||
case fs::SaveDataSpaceId::User: return "User";
|
|
||||||
case fs::SaveDataSpaceId::SdSystem: return "SdSystem";
|
|
||||||
case fs::SaveDataSpaceId::ProperSystem: return "ProperSystem";
|
|
||||||
default: return ToValueString(static_cast<int>(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char *IdString::ToString<fs::ContentType>(fs::ContentType id) {
|
|
||||||
switch (id) {
|
|
||||||
case fs::ContentType_Meta: return "Meta";
|
|
||||||
case fs::ContentType_Control: return "Control";
|
|
||||||
case fs::ContentType_Manual: return "Manual";
|
|
||||||
case fs::ContentType_Logo: return "Logo";
|
|
||||||
case fs::ContentType_Data: return "Data";
|
|
||||||
default: return ToValueString(static_cast<int>(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char *IdString::ToString<fs::BisPartitionId>(fs::BisPartitionId id) {
|
|
||||||
switch (id) {
|
|
||||||
case fs::BisPartitionId::BootPartition1Root: return "BootPartition1Root";
|
|
||||||
case fs::BisPartitionId::BootPartition2Root: return "BootPartition2Root";
|
|
||||||
case fs::BisPartitionId::UserDataRoot: return "UserDataRoot";
|
|
||||||
case fs::BisPartitionId::BootConfigAndPackage2Part1: return "BootConfigAndPackage2Part1";
|
|
||||||
case fs::BisPartitionId::BootConfigAndPackage2Part2: return "BootConfigAndPackage2Part2";
|
|
||||||
case fs::BisPartitionId::BootConfigAndPackage2Part3: return "BootConfigAndPackage2Part3";
|
|
||||||
case fs::BisPartitionId::BootConfigAndPackage2Part4: return "BootConfigAndPackage2Part4";
|
|
||||||
case fs::BisPartitionId::BootConfigAndPackage2Part5: return "BootConfigAndPackage2Part5";
|
|
||||||
case fs::BisPartitionId::BootConfigAndPackage2Part6: return "BootConfigAndPackage2Part6";
|
|
||||||
case fs::BisPartitionId::CalibrationBinary: return "CalibrationBinary";
|
|
||||||
case fs::BisPartitionId::CalibrationFile: return "CalibrationFile";
|
|
||||||
case fs::BisPartitionId::SafeMode: return "SafeMode";
|
|
||||||
case fs::BisPartitionId::User: return "User";
|
|
||||||
case fs::BisPartitionId::System: return "System";
|
|
||||||
case fs::BisPartitionId::SystemProperEncryption: return "SystemProperEncryption";
|
|
||||||
case fs::BisPartitionId::SystemProperPartition: return "SystemProperPartition";
|
|
||||||
default: return ToValueString(static_cast<int>(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class AccessLogPrinterCallbackManager {
|
|
||||||
private:
|
|
||||||
AccessLogPrinterCallback callback;
|
|
||||||
public:
|
|
||||||
constexpr AccessLogPrinterCallbackManager() : callback(nullptr) { /* ... */ }
|
|
||||||
|
|
||||||
constexpr bool IsRegisteredCallback() const { return this->callback != nullptr; }
|
|
||||||
|
|
||||||
constexpr void RegisterCallback(AccessLogPrinterCallback c) {
|
|
||||||
AMS_ASSERT(this->callback == nullptr);
|
|
||||||
this->callback = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int InvokeCallback(char *buf, size_t size) const {
|
|
||||||
AMS_ASSERT(this->callback != nullptr);
|
|
||||||
return this->callback(buf, size);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
constinit AccessLogPrinterCallbackManager g_access_log_manager_printer_callback_manager;
|
|
||||||
|
|
||||||
ALWAYS_INLINE AccessLogPrinterCallbackManager &GetStartAccessLogPrinterCallbackManager() {
|
|
||||||
return g_access_log_manager_printer_callback_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *GetPriorityRawName(fs::impl::IdString &id_string) {
|
|
||||||
return id_string.ToString(fs::GetPriorityRawOnCurrentThreadInternal());
|
|
||||||
}
|
|
||||||
|
|
||||||
Result OutputAccessLogToSdCardImpl(const char *log, size_t size) {
|
|
||||||
/* Use libnx bindings. */
|
|
||||||
return ::fsOutputAccessLogToSdCard(log, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogToSdCard(const char *format, std::va_list vl) {
|
|
||||||
if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) {
|
|
||||||
/* Create a buffer to hold the log's input string. */
|
|
||||||
int log_buffer_size = 1_KB;
|
|
||||||
auto log_buffer = fs::impl::MakeUnique<char[]>(log_buffer_size);
|
|
||||||
while (true) {
|
|
||||||
if (log_buffer == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto size = std::vsnprintf(log_buffer.get(), log_buffer_size, format, vl);
|
|
||||||
if (size < log_buffer_size) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_buffer_size = size + 1;
|
|
||||||
log_buffer = fs::impl::MakeUnique<char[]>(log_buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output. */
|
|
||||||
OutputAccessLogToSdCardImpl(log_buffer.get(), log_buffer_size - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogImpl(const char *log, size_t size) {
|
|
||||||
if ((g_global_access_log_mode & AccessLogMode_Log) != 0) {
|
|
||||||
/* TODO: Support logging. */
|
|
||||||
} else if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) {
|
|
||||||
OutputAccessLogToSdCardImpl(log, size - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, const char *priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *format, std::va_list vl) {
|
|
||||||
/* Create a buffer to hold the log's input string. */
|
|
||||||
int str_buffer_size = 1_KB;
|
|
||||||
auto str_buffer = fs::impl::MakeUnique<char[]>(str_buffer_size);
|
|
||||||
while (true) {
|
|
||||||
if (str_buffer == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto size = std::vsnprintf(str_buffer.get(), str_buffer_size, format, vl);
|
|
||||||
if (size < str_buffer_size) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
str_buffer_size = size + 1;
|
|
||||||
str_buffer = fs::impl::MakeUnique<char[]>(str_buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a buffer to hold the log. */
|
|
||||||
int log_buffer_size = 0;
|
|
||||||
decltype(str_buffer) log_buffer;
|
|
||||||
{
|
|
||||||
/* Declare format string. */
|
|
||||||
constexpr const char FormatString[] = "FS_ACCESS { "
|
|
||||||
"start: %9" PRId64 ", "
|
|
||||||
"end: %9" PRId64 ", "
|
|
||||||
"result: 0x%08" PRIX32 ", "
|
|
||||||
"handle: 0x%p, "
|
|
||||||
"priority: %s, "
|
|
||||||
"function: \"%s\""
|
|
||||||
"%s"
|
|
||||||
" }\n";
|
|
||||||
|
|
||||||
/* Convert the timing to ms. */
|
|
||||||
const s64 start_ms = start.ToTimeSpan().GetMilliSeconds();
|
|
||||||
const s64 end_ms = end.ToTimeSpan().GetMilliSeconds();
|
|
||||||
|
|
||||||
/* Print the log. */
|
|
||||||
int try_size = std::max<int>(str_buffer_size + sizeof(FormatString) + 0x100, 1_KB);
|
|
||||||
while (true) {
|
|
||||||
log_buffer = fs::impl::MakeUnique<char[]>(try_size);
|
|
||||||
if (log_buffer == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_buffer_size = 1 + std::snprintf(log_buffer.get(), try_size, FormatString, start_ms, end_ms, result.GetValue(), handle, priority, name, str_buffer.get());
|
|
||||||
if (log_buffer_size <= try_size) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
try_size = log_buffer_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputAccessLogImpl(log_buffer.get(), log_buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetProgramIndexFortAccessLog(u32 *out_index, u32 *out_count) {
|
|
||||||
if (hos::GetVersion() >= hos::Version_7_0_0) {
|
|
||||||
/* Use libnx bindings if available. */
|
|
||||||
R_ABORT_UNLESS(::fsGetProgramIndexForAccessLog(out_index, out_count));
|
|
||||||
} else {
|
|
||||||
/* Use hardcoded defaults. */
|
|
||||||
*out_index = 0;
|
|
||||||
*out_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogStart() {
|
|
||||||
/* Get the program index. */
|
|
||||||
u32 program_index = 0, program_count = 0;
|
|
||||||
GetProgramIndexFortAccessLog(std::addressof(program_index), std::addressof(program_count));
|
|
||||||
|
|
||||||
/* Print the log buffer. */
|
|
||||||
if (program_count < 2) {
|
|
||||||
constexpr const char StartLog[] = "FS_ACCESS: { "
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION ", "
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_SPEC
|
|
||||||
" }\n";
|
|
||||||
|
|
||||||
OutputAccessLogImpl(StartLog, sizeof(StartLog));
|
|
||||||
} else {
|
|
||||||
constexpr const char StartLog[] = "FS_ACCESS: { "
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION ", "
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_SPEC ", "
|
|
||||||
"program_index: %d"
|
|
||||||
" }\n";
|
|
||||||
|
|
||||||
char log_buffer[0x80];
|
|
||||||
const int len = 1 + std::snprintf(log_buffer, sizeof(log_buffer), StartLog, static_cast<int>(program_index));
|
|
||||||
if (static_cast<size_t>(len) <= sizeof(log_buffer)) {
|
|
||||||
OutputAccessLogImpl(log_buffer, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] void OutputAccessLogStartForSystem() {
|
|
||||||
constexpr const char StartLog[] = "FS_ACCESS: { "
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION ", "
|
|
||||||
AMS_FS_IMPL_ACCESS_LOG_SPEC ", "
|
|
||||||
"for_system: true"
|
|
||||||
" }\n";
|
|
||||||
OutputAccessLogImpl(StartLog, sizeof(StartLog));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogStartGeneratedByCallback() {
|
|
||||||
/* Get the manager. */
|
|
||||||
const auto &manager = GetStartAccessLogPrinterCallbackManager();
|
|
||||||
if (manager.IsRegisteredCallback()) {
|
|
||||||
/* Invoke the callback. */
|
|
||||||
char log_buffer[0x80];
|
|
||||||
const int len = 1 + manager.InvokeCallback(log_buffer, sizeof(log_buffer));
|
|
||||||
|
|
||||||
/* Print, if we fit. */
|
|
||||||
if (static_cast<size_t>(len) <= sizeof(log_buffer)) {
|
|
||||||
OutputAccessLogImpl(log_buffer, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledAccessLog(u32 target) {
|
|
||||||
/* If we don't need to log to the target, return false. */
|
|
||||||
if ((g_local_access_log_target & target) == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure we've initialized. */
|
|
||||||
if (!g_access_log_initialized) {
|
|
||||||
std::scoped_lock lk(g_access_log_initialization_mutex);
|
|
||||||
if (!g_access_log_initialized) {
|
|
||||||
|
|
||||||
#if defined (AMS_BUILD_FOR_DEBUGGING)
|
|
||||||
if ((g_local_access_log_target & fs::impl::AccessLogTarget_System) != 0)
|
|
||||||
{
|
|
||||||
g_global_access_log_mode = AccessLogMode_Log;
|
|
||||||
OutputAccessLogStartForSystem();
|
|
||||||
OutputAccessLogStartGeneratedByCallback();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
AMS_FS_R_ABORT_UNLESS(GetGlobalAccessLogMode(std::addressof(g_global_access_log_mode)));
|
|
||||||
if (g_global_access_log_mode != AccessLogMode_None) {
|
|
||||||
OutputAccessLogStart();
|
|
||||||
OutputAccessLogStartGeneratedByCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_access_log_initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_global_access_log_mode != AccessLogMode_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledAccessLog() {
|
|
||||||
return IsEnabledAccessLog(fs::impl::AccessLogTarget_Application | fs::impl::AccessLogTarget_System);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterStartAccessLogPrinterCallback(AccessLogPrinterCallback callback) {
|
|
||||||
GetStartAccessLogPrinterCallbackManager().RegisterCallback(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, fs::Priority priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
OutputAccessLog(result, fs::impl::IdString().ToString(priority), start, end, name, handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, fs::PriorityRaw priority_raw, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...){
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
OutputAccessLog(result, fs::impl::IdString().ToString(priority_raw), start, end, name, handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle.handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle.handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::impl::IdentifyAccessLogHandle handle, const char *fmt, ...) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle.handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogToOnlySdCard(const char *fmt, ...) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
OutputAccessLogToSdCard(fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) {
|
|
||||||
if (R_FAILED(result)) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle.handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) {
|
|
||||||
if (R_FAILED(result)) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle.handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) {
|
|
||||||
if (R_FAILED(result)) {
|
|
||||||
std::va_list vl;
|
|
||||||
va_start(vl, fmt);
|
|
||||||
fs::impl::IdString id_string;
|
|
||||||
OutputAccessLog(result, GetPriorityRawName(id_string), start, end, name, handle, fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledHandleAccessLog(fs::FileHandle handle) {
|
|
||||||
/* Get the file accessor. */
|
|
||||||
impl::FileAccessor *accessor = reinterpret_cast<impl::FileAccessor *>(handle.handle);
|
|
||||||
if (accessor == nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the parent. */
|
|
||||||
if (auto *parent = accessor->GetParent(); parent != nullptr) {
|
|
||||||
return parent->IsEnabledAccessLog();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledHandleAccessLog(fs::DirectoryHandle handle) {
|
|
||||||
/* Get the file accessor. */
|
|
||||||
impl::DirectoryAccessor *accessor = reinterpret_cast<impl::DirectoryAccessor *>(handle.handle);
|
|
||||||
if (accessor == nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the parent. */
|
|
||||||
if (auto *parent = accessor->GetParent(); parent != nullptr) {
|
|
||||||
return parent->IsEnabledAccessLog();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledHandleAccessLog(fs::impl::IdentifyAccessLogHandle handle) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledHandleAccessLog(const void *handle) {
|
|
||||||
if (handle == nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We should never receive non-null here. */
|
|
||||||
AMS_ASSERT(handle == nullptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabledFileSystemAccessorAccessLog(const char *mount_name) {
|
|
||||||
/* Get the accessor. */
|
|
||||||
impl::FileSystemAccessor *accessor;
|
|
||||||
if (R_FAILED(impl::Find(std::addressof(accessor), mount_name))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return accessor->IsEnabledAccessLog();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnableFileSystemAccessorAccessLog(const char *mount_name) {
|
|
||||||
/* Get the accessor. */
|
|
||||||
impl::FileSystemAccessor *accessor;
|
|
||||||
AMS_FS_R_ABORT_UNLESS(impl::Find(std::addressof(accessor), mount_name));
|
|
||||||
accessor->SetAccessLogEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constinit bool g_auto_abort_enabled = true;
|
|
||||||
|
|
||||||
/* NOTE: This generates a global constructor. */
|
|
||||||
os::SdkThreadLocalStorage g_context_tls;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetEnabledAutoAbort(bool enabled) {
|
|
||||||
g_auto_abort_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbortSpecifier DefaultResultHandler(Result result) {
|
|
||||||
if (g_auto_abort_enabled) {
|
|
||||||
return AbortSpecifier::Default;
|
|
||||||
} else {
|
|
||||||
return AbortSpecifier::Return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbortSpecifier AlwaysReturnResultHandler(Result result) {
|
|
||||||
return AbortSpecifier::Return;
|
|
||||||
}
|
|
||||||
|
|
||||||
constinit FsContext g_default_context(DefaultResultHandler);
|
|
||||||
constinit FsContext g_always_return_context(AlwaysReturnResultHandler);
|
|
||||||
|
|
||||||
void SetDefaultFsContextResultHandler(const ResultHandler handler) {
|
|
||||||
if (handler == nullptr) {
|
|
||||||
g_default_context.SetHandler(DefaultResultHandler);
|
|
||||||
} else {
|
|
||||||
g_default_context.SetHandler(handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const FsContext *GetCurrentThreadFsContext() {
|
|
||||||
const FsContext *context = reinterpret_cast<const FsContext *>(g_context_tls.GetValue());
|
|
||||||
|
|
||||||
if (context == nullptr) {
|
|
||||||
context = std::addressof(g_default_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCurrentThreadFsContext(const FsContext *context) {
|
|
||||||
g_context_tls.SetValue(reinterpret_cast<uintptr_t>(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedAutoAbortDisabler::ScopedAutoAbortDisabler() : prev_context(GetCurrentThreadFsContext()) {
|
|
||||||
SetCurrentThreadFsContext(std::addressof(g_always_return_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr bool IsValidPriority(fs::Priority priority) {
|
|
||||||
return priority == Priority_Low || priority == Priority_Normal || priority == Priority_Realtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool IsValidPriorityRaw(fs::PriorityRaw priority_raw) {
|
|
||||||
return priority_raw == PriorityRaw_Background || priority_raw == PriorityRaw_Low || priority_raw == PriorityRaw_Normal || priority_raw == PriorityRaw_Realtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::PriorityRaw ConvertPriorityToPriorityRaw(fs::Priority priority) {
|
|
||||||
AMS_ASSERT(IsValidPriority(priority));
|
|
||||||
|
|
||||||
switch (priority) {
|
|
||||||
case Priority_Low: return PriorityRaw_Low;
|
|
||||||
case Priority_Normal: return PriorityRaw_Normal;
|
|
||||||
case Priority_Realtime: return PriorityRaw_Realtime;
|
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::Priority ConvertPriorityRawToPriority(fs::PriorityRaw priority_raw) {
|
|
||||||
AMS_ASSERT(IsValidPriorityRaw(priority_raw));
|
|
||||||
|
|
||||||
switch (priority_raw) {
|
|
||||||
case PriorityRaw_Background: return Priority_Low;
|
|
||||||
case PriorityRaw_Low: return Priority_Low;
|
|
||||||
case PriorityRaw_Normal: return Priority_Normal;
|
|
||||||
case PriorityRaw_Realtime: return Priority_Realtime;
|
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateTlsIoPriority(os::ThreadType *thread, u8 tls_io) {
|
|
||||||
sf::SetFsInlineContext(thread, (tls_io & impl::TlsIoPriorityMask) | (sf::GetFsInlineContext(thread) & ~impl::TlsIoPriorityMask));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetPriorityRawImpl(fs::PriorityRaw *out, os::ThreadType *thread) {
|
|
||||||
/* Validate arguments. */
|
|
||||||
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
|
|
||||||
|
|
||||||
/* Get the raw priority. */
|
|
||||||
PriorityRaw priority_raw;
|
|
||||||
R_TRY(impl::ConvertTlsIoPriorityToFsPriority(std::addressof(priority_raw), impl::GetTlsIoPriority(thread)));
|
|
||||||
|
|
||||||
/* Set output. */
|
|
||||||
*out = priority_raw;
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetPriorityImpl(fs::Priority *out, os::ThreadType *thread) {
|
|
||||||
/* Validate arguments. */
|
|
||||||
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
|
|
||||||
|
|
||||||
/* Get the raw priority. */
|
|
||||||
PriorityRaw priority_raw;
|
|
||||||
R_TRY(impl::ConvertTlsIoPriorityToFsPriority(std::addressof(priority_raw), impl::GetTlsIoPriority(thread)));
|
|
||||||
|
|
||||||
/* Set output. */
|
|
||||||
*out = ConvertPriorityRawToPriority(priority_raw);
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SetPriorityRawImpl(os::ThreadType *thread, fs::PriorityRaw priority_raw) {
|
|
||||||
/* Validate arguments. */
|
|
||||||
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
|
|
||||||
R_UNLESS(IsValidPriorityRaw(priority_raw), fs::ResultInvalidArgument());
|
|
||||||
|
|
||||||
/* Convert to tls io. */
|
|
||||||
u8 tls_io;
|
|
||||||
R_TRY(impl::ConvertFsPriorityToTlsIoPriority(std::addressof(tls_io), priority_raw));
|
|
||||||
|
|
||||||
/* Update the priority. */
|
|
||||||
UpdateTlsIoPriority(thread, tls_io);
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SetPriorityImpl(os::ThreadType *thread, fs::Priority priority) {
|
|
||||||
/* Validate arguments. */
|
|
||||||
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
|
|
||||||
R_UNLESS(IsValidPriority(priority), fs::ResultInvalidArgument());
|
|
||||||
|
|
||||||
/* Convert to tls io. */
|
|
||||||
u8 tls_io;
|
|
||||||
R_TRY(impl::ConvertFsPriorityToTlsIoPriority(std::addressof(tls_io), ConvertPriorityToPriorityRaw(priority)));
|
|
||||||
|
|
||||||
/* Update the priority. */
|
|
||||||
UpdateTlsIoPriority(thread, tls_io);
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Priority GetPriorityOnCurrentThread() {
|
|
||||||
fs::Priority priority;
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityImpl(std::addressof(priority), os::GetCurrentThread()), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
Priority GetPriority(os::ThreadType *thread) {
|
|
||||||
fs::Priority priority;
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityImpl(std::addressof(priority), thread), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
PriorityRaw GetPriorityRawOnCurrentThread() {
|
|
||||||
fs::PriorityRaw priority_raw;
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityRawImpl(std::addressof(priority_raw), os::GetCurrentThread()), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
|
|
||||||
return priority_raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
PriorityRaw GetPriorityRawOnCurrentThreadInternal() {
|
|
||||||
fs::PriorityRaw priority_raw;
|
|
||||||
R_ABORT_UNLESS(GetPriorityRawImpl(std::addressof(priority_raw), os::GetCurrentThread()));
|
|
||||||
return priority_raw;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PriorityRaw GetPriorityRaw(os::ThreadType *thread) {
|
|
||||||
fs::PriorityRaw priority_raw;
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityRawImpl(std::addressof(priority_raw), thread), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
|
|
||||||
return priority_raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPriorityOnCurrentThread(Priority priority) {
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityImpl(os::GetCurrentThread(), priority), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPriority(os::ThreadType *thread, Priority priority) {
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityImpl(os::GetCurrentThread(), priority), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPriorityRawOnCurrentThread(PriorityRaw priority_raw) {
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityRawImpl(os::GetCurrentThread(), priority_raw), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPriorityRaw(os::ThreadType *thread, PriorityRaw priority_raw) {
|
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityRawImpl(os::GetCurrentThread(), priority_raw), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constinit bool g_handled_by_application = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetResultHandledByApplication(bool application) {
|
|
||||||
g_handled_by_application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
bool IsAbortNeeded(Result result) {
|
|
||||||
/* If the result succeeded, we never need to abort. */
|
|
||||||
if (R_SUCCEEDED(result)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the abort specifier from current context. */
|
|
||||||
switch (GetCurrentThreadFsContext()->HandleResult(result)) {
|
|
||||||
case AbortSpecifier::Default:
|
|
||||||
if (g_handled_by_application) {
|
|
||||||
return !fs::ResultHandledByAllProcess::Includes(result);
|
|
||||||
} else {
|
|
||||||
return !(fs::ResultHandledByAllProcess::Includes(result) || fs::ResultHandledBySystemProcess::Includes(result));
|
|
||||||
}
|
|
||||||
case AbortSpecifier::Abort:
|
|
||||||
return true;
|
|
||||||
case AbortSpecifier::Return:
|
|
||||||
return false;
|
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogResultErrorMessage(Result result) {
|
|
||||||
/* TODO: log specific results */
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogErrorMessage(Result result, const char *function) {
|
|
||||||
/* If the result succeeded, there's nothing to log. */
|
|
||||||
if (R_SUCCEEDED(result)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Actually log stuff. */
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -32,7 +32,7 @@ namespace ams::fs::impl {
|
|||||||
Result Read(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries);
|
Result Read(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries);
|
||||||
Result GetEntryCount(s64 *out);
|
Result GetEntryCount(s64 *out);
|
||||||
|
|
||||||
FileSystemAccessor *GetParent() const { return std::addressof(this->parent); }
|
FileSystemAccessor &GetParent() const { return this->parent; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ namespace ams::fs::impl {
|
|||||||
|
|
||||||
FileAccessor::~FileAccessor() {
|
FileAccessor::~FileAccessor() {
|
||||||
/* Ensure that all files are flushed. */
|
/* Ensure that all files are flushed. */
|
||||||
if (R_SUCCEEDED(this->write_result)) {
|
if (R_FAILED(this->write_result)) {
|
||||||
AMS_FS_ABORT_UNLESS_WITH_RESULT(this->write_state != WriteState::NeedsFlush, fs::ResultNeedFlush());
|
AMS_ABORT_UNLESS(this->write_state != WriteState::NeedsFlush);
|
||||||
}
|
}
|
||||||
this->impl.reset();
|
this->impl.reset();
|
||||||
|
|
||||||
@@ -40,7 +40,6 @@ namespace ams::fs::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result FileAccessor::ReadWithCacheAccessLog(size_t *out, s64 offset, void *buf, size_t size, const ReadOption &option, bool use_path_cache, bool use_data_cache) {
|
Result FileAccessor::ReadWithCacheAccessLog(size_t *out, s64 offset, void *buf, size_t size, const ReadOption &option, bool use_path_cache, bool use_data_cache) {
|
||||||
/* TODO */
|
|
||||||
AMS_ABORT();
|
AMS_ABORT();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,12 +48,10 @@ namespace ams::fs::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result FileAccessor::Read(size_t *out, s64 offset, void *buf, size_t size, const ReadOption &option) {
|
Result FileAccessor::Read(size_t *out, s64 offset, void *buf, size_t size, const ReadOption &option) {
|
||||||
/* Get a handle to this file for use in logging. */
|
|
||||||
FileHandle handle = { this };
|
|
||||||
|
|
||||||
/* Fail after a write fails. */
|
/* Fail after a write fails. */
|
||||||
R_UNLESS(R_SUCCEEDED(this->write_result), AMS_FS_IMPL_ACCESS_LOG_WITH_NAME(this->write_result, handle, "ReadFile", AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_FILE(out, offset, size)));
|
R_TRY(this->write_result);
|
||||||
|
|
||||||
|
/* TODO: Logging. */
|
||||||
/* TODO: Support cache. */
|
/* TODO: Support cache. */
|
||||||
const bool use_path_cache = this->parent != nullptr && this->file_path_hash != nullptr;
|
const bool use_path_cache = this->parent != nullptr && this->file_path_hash != nullptr;
|
||||||
const bool use_data_cache = /* TODO */false && this->parent != nullptr && this->parent->IsFileDataCacheAttachable();
|
const bool use_data_cache = /* TODO */false && this->parent != nullptr && this->parent->IsFileDataCacheAttachable();
|
||||||
@@ -63,7 +60,7 @@ namespace ams::fs::impl {
|
|||||||
/* TODO */
|
/* TODO */
|
||||||
return this->ReadWithCacheAccessLog(out, offset, buf, size, option, use_path_cache, use_data_cache);
|
return this->ReadWithCacheAccessLog(out, offset, buf, size, option, use_path_cache, use_data_cache);
|
||||||
} else {
|
} else {
|
||||||
return AMS_FS_IMPL_ACCESS_LOG_WITH_NAME(this->ReadWithoutCacheAccessLog(out, offset, buf, size, option), handle, "ReadFile", AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_FILE(out, offset, size));
|
return this->ReadWithoutCacheAccessLog(out, offset, buf, size, option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace ams::fs::impl {
|
|||||||
void SetPathBasedFileDataCacheAttachable(bool en) { this->path_cache_attachable = en; }
|
void SetPathBasedFileDataCacheAttachable(bool en) { this->path_cache_attachable = en; }
|
||||||
void SetMultiCommitSupported(bool en) { this->multi_commit_supported = en; }
|
void SetMultiCommitSupported(bool en) { this->multi_commit_supported = en; }
|
||||||
|
|
||||||
bool IsEnabledAccessLog() const { return this->access_log_enabled; }
|
bool IsAccessLogEnabled() const { return this->access_log_enabled; }
|
||||||
bool IsFileDataCacheAttachable() const { return this->data_cache_attachable; }
|
bool IsFileDataCacheAttachable() const { return this->data_cache_attachable; }
|
||||||
bool IsPathBasedFileDataCacheAttachable() const { return this->path_cache_attachable; }
|
bool IsPathBasedFileDataCacheAttachable() const { return this->path_cache_attachable; }
|
||||||
|
|
||||||
|
|||||||
@@ -120,49 +120,49 @@ namespace ams::fs::impl {
|
|||||||
return impl::Find(out_accessor, mount_name.str);
|
return impl::Find(out_accessor, mount_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Unmount(const char *name) {
|
|
||||||
impl::FileSystemAccessor *accessor;
|
|
||||||
R_TRY(impl::Find(std::addressof(accessor), name));
|
|
||||||
|
|
||||||
if (accessor->IsFileDataCacheAttachable()) {
|
|
||||||
/* TODO: Data cache purge */
|
|
||||||
}
|
|
||||||
|
|
||||||
impl::Unregister(name);
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
Result UnmountImpl(const char *name) {
|
||||||
|
impl::FileSystemAccessor *accessor;
|
||||||
|
R_TRY(impl::Find(std::addressof(accessor), name));
|
||||||
|
|
||||||
|
if (accessor->IsFileDataCacheAttachable()) {
|
||||||
|
/* TODO: Data cache purge */
|
||||||
|
}
|
||||||
|
|
||||||
|
impl::Unregister(name);
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src) {
|
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src) {
|
||||||
/* Ensure neither argument is nullptr. */
|
/* Ensure neither argument is nullptr. */
|
||||||
AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
||||||
AMS_FS_R_UNLESS(src != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(src != nullptr, fs::ResultNullptrArgument());
|
||||||
|
|
||||||
/* Get the mount name and sub path for the path. */
|
/* Get the mount name and sub path for the path. */
|
||||||
MountName mount_name;
|
MountName mount_name;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(impl::GetMountNameAndSubPath(std::addressof(mount_name), std::addressof(sub_path), src));
|
R_TRY(impl::GetMountNameAndSubPath(std::addressof(mount_name), std::addressof(sub_path), src));
|
||||||
|
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
AMS_FS_R_TRY(impl::Find(std::addressof(accessor), mount_name.str));
|
R_TRY(impl::Find(std::addressof(accessor), mount_name.str));
|
||||||
AMS_FS_R_TRY(accessor->GetCommonMountName(dst, dst_size));
|
R_TRY(accessor->GetCommonMountName(dst, dst_size));
|
||||||
|
|
||||||
const auto mount_name_len = strnlen(dst, dst_size);
|
const auto mount_name_len = strnlen(dst, dst_size);
|
||||||
const auto common_path_len = std::snprintf(dst + mount_name_len, dst_size - mount_name_len, "%s", sub_path);
|
const auto common_path_len = std::snprintf(dst + mount_name_len, dst_size - mount_name_len, "%s", sub_path);
|
||||||
|
|
||||||
AMS_FS_R_UNLESS(static_cast<size_t>(common_path_len) < dst_size - mount_name_len, fs::ResultTooLongPath());
|
R_UNLESS(static_cast<size_t>(common_path_len) < dst_size - mount_name_len, fs::ResultTooLongPath());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unmount(const char *mount_name) {
|
void Unmount(const char *mount_name) {
|
||||||
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG_UNMOUNT(impl::Unmount(mount_name), mount_name, AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT, mount_name));
|
R_ABORT_UNLESS(UnmountImpl(mount_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace ams::fs::impl {
|
|||||||
|
|
||||||
bool IsWindowsDrive(const char *name);
|
bool IsWindowsDrive(const char *name);
|
||||||
bool IsReservedMountName(const char *name);
|
bool IsReservedMountName(const char *name);
|
||||||
bool IsValidMountName(const char *name);
|
|
||||||
Result CheckMountName(const char *name);
|
Result CheckMountName(const char *name);
|
||||||
Result CheckMountNameAllowingReserved(const char *name);
|
Result CheckMountNameAllowingReserved(const char *name);
|
||||||
|
|
||||||
|
|||||||
@@ -28,17 +28,15 @@ namespace ams::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
|
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->Read(out_count, out_entries, max_entries), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_DIRECTORY(out_count, max_entries)));
|
return Get(handle)->Read(out_count, out_entries, max_entries);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetDirectoryEntryCount(s64 *out, DirectoryHandle handle) {
|
Result GetDirectoryEntryCount(s64 *out, DirectoryHandle handle) {
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->GetEntryCount(out), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_DIRECTORY_ENTRY_COUNT(out)));
|
return Get(handle)->GetEntryCount(out);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseDirectory(DirectoryHandle handle) {
|
void CloseDirectory(DirectoryHandle handle) {
|
||||||
AMS_FS_IMPL_ACCESS_LOG((delete Get(handle), ResultSuccess()), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE);
|
delete Get(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,70 +25,53 @@ namespace ams::fs {
|
|||||||
return reinterpret_cast<impl::FileAccessor *>(handle.handle);
|
return reinterpret_cast<impl::FileAccessor *>(handle.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFileImpl(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
|
||||||
R_TRY(Get(handle)->Read(out, offset, buffer, size, option));
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||||
size_t read_size;
|
size_t read_size;
|
||||||
AMS_FS_R_TRY(ReadFileImpl(std::addressof(read_size), handle, offset, buffer, size, option));
|
R_TRY(ReadFile(std::addressof(read_size), handle, offset, buffer, size, option));
|
||||||
AMS_FS_R_UNLESS(read_size == size, fs::ResultOutOfRange());
|
R_UNLESS(read_size == size, fs::ResultOutOfRange());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||||
size_t read_size;
|
return ReadFile(handle, offset, buffer, size, ReadOption());
|
||||||
AMS_FS_R_TRY(ReadFileImpl(std::addressof(read_size), handle, offset, buffer, size, ReadOption()));
|
|
||||||
AMS_FS_R_UNLESS(read_size == size, fs::ResultOutOfRange());
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||||
AMS_FS_R_TRY(ReadFileImpl(out, handle, offset, buffer, size, option));
|
return Get(handle)->Read(out, offset, buffer, size, option);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||||
AMS_FS_R_TRY(ReadFileImpl(out, handle, offset, buffer, size, ReadOption()));
|
return ReadFile(out, handle, offset, buffer, size, ReadOption());
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->GetSize(out), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_FILE_SIZE(out)));
|
return Get(handle)->GetSize(out);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FlushFile(FileHandle handle) {
|
Result FlushFile(FileHandle handle) {
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->Flush(), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
|
return Get(handle)->Flush();
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->Write(offset, buffer, size, option), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE(option), offset, size));
|
return Get(handle)->Write(offset, buffer, size, option);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetFileSize(FileHandle handle, s64 size) {
|
Result SetFileSize(FileHandle handle, s64 size) {
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->SetSize(size), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE, size));
|
return Get(handle)->SetSize(size);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFileOpenMode(FileHandle handle) {
|
int GetFileOpenMode(FileHandle handle) {
|
||||||
const int mode = Get(handle)->GetOpenMode();
|
return Get(handle)->GetOpenMode();
|
||||||
AMS_FS_IMPL_ACCESS_LOG(ResultSuccess(), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_OPEN_MODE, static_cast<u32>(mode));
|
|
||||||
return mode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseFile(FileHandle handle) {
|
void CloseFile(FileHandle handle) {
|
||||||
AMS_FS_IMPL_ACCESS_LOG((delete Get(handle), ResultSuccess()), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE);
|
delete Get(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) {
|
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) {
|
||||||
AMS_FS_R_TRY(Get(handle)->OperateRange(out, sizeof(*out), OperationId::QueryRange, offset, size, nullptr, 0));
|
return Get(handle)->OperateRange(out, sizeof(*out), OperationId::QueryRange, offset, size, nullptr, 0);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,46 +29,41 @@ namespace ams::fs {
|
|||||||
Result CreateFile(const char* path, s64 size, int option) {
|
Result CreateFile(const char* path, s64 size, int option) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->CreateFile(sub_path, size, option), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_SIZE, path, size));
|
return accessor->CreateFile(sub_path, size, option);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteFile(const char *path) {
|
Result DeleteFile(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->DeleteFile(sub_path), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
return accessor->DeleteFile(sub_path);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectory(const char *path) {
|
Result CreateDirectory(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->CreateDirectory(sub_path), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
return accessor->CreateDirectory(sub_path);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectory(const char *path) {
|
Result DeleteDirectory(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->DeleteDirectory(sub_path), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
return accessor->DeleteDirectory(sub_path);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectoryRecursively(const char *path) {
|
Result DeleteDirectoryRecursively(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->DeleteDirectoryRecursively(sub_path), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
return accessor->DeleteDirectoryRecursively(sub_path);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameFile(const char *old_path, const char *new_path) {
|
Result RenameFile(const char *old_path, const char *new_path) {
|
||||||
@@ -76,17 +71,11 @@ namespace ams::fs {
|
|||||||
impl::FileSystemAccessor *new_accessor;
|
impl::FileSystemAccessor *new_accessor;
|
||||||
const char *old_sub_path;
|
const char *old_sub_path;
|
||||||
const char *new_sub_path;
|
const char *new_sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(old_accessor), std::addressof(old_sub_path), old_path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME, old_path, new_path));
|
R_TRY(impl::FindFileSystem(std::addressof(old_accessor), std::addressof(old_sub_path), old_path));
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(new_accessor), std::addressof(new_sub_path), new_path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME, old_path, new_path));
|
R_TRY(impl::FindFileSystem(std::addressof(new_accessor), std::addressof(new_sub_path), new_path));
|
||||||
|
|
||||||
auto rename_impl = [=]() -> Result {
|
R_UNLESS(old_accessor == new_accessor, fs::ResultRenameToOtherFileSystem());
|
||||||
R_UNLESS(old_accessor == new_accessor, fs::ResultRenameToOtherFileSystem());
|
return old_accessor->RenameFile(old_sub_path, new_sub_path);
|
||||||
R_TRY(old_accessor->RenameFile(old_sub_path, new_sub_path));
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(rename_impl(), nullptr, old_accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME, old_path, new_path));
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameDirectory(const char *old_path, const char *new_path) {
|
Result RenameDirectory(const char *old_path, const char *new_path) {
|
||||||
@@ -94,42 +83,30 @@ namespace ams::fs {
|
|||||||
impl::FileSystemAccessor *new_accessor;
|
impl::FileSystemAccessor *new_accessor;
|
||||||
const char *old_sub_path;
|
const char *old_sub_path;
|
||||||
const char *new_sub_path;
|
const char *new_sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(old_accessor), std::addressof(old_sub_path), old_path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME, old_path, new_path));
|
R_TRY(impl::FindFileSystem(std::addressof(old_accessor), std::addressof(old_sub_path), old_path));
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(new_accessor), std::addressof(new_sub_path), new_path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME, old_path, new_path));
|
R_TRY(impl::FindFileSystem(std::addressof(new_accessor), std::addressof(new_sub_path), new_path));
|
||||||
|
|
||||||
auto rename_impl = [=]() -> Result {
|
R_UNLESS(old_accessor == new_accessor, fs::ResultRenameToOtherFileSystem());
|
||||||
R_UNLESS(old_accessor == new_accessor, fs::ResultRenameToOtherFileSystem());
|
return old_accessor->RenameDirectory(old_sub_path, new_sub_path);
|
||||||
R_TRY(old_accessor->RenameDirectory(old_sub_path, new_sub_path));
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(rename_impl(), nullptr, old_accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME, old_path, new_path));
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetEntryType(DirectoryEntryType *out, const char *path) {
|
Result GetEntryType(DirectoryEntryType *out, const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->GetEntryType(out, sub_path), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_ENTRY_TYPE(out, path)));
|
return accessor->GetEntryType(out, sub_path);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_OPEN_MODE, path, static_cast<u32>(mode)));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
|
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
||||||
|
|
||||||
std::unique_ptr<impl::FileAccessor> file_accessor;
|
std::unique_ptr<impl::FileAccessor> file_accessor;
|
||||||
|
R_TRY(accessor->OpenFile(std::addressof(file_accessor), sub_path, static_cast<OpenMode>(mode)));
|
||||||
auto open_impl = [&]() -> Result {
|
|
||||||
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
|
||||||
R_TRY(accessor->OpenFile(std::addressof(file_accessor), sub_path, static_cast<OpenMode>(mode)));
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(open_impl(), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_OPEN_MODE, path, static_cast<u32>(mode)));
|
|
||||||
|
|
||||||
out_file->handle = file_accessor.release();
|
out_file->handle = file_accessor.release();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
@@ -138,17 +115,12 @@ namespace ams::fs {
|
|||||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path, int mode) {
|
Result OpenDirectory(DirectoryHandle *out_dir, const char *path, int mode) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_OPEN_MODE, path, static_cast<u32>(mode)));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
|
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
||||||
|
|
||||||
std::unique_ptr<impl::DirectoryAccessor> dir_accessor;
|
std::unique_ptr<impl::DirectoryAccessor> dir_accessor;
|
||||||
|
R_TRY(accessor->OpenDirectory(std::addressof(dir_accessor), sub_path, static_cast<OpenDirectoryMode>(mode)));
|
||||||
auto open_impl = [&]() -> Result {
|
|
||||||
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
|
||||||
R_TRY(accessor->OpenDirectory(std::addressof(dir_accessor), sub_path, static_cast<OpenDirectoryMode>(mode)));
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(open_impl(), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_OPEN_MODE, path, static_cast<u32>(mode)));
|
|
||||||
|
|
||||||
out_dir->handle = dir_accessor.release();
|
out_dir->handle = dir_accessor.release();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
@@ -157,86 +129,48 @@ namespace ams::fs {
|
|||||||
Result CleanDirectoryRecursively(const char *path) {
|
Result CleanDirectoryRecursively(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(accessor->CleanDirectoryRecursively(sub_path), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
return accessor->CleanDirectoryRecursively(sub_path);
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetFreeSpaceSize(s64 *out, const char *path) {
|
Result GetFreeSpaceSize(s64 *out, const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path = nullptr;
|
const char *sub_path;
|
||||||
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
/* Get the accessor. */
|
return accessor->GetFreeSpaceSize(out, sub_path);
|
||||||
auto find_impl = [&]() -> Result {
|
|
||||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
|
||||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
|
||||||
if (impl::IsValidMountName(path)) {
|
|
||||||
R_TRY(impl::Find(std::addressof(accessor), path));
|
|
||||||
} else {
|
|
||||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
|
||||||
}
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(find_impl(), AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
|
||||||
|
|
||||||
/* Get the space size. */
|
|
||||||
auto get_size_impl = [&]() -> Result {
|
|
||||||
R_UNLESS(sub_path == nullptr || std::strcmp(sub_path, "/") == 0, fs::ResultInvalidMountName());
|
|
||||||
R_TRY(accessor->GetFreeSpaceSize(out, path));
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(get_size_impl(), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetTotalSpaceSize(s64 *out, const char *path) {
|
Result GetTotalSpaceSize(s64 *out, const char *path) {
|
||||||
/* NOTE: Nintendo does not do access logging here, and does not support mount-name instead of path. */
|
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path = nullptr;
|
const char *sub_path;
|
||||||
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
/* Get the accessor. */
|
return accessor->GetTotalSpaceSize(out, sub_path);
|
||||||
auto find_impl = [&]() -> Result {
|
|
||||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
|
||||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
|
||||||
if (impl::IsValidMountName(path)) {
|
|
||||||
R_TRY(impl::Find(std::addressof(accessor), path));
|
|
||||||
} else {
|
|
||||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
|
||||||
}
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(find_impl(), AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
|
||||||
|
|
||||||
/* Get the space size. */
|
|
||||||
auto get_size_impl = [&]() -> Result {
|
|
||||||
R_UNLESS(sub_path == nullptr || std::strcmp(sub_path, "/") == 0, fs::ResultInvalidMountName());
|
|
||||||
R_TRY(accessor->GetTotalSpaceSize(out, path));
|
|
||||||
return ResultSuccess();
|
|
||||||
};
|
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(get_size_impl(), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetConcatenationFileAttribute(const char *path) {
|
Result SetConcatenationFileAttribute(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
const char *sub_path;
|
const char *sub_path;
|
||||||
AMS_FS_R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(accessor->QueryEntry(nullptr, 0, nullptr, 0, fsa::QueryId::SetConcatenationFileAttribute, sub_path));
|
return accessor->QueryEntry(nullptr, 0, nullptr, 0, fsa::QueryId::SetConcatenationFileAttribute, sub_path);
|
||||||
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path) {
|
||||||
|
impl::FileSystemAccessor *accessor;
|
||||||
|
const char *sub_path;
|
||||||
|
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||||
|
|
||||||
|
return accessor->GetFileTimeStampRaw(out, sub_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode) {
|
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode) {
|
||||||
AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||||
|
|
||||||
auto file_accessor = std::make_unique<impl::FileAccessor>(std::move(file), nullptr, static_cast<OpenMode>(mode));
|
auto file_accessor = std::make_unique<impl::FileAccessor>(std::move(file), nullptr, static_cast<OpenMode>(mode));
|
||||||
AMS_FS_R_UNLESS(file_accessor != nullptr, fs::ResultAllocationFailureInNew());
|
R_UNLESS(file_accessor != nullptr, fs::ResultAllocationFailureInNew());
|
||||||
out->handle = file_accessor.release();
|
out->handle = file_accessor.release();
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
@@ -244,22 +178,22 @@ namespace ams::fs {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
Result CommitImpl(const char *path, const char *func_name) {
|
Result CommitImpl(const char *path) {
|
||||||
impl::FileSystemAccessor *accessor;
|
impl::FileSystemAccessor *accessor;
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::Find(std::addressof(accessor), path), AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, path));
|
R_TRY(impl::Find(std::addressof(accessor), path));
|
||||||
|
|
||||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM_WITH_NAME(accessor->Commit(), nullptr, accessor, func_name, AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT, path));
|
return accessor->Commit();
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Commit(const char *path) {
|
Result Commit(const char *path) {
|
||||||
return CommitImpl(path, AMS_CURRENT_FUNCTION_NAME);
|
return CommitImpl(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CommitSaveData(const char *path) {
|
Result CommitSaveData(const char *path) {
|
||||||
return CommitImpl(path, AMS_CURRENT_FUNCTION_NAME);
|
return CommitImpl(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
#include "fs_filesystem_accessor.hpp"
|
|
||||||
#include "fs_file_accessor.hpp"
|
|
||||||
#include "fs_directory_accessor.hpp"
|
|
||||||
#include "fs_mount_utils.hpp"
|
|
||||||
#include "fs_user_mount_table.hpp"
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
Result GetFileTimeStampRawForDebug(FileTimeStampRaw *out, const char *path) {
|
|
||||||
impl::FileSystemAccessor *accessor;
|
|
||||||
const char *sub_path;
|
|
||||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
|
||||||
|
|
||||||
R_TRY(accessor->GetFileTimeStampRaw(out, sub_path));
|
|
||||||
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetFileTimeStampRawForDebug(FileTimeStampRaw *out, const char *path) {
|
|
||||||
AMS_FS_R_TRY(GetFileTimeStampRawForDebug(out, path));
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -73,8 +73,6 @@ namespace ams::fssystem {
|
|||||||
core_size = (size < buffer_round_up_difference) ? 0 : util::AlignDown(size - buffer_round_up_difference, data_alignment);
|
core_size = (size < buffer_round_up_difference) ? 0 : util::AlignDown(size - buffer_round_up_difference, data_alignment);
|
||||||
buffer_gap = buffer_round_up_difference;
|
buffer_gap = buffer_round_up_difference;
|
||||||
offset_gap = GetRoundDownDifference(offset, data_alignment);
|
offset_gap = GetRoundDownDifference(offset, data_alignment);
|
||||||
|
|
||||||
covered_offset = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the core portion. */
|
/* Read the core portion. */
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ namespace ams::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ContentManagerImpl::BuildContentMetaDatabase(StorageId storage_id) {
|
Result ContentManagerImpl::BuildContentMetaDatabase(StorageId storage_id) {
|
||||||
if (hos::GetVersion() < hos::Version_5_0_0) {
|
if (hos::GetVersion() <= hos::Version_4_0_0) {
|
||||||
/* Temporarily activate the database. */
|
/* Temporarily activate the database. */
|
||||||
R_TRY(this->ActivateContentMetaDatabase(storage_id));
|
R_TRY(this->ActivateContentMetaDatabase(storage_id));
|
||||||
ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); };
|
ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); };
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace ams::ncm {
|
|||||||
Result ReadVariationContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const Path &path, FirmwareVariationId firmware_variation_id) {
|
Result ReadVariationContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const Path &path, FirmwareVariationId firmware_variation_id) {
|
||||||
AutoBuffer meta;
|
AutoBuffer meta;
|
||||||
{
|
{
|
||||||
fs::ScopedAutoAbortDisabler aad;
|
/* TODO: fs::ScopedAutoAbortDisabler aad; */
|
||||||
R_TRY(ReadContentMetaPath(std::addressof(meta), path.str));
|
R_TRY(ReadContentMetaPath(std::addressof(meta), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1000,7 +1000,7 @@ namespace ams::ncm {
|
|||||||
Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version) {
|
Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version) {
|
||||||
AutoBuffer meta;
|
AutoBuffer meta;
|
||||||
{
|
{
|
||||||
fs::ScopedAutoAbortDisabler aad;
|
/* TODO: fs::ScopedAutoAbortDisabler aad; */
|
||||||
R_TRY(ReadContentMetaPath(std::addressof(meta), path.str));
|
R_TRY(ReadContentMetaPath(std::addressof(meta), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ namespace ams::os::impl {
|
|||||||
thread->name_buffer[0] = '\x00';
|
thread->name_buffer[0] = '\x00';
|
||||||
thread->name_pointer = thread->name_buffer;
|
thread->name_pointer = thread->name_buffer;
|
||||||
|
|
||||||
/* Set internal tls variables. */
|
|
||||||
thread->atomic_sf_inline_context = 0;
|
|
||||||
|
|
||||||
/* Mark initialized. */
|
/* Mark initialized. */
|
||||||
thread->state = ThreadType::State_Initialized;
|
thread->state = ThreadType::State_Initialized;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
namespace ams::os {
|
|
||||||
|
|
||||||
/* TODO: Nintendo reserves half the TLS slots for SDK usage. */
|
|
||||||
/* We don't have that ability...how should this work? */
|
|
||||||
Result SdkAllocateTlsSlot(TlsSlot *out, TlsDestructor destructor) {
|
|
||||||
return os::AllocateTlsSlot(out, destructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -21,71 +21,47 @@ namespace ams::sf {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext(os::ThreadType *thread) {
|
thread_local InlineContext g_inline_context;
|
||||||
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<uintptr_t>));
|
|
||||||
return reinterpret_cast<std::atomic<uintptr_t> *>(std::addressof(thread->atomic_sf_inline_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext() {
|
ALWAYS_INLINE void OnSetInlineContext() {
|
||||||
return GetAtomicSfInlineContext(os::GetCurrentThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE void OnSetInlineContext(os::ThreadType *thread) {
|
|
||||||
/* Ensure that libnx receives the priority value. */
|
/* Ensure that libnx receives the priority value. */
|
||||||
::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext(thread)));
|
::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineContext GetInlineContext() {
|
InlineContext GetInlineContext() {
|
||||||
/* Get the context. */
|
|
||||||
uintptr_t thread_context = GetAtomicSfInlineContext()->load();
|
|
||||||
|
|
||||||
/* Copy it out. */
|
|
||||||
InlineContext ctx;
|
InlineContext ctx;
|
||||||
static_assert(sizeof(ctx) <= sizeof(thread_context));
|
std::memcpy(std::addressof(ctx), std::addressof(::ams::sf::cmif::g_inline_context), sizeof(ctx));
|
||||||
std::memcpy(std::addressof(ctx), std::addressof(thread_context), sizeof(ctx));
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineContext SetInlineContext(InlineContext ctx) {
|
InlineContext SetInlineContext(InlineContext ctx) {
|
||||||
/* Get current thread. */
|
ON_SCOPE_EXIT { OnSetInlineContext(); };
|
||||||
os::ThreadType * const cur_thread = os::GetCurrentThread();
|
static_assert(sizeof(ctx) <= sizeof(g_inline_context));
|
||||||
ON_SCOPE_EXIT { OnSetInlineContext(cur_thread); };
|
|
||||||
|
|
||||||
/* Create the new context. */
|
|
||||||
static_assert(sizeof(ctx) <= sizeof(uintptr_t));
|
|
||||||
uintptr_t new_context_value = 0;
|
|
||||||
std::memcpy(std::addressof(new_context_value), std::addressof(ctx), sizeof(ctx));
|
|
||||||
|
|
||||||
/* Get the old context. */
|
|
||||||
uintptr_t old_context_value = GetAtomicSfInlineContext(cur_thread)->exchange(new_context_value);
|
|
||||||
|
|
||||||
/* Convert and copy it out. */
|
|
||||||
InlineContext old_ctx;
|
InlineContext old_ctx;
|
||||||
std::memcpy(std::addressof(old_ctx), std::addressof(old_context_value), sizeof(old_ctx));
|
std::memcpy(std::addressof(old_ctx), std::addressof(g_inline_context), sizeof(old_ctx));
|
||||||
|
std::memcpy(std::addressof(g_inline_context), std::addressof(ctx), sizeof(ctx));
|
||||||
return old_ctx;
|
return old_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
u8 GetFsInlineContext() {
|
||||||
|
u8 ctx;
|
||||||
ALWAYS_INLINE std::atomic<u8> *GetAtomicFsInlineContext(os::ThreadType *thread) {
|
std::memcpy(std::addressof(ctx), std::addressof(cmif::g_inline_context), sizeof(ctx));
|
||||||
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<u8>));
|
return ctx;
|
||||||
return reinterpret_cast<std::atomic<u8> *>(std::addressof(thread->atomic_sf_inline_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 GetFsInlineContext(os::ThreadType *thread) {
|
u8 SetFsInlineContext(u8 ctx) {
|
||||||
return GetAtomicFsInlineContext(thread)->load();
|
ON_SCOPE_EXIT { cmif::OnSetInlineContext(); };
|
||||||
}
|
static_assert(sizeof(ctx) <= sizeof(cmif::g_inline_context));
|
||||||
|
|
||||||
u8 SetFsInlineContext(os::ThreadType *thread, u8 ctx) {
|
u8 old_ctx;
|
||||||
ON_SCOPE_EXIT { cmif::OnSetInlineContext(thread); };
|
std::memcpy(std::addressof(old_ctx), std::addressof(cmif::g_inline_context), sizeof(old_ctx));
|
||||||
|
std::memcpy(std::addressof(cmif::g_inline_context), std::addressof(ctx), sizeof(ctx));
|
||||||
return GetAtomicFsInlineContext(thread)->exchange(ctx);
|
return old_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,6 @@
|
|||||||
|
|
||||||
#define BITSIZEOF(x) (sizeof(x) * CHAR_BIT)
|
#define BITSIZEOF(x) (sizeof(x) * CHAR_BIT)
|
||||||
|
|
||||||
#define STRINGIZE(x) STRINGIZE_IMPL(x)
|
|
||||||
#define STRINGIZE_IMPL(x) #x
|
|
||||||
|
|
||||||
#ifdef __COUNTER__
|
#ifdef __COUNTER__
|
||||||
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
|
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cinttypes>
|
|
||||||
|
|
||||||
/* C++ headers. */
|
/* C++ headers. */
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|||||||
@@ -21,389 +21,386 @@ namespace ams::fs {
|
|||||||
|
|
||||||
R_DEFINE_NAMESPACE_RESULT_MODULE(2);
|
R_DEFINE_NAMESPACE_RESULT_MODULE(2);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(HandledByAllProcess, 0, 999);
|
R_DEFINE_ERROR_RESULT(PathNotFound, 1);
|
||||||
R_DEFINE_ERROR_RESULT(PathNotFound, 1);
|
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2);
|
||||||
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2);
|
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(TargetLocked, 7);
|
R_DEFINE_ERROR_RESULT(TargetLocked, 7);
|
||||||
R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8);
|
R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45);
|
R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45);
|
||||||
R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38);
|
R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38);
|
||||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35);
|
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35);
|
||||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36);
|
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36);
|
||||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37);
|
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37);
|
||||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38);
|
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38);
|
||||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39);
|
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedSdkVersion, 50);
|
R_DEFINE_ERROR_RESULT(UnsupportedSdkVersion, 50);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60);
|
R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(HandledBySystemProcess, 1000, 2999);
|
R_DEFINE_ERROR_RESULT(PartitionNotFound, 1001);
|
||||||
R_DEFINE_ERROR_RESULT(PartitionNotFound, 1001);
|
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002);
|
||||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002);
|
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499);
|
R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499);
|
||||||
R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);
|
R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999);
|
R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(NotImplemented, 3001);
|
R_DEFINE_ERROR_RESULT(NotImplemented, 3001);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedVersion, 3002);
|
R_DEFINE_ERROR_RESULT(UnsupportedVersion, 3002);
|
||||||
R_DEFINE_ERROR_RESULT(OutOfRange, 3005);
|
R_DEFINE_ERROR_RESULT(OutOfRange, 3005);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(SystemPartitionNotReady, 3100);
|
R_DEFINE_ERROR_RESULT(SystemPartitionNotReady, 3100);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499);
|
R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorA, 3211);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorA, 3211);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorB, 3212);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorB, 3212);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInApplicationA, 3213);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInApplicationA, 3213);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInBisA, 3215);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInBisA, 3215);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInBisB, 3216);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInBisB, 3216);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInBisC, 3217);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInBisC, 3217);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInCodeA, 3218);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInCodeA, 3218);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInContentA, 3219);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInContentA, 3219);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageA, 3220);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageA, 3220);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageB, 3221);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageB, 3221);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDataA, 3222);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInDataA, 3222);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDataB, 3223);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInDataB, 3223);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDeviceSaveDataA, 3224);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInDeviceSaveDataA, 3224);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardA, 3225);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardA, 3225);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardB, 3226);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardB, 3226);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardC, 3227);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardC, 3227);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardD, 3228);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardD, 3228);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInImageDirectoryA, 3232);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInImageDirectoryA, 3232);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardA, 3244);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardA, 3244);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardB, 3245);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardB, 3245);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSystemSaveDataA, 3246);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInSystemSaveDataA, 3246);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemA, 3247);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemA, 3247);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemB, 3248);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemB, 3248);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemC, 3249);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemC, 3249);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplD, 3256);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplD, 3256);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplE, 3257);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplE, 3257);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemCreatorA, 3280);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemCreatorA, 3280);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFileSystemCreatorA, 3281);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFileSystemCreatorA, 3281);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorA, 3288);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorA, 3288);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorB, 3289);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorB, 3289);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBuddyHeapA, 3294);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBuddyHeapA, 3294);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBufferManagerA, 3295);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBufferManagerA, 3295);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageA, 3296);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageA, 3296);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageB, 3297);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageB, 3297);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageA, 3304);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageA, 3304);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageB, 3305);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageB, 3305);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInNcaFileSystemDriverI, 3341);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInNcaFileSystemDriverI, 3341);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemA, 3347);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemA, 3347);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemB, 3348);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemB, 3348);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemC, 3349);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemC, 3349);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaA, 3350);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaA, 3350);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaB, 3351);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaB, 3351);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemD, 3352);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemD, 3352);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInNcaReaderA, 3363);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInNcaReaderA, 3363);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterA, 3365);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterA, 3365);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterB, 3366);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterB, 3366);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPathNormalizer, 3367);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInPathNormalizer, 3367);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDbmRomKeyValueStorage, 3375);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInDbmRomKeyValueStorage, 3375);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemE, 3377);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemE, 3377);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInReadOnlyFileSystemA, 3386);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInReadOnlyFileSystemA, 3386);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageA, 3399);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageA, 3399);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageB, 3400);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageB, 3400);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemInterfaceAdapter, 3407);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemInterfaceAdapter, 3407);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInBufferedStorageA, 3411);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInBufferedStorageA, 3411);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityRomFsStorageA, 3412);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityRomFsStorageA, 3412);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInNew, 3420);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInNew, 3420);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInMakeUnique, 3422);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInMakeUnique, 3422);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailureInAllocateShared, 3423);
|
R_DEFINE_ERROR_RESULT(AllocationFailureInAllocateShared, 3423);
|
||||||
R_DEFINE_ERROR_RESULT(AllocationFailurePooledBufferNotEnoughSize, 3424);
|
R_DEFINE_ERROR_RESULT(AllocationFailurePooledBufferNotEnoughSize, 3424);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(Internal, 3000, 7999);
|
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
|
||||||
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
|
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999);
|
R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999);
|
||||||
R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299);
|
R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedRomVersion, 4002);
|
R_DEFINE_ERROR_RESULT(UnsupportedRomVersion, 4002);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(AesCtrCounterExtendedStorageCorrupted, 4011, 4019);
|
R_DEFINE_ERROR_RANGE(AesCtrCounterExtendedStorageCorrupted, 4011, 4019);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedEntryOffset, 4012);
|
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedEntryOffset, 4012);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedTableSize, 4013);
|
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedTableSize, 4013);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedGeneration, 4014);
|
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedGeneration, 4014);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedOffset, 4015);
|
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedOffset, 4015);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(IndirectStorageCorrupted, 4021, 4029);
|
R_DEFINE_ERROR_RANGE(IndirectStorageCorrupted, 4021, 4029);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidIndirectEntryOffset, 4022);
|
R_DEFINE_ERROR_RESULT(InvalidIndirectEntryOffset, 4022);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidIndirectEntryStorageIndex, 4023);
|
R_DEFINE_ERROR_RESULT(InvalidIndirectEntryStorageIndex, 4023);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidIndirectStorageSize, 4024);
|
R_DEFINE_ERROR_RESULT(InvalidIndirectStorageSize, 4024);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidIndirectVirtualOffset, 4025);
|
R_DEFINE_ERROR_RESULT(InvalidIndirectVirtualOffset, 4025);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidIndirectPhysicalOffset, 4026);
|
R_DEFINE_ERROR_RESULT(InvalidIndirectPhysicalOffset, 4026);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidIndirectStorageIndex, 4027);
|
R_DEFINE_ERROR_RESULT(InvalidIndirectStorageIndex, 4027);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(BucketTreeCorrupted, 4031, 4039);
|
R_DEFINE_ERROR_RANGE(BucketTreeCorrupted, 4031, 4039);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeSignature, 4032);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeSignature, 4032);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryCount, 4033);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryCount, 4033);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeEntryCount, 4034);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeEntryCount, 4034);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeOffset, 4035);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeOffset, 4035);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryOffset, 4036);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryOffset, 4036);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntrySetOffset, 4037);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntrySetOffset, 4037);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeIndex, 4038);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeIndex, 4038);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidBucketTreeVirtualOffset, 4039);
|
R_DEFINE_ERROR_RESULT(InvalidBucketTreeVirtualOffset, 4039);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomNcaCorrupted, 4041, 4139);
|
R_DEFINE_ERROR_RANGE(RomNcaCorrupted, 4041, 4139);
|
||||||
R_DEFINE_ERROR_RANGE(RomNcaFileSystemCorrupted, 4051, 4069);
|
R_DEFINE_ERROR_RANGE(RomNcaFileSystemCorrupted, 4051, 4069);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomNcaFileSystemType, 4052);
|
R_DEFINE_ERROR_RESULT(InvalidRomNcaFileSystemType, 4052);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomAcidFileSize, 4053);
|
R_DEFINE_ERROR_RESULT(InvalidRomAcidFileSize, 4053);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomAcidSize, 4054);
|
R_DEFINE_ERROR_RESULT(InvalidRomAcidSize, 4054);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomAcid, 4055);
|
R_DEFINE_ERROR_RESULT(InvalidRomAcid, 4055);
|
||||||
R_DEFINE_ERROR_RESULT(RomAcidVerificationFailed, 4056);
|
R_DEFINE_ERROR_RESULT(RomAcidVerificationFailed, 4056);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomNcaSignature, 4057);
|
R_DEFINE_ERROR_RESULT(InvalidRomNcaSignature, 4057);
|
||||||
R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature1VerificationFailed, 4058);
|
R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature1VerificationFailed, 4058);
|
||||||
R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature2VerificationFailed, 4059);
|
R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature2VerificationFailed, 4059);
|
||||||
R_DEFINE_ERROR_RESULT(RomNcaFsHeaderHashVerificationFailed, 4060);
|
R_DEFINE_ERROR_RESULT(RomNcaFsHeaderHashVerificationFailed, 4060);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomNcaKeyIndex, 4061);
|
R_DEFINE_ERROR_RESULT(InvalidRomNcaKeyIndex, 4061);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderHashType, 4062);
|
R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderHashType, 4062);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderEncryptionType, 4063);
|
R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderEncryptionType, 4063);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomNcaHierarchicalSha256StorageCorrupted, 4071, 4079);
|
R_DEFINE_ERROR_RANGE(RomNcaHierarchicalSha256StorageCorrupted, 4071, 4079);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256BlockSize, 4072);
|
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256BlockSize, 4072);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256LayerCount, 4073);
|
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256LayerCount, 4073);
|
||||||
R_DEFINE_ERROR_RESULT(RomHierarchicalSha256BaseStorageTooLarge, 4074);
|
R_DEFINE_ERROR_RESULT(RomHierarchicalSha256BaseStorageTooLarge, 4074);
|
||||||
R_DEFINE_ERROR_RESULT(RomHierarchicalSha256HashVerificationFailed, 4075);
|
R_DEFINE_ERROR_RESULT(RomHierarchicalSha256HashVerificationFailed, 4075);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomIntegrityVerificationStorageCorrupted, 4141, 4179);
|
R_DEFINE_ERROR_RANGE(RomIntegrityVerificationStorageCorrupted, 4141, 4179);
|
||||||
R_DEFINE_ERROR_RESULT(IncorrectRomIntegrityVerificationMagic, 4142);
|
R_DEFINE_ERROR_RESULT(IncorrectRomIntegrityVerificationMagic, 4142);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomZeroHash, 4143);
|
R_DEFINE_ERROR_RESULT(InvalidRomZeroHash, 4143);
|
||||||
R_DEFINE_ERROR_RESULT(RomNonRealDataVerificationFailed, 4144);
|
R_DEFINE_ERROR_RESULT(RomNonRealDataVerificationFailed, 4144);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalIntegrityVerificationLayerCount, 4145);
|
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalIntegrityVerificationLayerCount, 4145);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomRealDataVerificationFailed, 4151, 4159);
|
R_DEFINE_ERROR_RANGE(RomRealDataVerificationFailed, 4151, 4159);
|
||||||
R_DEFINE_ERROR_RESULT(ClearedRomRealDataVerificationFailed, 4152);
|
R_DEFINE_ERROR_RESULT(ClearedRomRealDataVerificationFailed, 4152);
|
||||||
R_DEFINE_ERROR_RESULT(UnclearedRomRealDataVerificationFailed, 4153);
|
R_DEFINE_ERROR_RESULT(UnclearedRomRealDataVerificationFailed, 4153);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomPartitionFileSystemCorrupted, 4181, 4199);
|
R_DEFINE_ERROR_RANGE(RomPartitionFileSystemCorrupted, 4181, 4199);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionHashTarget, 4182);
|
R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionHashTarget, 4182);
|
||||||
R_DEFINE_ERROR_RESULT(RomSha256PartitionHashVerificationFailed, 4183);
|
R_DEFINE_ERROR_RESULT(RomSha256PartitionHashVerificationFailed, 4183);
|
||||||
R_DEFINE_ERROR_RESULT(RomPartitionSignatureVerificationFailed, 4184);
|
R_DEFINE_ERROR_RESULT(RomPartitionSignatureVerificationFailed, 4184);
|
||||||
R_DEFINE_ERROR_RESULT(RomSha256PartitionSignatureVerificationFailed, 4185);
|
R_DEFINE_ERROR_RESULT(RomSha256PartitionSignatureVerificationFailed, 4185);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomPartitionEntryOffset, 4186);
|
R_DEFINE_ERROR_RESULT(InvalidRomPartitionEntryOffset, 4186);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionMetaDataSize, 4187);
|
R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionMetaDataSize, 4187);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomBuiltInStorageCorrupted, 4201, 4219);
|
R_DEFINE_ERROR_RANGE(RomBuiltInStorageCorrupted, 4201, 4219);
|
||||||
R_DEFINE_ERROR_RESULT(RomGptHeaderVerificationFailed, 4202);
|
R_DEFINE_ERROR_RESULT(RomGptHeaderVerificationFailed, 4202);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomHostFileSystemCorrupted, 4241, 4259);
|
R_DEFINE_ERROR_RANGE(RomHostFileSystemCorrupted, 4241, 4259);
|
||||||
R_DEFINE_ERROR_RESULT(RomHostEntryCorrupted, 4242);
|
R_DEFINE_ERROR_RESULT(RomHostEntryCorrupted, 4242);
|
||||||
R_DEFINE_ERROR_RESULT(RomHostFileDataCorrupted, 4243);
|
R_DEFINE_ERROR_RESULT(RomHostFileDataCorrupted, 4243);
|
||||||
R_DEFINE_ERROR_RESULT(RomHostFileCorrupted, 4244);
|
R_DEFINE_ERROR_RESULT(RomHostFileCorrupted, 4244);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomHostHandle, 4245);
|
R_DEFINE_ERROR_RESULT(InvalidRomHostHandle, 4245);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RomDatabaseCorrupted, 4261, 4279);
|
R_DEFINE_ERROR_RANGE(RomDatabaseCorrupted, 4261, 4279);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomAllocationTableBlock, 4262);
|
R_DEFINE_ERROR_RESULT(InvalidRomAllocationTableBlock, 4262);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidRomKeyValueListElementIndex, 4263);
|
R_DEFINE_ERROR_RESULT(InvalidRomKeyValueListElementIndex, 4263);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499);
|
R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499);
|
||||||
R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599);
|
R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599);
|
||||||
R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeA, 4508);
|
R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeA, 4508);
|
||||||
R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeB, 4509);
|
R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeB, 4509);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(NcaFileSystemCorrupted, 4511, 4529);
|
R_DEFINE_ERROR_RANGE(NcaFileSystemCorrupted, 4511, 4529);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaFileSystemType, 4512);
|
R_DEFINE_ERROR_RESULT(InvalidNcaFileSystemType, 4512);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAcidFileSize, 4513);
|
R_DEFINE_ERROR_RESULT(InvalidAcidFileSize, 4513);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAcidSize, 4514);
|
R_DEFINE_ERROR_RESULT(InvalidAcidSize, 4514);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAcid, 4515);
|
R_DEFINE_ERROR_RESULT(InvalidAcid, 4515);
|
||||||
R_DEFINE_ERROR_RESULT(AcidVerificationFailed, 4516);
|
R_DEFINE_ERROR_RESULT(AcidVerificationFailed, 4516);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 4517);
|
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 4517);
|
||||||
R_DEFINE_ERROR_RESULT(NcaHeaderSignature1VerificationFailed, 4518);
|
R_DEFINE_ERROR_RESULT(NcaHeaderSignature1VerificationFailed, 4518);
|
||||||
R_DEFINE_ERROR_RESULT(NcaHeaderSignature2VerificationFailed, 4519);
|
R_DEFINE_ERROR_RESULT(NcaHeaderSignature2VerificationFailed, 4519);
|
||||||
R_DEFINE_ERROR_RESULT(NcaFsHeaderHashVerificationFailed, 4520);
|
R_DEFINE_ERROR_RESULT(NcaFsHeaderHashVerificationFailed, 4520);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaKeyIndex, 4521);
|
R_DEFINE_ERROR_RESULT(InvalidNcaKeyIndex, 4521);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderHashType, 4522);
|
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderHashType, 4522);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderEncryptionType, 4523);
|
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderEncryptionType, 4523);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoIndirectSize, 4524);
|
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoIndirectSize, 4524);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExSize, 4525);
|
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExSize, 4525);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExOffset, 4526);
|
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExOffset, 4526);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaId, 4527);
|
R_DEFINE_ERROR_RESULT(InvalidNcaId, 4527);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaHeader, 4528);
|
R_DEFINE_ERROR_RESULT(InvalidNcaHeader, 4528);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeader, 4529);
|
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeader, 4529);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(NcaHierarchicalSha256StorageCorrupted, 4531, 4539);
|
R_DEFINE_ERROR_RANGE(NcaHierarchicalSha256StorageCorrupted, 4531, 4539);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256BlockSize, 4532);
|
R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256BlockSize, 4532);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256LayerCount, 4533);
|
R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256LayerCount, 4533);
|
||||||
R_DEFINE_ERROR_RESULT(HierarchicalSha256BaseStorageTooLarge, 4534);
|
R_DEFINE_ERROR_RESULT(HierarchicalSha256BaseStorageTooLarge, 4534);
|
||||||
R_DEFINE_ERROR_RESULT(HierarchicalSha256HashVerificationFailed, 4535);
|
R_DEFINE_ERROR_RESULT(HierarchicalSha256HashVerificationFailed, 4535);
|
||||||
|
|
||||||
/* TODO: Range? */
|
/* TODO: Range? */
|
||||||
R_DEFINE_ERROR_RESULT(InvalidNcaHeader1SignatureKeyGeneration, 4543);
|
R_DEFINE_ERROR_RESULT(InvalidNcaHeader1SignatureKeyGeneration, 4543);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639);
|
R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639);
|
||||||
R_DEFINE_ERROR_RESULT(IncorrectIntegrityVerificationMagic, 4602);
|
R_DEFINE_ERROR_RESULT(IncorrectIntegrityVerificationMagic, 4602);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidZeroHash, 4603);
|
R_DEFINE_ERROR_RESULT(InvalidZeroHash, 4603);
|
||||||
R_DEFINE_ERROR_RESULT(NonRealDataVerificationFailed, 4604);
|
R_DEFINE_ERROR_RESULT(NonRealDataVerificationFailed, 4604);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidHierarchicalIntegrityVerificationLayerCount, 4605);
|
R_DEFINE_ERROR_RESULT(InvalidHierarchicalIntegrityVerificationLayerCount, 4605);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(RealDataVerificationFailed, 4611, 4619);
|
R_DEFINE_ERROR_RANGE(RealDataVerificationFailed, 4611, 4619);
|
||||||
R_DEFINE_ERROR_RESULT(ClearedRealDataVerificationFailed, 4612);
|
R_DEFINE_ERROR_RESULT(ClearedRealDataVerificationFailed, 4612);
|
||||||
R_DEFINE_ERROR_RESULT(UnclearedRealDataVerificationFailed, 4613);
|
R_DEFINE_ERROR_RESULT(UnclearedRealDataVerificationFailed, 4613);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659);
|
R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidSha256PartitionHashTarget, 4642);
|
R_DEFINE_ERROR_RESULT(InvalidSha256PartitionHashTarget, 4642);
|
||||||
R_DEFINE_ERROR_RESULT(Sha256PartitionHashVerificationFailed, 4643);
|
R_DEFINE_ERROR_RESULT(Sha256PartitionHashVerificationFailed, 4643);
|
||||||
R_DEFINE_ERROR_RESULT(PartitionSignatureVerificationFailed, 4644);
|
R_DEFINE_ERROR_RESULT(PartitionSignatureVerificationFailed, 4644);
|
||||||
R_DEFINE_ERROR_RESULT(Sha256PartitionSignatureVerificationFailed, 4645);
|
R_DEFINE_ERROR_RESULT(Sha256PartitionSignatureVerificationFailed, 4645);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidPartitionEntryOffset, 4646);
|
R_DEFINE_ERROR_RESULT(InvalidPartitionEntryOffset, 4646);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidSha256PartitionMetaDataSize, 4647);
|
R_DEFINE_ERROR_RESULT(InvalidSha256PartitionMetaDataSize, 4647);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679);
|
R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679);
|
||||||
R_DEFINE_ERROR_RESULT(GptHeaderVerificationFailed, 4662);
|
R_DEFINE_ERROR_RESULT(GptHeaderVerificationFailed, 4662);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(FatFileSystemCorrupted, 4681, 4699);
|
R_DEFINE_ERROR_RANGE(FatFileSystemCorrupted, 4681, 4699);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719);
|
R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719);
|
||||||
R_DEFINE_ERROR_RESULT(HostEntryCorrupted, 4702);
|
R_DEFINE_ERROR_RESULT(HostEntryCorrupted, 4702);
|
||||||
R_DEFINE_ERROR_RESULT(HostFileDataCorrupted, 4703);
|
R_DEFINE_ERROR_RESULT(HostFileDataCorrupted, 4703);
|
||||||
R_DEFINE_ERROR_RESULT(HostFileCorrupted, 4704);
|
R_DEFINE_ERROR_RESULT(HostFileCorrupted, 4704);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidHostHandle, 4705);
|
R_DEFINE_ERROR_RESULT(InvalidHostHandle, 4705);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739);
|
R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAllocationTableBlock, 4722);
|
R_DEFINE_ERROR_RESULT(InvalidAllocationTableBlock, 4722);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidKeyValueListElementIndex, 4723);
|
R_DEFINE_ERROR_RESULT(InvalidKeyValueListElementIndex, 4723);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759);
|
R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759);
|
||||||
R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769);
|
R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769);
|
||||||
R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779);
|
R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781);
|
R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999);
|
R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedInAesCtrStorageA, 5315);
|
R_DEFINE_ERROR_RESULT(UnexpectedInAesCtrStorageA, 5315);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedInAesXtsStorageA, 5316);
|
R_DEFINE_ERROR_RESULT(UnexpectedInAesXtsStorageA, 5316);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedInFindFileSystemA, 5319);
|
R_DEFINE_ERROR_RESULT(UnexpectedInFindFileSystemA, 5319);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499);
|
R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499);
|
||||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199);
|
R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199);
|
||||||
R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029);
|
R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029);
|
||||||
R_DEFINE_ERROR_RESULT(TooLongPath, 6003);
|
R_DEFINE_ERROR_RESULT(TooLongPath, 6003);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004);
|
R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005);
|
R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005);
|
||||||
R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006);
|
R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006);
|
||||||
R_DEFINE_ERROR_RESULT(NotNormalized, 6007);
|
R_DEFINE_ERROR_RESULT(NotNormalized, 6007);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(InvalidPathForOperation, 6030, 6059);
|
R_DEFINE_ERROR_RANGE(InvalidPathForOperation, 6030, 6059);
|
||||||
R_DEFINE_ERROR_RESULT(DirectoryNotDeletable, 6031);
|
R_DEFINE_ERROR_RESULT(DirectoryNotDeletable, 6031);
|
||||||
R_DEFINE_ERROR_RESULT(DirectoryNotRenamable, 6032);
|
R_DEFINE_ERROR_RESULT(DirectoryNotRenamable, 6032);
|
||||||
R_DEFINE_ERROR_RESULT(IncompatiblePath, 6033);
|
R_DEFINE_ERROR_RESULT(IncompatiblePath, 6033);
|
||||||
R_DEFINE_ERROR_RESULT(RenameToOtherFileSystem, 6034);
|
R_DEFINE_ERROR_RESULT(RenameToOtherFileSystem, 6034);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 6061);
|
R_DEFINE_ERROR_RESULT(InvalidOffset, 6061);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6062);
|
R_DEFINE_ERROR_RESULT(InvalidSize, 6062);
|
||||||
R_DEFINE_ERROR_RESULT(NullptrArgument, 6063);
|
R_DEFINE_ERROR_RESULT(NullptrArgument, 6063);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064);
|
R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidMountName, 6065);
|
R_DEFINE_ERROR_RESULT(InvalidMountName, 6065);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066);
|
R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066);
|
||||||
R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067);
|
R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(InvalidOpenMode, 6072);
|
R_DEFINE_ERROR_RESULT(InvalidOpenMode, 6072);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099);
|
R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081);
|
R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082);
|
R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299);
|
R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299);
|
||||||
R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201);
|
R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201);
|
||||||
R_DEFINE_ERROR_RESULT(ReadNotPermitted, 6202);
|
R_DEFINE_ERROR_RESULT(ReadNotPermitted, 6202);
|
||||||
R_DEFINE_ERROR_RESULT(WriteNotPermitted, 6203);
|
R_DEFINE_ERROR_RESULT(WriteNotPermitted, 6203);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399);
|
R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageA, 6302);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageA, 6302);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageB, 6303);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageB, 6303);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageA, 6304);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageA, 6304);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageB, 6305);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageB, 6305);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageA, 6306);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageA, 6306);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageB, 6307);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageB, 6307);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSwitchStorageA, 6308);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSwitchStorageA, 6308);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageA, 6310);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageA, 6310);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageB, 6311);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageB, 6311);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageC, 6312);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageC, 6312);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalA, 6313);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalA, 6313);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalB, 6314);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalB, 6314);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageA, 6315);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageA, 6315);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageA, 6316);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageA, 6316);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageB, 6317);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageB, 6317);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageA, 6318);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageA, 6318);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageB, 6319);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageB, 6319);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageC, 6320);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageC, 6320);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageA, 6321);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageA, 6321);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageB, 6322);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageB, 6322);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageC, 6323);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageC, 6323);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageA, 6324);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageA, 6324);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageB, 6325);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageB, 6325);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageC, 6326);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageC, 6326);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageA, 6327);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageA, 6327);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageB, 6328);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageB, 6328);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalSha256StorageA, 6329);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalSha256StorageA, 6329);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageA, 6330);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageA, 6330);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageB, 6331);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageB, 6331);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityRomFsStorageA , 6332);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityRomFsStorageA , 6332);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileServiceObjectAdapterA, 6362);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileServiceObjectAdapterA, 6362);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemA, 6364);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemA, 6364);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemB, 6365);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemB, 6365);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemC, 6366);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemC, 6366);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileA, 6367);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileA, 6367);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileB, 6368);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileB, 6368);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateA, 6369);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateA, 6369);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateB, 6370);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateB, 6370);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateC, 6371);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateC, 6371);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileA, 6372);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileA, 6372);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileB, 6373);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileB, 6373);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemA, 6374);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemA, 6374);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemB, 6375);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemB, 6375);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileA, 6376);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileA, 6376);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileB, 6377);
|
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileB, 6377);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449);
|
R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(NeedFlush, 6454);
|
R_DEFINE_ERROR_RESULT(NeedFlush, 6454);
|
||||||
R_DEFINE_ERROR_RESULT(FileNotClosed, 6455);
|
R_DEFINE_ERROR_RESULT(FileNotClosed, 6455);
|
||||||
R_DEFINE_ERROR_RESULT(DirectoryNotClosed, 6456);
|
R_DEFINE_ERROR_RESULT(DirectoryNotClosed, 6456);
|
||||||
R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457);
|
R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457);
|
||||||
R_DEFINE_ERROR_RESULT(AllocatorAlreadyRegistered, 6458);
|
R_DEFINE_ERROR_RESULT(AllocatorAlreadyRegistered, 6458);
|
||||||
R_DEFINE_ERROR_RESULT(DefaultAllocatorUsed, 6459);
|
R_DEFINE_ERROR_RESULT(DefaultAllocatorUsed, 6459);
|
||||||
R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461);
|
R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461);
|
||||||
R_DEFINE_ERROR_RESULT(UserNotExist, 6465);
|
R_DEFINE_ERROR_RESULT(UserNotExist, 6465);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(NotFound, 6600, 6699);
|
R_DEFINE_ERROR_RANGE(NotFound, 6600, 6699);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799);
|
R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799);
|
||||||
R_DEFINE_ERROR_RESULT(BufferAllocationFailed, 6705);
|
R_DEFINE_ERROR_RESULT(BufferAllocationFailed, 6705);
|
||||||
R_DEFINE_ERROR_RESULT(MappingTableFull, 6706);
|
R_DEFINE_ERROR_RESULT(MappingTableFull, 6706);
|
||||||
R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709);
|
R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899);
|
R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899);
|
||||||
R_DEFINE_ERROR_RESULT(MapFull, 6811);
|
R_DEFINE_ERROR_RESULT(MapFull, 6811);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(BadState, 6900, 6999);
|
R_DEFINE_ERROR_RANGE(BadState, 6900, 6999);
|
||||||
R_DEFINE_ERROR_RESULT(NotInitialized, 6902);
|
R_DEFINE_ERROR_RESULT(NotInitialized, 6902);
|
||||||
R_DEFINE_ERROR_RESULT(NotMounted, 6905);
|
R_DEFINE_ERROR_RESULT(NotMounted, 6905);
|
||||||
|
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904);
|
R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904);
|
||||||
R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902);
|
R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902);
|
||||||
R_DEFINE_ERROR_RESULT(DbmFileNotFound, 7903);
|
R_DEFINE_ERROR_RESULT(DbmFileNotFound, 7903);
|
||||||
R_DEFINE_ERROR_RESULT(DbmDirectoryNotFound, 7904);
|
R_DEFINE_ERROR_RESULT(DbmDirectoryNotFound, 7904);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(DbmAlreadyExists, 7906);
|
R_DEFINE_ERROR_RESULT(DbmAlreadyExists, 7906);
|
||||||
R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907);
|
R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907);
|
||||||
R_DEFINE_ERROR_RESULT(DbmDirectoryEntryFull, 7908);
|
R_DEFINE_ERROR_RESULT(DbmDirectoryEntryFull, 7908);
|
||||||
R_DEFINE_ERROR_RESULT(DbmFileEntryFull, 7909);
|
R_DEFINE_ERROR_RESULT(DbmFileEntryFull, 7909);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RANGE(DbmFindFinished, 7910, 7912);
|
R_DEFINE_ERROR_RANGE(DbmFindFinished, 7910, 7912);
|
||||||
R_DEFINE_ERROR_RESULT(DbmFindKeyFinished, 7911);
|
R_DEFINE_ERROR_RESULT(DbmFindKeyFinished, 7911);
|
||||||
R_DEFINE_ERROR_RESULT(DbmIterationFinished, 7912);
|
R_DEFINE_ERROR_RESULT(DbmIterationFinished, 7912);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(DbmInvalidOperation, 7914);
|
R_DEFINE_ERROR_RESULT(DbmInvalidOperation, 7914);
|
||||||
R_DEFINE_ERROR_RESULT(DbmInvalidPathFormat, 7915);
|
R_DEFINE_ERROR_RESULT(DbmInvalidPathFormat, 7915);
|
||||||
R_DEFINE_ERROR_RESULT(DbmDirectoryNameTooLong, 7916);
|
R_DEFINE_ERROR_RESULT(DbmDirectoryNameTooLong, 7916);
|
||||||
R_DEFINE_ERROR_RESULT(DbmFileNameTooLong, 7917);
|
R_DEFINE_ERROR_RESULT(DbmFileNameTooLong, 7917);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,9 +86,6 @@ void __appInit(void) {
|
|||||||
spl::InitializeForFs();
|
spl::InitializeForFs();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Disable auto-abort in fs operations. */
|
|
||||||
fs::SetEnabledAutoAbort(false);
|
|
||||||
|
|
||||||
/* Initialize fssystem library. */
|
/* Initialize fssystem library. */
|
||||||
fssystem::InitializeForFileSystemProxy();
|
fssystem::InitializeForFileSystemProxy();
|
||||||
|
|
||||||
|
|||||||
@@ -142,9 +142,6 @@ namespace {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* Disable auto-abort in fs operations. */
|
|
||||||
fs::SetEnabledAutoAbort(false);
|
|
||||||
|
|
||||||
/* Set thread name. */
|
/* Set thread name. */
|
||||||
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(fatal, Main));
|
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(fatal, Main));
|
||||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(fatal, Main));
|
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(fatal, Main));
|
||||||
|
|||||||
@@ -115,9 +115,6 @@ namespace {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* Disable auto-abort in fs operations. */
|
|
||||||
fs::SetEnabledAutoAbort(false);
|
|
||||||
|
|
||||||
/* Set thread name. */
|
/* Set thread name. */
|
||||||
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ldr, Main));
|
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ldr, Main));
|
||||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ldr, Main));
|
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ldr, Main));
|
||||||
|
|||||||
@@ -262,9 +262,6 @@ namespace {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* Disable auto-abort in fs operations. */
|
|
||||||
fs::SetEnabledAutoAbort(false);
|
|
||||||
|
|
||||||
/* Set thread name. */
|
/* Set thread name. */
|
||||||
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ncm, MainWaitThreads));
|
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ncm, MainWaitThreads));
|
||||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads));
|
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads));
|
||||||
|
|||||||
@@ -145,9 +145,6 @@ void __appExit(void) {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* Disable auto-abort in fs operations. */
|
|
||||||
fs::SetEnabledAutoAbort(false);
|
|
||||||
|
|
||||||
/* Set thread name. */
|
/* Set thread name. */
|
||||||
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pgl, Main));
|
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pgl, Main));
|
||||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, Main));
|
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, Main));
|
||||||
|
|||||||
Reference in New Issue
Block a user