[U-Boot] [Patch v6 3/5] ARMv8/FSL_LSCH3: Add FSL_LSCH3 SoC

York Sun yorksun at freescale.com
Wed Jun 18 18:21:49 CEST 2014


On 06/18/2014 02:43 AM, Mark Rutland wrote:
> Hi York,
> 
> Apologies for the late reply on this.
> 
> I'm somewhat concerned regarding the issues you're seeing with cacheable
> page table walks, but I'll ignore that for the moment so we can get the
> ordering of maintenance sorted.
> 
> On Thu, Jun 05, 2014 at 08:23:09PM +0100, York Sun wrote:
>> Freescale LayerScape with Chassis Generation 3 is a set of SoCs with
>> ARMv8 cores and 3rd generation of Chassis. We use different MMU setup
>> to support memory map and cache attribute for these SoCs. MMU and cache
>> are enabled very early to bootst performance, especially for early
>> development on emulators. After u-boot relocates to DDR, a new MMU
>> table with QBMan cache access is created in DDR. SMMU pagesize is set
>> in SMMU_sACR register. Both DDR3 and DDR4 are supported.
>>
>> Signed-off-by: York Sun <yorksun at freescale.com>
>> Signed-off-by: Varun Sethi <Varun.Sethi at freescale.com>
>> Signed-off-by: Arnab Basu <arnab.basu at freescale.com>
>> ---
> 
> [...]
> 
>> +       /* point TTBR to the new table */
>> +       el = current_el();
> 
> Could we not place a dsb() here...
> 
>> +       if (el == 1) {
>> +               asm volatile("dsb sy;msr ttbr0_el1, %0;isb"
>> +                            : : "r" ((u64)level0_table) : "memory");
>> +       } else if (el == 2) {
>> +               asm volatile("dsb sy;msr ttbr0_el2, %0;isb"
>> +                            : : "r" ((u64)level0_table) : "memory");
>> +       } else if (el == 3) {
>> +               asm volatile("dsb sy;msr ttbr0_el3, %0;isb"
>> +                            : : "r" ((u64)level0_table) : "memory");
>> +       } else {
>> +               hang();
>> +       }
> 
> ...and an isb() here?
> 
> It would save duplicating them for each EL.

Sure. I can move them out.

> 
>> +       /*
>> +        * MMU is already enabled, just need to invalidate TLB to load the
>> +        * new table. The new table is compatible with the current table, if
>> +        * MMU somehow walks through the new table before invalidation TLB,
>> +        * it still works. So we don't need to turn off MMU here.
>> +        */
>> +}
>> +
>> +int arch_cpu_init(void)
>> +{
>> +       icache_enable();
> 
> Just to check: the icache is clean/invalid at this point?

It is not, but it is done first thing inside icache_enable().

> 
>> +       __asm_invalidate_dcache_all();
>> +       __asm_invalidate_tlb_all();
>> +       early_mmu_setup();
>> +       set_sctlr(get_sctlr() | CR_C);
>> +       return 0;
>> +}
> 
> [...]
> 
>> +/*
>> + * This function is called from lib/board.c.
>> + * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
>> + * There is no need to disable d-cache for this operation.
>> + */
>> +void enable_caches(void)
>> +{
>> +       final_mmu_setup();
>> +       flush_dcache_range(gd->arch.tlb_addr,
>> +                          gd->arch.tlb_addr +  gd->arch.tlb_size);
>> +       __asm_invalidate_tlb_all();
>> +}
> 
> This looks wrong, given your previous comments that you couldn't get the
> MMU to lookup from the cache.
> 
> In final_mmu_setup() you pointed the TTBR0_ELx to the new tables, but at
> that point the tables aren't guaranteed to be in memory, because they
> haven't been flushed. The MMU can start fetching the garbage from memory
> immediately, and things might go wrong before __asm_invalidate_tlb_all()
> blows away the garbage the MMU read from memory (for instance, the
> mapping covering the enable_caches function might get replaced by
> garbage).
> 
> If the page table walks are non-cacheable, you need to flush the tables
> to memory before programming the relevant TTBR.
> 

Agreed here. I will move the flushing before setting TTBR.

Thanks for review. v7 patch is coming after I verify all the changes.

York




More information about the U-Boot mailing list