Код: Выделить всё
проц FlushDCacheRange*(adr:адресВПамяти; len: размерМЗ);
конст
cacheline = 32;
L2CCBBase = 0F8F02000H; (*XPS_L2CC_BASEADDR*)
L2CCCacheSync = L2CCBBase + 00730H; (* Cache Sync *)(*XPS_L2CC_CACHE_SYNC_OFFSET *)
L2CCCacheInvClnPAOfs= 007F0H; (* Cache Clean by PA *)(*XPS_L2CC_CACHE_INV_CLN_PA_OFFSET*)
L2CCOffset = L2CCBBase + L2CCCacheInvClnPAOfs;
нач
если ~enableCaching или (len = 0) то возврат всё;
если len остОтДеленияНа cacheline # 0 то увел(len, cacheline - len остОтДеленияНа cacheline) всё;
если adr остОтДеленияНа cacheline # 0 то умень(adr, len остОтДеленияНа cacheline) всё;
машКод
LDR R0, [FP, #adr] ; R0 := adr
LDR R1, [FP, #len] ; R1 := len
LDR R2, [PC, #Cacheline - 8 - $] ; R2 := cacheline
SUB R3, R2, #1 ; R3 := cacheline - 1
AND R3, R0, R3 ; R3 := adr MOD cacheline
ADD R1, R1, R0
SUB R0, R0, R3 ; R0 := adr - adr MOD cacheline
;ADD R1, R1, R3 ; R1 := len + adr MOD cacheline
MOV R3, #0
MCR P15, 2, R3, C0, C0, 0 ; Select cache level 1
LDR R4, [PC, #L2COfs - 8 - $] ; R4 := L2 cache flush address register address
Loop:
CMP R0, R1 ; while R0 < R1
BEQ Sync
BHI Sync
MCR P15, 0, R0, C7, C14, 1 ; Clean Cache Level 1 By MVA (R0)
STR R0, [R4, #0] ; Clean Cache Level 2 By PA (R0)
DSB
ADD R0, R0, R2 ; R0 := R0 + cacheline
B Loop ; end
Sync:
DSB
LDR R0, [PC, #L2CSync - 8 - $] ; R0 := L2 cache sync register address
;MOV R1, #1
;STR R1, [R0, #0] ; [R0] := 1
SyncLoop: ; repeat
LDR R1, [R0, #0] ; R1 := l2 cache syc state
CMP R1, #0
BEQ Exit ; until R1 = 0
B SyncLoop
Cacheline: d32 cacheline
L2COfs: d32 L2CCOffset
L2CSync: d32 L2CCCacheSync
Exit:
кон;
кон FlushDCacheRange;