From 3ec66893e377b088c1284d2d23adb2aeea6d7965 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 27 Feb 2021 22:08:58 +0000 Subject: New port: FiiO M3K on bare metal Change-Id: I7517e7d5459e129dcfc9465c6fbd708619888fbe --- firmware/target/mips/ingenic_x1000/crt0.S | 265 ++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 firmware/target/mips/ingenic_x1000/crt0.S (limited to 'firmware/target/mips/ingenic_x1000/crt0.S') diff --git a/firmware/target/mips/ingenic_x1000/crt0.S b/firmware/target/mips/ingenic_x1000/crt0.S new file mode 100644 index 0000000000..b717f96692 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/crt0.S @@ -0,0 +1,265 @@ +/*************************************************************************** + * __________ __ ___. + * 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 -- cgit v1.2.3