ams: mark ams::Result [[nodiscard]] (partially complete).

NOTE: This work is not yet fully complete; kernel is done, but
it was taking an exceedingly long time to get through libstratosphere.
Thus, I've temporarily added -Wno-error=unused-result for libstratosphere/stratosphere.

All warnings should be fixed to do the same thing Nintendo does as relevant, but this
is taking a phenomenally long time and is not actually the most important work to do,
so it can be put off for some time to prioritize other tasks for 21.0.0 support.
This commit is contained in:
Michael Scire 2025-11-11 16:13:25 -07:00 committed by SciresM
parent 418fde40a8
commit 3bc1951820
86 changed files with 444 additions and 455 deletions

View File

@ -411,8 +411,9 @@ namespace ams::nxboot {
/* If we should, save the current warmboot firmware. */ /* If we should, save the current warmboot firmware. */
UpdateWarmbootPath(expected_fuses); UpdateWarmbootPath(expected_fuses);
if (!IsFileExist(warmboot_path)) { if (!IsFileExist(warmboot_path)) {
fs::CreateDirectory("sdmc:/warmboot_mariko"); /* Try to create the directory/file, allowing them to fail (if already exist). */
fs::CreateFile(warmboot_path, warmboot_src_size); static_cast<void>(fs::CreateDirectory("sdmc:/warmboot_mariko"));
static_cast<void>(fs::CreateFile(warmboot_path, warmboot_src_size));
Result result; Result result;
fs::FileHandle file; fs::FileHandle file;

View File

@ -26,7 +26,7 @@ ATMOSPHERE_OPTIMIZATION_FLAG := -O2
endif endif
export DEFINES = $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE export DEFINES = $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
export SETTINGS = $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers export SETTINGS = $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -Wno-error=unused-result
export CFLAGS = $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) export CFLAGS = $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) export CXXFLAGS = $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) export ASFLAGS = $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)

View File

@ -83,9 +83,9 @@ namespace ams::kern::arch::arm64 {
} }
NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level); NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
NOINLINE Result UnbindHandler(s32 irq, s32 core); NOINLINE void UnbindHandler(s32 irq, s32 core);
NOINLINE Result ClearInterrupt(s32 irq, s32 core_id); NOINLINE void ClearInterrupt(s32 irq, s32 core_id);
ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) { ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
m_interrupt_controller.SendInterProcessorInterrupt(irq, core_mask); m_interrupt_controller.SendInterProcessorInterrupt(irq, core_mask);
@ -99,10 +99,10 @@ namespace ams::kern::arch::arm64 {
private: private:
Result BindGlobal(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level); Result BindGlobal(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
Result BindLocal(KInterruptHandler *handler, s32 irq, s32 priority, bool manual_clear); Result BindLocal(KInterruptHandler *handler, s32 irq, s32 priority, bool manual_clear);
Result UnbindGlobal(s32 irq); void UnbindGlobal(s32 irq);
Result UnbindLocal(s32 irq); void UnbindLocal(s32 irq);
Result ClearGlobal(s32 irq); void ClearGlobal(s32 irq);
Result ClearLocal(s32 irq); void ClearLocal(s32 irq);
private: private:
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledState() { [[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledState() {
u64 intr_state; u64 intr_state;

View File

@ -197,7 +197,7 @@ namespace ams::kern::arch::arm64 {
cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id); cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id);
} }
NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); NOINLINE void InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end);
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index);
Result Finalize(); Result Finalize();

View File

@ -165,7 +165,7 @@ namespace ams::kern::arch::arm64 {
constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_fpcr(), m_fpsr(), m_callee_saved_fpu(), m_locked() { /* ... */ } constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_fpcr(), m_fpsr(), m_callee_saved_fpu(), m_locked() { /* ... */ }
explicit KThreadContext() { /* ... */ } explicit KThreadContext() { /* ... */ }
Result Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main); void Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main);
void SetArguments(uintptr_t arg0, uintptr_t arg1); void SetArguments(uintptr_t arg0, uintptr_t arg1);

View File

@ -93,9 +93,9 @@ namespace ams::kern {
static Result ProcessDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params); static Result ProcessDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
public: public:
static Result OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params); static Result OnDebugEvent(ams::svc::DebugEvent event, const uintptr_t *params, size_t num_params);
static Result OnExitProcess(KProcess *process); static void OnExitProcess(KProcess *process);
static Result OnTerminateProcess(KProcess *process); static void OnTerminateProcess(KProcess *process);
static Result OnExitThread(KThread *thread); static void OnExitThread(KThread *thread);
static KEventInfo *CreateDebugEvent(ams::svc::DebugEvent event, u64 thread_id, const uintptr_t *params, size_t num_params); static KEventInfo *CreateDebugEvent(ams::svc::DebugEvent event, u64 thread_id, const uintptr_t *params, size_t num_params);
}; };

View File

@ -50,8 +50,8 @@ namespace ams::kern {
KReadableEvent &GetReadableEvent() { return m_readable_event; } KReadableEvent &GetReadableEvent() { return m_readable_event; }
Result Signal(); void Signal();
Result Clear(); void Clear();
ALWAYS_INLINE void OnReadableEventDestroyed() { m_readable_event_destroyed = true; } ALWAYS_INLINE void OnReadableEventDestroyed() { m_readable_event_destroyed = true; }
}; };

View File

@ -38,13 +38,11 @@ namespace ams::kern {
Result Reset(); Result Reset();
Result Clear() { void Clear() {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
/* Try to perform a reset, succeeding unconditionally. */ /* Try to perform a reset, ignoring whether it succeeds. */
this->Reset(); static_cast<void>(this->Reset());
R_SUCCEED();
} }
bool IsInitialized() const { return m_is_initialized; } bool IsInitialized() const { return m_is_initialized; }

View File

@ -226,7 +226,7 @@ namespace ams::kern {
explicit KPageTableBase() { /* ... */ } explicit KPageTableBase() { /* ... */ }
NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); NOINLINE void InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end);
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit);
void Finalize(); void Finalize();

View File

@ -269,7 +269,7 @@ namespace ams::kern {
void RemoveIoRegion(KIoRegion *io_region); void RemoveIoRegion(KIoRegion *io_region);
Result CreateThreadLocalRegion(KProcessAddress *out); Result CreateThreadLocalRegion(KProcessAddress *out);
Result DeleteThreadLocalRegion(KProcessAddress addr); void DeleteThreadLocalRegion(KProcessAddress addr);
void *GetThreadLocalRegionPointer(KProcessAddress addr); void *GetThreadLocalRegionPointer(KProcessAddress addr);
constexpr KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; } constexpr KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; }

View File

@ -35,16 +35,14 @@ namespace ams::kern {
constexpr KEvent *GetParent() const { return m_parent; } constexpr KEvent *GetParent() const { return m_parent; }
Result Signal(); void Signal();
Result Reset(); Result Reset();
Result Clear() { void Clear() {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
/* Try to perform a reset, succeeding unconditionally. */ /* Try to perform a reset, ignoring whether it succeeds. */
this->Reset(); static_cast<void>(this->Reset());
R_SUCCEED();
} }
virtual bool IsSignaled() const override; virtual bool IsSignaled() const override;

View File

@ -523,7 +523,7 @@ namespace ams::kern {
Result GetCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask); Result GetCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
Result SetCoreMask(int32_t ideal_core, u64 affinity_mask); Result SetCoreMask(int32_t ideal_core, u64 affinity_mask);
Result GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask); void GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
constexpr ThreadState GetState() const { return static_cast<ThreadState>(m_thread_state & ThreadState_Mask); } constexpr ThreadState GetState() const { return static_cast<ThreadState>(m_thread_state & ThreadState_Mask); }
constexpr ThreadState GetRawState() const { return m_thread_state; } constexpr ThreadState GetRawState() const { return m_thread_state; }
@ -717,7 +717,7 @@ namespace ams::kern {
} }
void SetBasePriority(s32 priority); void SetBasePriority(s32 priority);
Result SetPriorityToIdle(); void SetPriorityToIdle();
Result Run(); Result Run();
void Exit(); void Exit();
@ -725,7 +725,7 @@ namespace ams::kern {
Result Terminate(); Result Terminate();
ThreadState RequestTerminate(); ThreadState RequestTerminate();
Result Sleep(s64 timeout); void Sleep(s64 timeout);
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(m_kernel_stack_top) - 1; } ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(m_kernel_stack_top) - 1; }
ALWAYS_INLINE void *GetKernelStackTop() const { return m_kernel_stack_top; } ALWAYS_INLINE void *GetKernelStackTop() const { return m_kernel_stack_top; }

View File

@ -77,7 +77,7 @@ namespace ams::kern {
} }
public: public:
Result Initialize(KProcess *process); Result Initialize(KProcess *process);
Result Finalize(); void Finalize();
KProcessAddress Reserve(); KProcessAddress Reserve();
void Release(KProcessAddress addr); void Release(KProcessAddress addr);

View File

@ -215,7 +215,7 @@ namespace ams::kern::arch::arm64::cpu {
KThread::Register(new_thread); KThread::Register(new_thread);
/* Run the thread. */ /* Run the thread. */
new_thread->Run(); MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
} }
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override { virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
@ -508,16 +508,16 @@ namespace ams::kern::arch::arm64::cpu {
g_cache_operation_handler.Initialize(core_id); g_cache_operation_handler.Initialize(core_id);
/* Bind all handlers to the relevant interrupts. */ /* Bind all handlers to the relevant interrupts. */
Kernel::GetInterruptManager().BindHandler(std::addressof(g_cache_operation_handler), KInterruptName_CacheOperation, core_id, KInterruptController::PriorityLevel_High, false, false); MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_cache_operation_handler), KInterruptName_CacheOperation, core_id, KInterruptController::PriorityLevel_High, false, false));
Kernel::GetInterruptManager().BindHandler(std::addressof(g_thread_termination_handler), KInterruptName_ThreadTerminate, core_id, KInterruptController::PriorityLevel_Scheduler, false, false); MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_thread_termination_handler), KInterruptName_ThreadTerminate, core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
Kernel::GetInterruptManager().BindHandler(std::addressof(g_core_barrier_handler), KInterruptName_CoreBarrier, core_id, KInterruptController::PriorityLevel_Scheduler, false, false); MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_core_barrier_handler), KInterruptName_CoreBarrier, core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
/* If we should, enable user access to the performance counter registers. */ /* If we should, enable user access to the performance counter registers. */
if (KTargetSystem::IsUserPmuAccessEnabled()) { SetPmUserEnrEl0(1ul); } if (KTargetSystem::IsUserPmuAccessEnabled()) { SetPmUserEnrEl0(1ul); }
/* If we should, enable the kernel performance counter interrupt handler. */ /* If we should, enable the kernel performance counter interrupt handler. */
#if defined(MESOSPHERE_ENABLE_PERFORMANCE_COUNTER) #if defined(MESOSPHERE_ENABLE_PERFORMANCE_COUNTER)
Kernel::GetInterruptManager().BindHandler(std::addressof(g_performance_counter_handler[core_id]), KInterruptName_PerformanceCounter, core_id, KInterruptController::PriorityLevel_Timer, false, false); MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(std::addressof(g_performance_counter_handler[core_id]), KInterruptName_PerformanceCounter, core_id, KInterruptController::PriorityLevel_Timer, false, false));
#endif #endif
} }

View File

@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 {
m_maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue())); m_maximum_time = static_cast<s64>(std::min<u64>(std::numeric_limits<s64>::max(), cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor().GetCompareValue()));
/* Bind the interrupt task for this core. */ /* Bind the interrupt task for this core. */
Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true); MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(this, KInterruptName_NonSecurePhysicalTimer, GetCurrentCoreId(), KInterruptController::PriorityLevel_Timer, true, true));
} }
void KHardwareTimer::Finalize() { void KHardwareTimer::Finalize() {

View File

@ -126,7 +126,7 @@ namespace ams::kern::arch::arm64 {
if (entry.handler != nullptr) { if (entry.handler != nullptr) {
/* Set manual clear needed if relevant. */ /* Set manual clear needed if relevant. */
if (entry.manually_cleared) { if (entry.manually_cleared) {
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low); m_interrupt_controller.Disable(irq);
entry.needs_clear = true; entry.needs_clear = true;
} }
@ -242,40 +242,40 @@ namespace ams::kern::arch::arm64 {
} }
} }
Result KInterruptManager::UnbindHandler(s32 irq, s32 core_id) { void KInterruptManager::UnbindHandler(s32 irq, s32 core_id) {
MESOSPHERE_UNUSED(core_id); MESOSPHERE_UNUSED(core_id);
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange()); MESOSPHERE_ASSERT(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq));
if (KInterruptController::IsGlobal(irq)) { if (KInterruptController::IsGlobal(irq)) {
KScopedInterruptDisable di; KScopedInterruptDisable di;
KScopedSpinLock lk(this->GetGlobalInterruptLock()); KScopedSpinLock lk(this->GetGlobalInterruptLock());
R_RETURN(this->UnbindGlobal(irq)); return this->UnbindGlobal(irq);
} else { } else if (KInterruptController::IsLocal(irq)) {
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId()); MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
KScopedInterruptDisable di; KScopedInterruptDisable di;
R_RETURN(this->UnbindLocal(irq)); return this->UnbindLocal(irq);
} }
} }
Result KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) { void KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) {
MESOSPHERE_UNUSED(core_id); MESOSPHERE_UNUSED(core_id);
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange()); MESOSPHERE_ASSERT(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq));
if (KInterruptController::IsGlobal(irq)) { if (KInterruptController::IsGlobal(irq)) {
KScopedInterruptDisable di; KScopedInterruptDisable di;
KScopedSpinLock lk(this->GetGlobalInterruptLock()); KScopedSpinLock lk(this->GetGlobalInterruptLock());
R_RETURN(this->ClearGlobal(irq)); return this->ClearGlobal(irq);
} else { } else if (KInterruptController::IsLocal(irq)) {
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId()); MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
KScopedInterruptDisable di; KScopedInterruptDisable di;
R_RETURN(this->ClearLocal(irq)); return this->ClearLocal(irq);
} }
} }
@ -332,7 +332,7 @@ namespace ams::kern::arch::arm64 {
R_SUCCEED(); R_SUCCEED();
} }
Result KInterruptManager::UnbindGlobal(s32 irq) { void KInterruptManager::UnbindGlobal(s32 irq) {
for (size_t core_id = 0; core_id < cpu::NumCores; core_id++) { for (size_t core_id = 0; core_id < cpu::NumCores; core_id++) {
m_interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id)); m_interrupt_controller.ClearTarget(irq, static_cast<s32>(core_id));
} }
@ -340,50 +340,35 @@ namespace ams::kern::arch::arm64 {
m_interrupt_controller.Disable(irq); m_interrupt_controller.Disable(irq);
GetGlobalInterruptEntry(irq).handler = nullptr; GetGlobalInterruptEntry(irq).handler = nullptr;
R_SUCCEED();
} }
Result KInterruptManager::UnbindLocal(s32 irq) { void KInterruptManager::UnbindLocal(s32 irq) {
auto &entry = this->GetLocalInterruptEntry(irq);
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low); m_interrupt_controller.SetPriorityLevel(irq, KInterruptController::PriorityLevel_Low);
m_interrupt_controller.Disable(irq); m_interrupt_controller.Disable(irq);
entry.handler = nullptr; this->GetLocalInterruptEntry(irq).handler = nullptr;
R_SUCCEED();
} }
Result KInterruptManager::ClearGlobal(s32 irq) { void KInterruptManager::ClearGlobal(s32 irq) {
/* We can't clear an entry with no handler. */ /* Get the entry. */
auto &entry = GetGlobalInterruptEntry(irq); auto &entry = GetGlobalInterruptEntry(irq);
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
/* If auto-cleared, we can succeed immediately. */ /* If not auto-cleared, clear and enable. */
R_SUCCEED_IF(!entry.manually_cleared); if (entry.manually_cleared && entry.needs_clear) {
R_SUCCEED_IF(!entry.needs_clear); entry.needs_clear = false;
m_interrupt_controller.Enable(irq);
/* Clear and enable. */ }
entry.needs_clear = false;
m_interrupt_controller.Enable(irq);
R_SUCCEED();
} }
Result KInterruptManager::ClearLocal(s32 irq) { void KInterruptManager::ClearLocal(s32 irq) {
/* We can't clear an entry with no handler. */ /* Get the entry. */
auto &entry = this->GetLocalInterruptEntry(irq); auto &entry = this->GetLocalInterruptEntry(irq);
R_UNLESS(entry.handler != nullptr, svc::ResultInvalidState());
/* If auto-cleared, we can succeed immediately. */ /* If not auto-cleared, clear and enable. */
R_SUCCEED_IF(!entry.manually_cleared); if (entry.manually_cleared && entry.needs_clear) {
R_SUCCEED_IF(!entry.needs_clear); entry.needs_clear = false;
m_interrupt_controller.Enable(irq);
/* Clear and set priority. */ }
entry.needs_clear = false;
m_interrupt_controller.SetPriorityLevel(irq, entry.priority);
R_SUCCEED();
} }
} }

View File

@ -119,15 +119,13 @@ namespace ams::kern::arch::arm64 {
MESOSPHERE_UNUSED(core_id); MESOSPHERE_UNUSED(core_id);
} }
Result KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) { void KPageTable::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) {
/* Initialize basic fields. */ /* Initialize basic fields. */
m_asid = 0; m_asid = 0;
m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer(); m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer();
/* Initialize the base page table. */ /* Initialize the base page table. */
MESOSPHERE_R_ABORT_UNLESS(KPageTableBase::InitializeForKernel(true, table, start, end)); KPageTableBase::InitializeForKernel(true, table, start, end);
R_SUCCEED();
} }
Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) {
@ -942,7 +940,7 @@ namespace ams::kern::arch::arm64 {
/* If we should flush entries, do so. */ /* If we should flush entries, do so. */
if ((apply_option & ApplyOption_FlushDataCache) != 0) { if ((apply_option & ApplyOption_FlushDataCache) != 0) {
if (IsHeapPhysicalAddress(next_entry.phys_addr)) { if (IsHeapPhysicalAddress(next_entry.phys_addr)) {
cpu::FlushDataCache(GetVoidPointer(GetHeapVirtualAddress(next_entry.phys_addr)), next_entry.block_size); MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(GetVoidPointer(GetHeapVirtualAddress(next_entry.phys_addr)), next_entry.block_size));
} }
} }

View File

@ -37,7 +37,7 @@ namespace ams::kern::arch::arm64 {
KScopedInterruptEnable ei; KScopedInterruptEnable ei;
const uintptr_t params[2] = { GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()) }; const uintptr_t params[2] = { GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()) };
KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params)); static_cast<void>(KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, params, util::size(params)));
} }
/* Handle any pending dpc. */ /* Handle any pending dpc. */
@ -116,7 +116,7 @@ namespace ams::kern::arch::arm64 {
} }
Result KThreadContext::Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main) { void KThreadContext::Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main) {
MESOSPHERE_ASSERT(k_sp != Null<KVirtualAddress>); MESOSPHERE_ASSERT(k_sp != Null<KVirtualAddress>);
/* Ensure that the stack pointers are aligned. */ /* Ensure that the stack pointers are aligned. */
@ -157,8 +157,6 @@ namespace ams::kern::arch::arm64 {
/* Lock the context, if we're a main thread. */ /* Lock the context, if we're a main thread. */
m_locked = is_main; m_locked = is_main;
R_SUCCEED();
} }
void KThreadContext::SetArguments(uintptr_t arg0, uintptr_t arg1) { void KThreadContext::SetArguments(uintptr_t arg0, uintptr_t arg1) {

View File

@ -660,8 +660,7 @@ namespace ams::kern::board::nintendo::nx {
ptm.Open(table_virt_addr, 1); ptm.Open(table_virt_addr, 1);
/* Save the page. Note that it is a pre-condition that the page is cleared, when allocated from the system page table manager. */ /* Save the page. Note that it is a pre-condition that the page is cleared, when allocated from the system page table manager. */
/* NOTE: Nintendo does not check the result of StoreDataCache. */ MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_virt_addr), PageDirectorySize));
cpu::StoreDataCache(GetVoidPointer(table_virt_addr), PageDirectorySize);
g_reserved_table_phys_addr = table_phys_addr; g_reserved_table_phys_addr = table_phys_addr;
/* Reserve an asid to correspond to no device. */ /* Reserve an asid to correspond to no device. */
@ -806,7 +805,7 @@ namespace ams::kern::board::nintendo::nx {
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr))); MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
ptm.Open(table_vaddr, 1); ptm.Open(table_vaddr, 1);
cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageDirectorySize); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageDirectorySize));
m_tables[i] = table_vaddr; m_tables[i] = table_vaddr;
} }
@ -1042,7 +1041,7 @@ namespace ams::kern::board::nintendo::nx {
if (l2_index == 0 && util::IsAligned(GetInteger(phys_addr), DeviceLargePageSize) && remaining >= DeviceLargePageSize) { if (l2_index == 0 && util::IsAligned(GetInteger(phys_addr), DeviceLargePageSize) && remaining >= DeviceLargePageSize) {
/* Set the large page. */ /* Set the large page. */
l1[l1_index].SetLargePage(read, write, true, phys_addr); l1[l1_index].SetLargePage(read, write, true, phys_addr);
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
/* Synchronize. */ /* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index])))); InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
@ -1062,11 +1061,11 @@ namespace ams::kern::board::nintendo::nx {
const KVirtualAddress table_vaddr = ptm.Allocate(); const KVirtualAddress table_vaddr = ptm.Allocate();
R_UNLESS(table_vaddr != Null<KVirtualAddress>, svc::ResultOutOfMemory()); R_UNLESS(table_vaddr != Null<KVirtualAddress>, svc::ResultOutOfMemory());
MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr))); MESOSPHERE_ASSERT(IsValidPhysicalAddress(GetPageTablePhysicalAddress(table_vaddr)));
cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageTableSize); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(table_vaddr), PageTableSize));
/* Set the l1 table. */ /* Set the l1 table. */
l1[l1_index].SetTable(true, true, true, GetPageTablePhysicalAddress(table_vaddr)); l1[l1_index].SetTable(true, true, true, GetPageTablePhysicalAddress(table_vaddr));
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
/* Synchronize. */ /* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index])))); InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
@ -1093,7 +1092,7 @@ namespace ams::kern::board::nintendo::nx {
/* Add a reference to the l2 page (from the l2 entry page). */ /* Add a reference to the l2 page (from the l2 entry page). */
ptm.Open(KVirtualAddress(l2), 1); ptm.Open(KVirtualAddress(l2), 1);
} }
cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)));
/* Invalidate the page table cache. */ /* Invalidate the page table cache. */
for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) { for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) {
@ -1199,7 +1198,7 @@ namespace ams::kern::board::nintendo::nx {
++num_closed; ++num_closed;
} }
} }
cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l2[l2_index]), map_count * sizeof(PageTableEntry)));
/* Invalidate the page table cache. */ /* Invalidate the page table cache. */
for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) { for (size_t i = util::AlignDown(l2_index, 4); i <= util::AlignDown(l2_index + map_count - 1, 4); i += 4) {
@ -1243,7 +1242,7 @@ namespace ams::kern::board::nintendo::nx {
if (ptm.Close(KVirtualAddress(l2), num_closed)) { if (ptm.Close(KVirtualAddress(l2), num_closed)) {
/* Invalidate the l1 entry. */ /* Invalidate the l1 entry. */
l1[l1_index].Invalidate(); l1[l1_index].Invalidate();
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
/* Synchronize. */ /* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index])))); InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));
@ -1266,7 +1265,7 @@ namespace ams::kern::board::nintendo::nx {
/* Invalidate the entry. */ /* Invalidate the entry. */
l1[l1_index].Invalidate(); l1[l1_index].Invalidate();
cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(std::addressof(l1[l1_index]), sizeof(PageDirectoryEntry)));
/* Synchronize. */ /* Synchronize. */
InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index])))); InvalidatePtc(GetPageTablePhysicalAddress(KVirtualAddress(std::addressof(l1[l1_index]))));

View File

@ -441,7 +441,7 @@ namespace ams::kern::board::nintendo::nx {
KThread::Register(new_thread); KThread::Register(new_thread);
/* Run the thread. */ /* Run the thread. */
new_thread->Run(); MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
} }
} }

View File

@ -140,14 +140,12 @@ namespace ams::kern {
/* Add the previously reserved pages. */ /* Add the previously reserved pages. */
if (src_pool == dst_pool && binary_pages != 0) { if (src_pool == dst_pool && binary_pages != 0) {
/* NOTE: Nintendo does not check the result of this operation. */ MESOSPHERE_R_ABORT_UNLESS(pg.AddBlock(KMemoryLayout::GetLinearPhysicalAddress(data), binary_pages));
pg.AddBlock(KMemoryLayout::GetLinearPhysicalAddress(data), binary_pages);
} }
/* Add the previously unreserved pages. */ /* Add the previously unreserved pages. */
for (const auto &block : unreserve_pg) { for (const auto &block : unreserve_pg) {
/* NOTE: Nintendo does not check the result of this operation. */ MESOSPHERE_R_ABORT_UNLESS(pg.AddBlock(block.GetAddress(), block.GetNumPages()));
pg.AddBlock(block.GetAddress(), block.GetNumPages());
} }
} }
MESOSPHERE_ABORT_UNLESS(pg.GetNumPages() == static_cast<size_t>(params.code_num_pages)); MESOSPHERE_ABORT_UNLESS(pg.GetNumPages() == static_cast<size_t>(params.code_num_pages));

View File

@ -37,7 +37,7 @@ namespace ams::kern {
/* Clear and store cache. */ /* Clear and store cache. */
void * const block_address = GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block.GetAddress())); void * const block_address = GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block.GetAddress()));
std::memset(block_address, 0xFF, block.GetSize()); std::memset(block_address, 0xFF, block.GetSize());
cpu::StoreDataCache(block_address, block.GetSize()); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(block_address, block.GetSize()));
} }
/* Set remaining tracking members. */ /* Set remaining tracking members. */

View File

@ -416,7 +416,8 @@ namespace ams::kern {
KProcess * const target = this->GetProcessUnsafe(); KProcess * const target = this->GetProcessUnsafe();
/* Terminate the process. */ /* Terminate the process. */
target->Terminate(); /* NOTE: This result is seemingly-intentionally not checked by Nintendo. */
static_cast<void>(target->Terminate());
R_SUCCEED(); R_SUCCEED();
} }
@ -1133,7 +1134,7 @@ namespace ams::kern {
R_SUCCEED(); R_SUCCEED();
} }
Result KDebugBase::OnExitProcess(KProcess *process) { void KDebugBase::OnExitProcess(KProcess *process) {
MESOSPHERE_ASSERT(process != nullptr); MESOSPHERE_ASSERT(process != nullptr);
/* Check if we're attached to a debugger. */ /* Check if we're attached to a debugger. */
@ -1148,11 +1149,9 @@ namespace ams::kern {
debug->NotifyAvailable(); debug->NotifyAvailable();
} }
} }
R_SUCCEED();
} }
Result KDebugBase::OnTerminateProcess(KProcess *process) { void KDebugBase::OnTerminateProcess(KProcess *process) {
MESOSPHERE_ASSERT(process != nullptr); MESOSPHERE_ASSERT(process != nullptr);
/* Check if we're attached to a debugger. */ /* Check if we're attached to a debugger. */
@ -1167,21 +1166,17 @@ namespace ams::kern {
debug->NotifyAvailable(); debug->NotifyAvailable();
} }
} }
R_SUCCEED();
} }
Result KDebugBase::OnExitThread(KThread *thread) { void KDebugBase::OnExitThread(KThread *thread) {
MESOSPHERE_ASSERT(thread != nullptr); MESOSPHERE_ASSERT(thread != nullptr);
/* Check if we're attached to a debugger. */ /* Check if we're attached to a debugger. */
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) { if (KProcess *process = thread->GetOwnerProcess(); process != nullptr && process->IsAttachedToDebugger()) {
/* If we are, submit the event. */ /* If we are, submit the event. */
const uintptr_t params[2] = { thread->GetId(), static_cast<uintptr_t>(thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread) }; const uintptr_t params[2] = { thread->GetId(), static_cast<uintptr_t>(thread->IsTerminationRequested() ? ams::svc::ThreadExitReason_TerminateThread : ams::svc::ThreadExitReason_ExitThread) };
R_TRY(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params))); static_cast<void>(OnDebugEvent(ams::svc::DebugEvent_ExitThread, params, util::size(params)));
} }
R_SUCCEED();
} }
} }

View File

@ -167,7 +167,7 @@ namespace ams::kern {
KThread::Register(new_thread); KThread::Register(new_thread);
/* Run the thread. */ /* Run the thread. */
new_thread->Run(); MESOSPHERE_R_ABORT_UNLESS(new_thread->Run());
} }
void KDpcManager::HandleDpc() { void KDpcManager::HandleDpc() {

View File

@ -38,20 +38,20 @@ namespace ams::kern {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
} }
Result KEvent::Signal() { void KEvent::Signal() {
KScopedSchedulerLock sl; KScopedSchedulerLock sl;
R_SUCCEED_IF(m_readable_event_destroyed); if (!m_readable_event_destroyed) {
m_readable_event.Signal();
R_RETURN(m_readable_event.Signal()); }
} }
Result KEvent::Clear() { void KEvent::Clear() {
KScopedSchedulerLock sl; KScopedSchedulerLock sl;
R_SUCCEED_IF(m_readable_event_destroyed); if (!m_readable_event_destroyed) {
m_readable_event.Clear();
R_RETURN(m_readable_event.Clear()); }
} }
void KEvent::PostDestroy(uintptr_t arg) { void KEvent::PostDestroy(uintptr_t arg) {

View File

@ -88,7 +88,7 @@ namespace ams::kern {
} }
} }
Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) { void KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
/* Initialize our members. */ /* Initialize our members. */
m_address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32); m_address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32);
m_address_space_start = KProcessAddress(GetInteger(start)); m_address_space_start = KProcessAddress(GetInteger(start));
@ -130,7 +130,7 @@ namespace ams::kern {
m_impl.InitializeForKernel(table, start, end); m_impl.InitializeForKernel(table, start, end);
/* Initialize our memory block manager. */ /* Initialize our memory block manager. */
R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager)); MESOSPHERE_R_ABORT_UNLESS(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager));
} }
Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) {
@ -1792,7 +1792,7 @@ namespace ams::kern {
/* Ensure cache coherency, if we're setting pages as executable. */ /* Ensure cache coherency, if we're setting pages as executable. */
if (is_x) { if (is_x) {
for (const auto &block : pg) { for (const auto &block : pg) {
cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()));
} }
cpu::InvalidateEntireInstructionCache(); cpu::InvalidateEntireInstructionCache();
} }
@ -2665,8 +2665,7 @@ namespace ams::kern {
/* Invalidate the block. */ /* Invalidate the block. */
if (cur_size > 0) { if (cur_size > 0) {
/* NOTE: Nintendo does not check the result of invalidation. */ MESOSPHERE_R_ABORT_UNLESS(cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
} }
/* Advance. */ /* Advance. */
@ -2689,8 +2688,7 @@ namespace ams::kern {
/* Invalidate the last block. */ /* Invalidate the last block. */
if (cur_size > 0) { if (cur_size > 0) {
/* NOTE: Nintendo does not check the result of invalidation. */ MESOSPHERE_R_ABORT_UNLESS(cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
cpu::InvalidateDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size);
} }
R_SUCCEED(); R_SUCCEED();
@ -2768,7 +2766,7 @@ namespace ams::kern {
if (cur_size >= sizeof(u32)) { if (cur_size >= sizeof(u32)) {
const size_t copy_size = util::AlignDown(cur_size, sizeof(u32)); const size_t copy_size = util::AlignDown(cur_size, sizeof(u32));
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)); const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
cpu::FlushDataCache(copy_src, copy_size); MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(copy_src, copy_size));
R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned32Bit(buffer, copy_src, copy_size), svc::ResultInvalidPointer()); R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned32Bit(buffer, copy_src, copy_size), svc::ResultInvalidPointer());
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size); buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
cur_addr += copy_size; cur_addr += copy_size;
@ -2778,7 +2776,7 @@ namespace ams::kern {
/* Copy remaining data. */ /* Copy remaining data. */
if (cur_size > 0) { if (cur_size > 0) {
const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)); const void * copy_src = GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr));
cpu::FlushDataCache(copy_src, cur_size); MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(copy_src, cur_size));
R_UNLESS(UserspaceAccess::CopyMemoryToUser(buffer, copy_src, cur_size), svc::ResultInvalidPointer()); R_UNLESS(UserspaceAccess::CopyMemoryToUser(buffer, copy_src, cur_size), svc::ResultInvalidPointer());
} }
@ -2853,7 +2851,7 @@ namespace ams::kern {
if (cur_size >= sizeof(u32)) { if (cur_size >= sizeof(u32)) {
const size_t copy_size = util::AlignDown(cur_size, sizeof(u32)); const size_t copy_size = util::AlignDown(cur_size, sizeof(u32));
R_UNLESS(UserspaceAccess::CopyMemoryFromUserAligned32Bit(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, copy_size), svc::ResultInvalidCurrentMemory()); R_UNLESS(UserspaceAccess::CopyMemoryFromUserAligned32Bit(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, copy_size), svc::ResultInvalidCurrentMemory());
cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), copy_size); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), copy_size));
buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size); buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(buffer) + copy_size);
cur_addr += copy_size; cur_addr += copy_size;
@ -2863,7 +2861,7 @@ namespace ams::kern {
/* Copy remaining data. */ /* Copy remaining data. */
if (cur_size > 0) { if (cur_size > 0) {
R_UNLESS(UserspaceAccess::CopyMemoryFromUser(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, cur_size), svc::ResultInvalidCurrentMemory()); R_UNLESS(UserspaceAccess::CopyMemoryFromUser(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), buffer, cur_size), svc::ResultInvalidCurrentMemory());
cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size); MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(GetVoidPointer(GetLinearMappedVirtualAddress(cur_addr)), cur_size));
} }
R_SUCCEED(); R_SUCCEED();

View File

@ -404,7 +404,7 @@ namespace ams::kern {
void KProcess::DoWorkerTaskImpl() { void KProcess::DoWorkerTaskImpl() {
/* Terminate child threads. */ /* Terminate child threads. */
TerminateChildren(this, nullptr); MESOSPHERE_R_ABORT_UNLESS(TerminateChildren(this, nullptr));
/* Finalize the handle table, if we're not immortal. */ /* Finalize the handle table, if we're not immortal. */
if (!m_is_immortal && m_is_handle_table_initialized) { if (!m_is_immortal && m_is_handle_table_initialized) {
@ -420,7 +420,7 @@ namespace ams::kern {
Result KProcess::StartTermination() { Result KProcess::StartTermination() {
/* Finalize the handle table when we're done, if the process isn't immortal. */ /* Finalize the handle table when we're done, if the process isn't immortal. */
ON_SCOPE_EXIT { ON_RESULT_SUCCESS {
if (!m_is_immortal) { if (!m_is_immortal) {
this->FinalizeHandleTable(); this->FinalizeHandleTable();
} }
@ -471,7 +471,7 @@ namespace ams::kern {
/* If we need to start termination, do so. */ /* If we need to start termination, do so. */
if (needs_terminate) { if (needs_terminate) {
this->StartTermination(); static_cast<void>(this->StartTermination());
/* Note for debug that we're exiting the process. */ /* Note for debug that we're exiting the process. */
MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name); MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name);
@ -507,23 +507,26 @@ namespace ams::kern {
/* If we need to terminate, do so. */ /* If we need to terminate, do so. */
if (needs_terminate) { if (needs_terminate) {
/* Start termination. */ /* If we fail to terminate, register as a worker task. */
if (R_SUCCEEDED(this->StartTermination())) { ON_RESULT_FAILURE {
/* Note for debug that we're terminating the process. */
MESOSPHERE_LOG("KProcess::Terminate() OK pid=%ld name=%-12s\n", m_process_id, m_name);
/* Call the debug callback. */
KDebug::OnTerminateProcess(this);
/* Finish termination. */
this->FinishTermination();
} else {
/* Note for debug that we're terminating the process. */ /* Note for debug that we're terminating the process. */
MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name); MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name);
/* Register the process as a work task. */ /* Register the process as a work task. */
KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this); KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this);
} };
/* Start termination. */
R_TRY(this->StartTermination());
/* Note for debug that we're terminating the process. */
MESOSPHERE_LOG("KProcess::Terminate() OK pid=%ld name=%-12s\n", m_process_id, m_name);
/* Call the debug callback. */
KDebug::OnTerminateProcess(this);
/* Finish termination. */
this->FinishTermination();
} }
R_SUCCEED(); R_SUCCEED();
@ -666,7 +669,7 @@ namespace ams::kern {
R_SUCCEED(); R_SUCCEED();
} }
Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) { void KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
KThreadLocalPage *page_to_free = nullptr; KThreadLocalPage *page_to_free = nullptr;
/* Release the region. */ /* Release the region. */
@ -678,7 +681,7 @@ namespace ams::kern {
if (it == m_partially_used_tlp_tree.end()) { if (it == m_partially_used_tlp_tree.end()) {
/* If we don't find it, it has to be in the fully used list. */ /* If we don't find it, it has to be in the fully used list. */
it = m_fully_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize)); it = m_fully_used_tlp_tree.find_key(util::AlignDown(GetInteger(addr), PageSize));
R_UNLESS(it != m_fully_used_tlp_tree.end(), svc::ResultInvalidAddress()); MESOSPHERE_ABORT_UNLESS(it != m_fully_used_tlp_tree.end());
/* Release the region. */ /* Release the region. */
it->Release(addr); it->Release(addr);
@ -710,8 +713,6 @@ namespace ams::kern {
KThreadLocalPage::Free(page_to_free); KThreadLocalPage::Free(page_to_free);
} }
R_SUCCEED();
} }
void *KProcess::GetThreadLocalRegionPointer(KProcessAddress addr) { void *KProcess::GetThreadLocalRegionPointer(KProcessAddress addr) {
@ -767,7 +768,7 @@ namespace ams::kern {
MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0); MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0);
if (const auto prev = m_num_running_threads--; prev == 1) { if (const auto prev = m_num_running_threads--; prev == 1) {
this->Terminate(); static_cast<void>(this->Terminate());
} }
} }

View File

@ -46,7 +46,7 @@ namespace ams::kern {
} }
} }
Result KReadableEvent::Signal() { void KReadableEvent::Signal() {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
KScopedSchedulerLock lk; KScopedSchedulerLock lk;
@ -55,8 +55,6 @@ namespace ams::kern {
m_is_signaled = true; m_is_signaled = true;
this->NotifyAvailable(); this->NotifyAvailable();
} }
R_SUCCEED();
} }
Result KReadableEvent::Reset() { Result KReadableEvent::Reset() {

View File

@ -65,7 +65,7 @@ namespace ams::kern {
} }
/* Bind interrupt handler. */ /* Bind interrupt handler. */
Kernel::GetInterruptManager().BindHandler(GetSchedulerInterruptHandler(), KInterruptName_Scheduler, m_core_id, KInterruptController::PriorityLevel_Scheduler, false, false); MESOSPHERE_R_ABORT_UNLESS(Kernel::GetInterruptManager().BindHandler(GetSchedulerInterruptHandler(), KInterruptName_Scheduler, m_core_id, KInterruptController::PriorityLevel_Scheduler, false, false));
/* Set the current thread. */ /* Set the current thread. */
m_current_thread = GetCurrentThreadPointer(); m_current_thread = GetCurrentThreadPointer();

View File

@ -476,8 +476,8 @@ namespace ams::kern {
/* Ensure that we clean up on failure. */ /* Ensure that we clean up on failure. */
ON_RESULT_FAILURE { ON_RESULT_FAILURE {
dst_page_table.CleanupForIpcServer(dst_address, size, dst_state); static_cast<void>(dst_page_table.CleanupForIpcServer(dst_address, size, dst_state));
src_page_table.CleanupForIpcClient(src_address, size, dst_state); static_cast<void>(src_page_table.CleanupForIpcClient(src_address, size, dst_state));
}; };
/* Push the appropriate mapping. */ /* Push the appropriate mapping. */
@ -582,7 +582,7 @@ namespace ams::kern {
/* Set up a guard to make sure that we end up in a clean state on error. */ /* Set up a guard to make sure that we end up in a clean state on error. */
ON_RESULT_FAILURE { ON_RESULT_FAILURE {
/* Cleanup mappings. */ /* Cleanup mappings. */
CleanupMap(request, std::addressof(dst_process), std::addressof(src_page_table)); static_cast<void>(CleanupMap(request, std::addressof(dst_process), std::addressof(src_page_table)));
/* Cleanup special data. */ /* Cleanup special data. */
if (src_header.GetHasSpecialHeader()) { if (src_header.GetHasSpecialHeader()) {
@ -835,11 +835,11 @@ namespace ams::kern {
CleanupSpecialData(dst_process, dst_msg_ptr, dst_buffer_size); CleanupSpecialData(dst_process, dst_msg_ptr, dst_buffer_size);
} }
} else { } else {
CleanupServerHandles(src_user ? src_message_buffer : 0, src_buffer_size, src_message_paddr); static_cast<void>(CleanupServerHandles(src_user ? src_message_buffer : 0, src_buffer_size, src_message_paddr));
} }
/* Cleanup mappings. */ /* Cleanup mappings. */
CleanupMap(request, std::addressof(src_process), std::addressof(dst_page_table)); static_cast<void>(CleanupMap(request, std::addressof(src_process), std::addressof(dst_page_table)));
}; };
/* Ensure that the headers fit. */ /* Ensure that the headers fit. */
@ -1052,7 +1052,7 @@ namespace ams::kern {
/* Unlock the client buffer. */ /* Unlock the client buffer. */
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size); static_cast<void>(client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size));
/* Signal the event. */ /* Signal the event. */
event->Signal(); event->Signal();
@ -1156,7 +1156,7 @@ namespace ams::kern {
/* Unlock the client buffer. */ /* Unlock the client buffer. */
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size); static_cast<void>(client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size));
/* Signal the event. */ /* Signal the event. */
event->Signal(); event->Signal();
@ -1284,7 +1284,7 @@ namespace ams::kern {
/* Unlock the client buffer. */ /* Unlock the client buffer. */
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size); static_cast<void>(client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size));
/* Signal the event. */ /* Signal the event. */
event->Signal(); event->Signal();
@ -1383,7 +1383,7 @@ namespace ams::kern {
/* Unlock the buffer. */ /* Unlock the buffer. */
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize()); static_cast<void>(client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize()));
/* Signal the event. */ /* Signal the event. */
event->Signal(); event->Signal();

View File

@ -42,7 +42,7 @@ namespace ams::kern {
R_UNLESS(m_resource_size > rc_size, svc::ResultOutOfMemory()); R_UNLESS(m_resource_size > rc_size, svc::ResultOutOfMemory());
/* Initialize slab heaps. */ /* Initialize slab heaps. */
m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size, PageSize); R_TRY(m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size, PageSize));
m_page_table_heap.Initialize(std::addressof(m_dynamic_page_manager), 0, GetPointer<KPageTableManager::RefCount>(m_resource_address)); m_page_table_heap.Initialize(std::addressof(m_dynamic_page_manager), 0, GetPointer<KPageTableManager::RefCount>(m_resource_address));
m_memory_block_heap.Initialize(std::addressof(m_dynamic_page_manager), 0); m_memory_block_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
m_block_info_heap.Initialize(std::addressof(m_dynamic_page_manager), 0); m_block_info_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);

View File

@ -392,7 +392,7 @@ namespace ams::kern {
/* If the thread has a local region, delete it. */ /* If the thread has a local region, delete it. */
if (m_tls_address != Null<KProcessAddress>) { if (m_tls_address != Null<KProcessAddress>) {
MESOSPHERE_R_ABORT_UNLESS(m_parent->DeleteThreadLocalRegion(m_tls_address)); m_parent->DeleteThreadLocalRegion(m_tls_address);
} }
/* Release any waiters. */ /* Release any waiters. */
@ -697,7 +697,7 @@ namespace ams::kern {
R_SUCCEED(); R_SUCCEED();
} }
Result KThread::GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask) { void KThread::GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask) {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
{ {
KScopedSchedulerLock sl; KScopedSchedulerLock sl;
@ -712,8 +712,6 @@ namespace ams::kern {
*out_affinity_mask = m_original_physical_affinity_mask.GetAffinityMask(); *out_affinity_mask = m_original_physical_affinity_mask.GetAffinityMask();
} }
} }
R_SUCCEED();
} }
Result KThread::SetCoreMask(int32_t core_id, u64 v_affinity_mask) { Result KThread::SetCoreMask(int32_t core_id, u64 v_affinity_mask) {
@ -852,7 +850,7 @@ namespace ams::kern {
} }
} }
Result KThread::SetPriorityToIdle() { void KThread::SetPriorityToIdle() {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
KScopedSchedulerLock sl; KScopedSchedulerLock sl;
@ -862,8 +860,6 @@ namespace ams::kern {
m_priority = IdleThreadPriority; m_priority = IdleThreadPriority;
m_base_priority = IdleThreadPriority; m_base_priority = IdleThreadPriority;
KScheduler::OnThreadPriorityChanged(this, old_priority); KScheduler::OnThreadPriorityChanged(this, old_priority);
R_SUCCEED();
} }
void KThread::RequestSuspend(SuspendType type) { void KThread::RequestSuspend(SuspendType type) {
@ -1407,7 +1403,7 @@ namespace ams::kern {
return this->GetState(); return this->GetState();
} }
Result KThread::Sleep(s64 timeout) { void KThread::Sleep(s64 timeout) {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
MESOSPHERE_ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread()); MESOSPHERE_ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread());
MESOSPHERE_ASSERT(this == GetCurrentThreadPointer()); MESOSPHERE_ASSERT(this == GetCurrentThreadPointer());
@ -1422,15 +1418,13 @@ namespace ams::kern {
/* Check if the thread should terminate. */ /* Check if the thread should terminate. */
if (this->IsTerminationRequested()) { if (this->IsTerminationRequested()) {
slp.CancelSleep(); slp.CancelSleep();
R_THROW(svc::ResultTerminationRequested()); return;
} }
/* Wait for the sleep to end. */ /* Wait for the sleep to end. */
wait_queue.SetHardwareTimer(timer); wait_queue.SetHardwareTimer(timer);
this->BeginWait(std::addressof(wait_queue)); this->BeginWait(std::addressof(wait_queue));
} }
R_SUCCEED();
} }
void KThread::BeginWait(KThreadQueue *queue) { void KThread::BeginWait(KThreadQueue *queue) {

View File

@ -32,7 +32,7 @@ namespace ams::kern {
R_RETURN(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, page_buf->GetPhysicalAddress(), KMemoryState_ThreadLocal, KMemoryPermission_UserReadWrite)); R_RETURN(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, page_buf->GetPhysicalAddress(), KMemoryState_ThreadLocal, KMemoryPermission_UserReadWrite));
} }
Result KThreadLocalPage::Finalize() { void KThreadLocalPage::Finalize() {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
/* Get the physical address of the page. */ /* Get the physical address of the page. */
@ -40,11 +40,10 @@ namespace ams::kern {
MESOSPHERE_ABORT_UNLESS(m_owner->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), this->GetAddress())); MESOSPHERE_ABORT_UNLESS(m_owner->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), this->GetAddress()));
/* Unmap the page. */ /* Unmap the page. */
R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState_ThreadLocal)); MESOSPHERE_R_ABORT_UNLESS(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState_ThreadLocal));
/* Free the page. */ /* Free the page. */
KPageBuffer::FreeChecked<PageSize>(KPageBuffer::FromPhysicalAddress(phys_addr)); KPageBuffer::FreeChecked<PageSize>(KPageBuffer::FromPhysicalAddress(phys_addr));
R_SUCCEED();
} }
KProcessAddress KThreadLocalPage::Reserve() { KProcessAddress KThreadLocalPage::Reserve() {

View File

@ -67,7 +67,7 @@ namespace ams::kern {
KThread::Register(thread); KThread::Register(thread);
/* Run the thread. */ /* Run the thread. */
thread->Run(); MESOSPHERE_R_ABORT_UNLESS(thread->Run());
} }
void KWorkerTaskManager::AddTask(WorkerType type, KWorkerTask *task) { void KWorkerTaskManager::AddTask(WorkerType type, KWorkerTask *task) {

View File

@ -52,8 +52,8 @@ namespace ams::kern {
void *idle_thread_stack = GetVoidPointer(KMemoryLayout::GetIdleStackTopAddress(core_id)); void *idle_thread_stack = GetVoidPointer(KMemoryLayout::GetIdleStackTopAddress(core_id));
KAutoObject::Create<KThread>(main_thread); KAutoObject::Create<KThread>(main_thread);
KAutoObject::Create<KThread>(idle_thread); KAutoObject::Create<KThread>(idle_thread);
main_thread->Initialize(nullptr, 0, main_thread_stack, 0, KThread::MainThreadPriority, core_id, nullptr, KThread::ThreadType_Main); MESOSPHERE_R_ABORT_UNLESS(main_thread->Initialize(nullptr, 0, main_thread_stack, 0, KThread::MainThreadPriority, core_id, nullptr, KThread::ThreadType_Main));
idle_thread->Initialize(nullptr, 0, idle_thread_stack, 0, KThread::IdleThreadPriority, core_id, nullptr, KThread::ThreadType_Main); MESOSPHERE_R_ABORT_UNLESS(idle_thread->Initialize(nullptr, 0, idle_thread_stack, 0, KThread::IdleThreadPriority, core_id, nullptr, KThread::ThreadType_Main));
/* Set the current thread to be the main thread, and we have no processes running yet. */ /* Set the current thread to be the main thread, and we have no processes running yet. */
SetCurrentThread(main_thread); SetCurrentThread(main_thread);
@ -79,7 +79,7 @@ namespace ams::kern {
KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr; KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr;
/* Initialize the resource managers' shared page manager. */ /* Initialize the resource managers' shared page manager. */
g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize)); MESOSPHERE_R_ABORT_UNLESS(g_resource_manager_page_manager.Initialize(address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize)));
/* Initialize the KPageBuffer slab heap. */ /* Initialize the KPageBuffer slab heap. */
KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager); KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager);

View File

@ -131,7 +131,7 @@ namespace ams::kern::svc {
} else { } else {
class StoreCacheOperation : public CacheOperation { class StoreCacheOperation : public CacheOperation {
public: public:
virtual void Operate(void *address, size_t size) const override { cpu::StoreDataCache(address, size); } virtual void Operate(void *address, size_t size) const override { MESOSPHERE_R_ABORT_UNLESS(cpu::StoreDataCache(address, size)); }
} operation; } operation;
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size)); R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));
@ -158,7 +158,7 @@ namespace ams::kern::svc {
} else { } else {
class FlushCacheOperation : public CacheOperation { class FlushCacheOperation : public CacheOperation {
public: public:
virtual void Operate(void *address, size_t size) const override { cpu::FlushDataCache(address, size); } virtual void Operate(void *address, size_t size) const override { MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(address, size)); }
} operation; } operation;
R_RETURN(DoProcessCacheOperation(operation, page_table, address, size)); R_RETURN(DoProcessCacheOperation(operation, page_table, address, size));

View File

@ -29,7 +29,8 @@ namespace ams::kern::svc {
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle); KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
R_UNLESS(event.IsNotNull(), svc::ResultInvalidHandle()); R_UNLESS(event.IsNotNull(), svc::ResultInvalidHandle());
R_RETURN(event->Signal()); event->Signal();
R_SUCCEED();
} }
Result ClearEvent(ams::svc::Handle event_handle) { Result ClearEvent(ams::svc::Handle event_handle) {
@ -40,7 +41,7 @@ namespace ams::kern::svc {
{ {
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle); KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
if (event.IsNotNull()) { if (event.IsNotNull()) {
R_RETURN(event->Clear()); event->Clear();
} }
} }
@ -49,9 +50,9 @@ namespace ams::kern::svc {
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle); KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
if (readable_event.IsNotNull()) { if (readable_event.IsNotNull()) {
if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) { if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) {
R_RETURN(interrupt_event->Clear()); interrupt_event->Clear();
} else { } else {
R_RETURN(readable_event->Clear()); readable_event->Clear();
} }
} }
} }

View File

@ -148,7 +148,7 @@ namespace ams::kern::svc {
{ {
/* If we fail to send the message, unlock the message buffer. */ /* If we fail to send the message, unlock the message buffer. */
ON_RESULT_FAILURE { page_table.UnlockForIpcUserBuffer(message, buffer_size); }; ON_RESULT_FAILURE { static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size)); };
/* Send the request. */ /* Send the request. */
MESOSPHERE_ASSERT(message != 0); MESOSPHERE_ASSERT(message != 0);
@ -220,7 +220,7 @@ namespace ams::kern::svc {
/* Ensure that if we fail and aren't terminating that we unlock the user buffer. */ /* Ensure that if we fail and aren't terminating that we unlock the user buffer. */
ON_RESULT_FAILURE_BESIDES(svc::ResultTerminationRequested) { ON_RESULT_FAILURE_BESIDES(svc::ResultTerminationRequested) {
page_table.UnlockForIpcUserBuffer(message, buffer_size); static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size));
}; };
/* Send the request. */ /* Send the request. */
@ -248,7 +248,7 @@ namespace ams::kern::svc {
{ {
/* If we fail to send the message, unlock the message buffer. */ /* If we fail to send the message, unlock the message buffer. */
ON_RESULT_FAILURE { page_table.UnlockForIpcUserBuffer(message, buffer_size); }; ON_RESULT_FAILURE { static_cast<void>(page_table.UnlockForIpcUserBuffer(message, buffer_size)); };
/* Reply/Receive the request. */ /* Reply/Receive the request. */
MESOSPHERE_ASSERT(message != 0); MESOSPHERE_ASSERT(message != 0);

View File

@ -165,8 +165,8 @@
HANDLER(NvHostErrInfo, 124 ) \ HANDLER(NvHostErrInfo, 124 ) \
HANDLER(RunningUlaInfo, 125 ) \ HANDLER(RunningUlaInfo, 125 ) \
HANDLER(InternalPanelInfo, 126 ) \ HANDLER(InternalPanelInfo, 126 ) \
HANDLER(ResourceLimitLimitInfo, 127 ) \ HANDLER(ResourceLimitInfo, 127 ) \
HANDLER(ResourceLimitPeakInfo, 128 ) \ HANDLER(ResourceLimitPeakInfoDeprecated, 128 ) \
HANDLER(TouchScreenInfo, 129 ) \ HANDLER(TouchScreenInfo, 129 ) \
HANDLER(AcpUserAccountSettingsInfo, 130 ) \ HANDLER(AcpUserAccountSettingsInfo, 130 ) \
HANDLER(AudioDeviceInfo, 131 ) \ HANDLER(AudioDeviceInfo, 131 ) \
@ -811,16 +811,16 @@
HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemThreadCountLimit, 619, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemEventCountLimit, 620, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemSessionCountLimit, 622, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemThreadCountPeak, 624, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemEventCountPeak, 625, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemSessionCountPeak, 627, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \

View File

@ -422,7 +422,7 @@ namespace ams::ncm {
public: public:
void Reset() { void Reset() {
if (m_accessor != nullptr) { if (m_accessor != nullptr) {
m_accessor->ReleasePin(m_pin_id); static_cast<void>(m_accessor->ReleasePin(m_pin_id));
m_accessor = nullptr; m_accessor = nullptr;
} }
} }
@ -479,7 +479,7 @@ namespace ams::ncm {
/* Mark the memory as in use. */ /* Mark the memory as in use. */
R_RETURN(m_mapper->MarkUsing(memory.id)); R_RETURN(m_mapper->MarkUsing(memory.id));
ON_SCOPE_EXIT { this->ReleasePin(memory.id); }; ON_SCOPE_EXIT { static_cast<void>(this->ReleasePin(memory.id)); };
/* Copy out the struct. */ /* Copy out the struct. */
*out = *reinterpret_cast<const T *>(memory.GetBuffer(offset, sizeof(T))); *out = *reinterpret_cast<const T *>(memory.GetBuffer(offset, sizeof(T)));

View File

@ -34,7 +34,7 @@ ATMOSPHERE_OPTIMIZATION_FLAG := -O2
endif endif
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -flto SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -Wextra -Werror -Wno-missing-field-initializers -flto -Wno-error=unused-result
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS)
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES)

View File

@ -20,7 +20,7 @@ namespace ams::cs {
void InitializeTargetIoServer() { void InitializeTargetIoServer() {
/* Launch target io server. */ /* Launch target io server. */
os::ProcessId process_id; os::ProcessId process_id;
scs::LaunchProgram(std::addressof(process_id), ncm::ProgramLocation::Make(ncm::SystemProgramId::DevServer, ncm::StorageId::None), nullptr, 0, 0); static_cast<void>(scs::LaunchProgram(std::addressof(process_id), ncm::ProgramLocation::Make(ncm::SystemProgramId::DevServer, ncm::StorageId::None), nullptr, 0, 0));
} }
} }

View File

@ -35,7 +35,9 @@ namespace ams::erpt::srv {
Attachment::~Attachment() { Attachment::~Attachment() {
this->CloseStream(); this->CloseStream();
if (m_record->RemoveReference()) { if (m_record->RemoveReference()) {
this->DeleteStream(this->FileName().name); if (R_FAILED(this->DeleteStream(this->FileName().name))) {
/* TODO: Log failure? */
}
delete m_record; delete m_record;
} }
} }

View File

@ -81,7 +81,7 @@ namespace ams::erpt::srv {
oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt)); oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt));
} }
Formatter::AddField(report, FieldId_CipherKey, cipher, sizeof(cipher)); R_TRY(Formatter::AddField(report, FieldId_CipherKey, cipher, s_need_to_store_cipher ? sizeof(cipher) : 1));
std::memset(s_key, 0, sizeof(s_key)); std::memset(s_key, 0, sizeof(s_key));
R_RETURN(Formatter::End(report)); R_RETURN(Formatter::End(report));

View File

@ -90,16 +90,15 @@ namespace ams::erpt::srv {
Result Context::WriteContextsToReport(Report *report) { Result Context::WriteContextsToReport(Report *report) {
R_TRY(report->Open(ReportOpenType_Create)); R_TRY(report->Open(ReportOpenType_Create));
ON_SCOPE_EXIT { report->Close(); };
R_TRY(Cipher::Begin(report, ContextRecord::GetRecordCount())); R_TRY(Cipher::Begin(report, ContextRecord::GetRecordCount()));
for (auto it = g_category_list.begin(); it != g_category_list.end(); it++) { for (auto it = g_category_list.begin(); it != g_category_list.end(); it++) {
R_TRY(it->AddCategoryToReport(report)); R_TRY(it->AddCategoryToReport(report));
} }
Cipher::End(report); R_RETURN(Cipher::End(report));
report->Close();
R_SUCCEED();
} }
Result Context::ClearContext(CategoryId cat) { Result Context::ClearContext(CategoryId cat) {

View File

@ -211,7 +211,7 @@ namespace ams::erpt::srv {
Result ContextImpl::InvalidateForcedShutdownDetection() { Result ContextImpl::InvalidateForcedShutdownDetection() {
/* NOTE: Nintendo does not check the result here. */ /* NOTE: Nintendo does not check the result here. */
erpt::srv::InvalidateForcedShutdownDetection(); static_cast<void>(erpt::srv::InvalidateForcedShutdownDetection());
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -228,27 +228,27 @@ namespace ams::erpt::srv {
/* Check if the forced shutdown context exists; if it doesn't, we should create an empty one. */ /* Check if the forced shutdown context exists; if it doesn't, we should create an empty one. */
if (!IsForceShutdownDetected()) { if (!IsForceShutdownDetected()) {
/* NOTE: Nintendo does not check result here. */ /* NOTE: Nintendo does not check result here. */
CreateForcedShutdownContext(); static_cast<void>(CreateForcedShutdownContext());
return; return;
} }
/* Load the forced shutdown context. */ /* Load the forced shutdown context. */
/* NOTE: Nintendo does not check that this succeeds. */ /* NOTE: Nintendo does not check that this succeeds. */
LoadForcedShutdownContext(); static_cast<void>(LoadForcedShutdownContext());
/* Create report for the forced shutdown. */ /* Create report for the forced shutdown. */
/* NOTE: Nintendo does not check that this succeeds. */ /* NOTE: Nintendo does not check that this succeeds. */
CreateReportForForcedShutdown(); static_cast<void>(CreateReportForForcedShutdown());
/* Clear the forced shutdown categories. */ /* Clear the forced shutdown categories. */
/* NOTE: Nintendo does not check that this succeeds. */ /* NOTE: Nintendo does not check that this succeeds. */
Context::ClearContext(CategoryId_RunningApplicationInfo); static_cast<void>(Context::ClearContext(CategoryId_RunningApplicationInfo));
Context::ClearContext(CategoryId_RunningAppletInfo); static_cast<void>(Context::ClearContext(CategoryId_RunningAppletInfo));
Context::ClearContext(CategoryId_FocusedAppletHistoryInfo); static_cast<void>(Context::ClearContext(CategoryId_FocusedAppletHistoryInfo));
/* Save the forced shutdown context. */ /* Save the forced shutdown context. */
/* NOTE: Nintendo does not check that this succeeds. */ /* NOTE: Nintendo does not check that this succeeds. */
SaveForcedShutdownContext(); static_cast<void>(SaveForcedShutdownContext());
} }
void FinalizeForcedShutdownDetection() { void FinalizeForcedShutdownDetection() {
@ -265,7 +265,7 @@ namespace ams::erpt::srv {
void SaveForcedShutdownContext() { void SaveForcedShutdownContext() {
/* NOTE: Nintendo does not check that saving the report succeeds. */ /* NOTE: Nintendo does not check that saving the report succeeds. */
SaveForcedShutdownContextImpl(); static_cast<void>(SaveForcedShutdownContextImpl());
} }
void SubmitContextForForcedShutdownDetection(const ContextEntry *entry, const u8 *data, u32 data_size) { void SubmitContextForForcedShutdownDetection(const ContextEntry *entry, const u8 *data, u32 data_size) {

View File

@ -42,7 +42,7 @@ namespace ams::erpt::srv {
/* Close and commit the stream. */ /* Close and commit the stream. */
stream.CloseStream(); stream.CloseStream();
stream.CommitStream(); R_TRY(stream.CommitStream());
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -34,7 +34,9 @@ namespace ams::erpt::srv {
auto *record = std::addressof(*it); auto *record = std::addressof(*it);
it = s_attachment_list.erase(s_attachment_list.iterator_to(*record)); it = s_attachment_list.erase(s_attachment_list.iterator_to(*record));
if (record->RemoveReference()) { if (record->RemoveReference()) {
Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name); if (R_FAILED(Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name))) {
/* TODO: Log failure? */
}
delete record; delete record;
} }
} }
@ -66,7 +68,9 @@ namespace ams::erpt::srv {
/* Delete the object, if we should. */ /* Delete the object, if we should. */
if (record->RemoveReference()) { if (record->RemoveReference()) {
Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name); const auto delete_res = Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
R_ASSERT(delete_res);
AMS_UNUSED(delete_res);
delete record; delete record;
} }
} else { } else {
@ -128,12 +132,13 @@ namespace ams::erpt::srv {
} }
if (record->m_info.flags.Test<AttachmentFlag::HasOwner>() && JournalForReports::RetrieveRecord(record->m_info.owner_report_id) != nullptr) { if (record->m_info.flags.Test<AttachmentFlag::HasOwner>() && JournalForReports::RetrieveRecord(record->m_info.owner_report_id) != nullptr) {
/* NOTE: Nintendo does not check the result of storing the new record... */
record_guard.Cancel(); record_guard.Cancel();
StoreRecord(record); R_TRY(StoreRecord(record));
} else { } else {
/* If the attachment has no owner (or we deleted the report), delete the file associated with it. */ /* If the attachment has no owner (or we deleted the report), delete the file associated with it. */
Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name); const auto delete_res = Stream::DeleteStream(Attachment::FileName(record->m_info.attachment_id).name);
R_ASSERT(delete_res);
AMS_UNUSED(delete_res);
} }
} }

View File

@ -29,7 +29,9 @@ namespace ams::erpt::srv {
auto *record = std::addressof(*it); auto *record = std::addressof(*it);
it = s_record_list.erase(s_record_list.iterator_to(*record)); it = s_record_list.erase(s_record_list.iterator_to(*record));
if (record->RemoveReference()) { if (record->RemoveReference()) {
Stream::DeleteStream(Report::FileName(record->m_info.id, false).name); if (R_FAILED(Stream::DeleteStream(Report::FileName(record->m_info.id, false).name))) {
/* TODO: Log failure? */
}
delete record; delete record;
} }
} }
@ -65,12 +67,14 @@ namespace ams::erpt::srv {
/* Delete any attachments. */ /* Delete any attachments. */
if (force_delete_attachments || record->m_info.flags.Test<ReportFlag::HasAttachment>()) { if (force_delete_attachments || record->m_info.flags.Test<ReportFlag::HasAttachment>()) {
JournalForAttachments::DeleteAttachments(record->m_info.id); static_cast<void>(JournalForAttachments::DeleteAttachments(record->m_info.id));
} }
/* Delete the object, if we should. */ /* Delete the object, if we should. */
if (record->RemoveReference()) { if (record->RemoveReference()) {
Stream::DeleteStream(Report::FileName(record->m_info.id, false).name); const auto delete_res = Stream::DeleteStream(Report::FileName(record->m_info.id, false).name);
R_ASSERT(delete_res);
AMS_UNUSED(delete_res);
delete record; delete record;
} }
} }
@ -164,8 +168,7 @@ namespace ams::erpt::srv {
record_guard.Cancel(); record_guard.Cancel();
/* NOTE: Nintendo does not check the result of storing the new record... */ R_TRY(StoreRecord(record));
StoreRecord(record);
} }
cleanup_guard.Cancel(); cleanup_guard.Cancel();

View File

@ -56,8 +56,8 @@ namespace ams::erpt::srv {
fs::DisableAutoSaveDataCreation(); fs::DisableAutoSaveDataCreation();
/* Extend the system save data. */ /* Extend the system save data. */
/* NOTE: Nintendo does not check result of this. */ /* NOTE: Nintendo used to not check the result of this; they do now, but . */
ExtendSystemSaveData(); static_cast<void>(ExtendSystemSaveData());
R_TRY_CATCH(fs::MountSystemSaveData(ReportStoragePath, SystemSaveDataId)) { R_TRY_CATCH(fs::MountSystemSaveData(ReportStoragePath, SystemSaveDataId)) {
R_CATCH(fs::ResultTargetNotFound) { R_CATCH(fs::ResultTargetNotFound) {
@ -97,7 +97,7 @@ namespace ams::erpt::srv {
} }
if (report_count >= MinimumReportCountForCleanup) { if (report_count >= MinimumReportCountForCleanup) {
fs::CleanDirectoryRecursively(ReportOnSdStorageRootDirectoryPath); static_cast<void>(fs::CleanDirectoryRecursively(ReportOnSdStorageRootDirectoryPath));
} }
} }
@ -110,7 +110,9 @@ namespace ams::erpt::srv {
AMS_ABORT_UNLESS(ctx != nullptr); AMS_ABORT_UNLESS(ctx != nullptr);
} }
Journal::Restore(); if (R_FAILED(Journal::Restore())) {
/* TODO: Nintendo deletes system savedata when this fails. Should we?. */
}
Reporter::UpdatePowerOnTime(); Reporter::UpdatePowerOnTime();
Reporter::UpdateAwakeTime(); Reporter::UpdateAwakeTime();

View File

@ -39,11 +39,10 @@ namespace ams::erpt::srv {
m_system_event.Signal(); m_system_event.Signal();
} }
Result ManagerImpl::NotifyAll() { void ManagerImpl::NotifyAll() {
for (auto &manager : g_manager_list) { for (auto &manager : g_manager_list) {
manager.NotifyOne(); manager.NotifyOne();
} }
R_SUCCEED();
} }
Result ManagerImpl::GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter) { Result ManagerImpl::GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter) {

View File

@ -27,7 +27,7 @@ namespace ams::erpt::srv {
private: private:
void NotifyOne(); void NotifyOne();
public: public:
static Result NotifyAll(); static void NotifyAll();
public: public:
Result GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter); Result GetReportList(const ams::sf::OutBuffer &out_list, ReportType type_filter);
Result GetEvent(ams::sf::OutCopyHandle out); Result GetEvent(ams::sf::OutCopyHandle out);

View File

@ -41,7 +41,9 @@ namespace ams::erpt::srv {
Report::~Report() { Report::~Report() {
this->CloseStream(); this->CloseStream();
if (m_record->RemoveReference()) { if (m_record->RemoveReference()) {
this->DeleteStream(this->FileName().name); if (R_FAILED(this->DeleteStream(this->FileName().name))) {
/* TODO: Log failure? */
}
delete m_record; delete m_record;
} }
} }

View File

@ -124,29 +124,19 @@ namespace ams::erpt::srv {
if (error_context_total_size == 0) { if (error_context_total_size == 0) {
return; return;
} }
record->Add(FieldId_ErrorContextTotalSize, error_context_total_size); static_cast<void>(record->Add(FieldId_ErrorContextTotalSize, error_context_total_size));
/* Set the context. */ /* Set the context. */
if (error_context_size == 0) { if (error_context_size == 0) {
return; return;
} }
record->Add(FieldId_ErrorContextSize, error_context_size); static_cast<void>(record->Add(FieldId_ErrorContextSize, error_context_size));
record->Add(FieldId_ErrorContext, error_context, error_context_size); static_cast<void>(record->Add(FieldId_ErrorContext, error_context, error_context_size));
} }
constinit os::SdkMutex g_limit_mutex; void SubmitResourceLimitContexts() {
constinit bool g_submitted_limit = false;
void SubmitResourceLimitLimitContext() {
std::scoped_lock lk(g_limit_mutex);
if (g_submitted_limit) {
return;
}
ON_SCOPE_EXIT { g_submitted_limit = true; };
/* Create and populate the record. */ /* Create and populate the record. */
auto record = std::make_unique<ContextRecord>(CategoryId_ResourceLimitLimitInfo); auto record = std::make_unique<ContextRecord>(CategoryId_ResourceLimitInfo);
if (record == nullptr) { if (record == nullptr) {
return; return;
} }
@ -165,7 +155,15 @@ namespace ams::erpt::srv {
if (R_FAILED(svc::GetResourceLimitLimitValue(std::addressof(limit_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ if (R_FAILED(svc::GetResourceLimitLimitValue(std::addressof(limit_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \
return; \ return; \
} \ } \
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \ if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \
return; \
} \
\
s64 peak_value; \
if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \
return; \
} \
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \
return; \ return; \
} \ } \
} while (0) } while (0)
@ -178,51 +176,7 @@ namespace ams::erpt::srv {
#undef ADD_RESOURCE #undef ADD_RESOURCE
Context::SubmitContextRecord(std::move(record)); static_cast<void>(Context::SubmitContextRecord(std::move(record)));
g_submitted_limit = true;
}
void SubmitResourceLimitPeakContext() {
/* Create and populate the record. */
auto record = std::make_unique<ContextRecord>(CategoryId_ResourceLimitPeakInfo);
if (record == nullptr) {
return;
}
u64 reslimit_handle_value;
if (R_FAILED(svc::GetInfo(std::addressof(reslimit_handle_value), svc::InfoType_ResourceLimit, svc::InvalidHandle, 0))) {
return;
}
const auto handle = static_cast<svc::Handle>(reslimit_handle_value);
ON_SCOPE_EXIT { R_ABORT_UNLESS(svc::CloseHandle(handle)); };
#define ADD_RESOURCE(__RESOURCE__) \
do { \
s64 peak_value; \
if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \
return; \
} \
if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \
return; \
} \
} while (0)
ADD_RESOURCE(PhysicalMemory);
ADD_RESOURCE(ThreadCount);
ADD_RESOURCE(EventCount);
ADD_RESOURCE(TransferMemoryCount);
ADD_RESOURCE(SessionCount);
#undef ADD_RESOURCE
Context::SubmitContextRecord(std::move(record));
}
void SubmitResourceLimitContexts() {
SubmitResourceLimitLimitContext();
SubmitResourceLimitPeakContext();
} }
#else #else
void SubmitErrorContext(ContextRecord *record, Result result) { void SubmitErrorContext(ContextRecord *record, Result result) {
@ -262,11 +216,11 @@ namespace ams::erpt::srv {
} }
if (!found_abort_flag) { if (!found_abort_flag) {
record->Add(FieldId_AbortFlag, false); static_cast<void>(record->Add(FieldId_AbortFlag, false));
} }
if (!found_syslog_flag) { if (!found_syslog_flag) {
record->Add(FieldId_HasSyslogFlag, true); static_cast<void>(record->Add(FieldId_HasSyslogFlag, true));
} }
R_TRY(Context::SubmitContextRecord(std::move(record))); R_TRY(Context::SubmitContextRecord(std::move(record)));
@ -377,7 +331,7 @@ namespace ams::erpt::srv {
auto report = std::make_unique<Report>(record.get(), redirect_new_reports); auto report = std::make_unique<Report>(record.get(), redirect_new_reports);
R_UNLESS(report != nullptr, erpt::ResultOutOfMemory()); R_UNLESS(report != nullptr, erpt::ResultOutOfMemory());
auto report_guard = SCOPE_GUARD { report->Delete(); }; auto report_guard = SCOPE_GUARD { const auto delete_res = report->Delete(); R_ASSERT(delete_res); AMS_UNUSED(delete_res); };
R_TRY(Context::WriteContextsToReport(report.get())); R_TRY(Context::WriteContextsToReport(report.get()));
R_TRY(report->GetSize(std::addressof(record->m_info.report_size))); R_TRY(report->GetSize(std::addressof(record->m_info.report_size)));
@ -429,9 +383,9 @@ namespace ams::erpt::srv {
Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) { Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr<ContextRecord> record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) {
/* Clear the automatic categories, when we're done with our report. */ /* Clear the automatic categories, when we're done with our report. */
ON_SCOPE_EXIT { ON_SCOPE_EXIT {
Context::ClearContext(CategoryId_ErrorInfo); static_cast<void>(Context::ClearContext(CategoryId_ErrorInfo));
Context::ClearContext(CategoryId_ErrorInfoAuto); static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoAuto));
Context::ClearContext(CategoryId_ErrorInfoDefaults); static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoDefaults));
}; };
/* Get the context entry pointer. */ /* Get the context entry pointer. */
@ -490,28 +444,28 @@ namespace ams::erpt::srv {
R_ABORT_UNLESS(time::GetStandardSteadyClockCurrentTimePoint(std::addressof(steady_clock_current_timepoint))); R_ABORT_UNLESS(time::GetStandardSteadyClockCurrentTimePoint(std::addressof(steady_clock_current_timepoint)));
/* Add automatic fields. */ /* Add automatic fields. */
auto_record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))); static_cast<void>(auto_record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))));
auto_record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))); static_cast<void>(auto_record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))));
auto_record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))); static_cast<void>(auto_record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))));
auto_record->Add(FieldId_ReportIdentifier, identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))); static_cast<void>(auto_record->Add(FieldId_ReportIdentifier, identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))));
auto_record->Add(FieldId_OccurrenceTimestamp, timestamp_user.value); static_cast<void>(auto_record->Add(FieldId_OccurrenceTimestamp, timestamp_user.value));
auto_record->Add(FieldId_OccurrenceTimestampNet, timestamp_network.value); static_cast<void>(auto_record->Add(FieldId_OccurrenceTimestampNet, timestamp_network.value));
auto_record->Add(FieldId_ReportVisibilityFlag, type == ReportType_Visible); static_cast<void>(auto_record->Add(FieldId_ReportVisibilityFlag, type == ReportType_Visible));
auto_record->Add(FieldId_OccurrenceTick, occurrence_tick.GetInt64Value()); static_cast<void>(auto_record->Add(FieldId_OccurrenceTick, occurrence_tick.GetInt64Value()));
auto_record->Add(FieldId_SteadyClockInternalOffset, steady_clock_internal_offset_seconds); static_cast<void>(auto_record->Add(FieldId_SteadyClockInternalOffset, steady_clock_internal_offset_seconds));
auto_record->Add(FieldId_SteadyClockCurrentTimePointValue, steady_clock_current_timepoint.value); static_cast<void>(auto_record->Add(FieldId_SteadyClockCurrentTimePointValue, steady_clock_current_timepoint.value));
auto_record->Add(FieldId_ElapsedTimeSincePowerOn, (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()); static_cast<void>(auto_record->Add(FieldId_ElapsedTimeSincePowerOn, (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()));
auto_record->Add(FieldId_ElapsedTimeSinceLastAwake, (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()); static_cast<void>(auto_record->Add(FieldId_ElapsedTimeSinceLastAwake, (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()));
if (s_initial_launch_settings_completion_time) { if (s_initial_launch_settings_completion_time) {
s64 elapsed_seconds; s64 elapsed_seconds;
if (R_SUCCEEDED(time::GetElapsedSecondsBetween(std::addressof(elapsed_seconds), *s_initial_launch_settings_completion_time, steady_clock_current_timepoint))) { if (R_SUCCEEDED(time::GetElapsedSecondsBetween(std::addressof(elapsed_seconds), *s_initial_launch_settings_completion_time, steady_clock_current_timepoint))) {
auto_record->Add(FieldId_ElapsedTimeSinceInitialLaunch, elapsed_seconds); static_cast<void>(auto_record->Add(FieldId_ElapsedTimeSinceInitialLaunch, elapsed_seconds));
} }
} }
if (s_application_launch_time) { if (s_application_launch_time) {
auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()); static_cast<void>(auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()));
} }
/* Submit applet active duration information. */ /* Submit applet active duration information. */
@ -535,7 +489,7 @@ namespace ams::erpt::srv {
#if defined(ATMOSPHERE_OS_HORIZON) #if defined(ATMOSPHERE_OS_HORIZON)
if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test<CreateReportOptionFlag::SubmitFsInfo>()) { if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test<CreateReportOptionFlag::SubmitFsInfo>()) {
/* NOTE: Nintendo ignores the result of this call. */ /* NOTE: Nintendo ignores the result of this call. */
SubmitFsInfo(); static_cast<void>(SubmitFsInfo());
} }
#else #else
AMS_UNUSED(flags); AMS_UNUSED(flags);

View File

@ -36,7 +36,10 @@ namespace ams::erpt::srv {
std::scoped_lock lk(s_fs_commit_mutex); std::scoped_lock lk(s_fs_commit_mutex);
fs::CommitSaveData(ReportStoragePath); const auto commit_res = fs::CommitSaveData(ReportStoragePath);
R_ASSERT(commit_res);
AMS_UNUSED(commit_res);
R_SUCCEED(); R_SUCCEED();
} }
@ -81,7 +84,7 @@ namespace ams::erpt::srv {
} R_END_TRY_CATCH; } R_END_TRY_CATCH;
break; break;
} }
fs::SetFileSize(m_file_handle, 0); R_TRY(fs::SetFileSize(m_file_handle, 0));
} else { } else {
R_UNLESS(mode == StreamMode_Read, erpt::ResultInvalidArgument()); R_UNLESS(mode == StreamMode_Read, erpt::ResultInvalidArgument());
@ -187,8 +190,13 @@ namespace ams::erpt::srv {
if (m_initialized) { if (m_initialized) {
if (s_can_access_fs) { if (s_can_access_fs) {
if (m_stream_mode == StreamMode_Write) { if (m_stream_mode == StreamMode_Write) {
this->Flush(); const auto self_flush_res = this->Flush();
fs::FlushFile(m_file_handle); R_ASSERT(self_flush_res);
AMS_UNUSED(self_flush_res);
const auto file_flush_res = fs::FlushFile(m_file_handle);
R_ASSERT(file_flush_res);
AMS_UNUSED(file_flush_res);
} }
fs::CloseFile(m_file_handle); fs::CloseFile(m_file_handle);
} }

View File

@ -585,7 +585,7 @@ namespace ams::fs::impl {
} }
/* Output. */ /* Output. */
OutputAccessLogToSdCardImpl(log_buffer.get(), log_buffer_size - 1); static_cast<void>(OutputAccessLogToSdCardImpl(log_buffer.get(), log_buffer_size - 1));
} }
} }
@ -593,7 +593,7 @@ namespace ams::fs::impl {
if ((g_global_access_log_mode & AccessLogMode_Log) != 0) { if ((g_global_access_log_mode & AccessLogMode_Log) != 0) {
/* TODO: Support logging. */ /* TODO: Support logging. */
} else if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) { } else if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) {
OutputAccessLogToSdCardImpl(log, size - 1); static_cast<void>(OutputAccessLogToSdCardImpl(log, size - 1));
} }
} }

View File

@ -105,7 +105,9 @@ namespace ams::fs {
AMS_ABORT_UNLESS(fsp_object != nullptr); AMS_ABORT_UNLESS(fsp_object != nullptr);
/* Set the current process. */ /* Set the current process. */
fsp_object->SetCurrentProcess({}); const auto scp_res = fsp_object->SetCurrentProcess({});
R_ASSERT(scp_res);
AMS_UNUSED(scp_res);
} }
#else #else
/* On non-horizon, use the system object. */ /* On non-horizon, use the system object. */

View File

@ -107,7 +107,7 @@ namespace ams::fs::impl {
size_t len; size_t len;
if (R_SUCCEEDED(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(len), p, m_path_flags)) && normalized) { if (R_SUCCEEDED(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(len), p, m_path_flags)) && normalized) {
/* We can use the input buffer directly. */ /* We can use the input buffer directly. */
out->SetShallowBuffer(p); R_TRY(out->SetShallowBuffer(p));
} else { } else {
/* Initialize with appropriate slash replacement. */ /* Initialize with appropriate slash replacement. */
if (m_path_flags.IsWindowsPathAllowed()) { if (m_path_flags.IsWindowsPathAllowed()) {

View File

@ -38,7 +38,7 @@ namespace ams::fs {
} }
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); static_cast<void>(AMS_FS_IMPL_ACCESS_LOG((delete Get(handle), ResultSuccess()), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
} }
} }

View File

@ -78,12 +78,12 @@ namespace ams::fs {
int GetFileOpenMode(FileHandle handle) { int GetFileOpenMode(FileHandle handle) {
const int mode = Get(handle)->GetOpenMode(); const int mode = Get(handle)->GetOpenMode();
AMS_FS_IMPL_ACCESS_LOG(ResultSuccess(), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_OPEN_MODE, static_cast<u32>(mode)); static_cast<void>(AMS_FS_IMPL_ACCESS_LOG(ResultSuccess(), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_OPEN_MODE, static_cast<u32>(mode)));
return 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); static_cast<void>(AMS_FS_IMPL_ACCESS_LOG((delete Get(handle), ResultSuccess()), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
} }
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) { Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) {

View File

@ -63,7 +63,7 @@ namespace ams::fssystem {
void BlockCacheBufferedStorage::Finalize() { void BlockCacheBufferedStorage::Finalize() {
if (m_block_cache_manager.IsInitialized()) { if (m_block_cache_manager.IsInitialized()) {
/* Invalidate all cache entries. */ /* Invalidate all cache entries. */
this->InvalidateAllCacheEntries(); static_cast<void>(this->InvalidateAllCacheEntries());
/* Finalize our block cache manager. */ /* Finalize our block cache manager. */
m_block_cache_manager.Finalize(); m_block_cache_manager.Finalize();

View File

@ -269,9 +269,10 @@ namespace ams::fssystem {
/* Setup the key area encryption keys. */ /* Setup the key area encryption keys. */
for (u8 i = 0; i < NcaCryptoConfiguration::KeyGenerationMax; ++i) { for (u8 i = 0; i < NcaCryptoConfiguration::KeyGenerationMax; ++i) {
spl::GenerateAesKek(std::addressof(GetNcaKekAccessKey(GetKeyTypeValue(0, i))), nca_crypto_cfg->key_area_encryption_key_source[0], KeySize, i, Option); /* NOTE: Nintendo allows these to fail, since the loop tries key generations past the maximum known. */
spl::GenerateAesKek(std::addressof(GetNcaKekAccessKey(GetKeyTypeValue(1, i))), nca_crypto_cfg->key_area_encryption_key_source[1], KeySize, i, Option); static_cast<void>(spl::GenerateAesKek(std::addressof(GetNcaKekAccessKey(GetKeyTypeValue(0, i))), nca_crypto_cfg->key_area_encryption_key_source[0], KeySize, i, Option));
spl::GenerateAesKek(std::addressof(GetNcaKekAccessKey(GetKeyTypeValue(2, i))), nca_crypto_cfg->key_area_encryption_key_source[2], KeySize, i, Option); static_cast<void>(spl::GenerateAesKek(std::addressof(GetNcaKekAccessKey(GetKeyTypeValue(1, i))), nca_crypto_cfg->key_area_encryption_key_source[1], KeySize, i, Option));
static_cast<void>(spl::GenerateAesKek(std::addressof(GetNcaKekAccessKey(GetKeyTypeValue(2, i))), nca_crypto_cfg->key_area_encryption_key_source[2], KeySize, i, Option));
} }
/* Setup the header encryption key. */ /* Setup the header encryption key. */

View File

@ -129,11 +129,15 @@ namespace ams::fssystem {
/* Initialize the buffer manager. */ /* Initialize the buffer manager. */
/* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */ /* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */
util::ConstructAt(g_buffer_manager); util::ConstructAt(g_buffer_manager);
GetReference(g_buffer_manager).Initialize(MaxCacheCount, reinterpret_cast<uintptr_t>(g_buffer_manager_heap), BufferManagerHeapSize, BlockSize); const auto bm_res = GetReference(g_buffer_manager).Initialize(MaxCacheCount, reinterpret_cast<uintptr_t>(g_buffer_manager_heap), BufferManagerHeapSize, BlockSize);
R_ASSERT(bm_res);
AMS_UNUSED(bm_res);
/* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */ /* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */
/* TODO FS-REIMPL: fssrv::storage::CreateDeviceAddressSpace(...); */ /* TODO FS-REIMPL: fssrv::storage::CreateDeviceAddressSpace(...); */
fssystem::InitializeBufferPool(reinterpret_cast<char *>(g_device_buffer), DeviceBufferSize); const auto ibp_res = fssystem::InitializeBufferPool(reinterpret_cast<char *>(g_device_buffer), DeviceBufferSize);
R_ASSERT(ibp_res);
AMS_UNUSED(ibp_res);
/* TODO FS-REIMPL: Create Pooled Threads/Stack Usage Reporter, fssystem::RegisterThreadPool. */ /* TODO FS-REIMPL: Create Pooled Threads/Stack Usage Reporter, fssystem::RegisterThreadPool. */
@ -231,11 +235,15 @@ namespace ams::fssystem {
/* Initialize the buffer manager. */ /* Initialize the buffer manager. */
/* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */ /* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */
util::ConstructAt(g_buffer_manager); util::ConstructAt(g_buffer_manager);
GetReference(g_buffer_manager).Initialize(MaxCacheCount, reinterpret_cast<uintptr_t>(g_buffer_manager_heap), BufferManagerHeapSize, BlockSize); const auto bm_res = GetReference(g_buffer_manager).Initialize(MaxCacheCount, reinterpret_cast<uintptr_t>(g_buffer_manager_heap), BufferManagerHeapSize, BlockSize);
R_ASSERT(bm_res);
AMS_UNUSED(bm_res);
/* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */ /* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */
/* TODO FS-REIMPL: fssrv::storage::CreateDeviceAddressSpace(...); */ /* TODO FS-REIMPL: fssrv::storage::CreateDeviceAddressSpace(...); */
fssystem::InitializeBufferPool(reinterpret_cast<char *>(g_device_buffer), DeviceBufferSize); const auto ibp_res = fssystem::InitializeBufferPool(reinterpret_cast<char *>(g_device_buffer), DeviceBufferSize);
R_ASSERT(ibp_res);
AMS_UNUSED(ibp_res);
/* TODO FS-REIMPL: Create Pooled Threads/Stack Usage Reporter, fssystem::RegisterThreadPool. */ /* TODO FS-REIMPL: Create Pooled Threads/Stack Usage Reporter, fssystem::RegisterThreadPool. */

View File

@ -89,7 +89,7 @@ namespace ams::htc::server::driver {
void HtclowDriver::Shutdown(htclow::ChannelId channel) { void HtclowDriver::Shutdown(htclow::ChannelId channel) {
/* Shut down the channel. */ /* Shut down the channel. */
m_manager->Shutdown(GetHtclowChannel(channel, m_module_id)); static_cast<void>(m_manager->Shutdown(GetHtclowChannel(channel, m_module_id)));
} }
Result HtclowDriver::Send(s64 *out, const void *src, s64 src_size, htclow::ChannelId channel) { Result HtclowDriver::Send(s64 *out, const void *src, s64 src_size, htclow::ChannelId channel) {

View File

@ -37,7 +37,7 @@ namespace ams::htc::server::rpc {
u8 m_driver_receive_buffer[4_KB]; u8 m_driver_receive_buffer[4_KB];
u8 m_driver_send_buffer[4_KB]; u8 m_driver_send_buffer[4_KB];
private: private:
static void ReceiveThreadEntry(void *arg) { static_cast<HtcmiscRpcServer *>(arg)->ReceiveThread(); } static void ReceiveThreadEntry(void *arg) { static_cast<void>(static_cast<HtcmiscRpcServer *>(arg)->ReceiveThread()); }
Result ReceiveThread(); Result ReceiveThread();
public: public:

View File

@ -71,8 +71,8 @@ namespace ams::htc::server::rpc {
char m_receive_buffer[BufferSize]; char m_receive_buffer[BufferSize];
char m_send_buffer[BufferSize]; char m_send_buffer[BufferSize];
private: private:
static void ReceiveThreadEntry(void *arg) { static_cast<RpcClient *>(arg)->ReceiveThread(); } static void ReceiveThreadEntry(void *arg) { static_cast<void>(static_cast<RpcClient *>(arg)->ReceiveThread()); }
static void SendThreadEntry(void *arg) { static_cast<RpcClient *>(arg)->SendThread(); } static void SendThreadEntry(void *arg) { static_cast<void>(static_cast<RpcClient *>(arg)->SendThread()); }
Result ReceiveThread(); Result ReceiveThread();
Result SendThread(); Result SendThread();

View File

@ -53,7 +53,7 @@ namespace ams::htcfs {
void ClientImpl::Start() { void ClientImpl::Start() {
/* Create our thread. */ /* Create our thread. */
os::CreateThread(std::addressof(m_monitor_thread), ThreadEntry, this, g_monitor_thread_stack, sizeof(g_monitor_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcfsMonitor)); R_ABORT_UNLESS(os::CreateThread(std::addressof(m_monitor_thread), ThreadEntry, this, g_monitor_thread_stack, sizeof(g_monitor_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcfsMonitor)));
/* Set thread name pointer. */ /* Set thread name pointer. */
os::SetThreadNamePointer(std::addressof(m_monitor_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, HtcfsMonitor)); os::SetThreadNamePointer(std::addressof(m_monitor_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, HtcfsMonitor));

View File

@ -22,7 +22,7 @@ namespace ams::htcfs {
DirectoryServiceObject::DirectoryServiceObject(s32 handle) : m_handle(handle) { /* ... */ } DirectoryServiceObject::DirectoryServiceObject(s32 handle) : m_handle(handle) { /* ... */ }
DirectoryServiceObject::~DirectoryServiceObject() { DirectoryServiceObject::~DirectoryServiceObject() {
htcfs::GetClient().CloseDirectory(m_handle); static_cast<void>(htcfs::GetClient().CloseDirectory(m_handle));
} }
Result DirectoryServiceObject::GetEntryCount(ams::sf::Out<s64> out) { Result DirectoryServiceObject::GetEntryCount(ams::sf::Out<s64> out) {

View File

@ -22,7 +22,7 @@ namespace ams::htcfs {
FileServiceObject::FileServiceObject(s32 handle) : m_handle(handle) { /* ... */ } FileServiceObject::FileServiceObject(s32 handle) : m_handle(handle) { /* ... */ }
FileServiceObject::~FileServiceObject() { FileServiceObject::~FileServiceObject() {
htcfs::GetClient().CloseFile(m_handle); static_cast<void>(htcfs::GetClient().CloseFile(m_handle));
} }
Result FileServiceObject::ReadFile(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, ams::fs::ReadOption option) { Result FileServiceObject::ReadFile(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, ams::fs::ReadOption option) {

View File

@ -32,15 +32,15 @@ namespace ams::htclow::driver {
m_open_driver = m_debug_driver; m_open_driver = m_debug_driver;
break; break;
case impl::DriverType::Socket: case impl::DriverType::Socket:
m_socket_driver.Open(); R_TRY(m_socket_driver.Open());
m_open_driver = std::addressof(m_socket_driver); m_open_driver = std::addressof(m_socket_driver);
break; break;
case impl::DriverType::Usb: case impl::DriverType::Usb:
m_usb_driver.Open(); R_TRY(m_usb_driver.Open());
m_open_driver = std::addressof(m_usb_driver); m_open_driver = std::addressof(m_usb_driver);
break; break;
case impl::DriverType::PlainChannel: case impl::DriverType::PlainChannel:
//m_plain_channel_driver.Open(); //R_TRY(m_plain_channel_driver.Open());
//m_open_driver = std::addressof(m_plain_channel_driver); //m_open_driver = std::addressof(m_plain_channel_driver);
//break; //break;
R_THROW(htclow::ResultUnknownDriverType()); R_THROW(htclow::ResultUnknownDriverType());

View File

@ -67,14 +67,20 @@ namespace ams::htclow::driver {
} }
void SocketDiscoveryManager::ThreadFunc() { void SocketDiscoveryManager::ThreadFunc() {
for (this->DoDiscovery(); !m_driver_closed; this->DoDiscovery()) { /* Do discovery. */
/* Check if the driver is closed five times. */ static_cast<void>(this->DoDiscovery());
while (!m_driver_closed) {
/* Check if the driver is closed 5 times. */
for (size_t i = 0; i < 5; ++i) { for (size_t i = 0; i < 5; ++i) {
os::SleepThread(TimeSpan::FromSeconds(1)); os::SleepThread(TimeSpan::FromSeconds(1));
if (m_driver_closed) { if (m_driver_closed) {
return; return;
} }
} }
/* Do discovery. */
static_cast<void>(this->DoDiscovery());
} }
} }

View File

@ -407,11 +407,11 @@ namespace ams::htclow::driver {
g_usb_break_event.Signal(); g_usb_break_event.Signal();
os::WaitThread(std::addressof(g_usb_indication_thread)); os::WaitThread(std::addressof(g_usb_indication_thread));
os::DestroyThread(std::addressof(g_usb_indication_thread)); os::DestroyThread(std::addressof(g_usb_indication_thread));
g_ds_client.DisableDevice(); static_cast<void>(g_ds_client.DisableDevice());
g_ds_endpoints[1].Finalize(); static_cast<void>(g_ds_endpoints[1].Finalize());
g_ds_endpoints[0].Finalize(); static_cast<void>(g_ds_endpoints[0].Finalize());
g_ds_interface.Finalize(); static_cast<void>(g_ds_interface.Finalize());
g_ds_client.Finalize(); static_cast<void>(g_ds_client.Finalize());
g_usb_interface_initialized = false; g_usb_interface_initialized = false;
} }
@ -454,8 +454,8 @@ namespace ams::htclow::driver {
void CancelUsbSendReceive() { void CancelUsbSendReceive() {
if (g_usb_interface_initialized) { if (g_usb_interface_initialized) {
g_ds_endpoints[0].Cancel(); static_cast<void>(g_ds_endpoints[0].Cancel());
g_ds_endpoints[1].Cancel(); static_cast<void>(g_ds_endpoints[1].Cancel());
} }
} }

View File

@ -34,7 +34,7 @@ namespace ams::htclow {
} }
void Channel::Close() { void Channel::Close() {
m_manager->Close(impl::ConvertChannelType(m_channel)); static_cast<void>(m_manager->Close(impl::ConvertChannelType(m_channel)));
} }
ChannelState Channel::GetChannelState() { ChannelState Channel::GetChannelState() {
@ -72,7 +72,7 @@ namespace ams::htclow {
} }
void Channel::Shutdown() { void Channel::Shutdown() {
m_manager->Shutdown(impl::ConvertChannelType(m_channel)); static_cast<void>(m_manager->Shutdown(impl::ConvertChannelType(m_channel)));
} }
Result Channel::Receive(s64 *out, void *dst, s64 size, ReceiveOption option) { Result Channel::Receive(s64 *out, void *dst, s64 size, ReceiveOption option) {
@ -221,7 +221,7 @@ namespace ams::htclow {
/* Perform the wait. */ /* Perform the wait. */
if (event != nullptr) { if (event != nullptr) {
if (os::WaitAny(event, m_manager->GetTaskEvent(task_id)) == 0) { if (os::WaitAny(event, m_manager->GetTaskEvent(task_id)) == 0) {
m_manager->WaitReceiveEnd(task_id); static_cast<void>(m_manager->WaitReceiveEnd(task_id));
R_THROW(htclow::ResultChannelWaitCancelled()); R_THROW(htclow::ResultChannelWaitCancelled());
} }
} else { } else {

View File

@ -64,13 +64,13 @@ namespace ams::htclow {
} }
void Worker::ReceiveThread() { void Worker::ReceiveThread() {
this->ProcessReceive(); static_cast<void>(this->ProcessReceive());
m_driver->CancelSendReceive(); m_driver->CancelSendReceive();
this->Cancel(); this->Cancel();
} }
void Worker::SendThread() { void Worker::SendThread() {
this->ProcessSend(); static_cast<void>(this->ProcessSend());
m_driver->CancelSendReceive(); m_driver->CancelSendReceive();
this->Cancel(); this->Cancel();
} }
@ -114,7 +114,9 @@ namespace ams::htclow {
} }
/* Process the received packet. */ /* Process the received packet. */
m_service->ProcessReceivePacket(header, m_receive_packet_body, header.body_size); if (R_FAILED(m_service->ProcessReceivePacket(header, m_receive_packet_body, header.body_size))) {
/* TODO: PrintIgnorePacket */
}
R_SUCCEED(); R_SUCCEED();
} }
@ -129,7 +131,9 @@ namespace ams::htclow {
} }
/* Process the received packet. */ /* Process the received packet. */
m_mux->ProcessReceivePacket(header, m_receive_packet_body, header.body_size); if (R_FAILED(m_mux->ProcessReceivePacket(header, m_receive_packet_body, header.body_size))) {
/* TODO: PrintIgnorePacket */
}
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -71,7 +71,9 @@ namespace ams::htclow::mux {
R_RETURN(m_channel_impl_map[it->second].ProcessReceivePacket(header, body, body_size)); R_RETURN(m_channel_impl_map[it->second].ProcessReceivePacket(header, body, body_size));
} else { } else {
if (header.packet_type == PacketType_Data || header.packet_type == PacketType_MaxData) { if (header.packet_type == PacketType_Data || header.packet_type == PacketType_MaxData) {
this->SendErrorPacket(header.channel); if (R_FAILED(this->SendErrorPacket(header.channel))) {
/* Nintendo doesn't do anything here. */
}
} }
R_THROW(htclow::ResultChannelNotExist()); R_THROW(htclow::ResultChannelNotExist());
} }

View File

@ -750,7 +750,9 @@ namespace ams::htcs::client {
if (index = this->Find(set->fds[i], std::addressof(error_code)); index >= 0) { if (index = this->Find(set->fds[i], std::addressof(error_code)); index >= 0) {
/* Get the primitive, if necessary. */ /* Get the primitive, if necessary. */
if (m_socket_list[index].m_primitive == InvalidPrimitive && m_socket_list[index].m_socket != nullptr) { if (m_socket_list[index].m_primitive == InvalidPrimitive && m_socket_list[index].m_socket != nullptr) {
m_socket_list[index].m_socket->GetPrimitive(std::addressof(m_socket_list[index].m_primitive)); if (R_FAILED(m_socket_list[index].m_socket->GetPrimitive(std::addressof(m_socket_list[index].m_primitive)))) {
/* Nintendo doesn't do anything here? */
}
} }
primitive = m_socket_list[index].m_primitive; primitive = m_socket_list[index].m_primitive;
@ -769,7 +771,9 @@ namespace ams::htcs::client {
/* Get the primitive. */ /* Get the primitive. */
if (index = this->Find(set->fds[i], std::addressof(error_code)); index >= 0) { if (index = this->Find(set->fds[i], std::addressof(error_code)); index >= 0) {
m_socket_list[index].m_socket->GetPrimitive(std::addressof(m_socket_list[index].m_primitive)); if (R_FAILED(m_socket_list[index].m_socket->GetPrimitive(std::addressof(m_socket_list[index].m_primitive)))) {
/* Nintendo doesn't do anything here? */
}
primitive = m_socket_list[index].m_primitive; primitive = m_socket_list[index].m_primitive;
} }

View File

@ -54,7 +54,7 @@ namespace ams::htcs {
R_ABORT_UNLESS(g_monitor->MonitorManager(process_id)); R_ABORT_UNLESS(g_monitor->MonitorManager(process_id));
/* Allocate a tls slot for our last error. */ /* Allocate a tls slot for our last error. */
os::SdkAllocateTlsSlot(std::addressof(g_tls_slot), nullptr); R_ABORT_UNLESS(os::SdkAllocateTlsSlot(std::addressof(g_tls_slot), nullptr));
/* Setup the virtual socket collection. */ /* Setup the virtual socket collection. */
AMS_ASSERT(buffer != nullptr); AMS_ASSERT(buffer != nullptr);
@ -185,7 +185,7 @@ namespace ams::htcs {
/* Get name. */ /* Get name. */
HtcsPeerName name; HtcsPeerName name;
g_manager->GetPeerNameAny(std::addressof(name)); static_cast<void>(g_manager->GetPeerNameAny(std::addressof(name)));
return name; return name;
} }
@ -196,7 +196,7 @@ namespace ams::htcs {
/* Get name. */ /* Get name. */
HtcsPeerName name; HtcsPeerName name;
g_manager->GetDefaultHostName(std::addressof(name)); static_cast<void>(g_manager->GetDefaultHostName(std::addressof(name)));
return name; return name;
} }
@ -472,7 +472,7 @@ namespace ams::htcs {
s32 close(sf::SharedPointer<tma::ISocket> socket, s32 &last_error) { s32 close(sf::SharedPointer<tma::ISocket> socket, s32 &last_error) {
s32 res; s32 res;
socket->Close(std::addressof(last_error), std::addressof(res)); static_cast<void>(socket->Close(std::addressof(last_error), std::addressof(res)));
return res; return res;
} }
@ -484,13 +484,13 @@ namespace ams::htcs {
util::Strlcpy(null_terminated_address.port_name.name, address->port_name.name, PortNameBufferLength); util::Strlcpy(null_terminated_address.port_name.name, address->port_name.name, PortNameBufferLength);
s32 res; s32 res;
socket->Bind(std::addressof(last_error), std::addressof(res), null_terminated_address); static_cast<void>(socket->Bind(std::addressof(last_error), std::addressof(res), null_terminated_address));
return res; return res;
} }
s32 listen(sf::SharedPointer<tma::ISocket> socket, s32 backlog_count, s32 &last_error) { s32 listen(sf::SharedPointer<tma::ISocket> socket, s32 backlog_count, s32 &last_error) {
s32 res; s32 res;
socket->Listen(std::addressof(last_error), std::addressof(res), backlog_count); static_cast<void>(socket->Listen(std::addressof(last_error), std::addressof(res), backlog_count));
return res; return res;
} }
@ -512,7 +512,7 @@ namespace ams::htcs {
os::WaitSystemEvent(std::addressof(event)); os::WaitSystemEvent(std::addressof(event));
/* End the accept. */ /* End the accept. */
socket->AcceptResults(std::addressof(last_error), std::addressof(res), address, task_id); static_cast<void>(socket->AcceptResults(std::addressof(last_error), std::addressof(res), address, task_id));
} else { } else {
/* Set error. */ /* Set error. */
last_error = HTCS_EINTR; last_error = HTCS_EINTR;
@ -528,13 +528,13 @@ namespace ams::htcs {
s32 fcntl(sf::SharedPointer<tma::ISocket> socket, s32 command, s32 value, s32 &last_error) { s32 fcntl(sf::SharedPointer<tma::ISocket> socket, s32 command, s32 value, s32 &last_error) {
s32 res; s32 res;
socket->Fcntl(std::addressof(last_error), std::addressof(res), command, value); static_cast<void>(socket->Fcntl(std::addressof(last_error), std::addressof(res), command, value));
return res; return res;
} }
s32 shutdown(sf::SharedPointer<tma::ISocket> socket, s32 how, s32 &last_error) { s32 shutdown(sf::SharedPointer<tma::ISocket> socket, s32 how, s32 &last_error) {
s32 res; s32 res;
socket->Shutdown(std::addressof(last_error), std::addressof(res), how); static_cast<void>(socket->Shutdown(std::addressof(last_error), std::addressof(res), how));
return res; return res;
} }
@ -546,7 +546,7 @@ namespace ams::htcs {
util::Strlcpy(null_terminated_address.port_name.name, address->port_name.name, PortNameBufferLength); util::Strlcpy(null_terminated_address.port_name.name, address->port_name.name, PortNameBufferLength);
s32 res; s32 res;
socket->Connect(std::addressof(last_error), std::addressof(res), null_terminated_address); static_cast<void>(socket->Connect(std::addressof(last_error), std::addressof(res), null_terminated_address));
return res; return res;
} }
@ -579,7 +579,7 @@ namespace ams::htcs {
os::WaitSystemEvent(std::addressof(event)); os::WaitSystemEvent(std::addressof(event));
/* End the select. */ /* End the select. */
g_manager->EndSelect(std::addressof(last_error), std::addressof(res), OutArray(read, num_read), OutArray(write, num_write), OutArray(except, num_except), task_id); static_cast<void>(g_manager->EndSelect(std::addressof(last_error), std::addressof(res), OutArray(read, num_read), OutArray(write, num_write), OutArray(except, num_except), task_id));
} else { } else {
/* Set error. */ /* Set error. */
last_error = HTCS_EINTR; last_error = HTCS_EINTR;
@ -614,7 +614,7 @@ namespace ams::htcs {
os::WaitSystemEvent(std::addressof(event)); os::WaitSystemEvent(std::addressof(event));
/* End the receive. */ /* End the receive. */
socket->EndRecv(std::addressof(last_error), std::addressof(res), sf::OutAutoSelectBuffer(buffer, buffer_size), task_id); static_cast<void>(socket->EndRecv(std::addressof(last_error), std::addressof(res), sf::OutAutoSelectBuffer(buffer, buffer_size), task_id));
} else { } else {
/* Set error. */ /* Set error. */
last_error = HTCS_EINTR; last_error = HTCS_EINTR;
@ -675,7 +675,7 @@ namespace ams::htcs {
} }
/* End the send. */ /* End the send. */
socket->EndSend(std::addressof(last_error), std::addressof(res), task_id); static_cast<void>(socket->EndSend(std::addressof(last_error), std::addressof(res), task_id));
} else { } else {
/* Set error. */ /* Set error. */
last_error = HTCS_EINTR; last_error = HTCS_EINTR;
@ -717,7 +717,7 @@ namespace ams::htcs {
os::WaitSystemEvent(std::addressof(event)); os::WaitSystemEvent(std::addressof(event));
/* End the receive. */ /* End the receive. */
socket->RecvResults(std::addressof(last_error), std::addressof(res), sf::OutAutoSelectBuffer(buffer, recv_size), task_id); static_cast<void>(socket->RecvResults(std::addressof(last_error), std::addressof(res), sf::OutAutoSelectBuffer(buffer, recv_size), task_id));
} else { } else {
/* Set error. */ /* Set error. */
last_error = HTCS_EINTR; last_error = HTCS_EINTR;
@ -750,7 +750,7 @@ namespace ams::htcs {
os::WaitSystemEvent(std::addressof(event)); os::WaitSystemEvent(std::addressof(event));
/* End the send. */ /* End the send. */
socket->SendResults(std::addressof(last_error), std::addressof(res), task_id); static_cast<void>(socket->SendResults(std::addressof(last_error), std::addressof(res), task_id));
} else { } else {
/* Set error. */ /* Set error. */
last_error = HTCS_EINTR; last_error = HTCS_EINTR;

View File

@ -101,7 +101,7 @@ namespace ams::htcs::impl {
Result HtcsManagerImpl::SendStart(u32 *out_task_id, os::NativeHandle *out_handle, const char *buffer, s64 size, s32 desc, s32 flags) { Result HtcsManagerImpl::SendStart(u32 *out_task_id, os::NativeHandle *out_handle, const char *buffer, s64 size, s32 desc, s32 flags) {
/* Start the send. */ /* Start the send. */
u32 task_id{}; u32 task_id{};
os::NativeHandle handle; os::NativeHandle handle = os::InvalidNativeHandle;
R_TRY(m_service.SendSmallStart(std::addressof(task_id), std::addressof(handle), desc, size, flags)); R_TRY(m_service.SendSmallStart(std::addressof(task_id), std::addressof(handle), desc, size, flags));
/* Continue the send. */ /* Continue the send. */
@ -113,14 +113,16 @@ namespace ams::htcs::impl {
R_SUCCEED(); R_SUCCEED();
} else { } else {
os::SystemEventType event;
os::AttachReadableHandleToSystemEvent(std::addressof(event), handle, true, os::EventClearMode_ManualClear);
s32 err; s32 err;
s64 rsize; s64 rsize;
m_service.SendSmallResults(std::addressof(err), std::addressof(rsize), task_id, desc); static_cast<void>(m_service.SendSmallResults(std::addressof(err), std::addressof(rsize), task_id, desc));
os::DestroySystemEvent(std::addressof(event)); if (handle != os::InvalidNativeHandle) {
os::SystemEventType event;
os::AttachReadableHandleToSystemEvent(std::addressof(event), handle, true, os::EventClearMode_ManualClear);
os::DestroySystemEvent(std::addressof(event));
}
R_RETURN(result); R_RETURN(result);
} }
@ -166,7 +168,7 @@ namespace ams::htcs::impl {
if (htcs::ResultCancelled::Includes(result)) { if (htcs::ResultCancelled::Includes(result)) {
s32 err; s32 err;
bool empty; bool empty;
m_service.SelectEnd(std::addressof(err), std::addressof(empty), Span<int>{}, Span<int>{}, Span<int>{}, task_id); static_cast<void>(m_service.SelectEnd(std::addressof(err), std::addressof(empty), Span<int>{}, Span<int>{}, Span<int>{}, task_id));
if (handle != os::InvalidNativeHandle) { if (handle != os::InvalidNativeHandle) {
os::SystemEventType event; os::SystemEventType event;

View File

@ -211,6 +211,9 @@ namespace ams::htcs::impl {
Result HtcsService::AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc) { Result HtcsService::AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc) {
AMS_UNUSED(out_address); AMS_UNUSED(out_address);
/* Wait for the task to complete. */
this->WaitTask(task_id);
/* Finish the task. */ /* Finish the task. */
htcs::SocketError err; htcs::SocketError err;
s32 ret_desc; s32 ret_desc;
@ -235,10 +238,14 @@ namespace ams::htcs::impl {
} }
Result HtcsService::ReceiveSmallResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { Result HtcsService::ReceiveSmallResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) {
AMS_UNUSED(desc); /* Verify the task. */
R_TRY(m_rpc_client->VerifyTaskIdWithHandle<rpc::ReceiveSmallTask>(task_id, desc));
/* Continue the task. */ /* Continue the task. */
m_rpc_client->ReceiveContinue<rpc::ReceiveSmallTask>(task_id, buffer, buffer_size); static_cast<void>(m_rpc_client->ReceiveContinue<rpc::ReceiveSmallTask>(task_id, buffer, buffer_size));
/* Wait for the task to complete. */
this->WaitTask(task_id);
/* Finish the task. */ /* Finish the task. */
htcs::SocketError err; htcs::SocketError err;
@ -274,7 +281,11 @@ namespace ams::htcs::impl {
} }
Result HtcsService::SendSmallResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { Result HtcsService::SendSmallResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) {
AMS_UNUSED(desc); /* Verify the task. */
R_TRY(m_rpc_client->VerifyTaskIdWithHandle<rpc::SendSmallTask>(task_id, desc));
/* Wait for the task to complete. */
this->WaitTask(task_id);
/* Finish the task. */ /* Finish the task. */
htcs::SocketError err; htcs::SocketError err;
@ -322,6 +333,9 @@ namespace ams::htcs::impl {
/* Verify the task. */ /* Verify the task. */
R_TRY(m_rpc_client->VerifyTaskIdWithHandle<rpc::SendTask>(task_id, desc)); R_TRY(m_rpc_client->VerifyTaskIdWithHandle<rpc::SendTask>(task_id, desc));
/* Wait for the task to complete. */
this->WaitTask(task_id);
/* Finish the task. */ /* Finish the task. */
htcs::SocketError err; htcs::SocketError err;
R_TRY(m_rpc_client->End<rpc::SendTask>(task_id, std::addressof(err), out_size)); R_TRY(m_rpc_client->End<rpc::SendTask>(task_id, std::addressof(err), out_size));
@ -347,6 +361,9 @@ namespace ams::htcs::impl {
/* Verify the task. */ /* Verify the task. */
R_TRY(m_rpc_client->VerifyTaskIdWithHandle<rpc::ReceiveTask>(task_id, desc)); R_TRY(m_rpc_client->VerifyTaskIdWithHandle<rpc::ReceiveTask>(task_id, desc));
/* Wait for the task to complete. */
this->WaitTask(task_id);
/* Get the result. */ /* Get the result. */
htcs::SocketError err{}; htcs::SocketError err{};
s64 recv_size{}; s64 recv_size{};
@ -399,6 +416,9 @@ namespace ams::htcs::impl {
} }
Result HtcsService::SelectEnd(s32 *out_err, bool *out_empty, Span<int> read_handles, Span<int> write_handles, Span<int> exception_handles, u32 task_id) { Result HtcsService::SelectEnd(s32 *out_err, bool *out_empty, Span<int> read_handles, Span<int> write_handles, Span<int> exception_handles, u32 task_id) {
/* Wait for the task to complete. */
this->WaitTask(task_id);
/* Finish the task. */ /* Finish the task. */
htcs::SocketError err; htcs::SocketError err;
bool empty; bool empty;

View File

@ -53,7 +53,7 @@ namespace ams {
return (v >> ofs) & ~(~BaseType() << num); return (v >> ofs) & ~(~BaseType() << num);
} }
public: public:
static constexpr ALWAYS_INLINE BaseType MakeValue(BaseType module, BaseType description) { [[nodiscard]] static constexpr ALWAYS_INLINE BaseType MakeValue(BaseType module, BaseType description) {
return (module) | (description << ModuleBits); return (module) | (description << ModuleBits);
} }
@ -63,23 +63,23 @@ namespace ams {
static_assert(description < (1 << DescriptionBits), "Invalid Description"); static_assert(description < (1 << DescriptionBits), "Invalid Description");
}; };
static constexpr ALWAYS_INLINE BaseType GetModuleFromValue(BaseType value) { [[nodiscard]] static constexpr ALWAYS_INLINE BaseType GetModuleFromValue(BaseType value) {
return GetBitsValue(value, 0, ModuleBits); return GetBitsValue(value, 0, ModuleBits);
} }
static constexpr ALWAYS_INLINE BaseType GetDescriptionFromValue(BaseType value) { [[nodiscard]] static constexpr ALWAYS_INLINE BaseType GetDescriptionFromValue(BaseType value) {
return GetBitsValue(value, ModuleBits, DescriptionBits); return GetBitsValue(value, ModuleBits, DescriptionBits);
} }
static constexpr ALWAYS_INLINE BaseType GetReservedFromValue(BaseType value) { [[nodiscard]] static constexpr ALWAYS_INLINE BaseType GetReservedFromValue(BaseType value) {
return GetBitsValue(value, ModuleBits + DescriptionBits, ReservedBits); return GetBitsValue(value, ModuleBits + DescriptionBits, ReservedBits);
} }
static constexpr ALWAYS_INLINE BaseType MaskReservedFromValue(BaseType value) { [[nodiscard]] static constexpr ALWAYS_INLINE BaseType MaskReservedFromValue(BaseType value) {
return value & ~(~(~BaseType() << ReservedBits) << (ModuleBits + DescriptionBits)); return value & ~(~(~BaseType() << ReservedBits) << (ModuleBits + DescriptionBits));
} }
static constexpr ALWAYS_INLINE BaseType MergeValueWithReserved(BaseType value, BaseType reserved) { [[nodiscard]] static constexpr ALWAYS_INLINE BaseType MergeValueWithReserved(BaseType value, BaseType reserved) {
return (value << 0) | (reserved << (ModuleBits + DescriptionBits)); return (value << 0) | (reserved << (ModuleBits + DescriptionBits));
} }
}; };
@ -90,8 +90,8 @@ namespace ams {
using BaseType = typename ResultTraits::BaseType; using BaseType = typename ResultTraits::BaseType;
static constexpr BaseType SuccessValue = ResultTraits::SuccessValue; static constexpr BaseType SuccessValue = ResultTraits::SuccessValue;
public: public:
constexpr ALWAYS_INLINE BaseType GetModule(this auto const &self) { return ResultTraits::GetModuleFromValue(self.GetValue()); } [[nodiscard]] constexpr ALWAYS_INLINE BaseType GetModule(this auto const &self) { return ResultTraits::GetModuleFromValue(self.GetValue()); }
constexpr ALWAYS_INLINE BaseType GetDescription(this auto const &self) { return ResultTraits::GetDescriptionFromValue(self.GetValue()); } [[nodiscard]] constexpr ALWAYS_INLINE BaseType GetDescription(this auto const &self) { return ResultTraits::GetDescriptionFromValue(self.GetValue()); }
}; };
class ResultInternalAccessor; class ResultInternalAccessor;
@ -100,7 +100,7 @@ namespace ams {
class ResultSuccess; class ResultSuccess;
class Result final : public result::impl::ResultBase { class [[nodiscard]] Result final : public result::impl::ResultBase {
friend class result::impl::ResultInternalAccessor; friend class result::impl::ResultInternalAccessor;
public: public:
using Base = typename result::impl::ResultBase; using Base = typename result::impl::ResultBase;
@ -115,16 +115,17 @@ namespace ams {
constexpr ALWAYS_INLINE Result(typename Base::BaseType v) : m_value(v) { static_assert(std::is_same<typename Base::BaseType, ::Result>::value); } constexpr ALWAYS_INLINE Result(typename Base::BaseType v) : m_value(v) { static_assert(std::is_same<typename Base::BaseType, ::Result>::value); }
constexpr ALWAYS_INLINE operator ResultSuccess() const; constexpr ALWAYS_INLINE operator ResultSuccess() const;
static constexpr ALWAYS_INLINE bool CanAccept(Result) { return true; }
constexpr ALWAYS_INLINE bool IsSuccess() const { return m_value == Base::SuccessValue; } [[nodiscard]] static constexpr ALWAYS_INLINE bool CanAccept(Result) { return true; }
constexpr ALWAYS_INLINE bool IsFailure() const { return !this->IsSuccess(); }
constexpr ALWAYS_INLINE typename Base::BaseType GetModule() const { return Base::GetModule(); }
constexpr ALWAYS_INLINE typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
constexpr ALWAYS_INLINE typename Base::BaseType GetInnerValue() const { return ::ams::result::impl::ResultTraits::MaskReservedFromValue(m_value); } [[nodiscard]] constexpr ALWAYS_INLINE bool IsSuccess() const { return m_value == Base::SuccessValue; }
[[nodiscard]] constexpr ALWAYS_INLINE bool IsFailure() const { return !this->IsSuccess(); }
[[nodiscard]] constexpr ALWAYS_INLINE typename Base::BaseType GetModule() const { return Base::GetModule(); }
[[nodiscard]] constexpr ALWAYS_INLINE typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
constexpr ALWAYS_INLINE typename Base::BaseType GetValue() const { return m_value; } [[nodiscard]] constexpr ALWAYS_INLINE typename Base::BaseType GetInnerValue() const { return ::ams::result::impl::ResultTraits::MaskReservedFromValue(m_value); }
[[nodiscard]] constexpr ALWAYS_INLINE typename Base::BaseType GetValue() const { return m_value; }
}; };
static_assert(sizeof(Result) == sizeof(Result::Base::BaseType), "sizeof(Result) == sizeof(Result::Base::BaseType)"); static_assert(sizeof(Result) == sizeof(Result::Base::BaseType), "sizeof(Result) == sizeof(Result::Base::BaseType)");
static_assert(std::is_trivially_destructible<Result>::value, "std::is_trivially_destructible<Result>::value"); static_assert(std::is_trivially_destructible<Result>::value, "std::is_trivially_destructible<Result>::value");
@ -137,20 +138,20 @@ namespace ams {
class ResultInternalAccessor { class ResultInternalAccessor {
public: public:
static constexpr ALWAYS_INLINE Result MakeResult(ResultTraits::BaseType value) { [[nodiscard]] static constexpr ALWAYS_INLINE Result MakeResult(ResultTraits::BaseType value) {
return Result(value); return Result(value);
} }
static constexpr ALWAYS_INLINE ResultTraits::BaseType GetReserved(Result result) { [[nodiscard]] static constexpr ALWAYS_INLINE ResultTraits::BaseType GetReserved(Result result) {
return ResultTraits::GetReservedFromValue(result.m_value); return ResultTraits::GetReservedFromValue(result.m_value);
} }
static constexpr ALWAYS_INLINE Result MergeReserved(Result result, ResultTraits::BaseType reserved) { [[nodiscard]] static constexpr ALWAYS_INLINE Result MergeReserved(Result result, ResultTraits::BaseType reserved) {
return Result(ResultTraits::MergeValueWithReserved(ResultTraits::MaskReservedFromValue(result.m_value), reserved)); return Result(ResultTraits::MergeValueWithReserved(ResultTraits::MaskReservedFromValue(result.m_value), reserved));
} }
}; };
constexpr ALWAYS_INLINE Result MakeResult(ResultTraits::BaseType value) { [[nodiscard]] constexpr ALWAYS_INLINE Result MakeResult(ResultTraits::BaseType value) {
return ResultInternalAccessor::MakeResult(value); return ResultInternalAccessor::MakeResult(value);
} }
@ -161,12 +162,12 @@ namespace ams {
using Base = typename result::impl::ResultBase; using Base = typename result::impl::ResultBase;
public: public:
constexpr ALWAYS_INLINE operator Result() const { return result::impl::MakeResult(Base::SuccessValue); } constexpr ALWAYS_INLINE operator Result() const { return result::impl::MakeResult(Base::SuccessValue); }
static constexpr ALWAYS_INLINE bool CanAccept(Result result) { return result.IsSuccess(); } [[nodiscard]] static constexpr ALWAYS_INLINE bool CanAccept(Result result) { return result.IsSuccess(); }
constexpr ALWAYS_INLINE bool IsSuccess() const { return true; } [[nodiscard]] constexpr ALWAYS_INLINE bool IsSuccess() const { return true; }
constexpr ALWAYS_INLINE bool IsFailure() const { return !this->IsSuccess(); } [[nodiscard]] constexpr ALWAYS_INLINE bool IsFailure() const { return !this->IsSuccess(); }
constexpr ALWAYS_INLINE typename Base::BaseType GetValue() const { return Base::SuccessValue; } [[nodiscard]] constexpr ALWAYS_INLINE typename Base::BaseType GetValue() const { return Base::SuccessValue; }
}; };
namespace result::impl { namespace result::impl {
@ -203,10 +204,10 @@ namespace ams {
return ResultSuccess(); return ResultSuccess();
} }
constexpr ALWAYS_INLINE bool IsSuccess() const { return false; } [[nodiscard]] constexpr ALWAYS_INLINE bool IsSuccess() const { return false; }
constexpr ALWAYS_INLINE bool IsFailure() const { return !this->IsSuccess(); } [[nodiscard]] constexpr ALWAYS_INLINE bool IsFailure() const { return !this->IsSuccess(); }
constexpr ALWAYS_INLINE typename Base::BaseType GetValue() const { return Value; } [[nodiscard]] constexpr ALWAYS_INLINE typename Base::BaseType GetValue() const { return Value; }
}; };
template<ResultTraits::BaseType _Module, ResultTraits::BaseType DescStart, ResultTraits::BaseType DescEnd> template<ResultTraits::BaseType _Module, ResultTraits::BaseType DescStart, ResultTraits::BaseType DescEnd>
@ -223,7 +224,7 @@ namespace ams {
static constexpr typename ResultTraits::BaseType StartValue = ResultTraits::MakeStaticValue<Module, DescriptionStart>::value; static constexpr typename ResultTraits::BaseType StartValue = ResultTraits::MakeStaticValue<Module, DescriptionStart>::value;
static constexpr typename ResultTraits::BaseType EndValue = ResultTraits::MakeStaticValue<Module, DescriptionEnd>::value; static constexpr typename ResultTraits::BaseType EndValue = ResultTraits::MakeStaticValue<Module, DescriptionEnd>::value;
public: public:
static constexpr ALWAYS_INLINE bool Includes(Result result) { [[nodiscard]] static constexpr ALWAYS_INLINE bool Includes(Result result) {
if constexpr (UseDirectValueComparison) { if constexpr (UseDirectValueComparison) {
const auto inner_value = result.GetInnerValue(); const auto inner_value = result.GetInnerValue();
if constexpr (StartValue == EndValue) { if constexpr (StartValue == EndValue) {

View File

@ -432,7 +432,7 @@ namespace ams::sdmmc::impl {
/* If the mmc is manufactured by toshiba, try to enable bkops auto. */ /* If the mmc is manufactured by toshiba, try to enable bkops auto. */
if (is_toshiba && !IsBkopAutoEnable(static_cast<const u8 *>(wb))) { if (is_toshiba && !IsBkopAutoEnable(static_cast<const u8 *>(wb))) {
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
this->EnableBkopsAuto(); static_cast<void>(this->EnableBkopsAuto());
} }
/* Extend the bus speed to as fast as we can. */ /* Extend the bus speed to as fast as we can. */
@ -689,7 +689,7 @@ namespace ams::sdmmc::impl {
m_mmc_device.GetCid(cid, sizeof(cid)); m_mmc_device.GetCid(cid, sizeof(cid));
if (IsToshibaMmc(cid)) { if (IsToshibaMmc(cid)) {
/* NOTE: Nintendo does not check the result of this operation. */ /* NOTE: Nintendo does not check the result of this operation. */
this->CancelToshibaMmcModel(); static_cast<void>(this->CancelToshibaMmcModel());
} }
} }

View File

@ -558,11 +558,11 @@ namespace ams::sdmmc::impl {
/* NOTE: Nintendo accepts a failure. */ /* NOTE: Nintendo accepts a failure. */
if (R_SUCCEEDED(this->IssueCommandAppCmd(DeviceState_Tran))) { if (R_SUCCEEDED(this->IssueCommandAppCmd(DeviceState_Tran))) {
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
this->IssueCommandClearCardDetect(); static_cast<void>(this->IssueCommandClearCardDetect());
} }
/* NOTE: Nintendo does not check the result of this. */ /* NOTE: Nintendo does not check the result of this. */
BaseDeviceAccessor::IssueCommandSendStatus(); static_cast<void>(BaseDeviceAccessor::IssueCommandSendStatus());
} }
Result SdCardDeviceAccessor::StartupSdCardDevice(BusWidth max_bw, SpeedMode max_sm, void *wb, size_t wb_size) { Result SdCardDeviceAccessor::StartupSdCardDevice(BusWidth max_bw, SpeedMode max_sm, void *wb, size_t wb_size) {

View File

@ -369,7 +369,7 @@ namespace ams::sdmmc::impl {
/* Otherwise, check if we've timed out. */ /* Otherwise, check if we've timed out. */
if (!timer.Update()) { if (!timer.Update()) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultCommandInhibitCmdSoftwareTimeout()); R_THROW(sdmmc::ResultCommandInhibitCmdSoftwareTimeout());
} }
} }
@ -389,7 +389,7 @@ namespace ams::sdmmc::impl {
/* Otherwise, check if we've timed out. */ /* Otherwise, check if we've timed out. */
if (!timer.Update()) { if (!timer.Update()) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultCommandInhibitDatSoftwareTimeout()); R_THROW(sdmmc::ResultCommandInhibitDatSoftwareTimeout());
} }
} }
@ -458,7 +458,7 @@ namespace ams::sdmmc::impl {
this->ClearInterrupt(); this->ClearInterrupt();
if (R_FAILED(result)) { if (R_FAILED(result)) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
} }
R_RETURN(result); R_RETURN(result);
@ -467,7 +467,7 @@ namespace ams::sdmmc::impl {
R_RETURN(result); R_RETURN(result);
} else { } else {
/* If the device wasn't removed, cancel our transaction. */ /* If the device wasn't removed, cancel our transaction. */
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultCommandCompleteSoftwareTimeout()); R_THROW(sdmmc::ResultCommandCompleteSoftwareTimeout());
} }
} }
@ -489,12 +489,12 @@ namespace ams::sdmmc::impl {
} else if (sdmmc::ResultNoWaitedInterrupt::Includes(result)) { } else if (sdmmc::ResultNoWaitedInterrupt::Includes(result)) {
/* Otherwise, if the wait for the interrupt isn't done, update the timer and check for timeout. */ /* Otherwise, if the wait for the interrupt isn't done, update the timer and check for timeout. */
if (!timer.Update()) { if (!timer.Update()) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultCommandCompleteSoftwareTimeout()); R_THROW(sdmmc::ResultCommandCompleteSoftwareTimeout());
} }
} else { } else {
/* Otherwise, we have a generic failure. */ /* Otherwise, we have a generic failure. */
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_RETURN(result); R_RETURN(result);
} }
} }
@ -537,7 +537,7 @@ namespace ams::sdmmc::impl {
} }
} else { } else {
/* Abort the transaction. */ /* Abort the transaction. */
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_RETURN(result); R_RETURN(result);
} }
@ -548,7 +548,7 @@ namespace ams::sdmmc::impl {
} else { } else {
/* Otherwise, timeout if the transfer hasn't advanced. */ /* Otherwise, timeout if the transfer hasn't advanced. */
if (last_block_count != reg::Read(m_registers->block_count)) { if (last_block_count != reg::Read(m_registers->block_count)) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultTransferCompleteSoftwareTimeout()); R_THROW(sdmmc::ResultTransferCompleteSoftwareTimeout());
} }
} }
@ -589,14 +589,14 @@ namespace ams::sdmmc::impl {
if (!timer.Update()) { if (!timer.Update()) {
/* Only timeout if the transfer hasn't advanced. */ /* Only timeout if the transfer hasn't advanced. */
if (last_block_count != reg::Read(m_registers->block_count)) { if (last_block_count != reg::Read(m_registers->block_count)) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultTransferCompleteSoftwareTimeout()); R_THROW(sdmmc::ResultTransferCompleteSoftwareTimeout());
} }
break; break;
} }
} else { } else {
/* Otherwise, we have a generic failure. */ /* Otherwise, we have a generic failure. */
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_RETURN(result); R_RETURN(result);
} }
} }
@ -624,7 +624,7 @@ namespace ams::sdmmc::impl {
/* Otherwise, check if we're timed out. */ /* Otherwise, check if we're timed out. */
if (!timer.Update()) { if (!timer.Update()) {
this->AbortTransaction(); static_cast<void>(this->AbortTransaction());
R_THROW(sdmmc::ResultBusySoftwareTimeout()); R_THROW(sdmmc::ResultBusySoftwareTimeout());
} }
} }

View File

@ -471,7 +471,7 @@ namespace ams::sdmmc::impl {
SdHostStandardController::EnsureControl(); SdHostStandardController::EnsureControl();
WaitMicroSeconds(1); WaitMicroSeconds(1);
SdHostStandardController::AbortTransaction(); static_cast<void>(SdHostStandardController::AbortTransaction());
} }
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE)); reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
@ -520,7 +520,7 @@ namespace ams::sdmmc::impl {
/* Otherwise, check if we timed out. */ /* Otherwise, check if we timed out. */
if (!timer.Update()) { if (!timer.Update()) {
SdHostStandardController::AbortTransaction(); static_cast<void>(SdHostStandardController::AbortTransaction());
R_THROW(sdmmc::ResultIssueTuningCommandSoftwareTimeout()); R_THROW(sdmmc::ResultIssueTuningCommandSoftwareTimeout());
} }
} }
@ -857,7 +857,8 @@ namespace ams::sdmmc::impl {
R_TRY(this->CheckRemoved()); R_TRY(this->CheckRemoved());
/* Issue the command. */ /* Issue the command. */
this->IssueTuningCommand(command_index); /* NOTE: Nintendo does not check the result of this call. */
static_cast<void>(this->IssueTuningCommand(command_index));
/* Check if tuning is done. */ /* Check if tuning is done. */
if (i >= num_tries) { if (i >= num_tries) {
@ -902,7 +903,8 @@ namespace ams::sdmmc::impl {
/* If we're at 3.3V, lower to 1.8V. */ /* If we're at 3.3V, lower to 1.8V. */
if (m_current_bus_power == BusPower_3_3V) { if (m_current_bus_power == BusPower_3_3V) {
/* pcv::ChangeVoltage(pcv::PowerControlTarget_SdCard, 1800000); */ /* pcv::ChangeVoltage(pcv::PowerControlTarget_SdCard, 1800000); */
m_power_controller->LowerBusPower(); /* NOTE: Nintendo does not check the result of this call. */
static_cast<void>(m_power_controller->LowerBusPower());
/* Set our bus power. */ /* Set our bus power. */
m_current_bus_power = BusPower_1_8V; m_current_bus_power = BusPower_1_8V;
@ -913,7 +915,8 @@ namespace ams::sdmmc::impl {
/* pcv::PowerOff(pcv::PowerControlTarget_SdCard); */ /* pcv::PowerOff(pcv::PowerControlTarget_SdCard); */
m_power_controller->PowerOff(); /* NOTE: Nintendo does not check the result of this call. */
static_cast<void>(m_power_controller->PowerOff());
/* Set our bus power. */ /* Set our bus power. */
m_current_bus_power = BusPower_Off; m_current_bus_power = BusPower_Off;
@ -1276,7 +1279,8 @@ namespace ams::sdmmc::impl {
R_UNLESS(m_current_bus_power == BusPower_1_8V, pcv::ResultIllegalRequest()); R_UNLESS(m_current_bus_power == BusPower_1_8V, pcv::ResultIllegalRequest());
/* Disable vddio, and wait 4 ms. */ /* Disable vddio, and wait 4 ms. */
this->ControlVddioSdmmc1(BusPower_Off); /* NOTE: Nintendo does not check the result of this call. */
static_cast<void>(this->ControlVddioSdmmc1(BusPower_Off));
WaitMicroSeconds(4000); WaitMicroSeconds(4000);
/* Set the SD power GPIO to low. */ /* Set the SD power GPIO to low. */

View File

@ -223,8 +223,8 @@ CATEGORIES = {
124 : 'NvHostErrInfo', 124 : 'NvHostErrInfo',
125 : 'RunningUlaInfo', 125 : 'RunningUlaInfo',
126 : 'InternalPanelInfo', 126 : 'InternalPanelInfo',
127 : 'ResourceLimitLimitInfo', 127 : 'ResourceLimitInfo',
128 : 'ResourceLimitPeakInfo', # 128 : 'ResourceLimitPeakInfoDeprecated',
129 : 'TouchScreenInfo', 129 : 'TouchScreenInfo',
130 : 'AcpUserAccountSettingsInfo', 130 : 'AcpUserAccountSettingsInfo',
131 : 'AudioDeviceInfo', 131 : 'AudioDeviceInfo',