1/* ------------------------------------------------------------------------- */
2/*  @file:    startup_RV32M1_ri5cy.s                                         */
3/*  @purpose: RI5CY Core Device Startup File                                 */
4/*            RV32M1_ri5cy                                                   */
5/*  @version: 1.0                                                            */
6/*  @date:    2018-10-2                                                      */
7/*  @build:   b180926                                                        */
8/* ------------------------------------------------------------------------- */
9/*                                                                           */
10/* Copyright 1997-2016 Freescale Semiconductor, Inc.                         */
11/* Copyright 2016-2018 NXP                                                   */
12/* All rights reserved.                                                      */
13/*                                                                           */
14/* SPDX-License-Identifier: BSD-3-Clause                                     */
15
16
17// Copyright 2017 ETH Zurich and University of Bologna.
18// Copyright and related rights are licensed under the Solderpad Hardware
19// License, Version 0.51 (the "License"); you may not use this file except in
20// compliance with the License.  You may obtain a copy of the License at
21// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
22// or agreed to in writing, software, hardware and materials distributed under
23// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
24// CONDITIONS OF ANY KIND, either express or implied. See the License for the
25// specific language governing permissions and limitations under the License.
26
27#define EXCEPTION_STACK_SIZE 0x58
28
29    .text
30    .section .vectors, "ax"
31    .option norvc;
32
33    jal x0, SW_handler
34    jal x0, SW_handler
35    jal x0, SW_handler
36    jal x0, SW_handler
37    jal x0, SW_handler
38    jal x0, SW_handler
39    jal x0, SW_handler
40    jal x0, SW_handler
41    jal x0, SW_handler
42    jal x0, SW_handler
43    jal x0, SW_handler
44    jal x0, SW_handler
45    jal x0, SW_handler
46    jal x0, SW_handler
47    jal x0, SW_handler
48    jal x0, SW_handler
49    jal x0, SW_handler
50    jal x0, SW_handler
51    jal x0, SW_handler
52    jal x0, SW_handler
53    jal x0, SW_handler
54    jal x0, SW_handler
55    jal x0, SW_handler
56    jal x0, SW_handler
57    jal x0, SW_handler
58    jal x0, SW_handler
59    jal x0, SW_handler
60    jal x0, SW_handler
61    jal x0, SW_handler
62    jal x0, SW_handler
63    jal x0, SW_handler
64    jal x0, SW_handler
65
66    // reset vector
67    jal x0, Reset_Handler
68
69    // Illegal instrution exception
70    jal x0, IllegalInstruction_Handler
71
72    // ecall handler
73    jal x0, Ecall_Handler
74
75    // LSU error
76    jal x0, LSU_Handler
77
78    .section .startup
79
80/* Reset Handler */
81Reset_Handler:
82
83    # Disable global interrupt. */
84    csrci mstatus, 8
85
86    # initialize stack pointer
87    la sp, __StackTop
88
89    # initialize global pointer
90    la gp, __global_pointer
91
92#ifndef __NO_SYSTEM_INIT
93    jal SystemInit
94#endif
95
96    # call __libc_init_array
97
98    # Enable global interrupt. */
99    # csrsi mstatus, 8
100    la t0, __stack
101    csrw mscratch,t0
102
103    jal entry
104    ebreak
105
106    .size Reset_Handler, . - Reset_Handler
107
108    .global _init
109    .global _fini
110_init:
111_fini:
112    ret
113
114  // saves all caller-saved registers (except return address)
115store_regs:
116    sw  x3, 0x00(x2)  // gp
117    sw  x4, 0x04(x2)  // tp
118    sw  x5, 0x08(x2)  // t0
119    sw  x6, 0x0c(x2)  // t1
120    sw  x7, 0x10(x2)  // t2
121    sw x10, 0x14(x2)  // a0
122    sw x11, 0x18(x2)  // a1
123    sw x12, 0x1c(x2)  // a2
124    sw x13, 0x20(x2)  // a3
125    sw x14, 0x24(x2)  // a4
126    sw x15, 0x28(x2)  // a5
127    sw x16, 0x2c(x2)  // a6
128    sw x17, 0x30(x2)  // a7
129
130    csrr a0, 0x7B0
131    csrr a1, 0x7B1
132    csrr a2, 0x7B2
133    sw a0, 0x34(x2)  // lpstart[0]
134    sw a1, 0x38(x2)  // lpend[0]
135    sw a2, 0x3c(x2)  // lpcount[0]
136    csrr a0, 0x7B4
137    csrr a1, 0x7B5
138    csrr a2, 0x7B6
139    sw a0, 0x40(x2)  // lpstart[1]
140    sw a1, 0x44(x2)  // lpend[1]
141    sw a2, 0x48(x2)  // lpcount[1]
142
143    csrr a0, 0x341
144    sw a0, 0x4c(x2)  // mepc
145    csrr a1, 0x300
146    sw a1, 0x50(x2)  // mstatus
147    jalr x0, x1
148
149    // load back registers from stack
150end_except:
151    lw a1, 0x50(x2)  // mstatus
152    csrrw x0, 0x300, a1
153    lw a0, 0x4c(x2)  // mepc
154    csrrw x0, 0x341, a0
155
156    lw a0, 0x40(x2)  // lpstart[1]
157    lw a1, 0x44(x2)  // lpend[1]
158    lw a2, 0x48(x2)  // lpcount[1]
159    csrrw x0, 0x7B4, a0
160    csrrw x0, 0x7B5, a1
161    csrrw x0, 0x7B6, a2
162    lw a0, 0x34(x2)  // lpstart[0]
163    lw a1, 0x38(x2)  // lpend[0]
164    lw a2, 0x3c(x2)  // lpcount[0]
165    csrrw x0, 0x7B0, a0
166    csrrw x0, 0x7B1, a1
167    csrrw x0, 0x7B2, a2
168
169    lw  x3, 0x00(x2)  // gp
170    lw  x4, 0x04(x2)  // tp
171    lw  x5, 0x08(x2)  // t0
172    lw  x6, 0x0c(x2)  // t1
173    lw  x7, 0x10(x2)  // t2
174    lw x10, 0x14(x2)  // a0
175    lw x11, 0x18(x2)  // a1
176    lw x12, 0x1c(x2)  // a2
177    lw x13, 0x20(x2)  // a3
178    lw x14, 0x24(x2)  // a4
179    lw x15, 0x28(x2)  // a5
180    lw x16, 0x2c(x2)  // a6
181    lw x17, 0x30(x2)  // a7
182
183    lw  x1, 0x54(x2)
184    addi x2, x2, EXCEPTION_STACK_SIZE
185    mret
186
187    .weak SW_handler
188    .type SW_handler, %function
189SW_handler:
190    addi x2, x2, -EXCEPTION_STACK_SIZE
191    sw x1, 0x54(x2)
192    jal x1, store_regs
193    la x1, end_except
194    csrr a0, mcause
195    jal x0, SystemIrqHandler
196    .size SW_handler, . - SW_handler
197
198    .macro define_exception_entry entry_name handler_name
199    .weak \entry_name
200\entry_name:
201    addi x2, x2, -EXCEPTION_STACK_SIZE
202    sw x1, 0x54(x2)
203    jal x1, store_regs
204    la x1, end_except
205    jal x0, \handler_name
206    .endm
207
208define_exception_entry IllegalInstruction_Handler IllegalInstruction_HandlerFunc
209define_exception_entry Ecall_Handler Ecall_HandlerFunc
210define_exception_entry LSU_Handler LSU_HandlerFunc
211
212    .weak IllegalInstruction_HandlerFunc
213    .type IllegalInstruction_HandlerFunc, %function
214IllegalInstruction_HandlerFunc:
215    j .
216    .size IllegalInstruction_HandlerFunc, . - IllegalInstruction_HandlerFunc
217
218    .weak Ecall_HandlerFunc
219    .type Ecall_HandlerFunc, %function
220Ecall_HandlerFunc:
221    j .
222    .size Ecall_HandlerFunc, . - Ecall_HandlerFunc
223
224    .weak LSU_HandlerFunc
225    .type LSU_HandlerFunc, %function
226LSU_HandlerFunc:
227    j .
228    .size LSU_HandlerFunc, . - LSU_HandlerFunc
229