1 /* 2 * Copyright (C) 2018-2024 Intel Corporation. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef PAGE_H 8 #define PAGE_H 9 10 #include <asm/lib/spinlock.h> 11 #include <board_info.h> 12 13 /** 14 * @defgroup hwmgmt_page hwmgmt.page 15 * @ingroup hwmgmt 16 * @brief Support the basic paging mechanism. 17 * 18 * This module mainly provides the interfaces to manipulate the paging structures. 19 * These operations are commonly used by: 20 * 1. hypervisor's MMU (Memory Management Unit) to manage the host page tables; 21 * 2. EPT to manage the extended page tables for guest. 22 * It also provides the interfaces to conduct the address translation between Host Physical Address and Host Virtual 23 * Address. 24 * 25 * @{ 26 */ 27 28 /** 29 * @file 30 * @brief All APIs to support page management. 31 * 32 * This file defines macros, structures and function declarations for managing memory pages. 33 */ 34 35 #define PAGE_SHIFT 12U 36 #define PAGE_SIZE (1U << PAGE_SHIFT) 37 #define PAGE_MASK 0xFFFFFFFFFFFFF000UL 38 39 #define MAX_PHY_ADDRESS_SPACE (1UL << MAXIMUM_PA_WIDTH) 40 41 /* size of the low MMIO address space: 2GB */ 42 #define PLATFORM_LO_MMIO_SIZE 0x80000000UL 43 44 /* size of the high MMIO address space: 1GB */ 45 #define PLATFORM_HI_MMIO_SIZE 0x40000000UL 46 47 /** 48 * @brief Calculate the number of page map level-4(PML4) that is requested to control the memory region with the 49 * specified size. 50 * 51 * Page map level-4(PML4) table is the top-level table in the x86-64 paging hierarchy. Each entry in the PML4 table can 52 * potentially map a 512 GiB region, with the entire PML4 table capable of addressing up to 256 TiB. So 1 PML4 table is 53 * enough to control the entire physical address space. 54 */ 55 #define PML4_PAGE_NUM(size) 1UL 56 /** 57 * @brief Calculate the number of page directory pointer tables(PDPT) that is requested to control the memory region 58 * with the specified size. 59 * 60 * A page directory pointer table(PDPT) can be referenced by a PML4E and each PML4E controls access to a 512-GByte 61 * region. It is supposed to be called when hypervisor allocates the page-directory-pointer tables for hypervisor and 62 * all VMs. 63 */ 64 #define PDPT_PAGE_NUM(size) (((size) + PML4E_SIZE - 1UL) >> PML4E_SHIFT) 65 /** 66 * @brief Calculate the number of page directories(PD) that is requested to control the memory region with the specified 67 * size. 68 * 69 * A page directory(PD) can be referenced by a PDPTE and each PDPTE controls access to a 1-GByte region. It is supposed 70 * to be called when hypervisor allocates the page directories for hypervisor and all VMs. 71 */ 72 #define PD_PAGE_NUM(size) (((size) + PDPTE_SIZE - 1UL) >> PDPTE_SHIFT) 73 /** 74 * @brief Calculate the number of page tables(PT) that is requested to control the memory region with the specified 75 * size. 76 * 77 * A page table(PT) can be referenced by a PDE and each PDE controls access to a 2-MByte region. It is supposed to be 78 * called when hypervisor allocates the page tables for hypervisor and all VMs. 79 */ 80 #define PT_PAGE_NUM(size) (((size) + PDE_SIZE - 1UL) >> PDE_SHIFT) 81 82 /** 83 * @brief Data structure to illustrate a 4-KByte memory region with an alignment of 4-KByte. 84 * 85 * This data structure is used to illustrate a 4-KByte memory region with an alignment of 4-KByte, calling it a 4-KByte 86 * page. It can be used to support the memory management in hypervisor and the extended page-table mechanism for VMs. It 87 * can also be used when hypervisor accesses the 4-KByte aligned memory region whose size is a multiple of 4-KByte. 88 * 89 * @consistency N/A 90 * @alignment 4096 91 * 92 * @remark N/A 93 */ 94 struct page { 95 uint8_t contents[PAGE_SIZE]; /**< A 4-KByte page in the memory. */ 96 } __aligned(PAGE_SIZE); 97 98 /** 99 * @brief Data structure that contains a pool of memory pages. 100 * 101 * This structure is designed to manage a collection of memory pages, facilitating efficient allocation, 102 * deallocation, and reuse of pages. It is typically used in scenarios where memory allocation performance 103 * is critical, such as in operating systems or high-performance applications. The page pool aims to minimize 104 * the overhead associated with frequent memory page allocations by maintaining a ready-to-use pool of pages. 105 * It is used to support the memory management in hypervisor and the extended page-table mechanism for VMs. 106 * 107 * @consistency N/A 108 * @alignment N/A 109 * 110 * @remark N/A 111 */ 112 struct page_pool { 113 struct page *start_page; /**< The first page in the pool. */ 114 spinlock_t lock; /**< The spinlock to protect simultaneous access of the page pool. */ 115 /** 116 * @brief A pointer to the bitmap that represents the allocation status of each page in the pool. 117 * 118 * The bitmap is a data structure that represents the allocation status of each page in the pool. Each bit in 119 * the bitmap corresponds to a page in the pool. If the bit is set to 1, the page is allocated; otherwise, the 120 * page is free. The bitmap is used to track the allocation status of each page in the pool. 121 */ 122 uint64_t *bitmap; 123 uint64_t bitmap_size; /**< The number of bitmap. */ 124 uint64_t last_hint_id; /**< The last bitmap ID that is used to allocate a page. */ 125 /** 126 * @brief A pointer to the dummy page 127 * 128 * This is used when there's no page available in the pool. 129 */ 130 struct page *dummy_page; 131 }; 132 133 struct page *alloc_page(struct page_pool *pool); 134 void free_page(struct page_pool *pool, struct page *page); 135 #endif /* PAGE_H */ 136 137 /** 138 * @} 139 */