All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [Bug] MIPS code fails at branch instruction
@ 2007-03-16 23:12 Stefan Weil
  2007-03-17  0:46 ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Weil @ 2007-03-16 23:12 UTC (permalink / raw)
  To: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 825 bytes --]

Hi,

QEMU MIPS emulation fails with code using "illegal" commands
in the delay slot of a branch.

I had an endless loop with QEMU running the firmware of a
MIPS based router.

MIPS says: branches, jumps, ... instructions should not be
placed in the delay slot of a branch or jump.

Nevertheless, some routers use this kind of code.

I wrote a test program to examine the difference between emulation
and a real MIPS CPU (see appendices).

Results are given below for real hardware, normal emulation and
emulation using single stepping.

Stefan


Compile branch test like this:
mipsel-linux-gcc -Os -g btest.c btest2.S

AR7 (MIPS 4KEc) router:
# ./a.out
0
1100
1000

qemu-system-mipsel (unmodified):
# ./a.out
0
# (program hangs)

qemu-system-mipsel (single stepping / MIPS_SINGLE_STEP in translate.c):
# ./a.out
0
1221
1221


[-- Attachment #2: btest.c --]
[-- Type: text/x-csrc, Size: 746 bytes --]

/*

Compile branch test like this:
mipsel-linux-gcc -Os -g btest.c btest2.S

Original code failing with emulation:
218:       8d090000        lw      t1,0(t0)
21c:       31290001        andi    t1,t1,0x1
220:       1120fffd        beqz    t1,0x218
224:       03e00008        jr      ra
228:       3c088000        lui     t0,0x8000
22c:       3c093c1a        lui     t1,0x3c1a

AR7 router:
# ./a.out
0
1100
1000

qemu-system-mipsel (unmodified):
# ./a.out
0
# (program hangs)

qemu-system-mipsel (unmodified):
# ./a.out
0
1221
1221

*/

#include <stdio.h>

extern int test1(int i);
extern int test2(int i);

int main(void)
{
  int i = 0;
  printf("%d\n", i);
  i = test1(0);
  printf("%d\n", i);
  i = test2(0);
  printf("%d\n", i);
  return 0;
}

[-- Attachment #3: btest2.S --]
[-- Type: text/plain, Size: 1141 bytes --]

#if 0
218:       8d090000        lw      t1,0(t0)
21c:       31290001        andi    t1,t1,0x1
220:       1120fffd        beqz    t1,0x218
224:       03e00008        jr      ra
228:       3c088000        lui     t0,0x8000
22c:       3c093c1a        lui     t1,0x3c1a
230:       35299400        ori     t1,t1,0x9400
234:       ad090000        sw      t1,0(t0)
238:       3c09275a        lui     t1,0x275a
23c:       ad090004        sw      t1,4(t0)
#endif

#include <asm/asm.h>
#include <asm/regdef.h>

        .text
        .set noreorder
        .set mips32r2

        LEAF(test1)
        move    v0,a0
        addiu   v0,v0,1000
        bnez    a0,$L1
        jr      ra
        addiu   v0,v0,100
$L1:
        beqz    a0,$L2
        jr      ra
        addiu   v0,v0,10
$L2:
        addiu   v0,v0,1
        jr      ra
        nop
        END(test1)

        LEAF(test2)
        move    v0,a0
        addiu   v0,v0,1000
        beqz    a0,$L3
        jr      ra
        addiu   v0,v0,100
$L3:
        bnez    a0,$L4
        jr      ra
        addiu   v0,v0,10
$L4:
        addiu   v0,v0,1
        jr      ra
        nop
        END(test2)



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

* Re: [Qemu-devel] [Bug] MIPS code fails at branch instruction
  2007-03-16 23:12 [Qemu-devel] [Bug] MIPS code fails at branch instruction Stefan Weil
@ 2007-03-17  0:46 ` Thiemo Seufer
  2007-03-17 11:37   ` Stefan Weil
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-17  0:46 UTC (permalink / raw)
  To: Stefan Weil; +Cc: QEMU Developers

Stefan Weil wrote:
> Hi,
> 
> QEMU MIPS emulation fails with code using "illegal" commands
> in the delay slot of a branch.
> 
> I had an endless loop with QEMU running the firmware of a
> MIPS based router.
> 
> MIPS says: branches, jumps, ... instructions should not be
> placed in the delay slot of a branch or jump.
> 
> Nevertheless, some routers use this kind of code.

The architecture spec defines this as undefined behaviour. Other
implementations of MIPS CPUs show funny effects which are hard
to explain without detailed knowledge of the microarchitecture.

> I wrote a test program to examine the difference between emulation
> and a real MIPS CPU (see appendices).

I wouldn't be surprised if it starts to fail for some other combinations
like a mix of branch and branch likely instructions.

(The semantics of a branch delay slot are: The instruction in the delay
slot is executed, then the branch is executed. Now, when the instruction
in the delay slot is itself a branch, what will happen to its delay slot?)


Thiemo

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

* Re: [Qemu-devel] [Bug] MIPS code fails at branch instruction
  2007-03-17  0:46 ` Thiemo Seufer
@ 2007-03-17 11:37   ` Stefan Weil
  2007-03-17 14:31     ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Weil @ 2007-03-17 11:37 UTC (permalink / raw)
  To: Thiemo Seufer, QEMU Developers

So an emulation has several options:

1. Show undefined behaviour (this is what it does today).
2. Emulate the behaviour of existing CPUs as far as possible.
   As different CPUs behave different, this must depend on the
   current CPU.
3. Display an error message.

The current solution (1) is not good, because users get crashes
and don't know the reason, and experienced users spend a lot of
time with debugging (at least I did).

Solution (2) is needed to run existing binary code.

Solution (3) is the minimum I expect of an emulation like QEMU.

I prefer a mix of solutions (2) and (3): display a message and
try to emulate the original behaviour.

Do you agree, and would you accept patches which implement this?

Stefan

PS. Emulation of undefined instructions / undefined behaviour has
    a long tradition. In the old Z80 and 8086 days, it was
    something like a game to analyse and use them :-)


Thiemo Seufer schrieb:
> Stefan Weil wrote:
>> QEMU MIPS emulation fails with code using "illegal" commands
>> in the delay slot of a branch.
>>
>> I had an endless loop with QEMU running the firmware of a
>> MIPS based router.
>>
>> MIPS says: branches, jumps, ... instructions should not be
>> placed in the delay slot of a branch or jump.
>>
>> Nevertheless, some routers use this kind of code.
>
> The architecture spec defines this as undefined behaviour. Other
> implementations of MIPS CPUs show funny effects which are hard
> to explain without detailed knowledge of the microarchitecture.
>
>> I wrote a test program to examine the difference between emulation
>> and a real MIPS CPU (see appendices).
>
> I wouldn't be surprised if it starts to fail for some other combinations
> like a mix of branch and branch likely instructions.
>
> (The semantics of a branch delay slot are: The instruction in the delay
> slot is executed, then the branch is executed. Now, when the instruction
> in the delay slot is itself a branch, what will happen to its delay slot?)
>
>
> Thiemo
>

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

* Re: [Qemu-devel] [Bug] MIPS code fails at branch instruction
  2007-03-17 11:37   ` Stefan Weil
@ 2007-03-17 14:31     ` Thiemo Seufer
  2007-03-17 18:57       ` Stefan Weil
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-17 14:31 UTC (permalink / raw)
  To: Stefan Weil; +Cc: QEMU Developers

Stefan Weil wrote:
> So an emulation has several options:
> 
> 1. Show undefined behaviour (this is what it does today).
> 2. Emulate the behaviour of existing CPUs as far as possible.
>    As different CPUs behave different, this must depend on the
>    current CPU.
> 3. Display an error message.

(3) is bad, as it amounts to a DoS.

> The current solution (1) is not good, because users get crashes
> and don't know the reason, and experienced users spend a lot of
> time with debugging (at least I did).
> 
> Solution (2) is needed to run existing binary code.
> 
> Solution (3) is the minimum I expect of an emulation like QEMU.
> 
> I prefer a mix of solutions (2) and (3): display a message and
> try to emulate the original behaviour.
> 
> Do you agree, and would you accept patches which implement this?

If the AR7 CPU spec defines the semantics of branch delay slots more
precisely than the architecture spec then I'll consider a patch.

If this isn't the case then I ask you to use a non-broken compiler/
assembly code.


Thiemo

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

* Re: [Qemu-devel] [Bug] MIPS code fails at branch instruction
  2007-03-17 14:31     ` Thiemo Seufer
@ 2007-03-17 18:57       ` Stefan Weil
  2007-03-17 20:32         ` Paul Brook
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Weil @ 2007-03-17 18:57 UTC (permalink / raw)
  To: Thiemo Seufer, QEMU Developers

Thiemo Seufer wrote
> Stefan Weil wrote:
>> So an emulation has several options:
>>
>> 1. Show undefined behaviour (this is what it does today).
>> 2. Emulate the behaviour of existing CPUs as far as possible.
>> As different CPUs behave different, this must depend on the
>> current CPU.
>> 3. Display an error message.
> (3) is bad, as it amounts to a DoS.
DoS = Denial of Service? Then (1) is some kind of DoS, because QEMU hangs
with code which works on real hardware. I don't understand why an
error message (something printed to stdout or stderr like other boot
messages of QEMU) amounts to a DoS.
>> The current solution (1) is not good, because users get crashes
>> and don't know the reason, and experienced users spend a lot of
>> time with debugging (at least I did).
>>
>> Solution (2) is needed to run existing binary code.
>>
>> Solution (3) is the minimum I expect of an emulation like QEMU.
>>
>> I prefer a mix of solutions (2) and (3): display a message and
>> try to emulate the original behaviour.
>>
>> Do you agree, and would you accept patches which implement this?
> If the AR7 CPU spec defines the semantics of branch delay slots more
> precisely than the architecture spec then I'll consider a patch.
AR7 claims to use a 4KEc CPU, so there is only the official
spec from MIPS.
> If this isn't the case then I ask you to use a non-broken compiler/
> assembly code.
What about closed source binary code (firmware in my case)?
Of course it can be patched, but this is more work than implementing
(2) and (3) in QEMU.

Stefan

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

* Re: [Qemu-devel] [Bug] MIPS code fails at branch instruction
  2007-03-17 18:57       ` Stefan Weil
@ 2007-03-17 20:32         ` Paul Brook
  2007-03-19 21:04           ` [Qemu-devel] [Bug] [Patch] " Stefan Weil
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Brook @ 2007-03-17 20:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Weil

> >> So an emulation has several options:
> >>
> >> 1. Show undefined behaviour (this is what it does today).
> >> 2. Emulate the behaviour of existing CPUs as far as possible.
> >> As different CPUs behave different, this must depend on the
> >> current CPU.
> >> 3. Display an error message.
> >
> > (3) is bad, as it amounts to a DoS.
>
> DoS = Denial of Service? Then (1) is some kind of DoS, because QEMU hangs
> with code which works on real hardware. I don't understand why an
> error message (something printed to stdout or stderr like other boot
> messages of QEMU) amounts to a DoS.

It's not the same thing at all. In both cases buggy code crashes. I expect 
this could also happen on a fair proportion of real MIPS hardware. It may 
even happen on AR7 hardware is a interrupt or fault happens to trigger at the 
wrong time.

With (1) the buggy program crashes, and the rest of the machine keeps going.
With (3) an unprivileged user can effectively bring the whole machine down 
just by executing invalid code sequences.

Paul

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-17 20:32         ` Paul Brook
@ 2007-03-19 21:04           ` Stefan Weil
  2007-03-19 21:34             ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Weil @ 2007-03-19 21:04 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2635 bytes --]

Thank you, Paul, for your explanation which clarified Thiemo's statement.

I now checked how my published test code could contribute to a DoS attack.

Current QEMU HEAD:

* The code "hangs" as I wrote before. This is from a user's point of view.
  "Hanging" means, that the test process runs in an infinite loop using any
  CPU time it can get in the virtual machine. QEMU uses all available
  CPU time from the host CPU.
  With single stepping enabled or in the debugger, the test code won't
  hang but give a random result.

Patched QEMU HEAD (see appended patch file):

* The code works in a well defined way. An optional message in the log file
  will show the faulty statement. It won't amount to a DoS because it
  is disabled by default.
  Using single stepping, the test code's result remains the same.

So the patch improves the situation. Although it does not model the real
behaviour of an AR7 cpu, it solved my problem with a Zyxel firmware.
Maybe you can apply at least part of it or even improve and extend it to
other branch operations.

Thank you
Stefan


Details of the patch

* show optional message when any branch bits in hflags are already set
  before a branch instruction is generated (so we have a branch in the
  delay slot)

* mask branch bits before setting new ones (implemented only for the jr
  statement because this was the one I needed and examined)
  - this part could be improved

* make gen_intermediate_code_internal static (might improve compiler
  optimizations and is completely unrelated to the other two changes)



Paul Brook wrote:
>>>> So an emulation has several options:
>>>>
>>>> 1. Show undefined behaviour (this is what it does today).
>>>> 2. Emulate the behaviour of existing CPUs as far as possible.
>>>> As different CPUs behave different, this must depend on the
>>>> current CPU.
>>>> 3. Display an error message.
>>> (3) is bad, as it amounts to a DoS.
>> DoS = Denial of Service? Then (1) is some kind of DoS, because QEMU hangs
>> with code which works on real hardware. I don't understand why an
>> error message (something printed to stdout or stderr like other boot
>> messages of QEMU) amounts to a DoS.
>
> It's not the same thing at all. In both cases buggy code crashes. I
> expect
> this could also happen on a fair proportion of real MIPS hardware. It may
> even happen on AR7 hardware is a interrupt or fault happens to trigger
> at the
> wrong time.
>
> With (1) the buggy program crashes, and the rest of the machine keeps
> going.
> With (3) an unprivileged user can effectively bring the whole machine
> down
> just by executing invalid code sequences.
>
> Paul

[-- Attachment #2: translate.patch --]
[-- Type: text/x-diff, Size: 1280 bytes --]

Index: target-mips/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate.c,v
retrieving revision 1.37
diff -u -b -B -u -r1.37 translate.c
--- target-mips/translate.c	18 Mar 2007 00:30:29 -0000	1.37
+++ target-mips/translate.c	19 Mar 2007 20:26:31 -0000
@@ -1371,6 +1371,13 @@
     target_ulong btarget;
     int blink, bcond;
 
+    if (ctx->hflags & MIPS_HFLAG_BMASK) {
+        if (loglevel & CPU_LOG_TB_IN_ASM) {
+            fprintf(logfile,
+                    "undefined branch in delay slot at pc 0x%08x\n", ctx->pc);
+        }
+    }
+
     btarget = -1;
     blink = 0;
     bcond = 0;
@@ -1480,7 +1487,7 @@
             MIPS_DEBUG("jal %08x", btarget);
             break;
         case OPC_JR:
-            ctx->hflags |= MIPS_HFLAG_BR;
+            ctx->hflags = ((ctx->hflags & ~MIPS_HFLAG_BMASK) | MIPS_HFLAG_BR);
             MIPS_DEBUG("jr %s", regnames[rs]);
             break;
         case OPC_JALR:
@@ -4999,7 +5006,7 @@
     }
 }
 
-int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
+static int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
                                     int search_pc)
 {
     DisasContext ctx, *ctxp = &ctx;

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-19 21:04           ` [Qemu-devel] [Bug] [Patch] " Stefan Weil
@ 2007-03-19 21:34             ` Thiemo Seufer
  2007-03-19 22:34               ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-19 21:34 UTC (permalink / raw)
  To: qemu-devel

Stefan Weil wrote:
> Thank you, Paul, for your explanation which clarified Thiemo's statement.
> 
> I now checked how my published test code could contribute to a DoS attack.
> 
> Current QEMU HEAD:
> 
> * The code "hangs" as I wrote before. This is from a user's point of view.
>   "Hanging" means, that the test process runs in an infinite loop using any
>   CPU time it can get in the virtual machine. QEMU uses all available
>   CPU time from the host CPU.

This is a bug in qemu, since it doesn't match CPU behaviour. While the
architecture spec claims UNPREDICTABLE, such a code sequence shouldn't
impede other processes on the same CPU. Throwing an RI exception should
suffice for the general case (i.e. not AR7).

>   With single stepping enabled or in the debugger, the test code won't
>   hang but give a random result.
> 
> Patched QEMU HEAD (see appended patch file):
> 
> * The code works in a well defined way. An optional message in the log file
>   will show the faulty statement. It won't amount to a DoS because it
>   is disabled by default.

Sorry, but I missed the "well defined". What does the jump in the branch
delay slot exactly _do_ now? Where does the PC point to when it was a
conditional branch which wasn't taken?

[snip]
> * show optional message when any branch bits in hflags are already set
>   before a branch instruction is generated (so we have a branch in the
>   delay slot)

Agreed on that, since it is debug output which is only written when
asked for.


Thiemo

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-19 21:34             ` Thiemo Seufer
@ 2007-03-19 22:34               ` Thiemo Seufer
  2007-03-20  7:54                 ` Alexander Voropay
  2007-03-20 18:27                 ` Stefan Weil
  0 siblings, 2 replies; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-19 22:34 UTC (permalink / raw)
  To: Stefan Weil; +Cc: qemu-devel

Thiemo Seufer wrote:
[snip]
> > Patched QEMU HEAD (see appended patch file):
> > 
> > * The code works in a well defined way. An optional message in the log file
> >   will show the faulty statement. It won't amount to a DoS because it
> >   is disabled by default.
> 
> Sorry, but I missed the "well defined". What does the jump in the branch
> delay slot exactly _do_ now? Where does the PC point to when it was a
> conditional branch which wasn't taken?

I committed something which cover the rest of your patch, and throws
now a RI exception for branch-in-branch-delay-slot.

For the AR7 case, could you
 - add AR7 as a CPU type
 - handle the interesting cases for AR7 only, after verifying the
   cornercase behaviour of qemu and real hardware is consistent.

The cornercases which come to mind:
 - conditional vs. unconditional branches
 - the various condition types
 - taken vs. non-taken branches
 - linked vs. non-linked branches
 - likely vs. non-likely branches
 - the side effects of j / jal in the delayslot
 - the value of PC/ra (if it changes)

I don't ask for an exhaustive analysis, I just want to see the cases of
interest covered, so we can be reasonably sure the qemu results will be
useful for other AR7 users as well.


Thiemo

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-19 22:34               ` Thiemo Seufer
@ 2007-03-20  7:54                 ` Alexander Voropay
  2007-03-20  9:51                   ` Thiemo Seufer
  2007-03-20 18:27                 ` Stefan Weil
  1 sibling, 1 reply; 16+ messages in thread
From: Alexander Voropay @ 2007-03-20  7:54 UTC (permalink / raw)
  To: qemu-devel, Stefan Weil, Thiemo Seufer

"Thiemo Seufer" <ths@networkno.de> wrote:

> For the AR7 case, could you
> - add AR7 as a CPU type
> - handle the interesting cases for AR7 only, after verifying the
>   cornercase behaviour of qemu and real hardware is consistent.

 AFAIK, Texas Instrument AR7 isn't a CPU. It's a SoC which
combines well-known MIPS 4KEc synthesizable *core* and ADSL stuff.

http://www.linux-mips.org/wiki/AR7

--
-=AV=-

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-20  7:54                 ` Alexander Voropay
@ 2007-03-20  9:51                   ` Thiemo Seufer
  0 siblings, 0 replies; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-20  9:51 UTC (permalink / raw)
  To: Alexander Voropay; +Cc: qemu-devel

Alexander Voropay wrote:
> "Thiemo Seufer" <ths@networkno.de> wrote:
> 
> >For the AR7 case, could you
> >- add AR7 as a CPU type
> >- handle the interesting cases for AR7 only, after verifying the
> >  cornercase behaviour of qemu and real hardware is consistent.
> 
> AFAIK, Texas Instrument AR7 isn't a CPU. It's a SoC which
> combines well-known MIPS 4KEc synthesizable *core* and ADSL stuff.

Other 4KEc behave differently (probably due to differences in the
synthesizing technology used), so I figure AR7 becomes a special
CPU for qemu's purposes.


Thiemo

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-19 22:34               ` Thiemo Seufer
  2007-03-20  7:54                 ` Alexander Voropay
@ 2007-03-20 18:27                 ` Stefan Weil
  2007-03-25  0:22                   ` Thiemo Seufer
  1 sibling, 1 reply; 16+ messages in thread
From: Stefan Weil @ 2007-03-20 18:27 UTC (permalink / raw)
  To: Thiemo Seufer, QEMU Developers

Hi,

here is the patch which adds a "4KEcR1" CPU (a 4KEc, processor revision 2.2,
with MIPS32 Release 1 (!) instruction set is the heart of the AR7 SoC).

See also include/asm-mips/cpu.h in the Linux kernel sources:
./include/asm-mips/cpu.h:#define PRID_IMP_4KEC          0x8400
./include/asm-mips/cpu.h:#define PRID_IMP_4KECR2        0x9000

Stefan

PS. Did anybody run my branch test code on other MIPS CPUs?
    What was the result?

Sorry, because of trouble with the Savannah CVS server, the patch is not
against CVS.

--- ../branches/head/target-mips/translate_init.c       2007-03-18
01:30:29.000000000 +0100
+++ target-mips/translate_init.c        2007-03-20 18:47:59.000000000 +0100
@@ -44,6 +44,12 @@
         .CP0_Config1 = MIPS_CONFIG1,
     },
     {
+        .name = "4KEcR1",
+        .CP0_PRid = 0x00018448,
+        .CP0_Config0 = MIPS_CONFIG0,
+        .CP0_Config1 = MIPS_CONFIG1,
+    },
+    {
         .name = "24Kf",
         .CP0_PRid = 0x00019300,
         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),


Thiemo Seufer schrieb:
> Thiemo Seufer wrote:
> [snip]
> I committed something which cover the rest of your patch, and throws
> now a RI exception for branch-in-branch-delay-slot.
>
> For the AR7 case, could you
> - add AR7 as a CPU type
> - handle the interesting cases for AR7 only, after verifying the
> cornercase behaviour of qemu and real hardware is consistent.
>
> The cornercases which come to mind:
> - conditional vs. unconditional branches
> - the various condition types
> - taken vs. non-taken branches
> - linked vs. non-linked branches
> - likely vs. non-likely branches
> - the side effects of j / jal in the delayslot
> - the value of PC/ra (if it changes)
>
> I don't ask for an exhaustive analysis, I just want to see the cases of
> interest covered, so we can be reasonably sure the qemu results will be
> useful for other AR7 users as well.
>
>
> Thiemo

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-20 18:27                 ` Stefan Weil
@ 2007-03-25  0:22                   ` Thiemo Seufer
  2007-03-25  1:43                     ` Aurelien Jarno
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-25  0:22 UTC (permalink / raw)
  To: Stefan Weil; +Cc: QEMU Developers

Stefan Weil wrote:
> Hi,
> 
> here is the patch which adds a "4KEcR1" CPU (a 4KEc, processor revision 2.2,
> with MIPS32 Release 1 (!) instruction set is the heart of the AR7 SoC).
> 
> See also include/asm-mips/cpu.h in the Linux kernel sources:
> ./include/asm-mips/cpu.h:#define PRID_IMP_4KEC          0x8400
> ./include/asm-mips/cpu.h:#define PRID_IMP_4KECR2        0x9000

This was the bit which prompted to to ask The People Who Know[TM].
Indeed the early 4KEc were MIPS32R1 only. About the branch-in-delay-slot
I got the following information:

Very simple pipelines with branch delay slots tend to behave like this
(when both branches are taken):

 - Execute the first branch, that is, calculate the target of the
   branch. This has no effect until it ran far enough through the
   pipeline. Increment PC.
 - Execute the second branch. This changes the branch target value
   again. Increment PC.
 - Execute the second branch's delay slot instruction. Increment PC.
 - Now the PC is overridden by the first branch's target. A single
   instruction from that place is executed.
 - The PC is overridden again by the second branch's target. Normal
   execution resumes from there.

Apparently the SPARC architecture _requires_ this behaviour for all
CPUs.

Can you check if this is the behaviour you see on an AR7?


Thiemo

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-25  0:22                   ` Thiemo Seufer
@ 2007-03-25  1:43                     ` Aurelien Jarno
  2007-03-25 12:51                       ` Stuart Brady
  0 siblings, 1 reply; 16+ messages in thread
From: Aurelien Jarno @ 2007-03-25  1:43 UTC (permalink / raw)
  To: qemu-devel

Thiemo Seufer a écrit :
> Stefan Weil wrote:
>> Hi,
>>
>> here is the patch which adds a "4KEcR1" CPU (a 4KEc, processor revision 2.2,
>> with MIPS32 Release 1 (!) instruction set is the heart of the AR7 SoC).
>>
>> See also include/asm-mips/cpu.h in the Linux kernel sources:
>> ./include/asm-mips/cpu.h:#define PRID_IMP_4KEC          0x8400
>> ./include/asm-mips/cpu.h:#define PRID_IMP_4KECR2        0x9000
> 
> This was the bit which prompted to to ask The People Who Know[TM].
> Indeed the early 4KEc were MIPS32R1 only. About the branch-in-delay-slot
> I got the following information:
> 
> Very simple pipelines with branch delay slots tend to behave like this
> (when both branches are taken):
> 
>  - Execute the first branch, that is, calculate the target of the
>    branch. This has no effect until it ran far enough through the
>    pipeline. Increment PC.
>  - Execute the second branch. This changes the branch target value
>    again. Increment PC.
>  - Execute the second branch's delay slot instruction. Increment PC.
>  - Now the PC is overridden by the first branch's target. A single
>    instruction from that place is executed.
>  - The PC is overridden again by the second branch's target. Normal
>    execution resumes from there.
> 
> Apparently the SPARC architecture _requires_ this behaviour for all
> CPUs.

Yep I confirm that, it is clearly explained starting at the page 54 of
the SPARC v8 manual. To avoid this behaviour it is possible to cancel
the delay slot instruction by having a=1.

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-25  1:43                     ` Aurelien Jarno
@ 2007-03-25 12:51                       ` Stuart Brady
  2007-03-25 16:26                         ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Stuart Brady @ 2007-03-25 12:51 UTC (permalink / raw)
  To: qemu-devel

On Sun, Mar 25, 2007 at 03:43:16AM +0200, Aurelien Jarno wrote:
> Thiemo Seufer a écrit :
[...]
> >  - Execute the second branch's delay slot instruction. Increment PC.
[...]

I'm surprised that this step would be there -- I would have expected it
to be simpler to execute the target of the first branch in place of the
second branch's delay slot.

> Yep I confirm that, it is clearly explained starting at the page 54 of
> the SPARC v8 manual. To avoid this behaviour it is possible to cancel
> the delay slot instruction by having a=1.

SPARC doesn't have the "execute the second branch's delay slot" step.

>From the table on page 56, it seems to execute:

    branch1
    branch2
    target of branch1 (one instruction only)
    target of branch2 (continuing)

PA-RISC has the same requirement (PA-RISC 2.0 manual, pages 4-5 and 4-6,
and PA-RISC 1.1 manual, page 4-10).
-- 
Stuart Brady

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

* Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
  2007-03-25 12:51                       ` Stuart Brady
@ 2007-03-25 16:26                         ` Thiemo Seufer
  0 siblings, 0 replies; 16+ messages in thread
From: Thiemo Seufer @ 2007-03-25 16:26 UTC (permalink / raw)
  To: Stuart Brady; +Cc: qemu-devel

Stuart Brady wrote:
> On Sun, Mar 25, 2007 at 03:43:16AM +0200, Aurelien Jarno wrote:
> > Thiemo Seufer a écrit :
> [...]
> > >  - Execute the second branch's delay slot instruction. Increment PC.
> [...]
> 
> I'm surprised that this step would be there -- I would have expected it
> to be simpler to execute the target of the first branch in place of the
> second branch's delay slot.

Maybe you are right. It depends on how many cycles of delay the branch
incurs.


Thiemo

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

end of thread, other threads:[~2007-03-25 16:28 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-16 23:12 [Qemu-devel] [Bug] MIPS code fails at branch instruction Stefan Weil
2007-03-17  0:46 ` Thiemo Seufer
2007-03-17 11:37   ` Stefan Weil
2007-03-17 14:31     ` Thiemo Seufer
2007-03-17 18:57       ` Stefan Weil
2007-03-17 20:32         ` Paul Brook
2007-03-19 21:04           ` [Qemu-devel] [Bug] [Patch] " Stefan Weil
2007-03-19 21:34             ` Thiemo Seufer
2007-03-19 22:34               ` Thiemo Seufer
2007-03-20  7:54                 ` Alexander Voropay
2007-03-20  9:51                   ` Thiemo Seufer
2007-03-20 18:27                 ` Stefan Weil
2007-03-25  0:22                   ` Thiemo Seufer
2007-03-25  1:43                     ` Aurelien Jarno
2007-03-25 12:51                       ` Stuart Brady
2007-03-25 16:26                         ` Thiemo Seufer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.