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