PYNQ: PYTHON PRODUCTIVITY

Confilicting DDR memory overwrite

I have set up a system like the following diagram. I have developed custom VHDL code to control DMA axi slave and read-write to specific addresses (I have tested it without vdma connecting to it and it’s working fine). I have changed the address editor as shown (attached the image).

The program runs sometimes without any error, but most of the time it’s shows different errors like segment fault, bus error, a lot of other errors. I suppose it’s happening because the Linux kernel wants to write in the same space in the DDR. What could be done to restrict the DDR region not to be accessed by Linux?

Sample errors:
Segment fault
Bus error

 Successfully loaded edid.
[ 1292.088673] Unable to handle kernel paging request at virtual address 000f71cd000f71e4
[ 1292.096588] Mem abort info:
[ 1292.099371]   ESR = 0x96000004
[ 1292.102410]   EC = 0x25: DABT (current EL), IL = 32 bits
[ 1292.107704]   SET = 0, FnV = 0
[ 1292.110742]   EA = 0, S1PTW = 0
[ 1292.113866] Data abort info:
[ 1292.116731]   ISV = 0, ISS = 0x00000004
[ 1292.120550]   CM = 0, WnR = 0
[ 1292.123502] [000f71cd000f71e4] address between user and kernel address ranges
[ 1292.130621] Internal error: Oops: 96000004 [#1] SMP
[ 1292.135480] Modules linked in: zocl(O) uio_pdrv_genirq
[ 1292.140615] CPU: 1 PID: 1498 Comm: python3 Tainted: G           O      5.4.0-xilinx-v2020.1 #1
[ 1292.149212] Hardware name: ZynqMP ZCU104 RevC (DT)
[ 1292.153988] pstate: 80000085 (Nzcv daIf -PAN -UAO)
[ 1292.158768] pc : timerqueue_add+0x44/0xc0
[ 1292.162766] lr : __hrtimer_run_queues+0x1cc/0x1e8
[ 1292.167457] sp : ffffffc01000be20
[ 1292.170755] x29: ffffffc01000be20 x28: ffffff805fa91430
[ 1292.176050] x27: 0000000000000004 x26: 0000000000000060
[ 1292.181344] x25: 0000000000000080 x24: 0000012cd6355666
[ 1292.186639] x23: ffffff805fa90f00 x22: 0000000000000000
[ 1292.191934] x21: 0000000000000001 x20: ffffff805fa90f00
[ 1292.197229] x19: 0000000000000001 x18: 0000000000000000
[ 1292.202524] x17: 0000000000000000 x16: 0000000000000000
[ 1292.207818] x15: 0000000000000000 x14: 0000000000000000
[ 1292.213113] x13: 0000000000000000 x12: 0000000000000001
[ 1292.218408] x11: 0000000000000000 x10: 00000000000003ba
[ 1292.223703] x9 : 00000000024b7314 x8 : 0000012cd6353500
[ 1292.228998] x7 : 7fffffffffffffff x6 : 0000012cd6723e00
[ 1292.234292] x5 : ffffff805fa91430 x4 : ffffffc012973c30
[ 1292.239587] x3 : 000f71cd000f71cc x2 : 000f71cd000f71cc
[ 1292.244882] x1 : ffffff805fa90f60 x0 : ffffff805fa91430
[ 1292.250177] Call trace:
[ 1292.252611]  timerqueue_add+0x44/0xc0
[ 1292.256263]  __hrtimer_run_queues+0x1cc/0x1e8
[ 1292.260604]  hrtimer_interrupt+0x110/0x2c0
[ 1292.264685]  arch_timer_handler_phys+0x30/0x40
[ 1292.269120]  handle_percpu_devid_irq+0x80/0x140
[ 1292.273642]  generic_handle_irq+0x24/0x38
[ 1292.277634]  __handle_domain_irq+0x60/0xb8
[ 1292.281714]  gic_handle_irq+0x5c/0xb8
[ 1292.285359]  el0_irq_naked+0x4c/0x54
[ 1292.288921] Code: f9400843 91004044 b4000123 aa0303e2 (f9400c43)
[ 1292.295003] ---[ end trace c5b4ba53c8754cad ]---
[ 1292.299603] Kernel panic - not syncing: Fatal exception in interrupt
[ 1292.305941] SMP: stopping secondary CPUs
[ 1292.309856] Kernel Offset: disabled
[ 1292.313334] CPU features: 0x0002,20002004
[ 1292.317325] Memory Limit: none
[ 1292.320367] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

Any help would be really appreciated.

You need to Allocate DRAM that you want to use from the PL.
The OS is using virtual memory, but the PL is accessing the physical memory. PYNQ allocate allows you to allocate memory and also get the physical address for the memory that can be used from the PL.

PYNQ DMA example with allocate

Cathal

2 Likes

It is working completely okay (MIPI → Demosaicing → VDMA → PS → DP).

vdma = overlay.pass_stream.pass_dma
vdma.readchannel.mode= frameMode
displayport = DisplayPort()
displayport.configure(frameMode, PIXEL_RGB)
vdma.readchannel.start()
while(1): 
            frame = vdma.readchannel.readframe()
            outframe = displayport.newframe()
            outframe[:] = frame
            displayport.writeframe(outframe)

Also my custom controller with separate DMA is working okay (MIPI-> DMA (controlled by custom code) → Demosaic → ILA)
When I combine both of those the problem occurs.

I used allocate function when I was using dma. But after switching to VDMA, i haven’t used it. Can you specify where and how i should use allocate function for VDMA?

Now i have added some ila in every place and it is not even running at all, showing this error:

Successfully loaded edid.
[   75.830753] fpga_manager fpga0: Error while writing image data to FPGA
[   76.371730] fpga_manager fpga0: Error while writing image data to FPGA
OSError: [Errno 22] Invalid argument

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "vdma.py", line 29, in <module>
    overlay = Overlay(a)
  File "/home/xilinx/pynq/overlay.py", line 355, in __init__
    self.download()
  File "/home/xilinx/pynq/overlay.py", line 419, in download
    super().download(self.parser)
  File "/home/xilinx/pynq/bitstream.py", line 187, in download
    self.device.download(self, parser)
  File "/home/xilinx/pynq/pl_server/device.py", line 770, in download
    fd.write(bitstream.binfile_name)
OSError: [Errno 22] Invalid argument