Atmosphere/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp
2022-10-12 09:15:16 -07:00

108 lines
5.4 KiB
C++

/*
* 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 <mesosphere/kern_common.hpp>
#include <mesosphere/kern_k_auto_object.hpp>
#include <mesosphere/kern_slab_helpers.hpp>
#include <mesosphere/kern_k_memory_manager.hpp>
#include <mesosphere/kern_k_dynamic_resource_manager.hpp>
#include <mesosphere/kern_k_page_table_manager.hpp>
#include <mesosphere/kern_k_resource_limit.hpp>
namespace ams::kern {
/* NOTE: Nintendo's implementation does not have the "is_secure_resource" field, and instead uses virtual IsSecureResource(). */
class KSystemResource : public KAutoObject {
MESOSPHERE_AUTOOBJECT_TRAITS(KSystemResource, KAutoObject);
private:
KMemoryBlockSlabManager *m_p_memory_block_slab_manager{};
KBlockInfoManager *m_p_block_info_manager{};
KPageTableManager *m_p_page_table_manager{};
bool m_is_secure_resource{false};
public:
explicit KSystemResource() : KAutoObject() { /* ... */ }
constexpr explicit KSystemResource(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize) { /* ... */ }
protected:
ALWAYS_INLINE void SetSecureResource() { m_is_secure_resource = true; }
public:
virtual void Destroy() override { MESOSPHERE_PANIC("KSystemResource::Destroy() was called"); }
ALWAYS_INLINE bool IsSecureResource() const { return m_is_secure_resource; }
void SetManagers(KMemoryBlockSlabManager &mb, KBlockInfoManager &bi, KPageTableManager &pt) {
MESOSPHERE_ASSERT(m_p_memory_block_slab_manager == nullptr);
MESOSPHERE_ASSERT(m_p_block_info_manager == nullptr);
MESOSPHERE_ASSERT(m_p_page_table_manager == nullptr);
m_p_memory_block_slab_manager = std::addressof(mb);
m_p_block_info_manager = std::addressof(bi);
m_p_page_table_manager = std::addressof(pt);
}
const KMemoryBlockSlabManager &GetMemoryBlockSlabManager() const { return *m_p_memory_block_slab_manager; }
const KBlockInfoManager &GetBlockInfoManager() const { return *m_p_block_info_manager; }
const KPageTableManager &GetPageTableManager() const { return *m_p_page_table_manager; }
KMemoryBlockSlabManager &GetMemoryBlockSlabManager() { return *m_p_memory_block_slab_manager; }
KBlockInfoManager &GetBlockInfoManager() { return *m_p_block_info_manager; }
KPageTableManager &GetPageTableManager() { return *m_p_page_table_manager; }
KMemoryBlockSlabManager *GetMemoryBlockSlabManagerPointer() { return m_p_memory_block_slab_manager; }
KBlockInfoManager *GetBlockInfoManagerPointer() { return m_p_block_info_manager; }
KPageTableManager *GetPageTableManagerPointer() { return m_p_page_table_manager; }
};
class KSecureSystemResource final : public KAutoObjectWithSlabHeap<KSecureSystemResource, KSystemResource> {
private:
bool m_is_initialized;
KMemoryManager::Pool m_resource_pool;
KDynamicPageManager m_dynamic_page_manager;
KMemoryBlockSlabManager m_memory_block_slab_manager;
KBlockInfoManager m_block_info_manager;
KPageTableManager m_page_table_manager;
KMemoryBlockSlabHeap m_memory_block_heap;
KBlockInfoSlabHeap m_block_info_heap;
KPageTableSlabHeap m_page_table_heap;
KResourceLimit *m_resource_limit;
KVirtualAddress m_resource_address;
size_t m_resource_size;
public:
explicit KSecureSystemResource() : m_is_initialized(false), m_resource_limit(nullptr) {
/* Mark ourselves as being a secure resource. */
this->SetSecureResource();
}
Result Initialize(size_t size, KResourceLimit *resource_limit, KMemoryManager::Pool pool);
void Finalize();
bool IsInitialized() const { return m_is_initialized; }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
ALWAYS_INLINE size_t CalculateRequiredSecureMemorySize() const {
return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool);
}
ALWAYS_INLINE size_t GetSize() const { return m_resource_size; }
ALWAYS_INLINE size_t GetUsedSize() const { return m_dynamic_page_manager.GetUsed() * PageSize; }
const KDynamicPageManager &GetDynamicPageManager() const { return m_dynamic_page_manager; }
public:
static size_t CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool);
};
}