DMA一致性映射使用

DMA映射可参考:https://www.cnblogs.com/lethe1203/p/18092749

 

reserved_memory方式

1、定义保留内存的节点,由设备节点使用
test_device_reserved: pmu_noc@0xe8000000 {
            compatible = "shared-dma-pool";
            reg = <0x0 0xe8000000 0x0 0x800000>;
            reusable;
        };

&test_device {
    status = "okay";
    memory-region = <&test_device_reserved>;
};
 
2、驱动probe中初始化reserved_mem,即提取memory-region信息绑定设备
ret = of_reserved_mem_device_init(&pdev->dev);
或
struct device_node *np = pdev->dev.of_node;
ret = of_reserved_mem_device_init_by_idx(&pdev->dev, np, 0);

 

3、驱动中申请设备内存使用
dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); // 可以访问64bit

buf->virt = NULL;    // 申请成功后得到的虚拟地址
buf->phys = 0;    // 成功后phys值为设备树填写的物理地址
buf->size = size;    // 要申请的长度
buf->dev = dev;
buf->virt = dma_alloc_coherent(dev, buf->size, &buf->phys, GFP_KERNEL);

... ... 
dma_free_coherent(buf->dev, buf->size, buf->virt, buf->phys);

 

SMMU方式

使用smmu方式需要硬件上多一个TBU
例如:GPU需要一致性映射一块内存,不使用预留内存方式的话,就需要给GPU一块专属的TBU
此时需要协同smmu工程师协同调试。此时直接使用:
dma_set_mask(dev, DMA_BIT_MASK(64));
virt = dma_alloc_coherent(dev, size, phys, GFP_KERNEL);

... ... 
dma_free_coherent(buf->dev, buf->size, buf->virt, buf->phys);
得到的phys便是kernel看到的地址,virt表示GPU设备看到的地址
posted @ 2024-03-24 18:12  lethe1203  阅读(31)  评论(0编辑  收藏  举报