Patchwork [0/3] PPC: E500: Support SPE guest

login
register
mail settings
Submitter Edgar Iglesias
Date Aug. 23, 2011, 8:10 p.m.
Message ID <20110823201017.GE32250@zapo>
Download mbox | patch
Permalink /patch/111177/
State New
Headers show

Comments

Edgar Iglesias - Aug. 23, 2011, 8:10 p.m.
On Tue, Aug 23, 2011 at 12:00:00PM -0500, Jason Wessel wrote:
> On 08/22/2011 11:55 PM, Alexander Graf wrote:
> > When I bumped into Jason on Linuxcon, we tried out to run the e500 target
> > on his Windriver build that used SPE and immediately ran into emulation
> > issues. Fortunately there weren't too many, so here are the patches to get
> > a guest using SPE instructions working just fine.
> >
> 
> The patch set looks good to me.  I tried it out this morning.
> 
> I have a patch that implements enough of the the dbcr0, dbsr, and msr DE bit in
> order to single step, but I am seeing random fatal mmu faults.   Before we go

Hi Jason,

We did something with PetaLogix to get the gdbserver working on a ppc440
linux a while ago. It was done a bit in a hurry and I've been meaning to
get back to it for rebase/cleanup and contribution, but it just hasnt
happened yet, sorry. ATM I dont recall the details, but IIRC it worked
quite OK at the time.

Maybe useful to compare notes at least.

Cheers

commit 3c905e20ca654e019db045749b4e1abeb46704ae
Author: Edgar E. Iglesias <edgar.iglesias@petalogix.com>
Date:   Wed Nov 24 22:15:53 2010 +0100

    ppc: Implement parts of the BookE debug features
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias@petalogix.com>

Patch

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 74526a2..2264bc1 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1349,6 +1349,26 @@  static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
 #define SPR_604_HID15         (0x3FF)
 #define SPR_E500_SVR          (0x3FF)
 
+/* DBCR0 Definitions.  */
+#define DBCR0_EDM              31
+#define DBCR0_IDM              30
+#define DBCR0_ICMP             27
+#define DBCR0_IAC1             23
+#define DBCR0_IAC2             22
+#define DBCR0_IAC3             21
+#define DBCR0_IAC4             20
+#define DBCR0_DAC1R            19
+#define DBCR0_DAC1W            18
+#define DBCR0_DAC2R            17
+#define DBCR0_DAC2W            16
+
+/* DBSR Definitions.  */
+#define DBSR_ICMP              27
+#define DBSR_IAC1              23
+#define DBSR_IAC2              22
+#define DBSR_IAC3              21
+#define DBSR_IAC4              20
+
 /*****************************************************************************/
 /* PowerPC Instructions types definitions                                    */
 enum {
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 3bc8a34..22b148e 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -2281,7 +2281,6 @@  static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
             break;
         }
         /* XXX: TODO */
-        cpu_abort(env, "Debug exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
         goto store_current;
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index c4e72b1..f1a0093 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -400,6 +400,9 @@  DEF_HELPER_2(store_dbatl, void, i32, tl)
 DEF_HELPER_2(store_dbatu, void, i32, tl)
 DEF_HELPER_2(store_601_batl, void, i32, tl)
 DEF_HELPER_2(store_601_batu, void, i32, tl)
+
+DEF_HELPER_1(embdebug_issue, void, i32)
+DEF_HELPER_2(embdebug_icmp, void, i32, i32)
 #endif
 
 #include "def-helper.h"
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index 3c98850..265d544 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -56,7 +56,7 @@  static inline void hreg_compute_hflags(CPUPPCState *env)
     /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */
     hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) |
         (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) |
-        (1 << MSR_LE);
+        (1 << MSR_LE) | (1 << MSR_DE);
     hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB;
     hreg_compute_mem_idx(env);
     env->hflags = env->msr & hflags_mask;
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index c050b04..e4b2d79 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -4171,4 +4171,57 @@  target_ulong helper_440_tlbsx (target_ulong address)
     return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF);
 }
 
+/* DEBUG helpers.  */
+void helper_embdebug_issue(target_ulong pc)
+{
+    if (!env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_EDM)) {
+        return;
+    }
+
+    if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC1)
+         && pc == env->spr[SPR_BOOKE_IAC1]) {
+        /* Assert the ICMP bit in the debug status reg.  */
+        env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC1;
+        /* And raise the debug exception.  */
+        helper_raise_exception(POWERPC_EXCP_DEBUG);
+    }
+
+    if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC2)
+         && pc == env->spr[SPR_BOOKE_IAC2]) {
+        /* Assert the ICMP bit in the debug status reg.  */
+        env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC2;
+        /* And raise the debug exception.  */
+        helper_raise_exception(POWERPC_EXCP_DEBUG);
+    }
+
+    if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC3)
+         && pc == env->spr[SPR_BOOKE_IAC3]) {
+        /* Assert the ICMP bit in the debug status reg.  */
+        env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC3;
+        /* And raise the debug exception.  */
+        helper_raise_exception(POWERPC_EXCP_DEBUG);
+    }
+
+    if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IAC4)
+         && pc == env->spr[SPR_BOOKE_IAC4]) {
+        /* Assert the ICMP bit in the debug status reg.  */
+        env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_IAC4;
+        /* And raise the debug exception.  */
+        helper_raise_exception(POWERPC_EXCP_DEBUG);
+    }
+}
+
+void helper_embdebug_icmp(target_ulong pc, target_ulong branch)
+{
+    if (!env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_IDM)) {
+        return;
+    }
+    if (env->spr[SPR_BOOKE_DBCR0] & (1 << DBCR0_ICMP)) {
+        /* Assert the ICMP bit in the debug status reg.  */
+        env->spr[SPR_BOOKE_DBSR] |= 1 << DBSR_ICMP;
+        /* And raise the debug exception.  */
+        helper_raise_exception(POWERPC_EXCP_DEBUG);
+    }
+}
+
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 09f22a3..f5c3c21 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9032,6 +9032,14 @@  static inline void gen_intermediate_code_internal(CPUState *env,
                   ctx.nip, ctx.mem_idx, (int)msr_ir);
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
+
+#if !defined(CONFIG_USER_ONLY)
+        if (env->mmu_model == POWERPC_MMU_BOOKE
+            && env->hflags & (1 << MSR_DE)) {
+            gen_helper_embdebug_issue(tcg_const_tl(ctx.nip));
+        }
+#endif
+
         if (unlikely(ctx.le_mode)) {
             ctx.opcode = bswap32(ldl_code(ctx.nip));
         } else {
@@ -9079,6 +9087,21 @@  static inline void gen_intermediate_code_internal(CPUState *env,
 #if defined(DO_PPC_STATISTICS)
         handler->count++;
 #endif
+
+#if !defined(CONFIG_USER_ONLY)
+        if (env->mmu_model == POWERPC_MMU_BOOKE
+            && env->hflags & (1 << MSR_DE)) {
+            target_ulong branch = 0;
+            if (ctx.exception == POWERPC_EXCP_BRANCH) {
+                  branch = 1;
+            } else
+                  gen_update_nip(&ctx, ctx.nip);
+
+            gen_helper_embdebug_icmp(tcg_const_tl(ctx.nip),
+                                     tcg_const_tl(branch));
+        }
+#endif
+
         /* Check trace mode exceptions */
         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&