Files
ciciec2026_loongson/sdk/software/examples/dma/main.c

71 lines
2.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
// 配置 DMADMA 只需要最纯粹的物理地址
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;
}