diff --git a/include/cache.h b/include/cache.h index 518c8e7..1e68d3e 100644 --- a/include/cache.h +++ b/include/cache.h @@ -7,6 +7,8 @@ void invalidateICache(void); void invalidateICacheRange(const void *const base, u32 size); void flushDCache(void); +void flushInvalidateDCache(void); void flushDCacheRange(const void *const base, u32 size); +void flushInvalidateDCacheRange(const void *const base, u32 size); void invalidateDCache(void); void invalidateDCacheRange(const void *const base, u32 size); diff --git a/source/arm11/cache.s b/source/arm11/cache.s index b3769a8..5c0f678 100644 --- a/source/arm11/cache.s +++ b/source/arm11/cache.s @@ -5,14 +5,18 @@ .global invalidateICache .global invalidateICacheRange .global flushDCache +.global flushInvalidateDCache .global flushDCacheRange +.global flushInvalidateDCacheRange .global invalidateDCache .global invalidateDCacheRange .type invalidateICache STT_FUNC .type invalidateICacheRange STT_FUNC .type flushDCache STT_FUNC +.type flushInvalidateDCache STT_FUNC .type flushDCacheRange STT_FUNC +.type flushInvalidateDCacheRange STT_FUNC .type invalidateDCache STT_FUNC .type invalidateDCacheRange STT_FUNC @@ -54,6 +58,13 @@ bx lr +flushInvalidateDCache: + mov r0, #0 + mcr p15, 0, r0, c7, c14, 0 @ "Clean and Invalidate Entire Data Cache" + mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier + bx lr + + flushDCacheRange: add r1, r1, r0 bic r0, r0, #(CACHE_LINE_SIZE - 1) @@ -67,6 +78,19 @@ bx lr +flushInvalidateDCacheRange: + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) + mov r2, #0 + flushInvalidateDCacheRange_lp: + mcr p15, 0, r0, c7, c14, 1 @ "Clean and Invalidate Data Cache Line (using MVA)" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt flushInvalidateDCacheRange_lp + mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier + bx lr + + invalidateDCache: mov r0, #0 mcr p15, 0, r0, c7, c6, 0 @ Invalidate Entire Data Cache diff --git a/source/arm9/cache.s b/source/arm9/cache.s index 02b3c80..003ab02 100644 --- a/source/arm9/cache.s +++ b/source/arm9/cache.s @@ -5,14 +5,18 @@ .global invalidateICache .global invalidateICacheRange .global flushDCache +.global flushInvalidateDCache .global flushDCacheRange +.global flushInvalidateDCacheRange .global invalidateDCache .global invalidateDCacheRange .type invalidateICache STT_FUNC .type invalidateICacheRange STT_FUNC .type flushDCache STT_FUNC +.type flushInvalidateDCache STT_FUNC .type flushDCacheRange STT_FUNC +.type flushInvalidateDCacheRange STT_FUNC .type invalidateDCache STT_FUNC .type invalidateDCacheRange STT_FUNC @@ -55,7 +59,25 @@ add r1, r1, #0x40000000 cmp r1, #0 bne flushDCache_outer_lp - b drainWriteBuffer + b drainWriteBufferFlushInvalidate + + +flushInvalidateDCache: + mov r1, #0 + flushInvalidateDCache_outer_lp: + mov r0, #0 + flushInvalidateDCache_inner_lp: + orr r2, r1, r0 @ Generate segment and line address + mcr p15, 0, r2, c7, c14, 2 @ "Clean and flush data cache entry Index and segment" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, #(DCACHE_SIZE / 4) + bne flushInvalidateDCache_inner_lp + add r1, r1, #0x40000000 + cmp r1, #0 + bne flushInvalidateDCache_outer_lp +drainWriteBufferFlushInvalidate: + mcr p15, 0, r1, c7, c10, 4 @ Drain write buffer + bx lr flushDCacheRange: @@ -66,8 +88,18 @@ add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blt flushDCacheRange_lp + b drainWriteBufferFlushInvalidateRange -drainWriteBuffer: + +flushInvalidateDCacheRange: + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) + flushInvalidateDCacheRange_lp: + mcr p15, 0, r0, c7, c14, 1 @ "Clean and flush data cache entry Address" + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt flushInvalidateDCacheRange_lp +drainWriteBufferFlushInvalidateRange: mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer bx lr diff --git a/source/arm9/crypto.c b/source/arm9/crypto.c index bbb21ca..53493e6 100644 --- a/source/arm9/crypto.c +++ b/source/arm9/crypto.c @@ -10,7 +10,6 @@ #include "arm9/crypto.h" #include "arm9/interrupt.h" #include "arm9/ndma.h" -#include "cache.h" @@ -362,12 +361,6 @@ const u32 aesParams = AES_MODE_CTR | ctx->aesParams; - if(dma) - { - flushDCacheRange(in, blocks<<4); - invalidateDCacheRange(out, blocks<<4); - } - while(blocks) { REG_AESCNT = ctrParams; diff --git a/source/arm9/dev.c b/source/arm9/dev.c index 7d37e93..8233a79 100644 --- a/source/arm9/dev.c +++ b/source/arm9/dev.c @@ -8,7 +8,7 @@ #include "arm9/sdmmc.h" #include "arm9/spiflash.h" #include "arm9/crypto.h" -#include "arm9/ndma.h" +#include "cache.h" #include "arm9/timer.h" #include "util.h" #include "arm9/dev.h" @@ -371,6 +371,7 @@ } if(sdmmc_nand_readsectors(sector, count, buf)) return false; + flushInvalidateDCacheRange(buf, count<<9); AES_ctr(ctx, buf, buf, count<<5, true); return true; @@ -399,7 +400,9 @@ void *crypto_buf = malloc(crypto_sec_size<<9); if(!crypto_buf) return false; - + + flushDCacheRange(buf, count<<9); + AES_selectKeyslot(keyslot); AES_ctx *ctx; if(keyslot == 0x03) @@ -418,6 +421,7 @@ do { size_t crypt_size = min(count, crypto_sec_size); + invalidateDCacheRange(crypto_buf, crypt_size<<9); AES_ctr(ctx, buf, crypto_buf, crypt_size<<5, true); if(sdmmc_nand_writesectors(sector, crypt_size, crypto_buf)) {