cache_flush_and_enablecache_clean_flush_and_disablecache_flush_rangecache_clean_flush_rangecache_clean_range
icache_flush_and_enableicache_disable_and_flushdcache_flush_and_enabledcache_clean_flush_and_disabledcache_flush_rangedcache_clean_rangedcache_clean_flush_rangeicache_flush_range
Index: include/cache.h===================================================================--- include/cache.h (revision 5635)+++ include/cache.h (working copy)@@ -7,7 +7,7 @@ /* arm cache control */-void icache_flush_all(void);+void icache_flush_range(void *addr, unsigned int size); void dcache_clean_all(void); #endifIndex: lib/armutil/cache.c===================================================================--- lib/armutil/cache.c (revision 5635)+++ lib/armutil/cache.c (working copy)@@ -23,6 +23,11 @@ ); } +/* flushing range only required on ARMv5, flushing all icache instead */+void icache_flush_range(void *addr, unsigned int size) {+ icache_flush_all();+}+ /* Values for Ctype fields in CLIDR */ #define ARMV7_CLIDR_CTYPE_NO_CACHE 0 #define ARMV7_CLIDR_CTYPE_INSTRUCTION_ONLY 1@@ -222,6 +227,15 @@ return 0x200 << sz; } +unsigned int is_dcache_locked() {+ unsigned int statusd = 0;+ asm volatile (+ /* get lockdown status */\+ "MRC p15, 0, %0, c9, c0, 0\n"+ : "=r"(statusd) : );+ return statusd & 0xff;+}+ /* flush (mark as invalid) entire instruction cache */@@ -234,6 +248,22 @@ } /*+flush address range from instruction cache - cache hack friendly+*/+void __attribute__((naked,noinline)) icache_flush_range(void *addr, unsigned int size) {+ asm volatile (+ "add r1, r1, r0\n"+ "bic r0, r0, #0x1F\n"+"ifr1:\n"+ "mcr p15, 0, r0, c7, c5, 1\n"+ "add r0, r0, #0x20\n"+ "cmp r0, r1\n"+ "bcc ifr1\n"+ "bx lr\n"+ );+}++/* clean (write all dirty) entire data cache also drains write buffer (like canon code) does *not* flush@@ -240,7 +270,11 @@ */ void __attribute__((naked,noinline)) dcache_clean_all(void) { asm volatile (- "PUSH {LR}\n"+ "PUSH {R4,LR}\n"+ "bl is_dcache_locked\n" // check for "cache hacks" being used+ "mov r4, #0\n"+ "cmp r0, #0\n"+ "movne r4, #0x40000000\n" // avoid cleaning locked 1st segment "BL cache_get_config\n" "BL dcache_get_size\n" "CMP r0, #0\n"@@ -248,7 +282,7 @@ // index limit (max index+1) // per ARM DDI 0201D 4kb = bits 9:5 "LSR r3, r0, #2\n" - "MOV r1, #0\n"+ "MOV r1, r4\n" "2:\n" "MOV r0, #0\n" "1:\n"@@ -262,7 +296,7 @@ "BNE 2b\n" "MCR p15, 0, r1, c7, c10, 4\n" // drain write buffer "3:\n"- "POP {LR}\n"+ "POP {R4,LR}\n" "BX LR\n" ); }Index: modules/module_load.c===================================================================--- modules/module_load.c (revision 5635)+++ modules/module_load.c (working copy)@@ -573,7 +573,7 @@ // clean data cache to ensure code is in main memory dcache_clean_all(); // then flush instruction cache to ensure no addresses containing new code are cached- icache_flush_all();+ icache_flush_range(flat_buf, flat.reloc_start); // Return module memory address return flat_buf;
FWIW, the only reason I didn't do range originally for modules was laziness.
Flushing a range has the downside of being a slower operation (cycling over the range doing 0x20 bytes per cycle). Do we have modules that are large and their loading is time-critical?
Started by Avaviel Hello, I'm a NEWBIE - HELP!! (Newbies assistance, User Guides and thank you notes)
Started by Conklin CHDK Releases
Started by arm.indiana DSLR Hack development
Started by artfolio Creative Uses of CHDK
Started by names_are_hard General Chat