1 /*
2 * Copyright (C) 2018-2024 Intel Corporation.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include <types.h>
7 #include <asm/lib/bits.h>
8 #include <asm/page.h>
9 #include <logmsg.h>
10
11 /**
12 * @addtogroup hwmgmt_page
13 *
14 * @{
15 */
16
17 /**
18 * @file
19 * @brief Implementation of page management.
20 *
21 * This file provides the core functionality required for allocating and freeing memory pages. It's a fundamental
22 * support to manage memory resources.
23 */
24
alloc_page(struct page_pool * pool)25 struct page *alloc_page(struct page_pool *pool)
26 {
27 struct page *page = NULL;
28 uint64_t loop_idx, idx, bit;
29
30 spinlock_obtain(&pool->lock);
31 for (loop_idx = pool->last_hint_id;
32 loop_idx < (pool->last_hint_id + pool->bitmap_size); loop_idx++) {
33 idx = loop_idx % pool->bitmap_size;
34 if (*(pool->bitmap + idx) != ~0UL) {
35 bit = ffz64(*(pool->bitmap + idx));
36 bitmap_set_nolock(bit, pool->bitmap + idx);
37 page = pool->start_page + ((idx << 6U) + bit);
38
39 pool->last_hint_id = idx;
40 break;
41 }
42 }
43 spinlock_release(&pool->lock);
44
45 ASSERT(page != NULL, "no page aviable!");
46 page = (page != NULL) ? page : pool->dummy_page;
47 if (page == NULL) {
48 /* For HV MMU page-table mapping, we didn't use dummy page when there's no page
49 * available in the page pool. This because we only do MMU page-table mapping on
50 * the early boot time and we reserve enough pages for it. After that, we would
51 * not do any MMU page-table mapping. We would let the system boot fail when page
52 * allocation failed.
53 */
54 panic("no dummy aviable!");
55 }
56 (void)memset(page, 0U, PAGE_SIZE);
57 return page;
58 }
59
60 /*
61 *@pre: ((page - pool->start_page) >> 6U) < pool->bitmap_size
62 */
free_page(struct page_pool * pool,struct page * page)63 void free_page(struct page_pool *pool, struct page *page)
64 {
65 uint64_t idx, bit;
66
67 spinlock_obtain(&pool->lock);
68 idx = (page - pool->start_page) >> 6U;
69 bit = (page - pool->start_page) & 0x3fUL;
70 bitmap_clear_nolock(bit, pool->bitmap + idx);
71 spinlock_release(&pool->lock);
72 }
73
74 /**
75 * @}
76 */