RV32 SoC DS UG
High-Perf RV32 SoC DS UG
RV64 SoC DS UG API and Examples
Embedded IDE UG
Loading...
Searching...
No Matches
riscv.h
Go to the documentation of this file.
1
2// Copyright (C) 2013-2026 Efinix Inc. All rights reserved.
3// Full license header bsp/efinix/EfxSapphireSocRV64/include/LICENSE.MD
5
6#ifndef RISC_V_H_
7#define RISC_V_H_
8
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21/* -----------------------------------------------------------------------------*/
22 /* HARDWARE ARCHITECTURE SANITY CHECKS */
23 /* -----------------------------------------------------------------------------*/
24#if (DEBUG_MODE == 1) && (ACTIVE_DEBUG_MOD & DBG_MOD_SYS)
25 #if __riscv_xlen == 32
26 #pragma message "BUILD INFO: RISCV-32 Architecture is detected."
27 #else
28 #pragma message "BUILD INFO: RISCV-64 Architecture is detected."
29 #endif
30
31 #ifdef __riscv_zicbom
32 #pragma message "BUILD INFO: Zicbom Extension enabled. Cache-block instructions are safe to use."
33 #else
34 #pragma message "BUILD INFO: Zicbom Extension NOT found."
35 #endif
36
37 #ifdef __riscv_flen
38 #if __riscv_flen == 64
39 #pragma message "BUILD INFO: FPU is enabled (Double Precision / 64-bit FPRs)"
40 #elif __riscv_flen == 32
41 #pragma message "BUILD INFO: FPU is enabled (Single Precision / 32-bit FPRs)"
42 #endif
43 #else
44 #pragma message "BUILD INFO: No FPU detected. Core is Integer only."
45 #endif
46#endif
47
74
75/* ========================================================================== */
76/* SUB-GROUP : REGISTER DEFINITIONS */
77/* ========================================================================== */
78
88 #define CAUSE_SUPERVISOR_SOFTWARE 1
89 #define CAUSE_MACHINE_SOFTWARE 3
90 #define CAUSE_USER_TIME 4
91 #define CAUSE_SUPERVISOR_TIMER 5
92 #define CAUSE_MACHINE_TIMER 7
93 #define CAUSE_USER_EXTERNAL 8
94 #define CAUSE_SCALL 9
95 #define CAUSE_MACHINE_EXTERNAL 11
97
101 #define CAUSE_INSTRUCTION_ADDR_MISALIGNED 0
102 #define CAUSE_ACCESS_FAULT 1
103 #define CAUSE_ILLEGAL_INSTRUCTION 2
104 #define CAUSE_BREAKPOINT 3
105 #define CAUSE_LOAD_ADDR_MISALIGNED 4
106 #define CAUSE_LOAD_ACCESS_FAULT 5
107 #define CAUSE_STORE_AMO_ADDR_MISALIGNED 6
108 #define CAUSE_STORE_AMO_ACCESS_FAULT 7
109 #define CAUSE_ENV_CALL_U_MODE 8
110 #define CAUSE_ENV_CALL_S_MODE 9
111 #define CAUSE_ENV_CALL_M_MODE 11
112 #define CAUSE_INSTRUCTION_PAGE_FAULT 12
113 #define CAUSE_LOAD_PAGE_FAULT 13
114 #define CAUSE_STORE_AMO_PAGE_FAULT 15
116
120 #define MEDELEG_INSTRUCTION_PAGE_FAULT (1 << 12)
121 #define MEDELEG_LOAD_PAGE_FAULT (1 << 13)
122 #define MEDELEG_STORE_PAGE_FAULT (1 << 15)
123 #define MEDELEG_USER_ENVIRONNEMENT_CALL (1 << 8)
124 #define MIDELEG_SUPERVISOR_SOFTWARE (1 << 1)
125 #define MIDELEG_SUPERVISOR_TIMER (1 << 5)
126 #define MIDELEG_SUPERVISOR_EXTERNAL (1 << 9)
131 #define MIE_MSIE (1 << CAUSE_MACHINE_SOFTWARE)
132 #define MIE_MTIE (1 << CAUSE_MACHINE_TIMER)
133 #define MIE_MEIE (1 << CAUSE_MACHINE_EXTERNAL)
138 #define RDCYCLE 0xC00
139 #define RDTIME 0xC01
140 #define RDINSTRET 0xC02
141 #define RDCYCLEH 0xC80
142 #define RDTIMEH 0xC81
143 #define RDINSTRETH 0xC82
146 #define MIP_STIP (1 << 5)
147 #define MSTATUS_UIE 0x00000001
148 #define MSTATUS_SIE 0x00000002
149 #define MSTATUS_HIE 0x00000004
150 #define MSTATUS_MIE 0x00000008
151 #define MSTATUS_UPIE 0x00000010
152 #define MSTATUS_SPIE 0x00000020
153 #define MSTATUS_HPIE 0x00000040
154 #define MSTATUS_MPIE 0x00000080
155 #define MSTATUS_SPP 0x00000100
156 #define MSTATUS_HPP 0x00000600
157 #define MSTATUS_MPP 0x00001800
158 #define MSTATUS_FS 0x00006000
159 #define MSTATUS_XS 0x00018000
160 #define MSTATUS_MPRV 0x00020000
161 #define MSTATUS_SUM 0x00040000
162 #define MSTATUS_MXR 0x00080000
163 #define MSTATUS_TVM 0x00100000
164 #define MSTATUS_TW 0x00200000
165 #define MSTATUS_TSR 0x00400000
166 #define MSTATUS32_SD 0x80000000
167 #define MSTATUS_UXL 0x0000000300000000
168 #define MSTATUS_SXL 0x0000000C00000000
169 #define MSTATUS64_SD 0x8000000000000000
170 #define SSTATUS_UIE 0x00000001
171 #define SSTATUS_SIE 0x00000002
172 #define SSTATUS_UPIE 0x00000010
173 #define SSTATUS_SPIE 0x00000020
174 #define SSTATUS_SPP 0x00000100
175 #define SSTATUS_FS 0x00006000
176 #define SSTATUS_XS 0x00018000
177 #define SSTATUS_SUM 0x00040000
178 #define SSTATUS_MXR 0x00080000
179 #define SSTATUS32_SD 0x80000000
180 #define SSTATUS_UXL 0x0000000300000000
181 #define SSTATUS64_SD 0x8000000000000000
182 #define PMP_R 0x01
183 #define PMP_W 0x02
184 #define PMP_X 0x04
185 #define PMP_A 0x18
186 #define PMP_L 0x80
187 #define PMP_SHIFT 2
188 #define PMP_TOR 0x08
189 #define PMP_NA4 0x10
190 #define PMP_NAPOT 0x18
192
194
195/* ========================================================================== */
196/* FUNCTION PROTOTYPES */
197/* ========================================================================== */
198
205
216 #define csr_swap(csr, val) \
217 ({ \
218 unsigned long __v = (unsigned long)(val); \
219 __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \
220 : "=r" (__v) : "rK" (__v)); \
221 __v; \
222 })
223
232 #define csr_read(csr) \
233 ({ \
234 register unsigned long __v; \
235 __asm__ __volatile__ ("csrr %0, " #csr \
236 : "=r" (__v)); \
237 __v; \
238 })
239
240
249 #define csr_write(csr, val) \
250 ({ \
251 unsigned long __v = (unsigned long)(val); \
252 __asm__ __volatile__ ("csrw " #csr ", %0" \
253 : : "rK" (__v)); \
254 })
255
265 #define csr_read_set(csr, val) \
266 ({ \
267 unsigned long __v = (unsigned long)(val); \
268 __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \
269 : "=r" (__v) : "rK" (__v)); \
270 __v; \
271 })
272
278 #define csr_set(csr, val) \
279 ({ \
280 unsigned long __v = (unsigned long)(val); \
281 __asm__ __volatile__ ("csrs " #csr ", %0" \
282 : : "rK" (__v)); \
283 })
284
291 #define csr_read_clear(csr, val) \
292 ({ \
293 unsigned long __v = (unsigned long)(val); \
294 __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \
295 : "=r" (__v) : "rK" (__v)); \
296 __v; \
297 })
298
307 #define csr_clear(csr, val) \
308 ({ \
309 unsigned long __v = (unsigned long)(val); \
310 __asm__ __volatile__ ("csrc " #csr ", %0" \
311 : : "rK" (__v)); \
312 })
313
315 /*******************************************************************************
316 * @brief Definition of symbolic constants for RISC-V registers.
317 * @note
318 * General-purpose registers (x0-x31):
319 * Lines 1-32 define constants regnum_x0 through regnum_x31 for the 32 general-
320 * purpose registers.
321 *
322 * Special-purpose registers:
323 * Lines 34-63 define constants for special-purpose registers such as zero, ra,
324 * sp, gp, tp, and the temporary registers t0-t6.
325 *
326 * Custom register:
327 * Line 65 defines a symbolic constant CUSTOM0 for a custom register, which
328 * could be used for a specific purpose defined by the programmer.
329 *
330 ******************************************************************************/
331 asm(".set regnum_x0 , 0");
332 asm(".set regnum_x1 , 1");
333 asm(".set regnum_x2 , 2");
334 asm(".set regnum_x3 , 3");
335 asm(".set regnum_x4 , 4");
336 asm(".set regnum_x5 , 5");
337 asm(".set regnum_x6 , 6");
338 asm(".set regnum_x7 , 7");
339 asm(".set regnum_x8 , 8");
340 asm(".set regnum_x9 , 9");
341 asm(".set regnum_x10 , 10");
342 asm(".set regnum_x11 , 11");
343 asm(".set regnum_x12 , 12");
344 asm(".set regnum_x13 , 13");
345 asm(".set regnum_x14 , 14");
346 asm(".set regnum_x15 , 15");
347 asm(".set regnum_x16 , 16");
348 asm(".set regnum_x17 , 17");
349 asm(".set regnum_x18 , 18");
350 asm(".set regnum_x19 , 19");
351 asm(".set regnum_x20 , 20");
352 asm(".set regnum_x21 , 21");
353 asm(".set regnum_x22 , 22");
354 asm(".set regnum_x23 , 23");
355 asm(".set regnum_x24 , 24");
356 asm(".set regnum_x25 , 25");
357 asm(".set regnum_x26 , 26");
358 asm(".set regnum_x27 , 27");
359 asm(".set regnum_x28 , 28");
360 asm(".set regnum_x29 , 29");
361 asm(".set regnum_x30 , 30");
362 asm(".set regnum_x31 , 31");
363 asm(".set regnum_zero, 0");
364 asm(".set regnum_ra , 1");
365 asm(".set regnum_sp , 2");
366 asm(".set regnum_gp , 3");
367 asm(".set regnum_tp , 4");
368 asm(".set regnum_t0 , 5");
369 asm(".set regnum_t1 , 6");
370 asm(".set regnum_t2 , 7");
371 asm(".set regnum_s0 , 8");
372 asm(".set regnum_s1 , 9");
373 asm(".set regnum_a0 , 10");
374 asm(".set regnum_a1 , 11");
375 asm(".set regnum_a2 , 12");
376 asm(".set regnum_a3 , 13");
377 asm(".set regnum_a4 , 14");
378 asm(".set regnum_a5 , 15");
379 asm(".set regnum_a6 , 16");
380 asm(".set regnum_a7 , 17");
381 asm(".set regnum_s2 , 18");
382 asm(".set regnum_s3 , 19");
383 asm(".set regnum_s4 , 20");
384 asm(".set regnum_s5 , 21");
385 asm(".set regnum_s6 , 22");
386 asm(".set regnum_s7 , 23");
387 asm(".set regnum_s8 , 24");
388 asm(".set regnum_s9 , 25");
389 asm(".set regnum_s10 , 26");
390 asm(".set regnum_s11 , 27");
391 asm(".set regnum_t3 , 28");
392 asm(".set regnum_t4 , 29");
393 asm(".set regnum_t5 , 30");
394 asm(".set regnum_t6 , 31");
395 asm(".set CUSTOM0 , 0x0B");
396 asm(".set CUSTOM1 , 0x2B");
397 asm(".set CUSTOM2 , 0x5B");
399
414 #define opcode_R(opcode, func3, func7, rs1, rs2) \
415 ({ \
416 register unsigned long __v; \
417 asm volatile( \
418 ".word ((" #opcode ") | (regnum_%0 << 7) | (regnum_%1 << 15) | (regnum_%2 << 20) | ((" #func3 ") << 12) | ((" #func7 ") << 25));" \
419 : [rd] "=r" (__v) \
420 : "r" (rs1), "r" (rs2) \
421 ); \
422 __v; \
423 })
424
432 #define cfu_type_R(func3, func7, rs1, rs2) opcode_R(CUSTOM0, func3, func7, rs1, rs2)
433
442 #define cfu_push(func3, func7, rs1, rs2) opcode_R(CUSTOM1, func3, func7, rs1, rs2)
443 #define cfu_pop2() ({ register unsigned long __v; asm volatile( ".word ((0x5B) | (regnum_%0 << 7));" : [rd] "=r" (__v) : ); __v; })
444 #define cfu_pop() \
445 ({ \
446 register unsigned long __v; \
447 asm volatile( \
448 ".word ((0x5B) | (regnum_%0 << 7));" \
449 : [rd] "=r" (__v) \
450 : \
451 ); \
452 __v; \
453 })
454 // End of RISCV_Funcs group
456
457#ifdef __cplusplus
458}
459#endif // C_plusplus
460 // End of RISCV Group
462#endif //RISC_V_H_