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

Subversion Repositories neorv32

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

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

powered by: WebSVN 2.1.0

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