mshr.cc revision 2813
1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Erik Hallnor 29 * Dave Greene 30 */ 31 32/** 33 * @file 34 * Miss Status and Handling Register (MSHR) definitions. 35 */ 36 37#include <assert.h> 38#include <string> 39#include <vector> 40 41#include "mem/cache/miss/mshr.hh" 42#include "sim/root.hh" // for curTick 43#include "sim/host.hh" 44#include "base/misc.hh" 45#include "mem/cache/cache.hh" 46 47using namespace std; 48 49MSHR::MSHR() 50{ 51 inService = false; 52 ntargets = 0; 53 threadNum = -1; 54} 55 56void 57MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size, 58 Packet * &target) 59{ 60 assert("NEED TO FIX YET\n" && 0); 61#if 0 62 assert(targets.empty()); 63 addr = _addr; 64 asid = _asid; 65 66 pkt = new Packet(); // allocate new memory request 67 pkt->addr = addr; //picked physical address for now 68 pkt->cmd = cmd; 69 pkt->size = size; 70 pkt->data = new uint8_t[size]; 71 pkt->senderState = this; 72 //Set the time here for latency calculations 73 pkt->time = curTick; 74 75 if (target) { 76 pkt->req = target->req; 77 allocateTarget(target); 78 } 79#endif 80} 81 82// Since we aren't sure if data is being used, don't copy here. 83/** 84 * @todo When we have a "global" data flag, might want to copy data here. 85 */ 86void 87MSHR::allocateAsBuffer(Packet * &target) 88{ 89 addr = target->getAddr(); 90 asid = target->req->getAsid(); 91 threadNum = target->req->getThreadNum(); 92 pkt = new Packet(target->req, target->cmd, -1); 93 uint8_t *new_data = new uint8_t[target->getSize()]; 94 pkt->dataDynamicArray<uint8_t>(new_data); 95 pkt->senderState = (Packet::SenderState*)this; 96 pkt->time = curTick; 97} 98 99void 100MSHR::deallocate() 101{ 102 assert(targets.empty()); 103 assert(ntargets == 0); 104 pkt = NULL; 105 inService = false; 106 allocIter = NULL; 107 readyIter = NULL; 108} 109 110/* 111 * Adds a target to an MSHR 112 */ 113void 114MSHR::allocateTarget(Packet * &target) 115{ 116 //If we append an invalidate and we issued a read to the bus, 117 //but now have some pending writes, we need to move 118 //the invalidate to before the first non-read 119 if (inService && pkt->isRead() && target->isInvalidate()) { 120 std::list<Packet *> temp; 121 122 while (!targets.empty()) { 123 if (!targets.front()->isRead()) break; 124 //Place on top of temp stack 125 temp.push_front(targets.front()); 126 //Remove from targets 127 targets.pop_front(); 128 } 129 130 //Now that we have all the reads off until first non-read, we can 131 //place the invalidate on 132 targets.push_front(target); 133 134 //Now we pop off the temp_stack and put them back 135 while (!temp.empty()) { 136 targets.push_front(temp.front()); 137 temp.pop_front(); 138 } 139 } 140 else { 141 targets.push_back(target); 142 } 143 144 ++ntargets; 145 assert(targets.size() == ntargets); 146 /** 147 * @todo really prioritize the target commands. 148 */ 149 150 if (!inService && target->isWrite()) { 151 pkt->cmd = Packet::WriteReq; 152 } 153} 154 155 156 157void 158MSHR::dump() 159{ 160 ccprintf(cerr, 161 "inService: %d thread: %d\n" 162 "Addr: %x asid: %d ntargets %d\n" 163 "Targets:\n", 164 inService, threadNum, addr, asid, ntargets); 165 166 TargetListIterator tar_it = targets.begin(); 167 for (int i = 0; i < ntargets; i++) { 168 assert(tar_it != targets.end()); 169 170 ccprintf(cerr, "\t%d: Addr: %x cmd: %d\n", 171 i, (*tar_it)->getAddr(), (*tar_it)->cmdToIndex()); 172 173 tar_it++; 174 } 175 ccprintf(cerr, "\n"); 176} 177 178MSHR::~MSHR() 179{ 180 if (pkt) 181 pkt = NULL; 182} 183