Posts: 11
Joined: Sun Aug 17, 2014 9:48 pm

Fix for SimonJHall's Q3 ARM Driver

Wed Sep 10, 2014 6:07 pm

I have been attempting to get SimonJHall's quake 3 build using the ARM side V3D drivers working. I am cross compiling but broadly following the instructions from here: ... -a-winner/

(TL;DR: Had to fix some of the code, explanation follows see bottom of post for change I made to make it work)

After getting the cross compilation working quake 3 was still not working. It started up and you could hear the intro movie sound and press arrow keys to hear the menu sounds as you moved around it but the display was just a straight gradient pattern. I enabled the debug output of the dmaer module and you could see that V3D was receiving jobs and happily processing things just nothing was appearing on the screen.

Eventually I tracked down the problem to init_dispmanx in dispman_connection.c. This sends mailbox messages to the GPU to allocate a framebuffer. At the end of the file it mmaps physical memory to write 0xFF to the framebuffer memory. There is a comment saying that we need to touch all the pixels before anything appears on screen.

Given I saw a gradient pattern rather than a white screen it looked like this final bit of code wasn't doing anything, looking at the address it was using it had received an address 0xd8402260 from the GPU for the framebuffer and writing directly to that. This was a bit suspicious as it looks like a bus address rather than an ARM physical address. I added an & ~0xC0000000 to turn it into an ARM physical address and now everything works (see an initial white screen as expected and then Q3 actually displays).

My question is why did this work in the first place? Has there been a recent firmware change? Perhaps that mailbox message which allocates the buffer used to return ARM physical addresses rather than bus addresses?


Line 225 of dispman_connection.c should be changed from

Code: Select all

unsigned int pa = ((unsigned int)gRectVars.buffers[0].m_pMemory);

Code: Select all

unsigned int pa = ((unsigned int)gRectVars.buffers[0].m_pMemory) & ~0xC0000000;

Posts: 11
Joined: Sun Aug 17, 2014 9:48 pm

Re: Fix for SimonJHall's Q3 ARM Driver

Wed Sep 10, 2014 11:06 pm

Turns out I was wrong about the source of the error.

What was actually happening is gcc appears to be optimising out the memset used to clear the framebuffer to 0xFF. The first time I altered the physical address being written to I had also disabled optimisation.

I couldn't find an obvious way to stop gcc from doing this without disabling optimisation. So I did a build that had that specific file built without optimisation and everything else with. That seemed to do the trick.

Out of interest both the original version of the framebuffer physical address and the one post modification (the & ~0xC0000000) seem to work. It's being accessed via /dev/mem so maybe that wraps addresses around at the 0x40000000 boundary?

It's odd that this is needed in the first place as well. Would be nice to know why.

Return to “Advanced users”