550W Document
550W, a high-end OS
privileged.h
浏览该文件的文档.
1 #pragma once
2 
3 #include <common/types.h>
4 
5 // which hart (core) is this?
6 static inline uint64_t asm_r_mhartid() {
7  uint64_t x;
8  asm volatile("csrr %0, mhartid" : "=r"(x));
9  return x;
10 }
11 
12 // Machine Status Register, mstatus
13 
14 #define MSTATUS_MPP_MASK (3L << 11) // previous mode.
15 #define MSTATUS_MPP_M (3L << 11)
16 #define MSTATUS_MPP_S (1L << 11)
17 #define MSTATUS_MPP_U (0L << 11)
18 #define MSTATUS_MIE (1L << 3) // machine-mode interrupt enable.
19 
20 static inline uint64_t asm_r_mstatus() {
21  uint64_t x;
22  asm volatile("csrr %0, mstatus" : "=r"(x));
23  return x;
24 }
25 
26 static inline void asm_w_mstatus(uint64_t x) {
27  asm volatile("csrw mstatus, %0" : : "r"(x));
28 }
29 
30 // machine exception program counter, holds the
31 // instruction address to which a return from
32 // exception will go.
33 static inline void asm_w_mepc(uint64_t x) {
34  asm volatile("csrw mepc, %0" : : "r"(x));
35 }
36 
37 // Supervisor Status Register, sstatus
38 
39 #define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
40 #define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable
41 #define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable
42 #define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
43 #define SSTATUS_UIE (1L << 0) // User Interrupt Enable
44 
45 static inline uint64_t asm_r_sstatus() {
46  uint64_t x;
47  asm volatile("csrr %0, sstatus" : "=r"(x));
48  return x;
49 }
50 
51 static inline void asm_w_sstatus(uint64_t x) {
52  asm volatile("csrw sstatus, %0" : : "r"(x));
53 }
54 
55 // Supervisor Interrupt Pending
56 static inline uint64_t asm_r_sip() {
57  uint64_t x;
58  asm volatile("csrr %0, sip" : "=r"(x));
59  return x;
60 }
61 
62 static inline void asm_w_sip(uint64_t x) {
63  asm volatile("csrw sip, %0" : : "r"(x));
64 }
65 
66 // Supervisor Interrupt Enable
67 #define SIE_SEIE (1L << 9) // external
68 #define SIE_STIE (1L << 5) // timer
69 #define SIE_SSIE (1L << 1) // software
70 static inline uint64_t asm_r_sie() {
71  uint64_t x;
72  asm volatile("csrr %0, sie" : "=r"(x));
73  return x;
74 }
75 
76 static inline void asm_w_sie(uint64_t x) {
77  asm volatile("csrw sie, %0" : : "r"(x));
78 }
79 
80 // Machine-mode Interrupt Enable
81 #define MIE_MEIE (1L << 11) // external
82 #define MIE_MTIE (1L << 7) // timer
83 #define MIE_MSIE (1L << 3) // software
84 static inline uint64_t asm_r_mie() {
85  uint64_t x;
86  asm volatile("csrr %0, mie" : "=r"(x));
87  return x;
88 }
89 
90 static inline void asm_w_mie(uint64_t x) {
91  asm volatile("csrw mie, %0" : : "r"(x));
92 }
93 
94 // machine exception program counter, holds the
95 // instruction address to which a return from
96 // exception will go.
97 static inline void asm_w_sepc(uint64_t x) {
98  asm volatile("csrw sepc, %0" : : "r"(x));
99 }
100 
101 static inline uint64_t asm_r_sepc() {
102  uint64_t x;
103  asm volatile("csrr %0, sepc" : "=r"(x));
104  return x;
105 }
106 
107 // Machine Exception Delegation
108 static inline uint64_t asm_r_medeleg() {
109  uint64_t x;
110  asm volatile("csrr %0, medeleg" : "=r"(x));
111  return x;
112 }
113 
114 static inline void asm_w_medeleg(uint64_t x) {
115  asm volatile("csrw medeleg, %0" : : "r"(x));
116 }
117 
118 // Machine Interrupt Delegation
119 static inline uint64_t asm_r_mideleg() {
120  uint64_t x;
121  asm volatile("csrr %0, mideleg" : "=r"(x));
122  return x;
123 }
124 
125 static inline void asm_w_mideleg(uint64_t x) {
126  asm volatile("csrw mideleg, %0" : : "r"(x));
127 }
128 
129 // Supervisor Trap-Vector Base Address
130 // low two bits are mode.
131 static inline void asm_w_stvec(uint64_t x) {
132  asm volatile("csrw stvec, %0" : : "r"(x));
133 }
134 
135 static inline uint64_t asm_r_stvec() {
136  uint64_t x;
137  asm volatile("csrr %0, stvec" : "=r"(x));
138  return x;
139 }
140 
141 // Machine-mode interrupt vector
142 static inline void asm_w_mtvec(uint64_t x) {
143  asm volatile("csrw mtvec, %0" : : "r"(x));
144 }
145 
146 // use riscv's sv39 page table scheme.
147 #define SATP_SV39 (8L << 60)
148 
149 #define MAKE_SATP(pagetable) (SATP_SV39 | (((uint64_t)pagetable) >> 12))
150 
151 // supervisor address translation and protection;
152 // holds the address of the page table.
153 static inline void asm_w_satp(uint64_t x) {
154  asm volatile("csrw satp, %0" : : "r"(x));
155 }
156 
157 static inline uint64_t asm_r_satp() {
158  uint64_t x;
159  asm volatile("csrr %0, satp" : "=r"(x));
160  return x;
161 }
162 
163 // Supervisor Scratch register, for early trap handler in trampoline.S.
164 static inline void asm_w_sscratch(uint64_t x) {
165  asm volatile("csrw sscratch, %0" : : "r"(x));
166 }
167 
168 static inline void asm_w_mscratch(uint64_t x) {
169  asm volatile("csrw mscratch, %0" : : "r"(x));
170 }
171 
172 // Supervisor Trap Cause
173 static inline uint64_t asm_r_scause() {
174  uint64_t x;
175  asm volatile("csrr %0, scause" : "=r"(x));
176  return x;
177 }
178 
179 // Supervisor Trap Value
180 static inline uint64_t asm_r_stval() {
181  uint64_t x;
182  asm volatile("csrr %0, stval" : "=r"(x));
183  return x;
184 }
185 
186 // Machine-mode Counter-Enable
187 static inline void asm_w_mcounteren(uint64_t x) {
188  asm volatile("csrw mcounteren, %0" : : "r"(x));
189 }
190 
191 static inline uint64_t asm_r_mcounteren() {
192  uint64_t x;
193  asm volatile("csrr %0, mcounteren" : "=r"(x));
194  return x;
195 }
196 
197 // supervisor-mode cycle counter
198 static inline uint64_t asm_r_time() {
199  uint64_t x;
200  // asm volatile("csrr %0, time" : "=r" (x) );
201  // this instruction will trap in SBI
202  asm volatile("rdtime %0" : "=r"(x));
203  return x;
204 }
205 
206 // enable device interrupts
207 static inline void intr_on() {
208  asm_w_sstatus(asm_r_sstatus() | SSTATUS_SIE);
209 }
210 
211 // disable device interrupts
212 static inline void intr_off() {
213  asm_w_sstatus(asm_r_sstatus() & ~SSTATUS_SIE);
214 }
215 
216 // are device interrupts enabled?
217 static inline int intr_get() {
218  uint64_t x = asm_r_sstatus();
219  return (x & SSTATUS_SIE) != 0;
220 }
221 
222 static inline uint64_t asm_r_sp() {
223  uint64_t x;
224  asm volatile("mv %0, sp" : "=r"(x));
225  return x;
226 }
227 
228 // read and write tp, the thread pointer, which holds
229 // this core's hartid (core number), the index into cpus[].
230 static inline uint64_t asm_r_tp() {
231  uint64_t x;
232  asm volatile("mv %0, tp" : "=r"(x));
233  return x;
234 }
235 
236 static inline void asm_w_tp(uint64_t x) {
237  asm volatile("mv tp, %0" : : "r"(x));
238 }
239 
240 static inline uint64_t asm_r_ra() {
241  uint64_t x;
242  asm volatile("mv %0, ra" : "=r"(x));
243  return x;
244 }
245 
246 // flush the TLB.
247 static inline void sfence_vma() {
248  // the zero, zero means flush all TLB entries.
249  // asm volatile("sfence.vma zero, zero");
250  asm volatile("sfence.vma");
251 }
#define SSTATUS_SIE
Definition: privileged.h:42