From 4b3ba1daa628b14213c3b42c853f62268db58ebd Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 22 Aug 2024 05:08:19 -0700 Subject: [PATCH 1/5] stdlib: Deprecate Simulator 'full_system' param THis is deprecated in favor of the board determining whether the simulation is FS or SE. Usually this will be contingent on which `set_workload` funciton has been called. Regardless, it is the board's responsibility. The user should not need to explicitly declare this any longer. --- src/python/gem5/simulate/simulator.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/python/gem5/simulate/simulator.py b/src/python/gem5/simulate/simulator.py index 49dfac2bdf..59385fe17d 100644 --- a/src/python/gem5/simulate/simulator.py +++ b/src/python/gem5/simulate/simulator.py @@ -117,6 +117,10 @@ class Simulator: behavior. If not set, whether or not to run in FS mode will be determined via the board's ``is_fullsystem()`` function. + **Warning: This parameter is deprecated. The board + determines if the simulation is full system or not. + This parameter will be removed in a future gem5 + release.** :param on_exit_event: An optional map to specify what to execute on each exit event. There are three possibilities here: a generator, a list of functions, or a single function. @@ -291,6 +295,15 @@ class Simulator: """ + if full_system is not None: + warn( + "Setting the full_system parameter via the Simulator " + "constructor is deprecated and will be removed in future " + "releases of gem5. " + "The board determines if the simulation is full system or not " + "via it's `is_fullsystem` method." + ) + self.set_max_ticks(max_ticks) if id: From 4bdcb040d0cc94c8f6e609d5c584228a749a9f15 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 22 Aug 2024 05:16:47 -0700 Subject: [PATCH 2/5] stdlib: Move Root obj creation from Simulator to Board It makes much more sense for the Root Object to be create within the board and passed where required. Creating it in the Simulator class is not required. For this to work the signuature of the `_pre_instantiate` function in `AbstractBoard` has been updated to return the Root object. --- configs/example/lupv/run_lupv.py | 3 +-- .../gem5/components/boards/abstract_board.py | 25 +++++++++++++++++-- .../gem5/components/boards/arm_board.py | 5 ++-- .../gem5/components/boards/riscv_board.py | 9 ++++--- .../riscvmatched/riscvmatched_board.py | 4 +-- src/python/gem5/simulate/simulator.py | 18 +++---------- .../configs/boot_kvm_fork_run.py | 8 +++--- .../configs/run_replacement_policy.py | 3 +-- .../run_replacement_policy.py | 3 +-- .../traffic_gen/configs/simple_traffic_run.py | 4 +-- 10 files changed, 46 insertions(+), 36 deletions(-) diff --git a/configs/example/lupv/run_lupv.py b/configs/example/lupv/run_lupv.py index f6f938b16c..57bf6ca6b8 100644 --- a/configs/example/lupv/run_lupv.py +++ b/configs/example/lupv/run_lupv.py @@ -110,8 +110,7 @@ board.set_kernel_disk_workload( # Begin running of the simulation. print("Running with ISA: " + processor.get_isa().name) print() -root = Root(full_system=True, system=board) -board._pre_instantiate() +root = board._pre_instantiate() m5.instantiate() print("Beginning simulation!") diff --git a/src/python/gem5/components/boards/abstract_board.py b/src/python/gem5/components/boards/abstract_board.py index 83ca32d9c0..34308a1e11 100644 --- a/src/python/gem5/components/boards/abstract_board.py +++ b/src/python/gem5/components/boards/abstract_board.py @@ -41,6 +41,7 @@ from m5.objects import ( ClockDomain, IOXBar, Port, + Root, SrcClockDomain, System, VoltageDomain, @@ -391,13 +392,33 @@ class AbstractBoard: self.get_cache_hierarchy()._post_instantiate() self.get_memory()._post_instantiate() - def _pre_instantiate(self): + def _pre_instantiate(self, full_system: Optional[bool] = None) -> Root: """To be called immediately before ``m5.instantiate``. This is where - ``_connect_things`` is executed by default.""" + ``_connect_things`` is executed by default and the root object is Root + object is created and returned. + + :param full_system: Used to pass the full system flag to the board from + the Simulator module. **Note**: This was + implemented solely to maintain backawards + compatibility with while the Simululator module's + `full_system` flag is in state of deprecation. This + parameter will be removed when it is. When this + 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. self._connect_things() + # Return the Root object. + return Root( + full_system=( + full_system + if full_system is not None + else self.is_fullsystem() + ), + board=self, + ) + def _connect_things_check(self): """ Here we check that connect things has been called and throw an diff --git a/src/python/gem5/components/boards/arm_board.py b/src/python/gem5/components/boards/arm_board.py index 0a0cd2fa28..e8907a99c9 100644 --- a/src/python/gem5/components/boards/arm_board.py +++ b/src/python/gem5/components/boards/arm_board.py @@ -28,6 +28,7 @@ import os from abc import ABCMeta from typing import ( List, + Optional, Sequence, Tuple, ) @@ -327,8 +328,8 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload): self.system_port = port @overrides(AbstractBoard) - def _pre_instantiate(self): - super()._pre_instantiate() + def _pre_instantiate(self, full_system: Optional[bool] = None) -> None: + super()._pre_instantiate(full_system=full_system) # Add the PCI devices. self.pci_devices = self._pci_devices diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index e8e27029f2..e14833c996 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -26,7 +26,10 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os -from typing import List +from typing import ( + List, + Optional, +) import m5 from m5.objects import ( @@ -498,7 +501,7 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): return "/dev/vda" @overrides(AbstractSystemBoard) - def _pre_instantiate(self): + def _pre_instantiate(self, full_system: Optional[bool] = None): if len(self._bootloader) > 0: self.workload.bootloader_addr = 0x0 self.workload.bootloader_filename = self._bootloader[0] @@ -507,7 +510,7 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): else: self.workload.kernel_addr = 0x0 self.workload.entry_point = 0x80000000 - self._connect_things() + super()._pre_instantiate(full_system=full_system) @overrides(KernelDiskWorkload) def _add_disk_to_board(self, disk_image: AbstractResource): diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index 23a7dcc8cb..ba9588c725 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -313,7 +313,7 @@ class RISCVMatchedBoard( memory.set_memory_range(self.mem_ranges) @overrides(AbstractSystemBoard) - def _pre_instantiate(self): + def _pre_instantiate(self, full_system: Optional[bool] = None) -> None: if self._fs: if len(self._bootloader) > 0: self.workload.bootloader_addr = 0x0 @@ -326,7 +326,7 @@ class RISCVMatchedBoard( self.workload.kernel_addr = 0x0 self.workload.entry_point = 0x80000000 - self._connect_things() + super()._pre_instantiate(full_system=full_system) def generate_device_tree(self, outdir: str) -> None: """Creates the ``dtb`` and ``dts`` files. diff --git a/src/python/gem5/simulate/simulator.py b/src/python/gem5/simulate/simulator.py index 59385fe17d..a1b75a0523 100644 --- a/src/python/gem5/simulate/simulator.py +++ b/src/python/gem5/simulate/simulator.py @@ -664,22 +664,12 @@ class Simulator: if not self._instantiated: # Before anything else we run the AbstractBoard's - # `_pre_instantiate` function. - self._board._pre_instantiate() - - root = Root( - full_system=( - self._full_system - if self._full_system is not None - else self._board.is_fullsystem() - ), - board=self._board, + # `_pre_instantiate` function. This returns the root object which + # is required for instantiation. + self._root = self._board._pre_instantiate( + full_system=self._full_system ) - # We take a copy of the Root in case it's required elsewhere - # (for example, in `get_stats()`). - self._root = 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 diff --git a/tests/gem5/kvm_fork_tests/configs/boot_kvm_fork_run.py b/tests/gem5/kvm_fork_tests/configs/boot_kvm_fork_run.py index 8850a27c75..be6e6009e1 100644 --- a/tests/gem5/kvm_fork_tests/configs/boot_kvm_fork_run.py +++ b/tests/gem5/kvm_fork_tests/configs/boot_kvm_fork_run.py @@ -207,15 +207,15 @@ print("Running with ISA: " + processor.get_isa().name) print("Running with protocol: " + get_runtime_coherence_protocol().name) print() -root = Root(full_system=True, system=motherboard) +# Disable the gdb ports. Required for forking. +m5.disableAllListeners() +root = motherboard._pre_instantiate() # TODO: This of annoying. Is there a way to fix this to happen # automatically when running KVM? root.sim_quantum = int(1e9) -# Disable the gdb ports. Required for forking. -m5.disableAllListeners() -motherboard._pre_instantiate() + m5.instantiate() # Simulate the inital boot with the starting KVM cpu diff --git a/tests/gem5/replacement_policies/configs/run_replacement_policy.py b/tests/gem5/replacement_policies/configs/run_replacement_policy.py index 8f52a061f6..f7ecdb71de 100644 --- a/tests/gem5/replacement_policies/configs/run_replacement_policy.py +++ b/tests/gem5/replacement_policies/configs/run_replacement_policy.py @@ -83,9 +83,8 @@ motherboard = TestBoard( memory=memory, cache_hierarchy=cache_hierarchy, ) -root = Root(full_system=False, system=motherboard) -motherboard._pre_instantiate() +root = motherboard._pre_instantiate() m5.instantiate() generator.start_traffic() diff --git a/tests/gem5/replacement_policies/run_replacement_policy.py b/tests/gem5/replacement_policies/run_replacement_policy.py index 8f52a061f6..f7ecdb71de 100644 --- a/tests/gem5/replacement_policies/run_replacement_policy.py +++ b/tests/gem5/replacement_policies/run_replacement_policy.py @@ -83,9 +83,8 @@ motherboard = TestBoard( memory=memory, cache_hierarchy=cache_hierarchy, ) -root = Root(full_system=False, system=motherboard) -motherboard._pre_instantiate() +root = motherboard._pre_instantiate() m5.instantiate() generator.start_traffic() diff --git a/tests/gem5/traffic_gen/configs/simple_traffic_run.py b/tests/gem5/traffic_gen/configs/simple_traffic_run.py index 3a850b497d..7c264cefe9 100644 --- a/tests/gem5/traffic_gen/configs/simple_traffic_run.py +++ b/tests/gem5/traffic_gen/configs/simple_traffic_run.py @@ -202,9 +202,7 @@ motherboard = TestBoard( cache_hierarchy=cache_hierarchy, ) -root = Root(full_system=False, system=motherboard) - -motherboard._pre_instantiate() +root = motherboard._pre_instantiate() m5.instantiate() generator.start_traffic() From b358471eb954660b6fba9be327ee91d62f366761 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 22 Aug 2024 05:20:58 -0700 Subject: [PATCH 3/5] stdlib: Move 'sim_quantum' set from Simulator to Processor The setting of the `sim_quantum` parameter makes considerably more sense to occur in the Processor. Through the `_pre_instnatiate` functions this is now possible. --- .../gem5/components/boards/abstract_board.py | 13 ++++++++--- .../processors/abstract_processor.py | 14 ++++++++++- .../processors/base_cpu_processor.py | 8 +++++++ .../processors/switchable_processor.py | 22 ++++++++++++++++++ src/python/gem5/simulate/simulator.py | 23 ------------------- 5 files changed, 53 insertions(+), 27 deletions(-) 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. From 7c83e3379b169f1dd6ed28ce1780602e88849ffd Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Fri, 4 Oct 2024 11:56:48 -0700 Subject: [PATCH 4/5] stdlib: Add `_pre_instantiate` funcs for caches and memory Note: At present this is not used but these functions can be filled or overriden in subclasses as required. --- .../gem5/components/boards/abstract_board.py | 4 +++- .../abstract_cache_hierarchy.py | 17 ++++++++++++++++- .../components/memory/abstract_memory_system.py | 13 +++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/python/gem5/components/boards/abstract_board.py b/src/python/gem5/components/boards/abstract_board.py index af9ff300b6..5819adc9de 100644 --- a/src/python/gem5/components/boards/abstract_board.py +++ b/src/python/gem5/components/boards/abstract_board.py @@ -420,8 +420,10 @@ class AbstractBoard: ) # 3. Call any of the components' `_pre_instantiate` functions. - # Right now, only the processor requires this. self.get_processor()._pre_instantiate(root) + self.get_memory()._pre_instantiate(root) + if self.get_cache_hierarchy(): + self.get_cache_hierarchy()._pre_instantiate(root) # 4. Return the root object. return root diff --git a/src/python/gem5/components/cachehierarchies/abstract_cache_hierarchy.py b/src/python/gem5/components/cachehierarchies/abstract_cache_hierarchy.py index b0435543af..dc20c14f70 100644 --- a/src/python/gem5/components/cachehierarchies/abstract_cache_hierarchy.py +++ b/src/python/gem5/components/cachehierarchies/abstract_cache_hierarchy.py @@ -42,7 +42,10 @@ from abc import ( ) from typing import Callable -from m5.objects import SubSystem +from m5.objects import ( + Root, + SubSystem, +) from m5.util.fdthelper import * from ..boards.abstract_board import AbstractBoard @@ -139,6 +142,18 @@ class AbstractCacheHierarchy(SubSystem): """ raise NotImplementedError + 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. + + At present there is no general task that must be specified here and is + default or applicable to all cache hierarchies. + """ + pass + def _post_instantiate(self): """Called to set up anything needed after ``m5.instantiate``.""" pass diff --git a/src/python/gem5/components/memory/abstract_memory_system.py b/src/python/gem5/components/memory/abstract_memory_system.py index 06fa60cad8..6d24e724b6 100644 --- a/src/python/gem5/components/memory/abstract_memory_system.py +++ b/src/python/gem5/components/memory/abstract_memory_system.py @@ -38,6 +38,7 @@ from m5.objects import ( AddrRange, MemCtrl, Port, + Root, SubSystem, ) @@ -50,6 +51,18 @@ class AbstractMemorySystem(SubSystem): def __init__(self) -> None: super().__init__() + 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. + + At present there is no general task that must be specified here and is + default or applicable to all memory systems. + """ + pass + @abstractmethod def incorporate_memory(self, board: AbstractBoard) -> None: """This function completes all of the necessary steps to add this From 11fa0ac9a5ea9e2ef5814be0a7e433698c47a633 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Wed, 9 Oct 2024 05:06:13 -0700 Subject: [PATCH 5/5] stdlib: Mv setup_board/setup_mem_ranges calls to set_fs This change allows for the `_setup_memory_range` and `_setup_board` functions to know if the board is to run a FS or SE workload, thus allowing for a baord to handle both cases considerably easier than before. With this change all functions are called after FS or SE is declared via the `_set_fullsystem` function and thus all can accomodate for SE and FS workloads. --- .../gem5/components/boards/abstract_board.py | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/python/gem5/components/boards/abstract_board.py b/src/python/gem5/components/boards/abstract_board.py index 5819adc9de..cd6f559937 100644 --- a/src/python/gem5/components/boards/abstract_board.py +++ b/src/python/gem5/components/boards/abstract_board.py @@ -118,12 +118,6 @@ class AbstractBoard: # Simulator module. self._checkpoint = None - # Setup the board and memory system's memory ranges. - self._setup_memory_ranges() - - # Setup board properties unique to the board being constructed. - self._setup_board() - # A private variable to record whether `_connect_things` has been # been called. self._connect_things_called = False @@ -195,6 +189,9 @@ class AbstractBoard: """ self._is_fs = is_fs + self._setup_memory_ranges() + self._setup_board() + def is_fullsystem(self) -> bool: """ Returns ``True`` if the board is to be run in FS mode. Otherwise the board @@ -253,11 +250,14 @@ class AbstractBoard: @abstractmethod def _setup_board(self) -> None: """ - This function is called in the AbstractBoard constructor, before the - memory, processor, and cache hierarchy components are incorporated via - ``_connect_thing()``, but after the ``_setup_memory_ranges()`` function. - This function should be overridden by boards to specify components, - connections unique to that board. + This function is called at the end of `_set_fullsystem`. The reason for + this is the board's configuraiton varies significantly depending on + whether it is to be run in FS or SE mode. This function is therefore + called when a workload is set --- after construction but before + `_pre_instantiate` is called. + + As `_setup_memory_ranges()` is set in the constructor, this function + can be considered to have been called prior to `_setup_board """ raise NotImplementedError @@ -331,10 +331,18 @@ class AbstractBoard: """ Set the memory ranges for this board and memory system. - This is called in the constructor, prior to ``_setup_board`` and - ``_connect_things``. It should query the board's memory to determine the - size and the set the memory ranges on the memory system and on the - board. + This is called at the end of the `_set_fullsystem` function but before + `_setup_board`. `_set_fullsystem` is called when the workload is + declared. It is before `_pre_instantiate` (but, obviously after + construction). + + It should query the board's memory + to determine the size and the set the memory ranges on the memory + system and on the board. + + As thisis called at the end of `_set_fullsystem`, the board's memory + can be setup differently depending on whether the board is to be run in + FS or SE mode. The simplest implementation sets the board's memory range to the size of memory and memory system's range to be the same as the board. Full