stdlib: Add support for ELFies

This enables the stdlib to load and run ELFie-based binaries

See https://github.com/intel/pinball2elf for more details on ELFies

Change-Id: Ic1b624df64da1c77afc0907257a9e989488912ec
Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/68038
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/python/SConscript b/src/python/SConscript
index f401c03..900723b 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -263,6 +263,7 @@
 PySource('gem5.resources', 'gem5/resources/resource.py')
 PySource('gem5.resources', 'gem5/resources/workload.py')
 PySource('gem5.resources', 'gem5/resources/looppoint.py')
+PySource('gem5.resources', 'gem5/resources/elfie.py')
 PySource('gem5.utils', 'gem5/utils/__init__.py')
 PySource('gem5.utils', 'gem5/utils/filelock.py')
 PySource('gem5.utils', 'gem5/utils/override.py')
diff --git a/src/python/gem5/components/boards/se_binary_workload.py b/src/python/gem5/components/boards/se_binary_workload.py
index 2558ce3..23be81b 100644
--- a/src/python/gem5/components/boards/se_binary_workload.py
+++ b/src/python/gem5/components/boards/se_binary_workload.py
@@ -35,6 +35,7 @@
     SimpointDirectoryResource,
 )
 
+from gem5.resources.elfie import ELFieInfo
 from gem5.resources.looppoint import Looppoint
 
 from m5.objects import SEWorkload, Process
@@ -210,6 +211,37 @@
             checkpoint=checkpoint,
         )
 
+    def set_se_elfie_workload(
+        self,
+        elfie: AbstractResource,
+        elfie_info: ELFieInfo,
+        arguments: List[str] = [],
+        checkpoint: Optional[Union[Path, AbstractResource]] = None,
+    ) -> None:
+        """Set up the system to run a ELFie workload.
+
+        **Limitations**
+        * Dynamically linked executables are partially supported when the host
+          ISA and the simulated ISA are the same.
+
+        :param elfie: The resource encapsulating the binary elfie to be run.
+        :param elfie_info: The ELFieInfo object that contain all the
+        information for the ELFie
+        :param arguments: The input arguments for the binary
+        """
+
+        assert isinstance(elfie_info, ELFieInfo)
+        self._elfie_info_object = elfie_info
+
+        self._elfie_info_object.setup_processor(self.get_processor())
+
+        # Call set_se_binary_workload after LoopPoint setup is complete
+        self.set_se_binary_workload(
+            binary=elfie,
+            arguments=arguments,
+            checkpoint=checkpoint,
+        )
+
     def get_looppoint(self) -> Looppoint:
         """
         Returns the LoopPoint object set. If no LoopPoint object has been set
diff --git a/src/python/gem5/resources/elfie.py b/src/python/gem5/resources/elfie.py
new file mode 100644
index 0000000..ae51388
--- /dev/null
+++ b/src/python/gem5/resources/elfie.py
@@ -0,0 +1,67 @@
+# Copyright (c) 2023 The Regents of the University of California
+# All rights reserved.
+#
+# 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.
+
+from m5.params import PcCountPair
+from m5.objects import PcCountTrackerManager
+
+from typing import List
+
+
+class ELFieInfo:
+    """Stores information to load/run ELFies
+
+    See https://github.com/intel/pinball2elf for more information
+    """
+
+    def __init__(self, start: PcCountPair, end: PcCountPair):
+        self._start = start
+        self._end = end
+        self._manager = PcCountTrackerManager()
+        self._manager.targets = self.get_targets()
+
+    def setup_processor(
+        self,
+        processor: "AbstractProcessor",
+    ) -> None:
+        """
+        A function is used to setup a PC tracker in all the cores and
+        connect all the tracker to the PC tracker manager to perform
+        multithread PC tracking.
+        :param processor: The processor used in the simulation configuration.
+        """
+        for core in processor.get_cores():
+            core.add_pc_tracker_probe(self.get_targets(), self.get_manager())
+
+    def get_targets(self) -> List[PcCountPair]:
+        """Returns the complete list of targets PcCountPairs. That is, the
+        PcCountPairs each region starts with as well as the relevant warmup
+        intervals."""
+        return [self._start, self._end]
+
+    def get_manager(self) -> PcCountTrackerManager:
+        """Returns the PcCountTrackerManager for this ELFie data
+        structure."""
+        return self._manager