tlb.cc (5232:d3801ea2792e) tlb.cc (5236:0050ad4fb3ef)
1/*
2 * Copyright (c) 2007 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 "cpu/thread_context.hh"
68#include "cpu/base.hh"
69#include "mem/packet_access.hh"
70#include "mem/request.hh"
71#include "sim/system.hh"
72
73namespace X86ISA {
74
1/*
2 * Copyright (c) 2007 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 "cpu/thread_context.hh"
68#include "cpu/base.hh"
69#include "mem/packet_access.hh"
70#include "mem/request.hh"
71#include "sim/system.hh"
72
73namespace X86ISA {
74
75TLB::TLB(const Params *p) : SimObject(p), size(p->size)
75TLB::TLB(const Params *p) : MemObject(p), walker(name(), this), size(p->size)
76{
77 tlb = new TlbEntry[size];
78 std::memset(tlb, 0, sizeof(TlbEntry) * size);
79
80 for (int x = 0; x < size; x++)
81 freeList.push_back(&tlb[x]);
82}
83
76{
77 tlb = new TlbEntry[size];
78 std::memset(tlb, 0, sizeof(TlbEntry) * size);
79
80 for (int x = 0; x < size; x++)
81 freeList.push_back(&tlb[x]);
82}
83
84bool
85TLB::Walker::doNext(uint64_t data, PacketPtr &write)
86{
87 assert(state != Ready && state != Waiting);
88 write = NULL;
89 switch(state) {
90 case LongPML4:
91 nextState = LongPDP;
92 break;
93 case LongPDP:
94 nextState = LongPD;
95 break;
96 case LongPD:
97 nextState = LongPTE;
98 break;
99 case LongPTE:
100 nextState = Ready;
101 return false;
102 case PAEPDP:
103 nextState = PAEPD;
104 break;
105 case PAEPD:
106 break;
107 case PAEPTE:
108 nextState = Ready;
109 return false;
110 case PSEPD:
111 break;
112 case PD:
113 nextState = PTE;
114 break;
115 case PTE:
116 nextState = Ready;
117 return false;
118 default:
119 panic("Unknown page table walker state %d!\n");
120 }
121 return true;
122}
123
84void
124void
125TLB::Walker::buildReadPacket(Addr addr)
126{
127 readRequest.setPhys(addr, size, PHYSICAL | uncachable ? UNCACHEABLE : 0);
128 readPacket.reinitFromRequest();
129}
130
131TLB::walker::buildWritePacket(Addr addr)
132{
133 writeRequest.setPhys(addr, size, PHYSICAL | uncachable ? UNCACHEABLE : 0);
134 writePacket.reinitFromRequest();
135
136bool
137TLB::Walker::WalkerPort::recvTiming(PacketPtr pkt)
138{
139 if (pkt->isResponse() && !pkt->wasNacked()) {
140 if (pkt->isRead()) {
141 assert(packet);
142 assert(walker->state == Waiting);
143 packet = NULL;
144 walker->state = walker->nextState;
145 walker->nextState = Ready;
146 PacketPtr write;
147 if (walker->doNext(pkt, write)) {
148 packet = &walker->packet;
149 port->sendTiming(packet);
150 }
151 if (write) {
152 writes.push_back(write);
153 }
154 while (!port->blocked() && writes.size()) {
155 if (port->sendTiming(writes.front())) {
156 writes.pop_front();
157 outstandingWrites++;
158 }
159 }
160 } else {
161 outstandingWrites--;
162 }
163 } else if (pkt->wasNacked()) {
164 pkt->reinitNacked();
165 if (!sendTiming(pkt)) {
166 if (pkt->isWrite()) {
167 writes.push_front(pkt);
168 }
169 }
170 }
171 return true;
172}
173
174Tick
175TLB::Walker::WalkerPort::recvAtomic(PacketPtr pkt)
176{
177 return 0;
178}
179
180void
181TLB::Walker::WalkerPort::recvFunctional(PacketPtr pkt)
182{
183 return;
184}
185
186void
187TLB::Walker::WalkerPort::recvStatusChange(Status status)
188{
189 if (status == RangeChange) {
190 if (!snoopRangeSent) {
191 snoopRangeSent = true;
192 sendStatusChange(Port::RangeChange);
193 }
194 return;
195 }
196
197 panic("Unexpected recvStatusChange.\n");
198}
199
200void
201TLB::Walker::WalkerPort::recvRetry()
202{
203 retrying = false;
204 if (!sendTiming(packet)) {
205 retrying = true;
206 }
207}
208
209Port *
210TLB::getPort(const std::string &if_name, int idx)
211{
212 if (if_name == "walker_port")
213 return &walker.port;
214 else
215 panic("No tlb port named %s!\n", if_name);
216}
217
218void
85TLB::insert(Addr vpn, TlbEntry &entry)
86{
87 //TODO Deal with conflicting entries
88
89 TlbEntry *newEntry = NULL;
90 if (!freeList.empty()) {
91 newEntry = freeList.front();
92 freeList.pop_front();

--- 481 unchanged lines hidden ---
219TLB::insert(Addr vpn, TlbEntry &entry)
220{
221 //TODO Deal with conflicting entries
222
223 TlbEntry *newEntry = NULL;
224 if (!freeList.empty()) {
225 newEntry = freeList.front();
226 freeList.pop_front();

--- 481 unchanged lines hidden ---