rulimine/common/mm/vmm.h

85 lines
1.9 KiB
C

#ifndef __MM__VMM_H__
#define __MM__VMM_H__
#include <stdint.h>
#include <stdbool.h>
#if defined (__x86_64__) || defined (__i386__)
#define VMM_FLAG_WRITE ((uint64_t)1 << 1)
#define VMM_FLAG_NOEXEC ((uint64_t)1 << 63)
#define VMM_FLAG_FB (((uint64_t)1 << 3) | ((uint64_t)1 << 12))
#define VMM_MAX_LEVEL 3
#define PAGING_MODE_X86_64_4LVL 0
#define PAGING_MODE_X86_64_5LVL 1
#define paging_mode_va_bits(mode) ((mode) ? 57 : 48)
static inline uint64_t paging_mode_higher_half(int paging_mode) {
if (paging_mode == PAGING_MODE_X86_64_5LVL) {
return 0xff00000000000000;
} else {
return 0xffff800000000000;
}
}
typedef struct {
int levels;
void *top_level;
} pagemap_t;
enum page_size {
Size4KiB,
Size2MiB,
Size1GiB
};
pagemap_t new_pagemap(int lv);
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
#elif defined (__aarch64__)
// We use fake flags here because these don't properly map onto the
// aarch64 flags.
#define VMM_FLAG_WRITE ((uint64_t)1 << 0)
#define VMM_FLAG_NOEXEC ((uint64_t)1 << 1)
#define VMM_FLAG_FB ((uint64_t)1 << 2)
#define VMM_MAX_LEVEL 3
#define PAGING_MODE_AARCH64_4LVL 0
#define PAGING_MODE_AARCH64_5LVL 1
#define paging_mode_va_bits(mode) ((mode) ? 52 : 48)
static inline uint64_t paging_mode_higher_half(int paging_mode) {
if (paging_mode == PAGING_MODE_AARCH64_5LVL) {
return 0xffc0000000000000;
} else {
return 0xffff000000000000;
}
}
typedef struct {
int levels;
void *top_level[2];
} pagemap_t;
enum page_size {
Size4KiB,
Size2MiB,
Size1GiB
};
void vmm_assert_4k_pages(void);
pagemap_t new_pagemap(int lv);
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
#else
#error Unknown architecture
#endif
#endif