aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/memory.h
blob: 90b2aeee87fe4eb0c74e9a4cc363184db3d6316c (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
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <optional>
#include <boost/icl/interval_set.hpp>
#include <boost/serialization/export.hpp>
#include "common/common_types.h"
#include "common/serialization/boost_interval_set.hpp"

namespace Kernel {

struct AddressMapping;
class VMManager;

struct MemoryRegionInfo {
    u32 base; // Not an address, but offset from start of FCRAM
    u32 size;
    u32 used;

    // The domain of the interval_set are offsets from start of FCRAM
    using IntervalSet = boost::icl::interval_set<u32>;
    using Interval = IntervalSet::interval_type;

    IntervalSet free_blocks;

    // When locked, Free calls will be ignored, while Allocate calls will hit an assert. A memory
    // region locks itself after deserialization.
    bool is_locked{};

    /**
     * Reset the allocator state
     * @param base The base offset the beginning of FCRAM.
     * @param size The region size this allocator manages
     */
    void Reset(u32 base, u32 size);

    /**
     * Allocates memory from the heap.
     * @param size The size of memory to allocate.
     * @returns The set of blocks that make up the allocation request. Empty set if there is no
     *     enough space.
     */
    IntervalSet HeapAllocate(u32 size);

    /**
     * Allocates memory from the linear heap with specific address and size.
     * @param offset the address offset to the beginning of FCRAM.
     * @param size size of the memory to allocate.
     * @returns true if the allocation is successful. false if the requested region is not free.
     */
    bool LinearAllocate(u32 offset, u32 size);

    /**
     * Allocates memory from the linear heap with only size specified.
     * @param size size of the memory to allocate.
     * @returns the address offset to the beginning of FCRAM; null if there is no enough space
     */
    std::optional<u32> LinearAllocate(u32 size);

    /**
     * Allocates memory from the linear heap with only size specified.
     * @param size size of the memory to allocate.
     * @returns the address offset to the found block, searching from the end of FCRAM; null if
     * there is no enough space
     */
    std::optional<u32> RLinearAllocate(u32 size);

    /**
     * Frees one segment of memory. The memory must have been allocated as heap or linear heap.
     * @param offset the region address offset to the beginning of FCRAM.
     * @param size the size of the region to free.
     */
    void Free(u32 offset, u32 size);

    /**
     * Unlock the MemoryRegion. Used after loading is completed.
     */
    void Unlock();

private:
    friend class boost::serialization::access;
    template <class Archive>
    void serialize(Archive& ar, const unsigned int);
};

} // namespace Kernel

BOOST_CLASS_EXPORT_KEY(Kernel::MemoryRegionInfo)