On 8/2/25 18:17, Mohamed Mediouni wrote:
+struct whpx_sreg_match {
+ WHV_REGISTER_NAME reg;
+ uint32_t key;
+ bool global;
+ uint32_t cp_idx;
+};
+
+static struct whpx_sreg_match whpx_sreg_match[] = {
const.
+#ifdef SYNC_NO_RAW_REGS
+ /*
+ * The registers below are manually synced on init because they are
+ * marked as NO_RAW. We still list them to make number space sync easier.
+ */
+ { WHvArm64RegisterMidrEl1, WHPX_SYSREG(0, 0, 3, 0, 0) },
+ { WHvArm64RegisterMpidrEl1, WHPX_SYSREG(0, 0, 3, 0, 5) },
+ { WHvArm64RegisterIdPfr0El1, WHPX_SYSREG(0, 4, 3, 0, 0) },
+#endif
+ { WHvArm64RegisterIdAa64Pfr1El1, WHPX_SYSREG(0, 4, 3, 0, 1), true },
+ { WHvArm64RegisterIdAa64Dfr0El1, WHPX_SYSREG(0, 5, 3, 0, 0), true },
+ { WHvArm64RegisterIdAa64Dfr1El1, WHPX_SYSREG(0, 5, 3, 0, 1), true },
+ { WHvArm64RegisterIdAa64Isar0El1, WHPX_SYSREG(0, 6, 3, 0, 0), true },
+ { WHvArm64RegisterIdAa64Isar1El1, WHPX_SYSREG(0, 6, 3, 0, 1), true },
+#ifdef SYNC_NO_MMFR0
+ /* We keep the hardware MMFR0 around. HW limits are there anyway */
+ { WHvArm64RegisterIdAa64Mmfr0El1, WHPX_SYSREG(0, 7, 3, 0, 0) },
+#endif
+ { WHvArm64RegisterIdAa64Mmfr1El1, WHPX_SYSREG(0, 7, 3, 0, 1), true },
+ { WHvArm64RegisterIdAa64Mmfr2El1, WHPX_SYSREG(0, 7, 3, 0, 2), true },
+ { WHvArm64RegisterIdAa64Mmfr3El1, WHPX_SYSREG(0, 7, 3, 0, 3), true },
All of these are id registers. I can understand reading them once at startup, to populate
-cpu host, but they need not be synced otherwise.
+static uint64_t whpx_get_gp_reg(CPUState *cpu, int rt)
+{
+ if (rt >= 31) {
+ return 0;
+ }
assert? Or return 0 for 31 and assert <= 32?
+ WHV_REGISTER_NAME reg = WHvArm64RegisterX0 + rt;
+ WHV_REGISTER_VALUE val;
+ whpx_get_reg(cpu, reg, &val);
+
+ return val.Reg64;
+}
+
+static void whpx_set_gp_reg(CPUState *cpu, int rt, uint64_t val)
+{
+ if (rt >= 31) {
+ abort();
+ }
assert. Or ignore write to 31 and assert <= 32?
+ if (cm) {
+ /* We don't cache MMIO regions */
+ abort();
+ return 0;
+ }
assert.
r~