• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 // Copyright (C) 2022 Beken Corporation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef __PORTMACRO_H__
17 #define __PORTMACRO_H__
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 
24 #include <stdint.h>
25 #include <os/os.h>
26 
27 /* Type definitions. */
28 #if __riscv_xlen == 64
29     #define portSTACK_TYPE          uint64_t
30     #define portBASE_TYPE           int64_t
31     #define portUBASE_TYPE          uint64_t
32     #define portMAX_DELAY           ( TickType_t ) 0xffffffffffffffffUL
33     #define portPOINTER_SIZE_TYPE   uint64_t
34 #elif __riscv_xlen == 32
35     #define portSTACK_TYPE  uint32_t
36     #define portBASE_TYPE   int32_t
37     #define portUBASE_TYPE  uint32_t
38     #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
39 #else
40     #error Assembler did not define __riscv_xlen
41 #endif
42 
43 typedef portSTACK_TYPE StackType_t;
44 typedef portBASE_TYPE BaseType_t;
45 typedef portUBASE_TYPE UBaseType_t;
46 typedef portUBASE_TYPE TickType_t;
47 
48 
49 /* Macros to access high and low part of 64-bit mtime registers in RV32 */
50 #if __riscv_xlen == 32
51     #define portREG64_HI(reg_addr) ( ( (volatile uint32_t *)reg_addr )[1] )
52     #define portREG64_LO(reg_addr) ( ( (volatile uint32_t *)reg_addr )[0] )
53 #endif
54 
55 extern volatile uint64_t *mtime;
56 extern volatile uint64_t *mtimecmp;
57 
58 extern unsigned int port_disable_mie_flag(void);
59 extern void port_enable_mie_flag(uint32_t val);
60 
61 __attribute__((always_inline))
prvMieSave()62 static inline UBaseType_t prvMieSave()
63 {
64 UBaseType_t uxSavedStatusValue;
65 
66     __asm volatile( "csrrc %0, mstatus, 0x8":"=r"( uxSavedStatusValue ) );
67     return uxSavedStatusValue;
68 }
69 /*-----------------------------------------------------------*/
70 
71 __attribute__((always_inline))
prvMieRestore(UBaseType_t uxSavedStatusValue)72 static inline void prvMieRestore( UBaseType_t uxSavedStatusValue )
73 {
74     __asm volatile( "csrw mstatus, %0"::"r"( uxSavedStatusValue ) );
75 }
76 /*-----------------------------------------------------------*/
77 
78 /* prvReadMtime(): Read machine timer register.
79 Note: Always use this API to access mtime */
80 __attribute__((always_inline))
prvReadMtime(void)81 inline uint64_t prvReadMtime( void )
82 {
83 uint32_t ulTimeHigh, ulTimeLow;
84 
85     #if __riscv_xlen == 32
86         do
87         {
88             ulTimeHigh = portREG64_HI( mtime );
89             ulTimeLow = portREG64_LO( mtime );
90 
91             if( ulTimeHigh == portREG64_HI( mtime ) )
92                 return ( ((uint64_t)ulTimeHigh) << 32 ) | ulTimeLow;
93         } while( 1 );
94     #else
95         return *mtime;
96     #endif
97 }
98 /*-----------------------------------------------------------*/
99 
100 /* prvWriteMtimeCmp(ullNewMtimeCmp): Write machine timer compare register.
101 Note: Use this API to access register if timer interrupt is enabled. */
102 __attribute__((always_inline))
prvWriteMtimeCmp(uint64_t ullNewMtimeCmp)103 static inline void prvWriteMtimeCmp( uint64_t ullNewMtimeCmp )
104 {
105     #if __riscv_xlen == 32
106         /* To avoid triggering spurious interrupts when writting to mtimecmp,
107         keeping the high part to the maximum value in the writing progress.
108 
109         We assume mtime overflow doesn't occur, because 64-bit mtime overflow
110         period is longer than 500 years for the CPUs whose clock rate is lower
111         than 1GHz. */
112 
113         portREG64_HI( mtimecmp ) = UINT32_MAX;
114         portREG64_LO( mtimecmp ) = ullNewMtimeCmp & 0xFFFFFFFF;
115         portREG64_HI( mtimecmp ) = ( ullNewMtimeCmp >> 32 ) & 0xFFFFFFFF;
116     #else
117         *mtimecmp = ullNewMtimeCmp;
118     #endif
119 }
120 
121 
122 void vPortSetupTimerInterrupt(void);
123 void vPortSetupMEXTInterrupt(void);
124 
port_disable_interrupts_flag(void)125 __inline static int port_disable_interrupts_flag(void)
126 {
127 	uint32_t uxSavedStatusValue;
128 
129 	__asm volatile( "csrrc %0, mstatus, 0x8":"=r"( uxSavedStatusValue ) );
130 	return uxSavedStatusValue;
131 }
132 
133 /*
134  * Enable Interrupts
135  */
port_enable_interrupts_flag(int val)136 __inline static void port_enable_interrupts_flag(int val)
137 {
138 	__asm volatile( "csrw mstatus, %0"::"r"( val ) );
139 }
140 
port_set_interrupt_mask_from_isr(void)141 __inline static unsigned int port_set_interrupt_mask_from_isr(void)
142 {
143 	unsigned int val;
144 
145 	__asm volatile( "csrrc %0, mstatus, 0x8":"=r"( val ) );
146 
147 	return val;
148 }
149 
port_clear_interrupt_mask_from_isr(int val)150 __inline static void port_clear_interrupt_mask_from_isr(int val)
151 {
152 	__asm volatile( "csrw mstatus, %0"::"r"( val ) );
153 }
154 
155 
156 #define portDISABLE_INTERRUPTS()	__asm volatile( "csrc mstatus, 8" )
157 #define portENABLE_INTERRUPTS()		__asm volatile( "csrs mstatus, 8" )
158 #define portENTER_CRITICAL()
159 #define portEXIT_CRITICAL()
160 
161 
162 #define portNOP() __asm volatile 	( " nop " )
163 
164 
165 extern uint32_t platform_is_in_interrupt_context( void );
166 
167 
168 
169 #ifdef __cplusplus
170 }
171 #endif
172 
173 #endif /* _PORTMACRO_H_ */
174