X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/45e1f8b055043e54be35462852ab6649d634da7c..refs/heads/feat/user_model:/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 8141113..60a5c68 100644 --- a/lunaix-os/includes/lunaix/mm/pmm.h +++ b/lunaix-os/includes/lunaix/mm/pmm.h @@ -2,89 +2,108 @@ #define __LUNAIX_PMM_H // Physical memory manager -#include -#include -#include +#include +#include +#include +#include + +enum { + POOL_UNIFIED, + POOL_COUNT +}; -#define PM_PAGE_SIZE 4096 -#define PM_BMP_MAX_SIZE (1024 * 1024) +typedef unsigned int ppage_type_t; -/** - * @brief 长久页:不会被缓存,但允许释放 - * - */ -#define PP_FGPERSIST 0x1 +// Maximum non-huge page order. +#define MAX_PAGE_ORDERS ( LEVEL_SHIFT - 1 ) -/** - * @brief 锁定页:不会被缓存,不能被释放 - * - */ -#define PP_FGLOCKED 0x2 +#define RESERVE_MARKER 0xf0f0f0f0 + +struct pmem_pool +{ + int type; + struct ppage* pool_start; + struct ppage* pool_end; + +#if defined(CONFIG_PMALLOC_NCONTIG) -typedef u32_t pp_attr_t; + struct llist_header idle_page; + struct llist_header busy_page; + +#elif defined(CONFIG_PMALLOC_BUDDY) -struct pp_struct + 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 { - pid_t owner; - u32_t ref_counts; - pp_attr_t attr; + struct pmem_pool pool[POOL_COUNT]; + + pfn_t list_len; + struct ppage* pplist; + struct llist_header reserved; }; -/** - * @brief 标注物理页为可使用 - * - * @param ppn page number - */ -void -pmm_mark_page_free(ptr_t ppn); +static inline struct ppage* +ppage(pfn_t pfn) +{ + return (struct ppage*)(PPLIST_STARTVM) + pfn; +} -/** - * @brief 标注物理页为已占用 - * - * @param ppn - */ -void -pmm_mark_page_occupied(pid_t owner, ptr_t ppn, pp_attr_t attr); +static inline struct ppage* +leading_page(struct ppage* page) { + return page - page->companion; +} -/** - * @brief 标注多个连续的物理页为可用 - * - * @param start_ppn 起始PPN - * @param page_count 数量 - */ -void -pmm_mark_chunk_free(ptr_t start_ppn, size_t page_count); +static inline struct ppage* +ppage_of(struct pmem_pool* pool, pfn_t pfn) +{ + return pool->pool_start + pfn; +} -/** - * @brief 标注多个连续的物理页为已占用 - * - * @param start_ppn 起始PPN - * @param page_count 数量 - */ -void -pmm_mark_chunk_occupied(pid_t owner, - u32_t start_ppn, - size_t page_count, - pp_attr_t attr); +static inline pfn_t +ppfn(struct ppage* page) +{ + return (pfn_t)((ptr_t)page - PPLIST_STARTVM) / sizeof(struct ppage); +} -/** - * @brief 分配一个可用的物理页 - * - * @return void* 可用的页地址,否则为 NULL - */ -ptr_t -pmm_alloc_page(pid_t owner, pp_attr_t attr); +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 分配一个连续的物理内存区域 - * - * @param owner - * @param num_pages 区域大小,单位为页 - * @param attr - * @return ptr_t - */ -ptr_t -pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr); /** * @brief 初始化物理内存管理器 @@ -92,21 +111,60 @@ pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr); * @param mem_upper_lim 最大可用内存地址 */ void -pmm_init(ptr_t mem_upper_lim); +pmm_init(struct boot_handoff* bctx); -struct pp_struct* -pmm_query(ptr_t pa); +ptr_t +pmm_arch_init_remap(struct pmem* memory, struct boot_handoff* bctx); -/** - * @brief 释放一个已分配的物理页,假若页地址不存在,则无操作。 - * - * @param page 页地址 - * @return 是否成功 - */ -int -pmm_free_page(pid_t owner, ptr_t 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); +} -int -pmm_ref_page(pid_t owner, ptr_t page); #endif /* __LUNAIX_PMM_H */