Serenity Operating System
1/*
2 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/OwnPtr.h>
10#include <AK/Vector.h>
11#include <Kernel/Memory/PhysicalPage.h>
12#include <Kernel/Memory/PhysicalZone.h>
13
14namespace Kernel::Memory {
15
16class PhysicalRegion {
17 AK_MAKE_NONCOPYABLE(PhysicalRegion);
18 AK_MAKE_NONMOVABLE(PhysicalRegion);
19
20public:
21 static OwnPtr<PhysicalRegion> try_create(PhysicalAddress lower, PhysicalAddress upper)
22 {
23 return adopt_own_if_nonnull(new PhysicalRegion { lower, upper });
24 }
25
26 ~PhysicalRegion();
27
28 void initialize_zones();
29
30 PhysicalAddress lower() const { return m_lower; }
31 PhysicalAddress upper() const { return m_upper; }
32 size_t size() const { return m_pages; }
33 bool contains(PhysicalAddress paddr) const { return paddr >= m_lower && paddr < m_upper; }
34
35 OwnPtr<PhysicalRegion> try_take_pages_from_beginning(size_t);
36
37 RefPtr<PhysicalPage> take_free_page();
38 Vector<NonnullRefPtr<PhysicalPage>> take_contiguous_free_pages(size_t count);
39 void return_page(PhysicalAddress);
40
41private:
42 PhysicalRegion(PhysicalAddress lower, PhysicalAddress upper);
43
44 static constexpr size_t large_zone_size = 16 * MiB;
45 static constexpr size_t small_zone_size = 1 * MiB;
46
47 Vector<NonnullOwnPtr<PhysicalZone>> m_zones;
48
49 size_t m_large_zones { 0 };
50
51 PhysicalZone::List m_usable_zones;
52 PhysicalZone::List m_full_zones;
53
54 PhysicalAddress m_lower;
55 PhysicalAddress m_upper;
56 size_t m_pages { 0 };
57};
58
59}