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

Subversion Repositories neorv32

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

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

Line No. Rev Author Line
1 2 zero_gravi
/* ################################################################################################# */
2 21 zero_gravi
/* # << NEORV32 - crt0.S - Start-Up Code >>                                                        # */
3 2 zero_gravi
/* # ********************************************************************************************* # */
4
/* # BSD 3-Clause License                                                                          # */
5
/* #                                                                                               # */
6
/* # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     # */
7
/* #                                                                                               # */
8
/* # Redistribution and use in source and binary forms, with or without modification, are          # */
9
/* # permitted provided that the following conditions are met:                                     # */
10
/* #                                                                                               # */
11
/* # 1. Redistributions of source code must retain the above copyright notice, this list of        # */
12
/* #    conditions and the following disclaimer.                                                   # */
13
/* #                                                                                               # */
14
/* # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     # */
15
/* #    conditions and the following disclaimer in the documentation and/or other materials        # */
16
/* #    provided with the distribution.                                                            # */
17
/* #                                                                                               # */
18
/* # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  # */
19
/* #    endorse or promote products derived from this software without specific prior written      # */
20
/* #    permission.                                                                                # */
21
/* #                                                                                               # */
22
/* # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   # */
23
/* # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               # */
24
/* # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    # */
25
/* # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     # */
26
/* # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # */
27
/* # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    # */
28
/* # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     # */
29
/* # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  # */
30
/* # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            # */
31
/* # ********************************************************************************************* # */
32
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting # */
33
/* ################################################################################################# */
34
 
35 21 zero_gravi
.file   "crt0.S"
36
.section .text.boot
37
.balign 4
38
.global _start
39 2 zero_gravi
 
40
 
41 21 zero_gravi
// IO region
42 47 zero_gravi
.equ IO_BEGIN, 0xFFFFFF00 // start of processor-internal IO region
43 2 zero_gravi
 
44
 
45
_start:
46 21 zero_gravi
.cfi_startproc
47
.cfi_undefined ra
48 2 zero_gravi
 
49
// *********************************************************
50 52 zero_gravi
// Clear integer register file (lower half, assume E extension)
51 2 zero_gravi
// *********************************************************
52
__crt0_reg_file_clear:
53 32 zero_gravi
//addi  x0, x0, 0 // hardwired to zero
54
  addi  x1, x0, 0
55
  addi  x2, x0, 0
56
  addi  x3, x0, 0
57
  addi  x4, x0, 0
58
  addi  x5, x0, 0
59
  addi  x6, x0, 0
60
  addi  x7, x0, 0
61
  addi  x8, x0, 0
62
  addi  x9, x0, 0
63
//addi x10, x0, 0
64
//addi x11, x0, 0
65
//addi x12, x0, 0
66
//addi x13, x0, 0
67
  addi x14, x0, 0
68
  addi x15, x0, 0
69 2 zero_gravi
 
70
 
71
// *********************************************************
72 52 zero_gravi
// Initialize dummy trap handler base address
73 32 zero_gravi
// *********************************************************
74 52 zero_gravi
__crt0_neorv32_trap_init:
75
  la    x11, __crt0_dummy_trap_handler
76
  csrw  mtvec, x11 // set address of first-level exception handler
77
 
78
 
79
// *********************************************************
80
// Clear integer register file (upper half, if no E extension)
81
// *********************************************************
82 32 zero_gravi
#ifndef __riscv_32e
83 52 zero_gravi
// DO NOT DO THIS if compiling bootloader (to save some program space)
84 32 zero_gravi
#ifndef make_bootloader
85
  addi x16, x0, 0
86
  addi x17, x0, 0
87
  addi x18, x0, 0
88
  addi x19, x0, 0
89
  addi x20, x0, 0
90
  addi x21, x0, 0
91
  addi x22, x0, 0
92
  addi x23, x0, 0
93
  addi x24, x0, 0
94
  addi x25, x0, 0
95
  addi x26, x0, 0
96
  addi x27, x0, 0
97
  addi x28, x0, 0
98
  addi x29, x0, 0
99
  addi x30, x0, 0
100
  addi x31, x0, 0
101
#endif
102
#endif
103
 
104
 
105
// *********************************************************
106 52 zero_gravi
// Clear floating-point register file (if F extension enabled)
107
// *********************************************************
108
#ifdef __riscv_flen
109
// DO NOT DO THIS if compiling bootloader (to save some program space)
110
#ifndef make_bootloader
111
  fmv.s.x f0,  x0
112
  fmv.s.x f1,  x0
113
  fmv.s.x f2,  x0
114
  fmv.s.x f3,  x0
115
  fmv.s.x f4,  x0
116
  fmv.s.x f5,  x0
117
  fmv.s.x f6,  x0
118
  fmv.s.x f7,  x0
119
  fmv.s.x f8,  x0
120
  fmv.s.x f9,  x0
121
  fmv.s.x f10, x0
122
  fmv.s.x f11, x0
123
  fmv.s.x f12, x0
124
  fmv.s.x f13, x0
125
  fmv.s.x f14, x0
126
  fmv.s.x f15, x0
127
  fmv.s.x f16, x0
128
  fmv.s.x f17, x0
129
  fmv.s.x f18, x0
130
  fmv.s.x f19, x0
131
  fmv.s.x f20, x0
132
  fmv.s.x f21, x0
133
  fmv.s.x f22, x0
134
  fmv.s.x f23, x0
135
  fmv.s.x f24, x0
136
  fmv.s.x f25, x0
137
  fmv.s.x f26, x0
138
  fmv.s.x f27, x0
139
  fmv.s.x f28, x0
140
  fmv.s.x f29, x0
141
  fmv.s.x f30, x0
142
  fmv.s.x f31, x0
143
#endif
144
#endif
145
 
146
 
147
// *********************************************************
148 23 zero_gravi
// No interrupts, thanks
149 2 zero_gravi
// *********************************************************
150 23 zero_gravi
__crt0_status_init:
151
  li x10, 0x00001800    // clear mstatus and set mpp(1:0)
152
  csrrw zero, mstatus, x10
153
  csrrw zero, mie, zero // clear mie
154 2 zero_gravi
 
155
 
156
// *********************************************************
157 39 zero_gravi
// Setup pointers using linker script symbols
158 2 zero_gravi
// *********************************************************
159 23 zero_gravi
__crt0_pointer_init:
160 21 zero_gravi
.option push
161
.option norelax
162 23 zero_gravi
  la    sp, __crt0_stack_begin
163
  andi  sp, sp, 0xfffffffc // make sure this is aligned
164
  addi  fp, sp, 0          // frame pointer = stack pointer
165
  la gp, __global_pointer$ // global pointer
166 21 zero_gravi
.option pop
167 2 zero_gravi
 
168
 
169
// *********************************************************
170
// Reset/deactivate IO/peripheral devices
171
// Devices, that are not implemented, will cause a store access fault
172
// which is captured but actually ignored due to the dummy handler.
173
// *********************************************************
174
__crt0_reset_io:
175
  li x11, IO_BEGIN // start of processor-internal IO region
176
 
177
__crt0_reset_io_loop:
178
  sw   zero, 0(x11)
179
  addi x11, x11, 4
180
  bne  zero, x11, __crt0_reset_io_loop
181
 
182
 
183
// *********************************************************
184 23 zero_gravi
// Clear .bss section (byte-wise) using linker script symbols
185 2 zero_gravi
// *********************************************************
186
__crt0_clear_bss:
187
  la x11, __crt0_bss_start
188
  la x12, __crt0_bss_end
189
 
190
__crt0_clear_bss_loop:
191
  bge  x11, x12, __crt0_clear_bss_loop_end
192
  sb   zero, 0(x11)
193
  addi x11, x11, 1
194
  j    __crt0_clear_bss_loop
195
 
196
__crt0_clear_bss_loop_end:
197
 
198
 
199
// *********************************************************
200 23 zero_gravi
// Copy initialized .data section from ROM to RAM (byte-wise) using linker script symbols
201 2 zero_gravi
// *********************************************************
202
__crt0_copy_data:
203
  la x11, __crt0_copy_data_src_begin  // start of data area (copy source)
204
  la x12, __crt0_copy_data_dst_begin  // start of data area (copy destination)
205
  la x13, __crt0_copy_data_dst_end    // last address of destination data area
206
 
207
__crt0_copy_data_loop:
208
  bge  x12, x13,  __crt0_copy_data_loop_end
209
  lb   x14, 0(x11)
210
  sb   x14, 0(x12)
211
  addi x11, x11, 1
212
  addi x12, x12, 1
213
  j    __crt0_copy_data_loop
214
 
215
__crt0_copy_data_loop_end:
216
 
217
 
218
// *********************************************************
219 39 zero_gravi
// Call main function
220 2 zero_gravi
// *********************************************************
221
__crt0_main_entry:
222
 
223 39 zero_gravi
  // setup arguments for calling main
224 2 zero_gravi
  addi x10, zero, 0 // argc = 0
225
  addi x11, zero, 0 // argv = 0
226
 
227 39 zero_gravi
  // clear cycle and instruction counters
228
  csrw mcycle,    zero
229
  csrw mcycleh,   zero
230
  csrw minstret,  zero
231
  csrw minstreth, zero
232 41 zero_gravi
  // enable read-access from user-mode for cycle[h], time[h] and instret[h]
233
  csrwi 0x306, 7 // mcounteren
234
  // enable auto-increment of all counters
235
  csrw 0x320, x0 // mcountinhibit
236 39 zero_gravi
 
237 40 zero_gravi
  // restore mcause reset value (so that 'main' knows we are coming from reset)
238
  li x12, 0x80000000
239
  csrw mcause, x12
240
 
241
  // call actual app's main function
242 2 zero_gravi
  jal ra, main
243
 
244
 
245
// *********************************************************
246
// Go to endless sleep mode if main returns
247
// *********************************************************
248
__crt0_this_is_the_end:
249 11 zero_gravi
  csrrci zero, mstatus, 8 // mstatus: disable global IRQs (MIE)
250 39 zero_gravi
  nop
251 2 zero_gravi
  wfi
252 39 zero_gravi
__crt0_this_is_the_end_my_friend:
253
  j __crt0_this_is_the_end_my_friend // in case WFI is not available
254 2 zero_gravi
 
255
 
256
// *********************************************************
257 14 zero_gravi
// dummy trap handler (for exceptions & IRQs)
258
// tries to move on to next instruction
259 2 zero_gravi
// *********************************************************
260 21 zero_gravi
.global __crt0_dummy_trap_handler
261
.balign 4
262 14 zero_gravi
__crt0_dummy_trap_handler:
263 2 zero_gravi
 
264 14 zero_gravi
  addi  sp, sp, -8
265
  sw      x8, 0(sp)
266
  sw      x9, 4(sp)
267 2 zero_gravi
 
268 14 zero_gravi
  csrr  x8, mcause
269
  blt   x8, zero, __crt0_dummy_trap_handler_irq  // skip mepc modification if interrupt
270 2 zero_gravi
 
271 14 zero_gravi
  csrr  x8, mepc
272 2 zero_gravi
 
273 14 zero_gravi
// is compressed instruction?
274 23 zero_gravi
__crt0_dummy_trap_handler_exc_c_check:
275 14 zero_gravi
  lh    x9, 0(x8)   // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
276
  andi  x9, x9, 3   // mask: isolate lowest 2 opcode bits (= 11 for uncompressed instructions)
277 2 zero_gravi
 
278 14 zero_gravi
  addi  x8, x8, +2  // only this for compressed instructions
279
  csrw  mepc, x8    // set return address when compressed instruction
280 2 zero_gravi
 
281 14 zero_gravi
  addi  x8, zero, 3
282
  bne   x8, x9, __crt0_dummy_trap_handler_irq // jump if compressed instruction
283 7 zero_gravi
 
284 14 zero_gravi
// is uncompressed instruction
285 23 zero_gravi
__crt0_dummy_trap_handler_exc_uncrompressed:
286 14 zero_gravi
  csrr  x8, mepc
287
  addi  x8, x8, +2  // add another 2 (making +4) for uncompressed instructions
288
  csrw  mepc, x8
289 2 zero_gravi
 
290 14 zero_gravi
__crt0_dummy_trap_handler_irq:
291 2 zero_gravi
 
292 23 zero_gravi
  lw    x9, 0(sp)
293
  lw    x8, 4(sp)
294
  addi  sp, sp, +8
295 2 zero_gravi
 
296
  mret
297
 
298 21 zero_gravi
.cfi_endproc
299
.end

powered by: WebSVN 2.1.0

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