:: limine / common / mm / vmm.h 4.2 KB raw

1
#ifndef MM__VMM_H__
2
#define MM__VMM_H__
3
4
#include <stdint.h>
5
#include <stdbool.h>
6
7
#if defined (__x86_64__) || defined (__i386__)
8
9
#define VMM_FLAG_WRITE   ((uint64_t)1 << 1)
10
#define VMM_FLAG_NOEXEC  ((uint64_t)1 << 63)
11
#define VMM_FLAG_FB      (((uint64_t)1 << 3) | ((uint64_t)1 << 12))
12
13
#define VMM_MAX_LEVEL 3
14
15
#define PAGING_MODE_X86_64_4LVL 0
16
#define PAGING_MODE_X86_64_5LVL 1
17
18
#define PAGING_MODE_MIN PAGING_MODE_X86_64_4LVL
19
#define PAGING_MODE_MAX PAGING_MODE_X86_64_5LVL
20
21
#define paging_mode_va_bits(mode) ((mode) ? 57 : 48)
22
23
static inline uint64_t paging_mode_higher_half(int paging_mode) {
24
    if (paging_mode == PAGING_MODE_X86_64_5LVL) {
25
        return 0xff00000000000000;
26
    } else {
27
        return 0xffff800000000000;
28
    }
29
}
30
31
typedef struct {
32
    int   levels;
33
    void *top_level;
34
} pagemap_t;
35
36
enum page_size {
37
    Size4KiB,
38
    Size2MiB,
39
    Size1GiB
40
};
41
42
pagemap_t new_pagemap(int lv);
43
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
44
45
#elif defined (__aarch64__)
46
47
// We use fake flags here because these don't properly map onto the
48
// aarch64 flags.
49
#define VMM_FLAG_WRITE   ((uint64_t)1 << 0)
50
#define VMM_FLAG_NOEXEC  ((uint64_t)1 << 1)
51
#define VMM_FLAG_FB      ((uint64_t)1 << 2)
52
53
#define VMM_MAX_LEVEL 3
54
55
#define PAGING_MODE_AARCH64_4LVL 0
56
#define PAGING_MODE_AARCH64_5LVL 1
57
58
#define PAGING_MODE_MIN PAGING_MODE_AARCH64_4LVL
59
#define PAGING_MODE_MAX PAGING_MODE_AARCH64_5LVL
60
61
#define paging_mode_va_bits(mode) ((mode) ? 53 : 49)
62
63
static inline uint64_t paging_mode_higher_half(int paging_mode) {
64
    if (paging_mode == PAGING_MODE_AARCH64_5LVL) {
65
        return 0xfff0000000000000;
66
    } else {
67
        return 0xffff000000000000;
68
    }
69
}
70
71
typedef struct {
72
    int   levels;
73
    void *top_level[2];
74
} pagemap_t;
75
76
enum page_size {
77
    Size4KiB,
78
    Size2MiB,
79
    Size1GiB
80
};
81
82
void vmm_assert_4k_pages(void);
83
pagemap_t new_pagemap(int lv);
84
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
85
86
#elif defined (__riscv)
87
88
// We use fake flags here because these don't properly map onto the
89
// RISC-V flags.
90
#define VMM_FLAG_WRITE   ((uint64_t)1 << 0)
91
#define VMM_FLAG_NOEXEC  ((uint64_t)1 << 1)
92
#define VMM_FLAG_FB      ((uint64_t)1 << 2)
93
94
#define VMM_MAX_LEVEL 5
95
96
#define PAGING_MODE_RISCV_SV39 8
97
#define PAGING_MODE_RISCV_SV48 9
98
#define PAGING_MODE_RISCV_SV57 10
99
100
#define PAGING_MODE_MIN PAGING_MODE_RISCV_SV39
101
#define PAGING_MODE_MAX PAGING_MODE_RISCV_SV57
102
103
int paging_mode_va_bits(int paging_mode);
104
105
enum page_size {
106
    Size4KiB,
107
    Size2MiB,
108
    Size1GiB,
109
    Size512GiB,
110
    Size256TiB
111
};
112
113
typedef struct {
114
    enum page_size max_page_size;
115
    int            paging_mode;
116
    void          *top_level;
117
} pagemap_t;
118
119
uint64_t paging_mode_higher_half(int paging_mode);
120
int vmm_max_paging_mode(void);
121
pagemap_t new_pagemap(int paging_mode);
122
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
123
124
#elif defined (__loongarch64)
125
126
static inline uint32_t read_cpucfg(uint32_t reg) {
127
    uint32_t val = 0;
128
    asm volatile("cpucfg %0, %1\n\t"
129
        :"=r"(val)
130
        :"r"(reg)
131
    );
132
    return val;
133
}
134
135
#define paging_mode_va_bits(mode) (((read_cpucfg(0x1) >> 12) & 0xFF) + 1)
136
137
static inline uint64_t paging_mode_higher_half(int paging_mode) {
138
    (void)paging_mode;
139
    return 0UL - (1UL << (paging_mode_va_bits(paging_mode) - 1));
140
}
141
142
// We use fake flags here because these don't properly map onto the
143
// LoongArch flags.
144
#define VMM_FLAG_WRITE   ((uint64_t)1 << 0)
145
#define VMM_FLAG_NOEXEC  ((uint64_t)1 << 1)
146
#define VMM_FLAG_FB      ((uint64_t)1 << 2)
147
148
#define VMM_MAX_LEVEL 3
149
150
#define PAGING_MODE_LOONGARCH64_4LVL 0
151
152
#define PAGING_MODE_MIN PAGING_MODE_LOONGARCH64_4LVL
153
#define PAGING_MODE_MAX PAGING_MODE_LOONGARCH64_4LVL
154
155
enum page_size {
156
    Size4KiB,
157
    Size2MiB,
158
    Size1GiB
159
};
160
161
typedef struct {
162
    void *pgd[2];
163
} pagemap_t;
164
165
pagemap_t new_pagemap(int paging_mode);
166
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
167
168
#else
169
#error Unknown architecture
170
#endif
171
172
int vmm_max_paging_mode(void);
173
void map_pages(pagemap_t pagemap, uint64_t virt, uint64_t phys, uint64_t flags, uint64_t count);
174
175
#endif
tab: 248 wrap: offon