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,
+};


Reply via email to