tlb.cc (5894:8091ac99341a) tlb.cc (5895:569e3b31a868)
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 *

--- 58 unchanged lines hidden (view full) ---

67#include "config/full_system.hh"
68#include "cpu/thread_context.hh"
69#include "cpu/base.hh"
70#include "mem/packet_access.hh"
71#include "mem/request.hh"
72
73#if FULL_SYSTEM
74#include "arch/x86/pagetable_walker.hh"
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 *

--- 58 unchanged lines hidden (view full) ---

67#include "config/full_system.hh"
68#include "cpu/thread_context.hh"
69#include "cpu/base.hh"
70#include "mem/packet_access.hh"
71#include "mem/request.hh"
72
73#if FULL_SYSTEM
74#include "arch/x86/pagetable_walker.hh"
75#else
76#include "mem/page_table.hh"
77#include "sim/process.hh"
75#endif
76
77namespace X86ISA {
78
79TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size)
80{
81 tlb = new TlbEntry[size];
82 std::memset(tlb, 0, sizeof(TlbEntry) * size);
83
84 for (int x = 0; x < size; x++)
85 freeList.push_back(&tlb[x]);
86
87#if FULL_SYSTEM
88 walker = p->walker;
89 walker->setTLB(this);
90#endif
91}
92
78#endif
79
80namespace X86ISA {
81
82TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size)
83{
84 tlb = new TlbEntry[size];
85 std::memset(tlb, 0, sizeof(TlbEntry) * size);
86
87 for (int x = 0; x < size; x++)
88 freeList.push_back(&tlb[x]);
89
90#if FULL_SYSTEM
91 walker = p->walker;
92 walker->setTLB(this);
93#endif
94}
95
93void
96TlbEntry *
94TLB::insert(Addr vpn, TlbEntry &entry)
95{
96 //TODO Deal with conflicting entries
97
98 TlbEntry *newEntry = NULL;
99 if (!freeList.empty()) {
100 newEntry = freeList.front();
101 freeList.pop_front();
102 } else {
103 newEntry = entryList.back();
104 entryList.pop_back();
105 }
106 *newEntry = entry;
107 newEntry->vaddr = vpn;
108 entryList.push_front(newEntry);
97TLB::insert(Addr vpn, TlbEntry &entry)
98{
99 //TODO Deal with conflicting entries
100
101 TlbEntry *newEntry = NULL;
102 if (!freeList.empty()) {
103 newEntry = freeList.front();
104 freeList.pop_front();
105 } else {
106 newEntry = entryList.back();
107 entryList.pop_back();
108 }
109 *newEntry = entry;
110 newEntry->vaddr = vpn;
111 entryList.push_front(newEntry);
112 return newEntry;
109}
110
111TLB::EntryList::iterator
112TLB::lookupIt(Addr va, bool update_lru)
113{
114 //TODO make this smarter at some point
115 EntryList::iterator entry;
116 for (entry = entryList.begin(); entry != entryList.end(); entry++) {

--- 16 unchanged lines hidden (view full) ---

133{
134 EntryList::iterator entry = lookupIt(va, update_lru);
135 if (entry == entryList.end())
136 return NULL;
137 else
138 return *entry;
139}
140
113}
114
115TLB::EntryList::iterator
116TLB::lookupIt(Addr va, bool update_lru)
117{
118 //TODO make this smarter at some point
119 EntryList::iterator entry;
120 for (entry = entryList.begin(); entry != entryList.end(); entry++) {

--- 16 unchanged lines hidden (view full) ---

137{
138 EntryList::iterator entry = lookupIt(va, update_lru);
139 if (entry == entryList.end())
140 return NULL;
141 else
142 return *entry;
143}
144
141#if FULL_SYSTEM
142void
145void
143TLB::walk(ThreadContext * _tc, Addr vaddr, bool write, bool execute)
144{
145 walker->start(_tc, vaddr, write, execute);
146}
147#endif
148
149void
150TLB::invalidateAll()
151{
152 DPRINTF(TLB, "Invalidating all entries.\n");
153 while (!entryList.empty()) {
154 TlbEntry *entry = entryList.front();
155 entryList.pop_front();
156 freeList.push_back(entry);
157 }

--- 25 unchanged lines hidden (view full) ---

183{
184 EntryList::iterator entry = lookupIt(va, false);
185 if (entry != entryList.end()) {
186 freeList.push_back(*entry);
187 entryList.erase(entry);
188 }
189}
190
146TLB::invalidateAll()
147{
148 DPRINTF(TLB, "Invalidating all entries.\n");
149 while (!entryList.empty()) {
150 TlbEntry *entry = entryList.front();
151 entryList.pop_front();
152 freeList.push_back(entry);
153 }

--- 25 unchanged lines hidden (view full) ---

179{
180 EntryList::iterator entry = lookupIt(va, false);
181 if (entry != entryList.end()) {
182 freeList.push_back(*entry);
183 entryList.erase(entry);
184 }
185}
186
191template<class TlbFault>
192Fault
187Fault
193TLB::translateAtomic(RequestPtr req, ThreadContext *tc,
194 bool write, bool execute)
188TLB::translate(RequestPtr req, ThreadContext *tc,
189 Translation *translation, bool write, bool execute,
190 bool &delayedResponse, bool timing)
195{
191{
192 delayedResponse = false;
196 Addr vaddr = req->getVaddr();
197 DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
198 uint32_t flags = req->getFlags();
199 bool storeCheck = flags & StoreCheck;
200
201 int seg = flags & mask(4);
202
203 //XXX Junk code to surpress the warning

--- 408 unchanged lines hidden (view full) ---

612 }
613 }
614 // If paging is enabled, do the translation.
615 if (cr0.pg) {
616 DPRINTF(TLB, "Paging enabled.\n");
617 // The vaddr already has the segment base applied.
618 TlbEntry *entry = lookup(vaddr);
619 if (!entry) {
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 & mask(4);
199
200 //XXX Junk code to surpress the warning

--- 408 unchanged lines hidden (view full) ---

609 }
610 }
611 // If paging is enabled, do the translation.
612 if (cr0.pg) {
613 DPRINTF(TLB, "Paging enabled.\n");
614 // The vaddr already has the segment base applied.
615 TlbEntry *entry = lookup(vaddr);
616 if (!entry) {
620 return new TlbFault(vaddr, write, execute);
621 } else {
622 // Do paging protection checks.
623 DPRINTF(TLB, "Entry found with paddr %#x, doing protection checks.\n", entry->paddr);
624 Addr paddr = entry->paddr | (vaddr & (entry->size-1));
625 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr);
626 req->setPaddr(paddr);
617#if FULL_SYSTEM
618 Fault fault = walker->start(tc, translation, req,
619 write, execute);
620 if (timing || fault != NoFault) {
621 // This gets ignored in atomic mode.
622 delayedResponse = true;
623 return fault;
624 }
625 entry = lookup(vaddr);
626 assert(entry);
627#else
628 DPRINTF(TLB, "Handling a TLB miss for "
629 "address %#x at pc %#x.\n",
630 vaddr, tc->readPC());
631
632 Process *p = tc->getProcessPtr();
633 TlbEntry newEntry;
634 bool success = p->pTable->lookup(vaddr, newEntry);
635 if(!success && !execute) {
636 p->checkAndAllocNextPage(vaddr);
637 success = p->pTable->lookup(vaddr, newEntry);
638 }
639 if(!success) {
640 panic("Tried to execute unmapped address %#x.\n", vaddr);
641 } else {
642 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
643 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
644 newEntry.pageStart());
645 entry = insert(alignedVaddr, newEntry);
646 }
647 DPRINTF(TLB, "Miss was serviced.\n");
648#endif
627 }
649 }
650 // Do paging protection checks.
651 DPRINTF(TLB, "Entry found with paddr %#x, "
652 "doing protection checks.\n", entry->paddr);
653 Addr paddr = entry->paddr | (vaddr & (entry->size-1));
654 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr);
655 req->setPaddr(paddr);
628 } else {
629 //Use the address which already has segmentation applied.
630 DPRINTF(TLB, "Paging disabled.\n");
631 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr);
632 req->setPaddr(vaddr);
633 }
634 } else {
635 // Real mode

--- 24 unchanged lines hidden (view full) ---

660 }
661#endif
662 return NoFault;
663};
664
665Fault
666DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
667{
656 } else {
657 //Use the address which already has segmentation applied.
658 DPRINTF(TLB, "Paging disabled.\n");
659 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr);
660 req->setPaddr(vaddr);
661 }
662 } else {
663 // Real mode

--- 24 unchanged lines hidden (view full) ---

688 }
689#endif
690 return NoFault;
691};
692
693Fault
694DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write)
695{
668 return TLB::translateAtomic<FakeDTLBFault>(req, tc, write, false);
696 bool delayedResponse;
697 return TLB::translate(req, tc, NULL, write,
698 false, delayedResponse, false);
669}
670
671void
672DTB::translateTiming(RequestPtr req, ThreadContext *tc,
673 Translation *translation, bool write)
674{
699}
700
701void
702DTB::translateTiming(RequestPtr req, ThreadContext *tc,
703 Translation *translation, bool write)
704{
705 bool delayedResponse;
675 assert(translation);
706 assert(translation);
676 translation->finish(translateAtomic(req, tc, write), req, tc, write);
707 Fault fault = TLB::translate(req, tc, translation,
708 write, false, delayedResponse, true);
709 if (!delayedResponse)
710 translation->finish(fault, req, tc, write);
677}
678
679Fault
680ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
681{
711}
712
713Fault
714ITB::translateAtomic(RequestPtr req, ThreadContext *tc)
715{
682 return TLB::translateAtomic<FakeITLBFault>(req, tc, false, true);
716 bool delayedResponse;
717 return TLB::translate(req, tc, NULL, false,
718 true, delayedResponse, false);
683}
684
685void
686ITB::translateTiming(RequestPtr req, ThreadContext *tc,
687 Translation *translation)
688{
719}
720
721void
722ITB::translateTiming(RequestPtr req, ThreadContext *tc,
723 Translation *translation)
724{
725 bool delayedResponse;
689 assert(translation);
726 assert(translation);
690 translation->finish(translateAtomic(req, tc), req, tc, false);
727 Fault fault = TLB::translate(req, tc, translation,
728 false, true, delayedResponse, true);
729 if (!delayedResponse)
730 translation->finish(fault, req, tc, false);
691}
692
693#if FULL_SYSTEM
694
695Tick
696DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
697{
698 return tc->getCpuPtr()->ticks(1);

--- 45 unchanged lines hidden ---
731}
732
733#if FULL_SYSTEM
734
735Tick
736DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
737{
738 return tc->getCpuPtr()->ticks(1);

--- 45 unchanged lines hidden ---