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:
11
sdk/software/examples/dma/Makefile
Normal file
11
sdk/software/examples/dma/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
TARGET = dma
|
||||
|
||||
CFLAGS += -O3 -g
|
||||
|
||||
C_SRCS := $(wildcard ./*.c )
|
||||
|
||||
OBJDIR = obj
|
||||
COMMON_DIR = ../../bsp
|
||||
GCC_DIR=../../../toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0
|
||||
PICOLIBC_DIR=../../../toolchains/picolibc
|
||||
include ../../bsp/common.mk
|
||||
71
sdk/software/examples/dma/main.c
Normal file
71
sdk/software/examples/dma/main.c
Normal 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;
|
||||
}
|
||||
75
sdk/software/examples/dma/result.txt
Normal file
75
sdk/software/examples/dma/result.txt
Normal file
@@ -0,0 +1,75 @@
|
||||
dma_status init = 0
|
||||
src_array: 1c080d80
|
||||
dst_array: 1c080c80
|
||||
phys_src_array: 1c080d80
|
||||
phys_dst_array: 1c080c80
|
||||
uncached_src: bc080d80
|
||||
uncached_dst: bc080c80
|
||||
polling...
|
||||
dma passed!
|
||||
0: 0
|
||||
1: 1
|
||||
2: 4
|
||||
3: 9
|
||||
4: 16
|
||||
5: 25
|
||||
6: 36
|
||||
7: 49
|
||||
8: 64
|
||||
9: 81
|
||||
10: 100
|
||||
11: 121
|
||||
12: 144
|
||||
13: 169
|
||||
14: 196
|
||||
15: 225
|
||||
16: 256
|
||||
17: 289
|
||||
18: 324
|
||||
19: 361
|
||||
20: 400
|
||||
21: 441
|
||||
22: 484
|
||||
23: 529
|
||||
24: 576
|
||||
25: 625
|
||||
26: 676
|
||||
27: 729
|
||||
28: 784
|
||||
29: 841
|
||||
30: 900
|
||||
31: 961
|
||||
32: 1024
|
||||
33: 1089
|
||||
34: 1156
|
||||
35: 1225
|
||||
36: 1296
|
||||
37: 1369
|
||||
38: 1444
|
||||
39: 1521
|
||||
40: 1600
|
||||
41: 1681
|
||||
42: 1764
|
||||
43: 1849
|
||||
44: 1936
|
||||
45: 2025
|
||||
46: 2116
|
||||
47: 2209
|
||||
48: 2304
|
||||
49: 2401
|
||||
50: 2500
|
||||
51: 2601
|
||||
52: 2704
|
||||
53: 2809
|
||||
54: 2916
|
||||
55: 3025
|
||||
56: 3136
|
||||
57: 3249
|
||||
58: 3364
|
||||
59: 3481
|
||||
60: 3600
|
||||
61: 3721
|
||||
62: 3844
|
||||
63: 3969
|
||||
|
||||
Success! Array to Array DMA transfer verified.
|
||||
Reference in New Issue
Block a user