Hi Aneesh,

Le 22/12/2010 12:54, Aneesh V a écrit :
> - Enable I-cache on bootup
> - Enable MMU and D-cache immediately after relocation
>       - Do necessary initialization before enabling d-cache and MMU
> - Changes to cleanup_before_linux()
>       - Make changes according to the new framework
>
> Signed-off-by: Aneesh V<ane...@ti.com>
> ---
>   arch/arm/cpu/armv7/cpu.c   |   47 
> +++++++++++++++++++------------------------
>   arch/arm/cpu/armv7/start.S |   18 +++++++++++++++-
>   arch/arm/lib/board.c       |    6 +++++
>   arch/arm/lib/cache-cp15.c  |    9 ++++++++
>   4 files changed, 53 insertions(+), 27 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
> index a01e0d6..b418304 100644
> --- a/arch/arm/cpu/armv7/cpu.c
> +++ b/arch/arm/cpu/armv7/cpu.c
> @@ -38,13 +38,10 @@
>   #ifndef CONFIG_L2_OFF
>   #include<asm/arch/sys_proto.h>
>   #endif
> -
> -static void cache_flush(void);
> +#include<asm/armv7.h>
>
>   int cleanup_before_linux(void)
>   {
> -     unsigned int i;
> -
>       /*
>        * this function is called just before we call linux
>        * it prepares the processor for linux
> @@ -53,31 +50,29 @@ int cleanup_before_linux(void)
>        */
>       disable_interrupts();
>
> -     /* turn off I/D-cache */
> +     /*
> +      * Turn off I-cache and invalidate it
> +      */
>       icache_disable();
> -     dcache_disable();

(1) -- see below

> +     invalidate_icache_all();
>
> -     /* invalidate I-cache */
> -     cache_flush();

(2) -- see below

> -
> -#ifndef CONFIG_L2_OFF
> -     /* turn off L2 cache */
> -     l2_cache_disable();
> -     /* invalidate L2 cache also */
> -     invalidate_dcache(get_device_type());
> -#endif
> -     i = 0;
> -     /* mem barrier to sync up things */
> -     asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
> +     /*
> +      * turn off D-cache
> +      * dcache_disable() in turn flushes the d-cache and disables MMU
> +      */
> +     dcache_disable();

(3) -- see below

> -#ifndef CONFIG_L2_OFF
> -     l2_cache_enable();
> -#endif
> +     /*
> +      * After D-cache is flushed and before it is disabled there may
> +      * be some new valid entries brought into the cache. We are sure
> +      * that these lines are not dirty and will not affect our execution.
> +      * (because unwinding the call-stack and setting a bit in CP15 SCTRL
> +      * is all we did during this. We have not pushed anything on to the
> +      * stack. Neither have we affected any static data)
> +      * So just invalidate the entire d-cache again to avoid coherency
> +      * problems for kernel
> +      */
> +     invalidate_dcache_all();

I'm not sure about the logic here, but I am no cache guru, so don't 
hesitate to make me... flush... with shame. If dcache_disable stayed in 
(1) instead of being moved to (3), wouldn't the cache_flush in (2) 
ensure the no new valid entries would appear in the dcache?
  Put another way, I'd have naively thought the sequence would be:

- disable L2 cache
- disable L1 I and D cache
- invalidate L1 I cache and flush L1 D cache
- flush L2 D cache

>       return 0;
>   }
> -
> -static void cache_flush(void)
> -{
> -     asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
> -}
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 684f2d2..7d17f1e 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -241,6 +241,14 @@ clbss_l:str      r2, [r0]                /* clear 
> loop...                    */
>    * initialization, now running from RAM.
>    */
>   jump_2_ram:
> +/*
> + * If I-cache is enabled invalidate it
> + */
> +#ifndef CONFIG_SYS_NO_ICACHE
> +     mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
> +     dsb
> +     isb
> +#endif
>       ldr     r0, _board_init_r_ofs
>       adr     r1, _start
>       add     lr, r0, r1
> @@ -276,6 +284,9 @@ cpu_init_crit:
>       mov     r0, #0                  @ set up for MCR
>       mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
>       mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
> +     mcr     p15, 0, r0, c7, c5, 6  /* invalidate BP array */
> +     dsb
> +     isb
>
>       /*
>        * disable MMU stuff and caches
> @@ -284,7 +295,12 @@ cpu_init_crit:
>       bic     r0, r0, #0x00002000     @ clear bits 13 (--V-)
>       bic     r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)
>       orr     r0, r0, #0x00000002     @ set bit 1 (--A-) Align
> -     orr     r0, r0, #0x00000800     @ set bit 12 (Z---) BTB
> +     orr     r0, r0, #0x00000800     @ set bit 11 (Z---) BTB
> +#ifdef CONFIG_SYS_NO_ICACHE
> +     bic     r0, r0, #0x00001000     @ clear bit 12 (I) I-cache
> +#else
> +     orr     r0, r0, #0x00001000     @ set bit 12 (I) I-cache
> +#endif
>       mcr     p15, 0, r0, c1, c0, 0
>
>       /*
> diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
> index 7266381..bef32a6 100644
> --- a/arch/arm/lib/board.c
> +++ b/arch/arm/lib/board.c
> @@ -459,6 +459,12 @@ void board_init_r (gd_t *id, ulong dest_addr)
>
>       gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
>
> +     /*
> +      * Enable D$:
> +      * I$, if needed, must be already enabled in start.S
> +      */
> +     dcache_enable();
> +
>       monitor_flash_len = _bss_start_ofs;
>       debug ("monitor flash len: %08lX\n", monitor_flash_len);
>       board_init();   /* Setup chipselects */
> diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
> index d9175f0..ca526fb 100644
> --- a/arch/arm/lib/cache-cp15.c
> +++ b/arch/arm/lib/cache-cp15.c
> @@ -34,6 +34,14 @@
>
>   DECLARE_GLOBAL_DATA_PTR;
>
> +void __arm_init_before_mmu(void)
> +{
> +     puts("__arm_init_before_mmu: dummy implementation! "
> +          "real implementation missing!!\n");
> +}

If the function is absolutely needed, please make sure booting does not 
continue. If the function is not absolutely needed, please rewrite 
message since nothing would actually be 'missing', but rather 'could be 
added'.

> +void arm_init_before_mmu(void)
> +     __attribute__((weak, alias("__arm_init_before_mmu")));
> +
>   static void cp_delay (void)
>   {
>       volatile int i;
> @@ -65,6 +73,7 @@ static inline void mmu_setup(void)
>       int i;
>       u32 reg;
>
> +     arm_init_before_mmu();
>       /* Set up an identity-mapping for all 4GB, rw for everyone */
>       for (i = 0; i<  4096; i++)
>               page_table[i] = i<<  20 | (3<<  10) | 0x12;

Amicalement,
-- 
Albert.
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to