DMA to RAM buffer

Hello,

I allocated a contiguous physical buffer with the attached code.
The physical address of this buffer is written to a register in the FPGA
The FPGA initiates a DMA of data from its internal FIFO to the RAM.

In the first DMA, the data in RAM is OK. But starting from the next DMAs, the data is not changed.
I suspect that the buffer is in cache so I’m not reading the actual new data.

According to: https://community.osr.com/discussion/comment/289920#Comment_289920
x86 has snooping. Am I right ?

If not, is it possible to invalidate a specified region in user space ?

Thank you,
Zvika

Hello,

According to: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdfcommonbuffer/nf-wdfcommonbuffer-wdfcommonbuffercreate

“The operating system determines whether to enable cached memory in the common buffer that is to be allocated. That decision is based on the processor architecture and device bus.
On computers with x86-based, x64-based, and Itanium-based processors, cached memory is enabled”

Thank you,
Zvika

Mostly nobody is going to download anything, so if you want people to look at your code either paste it directly into your message or put it up on github. Cache coherency is not your problem.

You can’t use the Physical Address for DMA. Are you using the WDF DMA APIs or not?

Peter

Hello,

The code I’m using to allocate a contiguous common buffer is:


WDF_DMA_ENABLER_CONFIG_INIT(&dmaConfig,
	WdfDmaProfilePacket64,
	COMMON_BUFFER_SIZE);

status = WdfDmaEnablerCreate(devExt->Device,
	&dmaConfig,
	WDF_NO_OBJECT_ATTRIBUTES,
	&devExt->DmaEnabler);
if (!NT_SUCCESS(status))
{
	KdPrint(("WdfDmaEnblerCreate failed: %08X\n", status));
	return status;
}

status = WdfCommonBufferCreate(devExt->DmaEnabler,
	COMMON_BUFFER_SIZE,
	WDF_NO_OBJECT_ATTRIBUTES,
	&devExt->CommonBuffer);

if (!NT_SUCCESS(status))
{
	KdPrint(("WdfCommonBufferCreate failed: %08X\n", status));
	return status;
}

devExt->KernelCommonBuffer = WdfCommonBufferGetAlignedVirtualAddress(devExt->CommonBuffer);
devExt->PhysicalKernelCommonBuffer = WdfCommonBufferGetAlignedLogicalAddress(devExt->CommonBuffer);

devExt->PhysicalKernelCommonBuffer is set to an FPGA register which is the destination for DMA.

I’m not using WDF DMA API. The FPGA does not support scatter-gather DMA.

Thank you,
Zvika

Yes, you most certainly are using the WDF DMA API. See those calls you’re making that start WdfDma? And you’re using the device bus logical address of the buffer… it the physical address.

Now that we understand what you’re doing… I don’t see any reason why subsequent DMAs to the same device bus logical address wouldn’t work.

Peter

Is it possible your FPGA is automatically advancing to the next page in memory? Are you writing all of the registers again before triggering the next write?

Hello Mark, Peter, Tim,

The data error problem was caused by a BUG in the application.
The destination RAM address was not properly advanced.
Thank you very much for your help !
As Mark wrote, cache coherency is not handled by driver\application.

Best regards,
Zvika