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