NEORV32 - Software Framework Documentation
Loading...
Searching...
No Matches
neorv32_cpu.h
Go to the documentation of this file.
1// #################################################################################################
2// # << NEORV32: neorv32_cpu.h - CPU Core Functions HW Driver >> #
3// # ********************************************************************************************* #
4// # BSD 3-Clause License #
5// # #
6// # Copyright (c) 2024, 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
36/**********************************************************************/
41#ifndef neorv32_cpu_h
42#define neorv32_cpu_h
43
44
45/**********************************************************************/
49uint64_t neorv32_cpu_get_cycle(void);
50void neorv32_cpu_set_mcycle(uint64_t value);
51uint64_t neorv32_cpu_get_instret(void);
52void neorv32_cpu_set_minstret(uint64_t value);
53void neorv32_cpu_delay_ms(uint32_t time_ms);
54uint32_t neorv32_cpu_get_clk_from_prsc(int prsc);
57int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config);
59uint32_t neorv32_cpu_hpm_get_size(void);
64// #################################################################################################
65// Context save/restore helpers
66// #################################################################################################
67
68/**********************************************************************/
74inline void __attribute__ ((always_inline)) neorv32_context_save(void) {
75
76 // do not backup x0 and sp
77 asm volatile (
78#ifndef __riscv_32e
79 "addi sp, sp, -30*4 \n"
80#else
81 "addi sp, sp, -14*4 \n"
82#endif
83 "sw x1, 0*4(sp) \n"
84 "sw x3, 1*4(sp) \n"
85 "sw x4, 2*4(sp) \n"
86 "sw x5, 3*4(sp) \n"
87 "sw x6, 4*4(sp) \n"
88 "sw x7, 5*4(sp) \n"
89 "sw x8, 6*4(sp) \n"
90 "sw x9, 7*4(sp) \n"
91 "sw x10, 8*4(sp) \n"
92 "sw x11, 9*4(sp) \n"
93 "sw x12, 10*4(sp) \n"
94 "sw x13, 11*4(sp) \n"
95 "sw x14, 12*4(sp) \n"
96 "sw x15, 13*4(sp) \n"
97#ifndef __riscv_32e
98 "sw x16, 14*4(sp) \n"
99 "sw x17, 15*4(sp) \n"
100 "sw x18, 16*4(sp) \n"
101 "sw x19, 17*4(sp) \n"
102 "sw x20, 18*4(sp) \n"
103 "sw x21, 19*4(sp) \n"
104 "sw x22, 20*4(sp) \n"
105 "sw x23, 21*4(sp) \n"
106 "sw x24, 22*4(sp) \n"
107 "sw x25, 23*4(sp) \n"
108 "sw x26, 24*4(sp) \n"
109 "sw x27, 25*4(sp) \n"
110 "sw x28, 26*4(sp) \n"
111 "sw x29, 27*4(sp) \n"
112 "sw x30, 28*4(sp) \n"
113 "sw x31, 29*4(sp) \n"
114#endif
115 );
116}
117
118
119/**********************************************************************/
125inline void __attribute__ ((always_inline)) neorv32_context_restore(void) {
126
127 // do not restore x0 and sp
128 asm volatile (
129 "lw x1, 0*4(sp) \n"
130 "lw x3, 1*4(sp) \n"
131 "lw x4, 2*4(sp) \n"
132 "lw x5, 3*4(sp) \n"
133 "lw x6, 4*4(sp) \n"
134 "lw x7, 5*4(sp) \n"
135 "lw x8, 6*4(sp) \n"
136 "lw x9, 7*4(sp) \n"
137 "lw x10, 8*4(sp) \n"
138 "lw x11, 9*4(sp) \n"
139 "lw x12, 10*4(sp) \n"
140 "lw x13, 11*4(sp) \n"
141 "lw x14, 12*4(sp) \n"
142 "lw x15, 13*4(sp) \n"
143#ifndef __riscv_32e
144 "lw x16, 14*4(sp) \n"
145 "lw x17, 15*4(sp) \n"
146 "lw x18, 16*4(sp) \n"
147 "lw x19, 17*4(sp) \n"
148 "lw x20, 18*4(sp) \n"
149 "lw x21, 19*4(sp) \n"
150 "lw x22, 20*4(sp) \n"
151 "lw x23, 21*4(sp) \n"
152 "lw x24, 22*4(sp) \n"
153 "lw x25, 23*4(sp) \n"
154 "lw x26, 24*4(sp) \n"
155 "lw x27, 25*4(sp) \n"
156 "lw x28, 26*4(sp) \n"
157 "lw x29, 27*4(sp) \n"
158 "lw x30, 28*4(sp) \n"
159 "lw x31, 29*4(sp) \n"
160#endif
161#ifndef __riscv_32e
162 "addi sp, sp, +30*4 \n"
163#else
164 "addi sp, sp, +14*4 \n"
165#endif
166 "ret \n"
167 );
168}
169
170
171// #################################################################################################
172// Load/store helpers
173// #################################################################################################
174
175
176/**********************************************************************/
184inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata) {
185
186 uint32_t reg_addr = addr;
187 uint32_t reg_data = wdata;
188
189 asm volatile ("sw %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
190}
191
192
193/**********************************************************************/
201inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata) {
202
203 uint32_t reg_addr = addr;
204 uint32_t reg_data = (uint32_t)wdata;
205
206 asm volatile ("sh %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
207}
208
209
210/**********************************************************************/
216inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata) {
217
218 uint32_t reg_addr = addr;
219 uint32_t reg_data = (uint32_t)wdata;
220
221 asm volatile ("sb %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
222}
223
224
225/**********************************************************************/
233inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_word(uint32_t addr) {
234
235 uint32_t reg_addr = addr;
236 uint32_t reg_data;
237
238 asm volatile ("lw %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
239
240 return reg_data;
241}
242
243
244/**********************************************************************/
252inline uint16_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_half(uint32_t addr) {
253
254 uint32_t reg_addr = addr;
255 uint16_t reg_data;
256
257 asm volatile ("lhu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
258
259 return reg_data;
260}
261
262
263/**********************************************************************/
271inline int16_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_half(uint32_t addr) {
272
273 uint32_t reg_addr = addr;
274 int16_t reg_data;
275
276 asm volatile ("lh %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
277
278 return reg_data;
279}
280
281
282/**********************************************************************/
288inline uint8_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_byte(uint32_t addr) {
289
290 uint32_t reg_addr = addr;
291 uint8_t reg_data;
292
293 asm volatile ("lbu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
294
295 return reg_data;
296}
297
298
299/**********************************************************************/
305inline int8_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_byte(uint32_t addr) {
306
307 uint32_t reg_addr = addr;
308 int8_t reg_data;
309
310 asm volatile ("lb %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
311
312 return reg_data;
313}
314
315
316// #################################################################################################
317// Atomic memory access / load-reservate/store-conditional helpers
318// #################################################################################################
319
320
321/**********************************************************************/
330inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_reservate_word(uint32_t addr) {
331
332#if defined __riscv_atomic
333 uint32_t amo_addr = addr;
334 uint32_t amo_rdata;
335
336 asm volatile ("lr.w %[dst], 0(%[addr])" : [dst] "=r" (amo_rdata) : [addr] "r" (amo_addr));
337
338 return amo_rdata;
339#else
340 (void)addr;
341
342 return 0;
343#endif
344}
345
346
347/**********************************************************************/
357inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_store_conditional_word(uint32_t addr, uint32_t wdata) {
358
359#if defined __riscv_atomic
360 uint32_t amo_addr = addr;
361 uint32_t amo_wdata = wdata;
362 uint32_t amo_status;
363
364 asm volatile ("sc.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_status) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
365
366 return amo_status;
367#else
368 (void)addr;
369 (void)wdata;
370
371 return 1; // always fail
372#endif
373}
374
375
376/**********************************************************************/
381inline void __attribute__ ((always_inline)) neorv32_cpu_invalidate_reservations(void) {
382
383#if defined __riscv_atomic
384 asm volatile ("sc.w zero, zero, (zero)");
385#endif
386}
387
388
389// #################################################################################################
390// CSR access helpers
391// #################################################################################################
392
393
394/**********************************************************************/
400inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_read(const int csr_id) {
401
402 uint32_t csr_data;
403
404 asm volatile ("csrr %[result], %[input_i]" : [result] "=r" (csr_data) : [input_i] "i" (csr_id));
405
406 return csr_data;
407}
408
409
410/**********************************************************************/
416inline void __attribute__ ((always_inline)) neorv32_cpu_csr_write(const int csr_id, uint32_t data) {
417
418 uint32_t csr_data = data;
419
420 asm volatile ("csrw %[input_i], %[input_j]" : : [input_i] "i" (csr_id), [input_j] "r" (csr_data));
421}
422
423
424/**********************************************************************/
430inline void __attribute__ ((always_inline)) neorv32_cpu_csr_set(const int csr_id, uint32_t mask) {
431
432 uint32_t csr_data = mask;
433
434 asm volatile ("csrs %[input_i], %[input_j]" : : [input_i] "i" (csr_id), [input_j] "r" (csr_data));
435}
436
437
438/**********************************************************************/
444inline void __attribute__ ((always_inline)) neorv32_cpu_csr_clr(const int csr_id, uint32_t mask) {
445
446 uint32_t csr_data = mask;
447
448 asm volatile ("csrc %[input_i], %[input_j]" : : [input_i] "i" (csr_id), [input_j] "r" (csr_data));
449}
450
451
452// #################################################################################################
453// Misc helpers
454// #################################################################################################
455
456/**********************************************************************/
462inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
463
464 asm volatile ("wfi");
465}
466
467
468#endif // neorv32_cpu_h
void neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:184
void neorv32_context_restore(void)
Definition neorv32_cpu.h:125
void neorv32_cpu_set_mcycle(uint64_t value)
Definition neorv32_cpu.c:99
void neorv32_cpu_csr_set(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:430
uint32_t neorv32_cpu_pmp_get_num_regions(void)
Definition neorv32_cpu.c:257
void neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata)
Definition neorv32_cpu.h:201
int8_t neorv32_cpu_load_signed_byte(uint32_t addr)
Definition neorv32_cpu.h:305
uint16_t neorv32_cpu_load_unsigned_half(uint32_t addr)
Definition neorv32_cpu.h:252
uint64_t neorv32_cpu_get_instret(void)
Definition neorv32_cpu.c:120
uint32_t neorv32_cpu_load_unsigned_word(uint32_t addr)
Definition neorv32_cpu.h:233
void neorv32_cpu_set_minstret(uint64_t value)
Definition neorv32_cpu.c:149
uint32_t neorv32_cpu_hpm_get_num_counters(void)
Definition neorv32_cpu.c:395
uint32_t neorv32_cpu_load_reservate_word(uint32_t addr)
Definition neorv32_cpu.h:330
void neorv32_cpu_sleep(void)
Definition neorv32_cpu.h:462
uint32_t neorv32_cpu_get_clk_from_prsc(int prsc)
Definition neorv32_cpu.c:224
void neorv32_cpu_invalidate_reservations(void)
Definition neorv32_cpu.h:381
int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config)
Definition neorv32_cpu.c:344
void neorv32_cpu_delay_ms(uint32_t time_ms)
Definition neorv32_cpu.c:174
uint32_t neorv32_cpu_csr_read(const int csr_id)
Definition neorv32_cpu.h:400
uint32_t neorv32_cpu_store_conditional_word(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:357
void neorv32_cpu_csr_clr(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:444
void neorv32_context_save(void)
Definition neorv32_cpu.h:74
uint64_t neorv32_cpu_get_cycle(void)
Definition neorv32_cpu.c:70
uint8_t neorv32_cpu_load_unsigned_byte(uint32_t addr)
Definition neorv32_cpu.h:288
void neorv32_cpu_goto_user_mode(void)
Definition neorv32_cpu.c:468
uint32_t neorv32_cpu_pmp_get_granularity(void)
Definition neorv32_cpu.c:302
uint32_t neorv32_cpu_hpm_get_size(void)
Definition neorv32_cpu.c:430
int16_t neorv32_cpu_load_signed_half(uint32_t addr)
Definition neorv32_cpu.h:271
void neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata)
Definition neorv32_cpu.h:216
void neorv32_cpu_csr_write(const int csr_id, uint32_t data)
Definition neorv32_cpu.h:416