#include <stdbool.h>
//paging errors
#define PAGEMAP_LOCATION 0x4000
#ifndef _PAGE_H_
#define _PAGE_H_ 
#include <stdint.h>

#define PAGE_VIRT_UNALIGNED 0x01 
#define PAGE_PHYS_UNALIGNED 0x02
#define PAGE_PHYS_INVALID   0x03
#define PAGE_VIRT_INVALID   0x04

//*
typedef struct __attribute__((packed)) {
  unsigned int present : 1;            // present, must be one when accessed.
  unsigned int read_write : 1;         // if set to one, read and write is set
  unsigned int user : 1;               // another bit we'll never use, for seperating CPL 0-2 and 3+
  unsigned int writethrough_cache : 1; // honestly maybe I should look into caching
  unsigned int cachable : 1;           // hardware chaching. 0 is enabled, whats the worst that could happen? 
  unsigned int accessed : 1;           // we'll never use any of these!
  unsigned int zg0 : 1;                // needs to be (and will be) zero'd
  unsigned int size : 1;
  unsigned int zg1 : 1;                // needs to be (and will be) zero'd
  unsigned int software_marks : 3;     // available for our own use, I doubt we'll use it in such a simple thing
  
  uintptr_t base_ptr : 40;
  unsigned int available:11;
} page_entry;


typedef struct __attribute__((packed)) {
  page_entry pml4e[512];
  page_entry pdpe[512];
  page_entry pde[512];
  page_entry pte[512];
} page_table;

#define MEM_AVAILABLE             0
#define MEM_RESERVED              1
#define MEM_APCI_RECLAIMABLE      2
#define MEM_APCI_NVS              3
#define MEM_BAD                   4

#define PAGE_SIZE_4K              12
#define PAGE_SIZE_2M              21
#define PAGE_SIZE_1G              30

struct memory_table {
  uint64_t base;
  uint64_t length;
  uint32_t type;
  uint32_t ACPI; //we'll never use this
} __attribute__((packed));


extern void* _meminfo_loc;

bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t PAGE_SIZE);
void debug_print_memory();
#endif
