diff --git a/include/hardware/cache.h b/include/hardware/cache.h index a2f511b..d023cab 100644 --- a/include/hardware/cache.h +++ b/include/hardware/cache.h @@ -23,10 +23,10 @@ void invalidateICache(void); -void invalidateICacheRange(const void *const base, u32 size); +void invalidateICacheRange(const void *base, u32 size); +void cleanDCache(void); void flushDCache(void); -void flushInvalidateDCache(void); -void flushDCacheRange(const void *const base, u32 size); -void flushInvalidateDCacheRange(const void *const base, u32 size); +void cleanDCacheRange(const void *base, u32 size); +void flushDCacheRange(const void *base, u32 size); void invalidateDCache(void); -void invalidateDCacheRange(const void *const base, u32 size); +void invalidateDCacheRange(const void *base, u32 size); diff --git a/source/arm11/hardware/cache.s b/source/arm11/hardware/cache.s index 87515a1..0084710 100644 --- a/source/arm11/hardware/cache.s +++ b/source/arm11/hardware/cache.s @@ -54,22 +54,38 @@ BEGIN_ASM_FUNC invalidateICacheRange END_ASM_FUNC -BEGIN_ASM_FUNC flushDCache +BEGIN_ASM_FUNC cleanDCache mov r0, #0 - mcr p15, 0, r0, c7, c10, 0 @ "Clean Entire Data Cache" + mcr p15, 0, r0, c7, c10, 0 @ Clean Entire Data Cache mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier bx lr END_ASM_FUNC -BEGIN_ASM_FUNC flushInvalidateDCache +BEGIN_ASM_FUNC flushDCache mov r0, #0 - mcr p15, 0, r0, c7, c14, 0 @ "Clean and Invalidate Entire Data Cache" + 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 END_ASM_FUNC +BEGIN_ASM_FUNC cleanDCacheRange + cmp r1, #DCACHE_SIZE + bhi cleanDCache + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) + mov r2, #0 + cleanDCacheRange_lp: + mcr p15, 0, r0, c7, c10, 1 @ Clean Data Cache Line (using MVA) + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt cleanDCacheRange_lp + mcr p15, 0, r2, c7, c10, 4 @ Data Synchronization Barrier + bx lr +END_ASM_FUNC + + BEGIN_ASM_FUNC flushDCacheRange cmp r1, #DCACHE_SIZE bhi flushDCache @@ -77,7 +93,7 @@ BEGIN_ASM_FUNC flushDCacheRange bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 flushDCacheRange_lp: - mcr p15, 0, r0, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" + 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 flushDCacheRange_lp @@ -86,22 +102,6 @@ BEGIN_ASM_FUNC flushDCacheRange END_ASM_FUNC -BEGIN_ASM_FUNC flushInvalidateDCacheRange - cmp r1, #DCACHE_SIZE - bhi flushInvalidateDCache - 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 -END_ASM_FUNC - - BEGIN_ASM_FUNC invalidateDCache mov r0, #0 mcr p15, 0, r0, c7, c6, 0 @ Invalidate Entire Data Cache @@ -112,12 +112,12 @@ END_ASM_FUNC BEGIN_ASM_FUNC invalidateDCacheRange cmp r1, #DCACHE_SIZE - bhi flushInvalidateDCache + bhi flushDCache add r1, r1, r0 tst r0, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r0, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" + mcrne p15, 0, r0, c7, c10, 1 @ Clean Data Cache Line (using MVA) tst r1, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r1, c7, c10, 1 @ "Clean Data Cache Line (using MVA)" + mcrne p15, 0, r1, c7, c10, 1 @ Clean Data Cache Line (using MVA) bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 invalidateDCacheRange_lp: diff --git a/source/arm11/ipc_handler.c b/source/arm11/ipc_handler.c index 5e511c5..2821741 100644 --- a/source/arm11/ipc_handler.c +++ b/source/arm11/ipc_handler.c @@ -46,7 +46,7 @@ u32 IPC_handleCmd(u8 cmdId, u32 inBufs, u32 outBufs, UNUSED const u32 *const buf for(u32 i = inBufs; i < inBufs + outBufs; i++) { const IpcBuffer *const outBuf = (IpcBuffer*)&buf[i * sizeof(IpcBuffer) / 4]; - if(outBuf->ptr && outBuf->size) flushInvalidateDCacheRange(outBuf->ptr, outBuf->size); + if(outBuf->ptr && outBuf->size) flushDCacheRange(outBuf->ptr, outBuf->size); } return result; diff --git a/source/arm11/power.c b/source/arm11/power.c index 1dc36ae..0ddf524 100644 --- a/source/arm11/power.c +++ b/source/arm11/power.c @@ -34,7 +34,7 @@ static void power_safe_halt(void) // give the screens a bit of time to turn off TIMER_sleepMs(400); - flushDCache(); + cleanDCache(); } noreturn void power_off(void) diff --git a/source/arm11/start.s b/source/arm11/start.s index 938a572..977bad4 100644 --- a/source/arm11/start.s +++ b/source/arm11/start.s @@ -192,7 +192,7 @@ BEGIN_ASM_FUNC deinitCpu cpsid aif, #PSR_SYS_MODE bl stubExceptionVectors - bl flushDCache + bl cleanDCache ldr r1, =0xC03805 @ Disable MMU, D-Cache, Program flow prediction, I-Cache, @ high exception vectors, Unaligned data access, diff --git a/source/arm9/hardware/cache.s b/source/arm9/hardware/cache.s index 8266651..8ad2322 100644 --- a/source/arm9/hardware/cache.s +++ b/source/arm9/hardware/cache.s @@ -47,6 +47,24 @@ BEGIN_ASM_FUNC invalidateICacheRange END_ASM_FUNC +BEGIN_ASM_FUNC cleanDCache + mov r1, #0 + cleanDCache_outer_lp: + mov r0, #0 + cleanDCache_inner_lp: + orr r2, r1, r0 @ Generate segment and line address + add r0, r0, #CACHE_LINE_SIZE + mcr p15, 0, r2, c7, c10, 2 @ "Clean data cache entry Index and segment" + cmp r0, #(DCACHE_SIZE / 4) + bne cleanDCache_inner_lp + add r1, r1, #0x40000000 + cmp r1, #0 + bne cleanDCache_outer_lp + mcr p15, 0, r1, c7, c10, 4 @ Drain write buffer + bx lr +END_ASM_FUNC + + BEGIN_ASM_FUNC flushDCache mov r1, #0 flushDCache_outer_lp: @@ -54,7 +72,7 @@ BEGIN_ASM_FUNC flushDCache flushDCache_inner_lp: orr r2, r1, r0 @ Generate segment and line address add r0, r0, #CACHE_LINE_SIZE - mcr p15, 0, r2, c7, c10, 2 @ "Clean data cache entry Index and segment" + mcr p15, 0, r2, c7, c14, 2 @ Clean and flush data cache entry Index and segment cmp r0, #(DCACHE_SIZE / 4) bne flushDCache_inner_lp add r1, r1, #0x40000000 @@ -65,20 +83,18 @@ BEGIN_ASM_FUNC flushDCache END_ASM_FUNC -BEGIN_ASM_FUNC flushInvalidateDCache - mov r1, #0 - flushInvalidateDCache_outer_lp: - mov r0, #0 - flushInvalidateDCache_inner_lp: - orr r2, r1, r0 @ Generate segment and line address - add r0, r0, #CACHE_LINE_SIZE - mcr p15, 0, r2, c7, c14, 2 @ "Clean and flush data cache entry Index and segment" - cmp r0, #(DCACHE_SIZE / 4) - bne flushInvalidateDCache_inner_lp - add r1, r1, #0x40000000 - cmp r1, #0 - bne flushInvalidateDCache_outer_lp - mcr p15, 0, r1, c7, c10, 4 @ Drain write buffer +BEGIN_ASM_FUNC cleanDCacheRange + cmp r1, #DCACHE_SIZE + bhi cleanDCache + add r1, r1, r0 + bic r0, r0, #(CACHE_LINE_SIZE - 1) + mov r2, #0 + cleanDCacheRange_lp: + mcr p15, 0, r0, c7, c10, 1 @ Clean data cache entry Address + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blt cleanDCacheRange_lp + mcr p15, 0, r2, c7, c10, 4 @ Drain write buffer bx lr END_ASM_FUNC @@ -90,7 +106,7 @@ BEGIN_ASM_FUNC flushDCacheRange bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 flushDCacheRange_lp: - mcr p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" + mcr p15, 0, r0, c7, c14, 1 @ Clean and flush data cache entry Address add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blt flushDCacheRange_lp @@ -99,22 +115,6 @@ BEGIN_ASM_FUNC flushDCacheRange END_ASM_FUNC -BEGIN_ASM_FUNC flushInvalidateDCacheRange - cmp r1, #DCACHE_SIZE - bhi flushInvalidateDCache - 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 flush data cache entry Address" - add r0, r0, #CACHE_LINE_SIZE - cmp r0, r1 - blt flushInvalidateDCacheRange_lp - mcr p15, 0, r2, c7, c10, 4 @ Drain write buffer - bx lr -END_ASM_FUNC - - BEGIN_ASM_FUNC invalidateDCache mov r0, #0 mcr p15, 0, r0, c7, c6, 0 @ "Flush data cache" @@ -124,16 +124,16 @@ END_ASM_FUNC BEGIN_ASM_FUNC invalidateDCacheRange cmp r1, #DCACHE_SIZE - bhi flushInvalidateDCache + bhi flushDCache add r1, r1, r0 tst r0, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" + mcrne p15, 0, r0, c7, c10, 1 @ Clean data cache entry Address tst r1, #(CACHE_LINE_SIZE - 1) - mcrne p15, 0, r1, c7, c10, 1 @ "Clean data cache entry Address" + mcrne p15, 0, r1, c7, c10, 1 @ Clean data cache entry Address bic r0, r0, #(CACHE_LINE_SIZE - 1) mov r2, #0 invalidateDCacheRange_lp: - mcr p15, 0, r0, c7, c6, 1 @ "Flush data cache single entry Address" + mcr p15, 0, r0, c7, c6, 1 @ Flush data cache single entry Address add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blt invalidateDCacheRange_lp diff --git a/source/arm9/ipc_handler.c b/source/arm9/ipc_handler.c index fc09303..881aeae 100644 --- a/source/arm9/ipc_handler.c +++ b/source/arm9/ipc_handler.c @@ -48,7 +48,7 @@ u32 IPC_handleCmd(u8 cmdId, u32 inBufs, u32 outBufs, const u32 *const buf) for(u32 i = inBufs; i < inBufs + outBufs; i++) { const IpcBuffer *const outBuf = (IpcBuffer*)&buf[i * sizeof(IpcBuffer) / 4]; - if(outBuf->ptr && outBuf->size) flushInvalidateDCacheRange(outBuf->ptr, outBuf->size); + if(outBuf->ptr && outBuf->size) flushDCacheRange(outBuf->ptr, outBuf->size); } return result; diff --git a/source/arm9/start.s b/source/arm9/start.s index dc6975b..9410a3b 100644 --- a/source/arm9/start.s +++ b/source/arm9/start.s @@ -317,7 +317,7 @@ BEGIN_ASM_FUNC deinitCpu subs r1, r1, #1 bne deinitCpu_lp - bl flushDCache + bl cleanDCache mov r2, #0 ldrh r1, =0x1005 @ MPU, D-Cache and I-Cache bitmask mrc p15, 0, r0, c1, c0, 0 @ Read control register diff --git a/source/hardware/corelink_dma-330.c b/source/hardware/corelink_dma-330.c index 583719d..92ea9cf 100644 --- a/source/hardware/corelink_dma-330.c +++ b/source/hardware/corelink_dma-330.c @@ -204,7 +204,7 @@ void DMA330_init(void) waitForChannelStatus(0, CSR_STATUS_STOPPED); progBuf[1] = i<<3; // Periphal ID - flushDCacheRange(progBuf, 3); + cleanDCacheRange(progBuf, 3); // DMAGO channel 0 non-secure sendDebugCmd(DBGINST0_BYTES01(0x00A2u) | DBGINST0_THREAD_MGR, (u32)progBuf); } diff --git a/source/hardware/pxi.c b/source/hardware/pxi.c index 227d4ae..8e940e6 100644 --- a/source/hardware/pxi.c +++ b/source/hardware/pxi.c @@ -112,7 +112,7 @@ u32 PXI_sendCmd(u32 cmd, const u32 *buf, u32 words) for(u32 i = 0; i < inBufs; i++) { const IpcBuffer *const inBuf = (IpcBuffer*)&buf[i * sizeof(IpcBuffer) / 4]; - if(inBuf->ptr && inBuf->size) flushDCacheRange(inBuf->ptr, inBuf->size); + if(inBuf->ptr && inBuf->size) cleanDCacheRange(inBuf->ptr, inBuf->size); } for(u32 i = inBufs; i < inBufs + outBufs; i++) {