3 // Physical memory manager
5 #include <lunaix/boot_generic.h>
6 #include <lunaix/mm/physical.h>
7 #include <lunaix/types.h>
8 #include <lunaix/spike.h>
15 typedef unsigned int ppage_type_t;
17 // Maximum non-huge page order.
18 #define MAX_PAGE_ORDERS ( LEVEL_SHIFT - 1 )
20 #define RESERVE_MARKER 0xf0f0f0f0
25 struct ppage* pool_start;
26 struct ppage* pool_end;
28 #if defined(CONFIG_PMALLOC_NCONTIG)
30 struct llist_header idle_page;
31 struct llist_header busy_page;
33 #elif defined(CONFIG_PMALLOC_BUDDY)
35 struct llist_header idle_order[MAX_PAGE_ORDERS];
37 #elif defined(CONFIG_PMALLOC_SIMPLE)
39 struct llist_header idle_order[MAX_PAGE_ORDERS];
40 int count[MAX_PAGE_ORDERS];
47 struct pmem_pool pool[POOL_COUNT];
51 struct llist_header reserved;
54 static inline struct ppage*
57 return (struct ppage*)(PPLIST_STARTVM) + pfn;
60 static inline struct ppage*
61 leading_page(struct ppage* page) {
62 return page - page->companion;
65 static inline struct ppage*
66 ppage_of(struct pmem_pool* pool, pfn_t pfn)
68 return pool->pool_start + pfn;
72 ppfn(struct ppage* page)
74 return (pfn_t)((ptr_t)page - PPLIST_STARTVM) / sizeof(struct ppage);
78 ppfn_of(struct pmem_pool* pool, struct ppage* page)
80 return (pfn_t)((ptr_t)page - (ptr_t)pool->pool_start) / sizeof(struct ppage);
84 ppage_addr(struct ppage* page) {
85 return ppfn(page) * PAGE_SIZE;
88 static inline unsigned int
89 count_order(size_t page_count) {
90 unsigned int po = ILOG2(page_count);
91 assert(!(page_count % (1 << po)));
95 static inline unsigned int
96 ppage_order(struct ppage* page) {
102 reserved_page(struct ppage* page)
104 return page->refs == RESERVE_MARKER && page->type == PP_RESERVED;
111 * @param mem_upper_lim 最大可用内存地址
114 pmm_init(struct boot_handoff* bctx);
117 pmm_arch_init_remap(struct pmem* memory, struct boot_handoff* bctx);
120 pmm_pool_get(int pool_index);
123 pmm_arch_init_pool(struct pmem* memory);
126 pmm_onhold_range(pfn_t start, size_t npages);
129 pmm_unhold_range(pfn_t start, size_t npages);
133 pmm_declare_pool(int pool, pfn_t start, pfn_t size);
135 // ---- allocator specific ----
138 pmm_free_one(struct ppage* page, int type_mask);
141 pmm_alloc_napot_type(int pool, size_t order, ppage_type_t type);
145 static inline struct ppage*
146 pmm_alloc_normal(size_t order)
148 return pmm_alloc_napot_type(POOL_UNIFIED, order, 0);
151 static inline struct ppage*
152 pmm_alloc_locked(size_t order)
154 return pmm_alloc_napot_type(POOL_UNIFIED, order, PP_FGLOCKED);
158 change_page_type(struct ppage* page, ppage_type_t type)
163 static inline struct pmem_pool*
164 pmm_pool_lookup(struct ppage* page)
166 return pmm_pool_get(page->pool);
170 #endif /* __LUNAIX_PMM_H */