1/* @title: Physical memory manager */
2#pragma once
3#include <compiler/core.h>
4#include <mem/alloc.h>
5#include <stdbool.h>
6#include <stddef.h>
7#include <types/types.h>
8struct limine_memmap_request;
9
10extern struct limine_memmap_response *memmap;
11paddr_t pmm_alloc_page_full(enum alloc_flags flags);
12paddr_t pmm_alloc_pages_full(size_t count, enum alloc_flags flags);
13
14void pmm_free_pages(paddr_t addr, uint64_t count);
15void pmm_free_page(paddr_t addr);
16
17void pmm_early_init(struct limine_memmap_request m);
18void pmm_mid_init(void);
19void pmm_late_init(void);
20
21uint64_t pmm_get_usable_ram(void);
22
23/* The reason we use an inline function here is to allow a check of
24 * `count` to make sure it somehow has not ended up equaling
25 * ALLOC_PARAMS_DEFAULT and warning once if this has ended up being the case */
26#define pmm_alloc_pages_1(count) \
27 ({ \
28 if ((enum alloc_flags) count == ALLOC_FLAGS_DEFAULT) \
29 log_msg_once(LOG_WARN, \
30 "Input to alloc_pages matches ALLOC_FLAGS_DEFAULT, " \
31 "possible mistake"); \
32 \
33 pmm_alloc_pages_2(count, ALLOC_FLAGS_DEFAULT); \
34 })
35
36#define pmm_alloc_pages_2(count, f) pmm_alloc_pages_full((count), (f))
37
38#define pmm_alloc_pages(...) PP_CALL(pmm_alloc_pages, __VA_ARGS__)
39
40#define pmm_alloc_page_0() pmm_alloc_page_1(ALLOC_FLAGS_DEFAULT)
41#define pmm_alloc_page_1(f) pmm_alloc_page_full((f))
42
43#define pmm_alloc_page(...) PP_CALL(pmm_alloc_page, __VA_ARGS__)
44