Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

ACP port under Linux

Altera_Forum
Honored Contributor II
3,179 Views

Hi, 

 

Is there any trick to using the ACP port from FPGA under Linux (3.9)? I'm setting the f2h AR & AW CACHE/PROT/USER by hand, post-qsys, but don't see any indication that the SCU cares at all about the address I send on f2h_axi_slave and reads go to SDRAM instead of L1 or L2 cache. 

 

Thanks
0 Kudos
23 Replies
Altera_Forum
Honored Contributor II
1,433 Views

The answer turned out to be surprisingly simple. Make sure the physical address passed by the driver to the FPGA accelerator is "| 0x80000000". This puts the address in the ACP range. Otherwise, the address bypasses the SCU.  

 

This also allows one to test performance with and without the ACP by simply changing the address at runtime. 

 

Thanks to LegUp for the solution: http://janders.eecg.toronto.edu/pdfs/euc14.pdf 

 

Note: cache attributes set by hand in the top level HDL after Qsys compile are: 

 

.f2h_ARCACHE (4'hf) 

.f2h_ARPROT (3'h0) 

.f2h_ARUSER (5'h1f) 

 

.f2h_AWCACHE (4'hf) 

.f2h_AWPROT (3'h0) 

.f2h_AWUSER (5'h1f) 

 

ACDS is 14.0.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

The answer turned out to be surprisingly simple. Make sure the physical address passed by the driver to the FPGA accelerator is "| 0x80000000". This puts the address in the ACP range. Otherwise, the address bypasses the SCU.  

 

This also allows one to test performance with and without the ACP by simply changing the address at runtime. 

 

Thanks to LegUp for the solution: http://janders.eecg.toronto.edu/pdfs/euc14.pdf 

 

Note: cache attributes set by hand in the top level HDL after Qsys compile are: 

 

.f2h_ARCACHE (4'hf) 

.f2h_ARPROT (3'h0) 

.f2h_ARUSER (5'h1f) 

 

.f2h_AWCACHE (4'hf) 

.f2h_AWPROT (3'h0) 

.f2h_AWUSER (5'h1f) 

 

ACDS is 14.0. 

--- Quote End ---  

 

 

 

Hi Sir, 

 

I am trying to interface a program executed from linux to a FPGA master, I need to use the ACP port, I changed the cache attributes as you said. 

But What I am not sure is what physical address to map in map linux program or what address send to the FPGA master I have developed. 

 

I will appreciate any help you can give me! 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Hi Sir, I am trying to interface a linux program to a FPGA master using the ACP port, what address do I need to use to ensure read and writes go through the ACP port? 

Actually I am not familiar with using the ACP port at all, if you can give me some guide, I will appreciate it. 

I configured the AXI port cache settings as you said. Any example or reference where I can find information related to it. 

 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

Hi Sir, I am trying to interface a linux program to a FPGA master using the ACP port, what address do I need to use to ensure read and writes go through the ACP port? 

Actually I am not familiar with using the ACP port at all, if you can give me some guide, I will appreciate it. 

I configured the AXI port cache settings as you said. Any example or reference where I can find information related to it. 

 

Thanks. 

--- Quote End ---  

 

 

Hi norxander,  

 

For access to ACP port, my driver code looks like (literally):  

 

dma->csr[2] = c->dma_currimage.write_buf_phys_addr | 0x80000000; 

 

The bit-wise OR was the only trick.  

 

However, I found the ACP speed slow and I gave up on ACP port and used the much faster FPGA-SDRAM ports. 

I've heard rumors that ACP port has a design flaw that will be fixed. My notes apply to Cyclone 5 SoC 5CSXFC6D6F31C8ES and you'll find best performance there by using the FPGA-SDRAM ports and using driver calls dma_sync_single_for_device/cpu on buffers shared between FPGA and CPU. 

 

Best wishes
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Thanks for you quick reply Sir. 

 

Now, why did you say the FPGA-SDRAM port is faster than ACP port, I have read that by using the ACP port you can get data that is cached, so you don't have to read/write data to the DDR SDRAM in some cases. 

I am using the DE1-SoC board. 

If by using the FPGA-SDRAM ports I will get better performance, can you explain me how to use the dma_sync_single_for_device/cpu functions. 

I am working of a project where I have a user application which will send some information to the FPGA module I have developed (some like a DMA module, but it doesn't move data in the way *dest++ = *src++), so how can I allocate physical memory that I can share between the FPGA and CPU? and what it the use of the dma_sync... functions?
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

Now, why did you say the FPGA-SDRAM port is faster than ACP port, I have read that by using the ACP port you can get data that is cached, so you don't have to read/write data to the DDR SDRAM in some cases. 

--- Quote End ---  

 

 

 

If you're using Xilinx Zynq, that might be true. But the Altera SoC ACP architecture ends up being slower in my experience than just using dma_sync functions with FPGA-SDRAM. This is an architecture flaw I believe that might be fixed in future updates to the SoC architecture. 

 

 

 

--- Quote Start ---  

If by using the FPGA-SDRAM ports I will get better performance, can you explain me how to use the dma_sync_single_for_device/cpu functions. 

I am working of a project where I have a user application which will send some information to the FPGA module I have developed (some like a DMA module, but it doesn't move data in the way *dest++ = *src++), so how can I allocate physical memory that I can share between the FPGA and CPU? and what it the use of the dma_sync... functions?  

--- Quote End ---  

 

 

 

Check out https://gnuradio.org/redmine/projects/gnuradio/wiki/zynq for some general resources for this idea. I used https://github.com/jpendlum/user-peripheral-kmod as the basis for my kernel driver for a similar device. It allocates shared buffers between CPU and FPGA peripheral with no special cache management and also has extension for the Zynq ACP. 

 

 

Basically I extended the user peripheral code above which bypasses cache when the mmap procedure identifies memory as pgprot_noncached: 

 

 

static int user_peripheral_mmap(struct file *filp, struct vm_area_struct *vma) { struct user_peripheral_drvdata *d = to_drvdata(filp->private_data); if (vma->vm_pgoff == MMAP_REGS) { vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (remap_pfn_range(vma, vma->vm_start, d->regs_phys_addr >> PAGE_SHIFT, d->regs_len, vma->vm_page_prot)) return -EIO; ...  

 

 

When application code calls mmap(), the above driver call is used to link between application process memory space and kernel memory. And the driver has already allocated kernel memory that will be also read/written by the FPGA device. 

 

 

For my cached buffers, I skip the call to pgprot_noncached so that memory is cached as needed and then create ioctl stub in the driver: 

 

 

static long my_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ struct my_drvdata *d = to_drvdata(filp->private_data); if(arg < 0 || arg >= MAX_BUFFERS){ dev_err(&d->pdev->dev, "Improper argument %lu.\n", arg); return -1; } switch(cmd){ case MY_SYNC_DEVICE: //device now owns buffer to read dma_sync_single_for_device(&d->pdev->dev, d->my_buf.buf_phys_addr, d->myfx_buf.buf_len, DMA_TO_DEVICE); break; case MY_SYNC_CPU: //cpu now owns buffer to read dma_sync_single_for_cpu(&d->pdev->dev, d->my_buf.buf_phys_addr, d->my_buf.buf_len, DMA_FROM_DEVICE); break; default: dev_err(&d->pdev->dev, "Improper ioctl command %d.\n", cmd); return -1; } return 0; }  

 

 

Now in my application code I can use ioctl to do cache flushing or invalidation. 

 

 

// make sure cache is flushed, FPGA device reads from buf_no ioctl(c->fd, MY_SYNC_DEVICE, buf_no); //now FPGA can process buf_no and write back // when FPGA finishes, invalidate the cache, CPU will now load memory into // cache as needed. ioctl(c->fd, MY_SYNC_CPU, buf_no);
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Thanks for all that information, I will apply it to my project. 

I am using this project: https://github.com/bvlc/caffe 

The idea is that the FPGA module performs what the im2col function does (https://github.com/bvlc/caffe/blob/master/src/caffe/util/im2col.cpp), translate an input image into a vector so later it can be used to perform some basic matrix operation. 

I found that the input data (const Dtype* data_im) is some RAM allocated using malloc (CaffeMallocHost() in caffe, https://github.com/bvlc/caffe/blob/master/include/caffe/syncedmem.hpp), so the idea is to change the CaffeMallocHost function to allocate memory which can be used later by the FPGA module to perform the im2col custom function, so I will need the physical address of that buffer already allocated by CaffeMallocHost(). 

 

I read that the dma_sync_single_for_device/cpu is required to sync the data, i.e., flush and invalidate the data cache, so the data is up to date when the CPU or DMA need to handle it. 

 

So the function user_peripheral_mmap gets called when the mmap is called from the user space application? If so, what is the physical address we need to pass to the mmap function in the user app? 

Also in the github link you provided to me, there is a file named as devicetree.template, what is the meaning of "reg = <0x40000000 0x20000>", The DE1-SoC has 1GB DDR3 SDRAM. 

can you provide to me a sample code for a user app trying to allocate memory using the approach you are giving me please. 

 

Thanks for all you time yxi95! I appreciate it!
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

BTW, I should mention that rocketboards.org has a lot of project examples and forums for the SoC boards, check out http://rocketboards.org/foswiki/view/projects, there might be something newer than my suggestions that is closer to your target. And http://forum.rocketboards.org/ of course has a lot of discussion on these topics. 

 

 

 

--- Quote Start ---  

 

So the function user_peripheral_mmap gets called when the mmap is called from the user space application? If so, what is the physical address we need to pass to the mmap function in the user app? 

 

--- Quote End ---  

 

 

 

None, just NULL. The offset passed to mmap is being used as a flag for the driver. Here's how the user space application calls it: 

 

d->csr = (unsigned int *) mmap(NULL, d->csr_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, MMAP_REGS); if(d->csr == MAP_FAILED){ perror("Error mapping buffer"); return 0; }  

 

 

--- Quote Start ---  

 

Also in the github link you provided to me, there is a file named as devicetree.template, what is the meaning of "reg = <0x40000000 0x20000>", The DE1-SoC has 1GB DDR3 SDRAM. 

 

--- Quote End ---  

 

 

 

The first is address (0x40000000), the second is length (0x20000), but you shouldn't have to actually edit the devicetree, the SoC Embedded Suite (https://dl.altera.com/soceds/) should have everything you need. You can use the defaults set up for the right device, i.e. something like embedded/examples/hardware/cv_soc_devkit_ghrd. Rocketboards.org has good defaults for most boards, you might want to check there first if you haven't yet. 

 

 

 

--- Quote Start ---  

 

can you provide to me a sample code for a user app trying to allocate memory using the approach you are giving me please. 

 

--- Quote End ---  

 

 

 

The user-periph driver and app code above assumes the kernel allocates the buffers and the application uses mmap to get the buffers. The application can then pass that buffer pointer around to any algorithm to write to it, make sure the buffer is synced to the device (ioctl), signal the FPGA by writing control registers, wait for completion, make sure the buffer is synced to the CPU (ioctl) and then read the FPGA-computed result right out of the same pointer. That's one approach. So the user app isn't allocating memory, in this approach, but rather borrowing kernel driver buffers which have shared access between CPU and FPGA. 

 

 

But also check out the rocketboards.org projects because there might be newer source code and methods for accelerators than what I describe here.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Hello again, 

 

Thanks for the references, I took a look at the pages and I ended up on using the zynq reference, I have the driver already developed for my FPGA module, a lot of thing I learned coding and configuring the environment. :)  

 

Just one more question, you said that you are using the ioctl calls to sync the buffer when the FPGA is going to handle the data, but according to the driver the buffer is not being cached, am I wrong on that? 

I see in the driver code the call to pgprot_noncached and in the user application the MAP_SHARED flag when mapping the buffer. 

 

I noticed that in your code (d->my_buf[arg]) you are using an array of buffers, is that correct? then how are you managing the map requests from multiple map calls? 

 

Also, I have a requested the linux system to only take 850M of my DDR3 SRAM (1G total), so I need in the kernel driver to allocate the last 150M of mem to be used as the buffer, how can I allocate that memory so I can then remap this area later to the user application? And still have the physical address reference there to be used by the FPGA transactions. 

 

Thanks in advance for all your support!
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

 

Just one more question, you said that you are using the ioctl calls to sync the buffer when the FPGA is going to handle the data, but according to the driver the buffer is not being cached, am I wrong on that? 

I see in the driver code the call to pgprot_noncached and in the user application the MAP_SHARED flag when mapping the buffer. 

 

--- Quote End ---  

 

 

 

This driver? https://github.com/jpendlum/user-peripheral-kmod/blob/master/user_peripheral.c 

 

 

It looks to me like they only do pgprot_noncached for the control registers MMAP_REGS. The buffers MMAP_BUFFS are default which would be cached. If the ACP port is used, everything is fine. But if not, dma_sync_single calls would be needed. 

 

 

 

--- Quote Start ---  

 

I noticed that in your code (d->my_buf[arg]) you are using an array of buffers, is that correct? then how are you managing the map requests from multiple map calls? 

 

--- Quote End ---  

 

 

 

I'm following the scheme used by the above driver which treats a page offset like a flag, maybe a little kludgy. The driver uses 

 

 

# define MMAP_REGS 0x1# define MMAP_BUFFS 0x2  

 

 

And the application does (https://github.com/jpendlum/zynq-fir-filter-example/blob/master/zynq_fir_filter_example.c

 

 

*control_regs = (unsigned int*)mmap(NULL, *control_length, PROT_READ|PROT_WRITE, MAP_SHARED, *fd, 0x1000); //corresponds to MMAP_REGS if (control_regs == MAP_FAILED) { perror("Error mapping control_regs"); close(*fd); return(-1); } *buff = (unsigned int*)mmap(NULL, *buffer_length, PROT_READ|PROT_WRITE, MAP_SHARED, *fd, 0x2000); //corresponds to MMAP_BUFFS if (buff == MAP_FAILED) { perror("Error mapping buff"); close(*fd); return(-1); }  

 

 

 

 

 

--- Quote Start ---  

 

Also, I have a requested the linux system to only take 850M of my DDR3 SRAM (1G total), so I need in the kernel driver to allocate the last 150M of mem to be used as the buffer, how can I allocate that memory so I can then remap this area later to the user application? And still have the physical address reference there to be used by the FPGA transactions. 

 

--- Quote End ---  

 

 

 

Hmm... I've always allocated all the memory available to the linux system so the kernel has access to all of it. That way, I can allocate as much or as little buffer space in the driver as needed. I'm not sure how to keep memory off-limits to the kernel but still accessible to drivers, is it possible? Sorry, not sure. 

 

 

Best,
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Hi, 

 

I am trying to use the functions to sync the memory buffer so the FPGA can handle the data, but I am getting a segmentation fault when calling the dma_sync_single_for_device function, so I wonder if I am using the wrong parameters, 

what is the dma_addr_t dma_handle parameter? is it the physical address? or the virtual address after the mem allocation? I read that the dma_addr_t is not the same as the physical address, or am I missing something before calling the functions, something like doing a dma map before? 

 

switch(cmd){ case MY_SYNC_DEVICE: //device now owns buffer to read dma_sync_single_for_device(&d->pdev->dev, d->my_buf.buf_phys_addr, d->myfx_buf.buf_len, DMA_TO_DEVICE); break; case MY_SYNC_CPU: //cpu now owns buffer to read dma_sync_single_for_cpu(&d->pdev->dev, d->my_buf.buf_phys_addr, d->my_buf.buf_len, DMA_FROM_DEVICE); break; default: dev_err(&d->pdev->dev, "Improper ioctl command %d.\n", cmd); return -1; }  

 

 

--- Quote Start ---  

 

Hmm... I've always allocated all the memory available to the linux system so the kernel has access to all of it. That way, I can allocate as much or as little buffer space in the driver as needed. I'm not sure how to keep memory off-limits to the kernel but still accessible to drivers, is it possible? Sorry, not sure. 

 

--- Quote End ---  

 

 

What I did was to boot the kernel with the argument mem=896M, so the kernel can only see that memory, then in the kernel module I request access to missing memory by using the request_mem_region function, then from the user app I call the mmap to actual remap the physical region from the kernel to the user app space by using the remap_pfn_range function, so if I call the dma_sync_single_for_device function with the physical start address of that region I get the segmentation fault. 

 

Any advice on how to handle the reserved memory from the booting process, or the reason on getting the segmentation fault? 

 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Hello again, 

 

I will try to allocate some memory in the same way the example you provided using the link https://github.com/jpendlum/user-peripheral-kmod/blob/master/user_peripheral.c

d->xx_buf = alloc_pages(GFP_ATOMIC, PAGE_ORDER);  

 

But from you code hint, 

d->my_buf.buf_phys_addr, d->myfx_buf.buf_len,  

 

I don't know what is my_buf, it seem for me an array of structs, so how were you getting the allocated memory? what is the relation between the virtual address you got from this and the variable buf_phys_addr? 

is the buf_phys_addr the physical address of a given start virtual address of a buffer or is it the dma address? 

 

If I would like to use the ACP port, I need to send to the FPGA module the physical address | 0x80000000, right? so how did you get the buffer's physical address you allocated? Using the same function page_to_phys? 

 

Just I would like to give a try on using the ACP because I was requested to use it and see if my implementation of the driver is working. 

Another thing would be, what is the address I need to use as a parameter for the function call dma_sync_single_for_device? 

 

Thanks!
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

 

I am trying to use the functions to sync the memory buffer so the FPGA can handle the data, but I am getting a segmentation fault when calling the dma_sync_single_for_device function, so I wonder if I am using the wrong parameters, 

what is the dma_addr_t dma_handle parameter? is it the physical address? or the virtual address after the mem allocation? I read that the dma_addr_t is not the same as the physical address, or am I missing something before calling the functions, something like doing a dma map before? 

 

--- Quote End ---  

 

 

 

Here's how my driver gets buf_phys_addr for dma_handle parameter: 

 

 

typedef struct _yx_buffer { struct page *buf; unsigned long buf_phys_addr; size_t buf_len; } Buffer; static int _allocBuffer(struct platform_device *pdev, Buffer *b, int page){ dma_addr_t dma; b->buf = alloc_pages(GFP_ATOMIC, page); if (!b->buf) { dev_err(&pdev->dev, "Error allocating buffer 2^%d pages of %lu\n", page, PAGE_SIZE); return -ENOMEM; } dma = dma_map_page(&pdev->dev, b->buf, 0, page, DMA_BIDIRECTIONAL); if(dma != page_to_phys(b->buf)){ dev_err(&pdev->dev, "BAD DMA ASSUMPTION: page address is %u, and dma is %u\n", page_to_phys(b->buf), dma); return -ENOMEM; } b->buf_phys_addr = page_to_phys(b->buf); b->buf_len = (1 << page) * PAGE_SIZE; dev_info(&pdev->dev, "allocBuffer, %lx at size %u bytes\n", b->buf_phys_addr, b->buf_len); return 0; }  

 

 

Also, if you're using ioctl control between app and driver, make sure you define it with the _IOR macro. I first made the mistake of using a simple number which collides with existing ioctl. 

 

 

# define SYNC_DEVICE _IOR(0xAF, 1, unsigned long)# define SYNC_CPU _IOR(0xAF, 2, unsigned long)  

 

 

On the memory mapping, I guess that should work but I don't have working experience with that arrangement. 

 

 

 

--- Quote Start ---  

 

If I would like to use the ACP port, I need to send to the FPGA module the physical address | 0x80000000, right? so how did you get the buffer's physical address you allocated? Using the same function page_to_phys? 

 

--- Quote End ---  

 

 

 

Yes, page_to_phys in the driver is where it is first assigned. The GnuRadio FPGA module approach I linked to earlier takes that address and creates a device attribute out of it which is then read by the user-space application using the udev library given the device tree node of the accelerator (which looks something like "ff203000.accel" on my system). 

 

 

Yes, definitely test using the ACP because that's simpler than the DMA scheme.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Hello yxi95, 

 

I successfully got the driver and the user application working using the dma approach you told me. 

I realized that the dma_addr I got by using the dma mapping was the same value as the physical address of the buffer I allocated using the alloc_pages, I think it is only applicable for my current architecture and its Linux. 

 

Yes, I ended up using the ioctl to sync the data between the CPU and the FPGA, I will apply your advice. 

I am not sure if taking some time to develop the ACP way will provide me something better than the current DMA approach you said you got something not so good when using the ACP port. 

How did you measure the performance comparison between using the ACP port and FPGA-SDRAM port? 

 

If I would use the ACP port, do I need to cast the buffer to an unsigned long long to manage the data in 64 bits format? is it required? My FPGA module has a 32 bits bus data. 

 

Also from the kernel driver I allocated 32 buffers (4MB each one by calling the alloc_pages function several times) to get a total of 128MB of contiguous physical memory, I am planning on making a custom malloc function (or memory pools) to provide dynamic memory allocation to a user application. Is there a different way to get +100MB of contiguous physical memory without calling the alloc_pages multiple times? Maybe another function? 

 

Thanks for your support!
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Hello again, 

 

I am trying to setup the ACP port, so I have some questions: 

1. Do I need to use the FPGA to HPS port instead the FPGA to SDRAM ports? 

2. Do I need to cast the buffer I allocated in the driver to a 'unsigned long long' to read/write data? is it required? 

3. Is it required to set the f2h_AR[AW]CACHE attributes as you said in the second post? 

4. After sending the command to perform the DMA task using the ACP port (phy_addr | 0x80000000) I got a "Kernel panic - not syncing", do you have a repository where I can take a look at the code of your driver when using the ACP? 

And the FPGA qsys system. 

Also this is the Linux I am using: Linux cyclone5 3.10.31-ltsi-altera# 1 SMP Thu Feb 11 22:06:58 UTC 2016 armv7l GNU/Linux and the DE1-SoC board. 

 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

 

How did you measure the performance comparison between using the ACP port and FPGA-SDRAM port? 

 

--- Quote End ---  

 

 

 

Running the clock at 150Mhz and seeing how much streaming data we could get over the bus from an mSGDMA. From my notes: ACP was 280MB/s, f2h_axi was 380MB/s, f2h_sdram was 564MB/s. 

 

 

 

--- Quote Start ---  

 

If I would use the ACP port, do I need to cast the buffer to an unsigned long long to manage the data in 64 bits format? is it required? My FPGA module has a 32 bits bus data. 

 

--- Quote End ---  

 

 

 

I think you'll get best performance with a 64-bit bus, but I don't think the datatype of the structure matters since all software accesses to memory will go through the optimized cache/memory-interfaces first. But if you do any kind of random access in the FPGA module (as opposed to streaming), though, that should probably be in 64-bit chunks and might turn out to be easier with the ACP port, but will of course be much slower than streaming. 

 

 

 

 

 

--- Quote Start ---  

 

I am trying to setup the ACP port, so I have some questions: 

1. Do I need to use the FPGA to HPS port instead the FPGA to SDRAM ports? 

 

--- Quote End ---  

 

 

 

Yes, only the FPGA to HPS works for ACP. f2h_axi on my qsys. 

 

 

 

--- Quote Start ---  

 

2. Do I need to cast the buffer I allocated in the driver to a 'unsigned long long' to read/write data? is it required? 

 

--- Quote End ---  

 

 

 

I don't see any need to per above. 

 

 

 

--- Quote Start ---  

 

3. Is it required to set the f2h_AR[AW]CACHE attributes as you said in the second post? 

 

--- Quote End ---  

 

 

 

Check if latest Qsys does this automatically now. But it might still be needed. 

 

 

 

--- Quote Start ---  

 

After sending the command to perform the DMA task using the ACP port (phy_addr | 0x80000000) I got a "Kernel panic - not syncing", do you have a repository where I can take a look at the code of your driver when using the ACP? 

 

--- Quote End ---  

 

 

 

Sorry, no, but I'm using configuration identical to GnuRadio. I do recall spending a lot of time getting the right boot-loader/device-tree/kernel/, any chance it is that? If so, try to get any kind of working system at all first so you can rule out these issues. Then, just add/subtract your HDL to this working system. When I started my project late 2014, I did everything from the SocKit Linaro Desktop at rocketboards, that was my golden model. I could add/delete software and hardware incrementally from that version and know immediately if I'd done something wrong.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

Thanks for your reply. 

 

I have a working system, using yocto I can build the bootloader, kernel image, device tree and the file system. Is the GnuRadio ACP port configuration similar for the Altera devices? 

I have configures the AXI port attributes as you said and also sending to the HDL module the physical address | 0x80000000, but I am getting a kernel panic after starting writing to that memory location, did you configure something for the ACP port before using it?
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

 

--- Quote Start ---  

 

I have configures the AXI port attributes as you said and also sending to the HDL module the physical address | 0x80000000, but I am getting a kernel panic after starting writing to that memory location, did you configure something for the ACP port before using it? 

 

--- Quote End ---  

 

 

 

Does it work without "| 0x80000000"? That bypasses the cache so needs non-cached memory (pgprot_noncached) but should work correctly. If you get kernel panic on both, it has to be a driver typo/issue. If it only happens on ACP, I don't know. The AXI port attributes were the only thing I needed to change for ACP, no software changes were needed other than the flag.
0 Kudos
Altera_Forum
Honored Contributor II
1,433 Views

The FPGA module I have developed has an Altera Avalon MM master which is connected to the AXI port FPGA2HPS, the port that your FPGA design has is an AXI or Avalon port?

0 Kudos
Altera_Forum
Honored Contributor II
1,349 Views

 

--- Quote Start ---  

The FPGA module I have developed has an Altera Avalon MM master which is connected to the AXI port FPGA2HPS, the port that your FPGA design has is an AXI or Avalon port? 

--- Quote End ---  

 

 

It's Avalon MM master too. At least one test case just used Altera's modular SGDMA connected to f2h_axi_slave.
0 Kudos
Reply