DawidPi
Posts: 8
Joined: Fri May 13, 2016 11:18 am

Translate uniformly physical adress to the BUS adress - DMA

Fri May 13, 2016 11:36 am

Hello I need to use DMA for communication with GPU.

Basically I have:
-> myOwn buffer, where I am painting things in some place in memory let's call it myBufferPtr
-> GPU physical memory used for drawing things on the screen. Let's call it GPUBufferPtr

as I do not know what address will be returned from GPU I need to have some sort of function, that uniformly translates
physical addresses to the BUS addresses, which I need for DMA usage.

Unfortunatelly I could not find any uniform map, that says us what is mapped where. Documentation is clear only for parts of memory (eg. only peripherals part of memory)

Question is how can I do mapping from one address to the another?

Thanks in advance :)

User avatar
Ultibo
Posts: 160
Joined: Wed Sep 30, 2015 10:29 am
Location: Australia
Contact: Website

Re: Translate uniformly physical adress to the BUS adress -

Sat May 14, 2016 2:50 am

Hi,
I'm assuming that you are allocating a framebuffer by using the GPU mailbox functions and the GPUBufferPtr in your example is the value returned from that call.

To use DMA to copy from memory to the framebuffer both the source and destination address need to be BUS addresses.

On the Pi there are 4 regions of addressable memory that are 1GB each which start at 0x00000000, 0x40000000, 0x80000000 and 0xC0000000. Because the Pi can only have 1GB of physical memory your code should always address physical memory in the 0x00000000 region but you need to translate that to a different region for the GPU, DMA and others.

On the Pi2 and 3 it seems best to use the region 0xC0000000 for the BUS addresses, to convert from a physical address to a BUS address simply OR the values:

Code: Select all

 DMASourcePtr = myBufferPtr or 0xC0000000
 DMADestPtr = GPUBufferPtr or 0xC0000000
To convert from a BUS address to a physical address you AND NOT the values:

Code: Select all

 myBufferPtr = DMASourcePtr and not(0xC0000000)
I hope this makes sense, for reference the GPU normally returns a BUS address for the framebuffer which you need to convert to a physical address for your code, but would be suitable to pass directly to DMA.
Ultibo.org | Make something amazing
https://ultibo.org

Threads, multi-core, OpenGL, Camera, FAT, NTFS, TCP/IP, USB and more in 3MB with 2 second boot!

DawidPi
Posts: 8
Joined: Fri May 13, 2016 11:18 am

Re: Translate uniformly physical adress to the BUS adress -

Sat May 14, 2016 9:46 am

Hi, thanks for response.

Yes, I am using mailbox to get information about GPU memory, where I should write data. Although I must add 0x40000000 to this address, because otherwise even manual writes to this place does not work. by GpuBuffer I mean one returned from mailbox and added 0x40000000 adress that I get in result is 3D402000, so it's in neither memories you mentioned. Raw mailbox message returns me: FD402000. I have no idea why I have to add this value, but I found, that someone had simillar problem and it was a solution. So, generally when I write to 3D402000 manually everything is fine and is displayed on the screen.

So I understand, that I should or 3D402000 with 0xC0000000, because making or with F... will make no difference?
Also, should Control Block's pointer should be given there as or'ed value or not?

User avatar
Ultibo
Posts: 160
Joined: Wed Sep 30, 2015 10:29 am
Location: Australia
Contact: Website

Re: Translate uniformly physical adress to the BUS adress -

Sun May 15, 2016 2:28 am

Hi,

What you are seeing is just a trick of 32 bit binary arithmetic. The GPU returns you the address 0xFD402000 which is a BUS address in the region 0xC0000000 (0xC0000000 to 0xFFFFFFFF) and you can do this

0xFD402000 + 0x40000000 = 0x3D402000

or this

0xFD402000 and not(0xC0000000) = 0x3D402000

to get the physical address for writing to. Both give the same answer but the second one is better because it will always work even if you use a 64 bit value.
Also, should Control Block's pointer should be given there as or'ed value or not
Yes, the Control Block addresses passed to DMA need to be BUS addresses too.
Ultibo.org | Make something amazing
https://ultibo.org

Threads, multi-core, OpenGL, Camera, FAT, NTFS, TCP/IP, USB and more in 3MB with 2 second boot!

DawidPi
Posts: 8
Joined: Fri May 13, 2016 11:18 am

Re: Translate uniformly physical adress to the BUS adress -

Sun May 15, 2016 11:39 am

Ah ok, now I see it :)

Thank you a lot :)

Return to “Bare metal, Assembly language”