From 32eae8094d8931f161784825ad013e9c6d995c17 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Fri, 2 Mar 2012 09:21:48 -0500 Subject: [PATCH] CPU: Check that the interrupt controller is created when needed This patch adds a creation-time check to the CPU to ensure that the interrupt controller is created for the cases where it is needed, i.e. if the CPU is not being switched in later and not a checker CPU. The patch also adds the "createInterruptController" call to a number of the regression scripts. --- src/cpu/base.cc | 17 ++++++++++++----- src/cpu/base.hh | 2 +- src/cpu/checker/cpu.cc | 2 +- src/cpu/inorder/cpu.cc | 6 ++++++ src/cpu/o3/cpu.cc | 6 ++++++ tests/configs/inorder-timing.py | 2 ++ tests/configs/o3-timing-mp-ruby.py | 2 ++ tests/configs/o3-timing-mp.py | 2 ++ tests/configs/o3-timing-ruby.py | 2 ++ tests/configs/o3-timing.py | 2 ++ tests/configs/pc-o3-timing.py | 2 ++ tests/configs/pc-simple-atomic.py | 2 ++ tests/configs/pc-simple-timing.py | 2 ++ tests/configs/realview-o3-dual.py | 2 ++ tests/configs/realview-o3.py | 2 ++ tests/configs/realview-simple-atomic-dual.py | 2 ++ tests/configs/realview-simple-atomic.py | 2 ++ tests/configs/realview-simple-timing-dual.py | 2 ++ tests/configs/realview-simple-timing.py | 2 ++ tests/configs/simple-atomic-mp.py | 2 ++ tests/configs/simple-atomic.py | 2 ++ tests/configs/simple-timing-mp.py | 2 ++ tests/configs/simple-timing-ruby.py | 3 +++ tests/configs/simple-timing.py | 2 ++ tests/configs/tsunami-o3-dual.py | 2 ++ tests/configs/tsunami-o3.py | 2 ++ tests/configs/tsunami-simple-atomic-dual.py | 2 ++ tests/configs/tsunami-simple-atomic.py | 2 ++ tests/configs/tsunami-simple-timing-dual.py | 2 ++ tests/configs/tsunami-simple-timing.py | 2 ++ tests/configs/twosys-tsunami-simple-atomic.py | 4 ++++ 31 files changed, 81 insertions(+), 7 deletions(-) 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')]) -- 2.30.2