diff --git a/src/python/gem5/components/boards/abstract_board.py b/src/python/gem5/components/boards/abstract_board.py index 34308a1e11..af9ff300b6 100644 --- a/src/python/gem5/components/boards/abstract_board.py +++ b/src/python/gem5/components/boards/abstract_board.py @@ -406,11 +406,11 @@ class AbstractBoard: occurs whether a simulation is to be run in FS or SE mode will be determined by the board set.""" - # Connect the memory, processor, and cache hierarchy. + # 1. Connect the memory, processor, and cache hierarchy. self._connect_things() - # Return the Root object. - return Root( + # 2. Create the root object + root = Root( full_system=( full_system if full_system is not None @@ -419,6 +419,13 @@ class AbstractBoard: board=self, ) + # 3. Call any of the components' `_pre_instantiate` functions. + # Right now, only the processor requires this. + self.get_processor()._pre_instantiate(root) + + # 4. Return the root object. + return root + def _connect_things_check(self): """ Here we check that connect things has been called and throw an diff --git a/src/python/gem5/components/processors/abstract_processor.py b/src/python/gem5/components/processors/abstract_processor.py index 79dba438a2..303b9658f2 100644 --- a/src/python/gem5/components/processors/abstract_processor.py +++ b/src/python/gem5/components/processors/abstract_processor.py @@ -33,7 +33,10 @@ from typing import ( Optional, ) -from m5.objects import SubSystem +from m5.objects import ( + Root, + SubSystem, +) from ...isas import ISA from ...utils.requires import requires @@ -83,3 +86,12 @@ class AbstractProcessor(SubSystem): def _post_instantiate(self) -> None: """Called to set up anything needed after ``m5.instantiate``.""" pass + + def _pre_instantiate(self, root: Root) -> None: + """Called in the `AbstractBoard`'s `_pre_instantiate` method. This is + called after `connect_things`, after the creation of the root object + (which is passed in as an argument), but before `m5.instantiate`). + + Subclasses should override this method to set up any connections. + """ + pass diff --git a/src/python/gem5/components/processors/base_cpu_processor.py b/src/python/gem5/components/processors/base_cpu_processor.py index b1a63ea8ce..674148b409 100644 --- a/src/python/gem5/components/processors/base_cpu_processor.py +++ b/src/python/gem5/components/processors/base_cpu_processor.py @@ -27,12 +27,14 @@ from typing import List +import m5 from m5.objects import ( BaseAtomicSimpleCPU, BaseMinorCPU, BaseNonCachingSimpleCPU, BaseO3CPU, BaseTimingSimpleCPU, + Root, ) from m5.util import warn @@ -99,3 +101,9 @@ class BaseCPUProcessor(AbstractProcessor): board.set_mem_mode(MemMode.ATOMIC) else: raise NotImplementedError + + def _pre_instantiate(self, root: Root) -> None: + super()._pre_instantiate(root) + if any(core.is_kvm_core() for core in self.get_cores()): + m5.ticks.fixGlobalFrequency() + root.sim_quantum = m5.ticks.fromSeconds(0.001) diff --git a/src/python/gem5/components/processors/switchable_processor.py b/src/python/gem5/components/processors/switchable_processor.py index 2436c9e81f..a5a9ae2b6b 100644 --- a/src/python/gem5/components/processors/switchable_processor.py +++ b/src/python/gem5/components/processors/switchable_processor.py @@ -31,6 +31,7 @@ from typing import ( ) import m5 +from m5.objects import Root from ...utils.override import * from ..boards.abstract_board import AbstractBoard @@ -155,3 +156,24 @@ class SwitchableProcessor(AbstractProcessor): # Ensure the current processor is updated. self._current_cores = to_switch + + def _pre_instantiate(self, root: Root) -> None: + super()._pre_instantiate(root) + # The following is a bit of a hack. If a simulation is to use a KVM + # core then the `sim_quantum` value must be set. However, in the + # case of using a SwitchableProcessor the KVM cores may be + # switched out and therefore not accessible via `get_cores()`. + # This is the reason for the `isinstance` check. + # + # We cannot set the `sim_quantum` value in every simulation as + # setting it causes the scheduling of exits to be off by the + # `sim_quantum` value (something necessary if we are using KVM + # cores). Ergo we only set the value of KVM cores are present. + # + # There is still a bug here in that if the user is switching to and + # from KVM and non-KVM cores via the SwitchableProcessor then the + # scheduling of exits for the non-KVM cores will be incorrect. This + # will be fixed at a later date. + if self._prepare_kvm: + m5.ticks.fixGlobalFrequency() + root.sim_quantum = m5.ticks.fromSeconds(0.001) diff --git a/src/python/gem5/simulate/simulator.py b/src/python/gem5/simulate/simulator.py index a1b75a0523..ba74361915 100644 --- a/src/python/gem5/simulate/simulator.py +++ b/src/python/gem5/simulate/simulator.py @@ -670,29 +670,6 @@ class Simulator: full_system=self._full_system ) - # The following is a bit of a hack. If a simulation is to use a KVM - # core then the `sim_quantum` value must be set. However, in the - # case of using a SwitchableProcessor the KVM cores may be - # switched out and therefore not accessible via `get_cores()`. - # This is the reason for the `isinstance` check. - # - # We cannot set the `sim_quantum` value in every simulation as - # setting it causes the scheduling of exits to be off by the - # `sim_quantum` value (something necessary if we are using KVM - # cores). Ergo we only set the value of KVM cores are present. - # - # There is still a bug here in that if the user is switching to and - # from KVM and non-KVM cores via the SwitchableProcessor then the - # scheduling of exits for the non-KVM cores will be incorrect. This - # will be fixed at a later date. - processor = self._board.processor - if any(core.is_kvm_core() for core in processor.get_cores()) or ( - isinstance(processor, SwitchableProcessor) - and any(core.is_kvm_core() for core in processor._all_cores()) - ): - m5.ticks.fixGlobalFrequency() - root.sim_quantum = m5.ticks.fromSeconds(0.001) - # m5.instantiate() takes a parameter specifying the path to the # checkpoint directory. If the parameter is None, no checkpoint # will be restored.