summaryrefslogtreecommitdiff
path: root/sys/include/vm.h
blob: 4378552055faa5368946deab418a208f7b10d1b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifndef _VM_H
#define _VM_H

#include <stdint.h>

#define PAGEBITS_VALID    (1 << 0)
#define PAGEBITS_R        (1 << 1)
#define PAGEBITS_W        (1 << 2)
#define PAGEBITS_X        (1 << 3)
#define PAGEBITS_USER     (1 << 4)
#define PAGEBITS_GLOBAL   (1 << 5)
#define PAGEBITS_ACCESSED (1 << 6)
#define PAGEBITS_DIRTY    (1 << 7)

#define PAGEBITS_RO	PAGEBITS_R
#define PAGEBITS_XO	PAGEBITS_X
#define PAGEBITS_RW	(PAGEBITS_R | PAGEBITS_W)
#define PAGEPITS_RX	(PAGEBITS_R | PAGEBITS_X)
#define PAGEBITS_RWX	(PAGEBITS_R | PAGEBITS_W | PAGEBITS_X)

#define MODE_SV39 	(8L << 60)

typedef uint64_t pt_entry_t;
typedef struct _pagetable {
	pt_entry_t entries[512];
} pagetable_t; 

/* allocate kernel pagetable */ 
void kptinit(void);
void kptinithart(void);
//void kptinitharts(uintptr_t mask);

/* maps virtual address to physical address for @pt. */
void vmap(pagetable_t *root, uintptr_t vaddr, uintptr_t paddr, int bits, int level);

/* returns address of page table entry for @vaddr. if @alloc, next level page tables will be allocated */ 
pt_entry_t *walkpt(pagetable_t *root, uintptr_t vaddr, int alloc);

/* helper functions */
static inline void write_satp(uintptr_t mode, uintptr_t ppn);
static inline int pte_is_branch(pt_entry_t);
static inline int pte_is_valid(pt_entry_t);

#define PA2PTE(pa) ((uintptr_t)pa >> 2)
#define PTE2PA(pa) ((uintptr_t)pa << 2)
#define FLUSH_TLB() asm volatile("sfence.vma zero, zero")

static inline void 
write_satp(uintptr_t mode, uintptr_t ppn)
{
	FLUSH_TLB();
	asm volatile("csrw satp, %0" : : "r"((ppn >> 12) | mode));
	FLUSH_TLB();
}

static inline int
pte_is_branch(pt_entry_t e)
{
	return ((e & PAGEBITS_RWX) == 0);
}
#define pte_is_leaf(e) (!pte_is_branch(e))

static inline int
pte_is_valid(pt_entry_t e)
{
	return (e & PAGEBITS_VALID);
}


#endif /* _VM_H */