libstrat: namespace remaining non-namespaced code. more new-ipc updates

This commit is contained in:
Michael Scire
2019-10-19 17:42:53 -07:00
committed by SciresM
parent ae2fa2fa60
commit 0b22af1206
68 changed files with 1257 additions and 2118 deletions

View File

@@ -17,20 +17,13 @@
#pragma once
#include "stratosphere/defines.hpp"
#include "stratosphere/utilities.hpp"
#include "stratosphere/emummc_utilities.hpp"
#include "stratosphere/version_check.hpp"
#include "stratosphere/results.hpp"
#include "stratosphere/on_crash.hpp"
#include "stratosphere/util.hpp"
#include "stratosphere/svc.hpp"
#include "stratosphere/ams.hpp"
#include "stratosphere/os.hpp"
#include "stratosphere/dd.hpp"
#include "stratosphere/cfg.hpp"
#include "stratosphere/fatal.hpp"
#include "stratosphere/hid.hpp"

View File

@@ -17,4 +17,7 @@
#pragma once
#include "ams/ams_types.hpp"
#include "ams/ams_hos_version_api.hpp"
#include "ams/ams_hos_version_api.hpp"
#include "ams/ams_exosphere_api.hpp"
#include "ams/ams_emummc_api.hpp"
#include "ams/ams_environment.hpp"

View File

@@ -15,13 +15,17 @@
*/
#pragma once
#include <switch.h>
#include <cstdlib>
#include "services/bpc_ams.h"
#include "ams_types.hpp"
static constexpr size_t AtmosphereFatalErrorNumGprs = 29;
namespace sts::ams::emummc {
static constexpr u32 AtmosphereFatalErrorMagic = 0x31454641; /* "AFE1" */
/* Get whether emummc is active. */
bool IsActive();
/* Will be called by libstratosphere on crash. */
void StratosphereCrashHandler(ThreadExceptionDump *ctx);
/* Get Nintendo redirection path. */
const char *GetNintendoDirPath();
/* Get Emummc folderpath, NULL if not file-based. */
const char *GetFilePath();
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2019 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 "ams_types.hpp"
namespace sts::ams {
/* Will be called by libstratosphere on crash. */
void CrashHandler(ThreadExceptionDump *ctx);
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2018-2019 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 "ams_types.hpp"
namespace sts::ams {
ApiInfo GetApiInfo();
void ForceRebootToRcm();
void ForceRebootToIramPayload();
void ForceShutdown();
bool IsRcmBugPatched();
void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size);
void CopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size);
/* Version checking utility. */
#ifdef ATMOSPHERE_RELEASE_VERSION_MAJOR
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
inline void CheckApiVersion() {
const u32 runtime_version = GetApiInfo().GetVersion();
const u32 build_version = GetVersion(ATMOSPHERE_RELEASE_VERSION);
if (runtime_version < build_version) {
R_ASSERT(ResultAtmosphereVersionMismatch);
}
}
#endif
#ifdef ATMOSPHERE_GIT_BRANCH
NX_CONSTEXPR const char *GetGitBranch() {
return ATMOSPHERE_GIT_BRANCH;
}
#endif
#ifdef ATMOSPHERE_GIT_REV
NX_CONSTEXPR const char *GetGitRevision() {
return ATMOSPHERE_GIT_REV;
}
#endif
}

View File

@@ -17,6 +17,8 @@
#pragma once
#include <switch.h>
#include "../defines.hpp"
#include "../results.hpp"
#include "../sf/sf_buffer_tags.hpp"
/* Define firmware version in global namespace, for convenience. */
namespace sts {
@@ -59,4 +61,67 @@ namespace sts::ams {
TargetFirmware_900 = 11,
};
constexpr inline u32 GetVersion(u32 major, u32 minor, u32 micro) {
return (major << 16) | (minor << 8) | (micro);
}
struct ApiInfo {
u32 major_version;
u32 minor_version;
u32 micro_version;
TargetFirmware target_firmware;
u32 master_key_revision;
constexpr u32 GetVersion() const {
return ::sts::ams::GetVersion(this->major_version, this->minor_version, this->micro_version);
}
constexpr TargetFirmware GetTargetFirmware() const {
return this->target_firmware;
}
constexpr u32 GetMasterKeyRevision() const {
return this->master_key_revision;
}
};
struct FatalErrorContext : sf::LargeData, sf::PrefersMapAliasTransferMode {
static constexpr size_t MaxStackTrace = 0x20;
static constexpr size_t MaxStackDumpSize = 0x100;
static constexpr size_t NumGprs = 29;
static constexpr uintptr_t StdAbortMagicAddress = 0x8;
static constexpr u64 StdAbortMagicValue = 0xA55AF00DDEADCAFEul;
static constexpr u32 StdAbortErrorDesc = 0xFFE;
static constexpr u32 DataAbortErrorDesc = 0x101;
static constexpr u32 Magic = 0x31454641;
u32 magic;
u32 error_desc;
u64 title_id;
union {
u64 gprs[32];
struct {
u64 _gprs[29];
u64 fp;
u64 lr;
u64 sp;
};
};
u64 pc;
u64 module_base;
u32 pstate;
u32 afsr0;
u32 afsr1;
u32 esr;
u64 far;
u64 report_identifier; /* Normally just system tick. */
u64 stack_trace_size;
u64 stack_dump_size;
u64 stack_trace[MaxStackTrace];
u8 stack_dump[MaxStackDumpSize];
};
static_assert(sizeof(FatalErrorContext) == 0x350, "sizeof(FatalErrorContext)");
static_assert(std::is_pod<FatalErrorContext>::value, "FatalErrorContext");
}

View File

@@ -16,13 +16,5 @@
#pragma once
#include <switch.h>
#include <cstdlib>
/* Get whether emummc is active. */
bool IsEmummc();
/* Get Nintendo redirection path. */
const char *GetEmummcNintendoDirPath();
/* Get Emummc folderpath, NULL if not file-based. */
const char *GetEmummcFilePath();
#include "dd/dd_io_mappings.hpp"

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018-2019 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 <switch.h>
#include "../defines.hpp"
namespace sts::dd {
uintptr_t QueryIoMapping(uintptr_t phys_addr, size_t size);
u32 ReadRegister(uintptr_t phys_addr);
void WriteRegister(uintptr_t phys_addr, u32 value);
u32 ReadWriteRegister(uintptr_t phys_addr, u32 value, u32 mask);
/* Convenience Helper. */
inline uintptr_t GetIoMapping(uintptr_t phys_addr, size_t size) {
const uintptr_t io_mapping = QueryIoMapping(phys_addr, size);
STS_ASSERT(io_mapping);
return io_mapping;
}
}

View File

@@ -15,6 +15,7 @@
*/
#pragma once
#include <cstdint>
#include <iterator>
/* Any broadly useful language defines should go here. */

View File

@@ -46,14 +46,18 @@ namespace sts::os {
inline constexpr const ProcessId InvalidProcessId = ProcessId::Invalid;
NX_INLINE Result GetProcessId(os::ProcessId *out, ::Handle process_handle) {
NX_INLINE Result TryGetProcessId(os::ProcessId *out, ::Handle process_handle) {
return svcGetProcessId(&out->value, process_handle);
}
NX_INLINE os::ProcessId GetProcessId(::Handle process_handle) {
os::ProcessId process_id;
R_ASSERT(TryGetProcessId(&process_id, process_handle));
return process_id;
}
NX_INLINE ProcessId GetCurrentProcessId() {
os::ProcessId current_process_id;
R_ASSERT(GetProcessId(&current_process_id, CUR_PROCESS_HANDLE));
return current_process_id;
return GetProcessId(CUR_PROCESS_HANDLE);
}
inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) {

View File

@@ -1,66 +0,0 @@
/*
* Copyright (c) 2018-2019 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 <switch.h>
#ifdef __cplusplus
extern "C" {
#endif
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
#define STD_ABORT_ADDR_MAGIC (0x8)
#define STD_ABORT_VALUE_MAGIC (0xA55AF00DDEADCAFEul)
#define DATA_ABORT_ERROR_DESC (0x101)
#define STD_ABORT_ERROR_DESC (0xFFE)
typedef struct {
u32 magic;
u32 error_desc;
u64 title_id;
union {
u64 gprs[32];
struct {
u64 _gprs[29];
u64 fp;
u64 lr;
u64 sp;
};
};
u64 pc;
u64 module_base;
u32 pstate;
u32 afsr0;
u32 afsr1;
u32 esr;
u64 far;
u64 report_identifier; /* Normally just system tick. */
u64 stack_trace_size;
u64 stack_dump_size;
u64 stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE];
u8 stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP];
} AtmosphereFatalErrorContext;
Result bpcAmsInitialize(void);
void bpcAmsExit(void);
Result bpcAmsRebootToFatalError(AtmosphereFatalErrorContext *ctx);
#ifdef __cplusplus
}
#endif

View File

@@ -1,92 +0,0 @@
/*
* Copyright (c) 2018-2019 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 <switch.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
u64 base;
u64 size;
} DmntMemoryRegionExtents;
typedef struct {
u64 process_id;
u64 title_id;
DmntMemoryRegionExtents main_nso_extents;
DmntMemoryRegionExtents heap_extents;
DmntMemoryRegionExtents alias_extents;
DmntMemoryRegionExtents address_space_extents;
u8 main_nso_build_id[0x20];
} DmntCheatProcessMetadata;
typedef struct {
char readable_name[0x40];
uint32_t num_opcodes;
uint32_t opcodes[0x100];
} DmntCheatDefinition;
typedef struct {
bool enabled;
uint32_t cheat_id;
DmntCheatDefinition definition;
} DmntCheatEntry;
typedef struct {
u64 value;
u8 width;
} DmntFrozenAddressValue;
typedef struct {
u64 address;
DmntFrozenAddressValue value;
} DmntFrozenAddressEntry;
Result dmntchtInitialize(void);
void dmntchtExit(void);
Service* dmntchtGetServiceSession(void);
Result dmntchtHasCheatProcess(bool *out);
Result dmntchtGetCheatProcessEvent(Event *event);
Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata);
Result dmntchtForceOpenCheatProcess(void);
Result dmntchtGetCheatProcessMappingCount(u64 *out_count);
Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count);
Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size);
Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size);
Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address);
Result dmntchtGetCheatCount(u64 *out_count);
Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count);
Result dmntchtGetCheatById(DmntCheatEntry *out_cheat, u32 cheat_id);
Result dmntchtToggleCheat(u32 cheat_id);
Result dmntchtAddCheat(DmntCheatDefinition *cheat, bool enabled, u32 *out_cheat_id);
Result dmntchtRemoveCheat(u32 cheat_id);
Result dmntchtGetFrozenAddressCount(u64 *out_count);
Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count);
Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address);
Result dmntchtEnableFrozenAddress(u64 address, u64 width, u64 *out_value);
Result dmntchtDisableFrozenAddress(u64 address);
#ifdef __cplusplus
}
#endif

View File

@@ -20,3 +20,4 @@
#include "sm/sm_types.hpp"
#include "sm/sm_api.hpp"
#include "sm/sm_mitm_api.hpp"
#include "sm/sm_scoped_holder.hpp"

View File

@@ -29,4 +29,17 @@ namespace sts::sm {
Result HasService(bool *out, ServiceName name);
Result WaitService(ServiceName name);
/* Scoped session access. */
namespace impl {
void DoWithSessionImpl(void (*Invoker)(void *), void *Function);
}
template<typename F>
NX_CONSTEXPR void DoWithSession(F f) {
auto invoker = +[](void *func) { (*(F *)func)(); };
impl::DoWithSessionImpl(invoker, &f);
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2018-2019 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 "sm_api.hpp"
namespace sts::sm {
/* Utility, for scoped access to libnx services. */
template<Result Initializer(), void Finalizer()>
class ScopedServiceHolder {
NON_COPYABLE(ScopedServiceHolder);
private:
Result result;
bool has_initialized;
public:
ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) {
if (initialize) {
this->Initialize();
}
}
~ScopedServiceHolder() {
if (this->has_initialized) {
this->Finalize();
}
}
ScopedServiceHolder(ScopedServiceHolder&& rhs) {
this->result = rhs.result;
this->has_initialized = rhs.has_initialized;
rhs.result = ResultSuccess;
rhs.has_initialized = false;
}
ScopedServiceHolder& operator=(ScopedServiceHolder&& rhs) {
rhs.Swap(*this);
return *this;
}
void Swap(ScopedServiceHolder& rhs) {
std::swap(this->result, rhs.result);
std::swap(this->has_initialized, rhs.has_initialized);
}
explicit operator bool() const {
return this->has_initialized;
}
Result Initialize() {
STS_ASSERT(!this->has_initialized);
sm::DoWithSession([&]() {
this->result = Initializer();
});
this->has_initialized = R_SUCCEEDED(this->result);
return this->result;
}
void Finalize() {
STS_ASSERT(this->has_initialized);
Finalizer();
this->has_initialized = false;
}
Result GetResult() const {
return this->result;
}
};
}

View File

@@ -70,67 +70,4 @@ namespace sts::sm {
};
static_assert(sizeof(ServiceRecord) == 0x30, "ServiceRecord definition!");
/* Utility, for scoped access to libnx services. */
template<Result Initializer(), void Finalizer()>
class ScopedServiceHolder {
NON_COPYABLE(ScopedServiceHolder);
private:
Result result;
bool has_initialized;
public:
ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) {
if (initialize) {
this->Initialize();
}
}
~ScopedServiceHolder() {
if (this->has_initialized) {
this->Finalize();
}
}
ScopedServiceHolder(ScopedServiceHolder&& rhs) {
this->result = rhs.result;
this->has_initialized = rhs.has_initialized;
rhs.result = ResultSuccess;
rhs.has_initialized = false;
}
ScopedServiceHolder& operator=(ScopedServiceHolder&& rhs) {
rhs.Swap(*this);
return *this;
}
void Swap(ScopedServiceHolder& rhs) {
std::swap(this->result, rhs.result);
std::swap(this->has_initialized, rhs.has_initialized);
}
explicit operator bool() const {
return this->has_initialized;
}
Result Initialize() {
STS_ASSERT(!this->has_initialized);
DoWithSmSession([&]() {
this->result = Initializer();
});
this->has_initialized = R_SUCCEEDED(this->result);
return this->result;
}
void Finalize() {
STS_ASSERT(this->has_initialized);
Finalizer();
this->has_initialized = false;
}
Result GetResult() const {
return this->result;
}
};
}

View File

@@ -16,6 +16,7 @@
#pragma once
#include <switch.h>
#include <type_traits>
#include "../spl_types.hpp"
@@ -54,4 +55,21 @@ namespace sts::spl::smc {
Result DecryptRsaPrivateKey(size_t *out_size, void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
Result ImportSecureExpModKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
/* Atmosphere functions. */
Result AtmosphereCopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size);
Result AtmosphereCopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size);
Result AtmosphereReadWriteRegister(uint64_t address, uint32_t mask, uint32_t value, uint32_t *out_value);
Result AtmosphereWriteAddress(void *dst, const void *src, size_t size);
/* Helpers. */
inline Result SetConfig(SplConfigItem which, const u64 value) {
return SetConfig(which, &value, 1);
}
template<typename T>
inline Result AtmosphereWriteAddress(void *dst, const T value) {
static_assert(std::is_integral<T>::value && sizeof(T) <= 8 && (sizeof(T) & (sizeof(T) - 1)) == 0, "AtmosphereWriteAddress requires integral type.");
return AtmosphereWriteAddress(dst, &value, sizeof(T));
}
}

View File

@@ -46,6 +46,12 @@ namespace sts::spl {
ImportEsKey = 0xC300100C,
DecryptRsaPrivateKey = 0xC300100D,
ImportSecureExpModKey = 0xC300100E,
/* Atmosphere functions. */
AtmosphereIramCopy = 0xF0000201,
AtmosphereReadWriteRegister = 0xF0000002,
AtmosphereWriteAddress = 0xF0000003,
AtmosphereGetEmummcConfig = 0xF0000404,
};
enum class Result {
@@ -177,3 +183,10 @@ namespace sts::spl {
#pragma pack(pop)
}
/* Extensions to libnx spl config item enum. */
constexpr inline SplConfigItem SplConfigItem_ExosphereApiVersion = static_cast<SplConfigItem>(65000);
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsReboot = static_cast<SplConfigItem>(65001);
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsShutdown = static_cast<SplConfigItem>(65002);
constexpr inline SplConfigItem SplConfigItem_ExosphereGitCommitHash = static_cast<SplConfigItem>(65003);
constexpr inline SplConfigItem SplConfigItem_ExosphereHasRcmBugPatch = static_cast<SplConfigItem>(65004);

View File

@@ -1,128 +0,0 @@
/*
* Copyright (c) 2018-2019 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 <switch.h>
#include "defines.hpp"
#include "results.hpp"
#include "os.hpp"
static inline uintptr_t GetIoMapping(const u64 io_addr, const u64 io_size) {
u64 vaddr;
const u64 aligned_addr = (io_addr & ~0xFFFul);
const u64 aligned_size = io_size + (io_addr - aligned_addr);
R_ASSERT(svcQueryIoMapping(&vaddr, aligned_addr, aligned_size));
return static_cast<uintptr_t>(vaddr + (io_addr - aligned_addr));
}
static inline void RebootToRcm() {
SecmonArgs args = {0};
args.X[0] = 0xC3000401; /* smcSetConfig */
args.X[1] = 65001; /* Exosphere reboot */
args.X[3] = 1; /* Perform reboot to RCM. */
svcCallSecureMonitor(&args);
}
static inline void RebootToIramPayload() {
SecmonArgs args = {0};
args.X[0] = 0xC3000401; /* smcSetConfig */
args.X[1] = 65001; /* Exosphere reboot */
args.X[3] = 2; /* Perform reboot to payload at 0x40010000 in IRAM. */
svcCallSecureMonitor(&args);
}
static inline void PerformShutdownSmc() {
SecmonArgs args = {0};
args.X[0] = 0xC3000401; /* smcSetConfig */
args.X[1] = 65002; /* Exosphere shutdown */
args.X[3] = 1; /* Perform shutdown. */
svcCallSecureMonitor(&args);
}
static inline void CopyToIram(uintptr_t iram_addr, void *src_addr, size_t size) {
SecmonArgs args = {0};
args.X[0] = 0xF0000201; /* smcAmsIramCopy */
args.X[1] = (u64)src_addr; /* DRAM address */
args.X[2] = (u64)iram_addr; /* IRAM address */
args.X[3] = size; /* Amount to copy */
args.X[4] = 1; /* 1 = Write */
svcCallSecureMonitor(&args);
}
static inline void CopyFromIram(void *dst_addr, uintptr_t iram_addr, size_t size) {
SecmonArgs args = {0};
args.X[0] = 0xF0000201; /* smcAmsIramCopy */
args.X[1] = (u64)dst_addr; /* DRAM address */
args.X[2] = (u64)iram_addr; /* IRAM address */
args.X[3] = size; /* Amount to copy */
args.X[4] = 0; /* 0 = Read */
svcCallSecureMonitor(&args);
}
static inline Result SmcGetConfig(SplConfigItem config_item, u64 *out_config) {
SecmonArgs args = {0};
args.X[0] = 0xC3000002; /* smcGetConfig */
args.X[1] = (u64)config_item; /* config item */
R_TRY(svcCallSecureMonitor(&args));
if (args.X[0] != 0) {
/* SPL result n = SMC result n */
return MAKERESULT(26, args.X[0]);
}
if (out_config) {
*out_config = args.X[1];
}
return ResultSuccess;
}
static inline Result GetRcmBugPatched(bool *out) {
u64 tmp = 0;
R_TRY(SmcGetConfig((SplConfigItem)65004, &tmp));
*out = (tmp != 0);
return ResultSuccess;
}
static inline bool IsRcmBugPatched() {
bool rcm_bug_patched;
R_ASSERT(GetRcmBugPatched(&rcm_bug_patched));
return rcm_bug_patched;
}
static inline Result GetShouldBlankProdInfo(bool *out) {
u64 tmp = 0;
R_TRY(SmcGetConfig((SplConfigItem)65005, &tmp));
*out = (tmp != 0);
return ResultSuccess;
}
static inline bool ShouldBlankProdInfo() {
bool should_blank_prodinfo;
R_ASSERT(GetShouldBlankProdInfo(&should_blank_prodinfo));
return should_blank_prodinfo;
}
sts::os::RecursiveMutex &GetSmSessionMutex();
template<typename F>
static void DoWithSmSession(F f) {
std::scoped_lock lk(GetSmSessionMutex());
{
R_ASSERT(smInitialize());
f();
smExit();
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright (c) 2018-2019 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 <switch.h>
#include "results.hpp"
static inline void GetAtmosphereApiVersion(u32 *major, u32 *minor, u32 *micro, u32 *target_fw, u32 *mkey_rev) {
/* Check for exosphere API compatibility. */
u64 exosphere_cfg;
if (R_FAILED(SmcGetConfig((SplConfigItem)65000, &exosphere_cfg))) {
fatalSimple(ResultAtmosphereExosphereNotPresent);
}
if (mkey_rev) {
*mkey_rev = (u32)((exosphere_cfg >> 0x00) & 0xFF);
}
if (target_fw) {
*target_fw = (u32)((exosphere_cfg >> 0x08) & 0xFF);
}
if (micro) {
*micro = (u32)((exosphere_cfg >> 0x10) & 0xFF);
}
if (minor) {
*minor = (u32)((exosphere_cfg >> 0x18) & 0xFF);
}
if (major) {
*major = (u32)((exosphere_cfg >> 0x20) & 0xFF);
}
}
static inline u32 MakeAtmosphereVersion(u32 major, u32 minor, u32 micro) {
return (major << 16) | (minor << 8) | micro;
}
static inline void CheckAtmosphereVersion(u32 expected_major, u32 expected_minor, u32 expected_micro) {
u32 major, minor, micro;
GetAtmosphereApiVersion(&major, &minor, &micro, nullptr, nullptr);
if (MakeAtmosphereVersion(major, minor, micro) < MakeAtmosphereVersion(expected_major, expected_minor, expected_micro)) {
fatalSimple(ResultAtmosphereVersionMismatch);
}
}
#define CURRENT_ATMOSPHERE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
#ifdef ATMOSPHERE_GIT_BRANCH
static inline const char *GetAtmosphereGitBranch() {
return ATMOSPHERE_GIT_BRANCH;
}
#endif
#ifdef ATMOSPHERE_GIT_REV
static inline const char *GetAtmosphereGitRevision() {
return ATMOSPHERE_GIT_REV;
}
#endif