qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Filippov <jcmvbkbc@gmail.com>
To: qemu-devel@nongnu.org
Cc: jcmvbkbc@gmail.com
Subject: [Qemu-devel] [RFC 3/9] target-xtensa: add ICOUNT SR and debug exception
Date: Sun, 29 Jan 2012 06:19:25 +0400	[thread overview]
Message-ID: <1327803571-30553-4-git-send-email-jcmvbkbc@gmail.com> (raw)
In-Reply-To: <1327803571-30553-1-git-send-email-jcmvbkbc@gmail.com>

ICOUNT SR gets incremented on every instruction completion provided that
CINTLEVEL at the beginning of the instruction execution is lower than
ICOUNTLEVEL.

When ICOUNT would increment to 0 a debug exception is raised if
CINTLEVEL is lower than DEBUGLEVEL.

See ISA, 4.7.7.5 for more details.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 target-xtensa/cpu.h       |    6 +++++
 target-xtensa/translate.c |   49 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 2875197..fbe5d15 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -142,6 +142,8 @@ enum {
     DEBUGCAUSE = 233,
     CCOUNT = 234,
     PRID = 235,
+    ICOUNT = 236,
+    ICOUNTLEVEL = 237,
     EXCVADDR = 238,
     CCOMPARE = 240,
 };
@@ -428,6 +430,7 @@ static inline int cpu_mmu_index(CPUState *env)
 #define XTENSA_TBFLAG_EXCM 0x4
 #define XTENSA_TBFLAG_LITBASE 0x8
 #define XTENSA_TBFLAG_DEBUG 0x10
+#define XTENSA_TBFLAG_ICOUNT 0x20
 
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
         target_ulong *cs_base, int *flags)
@@ -447,6 +450,9 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
         if (xtensa_get_cintlevel(env) < env->config->debug_level) {
             *flags |= XTENSA_TBFLAG_DEBUG;
         }
+        if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) {
+            *flags |= XTENSA_TBFLAG_ICOUNT;
+        }
     }
 }
 
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 71fbf34..85f41a7 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -63,6 +63,8 @@ typedef struct DisasContext {
     unsigned used_window;
 
     bool debug;
+    bool icount;
+    TCGv_i32 next_icount;
 } DisasContext;
 
 static TCGv_ptr cpu_env;
@@ -127,6 +129,8 @@ static const char * const sregnames[256] = {
     [DEBUGCAUSE] = "DEBUGCAUSE",
     [CCOUNT] = "CCOUNT",
     [PRID] = "PRID",
+    [ICOUNT] = "ICOUNT",
+    [ICOUNTLEVEL] = "ICOUNTLEVEL",
     [EXCVADDR] = "EXCVADDR",
     [CCOMPARE] = "CCOMPARE0",
     [CCOMPARE + 1] = "CCOMPARE1",
@@ -313,10 +317,13 @@ static void gen_check_privilege(DisasContext *dc)
 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
 {
     tcg_gen_mov_i32(cpu_pc, dest);
+    gen_advance_ccount(dc);
+    if (dc->icount) {
+        tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
+    }
     if (dc->singlestep_enabled) {
         gen_exception(dc, EXCP_DEBUG);
     } else {
-        gen_advance_ccount(dc);
         if (slot >= 0) {
             tcg_gen_goto_tb(slot);
             tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
@@ -580,6 +587,22 @@ static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {
 }
 
+static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
+{
+    if (dc->icount) {
+        tcg_gen_mov_i32(dc->next_icount, v);
+    } else {
+        tcg_gen_mov_i32(cpu_SR[sr], v);
+    }
+}
+
+static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
+{
+    tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
+    /* This can change tb->flags, so exit tb */
+    gen_jumpi_check_loop_end(dc, -1);
+}
+
 static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {
     uint32_t id = sr - CCOMPARE;
@@ -617,6 +640,8 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
         [PS] = gen_wsr_ps,
         [DEBUGCAUSE] = gen_wsr_debugcause,
         [PRID] = gen_wsr_prid,
+        [ICOUNT] = gen_wsr_icount,
+        [ICOUNTLEVEL] = gen_wsr_icountlevel,
         [CCOMPARE] = gen_wsr_ccompare,
         [CCOMPARE + 1] = gen_wsr_ccompare,
         [CCOMPARE + 2] = gen_wsr_ccompare,
@@ -2492,10 +2517,14 @@ static void gen_intermediate_code_internal(
     dc.is_jmp = DISAS_NEXT;
     dc.ccount_delta = 0;
     dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
+    dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
 
     init_litbase(&dc);
     init_sar_tracker(&dc);
     reset_used_window(&dc);
+    if (dc.icount) {
+        dc.next_icount = tcg_temp_local_new_i32();
+    }
 
     gen_icount_start();
 
@@ -2531,12 +2560,27 @@ static void gen_intermediate_code_internal(
             gen_io_start();
         }
 
+        if (dc.icount) {
+            int label = gen_new_label();
+
+            tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);
+            tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);
+            tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);
+            if (dc.debug) {
+                gen_debug_exception(&dc, DEBUGCAUSE_IC);
+            }
+            gen_set_label(label);
+        }
+
         if (dc.debug) {
             gen_ibreak_check(env, &dc);
         }
 
         disas_xtensa_insn(&dc);
         ++insn_count;
+        if (dc.icount) {
+            tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
+        }
         if (env->singlestep_enabled) {
             tcg_gen_movi_i32(cpu_pc, dc.pc);
             gen_exception(&dc, EXCP_DEBUG);
@@ -2549,6 +2593,9 @@ static void gen_intermediate_code_internal(
 
     reset_litbase(&dc);
     reset_sar_tracker(&dc);
+    if (dc.icount) {
+        tcg_temp_free(dc.next_icount);
+    }
 
     if (tb->cflags & CF_LAST_IO) {
         gen_io_end();
-- 
1.7.7.6

  parent reply	other threads:[~2012-01-29  2:19 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-29  2:19 [Qemu-devel] [RFC 0/9] target-xtensa: implement debug option Max Filippov
2012-01-29  2:19 ` [Qemu-devel] [RFC 1/9] target-xtensa: add DEBUGCAUSE SR and configuration Max Filippov
2012-01-29  2:19 ` [Qemu-devel] [RFC 2/9] target-xtensa: implement instruction breakpoints Max Filippov
2012-01-29  2:19 ` Max Filippov [this message]
2012-01-29  2:19 ` [Qemu-devel] [RFC 4/9] exec: add missing breaks to the watch_mem_write Max Filippov
2012-01-29  9:49   ` Andreas Färber
2012-01-29  2:19 ` [Qemu-devel] [RFC 5/9] exec: fix check_watchpoint exiting cpu_loop Max Filippov
2012-01-29  2:19 ` [Qemu-devel] [RFC 6/9] exec: let cpu_watchpoint_insert accept larger watchpoints Max Filippov
2012-01-29  2:19 ` [Qemu-devel] [RFC 7/9] target-xtensa: add DBREAK data breakpoints Max Filippov
2012-01-29  2:19 ` [Qemu-devel] [RFC 8/9] target-xtensa: add DEBUG_SECTION to overlay tool Max Filippov
2012-01-29  2:19 ` [Qemu-devel] [RFC 9/9] target-xtensa: add breakpoint tests Max Filippov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1327803571-30553-4-git-send-email-jcmvbkbc@gmail.com \
    --to=jcmvbkbc@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).