/* * 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 . */ #pragma once #include #include #include #include #include #include #include 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 { 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); }; }