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

Subversion Repositories neorv32

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

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

Line No. Rev Author Line
1 2 zero_gravi
/* ################################################################################################# */
2
/* # << NEORV32 - crt0.S - Application Start-Up Code >>                                            # */
3
/* # ********************************************************************************************* # */
4
/* # The start-up code provides a minimal runtime environment that catches all exceptions/         # */
5
/* # 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
  csrrw x11, CSR_MDSPACEBASE, zero // data memory space base address
121
  csrrw x12, CSR_MDSPACESIZE, zero // data memory space size
122
  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
  csrrw zero, mtvec, x11 // set address of first-level exception handler
143
 
144
  csrrw x11, CSR_MDSPACEBASE, zero // data memory space base address
145
  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
  csrrw t0, mcause, zero  // get cause code
282
 
283
  andi  t1, t0, 0x0f      // isolate cause ID
284
  slli  t1, t1, 2         // make address offset
285
  csrrw ra, CSR_MDSPACEBASE, zero  // data memory space base address
286
  add   t1, t1, ra        // get vetor table entry address (EXC vectors)
287
 
288
  csrrw ra, mepc, zero    // get return address
289
 
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
  csrrw t0, mtinst, zero
300
  andi  t0, t0, 2   // get compression flag (bit #1): 0=compressed, 2=uncompressed
301
 
302
  addi  ra, ra, +2  // only this for compressed instr
303
  add   ra, ra, t0  // add another 2 (0+4) for uncompressed instr
304
  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
csrrw zero, mscratch, ra
324
 
325
  jalr  ra, t0          // call second-level handler
326
 
327
  // pop ra
328
  lw    ra, 0(sp)
329
  addi  sp, sp, +4
330
 
331
  csrrw zero, mepc, ra
332
 
333
 
334
  // --------------------------------------------
335
  // full context restore
336
  // --------------------------------------------
337
  lw    ra,0(sp)
338
  lw    gp,4(sp)
339
  lw    tp,8(sp)
340
  lw    t0,12(sp)
341
  lw    t1,16(sp)
342
  lw    t2,20(sp)
343
  lw    s0,24(sp)
344
  lw    s1,28(sp)
345
  lw    a0,32(sp)
346
  lw    a1,36(sp)
347
  lw    a2,40(sp)
348
  lw    a3,44(sp)
349
  lw    a4,48(sp)
350
  lw    a5,52(sp)
351
#ifndef __RISCV_EMBEDDED_CPU__
352
  lw    a6,56(sp)
353
  lw    a7,60(sp)
354
  lw    s2,64(sp)
355
  lw    s3,68(sp)
356
  lw    s4,72(sp)
357
  lw    s5,76(sp)
358
  lw    s6,80(sp)
359
  lw    s7,84(sp)
360
  lw    s8,88(sp)
361
  lw    s9,92(sp)
362
  lw    s10,96(sp)
363
  lw    s11,100(sp)
364
  lw    t3,104(sp)
365
  lw    t4,108(sp)
366
  lw    t5,112(sp)
367
  lw    t6,116(sp)
368
#endif
369
 
370
#ifndef __RISCV_EMBEDDED_CPU__
371
  addi  sp, sp, +120
372
#else
373
  addi  sp, sp, +56
374
#endif
375
 
376
 
377
  // --------------------------------------------
378
  // this is the ONLY place where MRET should be used!
379
  // --------------------------------------------
380
  mret
381
 
382
 
383
// *********************************************************
384
// Dummy exception handler: just move on to next instruction
385
// *********************************************************
386
__crt0_neorv32_rte_dummy_hanlder:
387
  ret
388
 
389
  .cfi_endproc
390
  .end

powered by: WebSVN 2.1.0

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