arch-riscv,dev: Add PCI Host to RISCV Board

Add GenericRiscvPciHost to RISCV Board. In addition, we connect the IGbE_e1000
ethernet card to PCI in order to verify the correct functionality.

To be noticed that we build a new Linux kernel v5.10 (with Bootloader) according to these steps (
https://github.com/gem5/gem5-resources/tree/stable/src/riscv-fs) adding the the PCI and e1000 drivers:

CONFIG_PCI_SYSCALL=y
CONFIG_PCI_STUB=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_NET_VENDOR_INTEL=y
CONFIG_E1000=y
CONFIG_E1000E=y
CONFIG_IGB=y
CONFIG_NET_VENDOR_I825XX=y

Here you can find the kernel.config and our prebuild kernel to verify the correct behaviour:
https://www.dropbox.com/scl/fo/sz9s37vybpfecbfilxqzz/h?dl=0&rlkey=klkxh33anjqnzwj3sopucqqzx

You can verify it with the following command:
build/RISCV/gem5.fast configs/example/gem5_library/riscv-fs.py

Dear Jason Lowe-Power,

Thank you for your comments! We have addressed all of them.

Best regards,
Nikolaos Tampouratzis

Dear Jason,

I think that it is ok now! :)

Thanks!

Best regards,
Nikolaos Tampouratzis

Change-Id: Id27d84a5588648b82cbfd5c88471927157ae6759
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/59969
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
ntampouratzis
2022-05-24 23:30:58 +03:00
committed by Bobby Bruce
parent c685cfcb7e
commit f3e9484969
5 changed files with 241 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2021 The Regents of the University of California
# Copyright (c) 2022 EXAscale Performance SYStems (EXAPSYS)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -49,6 +50,8 @@ from m5.objects import (
IOXBar,
RiscvRTC,
HiFive,
GenericRiscvPciHost,
IGbE_e1000,
CowDiskImage,
RawDiskImage,
RiscvMmioVirtIO,
@@ -138,6 +141,16 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
def _setup_io_devices(self) -> None:
"""Connect the I/O devices to the I/O bus"""
#Add PCI
self.platform.pci_host.pio = self.iobus.mem_side_ports
#Add Ethernet card
self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
InterruptLine=1, InterruptPin=1)
self.ethernet.host = self.platform.pci_host
self.ethernet.pio = self.iobus.mem_side_ports
self.ethernet.dma = self.iobus.cpu_side_ports
if self.get_cache_hierarchy().is_ruby():
for device in self._off_chip_devices + self._on_chip_devices:
@@ -159,6 +172,11 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
for dev in self._off_chip_devices
]
#PCI
self.bridge.ranges.append(AddrRange(0x2F000000, size='16MB'))
self.bridge.ranges.append(AddrRange(0x30000000, size='256MB'))
self.bridge.ranges.append(AddrRange(0x40000000, size='512MB'))
def _setup_pma(self) -> None:
"""Set the PMA devices on each core"""
@@ -167,6 +185,11 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
for dev in self._on_chip_devices + self._off_chip_devices
]
#PCI
uncacheable_range.append(AddrRange(0x2F000000, size='16MB'))
uncacheable_range.append(AddrRange(0x30000000, size='256MB'))
uncacheable_range.append(AddrRange(0x40000000, size='512MB'))
# TODO: Not sure if this should be done per-core like in the example
for cpu in self.get_processor().get_cores():
cpu.get_mmu().pma_checker = PMAChecker(
@@ -322,6 +345,71 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload):
soc_node.append(plic_node)
# PCI
pci_state = FdtState(addr_cells=3, size_cells=2,
cpu_cells=1, interrupt_cells=1)
pci_node = FdtNode("pci")
if int(self.platform.pci_host.conf_device_bits) == 8:
pci_node.appendCompatible("pci-host-cam-generic")
elif int(self.platform.pci_host.conf_device_bits) == 12:
pci_node.appendCompatible("pci-host-ecam-generic")
else:
m5.fatal("No compatibility string for the set conf_device_width")
pci_node.append(FdtPropertyStrings("device_type", ["pci"]))
# Cell sizes of child nodes/peripherals
pci_node.append(pci_state.addrCellsProperty())
pci_node.append(pci_state.sizeCellsProperty())
pci_node.append(pci_state.interruptCellsProperty())
# PCI address for CPU
pci_node.append(FdtPropertyWords("reg",
soc_state.addrCells(self.platform.pci_host.conf_base) +
soc_state.sizeCells(self.platform.pci_host.conf_size) ))
# Ranges mapping
# For now some of this is hard coded, because the PCI module does not
# have a proper full understanding of the memory map, but adapting the
# PCI module is beyond the scope of what I'm trying to do here.
# Values are taken from the ARM VExpress_GEM5_V1 platform.
ranges = []
# Pio address range
ranges += self.platform.pci_host.pciFdtAddr(space=1, addr=0)
ranges += soc_state.addrCells(self.platform.pci_host.pci_pio_base)
ranges += pci_state.sizeCells(0x10000) # Fixed size
# AXI memory address range
ranges += self.platform.pci_host.pciFdtAddr(space=2, addr=0)
ranges += soc_state.addrCells(self.platform.pci_host.pci_mem_base)
ranges += pci_state.sizeCells(0x40000000) # Fixed size
pci_node.append(FdtPropertyWords("ranges", ranges))
# Interrupt mapping
plic_handle = int_state.phandle(plic)
int_base = self.platform.pci_host.int_base
interrupts = []
for i in range(int(self.platform.pci_host.int_count)):
interrupts += self.platform.pci_host.pciFdtAddr(device=i,
addr=0) + [int(i) + 1, plic_handle, int(int_base) + i]
pci_node.append(FdtPropertyWords("interrupt-map", interrupts))
int_count = int(self.platform.pci_host.int_count)
if int_count & (int_count - 1):
fatal("PCI interrupt count should be power of 2")
intmask = self.platform.pci_host.pciFdtAddr(device=int_count - 1,
addr=0) + [0x0]
pci_node.append(FdtPropertyWords("interrupt-map-mask", intmask))
if self.platform.pci_host._dma_coherent:
pci_node.append(FdtProperty("dma-coherent"))
soc_node.append(pci_node)
# UART node
uart = self.platform.uart
uart_node = uart.generateBasicPioDeviceNode(