#pragma once
#include <luna/Types.h>

const usize ARCH_PAGE_SIZE = 4096;
const usize ARCH_HUGE_PAGE_SIZE = 2 * 1024 * 1024; // 2 MiB

struct [[gnu::packed]] PageTableEntry
{
    union {
        struct [[gnu::packed]]
        {
            bool present : 1;
            bool read_write : 1;
            bool user : 1;
            bool write_through : 1;
            bool cache_disabled : 1;
            bool accessed : 1;
            bool ignore0 : 1;
            bool larger_pages : 1;
            bool ignore1 : 1;
            u8 available : 3;
            u64 address : 48;
            u8 available2 : 3;
            bool no_execute : 1;
        };
        u64 raw;
    };

    void set_address(u64 addr);
    u64 get_address() const;

    void clear();
};

struct alignas(ARCH_PAGE_SIZE) PageDirectory
{
    PageTableEntry entries[512];
};

static_assert(sizeof(PageTableEntry) == 8UL);
static_assert(sizeof(PageDirectory) == ARCH_PAGE_SIZE);