diff options
author | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
---|---|---|
committer | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
commit | c63f340d90800895f007de64b7d2d14624263331 (patch) | |
tree | 2c0849fa597dd6da831c8707b6f2603403778d7b /kernel/include/mm/page.h |
Created student weenix repository
Diffstat (limited to 'kernel/include/mm/page.h')
-rw-r--r-- | kernel/include/mm/page.h | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/kernel/include/mm/page.h b/kernel/include/mm/page.h new file mode 100644 index 0000000..5230a85 --- /dev/null +++ b/kernel/include/mm/page.h @@ -0,0 +1,124 @@ +#pragma once + +#ifdef __KERNEL__ +#include "types.h" +#else +#include "sys/types.h" +#endif + +/* This header file contains the functions for allocating + * and freeing page-aligned chunks of data which are a + * multiple of a page in size. These are the lowest level + * memory allocation functions. In general code should + * use the slab allocator functions in mm/slab.h unless + * they require page-aligned buffers. */ + +#define PAGE_SHIFT 12 +#define PAGE_SIZE ((uintptr_t)(1UL << PAGE_SHIFT)) +#define PAGE_MASK (0xffffffffffffffff << PAGE_SHIFT) + +#define PAGE_ALIGN_DOWN(x) ((void *)(((uintptr_t)(x)&PAGE_MASK))) +#define PAGE_ALIGN_UP(x) \ + ((void *)((((uintptr_t)(x) + (PAGE_SIZE - 1)) & PAGE_MASK))) + +#define PAGE_OFFSET(x) (((uintptr_t)(x)) & ~PAGE_MASK) +#define PAGE_ALIGNED(x) (!PAGE_OFFSET(x)) + +#define PN_TO_ADDR(x) ((void *)(((uintptr_t)(x)) << PAGE_SHIFT)) +#define ADDR_TO_PN(x) (((uintptr_t)(x)) >> PAGE_SHIFT) + +#define PAGE_SAME(x, y) (PAGE_ALIGN_DOWN(x) == PAGE_ALIGN_DOWN(y)) + +#define PAGE_NSIZES 8 + +#define USE_2MB_PAGES 1 +#define USE_1GB_PAGES 1 + +#define PAGE_SHIFT_2MB 21 +#define PAGE_SIZE_2MB ((uintptr_t)(1UL << PAGE_SHIFT_2MB)) +#define PAGE_MASK_2MB (0xffffffffffffffff << PAGE_SHIFT_2MB) +#define PAGE_ALIGN_DOWN_2MB(x) (((uintptr_t)(x)) & PAGE_MASK_2MB) +#define PAGE_ALIGN_UP_2MB(x) (PAGE_ALIGN_DOWN_2MB((x)-1) + PAGE_SIZE_2MB) +#define PAGE_OFFSET_2MB(x) (((uintptr_t)(x)) & ~PAGE_MASK_2MB) +#define PAGE_ALIGNED_2MB(x) ((x) == PAGE_ALIGN_DOWN_2MB(x)) +#define PAGE_SAME_2MB(x, y) (PAGE_ALIGN_DOWN_2MB(x) == PAGE_ALIGN_DOWN_2MB(y)) + +#define PAGE_SHIFT_1GB 30 +#define PAGE_MASK_1GB (0xffffffffffffffff << PAGE_SHIFT_1GB) +#define PAGE_SIZE_1GB ((uintptr_t)(1UL << PAGE_SHIFT_1GB)) +#define PAGE_ALIGN_DOWN_1GB(x) (((uintptr_t)(x)) & PAGE_MASK_1GB) +#define PAGE_ALIGN_UP_1GB(x) (PAGE_ALIGN_DOWN_1GB((x)-1) + PAGE_SIZE_1GB) +#define PAGE_OFFSET_1GB(x) (((uintptr_t)(x)) & ~PAGE_MASK_1GB) +#define PAGE_ALIGNED_1GB(x) ((x) == PAGE_ALIGN_DOWN_1GB(x)) +#define PAGE_SAME_1GB(x, y) (PAGE_ALIGN_DOWN_1GB(x) == PAGE_ALIGN_DOWN_1GB(y)) + +#define PAGE_SHIFT_512GB 39 +#define PAGE_SIZE_512GB ((uintptr_t)(1UL << PAGE_SHIFT_512GB)) +#define PAGE_MASK_512GB (0xffffffffffffffff << PAGE_SHIFT_512GB) +#define PAGE_ALIGN_DOWN_512GB(x) (((uintptr_t)(x)) & PAGE_MASK_512GB) +#define PAGE_ALIGN_UP_512GB(x) (PAGE_ALIGN_DOWN_512GB((x)-1) + PAGE_SIZE_512GB) + +#define PAGE_CONTROL_FLAGS(x) \ + ((x) & (PT_PRESENT | PT_WRITE | PT_USER | PT_WRITE_THROUGH | \ + PT_CACHE_DISABLED | PT_SIZE | PT_GLOBAL)) +#define PAGE_FLAGS(x) ((x) & (~PAGE_MASK)) + +typedef enum page_size +{ + ps_4kb, + ps_2mb, + ps_1gb, + ps_512gb, +} page_size_t; + +typedef struct page_status +{ + page_size_t size; + int mapped; +} page_status_t; + +/* Performs all initialization necessary for the + * page allocation system. This should be called + * only once at boot time before any other functions + * in this header are called. */ +void page_init(); + +void *physmap_start(); + +void *physmap_end(); + +/* These functions allocate and free one page-aligned, + * page-sized block of memory. Values passed to + * page_free MUST have been returned by page_alloc + * at some previous point. There should be only one + * call to page_free for each value returned by + * page_alloc. If the system is out of memory page_alloc + * will return NULL. */ +void *page_alloc(void); + +void *page_alloc_bounded(void *max_paddr); + +void page_free(void *addr); + +/* These functions allocate and free a page-aligned + * block of memory which are npages pages in length. + * A call to page_alloc_n will allocate a block, to free + * that block a call should be made to page_free_n with + * npages set to the same as it was when the block was + * allocated */ +void *page_alloc_n(size_t npages); + +void *page_alloc_n_bounded(size_t npages, void *max_paddr); + +void page_free_n(void *start, size_t npages); + +void page_add_range(void *start, void *end); + +void page_mark_reserved(void *paddr); + +void page_init_finish(); + +/* Returns the number of free pages remaining in the + * system. Note that calls to page_alloc_n(npages) may + * fail even if page_free_count() >= npages. */ +size_t page_free_count(); |