Changeset 35 for trunk/hal/x86_64/hal_gpt.c
- Timestamp:
- Jun 22, 2017, 8:10:37 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/x86_64/hal_gpt.c
r25 r35 1 1 /* 2 * hal_gpt.c - implementation of the Generic Page Table API for TSAR-MIPS32 3 * 4 * Author Alain Greiner (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 2 * hal_gpt.c - implementation of the Generic Page Table API for x86_64 3 * 4 * Copyright (c) 2017 Maxime Villard 7 5 * 8 6 * This file is part of ALMOS-MKH. 9 7 * 10 * ALMOS-MKH .is free software; you can redistribute it and/or modify it8 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 9 * under the terms of the GNU General Public License as published by 12 10 * the Free Software Foundation; version 2.0 of the License. 13 11 * 14 * ALMOS-MKH .is distributed in the hope that it will be useful, but12 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 23 21 24 22 #include <hal_types.h> 23 #include <hal_boot.h> /* XXX */ 25 24 #include <hal_gpt.h> 26 25 #include <hal_special.h> 26 #include <hal_internal.h> 27 27 28 #include <printk.h> 28 29 #include <bits.h> 30 #include <string.h> 29 31 #include <process.h> 30 32 #include <kmem.h> … … 33 35 #include <ppm.h> 34 36 #include <page.h> 37 38 #define VA_SIGN_MASK 0xffff000000000000 39 #define VA_SIGN_POS(va) ((va) & ~VA_SIGN_MASK) 40 41 #define pl1_i(VA) (((VA_SIGN_POS(VA)) & L1_FRAME) >> L1_SHIFT) 42 #define pl2_i(VA) (((VA_SIGN_POS(VA)) & L2_FRAME) >> L2_SHIFT) 43 #define pl3_i(VA) (((VA_SIGN_POS(VA)) & L3_FRAME) >> L3_SHIFT) 44 #define pl4_i(VA) (((VA_SIGN_POS(VA)) & L4_FRAME) >> L4_SHIFT) 45 46 paddr_t pa_avail __in_kdata = 0; 47 vaddr_t va_avail __in_kdata = 0; 48 vaddr_t tmpva __in_kdata = (KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2); 49 50 paddr_t hal_gpt_bootstrap_palloc(size_t npages) 51 { 52 paddr_t pa = pa_avail; 53 pa_avail += npages * PAGE_SIZE; 54 return pa; 55 } 56 57 vaddr_t hal_gpt_bootstrap_valloc(size_t npages) 58 { 59 vaddr_t va = va_avail; 60 va_avail += npages * PAGE_SIZE; 61 return va; 62 } 63 64 void hal_gpt_enter(vaddr_t va, paddr_t pa) 65 { 66 PTE_BASE[pl1_i(va)] = (pa & PG_FRAME) | PG_V | PG_KW | PG_NX; 67 } 68 69 /* 70 * Create a page tree that can map va_start->va_end. The caller can then 71 * enter these addresses to physical locations. 72 * 73 * This functions is a bit complicated, and may need to be revisited. 74 */ 75 void hal_gpt_maptree_area(vaddr_t va_start, vaddr_t va_end) 76 { 77 size_t L4start, L4end, nL4e; 78 size_t L3start, L3end, nL3e; 79 size_t L2start, L2end, nL2e; 80 paddr_t L3page, L2page, L1page; 81 paddr_t pa; 82 size_t i, npa; 83 pt_entry_t *pde; 84 85 /* Allocate L3 */ 86 L4start = pl4_i(va_start); 87 L4end = pl4_i(va_end); 88 nL4e = (L4end - L4start + 1); 89 L3page = hal_gpt_bootstrap_palloc(nL4e); 90 91 /* Allocate L2 */ 92 L3start = pl3_i(va_start); 93 L3end = pl3_i(va_end); 94 nL3e = (L3end - L3start + 1); 95 L2page = hal_gpt_bootstrap_palloc(nL3e); 96 97 /* Allocate L1 */ 98 L2start = pl2_i(va_start); 99 L2end = pl2_i(va_end); 100 nL2e = (L2end - L2start + 1); 101 L1page = hal_gpt_bootstrap_palloc(nL2e); 102 103 /* Zero out L1 */ 104 for (i = 0; i < nL2e; i++) { 105 pa = L1page + i * PAGE_SIZE; 106 hal_gpt_enter(tmpva, pa); 107 invlpg(tmpva); 108 109 memset((void *)tmpva, 0, PAGE_SIZE); 110 } 111 112 /* Zero out L2 */ 113 for (i = 0; i < nL3e; i++) { 114 pa = L2page + i * PAGE_SIZE; 115 hal_gpt_enter(tmpva, pa); 116 invlpg(tmpva); 117 118 memset((void *)tmpva, 0, PAGE_SIZE); 119 } 120 121 /* Zero out L3 */ 122 for (i = 0; i < nL4e; i++) { 123 pa = L3page + i * PAGE_SIZE; 124 hal_gpt_enter(tmpva, pa); 125 invlpg(tmpva); 126 127 memset((void *)tmpva, 0, PAGE_SIZE); 128 } 129 130 /* Create L2, linked to L1 */ 131 npa = (L2start / NPDPG) * PAGE_SIZE; 132 for (i = L2start; i <= L2end; i++) { 133 pa = (paddr_t)&(((pt_entry_t *)L2page)[i]); 134 pa -= npa; /* shift on the left */ 135 pa &= PG_FRAME; /* rounddown to a page boundary */ 136 hal_gpt_enter(tmpva, pa); 137 invlpg(tmpva); 138 139 pde = (pt_entry_t *)tmpva; 140 pa = L1page + (i - L2start) * PAGE_SIZE; 141 pde[i % NPDPG] = (pa & PG_FRAME) | PG_V | PG_KW; 142 } 143 144 /* Create L3, linked to L2 */ 145 npa = (L3start / NPDPG) * PAGE_SIZE; 146 for (i = L3start; i <= L3end; i++) { 147 pa = (paddr_t)&(((pt_entry_t *)L3page)[i]); 148 pa -= npa; /* shift on the left */ 149 pa &= PG_FRAME; /* rounddown to a page boundary */ 150 hal_gpt_enter(tmpva, pa); 151 invlpg(tmpva); 152 153 pde = (pt_entry_t *)tmpva; 154 pa = L2page + (i - L3start) * PAGE_SIZE; 155 pde[i % NPDPG] = (pa & PG_FRAME) | PG_V | PG_KW; 156 } 157 158 /* Link L3 into L4 */ 159 for (i = 0; i < nL4e; i++) { 160 pa = L3page + i * PAGE_SIZE; 161 L4_BASE[L4start + i] = (pa & PG_FRAME) | PG_V | PG_KW; 162 } 163 } 164 165 void hal_gpt_init(paddr_t firstpa) 166 { 167 pa_avail = firstpa; 168 va_avail = CLUSTER0_MIN_VA; 169 hal_gpt_maptree_area(CLUSTER0_MIN_VA, CLUSTER0_MAX_VA); 170 } 171 172 /* -------------------------------------------------------------------------- */ 35 173 36 174 /****************************************************************************************
Note: See TracChangeset
for help on using the changeset viewer.