qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] PPC 440 : Endless loop executing "mtmsr r3" with r3 set t


From: Pierre Mallard
Subject: Re: [Qemu-ppc] PPC 440 : Endless loop executing "mtmsr r3" with r3 set to 0x10
Date: Wed, 3 Sep 2014 20:44:34 +0200

Thanks Tom for your answer I was further more investigating when I received your mail but I have the same feeling as you.
I propose a patch since return of helper_store_msr returns an exception.

The function "helper_store_msr" calls "hreg_store_msr".
"hreg_store_msr" return POWERPC_EXCP_NONE which is -1.
"helper_store_msr" test for non null return value and generates an exception calling "helper_raise_exception"
This one generates an exception with id -1 which leads to this behavior.
I guess this is not the intended behavior and POWERPC_EXCP_NONE shall not raize any exception.
Either helper_store_msr should test for POWERPC_EXCP_NONE or hreg_store_msr shall send 0. I suppose keeping 0 for other exception is best ?


diff -ru qemu-2.1.0.orig/target-ppc/excp_helper.c qemu-2.1.0/target-ppc/excp_helper.c
--- qemu-2.1.0.orig/target-ppc/excp_helper.c 2014-08-01 16:12:17.000000000 +0200
+++ qemu-2.1.0/target-ppc/excp_helper.c 2014-09-03 18:59:06.680102135 +0200
@@ -847,7 +847,7 @@
     CPUState *cs;
 
     val = hreg_store_msr(env, val, 0);
-    if (val != 0) {
+    if (val != POWERPC_EXCP_NONE) {
         cs = CPU(ppc_env_get_cpu(env));
         cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
         helper_raise_exception(env, val);
diff -ru qemu-2.1.0.orig/target-ppc/helper_regs.h qemu-2.1.0/target-ppc/helper_regs.h
--- qemu-2.1.0.orig/target-ppc/helper_regs.h 2014-08-01 16:12:17.000000000 +0200
+++ qemu-2.1.0/target-ppc/helper_regs.h 2014-09-03 19:15:51.731467306 +0200
@@ -72,7 +72,7 @@
     CPUState *cs = CPU(ppc_env_get_cpu(env));
 #endif
 
-    excp = 0;
+    excp = POWERPC_EXCP_NONE;
     value &= env->msr_mask;
 #if !defined(CONFIG_USER_ONLY)
     if (!alter_hv) {



I go a little bit further (one instruction after exactly !) and got a POWERPC_EXCP_DTLB (13) that is handled by IVOR12 ... but that is another story , ... for sure ! :D

Cheers
Pierre


On Wed, Sep 3, 2014 at 7:34 PM, Tom Musta <address@hidden> wrote:
On 9/3/2014 8:05 AM, Pierre Mallard wrote:
> Hi,
>
> I'm using qemu-2.1.0 on a ppc440 target trying to run xilkernel v5.01.a on it.
> This is definitely a newbee question but I'm a bit confused on what could be causing this behavior :
>
> Interrupt function set in xilkernel such as critical_irq, kernel_irq and non_critical_irq, have this piece of code as function header :
>
> mtsprg  0,r3
> ori         r3,16,r3
> mtmsr   r3
>
> From what I understand it raises level of instruction and data to pass in system mode (r3 is 0x10).

The code sequence sets MSR[DS] = 1.  On the 440, this means that must be TLBs established with TS=1 in order to support data access.  If no such TLB exists, the expected behavior would be a Data TLB Error interrupt (IVOR13).
>
> The problem is that at each time the last instruction is reached (mtmsr r3), pc jump automatically to IVOR12 which appears to be the Watch Dog Interrupt if I understand clearly.

When you say "automatically", do you also mean "immediately?"  I.e., is the instruction following the msr ever executed?  If not, and if that instruction is not a load/store, then this sounds like a QEMU bug.
>
> Since IVOR12 calls critical_irq, which in turn execute the piece of code shown above, the system enters a endless loop instead of executing interrupt handler instruction :
>
> kernel_irq => ... mtmsr r3 => IVOR12 => ... b critical_irq =>
> critical_irq => ... mtmsr r3 => IVOR12 => ... b critical_irq
> ...
>
> Can anyone give me a clue on what is going on here and what do I do wrong ?
>

Reading the code for mtmsr (target-ppc/excp_helper.c), I see this:

void helper_store_msr(CPUPPCState *env, target_ulong val)
{
    CPUState *cs;

    val = hreg_store_msr(env, val, 0);
    if (val != 0) {
        cs = CPU(ppc_env_get_cpu(env));
        cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
        helper_raise_exception(env, val); // <<<<<<<<<<<<<<<<<<<<
    }
}

The "val" argument is the contents of the GPR being written into the MSR and thus is the value 0x10 in this specific case.  The highlighted line looks strange to me -- the helper_raise_exception() routine typically takes an exception mnemonic as an
argument ... not an arbitary 64 bit value.  In fact, I'm not sure that I know what specifically the line of code is trying to do.


> Thanks a lot for your advice,
> Pierre
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]