diff --git a/exosphere2/program/source/secmon_setup.cpp b/exosphere2/program/source/secmon_setup.cpp index 02f044d4e..da611c9bd 100644 --- a/exosphere2/program/source/secmon_setup.cpp +++ b/exosphere2/program/source/secmon_setup.cpp @@ -1194,4 +1194,13 @@ namespace ams::secmon { hw::InstructionSynchronizationBarrier(); } + void SetKernelCarveoutRegion(int index, uintptr_t address, size_t size) { + /* Configure the carveout. */ + auto &carveout = g_kernel_carveouts[index]; + carveout.address = address; + carveout.size = size; + + SetupKernelCarveouts(); + } + } \ No newline at end of file diff --git a/exosphere2/program/source/secmon_setup.hpp b/exosphere2/program/source/secmon_setup.hpp index c3c468fee..f6e1f3776 100644 --- a/exosphere2/program/source/secmon_setup.hpp +++ b/exosphere2/program/source/secmon_setup.hpp @@ -23,6 +23,8 @@ namespace ams::secmon { constexpr inline int KernelCarveoutCount = 2; + constexpr size_t CarveoutSizeMax = 512_MB - 128_KB; + void SetupCpuMemoryControllersEnableMmu(); void SetupCpuCoreContext(); void SetupCpuSErrorDebug(); @@ -37,4 +39,6 @@ namespace ams::secmon { void SaveSecurityEngineAesKeySlotTestVector(); + void SetKernelCarveoutRegion(int index, uintptr_t address, size_t size); + } \ No newline at end of file diff --git a/exosphere2/program/source/smc/secmon_smc_aes.cpp b/exosphere2/program/source/smc/secmon_smc_aes.cpp index e517e611e..3ca701edb 100644 --- a/exosphere2/program/source/smc/secmon_smc_aes.cpp +++ b/exosphere2/program/source/smc/secmon_smc_aes.cpp @@ -111,7 +111,7 @@ namespace ams::secmon::smc { u8 kek_source[AesKeySize]; std::memcpy(kek_source, std::addressof(args.r[1]), AesKeySize); - const int generation = std::min(args.r[3] - 1, pkg1::KeyGeneration_1_0_0); + const int generation = std::max(static_cast(args.r[3]) - 1, pkg1::KeyGeneration_1_0_0); const util::BitPack32 option = { static_cast(args.r[4]) }; const bool is_device_unique = option.Get(); diff --git a/exosphere2/program/source/smc/secmon_smc_carveout.cpp b/exosphere2/program/source/smc/secmon_smc_carveout.cpp index 2f947431e..120ae9029 100644 --- a/exosphere2/program/source/smc/secmon_smc_carveout.cpp +++ b/exosphere2/program/source/smc/secmon_smc_carveout.cpp @@ -15,13 +15,27 @@ */ #include #include "../secmon_error.hpp" +#include "../secmon_setup.hpp" #include "secmon_smc_carveout.hpp" namespace ams::secmon::smc { SmcResult SmcSetKernelCarveoutRegion(SmcArguments &args) { - /* TODO */ - return SmcResult::NotImplemented; + /* Decode arguments. */ + const int index = args.r[1]; + const uintptr_t address = args.r[2]; + const size_t size = args.r[3]; + + /* Validate arguments. */ + SMC_R_UNLESS(0 <= index && index < KernelCarveoutCount, InvalidArgument); + SMC_R_UNLESS(util::IsAligned(address, 128_KB), InvalidArgument); + SMC_R_UNLESS(util::IsAligned(size, 128_KB), InvalidArgument); + SMC_R_UNLESS(size <= CarveoutSizeMax, InvalidArgument); + + /* Set the carveout. */ + SetKernelCarveoutRegion(index, address, size); + + return SmcResult::Success; } } diff --git a/exosphere2/program/source/smc/secmon_smc_handler.cpp b/exosphere2/program/source/smc/secmon_smc_handler.cpp index ac960fae4..ddea4311e 100644 --- a/exosphere2/program/source/smc/secmon_smc_handler.cpp +++ b/exosphere2/program/source/smc/secmon_smc_handler.cpp @@ -242,7 +242,7 @@ namespace ams::secmon::smc { util::WaitMicroSeconds(1000); } - if (args.r[0] != static_cast(SmcResult::Success)) { + if (args.r[0] != static_cast(SmcResult::Success) && info.function_id != 0xC3000007 /* generate aes key fails during SetupKekAccessKeys */) { *(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress()) = 0xCCCCCCCC; *(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x10) = static_cast(info.function_id); for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) {