64// The one downside to bitsets is that static initializers can get ugly. 65#define SET1(a1) (1 << (a1)) 66#define SET2(a1, a2) (SET1(a1) | SET1(a2)) 67#define SET3(a1, a2, a3) (SET2(a1, a2) | SET1(a3)) 68#define SET4(a1, a2, a3, a4) (SET3(a1, a2, a3) | SET1(a4)) 69#define SET5(a1, a2, a3, a4, a5) (SET4(a1, a2, a3, a4) | SET1(a5)) 70#define SET6(a1, a2, a3, a4, a5, a6) (SET5(a1, a2, a3, a4, a5) | SET1(a6)) 71#define SET7(a1, a2, a3, a4, a5, a6, a7) (SET6(a1, a2, a3, a4, a5, a6) | \ 72 SET1(a7)) 73 74const MemCmd::CommandInfo 75MemCmd::commandInfo[] = 76{ 77 /* InvalidCmd */ 78 { 0, InvalidCmd, "InvalidCmd" }, 79 /* ReadReq - Read issued by a non-caching agent such as a CPU or 80 * device, with no restrictions on alignment. */ 81 { SET3(IsRead, IsRequest, NeedsResponse), ReadResp, "ReadReq" }, 82 /* ReadResp */ 83 { SET3(IsRead, IsResponse, HasData), InvalidCmd, "ReadResp" }, 84 /* ReadRespWithInvalidate */ 85 { SET4(IsRead, IsResponse, HasData, IsInvalidate), 86 InvalidCmd, "ReadRespWithInvalidate" }, 87 /* WriteReq */ 88 { SET5(IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData), 89 WriteResp, "WriteReq" }, 90 /* WriteResp */ 91 { SET2(IsWrite, IsResponse), InvalidCmd, "WriteResp" }, 92 /* WritebackDirty */ 93 { SET5(IsWrite, IsRequest, IsEviction, HasData, FromCache), 94 InvalidCmd, "WritebackDirty" }, 95 /* WritebackClean - This allows the upstream cache to writeback a 96 * line to the downstream cache without it being considered 97 * dirty. */ 98 { SET5(IsWrite, IsRequest, IsEviction, HasData, FromCache), 99 InvalidCmd, "WritebackClean" }, 100 /* WriteClean - This allows a cache to write a dirty block to a memory 101 below without evicting its copy. */ 102 { SET4(IsWrite, IsRequest, HasData, FromCache), InvalidCmd, "WriteClean" }, 103 /* CleanEvict */ 104 { SET3(IsRequest, IsEviction, FromCache), InvalidCmd, "CleanEvict" }, 105 /* SoftPFReq */ 106 { SET4(IsRead, IsRequest, IsSWPrefetch, NeedsResponse), 107 SoftPFResp, "SoftPFReq" }, 108 /* HardPFReq */ 109 { SET5(IsRead, IsRequest, IsHWPrefetch, NeedsResponse, FromCache), 110 HardPFResp, "HardPFReq" }, 111 /* SoftPFResp */ 112 { SET4(IsRead, IsResponse, IsSWPrefetch, HasData), 113 InvalidCmd, "SoftPFResp" }, 114 /* HardPFResp */ 115 { SET4(IsRead, IsResponse, IsHWPrefetch, HasData), 116 InvalidCmd, "HardPFResp" }, 117 /* WriteLineReq */ 118 { SET5(IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData), 119 WriteResp, "WriteLineReq" }, 120 /* UpgradeReq */ 121 { SET6(IsInvalidate, NeedsWritable, IsUpgrade, IsRequest, NeedsResponse, 122 FromCache), 123 UpgradeResp, "UpgradeReq" }, 124 /* SCUpgradeReq: response could be UpgradeResp or UpgradeFailResp */ 125 { SET7(IsInvalidate, NeedsWritable, IsUpgrade, IsLlsc, 126 IsRequest, NeedsResponse, FromCache), 127 UpgradeResp, "SCUpgradeReq" }, 128 /* UpgradeResp */ 129 { SET2(IsUpgrade, IsResponse), 130 InvalidCmd, "UpgradeResp" }, 131 /* SCUpgradeFailReq: generates UpgradeFailResp but still gets the data */ 132 { SET7(IsRead, NeedsWritable, IsInvalidate, 133 IsLlsc, IsRequest, NeedsResponse, FromCache), 134 UpgradeFailResp, "SCUpgradeFailReq" }, 135 /* UpgradeFailResp - Behaves like a ReadExReq, but notifies an SC 136 * that it has failed, acquires line as Dirty*/ 137 { SET3(IsRead, IsResponse, HasData), 138 InvalidCmd, "UpgradeFailResp" }, 139 /* ReadExReq - Read issues by a cache, always cache-line aligned, 140 * and the response is guaranteed to be writeable (exclusive or 141 * even modified) */ 142 { SET6(IsRead, NeedsWritable, IsInvalidate, IsRequest, NeedsResponse, 143 FromCache), 144 ReadExResp, "ReadExReq" }, 145 /* ReadExResp - Response matching a read exclusive, as we check 146 * the need for exclusive also on responses */ 147 { SET3(IsRead, IsResponse, HasData), 148 InvalidCmd, "ReadExResp" }, 149 /* ReadCleanReq - Read issued by a cache, always cache-line 150 * aligned, and the response is guaranteed to not contain dirty data 151 * (exclusive or shared).*/ 152 { SET4(IsRead, IsRequest, NeedsResponse, FromCache), 153 ReadResp, "ReadCleanReq" }, 154 /* ReadSharedReq - Read issued by a cache, always cache-line 155 * aligned, response is shared, possibly exclusive, owned or even 156 * modified. */ 157 { SET4(IsRead, IsRequest, NeedsResponse, FromCache), 158 ReadResp, "ReadSharedReq" }, 159 /* LoadLockedReq: note that we use plain ReadResp as response, so that 160 * we can also use ReadRespWithInvalidate when needed */ 161 { SET4(IsRead, IsLlsc, IsRequest, NeedsResponse), 162 ReadResp, "LoadLockedReq" }, 163 /* StoreCondReq */ 164 { SET6(IsWrite, NeedsWritable, IsLlsc, 165 IsRequest, NeedsResponse, HasData), 166 StoreCondResp, "StoreCondReq" }, 167 /* StoreCondFailReq: generates failing StoreCondResp */ 168 { SET6(IsWrite, NeedsWritable, IsLlsc, 169 IsRequest, NeedsResponse, HasData), 170 StoreCondResp, "StoreCondFailReq" }, 171 /* StoreCondResp */ 172 { SET3(IsWrite, IsLlsc, IsResponse), 173 InvalidCmd, "StoreCondResp" }, 174 /* SwapReq -- for Swap ldstub type operations */ 175 { SET6(IsRead, IsWrite, NeedsWritable, IsRequest, HasData, NeedsResponse), 176 SwapResp, "SwapReq" }, 177 /* SwapResp -- for Swap ldstub type operations */ 178 { SET4(IsRead, IsWrite, IsResponse, HasData), 179 InvalidCmd, "SwapResp" }, 180 /* IntReq -- for interrupts */ 181 { SET4(IsWrite, IsRequest, NeedsResponse, HasData), 182 MessageResp, "MessageReq" }, 183 /* IntResp -- for interrupts */ 184 { SET2(IsWrite, IsResponse), InvalidCmd, "MessageResp" }, 185 /* MemFenceReq -- for synchronization requests */ 186 {SET2(IsRequest, NeedsResponse), MemFenceResp, "MemFenceReq"}, 187 /* MemFenceResp -- for synchronization responses */ 188 {SET1(IsResponse), InvalidCmd, "MemFenceResp"}, 189 /* Cache Clean Request -- Update with the latest data all existing 190 copies of the block down to the point indicated by the 191 request */ 192 { SET4(IsRequest, IsClean, NeedsResponse, FromCache), 193 CleanSharedResp, "CleanSharedReq" }, 194 /* Cache Clean Response - Indicates that all caches up to the 195 specified point of reference have a up-to-date copy of the 196 cache block or no copy at all */ 197 { SET2(IsResponse, IsClean), InvalidCmd, "CleanSharedResp" }, 198 /* Cache Clean and Invalidate Request -- Invalidate all existing 199 copies down to the point indicated by the request */ 200 { SET5(IsRequest, IsInvalidate, IsClean, NeedsResponse, FromCache), 201 CleanInvalidResp, "CleanInvalidReq" }, 202 /* Cache Clean and Invalidate Respose -- Indicates that no cache 203 above the specified point holds the block and that the block 204 was written to a memory below the specified point. */ 205 { SET3(IsResponse, IsInvalidate, IsClean), 206 InvalidCmd, "CleanInvalidResp" }, 207 /* InvalidDestError -- packet dest field invalid */ 208 { SET2(IsResponse, IsError), InvalidCmd, "InvalidDestError" }, 209 /* BadAddressError -- memory address invalid */ 210 { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" }, 211 /* FunctionalReadError */ 212 { SET3(IsRead, IsResponse, IsError), InvalidCmd, "FunctionalReadError" }, 213 /* FunctionalWriteError */ 214 { SET3(IsWrite, IsResponse, IsError), InvalidCmd, "FunctionalWriteError" }, 215 /* PrintReq */ 216 { SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" }, 217 /* Flush Request */ 218 { SET3(IsRequest, IsFlush, NeedsWritable), InvalidCmd, "FlushReq" }, 219 /* Invalidation Request */ 220 { SET5(IsInvalidate, IsRequest, NeedsWritable, NeedsResponse, FromCache), 221 InvalidateResp, "InvalidateReq" }, 222 /* Invalidation Response */ 223 { SET2(IsInvalidate, IsResponse), 224 InvalidCmd, "InvalidateResp" } 225}; 226 227bool 228Packet::checkFunctional(Printable *obj, Addr addr, bool is_secure, int size, 229 uint8_t *_data) 230{ 231 const Addr func_start = getAddr(); 232 const Addr func_end = getAddr() + getSize() - 1; 233 const Addr val_start = addr; 234 const Addr val_end = val_start + size - 1; 235 236 if (is_secure != _isSecure || func_start > val_end || 237 val_start > func_end) { 238 // no intersection 239 return false; 240 } 241 242 // check print first since it doesn't require data 243 if (isPrint()) { 244 assert(!_data); 245 safe_cast<PrintReqState*>(senderState)->printObj(obj); 246 return false; 247 } 248 249 // we allow the caller to pass NULL to signify the other packet 250 // has no data 251 if (!_data) { 252 return false; 253 } 254 255 const Addr val_offset = func_start > val_start ? 256 func_start - val_start : 0; 257 const Addr func_offset = func_start < val_start ? 258 val_start - func_start : 0; 259 const Addr overlap_size = std::min(val_end, func_end)+1 - 260 std::max(val_start, func_start); 261 262 if (isRead()) {
| 64// The one downside to bitsets is that static initializers can get ugly. 65#define SET1(a1) (1 << (a1)) 66#define SET2(a1, a2) (SET1(a1) | SET1(a2)) 67#define SET3(a1, a2, a3) (SET2(a1, a2) | SET1(a3)) 68#define SET4(a1, a2, a3, a4) (SET3(a1, a2, a3) | SET1(a4)) 69#define SET5(a1, a2, a3, a4, a5) (SET4(a1, a2, a3, a4) | SET1(a5)) 70#define SET6(a1, a2, a3, a4, a5, a6) (SET5(a1, a2, a3, a4, a5) | SET1(a6)) 71#define SET7(a1, a2, a3, a4, a5, a6, a7) (SET6(a1, a2, a3, a4, a5, a6) | \ 72 SET1(a7)) 73 74const MemCmd::CommandInfo 75MemCmd::commandInfo[] = 76{ 77 /* InvalidCmd */ 78 { 0, InvalidCmd, "InvalidCmd" }, 79 /* ReadReq - Read issued by a non-caching agent such as a CPU or 80 * device, with no restrictions on alignment. */ 81 { SET3(IsRead, IsRequest, NeedsResponse), ReadResp, "ReadReq" }, 82 /* ReadResp */ 83 { SET3(IsRead, IsResponse, HasData), InvalidCmd, "ReadResp" }, 84 /* ReadRespWithInvalidate */ 85 { SET4(IsRead, IsResponse, HasData, IsInvalidate), 86 InvalidCmd, "ReadRespWithInvalidate" }, 87 /* WriteReq */ 88 { SET5(IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData), 89 WriteResp, "WriteReq" }, 90 /* WriteResp */ 91 { SET2(IsWrite, IsResponse), InvalidCmd, "WriteResp" }, 92 /* WritebackDirty */ 93 { SET5(IsWrite, IsRequest, IsEviction, HasData, FromCache), 94 InvalidCmd, "WritebackDirty" }, 95 /* WritebackClean - This allows the upstream cache to writeback a 96 * line to the downstream cache without it being considered 97 * dirty. */ 98 { SET5(IsWrite, IsRequest, IsEviction, HasData, FromCache), 99 InvalidCmd, "WritebackClean" }, 100 /* WriteClean - This allows a cache to write a dirty block to a memory 101 below without evicting its copy. */ 102 { SET4(IsWrite, IsRequest, HasData, FromCache), InvalidCmd, "WriteClean" }, 103 /* CleanEvict */ 104 { SET3(IsRequest, IsEviction, FromCache), InvalidCmd, "CleanEvict" }, 105 /* SoftPFReq */ 106 { SET4(IsRead, IsRequest, IsSWPrefetch, NeedsResponse), 107 SoftPFResp, "SoftPFReq" }, 108 /* HardPFReq */ 109 { SET5(IsRead, IsRequest, IsHWPrefetch, NeedsResponse, FromCache), 110 HardPFResp, "HardPFReq" }, 111 /* SoftPFResp */ 112 { SET4(IsRead, IsResponse, IsSWPrefetch, HasData), 113 InvalidCmd, "SoftPFResp" }, 114 /* HardPFResp */ 115 { SET4(IsRead, IsResponse, IsHWPrefetch, HasData), 116 InvalidCmd, "HardPFResp" }, 117 /* WriteLineReq */ 118 { SET5(IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData), 119 WriteResp, "WriteLineReq" }, 120 /* UpgradeReq */ 121 { SET6(IsInvalidate, NeedsWritable, IsUpgrade, IsRequest, NeedsResponse, 122 FromCache), 123 UpgradeResp, "UpgradeReq" }, 124 /* SCUpgradeReq: response could be UpgradeResp or UpgradeFailResp */ 125 { SET7(IsInvalidate, NeedsWritable, IsUpgrade, IsLlsc, 126 IsRequest, NeedsResponse, FromCache), 127 UpgradeResp, "SCUpgradeReq" }, 128 /* UpgradeResp */ 129 { SET2(IsUpgrade, IsResponse), 130 InvalidCmd, "UpgradeResp" }, 131 /* SCUpgradeFailReq: generates UpgradeFailResp but still gets the data */ 132 { SET7(IsRead, NeedsWritable, IsInvalidate, 133 IsLlsc, IsRequest, NeedsResponse, FromCache), 134 UpgradeFailResp, "SCUpgradeFailReq" }, 135 /* UpgradeFailResp - Behaves like a ReadExReq, but notifies an SC 136 * that it has failed, acquires line as Dirty*/ 137 { SET3(IsRead, IsResponse, HasData), 138 InvalidCmd, "UpgradeFailResp" }, 139 /* ReadExReq - Read issues by a cache, always cache-line aligned, 140 * and the response is guaranteed to be writeable (exclusive or 141 * even modified) */ 142 { SET6(IsRead, NeedsWritable, IsInvalidate, IsRequest, NeedsResponse, 143 FromCache), 144 ReadExResp, "ReadExReq" }, 145 /* ReadExResp - Response matching a read exclusive, as we check 146 * the need for exclusive also on responses */ 147 { SET3(IsRead, IsResponse, HasData), 148 InvalidCmd, "ReadExResp" }, 149 /* ReadCleanReq - Read issued by a cache, always cache-line 150 * aligned, and the response is guaranteed to not contain dirty data 151 * (exclusive or shared).*/ 152 { SET4(IsRead, IsRequest, NeedsResponse, FromCache), 153 ReadResp, "ReadCleanReq" }, 154 /* ReadSharedReq - Read issued by a cache, always cache-line 155 * aligned, response is shared, possibly exclusive, owned or even 156 * modified. */ 157 { SET4(IsRead, IsRequest, NeedsResponse, FromCache), 158 ReadResp, "ReadSharedReq" }, 159 /* LoadLockedReq: note that we use plain ReadResp as response, so that 160 * we can also use ReadRespWithInvalidate when needed */ 161 { SET4(IsRead, IsLlsc, IsRequest, NeedsResponse), 162 ReadResp, "LoadLockedReq" }, 163 /* StoreCondReq */ 164 { SET6(IsWrite, NeedsWritable, IsLlsc, 165 IsRequest, NeedsResponse, HasData), 166 StoreCondResp, "StoreCondReq" }, 167 /* StoreCondFailReq: generates failing StoreCondResp */ 168 { SET6(IsWrite, NeedsWritable, IsLlsc, 169 IsRequest, NeedsResponse, HasData), 170 StoreCondResp, "StoreCondFailReq" }, 171 /* StoreCondResp */ 172 { SET3(IsWrite, IsLlsc, IsResponse), 173 InvalidCmd, "StoreCondResp" }, 174 /* SwapReq -- for Swap ldstub type operations */ 175 { SET6(IsRead, IsWrite, NeedsWritable, IsRequest, HasData, NeedsResponse), 176 SwapResp, "SwapReq" }, 177 /* SwapResp -- for Swap ldstub type operations */ 178 { SET4(IsRead, IsWrite, IsResponse, HasData), 179 InvalidCmd, "SwapResp" }, 180 /* IntReq -- for interrupts */ 181 { SET4(IsWrite, IsRequest, NeedsResponse, HasData), 182 MessageResp, "MessageReq" }, 183 /* IntResp -- for interrupts */ 184 { SET2(IsWrite, IsResponse), InvalidCmd, "MessageResp" }, 185 /* MemFenceReq -- for synchronization requests */ 186 {SET2(IsRequest, NeedsResponse), MemFenceResp, "MemFenceReq"}, 187 /* MemFenceResp -- for synchronization responses */ 188 {SET1(IsResponse), InvalidCmd, "MemFenceResp"}, 189 /* Cache Clean Request -- Update with the latest data all existing 190 copies of the block down to the point indicated by the 191 request */ 192 { SET4(IsRequest, IsClean, NeedsResponse, FromCache), 193 CleanSharedResp, "CleanSharedReq" }, 194 /* Cache Clean Response - Indicates that all caches up to the 195 specified point of reference have a up-to-date copy of the 196 cache block or no copy at all */ 197 { SET2(IsResponse, IsClean), InvalidCmd, "CleanSharedResp" }, 198 /* Cache Clean and Invalidate Request -- Invalidate all existing 199 copies down to the point indicated by the request */ 200 { SET5(IsRequest, IsInvalidate, IsClean, NeedsResponse, FromCache), 201 CleanInvalidResp, "CleanInvalidReq" }, 202 /* Cache Clean and Invalidate Respose -- Indicates that no cache 203 above the specified point holds the block and that the block 204 was written to a memory below the specified point. */ 205 { SET3(IsResponse, IsInvalidate, IsClean), 206 InvalidCmd, "CleanInvalidResp" }, 207 /* InvalidDestError -- packet dest field invalid */ 208 { SET2(IsResponse, IsError), InvalidCmd, "InvalidDestError" }, 209 /* BadAddressError -- memory address invalid */ 210 { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" }, 211 /* FunctionalReadError */ 212 { SET3(IsRead, IsResponse, IsError), InvalidCmd, "FunctionalReadError" }, 213 /* FunctionalWriteError */ 214 { SET3(IsWrite, IsResponse, IsError), InvalidCmd, "FunctionalWriteError" }, 215 /* PrintReq */ 216 { SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" }, 217 /* Flush Request */ 218 { SET3(IsRequest, IsFlush, NeedsWritable), InvalidCmd, "FlushReq" }, 219 /* Invalidation Request */ 220 { SET5(IsInvalidate, IsRequest, NeedsWritable, NeedsResponse, FromCache), 221 InvalidateResp, "InvalidateReq" }, 222 /* Invalidation Response */ 223 { SET2(IsInvalidate, IsResponse), 224 InvalidCmd, "InvalidateResp" } 225}; 226 227bool 228Packet::checkFunctional(Printable *obj, Addr addr, bool is_secure, int size, 229 uint8_t *_data) 230{ 231 const Addr func_start = getAddr(); 232 const Addr func_end = getAddr() + getSize() - 1; 233 const Addr val_start = addr; 234 const Addr val_end = val_start + size - 1; 235 236 if (is_secure != _isSecure || func_start > val_end || 237 val_start > func_end) { 238 // no intersection 239 return false; 240 } 241 242 // check print first since it doesn't require data 243 if (isPrint()) { 244 assert(!_data); 245 safe_cast<PrintReqState*>(senderState)->printObj(obj); 246 return false; 247 } 248 249 // we allow the caller to pass NULL to signify the other packet 250 // has no data 251 if (!_data) { 252 return false; 253 } 254 255 const Addr val_offset = func_start > val_start ? 256 func_start - val_start : 0; 257 const Addr func_offset = func_start < val_start ? 258 val_start - func_start : 0; 259 const Addr overlap_size = std::min(val_end, func_end)+1 - 260 std::max(val_start, func_start); 261 262 if (isRead()) {
|