1
0
Fork 0
forked from len0rd/rockbox
foxbox/firmware/target/mips/ingenic_x1000/crt0.S
Aidan MacDonald 67f7d399e5 x1000: restore crt0.S cache flush
I-cache must be flushed after copying code to IRAM... duh.

Change-Id: I6eacc4b7c4385175724c947f6c53f7bbddcb6295
2022-03-16 23:21:29 +00:00

265 lines
5.9 KiB
ArmAsm

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021-2022 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
.extern system_early_init
.extern _loadaddress
.global _start
.set push
.set mips32
.set noreorder
.set noat
.section .init.text
_start:
b _realstart
nop
/* Header entries are 4-byte string labels (not null terminated!) followed
* by 4-byte values. Header should begin in the first 128 bytes and should
* be no more than 256 bytes in length. */
_header:
.ascii "BEGINHDR" /* beginning of header */
.ascii "LOAD"
.word _loadaddress
.ascii "ENDH" /* end of header structure */
_realstart:
/* Copy IRAM from BSS to low memory. */
la a0, _iramcopy
la a1, _iramstart
la a2, _iramend
bal _copy
nop
/* Copy TCSM from BSS */
la a0, _tcsmcopy
la a1, _tcsmstart
la a2, _tcsmend
bal _copy
nop
/* Clear the BSS segment (needed to zero-initialize C static values) */
la a0, _bssbegin
la a1, _bssend
bal _clear
move a2, $0
/* Set stack pointer and clear the stack */
la sp, stackend
la a0, stackbegin
li a2, 0xDEADBEEF
bal _clear
move a1, sp
/* Clear the IRQ stack */
la k0, _irqstackend
la a0, _irqstackbegin
bal _clear
move a1, k0
/* Write back D-cache and invalidate I-cache */
li v0, 0x80000000
ori v1, v0, (0x4000 - 32)
mtc0 zero, C0_TAGLO
mtc0 zero, C0_TAGHI
1:
cache DCIndexWBInv, 0(v0)
cache ICIndexStTag, 0(v0)
bne v0, v1, 1b
addiu v0, v0, 32
/* Invalidate BTB */
mfc0 v0, C0_Config, 7
nop
ori v0, v0, 2
mtc0 v0, C0_Config, 7
nop
/* Jump to C code */
jal system_early_init
nop
j main
nop
/* copy(void* src, void* dst, void* dst_end) */
_copy:
beq a1, a2, 1f
addiu a1, 4
lw t0, 0(a0)
addiu a0, 4
b _copy
sw t0, -4(a1)
1:
jr ra
nop
/* clear(void* dst, void* dst_end, int value) */
_clear:
beq a0, a1, 1f
addiu a0, 4
b _clear
sw a2, -4(a0)
1:
jr ra
nop
/* 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
.set pop