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

Subversion Repositories neorv32

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

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