Saya menerapkan fungsi pemeliharaan cache untuk ARMv8 (Cortex-A53) yang berjalan dalam mode 32 bit. Ada masalah saat saya mencoba membersihkan wilayah memori dengan menggunakan alamat virtual (VA). DCacheFlushByRange
terlihat seperti ini
// some init.
// kDCacheL1 = 0; kDCacheL2 = 2;
while (alignedVirtAddr < endAddr)
{
// Flushing L1
asm volatile("mcr p15, 2, %0, c0, c0, 0" : : "r"(kDCacheL1) :); // select cache
isb();
asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r"(alignedVirtAddr) :); // clean & invalidate
dsb();
// Flushing L2
asm volatile("mcr p15, 2, %0, c0, c0, 0" : : "r"(kDCacheL2) :); // select cache
isb();
asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r"(alignedVirtAddr) :); // clean & invalidate
dsb();
alignedVirtAddr += lineSize;
}
DMA digunakan untuk memvalidasi fungsi. DMA menyalin satu buffer ke buffer lainnya. Buffer sumber dihapus sebelum DMA, buffer tujuan tidak valid setelah DMA selesai. Buffer diselaraskan dengan 64 byte. Tes
for (uint32_t i = 0; i < kBufSize; i++)
buf1[i] = 0;
for (uint32_t i = 0; i < kBufSize; i++)
buf0[i] = kRefValue;
DCacheFlushByRange(buf0, sizeof(buf0));
// run DMA
while (1) // wait DMA completion;
DCacheInvalidateByRange(buf1, sizeof(buf1));
compare(buf0, buf1);
Di dump saya dapat melihat bahwa buf1
masih hanya berisi nol. Ketika cache dimatikan, hasilnya benar sehingga DMA sendiri berfungsi dengan benar.
Poin lainnya adalah ketika seluruh D-cache di-flush/dibatalkan karena hasil set/caranya benar.
// loops th/ way & set for L1 & L2
asm volatile("mcr p15, 0, %0, c7, c14, 2" : : "r"(setway) :)
Segera siram/batalkan dengan set/cara bekerja dengan benar. Begitu pula dengan mem-flash/membatalkan menggunakan VA tidak. Apa yang mungkin menjadi masalah?
PS: kBufSize=4096;
, total ukuran buffer 4096 * sizeof(uint32_t) == 16KB