acrn-hypervisor/hypervisor/include/arch/x86/asm/page.h
Haiwei Li fa2b8fcfbe doc: add module design for some defines in hwmgmt_page
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

ACRN hypervisor is decomposed into a series of components and modules. The
module design in hypervisor is to add inline doxygen style comments above
functions, macros, structures, etc.

This patch is to add comments for some elements in hwmgmt_page module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-08-01 14:50:27 +08:00

139 lines
5.3 KiB
C

/*
* Copyright (C) 2018-2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PAGE_H
#define PAGE_H
#include <asm/lib/spinlock.h>
#include <board_info.h>
/**
* @defgroup hwmgmt_page hwmgmt.page
* @ingroup hwmgmt
* @brief Support the basic paging mechanism.
*
* This module mainly provides the interfaces to manipulate the paging structures.
* These operations are commonly used by:
* 1. hypervisor's MMU (Memory Management Unit) to manage the host page tables;
* 2. EPT to manage the extended page tables for guest.
* It also provides the interfaces to conduct the address translation between Host Physical Address and Host Virtual
* Address.
*
* @{
*/
/**
* @file
* @brief All APIs to support page management.
*
* This file defines macros, structures and function declarations for managing memory pages.
*/
#define PAGE_SHIFT 12U
#define PAGE_SIZE (1U << PAGE_SHIFT)
#define PAGE_MASK 0xFFFFFFFFFFFFF000UL
#define MAX_PHY_ADDRESS_SPACE (1UL << MAXIMUM_PA_WIDTH)
/* size of the low MMIO address space: 2GB */
#define PLATFORM_LO_MMIO_SIZE 0x80000000UL
/* size of the high MMIO address space: 1GB */
#define PLATFORM_HI_MMIO_SIZE 0x40000000UL
/**
* @brief Calculate the number of page map level-4(PML4) that is requested to control the memory region with the
* specified size.
*
* Page map level-4(PML4) table is the top-level table in the x86-64 paging hierarchy. Each entry in the PML4 table can
* potentially map a 512 GiB region, with the entire PML4 table capable of addressing up to 256 TiB. So 1 PML4 table is
* enough to control the entire physical address space.
*/
#define PML4_PAGE_NUM(size) 1UL
/**
* @brief Calculate the number of page directory pointer tables(PDPT) that is requested to control the memory region
* with the specified size.
*
* A page directory pointer table(PDPT) can be referenced by a PML4E and each PML4E controls access to a 512-GByte
* region. It is supposed to be called when hypervisor allocates the page-directory-pointer tables for hypervisor and
* all VMs.
*/
#define PDPT_PAGE_NUM(size) (((size) + PML4E_SIZE - 1UL) >> PML4E_SHIFT)
/**
* @brief Calculate the number of page directories(PD) that is requested to control the memory region with the specified
* size.
*
* A page directory(PD) can be referenced by a PDPTE and each PDPTE controls access to a 1-GByte region. It is supposed
* to be called when hypervisor allocates the page directories for hypervisor and all VMs.
*/
#define PD_PAGE_NUM(size) (((size) + PDPTE_SIZE - 1UL) >> PDPTE_SHIFT)
/**
* @brief Calculate the number of page tables(PT) that is requested to control the memory region with the specified
* size.
*
* 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
* called when hypervisor allocates the page tables for hypervisor and all VMs.
*/
#define PT_PAGE_NUM(size) (((size) + PDE_SIZE - 1UL) >> PDE_SHIFT)
/**
* @brief Data structure to illustrate a 4-KByte memory region with an alignment of 4-KByte.
*
* This data structure is used to illustrate a 4-KByte memory region with an alignment of 4-KByte, calling it a 4-KByte
* page. It can be used to support the memory management in hypervisor and the extended page-table mechanism for VMs. It
* can also be used when hypervisor accesses the 4-KByte aligned memory region whose size is a multiple of 4-KByte.
*
* @consistency N/A
* @alignment 4096
*
* @remark N/A
*/
struct page {
uint8_t contents[PAGE_SIZE]; /**< A 4-KByte page in the memory. */
} __aligned(PAGE_SIZE);
/**
* @brief Data structure that contains a pool of memory pages.
*
* This structure is designed to manage a collection of memory pages, facilitating efficient allocation,
* deallocation, and reuse of pages. It is typically used in scenarios where memory allocation performance
* is critical, such as in operating systems or high-performance applications. The page pool aims to minimize
* the overhead associated with frequent memory page allocations by maintaining a ready-to-use pool of pages.
* It is used to support the memory management in hypervisor and the extended page-table mechanism for VMs.
*
* @consistency N/A
* @alignment N/A
*
* @remark N/A
*/
struct page_pool {
struct page *start_page; /**< The first page in the pool. */
spinlock_t lock; /**< The spinlock to protect simultaneous access of the page pool. */
/**
* @brief A pointer to the bitmap that represents the allocation status of each page in the pool.
*
* The bitmap is a data structure that represents the allocation status of each page in the pool. Each bit in
* the bitmap corresponds to a page in the pool. If the bit is set to 1, the page is allocated; otherwise, the
* page is free. The bitmap is used to track the allocation status of each page in the pool.
*/
uint64_t *bitmap;
uint64_t bitmap_size; /**< The number of bitmap. */
uint64_t last_hint_id; /**< The last bitmap ID that is used to allocate a page. */
/**
* @brief A pointer to the dummy page
*
* This is used when there's no page available in the pool.
*/
struct page *dummy_page;
};
struct page *alloc_page(struct page_pool *pool);
void free_page(struct page_pool *pool, struct page *page);
#endif /* PAGE_H */
/**
* @}
*/