52 lines
1.1 KiB
C
52 lines
1.1 KiB
C
#include <memory.h>
|
|
|
|
#define FLAGS_MASK (PAGE_SIZE-1)
|
|
#define MASK_FLAGS(addr) ((uintptr_t)addr & ~FLAGS_MASK)
|
|
|
|
union PTE {
|
|
uint64_t value;
|
|
struct {
|
|
uintptr_t present:1;
|
|
uintptr_t write:1;
|
|
uintptr_t user:1;
|
|
uintptr_t write_through:1;
|
|
uintptr_t nocache:1;
|
|
uintptr_t accessed:1;
|
|
uintptr_t dirty:1;
|
|
uintptr_t huge:1;
|
|
uintptr_t global:1;
|
|
uintptr_t flags:3;
|
|
};
|
|
};
|
|
|
|
#define PT(ptr) ((union PTE *)MASK_FLAGS(ptr))
|
|
#define P4e(pt, addr) (PT(pt)[P4_OFFSET(addr)])
|
|
#define P3e(pt, addr) PT(P4e(pt, addr).value)[P3_OFFSET(addr)]
|
|
#define P2e(pt, addr) PT(P3e(pt, addr).value)[P2_OFFSET(addr)]
|
|
#define P1e(pt, addr) PT(P2e(pt, addr).value)[P1_OFFSET(addr)]
|
|
|
|
uintptr_t vmm_get_page(void *P4, uintptr_t addr)
|
|
{
|
|
if(P4
|
|
&& P4e(P4, addr).present
|
|
&& P3e(P4, addr).present
|
|
&& P2e(P4, addr).present
|
|
)
|
|
return P1e(P4, addr).value;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
int vmm_set_page(void *P4, uintptr_t addr, uintptr_t page, uint16_t flags)
|
|
{
|
|
if(!(P4
|
|
&& P4e(P4, addr).present
|
|
&& P3e(P4, addr).present
|
|
&& P2e(P4, addr).present
|
|
))
|
|
return -1;
|
|
|
|
P1e(P4, addr).value = page | flags;
|
|
return 0;
|
|
}
|