1/* c-isr library stuff of Andes NDS32 cpu for GNU compiler 2 Copyright (C) 2012-2019 Free Software Foundation, Inc. 3 Contributed by Andes Technology Corporation. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published 9 by the Free Software Foundation; either version 3, or (at your 10 option) any later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 Under Section 7 of GPL version 3, you are granted additional 18 permissions described in the GCC Runtime Library Exception, version 19 3.1, as published by the Free Software Foundation. 20 21 You should have received a copy of the GNU General Public License and 22 a copy of the GCC Runtime Library Exception along with this program; 23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 <http://www.gnu.org/licenses/>. */ 25 26 .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ 27 .align 1 28 .weak _SDA_BASE_ /* For reset handler only. */ 29 .weak _nds32_init_mem /* User defined memory initialization function. */ 30 .globl _start 31 .globl _nds32_reset 32 .type _nds32_reset, @function 33_nds32_reset: 34_start: 35 /* Handle NMI and warm boot if any of them exists. */ 36 beqz $sp, 1f /* Reset, NMI or warm boot? */ 37 /* Either NMI or warm boot; save all regs. */ 38 39 /* Preserve registers for context-switching. */ 40#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS 41 /* For 16-reg mode. */ 42 smw.adm $r0, [$sp], $r10, #0x0 43 smw.adm $r15, [$sp], $r15, #0xf 44#else 45 /* For 32-reg mode. */ 46 smw.adm $r0, [$sp], $r27, #0xf 47#endif 48#if __NDS32_EXT_IFC__ 49 mfusr $r1, $IFC_LP 50 smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte alignment. */ 51#endif 52 53 la $gp, _SDA_BASE_ /* Init GP for small data access. */ 54 move $r0, $sp /* Init parameter. */ 55 mfsr $r1, $ITYPE /* Check ITYPE for NMI or warm boot. */ 56 andi $r1, $r1, #0xf 57 addi $r1, $r1, #-1 58 beqz $r1, 2f /* Warm boot if true. */ 59 l.w $r15, _nds32_nmih /* Load NMI handler. */ 60 j 3f 612: 62 l.w $r15, _nds32_wrh /* Load warm boot handler. */ 633: 64 beqz $r15, 1f /* If no handler, do cold boot. */ 65 jral $r15 /* Call handler. */ 66 bnez $r0, 1f /* If fail to resume, do cold boot. */ 67 68 /* Restore registers for context-switching. */ 69#if __NDS32_EXT_IFC__ 70 lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep stack 8-byte alignment. */ 71 mtusr $r1, $IFC_LP 72#endif 73#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS 74 /* For 16-reg mode. */ 75 lmw.bim $r15, [$sp], $r15, #0xf 76 lmw.bim $r0, [$sp], $r10, #0x0 77#else 78 /* For 32-reg mode. */ 79 lmw.bim $r0, [$sp], $r27, #0xf 80#endif 81 iret /* Resume operation. */ 82 83 841: /* Cold boot. */ 85#if __NDS32_ISR_VECTOR_SIZE_4__ 86 /* With vector ID feature for v3 architecture, default vector size is 4-byte. */ 87 /* Set IVB.ESZ = 0 (vector table entry size = 4 bytes) */ 88 mfsr $r0, $IVB 89 li $r1, #0xc000 90 or $r0, $r0, $r1 91 xor $r0, $r0, $r1 92 mtsr $r0, $IVB 93 dsb 94#else 95 /* There is no vector ID feature, so the vector size must be 16-byte. */ 96 /* Set IVB.ESZ = 1 (vector table entry size = 16 bytes) */ 97 mfsr $r0, $IVB 98 li $r1, #0xffff3fff 99 and $r0, $r0, $r1 100 ori $r0, $r0, #0x4000 101 mtsr $r0, $IVB 102 dsb 103#endif 104 105 la $gp, _SDA_BASE_ /* Init $gp. */ 106 la $sp, _stack /* Init $sp. */ 107 108#if __NDS32_EXT_EX9__ 109.L_init_itb: 110 /* Initialization for Instruction Table Base (ITB). 111 The symbol _ITB_BASE_ is determined by Linker. 112 Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ 113 mfsr $r0, $MSC_CFG 114 srli $r0, $r0, 24 115 andi $r0, $r0, 0x1 116 beqz $r0, 4f /* Fall through ? */ 117 la $r0, _ITB_BASE_ 118 mtusr $r0, $ITB 1194: 120#endif 121 122#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__ 123.L_init_fpu: 124 /* Initialize FPU 125 Set FUCOP_CTL.CP0EN (fucpr.b'0). */ 126 mfsr $r0, $FUCOP_CTL 127 ori $r0, $r0, 0x1 128 mtsr $r0, $FUCOP_CTL 129 dsb 130 /* According to [bugzilla #9425], set flush-to-zero mode. 131 That is, set $FPCSR.DNZ(b'12) = 1. */ 132 FMFCSR $r0 133 ori $r0, $r0, 0x1000 134 FMTCSR $r0 135 dsb 136#endif 137 138 /* Call DRAM init. _nds32_init_mem may written by C language. */ 139 la $r15, _nds32_init_mem 140 beqz $r15, 6f 141 jral $r15 1426: 143 l.w $r15, _nds32_jmptbl_00 /* Load reset handler. */ 144 jral $r15 145 146 /* Reset handler() should never return in a RTOS or non-OS system. 147 In case it does return, an exception will be generated. 148 This exception will be caught either by default break handler or by EDM. 149 Default break handle may just do an infinite loop. 150 EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */ 1515: 152 break #0x7fff 153 .size _nds32_reset, .-_nds32_reset 154