Having trouble getting a framebuffer


8 posts
by jawline » Tue Jan 08, 2013 6:42 pm
I have been trying to write some code which uses the mailbox to get a framebuffer and emulating it using qemu-system-arm with versitilePB (qemu-system-arm -kernel kernel.img -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio )

my code is as follows

framebuffer.c
Code: Select all
 #include "framebuffer.h"
#include "console.h"
#include <mailbox.h>
#include <stdint.h>

struct FramebufferRequest {
   uint32 width;
   uint32 height;
   uint32 vwidth;
   uint32 vheight;
   uint32 pitch;
   uint32 depth;
   uint32 x;
   uint32 y;
   uint32 pointer;
   uint32 size;
} FBRequest __attribute__((aligned(4)));

const unsigned int FramebufferMailboxChannel = 1;

void FramebufferInitialize() {

   ConsoleWrite("Constructing a framebuffer request\n");

   FBRequest.width = 800;
   FBRequest.height = 600;
   FBRequest.vwidth = 800;
   FBRequest.vheight = 600;
   FBRequest.pitch = 0;
   FBRequest.depth = 0;
   FBRequest.x = 0;
   FBRequest.y = 0;
   FBRequest.pointer = 0;
   FBRequest.size = 0;

   ConsoleWrite("Sending mailbox request\n");
   MailboxWrite(1, &FBRequest);

   ConsoleWrite("Reading mailbox response\n");
   uint32 response = MailboxRead(1);

   if (response != 0) {
      ConsoleWrite("Framebuffer failed to initialize\n");
   }
}


and mailbox.c
Code: Select all
#include "mailbox.h"
#include <console.h>

const static uint32* MailboxReadRegister = (unsigned int*) 0x2000B880;
const static uint32* MailboxWriteRegister = (unsigned int*) 0x2000B8A0;
const static uint32* MailboxStatusRegister = (unsigned int*) 0x2000B898;
const static uint32 MailFullFlag = 0x80000000;
const static uint32 MailEmptyFlag = 0x40000000;

uint32 MBReadRegister(uint32* address) {
   return *address;
}

void MBWriteRegister(uint32* address, uint32 data) {
   *address = data;
}


uint32 MailboxRead(uint8 channel) {

   //Loop until found for channel
   for (;;) {

      while ((MBReadRegister(MailboxStatusRegister) & MailEmptyFlag) != 0) {
         //Wait until there is data to read
         ConsoleWrite("Wait-Read\n");
      }

      uint32 data = MBReadRegister(MailboxReadRegister);
      uint8 readChannel = data & 0xF;
      data >>= 4;
      

      if (channel == readChannel) {
         return data;
      }

   }

}

void MailboxWrite(uint8 channel, uint32 data) {

   while ((MBReadRegister(MailboxStatusRegister) & MailFullFlag) != 0) {
      //Wait until there is space to read
      ConsoleWrite("Wait-Write\n");
   }

   MBWriteRegister(MailboxWriteRegister, (data << 4) & channel);
   ConsoleWrite("MB-Write\n");
}


however this code gives the output blake@ubuntu:~/Dropbox/Current/PiOS$ sh emulate.sh
Initializing PiOS
Constructing a framebuffer request
Sending mailbox request
MB-Write
Reading mailbox response
before it hangs, getting stuck on the MailboxRead function as there is never any message from channel 1 ( Debugging the readchannel shows that the lower 4 bits of the data received are always 0 )

Does anybody have any advice as to what the problem is? Thanks
Posts: 3
Joined: Tue Jan 08, 2013 6:39 pm
by tufty » Wed Jan 09, 2013 6:27 am
QEMU emulating versatilepb / generic ARM1176 doesn't know anything about the broadcom chip's mailboxes. You might get further by trying Torlus' patches to qemu
Posts: 1367
Joined: Sun Sep 11, 2011 2:32 pm
by DavidS » Wed Jan 09, 2013 11:18 am
Ok, now that I reread that and see that you are in QEMU:
You may wish to attempt to d this on your RPi. Compile, assemble, nd link on an OS running on the RPi, copy the your kernel to the boot partition, make sure that you have config txtset up correctly, and reboot.
ARM Assembly Language: For those that want: Simple, Powerful, Easy to learn, and Easy to debug.
User avatar
Posts: 1251
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
by -rst- » Wed Jan 09, 2013 11:45 am
And here is some allegedly working code (I got sidetracked myself so haven't tested, but looking at Valtonia's track record, I have no doubts) to compare yours to viewtopic.php?f=72&t=11682#p226546
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 899
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by jawline » Wed Jan 09, 2013 12:17 pm
Thanks for these examples. I'll try and get them working. However given that the QEMU emulator in some cases may not have any mailboxs setup is there any way I can check in software about the existence of a valid mailbox at a given address ( So that I could provide some meaningful output to the user and not hang on a call expecting a 1 if there is no valid mailbox )

Thanks,
Blake Loring
Posts: 3
Joined: Tue Jan 08, 2013 6:39 pm
by DavidS » Wed Jan 09, 2013 2:13 pm
jawline wrote:Thanks for these examples. I'll try and get them working. However given that the QEMU emulator in some cases may not have any mailboxs setup is there any way I can check in software about the existence of a valid mailbox at a given address ( So that I could provide some meaningful output to the user and not hang on a call expecting a 1 if there is no valid mailbox )

I am cofused, is your goal to have something that works in QEMU or something that works on the RPi? If you are writing to work with QEMU, then why ask on the RPi forum, if you want something that works on Tthe RPi, even with the patches QEMU is far from providing an accurate enough emulation of the RPi to be usable to develop bare metal RPi software.
ARM Assembly Language: For those that want: Simple, Powerful, Easy to learn, and Easy to debug.
User avatar
Posts: 1251
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
by -rst- » Wed Jan 09, 2013 4:26 pm
Accomp'ing DavidS: 'half' of RPi is the GPU binary that runs on the VideoCore - even if you get the mailbox interface to work in your emulator (emulating the ARM CPU 'half' of RPi), there most likely cannot be anything for the interface to talk to (there hardly is an emulator for VC GPU), so you would never get a response back :roll:
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 899
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by jawline » Wed Jan 09, 2013 4:36 pm
I'm trying to develop a program that if run on a emulator will not hang at this point ( So I need some way of detecting whether there is a videocore mailbox setup at the given address ) if that is possible.
Posts: 3
Joined: Tue Jan 08, 2013 6:39 pm