#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 }