From 403817cd0dbcf36031ebd64882c345406560fb2e Mon Sep 17 00:00:00 2001 From: Jason Lowe-Power Date: Thu, 12 Aug 2021 14:49:20 -0700 Subject: [PATCH] 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49431 Maintainer: Bobby R. Bruce Reviewed-by: Ayaz Akram Tested-by: kokoro --- configs/example/riscv/fs_linux.py | 1 + src/dev/riscv/Clint.py | 1 + src/dev/riscv/HiFive.py | 16 +++++++++++----- src/dev/riscv/Plic.py | 2 ++ src/dev/riscv/clint.cc | 2 +- src/dev/riscv/plic.cc | 3 +-- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/configs/example/riscv/fs_linux.py b/configs/example/riscv/fs_linux.py index 55097ba442..982dfa4942 100644 --- a/configs/example/riscv/fs_linux.py +++ b/configs/example/riscv/fs_linux.py @@ -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 --------------------------- # diff --git a/src/dev/riscv/Clint.py b/src/dev/riscv/Clint.py index 75c89aaf8f..70ec0ed4cf 100644 --- a/src/dev/riscv/Clint.py +++ b/src/dev/riscv/Clint.py @@ -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, diff --git a/src/dev/riscv/HiFive.py b/src/dev/riscv/HiFive.py index 8af2ddd7eb..d945590561 100755 --- a/src/dev/riscv/HiFive.py +++ b/src/dev/riscv/HiFive.py @@ -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) diff --git a/src/dev/riscv/Plic.py b/src/dev/riscv/Plic.py index 24ed5a5a44..be0b629a76 100644 --- a/src/dev/riscv/Plic.py +++ b/src/dev/riscv/Plic.py @@ -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, diff --git a/src/dev/riscv/clint.cc b/src/dev/riscv/clint.cc index 0356af0398..b27b9bf61d 100644 --- a/src/dev/riscv/clint.cc +++ b/src/dev/riscv/clint.cc @@ -52,6 +52,7 @@ using namespace RiscvISA; Clint::Clint(const Params ¶ms) : 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(); } diff --git a/src/dev/riscv/plic.cc b/src/dev/riscv/plic.cc index 4dea47566a..b8f765a17c 100644 --- a/src/dev/riscv/plic.cc +++ b/src/dev/riscv/plic.cc @@ -56,6 +56,7 @@ Plic::Plic(const Params ¶ms) : 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);