make rule for user header file install
[lunaix-os.git] / lunaix-os / includes / lunaix / mm / pmm.h
1 #ifndef __LUNAIX_PMM_H
2 #define __LUNAIX_PMM_H
3 // Physical memory manager
4
5 #include <lunaix/boot_generic.h>
6 #include <lunaix/mm/physical.h>
7 #include <lunaix/types.h>
8 #include <lunaix/spike.h>
9
10 enum {
11     POOL_UNIFIED,
12     POOL_COUNT
13 };
14
15 typedef unsigned int ppage_type_t;
16
17 // Maximum non-huge page order.
18 #define MAX_PAGE_ORDERS ( LEVEL_SHIFT - 1 )
19
20 #define RESERVE_MARKER 0xf0f0f0f0
21
22 struct pmem_pool
23 {
24     int type;
25     struct ppage* pool_start;
26     struct ppage* pool_end;
27     
28 #if defined(CONFIG_PMALLOC_METHOD_NCONTIG)
29
30     struct llist_header idle_page;
31     struct llist_header busy_page;
32     
33 #elif defined(CONFIG_PMALLOC_METHOD_BUDDY)
34
35     struct llist_header idle_order[MAX_PAGE_ORDERS];
36     
37 #elif defined(CONFIG_PMALLOC_METHOD_SIMPLE)
38
39     struct llist_header idle_order[MAX_PAGE_ORDERS];
40     int count[MAX_PAGE_ORDERS];
41
42 #endif
43 };
44
45 struct pmem
46 {
47     struct pmem_pool pool[POOL_COUNT];
48
49     pfn_t list_len;
50     struct ppage* pplist;
51     struct llist_header reserved;
52 };
53
54 static inline struct ppage*
55 ppage(pfn_t pfn) 
56 {
57     return (struct ppage*)(PPLIST_STARTVM) + pfn;
58 }
59
60 static inline struct ppage*
61 leading_page(struct ppage* page) {
62     return page - page->companion;
63 }
64
65 static inline struct ppage*
66 ppage_of(struct pmem_pool* pool, pfn_t pfn) 
67 {
68     return pool->pool_start + pfn;
69 }
70
71 static inline pfn_t
72 ppfn(struct ppage* page) 
73 {
74     return (pfn_t)((ptr_t)page - PPLIST_STARTVM) / sizeof(struct ppage);
75 }
76
77 static inline pfn_t
78 ppfn_of(struct pmem_pool* pool, struct ppage* page) 
79 {
80     return (pfn_t)((ptr_t)page - (ptr_t)pool->pool_start) / sizeof(struct ppage);
81 }
82
83 static inline ptr_t
84 ppage_addr(struct ppage* page) {
85     return ppfn(page) * PAGE_SIZE;
86 }
87
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)));
92     return po;
93 }
94
95 static inline unsigned int
96 ppage_order(struct ppage* page) {
97     return page->order;
98 }
99
100
101 static inline bool
102 reserved_page(struct ppage* page)
103 {
104     return page->refs == RESERVE_MARKER && page->type == PP_RESERVED;
105 }
106
107
108 /**
109  * @brief 初始化物理内存管理器
110  *
111  * @param mem_upper_lim 最大可用内存地址
112  */
113 void
114 pmm_init(struct boot_handoff* bctx);
115
116 ptr_t
117 pmm_arch_init_remap(struct pmem* memory, struct boot_handoff* bctx);
118
119 struct pmem_pool*
120 pmm_pool_get(int pool_index);
121
122 void
123 pmm_arch_init_pool(struct pmem* memory);
124
125 bool
126 pmm_onhold_range(pfn_t start, size_t npages);
127
128 bool
129 pmm_unhold_range(pfn_t start, size_t npages);
130
131
132 struct pmem_pool*
133 pmm_declare_pool(int pool, pfn_t start, pfn_t size);
134
135 // ---- allocator specific ----
136
137 void
138 pmm_free_one(struct ppage* page, int type_mask);
139
140 struct ppage*
141 pmm_alloc_napot_type(int pool, size_t order, ppage_type_t type);
142
143 // ---- 
144
145 static inline struct ppage*
146 pmm_alloc_normal(size_t order)
147 {
148     return pmm_alloc_napot_type(POOL_UNIFIED, order, 0);
149 }
150
151 static inline struct ppage*
152 pmm_alloc_locked(size_t order)
153 {
154     return pmm_alloc_napot_type(POOL_UNIFIED, order, PP_FGLOCKED);
155 }
156
157 static inline void
158 change_page_type(struct ppage* page, ppage_type_t type)
159 {
160     page->type = type;
161 }
162
163 static inline struct pmem_pool*
164 pmm_pool_lookup(struct ppage* page)
165 {
166     return pmm_pool_get(page->pool);
167 }
168
169
170 #endif /* __LUNAIX_PMM_H */