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 ---