tlb.cc (6022:410194bb3049) | tlb.cc (6023:47b4fcb10c11) |
---|---|
1/* 2 * Copyright (c) 2007-2008 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 * --- 172 unchanged lines hidden (view full) --- 181 EntryList::iterator entry = lookupIt(va, false); 182 if (entry != entryList.end()) { 183 freeList.push_back(*entry); 184 entryList.erase(entry); 185 } 186} 187 188Fault | 1/* 2 * Copyright (c) 2007-2008 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 * --- 172 unchanged lines hidden (view full) --- 181 EntryList::iterator entry = lookupIt(va, false); 182 if (entry != entryList.end()) { 183 freeList.push_back(*entry); 184 entryList.erase(entry); 185 } 186} 187 188Fault |
189TLB::translate(RequestPtr req, ThreadContext *tc, 190 Translation *translation, bool write, bool execute, 191 bool &delayedResponse, bool timing) | 189TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, 190 Mode mode, bool &delayedResponse, bool timing) |
192{ 193 delayedResponse = false; 194 Addr vaddr = req->getVaddr(); 195 DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); 196 uint32_t flags = req->getFlags(); 197 bool storeCheck = flags & StoreCheck; 198 199 int seg = flags & SegmentFlagMask; --- 372 unchanged lines hidden (view full) --- 572 if (!efer.lma || !csAttr.longMode) { 573 DPRINTF(TLB, "Not in long mode. Checking segment protection.\n"); 574 // Check for a NULL segment selector. 575 if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) 576 return new GeneralProtection(0); 577 bool expandDown = false; 578 SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); 579 if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { | 191{ 192 delayedResponse = false; 193 Addr vaddr = req->getVaddr(); 194 DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); 195 uint32_t flags = req->getFlags(); 196 bool storeCheck = flags & StoreCheck; 197 198 int seg = flags & SegmentFlagMask; --- 372 unchanged lines hidden (view full) --- 571 if (!efer.lma || !csAttr.longMode) { 572 DPRINTF(TLB, "Not in long mode. Checking segment protection.\n"); 573 // Check for a NULL segment selector. 574 if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) 575 return new GeneralProtection(0); 576 bool expandDown = false; 577 SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); 578 if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { |
580 if (!attr.writable && write) | 579 if (!attr.writable && mode == Write) |
581 return new GeneralProtection(0); | 580 return new GeneralProtection(0); |
582 if (!attr.readable && !write && !execute) | 581 if (!attr.readable && mode == Read) |
583 return new GeneralProtection(0); 584 expandDown = attr.expandDown; 585 586 } 587 Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg)); 588 Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg)); 589 // This assumes we're not in 64 bit mode. If we were, the default 590 // address size is 64 bits, overridable to 32. --- 16 unchanged lines hidden (view full) --- 607 } 608 // If paging is enabled, do the translation. 609 if (cr0.pg) { 610 DPRINTF(TLB, "Paging enabled.\n"); 611 // The vaddr already has the segment base applied. 612 TlbEntry *entry = lookup(vaddr); 613 if (!entry) { 614#if FULL_SYSTEM | 582 return new GeneralProtection(0); 583 expandDown = attr.expandDown; 584 585 } 586 Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg)); 587 Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg)); 588 // This assumes we're not in 64 bit mode. If we were, the default 589 // address size is 64 bits, overridable to 32. --- 16 unchanged lines hidden (view full) --- 606 } 607 // If paging is enabled, do the translation. 608 if (cr0.pg) { 609 DPRINTF(TLB, "Paging enabled.\n"); 610 // The vaddr already has the segment base applied. 611 TlbEntry *entry = lookup(vaddr); 612 if (!entry) { 613#if FULL_SYSTEM |
615 Fault fault = walker->start(tc, translation, req, 616 write, execute); | 614 Fault fault = walker->start(tc, translation, req, mode); |
617 if (timing || fault != NoFault) { 618 // This gets ignored in atomic mode. 619 delayedResponse = true; 620 return fault; 621 } 622 entry = lookup(vaddr); 623 assert(entry); 624#else 625 DPRINTF(TLB, "Handling a TLB miss for " 626 "address %#x at pc %#x.\n", 627 vaddr, tc->readPC()); 628 629 Process *p = tc->getProcessPtr(); 630 TlbEntry newEntry; 631 bool success = p->pTable->lookup(vaddr, newEntry); | 615 if (timing || fault != NoFault) { 616 // This gets ignored in atomic mode. 617 delayedResponse = true; 618 return fault; 619 } 620 entry = lookup(vaddr); 621 assert(entry); 622#else 623 DPRINTF(TLB, "Handling a TLB miss for " 624 "address %#x at pc %#x.\n", 625 vaddr, tc->readPC()); 626 627 Process *p = tc->getProcessPtr(); 628 TlbEntry newEntry; 629 bool success = p->pTable->lookup(vaddr, newEntry); |
632 if(!success && !execute) { | 630 if(!success && mode != Execute) { |
633 p->checkAndAllocNextPage(vaddr); 634 success = p->pTable->lookup(vaddr, newEntry); 635 } 636 if(!success) { 637 panic("Tried to execute unmapped address %#x.\n", vaddr); 638 } else { 639 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 640 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 641 newEntry.pageStart()); 642 entry = insert(alignedVaddr, newEntry); 643 } 644 DPRINTF(TLB, "Miss was serviced.\n"); 645#endif 646 } 647 // Do paging protection checks. 648 bool inUser = (csAttr.dpl == 3 && 649 !(flags & (CPL0FlagBit << FlagShift))); 650 if ((inUser && !entry->user) || | 631 p->checkAndAllocNextPage(vaddr); 632 success = p->pTable->lookup(vaddr, newEntry); 633 } 634 if(!success) { 635 panic("Tried to execute unmapped address %#x.\n", vaddr); 636 } else { 637 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 638 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 639 newEntry.pageStart()); 640 entry = insert(alignedVaddr, newEntry); 641 } 642 DPRINTF(TLB, "Miss was serviced.\n"); 643#endif 644 } 645 // Do paging protection checks. 646 bool inUser = (csAttr.dpl == 3 && 647 !(flags & (CPL0FlagBit << FlagShift))); 648 if ((inUser && !entry->user) || |
651 (write && !entry->writable)) { | 649 (mode == Write && !entry->writable)) { |
652 // The page must have been present to get into the TLB in 653 // the first place. We'll assume the reserved bits are 654 // fine even though we're not checking them. | 650 // The page must have been present to get into the TLB in 651 // the first place. We'll assume the reserved bits are 652 // fine even though we're not checking them. |
655 return new PageFault(vaddr, true, write, 656 inUser, false, execute); | 653 return new PageFault(vaddr, true, mode, inUser, false); |
657 } 658 659 660 DPRINTF(TLB, "Entry found with paddr %#x, " 661 "doing protection checks.\n", entry->paddr); 662 Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 663 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 664 req->setPaddr(paddr); --- 30 unchanged lines hidden (view full) --- 695 req->setFlags(Request::UNCACHEABLE); 696 req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr)); 697 } 698#endif 699 return NoFault; 700}; 701 702Fault | 654 } 655 656 657 DPRINTF(TLB, "Entry found with paddr %#x, " 658 "doing protection checks.\n", entry->paddr); 659 Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 660 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 661 req->setPaddr(paddr); --- 30 unchanged lines hidden (view full) --- 692 req->setFlags(Request::UNCACHEABLE); 693 req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr)); 694 } 695#endif 696 return NoFault; 697}; 698 699Fault |
703TLB::translateAtomic(RequestPtr req, ThreadContext *tc, 704 bool write, bool execute) | 700TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) |
705{ 706 bool delayedResponse; | 701{ 702 bool delayedResponse; |
707 return TLB::translate(req, tc, NULL, write, 708 execute, delayedResponse, false); | 703 return TLB::translate(req, tc, NULL, mode, delayedResponse, false); |
709} 710 711void 712TLB::translateTiming(RequestPtr req, ThreadContext *tc, | 704} 705 706void 707TLB::translateTiming(RequestPtr req, ThreadContext *tc, |
713 Translation *translation, bool write, bool execute) | 708 Translation *translation, Mode mode) |
714{ 715 bool delayedResponse; 716 assert(translation); | 709{ 710 bool delayedResponse; 711 assert(translation); |
717 Fault fault = TLB::translate(req, tc, translation, 718 write, execute, delayedResponse, true); | 712 Fault fault = 713 TLB::translate(req, tc, translation, mode, delayedResponse, true); |
719 if (!delayedResponse) | 714 if (!delayedResponse) |
720 translation->finish(fault, req, tc, write, execute); | 715 translation->finish(fault, req, tc, mode); |
721} 722 723#if FULL_SYSTEM 724 725Tick 726TLB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 727{ 728 return tc->getCpuPtr()->ticks(1); --- 27 unchanged lines hidden --- | 716} 717 718#if FULL_SYSTEM 719 720Tick 721TLB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 722{ 723 return tc->getCpuPtr()->ticks(1); --- 27 unchanged lines hidden --- |