Re: [PATCH] target/i386: Expand eflags updates inline

2022-10-30 Thread Richard Henderson

On 10/27/22 21:26, Richard Henderson wrote:

The helpers for reset_rf, cli, sti, clac, stac are
completely trivial; implement them inline.

Drop some nearby #if 0 code.

Signed-off-by: Richard Henderson 
---
  target/i386/helper.h|  5 -
  target/i386/tcg/cc_helper.c | 41 -
  target/i386/tcg/translate.c | 30 ++-
  3 files changed, 25 insertions(+), 51 deletions(-)


Queuing to tcg-next, for convenience.


r~



Re: [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269)

2022-10-30 Thread Richard Henderson

On 10/27/22 21:02, Richard Henderson wrote:

As per #1269, this affects NetBSD installer boot.

The problem is that one of the x86 acpi callbacks modifies
env->eip during an mmio store, which means that the tracking
that translate.c does is thrown out of whack.

Introduce a method to extract unwind data without the
writeback to env.  This isn't a perfect abstraction, but I
couldn't think of anything better.  There's a couple of lines
of code duplication, but probably less than any abstration
that we might put on top

Changes for v2:
   * Rebase on master, 23 patches merged.
   * Comments adjusted per review (claudio)


r~


Queuing to tcg-next.


r~



Re: [PULL 25/47] accel/tcg: Add restore_state_to_opc to TCGCPUOps

2022-10-30 Thread Richard Henderson

On 10/29/22 21:42, Alex Bennée wrote:


Richard Henderson  writes:


Add a tcg_ops hook to replace the restore_state_to_opc
function call.  Because these generic hooks cannot depend
on target-specific types, temporarily, copy the current
target_ulong data[] into uint64_t d64[].

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 


This has triggered a regression in x86_64 stuff:


Patches posted: 20221027100254.215253-1-richard.hender...@linaro.org
("[PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269)")


r~



[PULL 10/11] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb

2022-10-30 Thread Richard Henderson
The value passed is always true.

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 accel/tcg/internal.h  |  2 +-
 accel/tcg/tb-maint.c  |  4 ++--
 accel/tcg/translate-all.c | 15 +++
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index 9c06b320b7..cb13bade4f 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -107,7 +107,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb, 
tb_page_addr_t phys_pc,
tb_page_addr_t phys_page2);
 bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
 void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-   uintptr_t host_pc, bool reset_icount);
+   uintptr_t host_pc);
 
 /* Return the current PC from CPU, which may be cached in TB. */
 static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index c8e921089d..0cdb35548c 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -536,7 +536,7 @@ tb_invalidate_phys_page_range__locked(struct 
page_collection *pages,
  * restore the CPU state.
  */
 current_tb_modified = true;
-cpu_restore_state_from_tb(cpu, current_tb, retaddr, true);
+cpu_restore_state_from_tb(cpu, current_tb, retaddr);
 }
 #endif /* TARGET_HAS_PRECISE_SMC */
 tb_phys_invalidate__locked(tb);
@@ -685,7 +685,7 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, 
uintptr_t pc)
  * function to partially restore the CPU state.
  */
 current_tb_modified = true;
-cpu_restore_state_from_tb(cpu, current_tb, pc, true);
+cpu_restore_state_from_tb(cpu, current_tb, pc);
 }
 #endif /* TARGET_HAS_PRECISE_SMC */
 tb_phys_invalidate(tb, addr);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 90997fed47..0089578f8f 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -282,12 +282,11 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, 
uintptr_t host_pc,
 }
 
 /*
- * The cpu state corresponding to 'host_pc' is restored.
- * When reset_icount is true, current TB will be interrupted and
- * icount should be recalculated.
+ * The cpu state corresponding to 'host_pc' is restored in
+ * preparation for exiting the TB.
  */
 void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-   uintptr_t host_pc, bool reset_icount)
+   uintptr_t host_pc)
 {
 uint64_t data[TARGET_INSN_START_WORDS];
 #ifdef CONFIG_PROFILER
@@ -300,7 +299,7 @@ void cpu_restore_state_from_tb(CPUState *cpu, 
TranslationBlock *tb,
 return;
 }
 
-if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
+if (tb_cflags(tb) & CF_USE_ICOUNT) {
 assert(icount_enabled());
 /*
  * Reset the cycle counter to the start of the block and
@@ -333,7 +332,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
 if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
 TranslationBlock *tb = tcg_tb_lookup(host_pc);
 if (tb) {
-cpu_restore_state_from_tb(cpu, tb, host_pc, true);
+cpu_restore_state_from_tb(cpu, tb, host_pc);
 return true;
 }
 }
@@ -1032,7 +1031,7 @@ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr)
 tb = tcg_tb_lookup(retaddr);
 if (tb) {
 /* We can use retranslation to find the PC.  */
-cpu_restore_state_from_tb(cpu, tb, retaddr, true);
+cpu_restore_state_from_tb(cpu, tb, retaddr);
 tb_phys_invalidate(tb, -1);
 } else {
 /* The exception probably happened in a helper.  The CPU state should
@@ -1068,7 +1067,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
 cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
   (void *)retaddr);
 }
-cpu_restore_state_from_tb(cpu, tb, retaddr, true);
+cpu_restore_state_from_tb(cpu, tb, retaddr);
 
 /*
  * Some guests must re-execute the branch when re-executing a delay
-- 
2.34.1




[PULL 01/11] tcg/sparc: Remove support for sparc32plus

2022-10-30 Thread Richard Henderson
Since 9b9c37c36439, we have only supported sparc64 cpus.
Debian and Gentoo now only support 64-bit sparc64 userland,
so it is time to drop the 32-bit sparc64 userland: sparc32plus.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/sparc/tcg-target.h |  11 ---
 tcg/tcg.c  |  75 +
 tcg/sparc/tcg-target.c.inc | 166 +++--
 3 files changed, 33 insertions(+), 219 deletions(-)

diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index c050763049..8655acdbe5 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -25,8 +25,6 @@
 #ifndef SPARC_TCG_TARGET_H
 #define SPARC_TCG_TARGET_H
 
-#define TCG_TARGET_REG_BITS 64
-
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
 #define TCG_TARGET_NB_REGS 32
@@ -70,19 +68,10 @@ typedef enum {
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_O6
 
-#ifdef __arch64__
 #define TCG_TARGET_STACK_BIAS   2047
 #define TCG_TARGET_STACK_ALIGN  16
 #define TCG_TARGET_CALL_STACK_OFFSET(128 + 6*8 + TCG_TARGET_STACK_BIAS)
-#else
-#define TCG_TARGET_STACK_BIAS   0
-#define TCG_TARGET_STACK_ALIGN  8
-#define TCG_TARGET_CALL_STACK_OFFSET(64 + 4 + 6*4)
-#endif
-
-#ifdef __arch64__
 #define TCG_TARGET_EXTEND_ARGS 1
-#endif
 
 #if defined(__VIS__) && __VIS__ >= 0x300
 #define use_vis3_instructions  1
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 612a12f58f..c9e664ee31 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1487,39 +1487,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 }
 #endif
 
-#if defined(__sparc__) && !defined(__arch64__) \
-&& !defined(CONFIG_TCG_INTERPRETER)
-/* We have 64-bit values in one register, but need to pass as two
-   separate parameters.  Split them.  */
-int orig_typemask = typemask;
-int orig_nargs = nargs;
-TCGv_i64 retl, reth;
-TCGTemp *split_args[MAX_OPC_PARAM];
-
-retl = NULL;
-reth = NULL;
-typemask = 0;
-for (i = real_args = 0; i < nargs; ++i) {
-int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
-bool is_64bit = (argtype & ~1) == dh_typecode_i64;
-
-if (is_64bit) {
-TCGv_i64 orig = temp_tcgv_i64(args[i]);
-TCGv_i32 h = tcg_temp_new_i32();
-TCGv_i32 l = tcg_temp_new_i32();
-tcg_gen_extr_i64_i32(l, h, orig);
-split_args[real_args++] = tcgv_i32_temp(h);
-typemask |= dh_typecode_i32 << (real_args * 3);
-split_args[real_args++] = tcgv_i32_temp(l);
-typemask |= dh_typecode_i32 << (real_args * 3);
-} else {
-split_args[real_args++] = args[i];
-typemask |= argtype << (real_args * 3);
-}
-}
-nargs = real_args;
-args = split_args;
-#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
 for (i = 0; i < nargs; ++i) {
 int argtype = extract32(typemask, (i + 1) * 3, 3);
 bool is_32bit = (argtype & ~1) == dh_typecode_i32;
@@ -1542,22 +1510,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 
 pi = 0;
 if (ret != NULL) {
-#if defined(__sparc__) && !defined(__arch64__) \
-&& !defined(CONFIG_TCG_INTERPRETER)
-if ((typemask & 6) == dh_typecode_i64) {
-/* The 32-bit ABI is going to return the 64-bit value in
-   the %o0/%o1 register pair.  Prepare for this by using
-   two return temporaries, and reassemble below.  */
-retl = tcg_temp_new_i64();
-reth = tcg_temp_new_i64();
-op->args[pi++] = tcgv_i64_arg(reth);
-op->args[pi++] = tcgv_i64_arg(retl);
-nb_rets = 2;
-} else {
-op->args[pi++] = temp_arg(ret);
-nb_rets = 1;
-}
-#else
 if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) {
 #if HOST_BIG_ENDIAN
 op->args[pi++] = temp_arg(ret + 1);
@@ -1571,7 +1523,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 op->args[pi++] = temp_arg(ret);
 nb_rets = 1;
 }
-#endif
 } else {
 nb_rets = 0;
 }
@@ -1634,29 +1585,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 tcg_debug_assert(TCGOP_CALLI(op) == real_args);
 tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
 
-#if defined(__sparc__) && !defined(__arch64__) \
-&& !defined(CONFIG_TCG_INTERPRETER)
-/* Free all of the parts we allocated above.  */
-for (i = real_args = 0; i < orig_nargs; ++i) {
-int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
-bool is_64bit = (argtype & ~1) == dh_typecode_i64;
-
-if (is_64bit) {
-tcg_temp_free_internal(args[real_args++]);
-

[PATCH] target/arm: Copy the entire vector in DO_ZIP

2022-10-30 Thread Richard Henderson
With odd_ofs set, we weren't copying enough data.

Fixes: 09eb6d7025d1 ("target/arm: Move sve zip high_ofs into simd_data")
Reported-by: Idan Horowitz 
Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 3d0d2987cd..1afeadf9c8 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -3366,10 +3366,10 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, 
uint32_t desc)   \
 /* We produce output faster than we consume input.   \
Therefore we must be mindful of possible overlap.  */ \
 if (unlikely((vn - vd) < (uintptr_t)oprsz)) {\
-vn = memcpy(_n, vn, oprsz_2);\
+vn = memcpy(_n, vn, oprsz);  \
 }\
 if (unlikely((vm - vd) < (uintptr_t)oprsz)) {\
-vm = memcpy(_m, vm, oprsz_2);\
+vm = memcpy(_m, vm, oprsz);  \
 }\
 for (i = 0; i < oprsz_2; i += sizeof(TYPE)) {\
 *(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + odd_ofs + H(i)); \
-- 
2.34.1




[PULL 03/11] tcg/sparc64: Remove sparc32plus constraints

2022-10-30 Thread Richard Henderson
With sparc64 we need not distinguish between registers that
can hold 32-bit values and those that can hold 64-bit values.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tcg/sparc64/tcg-target-con-set.h |  16 +
 tcg/sparc64/tcg-target-con-str.h |   3 -
 tcg/sparc64/tcg-target.c.inc | 109 ---
 3 files changed, 44 insertions(+), 84 deletions(-)

diff --git a/tcg/sparc64/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
index 3b751dc3fb..31e6fea1fc 100644
--- a/tcg/sparc64/tcg-target-con-set.h
+++ b/tcg/sparc64/tcg-target-con-set.h
@@ -11,22 +11,12 @@
  */
 C_O0_I1(r)
 C_O0_I2(rZ, r)
-C_O0_I2(RZ, r)
 C_O0_I2(rZ, rJ)
-C_O0_I2(RZ, RJ)
-C_O0_I2(sZ, A)
-C_O0_I2(SZ, A)
-C_O1_I1(r, A)
-C_O1_I1(R, A)
+C_O0_I2(sZ, s)
+C_O1_I1(r, s)
 C_O1_I1(r, r)
-C_O1_I1(r, R)
-C_O1_I1(R, r)
-C_O1_I1(R, R)
-C_O1_I2(R, R, R)
+C_O1_I2(r, r, r)
 C_O1_I2(r, rZ, rJ)
-C_O1_I2(R, RZ, RJ)
 C_O1_I4(r, rZ, rJ, rI, 0)
-C_O1_I4(R, RZ, RJ, RI, 0)
 C_O2_I2(r, r, rZ, rJ)
-C_O2_I4(R, R, RZ, RZ, RJ, RI)
 C_O2_I4(r, r, rZ, rZ, rJ, rJ)
diff --git a/tcg/sparc64/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
index fdb25d9313..8f5c7aef97 100644
--- a/tcg/sparc64/tcg-target-con-str.h
+++ b/tcg/sparc64/tcg-target-con-str.h
@@ -9,10 +9,7 @@
  * REGS(letter, register_mask)
  */
 REGS('r', ALL_GENERAL_REGS)
-REGS('R', ALL_GENERAL_REGS64)
 REGS('s', ALL_QLDST_REGS)
-REGS('S', ALL_QLDST_REGS64)
-REGS('A', TARGET_LONG_BITS == 64 ? ALL_QLDST_REGS64 : ALL_QLDST_REGS)
 
 /*
  * Define constraint letters for constants:
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index 097bcfcd12..cb9453efdd 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -80,19 +80,8 @@ static const char * const 
tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 #else
 #define SOFTMMU_RESERVE_REGS 0
 #endif
-
-/*
- * Note that sparcv8plus can only hold 64 bit quantities in %g and %o
- * registers.  These are saved manually by the kernel in full 64-bit
- * slots.  The %i and %l registers are saved by the register window
- * mechanism, which only allocates space for 32 bits.  Given that this
- * window spill/fill can happen on any signal, we must consider the
- * high bits of the %i and %l registers garbage at all times.
- */
 #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
-# define ALL_GENERAL_REGS64  ALL_GENERAL_REGS
 #define ALL_QLDST_REGS   (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
-#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS)
 
 /* Define some temporary registers.  T2 is used for constant generation.  */
 #define TCG_REG_T1  TCG_REG_G1
@@ -1738,107 +1727,91 @@ static TCGConstraintSetIndex 
tcg_target_op_def(TCGOpcode op)
 return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
+case INDEX_op_ld8u_i64:
 case INDEX_op_ld8s_i32:
+case INDEX_op_ld8s_i64:
 case INDEX_op_ld16u_i32:
+case INDEX_op_ld16u_i64:
 case INDEX_op_ld16s_i32:
+case INDEX_op_ld16s_i64:
 case INDEX_op_ld_i32:
+case INDEX_op_ld32u_i64:
+case INDEX_op_ld32s_i64:
+case INDEX_op_ld_i64:
 case INDEX_op_neg_i32:
+case INDEX_op_neg_i64:
 case INDEX_op_not_i32:
+case INDEX_op_not_i64:
+case INDEX_op_ext32s_i64:
+case INDEX_op_ext32u_i64:
+case INDEX_op_ext_i32_i64:
+case INDEX_op_extu_i32_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_extrh_i64_i32:
 return C_O1_I1(r, r);
 
 case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
 case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
 case INDEX_op_st_i32:
+case INDEX_op_st32_i64:
+case INDEX_op_st_i64:
 return C_O0_I2(rZ, r);
 
 case INDEX_op_add_i32:
+case INDEX_op_add_i64:
 case INDEX_op_mul_i32:
+case INDEX_op_mul_i64:
 case INDEX_op_div_i32:
+case INDEX_op_div_i64:
 case INDEX_op_divu_i32:
+case INDEX_op_divu_i64:
 case INDEX_op_sub_i32:
+case INDEX_op_sub_i64:
 case INDEX_op_and_i32:
+case INDEX_op_and_i64:
 case INDEX_op_andc_i32:
+case INDEX_op_andc_i64:
 case INDEX_op_or_i32:
+case INDEX_op_or_i64:
 case INDEX_op_orc_i32:
+case INDEX_op_orc_i64:
 case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
 case INDEX_op_shl_i32:
+case INDEX_op_shl_i64:
 case INDEX_op_shr_i32:
+case INDEX_op_shr_i64:
 case INDEX_op_sar_i32:
+case INDEX_op_sar_i64:
 case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
 return C_O1_I2(r, rZ, rJ);
 
 case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
 return C_O0_I2(rZ, rJ);
 case INDEX_op_movcond_i32:
+case INDEX_op_movcond_i64:
 return C_O1_I4(r, rZ, rJ, rI, 0);
 case INDEX_op_add2_i32:
+case INDEX_op_add2_i64:
 case INDEX_op_sub2_i32:
+case INDEX_op_sub2_i64:
 return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
 case INDEX_op_mulu2_i32:
 case INDEX_op_muls2_i32:
 return C_O2_I2(r, r, rZ, rJ);
-
-

[PULL 05/11] accel/tcg: Introduce cpu_unwind_state_data

2022-10-30 Thread Richard Henderson
Add a way to examine the unwind data without actually
restoring the data back into env.

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 accel/tcg/internal.h  |  4 +--
 include/exec/exec-all.h   | 21 ---
 accel/tcg/translate-all.c | 74 ++-
 3 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index 1227bb69bd..9c06b320b7 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n);
 TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
tb_page_addr_t phys_page2);
 bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-  uintptr_t searched_pc, bool reset_icount);
+void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
+   uintptr_t host_pc, bool reset_icount);
 
 /* Return the current PC from CPU, which may be cached in TB. */
 static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e948992a80..7d851f5907 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t;
 #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
 #endif
 
+/**
+ * cpu_unwind_state_data:
+ * @cpu: the cpu context
+ * @host_pc: the host pc within the translation
+ * @data: output data
+ *
+ * Attempt to load the the unwind state for a host pc occurring in
+ * translated code.  If @host_pc is not in translated code, the
+ * function returns false; otherwise @data is loaded.
+ * This is the same unwind info as given to restore_state_to_opc.
+ */
+bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
+
 /**
  * cpu_restore_state:
- * @cpu: the vCPU state is to be restore to
- * @searched_pc: the host PC the fault occurred at
+ * @cpu: the cpu context
+ * @host_pc: the host pc within the translation
  * @will_exit: true if the TB executed will be interrupted after some
cpu adjustments. Required for maintaining the correct
icount valus
  * @return: true if state was restored, false otherwise
  *
  * Attempt to restore the state for a fault occurring in translated
- * code. If the searched_pc is not in translated code no state is
+ * code. If @host_pc is not in translated code no state is
  * restored and the function returns false.
  */
-bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit);
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit);
 
 G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
 G_NORETURN void cpu_loop_exit(CPUState *cpu);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index f185356a36..319becb698 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t 
*block)
 return p - block;
 }
 
-/* The cpu state corresponding to 'searched_pc' is restored.
- * When reset_icount is true, current TB will be interrupted and
- * icount should be recalculated.
- */
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-  uintptr_t searched_pc, bool reset_icount)
+static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
+   uint64_t *data)
 {
-uint64_t data[TARGET_INSN_START_WORDS];
-uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
+uintptr_t iter_pc = (uintptr_t)tb->tc.ptr;
 const uint8_t *p = tb->tc.ptr + tb->tc.size;
 int i, j, num_insns = tb->icount;
-#ifdef CONFIG_PROFILER
-TCGProfile *prof = _ctx->prof;
-int64_t ti = profile_getclock();
-#endif
 
-searched_pc -= GETPC_ADJ;
+host_pc -= GETPC_ADJ;
 
-if (searched_pc < host_pc) {
+if (host_pc < iter_pc) {
 return -1;
 }
 
-memset(data, 0, sizeof(data));
+memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS);
 if (!TARGET_TB_PCREL) {
 data[0] = tb_pc(tb);
 }
 
-/* Reconstruct the stored insn data while looking for the point at
-   which the end of the insn exceeds the searched_pc.  */
+/*
+ * Reconstruct the stored insn data while looking for the point
+ * at which the end of the insn exceeds host_pc.
+ */
 for (i = 0; i < num_insns; ++i) {
 for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
 data[j] += decode_sleb128();
 }
-host_pc += decode_sleb128();
-if (host_pc > searched_pc) {
-goto found;
+iter_pc += decode_sleb128();
+if (iter_pc > host_pc) {
+return num_insns - i;
 }
 }
 return -1;
+}
+
+/*
+ * The cpu state corresponding to 'host_pc' is 

[PULL 09/11] accel/tcg: Remove will_exit argument from cpu_restore_state

2022-10-30 Thread Richard Henderson
The value passed is always true, and if the target's
synchronize_from_tb hook is non-trivial, not exiting
may be erroneous.

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h |  5 +
 accel/tcg/cpu-exec-common.c |  2 +-
 accel/tcg/translate-all.c   | 12 ++--
 target/alpha/helper.c   |  2 +-
 target/alpha/mem_helper.c   |  2 +-
 target/arm/op_helper.c  |  2 +-
 target/arm/tlb_helper.c |  8 
 target/cris/helper.c|  2 +-
 target/i386/tcg/sysemu/svm_helper.c |  2 +-
 target/m68k/op_helper.c |  4 ++--
 target/microblaze/helper.c  |  2 +-
 target/nios2/op_helper.c|  2 +-
 target/openrisc/sys_helper.c|  4 ++--
 target/ppc/excp_helper.c|  2 +-
 target/s390x/tcg/excp_helper.c  |  2 +-
 target/tricore/op_helper.c  |  2 +-
 target/xtensa/helper.c  |  6 +++---
 17 files changed, 25 insertions(+), 36 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 7d851f5907..9b7bfbf09a 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -56,16 +56,13 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t 
host_pc, uint64_t *data);
  * cpu_restore_state:
  * @cpu: the cpu context
  * @host_pc: the host pc within the translation
- * @will_exit: true if the TB executed will be interrupted after some
-   cpu adjustments. Required for maintaining the correct
-   icount valus
  * @return: true if state was restored, false otherwise
  *
  * Attempt to restore the state for a fault occurring in translated
  * code. If @host_pc is not in translated code no state is
  * restored and the function returns false.
  */
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit);
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc);
 
 G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
 G_NORETURN void cpu_loop_exit(CPUState *cpu);
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
index be6fe45aa5..c7bc8c6efa 100644
--- a/accel/tcg/cpu-exec-common.c
+++ b/accel/tcg/cpu-exec-common.c
@@ -71,7 +71,7 @@ void cpu_loop_exit(CPUState *cpu)
 void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
 {
 if (pc) {
-cpu_restore_state(cpu, pc, true);
+cpu_restore_state(cpu, pc);
 }
 cpu_loop_exit(cpu);
 }
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 319becb698..90997fed47 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -318,16 +318,8 @@ void cpu_restore_state_from_tb(CPUState *cpu, 
TranslationBlock *tb,
 #endif
 }
 
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
 {
-/*
- * The pc update associated with restore without exit will
- * break the relative pc adjustments performed by TARGET_TB_PCREL.
- */
-if (TARGET_TB_PCREL) {
-assert(will_exit);
-}
-
 /*
  * The host_pc has to be in the rx region of the code buffer.
  * If it is not we will not be able to resolve it here.
@@ -341,7 +333,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, 
bool will_exit)
 if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
 TranslationBlock *tb = tcg_tb_lookup(host_pc);
 if (tb) {
-cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
+cpu_restore_state_from_tb(cpu, tb, host_pc, true);
 return true;
 }
 }
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index a5a389b5a3..970c869771 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -532,7 +532,7 @@ G_NORETURN void dynamic_excp(CPUAlphaState *env, uintptr_t 
retaddr,
 cs->exception_index = excp;
 env->error_code = error;
 if (retaddr) {
-cpu_restore_state(cs, retaddr, true);
+cpu_restore_state(cs, retaddr);
 /* Floating-point exceptions (our only users) point to the next PC.  */
 env->pc += 4;
 }
diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c
index 47283a0612..a39b52c5dd 100644
--- a/target/alpha/mem_helper.c
+++ b/target/alpha/mem_helper.c
@@ -28,7 +28,7 @@ static void do_unaligned_access(CPUAlphaState *env, vaddr 
addr, uintptr_t retadd
 uint64_t pc;
 uint32_t insn;
 
-cpu_restore_state(env_cpu(env), retaddr, true);
+cpu_restore_state(env_cpu(env), retaddr);
 
 pc = env->pc;
 insn = cpu_ldl_code(env, pc);
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index c5bde1cfcc..70672bcd9f 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -78,7 +78,7 @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, 
uint32_t syndrome,
  * we must restore CPU state here before setting the syndrome
  * the caller passed us, and cannot use 

[PULL 06/11] target/i386: Use cpu_unwind_state_data for tpr access

2022-10-30 Thread Richard Henderson
Avoid cpu_restore_state, and modifying env->eip out from
underneath the translator with TARGET_TB_PCREL.  There is
some slight duplication from x86_restore_state_to_opc,
but it's just a few lines.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269
Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 target/i386/helper.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/target/i386/helper.c b/target/i386/helper.c
index b62a1e48e2..2cd1756f1a 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -509,6 +509,23 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int 
bank,
 }
 }
 
+static target_ulong get_memio_eip(CPUX86State *env)
+{
+uint64_t data[TARGET_INSN_START_WORDS];
+CPUState *cs = env_cpu(env);
+
+if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
+return env->eip;
+}
+
+/* Per x86_restore_state_to_opc. */
+if (TARGET_TB_PCREL) {
+return (env->eip & TARGET_PAGE_MASK) | data[0];
+} else {
+return data[0] - env->segs[R_CS].base;
+}
+}
+
 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
 {
 X86CPU *cpu = env_archcpu(env);
@@ -519,9 +536,9 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess 
access)
 
 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
 } else if (tcg_enabled()) {
-cpu_restore_state(cs, cs->mem_io_pc, false);
+target_ulong eip = get_memio_eip(env);
 
-apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
+apic_handle_tpr_access_report(cpu->apic_state, eip, access);
 }
 }
 #endif /* !CONFIG_USER_ONLY */
-- 
2.34.1




[PULL 11/11] target/i386: Expand eflags updates inline

2022-10-30 Thread Richard Henderson
The helpers for reset_rf, cli, sti, clac, stac are
completely trivial; implement them inline.

Drop some nearby #if 0 code.

Reviewed-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/i386/helper.h|  5 -
 target/i386/tcg/cc_helper.c | 41 -
 target/i386/tcg/translate.c | 30 ++-
 3 files changed, 25 insertions(+), 51 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 88143b2a24..b7de5429ef 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -56,13 +56,8 @@ DEF_HELPER_2(syscall, void, env, int)
 DEF_HELPER_2(sysret, void, env, int)
 #endif
 DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
-DEF_HELPER_1(reset_rf, void, env)
 DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
 DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
-DEF_HELPER_1(cli, void, env)
-DEF_HELPER_1(sti, void, env)
-DEF_HELPER_1(clac, void, env)
-DEF_HELPER_1(stac, void, env)
 DEF_HELPER_3(boundw, void, env, tl, int)
 DEF_HELPER_3(boundl, void, env, tl, int)
 
diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c
index cc7ea9e8b9..6227dbb30b 100644
--- a/target/i386/tcg/cc_helper.c
+++ b/target/i386/tcg/cc_helper.c
@@ -346,44 +346,3 @@ void helper_clts(CPUX86State *env)
 env->cr[0] &= ~CR0_TS_MASK;
 env->hflags &= ~HF_TS_MASK;
 }
-
-void helper_reset_rf(CPUX86State *env)
-{
-env->eflags &= ~RF_MASK;
-}
-
-void helper_cli(CPUX86State *env)
-{
-env->eflags &= ~IF_MASK;
-}
-
-void helper_sti(CPUX86State *env)
-{
-env->eflags |= IF_MASK;
-}
-
-void helper_clac(CPUX86State *env)
-{
-env->eflags &= ~AC_MASK;
-}
-
-void helper_stac(CPUX86State *env)
-{
-env->eflags |= AC_MASK;
-}
-
-#if 0
-/* vm86plus instructions */
-void helper_cli_vm(CPUX86State *env)
-{
-env->eflags &= ~VIF_MASK;
-}
-
-void helper_sti_vm(CPUX86State *env)
-{
-env->eflags |= VIF_MASK;
-if (env->eflags & VIP_MASK) {
-raise_exception_ra(env, EXCP0D_GPF, GETPC());
-}
-}
-#endif
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 546c427c23..0ee548ce56 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2746,6 +2746,26 @@ static void gen_reset_hflag(DisasContext *s, uint32_t 
mask)
 }
 }
 
+static void gen_set_eflags(DisasContext *s, target_ulong mask)
+{
+TCGv t = tcg_temp_new();
+
+tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_gen_ori_tl(t, t, mask);
+tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_temp_free(t);
+}
+
+static void gen_reset_eflags(DisasContext *s, target_ulong mask)
+{
+TCGv t = tcg_temp_new();
+
+tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_gen_andi_tl(t, t, ~mask);
+tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_temp_free(t);
+}
+
 /* Clear BND registers during legacy branches.  */
 static void gen_bnd_jmp(DisasContext *s)
 {
@@ -2776,7 +2796,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool 
recheck_tf, bool jr)
 }
 
 if (s->base.tb->flags & HF_RF_MASK) {
-gen_helper_reset_rf(cpu_env);
+gen_reset_eflags(s, RF_MASK);
 }
 if (recheck_tf) {
 gen_helper_rechecking_single_step(cpu_env);
@@ -5502,12 +5522,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
 #endif
 case 0xfa: /* cli */
 if (check_iopl(s)) {
-gen_helper_cli(cpu_env);
+gen_reset_eflags(s, IF_MASK);
 }
 break;
 case 0xfb: /* sti */
 if (check_iopl(s)) {
-gen_helper_sti(cpu_env);
+gen_set_eflags(s, IF_MASK);
 /* interruptions are enabled only the first insn after sti */
 gen_update_eip_next(s);
 gen_eob_inhibit_irq(s, true);
@@ -5789,7 +5809,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
 || CPL(s) != 0) {
 goto illegal_op;
 }
-gen_helper_clac(cpu_env);
+gen_reset_eflags(s, AC_MASK);
 s->base.is_jmp = DISAS_EOB_NEXT;
 break;
 
@@ -5798,7 +5818,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
 || CPL(s) != 0) {
 goto illegal_op;
 }
-gen_helper_stac(cpu_env);
+gen_set_eflags(s, AC_MASK);
 s->base.is_jmp = DISAS_EOB_NEXT;
 break;
 
-- 
2.34.1




[PULL 00/11] tcg patch queue

2022-10-30 Thread Richard Henderson
The following changes since commit 75d30fde55485b965a1168a21d016dd07b50ed32:

  Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into 
staging (2022-10-30 15:07:25 -0400)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221031

for you to fetch changes up to cb375590983fc3d23600d02ba05a05d34fe44150:

  target/i386: Expand eflags updates inline (2022-10-31 11:39:10 +1100)


Remove sparc32plus support from tcg/sparc.
target/i386: Use cpu_unwind_state_data for tpr access.
target/i386: Expand eflags updates inline


Icenowy Zheng (1):
  tcg/tci: fix logic error when registering helpers via FFI

Richard Henderson (10):
  tcg/sparc: Remove support for sparc32plus
  tcg/sparc64: Rename from tcg/sparc
  tcg/sparc64: Remove sparc32plus constraints
  accel/tcg: Introduce cpu_unwind_state_data
  target/i386: Use cpu_unwind_state_data for tpr access
  target/openrisc: Always exit after mtspr npc
  target/openrisc: Use cpu_unwind_state_data for mfspr
  accel/tcg: Remove will_exit argument from cpu_restore_state
  accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb
  target/i386: Expand eflags updates inline

 meson.build |   4 +-
 accel/tcg/internal.h|   4 +-
 include/exec/exec-all.h |  24 ++-
 target/i386/helper.h|   5 -
 tcg/{sparc => sparc64}/tcg-target-con-set.h |  16 +-
 tcg/{sparc => sparc64}/tcg-target-con-str.h |   3 -
 tcg/{sparc => sparc64}/tcg-target.h |  11 --
 accel/tcg/cpu-exec-common.c |   2 +-
 accel/tcg/tb-maint.c|   4 +-
 accel/tcg/translate-all.c   |  91 +
 target/alpha/helper.c   |   2 +-
 target/alpha/mem_helper.c   |   2 +-
 target/arm/op_helper.c  |   2 +-
 target/arm/tlb_helper.c |   8 +-
 target/cris/helper.c|   2 +-
 target/i386/helper.c|  21 ++-
 target/i386/tcg/cc_helper.c |  41 -
 target/i386/tcg/sysemu/svm_helper.c |   2 +-
 target/i386/tcg/translate.c |  30 ++-
 target/m68k/op_helper.c |   4 +-
 target/microblaze/helper.c  |   2 +-
 target/nios2/op_helper.c|   2 +-
 target/openrisc/sys_helper.c|  17 +-
 target/ppc/excp_helper.c|   2 +-
 target/s390x/tcg/excp_helper.c  |   2 +-
 target/tricore/op_helper.c  |   2 +-
 target/xtensa/helper.c  |   6 +-
 tcg/tcg.c   |  81 +---
 tcg/{sparc => sparc64}/tcg-target.c.inc | 275 
 MAINTAINERS |   2 +-
 30 files changed, 232 insertions(+), 437 deletions(-)
 rename tcg/{sparc => sparc64}/tcg-target-con-set.h (69%)
 rename tcg/{sparc => sparc64}/tcg-target-con-str.h (77%)
 rename tcg/{sparc => sparc64}/tcg-target.h (95%)
 rename tcg/{sparc => sparc64}/tcg-target.c.inc (91%)



[PULL 02/11] tcg/sparc64: Rename from tcg/sparc

2022-10-30 Thread Richard Henderson
Emphasize that we only support full 64-bit code generation.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 meson.build | 4 +---
 tcg/{sparc => sparc64}/tcg-target-con-set.h | 0
 tcg/{sparc => sparc64}/tcg-target-con-str.h | 0
 tcg/{sparc => sparc64}/tcg-target.h | 0
 tcg/{sparc => sparc64}/tcg-target.c.inc | 0
 MAINTAINERS | 2 +-
 6 files changed, 2 insertions(+), 4 deletions(-)
 rename tcg/{sparc => sparc64}/tcg-target-con-set.h (100%)
 rename tcg/{sparc => sparc64}/tcg-target-con-str.h (100%)
 rename tcg/{sparc => sparc64}/tcg-target.h (100%)
 rename tcg/{sparc => sparc64}/tcg-target.c.inc (100%)

diff --git a/meson.build b/meson.build
index 37737913df..e9853ad21a 100644
--- a/meson.build
+++ b/meson.build
@@ -49,7 +49,7 @@ qapi_trace_events = []
 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 
'darwin']
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
-  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
+  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
 
 cpu = host_machine.cpu_family()
 
@@ -469,8 +469,6 @@ if get_option('tcg').allowed()
   endif
   if get_option('tcg_interpreter')
 tcg_arch = 'tci'
-  elif host_arch == 'sparc64'
-tcg_arch = 'sparc'
   elif host_arch == 'x86_64'
 tcg_arch = 'i386'
   elif host_arch == 'ppc64'
diff --git a/tcg/sparc/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
similarity index 100%
rename from tcg/sparc/tcg-target-con-set.h
rename to tcg/sparc64/tcg-target-con-set.h
diff --git a/tcg/sparc/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
similarity index 100%
rename from tcg/sparc/tcg-target-con-str.h
rename to tcg/sparc64/tcg-target-con-str.h
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc64/tcg-target.h
similarity index 100%
rename from tcg/sparc/tcg-target.h
rename to tcg/sparc64/tcg-target.h
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
similarity index 100%
rename from tcg/sparc/tcg-target.c.inc
rename to tcg/sparc64/tcg-target.c.inc
diff --git a/MAINTAINERS b/MAINTAINERS
index 64893e36bc..1ab6962b0a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3379,7 +3379,7 @@ L: qemu-s3...@nongnu.org
 
 SPARC TCG target
 S: Odd Fixes
-F: tcg/sparc/
+F: tcg/sparc64/
 F: disas/sparc.c
 
 TCI TCG target
-- 
2.34.1




[PATCH] accel/tcg: Complete cpu initialization before registration

2022-10-30 Thread Richard Henderson
Delay cpu_list_add until realize is complete, so that cross-cpu
interaction does not happen with incomplete cpu state.  For this,
we must delay plugin initialization out of tcg_exec_realizefn,
because no cpu_index has been assigned.

Fixes a problem with cross-cpu jump cache flushing, when the
jump cache has not yet been allocated.

Fixes: a976a99a2975 ("include/hw/core: Create struct CPUJumpCache")
Reported-by: Ilya Leoshkevich 
Signed-off-by: Richard Henderson 
---
 accel/tcg/cpu-exec.c  |  8 +---
 accel/tcg/translate-all.c | 16 +++-
 cpu.c | 10 +-
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 82b06c1824..356fe348de 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -1052,23 +1052,25 @@ void tcg_exec_realizefn(CPUState *cpu, Error **errp)
 cc->tcg_ops->initialize();
 tcg_target_initialized = true;
 }
-tlb_init(cpu);
-qemu_plugin_vcpu_init_hook(cpu);
 
+cpu->tb_jmp_cache = g_new0(CPUJumpCache, 1);
+tlb_init(cpu);
 #ifndef CONFIG_USER_ONLY
 tcg_iommu_init_notifier_list(cpu);
 #endif /* !CONFIG_USER_ONLY */
+/* qemu_plugin_vcpu_init_hook delayed until cpu_index assigned. */
 }
 
 /* undo the initializations in reverse order */
 void tcg_exec_unrealizefn(CPUState *cpu)
 {
+qemu_plugin_vcpu_exit_hook(cpu);
 #ifndef CONFIG_USER_ONLY
 tcg_iommu_free_notifier_list(cpu);
 #endif /* !CONFIG_USER_ONLY */
 
-qemu_plugin_vcpu_exit_hook(cpu);
 tlb_destroy(cpu);
+g_free(cpu->tb_jmp_cache);
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 0089578f8f..921944a5ab 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1580,15 +1580,13 @@ void tcg_flush_jmp_cache(CPUState *cpu)
 {
 CPUJumpCache *jc = cpu->tb_jmp_cache;
 
-if (likely(jc)) {
-for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
-qatomic_set(>array[i].tb, NULL);
-}
-} else {
-/* This should happen once during realize, and thus never race. */
-jc = g_new0(CPUJumpCache, 1);
-jc = qatomic_xchg(>tb_jmp_cache, jc);
-assert(jc == NULL);
+/* During early initialization, the cache may not yet be allocated. */
+if (unlikely(jc == NULL)) {
+return;
+}
+
+for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
+qatomic_set(>array[i].tb, NULL);
 }
 }
 
diff --git a/cpu.c b/cpu.c
index 2a09b05205..4a7d865427 100644
--- a/cpu.c
+++ b/cpu.c
@@ -134,15 +134,23 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
 /* cache the cpu class for the hotpath */
 cpu->cc = CPU_GET_CLASS(cpu);
 
-cpu_list_add(cpu);
 if (!accel_cpu_realizefn(cpu, errp)) {
 return;
 }
+
 /* NB: errp parameter is unused currently */
 if (tcg_enabled()) {
 tcg_exec_realizefn(cpu, errp);
 }
 
+/* Wait until cpu initialization complete before exposing cpu. */
+cpu_list_add(cpu);
+
+/* Plugin initialization must wait until cpu_index assigned. */
+if (tcg_enabled()) {
+qemu_plugin_vcpu_init_hook(cpu);
+}
+
 #ifdef CONFIG_USER_ONLY
 assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
-- 
2.34.1




[PULL 08/11] target/openrisc: Use cpu_unwind_state_data for mfspr

2022-10-30 Thread Richard Henderson
Since we do not plan to exit, use cpu_unwind_state_data
and extract exactly the data requested.

This is a bug fix, in that we no longer clobber dflag.

Consider:

l.j   L2 // branch
l.mfspr   r1, ppc// delay

L1: boom
L2: l.lwa r3, (r4)

Here, dflag would be set by cpu_restore_state (because that is the current
state of the cpu), but but not cleared by tb_stop on exiting the TB
(because DisasContext has recorded the current value as zero).

The next TB begins at L2 with dflag incorrectly set.  If the load has a
tlb miss, then the exception will be delivered as per a delay slot:
with DSX set in the status register and PC decremented (delay slots
restart by re-executing the branch). This will cause the return from
interrupt to go to L1, and boom!

Signed-off-by: Richard Henderson 
---
 target/openrisc/sys_helper.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index a3508e421d..dde2fa1623 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -199,6 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, 
target_ulong rd,
target_ulong spr)
 {
 #ifndef CONFIG_USER_ONLY
+uint64_t data[TARGET_INSN_START_WORDS];
 MachineState *ms = MACHINE(qdev_get_machine());
 OpenRISCCPU *cpu = env_archcpu(env);
 CPUState *cs = env_cpu(env);
@@ -232,14 +233,20 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, 
target_ulong rd,
 return env->evbar;
 
 case TO_SPR(0, 16): /* NPC (equals PC) */
-cpu_restore_state(cs, GETPC(), false);
+if (cpu_unwind_state_data(cs, GETPC(), data)) {
+return data[0];
+}
 return env->pc;
 
 case TO_SPR(0, 17): /* SR */
 return cpu_get_sr(env);
 
 case TO_SPR(0, 18): /* PPC */
-cpu_restore_state(cs, GETPC(), false);
+if (cpu_unwind_state_data(cs, GETPC(), data)) {
+if (data[1] & 2) {
+return data[0] - 4;
+}
+}
 return env->ppc;
 
 case TO_SPR(0, 32): /* EPCR */
-- 
2.34.1




[PULL 04/11] tcg/tci: fix logic error when registering helpers via FFI

2022-10-30 Thread Richard Henderson
From: Icenowy Zheng 

When registering helpers via FFI for TCI, the inner loop that iterates
parameters of the helper reuses (and thus pollutes) the same variable
used by the outer loop that iterates all helpers, thus made some helpers
unregistered.

Fix this logic error by using a dedicated temporary variable for the
inner loop.

Fixes: 22f15579fa ("tcg: Build ffi data structures for helpers")
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Icenowy Zheng 
Message-Id: <20221028072145.1593205-1-...@icenowy.me>
[rth: Move declaration of j to the for loop itself]
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index c9e664ee31..b6c46b7e25 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -634,9 +634,9 @@ static void tcg_context_init(unsigned max_cpus)
 
 if (nargs != 0) {
 ca->cif.arg_types = ca->args;
-for (i = 0; i < nargs; ++i) {
-int typecode = extract32(typemask, (i + 1) * 3, 3);
-ca->args[i] = typecode_to_ffi[typecode];
+for (int j = 0; j < nargs; ++j) {
+int typecode = extract32(typemask, (j + 1) * 3, 3);
+ca->args[j] = typecode_to_ffi[typecode];
 }
 }
 
-- 
2.34.1




[PULL 07/11] target/openrisc: Always exit after mtspr npc

2022-10-30 Thread Richard Henderson
We have called cpu_restore_state asserting will_exit.
Do not go back on that promise.  This affects icount.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/openrisc/sys_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 09b3c97d7c..a3508e421d 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -51,8 +51,8 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, 
target_ulong rb)
 if (env->pc != rb) {
 env->pc = rb;
 env->dflag = 0;
-cpu_loop_exit(cs);
 }
+cpu_loop_exit(cs);
 break;
 
 case TO_SPR(0, 17): /* SR */
-- 
2.34.1




[PATCH] qga: Add initial OpenBSD support

2022-10-30 Thread Brad Smith
qga: Add initial OpenBSD support

Signed-off-by: Brad Smith 
---
 meson.build  | 2 +-
 qga/commands-bsd.c   | 5 +
 qga/commands-posix.c | 9 +++--
 qga/main.c   | 4 ++--
 4 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/meson.build b/meson.build
index 37737913df..fb69a6a683 100644
--- a/meson.build
+++ b/meson.build
@@ -75,7 +75,7 @@ have_tools = get_option('tools') \
   .allowed()
 have_ga = get_option('guest_agent') \
   .disable_auto_if(not have_system and not have_tools) \
-  .require(targetos in ['sunos', 'linux', 'windows', 'freebsd'],
+  .require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'openbsd'],
error_message: 'unsupported OS for QEMU guest agent') \
   .allowed()
 have_block = have_system or have_tools
diff --git a/qga/commands-bsd.c b/qga/commands-bsd.c
index 15cade2d4c..4deb3bf580 100644
--- a/qga/commands-bsd.c
+++ b/qga/commands-bsd.c
@@ -21,7 +21,12 @@
 #include 
 #include 
 #include 
+#ifdef __OpenBSD__
+#include 
+#include 
+#else
 #include 
+#endif
 #include 
 
 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 32493d6383..640f26dc16 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -45,7 +45,12 @@
 #include 
 #include 
 #include 
+#ifdef __OpenBSD__
+#include 
+#include 
+#else
 #include 
+#endif
 #include 
 #ifdef CONFIG_SOLARIS
 #include 
@@ -2881,7 +2886,7 @@ static int guest_get_network_stats(const char *name,
 return -1;
 }
 
-#ifndef __FreeBSD__
+#ifndef CONFIG_BSD
 /*
  * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
  * buffer with ETHER_ADDR_LEN length at least.
@@ -2930,7 +2935,7 @@ bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char 
*buf,
 close(sock);
 return true;
 }
-#endif /* __FreeBSD__ */
+#endif /* CONFIG_BSD */
 
 /*
  * Build information about guest interfaces
diff --git a/qga/main.c b/qga/main.c
index b3580508fa..0fe94e80d1 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -40,9 +40,9 @@
 #include "commands-common.h"
 
 #ifndef _WIN32
-#ifdef __FreeBSD__
+#ifdef CONFIG_BSD
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/vtcon/org.qemu.guest_agent.0"
-#else /* __FreeBSD__ */
+#else /* CONFIG_BSD */
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
 #endif /* __FreeBSD__ */
 #define QGA_SERIAL_PATH_DEFAULT "/dev/ttyS0"
-- 
2.38.0




Re: [PATCH v2 3/3] hw/i386/acpi-build: Resolve north rather than south bridges

2022-10-30 Thread Ani Sinha



On Fri, 28 Oct 2022, Bernhard Beschow wrote:

> The code currently assumes Q35 iff ICH9 and i440fx iff PIIX. Now that more
> AML generation has been moved into the south bridges and since the
> machines define themselves primarily through their north bridges, let's
> switch to resolving the north bridges for AML generation instead. This
> also allows for easier experimentation with different south bridges in
> the "pc" machine, e.g. with PIIX4 and VT82xx.
>
> Signed-off-by: Bernhard Beschow 

Reviewed-by: Ani Sinha 

> ---
>  hw/i386/acpi-build.c | 11 ++-
>  1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 73d8a59737..d9eaa5fc4d 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -60,6 +60,7 @@
>  #include "hw/i386/fw_cfg.h"
>  #include "hw/i386/ich9.h"
>  #include "hw/pci/pci_bus.h"
> +#include "hw/pci-host/i440fx.h"
>  #include "hw/pci-host/q35.h"
>  #include "hw/i386/x86-iommu.h"
>
> @@ -1322,8 +1323,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> AcpiPmInfo *pm, AcpiMiscInfo *misc,
> Range *pci_hole, Range *pci_hole64, MachineState *machine)
>  {
> -Object *piix = object_resolve_type_unambiguous(TYPE_PIIX4_PM);
> -Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE);
> +Object *i440fx = 
> object_resolve_type_unambiguous(TYPE_I440FX_PCI_HOST_BRIDGE);
> +Object *q35 = object_resolve_type_unambiguous(TYPE_Q35_HOST_DEVICE);
>  CrsRangeEntry *entry;
>  Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs;
>  CrsRangeSet crs_range_set;
> @@ -1344,13 +1345,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>  AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = x86ms->oem_id,
>  .oem_table_id = x86ms->oem_table_id };
>
> -assert(!!piix != !!lpc);
> +assert(!!i440fx != !!q35);
>
>  acpi_table_begin(, table_data);
>  dsdt = init_aml_allocator();
>
>  build_dbg_aml(dsdt);
> -if (piix) {
> +if (i440fx) {
>  sb_scope = aml_scope("_SB");
>  dev = aml_device("PCI0");
>  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
> @@ -1363,7 +1364,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>  build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
>  }
>  build_piix4_pci0_int(dsdt);
> -} else if (lpc) {
> +} else if (q35) {
>  sb_scope = aml_scope("_SB");
>  dev = aml_device("PCI0");
>  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
> --
> 2.38.1
>
>



Re: [PATCH 4/5] target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX

2022-10-30 Thread Anup Patel
On Mon, Oct 31, 2022 at 6:25 AM Alistair Francis  wrote:
>
> On Fri, Oct 28, 2022 at 2:53 AM Anup Patel  wrote:
> >
> > The time CSR will wrap-around immediately after reaching UINT64_MAX
> > so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
> > in riscv_timer_write_timecmp().
>
> I'm not clear what this is fixing?
>
> If the guest sets a timer for UINT64_MAX shouldn't that still trigger
> an event at some point?

Here's what Sstc says about timer interrupt using Sstc:
"A supervisor timer interrupt becomes pending - as reflected in the
STIP bit in the mip and sip registers - whenever time contains a
value greater than or equal to stimecmp, treating the values as
unsigned integers. Writes to stimecmp are guaranteed to be
reflected in STIP eventually, but not necessarily immediately.
The interrupt remains posted until stimecmp becomes greater
than time - typically as a result of writing stimecmp."

When timecmp = UINT64_MAX, the time CSR will eventually reach
timecmp value but on next timer tick the time CSR will wrap-around
and become zero which is less than UINT64_MAX. Now, the timer
interrupt behaves like a level triggered interrupt so it will become 1
when time = timecmp = UINT64_MAX and next timer tick it will
become 0 again because time = 0 < timecmp = UINT64_MAX.

This time CSR wrap-around comparison with timecmp is natural
to implement in HW but not straight forward in QEMU hence this
patch.

Software can potentially use timecmp = UINT64_MAX as a way
to clear the timer interrupt and keep timer disabled instead of
enabling/disabling sie.STIP. This timecmp = UINT64_MAX helps:
1) Linux RISC-V timer driver keep timer interrupt enable/disable
state in-sync with Linux interrupt subsystem.
2) Reduce number of traps taken when emulating Sstc for the
"Nested Guest" (i.e. Guest running under some "Guest Hypervisor"
which in-turn runs under a "Host Hypervisor").

In fact, the SBI set_timer() call also defines similar mechanism to
disable timer: "If the supervisor wishes to clear the timer interrupt
without scheduling the next timer event, it can either request a timer
interrupt infinitely far into the future (i.e., (uint64_t)-1), ...".

Regards,
Anup

>
> Alistair
>
> >
> > Signed-off-by: Anup Patel 
> > ---
> >  target/riscv/time_helper.c | 8 
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
> > index 4fb2a471a9..1ee9f94813 100644
> > --- a/target/riscv/time_helper.c
> > +++ b/target/riscv/time_helper.c
> > @@ -72,6 +72,14 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer 
> > *timer,
> >  riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
> >  }
> >
> > +/*
> > + * Don't re-start the QEMU timer when timecmp == UINT64_MAX because
> > + * time CSR will wrap-around immediately after reaching UINT64_MAX.
> > + */
> > +if (timecmp == UINT64_MAX) {
> > +return;
> > +}
> > +
> >  /* otherwise, set up the future timer interrupt */
> >  diff = timecmp - rtc_r;
> >  /* back to ns (note args switched in muldiv64) */
> > --
> > 2.34.1
> >
> >



Re: [PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Alex Williamson
On Mon, 31 Oct 2022 11:10:19 +0800
Cindy Lu  wrote:

> - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
>   change the name to memory_get_xlat_addr(). So we can use this
>   function on other devices, such as vDPA device.
> - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
>   whether the memory is backed by a discard manager. then device can
>   have its own warning.
> 
> Signed-off-by: Cindy Lu 
> ---
>  hw/vfio/common.c  | 66 +++
>  include/exec/memory.h |  4 +++
>  softmmu/memory.c  | 72 +++
>  3 files changed, 81 insertions(+), 61 deletions(-)

Acked-by: Alex Williamson 




[PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
- Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
  change the name to memory_get_xlat_addr(). So we can use this
  function on other devices, such as vDPA device.
- Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
  whether the memory is backed by a discard manager. then device can
  have its own warning.

Signed-off-by: Cindy Lu 
---
 hw/vfio/common.c  | 66 +++
 include/exec/memory.h |  4 +++
 softmmu/memory.c  | 72 +++
 3 files changed, 81 insertions(+), 61 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index ace9562a9b..6bc02b32c8 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -578,45 +578,11 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)
 static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only)
 {
-MemoryRegion *mr;
-hwaddr xlat;
-hwaddr len = iotlb->addr_mask + 1;
-bool writable = iotlb->perm & IOMMU_WO;
-
-/*
- * The IOMMU TLB entry we have just covers translation through
- * this IOMMU to its immediate target.  We need to translate
- * it the rest of the way through to memory.
- */
-mr = address_space_translate(_space_memory,
- iotlb->translated_addr,
- , , writable,
- MEMTXATTRS_UNSPECIFIED);
-if (!memory_region_is_ram(mr)) {
-error_report("iommu map to non memory area %"HWADDR_PRIx"",
- xlat);
-return false;
-} else if (memory_region_has_ram_discard_manager(mr)) {
-RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
-MemoryRegionSection tmp = {
-.mr = mr,
-.offset_within_region = xlat,
-.size = int128_make64(len),
-};
-
-/*
- * Malicious VMs can map memory into the IOMMU, which is expected
- * to remain discarded. vfio will pin all pages, populating memory.
- * Disallow that. vmstate priorities make sure any RamDiscardManager
- * were already restored before IOMMUs are restored.
- */
-if (!ram_discard_manager_is_populated(rdm, )) {
-error_report("iommu map to discarded memory (e.g., unplugged via"
- " virtio-mem): %"HWADDR_PRIx"",
- iotlb->translated_addr);
-return false;
-}
+bool ret, mr_has_discard_manager;
 
+ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
+   _has_discard_manager);
+if (ret && mr_has_discard_manager) {
 /*
  * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
  * pages will remain pinned inside vfio until unmapped, resulting in a
@@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void 
**vaddr,
  " intended via an IOMMU. It's possible to mitigate "
  " by setting/adjusting RLIMIT_MEMLOCK.");
 }
-
-/*
- * Translation truncates length to the IOMMU page size,
- * check that it did not truncate too much.
- */
-if (len & iotlb->addr_mask) {
-error_report("iommu has granularity incompatible with target AS");
-return false;
-}
-
-if (vaddr) {
-*vaddr = memory_region_get_ram_ptr(mr) + xlat;
-}
-
-if (ram_addr) {
-*ram_addr = memory_region_get_ram_addr(mr) + xlat;
-}
-
-if (read_only) {
-*read_only = !writable || mr->readonly;
-}
-
-return true;
+return ret;
 }
 
 static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bfb1de8eea..d1e79c39dc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -713,6 +713,10 @@ void 
ram_discard_manager_register_listener(RamDiscardManager *rdm,
 void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
  RamDiscardListener *rdl);
 
+bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
+  ram_addr_t *ram_addr, bool *read_only,
+  bool *mr_has_discard_manager);
+
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
 typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
 
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 7ba2048836..bc0be3f62c 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -33,6 +33,7 @@
 #include "qemu/accel.h"
 #include "hw/boards.h"
 #include "migration/vmstate.h"
+#include "exec/address-spaces.h"
 
 //#define DEBUG_UNASSIGNED
 
@@ -2121,6 +2122,77 @@ void 
ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
 rdmc->unregister_listener(rdm, rdl);
 }
 
+/* Called with rcu_read_lock held.  */

[PATCH v9 0/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
These patches are to support vIOMMU in vdpa device

changes in V3
1. Move function vfio_get_xlat_addr to memory.c
2. Use the existing memory listener, while the MR is
iommu MR then call the function iommu_region_add/
iommu_region_del

changes in V4
1.make the comments in vfio_get_xlat_addr more general

changes in V5
1. Address the comments in the last version
2. Add a new arg in the function vfio_get_xlat_addr, which shows whether
the memory is backed by a discard manager. So the device can have its
own warning.

changes in V6
move the error_report for the unpopulated discard back to
memeory_get_xlat_addr

changes in V7
organize the error massage to avoid the duplicate information

changes in V8
Organize the code follow the comments in the last version

changes in V9
Organize the code follow the comments

Cindy Lu (2):
  vfio: move implement of vfio_get_xlat_addr() to memory.c
  vhost-vdpa: add support for vIOMMU

 hw/vfio/common.c   |  66 ++
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/exec/memory.h  |   4 ++
 include/hw/virtio/vhost-vdpa.h |  10 +++
 softmmu/memory.c   |  72 +++
 5 files changed, 203 insertions(+), 72 deletions(-)

-- 
2.34.3




[PATCH v9 2/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
Add support for vIOMMU. add the new function to deal with iommu MR.
- during iommu_region_add register a specific IOMMU notifier,
 and store all notifiers in a list.
- during iommu_region_del, compare and delete the IOMMU notifier from the list

Verified in vp_vdpa and vdpa_sim_net driver

Signed-off-by: Cindy Lu 
---
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/hw/virtio/vhost-vdpa.h |  10 +++
 2 files changed, 122 insertions(+), 11 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3ff9ce3501..dcfaaccfa9 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -26,6 +26,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "hw/virtio/virtio-access.h"
 
 /*
  * Return one past the end of the end of section. Be careful with uint64_t
@@ -44,7 +45,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 uint64_t iova_min,
 uint64_t iova_max)
 {
-Int128 llend;
 
 if ((!memory_region_is_ram(section->mr) &&
  !memory_region_is_iommu(section->mr)) ||
@@ -61,14 +61,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 return true;
 }
 
-llend = vhost_vdpa_section_end(section);
-if (int128_gt(llend, int128_make64(iova_max))) {
-error_report("RAM section out of device range (max=0x%" PRIx64
- ", end addr=0x%" PRIx64 ")",
- iova_max, int128_get64(llend));
-return true;
-}
-
 return false;
 }
 
@@ -173,6 +165,106 @@ static void vhost_vdpa_listener_commit(MemoryListener 
*listener)
 v->iotlb_batch_begin_sent = false;
 }
 
+static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+{
+struct vdpa_iommu *iommu = container_of(n, struct vdpa_iommu, n);
+
+hwaddr iova = iotlb->iova + iommu->iommu_offset;
+struct vhost_vdpa *v = iommu->dev;
+void *vaddr;
+int ret;
+
+if (iotlb->target_as != _space_memory) {
+error_report("Wrong target AS \"%s\", only system memory is allowed",
+ iotlb->target_as->name ? iotlb->target_as->name : "none");
+return;
+}
+RCU_READ_LOCK_GUARD();
+vhost_vdpa_iotlb_batch_begin_once(v);
+
+if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
+bool read_only;
+
+if (!memory_get_xlat_addr(iotlb, , NULL, _only, NULL)) {
+return;
+}
+ret =
+vhost_vdpa_dma_map(v, iova, iotlb->addr_mask + 1, vaddr, 
read_only);
+if (ret) {
+error_report("vhost_vdpa_dma_map(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ", %p) = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, vaddr, ret);
+}
+} else {
+ret = vhost_vdpa_dma_unmap(v, iova, iotlb->addr_mask + 1);
+if (ret) {
+error_report("vhost_vdpa_dma_unmap(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ") = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, ret);
+}
+}
+}
+
+static void vhost_vdpa_iommu_region_add(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+Int128 end;
+int iommu_idx;
+IOMMUMemoryRegion *iommu_mr;
+int ret;
+
+iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+
+iommu = g_malloc0(sizeof(*iommu));
+end =  int128_add(int128_make64(section->offset_within_region),
+section->size);
+end = int128_sub(end, int128_one());
+iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+MEMTXATTRS_UNSPECIFIED);
+
+iommu->iommu_mr = iommu_mr;
+
+iommu_notifier_init(
+>n, vhost_vdpa_iommu_map_notify, IOMMU_NOTIFIER_IOTLB_EVENTS,
+section->offset_within_region, int128_get64(end), iommu_idx);
+iommu->iommu_offset =
+section->offset_within_address_space - section->offset_within_region;
+iommu->dev = v;
+
+ret = memory_region_register_iommu_notifier(section->mr, >n, NULL);
+if (ret) {
+g_free(iommu);
+return;
+}
+
+QLIST_INSERT_HEAD(>iommu_list, iommu, iommu_next);
+memory_region_iommu_replay(iommu->iommu_mr, >n);
+
+return;
+}
+
+static void vhost_vdpa_iommu_region_del(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+
+QLIST_FOREACH(iommu, >iommu_list, iommu_next)
+{
+if (MEMORY_REGION(iommu->iommu_mr) == section->mr &&
+iommu->n.start == section->offset_within_region) {
+memory_region_unregister_iommu_notifier(section->mr, 

Re: [PATCH v8 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
On Mon, 31 Oct 2022 at 10:30, Alex Williamson
 wrote:
>
> On Mon, 31 Oct 2022 09:56:04 +0800
> Cindy Lu  wrote:
>
> > - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
> >   change the name to memory_get_xlat_addr(). So we can use this
> >   function on other devices, such as vDPA device.
> > - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
> >   whether the memory is backed by a discard manager. the device can
> >   have its own warning.
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >  hw/vfio/common.c  | 101 +++---
> >  include/exec/memory.h |   4 ++
> >  softmmu/memory.c  |  72 ++
> >  3 files changed, 102 insertions(+), 75 deletions(-)
>
> Some changes I'd like to see below, but otherwise
>
> Acked-by: Alex Williamson 
>
> >
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index ace9562a9b..5bfd55de86 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -578,86 +578,37 @@ static bool 
> > vfio_listener_skipped_section(MemoryRegionSection *section)
> >  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > ram_addr_t *ram_addr, bool *read_only)
> >  {
> > -MemoryRegion *mr;
> > -hwaddr xlat;
> > -hwaddr len = iotlb->addr_mask + 1;
> > -bool writable = iotlb->perm & IOMMU_WO;
> > -
> > -/*
> > - * The IOMMU TLB entry we have just covers translation through
> > - * this IOMMU to its immediate target.  We need to translate
> > - * it the rest of the way through to memory.
> > - */
> > -mr = address_space_translate(_space_memory,
> > - iotlb->translated_addr,
> > - , , writable,
> > - MEMTXATTRS_UNSPECIFIED);
> > -if (!memory_region_is_ram(mr)) {
> > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > - xlat);
> > -return false;
> > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> > -MemoryRegionSection tmp = {
> > -.mr = mr,
> > -.offset_within_region = xlat,
> > -.size = int128_make64(len),
> > -};
> > -
> > +bool mr_has_discard_manager;
> > +if (memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> > + _has_discard_manager)) {
> >  /*
> > - * Malicious VMs can map memory into the IOMMU, which is expected
> > - * to remain discarded. vfio will pin all pages, populating memory.
> > - * Disallow that. vmstate priorities make sure any 
> > RamDiscardManager
> > - * were already restored before IOMMUs are restored.
> > + * if the mr has the discard_manager and the return value of
> > + * memory_get_xlat_addr() is ture then we need to warn
>
> s/ture/true/
>
> But then the comment below is really describing why we're generating a
> warning, so the above additional comment is mostly just noise.
>
sure, will remove this
> I'd also prefer to see this as:
>
> {
> bool ret, mr_has_discard_manager;
>
> ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
>_has_discard_manager));
>
> if (ret && mr_has_discard_manager) {
> // Unmodified comment and warn report from existing code
> }
>
> return ret;
> }
>
sure, Will change this, Thanks Alex
Thanks
Cindy
> >   */
> > -if (!ram_discard_manager_is_populated(rdm, )) {
> > -error_report("iommu map to discarded memory (e.g., unplugged 
> > via"
> > - " virtio-mem): %"HWADDR_PRIx"",
> > - iotlb->translated_addr);
> > -return false;
> > +if (mr_has_discard_manager) {
> > +/*
> > + * Malicious VMs might trigger discarding of IOMMU-mapped 
> > memory.
> > + * The pages will remain pinned inside vfio until unmapped,
> > + * resulting in a higher memory consumption than expected. If 
> > memory
> > + * would get populated again later, there would be an 
> > inconsistency
> > + * between pages pinned by vfio and pages seen by QEMU. This 
> > is the
> > + * case until unmapped from the IOMMU (e.g., during device 
> > reset).
> > + *
> > + * With malicious guests, we really only care about pinning 
> > more
> > + * memory than expected. RLIMIT_MEMLOCK set for the 
> > user/process can
> > + * never be exceeded and can be used to mitigate this problem.
> > + */
> > +warn_report_once(
> > +"Using vfio with vIOMMUs and coordinated discarding of"
> > +" RAM (e.g., virtio-mem) works, however, malicious"
> > +" guests can 

Re: [PATCH v8 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Alex Williamson
On Mon, 31 Oct 2022 09:56:04 +0800
Cindy Lu  wrote:

> - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
>   change the name to memory_get_xlat_addr(). So we can use this
>   function on other devices, such as vDPA device.
> - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
>   whether the memory is backed by a discard manager. the device can
>   have its own warning.
> 
> Signed-off-by: Cindy Lu 
> ---
>  hw/vfio/common.c  | 101 +++---
>  include/exec/memory.h |   4 ++
>  softmmu/memory.c  |  72 ++
>  3 files changed, 102 insertions(+), 75 deletions(-)

Some changes I'd like to see below, but otherwise

Acked-by: Alex Williamson 

> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index ace9562a9b..5bfd55de86 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -578,86 +578,37 @@ static bool 
> vfio_listener_skipped_section(MemoryRegionSection *section)
>  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> ram_addr_t *ram_addr, bool *read_only)
>  {
> -MemoryRegion *mr;
> -hwaddr xlat;
> -hwaddr len = iotlb->addr_mask + 1;
> -bool writable = iotlb->perm & IOMMU_WO;
> -
> -/*
> - * The IOMMU TLB entry we have just covers translation through
> - * this IOMMU to its immediate target.  We need to translate
> - * it the rest of the way through to memory.
> - */
> -mr = address_space_translate(_space_memory,
> - iotlb->translated_addr,
> - , , writable,
> - MEMTXATTRS_UNSPECIFIED);
> -if (!memory_region_is_ram(mr)) {
> -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> - xlat);
> -return false;
> -} else if (memory_region_has_ram_discard_manager(mr)) {
> -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> -MemoryRegionSection tmp = {
> -.mr = mr,
> -.offset_within_region = xlat,
> -.size = int128_make64(len),
> -};
> -
> +bool mr_has_discard_manager;
> +if (memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> + _has_discard_manager)) {
>  /*
> - * Malicious VMs can map memory into the IOMMU, which is expected
> - * to remain discarded. vfio will pin all pages, populating memory.
> - * Disallow that. vmstate priorities make sure any RamDiscardManager
> - * were already restored before IOMMUs are restored.
> + * if the mr has the discard_manager and the return value of
> + * memory_get_xlat_addr() is ture then we need to warn

s/ture/true/

But then the comment below is really describing why we're generating a
warning, so the above additional comment is mostly just noise.

I'd also prefer to see this as:

{
bool ret, mr_has_discard_manager;

ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
   _has_discard_manager));

if (ret && mr_has_discard_manager) {
// Unmodified comment and warn report from existing code
}

return ret;
}

>   */
> -if (!ram_discard_manager_is_populated(rdm, )) {
> -error_report("iommu map to discarded memory (e.g., unplugged via"
> - " virtio-mem): %"HWADDR_PRIx"",
> - iotlb->translated_addr);
> -return false;
> +if (mr_has_discard_manager) {
> +/*
> + * Malicious VMs might trigger discarding of IOMMU-mapped memory.
> + * The pages will remain pinned inside vfio until unmapped,
> + * resulting in a higher memory consumption than expected. If 
> memory
> + * would get populated again later, there would be an 
> inconsistency
> + * between pages pinned by vfio and pages seen by QEMU. This is 
> the
> + * case until unmapped from the IOMMU (e.g., during device 
> reset).
> + *
> + * With malicious guests, we really only care about pinning more
> + * memory than expected. RLIMIT_MEMLOCK set for the user/process 
> can
> + * never be exceeded and can be used to mitigate this problem.
> + */
> +warn_report_once(
> +"Using vfio with vIOMMUs and coordinated discarding of"
> +" RAM (e.g., virtio-mem) works, however, malicious"
> +" guests can trigger pinning of more memory than"
> +" intended via an IOMMU. It's possible to mitigate "
> +" by setting/adjusting RLIMIT_MEMLOCK.");
>  }
>  
> -/*
> - * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
> - * pages will remain pinned inside vfio until unmapped, resulting in 
> a

[PATCH qemu.git 10/11] hw/timer/imx_epit: fix compare timer update

2022-10-30 Thread ~axelheider
From: Axel Heider 

The compare timer will never fire if the reload value is less
than the compare value, so it must be disabled in this case.
The compare time fire exactly once when the compare value is
less than the current value, but the reload values is less
than the compare value.

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 112 +---
 1 file changed, 64 insertions(+), 48 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 196fc67c30..7dd9f54c9c 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -61,29 +61,12 @@ static const IMXClk imx_epit_clocks[] =  {
 CLK_32k,   /* 11 ipg_clk_32k -- ~32kHz */
 };
 
-/*
- * Must be called from within a ptimer_transaction_begin/commit block
- * for both s->timer_cmp and s->timer_reload.
- */
-static uint32_t imx_epit_set_freq(IMXEPITState *s)
+static uint32_t imx_epit_get_freq(IMXEPITState *s)
 {
-uint32_t clksrc;
-uint32_t prescaler;
-uint32_t freq;
-
-clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
-prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
-
-freq = imx_ccm_get_clock_frequency(s->ccm,
-imx_epit_clocks[clksrc]) / prescaler;
-
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
-}
-return freq;
+uint32_t clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
+uint32_t prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 
CR_PRESCALE_BITS);
+uint32_t f_in = imx_ccm_get_clock_frequency(s->ccm, 
imx_epit_clocks[clksrc]);
+return f_in / prescaler;
 }
 
 static void imx_epit_reset(DeviceState *dev)
@@ -106,7 +89,12 @@ static void imx_epit_reset(DeviceState *dev)
 ptimer_stop(s->timer_cmp);
 ptimer_stop(s->timer_reload);
 /* compute new frequency */
-uint32_t freq = imx_epit_set_freq(s);
+uint32_t freq = imx_epit_get_freq(s);
+DPRINTF("Setting ptimer frequency to %u\n", freq);
+if (freq) {
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
+}
 /* init both timers to EPIT_TIMER_MAX */
 ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
@@ -155,21 +143,51 @@ static uint64_t imx_epit_read(void *opaque, hwaddr 
offset, unsigned size)
 return reg_value;
 }
 
-/* Must be called from ptimer_transaction_begin/commit block for s->timer_cmp 
*/
-static void imx_epit_reload_compare_timer(IMXEPITState *s)
+/*
+ * Must be called from a ptimer_transaction_begin/commit block for
+ * s->timer_cmp, but outside of a transaction block of s->timer_reload,
+ * so the proper counter value is read.
+ */
+static void imx_epit_update_compare_timer(IMXEPITState *s)
 {
-if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
-/* if the compare feature is on and timers are running */
-uint32_t tmp = ptimer_get_count(s->timer_reload);
-uint64_t next;
-if (tmp > s->cmp) {
-/* It'll fire in this round of the timer */
-next = tmp - s->cmp;
-} else { /* catch it next time around */
-next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr);
+int is_oneshot = 0;
+
+/*
+ * The compare time will only be active when the EPIT timer is enabled
+ * (CR_EN), the compare interrupt generation is enabled (CR_OCIEN) and
+ *  the input clock if not off.
+ */
+uint32_t freq = imx_epit_get_freq(s);
+if (!freq || ((s->cr & (CR_EN | CR_OCIEN)) != (CR_EN | CR_OCIEN))) {
+ptimer_stop(s->timer_cmp);
+return;
+}
+
+/* calculate the next timeout for the compare timer. */
+uint64_t tmp = ptimer_get_count(s->timer_reload);
+uint64_t max = (s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr;
+if (s->cmp <= tmp) {
+/* fire in this round */
+tmp -= s->cmp;
+/* if the reload value is less than the compare value, the timer will
+ * only fire once
+ */
+is_oneshot = (s->cmp > max);
+} else {
+/*
+ * fire after a reload - but only if the reload value is equal
+ * or higher than the compare value.
+ */
+if (s->cmp > max) {
+ptimer_stop(s->timer_cmp);
+return;
 }
-ptimer_set_count(s->timer_cmp, next);
+tmp += max - s->cmp;
 }
+
+/* re-initialize the compare timer and run it */
+ptimer_set_count(s->timer_cmp, tmp);
+ptimer_run(s->timer_cmp, is_oneshot);
 }
 
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
@@ -193,7 +211,12 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 ptimer_transaction_begin(s->timer_reload);
 
 if (!(value & CR_SWR)) {
-freq = imx_epit_set_freq(s);
+uint32_t freq = 

[PATCH qemu.git 04/11] hw/timer/imx_epit: remove explicit fields cnt and freq

2022-10-30 Thread ~axelheider
From: Axel Heider 

The CNT register is a read-only register. There is no need to
store it's value, it can be calculated on demand.
The calculated frequency is needed temporarily only.

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 42 +++--
 include/hw/timer/imx_epit.h |  2 --
 2 files changed, 17 insertions(+), 27 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index a79f58c963..37b04a1b53 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -77,23 +77,25 @@ static void imx_epit_update_int(IMXEPITState *s)
  * Must be called from within a ptimer_transaction_begin/commit block
  * for both s->timer_cmp and s->timer_reload.
  */
-static void imx_epit_set_freq(IMXEPITState *s)
+static uint32_t imx_epit_set_freq(IMXEPITState *s)
 {
 uint32_t clksrc;
 uint32_t prescaler;
+uint32_t freq;
 
 clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
 prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
 
-s->freq = imx_ccm_get_clock_frequency(s->ccm,
+freq = imx_ccm_get_clock_frequency(s->ccm,
 imx_epit_clocks[clksrc]) / prescaler;
 
-DPRINTF("Setting ptimer frequency to %u\n", s->freq);
+DPRINTF("Setting ptimer frequency to %u\n", freq);
 
-if (s->freq) {
-ptimer_set_freq(s->timer_reload, s->freq);
-ptimer_set_freq(s->timer_cmp, s->freq);
+if (freq) {
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
 }
+return freq;
 }
 
 static void imx_epit_reset(DeviceState *dev)
@@ -107,18 +109,17 @@ static void imx_epit_reset(DeviceState *dev)
 s->sr = 0;
 s->lr = EPIT_TIMER_MAX;
 s->cmp = 0;
-s->cnt = 0;
 ptimer_transaction_begin(s->timer_cmp);
 ptimer_transaction_begin(s->timer_reload);
 /* stop both timers */
 ptimer_stop(s->timer_cmp);
 ptimer_stop(s->timer_reload);
 /* compute new frequency */
-imx_epit_set_freq(s);
+uint32_t freq = imx_epit_set_freq(s);
 /* init both timers to EPIT_TIMER_MAX */
 ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-if (s->freq && (s->cr & CR_EN)) {
+if (freq && (s->cr & CR_EN)) {
 /* if the timer is still enabled, restart it */
 ptimer_run(s->timer_reload, 0);
 }
@@ -126,13 +127,6 @@ static void imx_epit_reset(DeviceState *dev)
 ptimer_transaction_commit(s->timer_reload);
 }
 
-static uint32_t imx_epit_update_count(IMXEPITState *s)
-{
-s->cnt = ptimer_get_count(s->timer_reload);
-
-return s->cnt;
-}
-
 static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 {
 IMXEPITState *s = IMX_EPIT(opaque);
@@ -156,8 +150,7 @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, 
unsigned size)
 break;
 
 case 4: /* CNT */
-imx_epit_update_count(s);
-reg_value = s->cnt;
+reg_value = ptimer_get_count(s->timer_reload);
 break;
 
 default:
@@ -176,7 +169,7 @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
 {
 if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
 /* if the compare feature is on and timers are running */
-uint32_t tmp = imx_epit_update_count(s);
+uint32_t tmp = ptimer_get_count(s->timer_reload);
 uint64_t next;
 if (tmp > s->cmp) {
 /* It'll fire in this round of the timer */
@@ -190,6 +183,7 @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
 
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
+uint32_t freq = 0;
 uint32_t oldcr = s->cr;
 s->cr = value & 0x03ff;
 if (s->cr & CR_SWR) {
@@ -205,10 +199,10 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 ptimer_transaction_begin(s->timer_reload);
 
 if (!(s->cr & CR_SWR)) {
-imx_epit_set_freq(s);
+freq = imx_epit_set_freq(s);
 }
 
-if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
+if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
 if (s->cr & CR_ENMOD) {
 if (s->cr & CR_RLD) {
 ptimer_set_limit(s->timer_reload, s->lr, 1);
@@ -342,15 +336,13 @@ static const MemoryRegionOps imx_epit_ops = {
 
 static const VMStateDescription vmstate_imx_timer_epit = {
 .name = TYPE_IMX_EPIT,
-.version_id = 2,
-.minimum_version_id = 2,
+.version_id = 3,
+.minimum_version_id = 3,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(cr, IMXEPITState),
 VMSTATE_UINT32(sr, IMXEPITState),
 VMSTATE_UINT32(lr, IMXEPITState),
 VMSTATE_UINT32(cmp, IMXEPITState),
-VMSTATE_UINT32(cnt, IMXEPITState),
-VMSTATE_UINT32(freq, IMXEPITState),
 VMSTATE_PTIMER(timer_reload, IMXEPITState),
 VMSTATE_PTIMER(timer_cmp, IMXEPITState),
 VMSTATE_END_OF_LIST()
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
index 

[PATCH qemu.git 05/11] hw/timer/imx_epit: simplify interrupt logic

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 23 +--
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 37b04a1b53..d21cbf16f6 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -61,18 +61,6 @@ static const IMXClk imx_epit_clocks[] =  {
 CLK_32k,   /* 11 ipg_clk_32k -- ~32kHz */
 };
 
-/*
- * Update interrupt status
- */
-static void imx_epit_update_int(IMXEPITState *s)
-{
-if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
-qemu_irq_raise(s->irq);
-} else {
-qemu_irq_lower(s->irq);
-}
-}
-
 /*
  * Must be called from within a ptimer_transaction_begin/commit block
  * for both s->timer_cmp and s->timer_reload.
@@ -242,7 +230,7 @@ static void imx_epit_write_sr(IMXEPITState *s, uint32_t 
value)
 /* writing 1 to OCIF clears the OCIF bit */
 if (value & 0x01) {
 s->sr = 0;
-imx_epit_update_int(s);
+qemu_irq_lower(s->irq);
 }
 }
 
@@ -320,7 +308,14 @@ static void imx_epit_cmp(void *opaque)
 DPRINTF("sr was %d\n", s->sr);
 
 s->sr = 1;
-imx_epit_update_int(s);
+
+/*
+ * An interrupt is generated only if both the peripheral is enabled and the
+ * interrupt generation is enabled.
+ */
+if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
+qemu_irq_raise(s->irq);
+}
 }
 
 static void imx_epit_reload(void *opaque)
-- 
2.34.5




[PATCH qemu.git 11/11] hw/timer/imx_epit: rework CR write handling

2022-10-30 Thread ~axelheider
From: Axel Heider 

- simplify code, improve comments
- fix https://gitlab.com/qemu-project/qemu/-/issues/1263

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 139 +---
 1 file changed, 65 insertions(+), 74 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 7dd9f54c9c..4a6326b1de 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -69,43 +69,6 @@ static uint32_t imx_epit_get_freq(IMXEPITState *s)
 return f_in / prescaler;
 }
 
-static void imx_epit_reset(DeviceState *dev)
-{
-IMXEPITState *s = IMX_EPIT(dev);
-
-/*
- * Soft reset doesn't touch some bits; hard reset clears them
- */
-s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
-s->sr = 0;
-s->lr = EPIT_TIMER_MAX;
-s->cmp = 0;
-/* clear the interrupt */
-qemu_irq_lower(s->irq);
-
-ptimer_transaction_begin(s->timer_cmp);
-ptimer_transaction_begin(s->timer_reload);
-/* stop both timers */
-ptimer_stop(s->timer_cmp);
-ptimer_stop(s->timer_reload);
-/* compute new frequency */
-uint32_t freq = imx_epit_get_freq(s);
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
-}
-/* init both timers to EPIT_TIMER_MAX */
-ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
-ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-if (freq && (s->cr & CR_EN)) {
-/* if the timer is still enabled, restart it */
-ptimer_run(s->timer_reload, 0);
-}
-ptimer_transaction_commit(s->timer_cmp);
-ptimer_transaction_commit(s->timer_reload);
-}
-
 static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 {
 IMXEPITState *s = IMX_EPIT(opaque);
@@ -192,56 +155,75 @@ static void imx_epit_update_compare_timer(IMXEPITState *s)
 
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
-uint32_t freq = 0;
+ptimer_transaction_begin(s->timer_cmp);
+ptimer_transaction_begin(s->timer_reload);
 
-/* SWR bit is never persisted, it clears itself once reset is done */
 uint32_t oldcr = s->cr;
 s->cr = (value & ~CR_SWR) & 0x03ff;
 
 if (value & CR_SWR) {
-/* handle the reset */
-imx_epit_reset(DEVICE(s));
 /*
- * TODO: could we 'break' here? following operations appear
- * to duplicate the work imx_epit_reset() already did.
+ * Soft reset doesn't touch some bits, just a hard reset clears all
+ * of them. Clearing CLKSRC disables the input clock, which will
+ * happen when we re-init of the timer frequency below.
+ */
+s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
+/*
+ * We have applied the new CR value and then cleared most bits,
+ * thus some bits from the write request are now lost. The TRM
+ * is not clear about the behavior, maybe these bits are to be
+ * applied after the reset (e.g. for selecting a new clock
+ * source). However, it seem this is undefined behavior and a
+ * it's assumed a reset does not try to do anything else.
  */
+s->sr = 0;
+s->lr = EPIT_TIMER_MAX;
+s->cmp = 0;
+/* turn interrupt off since SR and the OCIEN bit is cleared */
+qemu_irq_lower(s->irq);
+/* reset timer limits, set timer values to the limits */
+ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
+ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
 }
 
-ptimer_transaction_begin(s->timer_cmp);
-ptimer_transaction_begin(s->timer_reload);
-
-if (!(value & CR_SWR)) {
-uint32_t freq = imx_epit_get_freq(s);
+/* re-initialize frequency, or turn off timers if input clock is off */
+uint32_t freq = imx_epit_get_freq(s);
+if (freq) {
 DPRINTF("Setting ptimer frequency to %u\n", freq);
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
-}
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
 }
 
-if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
-if (s->cr & CR_ENMOD) {
-uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
-/* set new limit and also set timer to this value right now */
-ptimer_set_limit(s->timer_reload, limit, 1);
-ptimer_set_limit(s->timer_cmp, limit, 1);
-}
-ptimer_run(s->timer_reload, 0);
-imx_epit_update_compare_timer(s);
-} else if (!(s->cr & CR_EN)) {
-/* stop both timers */
-ptimer_stop(s->timer_reload);
+if (!freq || !(s->cr & CR_EN)) {
+/*
+ * The EPIT timer is effectively disabled if it is not enabled or
+ * the input clock is off. In this case we can stop the ptimers.
+   

[PATCH qemu.git 09/11] hw/timer/imx_epit: cleanup CR defines

2022-10-30 Thread ~axelheider
From: Axel Heider 

remove unused defines, add needed defines

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 4 ++--
 include/hw/timer/imx_epit.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 5915d4b3d4..196fc67c30 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -71,8 +71,8 @@ static uint32_t imx_epit_set_freq(IMXEPITState *s)
 uint32_t prescaler;
 uint32_t freq;
 
-clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
-prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
+clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
+prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
 
 freq = imx_ccm_get_clock_frequency(s->ccm,
 imx_epit_clocks[clksrc]) / prescaler;
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
index 2219a426ab..f6d41be7e1 100644
--- a/include/hw/timer/imx_epit.h
+++ b/include/hw/timer/imx_epit.h
@@ -43,7 +43,7 @@
 #define CR_OCIEN(1 << 2)
 #define CR_RLD  (1 << 3)
 #define CR_PRESCALE_SHIFT (4)
-#define CR_PRESCALE_MASK  (0xfff)
+#define CR_PRESCALE_BITS  (12)
 #define CR_SWR  (1 << 16)
 #define CR_IOVW (1 << 17)
 #define CR_DBGEN(1 << 18)
@@ -51,7 +51,7 @@
 #define CR_DOZEN(1 << 20)
 #define CR_STOPEN   (1 << 21)
 #define CR_CLKSRC_SHIFT (24)
-#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
+#define CR_CLKSRC_BITS  (2)
 
 #define EPIT_TIMER_MAX  0XUL
 
-- 
2.34.5




[PATCH qemu.git 00/11] improve hw/timer/imx_epit

2022-10-30 Thread ~axelheider
This is a follow-up on my initial work to fix https://gitlab.com/qemu-
project/qemu/-/issues/1263.
- fix #1263 for CR writes
- fix compare timer update
- software reset clears the interrupt
- do not persist CR.SWR bit
- general code cleanup and comment improvements

Axel Heider (11):
  hw/timer/imx_epit: fix typo in comment
  hw/timer/imx_epit: improve comments
  hw/timer/imx_epit: factor out register write handlers
  hw/timer/imx_epit: remove explicit fields cnt and freq
  hw/timer/imx_epit: simplify interrupt logic
  hw/timer/imx_epit: software reset clears the interrupt
  hw/timer/imx_epit: do not persist CR.SWR bit
  hw/timer/imx_epit: simplify CR.ENMOD handling
  hw/timer/imx_epit: cleanup CR defines
  hw/timer/imx_epit: fix compare timer update
  hw/timer/imx_epit: rework CR write handling

 hw/timer/imx_epit.c | 372 +++-
 include/hw/timer/imx_epit.h |   6 +-
 2 files changed, 200 insertions(+), 178 deletions(-)

-- 
2.34.5



[PATCH qemu.git 06/11] hw/timer/imx_epit: software reset clears the interrupt

2022-10-30 Thread ~axelheider
From: Axel Heider 

---
 hw/timer/imx_epit.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index d21cbf16f6..2e4ff89613 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -97,6 +97,9 @@ static void imx_epit_reset(DeviceState *dev)
 s->sr = 0;
 s->lr = EPIT_TIMER_MAX;
 s->cmp = 0;
+/* clear the interrupt */
+qemu_irq_lower(s->irq);
+
 ptimer_transaction_begin(s->timer_cmp);
 ptimer_transaction_begin(s->timer_reload);
 /* stop both timers */
-- 
2.34.5




[PATCH qemu.git 07/11] hw/timer/imx_epit: do not persist CR.SWR bit

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 2e4ff89613..bba9c87cd4 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -175,9 +175,12 @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
 uint32_t freq = 0;
+
+/* SWR bit is never persisted, it clears itself once reset is done */
 uint32_t oldcr = s->cr;
-s->cr = value & 0x03ff;
-if (s->cr & CR_SWR) {
+s->cr = (value & ~CR_SWR) & 0x03ff;
+
+if (value & CR_SWR) {
 /* handle the reset */
 imx_epit_reset(DEVICE(s));
 /*
@@ -189,7 +192,7 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 ptimer_transaction_begin(s->timer_cmp);
 ptimer_transaction_begin(s->timer_reload);
 
-if (!(s->cr & CR_SWR)) {
+if (!(value & CR_SWR)) {
 freq = imx_epit_set_freq(s);
 }
 
-- 
2.34.5




[PATCH qemu.git 08/11] hw/timer/imx_epit: simplify CR.ENMOD handling

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index bba9c87cd4..5915d4b3d4 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -198,13 +198,10 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 
 if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
 if (s->cr & CR_ENMOD) {
-if (s->cr & CR_RLD) {
-ptimer_set_limit(s->timer_reload, s->lr, 1);
-ptimer_set_limit(s->timer_cmp, s->lr, 1);
-} else {
-ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
-}
+uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
+/* set new limit and also set timer to this value right now */
+ptimer_set_limit(s->timer_reload, limit, 1);
+ptimer_set_limit(s->timer_cmp, limit, 1);
 }
 
 imx_epit_reload_compare_timer(s);
-- 
2.34.5




[PATCH qemu.git 03/11] hw/timer/imx_epit: factor out register write handlers

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 189 
 1 file changed, 103 insertions(+), 86 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index b6c013292f..a79f58c963 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -188,111 +188,128 @@ static void imx_epit_reload_compare_timer(IMXEPITState 
*s)
 }
 }
 
-static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
-   unsigned size)
+static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
-IMXEPITState *s = IMX_EPIT(opaque);
-uint64_t oldcr;
-
-DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
-(uint32_t)value);
-
-switch (offset >> 2) {
-case 0: /* CR */
-
-oldcr = s->cr;
-s->cr = value & 0x03ff;
-if (s->cr & CR_SWR) {
-/* handle the reset */
-imx_epit_reset(DEVICE(s));
-/*
- * TODO: could we 'break' here? following operations appear
- * to duplicate the work imx_epit_reset() already did.
- */
-}
-
-ptimer_transaction_begin(s->timer_cmp);
-ptimer_transaction_begin(s->timer_reload);
+uint32_t oldcr = s->cr;
+s->cr = value & 0x03ff;
+if (s->cr & CR_SWR) {
+/* handle the reset */
+imx_epit_reset(DEVICE(s));
+/*
+ * TODO: could we 'break' here? following operations appear
+ * to duplicate the work imx_epit_reset() already did.
+ */
+}
 
-if (!(s->cr & CR_SWR)) {
-imx_epit_set_freq(s);
-}
+ptimer_transaction_begin(s->timer_cmp);
+ptimer_transaction_begin(s->timer_reload);
 
-if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
-if (s->cr & CR_ENMOD) {
-if (s->cr & CR_RLD) {
-ptimer_set_limit(s->timer_reload, s->lr, 1);
-ptimer_set_limit(s->timer_cmp, s->lr, 1);
-} else {
-ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
-}
-}
+if (!(s->cr & CR_SWR)) {
+imx_epit_set_freq(s);
+}
 
-imx_epit_reload_compare_timer(s);
-ptimer_run(s->timer_reload, 0);
-if (s->cr & CR_OCIEN) {
-ptimer_run(s->timer_cmp, 0);
+if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
+if (s->cr & CR_ENMOD) {
+if (s->cr & CR_RLD) {
+ptimer_set_limit(s->timer_reload, s->lr, 1);
+ptimer_set_limit(s->timer_cmp, s->lr, 1);
 } else {
-ptimer_stop(s->timer_cmp);
-}
-} else if (!(s->cr & CR_EN)) {
-/* stop both timers */
-ptimer_stop(s->timer_reload);
-ptimer_stop(s->timer_cmp);
-} else  if (s->cr & CR_OCIEN) {
-if (!(oldcr & CR_OCIEN)) {
-imx_epit_reload_compare_timer(s);
-ptimer_run(s->timer_cmp, 0);
+ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
+ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 }
+}
+
+imx_epit_reload_compare_timer(s);
+ptimer_run(s->timer_reload, 0);
+if (s->cr & CR_OCIEN) {
+ptimer_run(s->timer_cmp, 0);
 } else {
 ptimer_stop(s->timer_cmp);
 }
+} else if (!(s->cr & CR_EN)) {
+/* stop both timers */
+ptimer_stop(s->timer_reload);
+ptimer_stop(s->timer_cmp);
+} else if (s->cr & CR_OCIEN) {
+if (!(oldcr & CR_OCIEN)) {
+imx_epit_reload_compare_timer(s);
+ptimer_run(s->timer_cmp, 0);
+}
+} else {
+ptimer_stop(s->timer_cmp);
+}
+
+ptimer_transaction_commit(s->timer_cmp);
+ptimer_transaction_commit(s->timer_reload);
+}
+
+static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
+{
+/* writing 1 to OCIF clears the OCIF bit */
+if (value & 0x01) {
+s->sr = 0;
+imx_epit_update_int(s);
+}
+}
+
+static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
+{
+s->lr = value;
+
+ptimer_transaction_begin(s->timer_cmp);
+ptimer_transaction_begin(s->timer_reload);
+if (s->cr & CR_RLD) {
+/* Also set the limit if the LRD bit is set */
+/* If IOVW bit is set then set the timer value */
+ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
+ptimer_set_limit(s->timer_cmp, s->lr, 0);
+} else if (s->cr & CR_IOVW) {
+/* If IOVW bit is set then set the timer value */
+ptimer_set_count(s->timer_reload, s->lr);
+}
+/*
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
+ * the timer interrupt may not fire properly. The commit must happen
+ * 

[PATCH qemu.git 02/11] hw/timer/imx_epit: improve comments

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 06785fe6f6..b6c013292f 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -352,8 +352,18 @@ static void imx_epit_realize(DeviceState *dev, Error 
**errp)
   0x1000);
 sysbus_init_mmio(sbd, >iomem);
 
+/*
+ * The reload timer keeps running when the peripheral is enabled. It is a
+ * kind of wall clock that does not generate any interrupts. The callback
+ * needs to be provided, but it does nothing as the ptimer already supports
+ * all necessary reloading functionality.
+ */
 s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
 
+/*
+ * The compare timer is running only when the peripheral configuration is
+ * in a state that will generate compare interrupts.
+ */
 s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
 }
 
-- 
2.34.5




[PATCH qemu.git 01/11] hw/timer/imx_epit: fix typo in comment

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index ec0fa440d7..06785fe6f6 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -254,7 +254,7 @@ static void imx_epit_write(void *opaque, hwaddr offset, 
uint64_t value,
 break;
 
 case 1: /* SR - ACK*/
-/* writing 1 to OCIF clear the OCIF bit */
+/* writing 1 to OCIF clears the OCIF bit */
 if (value & 0x01) {
 s->sr = 0;
 imx_epit_update_int(s);
-- 
2.34.5




Re: [PATCH v7 1/2] vfio: move function vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
On Mon, 31 Oct 2022 at 01:35, Alex Williamson
 wrote:
>
> On Mon, 31 Oct 2022 00:45:38 +0800
> Cindy Lu  wrote:
>
> > - Move the function vfio_get_xlat_addr to softmmu/memory.c, and
> >   change the name to memory_get_xlat_addr(). So we can use this
> >   function on other devices, such as vDPA device.
> > - Add a new bool arg in this function, which shows whether the memory is
> >   backed by a discard manager. So the device can have its own warning.
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >  hw/vfio/common.c  | 107 +++---
> >  include/exec/memory.h |   4 ++
> >  softmmu/memory.c  |  72 
> >  3 files changed, 104 insertions(+), 79 deletions(-)
> >
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index ace9562a9b..a934262f39 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -573,61 +573,20 @@ static bool 
> > vfio_listener_skipped_section(MemoryRegionSection *section)
> >  */
> > section->offset_within_address_space & (1ULL << 63);
> >  }
> > -
> > -/* Called with rcu_read_lock held.  */
> > -static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > -   ram_addr_t *ram_addr, bool *read_only)
> > +static inline void vfio_mr_discard_manager_warn(bool 
> > mr_has_discard_manager)
> >  {
> > -MemoryRegion *mr;
> > -hwaddr xlat;
> > -hwaddr len = iotlb->addr_mask + 1;
> > -bool writable = iotlb->perm & IOMMU_WO;
> > -
> > -/*
> > - * The IOMMU TLB entry we have just covers translation through
> > - * this IOMMU to its immediate target.  We need to translate
> > - * it the rest of the way through to memory.
> > - */
> > -mr = address_space_translate(_space_memory,
> > - iotlb->translated_addr,
> > - , , writable,
> > - MEMTXATTRS_UNSPECIFIED);
> > -if (!memory_region_is_ram(mr)) {
> > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > - xlat);
> > -return false;
> > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> > -MemoryRegionSection tmp = {
> > -.mr = mr,
> > -.offset_within_region = xlat,
> > -.size = int128_make64(len),
> > -};
> > -
> > -/*
> > - * Malicious VMs can map memory into the IOMMU, which is expected
> > - * to remain discarded. vfio will pin all pages, populating memory.
> > - * Disallow that. vmstate priorities make sure any 
> > RamDiscardManager
> > - * were already restored before IOMMUs are restored.
> > - */
> > -if (!ram_discard_manager_is_populated(rdm, )) {
> > -error_report("iommu map to discarded memory (e.g., unplugged 
> > via"
> > - " virtio-mem): %"HWADDR_PRIx"",
> > - iotlb->translated_addr);
> > -return false;
> > -}
> > -
> > +if (mr_has_discard_manager) {
> >  /*
> > - * Malicious VMs might trigger discarding of IOMMU-mapped memory. 
> > The
> > - * pages will remain pinned inside vfio until unmapped, resulting 
> > in a
> > - * higher memory consumption than expected. If memory would get
> > - * populated again later, there would be an inconsistency between 
> > pages
> > - * pinned by vfio and pages seen by QEMU. This is the case until
> > - * unmapped from the IOMMU (e.g., during device reset).
> > + * Malicious VMs might trigger discarding of IOMMU-mapped memory.
> > + * The pages will remain pinned inside vfio until unmapped,
> > + * resulting in a higher memory consumption than expected. If 
> > memory
> > + * would get populated again later, there would be an inconsistency
> > + * between pages pinned by vfio and pages seen by QEMU. This is the
> > + * case until unmapped from the IOMMU (e.g., during device reset).
> >   *
> > - * With malicious guests, we really only care about pinning more 
> > memory
> > - * than expected. RLIMIT_MEMLOCK set for the user/process can 
> > never be
> > - * exceeded and can be used to mitigate this problem.
> > + * With malicious guests, we really only care about pinning more
> > + * memory than expected. RLIMIT_MEMLOCK set for the user/process 
> > can
> > + * never be exceeded and can be used to mitigate this problem.
> >   */
> >  warn_report_once("Using vfio with vIOMMUs and coordinated 
> > discarding of"
> >   " RAM (e.g., virtio-mem) works, however, 
> > malicious"
> > @@ -635,31 +594,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, 
> > void **vaddr,
> >   " intended 

[PATCH v8 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
- Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
  change the name to memory_get_xlat_addr(). So we can use this
  function on other devices, such as vDPA device.
- Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
  whether the memory is backed by a discard manager. the device can
  have its own warning.

Signed-off-by: Cindy Lu 
---
 hw/vfio/common.c  | 101 +++---
 include/exec/memory.h |   4 ++
 softmmu/memory.c  |  72 ++
 3 files changed, 102 insertions(+), 75 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index ace9562a9b..5bfd55de86 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -578,86 +578,37 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)
 static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only)
 {
-MemoryRegion *mr;
-hwaddr xlat;
-hwaddr len = iotlb->addr_mask + 1;
-bool writable = iotlb->perm & IOMMU_WO;
-
-/*
- * The IOMMU TLB entry we have just covers translation through
- * this IOMMU to its immediate target.  We need to translate
- * it the rest of the way through to memory.
- */
-mr = address_space_translate(_space_memory,
- iotlb->translated_addr,
- , , writable,
- MEMTXATTRS_UNSPECIFIED);
-if (!memory_region_is_ram(mr)) {
-error_report("iommu map to non memory area %"HWADDR_PRIx"",
- xlat);
-return false;
-} else if (memory_region_has_ram_discard_manager(mr)) {
-RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
-MemoryRegionSection tmp = {
-.mr = mr,
-.offset_within_region = xlat,
-.size = int128_make64(len),
-};
-
+bool mr_has_discard_manager;
+if (memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
+ _has_discard_manager)) {
 /*
- * Malicious VMs can map memory into the IOMMU, which is expected
- * to remain discarded. vfio will pin all pages, populating memory.
- * Disallow that. vmstate priorities make sure any RamDiscardManager
- * were already restored before IOMMUs are restored.
+ * if the mr has the discard_manager and the return value of
+ * memory_get_xlat_addr() is ture then we need to warn
  */
-if (!ram_discard_manager_is_populated(rdm, )) {
-error_report("iommu map to discarded memory (e.g., unplugged via"
- " virtio-mem): %"HWADDR_PRIx"",
- iotlb->translated_addr);
-return false;
+if (mr_has_discard_manager) {
+/*
+ * Malicious VMs might trigger discarding of IOMMU-mapped memory.
+ * The pages will remain pinned inside vfio until unmapped,
+ * resulting in a higher memory consumption than expected. If 
memory
+ * would get populated again later, there would be an inconsistency
+ * between pages pinned by vfio and pages seen by QEMU. This is the
+ * case until unmapped from the IOMMU (e.g., during device reset).
+ *
+ * With malicious guests, we really only care about pinning more
+ * memory than expected. RLIMIT_MEMLOCK set for the user/process 
can
+ * never be exceeded and can be used to mitigate this problem.
+ */
+warn_report_once(
+"Using vfio with vIOMMUs and coordinated discarding of"
+" RAM (e.g., virtio-mem) works, however, malicious"
+" guests can trigger pinning of more memory than"
+" intended via an IOMMU. It's possible to mitigate "
+" by setting/adjusting RLIMIT_MEMLOCK.");
 }
 
-/*
- * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
- * pages will remain pinned inside vfio until unmapped, resulting in a
- * higher memory consumption than expected. If memory would get
- * populated again later, there would be an inconsistency between pages
- * pinned by vfio and pages seen by QEMU. This is the case until
- * unmapped from the IOMMU (e.g., during device reset).
- *
- * With malicious guests, we really only care about pinning more memory
- * than expected. RLIMIT_MEMLOCK set for the user/process can never be
- * exceeded and can be used to mitigate this problem.
- */
-warn_report_once("Using vfio with vIOMMUs and coordinated discarding 
of"
- " RAM (e.g., virtio-mem) works, however, malicious"
- " guests can trigger pinning of more memory than"
- 

[PATCH v8 0/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
These patches are to support vIOMMU in vdpa device

changes in V3
1. Move function vfio_get_xlat_addr to memory.c
2. Use the existing memory listener, while the MR is
iommu MR then call the function iommu_region_add/
iommu_region_del

changes in V4
1.make the comments in vfio_get_xlat_addr more general

changes in V5
1. Address the comments in the last version
2. Add a new arg in the function vfio_get_xlat_addr, which shows whether
the memory is backed by a discard manager. So the device can have its
own warning.

changes in V6
move the error_report for the unpopulated discard back to
memeory_get_xlat_addr

changes in V7
organize the error massage to avoid the duplicate information

changes in V8
Organize the code follow the comments in the last version

Cindy Lu (2):
  vfio: move implement of vfio_get_xlat_addr() to memory.c
  vhost-vdpa: add support for vIOMMU

 hw/vfio/common.c   | 101 +++
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/exec/memory.h  |   4 ++
 include/hw/virtio/vhost-vdpa.h |  10 +++
 softmmu/memory.c   |  72 +++
 5 files changed, 224 insertions(+), 86 deletions(-)

-- 
2.34.3




[PATCH v8 2/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
Add support for vIOMMU. add the new function to deal with iommu MR.
- during iommu_region_add register a specific IOMMU notifier,
 and store all notifiers in a list.
- during iommu_region_del, compare and delete the IOMMU notifier from the list

Verified in vp_vdpa and vdpa_sim_net driver

Signed-off-by: Cindy Lu 
---
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/hw/virtio/vhost-vdpa.h |  10 +++
 2 files changed, 122 insertions(+), 11 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3ff9ce3501..dcfaaccfa9 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -26,6 +26,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "hw/virtio/virtio-access.h"
 
 /*
  * Return one past the end of the end of section. Be careful with uint64_t
@@ -44,7 +45,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 uint64_t iova_min,
 uint64_t iova_max)
 {
-Int128 llend;
 
 if ((!memory_region_is_ram(section->mr) &&
  !memory_region_is_iommu(section->mr)) ||
@@ -61,14 +61,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 return true;
 }
 
-llend = vhost_vdpa_section_end(section);
-if (int128_gt(llend, int128_make64(iova_max))) {
-error_report("RAM section out of device range (max=0x%" PRIx64
- ", end addr=0x%" PRIx64 ")",
- iova_max, int128_get64(llend));
-return true;
-}
-
 return false;
 }
 
@@ -173,6 +165,106 @@ static void vhost_vdpa_listener_commit(MemoryListener 
*listener)
 v->iotlb_batch_begin_sent = false;
 }
 
+static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+{
+struct vdpa_iommu *iommu = container_of(n, struct vdpa_iommu, n);
+
+hwaddr iova = iotlb->iova + iommu->iommu_offset;
+struct vhost_vdpa *v = iommu->dev;
+void *vaddr;
+int ret;
+
+if (iotlb->target_as != _space_memory) {
+error_report("Wrong target AS \"%s\", only system memory is allowed",
+ iotlb->target_as->name ? iotlb->target_as->name : "none");
+return;
+}
+RCU_READ_LOCK_GUARD();
+vhost_vdpa_iotlb_batch_begin_once(v);
+
+if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
+bool read_only;
+
+if (!memory_get_xlat_addr(iotlb, , NULL, _only, NULL)) {
+return;
+}
+ret =
+vhost_vdpa_dma_map(v, iova, iotlb->addr_mask + 1, vaddr, 
read_only);
+if (ret) {
+error_report("vhost_vdpa_dma_map(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ", %p) = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, vaddr, ret);
+}
+} else {
+ret = vhost_vdpa_dma_unmap(v, iova, iotlb->addr_mask + 1);
+if (ret) {
+error_report("vhost_vdpa_dma_unmap(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ") = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, ret);
+}
+}
+}
+
+static void vhost_vdpa_iommu_region_add(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+Int128 end;
+int iommu_idx;
+IOMMUMemoryRegion *iommu_mr;
+int ret;
+
+iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+
+iommu = g_malloc0(sizeof(*iommu));
+end =  int128_add(int128_make64(section->offset_within_region),
+section->size);
+end = int128_sub(end, int128_one());
+iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+MEMTXATTRS_UNSPECIFIED);
+
+iommu->iommu_mr = iommu_mr;
+
+iommu_notifier_init(
+>n, vhost_vdpa_iommu_map_notify, IOMMU_NOTIFIER_IOTLB_EVENTS,
+section->offset_within_region, int128_get64(end), iommu_idx);
+iommu->iommu_offset =
+section->offset_within_address_space - section->offset_within_region;
+iommu->dev = v;
+
+ret = memory_region_register_iommu_notifier(section->mr, >n, NULL);
+if (ret) {
+g_free(iommu);
+return;
+}
+
+QLIST_INSERT_HEAD(>iommu_list, iommu, iommu_next);
+memory_region_iommu_replay(iommu->iommu_mr, >n);
+
+return;
+}
+
+static void vhost_vdpa_iommu_region_del(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+
+QLIST_FOREACH(iommu, >iommu_list, iommu_next)
+{
+if (MEMORY_REGION(iommu->iommu_mr) == section->mr &&
+iommu->n.start == section->offset_within_region) {
+memory_region_unregister_iommu_notifier(section->mr, 

Re: [PATCH] ui/cocoa: Support hardware cursor interface

2022-10-30 Thread Akihiko Odaki

On 2022/10/30 19:12, Elliot Nunn wrote:

Akihiko,

Sounds like you've done a lot of work on ui/cocoa, with the goal of
improving the experience with modern Linux guests. My goal is to improve
the experience with antiquated Mac OS 9 guests.


My patch has been only tested with recent Linux, but it certainly should
be ensured that it works well for old systems when upstreaming.

First I'd like to know what display device you use. It looks like
dpy_mouse_set is used only by ati-vga, vhost-user-gpu, virtio-gpu, and
vmware.


I was using my own hardware cursor patches to the VGA device, but now I am
using virtio-gpu. My Mac OS 9 driver for virtio-gpu is in progress.


Interesting, but I'm worried that your driver may be not performant 
enough to drive dpy_mouse_set. Does your driver provide hardware cursor 
as smooth as software cursor? If not, the proper way to fix the problem 
is to fix your driver. Strictly speaking, ignoring dpy_mouse_set and 
using the input information directly violates the semantics and should 
be avoided if possible. That said, if your driver already does the best 
to the extent what Mac OS 9 allows and you want even better, it can be a 
worthwhile option.





1. In absolute pointing mode, re-enable Cocoa's cursor and let the host
OS move it according to user input.
2. Keep the cursor sprite, but move it according to Cocoa's mouse
movement events instead of dpy_mouse_set events.


Also, can you give reasoning while 2 is preferred? 1 would allow to
exploit the hardware's feature for cursor composition, resulting in
smoother experience and a bit less power consumption. But there may be
complications it can cause so I have not decided which one is the better
yet.


Mainly that it would simplify the code. OTOH, if we expect the guest to
use the hardware cursor facility, then it's only fair that the host does
the same. I'm open to either option. We should probably try both.


Regarding the code complexity, option  2 can be still the better option 
because option 1 requires additional code to pass the input information 
to the cursor composition code. But it is just a possibility and I guess 
we will not know which is the better unless we implement them as you say.





And I didn't realise that you had added VirGL support to cocoa.m. Well
done! Is it on track for release?
My patch should be withdrawn from consideration, in favour of a future
solution that does not use cursor warping.


I'm not really pushing my changes hard so it's kind of stale. Perhaps it
is better to rewrite the cursor composition patch in a way that does not
depend on the Virgl patch. I'm also aware that the cursor composition
using Core Graphics is somewhat laggy so it may be better to rewrite it
using subview, Core Animation, Metal, or something else. But I have not
done that yet.


Is there some Cocoa-native way of compositing within the window, that
will work with or without a GL surface? Subviews sound appropriate.


I'm for subview because we can retain the current implementation using 
[-NSView drawRect:] for the screen output in this way. The current 
implementation using Core Graphics or OpenGL for cursor composition 
should be avoided as Core Graphics cannot accelerate it with GPU and 
OpenGL requires the deprecated CGL or an external library like ANGLE.


Regards,
Akihiko Odaki



Not that I have any influence, but I think your virgl patch is an
excellent contribution and should go upstream.

Thanks again,

Elliot




[PATCH] cutils: Fix get_relocated_path on Windows

2022-10-30 Thread Akihiko Odaki
get_relocated_path() did not have error handling for PathCchSkipRoot()
because a path given to get_relocated_path() was expected to be a valid
path containing a drive letter or UNC server/share path elements on
Windows, but sometimes it turned out otherwise.

The paths passed to get_relocated_path() are defined by macros generated
by Meson. Meson in turn uses a prefix given by the configure script to
generate them. For Windows, the script passes /qemu as a prefix to
Meson by default.

As documented in docs/about/build-platforms.rst, typically MSYS2 is used
for the build system, but it is also possible to use Linux as well. When
MSYS2 is used, its Bash variant recognizes /qemu as a MSYS2 path, and
converts it to a Windows path, adding the MSYS2 prefix including a drive
letter or UNC server/share path elements. Such a conversion does not
happen on a shell on Linux however, and /qemu will be passed as is in
the case.

Implement a proper error handling of PathCchSkipRoot() in
get_relocated_path() so that it can handle a path without a drive letter
or UNC server/share path elements.

Reported-by: Stefan Weil 
Signed-off-by: Akihiko Odaki 
---
 util/cutils.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/util/cutils.c b/util/cutils.c
index cb43dda213..932c741d2b 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -1088,17 +1088,21 @@ char *get_relocated_path(const char *dir)
 g_string_append(result, "/qemu-bundle");
 if (access(result->str, R_OK) == 0) {
 #ifdef G_OS_WIN32
-size_t size = mbsrtowcs(NULL, , 0, &(mbstate_t){0}) + 1;
+const char *src = dir;
+size_t size = mbsrtowcs(NULL, , 0, &(mbstate_t){0}) + 1;
 PWSTR wdir = g_new(WCHAR, size);
-mbsrtowcs(wdir, , size, &(mbstate_t){0});
+mbsrtowcs(wdir, , size, &(mbstate_t){0});
 
 PCWSTR wdir_skipped_root;
-PathCchSkipRoot(wdir, _skipped_root);
+if (PathCchSkipRoot(wdir, _skipped_root)) {
+g_string_append(result, dir);
+} else {
+size = wcsrtombs(NULL, _skipped_root, 0, &(mbstate_t){0});
+char *cursor = result->str + result->len;
+g_string_set_size(result, result->len + size);
+wcsrtombs(cursor, _skipped_root, size + 1, &(mbstate_t){0});
+}
 
-size = wcsrtombs(NULL, _skipped_root, 0, &(mbstate_t){0});
-char *cursor = result->str + result->len;
-g_string_set_size(result, result->len + size);
-wcsrtombs(cursor, _skipped_root, size + 1, &(mbstate_t){0});
 g_free(wdir);
 #else
 g_string_append(result, dir);
-- 
2.38.1




Re: [PATCH 4/5] target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:53 AM Anup Patel  wrote:
>
> The time CSR will wrap-around immediately after reaching UINT64_MAX
> so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
> in riscv_timer_write_timecmp().

I'm not clear what this is fixing?

If the guest sets a timer for UINT64_MAX shouldn't that still trigger
an event at some point?

Alistair

>
> Signed-off-by: Anup Patel 
> ---
>  target/riscv/time_helper.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
> index 4fb2a471a9..1ee9f94813 100644
> --- a/target/riscv/time_helper.c
> +++ b/target/riscv/time_helper.c
> @@ -72,6 +72,14 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer 
> *timer,
>  riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
>  }
>
> +/*
> + * Don't re-start the QEMU timer when timecmp == UINT64_MAX because
> + * time CSR will wrap-around immediately after reaching UINT64_MAX.
> + */
> +if (timecmp == UINT64_MAX) {
> +return;
> +}
> +
>  /* otherwise, set up the future timer interrupt */
>  diff = timecmp - rtc_r;
>  /* back to ns (note args switched in muldiv64) */
> --
> 2.34.1
>
>



Re: [PATCH 3/5] target/riscv: Don't clear mask in riscv_cpu_update_mip() for VSTIP

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:52 AM Anup Patel  wrote:
>
> Instead of clearing mask in riscv_cpu_update_mip() for VSTIP, we
> should call riscv_cpu_update_mip() with mask == 0 from timer_helper.c
> for VSTIP.
>
> Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c  |  2 --
>  target/riscv/time_helper.c | 12 
>  2 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 5d66246c2c..a403825e49 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -617,8 +617,6 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t 
> mask, uint64_t value)
>  vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
>  }
>
> -/* No need to update mip for VSTIP */
> -mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
>  vstip = env->vstime_irq ? MIP_VSTIP : 0;
>
>  if (!qemu_mutex_iothread_locked()) {
> diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
> index 8cce667dfd..4fb2a471a9 100644
> --- a/target/riscv/time_helper.c
> +++ b/target/riscv/time_helper.c
> @@ -27,7 +27,7 @@ static void riscv_vstimer_cb(void *opaque)
>  RISCVCPU *cpu = opaque;
>  CPURISCVState *env = >env;
>  env->vstime_irq = 1;
> -riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
> +riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
>  }
>
>  static void riscv_stimer_cb(void *opaque)
> @@ -57,16 +57,20 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer 
> *timer,
>   */
>  if (timer_irq == MIP_VSTIP) {
>  env->vstime_irq = 1;
> +riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
> +} else {
> +riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
>  }
> -riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
>  return;
>  }
>
> +/* Clear the [VS|S]TIP bit in mip */
>  if (timer_irq == MIP_VSTIP) {
>  env->vstime_irq = 0;
> +riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(0));
> +} else {
> +riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
>  }
> -/* Clear the [V]STIP bit in mip */
> -riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
>
>  /* otherwise, set up the future timer interrupt */
>  diff = timecmp - rtc_r;
> --
> 2.34.1
>
>



Re: [PATCH 2/5] target/riscv: Update VS timer whenever htimedelta changes

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:52 AM Anup Patel  wrote:
>
> The htimedelta[h] CSR has impact on the VS timer comparison so we
> should call riscv_timer_write_timecmp() whenever htimedelta changes.
>
> Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 716f9d960e..4b1a608260 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2722,6 +2722,8 @@ static RISCVException read_htimedelta(CPURISCVState 
> *env, int csrno,
>  static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
> target_ulong val)
>  {
> +RISCVCPU *cpu = env_archcpu(env);
> +
>  if (!env->rdtime_fn) {
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
> @@ -2731,6 +2733,12 @@ static RISCVException write_htimedelta(CPURISCVState 
> *env, int csrno,
>  } else {
>  env->htimedelta = val;
>  }
> +
> +if (cpu->cfg.ext_sstc && env->rdtime_fn) {
> +riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
> +  env->htimedelta, MIP_VSTIP);
> +}
> +
>  return RISCV_EXCP_NONE;
>  }
>
> @@ -2748,11 +2756,19 @@ static RISCVException read_htimedeltah(CPURISCVState 
> *env, int csrno,
>  static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
>  target_ulong val)
>  {
> +RISCVCPU *cpu = env_archcpu(env);
> +
>  if (!env->rdtime_fn) {
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
>
>  env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
> +
> +if (cpu->cfg.ext_sstc && env->rdtime_fn) {
> +riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
> +  env->htimedelta, MIP_VSTIP);
> +}
> +
>  return RISCV_EXCP_NONE;
>  }
>
> --
> 2.34.1
>
>



Re: [PATCH 1/5] target/riscv: Typo fix in sstc() predicate

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:52 AM Anup Patel  wrote:
>
> We should use "&&" instead of "&" when checking hcounteren.TM and
> henvcfg.STCE bits.
>
> Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 5c9a7ee287..716f9d960e 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -838,7 +838,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
>  }
>
>  if (riscv_cpu_virt_enabled(env)) {
> -if (!(get_field(env->hcounteren, COUNTEREN_TM) &
> +if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
>get_field(env->henvcfg, HENVCFG_STCE))) {
>  return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>  }
> --
> 2.34.1
>
>



Re: [PATCH 1/3] tcg/sparc: Remove support for sparc32plus

2022-10-30 Thread Richard Henderson

On 10/31/22 04:21, Philippe Mathieu-Daudé wrote:

On 30/10/22 16:45, Peter Maydell wrote:

-#define TCG_TARGET_REG_BITS 64


Why do we delete this?


We get the default definition from include/tcg/tcg.h:

   58 /* Default target word size to pointer size.  */
   59 #ifndef TCG_TARGET_REG_BITS
   60 # if UINTPTR_MAX == UINT32_MAX
   61 #  define TCG_TARGET_REG_BITS 32
   62 # elif UINTPTR_MAX == UINT64_MAX
   63 #  define TCG_TARGET_REG_BITS 64


Exactly.


r~




Re: [PATCH 1/3] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-10-30 Thread Richard Henderson

On 10/29/22 13:00, Jiaxun Yang wrote:

As per "Loongson-2F processor user manual", CP0St_{KX, SX, UX}
should is not writeable and hardcoded to 1.

Without those bits set, kernel is unable to access XKPHYS address
segmant. So just set them up on CPU reset.

Signed-off-by: Jiaxun Yang
---
  target/mips/cpu.c | 6 ++
  1 file changed, 6 insertions(+)


Based on down-thread discussion of the manual:
Acked-by: Richard Henderson 


r~



Re: [PATCH] MAINTAINERS: Inherit from nanoMIPS

2022-10-30 Thread Richard Henderson

On 10/31/22 09:50, Philippe Mathieu-Daudé wrote:

6 months ago Stefan Pejic stepped in as nanoMIPS maintainer
(see commit a 8e0e23445a "target/mips: Undeprecate nanoMIPS
ISA support in QEMU"), however today his email is bouncing:

   ** Message blocked **

   Your message tostefan.pe...@syrmia.com  has been blocked. See technical 
details below for more information.

   The response from the remote server was:
   550 5.4.1 Recipient address rejected: Access denied. AS(201806281) 
[DBAEUR03FT030.eop-EUR03.prod.protection.outlook.com]

To avoid unmaintained code, I feel forced to merge this code
back with the generic MIPS section.

Historical references:
-https://lore.kernel.org/qemu-devel/ty0pr03mb679726901bd6c6be40114a2fe2...@ty0pr03mb6797.apcprd03.prod.outlook.com/
-https://lore.kernel.org/qemu-devel/b858a20e97b74e7b90a94948314d0...@mtkmbs62n2.mediatek.inc/

Cc: Vince Del Vecchio
Signed-off-by: Philippe Mathieu-Daudé
---
  MAINTAINERS | 8 +---
  1 file changed, 1 insertion(+), 7 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 3/3] target/mips: Disable DSP ASE for Octeon68XX

2022-10-30 Thread Richard Henderson

On 10/29/22 13:00, Jiaxun Yang wrote:

I don't have access to Octeon68XX hardware but accroading to
my investigation Octeon never had DSP ASE support.

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" CP0C3_DSPP is reserved bit and read as 0. Also I do have
access to a Ubiquiti Edgerouter 4 which has Octeon CN7130 processor
and I can confirm CP0C3_DSPP is read as 0 on that processor.

Further more, in linux kernel:
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
cpu_has_dsp is overridden as 0.

So I believe we shouldn't emulate DSP in QEMU as well.

Signed-off-by: Jiaxun Yang
---
  target/mips/cpu-defs.c.inc | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


Acked-by: Richard Henderson 

r~



Re: [PATCH] tcg/tci: fix logic error when registering helpers via FFI

2022-10-30 Thread Richard Henderson

On 10/29/22 11:44, Icenowy Zheng wrote:

Ah I think this is a C99 feature. Is our C standard baseline high
enough to use it?


Yes, we use C2011.  See the second line of meson.build:

default_options: ... 'c_std=gnu11'


r~



Re: [PATCH 1/3] tcg/sparc: Remove support for sparc32plus

2022-10-30 Thread Richard Henderson

On 10/31/22 02:45, Peter Maydell wrote:

+/* We only support generating code for 64-bit mode.  */
+#ifndef __arch64__
+#error "unsupported code generation mode"


We might as well be more specific:
"no support for generating code for 32-bit SPARC"
(though I guess that configure ought in theory to prevent us getting here
in that situation ?)


Yes, after patch 2 configure should prevent it.


r~



[PATCH] MAINTAINERS: Inherit from nanoMIPS

2022-10-30 Thread Philippe Mathieu-Daudé
6 months ago Stefan Pejic stepped in as nanoMIPS maintainer
(see commit a 8e0e23445a "target/mips: Undeprecate nanoMIPS
ISA support in QEMU"), however today his email is bouncing:

  ** Message blocked **

  Your message to stefan.pe...@syrmia.com has been blocked. See technical 
details below for more information.

  The response from the remote server was:
  550 5.4.1 Recipient address rejected: Access denied. AS(201806281) 
[DBAEUR03FT030.eop-EUR03.prod.protection.outlook.com]

To avoid unmaintained code, I feel forced to merge this code
back with the generic MIPS section.

Historical references:
- 
https://lore.kernel.org/qemu-devel/ty0pr03mb679726901bd6c6be40114a2fe2...@ty0pr03mb6797.apcprd03.prod.outlook.com/
- 
https://lore.kernel.org/qemu-devel/b858a20e97b74e7b90a94948314d0...@mtkmbs62n2.mediatek.inc/

Cc: Vince Del Vecchio 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 32e495e165..0ba3b589bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -239,16 +239,10 @@ R: Jiaxun Yang 
 R: Aleksandar Rikalo 
 S: Odd Fixes
 F: target/mips/
-F: disas/mips.c
+F: disas/*mips.c
 F: docs/system/cpu-models-mips.rst.inc
 F: tests/tcg/mips/
 
-MIPS TCG CPUs (nanoMIPS ISA)
-M: Stefan Pejic 
-S: Maintained
-F: disas/nanomips.*
-F: target/mips/tcg/*nanomips*
-
 NiosII TCG CPUs
 M: Chris Wulff 
 M: Marek Vasut 
-- 
2.37.3




[PULL 50/55] hw/isa/piix4: Add missing initialization

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

PIIX3 clears its reset control register, so do the same in PIIX4.

Signed-off-by: Bernhard Beschow 
Message-Id: <20221022150508.26830-28-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index e05e65d3bc..9126eb9edf 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -140,6 +140,8 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xab] = 0x00;
 pci_conf[0xac] = 0x00;
 pci_conf[0xae] = 0x00;
+
+d->rcr = 0;
 }
 
 static int piix4_post_load(void *opaque, int version_id)
-- 
2.37.3




[PULL 36/55] disas/nanomips: Replace Cpp enums for C enums

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Change enums to typedef enums to keep naming clear.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-23-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 1832c2d3cf..8b4bc910a4 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -40,16 +40,16 @@ typedef uint32_t uint32;
 typedef uint16_t uint16;
 typedef uint64_t img_address;
 
-enum TABLE_ENTRY_TYPE {
+typedef enum  {
 instruction,
 call_instruction,
 branch_instruction,
 return_instruction,
 reserved_block,
 pool,
-};
+} TABLE_ENTRY_TYPE;
 
-enum TABLE_ATTRIBUTE_TYPE {
+typedef enum {
 MIPS64_= 0x0001,
 XNP_   = 0x0002,
 XMMS_  = 0x0004,
@@ -67,7 +67,7 @@ enum TABLE_ATTRIBUTE_TYPE {
 TLB_   = 0x4000,
 MVH_   = 0x8000,
 ALL_ATTRIBUTES = 0xull,
-};
+} TABLE_ATTRIBUTE_TYPE;
 
 typedef struct Dis_info {
   img_address m_pc;
-- 
2.37.3




[PULL 46/55] hw/ide/piix: Introduce TYPE_ macros for PIIX IDE controllers

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Suggested-by: Mark Cave-Ayland 
Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-9-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c | 3 ++-
 hw/ide/piix.c | 5 +++--
 hw/isa/piix4.c| 3 ++-
 include/hw/ide/piix.h | 7 +++
 4 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 include/hw/ide/piix.h

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7a55b9ca8e..0ad0ed1603 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -40,6 +40,7 @@
 #include "hw/usb.h"
 #include "net/net.h"
 #include "hw/ide/pci.h"
+#include "hw/ide/piix.h"
 #include "hw/irq.h"
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
@@ -259,7 +260,7 @@ static void pc_init1(MachineState *machine,
 if (pcmc->pci_enabled) {
 PCIDevice *dev;
 
-dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide");
+dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE);
 pci_ide_create_devs(dev);
 idebus[0] = qdev_get_child_bus(>qdev, "ide.0");
 idebus[1] = qdev_get_child_bus(>qdev, "ide.1");
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index de1f4f0efb..267dbf37db 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -36,6 +36,7 @@
 #include "sysemu/blockdev.h"
 #include "sysemu/dma.h"
 
+#include "hw/ide/piix.h"
 #include "hw/ide/pci.h"
 #include "trace.h"
 
@@ -202,7 +203,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix3_ide_info = {
-.name  = "piix3-ide",
+.name  = TYPE_PIIX3_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= piix3_ide_class_init,
 };
@@ -224,7 +225,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix4_ide_info = {
-.name  = "piix4-ide",
+.name  = TYPE_PIIX4_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= piix4_ide_class_init,
 };
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index c88d3bf3bf..e05e65d3bc 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -28,6 +28,7 @@
 #include "hw/irq.h"
 #include "hw/southbridge/piix.h"
 #include "hw/pci/pci.h"
+#include "hw/ide/piix.h"
 #include "hw/isa/isa.h"
 #include "hw/intc/i8259.h"
 #include "hw/dma/i8257.h"
@@ -277,7 +278,7 @@ static void piix4_init(Object *obj)
 PIIX4State *s = PIIX4_PCI_DEVICE(obj);
 
 object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
-object_initialize_child(obj, "ide", >ide, "piix4-ide");
+object_initialize_child(obj, "ide", >ide, TYPE_PIIX4_IDE);
 object_initialize_child(obj, "uhci", >uhci, "piix4-usb-uhci");
 
 object_initialize_child(obj, "pm", >pm, TYPE_PIIX4_PM);
diff --git a/include/hw/ide/piix.h b/include/hw/ide/piix.h
new file mode 100644
index 00..ef3ef3d62d
--- /dev/null
+++ b/include/hw/ide/piix.h
@@ -0,0 +1,7 @@
+#ifndef HW_IDE_PIIX_H
+#define HW_IDE_PIIX_H
+
+#define TYPE_PIIX3_IDE "piix3-ide"
+#define TYPE_PIIX4_IDE "piix4-ide"
+
+#endif /* HW_IDE_PIIX_H */
-- 
2.37.3




[PULL 49/55] hw/isa/Kconfig: Fix dependencies of piix4 southbridge

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Signed-off-by: Bernhard Beschow 
Message-Id: <20221022150508.26830-27-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 configs/devices/mips-softmmu/common.mak | 1 -
 hw/isa/Kconfig  | 6 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index d2202c839e..416161f833 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -23,7 +23,6 @@ CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
-CONFIG_IDE_PIIX=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_I8259=y
 CONFIG_MC146818RTC=y
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 60aad28800..18b5c6bf3f 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -40,7 +40,13 @@ config PIIX4
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for PIIX4.
+select ACPI_PIIX4
+select I8254
+select I8257
+select I8259
+select IDE_PIIX
 select ISA_BUS
+select MC146818RTC
 select USB_UHCI
 
 config VT82C686
-- 
2.37.3




[PULL 47/55] hw/isa/piix3: Remove unused include

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Ammends commit 988fb613215993dd0ce642b89ca8182c479d39dd.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-19-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 0bea4aefe7..808fd4eadf 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -30,7 +30,6 @@
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
-#include "sysemu/xen.h"
 #include "sysemu/runstate.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/acpi_aml_interface.h"
-- 
2.37.3




[PULL 38/55] disas/nanomips: Rename nanomips.cpp to nanomips.c

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Now that everything has been converted to C code the nanomips.cpp file
has been renamed. Therefore, meson.build file is also changed.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-25-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/meson.build  | 2 +-
 disas/{nanomips.cpp => nanomips.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename disas/{nanomips.cpp => nanomips.c} (100%)

diff --git a/disas/meson.build b/disas/meson.build
index ba22f7cbcd..1977f5cd92 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -5,7 +5,7 @@ common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c'))
 common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
 common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
 common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c'))
-common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp'))
+common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.c'))
 common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
 common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c'))
 common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
diff --git a/disas/nanomips.cpp b/disas/nanomips.c
similarity index 100%
rename from disas/nanomips.cpp
rename to disas/nanomips.c
-- 
2.37.3




[PULL 41/55] hw/isa/piix3: Remove extra ';' outside of functions

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Fixes the "extra-semi" clang-tidy check.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-4-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 44a9998752..04895ce2e5 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -375,7 +375,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
  piix3, PIIX_NUM_PIRQS);
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
-};
+}
 
 static void piix3_class_init(ObjectClass *klass, void *data)
 {
@@ -410,7 +410,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp)
  */
 pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq,
  piix3, XEN_PIIX_NUM_PIRQS);
-};
+}
 
 static void piix3_xen_class_init(ObjectClass *klass, void *data)
 {
@@ -418,7 +418,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void 
*data)
 
 k->config_write = piix3_write_config_xen;
 k->realize = piix3_xen_realize;
-};
+}
 
 static const TypeInfo piix3_xen_info = {
 .name  = TYPE_PIIX3_XEN_DEVICE,
-- 
2.37.3




[PULL 52/55] hw/mips/boston: Don't set link_up for xilinx-pcie

2022-10-30 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

PCIe port 0 and 1 had link_up set as false previously,
that makes those two ports effectively useless. It can
be annoying for users to find that the device they plug
on those buses won't work at all.

As link_up is true by default, just don't set it again in
boston platform code.

Signed-off-by: Jiaxun Yang 
Message-Id: <20221024143540.97545-1-jiaxun.y...@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/boston.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index d2ab9da1a0..aa7942bbc0 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -424,7 +424,7 @@ static inline XilinxPCIEHost *
 xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
  hwaddr cfg_base, uint64_t cfg_size,
  hwaddr mmio_base, uint64_t mmio_size,
- qemu_irq irq, bool link_up)
+ qemu_irq irq)
 {
 DeviceState *dev;
 MemoryRegion *cfg, *mmio;
@@ -436,7 +436,6 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
 qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
 qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
 qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
-qdev_prop_set_bit(dev, "link_up", link_up);
 
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 
@@ -729,21 +728,21 @@ static void boston_mach_init(MachineState *machine)
  boston_memmap[BOSTON_PCIE0].size,
  boston_memmap[BOSTON_PCIE0_MMIO].base,
  boston_memmap[BOSTON_PCIE0_MMIO].size,
- get_cps_irq(>cps, 2), false);
+ get_cps_irq(>cps, 2));
 
 xilinx_pcie_init(sys_mem, 1,
  boston_memmap[BOSTON_PCIE1].base,
  boston_memmap[BOSTON_PCIE1].size,
  boston_memmap[BOSTON_PCIE1_MMIO].base,
  boston_memmap[BOSTON_PCIE1_MMIO].size,
- get_cps_irq(>cps, 1), false);
+ get_cps_irq(>cps, 1));
 
 pcie2 = xilinx_pcie_init(sys_mem, 2,
  boston_memmap[BOSTON_PCIE2].base,
  boston_memmap[BOSTON_PCIE2].size,
  boston_memmap[BOSTON_PCIE2_MMIO].base,
  boston_memmap[BOSTON_PCIE2_MMIO].size,
- get_cps_irq(>cps, 0), true);
+ get_cps_irq(>cps, 0));
 
 platreg = g_new(MemoryRegion, 1);
 memory_region_init_io(platreg, NULL, _platreg_ops, s,
-- 
2.37.3




[PULL 45/55] hw/isa/piix4: Rename wrongly named method

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

This method post-loads the southbridge, not the IDE device.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-8-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 15f344dbb7..c88d3bf3bf 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -141,7 +141,7 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xae] = 0x00;
 }
 
-static int piix4_ide_post_load(void *opaque, int version_id)
+static int piix4_post_load(void *opaque, int version_id)
 {
 PIIX4State *s = opaque;
 
@@ -156,7 +156,7 @@ static const VMStateDescription vmstate_piix4 = {
 .name = "PIIX4",
 .version_id = 3,
 .minimum_version_id = 2,
-.post_load = piix4_ide_post_load,
+.post_load = piix4_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_PCI_DEVICE(dev, PIIX4State),
 VMSTATE_UINT8_V(rcr, PIIX4State, 3),
-- 
2.37.3




[PULL 30/55] disas/nanomips: Remove IMMEDIATE functions

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Both versions of IMMEDIATE functions have been removed.

Before this patch, we'd been calling img_format twice, the first time
through the IMMEDIATE to get an appropriate string and the second time
to print that string. There's no more need for that. Therefore, calls to
IMMEDIATE are removed, and now we're directly printing the integer
values instead.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-17-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 756 -
 1 file changed, 265 insertions(+), 491 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index e4e122f3cf..3b1ca249ce 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -519,18 +519,6 @@ static const char *AC(uint64 reg)
 }
 
 
-static char *IMMEDIATE(uint64 value)
-{
-return img_format("0x%" PRIx64, value);
-}
-
-
-static char *IMMEDIATE(int64 value)
-{
-return img_format("%" PRId64, value);
-}
-
-
 static char *CPR(uint64 reg)
 {
 /* needs more work */
@@ -1674,11 +1662,10 @@ static char *ACLR(uint64 instruction, Dis_info *info)
 uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
 int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction);
 
-char *bit = IMMEDIATE(bit_value);
-char *s = IMMEDIATE(s_value);
 const char *rs = GPR(rs_value);
 
-return img_format("ACLR %s, %s(%s)", bit, s, rs);
+return img_format("ACLR 0x%" PRIx64 ", %" PRId64 "(%s)",
+  bit_value, s_value, rs);
 }
 
 
@@ -1772,9 +1759,8 @@ static char *ADDIU_32_(uint64 instruction, Dis_info *info)
 
 const char *rt = GPR(rt_value);
 const char *rs = GPR(rs_value);
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, %s, %s", rt, rs, u);
+return img_format("ADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value);
 }
 
 
@@ -1793,9 +1779,8 @@ static char *ADDIU_48_(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = IMMEDIATE(s_value);
 
-return img_format("ADDIU %s, %s", rt, s);
+return img_format("ADDIU %s, %" PRId64, rt, s_value);
 }
 
 
@@ -1814,9 +1799,8 @@ static char *ADDIU_GP48_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = IMMEDIATE(s_value);
 
-return img_format("ADDIU %s, $%d, %s", rt, 28, s);
+return img_format("ADDIU %s, $%d, %" PRId64, rt, 28, s_value);
 }
 
 
@@ -1835,9 +1819,8 @@ static char *ADDIU_GP_B_(uint64 instruction, Dis_info 
*info)
 uint64 u_value = extract_u_17_to_0(instruction);
 
 const char *rt = GPR(rt_value);
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, $%d, %s", rt, 28, u);
+return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value);
 }
 
 
@@ -1856,9 +1839,8 @@ static char *ADDIU_GP_W_(uint64 instruction, Dis_info 
*info)
 uint64 u_value = extract_u_20_to_2__s2(instruction);
 
 const char *rt = GPR(rt_value);
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, $%d, %s", rt, 28, u);
+return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value);
 }
 
 
@@ -1879,9 +1861,9 @@ static char *ADDIU_NEG_(uint64 instruction, Dis_info 
*info)
 
 const char *rt = GPR(rt_value);
 const char *rs = GPR(rs_value);
-char *u = IMMEDIATE(neg_copy(u_value));
+int64 u = neg_copy(u_value);
 
-return img_format("ADDIU %s, %s, %s", rt, rs, u);
+return img_format("ADDIU %s, %s, %" PRId64, rt, rs, u);
 }
 
 
@@ -1900,9 +1882,8 @@ static char *ADDIU_R1_SP_(uint64 instruction, Dis_info 
*info)
 uint64 rt3_value = extract_rt3_9_8_7(instruction);
 
 const char *rt3 = GPR(decode_gpr_gpr3(rt3_value));
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, $%d, %s", rt3, 29, u);
+return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt3, 29, u_value);
 }
 
 
@@ -1923,9 +1904,8 @@ static char *ADDIU_R2_(uint64 instruction, Dis_info *info)
 
 const char *rt3 = GPR(decode_gpr_gpr3(rt3_value));
 const char *rs3 = GPR(decode_gpr_gpr3(rs3_value));
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, %s, %s", rt3, rs3, u);
+return img_format("ADDIU %s, %s, 0x%" PRIx64, rt3, rs3, u_value);
 }
 
 
@@ -1943,9 +1923,8 @@ static char *ADDIU_RS5_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se3_4_2_1_0(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = IMMEDIATE(s_value);
 
-return img_format("ADDIU %s, %s", rt, s);
+return img_format("ADDIU %s, %" PRId64, rt, s_value);
 }
 
 
@@ -2513,9 +2492,9 @@ static char *ANDI_16_(uint64 instruction, Dis_info *info)
 
 const char *rt3 = GPR(decode_gpr_gpr3(rt3_value));
 const char *rs3 = GPR(decode_gpr_gpr3(rs3_value));
-char *eu = 

[PULL 13/55] hw/isa/vt82c686: Create rtc-time alias in boards instead

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

According to good QOM practice, an object should only deal with objects
of its own sub tree. Having devices create an alias on the machine
object doesn't respect this good practice. To resolve this, create the
alias in the machine's code.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-14-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c   | 2 --
 hw/mips/fuloong2e.c | 4 
 hw/ppc/pegasos2.c   | 4 
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 48cd4d0036..3f9bd0c04d 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -632,8 +632,6 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 if (!qdev_realize(DEVICE(>rtc), BUS(isa_bus), errp)) {
 return;
 }
-object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(>rtc),
-  "date");
 isa_connect_gpio_out(ISA_DEVICE(>rtc), 0, s->rtc.isairq);
 
 for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 3c46215616..b478483706 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -295,6 +295,10 @@ static void mips_fuloong2e_init(MachineState *machine)
 pci_dev = pci_create_simple_multifunction(pci_bus,
   PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
   true, TYPE_VT82C686B_ISA);
+object_property_add_alias(OBJECT(machine), "rtc-time",
+  object_resolve_path_component(OBJECT(pci_dev),
+"rtc"),
+  "date");
 qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]);
 
 dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 474723ee27..49809b2b75 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -161,6 +161,10 @@ static void pegasos2_init(MachineState *machine)
 /* VIA VT8231 South Bridge (multifunction PCI device) */
 via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
   TYPE_VT8231_ISA);
+object_property_add_alias(OBJECT(machine), "rtc-time",
+  object_resolve_path_component(OBJECT(via),
+"rtc"),
+  "date");
 qdev_connect_gpio_out(DEVICE(via), 0,
   qdev_get_gpio_in_named(pm->mv, "gpp", 31));
 
-- 
2.37.3




[PULL 43/55] hw/isa/piix3: Modernize reset handling

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Rather than registering the reset handler via a function which
appends the handler to a global list, prefer to implement it as
a virtual method - PIIX4 does the same already.

Note that this means that piix3_reset can now also be called writing to
the relevant configuration space register on a PCI bridge.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-6-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 72dbf688d9..723ad0a896 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -31,7 +31,6 @@
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
 #include "sysemu/xen.h"
-#include "sysemu/reset.h"
 #include "sysemu/runstate.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/acpi_aml_interface.h"
@@ -156,9 +155,9 @@ static void piix3_write_config_xen(PCIDevice *dev,
 piix3_write_config(dev, address, val, len);
 }
 
-static void piix3_reset(void *opaque)
+static void piix3_reset(DeviceState *dev)
 {
-PIIX3State *d = opaque;
+PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 uint8_t *pci_conf = d->dev.config;
 
 pci_conf[0x04] = 0x07; /* master, memory and I/O */
@@ -313,8 +312,6 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
-qemu_register_reset(piix3_reset, d);
-
 i8257_dma_init(isa_bus, 0);
 }
 
@@ -337,6 +334,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
 
+dc->reset   = piix3_reset;
 dc->desc= "ISA bridge";
 dc->vmsd= _piix3;
 dc->hotpluggable   = false;
-- 
2.37.3




[PULL 51/55] hw/isa/piix4: Move pci_ide_create_devs() call to board code

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

For the VIA south bridges there was a comment to have the call in board code.
Move it there for PIIX4 as well for consistency.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-29-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c  |  1 -
 hw/mips/malta.c | 10 ++
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 9126eb9edf..8fc1db6dc9 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -257,7 +257,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(>ide), BUS(pci_bus), errp)) {
 return;
 }
-pci_ide_create_devs(PCI_DEVICE(>ide));
 
 /* USB */
 qdev_prop_set_int32(DEVICE(>uhci), "addr", dev->devfn + 2);
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 6ac811763c..5a4e2abbdf 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -39,7 +39,7 @@
 #include "hw/pci/pci.h"
 #include "qemu/log.h"
 #include "hw/mips/bios.h"
-#include "hw/ide.h"
+#include "hw/ide/pci.h"
 #include "hw/irq.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -1400,11 +1400,13 @@ void mips_malta_init(MachineState *machine)
 /* Southbridge */
 piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true,
 TYPE_PIIX4_PCI_DEVICE);
-dev = DEVICE(piix4);
-isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
+
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide"));
+pci_ide_create_devs(PCI_DEVICE(dev));
 
 /* Interrupt controller */
-qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
+qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq);
 
 /* generate SPD EEPROM data */
 dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
-- 
2.37.3




[PULL 48/55] hw/mips/malta: Reuse dev variable

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

While at it, move the assignments closer to where they are used.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-26-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/malta.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 5099ed9592..6ac811763c 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1237,7 +1237,6 @@ void mips_malta_init(MachineState *machine)
 MaltaState *s;
 PCIDevice *piix4;
 DeviceState *dev;
-DeviceState *pm_dev;
 
 s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA));
 sysbus_realize_and_unref(SYS_BUS_DEVICE(s), _fatal);
@@ -1403,13 +1402,13 @@ void mips_malta_init(MachineState *machine)
 TYPE_PIIX4_PCI_DEVICE);
 dev = DEVICE(piix4);
 isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
-pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm"));
-smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c"));
 
 /* Interrupt controller */
 qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
 
 /* generate SPD EEPROM data */
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
+smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
 generate_eeprom_spd(_eeprom_buf[0 * 256], ram_size);
 generate_eeprom_serial(_eeprom_buf[6 * 256]);
 smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
-- 
2.37.3




[PULL 40/55] hw/i386/pc: Create DMA controllers in south bridges

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Just like in the real hardware (and in PIIX4), create the DMA
controllers in the south bridges.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-2-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c  | 3 ---
 hw/i386/pc_piix.c | 2 ++
 hw/isa/Kconfig| 2 ++
 hw/isa/lpc_ich9.c | 3 +++
 hw/isa/piix3.c| 9 +++--
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 768982ae9a..b39ecd4d0c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -47,7 +47,6 @@
 #include "multiboot.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/intc/i8259.h"
-#include "hw/dma/i8257.h"
 #include "hw/timer/i8254.h"
 #include "hw/input/i8042.h"
 #include "hw/irq.h"
@@ -1320,8 +1319,6 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 pcspk_init(pcms->pcspk, isa_bus, pit);
 }
 
-i8257_dma_init(isa_bus, 0);
-
 /* Super I/O */
 pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled,
 pcms->vmport != ON_OFF_AUTO_ON);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 0b1a79c0fa..7a55b9ca8e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -26,6 +26,7 @@
 #include CONFIG_DEVICES
 
 #include "qemu/units.h"
+#include "hw/dma/i8257.h"
 #include "hw/loader.h"
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
@@ -225,6 +226,7 @@ static void pc_init1(MachineState *machine,
 pci_bus = NULL;
 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
   _abort);
+i8257_dma_init(isa_bus, 0);
 pcms->hpet_enabled = false;
 }
 isa_bus_irqs(isa_bus, x86ms->gsi);
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 20de7e9294..60aad28800 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -33,6 +33,7 @@ config PC87312
 
 config PIIX3
 bool
+select I8257
 select ISA_BUS
 
 config PIIX4
@@ -68,6 +69,7 @@ config LPC_ICH9
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for ICH9.
+select I8257
 select ISA_BUS
 select ACPI_SMBUS
 select ACPI_X86_ICH
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 4553b5925b..8694e58b21 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -34,6 +34,7 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qemu/range.h"
+#include "hw/dma/i8257.h"
 #include "hw/isa/isa.h"
 #include "migration/vmstate.h"
 #include "hw/irq.h"
@@ -722,6 +723,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
 qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS);
 
 isa_bus_irqs(isa_bus, lpc->gsi);
+
+i8257_dma_init(isa_bus, 0);
 }
 
 static bool ich9_rst_cnt_needed(void *opaque)
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 48f9ab1096..44a9998752 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "qemu/range.h"
 #include "qapi/error.h"
+#include "hw/dma/i8257.h"
 #include "hw/southbridge/piix.h"
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
@@ -295,9 +296,11 @@ static const MemoryRegionOps rcr_ops = {
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 {
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+ISABus *isa_bus;
 
-if (!isa_bus_new(DEVICE(d), get_system_memory(),
- pci_address_space_io(dev), errp)) {
+isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+  pci_address_space_io(dev), errp);
+if (!isa_bus) {
 return;
 }
 
@@ -307,6 +310,8 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 PIIX_RCR_IOPORT, >rcr_mem, 1);
 
 qemu_register_reset(piix3_reset, d);
+
+i8257_dma_init(isa_bus, 0);
 }
 
 static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope)
-- 
2.37.3




[PULL 44/55] hw/isa/piix3: Prefer pci_address_space() over get_system_memory()

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

get_system_memory() accesses global state while pci_address_space() uses
whatever has been passed to the device instance, so avoid the global.
Moreover, PIIX4 uses pci_address_space() here as well.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-7-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 723ad0a896..0bea4aefe7 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -301,7 +301,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 ISABus *isa_bus;
 
-isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
   pci_address_space_io(dev), errp);
 if (!isa_bus) {
 return;
-- 
2.37.3




[PULL 14/55] hw: Remove unused MAX_IDE_BUS define

2022-10-30 Thread Philippe Mathieu-Daudé
From: BALATON Zoltan 

Several machines have an unused MAX_IDE_BUS define. Remove it from
these machines that don't need it.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220917115136.a32ef746...@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/alpha/dp264.c| 2 --
 hw/hppa/machine.c   | 2 --
 hw/mips/fuloong2e.c | 1 -
 hw/mips/malta.c | 2 --
 hw/ppc/prep.c   | 2 --
 hw/sparc64/sun4u.c  | 1 -
 6 files changed, 10 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f4349eba83..c502c8c62a 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -20,8 +20,6 @@
 #include "qemu/datadir.h"
 #include "net/net.h"
 
-#define MAX_IDE_BUS 2
-
 static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
 {
 if (((addr >> 41) & 3) == 2) {
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index e53d5f0fa7..355b3aac2e 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -30,8 +30,6 @@
 #include "qemu/log.h"
 #include "net/net.h"
 
-#define MAX_IDE_BUS 2
-
 #define MIN_SEABIOS_HPPA_VERSION 6 /* require at least this fw version */
 
 #define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index b478483706..50c61f0e4a 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -49,7 +49,6 @@
 
 /* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */
 #define BIOS_SIZE   (512 * KiB)
-#define MAX_IDE_BUS 2
 
 /*
  * PMON is not part of qemu and released with BSD license, anyone
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 0e932988e0..5099ed9592 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -69,8 +69,6 @@
 
 #define FLASH_SIZE  0x40
 
-#define MAX_IDE_BUS 2
-
 typedef struct {
 MemoryRegion iomem;
 MemoryRegion iomem_lo; /* 0 - 0x900 */
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f08714f2ec..fcbe4c5837 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -50,8 +50,6 @@
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
 
-#define MAX_IDE_BUS 2
-
 #define CFG_ADDR 0xf510
 
 #define KERNEL_LOAD_ADDR 0x0100
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 0e27715ac4..387181ff77 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -66,7 +66,6 @@
 #define PBM_PCI_IO_BASE  (PBM_SPECIAL_BASE + 0x0200ULL)
 #define PROM_FILENAME"openbios-sparc64"
 #define NVRAM_SIZE   0x2000
-#define MAX_IDE_BUS  2
 #define BIOS_CFG_IOPORT  0x510
 #define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
 #define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
-- 
2.37.3




[PULL 39/55] disas/mips: Fix branch displacement for BEQZC and BNEZC

2022-10-30 Thread Philippe Mathieu-Daudé
From: David Daney 

disas/mips.c got added in commit 6643d27ea0 ("MIPS disas support")
apparently based on binutils tag 'gdb_6_1-branchpoint' [1].
Back then, MIPSr6 was not supported (added in binutils commit
7361da2c952 during 2014 [2]).

Binutils codebase diverged so much over the last 18 years, it is
not possible to simply cherry-pick their changes, so fix it BEQZC /
BNEZC 21-bit signed branch displacement locally.

[1] 
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=opcodes/mips-dis.c;hb=refs/tags/gdb_6_1-branchpoint
[2] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7361da2c952

Fixes: 31837be3ee ("target-mips: add compact and CP1 branches")
Signed-off-by: David Daney 
Reviewed-by: Marcin Nowakowski 
[PMD: Added commit description]
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20221014112322.61119-1-phi...@fungible.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/mips.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index b9a5204304..5aacacb2c8 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public 
License
 along with this program; if not, see .  */
 
 #include "qemu/osdep.h"
+#include "qemu/bitops.h"
 #include "disas/dis-asm.h"
 
 /* mips.h.  Mips opcode list for GDB, the GNU debugger.
@@ -1334,9 +1335,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"balc","+p",   0xe800, 0xfc00, UBD|WR_31,0, 
I32R6},
 {"bc",  "+p",   0xc800, 0xfc00, UBD|WR_31,0, 
I32R6},
 {"jic", "t,o",  0xd800, 0xffe0, UBD|RD_t, 0, 
I32R6},
-{"beqzc",   "s,+p", 0xd800, 0xfc00, CBD|RD_s, 0, 
I32R6},
+{"beqzc",   "s,+q", 0xd800, 0xfc00, CBD|RD_s, 0, 
I32R6},
 {"jialc",   "t,o",  0xf800, 0xffe0, UBD|RD_t, 0, 
I32R6},
-{"bnezc",   "s,+p", 0xf800, 0xfc00, CBD|RD_s, 0, 
I32R6},
+{"bnezc",   "s,+q", 0xf800, 0xfc00, CBD|RD_s, 0, 
I32R6},
 {"beqzalc", "s,t,p",0x2000, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
 {"bovc","s,t,p",0x2000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
 {"beqc","s,t,p",0x2000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
@@ -4462,6 +4463,13 @@ print_insn_args (const char *d,
 (*info->print_address_func) (info->target, info);
 break;
 
+case 'q':
+/* Sign extend the displacement with 21 bits.  */
+delta = sextract32(l, OP_SH_DELTA, 21);
+info->target = (delta << 2) + pc + INSNLEN;
+(*info->print_address_func) (info->target, info);
+break;
+
case 't': /* Coprocessor 0 reg name */
  (*info->fprintf_func) (info->stream, "%s",
 mips_cp0_names[(l >> OP_SH_RT) &
-- 
2.37.3




[PULL 42/55] hw/isa/piix3: Add size constraints to rcr_ops

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

According to the PIIX3 datasheet, the reset control register is one byte in 
size.
Moreover, PIIX4 has it, so add it to PIIX3 as well.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-5-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 04895ce2e5..72dbf688d9 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -290,7 +290,11 @@ static uint64_t rcr_read(void *opaque, hwaddr addr, 
unsigned len)
 static const MemoryRegionOps rcr_ops = {
 .read = rcr_read,
 .write = rcr_write,
-.endianness = DEVICE_LITTLE_ENDIAN
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
 };
 
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
-- 
2.37.3




[PULL 33/55] disas/nanomips: Remove function overloading

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Disassemble function that calls the other variant of it is deleted.
Where it is called, now we're directly calling the other implementation.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-20-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index ce93fdad62..85f5784770 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -21917,12 +21917,6 @@ static const Pool MAJOR[2] = {
0x0 },/* P16 */
 };
 
-static int Disassemble(const uint16 *data, char **dis,
-   TABLE_ENTRY_TYPE & type, Dis_info *info)
-{
-return Disassemble(data, dis, type, MAJOR, 2, info);
-}
-
 static int nanomips_dis(char **buf,
  Dis_info *info,
  unsigned short one,
@@ -21932,7 +21926,7 @@ static int nanomips_dis(char **buf,
 uint16 bits[3] = {one, two, three};
 
 TABLE_ENTRY_TYPE type;
-int size = Disassemble(bits, buf, type, info);
+int size = Disassemble(bits, buf, type, MAJOR, 2, info);
 return size;
 }
 
-- 
2.37.3




[PULL 35/55] disas/nanomips: Replace exception handling

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Since there's no support for exception handling in C, the try-catch
blocks have been deleted, and throw clauses are replaced. When a runtime
error happens, we're printing out the error message. Disassembling of
the current instruction interrupts. This behavior is achieved by adding
sigsetjmp() to discard further disassembling after the error message
prints and by adding the siglongjmp() function to imitate throwing an
error. The goal was to maintain the same output as it was.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-22-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 100 -
 1 file changed, 45 insertions(+), 55 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 73329462ee..1832c2d3cf 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -31,7 +31,6 @@
 #include "disas/dis-asm.h"
 
 #include 
-#include 
 #include 
 #include 
 
@@ -133,10 +132,9 @@ static uint64 renumber_registers(uint64 index, uint64 
*register_list,
 return register_list[index];
 }
 
-throw std::runtime_error(img_format(
-   "Invalid register mapping index %" PRIu64
-   ", size of list = %zu",
-   index, register_list_size));
+info->fprintf_func(info->stream, "Invalid register mapping index %" PRIu64
+   ", size of list = %zu", index, register_list_size);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -466,8 +464,9 @@ static const char *GPR(uint64 reg, Dis_info *info)
 return gpr_reg[reg];
 }
 
-throw std::runtime_error(img_format("Invalid GPR register index %" PRIu64,
- reg));
+info->fprintf_func(info->stream, "Invalid GPR register index %" PRIu64,
+   reg);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -503,8 +502,9 @@ static const char *FPR(uint64 reg, Dis_info *info)
 return fpr_reg[reg];
 }
 
-throw std::runtime_error(img_format("Invalid FPR register index %" PRIu64,
- reg));
+info->fprintf_func(info->stream, "Invalid FPR register index %" PRIu64,
+   reg);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -518,8 +518,9 @@ static const char *AC(uint64 reg, Dis_info *info)
 return ac_reg[reg];
 }
 
-throw std::runtime_error(img_format("Invalid AC register index %" PRIu64,
- reg));
+info->fprintf_func(info->stream, "Invalid AC register index %" PRIu64,
+   reg);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -562,55 +563,38 @@ static int Disassemble(const uint16 *data, char **dis,
  TABLE_ENTRY_TYPE & type, const Pool *table,
  int table_size, Dis_info *info)
 {
-try
-{
-for (int i = 0; i < table_size; i++) {
-uint64 op_code = extract_op_code_value(data,
- table[i].instructions_size);
-if ((op_code & table[i].mask) == table[i].value) {
-/* possible match */
-conditional_function cond = table[i].condition;
-if ((cond == NULL) || cond(op_code)) {
-try
-{
-if (table[i].type == pool) {
-return Disassemble(data, dis, type,
-   table[i].next_table,
-   table[i].next_table_size,
-   info);
-} else if ((table[i].type == instruction) ||
-   (table[i].type == call_instruction) ||
-   (table[i].type == branch_instruction) ||
-   (table[i].type == return_instruction)) {
-disassembly_function dis_fn = table[i].disassembly;
-if (dis_fn == 0) {
-*dis = g_strdup(
-"disassembler failure - bad table entry");
-return -6;
-}
-type = table[i].type;
-*dis = dis_fn(op_code, info);
-return table[i].instructions_size;
-} else {
-*dis = g_strdup("reserved instruction");
-return -2;
-}
-}
-catch (std::runtime_error & e)
-{
-*dis = g_strdup(e.what());
-return -3;  /* runtime error */
+for (int i = 0; i < table_size; i++) {
+uint64 op_code = extract_op_code_value(data,
+  

[PULL 32/55] disas/nanomips: Prevent memory leaking

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

g_autofree attribute is added for every dynamically allocated string to
prevent memory leaking.

The implementation of the several functions that work with dynamically
allocated strings is slightly changed so we can add those attributes.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-19-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 96 --
 1 file changed, 51 insertions(+), 45 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 3a3a9a9b69..ce93fdad62 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -1937,7 +1937,7 @@ static char *ADDIUPC_32_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se21_0_20_to_1_s1(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("ADDIUPC %s, %s", rt, s);
 }
@@ -1959,7 +1959,7 @@ static char *ADDIUPC_48_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 6, info);
+g_autofree char *s = ADDRESS(s_value, 6, info);
 
 return img_format("ADDIUPC %s, %s", rt, s);
 }
@@ -2417,7 +2417,7 @@ static char *ALUIPC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s);
 }
@@ -2574,7 +2574,7 @@ static char *BALC_16_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 2, info);
+g_autofree char *s = ADDRESS(s_value, 2, info);
 
 return img_format("BALC %s", s);
 }
@@ -2594,7 +2594,7 @@ static char *BALC_32_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se25_0_24_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BALC %s", s);
 }
@@ -2639,7 +2639,7 @@ static char *BBEQZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BBEQZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s);
 }
@@ -2662,7 +2662,7 @@ static char *BBNEZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BBNEZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s);
 }
@@ -2682,7 +2682,7 @@ static char *BC_16_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 2, info);
+g_autofree char *s = ADDRESS(s_value, 2, info);
 
 return img_format("BC %s", s);
 }
@@ -2702,7 +2702,7 @@ static char *BC_32_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se25_0_24_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC %s", s);
 }
@@ -2724,7 +2724,7 @@ static char *BC1EQZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
 const char *ft = FPR(ft_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC1EQZC %s, %s", ft, s);
 }
@@ -2746,7 +2746,7 @@ static char *BC1NEZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
 const char *ft = FPR(ft_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC1NEZC %s, %s", ft, s);
 }
@@ -2767,7 +2767,7 @@ static char *BC2EQZC(uint64 instruction, Dis_info *info)
 uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC2EQZC CP%" PRIu64 ", %s", ct_value, s);
 }
@@ -2788,7 +2788,7 @@ static char *BC2NEZC(uint64 instruction, Dis_info *info)
 uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return 

[PULL 37/55] disas/nanomips: Remove argument passing by ref

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Replaced argument passing by reference with passing by address.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-24-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 8b4bc910a4..9647f1a8e3 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -560,7 +560,7 @@ static uint64 extract_op_code_value(const uint16 *data, int 
size)
  *  disassembly string  - on error will constain error string
  */
 static int Disassemble(const uint16 *data, char **dis,
- TABLE_ENTRY_TYPE & type, const Pool *table,
+ TABLE_ENTRY_TYPE *type, const Pool *table,
  int table_size, Dis_info *info)
 {
 for (int i = 0; i < table_size; i++) {
@@ -585,7 +585,7 @@ static int Disassemble(const uint16 *data, char **dis,
 "disassembler failure - bad table entry");
 return -6;
 }
-type = table[i].type;
+*type = table[i].type;
 *dis = dis_fn(op_code, info);
 return table[i].instructions_size;
 } else {
@@ -21914,7 +21914,7 @@ static int nanomips_dis(char **buf,
 uint16 bits[3] = {one, two, three};
 
 TABLE_ENTRY_TYPE type;
-int size = Disassemble(bits, buf, type, MAJOR, 2, info);
+int size = Disassemble(bits, buf, , MAJOR, 2, info);
 return size;
 }
 
-- 
2.37.3




[PULL 19/55] disas/nanomips: Remove helper methods from class

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Helper methods from NMD class like NMD::renumber_registers,
NMD::decode_gpr_gpr4... etc. are removed from the class. They're now
declared global static functions.

Following helper methods have been deleted because they're not used by
the nanomips disassembler:
- NMD::encode_msbd_from_pos_and_size,
- NMD::encode_s_from_s_hi,
- NMD::neg_copy

Global functions used by those methods:
- nanomips_dis
- sign_extend
- extract_bits
have also been defined as static global functions.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-6-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 328 +
 disas/nanomips.h   | 144 
 2 files changed, 154 insertions(+), 318 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 9005f26ee3..271afcde07 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -41,7 +41,7 @@
 #define IMGASSERTONCE(test)
 
 
-int nanomips_dis(char *buf,
+static int nanomips_dis(char *buf,
  Dis_info *info,
  unsigned short one,
  unsigned short two,
@@ -259,20 +259,20 @@ std::string to_string(img_address a)
 }
 
 
-uint64 extract_bits(uint64 data, uint32 bit_offset, uint32 bit_size)
+static uint64 extract_bits(uint64 data, uint32 bit_offset, uint32 bit_size)
 {
 return (data << (64 - (bit_size + bit_offset))) >> (64 - bit_size);
 }
 
 
-int64 sign_extend(int64 data, int msb)
+static int64 sign_extend(int64 data, int msb)
 {
 uint64 shift = 63 - msb;
 return (data << shift) >> shift;
 }
 
 
-uint64 NMD::renumber_registers(uint64 index, uint64 *register_list,
+static uint64 renumber_registers(uint64 index, uint64 *register_list,
size_t register_list_size)
 {
 if (index < register_list_size) {
@@ -287,7 +287,7 @@ uint64 NMD::renumber_registers(uint64 index, uint64 
*register_list,
 
 
 /*
- * NMD::decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type
+ * decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type
  *
  *   Map a 4-bit code to the 5-bit register space according to this pattern:
  *
@@ -312,7 +312,7 @@ uint64 NMD::renumber_registers(uint64 index, uint64 
*register_list,
  * - MUL[4X4]
  * - SW[4X4]
  */
-uint64 NMD::decode_gpr_gpr4(uint64 d)
+static uint64 decode_gpr_gpr4(uint64 d)
 {
 static uint64 register_list[] = {  8,  9, 10, 11,  4,  5,  6,  7,
   16, 17, 18, 19, 20, 21, 22, 23 };
@@ -322,7 +322,7 @@ uint64 NMD::decode_gpr_gpr4(uint64 d)
 
 
 /*
- * NMD::decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type
+ * decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type
  *
  *   Map a 4-bit code to the 5-bit register space according to this pattern:
  *
@@ -348,7 +348,7 @@ uint64 NMD::decode_gpr_gpr4(uint64 d)
  * - MOVEP
  * - SW[4X4]
  */
-uint64 NMD::decode_gpr_gpr4_zero(uint64 d)
+static uint64 decode_gpr_gpr4_zero(uint64 d)
 {
 static uint64 register_list[] = {  8,  9, 10,  0,  4,  5,  6,  7,
   16, 17, 18, 19, 20, 21, 22, 23 };
@@ -358,7 +358,7 @@ uint64 NMD::decode_gpr_gpr4_zero(uint64 d)
 
 
 /*
- * NMD::decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type
+ * decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type
  *
  *   Map a 3-bit code to the 5-bit register space according to this pattern:
  *
@@ -407,7 +407,7 @@ uint64 NMD::decode_gpr_gpr4_zero(uint64 d)
  * - SW[16]
  * - XOR[16]
  */
-uint64 NMD::decode_gpr_gpr3(uint64 d)
+static uint64 decode_gpr_gpr3(uint64 d)
 {
 static uint64 register_list[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
 return renumber_registers(d, register_list,
@@ -416,7 +416,7 @@ uint64 NMD::decode_gpr_gpr3(uint64 d)
 
 
 /*
- * NMD::decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding
+ * decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding
  * type
  *
  *   Map a 3-bit code to the 5-bit register space according to this pattern:
@@ -447,7 +447,7 @@ uint64 NMD::decode_gpr_gpr3(uint64 d)
  * - SW[16]
  * - SW[GP16]
  */
-uint64 NMD::decode_gpr_gpr3_src_store(uint64 d)
+static uint64 decode_gpr_gpr3_src_store(uint64 d)
 {
 static uint64 register_list[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
 return renumber_registers(d, register_list,
@@ -456,7 +456,7 @@ uint64 NMD::decode_gpr_gpr3_src_store(uint64 d)
 
 
 /*
- * NMD::decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type
+ * decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type
  *
  *   Map a 2-bit code to the 5-bit register space according to this pattern:
  *
@@ -477,7 +477,7 @@ uint64 NMD::decode_gpr_gpr3_src_store(uint64 d)
  * - MOVEP
  * - MOVEP[REV]
  */
-uint64 NMD::decode_gpr_gpr2_reg1(uint64 d)
+static uint64 decode_gpr_gpr2_reg1(uint64 d)
 {
 static uint64 

[PULL 24/55] disas/nanomips: Move typedefs etc to nanomips.cpp

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

The following is moved from the nanomips.h to nanomips.cpp file:
- #include line
- typedefs
- enums
- definition of the Pool struct.
Header file nanomips.h will be deleted to be consistent with the rest of
the disas/ code.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-11-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 57 +-
 disas/nanomips.h   | 57 --
 2 files changed, 56 insertions(+), 58 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 0d67462e5d..7d09fd1a69 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -36,7 +36,62 @@
 #include 
 #include 
 
-#include "nanomips.h"
+#include 
+
+typedef int64_t int64;
+typedef uint64_t uint64;
+typedef uint32_t uint32;
+typedef uint16_t uint16;
+typedef uint64_t img_address;
+
+enum TABLE_ENTRY_TYPE {
+instruction,
+call_instruction,
+branch_instruction,
+return_instruction,
+reserved_block,
+pool,
+};
+
+enum TABLE_ATTRIBUTE_TYPE {
+MIPS64_= 0x0001,
+XNP_   = 0x0002,
+XMMS_  = 0x0004,
+EVA_   = 0x0008,
+DSP_   = 0x0010,
+MT_= 0x0020,
+EJTAG_ = 0x0040,
+TLBINV_= 0x0080,
+CP0_   = 0x0100,
+CP1_   = 0x0200,
+CP2_   = 0x0400,
+UDI_   = 0x0800,
+MCU_   = 0x1000,
+VZ_= 0x2000,
+TLB_   = 0x4000,
+MVH_   = 0x8000,
+ALL_ATTRIBUTES = 0xull,
+};
+
+typedef struct Dis_info {
+  img_address m_pc;
+} Dis_info;
+
+typedef bool (*conditional_function)(uint64 instruction);
+typedef std::string (*disassembly_function)(uint64 instruction,
+Dis_info *info);
+
+typedef struct Pool {
+TABLE_ENTRY_TYPE type;
+const struct Pool*next_table;
+int  next_table_size;
+int  instructions_size;
+uint64   mask;
+uint64   value;
+disassembly_function disassembly;
+conditional_function condition;
+uint64   attributes;
+} Pool;
 
 #define IMGASSERTONCE(test)
 
diff --git a/disas/nanomips.h b/disas/nanomips.h
index 47b44af751..0fd7299900 100644
--- a/disas/nanomips.h
+++ b/disas/nanomips.h
@@ -23,61 +23,4 @@
 #ifndef DISAS_NANOMIPS_H
 #define DISAS_NANOMIPS_H
 
-#include 
-
-typedef int64_t int64;
-typedef uint64_t uint64;
-typedef uint32_t uint32;
-typedef uint16_t uint16;
-typedef uint64_t img_address;
-
-enum TABLE_ENTRY_TYPE {
-instruction,
-call_instruction,
-branch_instruction,
-return_instruction,
-reserved_block,
-pool,
-};
-
-enum TABLE_ATTRIBUTE_TYPE {
-MIPS64_= 0x0001,
-XNP_   = 0x0002,
-XMMS_  = 0x0004,
-EVA_   = 0x0008,
-DSP_   = 0x0010,
-MT_= 0x0020,
-EJTAG_ = 0x0040,
-TLBINV_= 0x0080,
-CP0_   = 0x0100,
-CP1_   = 0x0200,
-CP2_   = 0x0400,
-UDI_   = 0x0800,
-MCU_   = 0x1000,
-VZ_= 0x2000,
-TLB_   = 0x4000,
-MVH_   = 0x8000,
-ALL_ATTRIBUTES = 0xull,
-};
-
-typedef struct Dis_info {
-  img_address m_pc;
-} Dis_info;
-
-typedef bool (*conditional_function)(uint64 instruction);
-typedef std::string (*disassembly_function)(uint64 instruction,
-Dis_info *info);
-
-typedef struct Pool {
-TABLE_ENTRY_TYPE type;
-const struct Pool*next_table;
-int  next_table_size;
-int  instructions_size;
-uint64   mask;
-uint64   value;
-disassembly_function disassembly;
-conditional_function condition;
-uint64   attributes;
-} Pool;
-
 #endif
-- 
2.37.3




[PULL 26/55] disas/nanomips: Remove #include

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

 is a C++ library and it's not used by disassembler.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-13-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 7d09fd1a69..4b49630b8b 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -32,7 +32,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 
-- 
2.37.3




[PULL 31/55] disas/nanomips: Remove CPR function

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

CPR functions has been removed.

Before this patch, we'd been calling img_format twice, the first time
through the CPR function to get an appropriate string and the second
time to print that formatted string. There's no more need for that.
Therefore, calls to CPR are removed, and now we're directly printing
"CP" and integer value instead.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-18-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 110 +++--
 1 file changed, 45 insertions(+), 65 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 3b1ca249ce..3a3a9a9b69 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -519,13 +519,6 @@ static const char *AC(uint64 reg)
 }
 
 
-static char *CPR(uint64 reg)
-{
-/* needs more work */
-return img_format("CP%" PRIu64, reg);
-}
-
-
 static char *ADDRESS(uint64 value, int instruction_size, Dis_info *info)
 {
 /* token for string replace */
@@ -2774,10 +2767,9 @@ static char *BC2EQZC(uint64 instruction, Dis_info *info)
 uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
-char *ct = CPR(ct_value);
 char *s = ADDRESS(s_value, 4, info);
 
-return img_format("BC2EQZC %s, %s", ct, s);
+return img_format("BC2EQZC CP%" PRIu64 ", %s", ct_value, s);
 }
 
 
@@ -2796,10 +2788,9 @@ static char *BC2NEZC(uint64 instruction, Dis_info *info)
 uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
-char *ct = CPR(ct_value);
 char *s = ADDRESS(s_value, 4, info);
 
-return img_format("BC2NEZC %s, %s", ct, s);
+return img_format("BC2NEZC CP%" PRIu64 ", %s", ct_value, s);
 }
 
 
@@ -3403,9 +3394,8 @@ static char *CFC1(uint64 instruction, Dis_info *info)
 uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *cs = CPR(cs_value);
 
-return img_format("CFC1 %s, %s", rt, cs);
+return img_format("CFC1 %s, CP%" PRIu64, rt, cs_value);
 }
 
 
@@ -3425,9 +3415,8 @@ static char *CFC2(uint64 instruction, Dis_info *info)
 uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *cs = CPR(cs_value);
 
-return img_format("CFC2 %s, %s", rt, cs);
+return img_format("CFC2 %s, CP%" PRIu64, rt, cs_value);
 }
 
 
@@ -4889,9 +4878,8 @@ static char *CTC1(uint64 instruction, Dis_info *info)
 uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *cs = CPR(cs_value);
 
-return img_format("CTC1 %s, %s", rt, cs);
+return img_format("CTC1 %s, CP%" PRIu64, rt, cs_value);
 }
 
 
@@ -4911,9 +4899,8 @@ static char *CTC2(uint64 instruction, Dis_info *info)
 uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *cs = CPR(cs_value);
 
-return img_format("CTC2 %s, %s", rt, cs);
+return img_format("CTC2 %s, CP%" PRIu64, rt, cs_value);
 }
 
 
@@ -5745,9 +5732,9 @@ static char *DMFC0(uint64 instruction, Dis_info *info)
 uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
 
 const char *rt = GPR(rt_value);
-char *c0s = CPR(c0s_value);
 
-return img_format("DMFC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value);
+return img_format("DMFC0 %s, CP%" PRIu64 ", 0x%" PRIx64,
+  rt, c0s_value, sel_value);
 }
 
 
@@ -5789,9 +5776,8 @@ static char *DMFC2(uint64 instruction, Dis_info *info)
 uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *cs = CPR(cs_value);
 
-return img_format("DMFC2 %s, %s", rt, cs);
+return img_format("DMFC2 %s, CP%" PRIu64, rt, cs_value);
 }
 
 
@@ -5812,9 +5798,9 @@ static char *DMFGC0(uint64 instruction, Dis_info *info)
 uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
 
 const char *rt = GPR(rt_value);
-char *c0s = CPR(c0s_value);
 
-return img_format("DMFGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value);
+return img_format("DMFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64,
+  rt, c0s_value, sel_value);
 }
 
 
@@ -5883,9 +5869,9 @@ static char *DMTC0(uint64 instruction, Dis_info *info)
 uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
 
 const char *rt = GPR(rt_value);
-char *c0s = CPR(c0s_value);
 
-return img_format("DMTC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value);
+return img_format("DMTC0 %s, CP%" PRIu64 ", 0x%" PRIx64,
+  rt, c0s_value, sel_value);
 }
 
 
@@ -5927,9 +5913,8 @@ static char *DMTC2(uint64 instruction, Dis_info *info)
 uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *cs = CPR(cs_value);
 
-return 

[PULL 28/55] disas/nanomips: Delete wrapper functions

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Following functions just wrap the decode_gpr_gpr3() function:
- encode_rs3_and_check_rs3_ge_rt3()
- encode_rs3_and_check_rs3_lt_rt3()
Therefore those have been deleted. Calls to these two functions have
been replaced with calls to decode_gpr_gpr3.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-15-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 18 ++
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index b90be5744e..170f5c5c17 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -505,20 +505,6 @@ static int64 neg_copy(uint64 d)
 }
 
 
-/* strange wrapper around  gpr3 */
-static uint64 encode_rs3_and_check_rs3_ge_rt3(uint64 d)
-{
-return decode_gpr_gpr3(d);
-}
-
-
-/* strange wrapper around  gpr3 */
-static uint64 encode_rs3_and_check_rs3_lt_rt3(uint64 d)
-{
-return decode_gpr_gpr3(d);
-}
-
-
 static uint64 encode_count3_from_count(uint64 d)
 {
 IMGASSERTONCE(d < 8);
@@ -2958,7 +2944,7 @@ static std::string BEQC_16_(uint64 instruction, Dis_info 
*info)
 uint64 rs3_value = extract_rs3_6_5_4(instruction);
 uint64 u_value = extract_u_3_2_1_0__s1(instruction);
 
-std::string rs3 = GPR(encode_rs3_and_check_rs3_lt_rt3(rs3_value));
+std::string rs3 = GPR(decode_gpr_gpr3(rs3_value));
 std::string rt3 = GPR(decode_gpr_gpr3(rt3_value));
 std::string u = ADDRESS(u_value, 2, info);
 
@@ -3244,7 +3230,7 @@ static std::string BNEC_16_(uint64 instruction, Dis_info 
*info)
 uint64 rs3_value = extract_rs3_6_5_4(instruction);
 uint64 u_value = extract_u_3_2_1_0__s1(instruction);
 
-std::string rs3 = GPR(encode_rs3_and_check_rs3_ge_rt3(rs3_value));
+std::string rs3 = GPR(decode_gpr_gpr3(rs3_value));
 std::string rt3 = GPR(decode_gpr_gpr3(rt3_value));
 std::string u = ADDRESS(u_value, 2, info);
 
-- 
2.37.3




[PULL 25/55] disas/nanomips: Delete nanomips.h

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Header file nanomips.h has been deleted for the nanomips disassembler to
stay consistent with the rest of the disassemblers which don't include
extra header files.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-12-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.h | 26 --
 1 file changed, 26 deletions(-)
 delete mode 100644 disas/nanomips.h

diff --git a/disas/nanomips.h b/disas/nanomips.h
deleted file mode 100644
index 0fd7299900..00
--- a/disas/nanomips.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  Header file for nanoMIPS disassembler component of QEMU
- *
- *  Copyright (C) 2018  Wave Computing, Inc.
- *  Copyright (C) 2018  Matthew Fortune 
- *  Copyright (C) 2018  Aleksandar Markovic 
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see .
- *
- */
-
-#ifndef DISAS_NANOMIPS_H
-#define DISAS_NANOMIPS_H
-
-#endif
-- 
2.37.3




[PULL 20/55] disas/nanomips: Remove __cond methods from class

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

NMD class methods with the conditional_function type like
NMD::ADDIU_32__cond, NMD::ADDIU_RS5__cond, etc. are removed from the NMD
class. They're now declared global static functions. Therefore, typedef
of the function pointer, conditional_function is defined outside of the
class.

Now that conditional_function type functions are not part of the NMD
class we can't access them using the this pointer. Thus, the use of
the this pointer has been deleted.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-7-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 42 +-
 disas/nanomips.h   | 14 ++
 2 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 271afcde07..98a632a3fc 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -784,7 +784,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis,
 if ((op_code & table[i].mask) == table[i].value) {
 /* possible match */
 conditional_function cond = table[i].condition;
-if ((cond == 0) || (this->*cond)(op_code)) {
+if ((cond == NULL) || cond(op_code)) {
 try
 {
 if (table[i].type == pool) {
@@ -1672,28 +1672,28 @@ static uint64 extract_u_3_2_1_0__s1(uint64 instruction)
 
 
 
-bool NMD::ADDIU_32__cond(uint64 instruction)
+static bool ADDIU_32__cond(uint64 instruction)
 {
 uint64 rt = extract_rt_25_24_23_22_21(instruction);
 return rt != 0;
 }
 
 
-bool NMD::ADDIU_RS5__cond(uint64 instruction)
+static bool ADDIU_RS5__cond(uint64 instruction)
 {
 uint64 rt = extract_rt_9_8_7_6_5(instruction);
 return rt != 0;
 }
 
 
-bool NMD::BALRSC_cond(uint64 instruction)
+static bool BALRSC_cond(uint64 instruction)
 {
 uint64 rt = extract_rt_25_24_23_22_21(instruction);
 return rt != 0;
 }
 
 
-bool NMD::BEQC_16__cond(uint64 instruction)
+static bool BEQC_16__cond(uint64 instruction)
 {
 uint64 rs3 = extract_rs3_6_5_4(instruction);
 uint64 rt3 = extract_rt3_9_8_7(instruction);
@@ -1702,7 +1702,7 @@ bool NMD::BEQC_16__cond(uint64 instruction)
 }
 
 
-bool NMD::BNEC_16__cond(uint64 instruction)
+static bool BNEC_16__cond(uint64 instruction)
 {
 uint64 rs3 = extract_rs3_6_5_4(instruction);
 uint64 rt3 = extract_rt3_9_8_7(instruction);
@@ -1711,35 +1711,35 @@ bool NMD::BNEC_16__cond(uint64 instruction)
 }
 
 
-bool NMD::MOVE_cond(uint64 instruction)
+static bool MOVE_cond(uint64 instruction)
 {
 uint64 rt = extract_rt_9_8_7_6_5(instruction);
 return rt != 0;
 }
 
 
-bool NMD::P16_BR1_cond(uint64 instruction)
+static bool P16_BR1_cond(uint64 instruction)
 {
 uint64 u = extract_u_3_2_1_0__s1(instruction);
 return u != 0;
 }
 
 
-bool NMD::PREF_S9__cond(uint64 instruction)
+static bool PREF_S9__cond(uint64 instruction)
 {
 uint64 hint = extract_hint_25_24_23_22_21(instruction);
 return hint != 31;
 }
 
 
-bool NMD::PREFE_cond(uint64 instruction)
+static bool PREFE_cond(uint64 instruction)
 {
 uint64 hint = extract_hint_25_24_23_22_21(instruction);
 return hint != 31;
 }
 
 
-bool NMD::SLTU_cond(uint64 instruction)
+static bool SLTU_cond(uint64 instruction)
 {
 uint64 rd = extract_rd_15_14_13_12_11(instruction);
 return rd != 0;
@@ -16692,7 +16692,7 @@ NMD::Pool NMD::P_ADDIU[2] = {
0xffe0, 0x, 0  , 0,
0x0 },/* P.RI */
 { instruction , 0   , 0   , 32,
-   0xfc00, 0x, ::ADDIU_32_, ::ADDIU_32__cond   
,
+   0xfc00, 0x, ::ADDIU_32_, _32__cond   ,
0x0 },/* ADDIU[32] */
 };
 
@@ -16790,7 +16790,7 @@ NMD::Pool NMD::P_SLTU[2] = {
0xfc00fbff, 0x2390, 0  , 0,
0x0 },/* P.DVP */
 { instruction , 0   , 0   , 32,
-   0xfc0003ff, 0x2390, ::SLTU , ::SLTU_cond
,
+   0xfc0003ff, 0x2390, ::SLTU , _cond,
0x0 },/* SLTU */
 };
 
@@ -21335,7 +21335,7 @@ NMD::Pool NMD::P_PREF_S9_[2] = {
0xffe07f00, 0xa7e01800, ::SYNCI, 0,
0x0 },/* SYNCI */
 { instruction , 0   , 0   , 32,
-   0xfc007f00, 0xa4001800, ::PREF_S9_ , ::PREF_S9__cond
,
+   0xfc007f00, 0xa4001800, ::PREF_S9_ , _S9__cond,
0x0 },/* PREF[S9] */
 };
 
@@ -21547,7 +21547,7 @@ NMD::Pool NMD::P_PREFE[2] = {
0xffe07f00, 0xa7e01a00, ::SYNCIE   , 0,
CP0_ | EVA_ },/* SYNCIE */
 { instruction , 0   , 0   , 32,
-   

[PULL 22/55] disas/nanomips: Remove Pool tables from the class

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Pool tables are no longer declared as static fields of the NMD
class but as global static const variables. Pool struct is defined
outside of the class.

The NMD::Disassemble method is using the MAJOR Pool table variable, so
its implementation is moved to the end of the nanomips.cpp file,
right after the initialization of the MAJOR Pool table.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-9-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 363 ++---
 disas/nanomips.h   | 201 ++---
 2 files changed, 193 insertions(+), 371 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 5482284206..a73eae5b33 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -754,13 +754,6 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int 
size)
 }
 
 
-int NMD::Disassemble(const uint16 * data, std::string & dis,
- TABLE_ENTRY_TYPE & type, Dis_info *info)
-{
-return Disassemble(data, dis, type, MAJOR, 2, info);
-}
-
-
 /*
  * Recurse through tables until the instruction is found then return
  * the string and size
@@ -16661,7 +16654,7 @@ static std::string YIELD(uint64 instruction, Dis_info 
*info)
  *
  */
 
-NMD::Pool NMD::P_SYSCALL[2] = {
+static const Pool P_SYSCALL[2] = {
 { instruction , 0   , 0   , 32,
0xfffc, 0x0008, _32_  , 0,
0x0 },/* SYSCALL[32] */
@@ -16671,7 +16664,7 @@ NMD::Pool NMD::P_SYSCALL[2] = {
 };
 
 
-NMD::Pool NMD::P_RI[4] = {
+static const Pool P_RI[4] = {
 { instruction , 0   , 0   , 32,
0xfff8, 0x,, 0,
0x0 },/* SIGRIE */
@@ -16687,7 +16680,7 @@ NMD::Pool NMD::P_RI[4] = {
 };
 
 
-NMD::Pool NMD::P_ADDIU[2] = {
+static const Pool P_ADDIU[2] = {
 { pool, P_RI, 4   , 32,
0xffe0, 0x, 0  , 0,
0x0 },/* P.RI */
@@ -16697,7 +16690,7 @@ NMD::Pool NMD::P_ADDIU[2] = {
 };
 
 
-NMD::Pool NMD::P_TRAP[2] = {
+static const Pool P_TRAP[2] = {
 { instruction , 0   , 0   , 32,
0xfc0007ff, 0x2000,   , 0,
XMMS_   },/* TEQ */
@@ -16707,7 +16700,7 @@ NMD::Pool NMD::P_TRAP[2] = {
 };
 
 
-NMD::Pool NMD::P_CMOVE[2] = {
+static const Pool P_CMOVE[2] = {
 { instruction , 0   , 0   , 32,
0xfc0007ff, 0x2210,  , 0,
0x0 },/* MOVZ */
@@ -16717,7 +16710,7 @@ NMD::Pool NMD::P_CMOVE[2] = {
 };
 
 
-NMD::Pool NMD::P_D_MT_VPE[2] = {
+static const Pool P_D_MT_VPE[2] = {
 { instruction , 0   , 0   , 32,
0xfc1f3fff, 0x20010ab0,   , 0,
MT_ },/* DMT */
@@ -16727,7 +16720,7 @@ NMD::Pool NMD::P_D_MT_VPE[2] = {
 };
 
 
-NMD::Pool NMD::P_E_MT_VPE[2] = {
+static const Pool P_E_MT_VPE[2] = {
 { instruction , 0   , 0   , 32,
0xfc1f3fff, 0x20010eb0,   , 0,
MT_ },/* EMT */
@@ -16737,7 +16730,7 @@ NMD::Pool NMD::P_E_MT_VPE[2] = {
 };
 
 
-NMD::Pool NMD::_P_MT_VPE[2] = {
+static const Pool _P_MT_VPE[2] = {
 { pool, P_D_MT_VPE  , 2   , 32,
0xfc003fff, 0x2ab0, 0  , 0,
0x0 },/* P.D_MT_VPE */
@@ -16747,7 +16740,7 @@ NMD::Pool NMD::_P_MT_VPE[2] = {
 };
 
 
-NMD::Pool NMD::P_MT_VPE[8] = {
+static const Pool P_MT_VPE[8] = {
 { reserved_block  , 0   , 0   , 32,
0xfc003bff, 0x22b0, 0  , 0,
0x0 },/* P.MT_VPE~*(0) */
@@ -16775,7 +16768,7 @@ NMD::Pool NMD::P_MT_VPE[8] = {
 };
 
 
-NMD::Pool NMD::P_DVP[2] = {
+static const Pool P_DVP[2] = {
 { instruction , 0   , 0   , 32,
0xfc00, 0x2390,   , 0,
0x0 },/* DVP */
@@ -16785,7 +16778,7 @@ NMD::Pool NMD::P_DVP[2] = {
 };
 
 
-NMD::Pool NMD::P_SLTU[2] = {
+static const Pool P_SLTU[2] = {
 { pool, P_DVP   , 2   , 32,
0xfc00fbff, 0x2390, 0  , 0,
0x0 },/* P.DVP */
@@ -16795,7 +16788,7 @@ NMD::Pool NMD::P_SLTU[2] = {
 };
 
 
-NMD::Pool NMD::_POOL32A0[128] = {
+static const Pool _POOL32A0[128] = {
 { pool, P_TRAP  , 2   , 32,
0xfc0003ff, 0x2000, 0  , 0,
0x0 },/* P.TRAP */
@@ -17183,7 +17176,7 @@ NMD::Pool NMD::_POOL32A0[128] = {
 };
 
 
-NMD::Pool NMD::ADDQ__S__PH[2] = {
+static const Pool ADDQ__S__PH[2] = {
 

[PULL 23/55] disas/nanomips: Remove NMD class

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

NMD class has been deleted. The following methods are now declared as
static functions:
- public NMD::Disassemble method
- private NMD::Disassemble method
- private NMD::extract_op_code_value helper method

Also, the implementation of the print_insn_nanomips function and
nanomips_dis function is moved to the end of the nanomips.cpp file,
right after the implementation of the Disassemble function.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-10-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 204 ++---
 disas/nanomips.h   |  15 
 2 files changed, 101 insertions(+), 118 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index a73eae5b33..0d67462e5d 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -41,105 +41,6 @@
 #define IMGASSERTONCE(test)
 
 
-static int nanomips_dis(char *buf,
- Dis_info *info,
- unsigned short one,
- unsigned short two,
- unsigned short three)
-{
-std::string disasm;
-uint16 bits[3] = {one, two, three};
-
-TABLE_ENTRY_TYPE type;
-NMD d;
-int size = d.Disassemble(bits, disasm, type, info);
-
-strcpy(buf, disasm.c_str());
-return size;
-}
-
-int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info)
-{
-int status;
-bfd_byte buffer[2];
-uint16_t insn1 = 0, insn2 = 0, insn3 = 0;
-char buf[200];
-
-info->bytes_per_chunk = 2;
-info->display_endian = info->endian;
-info->insn_info_valid = 1;
-info->branch_delay_insns = 0;
-info->data_size = 0;
-info->insn_type = dis_nonbranch;
-info->target = 0;
-info->target2 = 0;
-
-Dis_info disassm_info;
-disassm_info.m_pc = memaddr;
-
-status = (*info->read_memory_func)(memaddr, buffer, 2, info);
-if (status != 0) {
-(*info->memory_error_func)(status, memaddr, info);
-return -1;
-}
-
-if (info->endian == BFD_ENDIAN_BIG) {
-insn1 = bfd_getb16(buffer);
-} else {
-insn1 = bfd_getl16(buffer);
-}
-(*info->fprintf_func)(info->stream, "%04x ", insn1);
-
-/* Handle 32-bit opcodes.  */
-if ((insn1 & 0x1000) == 0) {
-status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info);
-if (status != 0) {
-(*info->memory_error_func)(status, memaddr + 2, info);
-return -1;
-}
-
-if (info->endian == BFD_ENDIAN_BIG) {
-insn2 = bfd_getb16(buffer);
-} else {
-insn2 = bfd_getl16(buffer);
-}
-(*info->fprintf_func)(info->stream, "%04x ", insn2);
-} else {
-(*info->fprintf_func)(info->stream, " ");
-}
-/* Handle 48-bit opcodes.  */
-if ((insn1 >> 10) == 0x18) {
-status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info);
-if (status != 0) {
-(*info->memory_error_func)(status, memaddr + 4, info);
-return -1;
-}
-
-if (info->endian == BFD_ENDIAN_BIG) {
-insn3 = bfd_getb16(buffer);
-} else {
-insn3 = bfd_getl16(buffer);
-}
-(*info->fprintf_func)(info->stream, "%04x ", insn3);
-} else {
-(*info->fprintf_func)(info->stream, " ");
-}
-
-int length = nanomips_dis(buf, _info, insn1, insn2, insn3);
-
-/* FIXME: Should probably use a hash table on the major opcode here.  */
-
-(*info->fprintf_func) (info->stream, "%s", buf);
-if (length > 0) {
-return length / 8;
-}
-
-info->insn_type = dis_noninsn;
-
-return insn3 ? 6 : insn2 ? 4 : 2;
-}
-
-
 std::string img_format(const char *format, ...)
 {
 char buffer[256];
@@ -739,7 +640,7 @@ static std::string ADDRESS(uint64 value, int 
instruction_size, Dis_info *info)
 }
 
 
-uint64 NMD::extract_op_code_value(const uint16 * data, int size)
+static uint64 extract_op_code_value(const uint16 *data, int size)
 {
 switch (size) {
 case 16:
@@ -765,7 +666,7 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int 
size)
  *  instruction size- negative is error
  *  disassembly string  - on error will constain error string
  */
-int NMD::Disassemble(const uint16 * data, std::string & dis,
+static int Disassemble(const uint16 *data, std::string & dis,
  TABLE_ENTRY_TYPE & type, const Pool *table,
  int table_size, Dis_info *info)
 {
@@ -22348,8 +22249,105 @@ static const Pool MAJOR[2] = {
0x0 },/* P16 */
 };
 
-int NMD::Disassemble(const uint16 *data, std::string & dis,
- TABLE_ENTRY_TYPE & type, Dis_info *info)
+static int Disassemble(const uint16 *data, std::string & dis,
+   TABLE_ENTRY_TYPE & type, Dis_info *info)
 {
 return Disassemble(data, dis, type, MAJOR, 2, info);
 }
+
+static int 

[PULL 09/55] hw/isa/vt82c686: Instantiate PM function in host device

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

The PM controller has activity bits which monitor activity of other
built-in devices in the host device.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-10-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 13 +
 hw/mips/fuloong2e.c   |  2 +-
 hw/ppc/pegasos2.c |  3 +--
 include/hw/isa/vt82c686.h |  2 --
 4 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index f05fd9948a..d048607079 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -250,6 +250,8 @@ static const ViaPMInitInfo vt82c686b_pm_init_info = {
 .device_id = PCI_DEVICE_ID_VIA_82C686B_PM,
 };
 
+#define TYPE_VT82C686B_PM "vt82c686b-pm"
+
 static const TypeInfo vt82c686b_pm_info = {
 .name  = TYPE_VT82C686B_PM,
 .parent= TYPE_VIA_PM,
@@ -261,6 +263,8 @@ static const ViaPMInitInfo vt8231_pm_init_info = {
 .device_id = PCI_DEVICE_ID_VIA_8231_PM,
 };
 
+#define TYPE_VT8231_PM "vt8231-pm"
+
 static const TypeInfo vt8231_pm_info = {
 .name  = TYPE_VT8231_PM,
 .parent= TYPE_VIA_PM,
@@ -548,6 +552,7 @@ struct ViaISAState {
 ViaSuperIOState via_sio;
 PCIIDEState ide;
 UHCIState uhci[2];
+ViaPMState pm;
 };
 
 static const VMStateDescription vmstate_via = {
@@ -641,6 +646,12 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 return;
 }
 }
+
+/* Function 4: Power Management */
+qdev_prop_set_int32(DEVICE(>pm), "addr", d->devfn + 4);
+if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
+return;
+}
 }
 
 /* TYPE_VT82C686B_ISA */
@@ -683,6 +694,7 @@ static void vt82c686b_init(Object *obj)
 ViaISAState *s = VIA_ISA(obj);
 
 object_initialize_child(obj, "sio", >via_sio, TYPE_VT82C686B_SUPERIO);
+object_initialize_child(obj, "pm", >pm, TYPE_VT82C686B_PM);
 }
 
 static void vt82c686b_class_init(ObjectClass *klass, void *data)
@@ -746,6 +758,7 @@ static void vt8231_init(Object *obj)
 ViaISAState *s = VIA_ISA(obj);
 
 object_initialize_child(obj, "sio", >via_sio, TYPE_VT8231_SUPERIO);
+object_initialize_child(obj, "pm", >pm, TYPE_VT8231_PM);
 }
 
 static void vt8231_class_init(ObjectClass *klass, void *data)
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index dc92223b76..377108d313 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -208,7 +208,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int 
slot, qemu_irq intc,
 dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
 pci_ide_create_devs(dev);
 
-dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM);
+dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm"));
 *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
 
 /* Audio support */
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index bd3c5cf835..6b5d7265d3 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -168,8 +168,7 @@ static void pegasos2_init(MachineState *machine)
 dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
 pci_ide_create_devs(dev);
 
-/* VT8231 function 4: Power Management Controller */
-dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM);
+dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm"));
 i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
 spd_data = spd_data_generate(DDR, machine->ram_size);
 smbus_eeprom_init_one(i2c_bus, 0x57, spd_data);
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index e6f6dd4d43..eaa07881c5 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -4,10 +4,8 @@
 #include "hw/pci/pci.h"
 
 #define TYPE_VT82C686B_ISA "vt82c686b-isa"
-#define TYPE_VT82C686B_PM "vt82c686b-pm"
 #define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci"
 #define TYPE_VT8231_ISA "vt8231-isa"
-#define TYPE_VT8231_PM "vt8231-pm"
 #define TYPE_VIA_AC97 "via-ac97"
 #define TYPE_VIA_IDE "via-ide"
 #define TYPE_VIA_MC97 "via-mc97"
-- 
2.37.3




[PULL 11/55] hw/mips/fuloong2e: Inline vt82c686b_southbridge_init() and remove it

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

The previous patches moved most of this function into the via-isa device
model such that it has become fairly trivial. So inline it for
simplicity.

Suggested-by: BALATON Zoltan 
Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220901114127.53914-12-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/fuloong2e.c | 28 ++--
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 2d8723ab74..3c46215616 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -196,22 +196,6 @@ static void main_cpu_reset(void *opaque)
 }
 }
 
-static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq 
intc,
-   I2CBus **i2c_bus)
-{
-PCIDevice *dev, *via;
-
-via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true,
-  TYPE_VT82C686B_ISA);
-qdev_connect_gpio_out(DEVICE(via), 0, intc);
-
-dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
-pci_ide_create_devs(dev);
-
-dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm"));
-*i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
-}
-
 /* Network support */
 static void network_init(PCIBus *pci_bus)
 {
@@ -308,8 +292,16 @@ static void mips_fuloong2e_init(MachineState *machine)
 pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
 
 /* South bridge -> IP5 */
-vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5],
-   );
+pci_dev = pci_create_simple_multifunction(pci_bus,
+  PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
+  true, TYPE_VT82C686B_ISA);
+qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]);
+
+dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
+pci_ide_create_devs(PCI_DEVICE(dev));
+
+dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "pm"));
+smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
 
 /* GPU */
 if (vga_interface_type != VGA_NONE) {
-- 
2.37.3




[PULL 05/55] hw/isa/vt82c686: Introduce TYPE_VIA_IDE define

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Establishes consistency with other (VIA) devices.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-6-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/via.c  | 2 +-
 hw/mips/fuloong2e.c   | 2 +-
 hw/ppc/pegasos2.c | 2 +-
 include/hw/isa/vt82c686.h | 1 +
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 82def819c4..e1a429405d 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -230,7 +230,7 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo via_ide_info = {
-.name  = "via-ide",
+.name  = TYPE_VIA_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= via_ide_class_init,
 };
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 5ee546f5f6..44225fbe33 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -205,7 +205,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int 
slot, qemu_irq intc,
   TYPE_VT82C686B_ISA);
 qdev_connect_gpio_out(DEVICE(dev), 0, intc);
 
-dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide");
+dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), TYPE_VIA_IDE);
 pci_ide_create_devs(dev);
 
 pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci");
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index ecf682b148..0ccc130b88 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -166,7 +166,7 @@ static void pegasos2_init(MachineState *machine)
   qdev_get_gpio_in_named(pm->mv, "gpp", 31));
 
 /* VT8231 function 1: IDE Controller */
-dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
+dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), TYPE_VIA_IDE);
 pci_ide_create_devs(dev);
 
 /* VT8231 function 2-3: USB Ports */
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index 56ac141be3..87aca3e5bb 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -8,6 +8,7 @@
 #define TYPE_VT8231_ISA "vt8231-isa"
 #define TYPE_VT8231_PM "vt8231-pm"
 #define TYPE_VIA_AC97 "via-ac97"
+#define TYPE_VIA_IDE "via-ide"
 #define TYPE_VIA_MC97 "via-mc97"
 
 void via_isa_set_irq(PCIDevice *d, int n, int level);
-- 
2.37.3




[PULL 16/55] disas/nanomips: Extract enums out of the NMD class

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Definitions of enums TABLE_ENTRY_TYPE and TABLE_ATTRIBUTE_TYPE are moved
out of the NMD class. The main goal is to remove NMD class completely.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-3-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp |  8 +++
 disas/nanomips.h   | 59 +++---
 2 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 84529685bf..bdc640b38b 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -50,8 +50,8 @@ int nanomips_dis(char *buf,
 std::string disasm;
 uint16 bits[3] = {one, two, three};
 
-NMD::TABLE_ENTRY_TYPE type;
-NMD d(address, NMD::ALL_ATTRIBUTES);
+TABLE_ENTRY_TYPE type;
+NMD d(address, ALL_ATTRIBUTES);
 int size = d.Disassemble(bits, disasm, type);
 
 strcpy(buf, disasm.c_str());
@@ -772,7 +772,7 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int 
size)
 
 
 int NMD::Disassemble(const uint16 * data, std::string & dis,
- NMD::TABLE_ENTRY_TYPE & type)
+ TABLE_ENTRY_TYPE & type)
 {
 return Disassemble(data, dis, type, MAJOR, 2);
 }
@@ -790,7 +790,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis,
  *  disassembly string  - on error will constain error string
  */
 int NMD::Disassemble(const uint16 * data, std::string & dis,
- NMD::TABLE_ENTRY_TYPE & type, const Pool *table,
+ TABLE_ENTRY_TYPE & type, const Pool *table,
  int table_size)
 {
 try
diff --git a/disas/nanomips.h b/disas/nanomips.h
index 9fe0cc67da..f65a0957b8 100644
--- a/disas/nanomips.h
+++ b/disas/nanomips.h
@@ -31,41 +31,40 @@ typedef uint32_t uint32;
 typedef uint16_t uint16;
 typedef uint64_t img_address;
 
+enum TABLE_ENTRY_TYPE {
+instruction,
+call_instruction,
+branch_instruction,
+return_instruction,
+reserved_block,
+pool,
+};
+
+enum TABLE_ATTRIBUTE_TYPE {
+MIPS64_= 0x0001,
+XNP_   = 0x0002,
+XMMS_  = 0x0004,
+EVA_   = 0x0008,
+DSP_   = 0x0010,
+MT_= 0x0020,
+EJTAG_ = 0x0040,
+TLBINV_= 0x0080,
+CP0_   = 0x0100,
+CP1_   = 0x0200,
+CP2_   = 0x0400,
+UDI_   = 0x0800,
+MCU_   = 0x1000,
+VZ_= 0x2000,
+TLB_   = 0x4000,
+MVH_   = 0x8000,
+ALL_ATTRIBUTES = 0xull,
+};
+
 
 class NMD
 {
 public:
 
-enum TABLE_ENTRY_TYPE {
-instruction,
-call_instruction,
-branch_instruction,
-return_instruction,
-reserved_block,
-pool,
-};
-
-enum TABLE_ATTRIBUTE_TYPE {
-MIPS64_= 0x0001,
-XNP_   = 0x0002,
-XMMS_  = 0x0004,
-EVA_   = 0x0008,
-DSP_   = 0x0010,
-MT_= 0x0020,
-EJTAG_ = 0x0040,
-TLBINV_= 0x0080,
-CP0_   = 0x0100,
-CP1_   = 0x0200,
-CP2_   = 0x0400,
-UDI_   = 0x0800,
-MCU_   = 0x1000,
-VZ_= 0x2000,
-TLB_   = 0x4000,
-MVH_   = 0x8000,
-ALL_ATTRIBUTES = 0xull,
-};
-
-
 NMD(img_address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_categories)
 : m_pc(pc)
 , m_requested_instruction_categories(requested_instruction_categories)
-- 
2.37.3




[PULL 04/55] hw/isa/vt82c686: Reuse errp

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Rather than terminating abruptly, make use of the already present errp and
propagate the error to the caller.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220901114127.53914-5-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 5582c0b179..37e37b3855 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -590,7 +590,12 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 qdev_init_gpio_out(dev, >cpu_intr, 1);
 isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
 isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
-  _fatal);
+  errp);
+
+if (!isa_bus) {
+return;
+}
+
 s->isa_irqs = i8259_init(isa_bus, *isa_irq);
 isa_bus_irqs(isa_bus, s->isa_irqs);
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
-- 
2.37.3




[PULL 12/55] hw/isa/vt82c686: Embed RTCState in host device

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Embed the rtc in the host device, analoguous to the other child devices
and analoguous to PIIX4.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220901114127.53914-13-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 91686e9570..48cd4d0036 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -550,6 +550,7 @@ struct ViaISAState {
 qemu_irq cpu_intr;
 qemu_irq *isa_irqs;
 ViaSuperIOState via_sio;
+RTCState rtc;
 PCIIDEState ide;
 UHCIState uhci[2];
 ViaPMState pm;
@@ -571,6 +572,7 @@ static void via_isa_init(Object *obj)
 {
 ViaISAState *s = VIA_ISA(obj);
 
+object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
 object_initialize_child(obj, "ide", >ide, TYPE_VIA_IDE);
 object_initialize_child(obj, "uhci1", >uhci[0], 
TYPE_VT82C686B_USB_UHCI);
 object_initialize_child(obj, "uhci2", >uhci[1], 
TYPE_VT82C686B_USB_UHCI);
@@ -624,7 +626,15 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 isa_bus_irqs(isa_bus, s->isa_irqs);
 i8254_pit_init(isa_bus, 0x40, 0, NULL);
 i8257_dma_init(isa_bus, 0);
-mc146818_rtc_init(isa_bus, 2000, NULL);
+
+/* RTC */
+qdev_prop_set_int32(DEVICE(>rtc), "base_year", 2000);
+if (!qdev_realize(DEVICE(>rtc), BUS(isa_bus), errp)) {
+return;
+}
+object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(>rtc),
+  "date");
+isa_connect_gpio_out(ISA_DEVICE(>rtc), 0, s->rtc.isairq);
 
 for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
 if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
-- 
2.37.3




[PULL 17/55] disas/nanomips: Delete NMD class field

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

The m_requested_instruction_categories field always has the same value,
ALL_ATTRIBUTES. The only use of that field is within the if statement.
When replaced with a specific value, the if statement is always false,
so it has been removed.

Now, when the only use of the m_requested_instruction_categories field
is removed, we can delete the field declaration and initialization in
the NMD class. Also, we're changing the way of the construction of the
NMD object in the nanomips_dis function.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-4-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 13 +
 disas/nanomips.h   |  4 +---
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index bdc640b38b..721ca3f52b 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -51,7 +51,7 @@ int nanomips_dis(char *buf,
 uint16 bits[3] = {one, two, three};
 
 TABLE_ENTRY_TYPE type;
-NMD d(address, ALL_ATTRIBUTES);
+NMD d(address);
 int size = d.Disassemble(bits, disasm, type);
 
 strcpy(buf, disasm.c_str());
@@ -812,17 +812,6 @@ int NMD::Disassemble(const uint16 * data, std::string & 
dis,
(table[i].type == call_instruction) ||
(table[i].type == branch_instruction) ||
(table[i].type == return_instruction)) {
-if ((table[i].attributes != 0) &&
-(m_requested_instruction_categories &
- table[i].attributes) == 0) {
-/*
- * failed due to instruction having
- * an ASE attribute and the requested version
- * not having that attribute
- */
-dis = "ASE attribute mismatch";
-return -5;
-}
 disassembly_function dis_fn = table[i].disassembly;
 if (dis_fn == 0) {
 dis = "disassembler failure - bad table entry";
diff --git a/disas/nanomips.h b/disas/nanomips.h
index f65a0957b8..5bdfe1e30b 100644
--- a/disas/nanomips.h
+++ b/disas/nanomips.h
@@ -65,9 +65,8 @@ class NMD
 {
 public:
 
-NMD(img_address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_categories)
+NMD(img_address pc)
 : m_pc(pc)
-, m_requested_instruction_categories(requested_instruction_categories)
 {
 }
 
@@ -77,7 +76,6 @@ public:
 private:
 
 img_address   m_pc;
-TABLE_ATTRIBUTE_TYPE   m_requested_instruction_categories;
 
 typedef std::string(NMD:: *disassembly_function)(uint64 instruction);
 typedef bool(NMD:: *conditional_function)(uint64 instruction);
-- 
2.37.3




[PULL 06/55] hw/isa/vt82c686: Instantiate IDE function in host device

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

The IDE function is closely tied to the ISA function (e.g. the IDE
interrupt routing happens there), so it makes sense that the IDE
function is instantiated within the south bridge itself.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-7-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 configs/devices/mips64el-softmmu/default.mak |  1 -
 hw/isa/Kconfig   |  1 +
 hw/isa/vt82c686.c| 17 +
 hw/mips/fuloong2e.c  |  8 
 hw/ppc/Kconfig   |  1 -
 hw/ppc/pegasos2.c|  9 -
 6 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/configs/devices/mips64el-softmmu/default.mak 
b/configs/devices/mips64el-softmmu/default.mak
index c610749ac1..d5188f7ea5 100644
--- a/configs/devices/mips64el-softmmu/default.mak
+++ b/configs/devices/mips64el-softmmu/default.mak
@@ -1,7 +1,6 @@
 # Default configuration for mips64el-softmmu
 
 include ../mips-softmmu/common.mak
-CONFIG_IDE_VIA=y
 CONFIG_FULOONG=y
 CONFIG_LOONGSON3V=y
 CONFIG_ATI_VGA=y
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index d42143a991..20de7e9294 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -53,6 +53,7 @@ config VT82C686
 select I8254
 select I8257
 select I8259
+select IDE_VIA
 select MC146818RTC
 select PARALLEL
 
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 37e37b3855..63c1e3b8ce 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -17,6 +17,7 @@
 #include "hw/isa/vt82c686.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
+#include "hw/ide/pci.h"
 #include "hw/isa/isa.h"
 #include "hw/isa/superio.h"
 #include "hw/intc/i8259.h"
@@ -544,6 +545,7 @@ struct ViaISAState {
 qemu_irq cpu_intr;
 qemu_irq *isa_irqs;
 ViaSuperIOState via_sio;
+PCIIDEState ide;
 };
 
 static const VMStateDescription vmstate_via = {
@@ -556,10 +558,18 @@ static const VMStateDescription vmstate_via = {
 }
 };
 
+static void via_isa_init(Object *obj)
+{
+ViaISAState *s = VIA_ISA(obj);
+
+object_initialize_child(obj, "ide", >ide, TYPE_VIA_IDE);
+}
+
 static const TypeInfo via_isa_info = {
 .name  = TYPE_VIA_ISA,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(ViaISAState),
+.instance_init = via_isa_init,
 .abstract  = true,
 .interfaces= (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
@@ -583,6 +593,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 {
 ViaISAState *s = VIA_ISA(d);
 DeviceState *dev = DEVICE(d);
+PCIBus *pci_bus = pci_get_bus(d);
 qemu_irq *isa_irq;
 ISABus *isa_bus;
 int i;
@@ -612,6 +623,12 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 if (!qdev_realize(DEVICE(>via_sio), BUS(isa_bus), errp)) {
 return;
 }
+
+/* Function 1: IDE */
+qdev_prop_set_int32(DEVICE(>ide), "addr", d->devfn + 1);
+if (!qdev_realize(DEVICE(>ide), BUS(pci_bus), errp)) {
+return;
+}
 }
 
 /* TYPE_VT82C686B_ISA */
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 44225fbe33..32605901e7 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -199,13 +199,13 @@ static void main_cpu_reset(void *opaque)
 static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq 
intc,
I2CBus **i2c_bus)
 {
-PCIDevice *dev;
+PCIDevice *dev, *via;
 
-dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true,
+via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true,
   TYPE_VT82C686B_ISA);
-qdev_connect_gpio_out(DEVICE(dev), 0, intc);
+qdev_connect_gpio_out(DEVICE(via), 0, intc);
 
-dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), TYPE_VIA_IDE);
+dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
 pci_ide_create_devs(dev);
 
 pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci");
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 791fe78a50..76a4612d96 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -74,7 +74,6 @@ config PEGASOS2
 imply ATI_VGA
 select MV64361
 select VT82C686
-select IDE_VIA
 select SMBUS_EEPROM
 select VOF
 # This should come with VT82C686
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 0ccc130b88..76f0dee4aa 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -102,7 +102,7 @@ static void pegasos2_init(MachineState *machine)
 CPUPPCState *env;
 MemoryRegion *rom = g_new(MemoryRegion, 1);
 PCIBus *pci_bus;
-PCIDevice *dev;
+PCIDevice *dev, *via;
 I2CBus *i2c_bus;
 const char *fwname = machine->firmware ?: PROM_FILENAME;
 char *filename;
@@ -160,13 +160,12 @@ static void 

[PULL 10/55] hw/isa/vt82c686: Instantiate AC97 and MC97 functions in host device

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

The AC97 function's wakeup status is wired to the PM function and both
the AC97 and MC97 interrupt routing is determined by the ISA function.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-11-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c   | 16 
 hw/mips/fuloong2e.c |  4 
 hw/ppc/pegasos2.c   |  5 -
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index d048607079..91686e9570 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -553,6 +553,8 @@ struct ViaISAState {
 PCIIDEState ide;
 UHCIState uhci[2];
 ViaPMState pm;
+PCIDevice ac97;
+PCIDevice mc97;
 };
 
 static const VMStateDescription vmstate_via = {
@@ -572,6 +574,8 @@ static void via_isa_init(Object *obj)
 object_initialize_child(obj, "ide", >ide, TYPE_VIA_IDE);
 object_initialize_child(obj, "uhci1", >uhci[0], 
TYPE_VT82C686B_USB_UHCI);
 object_initialize_child(obj, "uhci2", >uhci[1], 
TYPE_VT82C686B_USB_UHCI);
+object_initialize_child(obj, "ac97", >ac97, TYPE_VIA_AC97);
+object_initialize_child(obj, "mc97", >mc97, TYPE_VIA_MC97);
 }
 
 static const TypeInfo via_isa_info = {
@@ -652,6 +656,18 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
 return;
 }
+
+/* Function 5: AC97 Audio */
+qdev_prop_set_int32(DEVICE(>ac97), "addr", d->devfn + 5);
+if (!qdev_realize(DEVICE(>ac97), BUS(pci_bus), errp)) {
+return;
+}
+
+/* Function 6: MC97 Modem */
+qdev_prop_set_int32(DEVICE(>mc97), "addr", d->devfn + 6);
+if (!qdev_realize(DEVICE(>mc97), BUS(pci_bus), errp)) {
+return;
+}
 }
 
 /* TYPE_VT82C686B_ISA */
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 377108d313..2d8723ab74 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -210,10 +210,6 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, 
int slot, qemu_irq intc,
 
 dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm"));
 *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
-
-/* Audio support */
-pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97);
-pci_create_simple(pci_bus, PCI_DEVFN(slot, 6), TYPE_VIA_MC97);
 }
 
 /* Network support */
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 6b5d7265d3..474723ee27 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -159,7 +159,6 @@ static void pegasos2_init(MachineState *machine)
 pci_bus = mv64361_get_pci_bus(pm->mv, 1);
 
 /* VIA VT8231 South Bridge (multifunction PCI device) */
-/* VT8231 function 0: PCI-to-ISA Bridge */
 via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
   TYPE_VT8231_ISA);
 qdev_connect_gpio_out(DEVICE(via), 0,
@@ -173,10 +172,6 @@ static void pegasos2_init(MachineState *machine)
 spd_data = spd_data_generate(DDR, machine->ram_size);
 smbus_eeprom_init_one(i2c_bus, 0x57, spd_data);
 
-/* VT8231 function 5-6: AC97 Audio & Modem */
-pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97);
-pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97);
-
 /* other PC hardware */
 pci_vga_init(pci_bus);
 
-- 
2.37.3




[PULL 02/55] hw/isa/vt82c686: Resolve unneeded attribute

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Now that also the super io device is realized in the common realize method,
the isa_bus attribute can be turned into a temporary.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220901114127.53914-3-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 0217c98fe4..9d12e1cae4 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -543,7 +543,6 @@ struct ViaISAState {
 PCIDevice dev;
 qemu_irq cpu_intr;
 qemu_irq *isa_irqs;
-ISABus *isa_bus;
 ViaSuperIOState via_sio;
 };
 
@@ -585,17 +584,18 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 ViaISAState *s = VIA_ISA(d);
 DeviceState *dev = DEVICE(d);
 qemu_irq *isa_irq;
+ISABus *isa_bus;
 int i;
 
 qdev_init_gpio_out(dev, >cpu_intr, 1);
 isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
-s->isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
+isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
   _fatal);
-s->isa_irqs = i8259_init(s->isa_bus, *isa_irq);
-isa_bus_irqs(s->isa_bus, s->isa_irqs);
-i8254_pit_init(s->isa_bus, 0x40, 0, NULL);
-i8257_dma_init(s->isa_bus, 0);
-mc146818_rtc_init(s->isa_bus, 2000, NULL);
+s->isa_irqs = i8259_init(isa_bus, *isa_irq);
+isa_bus_irqs(isa_bus, s->isa_irqs);
+i8254_pit_init(isa_bus, 0x40, 0, NULL);
+i8257_dma_init(isa_bus, 0);
+mc146818_rtc_init(isa_bus, 2000, NULL);
 
 for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
 if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
@@ -604,7 +604,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 }
 
 /* Super I/O */
-if (!qdev_realize(DEVICE(>via_sio), BUS(s->isa_bus), errp)) {
+if (!qdev_realize(DEVICE(>via_sio), BUS(isa_bus), errp)) {
 return;
 }
 }
-- 
2.37.3




[PULL 07/55] hw/isa/vt82c686: Introduce TYPE_VT82C686B_USB_UHCI define

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Suggested-by: BALATON Zoltan 
Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-8-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/fuloong2e.c| 4 ++--
 hw/ppc/pegasos2.c  | 4 ++--
 hw/usb/vt82c686-uhci-pci.c | 4 ++--
 include/hw/isa/vt82c686.h  | 1 +
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 32605901e7..6b7370f2aa 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -208,8 +208,8 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int 
slot, qemu_irq intc,
 dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
 pci_ide_create_devs(dev);
 
-pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci");
-pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci");
+pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), TYPE_VT82C686B_USB_UHCI);
+pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), TYPE_VT82C686B_USB_UHCI);
 
 dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM);
 *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 76f0dee4aa..23b4156a5e 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -169,8 +169,8 @@ static void pegasos2_init(MachineState *machine)
 pci_ide_create_devs(dev);
 
 /* VT8231 function 2-3: USB Ports */
-pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci");
-pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci");
+pci_create_simple(pci_bus, PCI_DEVFN(12, 2), TYPE_VT82C686B_USB_UHCI);
+pci_create_simple(pci_bus, PCI_DEVFN(12, 3), TYPE_VT82C686B_USB_UHCI);
 
 /* VT8231 function 4: Power Management Controller */
 dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM);
diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
index 0bf2b72ff0..46a901f56f 100644
--- a/hw/usb/vt82c686-uhci-pci.c
+++ b/hw/usb/vt82c686-uhci-pci.c
@@ -31,7 +31,7 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error 
**errp)
 
 static UHCIInfo uhci_info[] = {
 {
-.name  = "vt82c686b-usb-uhci",
+.name  = TYPE_VT82C686B_USB_UHCI,
 .vendor_id = PCI_VENDOR_ID_VIA,
 .device_id = PCI_DEVICE_ID_VIA_UHCI,
 .revision  = 0x01,
@@ -45,7 +45,7 @@ static UHCIInfo uhci_info[] = {
 
 static const TypeInfo vt82c686b_usb_uhci_type_info = {
 .parent = TYPE_UHCI,
-.name   = "vt82c686b-usb-uhci",
+.name   = TYPE_VT82C686B_USB_UHCI,
 .class_init = uhci_data_class_init,
 .class_data = uhci_info,
 };
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index 87aca3e5bb..e6f6dd4d43 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -5,6 +5,7 @@
 
 #define TYPE_VT82C686B_ISA "vt82c686b-isa"
 #define TYPE_VT82C686B_PM "vt82c686b-pm"
+#define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci"
 #define TYPE_VT8231_ISA "vt8231-isa"
 #define TYPE_VT8231_PM "vt8231-pm"
 #define TYPE_VIA_AC97 "via-ac97"
-- 
2.37.3




[PULL 08/55] hw/isa/vt82c686: Instantiate USB functions in host device

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

The USB functions can be enabled/disabled through the ISA function. Also
its interrupt routing can be influenced there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-9-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c   | 12 
 hw/mips/fuloong2e.c |  3 ---
 hw/ppc/pegasos2.c   |  4 
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 63c1e3b8ce..f05fd9948a 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -23,6 +23,7 @@
 #include "hw/intc/i8259.h"
 #include "hw/irq.h"
 #include "hw/dma/i8257.h"
+#include "hw/usb/hcd-uhci.h"
 #include "hw/timer/i8254.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "migration/vmstate.h"
@@ -546,6 +547,7 @@ struct ViaISAState {
 qemu_irq *isa_irqs;
 ViaSuperIOState via_sio;
 PCIIDEState ide;
+UHCIState uhci[2];
 };
 
 static const VMStateDescription vmstate_via = {
@@ -563,6 +565,8 @@ static void via_isa_init(Object *obj)
 ViaISAState *s = VIA_ISA(obj);
 
 object_initialize_child(obj, "ide", >ide, TYPE_VIA_IDE);
+object_initialize_child(obj, "uhci1", >uhci[0], 
TYPE_VT82C686B_USB_UHCI);
+object_initialize_child(obj, "uhci2", >uhci[1], 
TYPE_VT82C686B_USB_UHCI);
 }
 
 static const TypeInfo via_isa_info = {
@@ -629,6 +633,14 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 if (!qdev_realize(DEVICE(>ide), BUS(pci_bus), errp)) {
 return;
 }
+
+/* Functions 2-3: USB Ports */
+for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
+qdev_prop_set_int32(DEVICE(>uhci[i]), "addr", d->devfn + 2 + i);
+if (!qdev_realize(DEVICE(>uhci[i]), BUS(pci_bus), errp)) {
+return;
+}
+}
 }
 
 /* TYPE_VT82C686B_ISA */
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 6b7370f2aa..dc92223b76 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -208,9 +208,6 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int 
slot, qemu_irq intc,
 dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
 pci_ide_create_devs(dev);
 
-pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), TYPE_VT82C686B_USB_UHCI);
-pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), TYPE_VT82C686B_USB_UHCI);
-
 dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM);
 *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
 
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 23b4156a5e..bd3c5cf835 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -168,10 +168,6 @@ static void pegasos2_init(MachineState *machine)
 dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
 pci_ide_create_devs(dev);
 
-/* VT8231 function 2-3: USB Ports */
-pci_create_simple(pci_bus, PCI_DEVFN(12, 2), TYPE_VT82C686B_USB_UHCI);
-pci_create_simple(pci_bus, PCI_DEVFN(12, 3), TYPE_VT82C686B_USB_UHCI);
-
 /* VT8231 function 4: Power Management Controller */
 dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM);
 i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
-- 
2.37.3




[PULL 03/55] hw/isa/vt82c686: Prefer pci_address_space() over get_system_memory()

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Unlike get_system_memory(), pci_address_space() respects the memory tree
available to the parent device.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220901114127.53914-4-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 9d12e1cae4..5582c0b179 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -589,7 +589,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 
 qdev_init_gpio_out(dev, >cpu_intr, 1);
 isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
-isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
+isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
   _fatal);
 s->isa_irqs = i8259_init(isa_bus, *isa_irq);
 isa_bus_irqs(isa_bus, s->isa_irqs);
-- 
2.37.3




  1   2   >