From 3b749153b84425f6077b05af8d7fd891dc86ca6e Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Sat, 27 Dec 2025 02:08:36 +0100 Subject: [PATCH] riscv vm stuff --- riscv-vm.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 riscv-vm.c diff --git a/riscv-vm.c b/riscv-vm.c new file mode 100644 index 0000000..d3f9eec --- /dev/null +++ b/riscv-vm.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#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 + +}