aboutsummaryrefslogtreecommitdiff
path: root/kapi/include/kapi/memory.hpp
blob: ae33904c2bbfc359f5bf5c57d2de4f77ddf3a706 (plain)
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
#ifndef TEACHOS_KAPI_MEMORY_HPP
#define TEACHOS_KAPI_MEMORY_HPP

#include "kapi/memory/address.hpp"          // IWYU pragma: export
#include "kapi/memory/chunk.hpp"            // IWYU pragma: export
#include "kapi/memory/frame.hpp"            // IWYU pragma: export
#include "kapi/memory/frame_allocator.hpp"  // IWYU pragma: export
#include "kapi/memory/layout.hpp"           // IWYU pragma: export
#include "kapi/memory/page.hpp"             // IWYU pragma: export
#include "kapi/memory/page_mapper.hpp"      // IWYU pragma: export

#include <cstddef>
#include <optional>
#include <utility>

namespace kapi::memory
{

  //! @addtogroup kapi-memory-kernel-defined
  //! @{

  //! Initialize the physical memory manager.
  //!
  //! This function initializes the kernel-wide physical memory manager. The function will invoke the handoff handler to
  //! transfer the platform-specific frame allocation state to the physical memory manager.
  //!
  //! @note Once this function returns, the global allocator has been replaced by the platform-agnostic, kernel-defined
  //! allocator. Any state of the platform specific allocator may be released.
  //!
  //! @param frame_count The number of frames present in the system.
  //! @param handoff_handler A function to be invoked to transfer the platform-specific frame allocation state. The
  //! allocator to hand off to is passed to the handler.
  auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void;

  //! Get the currently active frame allocator.
  auto get_frame_allocator() -> frame_allocator &;

  //! Set the currently active frame allocator.
  //!
  //! @param allocator A new frame allocator.
  //! @return The previously active frame allocator.
  auto set_frame_allocator(frame_allocator & allocator) -> std::optional<frame_allocator *>;

  //! Set the currently active page mapper.
  //!
  //! @param mapper A new page mapper.
  //! @return The previously active page mapper.
  auto set_page_mapper(page_mapper & mapper) -> std::optional<page_mapper *>;

  //! Allocate a new frame of physical memory
  //!
  //! @warning This function will panic if no frame allocator has been registered.
  //!
  //! @return An engaged std::optional iff. a frame could be allocated, std::nullopt otherwise.
  auto allocate_frame() -> std::optional<frame>;

  //! Allocate multiple new frames of physical memory
  //!
  //! @warning This function will panic if no frame allocator has been registered.
  //!
  //! @return An engaged std::optional iff. @p count frames could be allocated, std::nullopt otherwise.
  auto allocate_many_frames(std::size_t count) -> std::optional<std::pair<frame, std::size_t>>;

  //! Map a page onto a frame.
  //!
  //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped.
  //! This function will not ensure that the frame is not already in use.
  //!
  //! @param page The page to map.
  //! @param frame The frame to map the page into.
  //! @param flags The flags to apply to this mapping.
  //! @return A pointer to the first byte of the mapped page.
  auto map(page page, frame frame, page_mapper::flags flags = page_mapper::flags::empty) -> std::byte *;

  //! Unmap a page.
  //!
  //! @warning This function will panic if no page mapper has been registered, or the page is not mapped.
  //!
  //! @param page The page to unmap
  auto unmap(page page) -> void;

  //! Initialize the Memory-mapped I/O region system.
  //!
  //! @param base The base address for the MMIO region.
  //! @param page_count The number of pages the MMIO region is spans.
  auto init_mmio(linear_address base, std::size_t page_count) -> void;

  //! Allocate a Memory-mapped I/O region of the given size.
  //!
  //! @warning This function will panic if the MMIO system has not been initialized!
  //! @param page_count The number of pages to allocate.
  auto allocate_mmio_region(std::size_t page_count) -> linear_address;

  //! Map a region of Memory-mapped I/O address space to a given hardware address using the given flags.
  //!
  //! @warning This function will panic if no page mapper has been registered, or the page has already been mapped.
  //! This function will not ensure that the frame is not already in use.
  //!
  //! This function will always set the @p uncached flag.
  //!
  //! @param base The base of the virtual region.
  //! @param hw_base The base of the hardware region.
  //! @param flags The flags to apply.
  auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *;

  //! Release a Memory-mapped I/O region.
  //!
  //! @warning This function will panic if the MMIO system has not been initialized!
  //! @param base The start address of the region to release.
  auto release_mmio_region(linear_address base) -> void;

  //! @}

  //! @addtogroup kapi-memory-platform-defined
  //! @{

  //! Initialize the memory subsystem.
  //!
  //! @note This function must be implemented by the target platform.
  //!
  //! This function initializes the memory subsystem and activates the platform-specific frame allocator and page
  //! mapper. When this function returns, a valid frame allocator and page mapper are expected to have been registered.
  auto init() -> void;

  //! @}

}  // namespace kapi::memory

#endif