cpu_impl.hh (2765:2962455d1c0a) | cpu_impl.hh (2789:f99d51ed08d6) |
---|---|
1/* 2 * Copyright (c) 2006 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; --- 18 unchanged lines hidden (view full) --- 27 * 28 * Authors: Kevin Lim 29 */ 30 31#include <list> 32#include <string> 33 34#include "base/refcnt.hh" | 1/* 2 * Copyright (c) 2006 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; --- 18 unchanged lines hidden (view full) --- 27 * 28 * Authors: Kevin Lim 29 */ 30 31#include <list> 32#include <string> 33 34#include "base/refcnt.hh" |
35#include "cpu/base.hh" | |
36#include "cpu/base_dyn_inst.hh" 37#include "cpu/checker/cpu.hh" 38#include "cpu/simple_thread.hh" 39#include "cpu/thread_context.hh" 40#include "cpu/static_inst.hh" 41#include "mem/packet_impl.hh" 42#include "sim/byteswap.hh" 43#include "sim/sim_object.hh" 44#include "sim/stats.hh" 45 46#if FULL_SYSTEM | 35#include "cpu/base_dyn_inst.hh" 36#include "cpu/checker/cpu.hh" 37#include "cpu/simple_thread.hh" 38#include "cpu/thread_context.hh" 39#include "cpu/static_inst.hh" 40#include "mem/packet_impl.hh" 41#include "sim/byteswap.hh" 42#include "sim/sim_object.hh" 43#include "sim/stats.hh" 44 45#if FULL_SYSTEM |
47#include "sim/system.hh" | |
48#include "arch/vtophys.hh" | 46#include "arch/vtophys.hh" |
49#include "kern/kernel_stats.hh" | |
50#endif // FULL_SYSTEM 51 52using namespace std; 53//The CheckerCPU does alpha only 54using namespace AlphaISA; 55 | 47#endif // FULL_SYSTEM 48 49using namespace std; 50//The CheckerCPU does alpha only 51using namespace AlphaISA; 52 |
56void 57CheckerCPU::init() 58{ 59} 60 61CheckerCPU::CheckerCPU(Params *p) 62 : BaseCPU(p), thread(NULL), tc(NULL) 63{ 64 memReq = NULL; 65 66 numInst = 0; 67 startNumInst = 0; 68 numLoad = 0; 69 startNumLoad = 0; 70 youngestSN = 0; 71 72 changedPC = willChangePC = changedNextPC = false; 73 74 exitOnError = p->exitOnError; 75 warnOnlyOnLoadError = p->warnOnlyOnLoadError; 76#if FULL_SYSTEM 77 itb = p->itb; 78 dtb = p->dtb; 79 systemPtr = NULL; 80#else 81 process = p->process; 82#endif 83 84 result.integer = 0; 85} 86 87CheckerCPU::~CheckerCPU() 88{ 89} 90 91void 92CheckerCPU::setMemory(MemObject *mem) 93{ 94#if !FULL_SYSTEM 95 memPtr = mem; 96 thread = new SimpleThread(this, /* thread_num */ 0, process, 97 /* asid */ 0, mem); 98 99 thread->setStatus(ThreadContext::Suspended); 100 tc = thread->getTC(); 101 threadContexts.push_back(tc); 102#endif 103} 104 105void 106CheckerCPU::setSystem(System *system) 107{ 108#if FULL_SYSTEM 109 systemPtr = system; 110 111 thread = new SimpleThread(this, 0, systemPtr, itb, dtb, false); 112 113 thread->setStatus(ThreadContext::Suspended); 114 tc = thread->getTC(); 115 threadContexts.push_back(tc); 116 delete thread->kernelStats; 117 thread->kernelStats = NULL; 118#endif 119} 120 121void 122CheckerCPU::setIcachePort(Port *icache_port) 123{ 124 icachePort = icache_port; 125} 126 127void 128CheckerCPU::setDcachePort(Port *dcache_port) 129{ 130 dcachePort = dcache_port; 131} 132 133void 134CheckerCPU::serialize(ostream &os) 135{ 136/* 137 BaseCPU::serialize(os); 138 SERIALIZE_SCALAR(inst); 139 nameOut(os, csprintf("%s.xc", name())); 140 thread->serialize(os); 141 cacheCompletionEvent.serialize(os); 142*/ 143} 144 145void 146CheckerCPU::unserialize(Checkpoint *cp, const string §ion) 147{ 148/* 149 BaseCPU::unserialize(cp, section); 150 UNSERIALIZE_SCALAR(inst); 151 thread->unserialize(cp, csprintf("%s.xc", section)); 152*/ 153} 154 155Fault 156CheckerCPU::copySrcTranslate(Addr src) 157{ 158 panic("Unimplemented!"); 159} 160 161Fault 162CheckerCPU::copy(Addr dest) 163{ 164 panic("Unimplemented!"); 165} 166 167template <class T> 168Fault 169CheckerCPU::read(Addr addr, T &data, unsigned flags) 170{ 171 // need to fill in CPU & thread IDs here 172 memReq = new Request(); 173 174 memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 175 176 // translate to physical address 177 translateDataReadReq(memReq); 178 179 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); 180 181 pkt->dataStatic(&data); 182 183 if (!(memReq->getFlags() & UNCACHEABLE)) { 184 // Access memory to see if we have the same data 185 dcachePort->sendFunctional(pkt); 186 } else { 187 // Assume the data is correct if it's an uncached access 188 memcpy(&data, &unverifiedResult.integer, sizeof(T)); 189 } 190 191 delete pkt; 192 193 return NoFault; 194} 195 196#ifndef DOXYGEN_SHOULD_SKIP_THIS 197 198template 199Fault 200CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags); 201 202template 203Fault 204CheckerCPU::read(Addr addr, uint32_t &data, unsigned flags); 205 206template 207Fault 208CheckerCPU::read(Addr addr, uint16_t &data, unsigned flags); 209 210template 211Fault 212CheckerCPU::read(Addr addr, uint8_t &data, unsigned flags); 213 214#endif //DOXYGEN_SHOULD_SKIP_THIS 215 216template<> 217Fault 218CheckerCPU::read(Addr addr, double &data, unsigned flags) 219{ 220 return read(addr, *(uint64_t*)&data, flags); 221} 222 223template<> 224Fault 225CheckerCPU::read(Addr addr, float &data, unsigned flags) 226{ 227 return read(addr, *(uint32_t*)&data, flags); 228} 229 230template<> 231Fault 232CheckerCPU::read(Addr addr, int32_t &data, unsigned flags) 233{ 234 return read(addr, (uint32_t&)data, flags); 235} 236 237template <class T> 238Fault 239CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 240{ 241 // need to fill in CPU & thread IDs here 242 memReq = new Request(); 243 244 memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); 245 246 // translate to physical address 247 thread->translateDataWriteReq(memReq); 248 249 // Can compare the write data and result only if it's cacheable, 250 // not a store conditional, or is a store conditional that 251 // succeeded. 252 // @todo: Verify that actual memory matches up with these values. 253 // Right now it only verifies that the instruction data is the 254 // same as what was in the request that got sent to memory; there 255 // is no verification that it is the same as what is in memory. 256 // This is because the LSQ would have to be snooped in the CPU to 257 // verify this data. 258 if (unverifiedReq && 259 !(unverifiedReq->getFlags() & UNCACHEABLE) && 260 (!(unverifiedReq->getFlags() & LOCKED) || 261 ((unverifiedReq->getFlags() & LOCKED) && 262 unverifiedReq->getScResult() == 1))) { 263 T inst_data; 264/* 265 // This code would work if the LSQ allowed for snooping. 266 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); 267 pkt.dataStatic(&inst_data); 268 269 dcachePort->sendFunctional(pkt); 270 271 delete pkt; 272*/ 273 memcpy(&inst_data, unverifiedMemData, sizeof(T)); 274 275 if (data != inst_data) { 276 warn("%lli: Store value does not match value in memory! " 277 "Instruction: %#x, memory: %#x", 278 curTick, inst_data, data); 279 handleError(); 280 } 281 } 282 283 // Assume the result was the same as the one passed in. This checker 284 // doesn't check if the SC should succeed or fail, it just checks the 285 // value. 286 if (res && unverifiedReq->scResultValid()) 287 *res = unverifiedReq->getScResult(); 288 289 return NoFault; 290} 291 292 293#ifndef DOXYGEN_SHOULD_SKIP_THIS 294template 295Fault 296CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); 297 298template 299Fault 300CheckerCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res); 301 302template 303Fault 304CheckerCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res); 305 306template 307Fault 308CheckerCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res); 309 310#endif //DOXYGEN_SHOULD_SKIP_THIS 311 312template<> 313Fault 314CheckerCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) 315{ 316 return write(*(uint64_t*)&data, addr, flags, res); 317} 318 319template<> 320Fault 321CheckerCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) 322{ 323 return write(*(uint32_t*)&data, addr, flags, res); 324} 325 326template<> 327Fault 328CheckerCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) 329{ 330 return write((uint32_t)data, addr, flags, res); 331} 332 333 334#if FULL_SYSTEM 335Addr 336CheckerCPU::dbg_vtophys(Addr addr) 337{ 338 return vtophys(tc, addr); 339} 340#endif // FULL_SYSTEM 341 342bool 343CheckerCPU::translateInstReq(Request *req) 344{ 345#if FULL_SYSTEM 346 return (thread->translateInstReq(req) == NoFault); 347#else 348 thread->translateInstReq(req); 349 return true; 350#endif 351} 352 353void 354CheckerCPU::translateDataReadReq(Request *req) 355{ 356 thread->translateDataReadReq(req); 357 358 if (req->getVaddr() != unverifiedReq->getVaddr()) { 359 warn("%lli: Request virtual addresses do not match! Inst: %#x, " 360 "checker: %#x", 361 curTick, unverifiedReq->getVaddr(), req->getVaddr()); 362 handleError(); 363 } 364 req->setPaddr(unverifiedReq->getPaddr()); 365 366 if (checkFlags(req)) { 367 warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", 368 curTick, unverifiedReq->getFlags(), req->getFlags()); 369 handleError(); 370 } 371} 372 373void 374CheckerCPU::translateDataWriteReq(Request *req) 375{ 376 thread->translateDataWriteReq(req); 377 378 if (req->getVaddr() != unverifiedReq->getVaddr()) { 379 warn("%lli: Request virtual addresses do not match! Inst: %#x, " 380 "checker: %#x", 381 curTick, unverifiedReq->getVaddr(), req->getVaddr()); 382 handleError(); 383 } 384 req->setPaddr(unverifiedReq->getPaddr()); 385 386 if (checkFlags(req)) { 387 warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", 388 curTick, unverifiedReq->getFlags(), req->getFlags()); 389 handleError(); 390 } 391} 392 393bool 394CheckerCPU::checkFlags(Request *req) 395{ 396 // Remove any dynamic flags that don't have to do with the request itself. 397 unsigned flags = unverifiedReq->getFlags(); 398 unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT; 399 flags = flags & (mask); 400 if (flags == req->getFlags()) { 401 return false; 402 } else { 403 return true; 404 } 405} 406 407void 408CheckerCPU::dumpAndExit() 409{ 410 warn("%lli: Checker PC:%#x, next PC:%#x", 411 curTick, thread->readPC(), thread->readNextPC()); 412 panic("Checker found an error!"); 413} 414 | |
415template <class DynInstPtr> 416void 417Checker<DynInstPtr>::verify(DynInstPtr &completed_inst) 418{ 419 DynInstPtr inst; 420 421 // Either check this instruction, or add it to a list of 422 // instructions waiting to be checked. Instructions must be --- 400 unchanged lines hidden --- | 53template <class DynInstPtr> 54void 55Checker<DynInstPtr>::verify(DynInstPtr &completed_inst) 56{ 57 DynInstPtr inst; 58 59 // Either check this instruction, or add it to a list of 60 // instructions waiting to be checked. Instructions must be --- 400 unchanged lines hidden --- |