summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_system_resource.h
blob: 9a991f72592460146e5ae9198898fbb1952f7d4c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "common/assert.h"
#include "common/common_types.h"
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_dynamic_resource_manager.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_page_table_manager.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/slab_helpers.h"

namespace Kernel {

// NOTE: Nintendo's implementation does not have the "is_secure_resource" field, and instead uses
// virtual IsSecureResource().

class KSystemResource : public KAutoObject {
    KERNEL_AUTOOBJECT_TRAITS(KSystemResource, KAutoObject);

public:
    explicit KSystemResource(KernelCore& kernel_) : KAutoObject(kernel_) {}

protected:
    void SetSecureResource() {
        m_is_secure_resource = true;
    }

public:
    virtual void Destroy() override {
        UNREACHABLE_MSG("KSystemResource::Destroy() was called");
    }

    bool IsSecureResource() const {
        return m_is_secure_resource;
    }

    void SetManagers(KMemoryBlockSlabManager& mb, KBlockInfoManager& bi, KPageTableManager& pt) {
        ASSERT(m_p_memory_block_slab_manager == nullptr);
        ASSERT(m_p_block_info_manager == nullptr);
        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;
    }

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};
};

class KSecureSystemResource final
    : public KAutoObjectWithSlabHeap<KSecureSystemResource, KSystemResource> {
public:
    explicit KSecureSystemResource(KernelCore& kernel_)
        : KAutoObjectWithSlabHeap<KSecureSystemResource, KSystemResource>(kernel_) {
        // 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([[maybe_unused]] uintptr_t arg) {}

    size_t CalculateRequiredSecureMemorySize() const {
        return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool);
    }

    size_t GetSize() const {
        return m_resource_size;
    }
    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);

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{};
    VAddr m_resource_address{};
    size_t m_resource_size{};
};

} // namespace Kernel