1/* @title: Physical memory manager */
2#pragma once
3#include <compiler.h>
4#include <limine.h>
5#include <mem/alloc.h>
6#include <stdbool.h>
7#include <stddef.h>
8#include <types/types.h>
9
10extern struct limine_memmap_response *memmap;
11paddr_t pmm_alloc_page_internal(enum alloc_flags flags);
12paddr_t pmm_alloc_pages_internal(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_warn_once("Input to alloc_pages matches ALLOC_FLAGS_DEFAULT, " \
30 "possible mistake"); \
31 \
32 pmm_alloc_pages_internal(count, ALLOC_FLAGS_DEFAULT); \
33 })
34
35#define pmm_alloc_pages_2(count, f) pmm_alloc_pages_internal((count), (f));
36
37#define pmm_alloc_pages(...) \
38 _DISPATCH(pmm_alloc_pages, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
39
40#define pmm_alloc_page_0() pmm_alloc_page_internal((ALLOC_FLAGS_DEFAULT))
41#define pmm_alloc_page_1(f) pmm_alloc_page_internal((f))
42
43#define pmm_alloc_page(...) \
44 _DISPATCH(pmm_alloc_page, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
45