pagetable_walker.cc (8949:3fa1ee293096) | pagetable_walker.cc (8953:488d45aeb672) |
---|---|
1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 40 unchanged lines hidden (view full) --- 49 * Authors: Gabe Black 50 */ 51 52#include "arch/x86/pagetable.hh" 53#include "arch/x86/pagetable_walker.hh" 54#include "arch/x86/tlb.hh" 55#include "arch/x86/vtophys.hh" 56#include "base/bitfield.hh" | 1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 40 unchanged lines hidden (view full) --- 49 * Authors: Gabe Black 50 */ 51 52#include "arch/x86/pagetable.hh" 53#include "arch/x86/pagetable_walker.hh" 54#include "arch/x86/tlb.hh" 55#include "arch/x86/vtophys.hh" 56#include "base/bitfield.hh" |
57#include "base/trie.hh" |
|
57#include "cpu/base.hh" 58#include "cpu/thread_context.hh" 59#include "debug/PageTableWalker.hh" 60#include "mem/packet_access.hh" 61#include "mem/request.hh" | 58#include "cpu/base.hh" 59#include "cpu/thread_context.hh" 60#include "debug/PageTableWalker.hh" 61#include "mem/packet_access.hh" 62#include "mem/request.hh" |
62#include "sim/system.hh" | |
63 64namespace X86ISA { 65 66// Unfortunately, the placement of the base field in a page table entry is 67// very erratic and would make a mess here. It might be moved here at some 68// point in the future. 69BitUnion64(PageTableEntry) 70 Bitfield<63> nx; --- 30 unchanged lines hidden (view full) --- 101 currStates.pop_front(); 102 delete newState; 103 } 104 return fault; 105 } 106} 107 108Fault | 63 64namespace X86ISA { 65 66// Unfortunately, the placement of the base field in a page table entry is 67// very erratic and would make a mess here. It might be moved here at some 68// point in the future. 69BitUnion64(PageTableEntry) 70 Bitfield<63> nx; --- 30 unchanged lines hidden (view full) --- 101 currStates.pop_front(); 102 delete newState; 103 } 104 return fault; 105 } 106} 107 108Fault |
109Walker::startFunctional(ThreadContext * _tc, Addr &addr, Addr &pageSize, | 109Walker::startFunctional(ThreadContext * _tc, Addr &addr, unsigned &logBytes, |
110 BaseTLB::Mode _mode) 111{ 112 funcState.initState(_tc, _mode); | 110 BaseTLB::Mode _mode) 111{ 112 funcState.initState(_tc, _mode); |
113 return funcState.startFunctional(addr, pageSize); | 113 return funcState.startFunctional(addr, logBytes); |
114} 115 116bool 117Walker::WalkerPort::recvTiming(PacketPtr pkt) 118{ 119 return walker->recvTiming(pkt); 120} 121 --- 97 unchanged lines hidden (view full) --- 219 } while(read); 220 state = Ready; 221 nextState = Waiting; 222 } 223 return fault; 224} 225 226Fault | 114} 115 116bool 117Walker::WalkerPort::recvTiming(PacketPtr pkt) 118{ 119 return walker->recvTiming(pkt); 120} 121 --- 97 unchanged lines hidden (view full) --- 219 } while(read); 220 state = Ready; 221 nextState = Waiting; 222 } 223 return fault; 224} 225 226Fault |
227Walker::WalkerState::startFunctional(Addr &addr, Addr &pageSize) | 227Walker::WalkerState::startFunctional(Addr &addr, unsigned &logBytes) |
228{ 229 Fault fault = NoFault; 230 assert(started == false); 231 started = true; 232 setupWalk(addr); 233 234 do { 235 walker->port.sendFunctional(read); 236 // On a functional access (page table lookup), writes should 237 // not happen so this pointer is ignored after stepWalk 238 PacketPtr write = NULL; 239 fault = stepWalk(write); 240 assert(fault == NoFault || read == NULL); 241 state = nextState; 242 nextState = Ready; 243 } while(read); | 228{ 229 Fault fault = NoFault; 230 assert(started == false); 231 started = true; 232 setupWalk(addr); 233 234 do { 235 walker->port.sendFunctional(read); 236 // On a functional access (page table lookup), writes should 237 // not happen so this pointer is ignored after stepWalk 238 PacketPtr write = NULL; 239 fault = stepWalk(write); 240 assert(fault == NoFault || read == NULL); 241 state = nextState; 242 nextState = Ready; 243 } while(read); |
244 pageSize = entry.size; | 244 logBytes = entry.logBytes; |
245 addr = entry.paddr; 246 247 return fault; 248} 249 250Fault 251Walker::WalkerState::stepWalk(PacketPtr &write) 252{ --- 53 unchanged lines hidden (view full) --- 306 entry.user = entry.user && pte.u; 307 if (badNX || !pte.p) { 308 doEndWalk = true; 309 fault = pageFault(pte.p); 310 break; 311 } 312 if (!pte.ps) { 313 // 4 KB page | 245 addr = entry.paddr; 246 247 return fault; 248} 249 250Fault 251Walker::WalkerState::stepWalk(PacketPtr &write) 252{ --- 53 unchanged lines hidden (view full) --- 306 entry.user = entry.user && pte.u; 307 if (badNX || !pte.p) { 308 doEndWalk = true; 309 fault = pageFault(pte.p); 310 break; 311 } 312 if (!pte.ps) { 313 // 4 KB page |
314 entry.size = 4 * (1 << 10); | 314 entry.logBytes = 12; |
315 nextRead = 316 ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl1 * dataSize; 317 nextState = LongPTE; 318 break; 319 } else { 320 // 2 MB page | 315 nextRead = 316 ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl1 * dataSize; 317 nextState = LongPTE; 318 break; 319 } else { 320 // 2 MB page |
321 entry.size = 2 * (1 << 20); | 321 entry.logBytes = 21; |
322 entry.paddr = (uint64_t)pte & (mask(31) << 21); 323 entry.uncacheable = uncacheable; 324 entry.global = pte.g; 325 entry.patBit = bits(pte, 12); 326 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 327 doTLBInsert = true; 328 doEndWalk = true; 329 break; --- 38 unchanged lines hidden (view full) --- 368 entry.user = pte.u; 369 if (badNX || !pte.p) { 370 doEndWalk = true; 371 fault = pageFault(pte.p); 372 break; 373 } 374 if (!pte.ps) { 375 // 4 KB page | 322 entry.paddr = (uint64_t)pte & (mask(31) << 21); 323 entry.uncacheable = uncacheable; 324 entry.global = pte.g; 325 entry.patBit = bits(pte, 12); 326 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 327 doTLBInsert = true; 328 doEndWalk = true; 329 break; --- 38 unchanged lines hidden (view full) --- 368 entry.user = pte.u; 369 if (badNX || !pte.p) { 370 doEndWalk = true; 371 fault = pageFault(pte.p); 372 break; 373 } 374 if (!pte.ps) { 375 // 4 KB page |
376 entry.size = 4 * (1 << 10); | 376 entry.logBytes = 12; |
377 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael1 * dataSize; 378 nextState = PAEPTE; 379 break; 380 } else { 381 // 2 MB page | 377 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael1 * dataSize; 378 nextState = PAEPTE; 379 break; 380 } else { 381 // 2 MB page |
382 entry.size = 2 * (1 << 20); | 382 entry.logBytes = 21; |
383 entry.paddr = (uint64_t)pte & (mask(31) << 21); 384 entry.uncacheable = uncacheable; 385 entry.global = pte.g; 386 entry.patBit = bits(pte, 12); 387 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 388 doTLBInsert = true; 389 doEndWalk = true; 390 break; --- 27 unchanged lines hidden (view full) --- 418 entry.user = pte.u; 419 if (!pte.p) { 420 doEndWalk = true; 421 fault = pageFault(pte.p); 422 break; 423 } 424 if (!pte.ps) { 425 // 4 KB page | 383 entry.paddr = (uint64_t)pte & (mask(31) << 21); 384 entry.uncacheable = uncacheable; 385 entry.global = pte.g; 386 entry.patBit = bits(pte, 12); 387 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); 388 doTLBInsert = true; 389 doEndWalk = true; 390 break; --- 27 unchanged lines hidden (view full) --- 418 entry.user = pte.u; 419 if (!pte.p) { 420 doEndWalk = true; 421 fault = pageFault(pte.p); 422 break; 423 } 424 if (!pte.ps) { 425 // 4 KB page |
426 entry.size = 4 * (1 << 10); | 426 entry.logBytes = 12; |
427 nextRead = 428 ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize; 429 nextState = PTE; 430 break; 431 } else { 432 // 4 MB page | 427 nextRead = 428 ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize; 429 nextState = PTE; 430 break; 431 } else { 432 // 4 MB page |
433 entry.size = 4 * (1 << 20); | 433 entry.logBytes = 21; |
434 entry.paddr = bits(pte, 20, 13) << 32 | bits(pte, 31, 22) << 22; 435 entry.uncacheable = uncacheable; 436 entry.global = pte.g; 437 entry.patBit = bits(pte, 12); 438 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1); 439 doTLBInsert = true; 440 doEndWalk = true; 441 break; --- 6 unchanged lines hidden (view full) --- 448 entry.writable = pte.w; 449 entry.user = pte.u; 450 if (!pte.p) { 451 doEndWalk = true; 452 fault = pageFault(pte.p); 453 break; 454 } 455 // 4 KB page | 434 entry.paddr = bits(pte, 20, 13) << 32 | bits(pte, 31, 22) << 22; 435 entry.uncacheable = uncacheable; 436 entry.global = pte.g; 437 entry.patBit = bits(pte, 12); 438 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1); 439 doTLBInsert = true; 440 doEndWalk = true; 441 break; --- 6 unchanged lines hidden (view full) --- 448 entry.writable = pte.w; 449 entry.user = pte.u; 450 if (!pte.p) { 451 doEndWalk = true; 452 fault = pageFault(pte.p); 453 break; 454 } 455 // 4 KB page |
456 entry.size = 4 * (1 << 10); | 456 entry.logBytes = 12; |
457 nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize; 458 nextState = PTE; 459 break; 460 case PTE: 461 DPRINTF(PageTableWalker, 462 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte); 463 doWrite = !pte.a; 464 pte.a = 1; --- 244 unchanged lines hidden --- | 457 nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * dataSize; 458 nextState = PTE; 459 break; 460 case PTE: 461 DPRINTF(PageTableWalker, 462 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte); 463 doWrite = !pte.a; 464 pte.a = 1; --- 244 unchanged lines hidden --- |