CPU: Check that the interrupt controller is created when needed
authorAndreas Hansson <andreas.hansson@arm.com>
Fri, 2 Mar 2012 14:21:48 +0000 (09:21 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Fri, 2 Mar 2012 14:21:48 +0000 (09:21 -0500)
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.

31 files changed:
src/cpu/base.cc
src/cpu/base.hh
src/cpu/checker/cpu.cc
src/cpu/inorder/cpu.cc
src/cpu/o3/cpu.cc
tests/configs/inorder-timing.py
tests/configs/o3-timing-mp-ruby.py
tests/configs/o3-timing-mp.py
tests/configs/o3-timing-ruby.py
tests/configs/o3-timing.py
tests/configs/pc-o3-timing.py
tests/configs/pc-simple-atomic.py
tests/configs/pc-simple-timing.py
tests/configs/realview-o3-dual.py
tests/configs/realview-o3.py
tests/configs/realview-simple-atomic-dual.py
tests/configs/realview-simple-atomic.py
tests/configs/realview-simple-timing-dual.py
tests/configs/realview-simple-timing.py
tests/configs/simple-atomic-mp.py
tests/configs/simple-atomic.py
tests/configs/simple-timing-mp.py
tests/configs/simple-timing-ruby.py
tests/configs/simple-timing.py
tests/configs/tsunami-o3-dual.py
tests/configs/tsunami-o3.py
tests/configs/tsunami-simple-atomic-dual.py
tests/configs/tsunami-simple-atomic.py
tests/configs/tsunami-simple-timing-dual.py
tests/configs/tsunami-simple-timing.py
tests/configs/twosys-tsunami-simple-atomic.py

index 86edf62cf9e7e9552d30773d131191d155492a9e..0722f319d25a53c31bd19069052820adc061cd3f 100644 (file)
@@ -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;
index 8728a6e0734e556326867f317ee31aa7ef55fead..74bb8dc12423b5718b5d61fd136626e5e5769348 100644 (file)
@@ -302,7 +302,7 @@ class BaseCPU : public MemObject
     typedef BaseCPUParams Params;
     const Params *params() const
     { return reinterpret_cast<const Params *>(_params); }
-    BaseCPU(Params *params);
+    BaseCPU(Params *params, bool is_checker = false);
     virtual ~BaseCPU();
 
     virtual void init();
index fb381d24d8a92706dc39c2fe2700b29fab58622d..b21ceeb926a96108bf65bbf128a856709276a07a 100644 (file)
@@ -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;
index 84f5e38509c577e22578434deb5fea96bdddfbf4..ac7a1b209de0b974d974d465c6a70178b599feef 100644 (file)
@@ -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();
index 5dd2c3f3ce19f572c3434e4eb7ba32d0257f21b1..bf2cc80e31b7a176fb719454a63e00f740c3d172 100644 (file)
@@ -460,6 +460,12 @@ FullO3CPU<Impl>::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);
 
index dcef25be89732bd763cb7eec9257822a8e476751..d6a456083ca707ffe0cd66973e649b7dc91bd3c9 100644 (file)
@@ -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)
index 3e5e34e71b446138751c1600059a98528f44e7f6..0bc54f0f0b86374583829175234dce9fe9cd501b 100644 (file)
@@ -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'
 
index 1974d686f936a1ef0a77be7d93e88e9161c7510d..1a0718fa8d88ac1730c11b79be3d9f53a5061c9d 100644 (file)
@@ -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'
index 0bdb734452f2e11fe4202e9477e7045b1f4cfbd9..8debc7d3dbfd39dce690d8492bda1cff27bff973 100644 (file)
@@ -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
index 3003f0bcdbf5849e9cc5dc7ea2cd7d7c8983d695..82a73a6aa40df865edd7eda7d84e99b4c633b5d7 100644 (file)
@@ -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)
index a04b0413428e82633ea1a7f5f833f75bc03cd48b..f358120857f2b36770838c0665751b618892476f 100644 (file)
@@ -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'
index 24270edb00483ef605159cd8d8f9338ecfc7d836..b78cb94952344cc9e557d0c5f40a1f837d76fd7e 100644 (file)
@@ -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'
index 97a607d8ec196b60bc430f1094080f1e6e38089a..b5117f2fecb9019cd8bfc63d396682769aa17b40 100644 (file)
@@ -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'
index ad1c4752b8727a935497e3d7e6faad2d7f51df87..2f06ab2d7ef8dda91132246b28e0c13443480cfe 100644 (file)
@@ -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'
index 058111d6708961c72ac8d7d46ac484c31e71aa9c..795bd534ab307c9a3eaaefb0ce131c04e95aa57f 100644 (file)
@@ -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'
index 20bf89bede3bbb0dba8e87044e0644bf2b1777f6..daee4f4786bcb0ad1c2371408e180ebb66db01a1 100644 (file)
@@ -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'
index 1e5bab50cc18ec01c89d53e4d4cfc7dec13435f2..f6377d21d53d1d96cb804dad95d67fdf49cb7a79 100644 (file)
@@ -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'
index e55cb72cb4d9844fc572eafadf2289cfce4d1b4c..c610bc4329cc567b3e880fac7813ebc7878d18f3 100644 (file)
@@ -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'
index 1e27a5dc99adfd0c8d820a9390b2003f98761214..a55358306e9ae3060ceff996b1e4004509e0684e 100644 (file)
@@ -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'
index 8bc2e6e4f913496c92c7983104ab5b67db115782..376d5ee27541ee8f4310f816d49a582cb5db23f2 100644 (file)
@@ -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'
index 5e5b94f27f19752352663e221fe2ee5bdc05860d..4d3fb65805f300f4ab317eb9ca22481cfc6a3581 100644 (file)
@@ -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'
 
index 5ec7a60678de03db94be0ab0aad0b04ff9549c58..f898797bb22b1552a47519e4a17d2c600e5f5737 100644 (file)
@@ -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'
index 4f812f209533f71387ab6194de6703b082d78038..8339e0e9a27759889ddc2016dc981fca3aa8cbe0 100644 (file)
@@ -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
index ea9428d8a2018050adcd4ecfa9918966ce957b0e..cd6bee863c28b481564482360cd179893ecd1652 100644 (file)
@@ -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'
 
index c30b1da04c19d035fa025efd0a0fd3fc7dce3984..603664d535031271a9d6df75e9ecd2da396f7133 100644 (file)
@@ -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'
index 015de3d0f880fa5e8322464960c036a774ec58a8..ce64c497f188f7601277c99ed5d705944fc6fadf 100644 (file)
@@ -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'
index 08c71df3369cabc5fe54f5060b6221b36e1253ea..f242c80ccda7c7673ec2ff11c0a79037df65051d 100644 (file)
@@ -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'
index 69337ac14d6c1fad4dd5fe31203882c33fe54625..456dc5da66c6750eeb0067d425e4867717438c29 100644 (file)
@@ -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'
index f61a3f054cd4adaf6547c1edc44c9897582df312..56daf0dd3587240012702818bf2d969d1034abbb 100644 (file)
@@ -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'
index e705e35dd1b3820ff5401480f0c8e5e8fedfecd4..ef055e38ea4f1f867e166c63c506ab0a3d1b3890 100644 (file)
@@ -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'
index 552acc0e1007bf13d7f7c8ec018746a57ad4ff7c..84f70db1416c2d5be9dcab03adbde695f7f517df 100644 (file)
@@ -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')])