libstrat: namespace remaining non-namespaced code. more new-ipc updates
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
/* Any broadly useful language defines should go here. */
|
||||
|
||||
@@ -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(¤t_process_id, CUR_PROCESS_HANDLE));
|
||||
return current_process_id;
|
||||
return GetProcessId(CUR_PROCESS_HANDLE);
|
||||
}
|
||||
|
||||
inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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, µ, 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
|
||||
Reference in New Issue
Block a user