[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: PowerNV decrementer fails to fire
From: |
Cédric Le Goater |
Subject: |
Re: PowerNV decrementer fails to fire |
Date: |
Thu, 24 Oct 2019 12:35:25 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.1 |
Hello Anton,
On 24/10/2019 00:04, Anton Blanchard wrote:
> Hi,
>
> Mikey and I noticed that the decrementer isn't firing when
> it should. If a decrementer is pending and an mtmsrd(MSR_EE) is
> executed then we should take the decrementer exception. From the PPC AS:
>
> If MSR EE = 0 and an External, Decrementer, or Per-
> formance Monitor exception is pending, executing
> an mtmsrd instruction that sets MSR EE to 1 will
> cause the interrupt to occur before the next instruc-
> tion is executed, if no higher priority exception
> exists
I suppose we are missing a test on MSR_EE in the store helper routine
of MSR to generate the exception ? See helper_store_msr() and
hreg_store_msr().
C.
>
> A test case is below. r31 is incremented for every decrementer
> exception.
>
> powerpc64le-linux-gcc -c test.S
> powerpc64le-linux-ld -Ttext=0x0 -o test.elf test.o
> powerpc64le-linux-objcopy -O binary test.elf test.bin
>
> r31 never moves. If I build with:
>
> powerpc64le-linux-gcc -DFIX_BROKEN -c test.S
>
> I see r31 move.
>
> Thanks,
> Anton
> --
>
> #include <ppc-asm.h>
>
> /* Load an immediate 64-bit value into a register */
> #define LOAD_IMM64(r, e) \
> lis r,(e)@highest; \
> ori r,r,(e)@higher; \
> rldicr r,r, 32, 31; \
> oris r,r, (e)@h; \
> ori r,r, (e)@l;
>
> #define FIXUP_ENDIAN \
> tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
> b 191f; /* Skip trampoline if endian is good */ \
> .long 0xa600607d; /* mfmsr r11 */ \
> .long 0x01006b69; /* xori r11,r11,1 */ \
> .long 0x05009f42; /* bcl 20,31,$+4 */ \
> .long 0xa602487d; /* mflr r10 */ \
> .long 0x14004a39; /* addi r10,r10,20 */ \
> .long 0xa64b5a7d; /* mthsrr0 r10 */ \
> .long 0xa64b7b7d; /* mthsrr1 r11 */ \
> .long 0x2402004c; /* hrfid */ \
> 191:
>
> .= 0x0
> .globl _start
> _start:
> b 1f
>
> .= 0x10
> FIXUP_ENDIAN
> b 1f
>
> .= 0x100
> 1:
> FIXUP_ENDIAN
> b __initialize
>
> #define EXCEPTION(nr) \
> .= nr ;\
> b .
>
> /* More exception stubs */
> EXCEPTION(0x300)
> EXCEPTION(0x380)
> EXCEPTION(0x400)
> EXCEPTION(0x480)
> EXCEPTION(0x500)
> EXCEPTION(0x600)
> EXCEPTION(0x700)
> EXCEPTION(0x800)
>
> .= 0x900
> LOAD_IMM64(r0, 0x1000000)
> mtdec r0
> addi r31,r31,1
> rfid
>
> EXCEPTION(0x980)
> EXCEPTION(0xa00)
> EXCEPTION(0xb00)
> EXCEPTION(0xc00)
> EXCEPTION(0xd00)
> EXCEPTION(0xe00)
> EXCEPTION(0xe20)
> EXCEPTION(0xe40)
> EXCEPTION(0xe60)
> EXCEPTION(0xe80)
> EXCEPTION(0xf00)
> EXCEPTION(0xf20)
> EXCEPTION(0xf40)
> EXCEPTION(0xf60)
> EXCEPTION(0xf80)
> EXCEPTION(0x1000)
> EXCEPTION(0x1100)
> EXCEPTION(0x1200)
> EXCEPTION(0x1300)
> EXCEPTION(0x1400)
> EXCEPTION(0x1500)
> EXCEPTION(0x1600)
>
> __initialize:
> /* SF, HV, EE, RI, LE */
> LOAD_IMM64(r0, 0x9000000000008003)
> mtmsrd r0
>
> LOAD_IMM64(r0, 0x1000000)
> mtdec r0
>
> 1: LOAD_IMM64(r30,0x8000)
> mtmsrd r30,1
>
> /* We should take the decrementer here */
> #ifdef FIX_BROKEN
> LOAD_IMM64(r29,0x100000000)
> mtctr r29
> 2: bdnz 2b
> #endif
>
> li r30,0x0
> mtmsrd r30,1
> b 1b
>