1 /********************************** (C) COPYRIGHT  *******************************
2  * File Name          : core_riscv.c
3  * Author             : WCH
4  * Version            : V1.0.0
5  * Date               : 2020/04/30
6  * Description        : RISC-V Core Peripheral Access Layer Source File
7  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
8  * SPDX-License-Identifier: Apache-2.0
9  *******************************************************************************/
10 #include <stdint.h>
11 
12 /* define compiler specific symbols */
13 #if defined(__CC_ARM)
14   #define __ASM       __asm     /*!< asm keyword for ARM Compiler          */
15   #define __INLINE    __inline  /*!< inline keyword for ARM Compiler       */
16 
17 #elif defined(__ICCARM__)
18   #define __ASM       __asm   /*!< asm keyword for IAR Compiler          */
19   #define __INLINE    inline  /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
20 
21 #elif defined(__GNUC__)
22   #define __ASM       __asm   /*!< asm keyword for GNU Compiler          */
23   #define __INLINE    inline  /*!< inline keyword for GNU Compiler       */
24 
25 #elif defined(__TASKING__)
26   #define __ASM       __asm   /*!< asm keyword for TASKING Compiler      */
27   #define __INLINE    inline  /*!< inline keyword for TASKING Compiler   */
28 
29 #endif
30 
31 /*********************************************************************
32  * @fn      __get_FFLAGS
33  *
34  * @brief   Return the Floating-Point Accrued Exceptions
35  *
36  * @return  fflags value
37  */
__get_FFLAGS(void)38 uint32_t __get_FFLAGS(void)
39 {
40     uint32_t result;
41 
42     __ASM volatile("csrr %0,""fflags": "=r"(result));
43     return (result);
44 }
45 
46 /*********************************************************************
47  * @fn      __set_FFLAGS
48  *
49  * @brief   Set the Floating-Point Accrued Exceptions
50  *
51  * @param   value  - set FFLAGS value
52  *
53  * @return  none
54  */
__set_FFLAGS(uint32_t value)55 void __set_FFLAGS(uint32_t value)
56 {
57     __ASM volatile("csrw fflags, %0":: "r"(value));
58 }
59 
60 /*********************************************************************
61  * @fn      __get_FRM
62  *
63  * @brief   Return the Floating-Point Dynamic Rounding Mode
64  *
65  * @return  frm value
66  */
__get_FRM(void)67 uint32_t __get_FRM(void)
68 {
69     uint32_t result;
70 
71     __ASM volatile("csrr %0,""frm": "=r"(result));
72     return (result);
73 }
74 
75 /*********************************************************************
76  * @fn      __set_FRM
77  *
78  * @brief   Set the Floating-Point Dynamic Rounding Mode
79  *
80  * @param   value  - set frm value
81  *
82  * @return  none
83  */
__set_FRM(uint32_t value)84 void __set_FRM(uint32_t value)
85 {
86     __ASM volatile("csrw frm, %0" :: "r"(value));
87 }
88 
89 /*********************************************************************
90  * @fn      __get_FCSR
91  *
92  * @brief   Return the Floating-Point Control and Status Register
93  *
94  * @return  fcsr value
95  */
__get_FCSR(void)96 uint32_t __get_FCSR(void)
97 {
98     uint32_t result;
99 
100     __ASM volatile("csrr %0," "fcsr" : "=r"(result));
101     return (result);
102 }
103 
104 /*********************************************************************
105  * @fn      __set_FCSR
106  *
107  * @brief   Set the Floating-Point Dynamic Rounding Mode
108  *
109  * @param   value  - set fcsr value
110  *
111  * @return  none
112  */
__set_FCSR(uint32_t value)113 void __set_FCSR(uint32_t value)
114 {
115     __ASM volatile("csrw fcsr, %0" : : "r"(value));
116 }
117 
118 /*********************************************************************
119  * @fn      __get_MSTATUS
120  *
121  * @brief   Return the Machine Status Register
122  *
123  * @return  mstatus value
124  */
__get_MSTATUS(void)125 uint32_t __get_MSTATUS(void)
126 {
127     uint32_t result;
128 
129     __ASM volatile("csrr %0," "mstatus": "=r"(result));
130     return (result);
131 }
132 
133 /*********************************************************************
134  * @fn      __set_MSTATUS
135  *
136  * @brief   Set the Machine Status Register
137  *
138  * @param   value  - set mstatus value
139  *
140  * @return  none
141  */
__set_MSTATUS(uint32_t value)142 void __set_MSTATUS(uint32_t value)
143 {
144     __ASM volatile("csrw mstatus, %0" : : "r"(value));
145 }
146 
147 /*********************************************************************
148  * @fn      __get_MISA
149  *
150  * @brief   Return the Machine ISA Register
151  *
152  * @return  misa value
153  */
__get_MISA(void)154 uint32_t __get_MISA(void)
155 {
156     uint32_t result;
157 
158     __ASM volatile("csrr %0,""misa" : "=r"(result));
159     return (result);
160 }
161 
162 /*********************************************************************
163  * @fn      __set_MISA
164  *
165  * @brief   Set the Machine ISA Register
166  *
167  * @param   value  - set misa value
168  *
169  * @return  none
170  */
__set_MISA(uint32_t value)171 void __set_MISA(uint32_t value)
172 {
173     __ASM volatile("csrw misa, %0" : : "r"(value));
174 }
175 
176 /*********************************************************************
177  * @fn      __get_MIE
178  *
179  * @brief   Return the Machine Interrupt Enable Register
180  *
181  * @return  mie value
182  */
__get_MIE(void)183 uint32_t __get_MIE(void)
184 {
185     uint32_t result;
186 
187     __ASM volatile("csrr %0," "mie": "=r"(result));
188     return (result);
189 }
190 
191 /*********************************************************************
192  * @fn      __set_MISA
193  *
194  * @brief   Set the Machine ISA Register
195  *
196  * @param   value  - set mie value
197  *
198  * @return  none
199  */
__set_MIE(uint32_t value)200 void __set_MIE(uint32_t value)
201 {
202     __ASM volatile("csrw mie, %0": : "r"(value));
203 }
204 
205 /*********************************************************************
206  * @fn      __get_MTVEC
207  *
208  * @brief   Return the Machine Trap-Vector Base-Address Register
209  *
210  * @return  mtvec value
211  */
__get_MTVEC(void)212 uint32_t __get_MTVEC(void)
213 {
214     uint32_t result;
215 
216     __ASM volatile("csrr %0," "mtvec": "=r"(result));
217     return (result);
218 }
219 
220 /*********************************************************************
221  * @fn      __set_MTVEC
222  *
223  * @brief   Set the Machine Trap-Vector Base-Address Register
224  *
225  * @param   value  - set mtvec value
226  *
227  * @return  none
228  */
__set_MTVEC(uint32_t value)229 void __set_MTVEC(uint32_t value)
230 {
231     __ASM volatile("csrw mtvec, %0":: "r"(value));
232 }
233 
234 /*********************************************************************
235  * @fn      __get_MTVEC
236  *
237  * @brief   Return the Machine Seratch Register
238  *
239  * @return  mscratch value
240  */
__get_MSCRATCH(void)241 uint32_t __get_MSCRATCH(void)
242 {
243     uint32_t result;
244 
245     __ASM volatile("csrr %0," "mscratch" : "=r"(result));
246     return (result);
247 }
248 
249 /*********************************************************************
250  * @fn      __set_MTVEC
251  *
252  * @brief   Set the Machine Seratch Register
253  *
254  * @param   value  - set mscratch value
255  *
256  * @return  none
257  */
__set_MSCRATCH(uint32_t value)258 void __set_MSCRATCH(uint32_t value)
259 {
260     __ASM volatile("csrw mscratch, %0" : : "r"(value));
261 }
262 
263 /*********************************************************************
264  * @fn      __get_MEPC
265  *
266  * @brief   Return the Machine Exception Program Register
267  *
268  * @return  mepc value
269  */
__get_MEPC(void)270 uint32_t __get_MEPC(void)
271 {
272     uint32_t result;
273 
274     __ASM volatile("csrr %0," "mepc" : "=r"(result));
275     return (result);
276 }
277 
278 /*********************************************************************
279  * @fn      __set_MEPC
280  *
281  * @brief   Set the Machine Exception Program Register
282  *
283  * @return  mepc value
284  */
__set_MEPC(uint32_t value)285 void __set_MEPC(uint32_t value)
286 {
287     __ASM volatile("csrw mepc, %0" : : "r"(value));
288 }
289 
290 /*********************************************************************
291  * @fn      __get_MCAUSE
292  *
293  * @brief   Return the Machine Cause Register
294  *
295  * @return  mcause value
296  */
__get_MCAUSE(void)297 uint32_t __get_MCAUSE(void)
298 {
299     uint32_t result;
300 
301     __ASM volatile("csrr %0," "mcause": "=r"(result));
302     return (result);
303 }
304 
305 /*********************************************************************
306  * @fn      __set_MEPC
307  *
308  * @brief   Set the Machine Cause Register
309  *
310  * @return  mcause value
311  */
__set_MCAUSE(uint32_t value)312 void __set_MCAUSE(uint32_t value)
313 {
314     __ASM volatile("csrw mcause, %0":: "r"(value));
315 }
316 
317 /*********************************************************************
318  * @fn      __get_MTVAL
319  *
320  * @brief   Return the Machine Trap Value Register
321  *
322  * @return  mtval value
323  */
__get_MTVAL(void)324 uint32_t __get_MTVAL(void)
325 {
326     uint32_t result;
327 
328     __ASM volatile("csrr %0," "mtval" : "=r"(result));
329     return (result);
330 }
331 
332 /*********************************************************************
333  * @fn      __set_MTVAL
334  *
335  * @brief   Set the Machine Trap Value Register
336  *
337  * @return  mtval value
338  */
__set_MTVAL(uint32_t value)339 void __set_MTVAL(uint32_t value)
340 {
341     __ASM volatile("csrw mtval, %0":: "r"(value));
342 }
343 
344 /*********************************************************************
345  * @fn      __get_MIP
346  *
347  * @brief   Return the Machine Interrupt Pending Register
348  *
349  * @return  mip value
350  */
__get_MIP(void)351 uint32_t __get_MIP(void)
352 {
353     uint32_t result;
354 
355     __ASM volatile("csrr %0," "mip": "=r"(result));
356     return (result);
357 }
358 
359 /*********************************************************************
360  * @fn      __set_MIP
361  *
362  * @brief   Set the Machine Interrupt Pending Register
363  *
364  * @return  mip value
365  */
__set_MIP(uint32_t value)366 void __set_MIP(uint32_t value)
367 {
368     __ASM volatile("csrw mip, %0":: "r"(value));
369 }
370 
371 /*********************************************************************
372  * @fn      __get_MCYCLE
373  *
374  * @brief   Return Lower 32 bits of Cycle counter
375  *
376  * @return  mcycle value
377  */
__get_MCYCLE(void)378 uint32_t __get_MCYCLE(void)
379 {
380     uint32_t result;
381 
382     __ASM volatile("csrr %0," "mcycle": "=r"(result));
383     return (result);
384 }
385 
386 /*********************************************************************
387  * @fn      __set_MCYCLE
388  *
389  * @brief   Set Lower 32 bits of Cycle counter
390  *
391  * @return  mcycle value
392  */
__set_MCYCLE(uint32_t value)393 void __set_MCYCLE(uint32_t value)
394 {
395     __ASM volatile("csrw mcycle, %0" : : "r"(value));
396 }
397 
398 /*********************************************************************
399  * @fn      __get_MCYCLEH
400  *
401  * @brief   Return Upper 32 bits of Cycle counter
402  *
403  * @return  mcycleh value
404  */
__get_MCYCLEH(void)405 uint32_t __get_MCYCLEH(void)
406 {
407     uint32_t result;
408 
409     __ASM volatile("csrr %0,""mcycleh" : "=r"(result));
410     return (result);
411 }
412 
413 /*********************************************************************
414  * @fn      __set_MCYCLEH
415  *
416  * @brief   Set Upper 32 bits of Cycle counter
417  *
418  * @return  mcycleh value
419  */
__set_MCYCLEH(uint32_t value)420 void __set_MCYCLEH(uint32_t value)
421 {
422     __ASM volatile("csrw mcycleh, %0":: "r"(value));
423 }
424 
425 /*********************************************************************
426  * @fn      __get_MINSTRET
427  *
428  * @brief   Return Lower 32 bits of Instructions-retired counter
429  *
430  * @return  mcause value
431  */
__get_MINSTRET(void)432 uint32_t __get_MINSTRET(void)
433 {
434     uint32_t result;
435 
436     __ASM volatile("csrr %0,""minstret": "=r"(result));
437     return (result);
438 }
439 
440 /*********************************************************************
441  * @fn      __set_MINSTRET
442  *
443  * @brief   Set Lower 32 bits of Instructions-retired counter
444  *
445  * @return  minstret value
446  */
__set_MINSTRET(uint32_t value)447 void __set_MINSTRET(uint32_t value)
448 {
449     __ASM volatile("csrw minstret, %0":: "r"(value));
450 }
451 
452 /*********************************************************************
453  * @fn      __get_MINSTRETH
454  *
455  * @brief   Return Upper 32 bits of Instructions-retired counter
456  *
457  * @return  minstreth value
458  */
__get_MINSTRETH(void)459 uint32_t __get_MINSTRETH(void)
460 {
461     uint32_t result;
462 
463     __ASM volatile("csrr %0,""minstreth": "=r"(result));
464     return (result);
465 }
466 
467 /*********************************************************************
468  * @fn      __set_MINSTRETH
469  *
470  * @brief   Set Upper 32 bits of Instructions-retired counter
471  *
472  * @return  minstreth value
473  */
__set_MINSTRETH(uint32_t value)474 void __set_MINSTRETH(uint32_t value)
475 {
476     __ASM volatile("csrw minstreth, %0":: "r"(value));
477 }
478 
479 /*********************************************************************
480  * @fn      __get_MVENDORID
481  *
482  * @brief   Return Vendor ID Register
483  *
484  * @return  mvendorid value
485  */
__get_MVENDORID(void)486 uint32_t __get_MVENDORID(void)
487 {
488     uint32_t result;
489 
490     __ASM volatile("csrr %0,""mvendorid": "=r"(result));
491     return (result);
492 }
493 
494 /*********************************************************************
495  * @fn      __get_MARCHID
496  *
497  * @brief   Return Machine Architecture ID Register
498  *
499  * @return  marchid value
500  */
__get_MARCHID(void)501 uint32_t __get_MARCHID(void)
502 {
503     uint32_t result;
504 
505     __ASM volatile("csrr %0,""marchid": "=r"(result));
506     return (result);
507 }
508 
509 /*********************************************************************
510  * @fn      __get_MIMPID
511  *
512  * @brief   Return Machine Implementation ID Register
513  *
514  * @return  mimpid value
515  */
__get_MIMPID(void)516 uint32_t __get_MIMPID(void)
517 {
518     uint32_t result;
519 
520     __ASM volatile("csrr %0,""mimpid": "=r"(result));
521     return (result);
522 }
523 
524 /*********************************************************************
525  * @fn      __get_MHARTID
526  *
527  * @brief   Return Hart ID Register
528  *
529  * @return  mhartid value
530  */
__get_MHARTID(void)531 uint32_t __get_MHARTID(void)
532 {
533     uint32_t result;
534 
535     __ASM volatile("csrr %0,""mhartid": "=r"(result));
536     return (result);
537 }
538 
539 /*********************************************************************
540  * @fn      __get_SP
541  *
542  * @brief   Return SP Register
543  *
544  * @return  SP value
545  */
__get_SP(void)546 uint32_t __get_SP(void)
547 {
548     uint32_t result;
549 
550     asm volatile("mv %0,""sp": "=r"(result):);
551     return (result);
552 }
553