rockbox/firmware/target/mips/ingenic_jz47xx/crt0.S
Solomon Peachy d015165bc5 mips: Convert 'nop' to 'ssnop' -- for future-proofing
Change-Id: I17625f4d56a1f5205887cb47668a2dcb628053f4
2020-09-05 22:18:26 +00:00

348 lines
8.2 KiB
ArmAsm

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Maurus Cuelenaere
*
* 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.
*
****************************************************************************/
/*
* init.S
*
* Initialization code for JzRISC.
*
* Author: Seeger Chin
* e-mail: seeger.chin@gmail.com
*
* Copyright (C) 2006 Ingenic Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include "config.h"
#include "mips.h"
.text
.extern system_main
.extern main
.global _start
.section .init.text
.set mips32
.set noreorder
.set noat
#ifdef BOOTLOADER
#ifndef XDUOO_X3
/* These will get filled in by scramble */
.word 0 /* Empty */
.word 0 /* Filesize */
/* Relocate bootloader */
la t0, (_loadaddress-0xE00000)
la t1, _loadaddress
la t2, _bootend
_relocate_loop:
lw t3, 0(t0)
addiu t1, 4
addiu t0, 4
bne t1, t2, _relocate_loop
sw t3, -4(t1)
#endif
#endif
_start:
la ra, _start
/*
----------------------------------------------------
Init CP0 registers.
----------------------------------------------------
*/
mtc0 zero, C0_WATCHLO
mtc0 zero, C0_WATCHHI
li t0, (M_StatusBEV | M_StatusIM7 | M_StatusIM6 \
| M_StatusIM5 | M_StatusIM4 | M_StatusIM3 \
| M_StatusIM2 | M_StatusERL)
/*
BEV = Enable Boot Exception Vectors
IMx = Interrupt mask
ERL = Denotes error level
*/
mtc0 t0, C0_STATUS
li t0, M_CauseIV
mtc0 t0, C0_CAUSE
/*
----------------------------------------------------
Init caches, assumes a 4way*128set*32byte I/D cache
----------------------------------------------------
*/
li t0, 3 # enable cache for kseg0 accesses
mtc0 t0, C0_CONFIG # CONFIG reg
la t0, 0x80000000 # an idx op should use an unmappable address
ori t1, t0, 0x4000 # 16kB cache
mtc0 zero, C0_TAGLO # TAGLO reg
mtc0 zero, C0_TAGHI # TAGHI reg
_cache_loop:
cache 0x8, 0(t0) # index store icache tag
cache 0x9, 0(t0) # index store dcache tag
addiu t0, t0, 0x20 # 32 bytes per cache line
bne t0, t1, _cache_loop
ssnop
/*
----------------------------------------------------
Invalidate BTB
----------------------------------------------------
*/
mfc0 t0, C0_CONFIG
ssnop
ori t0, 2
mtc0 t0, C0_CONFIG
ssnop
/*
----------------------------------------------------
Copy IRAM section
* copy IRAM first before BSS gets cleared, as both
have the same address
----------------------------------------------------
*/
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)
/*
----------------------------------------------------
Clear BSS section
----------------------------------------------------
*/
la t0, _edata
la t1, _end
_bss_loop:
addiu t0, 4
bne t0, t1, _bss_loop
sw zero, -4(t0)
/*
----------------------------------------------------
Set up stack
----------------------------------------------------
*/
la sp, stackend
la t0, stackbegin
li t2, 0xDEADBEEF
_stack_loop:
addiu t0, 4
bne t0, sp, _stack_loop
sw t2, -4(t0)
/*
----------------------------------------------------
Set up interrupt stack
----------------------------------------------------
*/
la k0, irqstackend
la t0, irqstackbegin
_irq_stack_loop:
addiu t0, 4
bne t0, k0, _irq_stack_loop
sw t2, -4(t0)
/*
----------------------------------------------------
Jump to C code
----------------------------------------------------
*/
jal system_main /* Init clocks etc first */
ssnop
j main
ssnop
/*
* 0x0 - Simple TLB refill handler
* 0x100 - Cache error handler
* 0x180 - Exception/Interrupt handler
* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE)
*/
.section .vectors.1, "ax", %progbits
j tlb_refill_handler
ssnop
.section .vectors.2, "ax", %progbits
j real_exception_handler
ssnop
.section .vectors.3, "ax", %progbits
j real_exception_handler
ssnop
.section .vectors.4, "ax", %progbits
j real_exception_handler
ssnop
.section .vectors, "ax", %progbits
real_exception_handler:
/* Store stack pointer */
move k0, sp
/* jump to IRQ stack */
la sp, irqstackend
/* Push crap on frame */
addiu sp, -0x84
/* store current stack pointer */
sw k0, 0x80(sp)
sw ra, 0(sp)
sw fp, 4(sp)
sw gp, 8(sp)
sw t9, 0xC(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
ssnop
sw k0, 0x70(sp)
mfhi k0
ssnop
sw k0, 0x74(sp)
mfc0 k0, C0_STATUS
ssnop
ssnop
ssnop
sw k0, 0x78(sp)
mfc0 k0, C0_EPC
ssnop
ssnop
ssnop
sw k0, 0x7C(sp)
li k1, M_CauseExcCode
mfc0 k0, C0_CAUSE
and k0, k1
beq zero, k0, _int
ssnop
j _exception
ssnop
_int:
jal intr_handler
ssnop
j _exception_return
_exception:
move a0, sp
mfc0 a1, C0_CAUSE
ssnop
ssnop
ssnop
mfc0 a2, C0_EPC
ssnop
ssnop
ssnop
jal exception_handler
ssnop
_exception_return:
lw ra, 0(sp)
lw fp, 4(sp)
lw gp, 8(sp)
lw t9, 0xC(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
ssnop
lw k0, 0x74(sp)
mthi k0
ssnop
lw k0, 0x78(sp)
mtc0 k0, C0_STATUS
ssnop
ssnop
ssnop
lw k0, 0x7C(sp)
mtc0 k0, C0_EPC
ssnop
ssnop
ssnop
/* Restore previous stack pointer */
lw sp, 0x80(sp)
eret
ssnop
.set reorder
.set at