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.
| 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 29#include "arch/utility.hh" 30#include "base/cprintf.hh" 31#include "base/inifile.hh" 32#include "base/loader/symtab.hh" 33#include "base/misc.hh" 34#include "base/pollevent.hh" 35#include "base/range.hh" 36#include "base/stats/events.hh" 37#include "base/trace.hh" 38#include "cpu/base.hh" 39#include "cpu/cpu_exec_context.hh" 40#include "cpu/exec_context.hh" 41#include "cpu/exetrace.hh" 42#include "cpu/profile.hh" 43#include "cpu/sampler/sampler.hh" 44#include "cpu/simple/base.hh" 45#include "cpu/smt.hh" 46#include "cpu/static_inst.hh" 47#include "kern/kernel_stats.hh" 48#include "mem/packet_impl.hh" 49#include "sim/byteswap.hh" 50#include "sim/builder.hh" 51#include "sim/debug.hh" 52#include "sim/host.hh" 53#include "sim/sim_events.hh" 54#include "sim/sim_object.hh" 55#include "sim/stats.hh" 56 57#if FULL_SYSTEM 58#include "base/remote_gdb.hh" 59#include "sim/system.hh" 60#include "arch/tlb.hh" 61#include "arch/stacktrace.hh" 62#include "arch/vtophys.hh" 63#else // !FULL_SYSTEM 64#include "mem/mem_object.hh" 65#endif // FULL_SYSTEM 66 67using namespace std; 68using namespace TheISA; 69 70BaseSimpleCPU::BaseSimpleCPU(Params *p) 71 : BaseCPU(p), mem(p->mem), cpuXC(NULL) 72{ 73#if FULL_SYSTEM 74 cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb); 75#else 76 cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, 77 /* asid */ 0, mem); 78#endif // !FULL_SYSTEM 79 80 xcProxy = cpuXC->getProxy(); 81 82 numInst = 0; 83 startNumInst = 0; 84 numLoad = 0; 85 startNumLoad = 0; 86 lastIcacheStall = 0; 87 lastDcacheStall = 0; 88 89 execContexts.push_back(xcProxy); 90} 91 92BaseSimpleCPU::~BaseSimpleCPU() 93{ 94} 95 96void 97BaseSimpleCPU::deallocateContext(int thread_num) 98{ 99 // for now, these are equivalent 100 suspendContext(thread_num); 101} 102 103 104void 105BaseSimpleCPU::haltContext(int thread_num) 106{ 107 // for now, these are equivalent 108 suspendContext(thread_num); 109} 110 111 112void 113BaseSimpleCPU::regStats() 114{ 115 using namespace Stats; 116 117 BaseCPU::regStats(); 118 119 numInsts 120 .name(name() + ".num_insts") 121 .desc("Number of instructions executed") 122 ; 123 124 numMemRefs 125 .name(name() + ".num_refs") 126 .desc("Number of memory references") 127 ; 128 129 notIdleFraction 130 .name(name() + ".not_idle_fraction") 131 .desc("Percentage of non-idle cycles") 132 ; 133 134 idleFraction 135 .name(name() + ".idle_fraction") 136 .desc("Percentage of idle cycles") 137 ; 138 139 icacheStallCycles 140 .name(name() + ".icache_stall_cycles") 141 .desc("ICache total stall cycles") 142 .prereq(icacheStallCycles) 143 ; 144 145 dcacheStallCycles 146 .name(name() + ".dcache_stall_cycles") 147 .desc("DCache total stall cycles") 148 .prereq(dcacheStallCycles) 149 ; 150 151 icacheRetryCycles 152 .name(name() + ".icache_retry_cycles") 153 .desc("ICache total retry cycles") 154 .prereq(icacheRetryCycles) 155 ; 156 157 dcacheRetryCycles 158 .name(name() + ".dcache_retry_cycles") 159 .desc("DCache total retry cycles") 160 .prereq(dcacheRetryCycles) 161 ; 162 163 idleFraction = constant(1.0) - notIdleFraction; 164} 165 166void 167BaseSimpleCPU::resetStats() 168{ 169 startNumInst = numInst; 170 // notIdleFraction = (_status != Idle); 171} 172 173void 174BaseSimpleCPU::serialize(ostream &os) 175{ 176 BaseCPU::serialize(os); 177 SERIALIZE_SCALAR(inst); 178 nameOut(os, csprintf("%s.xc", name())); 179 cpuXC->serialize(os); 180} 181 182void 183BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 184{ 185 BaseCPU::unserialize(cp, section); 186 UNSERIALIZE_SCALAR(inst); 187 cpuXC->unserialize(cp, csprintf("%s.xc", section)); 188} 189 190void 191change_thread_state(int thread_number, int activate, int priority) 192{ 193} 194 195Fault 196BaseSimpleCPU::copySrcTranslate(Addr src) 197{ 198#if 0 199 static bool no_warn = true; 200 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 201 // Only support block sizes of 64 atm. 202 assert(blk_size == 64); 203 int offset = src & (blk_size - 1); 204 205 // Make sure block doesn't span page 206 if (no_warn && 207 (src & PageMask) != ((src + blk_size) & PageMask) && 208 (src >> 40) != 0xfffffc) { 209 warn("Copied block source spans pages %x.", src); 210 no_warn = false; 211 } 212 213 memReq->reset(src & ~(blk_size - 1), blk_size); 214 215 // translate to physical address 216 Fault fault = cpuXC->translateDataReadReq(req); 217 218 if (fault == NoFault) { 219 cpuXC->copySrcAddr = src; 220 cpuXC->copySrcPhysAddr = memReq->paddr + offset; 221 } else { 222 assert(!fault->isAlignmentFault()); 223 224 cpuXC->copySrcAddr = 0; 225 cpuXC->copySrcPhysAddr = 0; 226 } 227 return fault; 228#else 229 return NoFault; 230#endif 231} 232 233Fault 234BaseSimpleCPU::copy(Addr dest) 235{ 236#if 0 237 static bool no_warn = true; 238 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 239 // Only support block sizes of 64 atm. 240 assert(blk_size == 64); 241 uint8_t data[blk_size]; 242 //assert(cpuXC->copySrcAddr); 243 int offset = dest & (blk_size - 1); 244 245 // Make sure block doesn't span page 246 if (no_warn && 247 (dest & PageMask) != ((dest + blk_size) & PageMask) && 248 (dest >> 40) != 0xfffffc) { 249 no_warn = false; 250 warn("Copied block destination spans pages %x. ", dest); 251 } 252 253 memReq->reset(dest & ~(blk_size -1), blk_size); 254 // translate to physical address 255 Fault fault = cpuXC->translateDataWriteReq(req); 256 257 if (fault == NoFault) { 258 Addr dest_addr = memReq->paddr + offset; 259 // Need to read straight from memory since we have more than 8 bytes. 260 memReq->paddr = cpuXC->copySrcPhysAddr; 261 cpuXC->mem->read(memReq, data); 262 memReq->paddr = dest_addr; 263 cpuXC->mem->write(memReq, data); 264 if (dcacheInterface) { 265 memReq->cmd = Copy; 266 memReq->completionEvent = NULL; 267 memReq->paddr = cpuXC->copySrcPhysAddr; 268 memReq->dest = dest_addr; 269 memReq->size = 64; 270 memReq->time = curTick; 271 memReq->flags &= ~INST_READ; 272 dcacheInterface->access(memReq); 273 } 274 } 275 else 276 assert(!fault->isAlignmentFault()); 277 278 return fault; 279#else 280 panic("copy not implemented"); 281 return NoFault; 282#endif 283} 284 285#if FULL_SYSTEM 286Addr 287BaseSimpleCPU::dbg_vtophys(Addr addr) 288{ 289 return vtophys(xcProxy, addr); 290} 291#endif // FULL_SYSTEM 292 293#if FULL_SYSTEM 294void 295BaseSimpleCPU::post_interrupt(int int_num, int index) 296{ 297 BaseCPU::post_interrupt(int_num, index); 298 299 if (cpuXC->status() == ExecContext::Suspended) { 300 DPRINTF(IPI,"Suspended Processor awoke\n"); 301 cpuXC->activate(); 302 } 303} 304#endif // FULL_SYSTEM 305 306void 307BaseSimpleCPU::checkForInterrupts() 308{ 309#if FULL_SYSTEM 310 if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode()) { 311 int ipl = 0; 312 int summary = 0; 313 checkInterrupts = false; 314 315 if (cpuXC->readMiscReg(IPR_SIRR)) { 316 for (int i = INTLEVEL_SOFTWARE_MIN; 317 i < INTLEVEL_SOFTWARE_MAX; i++) { 318 if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { 319 // See table 4-19 of 21164 hardware reference 320 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 321 summary |= (ULL(1) << i); 322 } 323 } 324 } 325 326 uint64_t interrupts = cpuXC->cpu->intr_status(); 327 for (int i = INTLEVEL_EXTERNAL_MIN; 328 i < INTLEVEL_EXTERNAL_MAX; i++) { 329 if (interrupts & (ULL(1) << i)) { 330 // See table 4-19 of 21164 hardware reference 331 ipl = i; 332 summary |= (ULL(1) << i); 333 } 334 } 335 336 if (cpuXC->readMiscReg(IPR_ASTRR)) 337 panic("asynchronous traps not implemented\n"); 338 339 if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { 340 cpuXC->setMiscReg(IPR_ISR, summary); 341 cpuXC->setMiscReg(IPR_INTID, ipl); 342 343 Fault(new InterruptFault)->invoke(xcProxy); 344 345 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 346 cpuXC->readMiscReg(IPR_IPLR), ipl, summary); 347 } 348 } 349#endif 350} 351 352 353Fault 354BaseSimpleCPU::setupFetchRequest(Request *req) 355{ 356 // set up memory request for instruction fetch 357 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), 358 cpuXC->readNextPC(),cpuXC->readNextNPC()); 359 360 req->setVirt(0, cpuXC->readPC() & ~3, sizeof(MachInst), 361 (FULL_SYSTEM && (cpuXC->readPC() & 1)) ? PHYSICAL : 0, 362 cpuXC->readPC()); 363 364 Fault fault = cpuXC->translateInstReq(req); 365 366 return fault; 367} 368 369 370void 371BaseSimpleCPU::preExecute() 372{ 373 // maintain $r0 semantics 374 cpuXC->setIntReg(ZeroReg, 0); 375#if THE_ISA == ALPHA_ISA 376 cpuXC->setFloatReg(ZeroReg, 0.0); 377#endif // ALPHA_ISA 378 379 // keep an instruction count 380 numInst++; 381 numInsts++; 382 383 cpuXC->func_exe_inst++; 384 385 // check for instruction-count-based events 386 comInstEventQueue[0]->serviceEvents(numInst); 387 388 // decode the instruction 389 inst = gtoh(inst); 390 curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC())); 391 392 traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, 393 cpuXC->readPC()); 394 395 DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", 396 curStaticInst->getName(), curStaticInst->getOpcode(), 397 curStaticInst->machInst); 398 399#if FULL_SYSTEM 400 cpuXC->setInst(inst); 401#endif // FULL_SYSTEM 402} 403 404void 405BaseSimpleCPU::postExecute() 406{ 407#if FULL_SYSTEM 408 if (system->kernelBinning->fnbin) { 409 assert(kernelStats); 410 system->kernelBinning->execute(xcProxy, inst); 411 } 412 413 if (cpuXC->profile) { 414 bool usermode = 415 (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; 416 cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); 417 ProfileNode *node = cpuXC->profile->consume(xcProxy, inst); 418 if (node) 419 cpuXC->profileNode = node; 420 } 421#endif 422 423 if (curStaticInst->isMemRef()) { 424 numMemRefs++; 425 } 426 427 if (curStaticInst->isLoad()) { 428 ++numLoad; 429 comLoadEventQueue[0]->serviceEvents(numLoad); 430 } 431 432 traceFunctions(cpuXC->readPC()); 433 434 if (traceData) { 435 traceData->finalize(); 436 } 437} 438 439 440void 441BaseSimpleCPU::advancePC(Fault fault) 442{ 443 if (fault != NoFault) { 444#if FULL_SYSTEM 445 fault->invoke(xcProxy); 446#else // !FULL_SYSTEM 447 fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC()); 448#endif // FULL_SYSTEM 449 } 450 else { 451 // go to the next instruction 452 cpuXC->setPC(cpuXC->readNextPC()); 453#if THE_ISA == ALPHA_ISA 454 cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); 455#else 456 cpuXC->setNextPC(cpuXC->readNextNPC()); 457 cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); 458#endif 459 460 } 461 462#if FULL_SYSTEM 463 Addr oldpc; 464 do { 465 oldpc = cpuXC->readPC(); 466 system->pcEventQueue.service(xcProxy); 467 } while (oldpc != cpuXC->readPC()); 468#endif 469} 470
| 29 */ 30 31#include "arch/utility.hh" 32#include "base/cprintf.hh" 33#include "base/inifile.hh" 34#include "base/loader/symtab.hh" 35#include "base/misc.hh" 36#include "base/pollevent.hh" 37#include "base/range.hh" 38#include "base/stats/events.hh" 39#include "base/trace.hh" 40#include "cpu/base.hh" 41#include "cpu/cpu_exec_context.hh" 42#include "cpu/exec_context.hh" 43#include "cpu/exetrace.hh" 44#include "cpu/profile.hh" 45#include "cpu/sampler/sampler.hh" 46#include "cpu/simple/base.hh" 47#include "cpu/smt.hh" 48#include "cpu/static_inst.hh" 49#include "kern/kernel_stats.hh" 50#include "mem/packet_impl.hh" 51#include "sim/byteswap.hh" 52#include "sim/builder.hh" 53#include "sim/debug.hh" 54#include "sim/host.hh" 55#include "sim/sim_events.hh" 56#include "sim/sim_object.hh" 57#include "sim/stats.hh" 58 59#if FULL_SYSTEM 60#include "base/remote_gdb.hh" 61#include "sim/system.hh" 62#include "arch/tlb.hh" 63#include "arch/stacktrace.hh" 64#include "arch/vtophys.hh" 65#else // !FULL_SYSTEM 66#include "mem/mem_object.hh" 67#endif // FULL_SYSTEM 68 69using namespace std; 70using namespace TheISA; 71 72BaseSimpleCPU::BaseSimpleCPU(Params *p) 73 : BaseCPU(p), mem(p->mem), cpuXC(NULL) 74{ 75#if FULL_SYSTEM 76 cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb); 77#else 78 cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, 79 /* asid */ 0, mem); 80#endif // !FULL_SYSTEM 81 82 xcProxy = cpuXC->getProxy(); 83 84 numInst = 0; 85 startNumInst = 0; 86 numLoad = 0; 87 startNumLoad = 0; 88 lastIcacheStall = 0; 89 lastDcacheStall = 0; 90 91 execContexts.push_back(xcProxy); 92} 93 94BaseSimpleCPU::~BaseSimpleCPU() 95{ 96} 97 98void 99BaseSimpleCPU::deallocateContext(int thread_num) 100{ 101 // for now, these are equivalent 102 suspendContext(thread_num); 103} 104 105 106void 107BaseSimpleCPU::haltContext(int thread_num) 108{ 109 // for now, these are equivalent 110 suspendContext(thread_num); 111} 112 113 114void 115BaseSimpleCPU::regStats() 116{ 117 using namespace Stats; 118 119 BaseCPU::regStats(); 120 121 numInsts 122 .name(name() + ".num_insts") 123 .desc("Number of instructions executed") 124 ; 125 126 numMemRefs 127 .name(name() + ".num_refs") 128 .desc("Number of memory references") 129 ; 130 131 notIdleFraction 132 .name(name() + ".not_idle_fraction") 133 .desc("Percentage of non-idle cycles") 134 ; 135 136 idleFraction 137 .name(name() + ".idle_fraction") 138 .desc("Percentage of idle cycles") 139 ; 140 141 icacheStallCycles 142 .name(name() + ".icache_stall_cycles") 143 .desc("ICache total stall cycles") 144 .prereq(icacheStallCycles) 145 ; 146 147 dcacheStallCycles 148 .name(name() + ".dcache_stall_cycles") 149 .desc("DCache total stall cycles") 150 .prereq(dcacheStallCycles) 151 ; 152 153 icacheRetryCycles 154 .name(name() + ".icache_retry_cycles") 155 .desc("ICache total retry cycles") 156 .prereq(icacheRetryCycles) 157 ; 158 159 dcacheRetryCycles 160 .name(name() + ".dcache_retry_cycles") 161 .desc("DCache total retry cycles") 162 .prereq(dcacheRetryCycles) 163 ; 164 165 idleFraction = constant(1.0) - notIdleFraction; 166} 167 168void 169BaseSimpleCPU::resetStats() 170{ 171 startNumInst = numInst; 172 // notIdleFraction = (_status != Idle); 173} 174 175void 176BaseSimpleCPU::serialize(ostream &os) 177{ 178 BaseCPU::serialize(os); 179 SERIALIZE_SCALAR(inst); 180 nameOut(os, csprintf("%s.xc", name())); 181 cpuXC->serialize(os); 182} 183 184void 185BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 186{ 187 BaseCPU::unserialize(cp, section); 188 UNSERIALIZE_SCALAR(inst); 189 cpuXC->unserialize(cp, csprintf("%s.xc", section)); 190} 191 192void 193change_thread_state(int thread_number, int activate, int priority) 194{ 195} 196 197Fault 198BaseSimpleCPU::copySrcTranslate(Addr src) 199{ 200#if 0 201 static bool no_warn = true; 202 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 203 // Only support block sizes of 64 atm. 204 assert(blk_size == 64); 205 int offset = src & (blk_size - 1); 206 207 // Make sure block doesn't span page 208 if (no_warn && 209 (src & PageMask) != ((src + blk_size) & PageMask) && 210 (src >> 40) != 0xfffffc) { 211 warn("Copied block source spans pages %x.", src); 212 no_warn = false; 213 } 214 215 memReq->reset(src & ~(blk_size - 1), blk_size); 216 217 // translate to physical address 218 Fault fault = cpuXC->translateDataReadReq(req); 219 220 if (fault == NoFault) { 221 cpuXC->copySrcAddr = src; 222 cpuXC->copySrcPhysAddr = memReq->paddr + offset; 223 } else { 224 assert(!fault->isAlignmentFault()); 225 226 cpuXC->copySrcAddr = 0; 227 cpuXC->copySrcPhysAddr = 0; 228 } 229 return fault; 230#else 231 return NoFault; 232#endif 233} 234 235Fault 236BaseSimpleCPU::copy(Addr dest) 237{ 238#if 0 239 static bool no_warn = true; 240 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 241 // Only support block sizes of 64 atm. 242 assert(blk_size == 64); 243 uint8_t data[blk_size]; 244 //assert(cpuXC->copySrcAddr); 245 int offset = dest & (blk_size - 1); 246 247 // Make sure block doesn't span page 248 if (no_warn && 249 (dest & PageMask) != ((dest + blk_size) & PageMask) && 250 (dest >> 40) != 0xfffffc) { 251 no_warn = false; 252 warn("Copied block destination spans pages %x. ", dest); 253 } 254 255 memReq->reset(dest & ~(blk_size -1), blk_size); 256 // translate to physical address 257 Fault fault = cpuXC->translateDataWriteReq(req); 258 259 if (fault == NoFault) { 260 Addr dest_addr = memReq->paddr + offset; 261 // Need to read straight from memory since we have more than 8 bytes. 262 memReq->paddr = cpuXC->copySrcPhysAddr; 263 cpuXC->mem->read(memReq, data); 264 memReq->paddr = dest_addr; 265 cpuXC->mem->write(memReq, data); 266 if (dcacheInterface) { 267 memReq->cmd = Copy; 268 memReq->completionEvent = NULL; 269 memReq->paddr = cpuXC->copySrcPhysAddr; 270 memReq->dest = dest_addr; 271 memReq->size = 64; 272 memReq->time = curTick; 273 memReq->flags &= ~INST_READ; 274 dcacheInterface->access(memReq); 275 } 276 } 277 else 278 assert(!fault->isAlignmentFault()); 279 280 return fault; 281#else 282 panic("copy not implemented"); 283 return NoFault; 284#endif 285} 286 287#if FULL_SYSTEM 288Addr 289BaseSimpleCPU::dbg_vtophys(Addr addr) 290{ 291 return vtophys(xcProxy, addr); 292} 293#endif // FULL_SYSTEM 294 295#if FULL_SYSTEM 296void 297BaseSimpleCPU::post_interrupt(int int_num, int index) 298{ 299 BaseCPU::post_interrupt(int_num, index); 300 301 if (cpuXC->status() == ExecContext::Suspended) { 302 DPRINTF(IPI,"Suspended Processor awoke\n"); 303 cpuXC->activate(); 304 } 305} 306#endif // FULL_SYSTEM 307 308void 309BaseSimpleCPU::checkForInterrupts() 310{ 311#if FULL_SYSTEM 312 if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode()) { 313 int ipl = 0; 314 int summary = 0; 315 checkInterrupts = false; 316 317 if (cpuXC->readMiscReg(IPR_SIRR)) { 318 for (int i = INTLEVEL_SOFTWARE_MIN; 319 i < INTLEVEL_SOFTWARE_MAX; i++) { 320 if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { 321 // See table 4-19 of 21164 hardware reference 322 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 323 summary |= (ULL(1) << i); 324 } 325 } 326 } 327 328 uint64_t interrupts = cpuXC->cpu->intr_status(); 329 for (int i = INTLEVEL_EXTERNAL_MIN; 330 i < INTLEVEL_EXTERNAL_MAX; i++) { 331 if (interrupts & (ULL(1) << i)) { 332 // See table 4-19 of 21164 hardware reference 333 ipl = i; 334 summary |= (ULL(1) << i); 335 } 336 } 337 338 if (cpuXC->readMiscReg(IPR_ASTRR)) 339 panic("asynchronous traps not implemented\n"); 340 341 if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { 342 cpuXC->setMiscReg(IPR_ISR, summary); 343 cpuXC->setMiscReg(IPR_INTID, ipl); 344 345 Fault(new InterruptFault)->invoke(xcProxy); 346 347 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 348 cpuXC->readMiscReg(IPR_IPLR), ipl, summary); 349 } 350 } 351#endif 352} 353 354 355Fault 356BaseSimpleCPU::setupFetchRequest(Request *req) 357{ 358 // set up memory request for instruction fetch 359 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), 360 cpuXC->readNextPC(),cpuXC->readNextNPC()); 361 362 req->setVirt(0, cpuXC->readPC() & ~3, sizeof(MachInst), 363 (FULL_SYSTEM && (cpuXC->readPC() & 1)) ? PHYSICAL : 0, 364 cpuXC->readPC()); 365 366 Fault fault = cpuXC->translateInstReq(req); 367 368 return fault; 369} 370 371 372void 373BaseSimpleCPU::preExecute() 374{ 375 // maintain $r0 semantics 376 cpuXC->setIntReg(ZeroReg, 0); 377#if THE_ISA == ALPHA_ISA 378 cpuXC->setFloatReg(ZeroReg, 0.0); 379#endif // ALPHA_ISA 380 381 // keep an instruction count 382 numInst++; 383 numInsts++; 384 385 cpuXC->func_exe_inst++; 386 387 // check for instruction-count-based events 388 comInstEventQueue[0]->serviceEvents(numInst); 389 390 // decode the instruction 391 inst = gtoh(inst); 392 curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC())); 393 394 traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, 395 cpuXC->readPC()); 396 397 DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", 398 curStaticInst->getName(), curStaticInst->getOpcode(), 399 curStaticInst->machInst); 400 401#if FULL_SYSTEM 402 cpuXC->setInst(inst); 403#endif // FULL_SYSTEM 404} 405 406void 407BaseSimpleCPU::postExecute() 408{ 409#if FULL_SYSTEM 410 if (system->kernelBinning->fnbin) { 411 assert(kernelStats); 412 system->kernelBinning->execute(xcProxy, inst); 413 } 414 415 if (cpuXC->profile) { 416 bool usermode = 417 (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; 418 cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); 419 ProfileNode *node = cpuXC->profile->consume(xcProxy, inst); 420 if (node) 421 cpuXC->profileNode = node; 422 } 423#endif 424 425 if (curStaticInst->isMemRef()) { 426 numMemRefs++; 427 } 428 429 if (curStaticInst->isLoad()) { 430 ++numLoad; 431 comLoadEventQueue[0]->serviceEvents(numLoad); 432 } 433 434 traceFunctions(cpuXC->readPC()); 435 436 if (traceData) { 437 traceData->finalize(); 438 } 439} 440 441 442void 443BaseSimpleCPU::advancePC(Fault fault) 444{ 445 if (fault != NoFault) { 446#if FULL_SYSTEM 447 fault->invoke(xcProxy); 448#else // !FULL_SYSTEM 449 fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC()); 450#endif // FULL_SYSTEM 451 } 452 else { 453 // go to the next instruction 454 cpuXC->setPC(cpuXC->readNextPC()); 455#if THE_ISA == ALPHA_ISA 456 cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); 457#else 458 cpuXC->setNextPC(cpuXC->readNextNPC()); 459 cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); 460#endif 461 462 } 463 464#if FULL_SYSTEM 465 Addr oldpc; 466 do { 467 oldpc = cpuXC->readPC(); 468 system->pcEventQueue.service(xcProxy); 469 } while (oldpc != cpuXC->readPC()); 470#endif 471} 472
|