armv7: integrate cache maintenance support

- 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 <aneesh@ti.com>
master
Aneesh V 14 years ago committed by Albert ARIBAUD
parent e47f2db537
commit c2dd0d4554
  1. 47
      arch/arm/cpu/armv7/cpu.c
  2. 18
      arch/arm/cpu/armv7/start.S
  3. 6
      arch/arm/lib/board.c
  4. 7
      arch/arm/lib/cache-cp15.c
  5. 5
      arch/arm/lib/cache.c

@ -35,13 +35,10 @@
#include <command.h> #include <command.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/cache.h> #include <asm/cache.h>
#include <asm/armv7.h>
static void cache_flush(void);
int cleanup_before_linux(void) int cleanup_before_linux(void)
{ {
unsigned int i;
/* /*
* this function is called just before we call linux * this function is called just before we call linux
* it prepares the processor for linux * it prepares the processor for linux
@ -50,31 +47,29 @@ int cleanup_before_linux(void)
*/ */
disable_interrupts(); disable_interrupts();
/* turn off I/D-cache */ /*
* Turn off I-cache and invalidate it
*/
icache_disable(); icache_disable();
dcache_disable(); invalidate_icache_all();
/* invalidate I-cache */
cache_flush();
#ifndef CONFIG_L2_OFF /*
/* turn off L2 cache */ * turn off D-cache
l2_cache_disable(); * dcache_disable() in turn flushes the d-cache and disables MMU
/* invalidate L2 cache also */ */
invalidate_dcache(get_device_type()); dcache_disable();
#endif
i = 0;
/* mem barrier to sync up things */
asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
#ifndef CONFIG_L2_OFF /*
l2_cache_enable(); * After D-cache is flushed and before it is disabled there may
#endif * 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();
return 0; return 0;
} }
static void cache_flush(void)
{
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
}

@ -255,6 +255,14 @@ clbss_l:str r2, [r0] /* clear loop... */
* initialization, now running from RAM. * initialization, now running from RAM.
*/ */
jump_2_ram: jump_2_ram:
/*
* If I-cache is enabled invalidate it
*/
#ifndef CONFIG_SYS_ICACHE_OFF
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
#endif
ldr r0, _board_init_r_ofs ldr r0, _board_init_r_ofs
adr r1, _start adr r1, _start
add lr, r0, r1 add lr, r0, r1
@ -290,6 +298,9 @@ cpu_init_crit:
mov r0, #0 @ set up for MCR mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
/* /*
* disable MMU stuff and caches * disable MMU stuff and caches
@ -298,7 +309,12 @@ cpu_init_crit:
bic r0, r0, #0x00002000 @ clear bits 13 (--V-) bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align 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_ICACHE_OFF
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 mcr p15, 0, r0, c1, c0, 0
/* /*

@ -450,6 +450,12 @@ void board_init_r (gd_t *id, ulong dest_addr)
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
monitor_flash_len = _end_ofs; monitor_flash_len = _end_ofs;
/*
* Enable D$:
* I$, if needed, must be already enabled in start.S
*/
dcache_enable();
debug ("monitor flash len: %08lX\n", monitor_flash_len); debug ("monitor flash len: %08lX\n", monitor_flash_len);
board_init(); /* Setup chipselects */ board_init(); /* Setup chipselects */

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

@ -38,11 +38,6 @@ void __flush_cache(unsigned long start, unsigned long size)
/* disable write buffer as well (page 2-22) */ /* disable write buffer as well (page 2-22) */
asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
#endif #endif
#ifdef CONFIG_OMAP34XX
void v7_flush_cache_all(void);
v7_flush_cache_all();
#endif
return; return;
} }
void flush_cache(unsigned long start, unsigned long size) void flush_cache(unsigned long start, unsigned long size)

Loading…
Cancel
Save