/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include namespace Kernel { class Process; class PageDirectory : public RefCounted { friend class MemoryManager; public: static RefPtr create_for_userspace(const RangeAllocator* parent_range_allocator = nullptr) { auto page_directory = adopt_ref(*new PageDirectory(parent_range_allocator)); if (!page_directory->is_valid()) return {}; return page_directory; } static NonnullRefPtr create_kernel_page_directory() { return adopt_ref(*new PageDirectory); } static RefPtr find_by_cr3(u32); ~PageDirectory(); u32 cr3() const { return m_directory_table->paddr().get(); } RangeAllocator& range_allocator() { return m_range_allocator; } const RangeAllocator& range_allocator() const { return m_range_allocator; } RangeAllocator& identity_range_allocator() { return m_identity_range_allocator; } bool is_valid() const { return m_valid; } Space* space() { return m_space; } const Space* space() const { return m_space; } void set_space(Badge, Space& space) { m_space = &space; } RecursiveSpinLock& get_lock() { return m_lock; } private: explicit PageDirectory(const RangeAllocator* parent_range_allocator); PageDirectory(); Space* m_space { nullptr }; RangeAllocator m_range_allocator; RangeAllocator m_identity_range_allocator; RefPtr m_directory_table; RefPtr m_directory_pages[4]; HashMap> m_page_tables; RecursiveSpinLock m_lock; bool m_valid { false }; }; }