On 14/03/12 02:59, Mark Cave-Ayland wrote:

Ha okay - I've obviously confused myself with the endian swap in QEMU :/
Let me make some changes, re-test and see if it's possible to submit a
corrected patch that will still work with all of my test images.

Hi Alex,

Please find attached the latest version of my patch which seems to have the same behaviour as git master, except that it now also boots HelenOS. This is based upon the PowerISA reference link you pointed me towards. I've also clarified the comments to make it clearer where the masks have been calculated from, plus modified it so (I hope) it will also work on PPC64.

Any feedback/review/testing greatly appreciated.

Mark.
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index bb76a8b..035a370 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -2478,11 +2478,15 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
                   " => %08x (%02x)\n", env->nip, excp, env->error_code);
 
-    /* new srr1 value excluding must-be-zero bits */
+    /* new srr1 value with interrupt-specific bits defaulting to zero */
     msr = env->msr & ~0x783f0000ULL;
 
-    /* new interrupt handler msr */
-    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
+    /* new interrupt handler msr (as per PowerISA 2.06B p.811 and p.814): 
+       1) force the following bits to zero
+          IR, DR, FE0, FE1, EE, BE, FP, PMM, PR, SE
+       2) default the following bits to zero (can be overidden later on)
+          RI, HVB (note HVB is a different bit between PPC32/64) */
+    new_msr = env->msr & ~0xed36ULL & ~((target_ulong)1 << MSR_HVB);
 
     /* target registers */
     srr0 = SPR_SRR0;
@@ -2960,7 +2964,7 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
     if (asrr1 != -1)
         env->spr[asrr1] = env->spr[srr1];
     /* If we disactivated any translation, flush TLBs */
-    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
+    if (msr & ((1 << MSR_IR) | (1 << MSR_DR)))
         tlb_flush(env, 1);
 
     if (msr_ile) {
_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/cgi-bin/listinfo/helenos-devel

Reply via email to