|
|
@ -7,9 +7,9 @@
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_PAGE_SIZE
|
|
|
|
* @name MEMM_PAGE_SIZE
|
|
|
|
* @addindex 平台定制宏
|
|
|
|
* @addindex 平台定制宏
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 最小的页大小。
|
|
|
|
* 最小的页大小。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @if arch == x86_64 then
|
|
|
|
* @if arch == x86_64 then
|
|
|
|
* 4096
|
|
|
|
* 4096
|
|
|
|
* @endif
|
|
|
|
* @endif
|
|
|
@ -28,7 +28,7 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_PAGE_TABLE_FLAGS_MASK
|
|
|
|
* @name MEMM_PAGE_TABLE_FLAGS_MASK
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 页表项中属性标志位使用的最低12位的掩码`0xfff`。
|
|
|
|
* 页表项中属性标志位使用的最低12位的掩码`0xfff`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff)
|
|
|
|
#define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff)
|
|
|
@ -36,7 +36,7 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_xx_ALIGN_MASK
|
|
|
|
* @name MEMM_xx_ALIGN_MASK
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 页对齐掩码。
|
|
|
|
* 页对齐掩码。
|
|
|
|
* `xx`为`x86_64`架构的页的三种大小,分别为`4K`、`2M`和`1G`。这些页一定是以它们自己的大小对齐,因此会出现低n位总为0的情况。
|
|
|
|
* `xx`为`x86_64`架构的页的三种大小,分别为`4K`、`2M`和`1G`。这些页一定是以它们自己的大小对齐,因此会出现低n位总为0的情况。
|
|
|
|
* `4K`对应`0xfff`;`2M`对应`0x1fffff`;`1G`对应`0x3fffffff`。
|
|
|
|
* `4K`对应`0xfff`;`2M`对应`0x1fffff`;`1G`对应`0x3fffffff`。
|
|
|
@ -48,9 +48,9 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_ENTRY_FLAG_xx
|
|
|
|
* @name MEMM_ENTRY_FLAG_xx
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 页表项属性标志位。定义如下:
|
|
|
|
* 页表项属性标志位。定义如下:
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ```c
|
|
|
|
* ```c
|
|
|
|
* #define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
|
|
|
|
* #define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
|
|
|
|
* #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
|
|
|
|
* #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
|
|
|
@ -65,7 +65,7 @@ extern u64 PML4[512];
|
|
|
|
* #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
|
|
|
|
* #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
|
|
|
|
* #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63)
|
|
|
|
* #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63)
|
|
|
|
* ```
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 其中`MEMM_PTE_ENTRY_FLAG_PAT`的`pte`表示此属性标志位只存在与`pte`页表项中。
|
|
|
|
* 其中`MEMM_PTE_ENTRY_FLAG_PAT`的`pte`表示此属性标志位只存在与`pte`页表项中。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
|
|
|
|
#define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
|
|
|
@ -84,9 +84,9 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name memm_entry_flag_get(entry, flag)
|
|
|
|
* @name memm_entry_flag_get(entry, flag)
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 获取页表项中某个属性标志位,得到布尔值。
|
|
|
|
* 获取页表项中某个属性标志位,得到布尔值。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 其中`flag`是`MEMM_ENTRY_FLAG_xx`。
|
|
|
|
* 其中`flag`是`MEMM_ENTRY_FLAG_xx`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define memm_entry_flag_get(entry, flag) \
|
|
|
|
#define memm_entry_flag_get(entry, flag) \
|
|
|
@ -95,13 +95,13 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK
|
|
|
|
* @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 页表项地址域掩码。将页表项与掩码作与运算可得到页表项指向的**下一级页表的起始地址**或**页框的起始地址**。
|
|
|
|
* 页表项地址域掩码。将页表项与掩码作与运算可得到页表项指向的**下一级页表的起始地址**或**页框的起始地址**。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 含`BP`的为大型页页表项的地址域掩码。
|
|
|
|
* 含`BP`的为大型页页表项的地址域掩码。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 定义如下:
|
|
|
|
* 定义如下:
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ```c
|
|
|
|
* ```c
|
|
|
|
* #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000)
|
|
|
|
* #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000)
|
|
|
|
* #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
|
|
|
|
* #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
|
|
|
@ -113,7 +113,7 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name memm_entry_get_address(entry)
|
|
|
|
* @name memm_entry_get_address(entry)
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 获取页表项指向的地址。
|
|
|
|
* 获取页表项指向的地址。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define memm_entry_get_address(entry) \
|
|
|
|
#define memm_entry_get_address(entry) \
|
|
|
@ -138,7 +138,7 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_LA_xxxxI
|
|
|
|
* @name MEMM_LA_xxxxI
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 在4级分页中,线性地址的四个页表项索引宏。其中`xxxx`分别为`PML4E`、`PDPTE`、`PDE`和`PE`。
|
|
|
|
* 在4级分页中,线性地址的四个页表项索引宏。其中`xxxx`分别为`PML4E`、`PDPTE`、`PDE`和`PE`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define MEMM_LA_PML4EI
|
|
|
|
#define MEMM_LA_PML4EI
|
|
|
@ -149,9 +149,9 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name memm_la_get_entry_index(addr, entry)
|
|
|
|
* @name memm_la_get_entry_index(addr, entry)
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 获取线性地址`addr`中的`entry`页表项索引。
|
|
|
|
* 获取线性地址`addr`中的`entry`页表项索引。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 其中`entry`应为宏`MEMM_LA_xxxxI`。
|
|
|
|
* 其中`entry`应为宏`MEMM_LA_xxxxI`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define memm_la_get_entry_index(addr, entry) \
|
|
|
|
#define memm_la_get_entry_index(addr, entry) \
|
|
|
@ -160,7 +160,7 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name MEMM_LA_xxx_PAGE_OFFSET
|
|
|
|
* @name MEMM_LA_xxx_PAGE_OFFSET
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 线性地址的页内偏移宏。其中`xxx`为三种页容量`4KB`、`2MB`、`1GB`。
|
|
|
|
* 线性地址的页内偏移宏。其中`xxx`为三种页容量`4KB`、`2MB`、`1GB`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define MEMM_LA_1GB_PAGE_OFFSET
|
|
|
|
#define MEMM_LA_1GB_PAGE_OFFSET
|
|
|
@ -170,9 +170,9 @@ extern u64 PML4[512];
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name memm_la_get_offset(addr, page_type)
|
|
|
|
* @name memm_la_get_offset(addr, page_type)
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 获取线性地址的页内偏移部分。
|
|
|
|
* 获取线性地址的页内偏移部分。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 其中`page_type`应为宏`MEMM_LA_xxx_PAGE_OFFSET`。
|
|
|
|
* 其中`page_type`应为宏`MEMM_LA_xxx_PAGE_OFFSET`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define memm_la_get_offset(addr, page_type) \
|
|
|
|
#define memm_la_get_offset(addr, page_type) \
|
|
|
@ -180,20 +180,20 @@ extern u64 PML4[512];
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name memm_map_pageframes_to
|
|
|
|
* @name memm_map_pageframes_to
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ```c
|
|
|
|
* ```c
|
|
|
|
* bool memm_map_pageframes_to(
|
|
|
|
* bool memm_map_pageframes_to(
|
|
|
|
* u64 target, u64 physical,
|
|
|
|
* u64 target, u64 physical,
|
|
|
|
* usize size,
|
|
|
|
* usize size,
|
|
|
|
* bool user, bool write);
|
|
|
|
* bool user, bool write);
|
|
|
|
* ```
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 仅支持**canonical**型地址
|
|
|
|
* 仅支持**canonical**型地址
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。
|
|
|
|
* `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false
|
|
|
|
* 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页;
|
|
|
|
* 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页;
|
|
|
|
* 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页;
|
|
|
|
* 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页;
|
|
|
|
* 否则映射4KB页。
|
|
|
|
* 否则映射4KB页。
|
|
|
@ -206,7 +206,7 @@ bool memm_map_pageframes_to(
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name reload_pml4
|
|
|
|
* @name reload_pml4
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ```c
|
|
|
|
* ```c
|
|
|
|
* void reload_pml4();
|
|
|
|
* void reload_pml4();
|
|
|
|
* ```
|
|
|
|
* ```
|
|
|
@ -216,9 +216,9 @@ extern void reload_pml4();
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name is_user_address(addr)
|
|
|
|
* @name is_user_address(addr)
|
|
|
|
* @addindex 平台定制宏
|
|
|
|
* @addindex 平台定制宏
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 判断`addr`是否是一个用户空间地址,得到一个布尔值。
|
|
|
|
* 判断`addr`是否是一个用户空间地址,得到一个布尔值。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @if arch == x86_64
|
|
|
|
* @if arch == x86_64
|
|
|
|
* `canonical`型地址的高地址为用户空间,低地址为内核空间。
|
|
|
|
* `canonical`型地址的高地址为用户空间,低地址为内核空间。
|
|
|
|
* @endif
|
|
|
|
* @endif
|
|
|
@ -229,7 +229,7 @@ extern void reload_pml4();
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name is_cannonical(addr)
|
|
|
|
* @name is_cannonical(addr)
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 判断`addr`是否是一个cannonical型地址。
|
|
|
|
* 判断`addr`是否是一个cannonical型地址。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define is_cannonical(addr) \
|
|
|
|
#define is_cannonical(addr) \
|
|
|
@ -238,9 +238,9 @@ extern void reload_pml4();
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @name memm_get_page_align(addr)
|
|
|
|
* @name memm_get_page_align(addr)
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
* @addindex 平台依赖宏 x86_64
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 获取地址`addr`的页对齐大小,得到一个`memm_page_size`类型值。
|
|
|
|
* 获取地址`addr`的页对齐大小,得到一个`memm_page_size`类型值。
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 当地址`addr`是*4KB对齐*或*没有4KB对齐时*,都得到`MEMM_PAGE_SIZE_4K`。
|
|
|
|
* 当地址`addr`是*4KB对齐*或*没有4KB对齐时*,都得到`MEMM_PAGE_SIZE_4K`。
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define memm_get_page_align(addr) \
|
|
|
|
#define memm_get_page_align(addr) \
|
|
|
@ -250,4 +250,21 @@ extern void reload_pml4();
|
|
|
|
? MEMM_PAGE_SIZE_2M \
|
|
|
|
? MEMM_PAGE_SIZE_2M \
|
|
|
|
: MEMM_PAGE_SIZE_4K))
|
|
|
|
: MEMM_PAGE_SIZE_4K))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @name memm_page_counter
|
|
|
|
|
|
|
|
* @addindex 平台定制结构
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* 页计数器
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @if arch == x86_64
|
|
|
|
|
|
|
|
* 使用三个成员分别记录`4KB`、`2MB`、`1GB`页的大小。
|
|
|
|
|
|
|
|
* @endif
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct __memm_page_counter
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
usize mapped_4k_page;
|
|
|
|
|
|
|
|
usize mapped_2m_page;
|
|
|
|
|
|
|
|
usize mapped_1g_page;
|
|
|
|
|
|
|
|
} memm_page_counter;
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|