1 /* 2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU) 3 * Licensed under the Mulan PSL v2. 4 * You can use this software according to the terms and conditions of the Mulan PSL v2. 5 * You may obtain a copy of Mulan PSL v2 at: 6 * http://license.coscl.org.cn/MulanPSL2 7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9 * PURPOSE. 10 * See the Mulan PSL v2 for more details. 11 */ 12 #ifndef MM_BUDDY_H 13 #define MM_BUDDY_H 14 15 #include <common/types.h> 16 #include <common/list.h> 17 #include <common/lock.h> 18 19 #define N_PHYS_MEM_POOLS 8 20 21 /* The following two are defined in mm.c and filled by mmparse.c. */ 22 extern paddr_t physmem_map[N_PHYS_MEM_POOLS][2]; 23 extern int physmem_map_num; 24 25 /* All the following symbols are only used locally in the mm module. */ 26 27 /* `struct page` is the metadata of one physical 4k page. */ 28 struct page { 29 /* Free list */ 30 struct list_head node; 31 /* Whether the correspond physical page is free now. */ 32 int allocated; 33 /* The order of the memory chunck that this page belongs to. */ 34 int order; 35 /* Used for ChCore slab allocator. */ 36 void *slab; 37 /* The physical memory pool this page belongs to */ 38 struct phys_mem_pool *pool; 39 }; 40 41 struct free_list { 42 struct list_head free_list; 43 unsigned long nr_free; 44 }; 45 46 /* 47 * Supported Order: [0, BUDDY_MAX_ORDER). 48 * The max allocated size (continous physical memory size) is 49 * 2^(BUDDY_MAX_ORDER - 1) * 4K. 50 * Given BUDDY_MAX_ORDER is 14, the max allocated chunk is 32M. 51 */ 52 #define BUDDY_PAGE_SIZE (0x1000) 53 #define BUDDY_MAX_ORDER (14) 54 55 /* One page size is 4K, so the order is 12. */ 56 #define BUDDY_PAGE_SIZE_ORDER (12) 57 58 /* Each physical memory chunk can be represented by one physical memory pool. */ 59 struct phys_mem_pool { 60 /* 61 * The start virtual address (for used in kernel) of 62 * this physical memory pool. 63 */ 64 vaddr_t pool_start_addr; 65 unsigned long pool_mem_size; 66 67 /* 68 * The start virtual address (for used in kernel) of 69 * the metadata area of this pool. 70 */ 71 struct page *page_metadata; 72 73 /* One lock for one pool. */ 74 struct lock buddy_lock; 75 76 /* The free list of different free-memory-chunk orders. */ 77 struct free_list free_lists[BUDDY_MAX_ORDER]; 78 79 /* 80 * This field is only used in ChCore unit test. 81 * The number of (4k) physical pages in this physical memory pool. 82 */ 83 unsigned long pool_phys_page_num; 84 }; 85 86 /* Disjoint physical memory can be represented by several phys_mem_pools. */ 87 extern struct phys_mem_pool global_mem[N_PHYS_MEM_POOLS]; 88 89 /* All interfaces are kernel/mm module internal interfaces. */ 90 91 void init_buddy(struct phys_mem_pool *, struct page *start_page, 92 vaddr_t start_addr, unsigned long page_num); 93 94 struct page *buddy_get_pages(struct phys_mem_pool *, int order); 95 void buddy_free_pages(struct phys_mem_pool *, struct page *page); 96 97 void *page_to_virt(struct page *page); 98 struct page *virt_to_page(void *ptr); 99 unsigned long get_free_mem_size_from_buddy(struct phys_mem_pool *); 100 101 #endif /* MM_BUDDY_H */