1/* 2 * Copyright (c) 2007 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 87 unchanged lines hidden (view full) --- 96 pte = read->get<uint32_t>(); 97 VAddr vaddr = entry.vaddr; 98 bool uncacheable = pte.pcd; 99 Addr nextRead = 0; 100 bool doWrite = false; 101 bool badNX = pte.nx && (!tlb->allowNX() || !enableNX); 102 switch(state) { 103 case LongPML4: |
104 DPRINTF(PageTableWalker, 105 "Got long mode PML4 entry %#016x.\n", (uint64_t)pte); |
106 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * size; 107 doWrite = !pte.a; 108 pte.a = 1; 109 entry.writable = pte.w; 110 entry.user = pte.u; 111 if (badNX || !pte.p) { 112 stop(); 113 return pageFault(pte.p); 114 } 115 entry.noExec = pte.nx; 116 nextState = LongPDP; 117 break; 118 case LongPDP: |
119 DPRINTF(PageTableWalker, 120 "Got long mode PDP entry %#016x.\n", (uint64_t)pte); |
121 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * size; 122 doWrite = !pte.a; 123 pte.a = 1; 124 entry.writable = entry.writable && pte.w; 125 entry.user = entry.user && pte.u; 126 if (badNX || !pte.p) { 127 stop(); 128 return pageFault(pte.p); 129 } 130 nextState = LongPD; 131 break; 132 case LongPD: |
133 DPRINTF(PageTableWalker, 134 "Got long mode PD entry %#016x.\n", (uint64_t)pte); |
135 doWrite = !pte.a; 136 pte.a = 1; 137 entry.writable = entry.writable && pte.w; 138 entry.user = entry.user && pte.u; 139 if (badNX || !pte.p) { 140 stop(); 141 return pageFault(pte.p); 142 } --- 12 unchanged lines hidden (view full) --- 155 entry.global = pte.g; 156 entry.patBit = bits(pte, 12); 157 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 158 tlb->insert(entry.vaddr, entry); 159 stop(); 160 return NoFault; 161 } 162 case LongPTE: |
163 DPRINTF(PageTableWalker, 164 "Got long mode PTE entry %#016x.\n", (uint64_t)pte); |
165 doWrite = !pte.a; 166 pte.a = 1; 167 entry.writable = entry.writable && pte.w; 168 entry.user = entry.user && pte.u; 169 if (badNX || !pte.p) { 170 stop(); 171 return pageFault(pte.p); 172 } 173 entry.paddr = (uint64_t)pte & (mask(40) << 12); 174 entry.uncacheable = uncacheable; 175 entry.global = pte.g; 176 entry.patBit = bits(pte, 12); 177 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); 178 tlb->insert(entry.vaddr, entry); 179 stop(); 180 return NoFault; 181 case PAEPDP: |
182 DPRINTF(PageTableWalker, 183 "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte); |
184 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size; 185 if (!pte.p) { 186 stop(); 187 return pageFault(pte.p); 188 } 189 nextState = PAEPD; 190 break; 191 case PAEPD: |
192 DPRINTF(PageTableWalker, 193 "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte); |
194 doWrite = !pte.a; 195 pte.a = 1; 196 entry.writable = pte.w; 197 entry.user = pte.u; 198 if (badNX || !pte.p) { 199 stop(); 200 return pageFault(pte.p); 201 } --- 11 unchanged lines hidden (view full) --- 213 entry.global = pte.g; 214 entry.patBit = bits(pte, 12); 215 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 216 tlb->insert(entry.vaddr, entry); 217 stop(); 218 return NoFault; 219 } 220 case PAEPTE: |
221 DPRINTF(PageTableWalker, 222 "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte); |
223 doWrite = !pte.a; 224 pte.a = 1; 225 entry.writable = entry.writable && pte.w; 226 entry.user = entry.user && pte.u; 227 if (badNX || !pte.p) { 228 stop(); 229 return pageFault(pte.p); 230 } 231 entry.paddr = (uint64_t)pte & (mask(40) << 12); 232 entry.uncacheable = uncacheable; 233 entry.global = pte.g; 234 entry.patBit = bits(pte, 7); 235 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); 236 tlb->insert(entry.vaddr, entry); 237 stop(); 238 return NoFault; 239 case PSEPD: |
240 DPRINTF(PageTableWalker, 241 "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte); |
242 doWrite = !pte.a; 243 pte.a = 1; 244 entry.writable = pte.w; 245 entry.user = pte.u; 246 if (!pte.p) { 247 stop(); 248 return pageFault(pte.p); 249 } --- 12 unchanged lines hidden (view full) --- 262 entry.global = pte.g; 263 entry.patBit = bits(pte, 12); 264 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1); 265 tlb->insert(entry.vaddr, entry); 266 stop(); 267 return NoFault; 268 } 269 case PD: |
270 DPRINTF(PageTableWalker, 271 "Got legacy mode PD entry %#08x.\n", (uint32_t)pte); |
272 doWrite = !pte.a; 273 pte.a = 1; 274 entry.writable = pte.w; 275 entry.user = pte.u; 276 if (!pte.p) { 277 stop(); 278 return pageFault(pte.p); 279 } 280 // 4 KB page 281 entry.size = 4 * (1 << 10); 282 nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * size; 283 nextState = PTE; 284 break; 285 case PTE: |
286 DPRINTF(PageTableWalker, 287 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte); |
288 doWrite = !pte.a; 289 pte.a = 1; 290 entry.writable = pte.w; 291 entry.user = pte.u; 292 if (!pte.p) { 293 stop(); 294 return pageFault(pte.p); 295 } --- 260 unchanged lines hidden (view full) --- 556 return &port; 557 else 558 panic("No page table walker port named %s!\n", if_name); 559} 560 561Fault 562Walker::pageFault(bool present) 563{ |
564 DPRINTF(PageTableWalker, "Raising page fault.\n"); |
565 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 566 return new PageFault(entry.vaddr, present, write, 567 m5reg.cpl == 3, false, execute && enableNX); 568} 569 570} 571 572X86ISA::Walker * 573X86PagetableWalkerParams::create() 574{ 575 return new X86ISA::Walker(this); 576} |