Linux - Hardware This forum is for Hardware issues.
Having trouble installing a piece of hardware? Want to know if that peripheral is compatible with Linux? |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
04-27-2020, 10:55 AM
|
#1
|
LQ Newbie
Registered: Apr 2020
Posts: 5
Rep: 
|
DMA for PCIe
Hi all!
Could you say please, what I am doing wrong?
Debian 10.
I am trying send data through PCIe + DMA. But I cannot fill sending array correctly. The data which I send from a host are received not which that I expect.
Code:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include "vi_cntr.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Drakonof");
MODULE_DESCRIPTION("PCI");
MODULE_VERSION("0.1");
#define CDMA_BAR 0
#define PCI_BAR 1
#define DDR_BAR 2
// cdma regs
#define CDMACR 0x00
#define CDMASR 0x04
#define CURDESC_PNTR 0x08
#define CURDESC_PNTR_MSB 0x0C
#define TAILDESC_PNTR 0x10
#define TAILDESC_PNTR_MSB 0x14
#define SA 0x18
#define SA_MSB 0x1C
#define DA 0x20
#define DA_MSB 0x24
#define BTT 0x28
#define DEVICE_NAME "drakonof_pci"
static dma_addr_t dma_handle = 0;
static void * dmabuf = NULL;
static volatile uint32_t *pci_reg_mem = NULL, *cdma_reg_mem = NULL;
static volatile uint32_t *ddr_mem = NULL;
static resource_size_t cdma_start,cdma_len,pci_start,pci_len,ddr_start,ddr_len;
static struct pci_device_id vi_cntr_pci_id[] = {
{ PCI_DEVICE(VI_CNTR_VENDOR, VI_CNTR_ID), },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, vi_cntr_pci_id);
static int vi_cntr_probe(struct pci_dev *pDev, const struct pci_device_id *id);
static void vi_cntr_remove(struct pci_dev *pDev);
static struct pci_driver vi_cntr_pci = {
.name = DEVICE_NAME,
.id_table = vi_cntr_pci_id,
.probe = vi_cntr_probe,
.remove = vi_cntr_remove
};
static int __init pci_init(void)
{
struct pci_dev *p_pci_dev = NULL;
if((p_pci_dev = pci_get_device(VI_CNTR_VENDOR,VI_CNTR_ID, p_pci_dev)) == NULL)
{
printk(KERN_NOTICE "PCI device not finded\n");
}
return pci_register_driver(&vi_cntr_pci);
}
static void __exit pci_exit(void)
{
pci_unregister_driver(&vi_cntr_pci);
}
static int vi_cntr_probe(struct pci_dev *p_pci_dev, const struct pci_device_id *pId)
{
u16 vendor = 0,
id = 0;
u32 i = 0;
if(pci_enable_device(p_pci_dev))
{
printk(KERN_INFO "pci_enable_device error\n");
}
pci_read_config_word(p_pci_dev, PCI_VENDOR_ID, &vendor);
pci_read_config_word(p_pci_dev, PCI_DEVICE_ID, &id);
printk(KERN_INFO "\n----------------------------------\n");
printk(KERN_INFO "Device vendor: 0x%X\nDevice id: 0x%X\n", vendor, id);
cdma_start = pci_resource_start(p_pci_dev,CDMA_BAR);
cdma_len = pci_resource_len(p_pci_dev,CDMA_BAR);
pci_start = pci_resource_start(p_pci_dev,PCI_BAR);
pci_len = pci_resource_len(p_pci_dev,PCI_BAR);
ddr_start = pci_resource_start(p_pci_dev,DDR_BAR);
ddr_len = pci_resource_len(p_pci_dev,DDR_BAR);
if(pci_set_dma_mask(p_pci_dev, DMA_BIT_MASK(64)))
{
printk(KERN_INFO "pci_set_dma_mask error.\n");
return -1;
}
if((dmabuf=dma_alloc_coherent(&p_pci_dev->dev,8192,&dma_handle,GFP_USER)) == NULL)
{
printk(KERN_INFO "dma_alloc_coherent error.\n");
return -1;
}
if(pci_request_regions(p_pci_dev, DEVICE_NAME))
{
printk(KERN_INFO "pci_request_regions error.\n");
return -1;
}
pci_set_master(p_pci_dev);
if((cdma_reg_mem = ioremap(cdma_start,cdma_len)) == NULL)
{
printk(KERN_INFO "ioremap pci_reg_mem error.\n");
return -1;
}
if((pci_reg_mem = ioremap(pci_start,pci_len)) == NULL)
{
printk(KERN_INFO "ioremap pci_reg_mem error.\n");
return -1;
}
if((ddr_mem = ioremap(ddr_start,ddr_len)) == NULL)
{
printk(KERN_INFO "ioremap pci_reg_mem error.\n");
return -1;
}
// filling test array by const
dma_sync_single_for_cpu(&p_pci_dev->dev, dma_handle, 8192, DMA_TO_DEVICE);
for(i = 0; i < 256; i++)
{
*(u32*)(dmabuf + i)= 0xABCDEF89;
}
dma_sync_single_for_device(&p_pci_dev->dev, dma_handle, 8192, DMA_TO_DEVICE);
// filling device pcie regs by phys host memory
// upper half of address to 0x208
pci_reg_mem[0x208/4]=(dma_handle >> 32);
// lower half to 0x20c
pci_reg_mem[0x20c/4]=(dma_handle & 0xFFFFFFFF);
// filling cdma regs
cdma_reg_mem[0x18/4]=0x30000000;
cdma_reg_mem[0x20/4]=0x80000000;
cdma_reg_mem[0x28/4]=256;
// checking received data
for(i = 0; i < 240; i++)
{
printk(KERN_INFO "%d. DDR %X vs ADDR %X\n",i,ddr_mem[i], *(u8*) (dmabuf + i));
}
printk(KERN_INFO "dma %llX\n",dma_handle);
printk(KERN_INFO "AXIU %X\n",pci_reg_mem[0x208/4]);
printk(KERN_INFO "AXIL %X\n",pci_reg_mem[0x20C/4]);
printk(KERN_INFO "SA %X\n",cdma_reg_mem[0x18/4]);
printk(KERN_INFO "DA %X\n",cdma_reg_mem[0x20/4]);
printk(KERN_INFO "SR %X\n",cdma_reg_mem[0x4/4]);
cdma_reg_mem[0x4/4] = 0x1000;
iounmap(pci_reg_mem);
iounmap(cdma_reg_mem);
iounmap(ddr_mem);
pci_release_regions(p_pci_dev);
pci_disable_device(p_pci_dev);
dma_free_coherent(&p_pci_dev->dev, 8192, dmabuf, dma_handle);
return 0;
}
Thank you in advance!
Last edited by drakonof; 04-27-2020 at 02:37 PM.
|
|
|
05-12-2020, 08:49 AM
|
#2
|
LQ Guru
Registered: Jan 2006
Location: Ireland
Distribution: Slackware, Slarm64 & Android
Posts: 17,543
|
Quote:
Originally Posted by drakonof
I am trying send data through PCIe + DMA. But I cannot fill sending array correctly. The data which I send from a host are received not which that I expect.
|
That's like the "Sad Mac" that came on early Macintoshes or the 'something went wrong' errors you see. NO information.
And now you've got 402 views, and no replies That tells you something about your question.
There's gdb and strace, both debugging programs for software guys. Have you used them? Let's see meaningful output. There's core dumps if things crash. There's error numbers that mean something if things exit. We don't even know what box/distro/kernel you're on. What have your investigations narrowed it down to? If you haven't put time into it, why should we?
|
|
|
All times are GMT -5. The time now is 11:42 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|