tlb.cc (8646:ef6cbf0f14dc) | tlb.cc (8752:28e899b7dee3) |
---|---|
1/* 2 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company 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 --- 30 unchanged lines hidden (view full) --- 39 40#include <cstring> 41 42#include "arch/x86/insts/microldstop.hh" 43#include "arch/x86/regs/misc.hh" 44#include "arch/x86/regs/msr.hh" 45#include "arch/x86/faults.hh" 46#include "arch/x86/pagetable.hh" | 1/* 2 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company 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 --- 30 unchanged lines hidden (view full) --- 39 40#include <cstring> 41 42#include "arch/x86/insts/microldstop.hh" 43#include "arch/x86/regs/misc.hh" 44#include "arch/x86/regs/msr.hh" 45#include "arch/x86/faults.hh" 46#include "arch/x86/pagetable.hh" |
47#include "arch/x86/pagetable_walker.hh" |
|
47#include "arch/x86/tlb.hh" 48#include "arch/x86/x86_traits.hh" 49#include "base/bitfield.hh" 50#include "base/trace.hh" 51#include "config/full_system.hh" 52#include "cpu/base.hh" 53#include "cpu/thread_context.hh" 54#include "debug/TLB.hh" 55#include "mem/packet_access.hh" 56#include "mem/request.hh" 57 | 48#include "arch/x86/tlb.hh" 49#include "arch/x86/x86_traits.hh" 50#include "base/bitfield.hh" 51#include "base/trace.hh" 52#include "config/full_system.hh" 53#include "cpu/base.hh" 54#include "cpu/thread_context.hh" 55#include "debug/TLB.hh" 56#include "mem/packet_access.hh" 57#include "mem/request.hh" 58 |
58#if FULL_SYSTEM 59#include "arch/x86/pagetable_walker.hh" 60#else | 59#if !FULL_SYSTEM |
61#include "mem/page_table.hh" 62#include "sim/process.hh" 63#endif 64 | 60#include "mem/page_table.hh" 61#include "sim/process.hh" 62#endif 63 |
64#include "sim/full_system.hh" 65 |
|
65namespace X86ISA { 66 67TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) 68{ 69 tlb = new TlbEntry[size]; 70 std::memset(tlb, 0, sizeof(TlbEntry) * size); 71 72 for (int x = 0; x < size; x++) 73 freeList.push_back(&tlb[x]); 74 | 66namespace X86ISA { 67 68TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) 69{ 70 tlb = new TlbEntry[size]; 71 std::memset(tlb, 0, sizeof(TlbEntry) * size); 72 73 for (int x = 0; x < size; x++) 74 freeList.push_back(&tlb[x]); 75 |
75#if FULL_SYSTEM | |
76 walker = p->walker; 77 walker->setTLB(this); | 76 walker = p->walker; 77 walker->setTLB(this); |
78#endif | |
79} 80 81TlbEntry * 82TLB::insert(Addr vpn, TlbEntry &entry) 83{ 84 //TODO Deal with conflicting entries 85 86 TlbEntry *newEntry = NULL; --- 201 unchanged lines hidden (view full) --- 288 } 289 } 290 // If paging is enabled, do the translation. 291 if (m5Reg.paging) { 292 DPRINTF(TLB, "Paging enabled.\n"); 293 // The vaddr already has the segment base applied. 294 TlbEntry *entry = lookup(vaddr); 295 if (!entry) { | 78} 79 80TlbEntry * 81TLB::insert(Addr vpn, TlbEntry &entry) 82{ 83 //TODO Deal with conflicting entries 84 85 TlbEntry *newEntry = NULL; --- 201 unchanged lines hidden (view full) --- 287 } 288 } 289 // If paging is enabled, do the translation. 290 if (m5Reg.paging) { 291 DPRINTF(TLB, "Paging enabled.\n"); 292 // The vaddr already has the segment base applied. 293 TlbEntry *entry = lookup(vaddr); 294 if (!entry) { |
296#if FULL_SYSTEM 297 Fault fault = walker->start(tc, translation, req, mode); 298 if (timing || fault != NoFault) { 299 // This gets ignored in atomic mode. 300 delayedResponse = true; 301 return fault; 302 } 303 entry = lookup(vaddr); 304 assert(entry); 305#else 306 DPRINTF(TLB, "Handling a TLB miss for " 307 "address %#x at pc %#x.\n", 308 vaddr, tc->instAddr()); 309 310 Process *p = tc->getProcessPtr(); 311 TlbEntry newEntry; 312 bool success = p->pTable->lookup(vaddr, newEntry); 313 if (!success && mode != Execute) { 314 // Check if we just need to grow the stack. 315 if (p->fixupStackFault(vaddr)) { 316 // If we did, lookup the entry for the new page. 317 success = p->pTable->lookup(vaddr, newEntry); | 295 if (FullSystem) { 296 Fault fault = walker->start(tc, translation, req, mode); 297 if (timing || fault != NoFault) { 298 // This gets ignored in atomic mode. 299 delayedResponse = true; 300 return fault; |
318 } | 301 } |
319 } 320 if (!success) { 321 return new PageFault(vaddr, true, mode, true, false); | 302 entry = lookup(vaddr); 303 assert(entry); |
322 } else { | 304 } else { |
323 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 324 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 325 newEntry.pageStart()); 326 entry = insert(alignedVaddr, newEntry); 327 } 328 DPRINTF(TLB, "Miss was serviced.\n"); | 305#if !FULL_SYSTEM 306 DPRINTF(TLB, "Handling a TLB miss for " 307 "address %#x at pc %#x.\n", 308 vaddr, tc->instAddr()); 309 310 Process *p = tc->getProcessPtr(); 311 TlbEntry newEntry; 312 bool success = p->pTable->lookup(vaddr, newEntry); 313 if (!success && mode != Execute) { 314 // Check if we just need to grow the stack. 315 if (p->fixupStackFault(vaddr)) { 316 // If we did, lookup the entry for the new page. 317 success = p->pTable->lookup(vaddr, newEntry); 318 } 319 } 320 if (!success) { 321 return new PageFault(vaddr, true, mode, true, false); 322 } else { 323 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 324 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 325 newEntry.pageStart()); 326 entry = insert(alignedVaddr, newEntry); 327 } 328 DPRINTF(TLB, "Miss was serviced.\n"); |
329#endif | 329#endif |
330 } |
|
330 } | 331 } |
331 332 DPRINTF(TLB, "Entry found with paddr %#x, " 333 "doing protection checks.\n", entry->paddr); | |
334 // Do paging protection checks. 335 bool inUser = (m5Reg.cpl == 3 && 336 !(flags & (CPL0FlagBit << FlagShift))); 337 CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 338 bool badWrite = (!entry->writable && (inUser || cr0.wp)); 339 if ((inUser && !entry->user) || (mode == Write && badWrite)) { 340 // The page must have been present to get into the TLB in 341 // the first place. We'll assume the reserved bits are 342 // fine even though we're not checking them. 343 return new PageFault(vaddr, true, mode, inUser, false); 344 } 345 if (storeCheck && badWrite) { 346 // This would fault if this were a write, so return a page 347 // fault that reflects that happening. 348 return new PageFault(vaddr, true, Write, inUser, false); 349 } 350 | 332 // Do paging protection checks. 333 bool inUser = (m5Reg.cpl == 3 && 334 !(flags & (CPL0FlagBit << FlagShift))); 335 CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 336 bool badWrite = (!entry->writable && (inUser || cr0.wp)); 337 if ((inUser && !entry->user) || (mode == Write && badWrite)) { 338 // The page must have been present to get into the TLB in 339 // the first place. We'll assume the reserved bits are 340 // fine even though we're not checking them. 341 return new PageFault(vaddr, true, mode, inUser, false); 342 } 343 if (storeCheck && badWrite) { 344 // This would fault if this were a write, so return a page 345 // fault that reflects that happening. 346 return new PageFault(vaddr, true, Write, inUser, false); 347 } 348 |
349 350 DPRINTF(TLB, "Entry found with paddr %#x, " 351 "doing protection checks.\n", entry->paddr); |
|
351 Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 352 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 353 req->setPaddr(paddr); 354 if (entry->uncacheable) 355 req->setFlags(Request::UNCACHEABLE); 356 } else { 357 //Use the address which already has segmentation applied. 358 DPRINTF(TLB, "Paging disabled.\n"); --- 92 unchanged lines hidden --- | 352 Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 353 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 354 req->setPaddr(paddr); 355 if (entry->uncacheable) 356 req->setFlags(Request::UNCACHEABLE); 357 } else { 358 //Use the address which already has segmentation applied. 359 DPRINTF(TLB, "Paging disabled.\n"); --- 92 unchanged lines hidden --- |