[U-Boot] [issue report] mainline u-boot was stuck before booting kernel

Ziyuan Xu xzy.xu at rock-chips.com
Tue Jul 26 15:47:38 CEST 2016


Hi Sandy,

I'm pleased to learn that it does fix for you.

On 2016年07月26日 21:16, Sandy Patterson wrote:
> Hi Ziyuan, good work!
>
> This does in fact fix it for me.
>
> I followed through your notes. What is isr() supposed to do? it looks 
> like it just tells the compiler that the memory cache has been 
> invalidated. But in the
isb()?
I'm not very enrich knowledgeable in cache, this issue I'm doing also is 
a big learning experience for me. I catch something from TRM, and review 
u-boot again and again in order to figure out the root cause. I suspect 
the former disable_dcache/mmu operation didn't complete, or branch 
prediction was abnormal?
I'm not really sure.

> TRM it says we need to actually do an ISB.
>
> Would fixing the dcache flush so it does an ISB when it disables the 
> MMU maybe be an alternative solution? (I couldn't figure out which 
> macro I should be using. isb() is defined for arm64 to do the actual op.
>
> Anyway, the following also fixes for me.
>
> diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
> index 1121dc3..3494a5c 100644
> --- a/arch/arm/lib/cache-cp15.c
> +++ b/arch/arm/lib/cache-cp15.c
> @@ -217,6 +217,8 @@ static void cache_disable(uint32_t cache_bit)
>         if (cache_bit == (CR_C | CR_M))
>                 flush_dcache_all();
>         set_cr(reg & ~cache_bit);
> +       if(cache_bit & CR_M)
> +               asm volatile ("isb" : : : "memory");
>  }
>  #endif
>
>
> I'm not sure what kinds of side effects for other boards these changes 
> would have.
Let's listen to the opinions of others.
>
> On Tue, Jul 26, 2016 at 8:15 AM, Ziyuan Xu <xzy.xu at rock-chips.com 
> <mailto:xzy.xu at rock-chips.com>> wrote:
>
>     + Simon and heiko
>
>     On 2016年07月26日 14:30, Ziyuan Xu wrote:
>
>         Dear All,
>
>         I add the ISB operation after dcache_disable(), and I can jump
>         to linux kernel entry.:-)
>
>         diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
>         index 6eac5ef..5cc09ba 100644
>         --- a/arch/arm/cpu/armv7/cpu.c
>         +++ b/arch/arm/cpu/armv7/cpu.c
>         @@ -43,6 +43,7 @@ int cleanup_before_linux_select(int flags)
>                         */
>                         dcache_disable();
>                         v7_outer_cache_disable();
>         +               ISB;
>
>                         /*
>                         * After D-cache is flushed and before it is
>         disabled there may
>
>         Sounds crazy. In fact, there is already an 'ISB' operation in
>         set_cr() which to disable dcache and MMU. But it just tell
>         processor that  memory had change, not real ISB for armv7.
>
>         dcache_disable
>                 ==>flush_dcache_all()
>                 ==>set_cr()   disable dcache and MMU.
>
>         #define isb() __asm__ __volatile__ ("" : : : "memory")
>         static inline void set_cr(unsigned int val)
>         {
>             if (is_hyp())
>                 asm volatile("mcr p15, 4, %0, c1, c0, 0    @ set CR" :
>                                           : "r" (val)
>                                           : "cc");
>             else
>                 asm volatile("mcr p15, 0, %0, c1, c0, 0    @ set CR" :
>                                           : "r" (val)
>                                           : "cc");
>             isb();
>         }
>
>         I also find something in ARM cortex-A17 TRM. ==>"Disable the
>         MMU from the each processor followed by an ISB to ensure the
>         MMU disable operation is complete, then followed by a DSB to
>         drain previous memory transactions."
>
>         In my humble opinion, maybe instructions tlb had alter, and
>         cause running away??? I'm not sure about it.
>         @Sandy, could you have a try with my update?
>
>         @Simon,  did you hit this glitch? I hope you can help ...:-)
>
>         On 2016年07月25日 23:00, Sandy Patterson wrote:
>
>             Ah, thanks. Your debugging looks the same as what I've
>             seen from printf debugging. I'll try to verify though.
>
>             On Mon, Jul 25, 2016 at 10:58 AM, Ziyuan Xu
>             <xzy.xu at rock-chips.com <mailto:xzy.xu at rock-chips.com>
>             <mailto:xzy.xu at rock-chips.com
>             <mailto:xzy.xu at rock-chips.com>>> wrote:
>
>                 hi Stany,
>
>                 The difference is that you print out assertion log.
>
>                 Reset not supported on this platform
>                 ### ERROR ### Please RESET the board ###
>
>                 You can add show_boot_progress() function in your bsp
>             file to find
>                 out something.
>                 #define CONFIG_SHOW_BOOT_PROGRESS
>                 void show_boot_progress(int progress)
>                 {
>                     printf("Boot reached stage %d\n", progress);
>
>                 }
>
>
>                 On 2016年07月25日 22:12, Ziyuan Xu wrote:
>
>                     Hi All,
>
>                     I'm sorry to tell you that I failed to boot linux
>             kernel with
>                     the mainline u-boot on rk3288 board(both evb-rk3288 &
>                     fennec-rk3288). It was stuck in
>             cleanup_before_linux() before
>                     jumping to linux, and the boot_stage_flag is
>                     BOOTSTAGE_ID_BOOTM_HANDOFF.
>
>                     ## Current stack ends at 0x7df638b0 * kernel:
>             cmdline image
>                     address = 0x02000000
>                     ## No init Ramdisk
>                        ramdisk start = 0x00000000, ramdisk end =
>             0x00000000
>                     ## No Flattened Device Tree
>                     Continuing to boot without FDT
>                     Initial value for argc=3
>                     Final value for argc=3
>                     using: ATAGS
>                     ## Transferring control to Linux (at address
>             02000000)...
>
>                     Starting kernel ...
>
>                     With the further investigation, it never returnned
>             back from
>                     invalidate_dcache_all(). I mean that I can't reach
>             stage 4 as
>                     below.
>
>                     cleanup_before_linux
>                         ==>cleanup_before_linux_select
>                             ==>1.disable_interrupts
>                             ==>2.dcache_disable
>                             ==>3.invalidate_dcache_all
>                             ==>4.icache_disable
>
>                     Debug further, invalidate_dcache_all invalidate
>             all cache
>                     one-by-one which cache type is DATA_ONLY,
>             INSTRUCTION_DATA or
>                     UNIFIED. And invalidate way from one set to
>             another set in
>                     order. The problem is that the PC ran away in
>             invalidate way
>                     loop  [cache level L1!!!].
>
>                     I add some serial output code in
>             __v7_flush_dcache_all to
>                     figure out the bog.
>                     I expect:
>                     Print the value of r9 in sequence, e.g 0x7f, 0x7e,
>             0x7d.....
>                     0x01, 0x00 (hex)
>                     In fact, print the value of r9 in sequence at
>             first, but print
>                     unexpected value afterwards.   e.g 0x7f, 0x7e,
>             0x7d, ..,0x73,
>                     0x40, 0x85,....
>
>                     ENTRY(__v7_flush_dcache_all)
>                     [snip]
>                     loop1:
>                         mov    r9, r7                @ create working
>             copy of max
>                     index
>                     loop2:
>                     +      stmfd    sp!, {r0}
>                     +      ldr     r0, =0xff690000
>                     +      str     r9, [r0]
>                     +      ldmfd    sp!, {r0}
>                      ARM(    orr    r11, r10, r4, lsl r5    ) @ factor
>             way and
>                     cache number into r11
>                      THUMB(    lsl    r6, r4, r5        )
>                      THUMB(    orr    r11, r10, r6        )    @
>             factor way and
>                     cache number into r11
>                      ARM(    orr    r11, r11, r9, lsl r2    ) @ factor
>             index
>                     number into r11
>                      THUMB(    lsl    r6, r9, r2        )
>                      THUMB(    orr    r11, r11, r6        )    @
>             factor index
>                     number into r11
>                         mcr    p15, 0, r11, c7, c14, 2        @ clean
>             & invalidate
>                     by set/way
>                         subs    r9, r9, #1            @ decrement the
>             index
>                         bge    loop2
>                         subs    r4, r4, #1            @ decrement the way
>                         bge    loop1
>                     skip:
>                     ENDPROC(__v7_flush_dcache_all)
>
>                     I don't have the jtag, hence I can't address the
>             current pc. I
>                     have no doubt that if any glitches in
>             __v7_flush_dcache_all, I
>                     reviewed several times, also copy kernel's
>             implement to here.
>                     :-( No effect.
>                     A more interesting thing is that Sandy had report
>             it. He and I
>                     have similar problem. Everything work fine after I
>             applied his
>                     patches, or disable dcache(active
>             CONFIG_SYS_DCACHE_OFF).
>                     @Stany, I'm sorry that I disable dcache during
>             hack.. That was
>                     a mistake:-(
>
>                     @Simon & hieko,
>                     Can you boot linux with the mainline u-boot? have
>             a try?
>
>
>             _______________________________________________
>                     U-Boot mailing list
>             U-Boot at lists.denx.de <mailto:U-Boot at lists.denx.de>
>             <mailto:U-Boot at lists.denx.de <mailto:U-Boot at lists.denx.de>>
>             http://lists.denx.de/mailman/listinfo/u-boot
>
>
>
>
>
>
>
>
>
>         _______________________________________________
>         U-Boot mailing list
>         U-Boot at lists.denx.de <mailto:U-Boot at lists.denx.de>
>         http://lists.denx.de/mailman/listinfo/u-boot
>
>
>
>




More information about the U-Boot mailing list