1/* |
2 * Copyright (c) 2013 ARM Limited 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 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * |
14 * Copyright (c) 2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright --- 124 unchanged lines hidden (view full) --- 146{ 147 DPRINTF(HWPrefetch, "Requesting a hw_pf to issue\n"); 148 149 if (pf.empty()) { 150 DPRINTF(HWPrefetch, "No HW_PF found\n"); 151 return NULL; 152 } 153 |
154 PacketPtr pkt = pf.begin()->pkt; |
155 while (!pf.empty()) { |
156 pkt = pf.begin()->pkt; |
157 pf.pop_front(); 158 159 Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); 160 161 if (!inCache(blk_addr) && !inMissQueue(blk_addr)) 162 // we found a prefetch, return it 163 break; 164 --- 10 unchanged lines hidden (view full) --- 175 pfIssued++; 176 assert(pkt != NULL); 177 DPRINTF(HWPrefetch, "returning 0x%x\n", pkt->getAddr()); 178 return pkt; 179} 180 181 182Tick |
183BasePrefetcher::notify(PacketPtr &pkt, Tick tick) |
184{ 185 if (!pkt->req->isUncacheable() && !(pkt->req->isInstFetch() && onlyData)) { 186 // Calculate the blk address 187 Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); 188 189 // Check if miss is in pfq, if so remove it |
190 std::list<DeferredPacket>::iterator iter = inPrefetch(blk_addr); |
191 if (iter != pf.end()) { 192 DPRINTF(HWPrefetch, "Saw a miss to a queued prefetch addr: " 193 "0x%x, removing it\n", blk_addr); 194 pfRemovedMSHR++; |
195 delete iter->pkt->req; 196 delete iter->pkt; |
197 iter = pf.erase(iter); 198 if (pf.empty()) 199 cache->deassertMemSideBusRequest(BaseCache::Request_PF); 200 } 201 202 // Remove anything in queue with delay older than time 203 // since everything is inserted in time order, start from end 204 // and work until pf.empty() or time is earlier 205 // This is done to emulate Aborting the previous work on a new miss 206 // Needed for serial calculators like GHB 207 if (serialSquash) { 208 iter = pf.end(); 209 if (iter != pf.begin()) 210 iter--; |
211 while (!pf.empty() && iter->tick >= tick) { |
212 pfSquashed++; 213 DPRINTF(HWPrefetch, "Squashing old prefetch addr: 0x%x\n", |
214 iter->pkt->getAddr()); 215 delete iter->pkt->req; 216 delete iter->pkt; |
217 iter = pf.erase(iter); 218 if (iter != pf.begin()) 219 iter--; 220 } 221 if (pf.empty()) 222 cache->deassertMemSideBusRequest(BaseCache::Request_PF); 223 } 224 --- 23 unchanged lines hidden (view full) --- 248 // create a prefetch memreq 249 Request *prefetchReq = new Request(*addrIter, blkSize, 0, masterId); 250 PacketPtr prefetch = 251 new Packet(prefetchReq, MemCmd::HardPFReq); 252 prefetch->allocate(); 253 prefetch->req->setThreadContext(pkt->req->contextId(), 254 pkt->req->threadId()); 255 |
256 // We just remove the head if we are full 257 if (pf.size() == size) { 258 pfRemovedFull++; |
259 PacketPtr old_pkt = pf.begin()->pkt; |
260 DPRINTF(HWPrefetch, "Prefetch queue full, " 261 "removing oldest 0x%x\n", old_pkt->getAddr()); 262 delete old_pkt->req; 263 delete old_pkt; 264 pf.pop_front(); 265 } 266 |
267 pf.push_back(DeferredPacket(tick + clockPeriod() * *delayIter, 268 prefetch)); |
269 } 270 } 271 |
272 return pf.empty() ? 0 : pf.front().tick; |
273} 274 |
275std::list<BasePrefetcher::DeferredPacket>::iterator |
276BasePrefetcher::inPrefetch(Addr address) 277{ 278 // Guaranteed to only be one match, we always check before inserting |
279 std::list<DeferredPacket>::iterator iter; |
280 for (iter = pf.begin(); iter != pf.end(); iter++) { |
281 if ((iter->pkt->getAddr() & ~(Addr)(blkSize-1)) == address) { |
282 return iter; 283 } 284 } 285 return pf.end(); 286} 287 288bool 289BasePrefetcher::samePage(Addr a, Addr b) 290{ 291 return roundDown(a, TheISA::VMPageSize) == roundDown(b, TheISA::VMPageSize); 292} 293 294 |