Hi Jiaxun,
On 12/5/24 14:20, Jiaxun Yang wrote:
Node counter is a timer presents on Loongson-3 chips, which runs
as fast as CPU clock. It's being mapped into a MMIO location.
Emulate this for loongson3_virt machine, in hope that kernel can
use it as a better clock source.
Hardware's behavior on 32-bit read/write is also emulated in case
legacy kernel is trying to use it with hi/lo splitted read.
Signed-off-by: Jiaxun Yang <[email protected]>
---
hw/mips/loongson3_bootp.h | 1 +
hw/mips/loongson3_virt.c | 38 ++++++++++++++++++++++++++++++++++----
2 files changed, 35 insertions(+), 4 deletions(-)
+static uint64_t loongson3_nodecnt_read(void *opaque,
+ hwaddr addr, unsigned size)
+{
+ LoongsonMachineState *s = opaque;
+ int64_t now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ uint64_t ticks = clock_ns_to_ticks(s->cpuclk, now_ns);
+
+ if (addr == 0x4) {
+ return ticks >> 32;
Does that imply .endianness = DEVICE_BIG_ENDIAN?
It could be simpler to let the core MMIO code do the hi/lo
bits management using ".impl.min_access_size = 8".
+ }
+
+ return ticks;
+}
+
+static const MemoryRegionOps loongson3_nodecnt_ops = {
+ .read = loongson3_nodecnt_read,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 8,
+};