ARM/QEMU PL110
Posted: Sat Apr 13, 2019 11:38 pm
I'm attempting to demo some low level graphics stuff for ARM. So I'm targeting what is supposed to be easy graphics, PL110. But so far all it does is sit black. I've attempted to follow the osdev wiki but it doesn't seem to work either. Chief problem is I'm pretty sure qemu changed it's memory map since that was written. I played around with the code a little but didn't see much. So here's mine:
DEBUG_PRINT is a UART print which is fed to stdio. I run qemu using and the output falls all the way to done so I know it should be doing something but the graphical window stays black.
Thanks for any help.
Code: Select all
#include "stdint.h"
#include "uart.h"
#include "utility.h"
volatile unsigned char * const CLCD = (unsigned char *) 0x10120000;
#define CLCDPERIPHID0 0xFE0
#define CLCDPERIPHID1 0xFE4
#define CLCDPERIPHID2 0xFE8
#define CLCDPERIPHID3 0xFEC
void PrintClcdPerifId()
{
char buffer[5];
DEBUG_PRINT("ClcdPerifId: ");
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPERIPHID0), buffer));
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPERIPHID1), buffer));
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPERIPHID2), buffer));
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPERIPHID3), buffer));
DEBUG_PRINT("\n");
}
#define CLCDPCELLID0 0xFF0
#define CLCDPCELLID1 0xFF4
#define CLCDPCELLID2 0xFF8
#define CLCDPCELLID3 0xFFC
void PrintClcdCellId()
{
char buffer[5];
DEBUG_PRINT("ClcdCellId: ");
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPCELLID0), buffer));
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPCELLID1), buffer));
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPCELLID2), buffer));
DEBUG_PRINT(CharToHex(*(CLCD + CLCDPCELLID3), buffer));
DEBUG_PRINT("\n");
}
#define LCDTIMING0 0x0
#define LCDTIMING1 0x4
#define LCDTIMING2 0x8
#define LCDTIMING3 0xC
#define VGATIM0 0x3F1F3F9C
#define VGATIM1 0x090B616F
#define VGATIM2 0x067F1800
#define QVGATIM0 0x0505054C
#define QVGATIM1 0x050514EF
#define QVGATIM2 0x05EF1800
void SetClcdTiming()
{
uint32_t volatile *pRegister;
DEBUG_PRINT("Setting CLCD timing registers\n");
pRegister = (uint32_t*) CLCD + LCDTIMING0;
*pRegister = VGATIM0;
pRegister = (uint32_t*) CLCD + LCDTIMING1;
*pRegister = VGATIM1;
pRegister = (uint32_t*) CLCD + LCDTIMING2;
*pRegister = VGATIM2;
}
#define LCDCONTROL 0x1C
#define TFT24BITEN 0x182B
void SetClcdControl()
{
uint32_t volatile *pRegister;
DEBUG_PRINT("Set CLCD Control Registers\n");
pRegister = (uint32_t *) CLCD + LCDCONTROL;
*pRegister = TFT24BITEN;
}
#define LCDUPBASE 0x10
void SetClcdBuffer(uint32_t frameBufferLoc)
{
uint32_t volatile *pRegister;
DEBUG_PRINT("Set CLCD Frame Buffer\n");
pRegister = (uint32_t *) CLCD + LCDUPBASE;
*pRegister = frameBufferLoc;
}
#define DEFAULT_BUFFER_LOC 0x200000
void InitClcd()
{
PrintClcdPerifId();
PrintClcdCellId();
SetClcdTiming();
SetClcdBuffer(DEFAULT_BUFFER_LOC);
SetClcdControl();
uint16_t volatile *fb;
fb = (uint16_t *) DEFAULT_BUFFER_LOC;
int x;
for (x = 0; x < (640 * 480) - 10; ++x)
fb[x] = 0x1f << (5 + 6) | 0xf << 5;
DEBUG_PRINT("InitCLCD Done\n");
}
Code: Select all
qemu-system-arm -M versatilepb -m 256M -serial stdio -kernel QG.elf
Code: Select all
Begin System Manager
ClcdPerifId: 10 11 04 00
ClcdCellId: 0D F0 05 B1
Setting CLCD timing registers
Set CLCD Frame Buffer
Set CLCD Control Registers
InitCLCD Done