base.cc (2680:246e7104f744) | base.cc (2683:d6b72bb2ed97) |
---|---|
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; --- 24 unchanged lines hidden (view full) --- 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" | 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; --- 24 unchanged lines hidden (view full) --- 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/thread_context.hh" | |
43#include "cpu/exetrace.hh" 44#include "cpu/profile.hh" 45#include "cpu/sampler/sampler.hh" 46#include "cpu/simple/base.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/simple_thread.hh" |
|
47#include "cpu/smt.hh" 48#include "cpu/static_inst.hh" | 46#include "cpu/smt.hh" 47#include "cpu/static_inst.hh" |
48#include "cpu/thread_context.hh" |
|
49#include "kern/kernel_stats.hh" 50#include "mem/packet_impl.hh" | 49#include "kern/kernel_stats.hh" 50#include "mem/packet_impl.hh" |
51#include "sim/byteswap.hh" | |
52#include "sim/builder.hh" | 51#include "sim/builder.hh" |
52#include "sim/byteswap.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" --- 4 unchanged lines hidden (view full) --- 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) | 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" --- 4 unchanged lines hidden (view full) --- 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) | 73 : BaseCPU(p), mem(p->mem), thread(NULL) |
74{ 75#if FULL_SYSTEM | 74{ 75#if FULL_SYSTEM |
76 cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb); | 76 thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); |
77#else | 77#else |
78 cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, | 78 thread = new SimpleThread(this, /* thread_num */ 0, p->process, |
79 /* asid */ 0, mem); 80#endif // !FULL_SYSTEM 81 | 79 /* asid */ 0, mem); 80#endif // !FULL_SYSTEM 81 |
82 cpuXC->setStatus(ThreadContext::Suspended); | 82 thread->setStatus(ThreadContext::Suspended); |
83 | 83 |
84 tc = cpuXC->getTC(); | 84 tc = thread->getTC(); |
85 86 numInst = 0; 87 startNumInst = 0; 88 numLoad = 0; 89 startNumLoad = 0; 90 lastIcacheStall = 0; 91 lastDcacheStall = 0; 92 --- 82 unchanged lines hidden (view full) --- 175} 176 177void 178BaseSimpleCPU::serialize(ostream &os) 179{ 180 BaseCPU::serialize(os); 181 SERIALIZE_SCALAR(inst); 182 nameOut(os, csprintf("%s.xc", name())); | 85 86 numInst = 0; 87 startNumInst = 0; 88 numLoad = 0; 89 startNumLoad = 0; 90 lastIcacheStall = 0; 91 lastDcacheStall = 0; 92 --- 82 unchanged lines hidden (view full) --- 175} 176 177void 178BaseSimpleCPU::serialize(ostream &os) 179{ 180 BaseCPU::serialize(os); 181 SERIALIZE_SCALAR(inst); 182 nameOut(os, csprintf("%s.xc", name())); |
183 cpuXC->serialize(os); | 183 thread->serialize(os); |
184} 185 186void 187BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 188{ 189 BaseCPU::unserialize(cp, section); 190 UNSERIALIZE_SCALAR(inst); | 184} 185 186void 187BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 188{ 189 BaseCPU::unserialize(cp, section); 190 UNSERIALIZE_SCALAR(inst); |
191 cpuXC->unserialize(cp, csprintf("%s.xc", section)); | 191 thread->unserialize(cp, csprintf("%s.xc", section)); |
192} 193 194void 195change_thread_state(int thread_number, int activate, int priority) 196{ 197} 198 199Fault --- 12 unchanged lines hidden (view full) --- 212 (src >> 40) != 0xfffffc) { 213 warn("Copied block source spans pages %x.", src); 214 no_warn = false; 215 } 216 217 memReq->reset(src & ~(blk_size - 1), blk_size); 218 219 // translate to physical address | 192} 193 194void 195change_thread_state(int thread_number, int activate, int priority) 196{ 197} 198 199Fault --- 12 unchanged lines hidden (view full) --- 212 (src >> 40) != 0xfffffc) { 213 warn("Copied block source spans pages %x.", src); 214 no_warn = false; 215 } 216 217 memReq->reset(src & ~(blk_size - 1), blk_size); 218 219 // translate to physical address |
220 Fault fault = cpuXC->translateDataReadReq(req); | 220 Fault fault = thread->translateDataReadReq(req); |
221 222 if (fault == NoFault) { | 221 222 if (fault == NoFault) { |
223 cpuXC->copySrcAddr = src; 224 cpuXC->copySrcPhysAddr = memReq->paddr + offset; | 223 thread->copySrcAddr = src; 224 thread->copySrcPhysAddr = memReq->paddr + offset; |
225 } else { 226 assert(!fault->isAlignmentFault()); 227 | 225 } else { 226 assert(!fault->isAlignmentFault()); 227 |
228 cpuXC->copySrcAddr = 0; 229 cpuXC->copySrcPhysAddr = 0; | 228 thread->copySrcAddr = 0; 229 thread->copySrcPhysAddr = 0; |
230 } 231 return fault; 232#else 233 return NoFault; 234#endif 235} 236 237Fault 238BaseSimpleCPU::copy(Addr dest) 239{ 240#if 0 241 static bool no_warn = true; 242 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 243 // Only support block sizes of 64 atm. 244 assert(blk_size == 64); 245 uint8_t data[blk_size]; | 230 } 231 return fault; 232#else 233 return NoFault; 234#endif 235} 236 237Fault 238BaseSimpleCPU::copy(Addr dest) 239{ 240#if 0 241 static bool no_warn = true; 242 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 243 // Only support block sizes of 64 atm. 244 assert(blk_size == 64); 245 uint8_t data[blk_size]; |
246 //assert(cpuXC->copySrcAddr); | 246 //assert(thread->copySrcAddr); |
247 int offset = dest & (blk_size - 1); 248 249 // Make sure block doesn't span page 250 if (no_warn && 251 (dest & PageMask) != ((dest + blk_size) & PageMask) && 252 (dest >> 40) != 0xfffffc) { 253 no_warn = false; 254 warn("Copied block destination spans pages %x. ", dest); 255 } 256 257 memReq->reset(dest & ~(blk_size -1), blk_size); 258 // translate to physical address | 247 int offset = dest & (blk_size - 1); 248 249 // Make sure block doesn't span page 250 if (no_warn && 251 (dest & PageMask) != ((dest + blk_size) & PageMask) && 252 (dest >> 40) != 0xfffffc) { 253 no_warn = false; 254 warn("Copied block destination spans pages %x. ", dest); 255 } 256 257 memReq->reset(dest & ~(blk_size -1), blk_size); 258 // translate to physical address |
259 Fault fault = cpuXC->translateDataWriteReq(req); | 259 Fault fault = thread->translateDataWriteReq(req); |
260 261 if (fault == NoFault) { 262 Addr dest_addr = memReq->paddr + offset; 263 // Need to read straight from memory since we have more than 8 bytes. | 260 261 if (fault == NoFault) { 262 Addr dest_addr = memReq->paddr + offset; 263 // Need to read straight from memory since we have more than 8 bytes. |
264 memReq->paddr = cpuXC->copySrcPhysAddr; 265 cpuXC->mem->read(memReq, data); | 264 memReq->paddr = thread->copySrcPhysAddr; 265 thread->mem->read(memReq, data); |
266 memReq->paddr = dest_addr; | 266 memReq->paddr = dest_addr; |
267 cpuXC->mem->write(memReq, data); | 267 thread->mem->write(memReq, data); |
268 if (dcacheInterface) { 269 memReq->cmd = Copy; 270 memReq->completionEvent = NULL; | 268 if (dcacheInterface) { 269 memReq->cmd = Copy; 270 memReq->completionEvent = NULL; |
271 memReq->paddr = cpuXC->copySrcPhysAddr; | 271 memReq->paddr = thread->copySrcPhysAddr; |
272 memReq->dest = dest_addr; 273 memReq->size = 64; 274 memReq->time = curTick; 275 memReq->flags &= ~INST_READ; 276 dcacheInterface->access(memReq); 277 } 278 } 279 else --- 15 unchanged lines hidden (view full) --- 295#endif // FULL_SYSTEM 296 297#if FULL_SYSTEM 298void 299BaseSimpleCPU::post_interrupt(int int_num, int index) 300{ 301 BaseCPU::post_interrupt(int_num, index); 302 | 272 memReq->dest = dest_addr; 273 memReq->size = 64; 274 memReq->time = curTick; 275 memReq->flags &= ~INST_READ; 276 dcacheInterface->access(memReq); 277 } 278 } 279 else --- 15 unchanged lines hidden (view full) --- 295#endif // FULL_SYSTEM 296 297#if FULL_SYSTEM 298void 299BaseSimpleCPU::post_interrupt(int int_num, int index) 300{ 301 BaseCPU::post_interrupt(int_num, index); 302 |
303 if (cpuXC->status() == ThreadContext::Suspended) { | 303 if (thread->status() == ThreadContext::Suspended) { |
304 DPRINTF(IPI,"Suspended Processor awoke\n"); | 304 DPRINTF(IPI,"Suspended Processor awoke\n"); |
305 cpuXC->activate(); | 305 thread->activate(); |
306 } 307} 308#endif // FULL_SYSTEM 309 310void 311BaseSimpleCPU::checkForInterrupts() 312{ 313#if FULL_SYSTEM | 306 } 307} 308#endif // FULL_SYSTEM 309 310void 311BaseSimpleCPU::checkForInterrupts() 312{ 313#if FULL_SYSTEM |
314 if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode()) { | 314 if (checkInterrupts && check_interrupts() && !thread->inPalMode()) { |
315 int ipl = 0; 316 int summary = 0; 317 checkInterrupts = false; 318 | 315 int ipl = 0; 316 int summary = 0; 317 checkInterrupts = false; 318 |
319 if (cpuXC->readMiscReg(IPR_SIRR)) { | 319 if (thread->readMiscReg(IPR_SIRR)) { |
320 for (int i = INTLEVEL_SOFTWARE_MIN; 321 i < INTLEVEL_SOFTWARE_MAX; i++) { | 320 for (int i = INTLEVEL_SOFTWARE_MIN; 321 i < INTLEVEL_SOFTWARE_MAX; i++) { |
322 if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { | 322 if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { |
323 // See table 4-19 of 21164 hardware reference 324 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 325 summary |= (ULL(1) << i); 326 } 327 } 328 } 329 | 323 // See table 4-19 of 21164 hardware reference 324 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 325 summary |= (ULL(1) << i); 326 } 327 } 328 } 329 |
330 uint64_t interrupts = cpuXC->cpu->intr_status(); | 330 uint64_t interrupts = thread->cpu->intr_status(); |
331 for (int i = INTLEVEL_EXTERNAL_MIN; 332 i < INTLEVEL_EXTERNAL_MAX; i++) { 333 if (interrupts & (ULL(1) << i)) { 334 // See table 4-19 of 21164 hardware reference 335 ipl = i; 336 summary |= (ULL(1) << i); 337 } 338 } 339 | 331 for (int i = INTLEVEL_EXTERNAL_MIN; 332 i < INTLEVEL_EXTERNAL_MAX; i++) { 333 if (interrupts & (ULL(1) << i)) { 334 // See table 4-19 of 21164 hardware reference 335 ipl = i; 336 summary |= (ULL(1) << i); 337 } 338 } 339 |
340 if (cpuXC->readMiscReg(IPR_ASTRR)) | 340 if (thread->readMiscReg(IPR_ASTRR)) |
341 panic("asynchronous traps not implemented\n"); 342 | 341 panic("asynchronous traps not implemented\n"); 342 |
343 if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { 344 cpuXC->setMiscReg(IPR_ISR, summary); 345 cpuXC->setMiscReg(IPR_INTID, ipl); | 343 if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) { 344 thread->setMiscReg(IPR_ISR, summary); 345 thread->setMiscReg(IPR_INTID, ipl); |
346 347 Fault(new InterruptFault)->invoke(tc); 348 349 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", | 346 347 Fault(new InterruptFault)->invoke(tc); 348 349 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", |
350 cpuXC->readMiscReg(IPR_IPLR), ipl, summary); | 350 thread->readMiscReg(IPR_IPLR), ipl, summary); |
351 } 352 } 353#endif 354} 355 356 357Fault 358BaseSimpleCPU::setupFetchRequest(Request *req) 359{ 360 // set up memory request for instruction fetch | 351 } 352 } 353#endif 354} 355 356 357Fault 358BaseSimpleCPU::setupFetchRequest(Request *req) 359{ 360 // set up memory request for instruction fetch |
361 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), 362 cpuXC->readNextPC(),cpuXC->readNextNPC()); | 361 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(), 362 thread->readNextPC(),thread->readNextNPC()); |
363 | 363 |
364 req->setVirt(0, cpuXC->readPC() & ~3, sizeof(MachInst), 365 (FULL_SYSTEM && (cpuXC->readPC() & 1)) ? PHYSICAL : 0, 366 cpuXC->readPC()); | 364 req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst), 365 (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0, 366 thread->readPC()); |
367 | 367 |
368 Fault fault = cpuXC->translateInstReq(req); | 368 Fault fault = thread->translateInstReq(req); |
369 370 return fault; 371} 372 373 374void 375BaseSimpleCPU::preExecute() 376{ 377 // maintain $r0 semantics | 369 370 return fault; 371} 372 373 374void 375BaseSimpleCPU::preExecute() 376{ 377 // maintain $r0 semantics |
378 cpuXC->setIntReg(ZeroReg, 0); | 378 thread->setIntReg(ZeroReg, 0); |
379#if THE_ISA == ALPHA_ISA | 379#if THE_ISA == ALPHA_ISA |
380 cpuXC->setFloatReg(ZeroReg, 0.0); | 380 thread->setFloatReg(ZeroReg, 0.0); |
381#endif // ALPHA_ISA 382 383 // keep an instruction count 384 numInst++; 385 numInsts++; 386 | 381#endif // ALPHA_ISA 382 383 // keep an instruction count 384 numInst++; 385 numInsts++; 386 |
387 cpuXC->func_exe_inst++; | 387 thread->funcExeInst++; |
388 389 // check for instruction-count-based events 390 comInstEventQueue[0]->serviceEvents(numInst); 391 392 // decode the instruction 393 inst = gtoh(inst); | 388 389 // check for instruction-count-based events 390 comInstEventQueue[0]->serviceEvents(numInst); 391 392 // decode the instruction 393 inst = gtoh(inst); |
394 curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC())); | 394 curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); |
395 396 traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst, | 395 396 traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst, |
397 cpuXC->readPC()); | 397 thread->readPC()); |
398 399 DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", 400 curStaticInst->getName(), curStaticInst->getOpcode(), 401 curStaticInst->machInst); 402 403#if FULL_SYSTEM | 398 399 DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", 400 curStaticInst->getName(), curStaticInst->getOpcode(), 401 curStaticInst->machInst); 402 403#if FULL_SYSTEM |
404 cpuXC->setInst(inst); | 404 thread->setInst(inst); |
405#endif // FULL_SYSTEM 406} 407 408void 409BaseSimpleCPU::postExecute() 410{ 411#if FULL_SYSTEM 412 if (system->kernelBinning->fnbin) { | 405#endif // FULL_SYSTEM 406} 407 408void 409BaseSimpleCPU::postExecute() 410{ 411#if FULL_SYSTEM 412 if (system->kernelBinning->fnbin) { |
413 assert(cpuXC->getKernelStats()); | 413 assert(thread->getKernelStats()); |
414 system->kernelBinning->execute(tc, inst); 415 } 416 | 414 system->kernelBinning->execute(tc, inst); 415 } 416 |
417 if (cpuXC->profile) { | 417 if (thread->profile) { |
418 bool usermode = | 418 bool usermode = |
419 (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; 420 cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); 421 ProfileNode *node = cpuXC->profile->consume(tc, inst); | 419 (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; 420 thread->profilePC = usermode ? 1 : thread->readPC(); 421 ProfileNode *node = thread->profile->consume(tc, inst); |
422 if (node) | 422 if (node) |
423 cpuXC->profileNode = node; | 423 thread->profileNode = node; |
424 } 425#endif 426 427 if (curStaticInst->isMemRef()) { 428 numMemRefs++; 429 } 430 431 if (curStaticInst->isLoad()) { 432 ++numLoad; 433 comLoadEventQueue[0]->serviceEvents(numLoad); 434 } 435 | 424 } 425#endif 426 427 if (curStaticInst->isMemRef()) { 428 numMemRefs++; 429 } 430 431 if (curStaticInst->isLoad()) { 432 ++numLoad; 433 comLoadEventQueue[0]->serviceEvents(numLoad); 434 } 435 |
436 traceFunctions(cpuXC->readPC()); | 436 traceFunctions(thread->readPC()); |
437 438 if (traceData) { 439 traceData->finalize(); 440 } 441} 442 443 444void 445BaseSimpleCPU::advancePC(Fault fault) 446{ 447 if (fault != NoFault) { 448#if FULL_SYSTEM 449 fault->invoke(tc); 450#else // !FULL_SYSTEM | 437 438 if (traceData) { 439 traceData->finalize(); 440 } 441} 442 443 444void 445BaseSimpleCPU::advancePC(Fault fault) 446{ 447 if (fault != NoFault) { 448#if FULL_SYSTEM 449 fault->invoke(tc); 450#else // !FULL_SYSTEM |
451 fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC()); | 451 fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC()); |
452#endif // FULL_SYSTEM 453 } 454 else { 455 // go to the next instruction | 452#endif // FULL_SYSTEM 453 } 454 else { 455 // go to the next instruction |
456 cpuXC->setPC(cpuXC->readNextPC()); | 456 thread->setPC(thread->readNextPC()); |
457#if THE_ISA == ALPHA_ISA | 457#if THE_ISA == ALPHA_ISA |
458 cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); | 458 thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); |
459#else | 459#else |
460 cpuXC->setNextPC(cpuXC->readNextNPC()); 461 cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); | 460 thread->setNextPC(thread->readNextNPC()); 461 thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); |
462#endif 463 464 } 465 466#if FULL_SYSTEM 467 Addr oldpc; 468 do { | 462#endif 463 464 } 465 466#if FULL_SYSTEM 467 Addr oldpc; 468 do { |
469 oldpc = cpuXC->readPC(); | 469 oldpc = thread->readPC(); |
470 system->pcEventQueue.service(tc); | 470 system->pcEventQueue.service(tc); |
471 } while (oldpc != cpuXC->readPC()); | 471 } while (oldpc != thread->readPC()); |
472#endif 473} 474 | 472#endif 473} 474 |