Add SE mode to X86Board and RiscvBoard (#1702)
This commit is contained in:
@@ -60,6 +60,7 @@ from m5.util.fdthelper import (
|
|||||||
FdtState,
|
FdtState,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from ...components.boards.se_binary_workload import SEBinaryWorkload
|
||||||
from ...isas import ISA
|
from ...isas import ISA
|
||||||
from ...resources.resource import AbstractResource
|
from ...resources.resource import AbstractResource
|
||||||
from ...utils.override import overrides
|
from ...utils.override import overrides
|
||||||
@@ -70,7 +71,7 @@ from .abstract_system_board import AbstractSystemBoard
|
|||||||
from .kernel_disk_workload import KernelDiskWorkload
|
from .kernel_disk_workload import KernelDiskWorkload
|
||||||
|
|
||||||
|
|
||||||
class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
|
class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload, SEBinaryWorkload):
|
||||||
"""
|
"""
|
||||||
A board capable of full system simulation for RISC-V.
|
A board capable of full system simulation for RISC-V.
|
||||||
|
|
||||||
@@ -100,47 +101,54 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def _setup_board(self) -> None:
|
def _setup_board(self) -> None:
|
||||||
self.workload = RiscvBootloaderKernelWorkload()
|
if self.is_fullsystem():
|
||||||
|
self.workload = RiscvBootloaderKernelWorkload()
|
||||||
|
|
||||||
# Contains a CLINT, PLIC, UART, and some functions for the dtb, etc.
|
# Contains a CLINT, PLIC, UART, and some functions for the dtb, etc.
|
||||||
self.platform = HiFive()
|
self.platform = HiFive()
|
||||||
# Note: This only works with single threaded cores.
|
# Note: This only works with single threaded cores.
|
||||||
self.platform.plic.hart_config = ",".join(
|
self.platform.plic.hart_config = ",".join(
|
||||||
["MS" for _ in range(self.processor.get_num_cores())]
|
["MS" for _ in range(self.processor.get_num_cores())]
|
||||||
)
|
)
|
||||||
self.platform.attachPlic()
|
self.platform.attachPlic()
|
||||||
self.platform.clint.num_threads = self.processor.get_num_cores()
|
self.platform.clint.num_threads = self.processor.get_num_cores()
|
||||||
|
|
||||||
# Add the RTC
|
# Add the RTC
|
||||||
# TODO: Why 100MHz? Does something else need to change when this does?
|
# TODO: Why 100MHz? Does something else need to change when this does?
|
||||||
self.platform.rtc = RiscvRTC(frequency=Frequency("100MHz"))
|
self.platform.rtc = RiscvRTC(
|
||||||
self.platform.clint.int_pin = self.platform.rtc.int_pin
|
frequency=Frequency("100MHz")
|
||||||
|
) # page 77, section 7.1
|
||||||
|
self.platform.clint.int_pin = self.platform.rtc.int_pin
|
||||||
|
|
||||||
# Incoherent I/O bus
|
# Incoherent I/O bus
|
||||||
self.iobus = IOXBar()
|
self.iobus = IOXBar()
|
||||||
self.iobus.badaddr_responder = BadAddr()
|
self.iobus.badaddr_responder = BadAddr()
|
||||||
self.iobus.default = self.iobus.badaddr_responder.pio
|
self.iobus.default = self.iobus.badaddr_responder.pio
|
||||||
|
|
||||||
# The virtio disk
|
# The virtio disk
|
||||||
self.disk = RiscvMmioVirtIO(
|
self.disk = RiscvMmioVirtIO(
|
||||||
vio=VirtIOBlock(),
|
vio=VirtIOBlock(),
|
||||||
interrupt_id=0x8,
|
interrupt_id=0x8,
|
||||||
pio_size=4096,
|
pio_size=4096,
|
||||||
pio_addr=0x10008000,
|
pio_addr=0x10008000,
|
||||||
)
|
)
|
||||||
|
|
||||||
# The virtio rng
|
# The virtio rng
|
||||||
self.rng = RiscvMmioVirtIO(
|
self.rng = RiscvMmioVirtIO(
|
||||||
vio=VirtIORng(),
|
vio=VirtIORng(),
|
||||||
interrupt_id=0x8,
|
interrupt_id=0x8,
|
||||||
pio_size=4096,
|
pio_size=4096,
|
||||||
pio_addr=0x10007000,
|
pio_addr=0x10007000,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Note: This overrides the platform's code because the platform isn't
|
# Note: This overrides the platform's code because the platform
|
||||||
# general enough.
|
# isn't general enough.
|
||||||
self._on_chip_devices = [self.platform.clint, self.platform.plic]
|
self._on_chip_devices = [self.platform.clint, self.platform.plic]
|
||||||
self._off_chip_devices = [self.platform.uart, self.disk, self.rng]
|
self._off_chip_devices = [self.platform.uart, self.disk, self.rng]
|
||||||
|
|
||||||
|
else:
|
||||||
|
# SE mode board setup
|
||||||
|
pass
|
||||||
|
|
||||||
def _setup_io_devices(self) -> None:
|
def _setup_io_devices(self) -> None:
|
||||||
"""Connect the I/O devices to the I/O bus."""
|
"""Connect the I/O devices to the I/O bus."""
|
||||||
@@ -206,26 +214,39 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def get_dma_ports(self) -> List[Port]:
|
def get_dma_ports(self) -> List[Port]:
|
||||||
raise NotImplementedError(
|
raise Exception(
|
||||||
"RISCVBoard does not have DMA Ports. "
|
"Cannot execute `get_dma_ports()`: Board does not have DMA ports "
|
||||||
"Use `has_dma_ports()` to check this."
|
"to return. Use `has_dma_ports()` to check this."
|
||||||
)
|
)
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def has_io_bus(self) -> bool:
|
def has_io_bus(self) -> bool:
|
||||||
return True
|
return self.is_fullsystem()
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def get_io_bus(self) -> IOXBar:
|
def get_io_bus(self) -> IOXBar:
|
||||||
return self.iobus
|
if self.has_io_bus():
|
||||||
|
return self.iobus
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"Cannot execute `get_io_bus()`: Board does not have an I/O "
|
||||||
|
"bus to return. Use `has_io_bus()` to check this."
|
||||||
|
)
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def has_coherent_io(self) -> bool:
|
def has_coherent_io(self) -> bool:
|
||||||
return True
|
return self.is_fullsystem()
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def get_mem_side_coherent_io_port(self) -> Port:
|
def get_mem_side_coherent_io_port(self) -> Port:
|
||||||
return self.iobus.mem_side_ports
|
if self.has_coherent_io():
|
||||||
|
return self.iobus.mem_side_ports
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"Cannot execute `get_mem_side_coherent_io_port()`: Board does "
|
||||||
|
"not have any I/O ports to return. Use `has_coherent_io()` to "
|
||||||
|
"check this."
|
||||||
|
)
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def _setup_memory_ranges(self):
|
def _setup_memory_ranges(self):
|
||||||
@@ -509,7 +530,7 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
#
|
#
|
||||||
# This should be refactored in the future as part of a chance to have
|
# This should be refactored in the future as part of a chance to have
|
||||||
# all boards support both FS and SE modes.
|
# all boards support both FS and SE modes.
|
||||||
if self._is_fs:
|
if self.is_fullsystem():
|
||||||
if len(self._bootloader) > 0:
|
if len(self._bootloader) > 0:
|
||||||
self.workload.bootloader_addr = 0x0
|
self.workload.bootloader_addr = 0x0
|
||||||
self.workload.bootloader_filename = self._bootloader[0]
|
self.workload.bootloader_filename = self._bootloader[0]
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ from m5.objects import (
|
|||||||
)
|
)
|
||||||
from m5.util.convert import toMemorySize
|
from m5.util.convert import toMemorySize
|
||||||
|
|
||||||
|
from ...components.boards.se_binary_workload import SEBinaryWorkload
|
||||||
from ...isas import ISA
|
from ...isas import ISA
|
||||||
from ...resources.resource import AbstractResource
|
from ...resources.resource import AbstractResource
|
||||||
from ...utils.override import overrides
|
from ...utils.override import overrides
|
||||||
@@ -66,7 +67,7 @@ from .abstract_system_board import AbstractSystemBoard
|
|||||||
from .kernel_disk_workload import KernelDiskWorkload
|
from .kernel_disk_workload import KernelDiskWorkload
|
||||||
|
|
||||||
|
|
||||||
class X86Board(AbstractSystemBoard, KernelDiskWorkload):
|
class X86Board(AbstractSystemBoard, KernelDiskWorkload, SEBinaryWorkload):
|
||||||
"""
|
"""
|
||||||
A board capable of full system simulation for X86.
|
A board capable of full system simulation for X86.
|
||||||
|
|
||||||
@@ -97,17 +98,18 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def _setup_board(self) -> None:
|
def _setup_board(self) -> None:
|
||||||
self.pc = Pc()
|
if self.is_fullsystem():
|
||||||
|
self.pc = Pc()
|
||||||
|
|
||||||
self.workload = X86FsLinux()
|
self.workload = X86FsLinux()
|
||||||
|
|
||||||
# North Bridge
|
# North Bridge
|
||||||
self.iobus = IOXBar()
|
self.iobus = IOXBar()
|
||||||
|
|
||||||
# Set up all of the I/O.
|
# Set up all of the I/O.
|
||||||
self._setup_io_devices()
|
self._setup_io_devices()
|
||||||
|
|
||||||
self.m5ops_base = 0xFFFF0000
|
self.m5ops_base = 0xFFFF0000
|
||||||
|
|
||||||
def _setup_io_devices(self):
|
def _setup_io_devices(self):
|
||||||
"""Sets up the x86 IO devices.
|
"""Sets up the x86 IO devices.
|
||||||
@@ -291,27 +293,46 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload):
|
|||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def has_io_bus(self) -> bool:
|
def has_io_bus(self) -> bool:
|
||||||
return True
|
return self.is_fullsystem()
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def get_io_bus(self) -> BaseXBar:
|
def get_io_bus(self) -> IOXBar:
|
||||||
return self.iobus
|
if self.has_io_bus():
|
||||||
|
return self.iobus
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"Cannot execute `get_io_bus()`: Board does not have an I/O "
|
||||||
|
"bus to return. Use `has_io_bus()` to check this."
|
||||||
|
)
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def has_dma_ports(self) -> bool:
|
def has_dma_ports(self) -> bool:
|
||||||
return True
|
return self.is_fullsystem()
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def get_dma_ports(self) -> Sequence[Port]:
|
def get_dma_ports(self) -> Sequence[Port]:
|
||||||
return [self.pc.south_bridge.ide.dma, self.iobus.mem_side_ports]
|
if self.has_dma_ports():
|
||||||
|
return [self.pc.south_bridge.ide.dma, self.iobus.mem_side_ports]
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"Cannot execute `get_dma_ports()`: Board does not have DMA "
|
||||||
|
"ports to return. Use `has_dma_ports()` to check this."
|
||||||
|
)
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def has_coherent_io(self) -> bool:
|
def has_coherent_io(self) -> bool:
|
||||||
return True
|
return self.is_fullsystem()
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def get_mem_side_coherent_io_port(self) -> Port:
|
def get_mem_side_coherent_io_port(self) -> Port:
|
||||||
return self.iobus.mem_side_ports
|
if self.has_coherent_io():
|
||||||
|
return self.iobus.mem_side_ports
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"Cannot execute `get_mem_side_coherent_io_port()`: Board does "
|
||||||
|
"not have I/O ports to return. Use `has_coherent_io()` to "
|
||||||
|
"check this."
|
||||||
|
)
|
||||||
|
|
||||||
@overrides(AbstractSystemBoard)
|
@overrides(AbstractSystemBoard)
|
||||||
def _setup_memory_ranges(self):
|
def _setup_memory_ranges(self):
|
||||||
|
|||||||
@@ -24,30 +24,9 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import m5
|
|
||||||
from m5.objects import (
|
|
||||||
AddrRange,
|
|
||||||
BadAddr,
|
|
||||||
Bridge,
|
|
||||||
CowDiskImage,
|
|
||||||
Frequency,
|
|
||||||
GenericRiscvPciHost,
|
|
||||||
HiFive,
|
|
||||||
IGbE_e1000,
|
|
||||||
IOXBar,
|
|
||||||
PMAChecker,
|
|
||||||
Port,
|
|
||||||
RawDiskImage,
|
|
||||||
RiscvBootloaderKernelWorkload,
|
|
||||||
RiscvMmioVirtIO,
|
|
||||||
RiscvRTC,
|
|
||||||
VirtIOBlock,
|
|
||||||
VirtIORng,
|
|
||||||
)
|
|
||||||
from m5.util import warn
|
from m5.util import warn
|
||||||
|
|
||||||
from ...components.boards.riscv_board import RiscvBoard
|
from ...components.boards.riscv_board import RiscvBoard
|
||||||
from ...components.boards.se_binary_workload import SEBinaryWorkload
|
|
||||||
from ...components.cachehierarchies.classic.private_l1_shared_l2_cache_hierarchy import (
|
from ...components.cachehierarchies.classic.private_l1_shared_l2_cache_hierarchy import (
|
||||||
PrivateL1SharedL2CacheHierarchy,
|
PrivateL1SharedL2CacheHierarchy,
|
||||||
)
|
)
|
||||||
@@ -60,7 +39,7 @@ from ...utils.override import overrides
|
|||||||
from ...utils.requires import requires
|
from ...utils.requires import requires
|
||||||
|
|
||||||
|
|
||||||
class RiscvDemoBoard(RiscvBoard, SEBinaryWorkload):
|
class RiscvDemoBoard(RiscvBoard):
|
||||||
"""
|
"""
|
||||||
This board is based on the X86DemoBoard.
|
This board is based on the X86DemoBoard.
|
||||||
|
|
||||||
@@ -106,83 +85,3 @@ class RiscvDemoBoard(RiscvBoard, SEBinaryWorkload):
|
|||||||
memory=memory,
|
memory=memory,
|
||||||
cache_hierarchy=cache_hierarchy,
|
cache_hierarchy=cache_hierarchy,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Taken from Riscv Matched board. Below are functions that are needed to
|
|
||||||
# get SE mode to work.
|
|
||||||
|
|
||||||
@overrides(RiscvBoard)
|
|
||||||
def _setup_board(self) -> None:
|
|
||||||
if self._is_fs:
|
|
||||||
self.workload = RiscvBootloaderKernelWorkload()
|
|
||||||
|
|
||||||
# Contains a CLINT, PLIC, UART, and some functions for the dtb, etc.
|
|
||||||
self.platform = HiFive()
|
|
||||||
# Note: This only works with single threaded cores.
|
|
||||||
self.platform.plic.hart_config = ",".join(
|
|
||||||
["MS" for _ in range(self.processor.get_num_cores())]
|
|
||||||
)
|
|
||||||
self.platform.attachPlic()
|
|
||||||
self.platform.clint.num_threads = self.processor.get_num_cores()
|
|
||||||
|
|
||||||
# Add the RTC
|
|
||||||
self.platform.rtc = RiscvRTC(
|
|
||||||
frequency=Frequency("100MHz")
|
|
||||||
) # page 77, section 7.1
|
|
||||||
self.platform.clint.int_pin = self.platform.rtc.int_pin
|
|
||||||
|
|
||||||
# Incoherent I/O bus
|
|
||||||
self.iobus = IOXBar()
|
|
||||||
self.iobus.badaddr_responder = BadAddr()
|
|
||||||
self.iobus.default = self.iobus.badaddr_responder.pio
|
|
||||||
|
|
||||||
# The virtio disk
|
|
||||||
self.disk = RiscvMmioVirtIO(
|
|
||||||
vio=VirtIOBlock(),
|
|
||||||
interrupt_id=0x8,
|
|
||||||
pio_size=4096,
|
|
||||||
pio_addr=0x10008000,
|
|
||||||
)
|
|
||||||
|
|
||||||
# The virtio rng
|
|
||||||
self.rng = RiscvMmioVirtIO(
|
|
||||||
vio=VirtIORng(),
|
|
||||||
interrupt_id=0x8,
|
|
||||||
pio_size=4096,
|
|
||||||
pio_addr=0x10007000,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Note: This overrides the platform's code because the platform isn't
|
|
||||||
# general enough.
|
|
||||||
self._on_chip_devices = [self.platform.clint, self.platform.plic]
|
|
||||||
self._off_chip_devices = [self.platform.uart, self.disk, self.rng]
|
|
||||||
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@overrides(RiscvBoard)
|
|
||||||
def has_io_bus(self) -> bool:
|
|
||||||
return self._is_fs
|
|
||||||
|
|
||||||
@overrides(RiscvBoard)
|
|
||||||
def get_io_bus(self) -> IOXBar:
|
|
||||||
if self.has_io_bus():
|
|
||||||
return self.iobus
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(
|
|
||||||
"RiscvDemoBoard does not have an IO bus. "
|
|
||||||
"Use `has_io_bus()` to check this."
|
|
||||||
)
|
|
||||||
|
|
||||||
@overrides(RiscvBoard)
|
|
||||||
def has_coherent_io(self) -> bool:
|
|
||||||
return self._is_fs
|
|
||||||
|
|
||||||
@overrides(RiscvBoard)
|
|
||||||
def get_mem_side_coherent_io_port(self) -> Port:
|
|
||||||
if self.has_coherent_io():
|
|
||||||
return self.iobus.mem_side_ports
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(
|
|
||||||
"RiscvDemoBoard does not have any I/O ports. Use has_coherent_io to "
|
|
||||||
"check this."
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -24,15 +24,8 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
from m5.objects import (
|
|
||||||
IOXBar,
|
|
||||||
Pc,
|
|
||||||
Port,
|
|
||||||
X86FsLinux,
|
|
||||||
)
|
|
||||||
from m5.util import warn
|
from m5.util import warn
|
||||||
|
|
||||||
from ...components.boards.se_binary_workload import SEBinaryWorkload
|
|
||||||
from ...components.boards.x86_board import X86Board
|
from ...components.boards.x86_board import X86Board
|
||||||
from ...components.cachehierarchies.classic.private_l1_shared_l2_cache_hierarchy import (
|
from ...components.cachehierarchies.classic.private_l1_shared_l2_cache_hierarchy import (
|
||||||
PrivateL1SharedL2CacheHierarchy,
|
PrivateL1SharedL2CacheHierarchy,
|
||||||
@@ -41,11 +34,10 @@ from ...components.memory.multi_channel import DualChannelDDR4_2400
|
|||||||
from ...components.processors.cpu_types import CPUTypes
|
from ...components.processors.cpu_types import CPUTypes
|
||||||
from ...components.processors.simple_processor import SimpleProcessor
|
from ...components.processors.simple_processor import SimpleProcessor
|
||||||
from ...isas import ISA
|
from ...isas import ISA
|
||||||
from ...utils.override import overrides
|
|
||||||
from ...utils.requires import requires
|
from ...utils.requires import requires
|
||||||
|
|
||||||
|
|
||||||
class X86DemoBoard(X86Board, SEBinaryWorkload):
|
class X86DemoBoard(X86Board):
|
||||||
"""
|
"""
|
||||||
This prebuilt X86 board is used for demonstration purposes. It simulates
|
This prebuilt X86 board is used for demonstration purposes. It simulates
|
||||||
an X86 3GHz dual-core system with a 3GiB DDR4_2400 memory system. The
|
an X86 3GHz dual-core system with a 3GiB DDR4_2400 memory system. The
|
||||||
@@ -99,46 +91,3 @@ class X86DemoBoard(X86Board, SEBinaryWorkload):
|
|||||||
memory=memory,
|
memory=memory,
|
||||||
cache_hierarchy=cache_hierarchy,
|
cache_hierarchy=cache_hierarchy,
|
||||||
)
|
)
|
||||||
|
|
||||||
@overrides(X86Board)
|
|
||||||
def _setup_board(self) -> None:
|
|
||||||
if self._is_fs:
|
|
||||||
self.pc = Pc()
|
|
||||||
|
|
||||||
self.workload = X86FsLinux()
|
|
||||||
|
|
||||||
# North Bridge
|
|
||||||
self.iobus = IOXBar()
|
|
||||||
|
|
||||||
# Set up all of the I/O.
|
|
||||||
self._setup_io_devices()
|
|
||||||
|
|
||||||
self.m5ops_base = 0xFFFF0000
|
|
||||||
|
|
||||||
@overrides(X86Board)
|
|
||||||
def has_io_bus(self) -> bool:
|
|
||||||
return self.is_fullsystem()
|
|
||||||
|
|
||||||
@overrides(X86Board)
|
|
||||||
def get_io_bus(self) -> IOXBar:
|
|
||||||
if self.has_io_bus():
|
|
||||||
return self.iobus
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(
|
|
||||||
"X86DemoBoard does not have an IO bus. "
|
|
||||||
"Use `has_io_bus()` to check this."
|
|
||||||
)
|
|
||||||
|
|
||||||
@overrides(X86Board)
|
|
||||||
def has_coherent_io(self) -> bool:
|
|
||||||
return self.is_fullsystem()
|
|
||||||
|
|
||||||
@overrides(X86Board)
|
|
||||||
def get_mem_side_coherent_io_port(self) -> Port:
|
|
||||||
if self.has_coherent_io():
|
|
||||||
return self.iobus.mem_side_ports
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(
|
|
||||||
"x86DemoBoard does not have any I/O ports. Use has_coherent_io"
|
|
||||||
" to check this."
|
|
||||||
)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user