qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/11] target-lm32 updates
@ 2013-09-25 18:59 Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 01/11] lm32_sys: increase test case name length limit Michael Walle
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

This is a pull for various updates and fixes for the LatticeMico32 target.

Please pull.

Thanks,
  michael



The following changes since commit f828a4c8faa118e0ebab3e353ac6840f3b2a0318:

  Merge remote-tracking branch 'stefanha/tracing' into staging (2013-09-23 11:53:22 -0500)

are available in the git repository at:


  git://github.com/mwalle/qemu for-upstream

for you to fetch changes up to 4470c88945cd4aba158e510c416e0321f101ff83:

  lm32_sys: dump cpu state if test case fails (2013-09-25 19:54:32 +0200)

----------------------------------------------------------------
Antony Pavlov (1):
      milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write()

Michael Walle (10):
      lm32_sys: increase test case name length limit
      tests: lm32: new rule for single test cases
      lm32_uart/lm32_juart: use qemu_chr_fe_write_all()
      target-lm32: register helper functions
      milkymist-vgafb: swap pixel data in source buffer
      target-lm32: kill cpu_abort() calls
      target-lm32: move model features to LM32CPU
      target-lm32: add breakpoint/watchpoint support
      lm32_sys: print test result on stderr
      lm32_sys: dump cpu state if test case fails

 hw/char/lm32_juart.c                  |    2 +-
 hw/char/lm32_uart.c                   |    2 +-
 hw/char/milkymist-uart.c              |    2 +-
 hw/display/milkymist-vgafb_template.h |    3 +
 hw/misc/lm32_sys.c                    |    7 ++-
 target-lm32/TODO                      |    2 -
 target-lm32/cpu-qom.h                 |    1 +
 target-lm32/cpu.c                     |    1 +
 target-lm32/cpu.h                     |   39 ++++++++++--
 target-lm32/helper.c                  |  104 ++++++++++++++++++++++++++++----
 target-lm32/helper.h                  |    3 +
 target-lm32/op_helper.c               |   58 +++++++++++++++++-
 target-lm32/translate.c               |  105 ++++++++++++++++++---------------
 tests/tcg/lm32/Makefile               |    3 +
 14 files changed, 259 insertions(+), 73 deletions(-)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 01/11] lm32_sys: increase test case name length limit
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 02/11] tests: lm32: new rule for single test cases Michael Walle
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

The new MMU tests use longer names.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/misc/lm32_sys.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/lm32_sys.c b/hw/misc/lm32_sys.c
index 9bdb781..8176cdb 100644
--- a/hw/misc/lm32_sys.c
+++ b/hw/misc/lm32_sys.c
@@ -42,7 +42,7 @@ enum {
     R_MAX
 };
 
-#define MAX_TESTNAME_LEN 16
+#define MAX_TESTNAME_LEN 32
 
 #define TYPE_LM32_SYS "lm32-sys"
 #define LM32_SYS(obj) OBJECT_CHECK(LM32SysState, (obj), TYPE_LM32_SYS)
@@ -80,7 +80,7 @@ static void sys_write(void *opaque, hwaddr addr,
     case R_PASSFAIL:
         s->regs[addr] = value;
         testname = (char *)s->testname;
-        qemu_log("TC  %-16s %s\n", testname, (value) ? "FAILED" : "OK");
+        qemu_log("TC  %-32s %s\n", testname, (value) ? "FAILED" : "OK");
         break;
     case R_TESTNAME:
         s->regs[addr] = value;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 02/11] tests: lm32: new rule for single test cases
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 01/11] lm32_sys: increase test case name length limit Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 03/11] milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write() Michael Walle
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

Introduce new target "check_%" to run indiviudal test caes, eg.
  make check_mmu

Signed-off-by: Michael Walle <michael@walle.cc>
---
 tests/tcg/lm32/Makefile |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile
index 9a00ef7..19e0664 100644
--- a/tests/tcg/lm32/Makefile
+++ b/tests/tcg/lm32/Makefile
@@ -101,5 +101,8 @@ check: $(CRT) $(SYS) $(TESTCASES)
 		$(SIM) $(SIMFLAGS) ./$$case; \
 	done
 
+check_%: test_%.tst $(CRT) $(SYS)
+	$(SIM) $(SIMFLAGS) $<
+
 clean:
 	$(RM) -fr $(TESTCASES) $(CRT)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 03/11] milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write()
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 01/11] lm32_sys: increase test case name length limit Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 02/11] tests: lm32: new rule for single test cases Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 04/11] lm32_uart/lm32_juart: use qemu_chr_fe_write_all() Michael Walle
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle, Antony Pavlov

From: Antony Pavlov <antonynpavlov@gmail.com>

qemu_chr_fe_write() is capable of returning 0
to indicate EAGAIN (and friends) and we don't
handle this.

Just change it to qemu_chr_fe_write_all() to fix.

Reported-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Acked-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/char/milkymist-uart.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 2e4b5c5..6e4bc20 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -124,7 +124,7 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value,
     switch (addr) {
     case R_RXTX:
         if (s->chr) {
-            qemu_chr_fe_write(s->chr, &ch, 1);
+            qemu_chr_fe_write_all(s->chr, &ch, 1);
         }
         s->regs[R_STAT] |= STAT_TX_EVT;
         break;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 04/11] lm32_uart/lm32_juart: use qemu_chr_fe_write_all()
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (2 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 03/11] milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write() Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 05/11] target-lm32: register helper functions Michael Walle
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

qemu_chr_fe_write() may return EAGAIN. Therefore, use
qemu_chr_fe_write_all().

Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/char/lm32_juart.c |    2 +-
 hw/char/lm32_uart.c  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index 252fe46..380cb5d 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -75,7 +75,7 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
 
     s->jtx = jtx;
     if (s->chr) {
-        qemu_chr_fe_write(s->chr, &ch, 1);
+        qemu_chr_fe_write_all(s->chr, &ch, 1);
     }
 }
 
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index 85d7265..84c2549 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -177,7 +177,7 @@ static void uart_write(void *opaque, hwaddr addr,
     switch (addr) {
     case R_RXTX:
         if (s->chr) {
-            qemu_chr_fe_write(s->chr, &ch, 1);
+            qemu_chr_fe_write_all(s->chr, &ch, 1);
         }
         break;
     case R_IER:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 05/11] target-lm32: register helper functions
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (3 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 04/11] lm32_uart/lm32_juart: use qemu_chr_fe_write_all() Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 06/11] milkymist-vgafb: swap pixel data in source buffer Michael Walle
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

This has been forgotton in the initial commit. Fix it.

Reported-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Walle <michael@walle.cc>
---
 target-lm32/translate.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 6ea0ecd..9605494 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1234,5 +1234,8 @@ void lm32_translate_init(void)
     cpu_deba = tcg_global_mem_new(TCG_AREG0,
                     offsetof(CPULM32State, deba),
                     "deba");
+
+#define GEN_HELPER 2
+#include "helper.h"
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 06/11] milkymist-vgafb: swap pixel data in source buffer
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (4 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 05/11] target-lm32: register helper functions Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 07/11] target-lm32: kill cpu_abort() calls Michael Walle
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Michael Walle

In commit fc97bb5ba3e7239c0b6d24095df6784868dfebbf the lduw_raw() call was
eliminated. But we are reading from the target buffer a 16-bit value, which
is in big-endian format. Therefore, swap the bytes if we are building for a
little-endian host.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/display/milkymist-vgafb_template.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/display/milkymist-vgafb_template.h b/hw/display/milkymist-vgafb_template.h
index e0036e1..5a906af 100644
--- a/hw/display/milkymist-vgafb_template.h
+++ b/hw/display/milkymist-vgafb_template.h
@@ -62,6 +62,9 @@ static void glue(draw_line_, BITS)(void *opaque, uint8_t *d, const uint8_t *s,
 
     while (width--) {
         memcpy(&rgb565, s, sizeof(rgb565));
+#ifndef HOST_WORDS_BIGENDIAN
+        rgb565 = bswap16(rgb565);
+#endif
         r = ((rgb565 >> 11) & 0x1f) << 3;
         g = ((rgb565 >>  5) & 0x3f) << 2;
         b = ((rgb565 >>  0) & 0x1f) << 3;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 07/11] target-lm32: kill cpu_abort() calls
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (5 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 06/11] milkymist-vgafb: swap pixel data in source buffer Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 08/11] target-lm32: move model features to LM32CPU Michael Walle
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle, Andreas Färber

Instead of killing QEMU, translate instructions which are not available on
the CPU model as a noop and issue a log message at translation time.

On the real hardware CPU unknown opcodes results in undefined behaviour.

These changes prepare the removal of CPULM32State from DisasContext.

Cc: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Walle <michael@walle.cc>
---
 target-lm32/translate.c |   72 ++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 32 deletions(-)

diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 9605494..1d94d52 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -80,7 +80,6 @@ typedef struct DisasContext {
     unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
     int is_jmp;
 
-    int nr_nops;
     struct TranslationBlock *tb;
     int singlestep_enabled;
 } DisasContext;
@@ -422,7 +421,8 @@ static void dec_divu(DisasContext *dc)
     LOG_DIS("divu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
 
     if (!(dc->env->features & LM32_FEATURE_DIVIDE)) {
-        cpu_abort(dc->env, "hardware divider is not available\n");
+        qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
+        return;
     }
 
     l1 = gen_new_label();
@@ -500,7 +500,8 @@ static void dec_modu(DisasContext *dc)
     LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);
 
     if (!(dc->env->features & LM32_FEATURE_DIVIDE)) {
-        cpu_abort(dc->env, "hardware divider is not available\n");
+        qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
+        return;
     }
 
     l1 = gen_new_label();
@@ -521,7 +522,9 @@ static void dec_mul(DisasContext *dc)
     }
 
     if (!(dc->env->features & LM32_FEATURE_MULTIPLY)) {
-        cpu_abort(dc->env, "hardware multiplier is not available\n");
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "hardware multiplier is not available\n");
+        return;
     }
 
     if (dc->format == OP_FMT_RI) {
@@ -590,7 +593,8 @@ static void dec_scall(DisasContext *dc)
     } else if (dc->imm5 == 2) {
         LOG_DIS("break\n");
     } else {
-        cpu_abort(dc->env, "invalid opcode\n");
+        qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode @0x%x", dc->pc);
+        return;
     }
 
     if (dc->imm5 == 7) {
@@ -647,10 +651,10 @@ static void dec_rcsr(DisasContext *dc)
     case CSR_WP1:
     case CSR_WP2:
     case CSR_WP3:
-        cpu_abort(dc->env, "invalid read access csr=%x\n", dc->csr);
+        qemu_log_mask(LOG_GUEST_ERROR, "invalid read access csr=%x\n", dc->csr);
         break;
     default:
-        cpu_abort(dc->env, "read_csr: unknown csr=%x\n", dc->csr);
+        qemu_log_mask(LOG_GUEST_ERROR, "read_csr: unknown csr=%x\n", dc->csr);
         break;
     }
 }
@@ -672,7 +676,9 @@ static void dec_sextb(DisasContext *dc)
     LOG_DIS("sextb r%d, r%d\n", dc->r2, dc->r0);
 
     if (!(dc->env->features & LM32_FEATURE_SIGN_EXTEND)) {
-        cpu_abort(dc->env, "hardware sign extender is not available\n");
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "hardware sign extender is not available\n");
+        return;
     }
 
     tcg_gen_ext8s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
@@ -683,7 +689,9 @@ static void dec_sexth(DisasContext *dc)
     LOG_DIS("sexth r%d, r%d\n", dc->r2, dc->r0);
 
     if (!(dc->env->features & LM32_FEATURE_SIGN_EXTEND)) {
-        cpu_abort(dc->env, "hardware sign extender is not available\n");
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "hardware sign extender is not available\n");
+        return;
     }
 
     tcg_gen_ext16s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
@@ -710,7 +718,8 @@ static void dec_sl(DisasContext *dc)
     }
 
     if (!(dc->env->features & LM32_FEATURE_SHIFT)) {
-        cpu_abort(dc->env, "hardware shifter is not available\n");
+        qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n");
+        return;
     }
 
     if (dc->format == OP_FMT_RI) {
@@ -736,7 +745,9 @@ static void dec_sr(DisasContext *dc)
             /* TODO: check r1 == 1 during runtime */
         } else {
             if (dc->imm5 != 1) {
-                cpu_abort(dc->env, "hardware shifter is not available\n");
+                qemu_log_mask(LOG_GUEST_ERROR,
+                        "hardware shifter is not available\n");
+                return;
             }
         }
     }
@@ -764,7 +775,9 @@ static void dec_sru(DisasContext *dc)
             /* TODO: check r1 == 1 during runtime */
         } else {
             if (dc->imm5 != 1) {
-                cpu_abort(dc->env, "hardware shifter is not available\n");
+                qemu_log_mask(LOG_GUEST_ERROR,
+                        "hardware shifter is not available\n");
+                return;
             }
         }
     }
@@ -802,7 +815,7 @@ static void dec_user(DisasContext *dc)
 {
     LOG_DIS("user");
 
-    cpu_abort(dc->env, "user insn undefined\n");
+    qemu_log_mask(LOG_GUEST_ERROR, "user instruction undefined\n");
 }
 
 static void dec_wcsr(DisasContext *dc)
@@ -868,7 +881,9 @@ static void dec_wcsr(DisasContext *dc)
     case CSR_BP3:
         no = dc->csr - CSR_BP0;
         if (dc->env->num_bps <= no) {
-            cpu_abort(dc->env, "breakpoint #%i is not available\n", no);
+            qemu_log_mask(LOG_GUEST_ERROR,
+                    "breakpoint #%i is not available\n", no);
+            break;
         }
         tcg_gen_mov_tl(cpu_bp[no], cpu_R[dc->r1]);
         break;
@@ -878,16 +893,20 @@ static void dec_wcsr(DisasContext *dc)
     case CSR_WP3:
         no = dc->csr - CSR_WP0;
         if (dc->env->num_wps <= no) {
-            cpu_abort(dc->env, "watchpoint #%i is not available\n", no);
+            qemu_log_mask(LOG_GUEST_ERROR,
+                    "watchpoint #%i is not available\n", no);
+            break;
         }
         tcg_gen_mov_tl(cpu_wp[no], cpu_R[dc->r1]);
         break;
     case CSR_CC:
     case CSR_CFG:
-        cpu_abort(dc->env, "invalid write access csr=%x\n", dc->csr);
+        qemu_log_mask(LOG_GUEST_ERROR, "invalid write access csr=%x\n",
+                dc->csr);
         break;
     default:
-        cpu_abort(dc->env, "write_csr unknown csr=%x\n", dc->csr);
+        qemu_log_mask(LOG_GUEST_ERROR, "write_csr: unknown csr=%x\n",
+                dc->csr);
         break;
     }
 }
@@ -933,7 +952,7 @@ static void dec_xor(DisasContext *dc)
 
 static void dec_ill(DisasContext *dc)
 {
-    cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode);
+    qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode 0x%02x\n", dc->opcode);
 }
 
 typedef void (*DecoderInfo)(DisasContext *dc);
@@ -959,18 +978,6 @@ static inline void decode(DisasContext *dc, uint32_t ir)
     dc->ir = ir;
     LOG_DIS("%8.8x\t", dc->ir);
 
-    /* try guessing 'empty' instruction memory, although it may be a valid
-     * instruction sequence (eg. srui r0, r0, 0) */
-    if (dc->ir) {
-        dc->nr_nops = 0;
-    } else {
-        LOG_DIS("nr_nops=%d\t", dc->nr_nops);
-        dc->nr_nops++;
-        if (dc->nr_nops > 4) {
-            cpu_abort(dc->env, "fetching nop sequence\n");
-        }
-    }
-
     dc->opcode = EXTRACT_FIELD(ir, 26, 31);
 
     dc->imm5 = EXTRACT_FIELD(ir, 0, 4);
@@ -1034,10 +1041,11 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
     dc->singlestep_enabled = cs->singlestep_enabled;
-    dc->nr_nops = 0;
 
     if (pc_start & 3) {
-        cpu_abort(env, "LM32: unaligned PC=%x\n", pc_start);
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "unaligned PC=%x. Ignoring lowest bits.\n", pc_start);
+        pc_start &= ~3;
     }
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 08/11] target-lm32: move model features to LM32CPU
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (6 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 07/11] target-lm32: kill cpu_abort() calls Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 09/11] target-lm32: add breakpoint/watchpoint support Michael Walle
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle, Andreas Färber

This allows us to completely remove CPULM32State from DisasContext.
Instead, copy the fields we need to DisasContext.

Cc: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Walle <michael@walle.cc>
---
 target-lm32/cpu-qom.h   |    1 +
 target-lm32/cpu.h       |   12 +++++++++---
 target-lm32/helper.c    |   15 ++-------------
 target-lm32/translate.c |   24 ++++++++++++------------
 4 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index 723f604..9f4e233 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -60,6 +60,7 @@ typedef struct LM32CPU {
     /*< public >*/
 
     CPULM32State env;
+    const LM32Def *def;
 } LM32CPU;
 
 static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index dbfe043..67a785e 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -149,6 +149,15 @@ enum {
     LM32_FLAG_IGNORE_MSB = 1,
 };
 
+typedef struct {
+    const char *name;
+    uint32_t revision;
+    uint8_t num_interrupts;
+    uint8_t num_breakpoints;
+    uint8_t num_watchpoints;
+    uint32_t features;
+} LM32Def;
+
 struct CPULM32State {
     /* general registers */
     uint32_t regs[32];
@@ -177,10 +186,7 @@ struct CPULM32State {
     DeviceState *juart_state;
 
     /* processor core features */
-    uint32_t features;
     uint32_t flags;
-    uint8_t num_bps;
-    uint8_t num_wps;
 
 };
 
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 15bc615..383bcf3 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -90,15 +90,6 @@ void lm32_cpu_do_interrupt(CPUState *cs)
     }
 }
 
-typedef struct {
-    const char *name;
-    uint32_t revision;
-    uint8_t num_interrupts;
-    uint8_t num_breakpoints;
-    uint8_t num_watchpoints;
-    uint32_t features;
-} LM32Def;
-
 static const LM32Def lm32_defs[] = {
     {
         .name = "lm32-basic",
@@ -214,11 +205,9 @@ LM32CPU *cpu_lm32_init(const char *cpu_model)
     }
 
     cpu = LM32_CPU(object_new(TYPE_LM32_CPU));
-    env = &cpu->env;
+    cpu->def = def;
 
-    env->features = def->features;
-    env->num_bps = def->num_breakpoints;
-    env->num_wps = def->num_watchpoints;
+    env = &cpu->env;
     env->cfg = cfg_by_def(def);
 
     object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 1d94d52..c8c862e 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -64,7 +64,7 @@ enum {
 
 /* This is the state at translation time.  */
 typedef struct DisasContext {
-    CPULM32State *env;
+    const LM32Def *def;
     target_ulong pc;
 
     /* Decoder.  */
@@ -420,7 +420,7 @@ static void dec_divu(DisasContext *dc)
 
     LOG_DIS("divu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
 
-    if (!(dc->env->features & LM32_FEATURE_DIVIDE)) {
+    if (!(dc->def->features & LM32_FEATURE_DIVIDE)) {
         qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
         return;
     }
@@ -499,7 +499,7 @@ static void dec_modu(DisasContext *dc)
 
     LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);
 
-    if (!(dc->env->features & LM32_FEATURE_DIVIDE)) {
+    if (!(dc->def->features & LM32_FEATURE_DIVIDE)) {
         qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
         return;
     }
@@ -521,7 +521,7 @@ static void dec_mul(DisasContext *dc)
         LOG_DIS("mul r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
     }
 
-    if (!(dc->env->features & LM32_FEATURE_MULTIPLY)) {
+    if (!(dc->def->features & LM32_FEATURE_MULTIPLY)) {
         qemu_log_mask(LOG_GUEST_ERROR,
                 "hardware multiplier is not available\n");
         return;
@@ -675,7 +675,7 @@ static void dec_sextb(DisasContext *dc)
 {
     LOG_DIS("sextb r%d, r%d\n", dc->r2, dc->r0);
 
-    if (!(dc->env->features & LM32_FEATURE_SIGN_EXTEND)) {
+    if (!(dc->def->features & LM32_FEATURE_SIGN_EXTEND)) {
         qemu_log_mask(LOG_GUEST_ERROR,
                 "hardware sign extender is not available\n");
         return;
@@ -688,7 +688,7 @@ static void dec_sexth(DisasContext *dc)
 {
     LOG_DIS("sexth r%d, r%d\n", dc->r2, dc->r0);
 
-    if (!(dc->env->features & LM32_FEATURE_SIGN_EXTEND)) {
+    if (!(dc->def->features & LM32_FEATURE_SIGN_EXTEND)) {
         qemu_log_mask(LOG_GUEST_ERROR,
                 "hardware sign extender is not available\n");
         return;
@@ -717,7 +717,7 @@ static void dec_sl(DisasContext *dc)
         LOG_DIS("sl r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
     }
 
-    if (!(dc->env->features & LM32_FEATURE_SHIFT)) {
+    if (!(dc->def->features & LM32_FEATURE_SHIFT)) {
         qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n");
         return;
     }
@@ -740,7 +740,7 @@ static void dec_sr(DisasContext *dc)
         LOG_DIS("sr r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
     }
 
-    if (!(dc->env->features & LM32_FEATURE_SHIFT)) {
+    if (!(dc->def->features & LM32_FEATURE_SHIFT)) {
         if (dc->format == OP_FMT_RI) {
             /* TODO: check r1 == 1 during runtime */
         } else {
@@ -770,7 +770,7 @@ static void dec_sru(DisasContext *dc)
         LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
     }
 
-    if (!(dc->env->features & LM32_FEATURE_SHIFT)) {
+    if (!(dc->def->features & LM32_FEATURE_SHIFT)) {
         if (dc->format == OP_FMT_RI) {
             /* TODO: check r1 == 1 during runtime */
         } else {
@@ -880,7 +880,7 @@ static void dec_wcsr(DisasContext *dc)
     case CSR_BP2:
     case CSR_BP3:
         no = dc->csr - CSR_BP0;
-        if (dc->env->num_bps <= no) {
+        if (dc->def->num_breakpoints <= no) {
             qemu_log_mask(LOG_GUEST_ERROR,
                     "breakpoint #%i is not available\n", no);
             break;
@@ -892,7 +892,7 @@ static void dec_wcsr(DisasContext *dc)
     case CSR_WP2:
     case CSR_WP3:
         no = dc->csr - CSR_WP0;
-        if (dc->env->num_wps <= no) {
+        if (dc->def->num_watchpoints <= no) {
             qemu_log_mask(LOG_GUEST_ERROR,
                     "watchpoint #%i is not available\n", no);
             break;
@@ -1033,7 +1033,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
     int max_insns;
 
     pc_start = tb->pc;
-    dc->env = env;
+    dc->def = cpu->def;
     dc->tb = tb;
 
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 09/11] target-lm32: add breakpoint/watchpoint support
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (7 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 08/11] target-lm32: move model features to LM32CPU Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 10/11] lm32_sys: print test result on stderr Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 11/11] lm32_sys: dump cpu state if test case fails Michael Walle
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

This patch adds in-target breakpoint and watchpoint support.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 target-lm32/TODO        |    2 --
 target-lm32/cpu.c       |    1 +
 target-lm32/cpu.h       |   27 ++++++++++++--
 target-lm32/helper.c    |   89 +++++++++++++++++++++++++++++++++++++++++++++++
 target-lm32/helper.h    |    3 ++
 target-lm32/op_helper.c |   58 +++++++++++++++++++++++++++++-
 target-lm32/translate.c |    6 ++--
 7 files changed, 178 insertions(+), 8 deletions(-)

diff --git a/target-lm32/TODO b/target-lm32/TODO
index b9ea0c8..e163c42 100644
--- a/target-lm32/TODO
+++ b/target-lm32/TODO
@@ -1,3 +1 @@
-* disassembler (lm32-dis.c)
 * linux-user emulation
-* native bp/wp emulation (?)
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 869878c..2ca8dee 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -71,6 +71,7 @@ static void lm32_cpu_initfn(Object *obj)
     if (tcg_enabled() && !tcg_initialized) {
         tcg_initialized = true;
         lm32_translate_init();
+        cpu_set_debug_excp_handler(lm32_debug_excp_handler);
     }
 }
 
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 67a785e..cef9167 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -172,8 +172,11 @@ struct CPULM32State {
 
     /* debug registers */
     uint32_t dc;        /* debug control */
-    uint32_t bp[4];     /* breakpoint addresses */
-    uint32_t wp[4];     /* watchpoint addresses */
+    uint32_t bp[4];     /* breakpoints */
+    uint32_t wp[4];     /* watchpoints */
+
+    CPUBreakpoint * cpu_breakpoint[4];
+    CPUWatchpoint * cpu_watchpoint[4];
 
     CPU_COMMON
 
@@ -190,6 +193,19 @@ struct CPULM32State {
 
 };
 
+typedef enum {
+    LM32_WP_DISABLED = 0,
+    LM32_WP_READ,
+    LM32_WP_WRITE,
+    LM32_WP_READ_WRITE,
+} lm32_wp_t;
+
+static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
+{
+    assert(idx < 4);
+    return (dc >> (idx+1)*2) & 0x3;
+}
+
 #include "cpu-qom.h"
 
 LM32CPU *cpu_lm32_init(const char *cpu_model);
@@ -202,6 +218,13 @@ int cpu_lm32_signal_handler(int host_signum, void *pinfo,
                           void *puc);
 void lm32_translate_init(void);
 void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value);
+void QEMU_NORETURN raise_exception(CPULM32State *env, int index);
+void lm32_debug_excp_handler(CPULM32State *env);
+void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address);
+void lm32_breakpoint_remove(CPULM32State *env, int index);
+void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
+        lm32_wp_t wp_type);
+void lm32_watchpoint_remove(CPULM32State *env, int index);
 
 static inline CPULM32State *cpu_init(const char *cpu_model)
 {
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 383bcf3..cff1b95 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -49,6 +49,95 @@ hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     }
 }
 
+void lm32_breakpoint_insert(CPULM32State *env, int idx, target_ulong address)
+{
+    cpu_breakpoint_insert(env, address, BP_CPU, &env->cpu_breakpoint[idx]);
+}
+
+void lm32_breakpoint_remove(CPULM32State *env, int idx)
+{
+    if (!env->cpu_breakpoint[idx]) {
+        return;
+    }
+
+    cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[idx]);
+    env->cpu_breakpoint[idx] = NULL;
+}
+
+void lm32_watchpoint_insert(CPULM32State *env, int idx, target_ulong address,
+                            lm32_wp_t wp_type)
+{
+    int flags = 0;
+
+    switch (wp_type) {
+    case LM32_WP_DISABLED:
+        /* nothing to to */
+        break;
+    case LM32_WP_READ:
+        flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_READ;
+        break;
+    case LM32_WP_WRITE:
+        flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_WRITE;
+        break;
+    case LM32_WP_READ_WRITE:
+        flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_ACCESS;
+        break;
+    }
+
+    if (flags != 0) {
+        cpu_watchpoint_insert(env, address, 1, flags,
+                &env->cpu_watchpoint[idx]);
+    }
+}
+
+void lm32_watchpoint_remove(CPULM32State *env, int idx)
+{
+    if (!env->cpu_watchpoint[idx]) {
+        return;
+    }
+
+    cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[idx]);
+    env->cpu_watchpoint[idx] = NULL;
+}
+
+static bool check_watchpoints(CPULM32State *env)
+{
+    LM32CPU *cpu = lm32_env_get_cpu(env);
+    int i;
+
+    for (i = 0; i < cpu->def->num_watchpoints; i++) {
+        if (env->cpu_watchpoint[i] &&
+                env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void lm32_debug_excp_handler(CPULM32State *env)
+{
+    CPUBreakpoint *bp;
+
+    if (env->watchpoint_hit) {
+        if (env->watchpoint_hit->flags & BP_CPU) {
+            env->watchpoint_hit = NULL;
+            if (check_watchpoints(env)) {
+                raise_exception(env, EXCP_WATCHPOINT);
+            } else {
+                cpu_resume_from_signal(env, NULL);
+            }
+        }
+    } else {
+        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
+            if (bp->pc == env->pc) {
+                if (bp->flags & BP_CPU) {
+                    raise_exception(env, EXCP_BREAKPOINT);
+                }
+                break;
+            }
+    }
+}
+
 void lm32_cpu_do_interrupt(CPUState *cs)
 {
     LM32CPU *cpu = LM32_CPU(cs);
diff --git a/target-lm32/helper.h b/target-lm32/helper.h
index 3ea15a6..ad44fdf 100644
--- a/target-lm32/helper.h
+++ b/target-lm32/helper.h
@@ -2,6 +2,9 @@
 
 DEF_HELPER_2(raise_exception, void, env, i32)
 DEF_HELPER_1(hlt, void, env)
+DEF_HELPER_3(wcsr_bp, void, env, i32, i32)
+DEF_HELPER_3(wcsr_wp, void, env, i32, i32)
+DEF_HELPER_2(wcsr_dc, void, env, i32)
 DEF_HELPER_2(wcsr_im, void, env, i32)
 DEF_HELPER_2(wcsr_ip, void, env, i32)
 DEF_HELPER_2(wcsr_jtx, void, env, i32)
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 8f5ef55..71f21d1 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -19,12 +19,17 @@
 #define SHIFT 3
 #include "exec/softmmu_template.h"
 
-void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
+void raise_exception(CPULM32State *env, int index)
 {
     env->exception_index = index;
     cpu_loop_exit(env);
 }
 
+void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
+{
+    raise_exception(env, index);
+}
+
 void HELPER(hlt)(CPULM32State *env)
 {
     CPUState *cs = CPU(lm32_env_get_cpu(env));
@@ -34,6 +39,57 @@ void HELPER(hlt)(CPULM32State *env)
     cpu_loop_exit(env);
 }
 
+void HELPER(wcsr_bp)(CPULM32State *env, uint32_t bp, uint32_t idx)
+{
+    uint32_t addr = bp & ~1;
+
+    assert(idx < 4);
+
+    env->bp[idx] = bp;
+    lm32_breakpoint_remove(env, idx);
+    if (bp & 1) {
+        lm32_breakpoint_insert(env, idx, addr);
+    }
+}
+
+void HELPER(wcsr_wp)(CPULM32State *env, uint32_t wp, uint32_t idx)
+{
+    lm32_wp_t wp_type;
+
+    assert(idx < 4);
+
+    env->wp[idx] = wp;
+
+    wp_type = lm32_wp_type(env->dc, idx);
+    lm32_watchpoint_remove(env, idx);
+    if (wp_type != LM32_WP_DISABLED) {
+        lm32_watchpoint_insert(env, idx, wp, wp_type);
+    }
+}
+
+void HELPER(wcsr_dc)(CPULM32State *env, uint32_t dc)
+{
+    uint32_t old_dc;
+    int i;
+    lm32_wp_t old_type;
+    lm32_wp_t new_type;
+
+    old_dc = env->dc;
+    env->dc = dc;
+
+    for (i = 0; i < 4; i++) {
+        old_type = lm32_wp_type(old_dc, i);
+        new_type = lm32_wp_type(dc, i);
+
+        if (old_type != new_type) {
+            lm32_watchpoint_remove(env, i);
+            if (new_type != LM32_WP_DISABLED) {
+                lm32_watchpoint_insert(env, i, env->wp[i], new_type);
+            }
+        }
+    }
+}
+
 void HELPER(wcsr_im)(CPULM32State *env, uint32_t im)
 {
     lm32_pic_set_im(env->pic_state, im);
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index c8c862e..5abd2aa 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -873,7 +873,7 @@ static void dec_wcsr(DisasContext *dc)
         gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);
         break;
     case CSR_DC:
-        tcg_gen_mov_tl(cpu_dc, cpu_R[dc->r1]);
+        gen_helper_wcsr_dc(cpu_env, cpu_R[dc->r1]);
         break;
     case CSR_BP0:
     case CSR_BP1:
@@ -885,7 +885,7 @@ static void dec_wcsr(DisasContext *dc)
                     "breakpoint #%i is not available\n", no);
             break;
         }
-        tcg_gen_mov_tl(cpu_bp[no], cpu_R[dc->r1]);
+        gen_helper_wcsr_bp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
         break;
     case CSR_WP0:
     case CSR_WP1:
@@ -897,7 +897,7 @@ static void dec_wcsr(DisasContext *dc)
                     "watchpoint #%i is not available\n", no);
             break;
         }
-        tcg_gen_mov_tl(cpu_wp[no], cpu_R[dc->r1]);
+        gen_helper_wcsr_wp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
         break;
     case CSR_CC:
     case CSR_CFG:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 10/11] lm32_sys: print test result on stderr
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (8 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 09/11] target-lm32: add breakpoint/watchpoint support Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  2013-09-25 18:59 ` [Qemu-devel] [PULL 11/11] lm32_sys: dump cpu state if test case fails Michael Walle
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

Do not use qemu_log().

Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/misc/lm32_sys.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/lm32_sys.c b/hw/misc/lm32_sys.c
index 8176cdb..6af0cca 100644
--- a/hw/misc/lm32_sys.c
+++ b/hw/misc/lm32_sys.c
@@ -80,7 +80,7 @@ static void sys_write(void *opaque, hwaddr addr,
     case R_PASSFAIL:
         s->regs[addr] = value;
         testname = (char *)s->testname;
-        qemu_log("TC  %-32s %s\n", testname, (value) ? "FAILED" : "OK");
+        fprintf(stderr, "TC  %-32s %s\n", testname, (value) ? "FAILED" : "OK");
         break;
     case R_TESTNAME:
         s->regs[addr] = value;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PULL 11/11] lm32_sys: dump cpu state if test case fails
  2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
                   ` (9 preceding siblings ...)
  2013-09-25 18:59 ` [Qemu-devel] [PULL 10/11] lm32_sys: print test result on stderr Michael Walle
@ 2013-09-25 18:59 ` Michael Walle
  10 siblings, 0 replies; 12+ messages in thread
From: Michael Walle @ 2013-09-25 18:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle

This will ease debugging the test cases.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/misc/lm32_sys.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/misc/lm32_sys.c b/hw/misc/lm32_sys.c
index 6af0cca..1fd69ff 100644
--- a/hw/misc/lm32_sys.c
+++ b/hw/misc/lm32_sys.c
@@ -81,6 +81,9 @@ static void sys_write(void *opaque, hwaddr addr,
         s->regs[addr] = value;
         testname = (char *)s->testname;
         fprintf(stderr, "TC  %-32s %s\n", testname, (value) ? "FAILED" : "OK");
+        if (value) {
+            cpu_dump_state(qemu_get_cpu(0), stderr, fprintf, 0);
+        }
         break;
     case R_TESTNAME:
         s->regs[addr] = value;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-09-25 19:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-25 18:59 [Qemu-devel] [PULL 00/11] target-lm32 updates Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 01/11] lm32_sys: increase test case name length limit Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 02/11] tests: lm32: new rule for single test cases Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 03/11] milkymist-uart: use qemu_chr_fe_write_all() instead of qemu_chr_fe_write() Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 04/11] lm32_uart/lm32_juart: use qemu_chr_fe_write_all() Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 05/11] target-lm32: register helper functions Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 06/11] milkymist-vgafb: swap pixel data in source buffer Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 07/11] target-lm32: kill cpu_abort() calls Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 08/11] target-lm32: move model features to LM32CPU Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 09/11] target-lm32: add breakpoint/watchpoint support Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 10/11] lm32_sys: print test result on stderr Michael Walle
2013-09-25 18:59 ` [Qemu-devel] [PULL 11/11] lm32_sys: dump cpu state if test case fails Michael Walle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).