On 2025/12/21 下午8:25, Yao Zi wrote:
Reading/writing unimplemented IOCSR on real LoongArch hardware doesn't
trigger any exceptions, instead, reading always results in zero and
writing is simply ignored.
From my memories, I have communicated with HW guys about IOCSR. They said that IOCSR is different with CPUCFG, the undocumented IOCSR registers may be used by UEFI BIOS or other firmwares. So we cannot suppose reading always results in zero and writing is simply ignored.

However g_assert_not_reached() is actually too serious here, QEMU should not crash anyway.

Real-world applications, like memtest86plus, depend on the behavior to
run. However, since commit f2e61edb2946 ("hw/loongarch/virt: Use
MemTxAttrs interface for misc ops") which adds a call to
g_assert_not_reached() in the path of handling unimplemented IOCSRs,
QEMU would abort in the case.

Replace the assertion with qemu_log_mask(LOG_UNIMP, ...), so these
applications could run. It's still possible to examine unimplemented
IOCSR access through "-d unimp" command line arguments.

Fixes: f2e61edb2946 ("hw/loongarch/virt: Use MemTxAttrs interface for misc ops")
Signed-off-by: Yao Zi <[email protected]>
---
  hw/loongarch/virt.c | 9 +++++++--
  1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 49434ad1828b..8d7da5fac550 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -46,6 +46,7 @@
  #include "hw/block/flash.h"
  #include "hw/virtio/virtio-iommu.h"
  #include "qemu/error-report.h"
+#include "qemu/log.h"
  #include "kvm/kvm_loongarch.h"
static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
@@ -622,7 +623,9 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, 
hwaddr addr,
                            features, attrs, NULL);
          break;
      default:
-        g_assert_not_reached();
+        qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx 
"\n",
+                      __func__, addr);
+        break;
      }
IOCSR address VERSION_REG/VENDOR_REG/CPUNAME_REG is read-only rather than unimplemented, the others are unimplemented.

The others look good to me.

Regards
Bibo Mao
return MEMTX_OK;
@@ -680,7 +683,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, 
hwaddr addr,
          }
          break;
      default:
-        g_assert_not_reached();
+        qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx 
"\n",
+                      __func__, addr);
+        break;
Replacing g_assert_not_reached() with with qemu_log_mask() is ok for me.
      }
*data = ret;



Reply via email to