Last active
April 25, 2025 21:23
-
-
Save hLunaaa/f23a48775bbe5425b4825eefcebf1197 to your computer and use it in GitHub Desktop.
complete IA-32e paging for vtop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
// | |
// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf | |
// | |
#define __pfn_to_page(pfn) (pfn << PAGE_SHIFT) | |
#define __page_to_pfn(pfn) (pfn >> PAGE_SHIFT) | |
union virt_addr_t | |
{ | |
struct | |
{ | |
u64 offset : 12; | |
u64 pml1_idx : 9; | |
u64 pml2_idx : 9; | |
u64 pml3_idx : 9; | |
u64 pml4_idx : 9; | |
u64 user : 16; // if (pml4_idx > 255) user = 0xffff; | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-12. Use of CR3 with IA-32e Paging and CR4.PCIDE = 0 | |
// | |
union cr3_t | |
{ | |
struct | |
{ | |
u64 ignored0 : 3; // 2:0 Ignored | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the PML4 table during linearaddress translation (see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the PML4 table during linear-address translation(see Section 4.9.2) | |
u64 ignored1 : 7; // 11:5 Ignored | |
u64 physical_address : 36; // 47:12 Physical address of the 4-KByte aligned PML4 table used for linear-address translation | |
u64 reserved0 : 16; // 63:48 Reserved (must be 0) | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-19. Format of an IA-32e Page-Table Entry that Maps a 4-KByte Page | |
// | |
union pml1e_t | |
{ | |
struct | |
{ | |
u64 present : 1; // 0 Present; must be 1 to map a 4-KByte page | |
u64 read_write : 1; // 1 Read/write; if 0, writes may not be allowed to the 4-KByte page referenced by this entry (see Section 4.6) | |
u64 user_supervisor : 1; // 2 User/supervisor; if 0, user-mode accesses are not allowed to the 4-KByte page referenced by this entry (see Section 4.6) | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the 4-KByte page referenced by this entry(see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the 4-KByte page referenced by this entry(see Section 4.9.2) | |
u64 accessed : 1; // 5 Accessed; indicates whether software has accessed the 4-KByte page referenced by this entry (see Section 4.8) | |
u64 dirty : 1; // 6 Dirty; indicates whether software has written to the 4-KByte page referenced by this entry (see Section 4.8) | |
u64 page_attribute_table : 1; // 7 Indirectly determines the memory type used to access the 4-KByte page referenced by this entry (see Section 4.9.2) | |
u64 global : 1; // 8 Global; if CR4.PGE = 1, determines whether the translation is global (see Section 4.10); ignored otherwise | |
u64 ignored0 : 3; // 11:9 Ignored | |
u64 physical_address : 36; // 49:12 Physical address of the 4-KByte page referenced by this entry | |
u64 reserved0 : 4; // 51:50 Reserved (must be 0) | |
u64 ignored1 : 7; // 58:52 Ignored | |
u64 protection_key : 4; // 62:59 Protection key; if CR4.PKE = 1, determines the protection key of the page (see Section 4.6.2); ignored otherwise | |
u64 execute_disable : 1; // 63 If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 4-KByte page controlled by this entry; see Section 4.6); otherwise, reserved(must be 0) | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-18. Format of an IA-32e Page-Directory Entry that References a Page Table | |
// | |
union pml2e_t | |
{ | |
struct | |
{ | |
u64 present : 1; // 0 Present; must be 1 to reference a page table | |
u64 read_write : 1; // 1 Read/write; if 0, writes may not be allowed to the 2-MByte region controlled by this entry (see Section 4.6) | |
u64 user_supervisor : 1; // 2 User/supervisor; if 0, user-mode accesses are not allowed to the 2-MByte region controlled by this entry (see Section 4.6) | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the page table referenced by this entry(see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the page table referenced by this entry(see Section 4.9.2) | |
u64 accessed : 1; // 5 Accessed; indicates whether this entry has been used for linear-address translation (see Section 4.8) | |
u64 ignored0 : 1; // 6 Ignored | |
u64 page_size : 1; // 7 Page size; must be 0 (otherwise, this entry maps a 2-MByte page; see Table 4-17) | |
u64 ignored1 : 4; // 11:8 Ignored | |
u64 physical_address : 36; // 49:12 Physical address of 4-KByte aligned page table referenced by this entry | |
u64 reserved0 : 4; // 51:50 Reserved (must be 0) | |
u64 ignored2 : 11; // 62:52 Ignored | |
u64 execute_disable : 1; // 63 If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 2-MByte region controlled by this entry; see Section 4.6); otherwise, reserved(must be 0) | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-17. Format of an IA-32e Page-Directory Entry that Maps a 2-MByte Page | |
// | |
union pml2e_large_t | |
{ | |
struct | |
{ | |
u64 present : 1; // 0 Present; must be 1 to map a 2-MByte page | |
u64 read_write : 1; // 1 Read/write; if 0, writes may not be allowed to the 2-MByte page referenced by this entry (see Section 4.6) | |
u64 user_supervisor : 1; // 2 User/supervisor; if 0, user-mode accesses are not allowed to the 2-MByte page referenced by this entry (see Section 4.6) | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the 2-MByte page referenced by this entry(see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the 2-MByte page referenced by this entry(see Section 4.9.2) | |
u64 accessed : 1; // 5 Accessed; indicates whether software has accessed the 2-MByte page referenced by this entry (see Section 4.8) | |
u64 dirty : 1; // 6 Dirty; indicates whether software has written to the 2-MByte page referenced by this entry (see Section 4.8) | |
u64 page_size : 1; // 7 Page size; must be 1 (otherwise, this entry references a page table; see Table 4-18) | |
u64 global : 1; // 8 Global; if CR4.PGE = 1, determines whether the translation is global (see Section 4.10); ignored otherwise | |
u64 ignored0 : 3; // 11:9 Ignored | |
u64 page_attribute_table : 1; // 12 Indirectly determines the memory type used to access the 2-MByte page referenced by this entry (see Section 4.9.2) | |
u64 reserved0 : 8; // 20:13 Reserved (must be 0) | |
u64 physical_address : 29; // 49:21 Physical address of the 2-MByte page referenced by this entry | |
u64 reserved1 : 2; // 51:50 Reserved (must be 0) | |
u64 ignored1 : 7; // 58:52 Ignored | |
u64 protection_key : 4; // 62:59 Protection key; if CR4.PKE = 1, determines the protection key of the page (see Section 4.6.2); ignored otherwise | |
u64 execute_disable : 1; // 63 If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 2-MByte page controlled by this entry; see Section 4.6); otherwise, reserved(must be 0) | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-16. Format of an IA-32e Page-Directory-Pointer-Table Entry (PDPTE) that References a Page Directory | |
// | |
union pml3e_t | |
{ | |
struct | |
{ | |
u64 present : 1; // 0 Present; must be 1 to reference a page directory | |
u64 read_write : 1; // 1 Read/write; if 0, writes may not be allowed to the 1-GByte region controlled by this entry (see Section 4.6) | |
u64 user_supervisor : 1; // 2 User/supervisor; if 0, user-mode accesses are not allowed to the 1-GByte region controlled by this entry (see Section 4.6) | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the page directory referenced by this entry(see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the page directory referenced by this entry(see Section 4.9.2) | |
u64 accessed : 1; // 5 Accessed; indicates whether this entry has been used for linear-address translation (see Section 4.8) | |
u64 ignored0 : 1; // 6 Ignored | |
u64 page_size : 1; // 7 Page size; must be 0 (otherwise, this entry maps a 1-GByte page; see Table 4-15) | |
u64 ignored1 : 4; // 11:8 Ignored | |
u64 physical_address : 36; // 49:12 Physical address of 4-KByte aligned page directory referenced by this entry | |
u64 reserved0 : 4; // 51:50 Reserved (must be 0) | |
u64 ignored2 : 11; // 62:52 Ignored | |
u64 execute_disable : 1; // 63 If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 1-GByte region controlled by this entry; see Section 4.6); otherwise, reserved(must be 0) | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-15. Format of an IA-32e Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page | |
// | |
union pml3e_large_t | |
{ | |
struct | |
{ | |
u64 present : 1; // 0 Present; must be 1 to map a 1-GByte page | |
u64 read_write : 1; // 1 Read/write; if 0, writes may not be allowed to the 1-GByte page referenced by this entry (see Section 4.6) | |
u64 user_supervisor : 1; // 2 User/supervisor; if 0, user-mode accesses are not allowed to the 1-GByte page referenced by this entry (see Section 4.6) | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the 1-GByte page referenced by this entry(see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the 1-GByte page referenced by this entry(see Section 4.9.2) | |
u64 accessed : 1; // 5 Accessed; indicates whether software has accessed the 1-GByte page referenced by this entry (see Section 4.8) | |
u64 dirty : 1; // 6 Dirty; indicates whether software has written to the 1-GByte page referenced by this entry (see Section 4.8) | |
u64 page_size : 1; // 7 Page size; must be 1 (otherwise, this entry references a page directory; see Table 4-16) | |
u64 global : 1; // 8 Global; if CR4.PGE = 1, determines whether the translation is global (see Section 4.10); ignored otherwise | |
u64 ignored0 : 3; // 11:9 Ignored | |
u64 page_attribute_table : 1; // 12 Indirectly determines the memory type used to access the 1-GByte page referenced by this entry (see Section 4.9.2) | |
u64 reserved0 : 17; // 29:13 Reserved (must be 0) | |
u64 physical_address : 21; // 50:30 Physical address of the 1-GByte page referenced by this entry | |
u64 reserved1 : 1; // 51 Reserved (must be 0) | |
u64 ignored1 : 7; // 58:52 Ignored | |
u64 protection_key : 4; // 62:59 Protection key; if CR4.PKE = 1, determines the protection key of the page (see Section 4.6.2); ignored otherwise | |
u64 execute_disable : 1; // 63 If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 1-GByte page controlled by this entry; see Section 4.6); otherwise, reserved(must be 0) | |
}; | |
u64 val; | |
}; | |
// | |
// Table 4-14. Format of an IA-32e PML4 Entry (PML4E) that References a Page-Directory-Pointer Table | |
// | |
union pml4e_t | |
{ | |
struct | |
{ | |
u64 present : 1; // 0 Present; must be 1 to reference a page-directory-pointer table | |
u64 read_write : 1; // 1 Read/write; if 0, writes may not be allowed to the 512-GByte region controlled by this entry (see Section 4.6) | |
u64 user_supervisor : 1; // 2 User/supervisor; if 0, user-mode accesses are not allowed to the 512-GByte region controlled by this entry (see Section 4.6) | |
u64 page_write_through : 1; // 3 Page-level write-through; indirectly determines the memory type used to access the page-directory-pointer table referenced by this entry(see Section 4.9.2) | |
u64 page_cache_disable : 1; // 4 Page-level cache disable; indirectly determines the memory type used to access the page-directory-pointer table referenced by this entry(see Section 4.9.2) | |
u64 accessed : 1; // 5 Accessed; indicates whether this entry has been used for linear-address translation (see Section 4.8) | |
u64 ignored0 : 1; // 6 Ignored | |
u64 page_size : 1; // 7 Reserved (must be 0) | |
u64 ignored1 : 4; // 11:8 Ignored | |
u64 physical_address : 36; // 50:12 Physical address of 4-KByte aligned page-directory-pointer table referenced by this entry | |
u64 reserved1 : 4; // 51 Reserved (must be 0) | |
u64 ignored2 : 11; // 62:52 Ignored | |
u64 execute_disable : 1; // 63 If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 512-GByte region controlled by this entry; see Section 4.6); otherwise, reserved(must be 0) | |
}; | |
u64 val; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment