riscv vm stuff
This commit is contained in:
parent
89abb3ac10
commit
3b749153b8
1 changed files with 66 additions and 0 deletions
66
riscv-vm.c
Normal file
66
riscv-vm.c
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define PPN_MASK (UINT64_MAX >> 20)
|
||||||
|
|
||||||
|
#define PPN_TO_PA(PPN) ((PPN & PPN_MASK) << 12)
|
||||||
|
#define PA_TO_PPN(PA) (PA >> 12)
|
||||||
|
|
||||||
|
#define ALIGN_UP(n, align) (((n) + (align) - 1) & ~((align) - 1))
|
||||||
|
#define ALIGN_DOWN(n, align) ((n) & ~((align) - 1))
|
||||||
|
|
||||||
|
#define IS_ALIGNED(x, align) (((uintptr_t)(x) & ((uintptr_t)(align) - 1)) == 0)
|
||||||
|
#define IS_ALIGNED_ANY(x, align) (((uintptr_t)(x) % (uintptr_t)(align)) == 0)
|
||||||
|
|
||||||
|
#define IS_POWER_OF_TWO(x) (((x) != 0) && (((x) & ((x) - 1)) == 0))
|
||||||
|
#define IS_ALIGNED_POW2(x, align) \
|
||||||
|
(assert(IS_POWER_OF_TWO((uintptr_t)(align))), (((uintptr_t)(x) & ((uintptr_t)(align) - 1)) == 0))
|
||||||
|
|
||||||
|
#define VM_MODE_SV39 (2 << 64)
|
||||||
|
|
||||||
|
#define PTE_V (1 << 0)
|
||||||
|
#define PTE_R (1 << 1)
|
||||||
|
#define PTE_W (1 << 2)
|
||||||
|
#define PTE_X (1 << 3)
|
||||||
|
/* And so on... */
|
||||||
|
|
||||||
|
#define IS_LEAF(PTE) ((PTE & (PTE_R | PTE_W | PTE_X)) != 0)
|
||||||
|
|
||||||
|
#define PTE_PPN(PTE, LEVEL) (((PTE) >> (10 + ((LEVEL) * 9)) & 0x1FF))
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
assert(IS_ALIGNED(0, 1));
|
||||||
|
assert(IS_ALIGNED(8, 8));
|
||||||
|
assert(IS_ALIGNED(12, 4));
|
||||||
|
assert(!IS_ALIGNED(66, 16));
|
||||||
|
assert(!IS_ALIGNED(234, 4096));
|
||||||
|
assert(!IS_ALIGNED(4099, 4096));
|
||||||
|
|
||||||
|
assert(PPN_MASK == 0b11111111111111111111111111111111111111111111);
|
||||||
|
assert(PPN_MASK == 17592186044415);
|
||||||
|
assert(PPN_MASK == 0xFFFFFFFFFFF);
|
||||||
|
|
||||||
|
printf("%lu", PPN_TO_PA(0xAAAAAA));
|
||||||
|
assert(IS_ALIGNED(PPN_TO_PA(0xAAAAAAAAAAAA), 4096));
|
||||||
|
|
||||||
|
uint64_t pte = 0b11111111110000000001111111110000000001111111111;
|
||||||
|
|
||||||
|
assert(pte & PTE_V);
|
||||||
|
assert(pte & PTE_R);
|
||||||
|
assert(pte & PTE_W);
|
||||||
|
assert(pte & PTE_X);
|
||||||
|
|
||||||
|
assert(IS_LEAF(pte));
|
||||||
|
|
||||||
|
assert(PTE_PPN(pte, 0) == 0);
|
||||||
|
assert(PTE_PPN(pte, 1) == 0b111111111);
|
||||||
|
assert(PTE_PPN(pte, 2) == 0);
|
||||||
|
pte <<= 9;
|
||||||
|
assert(PTE_PPN(pte, 0) == 0b111111111);
|
||||||
|
assert(PTE_PPN(pte, 1) == 0);
|
||||||
|
assert(PTE_PPN(pte, 2) == 0b111111111);
|
||||||
|
|
||||||
|
assert(!IS_LEAF(pte)); // Rightmost bits are now shifted out
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue