Tried to speed up wgt03.c FPS by booting into EL1 with simple caches, and setting ARM clock to 1.5Ghz

This commit is contained in:
Adam Greenwood-Byrne 2021-03-10 22:41:52 +00:00
parent 065f413ea7
commit 8d10ff5cc0
5 changed files with 157 additions and 7 deletions

View file

@ -1,3 +1,5 @@
#include "sysregs.h"
#define LOCAL_CONTROL 0xff800000
#define LOCAL_PRESCALER 0xff800008
#define OSC_FREQ 54000000
@ -40,10 +42,23 @@ _start:
br x4
b 1b
2: // We're on the main core!
ldr x0, =SCTLR_VALUE_MMU_DISABLED
msr sctlr_el1, x0
// Set stack to start somewhere safe
mov sp, #MAIN_STACK
ldr x0, =HCR_VALUE
msr hcr_el2, x0
ldr x0, =SCR_VALUE
msr scr_el3, x0
ldr x0, =SPSR_VALUE
msr spsr_el3, x0
adr x0, el1_entry
msr elr_el3, x0
eret
el1_entry:
// Clean the BSS section
ldr x1, =__bss_start // Start address
ldr w2, =__bss_size // Size of the section
@ -52,6 +67,9 @@ _start:
sub w2, w2, #1
cbnz w2, 3b // Loop if non-zero
// Set stack to start somewhere safe
mov sp, #MAIN_STACK
// Jump to our main() routine in C (make sure it doesn't return)
4: bl main
// In case it does return, halt the master core too
@ -78,3 +96,9 @@ spin_cpu2:
.globl spin_cpu3
spin_cpu3:
.quad 0
.globl get_el
get_el:
mrs x0, CurrentEL
lsr x0, x0, #2
ret

44
part12-wgt/boot/sysregs.h Normal file
View file

@ -0,0 +1,44 @@
#ifndef _SYSREGS_H
#define _SYSREGS_H
// ***************************************
// SCTLR_EL1, System Control Register (EL1), Page 2654 of AArch64-Reference-Manual.
// ***************************************
#define SCTLR_RESERVED (3 << 28) | (3 << 22) | (1 << 20) | (1 << 11)
#define SCTLR_EE_LITTLE_ENDIAN (0 << 25)
#define SCTLR_EOE_LITTLE_ENDIAN (0 << 24)
#define SCTLR_I_CACHE_DISABLED (0 << 12)
#define SCTLR_D_CACHE_DISABLED (0 << 2)
#define SCTLR_I_CACHE_ENABLED (1 << 12)
#define SCTLR_D_CACHE_ENABLED (1 << 2)
#define SCTLR_MMU_DISABLED (0 << 0)
#define SCTLR_MMU_ENABLED (1 << 0)
#define SCTLR_VALUE_MMU_DISABLED (SCTLR_RESERVED | SCTLR_EE_LITTLE_ENDIAN | SCTLR_I_CACHE_ENABLED | SCTLR_D_CACHE_ENABLED | SCTLR_MMU_DISABLED)
// ***************************************
// HCR_EL2, Hypervisor Configuration Register (EL2), Page 2487 of AArch64-Reference-Manual.
// ***************************************
#define HCR_RW (1 << 31)
#define HCR_VALUE HCR_RW
// ***************************************
// SCR_EL3, Secure Configuration Register (EL3), Page 2648 of AArch64-Reference-Manual.
// ***************************************
#define SCR_RESERVED (3 << 4)
#define SCR_RW (1 << 10)
#define SCR_NS (1 << 0)
#define SCR_VALUE (SCR_RESERVED | SCR_RW | SCR_NS)
// ***************************************
// SPSR_EL3, Saved Program Status Register (EL3) Page 389 of AArch64-Reference-Manual.
// ***************************************
#define SPSR_MASK_ALL (7 << 6)
#define SPSR_EL1h (5 << 0)
#define SPSR_VALUE (SPSR_MASK_ALL | SPSR_EL1h)
#endif

View file

@ -1,4 +1,6 @@
#include "wgt.h"
#include "include/mem.h"
#include "include/mb.h"
// ######## REQUIRED FUNCTIONS ########
@ -57,6 +59,8 @@ int clearcount; /* Counts the number of screen clears. */
int curx = 0;
int cury = 0;
extern int get_el(void);
void debugstr(char *str) {
if (curx + (strlen(str) * 8) >= 1920) {
curx = 0; cury += 8;
@ -96,6 +100,64 @@ void debughex(unsigned int d) {
debugstr(" ");
}
int get_max_clock()
{
mbox[0] = 8*4; // Length of message in bytes
mbox[1] = MBOX_REQUEST;
mbox[2] = MBOX_TAG_GETCLKMAXM; // Tag identifier
mbox[3] = 8; // Value size in bytes
mbox[4] = 0; // Value size in bytes
mbox[5] = 0x3; // Value
mbox[6] = 0; // Rate
mbox[7] = MBOX_TAG_LAST;
if (mbox_call(MBOX_CH_PROP)) {
if (mbox[5] == 0x3) {
return mbox[6];
}
}
return 0;
}
int get_clock_rate()
{
mbox[0] = 8*4; // Length of message in bytes
mbox[1] = MBOX_REQUEST;
mbox[2] = MBOX_TAG_GETCLKRATE; // Tag identifier
mbox[3] = 8; // Value size in bytes
mbox[4] = 0; // Value size in bytes
mbox[5] = 0x3; // Value
mbox[6] = 0; // Rate
mbox[7] = MBOX_TAG_LAST;
if (mbox_call(MBOX_CH_PROP)) {
if (mbox[5] == 0x3) {
return mbox[6];
}
}
return 0;
}
int set_clock_rate(unsigned int rate)
{
mbox[0] = 9*4; // Length of message in bytes
mbox[1] = MBOX_REQUEST;
mbox[2] = MBOX_TAG_SETCLKRATE; // Tag identifier
mbox[3] = 12; // Value size in bytes
mbox[4] = 0; // Value size in bytes
mbox[5] = 0x3; // Value
mbox[6] = rate; // Rate
mbox[7] = 0; // Rate
mbox[8] = MBOX_TAG_LAST;
if (mbox_call(MBOX_CH_PROP)) {
if (mbox[5] == 0x3 && mbox[6] == rate) {
return 1;
}
}
return 0;
}
void timer_routine (void)
{
timer++;
@ -103,13 +165,20 @@ void timer_routine (void)
void wgt03()
{
mem_init();
vga256 (); /* Initialize WGT system */
debugstr ("WGT Example #3"); debugcrlf(); debugcrlf();
debugstr ("This program will use the wcls routine to clear the screen"); debugcrlf();
debugstr ("using random colors as fast as it can until you press a key."); debugcrlf();
debugstr ("It will then report the highest frame rate possible on your computer."); debugcrlf(); debugcrlf(); debugcrlf();
debugstr ("Press any key to continue."); debugcrlf();
int el = get_el();
debugstr("Exception level: "); debughex(el); debugcrlf();
int setter = set_clock_rate(get_max_clock());
debugstr("Set clock returned "); debughex(setter); debugcrlf(); debugcrlf(); debugcrlf();
debugstr ("Press any key to continue.");
getch ();
clearcount = 0;
@ -134,10 +203,17 @@ void wgt03()
wcls(vgapal[0]);
int clock = get_clock_rate();
debugstr("Clock rate: "); debughex(clock); debugcrlf();
int maxclock = get_max_clock();
debugstr("Max clock rate: "); debughex(maxclock); debugcrlf();
unsigned int fps = clearcount / (timer / TIMERSPEED);
debughex(fps); debugstr("frames per second"); debugcrlf();
debughex(fps); debugstr("frames per second"); debugcrlf(); debugcrlf(); debugcrlf();
debugstr ("This is the highest frame rate your computer can produce for full screen\n"); debugcrlf();
debugstr ("animation."); debugcrlf();
debugstr ("animation.");
}
void main()

View file

@ -1,3 +1,5 @@
#pragma once
extern volatile unsigned int mbox[36];
enum {
@ -18,6 +20,9 @@ enum {
enum {
MBOX_TAG_SETPOWER = 0x28001,
MBOX_TAG_GETCLKRATE = 0x30002,
MBOX_TAG_GETCLKMAXM = 0x30004,
MBOX_TAG_SETCLKRATE = 0x38002,
MBOX_TAG_SETPHYWH = 0x48003,

View file

@ -2,8 +2,9 @@ extern unsigned char _end[];
// Define the heap
unsigned char *HEAP_START = &_end[0];
unsigned int HEAP_SIZE = 0x30000000; // Max heap size is 768Mb
// unsigned char *HEAP_START = &_end[0]; // End of kernel
unsigned char *HEAP_START = (unsigned char *)0x400000; // Top of stack
unsigned int HEAP_SIZE = 0x30000000; // Max heap size is 764Mb
unsigned char *HEAP_END;
// Set up some globals