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

Subversion Repositories neorv32

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

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
  // standard CSRs
46
  .set mtinst, 0x34a
47
 
48
  // custom CSRs
49
  .set CSR_MISPACEBASE, 0xfc4  // CUSTOM (r/-): Base address of instruction memory space (via MEM_ISPACE_BASE generic) */
50
  .set CSR_MDSPACEBASE, 0xfc5  // CUSTOM (r/-): Base address of data memory space (via MEM_DSPACE_BASE generic) */
51
  .set CSR_MISPACESIZE, 0xfc6  // CUSTOM (r/-): Total size of instruction memory space in byte (via MEM_ISPACE_SIZE generic) */
52
  .set CSR_MDSPACESIZE, 0xfc7  // CUSTOM (r/-): Total size of data memory space in byte (via MEM_DSPACE_SIZE generic) */
53
 
54
  // IO region
55
  .set IO_BEGIN,    0xFFFFFF80  // start of processor-internal IO region
56
  .set MTIMECMP_LO, 0xFFFFFF98
57
  .set MTIMECMP_HI, 0xFFFFFF9C
58
 
59
 
60
_start:
61
  .cfi_startproc
62
  .cfi_undefined ra
63
 
64
// *********************************************************
65
// Clear register file
66
// *********************************************************
67
__crt0_reg_file_clear:
68
  addi  x0,  x0, 0 // hardwired to zero
69
  addi  x1,  x0, 0
70
__crt0_reg_file_init:
71
  addi  x2,  x1, 0
72
  addi  x3,  x2, 0
73
  addi  x4,  x3, 0
74
  addi  x5,  x4, 0
75
  addi  x6,  x5, 0
76
  addi  x7,  x6, 0
77
  addi  x8,  x7, 0
78
  addi  x9,  x8, 0
79
  addi x10,  x9, 0
80
  addi x11, x10, 0
81
  addi x12, x11, 0
82
  addi x13, x12, 0
83
  addi x14, x13, 0
84
  addi x15, x14, 0
85
 
86
// the following registers do not exist in rv32e
87 3 zero_gravi
// "__RISCV_EMBEDDED_CPU__" is automatically defined by the makefiles when
88
// compiling for a rv32e architecture
89 2 zero_gravi
#ifndef __RISCV_EMBEDDED_CPU__
90
  addi x16, x15, 0
91
  addi x17, x16, 0
92
  addi x18, x17, 0
93
  addi x19, x18, 0
94
  addi x20, x19, 0
95
  addi x21, x20, 0
96
  addi x22, x21, 0
97
  addi x23, x22, 0
98
  addi x24, x23, 0
99
  addi x25, x24, 0
100
  addi x26, x25, 0
101
  addi x27, x26, 0
102
  addi x28, x27, 0
103
  addi x29, x28, 0
104
  addi x30, x29, 0
105
  addi x31, x30, 0
106
#endif
107
 
108
 
109
// *********************************************************
110
// TEST AREA / DANGER ZONE / IDEA-LAB
111
// *********************************************************
112
__crt0_tests:
113
  nop
114
 
115
 
116
// *********************************************************
117
// Setup stack pointer
118
// *********************************************************
119
__crt0_stack_pointer_init:
120 6 zero_gravi
  csrr  x11, CSR_MDSPACEBASE // data memory space base address
121
  csrr  x12, CSR_MDSPACESIZE // data memory space size
122 2 zero_gravi
  add   sp, x11, x12
123
  addi  sp, sp, -4 // stack pointer = last entry
124
  addi  fp, sp, 0  // frame pointer = stack pointer
125
 
126
 
127
// *********************************************************
128
// Setup global pointer
129
// *********************************************************
130
__crt0_global_pointer_init:
131
  .option push
132
  .option norelax
133
  la gp, __global_pointer$
134
  .option pop
135
 
136
 
137
// *********************************************************
138
// Init exception vector table (2x16 4-byte entries) with dummy handlers
139
// *********************************************************
140
__crt0_neorv32_rte_init:
141
  la    x11, __crt0_neorv32_rte
142 6 zero_gravi
  csrw  mtvec, x11 // set address of first-level exception handler
143 2 zero_gravi
 
144 6 zero_gravi
  csrr  x11, CSR_MDSPACEBASE // data memory space base address
145 2 zero_gravi
  la    x12, __crt0_neorv32_rte_dummy_hanlder
146
  li    x13, 2*16  // number of entries (16xEXC, 16xIRQ)
147
 
148
__crt0_neorv32_rte_init_loop:
149
  sw  x12,  0(x11) // set dummy handler
150
  add x11, x11, 4
151
  add x13, x13, -1
152
  bne zero, x13, __crt0_neorv32_rte_init_loop
153
 
154
 
155
// *********************************************************
156
// Reset/deactivate IO/peripheral devices
157
// Devices, that are not implemented, will cause a store access fault
158
// which is captured but actually ignored due to the dummy handler.
159
// *********************************************************
160
__crt0_reset_io:
161
  li x11, IO_BEGIN // start of processor-internal IO region
162
 
163
__crt0_reset_io_loop:
164
  sw   zero, 0(x11)
165
  addi x11, x11, 4
166
  bne  zero, x11, __crt0_reset_io_loop
167
 
168
  // set mtime_compare to MAX (to prevent an IRQ)
169
  li x11, -1
170
  sw x11, MTIMECMP_LO(zero)
171
  sw x11, MTIMECMP_HI(zero)
172
 
173
 
174
// *********************************************************
175
// Clear .bss section (byte-wise)
176
// *********************************************************
177
__crt0_clear_bss:
178
  la x11, __crt0_bss_start
179
  la x12, __crt0_bss_end
180
 
181
__crt0_clear_bss_loop:
182
  bge  x11, x12, __crt0_clear_bss_loop_end
183
  sb   zero, 0(x11)
184
  addi x11, x11, 1
185
  j    __crt0_clear_bss_loop
186
 
187
__crt0_clear_bss_loop_end:
188
 
189
 
190
// *********************************************************
191
// Copy initialized .data section from ROM to RAM (byte-wise)
192
// *********************************************************
193
__crt0_copy_data:
194
  la x11, __crt0_copy_data_src_begin  // start of data area (copy source)
195
  la x12, __crt0_copy_data_dst_begin  // start of data area (copy destination)
196
  la x13, __crt0_copy_data_dst_end    // last address of destination data area
197
 
198
__crt0_copy_data_loop:
199
  bge  x12, x13,  __crt0_copy_data_loop_end
200
  lb   x14, 0(x11)
201
  sb   x14, 0(x12)
202
  addi x11, x11, 1
203
  addi x12, x12, 1
204
  j    __crt0_copy_data_loop
205
 
206
__crt0_copy_data_loop_end:
207
 
208
 
209
// *********************************************************
210
// Call main function (with argc = argv = 0)
211
// *********************************************************
212
__crt0_main_entry:
213
 
214
  addi x10, zero, 0 // argc = 0
215
  addi x11, zero, 0 // argv = 0
216
 
217
  jal ra, main
218
 
219
 
220
// *********************************************************
221
// Go to endless sleep mode if main returns
222
// *********************************************************
223
__crt0_this_is_the_end:
224
  wfi                      // in case Ziscr is not available -> processor should stall here
225
  csrrci zero, mstatus, 8  // mstatus: disable global IRQs (MIE)
226
  wfi
227
  j .
228
 
229
 
230
// *********************************************************
231
// NEORV32 runtime environment: First-level exception/interrupt handler
232
// *********************************************************
233
__crt0_neorv32_rte:
234
 
235
  // --------------------------------------------
236
  // full context save
237
  // --------------------------------------------
238
#ifndef __RISCV_EMBEDDED_CPU__
239
  addi  sp, sp, -120
240
#else
241
  addi  sp, sp, -56
242
#endif
243
 
244
  sw    ra,0(sp)
245
  sw    gp,4(sp)
246
  sw    tp,8(sp)
247
  sw    t0,12(sp)
248
  sw    t1,16(sp)
249
  sw    t2,20(sp)
250
  sw    s0,24(sp)
251
  sw    s1,28(sp)
252
  sw    a0,32(sp)
253
  sw    a1,36(sp)
254
  sw    a2,40(sp)
255
  sw    a3,44(sp)
256
  sw    a4,48(sp)
257
  sw    a5,52(sp)
258
#ifndef __RISCV_EMBEDDED_CPU__
259
  sw    a6,56(sp)
260
  sw    a7,60(sp)
261
  sw    s2,64(sp)
262
  sw    s3,68(sp)
263
  sw    s4,72(sp)
264
  sw    s5,76(sp)
265
  sw    s6,80(sp)
266
  sw    s7,84(sp)
267
  sw    s8,88(sp)
268
  sw    s9,92(sp)
269
  sw    s10,96(sp)
270
  sw    s11,100(sp)
271
  sw    t3,104(sp)
272
  sw    t4,108(sp)
273
  sw    t5,112(sp)
274
  sw    t6,116(sp)
275
#endif
276
 
277
 
278
  // --------------------------------------------
279
  // get cause and prepare jump into vector table
280
  // --------------------------------------------
281 6 zero_gravi
  csrr  t0, mcause        // get cause code
282 2 zero_gravi
 
283
  andi  t1, t0, 0x0f      // isolate cause ID
284
  slli  t1, t1, 2         // make address offset
285 6 zero_gravi
  csrr  ra, CSR_MDSPACEBASE  // data memory space base address
286 2 zero_gravi
  add   t1, t1, ra        // get vetor table entry address (EXC vectors)
287
 
288 6 zero_gravi
  csrr  ra, mepc          // get return address
289 2 zero_gravi
 
290
  blt   t0, zero, __crt0_neorv32_rte_is_irq  // branch if this is an INTERRUPT
291
 
292
 
293
  // --------------------------------------------
294
  // compute return address for EXCEPTIONS only
295
  // --------------------------------------------
296
__crt0_neorv32_rte_is_exc:
297
 
298
  // is faulting instruction compressed?
299 6 zero_gravi
  csrr  t0, mtinst
300
  andi  t0, t0, 2   // get compression flag (bit #1): 0=compressed, 1=uncompressed
301 2 zero_gravi
 
302 6 zero_gravi
  addi  ra, ra, +2  // only this for compressed instructions
303
  add   ra, ra, t0  // add another 2 (making +4) for uncompressed instructions
304 2 zero_gravi
  j __crt0_neorv32_rte_execute
305
 
306
 
307
  // --------------------------------------------
308
  // vector table offset for INTERRUPTS only
309
  // --------------------------------------------
310
__crt0_neorv32_rte_is_irq:
311
  addi  t1, t1, 16*4
312
 
313
 
314
  // --------------------------------------------
315
  // call handler from vector table
316
  // --------------------------------------------
317
__crt0_neorv32_rte_execute:
318
  lw    t0, 0(t1)       // get base address of second-level handler
319
 
320
  // push ra
321
  addi  sp, sp, -4
322
  sw    ra, 0(sp)
323
 
324
  jalr  ra, t0          // call second-level handler
325
 
326
  // pop ra
327
  lw    ra, 0(sp)
328
  addi  sp, sp, +4
329
 
330 6 zero_gravi
  csrw  mepc, ra
331 2 zero_gravi
 
332
 
333
  // --------------------------------------------
334
  // full context restore
335
  // --------------------------------------------
336
  lw    ra,0(sp)
337
  lw    gp,4(sp)
338
  lw    tp,8(sp)
339
  lw    t0,12(sp)
340
  lw    t1,16(sp)
341
  lw    t2,20(sp)
342
  lw    s0,24(sp)
343
  lw    s1,28(sp)
344
  lw    a0,32(sp)
345
  lw    a1,36(sp)
346
  lw    a2,40(sp)
347
  lw    a3,44(sp)
348
  lw    a4,48(sp)
349
  lw    a5,52(sp)
350
#ifndef __RISCV_EMBEDDED_CPU__
351
  lw    a6,56(sp)
352
  lw    a7,60(sp)
353
  lw    s2,64(sp)
354
  lw    s3,68(sp)
355
  lw    s4,72(sp)
356
  lw    s5,76(sp)
357
  lw    s6,80(sp)
358
  lw    s7,84(sp)
359
  lw    s8,88(sp)
360
  lw    s9,92(sp)
361
  lw    s10,96(sp)
362
  lw    s11,100(sp)
363
  lw    t3,104(sp)
364
  lw    t4,108(sp)
365
  lw    t5,112(sp)
366
  lw    t6,116(sp)
367
#endif
368
 
369
#ifndef __RISCV_EMBEDDED_CPU__
370
  addi  sp, sp, +120
371
#else
372
  addi  sp, sp, +56
373
#endif
374
 
375
 
376
  // --------------------------------------------
377
  // this is the ONLY place where MRET should be used!
378
  // --------------------------------------------
379
  mret
380
 
381
 
382
// *********************************************************
383
// Dummy exception handler: just move on to next instruction
384
// *********************************************************
385
__crt0_neorv32_rte_dummy_hanlder:
386
  ret
387
 
388
  .cfi_endproc
389
  .end

powered by: WebSVN 2.1.0

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