diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 86edf62cf..0722f319d 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -118,7 +118,7 @@ CPUProgressEvent::description() const return "CPU Progress"; } -BaseCPU::BaseCPU(Params *p) +BaseCPU::BaseCPU(Params *p, bool is_checker) : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), _instMasterId(p->system->getMasterId(name() + ".inst")), _dataMasterId(p->system->getMasterId(name() + ".data")), @@ -219,10 +219,17 @@ BaseCPU::BaseCPU(Params *p) schedule(event, p->function_trace_start); } } - // Check if CPU model has interrupts connected. The CheckerCPU - // cannot take interrupts directly for example. - if (interrupts) - interrupts->setCPU(this); + + // The interrupts should always be present unless this CPU is + // switched in later or in case it is a checker CPU + if (!params()->defer_registration && !is_checker) { + if (interrupts) { + interrupts->setCPU(this); + } else { + fatal("CPU %s has no interrupt controller.\n" + "Ensure createInterruptController() is called.\n", name()); + } + } if (FullSystem) { profileEvent = NULL; diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 8728a6e07..74bb8dc12 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -302,7 +302,7 @@ class BaseCPU : public MemObject typedef BaseCPUParams Params; const Params *params() const { return reinterpret_cast(_params); } - BaseCPU(Params *params); + BaseCPU(Params *params, bool is_checker = false); virtual ~BaseCPU(); virtual void init(); diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index fb381d24d..b21ceeb92 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -64,7 +64,7 @@ CheckerCPU::init() } CheckerCPU::CheckerCPU(Params *p) - : BaseCPU(p), thread(NULL), tc(NULL) + : BaseCPU(p, true), thread(NULL), tc(NULL) { memReq = NULL; curStaticInst = NULL; diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 84f5e3850..ac7a1b209 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -387,6 +387,12 @@ InOrderCPU::InOrderCPU(Params *params) } + // InOrderCPU always requires an interrupt controller. + if (!params->defer_registration && !interrupts) { + fatal("InOrderCPU %s has no interrupt controller.\n" + "Ensure createInterruptController() is called.\n", name()); + } + dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0); dummyReqInst->setSquashed(); dummyReqInst->resetInstCount(); diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 5dd2c3f3c..bf2cc80e3 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -460,6 +460,12 @@ FullO3CPU::FullO3CPU(DerivO3CPUParams *params) this->threadContexts.push_back(tc); } + // FullO3CPU always requires an interrupt controller. + if (!params->defer_registration && !interrupts) { + fatal("FullO3CPU %s has no interrupt controller.\n" + "Ensure createInterruptController() is called.\n", name()); + } + for (ThreadID tid = 0; tid < this->numThreads; tid++) this->thread[tid]->setFuncExeInst(0); diff --git a/tests/configs/inorder-timing.py b/tests/configs/inorder-timing.py index dcef25be8..d6a456083 100644 --- a/tests/configs/inorder-timing.py +++ b/tests/configs/inorder-timing.py @@ -52,6 +52,8 @@ system = System(cpu = cpu, membus = Bus()) system.system_port = system.membus.slave system.physmem.port = system.membus.master +# create the interrupt controller +cpu.createInterruptController() cpu.connectAllPorts(system.membus) root = Root(full_system = False, system = system) diff --git a/tests/configs/o3-timing-mp-ruby.py b/tests/configs/o3-timing-mp-ruby.py index 3e5e34e71..0bc54f0f0 100644 --- a/tests/configs/o3-timing-mp-ruby.py +++ b/tests/configs/o3-timing-mp-ruby.py @@ -40,6 +40,8 @@ ruby_memory = ruby_config.generate("TwoLevel_SplitL1UnifiedL2.rb", nb_cores) system = System(cpu = cpus, physmem = ruby_memory, membus = Bus()) for cpu in cpus: + # create the interrupt controller + cpu.createInterruptController() cpu.connectAllPorts(system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/o3-timing-mp.py b/tests/configs/o3-timing-mp.py index 1974d686f..1a0718fa8 100644 --- a/tests/configs/o3-timing-mp.py +++ b/tests/configs/o3-timing-mp.py @@ -71,6 +71,8 @@ system.l2c.mem_side = system.membus.slave for cpu in cpus: cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/o3-timing-ruby.py b/tests/configs/o3-timing-ruby.py index 0bdb73445..8debc7d3d 100644 --- a/tests/configs/o3-timing-ruby.py +++ b/tests/configs/o3-timing-ruby.py @@ -41,6 +41,8 @@ system = System(cpu = cpu, physmem = ruby_memory, membus = Bus()) system.physmem.port = system.membus.master +# create the interrupt controller +cpu.createInterruptController() cpu.connectAllPorts(system.membus) # Connect the system port for loading of binaries etc diff --git a/tests/configs/o3-timing.py b/tests/configs/o3-timing.py index 3003f0bcd..82a73a6aa 100644 --- a/tests/configs/o3-timing.py +++ b/tests/configs/o3-timing.py @@ -52,6 +52,8 @@ system = System(cpu = cpu, membus = Bus()) system.system_port = system.membus.slave system.physmem.port = system.membus.master +# create the interrupt controller +cpu.createInterruptController() cpu.connectAllPorts(system.membus) root = Root(full_system = False, system = system) diff --git a/tests/configs/pc-o3-timing.py b/tests/configs/pc-o3-timing.py index a04b04134..f35812085 100644 --- a/tests/configs/pc-o3-timing.py +++ b/tests/configs/pc-o3-timing.py @@ -104,6 +104,8 @@ cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4), PageTableWalkerCache(), PageTableWalkerCache()) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/pc-simple-atomic.py b/tests/configs/pc-simple-atomic.py index 24270edb0..b78cb9495 100644 --- a/tests/configs/pc-simple-atomic.py +++ b/tests/configs/pc-simple-atomic.py @@ -106,6 +106,8 @@ cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4), PageTableWalkerCache(), PageTableWalkerCache()) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/pc-simple-timing.py b/tests/configs/pc-simple-timing.py index 97a607d8e..b5117f2fe 100644 --- a/tests/configs/pc-simple-timing.py +++ b/tests/configs/pc-simple-timing.py @@ -106,6 +106,8 @@ cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4), PageTableWalkerCache(), PageTableWalkerCache()) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/realview-o3-dual.py b/tests/configs/realview-o3-dual.py index ad1c4752b..2f06ab2d7 100644 --- a/tests/configs/realview-o3-dual.py +++ b/tests/configs/realview-o3-dual.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave for c in cpus: c.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + c.createInterruptController() # connect cpu level-1 caches to shared level-2 cache c.connectAllPorts(system.toL2Bus, system.membus) c.clock = '2GHz' diff --git a/tests/configs/realview-o3.py b/tests/configs/realview-o3.py index 058111d67..795bd534a 100644 --- a/tests/configs/realview-o3.py +++ b/tests/configs/realview-o3.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave #connect up the cpu and l1s cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/realview-simple-atomic-dual.py b/tests/configs/realview-simple-atomic-dual.py index 20bf89bed..daee4f478 100644 --- a/tests/configs/realview-simple-atomic-dual.py +++ b/tests/configs/realview-simple-atomic-dual.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave for c in cpus: c.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + c.createInterruptController() # connect cpu level-1 caches to shared level-2 cache c.connectAllPorts(system.toL2Bus, system.membus) c.clock = '2GHz' diff --git a/tests/configs/realview-simple-atomic.py b/tests/configs/realview-simple-atomic.py index 1e5bab50c..f6377d21d 100644 --- a/tests/configs/realview-simple-atomic.py +++ b/tests/configs/realview-simple-atomic.py @@ -86,6 +86,8 @@ system.l2c.mem_side = system.membus.slave #connect up the cpu and l1s cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/realview-simple-timing-dual.py b/tests/configs/realview-simple-timing-dual.py index e55cb72cb..c610bc432 100644 --- a/tests/configs/realview-simple-timing-dual.py +++ b/tests/configs/realview-simple-timing-dual.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave for c in cpus: c.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + c.createInterruptController() # connect cpu level-1 caches to shared level-2 cache c.connectAllPorts(system.toL2Bus, system.membus) c.clock = '2GHz' diff --git a/tests/configs/realview-simple-timing.py b/tests/configs/realview-simple-timing.py index 1e27a5dc9..a55358306 100644 --- a/tests/configs/realview-simple-timing.py +++ b/tests/configs/realview-simple-timing.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave #connect up the cpu and l1s cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/simple-atomic-mp.py b/tests/configs/simple-atomic-mp.py index 8bc2e6e4f..376d5ee27 100644 --- a/tests/configs/simple-atomic-mp.py +++ b/tests/configs/simple-atomic-mp.py @@ -70,6 +70,8 @@ system.l2c.mem_side = system.membus.slave for cpu in cpus: cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/simple-atomic.py b/tests/configs/simple-atomic.py index 5e5b94f27..4d3fb6580 100644 --- a/tests/configs/simple-atomic.py +++ b/tests/configs/simple-atomic.py @@ -34,6 +34,8 @@ system = System(cpu = AtomicSimpleCPU(cpu_id=0), membus = Bus()) system.system_port = system.membus.slave system.physmem.port = system.membus.master +# create the interrupt controller +system.cpu.createInterruptController() system.cpu.connectAllPorts(system.membus) system.cpu.clock = '2GHz' diff --git a/tests/configs/simple-timing-mp.py b/tests/configs/simple-timing-mp.py index 5ec7a6067..f898797bb 100644 --- a/tests/configs/simple-timing-mp.py +++ b/tests/configs/simple-timing-mp.py @@ -70,6 +70,8 @@ system.l2c.mem_side = system.membus.slave for cpu in cpus: cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/simple-timing-ruby.py b/tests/configs/simple-timing-ruby.py index 4f812f209..8339e0e9a 100644 --- a/tests/configs/simple-timing-ruby.py +++ b/tests/configs/simple-timing-ruby.py @@ -75,6 +75,9 @@ Ruby.create_system(options, system) assert(len(system.ruby._cpu_ruby_ports) == 1) +# create the interrupt controller +cpu.createInterruptController() + # # Tie the cpu cache ports to the ruby cpu ports and # physmem, respectively diff --git a/tests/configs/simple-timing.py b/tests/configs/simple-timing.py index ea9428d8a..cd6bee863 100644 --- a/tests/configs/simple-timing.py +++ b/tests/configs/simple-timing.py @@ -48,6 +48,8 @@ system = System(cpu = cpu, membus = Bus()) system.system_port = system.membus.slave system.physmem.port = system.membus.master +# create the interrupt controller +cpu.createInterruptController() cpu.connectAllPorts(system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/tsunami-o3-dual.py b/tests/configs/tsunami-o3-dual.py index c30b1da04..603664d53 100644 --- a/tests/configs/tsunami-o3-dual.py +++ b/tests/configs/tsunami-o3-dual.py @@ -90,6 +90,8 @@ system.l2c.mem_side = system.membus.slave for c in cpus: c.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + c.createInterruptController() # connect cpu level-1 caches to shared level-2 cache c.connectAllPorts(system.toL2Bus, system.membus) c.clock = '2GHz' diff --git a/tests/configs/tsunami-o3.py b/tests/configs/tsunami-o3.py index 015de3d0f..ce64c497f 100644 --- a/tests/configs/tsunami-o3.py +++ b/tests/configs/tsunami-o3.py @@ -89,6 +89,8 @@ system.l2c.mem_side = system.membus.slave #connect up the cpu and l1s cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/tsunami-simple-atomic-dual.py b/tests/configs/tsunami-simple-atomic-dual.py index 08c71df33..f242c80cc 100644 --- a/tests/configs/tsunami-simple-atomic-dual.py +++ b/tests/configs/tsunami-simple-atomic-dual.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave for c in cpus: c.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + c.createInterruptController() # connect cpu level-1 caches to shared level-2 cache c.connectAllPorts(system.toL2Bus, system.membus) c.clock = '2GHz' diff --git a/tests/configs/tsunami-simple-atomic.py b/tests/configs/tsunami-simple-atomic.py index 69337ac14..456dc5da6 100644 --- a/tests/configs/tsunami-simple-atomic.py +++ b/tests/configs/tsunami-simple-atomic.py @@ -87,6 +87,8 @@ system.l2c.mem_side = system.membus.slave #connect up the cpu and l1s cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/tsunami-simple-timing-dual.py b/tests/configs/tsunami-simple-timing-dual.py index f61a3f054..56daf0dd3 100644 --- a/tests/configs/tsunami-simple-timing-dual.py +++ b/tests/configs/tsunami-simple-timing-dual.py @@ -88,6 +88,8 @@ system.l2c.mem_side = system.membus.slave for c in cpus: c.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) + # create the interrupt controller + c.createInterruptController() # connect cpu level-1 caches to shared level-2 cache c.connectAllPorts(system.toL2Bus, system.membus) c.clock = '2GHz' diff --git a/tests/configs/tsunami-simple-timing.py b/tests/configs/tsunami-simple-timing.py index e705e35dd..ef055e38e 100644 --- a/tests/configs/tsunami-simple-timing.py +++ b/tests/configs/tsunami-simple-timing.py @@ -89,6 +89,8 @@ system.l2c.mem_side = system.membus.slave #connect up the cpu and l1s cpu.addPrivateSplitL1Caches(L1(size = '32kB', assoc = 1), L1(size = '32kB', assoc = 4)) +# create the interrupt controller +cpu.createInterruptController() # connect cpu level-1 caches to shared level-2 cache cpu.connectAllPorts(system.toL2Bus, system.membus) cpu.clock = '2GHz' diff --git a/tests/configs/twosys-tsunami-simple-atomic.py b/tests/configs/twosys-tsunami-simple-atomic.py index 552acc0e1..84f70db14 100644 --- a/tests/configs/twosys-tsunami-simple-atomic.py +++ b/tests/configs/twosys-tsunami-simple-atomic.py @@ -35,6 +35,8 @@ from Benchmarks import * test_sys = makeLinuxAlphaSystem('atomic', SysConfig('netperf-stream-client.rcS')) test_sys.cpu = AtomicSimpleCPU(cpu_id=0) +# create the interrupt controller +test_sys.cpu.createInterruptController() test_sys.cpu.connectAllPorts(test_sys.membus) # In contrast to the other (one-system) Tsunami configurations we do # not have an IO cache but instead rely on an IO bridge for accesses @@ -47,6 +49,8 @@ test_sys.iobridge.master = test_sys.membus.slave drive_sys = makeLinuxAlphaSystem('atomic', SysConfig('netperf-server.rcS')) drive_sys.cpu = AtomicSimpleCPU(cpu_id=0) +# create the interrupt controller +drive_sys.cpu.createInterruptController() drive_sys.cpu.connectAllPorts(drive_sys.membus) drive_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns', ranges = [AddrRange(0, '8GB')])