From e6604bf1097ea7af4bfc54dbda9c2db1b5561ed8 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Tue, 21 Feb 2023 12:02:37 +0800 Subject: [PATCH] arch-riscv,dev: Add HiFive Base Platform This is basic abstract platform and all of RISC-V system should use platform inherit from HiFiveBase, HiFiveBase declared the common way to handle interrupt. Change-Id: I52122e1c82c200d7e6012433c2535c07d427f637 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/68199 Maintainer: Jason Lowe-Power Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- src/dev/riscv/HiFive.py | 154 ++++++++++++++++++++++----------------- src/dev/riscv/SConscript | 2 +- src/dev/riscv/hifive.cc | 19 +++-- src/dev/riscv/hifive.hh | 11 +-- 4 files changed, 107 insertions(+), 79 deletions(-) diff --git a/src/dev/riscv/HiFive.py b/src/dev/riscv/HiFive.py index 466968602b..5bd6363363 100755 --- a/src/dev/riscv/HiFive.py +++ b/src/dev/riscv/HiFive.py @@ -1,5 +1,6 @@ # Copyright (c) 2021 Huawei International # Copyright (c) 2022 EXAscale Performance SYStems (EXAPSYS) +# Copyright (c) 2023 Google LLC # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -63,24 +64,14 @@ class GenericRiscvPciHost(GenericPciHost): _dma_coherent = True -class HiFive(Platform): - """HiFive Platform +class HiFiveBase(Platform): + """HiFive Base Abstract Platform Implementation: This is the base class for SiFive's HiFive board series. It contains the CLINT and PLIC interrupt controllers, Uart and Disk. - Implementation details are based on SiFive - FU540-C000. https://sifive.cdn.prismic.io/ - sifive/b5e7a29c-d3c2-44ea-85fb-acc1df282e2 - 1_FU540-C000-v1p3.pdf - - Setup: - The following sections outline the required - setup for a RISC-V HiFive platform. See - configs/example/riscv/fs_linux.py for example. - Driving CLINT: CLINT has an interrupt pin which increments mtime. It can be connected to any interrupt @@ -88,7 +79,7 @@ class HiFive(Platform): abstract RTC wrapper called RiscvRTC can be used. - Attaching PLIC devices: + Driving PLIC: PLIC handles external interrupts. Interrupt PioDevices should inherit from PlicIntDevice (PCI and DMA not yet implemented). It contains @@ -96,63 +87,30 @@ class HiFive(Platform): to call platform->postPciInt(id). All PLIC interrupt devices should be returned - by _off_chip_devices(). Calling attachPlic sets - up the PLIC interrupt source count. - - Uart: - The HiFive platform also has an uart_int_id. - This is because Uart8250 uses postConsoleInt - instead of postPciInt. In the future if a Uart - that inherits PlicIntDevice is implemented, - this can be removed. - - Disk: - See fs_linux.py for setup example. - - PMAChecker: - The PMAChecker will be attached to the MMU of - each CPU (which allows them to differ). See - fs_linux.py for setup example. + by _off_chip_devices(). """ - type = "HiFive" + type = "HiFiveBase" cxx_header = "dev/riscv/hifive.hh" - cxx_class = "gem5::HiFive" + cxx_class = "gem5::HiFiveBase" # CLINT - clint = Param.Clint(Clint(pio_addr=0x2000000), "CLINT") + clint = Param.Clint(NULL, "CLINT") # PLIC - plic = Param.Plic(Plic(pio_addr=0xC000000), "PLIC") + plic = Param.PlicBase(NULL, "PLIC") - # PCI - pci_host = GenericRiscvPciHost( - conf_base=0x30000000, - conf_size="256MB", - conf_device_bits=12, - pci_pio_base=0x2F000000, - pci_mem_base=0x40000000, - ) - - # Uart - uart = RiscvUart8250(pio_addr=0x10000000) # Int source ID to redirect console interrupts to # Set to 0 if using a pci interrupt for Uart instead - uart_int_id = Param.Int(0xA, "PLIC Uart interrupt ID") - terminal = Terminal() + uart_int_id = Param.Int(0, "PLIC Uart interrupt ID") def _on_chip_devices(self): """Returns a list of on-chip peripherals""" - return [self.clint, self.plic] + return [] def _off_chip_devices(self): """Returns a list of off-chip peripherals""" - devices = [self.uart] - if hasattr(self, "disk"): - devices.append(self.disk) - if hasattr(self, "rng"): - devices.append(self.rng) - return devices + return [] def _on_chip_ranges(self): """Returns a list of on-chip peripherals @@ -172,17 +130,6 @@ class HiFive(Platform): for dev in self._off_chip_devices() ] - def attachPlic(self): - """Count number of PLIC interrupt sources""" - plic_srcs = [ - self.uart_int_id, - self.pci_host.int_base + self.pci_host.int_count, - ] - 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 - def attachOnChipIO(self, bus): """Attach on-chip IO devices, needs modification to support DMA @@ -197,6 +144,83 @@ class HiFive(Platform): for device in self._off_chip_devices(): device.pio = bus.mem_side_ports + +class HiFive(HiFiveBase): + """HiFive Platform + + Implementation: + Implementation details are based on SiFive + FU540-C000. https://sifive.cdn.prismic.io/ + sifive/b5e7a29c-d3c2-44ea-85fb-acc1df282e2 + 1_FU540-C000-v1p3.pdf + + Setup: + The following sections outline the required + setup for a RISC-V HiFive platform. See + configs/example/riscv/fs_linux.py for example. + + Uart: + The HiFive platform also has an uart_int_id. + This is because Uart8250 uses postConsoleInt + instead of postPciInt. In the future if a Uart + that inherits PlicIntDevice is implemented, + this can be removed. + + Disk: + See fs_linux.py for setup example. + + PMAChecker: + The PMAChecker will be attached to the MMU of + each CPU (which allows them to differ). See + fs_linux.py for setup example. + """ + + # CLINT + clint = Clint(pio_addr=0x2000000) + + # PLIC + plic = Plic(pio_addr=0xC000000) + + # PCI + pci_host = GenericRiscvPciHost( + conf_base=0x30000000, + conf_size="256MB", + conf_device_bits=12, + pci_pio_base=0x2F000000, + pci_mem_base=0x40000000, + ) + + # Uart + uart = RiscvUart8250(pio_addr=0x10000000) + # Int source ID to redirect console interrupts to + # Set to 0 if using a pci interrupt for Uart instead + uart_int_id = 0xA + terminal = Terminal() + + def _on_chip_devices(self): + """Returns a list of on-chip peripherals""" + return [self.clint, self.plic] + + def _off_chip_devices(self): + """Returns a list of off-chip peripherals""" + devices = [self.uart] + if hasattr(self, "disk"): + devices.append(self.disk) + if hasattr(self, "rng"): + devices.append(self.rng) + return devices + + def attachPlic(self): + """Count and set number of PLIC interrupt sources""" + plic_srcs = [ + self.uart_int_id, + self.pci_host.int_base + self.pci_host.int_count, + ] + 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 + def setNumCores(self, num_cpu): """Sets the PLIC and CLINT to have the right number of threads and contexts. Assumes that the cores have a single hardware thread. diff --git a/src/dev/riscv/SConscript b/src/dev/riscv/SConscript index 6e3376bb02..be5ff8defe 100755 --- a/src/dev/riscv/SConscript +++ b/src/dev/riscv/SConscript @@ -30,7 +30,7 @@ Import('*') -SimObject('HiFive.py', sim_objects=['HiFive', 'GenericRiscvPciHost'], +SimObject('HiFive.py', sim_objects=['HiFiveBase', 'GenericRiscvPciHost'], tags='riscv isa') SimObject('LupV.py', sim_objects=['LupV'], tags='riscv isa') SimObject('Clint.py', sim_objects=['Clint'], tags='riscv isa') diff --git a/src/dev/riscv/hifive.cc b/src/dev/riscv/hifive.cc index 74ae346f1f..0487eabba2 100644 --- a/src/dev/riscv/hifive.cc +++ b/src/dev/riscv/hifive.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Huawei International + * Copyright (c) 2023 Google LLC * All rights reserved * * The license below extends only to copyright in the software and shall @@ -39,7 +40,7 @@ #include "dev/riscv/clint.hh" #include "dev/riscv/plic.hh" -#include "params/HiFive.hh" +#include "params/HiFiveBase.hh" #include "sim/system.hh" namespace gem5 @@ -47,44 +48,46 @@ namespace gem5 using namespace RiscvISA; -HiFive::HiFive(const Params ¶ms) : +HiFiveBase::HiFiveBase(const Params ¶ms) : Platform(params), clint(params.clint), plic(params.plic), uartIntID(params.uart_int_id) { + fatal_if(clint == nullptr, "CLINT should not be NULL"); + fatal_if(plic == nullptr, "PLIC should not be NULL"); } void -HiFive::postConsoleInt() +HiFiveBase::postConsoleInt() { plic->post(uartIntID); } void -HiFive::clearConsoleInt() +HiFiveBase::clearConsoleInt() { plic->clear(uartIntID); } void -HiFive::postPciInt(int line) +HiFiveBase::postPciInt(int line) { plic->post(line); } void -HiFive::clearPciInt(int line) +HiFiveBase::clearPciInt(int line) { plic->clear(line); } void -HiFive::serialize(CheckpointOut &cp) const +HiFiveBase::serialize(CheckpointOut &cp) const { } void -HiFive::unserialize(CheckpointIn &cp) +HiFiveBase::unserialize(CheckpointIn &cp) { } diff --git a/src/dev/riscv/hifive.hh b/src/dev/riscv/hifive.hh index 78d45046b1..99d7ae67b3 100644 --- a/src/dev/riscv/hifive.hh +++ b/src/dev/riscv/hifive.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Huawei International + * Copyright (c) 2023 Google LLC * All rights reserved * * The license below extends only to copyright in the software and shall @@ -41,23 +42,23 @@ #include "dev/platform.hh" #include "dev/riscv/clint.hh" #include "dev/riscv/plic.hh" -#include "params/HiFive.hh" +#include "params/HiFiveBase.hh" namespace gem5 { using namespace RiscvISA; -class HiFive : public Platform +class HiFiveBase : public Platform { public: Clint *clint; - Plic *plic; + PlicBase *plic; int uartIntID; public: - typedef HiFiveParams Params; - HiFive(const Params ¶ms); + typedef HiFiveBaseParams Params; + HiFiveBase(const Params ¶ms); void postConsoleInt() override;