mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-16 16:14:25 -04:00
exo2: implement through end of random cache init
This commit is contained in:
parent
f66b41c027
commit
cbcd1d87fb
11 changed files with 447 additions and 11 deletions
103
exosphere2/program/source/smc/secmon_random_cache.cpp
Normal file
103
exosphere2/program/source/smc/secmon_random_cache.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "secmon_smc_common.hpp"
|
||||
#include "secmon_random_cache.hpp"
|
||||
|
||||
namespace ams::secmon::smc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline size_t MaxRandomBytes = sizeof(SmcArguments) - sizeof(SmcArguments{}.r[0]);
|
||||
|
||||
constinit int g_random_offset_low = 0;
|
||||
constinit int g_random_offset_high = 0;
|
||||
|
||||
void FillRandomCache(int offset, int size) {
|
||||
/* Get the cache. */
|
||||
u8 * const random_cache_loc = GetRandomBytesCache() + offset;
|
||||
|
||||
/* Flush the region we're about to fill to ensure consistency with the SE. */
|
||||
hw::FlushDataCache(random_cache_loc, size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
|
||||
/* Generate random bytes. */
|
||||
se::GenerateRandomBytes(random_cache_loc, size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
|
||||
/* Flush to ensure the CPU sees consistent data for the region. */
|
||||
hw::FlushDataCache(random_cache_loc, size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FillRandomCache() {
|
||||
/* Fill the cache. */
|
||||
FillRandomCache(0, GetRandomBytesCacheSize());
|
||||
|
||||
/* Set the extents. */
|
||||
g_random_offset_low = 0;
|
||||
g_random_offset_high = GetRandomBytesCacheSize() - 1;
|
||||
}
|
||||
|
||||
void RefillRandomCache() {
|
||||
/* Check that we need to do any refilling. */
|
||||
if (const int used_start = (g_random_offset_high + 1) % GetRandomBytesCacheSize(); used_start != g_random_offset_low) {
|
||||
if (used_start < g_random_offset_low) {
|
||||
/* The region we need to fill is after used_start but before g_random_offset_low. */
|
||||
const auto size = g_random_offset_low - used_start;
|
||||
FillRandomCache(used_start, size);
|
||||
g_random_offset_high += size;
|
||||
} else {
|
||||
/* We need to fill the space from high to the end and from low to start. */
|
||||
const int high_size = GetRandomBytesCacheSize() - used_start;
|
||||
if (high_size > 0) {
|
||||
FillRandomCache(used_start, high_size);
|
||||
g_random_offset_high += high_size;
|
||||
}
|
||||
|
||||
const int low_size = g_random_offset_low;
|
||||
if (low_size > 0) {
|
||||
FillRandomCache(0, low_size);
|
||||
g_random_offset_high += low_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
g_random_offset_high %= GetRandomBytesCacheSize();
|
||||
}
|
||||
}
|
||||
|
||||
void GetRandomFromCache(void *dst, size_t size) {
|
||||
u8 * const cache = GetRandomBytesCache();
|
||||
u8 * cur_dst = static_cast<u8 *>(dst);
|
||||
|
||||
/* NOTE: Nintendo does not do bounds checking here, and does not do multiple reads when the get would wrap around. */
|
||||
while (size > 0) {
|
||||
const size_t copy_size = std::min(size, static_cast<size_t>(GetRandomBytesCacheSize() - g_random_offset_low));
|
||||
std::memcpy(cur_dst, cache + g_random_offset_low, copy_size);
|
||||
|
||||
cur_dst += copy_size;
|
||||
size -= copy_size;
|
||||
|
||||
if (g_random_offset_low + copy_size >= GetRandomBytesCacheSize()) {
|
||||
g_random_offset_low = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue