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 --- 40 unchanged lines hidden (view full) --- 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/page_table.hh" |
58#include "mem/request.hh" 59#include "sim/full_system.hh" |
60#include "sim/process.hh" |
61 |
62namespace X86ISA { 63 64TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) 65{ 66 tlb = new TlbEntry[size]; 67 std::memset(tlb, 0, sizeof(TlbEntry) * size); 68 69 for (int x = 0; x < size; x++) --- 223 unchanged lines hidden (view full) --- 293 if (timing || fault != NoFault) { 294 // This gets ignored in atomic mode. 295 delayedResponse = true; 296 return fault; 297 } 298 entry = lookup(vaddr); 299 assert(entry); 300 } else { |
301 DPRINTF(TLB, "Handling a TLB miss for " 302 "address %#x at pc %#x.\n", 303 vaddr, tc->instAddr()); 304 305 Process *p = tc->getProcessPtr(); 306 TlbEntry newEntry; 307 bool success = p->pTable->lookup(vaddr, newEntry); 308 if (!success && mode != Execute) { --- 7 unchanged lines hidden (view full) --- 316 return new PageFault(vaddr, true, mode, true, false); 317 } else { 318 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 319 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 320 newEntry.pageStart()); 321 entry = insert(alignedVaddr, newEntry); 322 } 323 DPRINTF(TLB, "Miss was serviced.\n"); |
324 } 325 } 326 // Do paging protection checks. 327 bool inUser = (m5Reg.cpl == 3 && 328 !(flags & (CPL0FlagBit << FlagShift))); 329 CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 330 bool badWrite = (!entry->writable && (inUser || cr0.wp)); 331 if ((inUser && !entry->user) || (mode == Write && badWrite)) { --- 24 unchanged lines hidden (view full) --- 356 } 357 } else { 358 // Real mode 359 DPRINTF(TLB, "In real mode.\n"); 360 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); 361 req->setPaddr(vaddr); 362 } 363 // Check for an access to the local APIC |
364 if (FullSystem) { 365 LocalApicBase localApicBase = 366 tc->readMiscRegNoEffect(MISCREG_APIC_BASE); 367 Addr baseAddr = localApicBase.base * PageBytes; 368 Addr paddr = req->getPaddr(); 369 if (baseAddr <= paddr && baseAddr + PageBytes > paddr) { 370 // The Intel developer's manuals say the below restrictions apply, 371 // but the linux kernel, because of a compiler optimization, breaks 372 // them. 373 /* 374 // Check alignment 375 if (paddr & ((32/8) - 1)) 376 return new GeneralProtection(0); 377 // Check access size 378 if (req->getSize() != (32/8)) 379 return new GeneralProtection(0); 380 */ 381 // Force the access to be uncacheable. 382 req->setFlags(Request::UNCACHEABLE); 383 req->setPaddr(x86LocalAPICAddress(tc->contextId(), 384 paddr - baseAddr)); 385 } |
386 } |
387 return NoFault; 388}; 389 390Fault 391TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 392{ 393 bool delayedResponse; 394 return TLB::translate(req, tc, NULL, mode, delayedResponse, false); --- 53 unchanged lines hidden --- |