RPi Framebuffer

Introduction
The aim of this page is to provide some documentation on BCM2835's frame buffer, as this is not publicly documented by Broadcom, and is necessary to write a basic OS for the Raspberry Pi. Most of this was worked out by reading the Linux source code (mostly drivers/video/bcm2708_fb.c and arch/arm/mach-bcm2708/) and experimentation. Note: At times I have used a different naming convention to that used by Broadcom's kernel source, partially because I used slightly different semantics where the kernel source is either unclear or seemed confusing. A working (more or less) example code for the frame buffer can be found here (note: this page includes corrections to the large comment in fb.c).

Basic procedure to get stuff on screen
The basic procedure to get a frame buffer is:
 * 1) Set up a structure with the frame buffer specification (resolution, etc)
 * 2) Tell the GPU about this structure by writing to the mailbox
 * 3) Wait by reading from the mailbox for the GPU to modify this structure
 * 4) Write to the frame buffer at the pointer we got in stage 3

Memory mapped registers
The bus address for the mailbox memory mapped registers is 0x7E00B880. This corresponds to an ARM physical address of 0x2000B880 (the address we use from the ARM processor, and hence here). We use three registers from the mail box:
 * MAIL0_READ
 * MAIL0_WRITE
 * MAIL0_STATUS

Mailbox operations
Read/write operatitons on the mailbox consist of transfering data via a 32 bit register. 28 bits of this 32 bit register are the data to be sent to the receiver, while the lower 4 bits specify the channel (channel 1 is the frame buffer, but there are others).

Procedure to Send Via the Mailbox

 * 1) Wait for space in the mailbox
 * 2) Execute a memory barrier
 * 3) Read MAIL0_STATUS
 * 4) Goto step 1 if MAIL_FULL bit is set
 * 5) Write channel and data to MAIL0_WRITE
 * 6) Execute a memory barrier

Procedure to Receive Via the Mailbox

 * 1) Wait for the mailbox to be non-empty
 * 2) Execute a memory barrier
 * 3) Read MAIL0_STATUS
 * 4) Goto step 1 if MAIL_EMPTY bit is set
 * 5) Execute a memory barrier
 * 6) Read from MAIL0_READ
 * 7) Check the channel (lowest 4 bits) of the read value for the correct channel
 * 8) If the channel is not the one we wish to read from (i.e: 1), go to step 1
 * 9) Return the data (i.e: the read value >> 4)

Format of GPU Framebuffer Structure
The structure expected by the GPU for initializing the frame buffer is as follows: Each of the 32-bit values should be little endian (i.e: that of the included ARM processor). Hence a simple C struct with a data type of uint32_t for each of these fields will suffice.