rockbox/firmware/target/mips/ingenic_x1000/crt0.S
Aidan MacDonald 3ec66893e3 New port: FiiO M3K on bare metal
Change-Id: I7517e7d5459e129dcfc9465c6fbd708619888fbe
2021-03-28 00:01:37 +00:00

265 lines
5.9 KiB
ArmAsm

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 Aidan MacDonald
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "mips.h"
.text
.extern main
.global _start
.set push
.set mips32
.set noreorder
.set noat
.section .init.text
_start:
/* Clear data watchpoint */
mtc0 zero, C0_WATCHLO
mtc0 zero, C0_WATCHHI
/* Set BEV, ERL, mask interrupts */
li v0, 0x40fc04
mtc0 v0, C0_Status
/* Set Cause_IV to 1 (use special interrupt vector) */
li v0, M_CauseIV
mtc0 v0, C0_Cause
/* Set CPU_MODE and BUS_MODE to 1 in CPM_OPCR (Ingenic does this) */
lui v0, 0xb000
lw v1, 0x24(v0)
ori v1, v1, 0x22
sw v1, 0x24(v0)
/* Enable kseg0 cacheability */
li v0, 3
mtc0 v0, C0_Config
nop
/* According to ingenic: "enable idx-store-data cache insn" */
li v0, 0x20000000
mtc0 v0, C0_ErrCtl
/* Cache init */
li v0, 0x80000000
ori v1, v0, 0x4000
mtc0 zero, C0_TAGLO
mtc0 zero, C0_TAGHI
_cache_loop:
cache ICIndexStTag, 0(v0)
cache DCIndexStTag, 0(v0)
addiu v0, v0, 32
bne v0, v1, _cache_loop
nop
/* Invalidate BTB */
mfc0 v0, C0_Config, 7
nop
ori v0, v0, 2
mtc0 v0, C0_Config, 7
nop
#ifndef BOOTLOADER_SPL
/* Copy IRAM from BSS to low memory. */
la t0, _iramcopy
la t1, _iramstart
la t2, _iramend
_iram_loop:
lw t3, 0(t0)
addiu t1, 4
addiu t0, 4
bne t1, t2, _iram_loop
sw t3, -4(t1)
#endif
/* Clear the BSS segment (needed to zero-initialize C static values) */
la t0, _bssbegin
la t1, _bssend
beq t0, t1, _bss_done
_bss_loop:
addiu t0, 4
bne t0, t1, _bss_loop
sw zero, -4(t0)
_bss_done:
#ifndef BOOTLOADER_SPL
/* Set stack pointer and clear the stack */
la sp, stackend
la t0, stackbegin
li t1, 0xDEADBEEF
_stack_loop:
addiu t0, 4
bne t0, sp, _stack_loop
sw t1, -4(t0)
/* Clear the IRQ stack */
la k0, _irqstackend
la t0, _irqstackbegin
_irqstack_loop:
addiu t0, 4
bne t0, k0, _irqstack_loop
sw t1, -4(t0)
#endif
/* Jump to C code */
j main
nop
#ifndef BOOTLOADER_SPL
/* Exception entry points */
.section .vectors.1, "ax", %progbits
j tlb_refill_handler
nop
.section .vectors.2, "ax", %progbits
j real_exception_handler
nop
.section .vectors.3, "ax", %progbits
j real_exception_handler
nop
.section .vectors.4, "ax", %progbits
j real_exception_handler
nop
.section .vectors, "ax", %progbits
real_exception_handler:
move k0, sp
la sp, _irqstackend
addiu sp, -0x84
sw k0, 0x80(sp)
sw ra, 0x00(sp)
sw fp, 0x04(sp)
sw gp, 0x08(sp)
sw t9, 0x0c(sp)
sw t8, 0x10(sp)
sw s7, 0x14(sp)
sw s6, 0x18(sp)
sw s5, 0x1c(sp)
sw s4, 0x20(sp)
sw s3, 0x24(sp)
sw s2, 0x28(sp)
sw s1, 0x2c(sp)
sw s0, 0x30(sp)
sw t7, 0x34(sp)
sw t6, 0x38(sp)
sw t5, 0x3c(sp)
sw t4, 0x40(sp)
sw t3, 0x44(sp)
sw t2, 0x48(sp)
sw t1, 0x4c(sp)
sw t0, 0x50(sp)
sw a3, 0x54(sp)
sw a2, 0x58(sp)
sw a1, 0x5c(sp)
sw a0, 0x60(sp)
sw v1, 0x64(sp)
sw v0, 0x68(sp)
sw $1, 0x6c(sp)
mflo k0
nop
sw k0, 0x70(sp)
mfhi k0
nop
sw k0, 0x74(sp)
mfc0 k0, C0_STATUS
nop
nop
nop
sw k0, 0x78(sp)
mfc0 k0, C0_EPC
nop
nop
nop
sw k0, 0x7c(sp)
li k1, M_CauseExcCode
mfc0 a0, C0_CAUSE
and k0, a0, k1
bnez k0, _exception
nop
jal intr_handler
nop
j _exception_return
_exception:
mfc0 a1, C0_EPC
nop
nop
nop
jal exception_handler
move a2, sp
_exception_return:
lw ra, 0x00(sp)
lw fp, 0x04(sp)
lw gp, 0x08(sp)
lw t9, 0x0c(sp)
lw t8, 0x10(sp)
lw s7, 0x14(sp)
lw s6, 0x18(sp)
lw s5, 0x1c(sp)
lw s4, 0x20(sp)
lw s3, 0x24(sp)
lw s2, 0x28(sp)
lw s1, 0x2c(sp)
lw s0, 0x30(sp)
lw t7, 0x34(sp)
lw t6, 0x38(sp)
lw t5, 0x3c(sp)
lw t4, 0x40(sp)
lw t3, 0x44(sp)
lw t2, 0x48(sp)
lw t1, 0x4c(sp)
lw t0, 0x50(sp)
lw a3, 0x54(sp)
lw a2, 0x58(sp)
lw a1, 0x5c(sp)
lw a0, 0x60(sp)
lw v1, 0x64(sp)
lw v0, 0x68(sp)
lw $1, 0x6c(sp)
lw k0, 0x70(sp)
mtlo k0
nop
lw k0, 0x74(sp)
mthi k0
nop
lw k0, 0x78(sp)
mtc0 k0, C0_STATUS
nop
nop
nop
lw k0, 0x7c(sp)
mtc0 k0, C0_EPC
nop
nop
nop
lw sp, 0x80(sp)
eret
nop
#endif
.set pop