hbc/channel/channelapp/stub/crt0.S

208 lines
6.1 KiB
ArmAsm
Raw Normal View History

2016-11-23 06:35:12 +01:00
// this file was taken from libogc, see http://www.devkitpro.org/
#include "asm.h"
#define _SDA_BASE_ 32768
#define _SDA2_BASE_ 32768
.text
.section .init
# crt0.s file for the GameCube V1.1 by Costis (costis@gbaemu.com)!
#
# Updates: Added support for clearing the BSS section so that global
# variables are cleared to 0 upon start-up.
#
# This is start-up code for initializing the GameCube system and hardware
# before executing the actual user program code. It clears the GPR's,
# initializes the FPR's, initializes the Data, Code, and L2 caches, clears
# and initializes SPR's, and disables exceptions (interrupts).
#
# Have fun!!! Please e-mail any suggestions or bugs to costis@gbaemu.com.
# Entry Point
.extern __PSInit
.extern __SyscallInit
.extern __CacheInit
.extern __SystemInit
.extern __sbss_start, __bss_end
.extern __bat_config
.extern _main
.globl _start, __main
_start:
b startup
.ascii "STUB"
.ascii "HAXX"
.long 0
startup:
# Disable interrupts first thing
mfmsr r3
rlwinm r4,r3,0,17,15
rlwinm r4,r4,0,26,24
mtmsr r4
# Go into real mode
isync
lis r3,real@h
ori r3,r3,real@l
clrlwi r3,r3,2
mtsrr0 r3
mfmsr r3
li r4,0x30
andc r3,r3,r4
mtsrr1 r3
rfi
real:
# Set up the BATs the way we like them
// HID0 = 00110c64:
// bus checkstops off, sleep modes off,
// caches off, caches invalidate,
// store gathering off, enable data cache
// flush assist, enable branch target cache,
// enable branch history table
lis 3,0x0011 ; ori 3,3,0x0c64 ; mtspr 1008,3 ; isync
// MSR = 00002000 (FP on)
li 4,0x2000 ; mtmsr 4
// HID0 |= 0000c000 (caches on)
ori 3,3,0xc000 ; mtspr 1008,3 ; isync
// clear all BATs
li 0,0
mtspr 528,0 ; mtspr 530,0 ; mtspr 532,0 ; mtspr 534,0 // IBATU 0..3
mtspr 536,0 ; mtspr 538,0 ; mtspr 540,0 ; mtspr 542,0 // DBATU 0..3
mtspr 560,0 ; mtspr 562,0 ; mtspr 564,0 ; mtspr 566,0 // IBATU 4..7
mtspr 568,0 ; mtspr 570,0 ; mtspr 572,0 ; mtspr 574,0 // DBATU 4..7
isync
// clear all SRs
lis 0,0x8000
mtsr 0,0 ; mtsr 1,0 ; mtsr 2,0 ; mtsr 3,0
mtsr 4,0 ; mtsr 5,0 ; mtsr 6,0 ; mtsr 7,0
mtsr 8,0 ; mtsr 9,0 ; mtsr 10,0 ; mtsr 11,0
mtsr 12,0 ; mtsr 13,0 ; mtsr 14,0 ; mtsr 15,0
isync
// set [DI]BAT0 for 256MB@80000000,
// real 00000000, WIMG=0000, R/W
li 3,2 ; lis 4,0x8000 ; ori 4,4,0x1fff
mtspr IBAT0L,3 ; mtspr IBAT0U,4 ; mtspr DBAT0L,3 ; mtspr DBAT0U,4 ; isync
// set [DI]BAT4 for 256MB@90000000,
// real 10000000, WIMG=0000, R/W
addis 3,3,0x1000 ; addis 4,4,0x1000
mtspr IBAT4L,3 ; mtspr IBAT4U,4 ; mtspr DBAT4L,3 ; mtspr DBAT4U,4 ; isync
// set DBAT1 for 256MB@c0000000,
// real 00000000, WIMG=0101, R/W
li 3,0x2a ; lis 4,0xc000 ; ori 4,4,0x1fff
mtspr DBAT1L,3 ; mtspr DBAT1U,4 ; isync
// set DBAT5 for 256MB@d0000000,
// real 10000000, WIMG=0101, R/W
addis 3,3,0x1000 ; addis 4,4,0x1000
mtspr DBAT5L,3 ; mtspr DBAT5U,4 ; isync
// enable [DI]BAT4-7 in HID4
lis 3, 0x8200
mtspr 1011,3
// set MSR[DR:IR] = 11, jump to _start
lis 3,virtual@h ; ori 3,3, virtual@l ; mtsrr0 3
mfmsr 3 ; ori 3,3,0x30 ; mtsrr1 3
rfi
virtual:
bl InitGPRS # Initialize the General Purpose Registers
bl __CacheInit # Initialize the system caches
bl __SyscallInit # Initialize the System Call handler
bl __SystemInit # Initialize more cache aspects, clear a few SPR's, and disable interrupts.
# Clear the BSS section!
lis r3,__sbss_start@h
ori r3,r3,__sbss_start@l
li r4,0
lis r5,__bss_end@h
ori r5,r5,__bss_end@l
sub r5,r5,r3
bl _memset
bl _main # Branch to the user code!
eloop:
b eloop # If the main function returns, which should never happen then just loop endlessly.
InitGPRS:
# Clear all of the GPR's to 0
li r0,0
li r3,0
li r4,0
li r5,0
li r6,0
li r7,0
li r8,0
li r9,0
li r10,0
li r11,0
li r12,0
li r14,0
li r15,0
li r16,0
li r17,0
li r18,0
li r19,0
li r20,0
li r21,0
li r22,0
li r23,0
li r24,0
li r25,0
li r26,0
li r27,0
li r28,0
li r29,0
li r30,0
li r31,0
lis sp,__crt0stack@h # we take 0x8173FFF0 as the topmost starting point for our stack,this gives us ~128Kb Stack
ori sp,sp,__crt0stack@l
addi sp,sp,-4
stw r0,0(sp)
stwu sp,-56(sp)
lis r2,_SDA2_BASE_@h
ori r2,r2,_SDA2_BASE_@l # Set the Small Data 2 (Read Only) base register.
lis r13,_SDA_BASE_@h
ori r13,r13,_SDA_BASE_@l # Set the Small Data (Read\Write) base register.
blr
//r3 = ptr, r4 = fill, r5 = size
.globl _memset
_memset:
clrlwi. r6,r5,29
srwi r5,r5,2
subi r3,r3,4
mtctr r5
1: stwu r4,4(r3)
bdnz 1b
cmplwi r6,0
beq 3f
2: stbu r4,1(r3)
addic. r6,r6,-1
bne+ 2b
3: blr
.section .bss
.balign 8
__crt0stack_end:
.space 0x8000
__crt0stack: