1/*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef KERNEL_ARCH_X86_PAGING_64BIT_PAGING_H
6#define KERNEL_ARCH_X86_PAGING_64BIT_PAGING_H
7
8
9#include <OS.h>
10
11
12// PML5 entry bits.
13#define X86_64_PML5E_PRESENT			(1LL << 0)
14#define X86_64_PML5E_WRITABLE			(1LL << 1)
15#define X86_64_PML5E_USER				(1LL << 2)
16#define X86_64_PML5E_WRITE_THROUGH		(1LL << 3)
17#define X86_64_PML5E_CACHING_DISABLED	(1LL << 4)
18#define X86_64_PML5E_ACCESSED			(1LL << 5)
19#define X86_64_PML5E_NOT_EXECUTABLE		(1LL << 63)
20#define X86_64_PML5E_ADDRESS_MASK		0x000ffffffffff000L
21
22// PML4 entry bits.
23#define X86_64_PML4E_PRESENT			(1LL << 0)
24#define X86_64_PML4E_WRITABLE			(1LL << 1)
25#define X86_64_PML4E_USER				(1LL << 2)
26#define X86_64_PML4E_WRITE_THROUGH		(1LL << 3)
27#define X86_64_PML4E_CACHING_DISABLED	(1LL << 4)
28#define X86_64_PML4E_ACCESSED			(1LL << 5)
29#define X86_64_PML4E_NOT_EXECUTABLE		(1LL << 63)
30#define X86_64_PML4E_ADDRESS_MASK		0x000ffffffffff000L
31
32// PDPT entry bits.
33#define X86_64_PDPTE_PRESENT			(1LL << 0)
34#define X86_64_PDPTE_WRITABLE			(1LL << 1)
35#define X86_64_PDPTE_USER				(1LL << 2)
36#define X86_64_PDPTE_WRITE_THROUGH		(1LL << 3)
37#define X86_64_PDPTE_CACHING_DISABLED	(1LL << 4)
38#define X86_64_PDPTE_ACCESSED			(1LL << 5)
39#define X86_64_PDPTE_DIRTY				(1LL << 6)
40#define X86_64_PDPTE_LARGE_PAGE			(1LL << 7)
41#define X86_64_PDPTE_GLOBAL				(1LL << 8)
42#define X86_64_PDPTE_PAT				(1LL << 12)
43#define X86_64_PDPTE_NOT_EXECUTABLE		(1LL << 63)
44#define X86_64_PDPTE_ADDRESS_MASK		0x000ffffffffff000L
45
46// Page directory entry bits.
47#define X86_64_PDE_PRESENT				(1LL << 0)
48#define X86_64_PDE_WRITABLE				(1LL << 1)
49#define X86_64_PDE_USER					(1LL << 2)
50#define X86_64_PDE_WRITE_THROUGH		(1LL << 3)
51#define X86_64_PDE_CACHING_DISABLED		(1LL << 4)
52#define X86_64_PDE_ACCESSED				(1LL << 5)
53#define X86_64_PDE_DIRTY				(1LL << 6)
54#define X86_64_PDE_LARGE_PAGE			(1LL << 7)
55#define X86_64_PDE_GLOBAL				(1LL << 8)
56#define X86_64_PDE_PAT					(1LL << 12)
57#define X86_64_PDE_NOT_EXECUTABLE		(1LL << 63)
58#define X86_64_PDE_ADDRESS_MASK			0x000ffffffffff000L
59
60// Page table entry bits.
61#define X86_64_PTE_PRESENT				(1LL << 0)
62#define X86_64_PTE_WRITABLE				(1LL << 1)
63#define X86_64_PTE_USER					(1LL << 2)
64#define X86_64_PTE_WRITE_THROUGH		(1LL << 3)
65#define X86_64_PTE_CACHING_DISABLED		(1LL << 4)
66#define X86_64_PTE_ACCESSED				(1LL << 5)
67#define X86_64_PTE_DIRTY				(1LL << 6)
68#define X86_64_PTE_PAT					(1LL << 7)
69#define X86_64_PTE_GLOBAL				(1LL << 8)
70#define X86_64_PTE_NOT_EXECUTABLE		(1LL << 63)
71#define X86_64_PTE_ADDRESS_MASK			0x000ffffffffff000L
72#define X86_64_PTE_PROTECTION_MASK		(X86_64_PTE_NOT_EXECUTABLE	\
73											| X86_64_PTE_WRITABLE	\
74											| X86_64_PTE_USER)
75#define X86_64_PTE_MEMORY_TYPE_MASK		(X86_64_PTE_WRITE_THROUGH \
76											| X86_64_PTE_CACHING_DISABLED)
77
78
79static const size_t k64BitPageTableRange = 0x200000L;
80static const size_t k64BitPageDirectoryRange = 0x40000000L;
81static const size_t k64BitPDPTRange = 0x8000000000L;
82static const size_t k64BitPML4TRange = 0x1000000000000L;
83
84static const size_t k64BitTableEntryCount = 512;
85
86
87#define VADDR_TO_PML5E(va)	(((va) & 0x01fffffffffff000L) / k64BitPML4TRange)
88#define VADDR_TO_PML4E(va)	(((va) % k64BitPML4TRange) / k64BitPDPTRange)
89#define VADDR_TO_PDPTE(va)	(((va) % k64BitPDPTRange) / k64BitPageDirectoryRange)
90#define VADDR_TO_PDE(va)	(((va) % k64BitPageDirectoryRange) / k64BitPageTableRange)
91#define VADDR_TO_PTE(va)	(((va) % k64BitPageTableRange) / B_PAGE_SIZE)
92
93
94#endif	// KERNEL_ARCH_X86_PAGING_64BIT_PAGING_H
95