Hi Nikolaos, Thanks for bringing this to our attention. We are looking at this problem here at Davis and will try to respond soon.
-Ayaz On Sat, Apr 10, 2021 at 4:42 AM Νικόλαος Ταμπουρατζής via gem5-users < gem5-users@gem5.org> wrote: > > Dear Gem5 community, > > I try to add PCI interface in RISCV arch doing the following steps > (similar with ARM RealView - I use the gem5-v21): > > 1) Create a file gem5/src/dev/riscv/pci_host.cc with the following code: > > #include "dev/riscv/pci_host.hh" > #include "params/GenericRiscvPciHost.hh" > > GenericRiscvPciHost::GenericRiscvPciHost(const GenericRiscvPciHostParams > &p) > : GenericPciHost(p), intBase(p.int_base), intCount(p.int_count) > { > } > > uint32_t > GenericRiscvPciHost::mapPciInterrupt( > const PciBusAddr &addr, PciIntPin pin) const > { > > fatal_if(pin == PciIntPin::NO_INT, > "%02x:%02x.%i: Interrupt from a device without interrupts\n", > addr.bus, addr.dev, addr.func); > > return intBase + (addr.dev % intCount); > } > > 2) Create a file gem5/src/dev/riscv/pci_host.hh with the following code: > > #ifndef __DEV_RISCV_PCI_HOST_HH__ > #define __DEV_RISCV_PCI_HOST_HH__ > > #include "dev/pci/host.hh" > > struct GenericRiscvPciHostParams; > > class GenericRiscvPciHost : public GenericPciHost > { > private: > const uint32_t intBase; > const uint32_t intCount; > > public: > GenericRiscvPciHost(const GenericRiscvPciHostParams &p); > virtual ~GenericRiscvPciHost() {} > > protected: > uint32_t mapPciInterrupt(const PciBusAddr &addr, > PciIntPin pin) const override; > }; > > #endif // __DEV_RISCV_PCI_HOST_HH__ > > 3) Add the "Source('pci_host.cc')" to gem5/src/dev/riscv/SConscript > > 4) Add the following code in gem5/src/dev/riscv/HiFive.py according to > RealView GenericArmPciHost: > > from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000 > > from m5.objects.Device import BasicPioDevice > from m5.objects.PciHost import * > from m5.SimObject import SimObject > > class GenericRiscvPciHost(GenericPciHost): #Add this class (PCI) > type = 'GenericRiscvPciHost' > cxx_header = "dev/riscv/pci_host.hh" > int_base = Param.Unsigned("PCI interrupt base") > int_count = Param.Unsigned("Maximum number of interrupts used by > this host") > > # This python parameter can be used in configuration scripts to turn > # on/off the fdt dma-coherent flag when doing dtb autogeneration > _dma_coherent = True > > def generateDeviceTree(self, state): > local_state = FdtState( > addr_cells=3, size_cells=2, > cpu_cells=1, interrupt_cells=1) > > node = FdtNode("pci") > > if int(self.conf_device_bits) == 8: > node.appendCompatible("pci-host-cam-generic") > elif int(self.conf_device_bits) == 12: > node.appendCompatible("pci-host-ecam-generic") > else: > m5.fatal("No compatibility string for the set > conf_device_width") > > node.append(FdtPropertyStrings("device_type", ["pci"])) > > # Cell sizes of child nodes/peripherals > node.append(local_state.addrCellsProperty()) > node.append(local_state.sizeCellsProperty()) > node.append(local_state.interruptCellsProperty()) > # PCI address for CPU > node.append(FdtPropertyWords("reg", > state.addrCells(self.conf_base) + > state.sizeCells(self.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 VExpress_GEM5_V1 platform. > ranges = [] > # Pio address range > ranges += self.pciFdtAddr(space=1, addr=0) > ranges += state.addrCells(self.pci_pio_base) > ranges += local_state.sizeCells(0x10000) # Fixed size > > # AXI memory address range > ranges += self.pciFdtAddr(space=2, addr=0) > ranges += state.addrCells(self.pci_mem_base) > ranges += local_state.sizeCells(0x40000000) # Fixed size > node.append(FdtPropertyWords("ranges", ranges)) > > if True: > #Change this to True because Realview calls always > ARM_PCI_INT_DEV > plic = self._parent.unproxy(self).plic > int_phandle = state.phandle(plic) > # Interrupt mapping > interrupts = [] > > # child interrupt specifier > child_interrupt = local_state.interruptCells(0x0) > > # parent unit address > parent_addr = 0x0 > #get this from /gem5/system/arm/dt/platforms file > > for i in range(int(self.int_count)): > parent_interrupt = int(self.int_base) + i > #RISCV uses only 1 interrupt_cell in plic > > interrupts += self.pciFdtAddr(device=i, addr=0) + \ > child_interrupt + [int_phandle] + [parent_addr] + \ > [parent_interrupt] > > node.append(FdtPropertyWords("interrupt-map", interrupts)) > > int_count = int(self.int_count) > if int_count & (int_count - 1): > fatal("PCI interrupt count should be power of 2") > > intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + > [0x0] > node.append(FdtPropertyWords("interrupt-map-mask", intmask)) > else: > m5.fatal("Unsupported PCI interrupt policy " + > "for Device Tree generation") > > if self._dma_coherent: > node.append(FdtProperty("dma-coherent")) > > yield node > > class HiFive(Platform): > ......... > pci_host = GenericRiscvPciHost( > > #Add these 3 lines (PCI) > conf_base=0x30000000, conf_size='256MiB', conf_device_bits=12, > pci_pio_base=0x2f000000, pci_mem_base=0x40000000, > int_base=100, int_count=4) > > ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0, > > #Add IGbE_e1000 PCI device (PCI) > InterruptLine=1, InterruptPin=1) > > def attachPlic(self): > """Count number of PLIC interrupt sources > """ > plic_srcs = [self.uart_int_id] > plic_srcs.append(self.pci_host.int_base) #Add this line (PCI) > for device in self._off_chip_devices(): > if hasattr(device, "interrupt_id"): > plic_srcs.append(device.interrupt_id) > self.plic.n_src = max(plic_srcs) + 1 > > 5) Add the following code in gem5/configs/example/riscv/fs_linux.py : > > #system.bridge.ranges = system.platform._off_chip_ranges() #Replaced > from 3 lines below > > range_list = system.platform._off_chip_ranges() > range_list.append(AddrRange(0x2f000000, 0x80000000)) > system.bridge.ranges = range_list > > system.platform.pci_host.pio = system.iobus.mem_side_ports > system.platform.ethernet.host = system.platform.pci_host > system.platform.ethernet.pio = system.iobus.mem_side_ports > system.platform.ethernet.dma = system.iobus.cpu_side_ports > > > 6) To be noticed that I use the prebuilt files from here: > https://github.com/ppeetteerrs/gem5-RISC-V-FS-Linux/. In addition, I > add the PCI and e1000 drivers to kernel.config and build the Linux > Kernel v5.10 according to this github: > 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 > > However, when I try to execute the gem5 (build/RISCV/gem5.opt -d > $RISCV/logs configs/example/riscv/fs_linux.py --kernel=$OUT/bbl > --caches --mem-size=1024MB --mem-type=DDR4_2400_8x8 > --cpu-type=AtomicSimpleCPU --disk-image=$OUT/riscv_parsec_disk -n 1) I > get the following panic: > > info: Entering event queue @ 0. Starting simulation... > 1086842500: system.platform.terminal: attach terminal 0 > panic: invalid access size(?) for PCI configspace! > Memory Usage: 437656 KBytes > Program aborted at tick 18474133000 > > Please help me to add PCI interface correctly! I think that it will be > very useful to gem5 community in order to add a wide range of PCI > devices! > > You can find the files with the above changes here: > https://www.dropbox.com/s/pf4iu3z31zy88vr/riscv_pci.tar.xz > > Best regards, > Nikolaos > > _______________________________________________ > gem5-users mailing list -- gem5-users@gem5.org > To unsubscribe send an email to gem5-users-le...@gem5.org > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s >
_______________________________________________ gem5-users mailing list -- gem5-users@gem5.org To unsubscribe send an email to gem5-users-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s