misc: Merge branch 'release-staging-v20.1.0.0' into develop

Change-Id: I1eacbc5719aa85c5a7650ec33fd99f673fdf443d
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index f62000e..73e2b5d 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -174,10 +174,10 @@
 
             0x2: decode FUNCTION_LO {
                 0x0: HiLoRsSelOp::mfhi({{ Rd = HI_RS_SEL; }},
-                             IntMultOp, IsIprAccess);
+                             IntMultOp, IsSerializeBefore);
                 0x1: HiLoRdSelOp::mthi({{ HI_RD_SEL = Rs; }});
                 0x2: HiLoRsSelOp::mflo({{ Rd = LO_RS_SEL; }},
-                             IntMultOp, IsIprAccess);
+                             IntMultOp, IsSerializeBefore);
                 0x3: HiLoRdSelOp::mtlo({{ LO_RD_SEL = Rs; }});
             }
 
@@ -719,7 +719,7 @@
                         LLFlag = 0;
                         Status = status;
                         SRSCtl = srsCtl;
-                    }}, IsReturn, IsSerializing, IsERET);
+                    }}, IsReturn, IsSerializing);
 
                     0x1F: deret({{
                         DebugReg debug = Debug;
@@ -732,7 +732,7 @@
                             // Undefined;
                         }
                         Debug = debug;
-                    }}, IsReturn, IsSerializing, IsERET);
+                    }}, IsReturn, IsSerializing);
                 }
                 format CP0TLB {
                     0x01: tlbr({{
diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa
index 4975a13..7c2b27c 100644
--- a/src/arch/mips/isa/formats/branch.isa
+++ b/src/arch/mips/isa/formats/branch.isa
@@ -241,7 +241,6 @@
             code += 'R31 = NNPC;\n'
         elif x == 'Likely':
             not_taken_code = 'NNPC = NPC; NPC = PC;'
-            inst_flags += ('IsCondDelaySlot', )
         else:
             inst_flags += (x, )
 
@@ -280,7 +279,6 @@
             code += 'R32 = NNPC;'
         elif x == 'Likely':
             not_taken_code = 'NNPC = NPC, NPC = PC;'
-            inst_flags += ('IsCondDelaySlot', )
         else:
             inst_flags += (x, )
 
diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh
index 8400ed6..153a991 100644
--- a/src/arch/mips/locked_mem.hh
+++ b/src/arch/mips/locked_mem.hh
@@ -50,6 +50,7 @@
 #include "arch/registers.hh"
 #include "base/logging.hh"
 #include "base/trace.hh"
+#include "cpu/base.hh"
 #include "debug/LLSC.hh"
 #include "mem/packet.hh"
 #include "mem/request.hh"
diff --git a/src/arch/null/SConscript b/src/arch/null/SConscript
index 41457e2..3f0b053 100644
--- a/src/arch/null/SConscript
+++ b/src/arch/null/SConscript
@@ -36,6 +36,3 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 Import('*')
-
-if env['TARGET_ISA'] == 'null':
-    Source('cpu_dummy.cc')
diff --git a/src/arch/null/cpu_dummy.cc b/src/arch/null/cpu_dummy.cc
deleted file mode 100644
index df30b81..0000000
--- a/src/arch/null/cpu_dummy.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder.  You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Provide the actual storage for maxThreadsPerCPU which is declared
- * extern and normally provided by src/cpu/base.cc
- */
-int maxThreadsPerCPU = 1;
diff --git a/src/arch/null/cpu_dummy.hh b/src/arch/null/cpu_dummy.hh
deleted file mode 100644
index 7e183eb..0000000
--- a/src/arch/null/cpu_dummy.hh
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder.  You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __ARCH_NULL_CPU_DUMMY_HH__
-#define __ARCH_NULL_CPU_DUMMY_HH__
-
-#include "sim/core.hh"
-
-class BaseCPU
-{
-  public:
-    static int numSimulatedInsts() { return 0; }
-    static int numSimulatedOps() { return 0; }
-    static void wakeup(ThreadID tid) { ; }
-};
-
-#endif // __ARCH_NULL_CPU_DUMMY_HH__
diff --git a/src/arch/riscv/locked_mem.hh b/src/arch/riscv/locked_mem.hh
index fd45b3f..10d1839 100644
--- a/src/arch/riscv/locked_mem.hh
+++ b/src/arch/riscv/locked_mem.hh
@@ -52,6 +52,7 @@
 #include "arch/registers.hh"
 #include "base/logging.hh"
 #include "base/trace.hh"
+#include "cpu/base.hh"
 #include "debug/LLSC.hh"
 #include "mem/packet.hh"
 #include "mem/request.hh"
diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh
index ed50a30..431ec06 100644
--- a/src/arch/sparc/linux/linux.hh
+++ b/src/arch/sparc/linux/linux.hh
@@ -230,6 +230,11 @@
 
         if (stack)
             ctc->setIntReg(SparcISA::StackPointerReg, stack);
+
+        // Set these extra values. Since "clone" doesn't return two values,
+        // we can set these and they won't be clobbered by the syscall ABI.
+        ptc->setIntReg(SparcISA::SyscallPseudoReturnReg, 0);
+        ctc->setIntReg(SparcISA::SyscallPseudoReturnReg, 1);
     }
 };
 
diff --git a/src/cpu/StaticInstFlags.py b/src/cpu/StaticInstFlags.py
index 1c2b63a..151074e 100644
--- a/src/cpu/StaticInstFlags.py
+++ b/src/cpu/StaticInstFlags.py
@@ -78,10 +78,6 @@
         'IsCall',           # Subroutine call.
         'IsReturn',         # Subroutine return.
 
-        'IsCondDelaySlot',  # Conditional Delay-Slot Instruction
-
-        'IsThreadSync',     # Thread synchronization operation.
-
         'IsSerializing',    # Serializes pipeline: won't execute until all
                             # older instructions have committed.
         'IsSerializeBefore',
@@ -89,12 +85,10 @@
         'IsMemBarrier',     # Is a memory barrier
         'IsWriteBarrier',   # Is a write barrier
         'IsReadBarrier',    # Is a read barrier
-        'IsERET',           # <- Causes the IFU to stall (MIPS ISA)
 
         'IsNonSpeculative', # Should not be executed speculatively
         'IsQuiesce',        # Is a quiesce instruction
 
-        'IsIprAccess',      # Accesses IPRs
         'IsUnverifiable',   # Can't be verified by a checker
 
         'IsSyscall',        # Causes a system call to be emulated in syscall
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 9ba1b31..ef843d7 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012,2016-2017, 2019 ARM Limited
+ * Copyright (c) 2011-2012,2016-2017, 2019-2020 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -63,6 +63,7 @@
 #include "sim/clocked_object.hh"
 #include "sim/full_system.hh"
 #include "sim/process.hh"
+#include "sim/root.hh"
 #include "sim/sim_events.hh"
 #include "sim/sim_exit.hh"
 #include "sim/system.hh"
@@ -72,6 +73,8 @@
 
 using namespace std;
 
+std::unique_ptr<BaseCPU::GlobalStats> BaseCPU::globalStats;
+
 vector<BaseCPU *> BaseCPU::cpuList;
 
 // This variable reflects the max number of threads in any CPU.  Be
@@ -370,6 +373,12 @@
 {
     ClockedObject::regStats();
 
+    if (!globalStats) {
+        /* We need to construct the global CPU stat structure here
+         * since it needs a pointer to the Root object. */
+        globalStats.reset(new GlobalStats(Root::root()));
+    }
+
     using namespace Stats;
 
     numCycles
@@ -754,3 +763,39 @@
 {
     return params()->wait_for_remote_gdb;
 }
+
+
+BaseCPU::GlobalStats::GlobalStats(::Stats::Group *parent)
+    : ::Stats::Group(parent),
+    simInsts(this, "sim_insts", "Number of instructions simulated"),
+    simOps(this, "sim_ops", "Number of ops (including micro ops) simulated"),
+    hostInstRate(this, "host_inst_rate",
+                 "Simulator instruction rate (inst/s)"),
+    hostOpRate(this, "host_op_rate",
+               "Simulator op (including micro ops) rate (op/s)")
+{
+    simInsts
+        .functor(BaseCPU::numSimulatedInsts)
+        .precision(0)
+        .prereq(simInsts)
+        ;
+
+    simOps
+        .functor(BaseCPU::numSimulatedOps)
+        .precision(0)
+        .prereq(simOps)
+        ;
+
+    hostInstRate
+        .precision(0)
+        .prereq(simInsts)
+        ;
+
+    hostOpRate
+        .precision(0)
+        .prereq(simOps)
+        ;
+
+    hostInstRate = simInsts / hostSeconds;
+    hostOpRate = simOps / hostSeconds;
+}
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 5320492..9cf4baa 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -48,7 +48,7 @@
 // and if so stop here
 #include "config/the_isa.hh"
 #if THE_ISA == NULL_ISA
-#include "arch/null/cpu_dummy.hh"
+#error Including BaseCPU in a system without CPU support
 #else
 #include "arch/generic/interrupts.hh"
 #include "base/statistics.hh"
@@ -145,6 +145,23 @@
     /** Cache the cache line size that we get from the system */
     const unsigned int _cacheLineSize;
 
+    /** Global CPU statistics that are merged into the Root object. */
+    struct GlobalStats : public Stats::Group {
+        GlobalStats(::Stats::Group *parent);
+
+        ::Stats::Value simInsts;
+        ::Stats::Value simOps;
+
+        ::Stats::Formula hostInstRate;
+        ::Stats::Formula hostOpRate;
+    };
+
+    /**
+     * Pointer to the global stat structure. This needs to be
+     * constructed from regStats since we merge it into the root
+     * group. */
+    static std::unique_ptr<GlobalStats> globalStats;
+
   public:
 
     /**
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index a6c08cc..00639ad 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -541,8 +541,6 @@
     bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
     bool isCondCtrl()     const { return staticInst->isCondCtrl(); }
     bool isUncondCtrl()   const { return staticInst->isUncondCtrl(); }
-    bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); }
-    bool isThreadSync()   const { return staticInst->isThreadSync(); }
     bool isSerializing()  const { return staticInst->isSerializing(); }
     bool
     isSerializeBefore() const
@@ -559,7 +557,6 @@
     bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
     bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
     bool isQuiesce() const { return staticInst->isQuiesce(); }
-    bool isIprAccess() const { return staticInst->isIprAccess(); }
     bool isUnverifiable() const { return staticInst->isUnverifiable(); }
     bool isSyscall() const { return staticInst->isSyscall(); }
     bool isMacroop() const { return staticInst->isMacroop(); }
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index 45ca002..f8db523 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -224,8 +224,7 @@
         !inst->isFault() &&
         inst->isLastOpInInst() &&
         (inst->staticInst->isSerializeAfter() ||
-         inst->staticInst->isSquashAfter() ||
-         inst->staticInst->isIprAccess());
+         inst->staticInst->isSquashAfter());
 
     DPRINTF(Branch, "tryToBranch before: %s after: %s%s\n",
         pc_before, target, (force_branch ? " (forcing)" : ""));
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 75d065f..0d5cbe5 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1233,11 +1233,6 @@
         return false;
     }
 
-    if (head_inst->isThreadSync()) {
-        // Not handled for now.
-        panic("Thread sync instructions are not handled yet.\n");
-    }
-
     // Check if the instruction caused a fault.  If so, trap.
     Fault inst_fault = head_inst->getFault();
 
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index 1cbe87a..052012e 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -684,8 +684,7 @@
         // instructions.  This is mainly due to lack of support for
         // out-of-order operations of either of those classes of
         // instructions.
-        if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
-            !inst->isSerializeHandled()) {
+        if (inst->isSerializeBefore() && !inst->isSerializeHandled()) {
             DPRINTF(Rename, "Serialize before instruction encountered.\n");
 
             if (!inst->isTempSerializeBefore()) {
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 146be8c..353c0e3 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -179,9 +179,7 @@
     bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
     bool isCondCtrl()     const { return flags[IsCondControl]; }
     bool isUncondCtrl()   const { return flags[IsUncondControl]; }
-    bool isCondDelaySlot() const { return flags[IsCondDelaySlot]; }
 
-    bool isThreadSync()   const { return flags[IsThreadSync]; }
     bool isSerializing()  const { return flags[IsSerializing] ||
                                       flags[IsSerializeBefore] ||
                                       flags[IsSerializeAfter]; }
@@ -192,7 +190,6 @@
     bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
     bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
     bool isQuiesce() const { return flags[IsQuiesce]; }
-    bool isIprAccess() const { return flags[IsIprAccess]; }
     bool isUnverifiable() const { return flags[IsUnverifiable]; }
     bool isSyscall() const { return flags[IsSyscall]; }
     bool isMacroop() const { return flags[IsMacroop]; }
diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc
index a5730c7..79f716c 100644
--- a/src/mem/abstract_mem.cc
+++ b/src/mem/abstract_mem.cc
@@ -45,7 +45,6 @@
 #include "arch/locked_mem.hh"
 #include "base/loader/memory_image.hh"
 #include "base/loader/object_file.hh"
-#include "cpu/base.hh"
 #include "cpu/thread_context.hh"
 #include "debug/LLSC.hh"
 #include "debug/MemoryAccess.hh"
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index a35be33..2ff466b 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -48,7 +48,6 @@
 #include <cassert>
 
 #include "base/intmath.hh"
-#include "cpu/base.hh"
 #include "mem/cache/base.hh"
 #include "params/BasePrefetcher.hh"
 #include "sim/system.hh"
diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc
index 9464c0d..5b66786 100644
--- a/src/sim/stat_control.cc
+++ b/src/sim/stat_control.cc
@@ -53,7 +53,6 @@
 #include "base/hostinfo.hh"
 #include "base/statistics.hh"
 #include "base/time.hh"
-#include "cpu/base.hh"
 #include "sim/global_event.hh"
 
 using namespace std;
@@ -62,6 +61,7 @@
 Stats::Value simTicks;
 Stats::Value finalTick;
 Stats::Value simFreq;
+Stats::Value hostSeconds;
 
 namespace Stats {
 
@@ -94,36 +94,14 @@
 
 struct Global
 {
-    Stats::Formula hostInstRate;
-    Stats::Formula hostOpRate;
     Stats::Formula hostTickRate;
     Stats::Value hostMemory;
-    Stats::Value hostSeconds;
-
-    Stats::Value simInsts;
-    Stats::Value simOps;
 
     Global();
 };
 
 Global::Global()
 {
-    simInsts
-        .functor(BaseCPU::numSimulatedInsts)
-        .name("sim_insts")
-        .desc("Number of instructions simulated")
-        .precision(0)
-        .prereq(simInsts)
-        ;
-
-    simOps
-        .functor(BaseCPU::numSimulatedOps)
-        .name("sim_ops")
-        .desc("Number of ops (including micro ops) simulated")
-        .precision(0)
-        .prereq(simOps)
-        ;
-
     simSeconds
         .name("sim_seconds")
         .desc("Number of seconds simulated")
@@ -148,20 +126,6 @@
               "(restored from checkpoints and never reset)")
         ;
 
-    hostInstRate
-        .name("host_inst_rate")
-        .desc("Simulator instruction rate (inst/s)")
-        .precision(0)
-        .prereq(simInsts)
-        ;
-
-    hostOpRate
-        .name("host_op_rate")
-        .desc("Simulator op (including micro ops) rate (op/s)")
-        .precision(0)
-        .prereq(simOps)
-        ;
-
     hostMemory
         .functor(memUsage)
         .name("host_mem_usage")
@@ -183,8 +147,6 @@
         ;
 
     simSeconds = simTicks / simFreq;
-    hostInstRate = simInsts / hostSeconds;
-    hostOpRate = simOps / hostSeconds;
     hostTickRate = simTicks / hostSeconds;
 
     registerResetCallback([]() {
diff --git a/src/sim/stats.hh b/src/sim/stats.hh
index ed68af6..4e17f64 100644
--- a/src/sim/stats.hh
+++ b/src/sim/stats.hh
@@ -34,5 +34,6 @@
 extern Stats::Formula simSeconds;
 extern Stats::Value simTicks;
 extern Stats::Value simFreq;
+extern Stats::Value hostSeconds;
 
 #endif // __SIM_SIM_STATS_HH__
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 05a29f9..9d1f6e2 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1506,11 +1506,6 @@
 
     desc->returnInto(ctc, 0);
 
-#if THE_ISA == SPARC_ISA
-    tc->setIntReg(TheISA::SyscallPseudoReturnReg, 0);
-    ctc->setIntReg(TheISA::SyscallPseudoReturnReg, 1);
-#endif
-
     TheISA::PCState cpc = tc->pcState();
     if (!p->kvmInSE)
         cpc.advance();
diff --git a/src/sim/system.cc b/src/sim/system.cc
index cb412a8..cbc30a9 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -50,12 +50,15 @@
 #include "base/loader/symtab.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
+#include "config/the_isa.hh"
 #include "config/use_kvm.hh"
 #if USE_KVM
 #include "cpu/kvm/base.hh"
 #include "cpu/kvm/vm.hh"
 #endif
+#if THE_ISA != NULL_ISA
 #include "cpu/base.hh"
+#endif
 #include "cpu/thread_context.hh"
 #include "debug/Loader.hh"
 #include "debug/Quiesce.hh"
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 7d77c48..fc93b85 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -52,7 +52,6 @@
 #include "base/loader/symtab.hh"
 #include "base/statistics.hh"
 #include "config/the_isa.hh"
-#include "cpu/base.hh"
 #include "cpu/pc_event.hh"
 #include "enums/MemoryMode.hh"
 #include "mem/mem_requestor.hh"
diff --git a/src/systemc/core/list.hh b/src/systemc/core/list.hh
index b1c5f55..6ba2825 100644
--- a/src/systemc/core/list.hh
+++ b/src/systemc/core/list.hh
@@ -102,8 +102,13 @@
         prevListNode = t;
     }
 
-    T *getNext() { return dynamic_cast<T *>(nextListNode); }
-    bool empty() { return getNext() == nullptr; }
+    T *
+    getNext()
+    {
+        return empty() ? nullptr : static_cast<T *>(nextListNode);
+    }
+
+    bool empty() { return nextListNode == this; }
 };
 
 } // namespace sc_gem5