1 /** @file
2   Page table management header file.
3 
4   Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef _PAGE_TABLE_LIB_H_
10 #define _PAGE_TABLE_LIB_H_
11 
12 #include <IndustryStandard/PeImage.h>
13 
14 #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE              BIT0
15 #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE              BIT1
16 #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT  BIT2
17 #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL          BIT3
18 #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE        BIT30
19 #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED     BIT31
20 // Other bits are reserved for future use
21 typedef struct {
22   UINT32  PageTableBase;
23   UINT32  Reserved;
24   UINT32  Attributes;
25 } PAGE_TABLE_LIB_PAGING_CONTEXT_IA32;
26 
27 typedef struct {
28   UINT64  PageTableBase;
29   UINT32  Attributes;
30 } PAGE_TABLE_LIB_PAGING_CONTEXT_X64;
31 
32 typedef union {
33   PAGE_TABLE_LIB_PAGING_CONTEXT_IA32  Ia32;
34   PAGE_TABLE_LIB_PAGING_CONTEXT_X64   X64;
35 } PAGE_TABLE_LIB_PAGING_CONTEXT_DATA;
36 
37 typedef struct {
38   //
39   // PE32+ Machine type for EFI images
40   //
41   // #define IMAGE_FILE_MACHINE_I386            0x014c
42   // #define IMAGE_FILE_MACHINE_X64             0x8664
43   //
44   UINT16                                 MachineType;
45   PAGE_TABLE_LIB_PAGING_CONTEXT_DATA     ContextData;
46 } PAGE_TABLE_LIB_PAGING_CONTEXT;
47 
48 #define PAGE_TABLE_POOL_ALIGNMENT   BASE_2MB
49 #define PAGE_TABLE_POOL_UNIT_SIZE   SIZE_2MB
50 #define PAGE_TABLE_POOL_UNIT_PAGES  EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)
51 #define PAGE_TABLE_POOL_ALIGN_MASK  \
52   (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))
53 
54 typedef struct {
55   VOID            *NextPool;
56   UINTN           Offset;
57   UINTN           FreePages;
58 } PAGE_TABLE_POOL;
59 
60 
61 /**
62   Allocates one or more 4KB pages for page table.
63 
64   @param  Pages                 The number of 4 KB pages to allocate.
65 
66   @return A pointer to the allocated buffer or NULL if allocation fails.
67 
68 **/
69 typedef
70 VOID *
71 (EFIAPI *PAGE_TABLE_LIB_ALLOCATE_PAGES) (
72   IN UINTN  Pages
73   );
74 
75 /**
76   This function assigns the page attributes for the memory region specified by BaseAddress and
77   Length from their current attributes to the attributes specified by Attributes.
78 
79   Caller should make sure BaseAddress and Length is at page boundary.
80 
81   Caller need guarantee the TPL <= TPL_NOTIFY, if there is split page request.
82 
83   @param  PagingContext     The paging context. NULL means get page table from current CPU context.
84   @param  BaseAddress       The physical address that is the start address of a memory region.
85   @param  Length            The size in bytes of the memory region.
86   @param  Attributes        The bit mask of attributes to set for the memory region.
87   @param  AllocatePagesFunc If page split is needed, this function is used to allocate more pages.
88                             NULL mean page split is unsupported.
89 
90   @retval RETURN_SUCCESS           The attributes were cleared for the memory region.
91   @retval RETURN_ACCESS_DENIED     The attributes for the memory resource range specified by
92                                    BaseAddress and Length cannot be modified.
93   @retval RETURN_INVALID_PARAMETER Length is zero.
94                                    Attributes specified an illegal combination of attributes that
95                                    cannot be set together.
96   @retval RETURN_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
97                                    the memory resource range.
98   @retval RETURN_UNSUPPORTED       The processor does not support one or more bytes of the memory
99                                    resource range specified by BaseAddress and Length.
100                                    The bit mask of attributes is not support for the memory resource
101                                    range specified by BaseAddress and Length.
102 **/
103 RETURN_STATUS
104 EFIAPI
105 AssignMemoryPageAttributes (
106   IN  PAGE_TABLE_LIB_PAGING_CONTEXT     *PagingContext OPTIONAL,
107   IN  PHYSICAL_ADDRESS                  BaseAddress,
108   IN  UINT64                            Length,
109   IN  UINT64                            Attributes,
110   IN  PAGE_TABLE_LIB_ALLOCATE_PAGES     AllocatePagesFunc OPTIONAL
111   );
112 
113 /**
114   Initialize the Page Table lib.
115 **/
116 VOID
117 InitializePageTableLib (
118   VOID
119   );
120 
121 /**
122   This API provides a way to allocate memory for page table.
123 
124   This API can be called more once to allocate memory for page tables.
125 
126   Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
127   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
128   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
129   returned.
130 
131   @param  Pages                 The number of 4 KB pages to allocate.
132 
133   @return A pointer to the allocated buffer or NULL if allocation fails.
134 
135 **/
136 VOID *
137 EFIAPI
138 AllocatePageTableMemory (
139   IN UINTN           Pages
140   );
141 
142 /**
143   Get paging details.
144 
145   @param  PagingContextData      The paging context.
146   @param  PageTableBase          Return PageTableBase field.
147   @param  Attributes             Return Attributes field.
148 
149 **/
150 VOID
151 GetPagingDetails (
152   IN  PAGE_TABLE_LIB_PAGING_CONTEXT_DATA *PagingContextData,
153   OUT UINTN                              **PageTableBase     OPTIONAL,
154   OUT UINT32                             **Attributes        OPTIONAL
155   );
156 
157 #endif
158