X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/cd09c4b222e4ddf45a42522563ae2471a829d1c8..d1b1c8d9119229dbeed06cd252917e54a1cb77f6:/lunaix-os/includes/lunaix/mm/pmm.h diff --git a/lunaix-os/includes/lunaix/mm/pmm.h b/lunaix-os/includes/lunaix/mm/pmm.h index 36396df..60a5c68 100644 --- a/lunaix-os/includes/lunaix/mm/pmm.h +++ b/lunaix-os/includes/lunaix/mm/pmm.h @@ -2,64 +2,169 @@ #define __LUNAIX_PMM_H // Physical memory manager -#include -#include +#include +#include +#include +#include -#define PM_PAGE_SIZE 4096 -#define PM_BMP_MAX_SIZE (128 * 1024) +enum { + POOL_UNIFIED, + POOL_COUNT +}; -/** - * @brief 标注物理页为可使用 - * - * @param ppn page number - */ -void pmm_mark_page_free(uintptr_t ppn); +typedef unsigned int ppage_type_t; -/** - * @brief 标注物理页为已占用 - * - * @param ppn - */ -void pmm_mark_page_occupied(uintptr_t ppn); +// Maximum non-huge page order. +#define MAX_PAGE_ORDERS ( LEVEL_SHIFT - 1 ) -/** - * @brief 标注多个连续的物理页为可用 - * - * @param start_ppn 起始PPN - * @param page_count 数量 - */ -void pmm_mark_chunk_free(uintptr_t start_ppn, size_t page_count); +#define RESERVE_MARKER 0xf0f0f0f0 -/** - * @brief 标注多个连续的物理页为已占用 - * - * @param start_ppn 起始PPN - * @param page_count 数量 - */ -void pmm_mark_chunk_occupied(uintptr_t start_ppn, size_t page_count); +struct pmem_pool +{ + int type; + struct ppage* pool_start; + struct ppage* pool_end; + +#if defined(CONFIG_PMALLOC_NCONTIG) + + struct llist_header idle_page; + struct llist_header busy_page; + +#elif defined(CONFIG_PMALLOC_BUDDY) + + struct llist_header idle_order[MAX_PAGE_ORDERS]; + +#elif defined(CONFIG_PMALLOC_SIMPLE) + + struct llist_header idle_order[MAX_PAGE_ORDERS]; + int count[MAX_PAGE_ORDERS]; + +#endif +}; + +struct pmem +{ + struct pmem_pool pool[POOL_COUNT]; + + pfn_t list_len; + struct ppage* pplist; + struct llist_header reserved; +}; + +static inline struct ppage* +ppage(pfn_t pfn) +{ + return (struct ppage*)(PPLIST_STARTVM) + pfn; +} + +static inline struct ppage* +leading_page(struct ppage* page) { + return page - page->companion; +} + +static inline struct ppage* +ppage_of(struct pmem_pool* pool, pfn_t pfn) +{ + return pool->pool_start + pfn; +} + +static inline pfn_t +ppfn(struct ppage* page) +{ + return (pfn_t)((ptr_t)page - PPLIST_STARTVM) / sizeof(struct ppage); +} + +static inline pfn_t +ppfn_of(struct pmem_pool* pool, struct ppage* page) +{ + return (pfn_t)((ptr_t)page - (ptr_t)pool->pool_start) / sizeof(struct ppage); +} + +static inline ptr_t +ppage_addr(struct ppage* page) { + return ppfn(page) * PAGE_SIZE; +} + +static inline unsigned int +count_order(size_t page_count) { + unsigned int po = ILOG2(page_count); + assert(!(page_count % (1 << po))); + return po; +} + +static inline unsigned int +ppage_order(struct ppage* page) { + return page->order; +} + + +static inline bool +reserved_page(struct ppage* page) +{ + return page->refs == RESERVE_MARKER && page->type == PP_RESERVED; +} -/** - * @brief 分配一个可用的物理页 - * - * @return void* 可用的页地址,否则为 NULL - */ -void* pmm_alloc_page(); /** * @brief 初始化物理内存管理器 - * + * * @param mem_upper_lim 最大可用内存地址 */ -void pmm_init(uintptr_t mem_upper_lim); +void +pmm_init(struct boot_handoff* bctx); +ptr_t +pmm_arch_init_remap(struct pmem* memory, struct boot_handoff* bctx); -/** - * @brief 释放一个已分配的物理页,假若页地址不存在,则无操作。 - * - * @param page 页地址 - * @return 是否成功 - */ -int pmm_free_page(void* page); +struct pmem_pool* +pmm_pool_get(int pool_index); + +void +pmm_arch_init_pool(struct pmem* memory); + +bool +pmm_onhold_range(pfn_t start, size_t npages); + +bool +pmm_unhold_range(pfn_t start, size_t npages); + + +struct pmem_pool* +pmm_declare_pool(int pool, pfn_t start, pfn_t size); + +// ---- allocator specific ---- + +void +pmm_free_one(struct ppage* page, int type_mask); + +struct ppage* +pmm_alloc_napot_type(int pool, size_t order, ppage_type_t type); + +// ---- + +static inline struct ppage* +pmm_alloc_normal(size_t order) +{ + return pmm_alloc_napot_type(POOL_UNIFIED, order, 0); +} + +static inline struct ppage* +pmm_alloc_locked(size_t order) +{ + return pmm_alloc_napot_type(POOL_UNIFIED, order, PP_FGLOCKED); +} + +static inline void +change_page_type(struct ppage* page, ppage_type_t type) +{ + page->type = type; +} + +static inline struct pmem_pool* +pmm_pool_lookup(struct ppage* page) +{ + return pmm_pool_get(page->pool); +} #endif /* __LUNAIX_PMM_H */