OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [common/] [crt0.S] - Blame information for rev 12

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zero_gravi
/* ################################################################################################# */
2 6 zero_gravi
/* # << NEORV32 - crt0.S - Application Start-Up Code & Minimal Runtime Environment >>              # */
3 2 zero_gravi
/* # ********************************************************************************************* # */
4 6 zero_gravi
/* # The start-up code provides a minimal runtime environment that catches all exceptions and      # */
5 2 zero_gravi
/* # interrupts and delegates them to the handler functions (installed by user via dedicated       # */
6
/* # install function from the neorv32 runtime environment library).                               # */
7
/* # ********************************************************************************************* # */
8
/* # BSD 3-Clause License                                                                          # */
9
/* #                                                                                               # */
10
/* # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     # */
11
/* #                                                                                               # */
12
/* # Redistribution and use in source and binary forms, with or without modification, are          # */
13
/* # permitted provided that the following conditions are met:                                     # */
14
/* #                                                                                               # */
15
/* # 1. Redistributions of source code must retain the above copyright notice, this list of        # */
16
/* #    conditions and the following disclaimer.                                                   # */
17
/* #                                                                                               # */
18
/* # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     # */
19
/* #    conditions and the following disclaimer in the documentation and/or other materials        # */
20
/* #    provided with the distribution.                                                            # */
21
/* #                                                                                               # */
22
/* # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  # */
23
/* #    endorse or promote products derived from this software without specific prior written      # */
24
/* #    permission.                                                                                # */
25
/* #                                                                                               # */
26
/* # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   # */
27
/* # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               # */
28
/* # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    # */
29
/* # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     # */
30
/* # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # */
31
/* # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    # */
32
/* # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     # */
33
/* # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  # */
34
/* # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            # */
35
/* # ********************************************************************************************* # */
36
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting # */
37
/* ################################################################################################# */
38
 
39
  .file "crt0.S"
40
  .section .text
41
  .balign 4
42
  .global _start
43
 
44
 
45
  // IO region
46 12 zero_gravi
  .set IO_BEGIN, 0xFFFFFF80 // start of processor-internal IO region
47 2 zero_gravi
 
48 12 zero_gravi
  // SYSINFO
49
  .set SYSINFO_DSPACE_BASE, 0xFFFFFFF4
50
  .set SYSINFO_DSPACE_SIZE, 0xFFFFFFFC
51 2 zero_gravi
 
52 12 zero_gravi
 
53 2 zero_gravi
_start:
54
  .cfi_startproc
55
  .cfi_undefined ra
56
 
57
// *********************************************************
58
// Clear register file
59
// *********************************************************
60
__crt0_reg_file_clear:
61
  addi  x0,  x0, 0 // hardwired to zero
62
  addi  x1,  x0, 0
63
__crt0_reg_file_init:
64
  addi  x2,  x1, 0
65
  addi  x3,  x2, 0
66
  addi  x4,  x3, 0
67
  addi  x5,  x4, 0
68
  addi  x6,  x5, 0
69
  addi  x7,  x6, 0
70
  addi  x8,  x7, 0
71
  addi  x9,  x8, 0
72
  addi x10,  x9, 0
73
  addi x11, x10, 0
74
  addi x12, x11, 0
75
  addi x13, x12, 0
76
  addi x14, x13, 0
77
  addi x15, x14, 0
78
 
79
// the following registers do not exist in rv32e
80 3 zero_gravi
// "__RISCV_EMBEDDED_CPU__" is automatically defined by the makefiles when
81
// compiling for a rv32e architecture
82 2 zero_gravi
#ifndef __RISCV_EMBEDDED_CPU__
83
  addi x16, x15, 0
84
  addi x17, x16, 0
85
  addi x18, x17, 0
86
  addi x19, x18, 0
87
  addi x20, x19, 0
88
  addi x21, x20, 0
89
  addi x22, x21, 0
90
  addi x23, x22, 0
91
  addi x24, x23, 0
92
  addi x25, x24, 0
93
  addi x26, x25, 0
94
  addi x27, x26, 0
95
  addi x28, x27, 0
96
  addi x29, x28, 0
97
  addi x30, x29, 0
98
  addi x31, x30, 0
99
#endif
100
 
101
 
102
// *********************************************************
103
// TEST AREA / DANGER ZONE / IDEA-LAB
104
// *********************************************************
105
__crt0_tests:
106
  nop
107
 
108
 
109
// *********************************************************
110
// Setup stack pointer
111
// *********************************************************
112
__crt0_stack_pointer_init:
113 12 zero_gravi
  lw    x11, SYSINFO_DSPACE_BASE(zero) // data memory space base address
114
  lw    x12, SYSINFO_DSPACE_SIZE(zero) // data memory space size
115 2 zero_gravi
  add   sp, x11, x12
116
  addi  sp, sp, -4 // stack pointer = last entry
117
  addi  fp, sp, 0  // frame pointer = stack pointer
118
 
119
 
120
// *********************************************************
121
// Setup global pointer
122
// *********************************************************
123
__crt0_global_pointer_init:
124
  .option push
125
  .option norelax
126
  la gp, __global_pointer$
127
  .option pop
128
 
129
 
130
// *********************************************************
131
// Init exception vector table (2x16 4-byte entries) with dummy handlers
132
// *********************************************************
133
__crt0_neorv32_rte_init:
134
  la    x11, __crt0_neorv32_rte
135 6 zero_gravi
  csrw  mtvec, x11 // set address of first-level exception handler
136 2 zero_gravi
 
137 12 zero_gravi
  lw    x11, SYSINFO_DSPACE_BASE(zero) // data memory space base address
138 2 zero_gravi
  la    x12, __crt0_neorv32_rte_dummy_hanlder
139
  li    x13, 2*16  // number of entries (16xEXC, 16xIRQ)
140
 
141
__crt0_neorv32_rte_init_loop:
142
  sw  x12,  0(x11) // set dummy handler
143
  add x11, x11, 4
144
  add x13, x13, -1
145
  bne zero, x13, __crt0_neorv32_rte_init_loop
146
 
147
 
148
// *********************************************************
149
// Reset/deactivate IO/peripheral devices
150
// Devices, that are not implemented, will cause a store access fault
151
// which is captured but actually ignored due to the dummy handler.
152
// *********************************************************
153
__crt0_reset_io:
154
  li x11, IO_BEGIN // start of processor-internal IO region
155
 
156
__crt0_reset_io_loop:
157
  sw   zero, 0(x11)
158
  addi x11, x11, 4
159
  bne  zero, x11, __crt0_reset_io_loop
160
 
161
 
162
// *********************************************************
163
// Clear .bss section (byte-wise)
164
// *********************************************************
165
__crt0_clear_bss:
166
  la x11, __crt0_bss_start
167
  la x12, __crt0_bss_end
168
 
169
__crt0_clear_bss_loop:
170
  bge  x11, x12, __crt0_clear_bss_loop_end
171
  sb   zero, 0(x11)
172
  addi x11, x11, 1
173
  j    __crt0_clear_bss_loop
174
 
175
__crt0_clear_bss_loop_end:
176
 
177
 
178
// *********************************************************
179
// Copy initialized .data section from ROM to RAM (byte-wise)
180
// *********************************************************
181
__crt0_copy_data:
182
  la x11, __crt0_copy_data_src_begin  // start of data area (copy source)
183
  la x12, __crt0_copy_data_dst_begin  // start of data area (copy destination)
184
  la x13, __crt0_copy_data_dst_end    // last address of destination data area
185
 
186
__crt0_copy_data_loop:
187
  bge  x12, x13,  __crt0_copy_data_loop_end
188
  lb   x14, 0(x11)
189
  sb   x14, 0(x12)
190
  addi x11, x11, 1
191
  addi x12, x12, 1
192
  j    __crt0_copy_data_loop
193
 
194
__crt0_copy_data_loop_end:
195
 
196
 
197
// *********************************************************
198
// Call main function (with argc = argv = 0)
199
// *********************************************************
200
__crt0_main_entry:
201
 
202
  addi x10, zero, 0 // argc = 0
203
  addi x11, zero, 0 // argv = 0
204
 
205
  jal ra, main
206
 
207
 
208
// *********************************************************
209
// Go to endless sleep mode if main returns
210
// *********************************************************
211
__crt0_this_is_the_end:
212 11 zero_gravi
  csrrci zero, mstatus, 8 // mstatus: disable global IRQs (MIE)
213 2 zero_gravi
  wfi
214 11 zero_gravi
__crt0_this_is_the_end_end:
215
  j __crt0_this_is_the_end_end // in case Ziscr is not available
216 2 zero_gravi
 
217
 
218
// *********************************************************
219
// NEORV32 runtime environment: First-level exception/interrupt handler
220
// *********************************************************
221 12 zero_gravi
.align 4
222 2 zero_gravi
__crt0_neorv32_rte:
223
 
224
  // --------------------------------------------
225
  // full context save
226
  // --------------------------------------------
227
#ifndef __RISCV_EMBEDDED_CPU__
228
  addi  sp, sp, -120
229
#else
230
  addi  sp, sp, -56
231
#endif
232
 
233
  sw    ra,0(sp)
234
  sw    gp,4(sp)
235
  sw    tp,8(sp)
236
  sw    t0,12(sp)
237
  sw    t1,16(sp)
238
  sw    t2,20(sp)
239
  sw    s0,24(sp)
240
  sw    s1,28(sp)
241
  sw    a0,32(sp)
242
  sw    a1,36(sp)
243
  sw    a2,40(sp)
244
  sw    a3,44(sp)
245
  sw    a4,48(sp)
246
  sw    a5,52(sp)
247
#ifndef __RISCV_EMBEDDED_CPU__
248
  sw    a6,56(sp)
249
  sw    a7,60(sp)
250
  sw    s2,64(sp)
251
  sw    s3,68(sp)
252
  sw    s4,72(sp)
253
  sw    s5,76(sp)
254
  sw    s6,80(sp)
255
  sw    s7,84(sp)
256
  sw    s8,88(sp)
257
  sw    s9,92(sp)
258
  sw    s10,96(sp)
259
  sw    s11,100(sp)
260
  sw    t3,104(sp)
261
  sw    t4,108(sp)
262
  sw    t5,112(sp)
263
  sw    t6,116(sp)
264
#endif
265
 
266
 
267
  // --------------------------------------------
268
  // get cause and prepare jump into vector table
269
  // --------------------------------------------
270 6 zero_gravi
  csrr  t0, mcause        // get cause code
271 2 zero_gravi
 
272
  andi  t1, t0, 0x0f      // isolate cause ID
273
  slli  t1, t1, 2         // make address offset
274 12 zero_gravi
  lw    ra, SYSINFO_DSPACE_BASE(zero)  // data memory space base address
275 2 zero_gravi
  add   t1, t1, ra        // get vetor table entry address (EXC vectors)
276
 
277 6 zero_gravi
  csrr  ra, mepc          // get return address
278 2 zero_gravi
 
279
  blt   t0, zero, __crt0_neorv32_rte_is_irq  // branch if this is an INTERRUPT
280
 
281
 
282
  // --------------------------------------------
283
  // compute return address for EXCEPTIONS only
284
  // --------------------------------------------
285
__crt0_neorv32_rte_is_exc:
286
 
287 7 zero_gravi
  // check if faulting instruction is compressed and adjust return address
288 2 zero_gravi
 
289 7 zero_gravi
  lh    t0, 0(ra)   // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
290
  addi  t2, zero, 3 // mask
291
  and   t0, t0, t2  // isolate lowest 2 opcode bits (= 11 for uncompressed instructions)
292
 
293 6 zero_gravi
  addi  ra, ra, +2  // only this for compressed instructions
294 7 zero_gravi
  bne   t0, t2, __crt0_neorv32_rte_execute // jump if compressed instruction
295
 
296
  addi  ra, ra, +2  // add another 2 (making +4) for uncompressed instructions
297 2 zero_gravi
  j __crt0_neorv32_rte_execute
298
 
299
 
300
  // --------------------------------------------
301
  // vector table offset for INTERRUPTS only
302
  // --------------------------------------------
303
__crt0_neorv32_rte_is_irq:
304
  addi  t1, t1, 16*4
305
 
306
 
307
  // --------------------------------------------
308
  // call handler from vector table
309
  // --------------------------------------------
310
__crt0_neorv32_rte_execute:
311
  lw    t0, 0(t1)       // get base address of second-level handler
312
 
313
  // push ra
314
  addi  sp, sp, -4
315
  sw    ra, 0(sp)
316
 
317
  jalr  ra, t0          // call second-level handler
318
 
319
  // pop ra
320
  lw    ra, 0(sp)
321
  addi  sp, sp, +4
322
 
323 6 zero_gravi
  csrw  mepc, ra
324 2 zero_gravi
 
325
 
326
  // --------------------------------------------
327
  // full context restore
328
  // --------------------------------------------
329
  lw    ra,0(sp)
330
  lw    gp,4(sp)
331
  lw    tp,8(sp)
332
  lw    t0,12(sp)
333
  lw    t1,16(sp)
334
  lw    t2,20(sp)
335
  lw    s0,24(sp)
336
  lw    s1,28(sp)
337
  lw    a0,32(sp)
338
  lw    a1,36(sp)
339
  lw    a2,40(sp)
340
  lw    a3,44(sp)
341
  lw    a4,48(sp)
342
  lw    a5,52(sp)
343
#ifndef __RISCV_EMBEDDED_CPU__
344
  lw    a6,56(sp)
345
  lw    a7,60(sp)
346
  lw    s2,64(sp)
347
  lw    s3,68(sp)
348
  lw    s4,72(sp)
349
  lw    s5,76(sp)
350
  lw    s6,80(sp)
351
  lw    s7,84(sp)
352
  lw    s8,88(sp)
353
  lw    s9,92(sp)
354
  lw    s10,96(sp)
355
  lw    s11,100(sp)
356
  lw    t3,104(sp)
357
  lw    t4,108(sp)
358
  lw    t5,112(sp)
359
  lw    t6,116(sp)
360
#endif
361
 
362
#ifndef __RISCV_EMBEDDED_CPU__
363
  addi  sp, sp, +120
364
#else
365
  addi  sp, sp, +56
366
#endif
367
 
368
 
369
  // --------------------------------------------
370
  // this is the ONLY place where MRET should be used!
371
  // --------------------------------------------
372
  mret
373
 
374
 
375
// *********************************************************
376
// Dummy exception handler: just move on to next instruction
377
// *********************************************************
378
__crt0_neorv32_rte_dummy_hanlder:
379
  ret
380
 
381
  .cfi_endproc
382
  .end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.