xv6-simplified 0.1
简化版xv6
Loading...
Searching...
No Matches
riscv.h
Go to the documentation of this file.
1
10#ifndef __ASSEMBLER__
11#define __ASSEMBLER__
12
17static inline uint64
18r_mhartid()
19{
20 uint64 x;
21 __asm__ volatile("csrr %0, mhartid" : "=r" (x) );
22 return x;
23}
24
25
26/* mstatus */
27// MPP位
28#define MSTATUS_MPP_MASK (3L << 11)
29#define MSTATUS_MPP_M (3L << 11)
30#define MSTATUS_MPP_S (1L << 11)
31#define MSTATUS_MPP_U (0L << 11)
32
33#define MSTATUS_MIE (1L << 3) // MIE位:使能M中断
34#define MSTATUS_SIE (1L << 1) // SIE位:使能S中断
35#define MSTATUS_MPIE (1L << 7) // MPIE位:M中断使能保存位
36#define MSTATUS_SPIE (1L << 5) // SPIE位:S中断使能保存位
37
42static inline uint64
43r_mstatus()
44{
45 uint64 x;
46 __asm__ volatile("csrr %0, mstatus" : "=r"(x) );
47 return x;
48}
49
54static inline void
55w_mstatus(uint64 x)
56{
57 __asm__ volatile("csrw mstatus, %0" : : "r" (x));
58}
59
60/* mepc:M模式处理完异常后返回的指令地址 */
61
66static inline void
67w_mepc(uint64 x)
68{
69 __asm__ volatile("csrw mepc, %0" : : "r" (x));
70}
71
72/* status */
73#define SSTATUS_SPP (1L << 8) // SPP位:1=S,0=U
74#define SSTATUS_SPIE (1L << 5) // SPIE位:S中断使能保存位
75#define SSTATUS_UPIE (1L << 4) // UPIE位:U中断使能保存位
76#define SSTATUS_SIE (1L << 1) // SIE位:使能S中断
77#define SSTATUS_UIE (1L << 0) // UIE位:使能U中断
78
83static inline uint64
84r_sstatus()
85{
86 uint64 x;
87 __asm__ volatile("csrr %0, sstatus" : "=r"(x) );
88 return x;
89}
90
95static inline void
96w_sstatus(uint64 x)
97{
98 __asm__ volatile("csrw sstatus, %0" : : "r" (x));
99}
100
101/* sip:哪些中断处于pending状态 */
102
107static inline uint64
108r_sip()
109{
110 uint64 x;
111 __asm__ volatile("csrr %0, sip" : "=r"(x) );
112 return x;
113}
114
119static inline void
120w_sip(uint64 x)
121{
122 __asm__ volatile("csrw sip, %0" : : "r" (x));
123}
124
125/* sie:控制S模式中断使能 */
126#define SIE_SEIE (1L << 9) // SEIE位:外部中断
127#define SIE_STIE (1L << 5) // STIE位:计时器中断
128#define SIE_SSIE (1L << 1) // SSIE位:软件中断
129
134static inline uint64
135r_sie()
136{
137 uint64 x;
138 __asm__ volatile("csrr %0, sie" : "=r"(x) );
139 return x;
140}
141
146static inline void
147w_sie(uint64 x)
148{
149 __asm__ volatile("csrw sie, %0" : : "r" (x));
150}
151
152/* mie:控制M模式中断使能*/
153#define MIE_MEIE (1L << 11) // MEIE位:外部中断
154#define MIE_MTIE (1L << 7) // MTIE位:计时器中断
155#define MIE_MSIE (1L << 3) // MSIE位:软件中断
156
161static inline uint64
162r_mie()
163{
164 uint64 x;
165 __asm__ volatile("csrr %0, mie" : "=r" (x) );
166 return x;
167}
168
173static inline void
174w_mie(uint64 x)
175{
176 __asm__ volatile("csrw mie, %0" : : "r" (x));
177}
178
179/* sepc:S模式处理完异常后返回的指令地址*/
180
185static inline uint64
186r_sepc()
187{
188 uint64 x;
189 __asm__ volatile("csrr %0, sepc" : "=r"(x) );
190 return x;
191}
192
197static inline void
198w_sepc(uint64 x)
199{
200 __asm__ volatile("csrw sepc, %0" : : "r" (x));
201}
202
203/* medeleg:M模式异常委托,决定哪些异常可以委托给低特权级 */
204
209static inline uint64
210r_medeleg()
211{
212 uint64 x;
213 __asm__ volatile("csrr %0, medeleg" : "=r"(x) );
214 return x;
215}
216
221static inline void
222w_medeleg(uint64 x)
223{
224 __asm__ volatile("csrw medeleg, %0" : : "r" (x));
225}
226
227/* mideleg:M模式中断委托,决定哪些中断可以委托给低特权级 */
228
233static inline uint64
234r_mideleg()
235{
236 uint64 x;
237 __asm__ volatile("csrr %0, mideleg" : "=r"(x) );
238 return x;
239}
240
245static inline void
246w_mideleg(uint64 x)
247{
248 __asm__ volatile("csrw mideleg, %0" : : "r" (x));
249}
250
251/* stvec:S模式异常向量表入口地址和异常访问模式 */
252
257static inline uint64
258r_stvec()
259{
260 uint64 x;
261 __asm__ volatile("csrr %0, stvec" : "=r"(x) );
262 return x;
263}
264
269static inline void
270w_stvec(uint64 x)
271{
272 __asm__ volatile("csrw stvec, %0" : : "r" (x));
273}
274
275/* mtvec:M模式异常向量表入口地址和异常访问模式 */
276
281static inline void
282w_mtvec(uint64 x)
283{
284 __asm__ volatile("csrw mtvec, %0" : : "r" (x));
285}
286
287/* pmpcfg0 & pmpadd0:PMP配置寄存器和地址寄存器 */
288
293static inline void
294w_pmpcfg0(uint64 x)
295{
296 __asm__ volatile("csrw pmpcfg0, %0" : : "r" (x));
297}
298
303static inline void
304w_pmpaddr0(uint64 x)
305{
306 __asm__ volatile("csrw pmpaddr0, %0" : : "r" (x));
307}
308
309/* satp:地址转换和保护寄存器 */
310// MODE位
311#define SATP_MASK (0xF << 60)
312#define SATP_SV39 (8L << 60)
313#define SATP_SV48 (9L << 60)
314
315// 默认设置当前页表pagetable为Sv39方案
316#define MAKE_SATP(pagetable) ( SATP_SV39 | (((uint64)pagetable) >> 12) )
317// 设置当前页表pagetable为Sv48方案
318#define MAKE_SV48(pagetable) ( SATP_SV48 | (((uint64)pagetable) >> 12) )
319
324static inline uint64
325r_satp()
326{
327 uint64 x;
328 __asm__ volatile("csrr %0, satp" : "=r"(x) );
329 return x;
330}
331
336static inline void
337w_satp(uint64 x)
338{
339 __asm__ volatile("csrw satp, %0" : : "r" (x));
340}
341
342/* mscratch:在当前模式在低特权模式时,保存M模式的上下文信息*/
343
348static inline uint64
349r_mscratch()
350{
351 uint64 x;
352 __asm__ volatile("csrr %0, mscratch" : "=r"(x) );
353 return x;
354}
355
360static inline void
361w_mscratch(uint64 x)
362{
363 __asm__ volatile("csrw mscratch, %0" : : "r" (x));
364}
365
366/* scause:S模式记录trap发生原因*/
367
372static inline uint64
373r_scause()
374{
375 uint64 x;
376 __asm__ volatile("csrr %0, scause" : "=r"(x) );
377 return x;
378}
379
380/* stval:S模式记录发生trap的地址*/
385static inline uint64
386r_stval()
387{
388 uint64 x;
389 __asm__ volatile("csrr %0, stval" : "=r"(x) );
390 return x;
391}
392
393/* mcounteren:使能S模式或U模式的硬件性能监测和计数寄存器 */
394
399static inline void
400w_mcounteren(uint64 x)
401{
402 __asm__ volatile("csrw mcounteren, %0" : : "r" (x));
403}
404
409static inline uint64
410r_mcounteren()
411{
412 uint64 x;
413 __asm__ volatile("csrr %0, mcounteren" : "=r"(x) );
414 return x;
415}
416
417/* time:系统实际时间 */
418
423static inline uint64
424r_time()
425{
426 uint64 x;
427 __asm__ volatile("csrr %0, time" : "=r"(x) );
428 return x;
429}
430
431/* 通用寄存器 */
432/* sp */
433
438static inline uint64
439r_sp()
440{
441 uint64 x;
442 __asm__ volatile("mv %0, sp" : "=r"(x) );
443 return x;
444}
445
446/* tp:本例用来存储内核id */
447
452static inline uint64
453r_tp()
454{
455 uint64 x;
456 __asm__ volatile("mv %0, tp" : "=r"(x) );
457 return x;
458}
459
464static inline void
465w_tp(uint64 x)
466{
467 __asm__ volatile("mv tp, %0" : : "r" (x));
468}
469
470/* ra */
471
476static inline uint64
477r_ra()
478{
479 uint64 x;
480 __asm__ volatile("mv %0, ra" : "=r"(x) );
481 return x;
482}
483
487static inline void
488intr_on()
489{
490 w_sstatus(r_sstatus() | SSTATUS_SIE);
491}
492
496static inline void
497intr_off()
498{
499 w_sstatus(r_sstatus() & ~SSTATUS_SIE);
500}
501
506static inline int
507intr_get()
508{
509 return (r_sstatus() & SSTATUS_SIE) != 0;
510}
511
515static inline void
516sfence_vma()
517{
518 //zero, zero表示刷新所有TLB
519 __asm__ volatile("sfence.vma zero, zero");
520}
521
522typedef uint64 pte_t; // 页表项类型
523typedef uint64 *pagetable_t; // 页表指针,存着512个页表项
524
525#endif
526
527#define PGSIZE 4096 // 页表大小
528#define PGSHIFT 12 // 页表偏移位数
529
530#define PTE_V (1L << 0) // 该PTE是否有效
531#define PTE_R (1L << 1)
532#define PTE_W (1L << 2)
533#define PTE_X (1L << 3)
534#define PTE_U (1L << 4) // 该PTE用户是否能访问
535
536// 通过物理地址得到PTE值
537#define PA2PTE(pa) ((((uint64)(pa)) >> 12) << 10)
538// 通过PTE值得到物理地址
539#define PTE2PA(pte) (((pte) >> 10) << 12)
540// 得到PTE的低10位的标志位,低到高分别是V, R, W, X, U, G(global), A(accessed), D(dirty)以及保留2位
541#define PTE_FLAGS(pte) ((pte) & 0x3FF)
542
543/* 提取出每一级的9位页表项索引 */
544
545#define PXMASK 0x1FF // 9位掩码
546// 需右移位数
547#define PXSHIFT(level) ( PGSHIFT + (9*(level)) )
548// 提取level级的PTE索引
549#define PX(level, va) ( (((uint64)(va)) >> PXSHIFT(level)) & PXMASK)
550
551// 取上整 sz = (sz + 0xfff) & ~0xfff
552#define PGROUNDUP(sz) ( ((sz) + PGSIZE - 1) & ~(PGSIZE-1) )
553// 取下整 a = a & ~0xfff
554#define PGROUNDDOWN(a) ( (a) & ~(PGSIZE-1) )
555
556
557#define MAXVA (1L << (9 + 9 + 9 + 12 - 1)) // 虚拟地址最大值,默认Sv39,空一位以防符号位
558#define MAXVA_48 (1L << (9 + 9 + 9 + 9 + 12 - 1)) // Sv48虚拟地址最大值,空一位以防符号位
#define SSTATUS_SIE
Definition riscv.h:76
uint64 * pagetable_t
Definition riscv.h:523
uint64 pte_t
Definition riscv.h:522
unsigned long uint64
Definition types.h:24