Use uncached ExtRAM access (0xBC400000) to bypass CPU data cache

The open-la500 core has USE_CACHE enabled. Writes to 0x1c400000
go to the write-back data cache and never reach the SRAM model
before the testbench checks ExtRAM. Use the 0xA0000000 uncached
segment (same pattern as fft_dma/main.c).
This commit is contained in:
2026-06-24 02:04:40 +08:00
parent b8a4fcc30b
commit e35fa5884d
14 changed files with 654 additions and 1 deletions

View File

@@ -0,0 +1,71 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <common_func.h>
#include <confreg_time.h>
#include <dma.h>
// BSP板级支持包所需全局变量
unsigned long UART_BASE = 0xbf000000;
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
// 加上 aligned(64) 是为了防止 DMA 突发传输时跨越缓存行或 AXI 非对齐边界
uint32_t src_array[64] __attribute__((aligned(64)));
uint32_t dst_array[64] __attribute__((aligned(64)));
int main(int argc, char** argv)
{
uint32_t data_len = 64;
uint32_t byte_len = data_len * 4;
// 虚拟地址转物理地址与无缓存地址
// 屏蔽掉高 3 位(& 0x1FFFFFFF)即可获得真实的物理地址
uint32_t phys_src_addr = ((uint32_t)src_array) & 0x1FFFFFFF;
uint32_t phys_dst_addr = ((uint32_t)dst_array) & 0x1FFFFFFF;
// 或上 0xA0000000 即可获得绕过 Cache 的无缓存(Uncached)指针
volatile uint32_t *uncached_src = (volatile uint32_t *)(phys_src_addr | 0xA0000000);
volatile uint32_t *uncached_dst = (volatile uint32_t *)(phys_dst_addr | 0xA0000000);
// CPU 必须通过无缓存指针写入
for (int i = 0; i < data_len; i++) {
uncached_src[i] = i * i; // 填入 0~63
uncached_dst[i] = 0xDEADBEEF; // 目的数组填入垃圾值,方便验证是否真的被覆盖
}
printf("src_array: %x\n", src_array);
printf("dst_array: %x\n", dst_array);
printf("phys_src_array: %x\n", phys_src_addr);
printf("phys_dst_array: %x\n", phys_dst_addr);
printf("uncached_src: %x\n", uncached_src);
printf("uncached_dst: %x\n", uncached_dst);
// 配置 DMA:DMA 只需要最纯粹的物理地址
dma_start_transfer(0, phys_src_addr, phys_dst_addr, byte_len);
dma_wait_polling(0);
printf("dma passed!\n");
// 校验数据:CPU 必须通过无缓存指针读取
int err = 0;
for (int i = 0; i < data_len; i++) {
uint32_t val = uncached_dst[i];
printf("%d: %d\n", i, val);
if (val != i * i) {
err++;
}
}
if (err == 0) {
printf("\nSuccess! Array to Array DMA transfer verified.\n");
} else {
printf("\nFailed! Found %d errors.\n", err);
}
return 0;
}