stdlib: Give board interface for mem ports

It is possible that the board has more than just a "main" memory. For
instance, the ArmBoard has a boot memory which is separate from the
`get_memory` function.

This moves the `get_mem_ports` function to the board so that the board
can optionally override it.

Change-Id: I05e388cc93e691e9a4fa674023f158af447349f9
Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64631
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/python/gem5/components/boards/abstract_board.py b/src/python/gem5/components/boards/abstract_board.py
index e22c9ef..720aaca 100644
--- a/src/python/gem5/components/boards/abstract_board.py
+++ b/src/python/gem5/components/boards/abstract_board.py
@@ -31,6 +31,7 @@
 from ...resources.workload import AbstractWorkload
 
 from m5.objects import (
+    AddrRange,
     System,
     Port,
     IOXBar,
@@ -39,7 +40,7 @@
     VoltageDomain,
 )
 
-from typing import List, Optional
+from typing import List, Optional, Sequence, Tuple
 
 
 class AbstractBoard:
@@ -128,6 +129,14 @@
         """
         return self.memory
 
+    def get_mem_ports(self) -> Sequence[Tuple[AddrRange, Port]]:
+        """Get the memory ports exposed on this board
+
+        Note: The ports should be returned such that the address ranges are
+        in ascending order.
+        """
+        return self.get_memory().get_mem_ports()
+
     def get_cache_hierarchy(self) -> Optional["AbstractCacheHierarchy"]:
         """Get the cache hierarchy connected to the board.
 
diff --git a/src/python/gem5/components/cachehierarchies/chi/private_l1_cache_hierarchy.py b/src/python/gem5/components/cachehierarchies/chi/private_l1_cache_hierarchy.py
index 2033903..9c91e05 100644
--- a/src/python/gem5/components/cachehierarchies/chi/private_l1_cache_hierarchy.py
+++ b/src/python/gem5/components/cachehierarchies/chi/private_l1_cache_hierarchy.py
@@ -202,7 +202,7 @@
         self, board: AbstractBoard
     ) -> List[MemoryController]:
         memory_controllers = []
-        for rng, port in board.get_memory().get_mem_ports():
+        for rng, port in board.get_mem_ports():
             mc = MemoryController(self.ruby_system.network, rng, port)
             mc.ruby_system = self.ruby_system
             memory_controllers.append(mc)
diff --git a/src/python/gem5/components/cachehierarchies/ruby/mesi_two_level_cache_hierarchy.py b/src/python/gem5/components/cachehierarchies/ruby/mesi_two_level_cache_hierarchy.py
index 96c7b70..82089a5 100644
--- a/src/python/gem5/components/cachehierarchies/ruby/mesi_two_level_cache_hierarchy.py
+++ b/src/python/gem5/components/cachehierarchies/ruby/mesi_two_level_cache_hierarchy.py
@@ -147,7 +147,7 @@
 
         self._directory_controllers = [
             Directory(self.ruby_system.network, cache_line_size, range, port)
-            for range, port in board.get_memory().get_mem_ports()
+            for range, port in board.get_mem_ports()
         ]
         # TODO: Make this prettier: The problem is not being able to proxy
         # the ruby system correctly
diff --git a/src/python/gem5/components/cachehierarchies/ruby/mi_example_cache_hierarchy.py b/src/python/gem5/components/cachehierarchies/ruby/mi_example_cache_hierarchy.py
index e3cf714..5955ad3 100644
--- a/src/python/gem5/components/cachehierarchies/ruby/mi_example_cache_hierarchy.py
+++ b/src/python/gem5/components/cachehierarchies/ruby/mi_example_cache_hierarchy.py
@@ -118,7 +118,7 @@
 
         # Create the directory controllers
         self._directory_controllers = []
-        for range, port in board.get_memory().get_mem_ports():
+        for range, port in board.get_mem_ports():
             dir = Directory(
                 self.ruby_system.network,
                 board.get_cache_line_size(),