mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 08:22:04 +00:00
os: add FlushDataCache
This commit is contained in:
parent
a595c232b9
commit
bc96ebb74c
7 changed files with 150 additions and 19 deletions
|
@ -37,7 +37,7 @@ namespace ams::ncm {
|
||||||
size_t m_peak_total_alloc_size;
|
size_t m_peak_total_alloc_size;
|
||||||
size_t m_peak_alloc_size;
|
size_t m_peak_alloc_size;
|
||||||
public:
|
public:
|
||||||
explicit ContentMetaMemoryResource(void *heap, size_t heap_size) : m_allocator(heap, heap_size), m_peak_alloc_size(0), m_peak_total_alloc_size(0) { /* ... */ }
|
explicit ContentMetaMemoryResource(void *heap, size_t heap_size) : m_allocator(heap, heap_size), m_peak_total_alloc_size(0), m_peak_alloc_size(0) { /* ... */ }
|
||||||
|
|
||||||
mem::StandardAllocator *GetAllocator() { return std::addressof(m_allocator); }
|
mem::StandardAllocator *GetAllocator() { return std::addressof(m_allocator); }
|
||||||
size_t GetPeakTotalAllocationSize() const { return m_peak_total_alloc_size; }
|
size_t GetPeakTotalAllocationSize() const { return m_peak_total_alloc_size; }
|
||||||
|
|
|
@ -53,3 +53,4 @@
|
||||||
#include <stratosphere/os/os_io_region.hpp>
|
#include <stratosphere/os/os_io_region.hpp>
|
||||||
#include <stratosphere/os/os_multiple_wait.hpp>
|
#include <stratosphere/os/os_multiple_wait.hpp>
|
||||||
#include <stratosphere/os/os_argument.hpp>
|
#include <stratosphere/os/os_argument.hpp>
|
||||||
|
#include <stratosphere/os/os_cache.hpp>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
|
||||||
|
namespace ams::os {
|
||||||
|
|
||||||
|
void FlushDataCache(const void *addr, size_t size);
|
||||||
|
void FlushEntireDataCache();
|
||||||
|
|
||||||
|
}
|
23
libraries/libstratosphere/source/os/impl/os_cache_impl.hpp
Normal file
23
libraries/libstratosphere/source/os/impl/os_cache_impl.hpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
#ifdef ATMOSPHERE_OS_HORIZON
|
||||||
|
#include "os_cache_impl.os.horizon.hpp"
|
||||||
|
#else
|
||||||
|
#error "Unknown OS for ThreadManagerImpl"
|
||||||
|
#endif
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::os::impl {
|
||||||
|
|
||||||
|
inline void FlushDataCacheImpl(const void *addr, size_t size) {
|
||||||
|
#if defined(ATMOSPHERE_ARCH_ARM64)
|
||||||
|
{
|
||||||
|
/* Declare helper variables. */
|
||||||
|
uintptr_t cache_type_register = 0;
|
||||||
|
uintptr_t cache_line_size = 0;
|
||||||
|
const uintptr_t end_addr = reinterpret_cast<uintptr_t>(addr) + size;
|
||||||
|
|
||||||
|
/* Get the cache type register. */
|
||||||
|
__asm__ __volatile__("mrs %[cache_type_register], ctr_el0" : [cache_type_register]"=r"(cache_type_register));
|
||||||
|
|
||||||
|
/* Calculate cache line size. */
|
||||||
|
cache_line_size = 4 << ((cache_type_register >> 16) & 0xF);
|
||||||
|
|
||||||
|
/* Iterate, flushing cache lines. */
|
||||||
|
for (uintptr_t cur = reinterpret_cast<uintptr_t>(addr) & ~(cache_line_size - 1); cur < end_addr; cur += cache_line_size) {
|
||||||
|
__asm__ __volatile__ ("dc civac, %[cur]" :: [cur]"r"(cur));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert a memory barrier, now that memory has been flushed. */
|
||||||
|
__asm__ __volatile__("dsb sy" ::: "memory");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const auto result = svc::FlushProcessDataCache(svc::PseudoHandle::CurrentProcess, reinterpret_cast<uintptr_t>(addr), size);
|
||||||
|
R_ASSERT(result);
|
||||||
|
AMS_UNUSED(result);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void FlushEntireDataCacheImpl() {
|
||||||
|
svc::FlushEntireDataCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
libraries/libstratosphere/source/os/os_cache.cpp
Normal file
29
libraries/libstratosphere/source/os/os_cache.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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 <stratosphere.hpp>
|
||||||
|
#include "impl/os_cache_impl.hpp"
|
||||||
|
|
||||||
|
namespace ams::os {
|
||||||
|
|
||||||
|
void FlushDataCache(const void *addr, size_t size) {
|
||||||
|
return impl::FlushDataCacheImpl(addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlushEntireDataCache() {
|
||||||
|
return impl::FlushEntireDataCacheImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -372,7 +372,7 @@ namespace ams::spl::impl {
|
||||||
|
|
||||||
std::memcpy(layout->in_block, src, sizeof(layout->in_block));
|
std::memcpy(layout->in_block, src, sizeof(layout->in_block));
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
{
|
{
|
||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
@ -390,7 +390,7 @@ namespace ams::spl::impl {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
|
|
||||||
std::memcpy(dst, layout->out_block, sizeof(layout->out_block));
|
std::memcpy(dst, layout->out_block, sizeof(layout->out_block));
|
||||||
return smc::Result::Success;
|
return smc::Result::Success;
|
||||||
|
@ -407,7 +407,7 @@ namespace ams::spl::impl {
|
||||||
R_UNLESS(src_size <= sizeof(DecryptAndStoreDeviceUniqueKeyLayout), spl::ResultInvalidSize());
|
R_UNLESS(src_size <= sizeof(DecryptAndStoreDeviceUniqueKeyLayout), spl::ResultInvalidSize());
|
||||||
std::memcpy(layout, src, src_size);
|
std::memcpy(layout, src, src_size);
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
smc::Result smc_res;
|
smc::Result smc_res;
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||||
smc_res = smc::DecryptDeviceUniqueData(layout->data, src_size, access_key, key_source, static_cast<smc::DeviceUniqueDataMode>(option));
|
smc_res = smc::DecryptDeviceUniqueData(layout->data, src_size, access_key, key_source, static_cast<smc::DeviceUniqueDataMode>(option));
|
||||||
|
@ -438,7 +438,7 @@ namespace ams::spl::impl {
|
||||||
std::memcpy(layout->mod + mod_ofs, mod, mod_size);
|
std::memcpy(layout->mod + mod_ofs, mod, mod_size);
|
||||||
|
|
||||||
/* Do exp mod operation. */
|
/* Do exp mod operation. */
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
{
|
{
|
||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
@ -452,7 +452,7 @@ namespace ams::spl::impl {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
armDCacheFlush(g_work_buffer, sizeof(out_size));
|
os::FlushDataCache(g_work_buffer, sizeof(out_size));
|
||||||
|
|
||||||
std::memcpy(out, g_work_buffer, out_size);
|
std::memcpy(out, g_work_buffer, out_size);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -478,7 +478,7 @@ namespace ams::spl::impl {
|
||||||
std::memcpy(layout->mod + mod_ofs, mod, mod_size);
|
std::memcpy(layout->mod + mod_ofs, mod, mod_size);
|
||||||
|
|
||||||
/* Do exp mod operation. */
|
/* Do exp mod operation. */
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
{
|
{
|
||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
@ -492,7 +492,7 @@ namespace ams::spl::impl {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
armDCacheFlush(g_work_buffer, sizeof(*out_access_key));
|
os::FlushDataCache(g_work_buffer, sizeof(*out_access_key));
|
||||||
|
|
||||||
std::memcpy(out_access_key, g_work_buffer, sizeof(*out_access_key));
|
std::memcpy(out_access_key, g_work_buffer, sizeof(*out_access_key));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -566,7 +566,7 @@ namespace ams::spl::impl {
|
||||||
std::memcpy(layout->mod + mod_ofs, mod, mod_size);
|
std::memcpy(layout->mod + mod_ofs, mod, mod_size);
|
||||||
|
|
||||||
/* Do exp mod operation. */
|
/* Do exp mod operation. */
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
{
|
{
|
||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
@ -580,7 +580,7 @@ namespace ams::spl::impl {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
armDCacheFlush(g_work_buffer, sizeof(out_size));
|
os::FlushDataCache(g_work_buffer, sizeof(out_size));
|
||||||
|
|
||||||
std::memcpy(out, g_work_buffer, out_size);
|
std::memcpy(out, g_work_buffer, out_size);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -701,9 +701,9 @@ namespace ams::spl::impl {
|
||||||
crypt_ctx->out.address = dst_se_addr;
|
crypt_ctx->out.address = dst_se_addr;
|
||||||
crypt_ctx->out.size = dst_size;
|
crypt_ctx->out.size = dst_size;
|
||||||
|
|
||||||
armDCacheFlush(crypt_ctx, sizeof(*crypt_ctx));
|
os::FlushDataCache(crypt_ctx, sizeof(*crypt_ctx));
|
||||||
armDCacheFlush(const_cast<void *>(src), src_size);
|
os::FlushDataCache(const_cast<void *>(src), src_size);
|
||||||
armDCacheFlush(dst, dst_size);
|
os::FlushDataCache(dst, dst_size);
|
||||||
{
|
{
|
||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
@ -720,7 +720,7 @@ namespace ams::spl::impl {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
armDCacheFlush(dst, dst_size);
|
os::FlushDataCache(dst, dst_size);
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
@ -783,7 +783,7 @@ namespace ams::spl::impl {
|
||||||
R_UNLESS(src_size <= sizeof(DecryptDeviceUniqueDataLayout), spl::ResultInvalidSize());
|
R_UNLESS(src_size <= sizeof(DecryptDeviceUniqueDataLayout), spl::ResultInvalidSize());
|
||||||
|
|
||||||
std::memcpy(layout->data, src, src_size);
|
std::memcpy(layout->data, src, src_size);
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
|
|
||||||
smc::Result smc_res;
|
smc::Result smc_res;
|
||||||
size_t copy_size = 0;
|
size_t copy_size = 0;
|
||||||
|
@ -795,7 +795,7 @@ namespace ams::spl::impl {
|
||||||
copy_size = std::min(dst_size, copy_size);
|
copy_size = std::min(dst_size, copy_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
if (smc_res == smc::Result::Success) {
|
if (smc_res == smc::Result::Success) {
|
||||||
std::memcpy(dst, layout->data, copy_size);
|
std::memcpy(dst, layout->data, copy_size);
|
||||||
}
|
}
|
||||||
|
@ -827,7 +827,7 @@ namespace ams::spl::impl {
|
||||||
|
|
||||||
std::memcpy(layout, src, src_size);
|
std::memcpy(layout, src, src_size);
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
return smc::ConvertResult(smc::LoadEsDeviceKey(layout->data, src_size, access_key, key_source, option));
|
return smc::ConvertResult(smc::LoadEsDeviceKey(layout->data, src_size, access_key, key_source, option));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -915,12 +915,12 @@ namespace ams::spl::impl {
|
||||||
layout->access_key_enc = access_key_enc;
|
layout->access_key_enc = access_key_enc;
|
||||||
layout->source_enc = source_enc;
|
layout->source_enc = source_enc;
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
os::FlushDataCache(layout, sizeof(*layout));
|
||||||
|
|
||||||
smc::Result smc_res = smc::ReencryptDeviceUniqueData(layout->data, src_size, layout->access_key_dec, layout->source_dec, layout->access_key_enc, layout->source_enc, option);
|
smc::Result smc_res = smc::ReencryptDeviceUniqueData(layout->data, src_size, layout->access_key_dec, layout->source_dec, layout->access_key_enc, layout->source_enc, option);
|
||||||
if (smc_res == smc::Result::Success) {
|
if (smc_res == smc::Result::Success) {
|
||||||
size_t copy_size = std::min(dst_size, src_size);
|
size_t copy_size = std::min(dst_size, src_size);
|
||||||
armDCacheFlush(layout, copy_size);
|
os::FlushDataCache(layout, copy_size);
|
||||||
std::memcpy(dst, layout->data, copy_size);
|
std::memcpy(dst, layout->data, copy_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue