cache_blk.hh revision 5314:e902f12a3af1
1/* 2 * Copyright (c) 2003-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 */ 30 31/** @file 32 * Definitions of a simple cache block class. 33 */ 34 35#ifndef __CACHE_BLK_HH__ 36#define __CACHE_BLK_HH__ 37 38#include <list> 39 40#include "base/printable.hh" 41#include "sim/core.hh" // for Tick 42#include "arch/isa_traits.hh" // for Addr 43#include "mem/packet.hh" 44#include "mem/request.hh" 45 46/** 47 * Cache block status bit assignments 48 */ 49enum CacheBlkStatusBits { 50 /** valid, readable */ 51 BlkValid = 0x01, 52 /** write permission */ 53 BlkWritable = 0x02, 54 /** dirty (modified) */ 55 BlkDirty = 0x04, 56 /** block was referenced */ 57 BlkReferenced = 0x10, 58 /** block was a hardware prefetch yet unaccessed*/ 59 BlkHWPrefetched = 0x20 60}; 61 62/** 63 * A Basic Cache block. 64 * Contains the tag, status, and a pointer to data. 65 */ 66class CacheBlk 67{ 68 public: 69 /** The address space ID of this block. */ 70 int asid; 71 /** Data block tag value. */ 72 Addr tag; 73 /** 74 * Contains a copy of the data in this block for easy access. This is used 75 * for efficient execution when the data could be actually stored in 76 * another format (COW, compressed, sub-blocked, etc). In all cases the 77 * data stored here should be kept consistant with the actual data 78 * referenced by this block. 79 */ 80 uint8_t *data; 81 /** the number of bytes stored in this block. */ 82 int size; 83 84 /** block state: OR of CacheBlkStatusBit */ 85 typedef unsigned State; 86 87 /** The current status of this block. @sa CacheBlockStatusBits */ 88 State status; 89 90 /** Which curTick will this block be accessable */ 91 Tick whenReady; 92 93 /** 94 * The set this block belongs to. 95 * @todo Move this into subclasses when we fix CacheTags to use them. 96 */ 97 int set; 98 99 /** Number of references to this block since it was brought in. */ 100 int refCount; 101 102 protected: 103 /** 104 * Represents that the indicated thread context has a "lock" on 105 * the block, in the LL/SC sense. 106 */ 107 class Lock { 108 public: 109 int cpuNum; // locking CPU 110 int threadNum; // locking thread ID within CPU 111 112 // check for matching execution context 113 bool matchesContext(Request *req) 114 { 115 return (cpuNum == req->getCpuNum() && 116 threadNum == req->getThreadNum()); 117 } 118 119 Lock(Request *req) 120 : cpuNum(req->getCpuNum()), threadNum(req->getThreadNum()) 121 { 122 } 123 }; 124 125 /** List of thread contexts that have performed a load-locked (LL) 126 * on the block since the last store. */ 127 std::list<Lock> lockList; 128 129 public: 130 131 CacheBlk() 132 : asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0), 133 set(-1), refCount(0) 134 {} 135 136 /** 137 * Copy the state of the given block into this one. 138 * @param rhs The block to copy. 139 * @return a const reference to this block. 140 */ 141 const CacheBlk& operator=(const CacheBlk& rhs) 142 { 143 asid = rhs.asid; 144 tag = rhs.tag; 145 data = rhs.data; 146 size = rhs.size; 147 status = rhs.status; 148 whenReady = rhs.whenReady; 149 set = rhs.set; 150 refCount = rhs.refCount; 151 return *this; 152 } 153 154 /** 155 * Checks the write permissions of this block. 156 * @return True if the block is writable. 157 */ 158 bool isWritable() const 159 { 160 const int needed_bits = BlkWritable | BlkValid; 161 return (status & needed_bits) == needed_bits; 162 } 163 164 /** 165 * Checks that a block is valid (readable). 166 * @return True if the block is valid. 167 */ 168 bool isValid() const 169 { 170 return (status & BlkValid) != 0; 171 } 172 173 /** 174 * Check to see if a block has been written. 175 * @return True if the block is dirty. 176 */ 177 bool isDirty() const 178 { 179 return (status & BlkDirty) != 0; 180 } 181 182 /** 183 * Check if this block has been referenced. 184 * @return True if the block has been referenced. 185 */ 186 bool isReferenced() const 187 { 188 return (status & BlkReferenced) != 0; 189 } 190 191 /** 192 * Check if this block was the result of a hardware prefetch, yet to 193 * be touched. 194 * @return True if the block was a hardware prefetch, unaccesed. 195 */ 196 bool isPrefetch() const 197 { 198 return (status & BlkHWPrefetched) != 0; 199 } 200 201 /** 202 * Track the fact that a local locked was issued to the block. If 203 * multiple LLs get issued from the same context we could have 204 * redundant records on the list, but that's OK, as they'll all 205 * get blown away at the next store. 206 */ 207 void trackLoadLocked(PacketPtr pkt) 208 { 209 assert(pkt->isLocked()); 210 lockList.push_front(Lock(pkt->req)); 211 } 212 213 /** 214 * Clear the list of valid load locks. Should be called whenever 215 * block is written to or invalidated. 216 */ 217 void clearLoadLocks() { lockList.clear(); } 218 219 /** 220 * Handle interaction of load-locked operations and stores. 221 * @return True if write should proceed, false otherwise. Returns 222 * false only in the case of a failed store conditional. 223 */ 224 bool checkWrite(PacketPtr pkt) 225 { 226 Request *req = pkt->req; 227 if (pkt->isLocked()) { 228 // it's a store conditional... have to check for matching 229 // load locked. 230 bool success = false; 231 232 for (std::list<Lock>::iterator i = lockList.begin(); 233 i != lockList.end(); ++i) 234 { 235 if (i->matchesContext(req)) { 236 // it's a store conditional, and as far as the memory 237 // system can tell, the requesting context's lock is 238 // still valid. 239 success = true; 240 break; 241 } 242 } 243 244 req->setExtraData(success ? 1 : 0); 245 clearLoadLocks(); 246 return success; 247 } else { 248 // for *all* stores (conditional or otherwise) we have to 249 // clear the list of load-locks as they're all invalid now. 250 clearLoadLocks(); 251 return true; 252 } 253 } 254}; 255 256class CacheBlkPrintWrapper : public Printable 257{ 258 CacheBlk *blk; 259 public: 260 CacheBlkPrintWrapper(CacheBlk *_blk) : blk(_blk) {} 261 virtual ~CacheBlkPrintWrapper() {} 262 void print(std::ostream &o, int verbosity = 0, 263 const std::string &prefix = "") const; 264}; 265 266 267 268#endif //__CACHE_BLK_HH__ 269