aboutsummaryrefslogtreecommitdiff
path: root/kapi/kapi/memory.hpp
blob: 8ad8d6ece6cec5b7e8822ccb7a4f84e0a264802f (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
130
131
#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
{

  using mmio_region = std::pair<linear_address, std::size_t>;

  //! @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) -> mmio_region;

  //! 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 region The region to map.
  //! @param hw_base The base of the hardware region.
  //! @param flags The flags to apply.
  auto map_mmio_region(mmio_region region, 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 region The region to release.
  auto release_mmio_region(mmio_region region) -> 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