diff --git a/exosphere2/program/source/secmon_setup.cpp b/exosphere2/program/source/secmon_setup.cpp index 02f044d..da611c9 100644 --- a/exosphere2/program/source/secmon_setup.cpp +++ b/exosphere2/program/source/secmon_setup.cpp @@ -1194,4 +1194,13 @@ 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 c3c468f..f6e1f37 100644 --- a/exosphere2/program/source/secmon_setup.hpp +++ b/exosphere2/program/source/secmon_setup.hpp @@ -23,6 +23,8 @@ constexpr inline int KernelCarveoutCount = 2; + constexpr size_t CarveoutSizeMax = 512_MB - 128_KB; + void SetupCpuMemoryControllersEnableMmu(); void SetupCpuCoreContext(); void SetupCpuSErrorDebug(); @@ -37,4 +39,6 @@ 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 e517e61..3ca701e 100644 --- a/exosphere2/program/source/smc/secmon_smc_aes.cpp +++ b/exosphere2/program/source/smc/secmon_smc_aes.cpp @@ -111,7 +111,7 @@ 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 2f94743..120ae90 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 ac960fa..ddea431 100644 --- a/exosphere2/program/source/smc/secmon_smc_handler.cpp +++ b/exosphere2/program/source/smc/secmon_smc_handler.cpp @@ -242,7 +242,7 @@ 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) {