diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/system.h | 12 | ||||
-rw-r--r-- | firmware/target/arm/mmu-arm.S | 107 | ||||
-rw-r--r-- | firmware/target/arm/mmu-arm.h | 52 | ||||
-rw-r--r-- | firmware/target/arm/mmu-armv6.S | 102 | ||||
-rw-r--r-- | firmware/target/arm/system-pp5002.c | 12 | ||||
-rw-r--r-- | firmware/target/arm/system-target.h | 3 | ||||
-rw-r--r-- | firmware/target/coldfire/system-coldfire.c | 4 | ||||
-rw-r--r-- | firmware/target/coldfire/system-target.h | 2 |
8 files changed, 191 insertions, 103 deletions
diff --git a/firmware/export/system.h b/firmware/export/system.h index ce6277ac7a..ed10c84a58 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h @@ -282,16 +282,28 @@ static inline uint32_t swap_odd_even32(uint32_t value) /* Just define these as empty if not declared */ #ifdef HAVE_CPUCACHE_INVALIDATE +void cpucache_commit_discard(void); +/* deprecated alias */ void cpucache_invalidate(void); #else +static inline void cpucache_commit_discard(void) +{ +} +/* deprecated alias */ static inline void cpucache_invalidate(void) { } #endif #ifdef HAVE_CPUCACHE_FLUSH +void cpucache_commit(void); +/* deprecated alias */ void cpucache_flush(void); #else +static inline void cpucache_commit(void) +{ +} +/* deprecated alias */ static inline void cpucache_flush(void) { } diff --git a/firmware/target/arm/mmu-arm.S b/firmware/target/arm/mmu-arm.S index 02f1454399..5693ca587b 100644 --- a/firmware/target/arm/mmu-arm.S +++ b/firmware/target/arm/mmu-arm.S @@ -171,15 +171,18 @@ enable_mmu: /** Cache coherency **/ /* - * Invalidate DCache for this range - * will do write back - * void invalidate_dcache_range(const void *base, unsigned int size); + * Write DCache back to RAM for the given range and remove cache lines + * from DCache afterwards + * void commit_discard_dcache_range(const void *base, unsigned int size); */ .section .text, "ax", %progbits .align 2 - .global invalidate_dcache_range - .type invalidate_dcache_range, %function + .global commit_discard_dcache_range + .type commit_discard_dcache_range, %function + .global invalidate_dcache_range @ Alias, deprecated + @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ +commit_discard_dcache_range: invalidate_dcache_range: add r1, r0, r1 @ size -> end cmp r1, r0 @ end <= start? @@ -214,18 +217,20 @@ invalidate_dcache_range: mov r0, #0 @ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer bx lr @ - .size invalidate_dcache_range, .-invalidate_dcache_range + .size commit_discard_dcache_range, .-commit_discard_dcache_range /* - * clean DCache for this range - * forces DCache writeback for the specified range - * void clean_dcache_range(const void *base, unsigned int size); + * Write DCache back to RAM for the given range + * void commit_dcache_range(const void *base, unsigned int size); */ .section .text, "ax", %progbits .align 2 - .global clean_dcache_range - .type clean_dcache_range, %function + .global commit_dcache_range + .type commit_dcache_range, %function + .global clean_dcache_range @ Alias, deprecated + @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ +commit_dcache_range: clean_dcache_range: add r1, r0, r1 @ size -> end cmp r1, r0 @ end <= start? @@ -260,19 +265,22 @@ clean_dcache_range: mov r0, #0 @ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer bx lr @ - .size clean_dcache_range, .-clean_dcache_range + .size commit_dcache_range, .-commit_dcache_range /* - * Dump DCache for this range + * Remove cache lines for the given range from DCache * will *NOT* do write back except for buffer edges not on a line boundary - * void dump_dcache_range(const void *base, unsigned int size); + * void discard_dcache_range(const void *base, unsigned int size); */ .section .text, "ax", %progbits .align 2 - .global dump_dcache_range - .type dump_dcache_range, %function + .global discard_dcache_range + .type discard_dcache_range, %function + .global dump_dcache_range @ Alias, deprecated + @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ - dump_dcache_range: +discard_dcache_range: +dump_dcache_range: add r1, r0, r1 @ size -> end cmp r1, r0 @ end <= start? bxls lr @ @@ -287,7 +295,7 @@ clean_dcache_range: mcrne p15, 0, r1, c7, c14, 1 @ Clean and invalidate line by MVA @ if not cache aligned cmp r1, r0 @ end <= start now? -1: @ dump_start @ +1: @ discard_start @ mcrhi p15, 0, r0, c7, c6, 1 @ Invalidate line by MVA addhi r0, r0, #32 @ cmphi r1, r0 @ @@ -312,30 +320,35 @@ clean_dcache_range: mcrhi p15, 0, r0, c7, c6, 1 @ Invalidate line by MVA addhi r0, r0, #32 @ cmphi r1, r0 @ - bhi 1b @ dump_start @ + bhi 1b @ discard_start @ mov r0, #0 @ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer bx lr @ - .size dump_dcache_range, .-dump_dcache_range + .size discard_dcache_range, .-discard_dcache_range /* - * Cleans entire DCache - * void clean_dcache(void); + * Write entire DCache back to RAM + * void commit_dcache(void); */ .section .text, "ax", %progbits .align 2 - .global clean_dcache - .type clean_dcache, %function - .global cpucache_flush @ Alias + .global commit_dcache + .type commit_dcache, %function + .global cpucache_commit @ Alias + .global clean_dcache @ Alias, deprecated + .global cpucache_flush @ Alias, deprecated + +commit_dcache: +cpucache_commit: clean_dcache: cpucache_flush: #ifdef HAVE_TEST_AND_CLEAN_CACHE mrc p15, 0, r15, c7, c10, 3 @ test and clean dcache - bne clean_dcache + bne commit_dcache mov r1, #0 #else mov r1, #0x00000000 @ -1: @ clean_start @ +1: @ commit_start @ mcr p15, 0, r1, c7, c10, 2 @ Clean entry by index add r0, r1, #(1<<CACHEALIGN_BITS) mcr p15, 0, r0, c7, c10, 2 @ Clean entry by index @@ -344,25 +357,27 @@ cpucache_flush: mcr p15, 0, r0, c7, c10, 2 @ Clean entry by index .endr adds r1, r1, #0x04000000 @ will wrap to zero at loop end - bne 1b @ clean_start @ + bne 1b @ commit_start @ #endif /* HAVE_TEST_AND_CLEAN_CACHE */ mcr p15, 0, r1, c7, c10, 4 @ Drain write buffer bx lr @ - .size clean_dcache, .-clean_dcache + .size commit_dcache, .-commit_dcache /* - * Invalidate entire DCache - * will do writeback - * void invalidate_dcache(void); + * Commit and discard entire DCache, will do writeback + * void commit_discard_dcache(void); */ .section .icode, "ax", %progbits .align 2 - .global invalidate_dcache - .type invalidate_dcache, %function + .global commit_discard_dcache + .type commit_discard_dcache, %function + .global invalidate_dcache @ Alias, deprecated + +commit_discard_dcache: invalidate_dcache: #ifdef HAVE_TEST_AND_CLEAN_CACHE mrc p15, 0, r15, c7, c14, 3 @ test, clean and invalidate dcache - bne invalidate_dcache + bne commit_discard_dcache mov r1, #0 #else mov r1, #0x00000000 @ @@ -379,22 +394,26 @@ invalidate_dcache: #endif /* HAVE_TEST_AND_CLEAN_CACHE */ mcr p15, 0, r1, c7, c10, 4 @ Drain write buffer bx lr @ - .size invalidate_dcache, .-invalidate_dcache + .size commit_discard_dcache, .-commit_discard_dcache /* - * Invalidate entire ICache and DCache - * will do writeback - * void invalidate_idcache(void); + * Discards the entire ICache, and commit+discards the entire DCache + * void commit_discard_idcache(void); */ .section .icode, "ax", %progbits .align 2 - .global invalidate_idcache - .type invalidate_idcache, %function - .global cpucache_invalidate @ Alias + .global commit_discard_idcache + .type commit_discard_idcache, %function + .global cpucache_commit_discard @ Alias + .global invalidate_idcache @ Alias, deprecated + .global cpucache_invalidate @ Alias, deprecated + +commit_discard_idcache: +cpucache_commit_discard: invalidate_idcache: cpucache_invalidate: mov r2, lr @ save lr to r1, call uses r0 only - bl invalidate_dcache @ Clean and invalidate entire DCache + bl commit_discard_dcache @ commit and discard entire DCache mcr p15, 0, r1, c7, c5, 0 @ Invalidate ICache (r1=0 from call) bx r2 - .size invalidate_idcache, .-invalidate_idcache + .size commit_discard_idcache, .-commit_discard_idcache diff --git a/firmware/target/arm/mmu-arm.h b/firmware/target/arm/mmu-arm.h index 1cf1f68d00..92a81c0c34 100644 --- a/firmware/target/arm/mmu-arm.h +++ b/firmware/target/arm/mmu-arm.h @@ -35,29 +35,59 @@ void ttb_init(void); void enable_mmu(void); void map_section(unsigned int pa, unsigned int va, int mb, int flags); -/* Cleans entire DCache */ +/* Note for the function names + * + * ARM refers to the cache coherency functions as (in the CPU manuals): + * clean (write-back) + * clean and invalidate (write-back and removing the line from cache) + * invalidate (removing from cache without write-back) + * + * The deprecated functions below don't follow the above (which is why + * they're deprecated). + * + * This names have been proven to cause confusion, therefore we use: + * commit + * commit and discard + * discard + */ + +/* Commits entire DCache */ +void commit_dcache(void); +/* deprecated alias */ void clean_dcache(void); -/* Invalidate entire DCache */ -/* will do writeback */ +/* Commit and discard entire DCache, will do writeback */ +void commit_discard_dcache(void); +/* deprecated alias */ void invalidate_dcache(void); -/* Invalidate DCache for this range */ -/* will do writeback */ +/* Write DCache back to RAM for the given range and remove cache lines + * from DCache afterwards */ +void commit_discard_dcache_range(const void *base, unsigned int size); +/* deprecated alias */ void invalidate_dcache_range(const void *base, unsigned int size); -/* clean DCache for this range */ -/* forces DCache writeback for the specified range */ +/* Write DCache back to RAM for the given range */ +void commit_dcache_range(const void *base, unsigned int size); +/* deprecated alias */ void clean_dcache_range(const void *base, unsigned int size); -/* Dump DCache for this range */ -/* Will *NOT* do write back except for buffer ends not on a line boundary */ +/* + * Remove cache lines for the given range from DCache + * will *NOT* do write back except for buffer edges not on a line boundary + */ +void discard_dcache_range(const void *base, unsigned int size); +/* deprecated alias */ void dump_dcache_range(const void *base, unsigned int size); -/* Invalidate entire ICache and DCache */ -/* will do writeback */ +/* Discards the entire ICache, and commit+discards the entire DCache */ +void commit_discard_idcache(void); +/* deprecated alias */ void invalidate_idcache(void); +#define HAVE_CPUCACHE_COMMIT_DISCARD +#define HAVE_CPUCACHE_COMMIT +/* deprecated alias */ #define HAVE_CPUCACHE_INVALIDATE #define HAVE_CPUCACHE_FLUSH diff --git a/firmware/target/arm/mmu-armv6.S b/firmware/target/arm/mmu-armv6.S index 58e03d6614..38eefece81 100644 --- a/firmware/target/arm/mmu-armv6.S +++ b/firmware/target/arm/mmu-armv6.S @@ -28,15 +28,18 @@ #if 0 /* unused */ /* - * Invalidate DCache for this range - * will do write back - * void invalidate_dcache_range(const void *base, unsigned int size) + * Write DCache back to RAM for the given range and remove cache lines + * from DCache afterwards + * void commit_discard_dcache_range(const void *base, unsigned int size); */ .section .text, "ax", %progbits .align 2 - .global invalidate_dcache_range - .type invalidate_dcache_range, %function - @ MVA format: 31:5 = Modified virtual address, 4:0 = Ignored + .global commit_discard_dcache_range + .type commit_discard_dcache_range, %function + .global invalidate_dcache_range @ Alias, deprecated + + @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ +commit_discard_dcache_range: invalidate_dcache_range: add r1, r0, r1 @ size -> end cmp r1, r0 @ end <= start? @@ -45,20 +48,22 @@ invalidate_dcache_range: mcrrhi p15, 0, r1, r0, c14 @ Clean and invalidate DCache range mcrhi p15, 0, r2, c7, c10, 4 @ Data synchronization barrier bx lr @ - .size invalidate_dcache_range, .-invalidate_dcache_range + .size commit_discard_dcache_range, .-commit_discard_dcache_range #endif /* unused function */ /* - * clean DCache for this range - * forces DCache writeback for the specified range - * void clean_dcache_range(const void *base, unsigned int size); + * Write DCache back to RAM for the given range + * void commit_dcache_range(const void *base, unsigned int size); */ .section .text, "ax", %progbits .align 2 - .global clean_dcache_range - .type clean_dcache_range, %function - @ MVA format: 31:5 = Modified virtual address, 4:0 = Ignored + .global commit_dcache_range + .type commit_dcache_range, %function + .global clean_dcache_range @ Alias, deprecated + + @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ +commit_dcache_range: clean_dcache_range: add r1, r0, r1 @ size -> end cmp r1, r0 @ end <= start? @@ -67,20 +72,22 @@ clean_dcache_range: mcrrhi p15, 0, r1, r0, c12 @ Clean DCache range mcrhi p15, 0, r2, c7, c10, 4 @ Data synchronization barrier bx lr @ - .size clean_dcache_range, .-clean_dcache_range + .size commit_dcache_range, .-commit_dcache_range /* - * Dump DCache for this range + * Remove cache lines for the given range from DCache * will *NOT* do write back except for buffer edges not on a line boundary - * void dump_dcache_range(const void *base, unsigned int size); + * void discard_dcache_range(const void *base, unsigned int size); */ .section .text, "ax", %progbits .align 2 - .global dump_dcache_range - .type dump_dcache_range, %function - @ MVA format (mcr): 31:5 = Modified virtual address, 4:0 = SBZ - @ MVA format (mcrr): 31:5 = Modified virtual address, 4:0 = Ignored - dump_dcache_range: + .global discard_dcache_range + .type discard_dcache_range, %function + .global dump_dcache_range @ Alias, deprecated + + @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ +discard_dcache_range: +dump_dcache_range: add r1, r0, r1 @ size -> end cmp r1, r0 @ end <= start? bxls lr @ @@ -100,52 +107,63 @@ clean_dcache_range: mov r0, #0 @ mcr p15, 0, r0, c7, c10, 4 @ Data synchronization barrier bx lr @ - .size dump_dcache_range, .-dump_dcache_range + .size discard_dcache_range, .-discard_dcache_range /* - * Cleans entire DCache - * void clean_dcache(void); + * Write entire DCache back to RAM + * void commit_dcache(void); */ .section .text, "ax", %progbits .align 2 - .global clean_dcache - .type clean_dcache, %function - .global cpucache_flush @ Alias + .global commit_dcache + .type commit_dcache, %function + .global cpucache_commit @ Alias + .global clean_dcache @ Alias, deprecated + .global cpucache_flush @ Alias, deprecated + +commit_dcache: +cpucache_commit: clean_dcache: cpucache_flush: mov r0, #0 @ mcr p15, 0, r0, c7, c10, 0 @ Clean entire DCache mcr p15, 0, r0, c7, c10, 4 @ Data synchronization barrier bx lr @ - .size clean_dcache, .-clean_dcache + .size commit_dcache, .-commit_dcache /* - * Invalidate entire DCache - * will do writeback - * void invalidate_dcache(void); + * Clean and invalidate entire DCache, will do writeback + * void commit_discard_dcache(void); */ - .section .text, "ax", %progbits + .section .icode, "ax", %progbits .align 2 - .global invalidate_dcache - .type invalidate_dcache, %function + .global commit_discard_dcache + .type commit_discard_dcache, %function + .global invalidate_dcache @ Alias, deprecated + +commit_discard_dcache: invalidate_dcache: mov r0, #0 @ mcr p15, 0, r0, c7, c14, 0 @ Clean and invalidate entire DCache mcr p15, 0, r0, c7, c10, 4 @ Data synchronization barrier bx lr @ - .size invalidate_dcache, .-invalidate_dcache + .size commit_discard_dcache, .-commit_discard_dcache + /* - * Invalidate entire ICache and DCache - * will do writeback - * void invalidate_idcache(void); + * Discards the entire ICache, and commit+discards the entire DCache + * void commit_discard_idcache(void); */ .section .icode, "ax", %progbits .align 2 - .global invalidate_idcache - .type invalidate_idcache, %function - .global cpucache_invalidate @ Alias + .global commit_discard_idcache + .type commit_discard_idcache, %function + .global cpucache_commit_discard @ Alias + .global invalidate_idcache @ Alias, deprecated + .global cpucache_invalidate @ Alias, deprecated + +commit_discard_idcache: invalidate_idcache: cpucache_invalidate: mov r0, #0 @ @@ -155,4 +173,4 @@ cpucache_invalidate: mcr p15, 0, r0, c7, c10, 4 @ Data synchronization barrier mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer (IMB) bx lr @ - .size invalidate_idcache, .-invalidate_idcache + .size commit_discard_idcache, .-commit_discard_idcache diff --git a/firmware/target/arm/system-pp5002.c b/firmware/target/arm/system-pp5002.c index 746441113e..04e052fa83 100644 --- a/firmware/target/arm/system-pp5002.c +++ b/firmware/target/arm/system-pp5002.c @@ -62,7 +62,7 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void) some other CPU frequency scaling. */ #ifndef BOOTLOADER -void ICODE_ATTR __attribute__((naked)) cpucache_flush(void) +void ICODE_ATTR __attribute__((naked)) cpucache_commit(void) { asm volatile( "mov r0, #0xf0000000 \n" @@ -70,14 +70,15 @@ void ICODE_ATTR __attribute__((naked)) cpucache_flush(void) "add r1, r0, #0x2000 \n" /* r1 = CACHE_FLUSH_BASE + CACHE_SIZE */ "mov r2, #0 \n" "1: \n" - "str r2, [r0], #16 \n" /* Flush */ + "str r2, [r0], #16 \n" /* Commit */ "cmp r0, r1 \n" "blo 1b \n" "bx lr \n" ); } +void cpucache_flush(void) __attribute__((alias("cpucache_commit"))); -void ICODE_ATTR __attribute__((naked)) cpucache_invalidate(void) +void ICODE_ATTR __attribute__((naked)) cpucache_commit_discard(void) { asm volatile( "mov r0, #0xf0000000 \n" @@ -86,13 +87,14 @@ void ICODE_ATTR __attribute__((naked)) cpucache_invalidate(void) "add r1, r0, #0x2000 \n" /* r2 = CACHE_FLUSH_BASE + CACHE_SIZE */ "mov r3, #0 \n" "1: \n" - "str r3, [r0], #16 \n" /* Flush */ - "str r3, [r2], #16 \n" /* Invalidate */ + "str r3, [r0], #16 \n" /* Commit */ + "str r3, [r2], #16 \n" /* Discard */ "cmp r0, r1 \n" "blo 1b \n" "bx lr \n" ); } +void cpucache_invalidate(void) __attribute__((alias("cpucache_commit_discard"))); static void ipod_init_cache(void) { diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h index c7503d7bcb..1e573be291 100644 --- a/firmware/target/arm/system-target.h +++ b/firmware/target/arm/system-target.h @@ -168,6 +168,9 @@ static inline void wake_core(int core) /** cache functions **/ #ifndef BOOTLOADER +#define HAVE_CPUCACHE_COMMIT_DISCARD +#define HAVE_CPUCACHE_COMMIT +/* deprecated alias */ #define HAVE_CPUCACHE_INVALIDATE #define HAVE_CPUCACHE_FLUSH #endif diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c index 75440a23bf..57d729f7e8 100644 --- a/firmware/target/coldfire/system-coldfire.c +++ b/firmware/target/coldfire/system-coldfire.c @@ -369,10 +369,12 @@ void coldfire_set_dataincontrol(unsigned long value) restore_irq(level); } -void cpucache_invalidate(void) +void cpucache_commit_discard(void) { asm volatile ("move.l #0x01000000,%d0\n" "movec.l %d0,%cacr\n" "move.l #0x80000000,%d0\n" "movec.l %d0,%cacr"); } + +void cpucache_invalidate(void) __attribute__((alias("cpucache_commit_discard"))); diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h index 347d8e13dc..2de8fd06c2 100644 --- a/firmware/target/coldfire/system-target.h +++ b/firmware/target/coldfire/system-target.h @@ -194,6 +194,8 @@ static inline uint32_t swap_odd_even32(uint32_t value) return value; } +#define HAVE_CPUCACHE_COMMIT_DISCARD +/* deprecated alias */ #define HAVE_CPUCACHE_INVALIDATE #define DEFAULT_PLLCR_AUDIO_BITS 0x10400000 |