[U-Boot] [PATCH] 85xx: Export invalidate_{i, d}cache and add flush_dcache

Added the ability for C code to invalidate the i/d-cache's and to flush the d-cache. This allows us to more efficient change mappings from cache-able to cache-inhibited.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- cpu/mpc85xx/start.S | 49 +++++++++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/cache.h | 1 + 2 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 10fe936..bedfac4 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -565,6 +565,7 @@ mck_return:
/* Cache functions. */ +.globl invalidate_icache invalidate_icache: mfspr r0,L1CSR1 ori r0,r0,L1CSR1_ICFI @@ -574,6 +575,7 @@ invalidate_icache: isync blr /* entire I cache */
+.globl invalidate_dcache invalidate_dcache: mfspr r0,L1CSR0 ori r0,r0,L1CSR0_DCFI @@ -1019,3 +1021,50 @@ unlock_ram_in_cache: tlbivax 0,r3 isync blr + +.globl flush_dcache +flush_dcache: + mfspr r3,SPRN_L1CFG0 + + rlwinm r5,r3,9,3 /* Extract cache block size */ + twlgti r5,1 /* Only 32 and 64 byte cache blocks + * are currently defined. + */ + li r4,32 + subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - + * log2(number of ways) + */ + slw r5,r4,r5 /* r5 = cache block size */ + + rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ + mulli r7,r7,13 /* An 8-way cache will require 13 + * loads per set. + */ + slw r7,r7,r6 + + /* save off HID0 and set DCFA */ + mfspr r8,SPRN_HID0 + ori r9,r8,HID0_DCFA@l + mtspr SPRN_HID0,r9 + isync + + lis r4,0 + mtctr r7 + +1: lwz r3,0(r4) /* Load... */ + add r4,r4,r5 + bdnz 1b + + msync + lis r4,0 + mtctr r7 + +1: dcbf 0,r4 /* ...and flush. */ + add r4,r4,r5 + bdnz 1b + + /* restore HID0 */ + mtspr SPRN_HID0,r8 + isync + + blr diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index 9d9b971..ce7400c 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -44,6 +44,7 @@ extern void clean_dcache_range(unsigned long start, unsigned long stop); extern void invalidate_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache(void); extern void invalidate_dcache(void); +extern void invalidate_icache(void); #ifdef CFG_INIT_RAM_LOCK extern void unlock_ram_in_cache(void); #endif /* CFG_INIT_RAM_LOCK */

Changing the flash from cacheable to cache-inhibited was taking a significant amount of time due to the fact that we were iterating over the full 256M of flash. Instead we can just flush the L1 d-cache and invalidate the i-cache.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- board/freescale/mpc8536ds/mpc8536ds.c | 10 ++++------ board/freescale/mpc8536ds/tlb.c | 2 +- board/freescale/mpc8572ds/mpc8572ds.c | 10 ++++------ board/freescale/mpc8572ds/tlb.c | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c index 8216c70..6794eb8 100644 --- a/board/freescale/mpc8536ds/mpc8536ds.c +++ b/board/freescale/mpc8536ds/mpc8536ds.c @@ -25,6 +25,7 @@ #include <pci.h> #include <asm/processor.h> #include <asm/mmu.h> +#include <asm/cache.h> #include <asm/immap_85xx.h> #include <asm/immap_fsl_pci.h> #include <asm/fsl_ddr_sdram.h> @@ -441,7 +442,6 @@ pci_init_board(void)
int board_early_init_r(void) { - unsigned int i; const unsigned int flashbase = CFG_FLASH_BASE; const u8 flash_esel = 1;
@@ -450,11 +450,9 @@ int board_early_init_r(void) * so that flash can be erased properly. */
- /* Invalidate any remaining lines of the flash from caches. */ - for (i = 0; i < 256*1024*1024; i+=32) { - asm volatile ("dcbi %0,%1": : "b" (flashbase), "r" (i)); - asm volatile ("icbi %0,%1": : "b" (flashbase), "r" (i)); - } + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache();
/* invalidate existing TLB entry for flash + promjet */ disable_tlb(flash_esel); diff --git a/board/freescale/mpc8536ds/tlb.c b/board/freescale/mpc8536ds/tlb.c index 28a9fa8..614f22e 100644 --- a/board/freescale/mpc8536ds/tlb.c +++ b/board/freescale/mpc8536ds/tlb.c @@ -54,7 +54,7 @@ struct fsl_e_tlb_entry tlb_table[] = { /* W**G* - Flash/promjet, localbus */ /* This will be changed to *I*G* after relocation to RAM. */ SET_TLB_ENTRY(1, CFG_FLASH_BASE, CFG_FLASH_BASE, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, 0, 1, BOOKE_PAGESZ_256M, 1),
/* *I*G* - PCI */ diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index 70b548b..c3a1c4c 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -25,6 +25,7 @@ #include <pci.h> #include <asm/processor.h> #include <asm/mmu.h> +#include <asm/cache.h> #include <asm/immap_85xx.h> #include <asm/immap_fsl_pci.h> #include <asm/fsl_ddr_sdram.h> @@ -359,7 +360,6 @@ void pci_init_board(void)
int board_early_init_r(void) { - unsigned int i; const unsigned int flashbase = CFG_FLASH_BASE; const u8 flash_esel = 2;
@@ -368,11 +368,9 @@ int board_early_init_r(void) * so that flash can be erased properly. */
- /* Invalidate any remaining lines of the flash from caches. */ - for (i = 0; i < 256*1024*1024; i+=32) { - asm volatile ("dcbi %0,%1": : "b" (flashbase), "r" (i)); - asm volatile ("icbi %0,%1": : "b" (flashbase), "r" (i)); - } + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache();
/* invalidate existing TLB entry for flash + promjet */ disable_tlb(flash_esel); diff --git a/board/freescale/mpc8572ds/tlb.c b/board/freescale/mpc8572ds/tlb.c index 965356a..0477a4b 100644 --- a/board/freescale/mpc8572ds/tlb.c +++ b/board/freescale/mpc8572ds/tlb.c @@ -59,7 +59,7 @@ struct fsl_e_tlb_entry tlb_table[] = { /* W**G* - Flash/promjet, localbus */ /* This will be changed to *I*G* after relocation to RAM. */ SET_TLB_ENTRY(1, CFG_FLASH_BASE, CFG_FLASH_BASE, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, 0, 2, BOOKE_PAGESZ_256M, 1),
/* *I*G* - PCI */
participants (1)
-
Kumar Gala