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_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 /* default flags for 4K page table entries */ 49 #define X86_KERNEL_PT_FLAGS (X86_MMU_PG_G | X86_MMU_PG_RW | X86_MMU_PG_P) 50 51 #if !defined(PAGE_SIZE) 52 #define PAGE_SIZE 4096 53 #elif PAGE_SIZE != 4096 54 #error "Found multiple incompatible definitions for PAGE_SIZE" 55 #endif 56 #define PAGE_DIV_SHIFT 12 57 58 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64 59 /* PAE mode */ 60 #define X86_PDPT_ADDR_MASK (0x00000000ffffffe0ul) 61 #define X86_PG_FRAME (0xfffffffffffff000ul) 62 /* ISDM:4.1.4 MAXPHYADDR is at most 52 */ 63 #define X86_PG_PHY_ADDR_MASK (0x000ffffffffff000ul) 64 /* NX Bit is ignored in the PAE mode */ 65 #define X86_FLAGS_MASK (0x8000000000000ffful) 66 #define X86_PTE_NOT_PRESENT (0xFFFFFFFFFFFFFFFEul) 67 #define X86_2MB_PAGE_FRAME (0x000fffffffe00000ul) 68 #define PAGE_OFFSET_MASK_4KB (0x0000000000000ffful) 69 #define PAGE_OFFSET_MASK_2MB (0x00000000001ffffful) 70 #define X86_MMU_PG_NX (1ul << 63) 71 72 #if ARCH_X86_64 73 #define X86_PAGING_LEVELS 4 74 #define PML4_SHIFT 39 75 #else 76 #define X86_PAGING_LEVELS 3 77 #endif 78 79 #define PDP_SHIFT 30 80 #define PD_SHIFT 21 81 #define PT_SHIFT 12 82 #define ADDR_OFFSET 9 83 #define PDPT_ADDR_OFFSET 2 84 #define NO_OF_PT_ENTRIES 512 85 86 #define X86_SET_FLAG(x) (x=1) 87 88 #else 89 /* non PAE mode */ 90 #define X86_PG_FRAME (0xfffff000) 91 #define X86_FLAGS_MASK (0x00000fff) 92 #define X86_PTE_NOT_PRESENT (0xfffffffe) 93 #define X86_4MB_PAGE_FRAME (0xffc00000) 94 #define PAGE_OFFSET_MASK_4KB (0x00000fff) 95 #define PAGE_OFFSET_MASK_4MB (0x003fffff) 96 #define NO_OF_PT_ENTRIES 1024 97 #define X86_PAGING_LEVELS 2 98 #define PD_SHIFT 22 99 #define PT_SHIFT 12 100 #define ADDR_OFFSET 10 101 102 #endif 103 104 /* on both x86-32 and x86-64 physical memory is mapped at the base of the kernel address space */ 105 #define X86_PHYS_TO_VIRT(x) ((uintptr_t)(x) + KERNEL_BASE - MEMBASE) 106 #define X86_VIRT_TO_PHYS(x) ((uintptr_t)(x) - KERNEL_BASE + MEMBASE) 107 108 /* C defines below */ 109 #ifndef ASSEMBLY 110 111 #include <sys/types.h> 112 #include <compiler.h> 113 114 __BEGIN_CDECLS 115 116 /* Different page table levels in the page table mgmt hirerachy */ 117 enum page_table_levels { 118 PF_L, 119 PT_L, 120 PD_L, 121 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64 122 PDP_L, 123 #endif 124 #if ARCH_X86_64 125 PML4_L 126 #endif 127 }; 128 129 130 struct map_range { 131 vaddr_t start_vaddr; 132 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64 133 uint64_t start_paddr; /* Physical address in the PAE mode is 64 bits wide */ 134 #else 135 paddr_t start_paddr; /* Physical address in the PAE mode is 32 bits wide */ 136 #endif 137 uint32_t size; 138 }; 139 140 #if defined(PAE_MODE_ENABLED) || ARCH_X86_64 141 typedef uint64_t map_addr_t; 142 typedef uint64_t arch_flags_t; 143 #define PRIxMAP_ADDR PRIx64 144 #define PRIxARCH_FLAGS PRIx64 145 #define PRIxMAP_RANGE_PADDR PRIx64 146 #else 147 typedef uint32_t map_addr_t; 148 typedef uint32_t arch_flags_t; 149 #define PRIxMAP_ADDR PRIx32 150 #define PRIxARCH_FLAGS PRIx32 151 #define PRIxMAP_RANGE_PADDR PRIxPADDR 152 #endif 153 154 #if ARCH_X86_64 155 status_t x86_mmu_check_mapping (addr_t pml4, paddr_t paddr, 156 vaddr_t vaddr, arch_flags_t in_flags, 157 uint32_t *ret_level, arch_flags_t *ret_flags, 158 map_addr_t *last_valid_entry); 159 #endif 160 161 status_t x86_mmu_get_mapping(map_addr_t init_table, vaddr_t vaddr, uint32_t *ret_level, 162 arch_flags_t *mmu_flags, map_addr_t *last_valid_entry); 163 164 status_t x86_mmu_map_range (map_addr_t pt, struct map_range *range, arch_flags_t flags); 165 status_t x86_mmu_add_mapping(map_addr_t init_table, map_addr_t paddr, 166 vaddr_t vaddr, arch_flags_t flags); 167 status_t x86_mmu_unmap(map_addr_t init_table, vaddr_t vaddr, size_t count); 168 169 void x86_mmu_early_init(void); 170 void x86_mmu_init(void); 171 172 __END_CDECLS 173 174 #endif // !ASSEMBLY 175