arch-riscv,dev: Explicitly set num CPUs on platform

Previously, the RISC-V devices queried the system object in
SimObject::init() for the number of CPUs and the number of threads.
However, the system object doesn't actually count the number of
CPUs/threads until it runs init(). Therefore, we've just been getting
lucky in the order that the SimObject init() functions were called.

This change instead decouples these two functions and makes the number
of CPUs/threads a parameter for the RISC-V interrupt devices. This
change also updates the example config script.

Change-Id: Ic4da5604156837cfeec05e58d188b42a02420de1
Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49431
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Reviewed-by: Ayaz Akram <yazakram@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Jason Lowe-Power
2021-08-12 14:49:20 -07:00
committed by Jason Lowe-Power
parent 182f79c3da
commit 403817cd0d
6 changed files with 17 additions and 8 deletions

View File

@@ -185,6 +185,7 @@ system.bridge.ranges = system.platform._off_chip_ranges()
system.platform.attachOnChipIO(system.membus)
system.platform.attachOffChipIO(system.iobus)
system.platform.attachPlic()
system.platform.setNumCores(np)
# ---------------------------- Default Setup --------------------------- #

View File

@@ -52,6 +52,7 @@ class Clint(BasicPioDevice):
cxx_class = 'gem5::Clint'
int_pin = IntSinkPin('Pin to receive RTC signal')
pio_size = Param.Addr(0xC000, "PIO Size")
num_threads = Param.Int("Number of threads in the system.")
def generateDeviceTree(self, state):
node = self.generateBasicPioDeviceNode(state, "clint", self.pio_addr,

View File

@@ -112,9 +112,6 @@ class HiFive(Platform):
uart_int_id = Param.Int(0xa, "PLIC Uart interrupt ID")
terminal = Terminal()
# Dummy param for generating devicetree
cpu_count = Param.Int(0, "dummy")
def _on_chip_devices(self):
"""Returns a list of on-chip peripherals
"""
@@ -172,6 +169,13 @@ class HiFive(Platform):
for device in self._off_chip_devices():
device.pio = bus.mem_side_ports
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.
"""
self.plic.n_contexts = num_cpu * 2
self.clint.num_threads = num_cpu
def generateDeviceTree(self, state):
cpus_node = FdtNode("cpus")
cpus_node.append(FdtPropertyWords("timebase-frequency", [10000000]))
@@ -189,6 +193,8 @@ class HiFive(Platform):
yield node
# For generating devicetree
_cpu_count = 0
def annotateCpuDeviceNode(self, cpu, state):
cpu.append(FdtPropertyStrings('mmu-type', 'riscv,sv48'))
cpu.append(FdtPropertyStrings('status', 'okay'))
@@ -202,8 +208,8 @@ class HiFive(Platform):
int_node.appendCompatible("riscv,cpu-intc")
cpus = self.system.unproxy(self).cpu
phandle = int_state.phandle(cpus[self.cpu_count])
self.cpu_count += 1
phandle = int_state.phandle(cpus[self._cpu_count])
self._cpu_count += 1
int_node.append(FdtPropertyWords("phandle", [phandle]))
cpu.append(int_node)

View File

@@ -51,6 +51,8 @@ class Plic(BasicPioDevice):
cxx_class = 'gem5::Plic'
pio_size = Param.Addr(0x4000000, "PIO Size")
n_src = Param.Int("Number of interrupt sources")
n_contexts = Param.Int("Number of interrupt contexts. Usually the number "
"of threads * 2. One for M mode, one for S mode")
def generateDeviceTree(self, state):
node = self.generateBasicPioDeviceNode(state, "plic", self.pio_addr,

View File

@@ -52,6 +52,7 @@ using namespace RiscvISA;
Clint::Clint(const Params &params) :
BasicPioDevice(params, params.pio_size),
system(params.system),
nThread(params.num_threads),
signal(params.name + ".signal", 0, this),
registers(params.name + ".registers", params.pio_addr, this)
{
@@ -194,7 +195,6 @@ Clint::write(PacketPtr pkt)
void
Clint::init()
{
nThread = system->threads.size();
registers.init();
BasicPioDevice::init();
}

View File

@@ -56,6 +56,7 @@ Plic::Plic(const Params &params) :
BasicPioDevice(params, params.pio_size),
system(params.system),
nSrc(params.n_src),
nContext(params.n_contexts),
registers(params.name, pioAddr, this),
update([this]{updateOutput();}, name() + ".update")
{
@@ -163,8 +164,6 @@ Plic::write(PacketPtr pkt)
void
Plic::init()
{
// Number of contexts
nContext = system->threads.size() * 2;
// Number of 32-bit pending registesrs where
// each bit correspondings to one interrupt source
nSrc32 = divCeil(nSrc, 32);