ams: allow bootloader to merely approximate correct target firmware

This commit is contained in:
Michael Scire
2021-10-11 00:54:17 -07:00
parent d41de21753
commit 5708bb1557
24 changed files with 281 additions and 396 deletions

View File

@@ -123,7 +123,8 @@ namespace ams::mitm::bpc {
std::memcpy(g_reboot_payload, payload, payload_size);
/* Note to the secure monitor that we have a payload. */
spl::smc::SetConfig(spl::ConfigItem::ExospherePayloadAddress, g_reboot_payload, nullptr, 0);
spl::smc::AsyncOperationKey dummy;
spl::smc::SetConfig(std::addressof(dummy), spl::ConfigItem::ExospherePayloadAddress, nullptr, 0, g_reboot_payload);
/* NOTE: Preferred reboot type may be overrwritten when parsed from settings during boot. */
g_reboot_type = RebootType::ToPayload;

View File

@@ -68,21 +68,31 @@ namespace ams {
}
namespace hos {
void SetNonApproximateVersionInternal();
}
namespace init {
void InitializeSystemModule() {
/* Initialize heaps. */
boot::InitializeHeaps();
/* Set fs allocator. */
fs::SetAllocator(boot::Allocate, boot::Deallocate);
/* Initialize services we need. */
/* Connect to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Initialize fs. */
fs::InitializeForSystem();
fs::SetAllocator(boot::Allocate, boot::Deallocate);
fs::SetEnabledAutoAbort(false);
/* Initialize spl. */
spl::Initialize();
R_ABORT_UNLESS(pmshellInitialize());
/* Set the true hos version. */
hos::SetNonApproximateVersionInternal();
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
@@ -174,6 +184,7 @@ namespace ams {
boot::FinalizeGpioDriverLibrary();
/* Tell PM to start boot2. */
R_ABORT_UNLESS(pmshellInitialize());
R_ABORT_UNLESS(pmshellNotifyBootFinished());
}

View File

@@ -195,9 +195,6 @@ namespace ams {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }

View File

@@ -165,6 +165,12 @@ namespace ams {
}
namespace hos {
void InitializeVersionInternal(bool allow_approximate);
}
namespace init {
void InitializeSystemModule() {
@@ -182,6 +188,12 @@ namespace ams {
/* Use our manager extension to tell SM that the FS bug has been worked around. */
R_ABORT_UNLESS(sm::manager::EndInitialDefers());
/* Wait for the true hos version to be available. */
hos::InitializeVersionInternal(false);
/* Now that the true hos version is available, we should once more end defers (alerting sm to the available hos version). */
R_ABORT_UNLESS(sm::manager::EndInitialDefers());
/* Initialize remaining services we need. */
R_ABORT_UNLESS(ldrPmInitialize());
spl::Initialize();

View File

@@ -17,6 +17,12 @@
#include "sm_service_manager.hpp"
#include "../sm_wait_list.hpp"
namespace ams::hos {
void InitializeVersionInternal(bool allow_approximate);
}
namespace ams::sm::impl {
namespace {
@@ -862,8 +868,12 @@ namespace ams::sm::impl {
std::scoped_lock lk(g_mutex);
/* Note that we have ended the initial deferral period. */
const bool had_ended_defers = g_ended_initial_defers;
g_ended_initial_defers = true;
/* Something about deferral state has changed, so we should refresh our hos version. */
hos::InitializeVersionInternal(!had_ended_defers);
/* This might undefer some requests. */
for (const auto &service_name : InitiallyDeferredServices) {
TriggerResume(service_name);

View File

@@ -162,9 +162,6 @@ namespace ams {
void InitializeSystemModule() {
/* Initialize our connection to sm. */
R_ABORT_UNLESS(sm::Initialize());
/* Verify that we can sanely execute. */
ams::CheckApiVersion();
}
void FinalizeSystemModule() { /* ... */ }