• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  * Copyright (c) 2015-2018 Intel Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files
7  * (the "Software"), to deal in the Software without restriction,
8  * including without limitation the rights to use, copy, modify, merge,
9  * publish, distribute, sublicense, and/or sell copies of the Software,
10  * and to permit persons to whom the Software is furnished to do so,
11  * subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #pragma once
25 
26 /* top level defines for the x86 mmu */
27 /* NOTE: the top part can be included from assembly */
28 #define KB                (1024UL)
29 #define MB                (1024UL*1024UL)
30 #define GB                (1024UL*1024UL*1024UL)
31 
32 #define X86_MMU_PG_P        0x001           /* P    Valid                   */
33 #define X86_MMU_PG_RW       0x002           /* R/W  Read/Write              */
34 #define X86_MMU_PG_U        0x004           /* U/S  User/Supervisor         */
35 #define X86_MMU_PG_PS       0x080           /* PS   Page size (0=4k,1=4M)   */
36 #define X86_MMU_PG_PTE_PAT  0x080           /* PAT  PAT index               */
37 #define X86_MMU_PG_G        0x100           /* G    Global                  */
38 #define X86_MMU_CLEAR       0x0
39 #define X86_DIRTY_ACCESS_MASK   0xf9f
40 #define X86_MMU_CACHE_DISABLE   0x010       /* C Cache disable */
41 
42 /* default flags for inner page directory entries */
43 #define X86_KERNEL_PD_FLAGS (X86_MMU_PG_G | X86_MMU_PG_RW | X86_MMU_PG_P | X86_MMU_PG_U)
44 
45 /* default flags for 2MB/4MB/1GB page directory entries */
46 #define X86_KERNEL_PD_LP_FLAGS (X86_MMU_PG_G | X86_MMU_PG_PS | X86_MMU_PG_RW | X86_MMU_PG_P)
47 
48 #if !defined(PAGE_SIZE)
49 #define PAGE_SIZE       4096
50 #elif PAGE_SIZE != 4096
51 #error "Found multiple incompatible definitions for PAGE_SIZE"
52 #endif
53 #define PAGE_DIV_SHIFT      12
54 
55 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64
56 /* PAE mode */
57 #define X86_PDPT_ADDR_MASK      (0x00000000ffffffe0ul)
58 #define X86_PG_FRAME            (0xfffffffffffff000ul)
59 /* ISDM:4.1.4 MAXPHYADDR is at most 52 */
60 #define X86_PG_PHY_ADDR_MASK    (0x000ffffffffff000ul)
61 /* NX Bit is ignored in the PAE mode */
62 #define X86_FLAGS_MASK          (0x8000000000000ffful)
63 #define X86_PTE_NOT_PRESENT     (0xFFFFFFFFFFFFFFFEul)
64 #define X86_2MB_PAGE_FRAME      (0x000fffffffe00000ul)
65 #define PAGE_OFFSET_MASK_4KB    (0x0000000000000ffful)
66 #define PAGE_OFFSET_MASK_2MB    (0x00000000001ffffful)
67 #define X86_MMU_PG_NX           (1ul << 63)
68 
69 #if ARCH_X86_64
70 #define X86_PAGING_LEVELS   4
71 #define PML4_SHIFT      39
72 #else
73 #define X86_PAGING_LEVELS   3
74 #endif
75 
76 #define PDP_SHIFT       30
77 #define PD_SHIFT        21
78 #define PT_SHIFT        12
79 #define ADDR_OFFSET     9
80 #define PDPT_ADDR_OFFSET    2
81 #define NO_OF_PT_ENTRIES    512
82 
83 #define X86_SET_FLAG(x)     (x=1)
84 
85 #else
86 /* non PAE mode */
87 #define X86_PG_FRAME        (0xfffff000)
88 #define X86_FLAGS_MASK          (0x00000fff)
89 #define X86_PTE_NOT_PRESENT     (0xfffffffe)
90 #define X86_4MB_PAGE_FRAME      (0xffc00000)
91 #define PAGE_OFFSET_MASK_4KB    (0x00000fff)
92 #define PAGE_OFFSET_MASK_4MB    (0x003fffff)
93 #define NO_OF_PT_ENTRIES    1024
94 #define X86_PAGING_LEVELS   2
95 #define PD_SHIFT        22
96 #define PT_SHIFT        12
97 #define ADDR_OFFSET     10
98 
99 #endif
100 
101 /* on both x86-32 and x86-64 physical memory is mapped at the base of the kernel address space */
102 #define X86_PHYS_TO_VIRT(x)     ((uintptr_t)(x) + KERNEL_BASE - MEMBASE)
103 #define X86_VIRT_TO_PHYS(x)     ((uintptr_t)(x) - KERNEL_BASE + MEMBASE)
104 
105 /* C defines below */
106 #ifndef ASSEMBLY
107 
108 #include <sys/types.h>
109 #include <compiler.h>
110 
111 __BEGIN_CDECLS
112 
113 /* Different page table levels in the page table mgmt hirerachy */
114 enum page_table_levels {
115     PF_L,
116     PT_L,
117     PD_L,
118 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64
119     PDP_L,
120 #endif
121 #if ARCH_X86_64
122     PML4_L
123 #endif
124 };
125 
126 
127 struct map_range {
128     vaddr_t start_vaddr;
129 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64
130     uint64_t start_paddr; /* Physical address in the PAE mode is 64 bits wide */
131 #else
132     paddr_t start_paddr; /* Physical address in the PAE mode is 32 bits wide */
133 #endif
134     uint32_t size;
135 };
136 
137 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64
138 typedef uint64_t map_addr_t;
139 typedef uint64_t arch_flags_t;
140 #define PRIxMAP_ADDR PRIx64
141 #define PRIxARCH_FLAGS PRIx64
142 #define PRIxMAP_RANGE_PADDR PRIx64
143 #else
144 typedef uint32_t map_addr_t;
145 typedef uint32_t arch_flags_t;
146 #define PRIxMAP_ADDR PRIx32
147 #define PRIxARCH_FLAGS PRIx32
148 #define PRIxMAP_RANGE_PADDR PRIxPADDR
149 #endif
150 
151 #if ARCH_X86_64
152 status_t x86_mmu_check_mapping (addr_t pml4, paddr_t paddr,
153                                 vaddr_t vaddr, arch_flags_t in_flags,
154                                 uint32_t *ret_level, arch_flags_t *ret_flags,
155                                 map_addr_t *last_valid_entry);
156 #endif
157 
158 status_t x86_mmu_get_mapping(map_addr_t init_table, vaddr_t vaddr, uint32_t *ret_level,
159                              arch_flags_t *mmu_flags, map_addr_t *last_valid_entry);
160 
161 status_t x86_mmu_map_range (map_addr_t pt, struct map_range *range, arch_flags_t flags);
162 status_t x86_mmu_add_mapping(map_addr_t init_table, map_addr_t paddr,
163                              vaddr_t vaddr, arch_flags_t flags);
164 status_t x86_mmu_unmap(map_addr_t init_table, vaddr_t vaddr, size_t count);
165 
166 void x86_mmu_early_init(void);
167 void x86_mmu_init(void);
168 
169 __END_CDECLS
170 
171 #endif // !ASSEMBLY
172