#include <palacios/vmm_types.h>
#include <palacios/vmm_util.h>
+
/*
In the following, when we say "page table", we mean the whole 2 or 4 layer
#define PTE32_INDEX(x) ((((uint_t)x) >> 12) & 0x3ff)
+#define PDPE32PAE_INDEX(x) ((((uint_t)x) >> 30) & 0x3)
+#define PDE32PAE_INDEX(x) ((((uint_t)x) >> 21) & 0x1ff)
+#define PTE32PAE_INDEX(x) ((((uint_t)x) >> 12) & 0x1ff)
+
+#define PML4E64_INDEX(x) ((((ullong_t)x) >> 39) & 0x1ff)
+#define PDPE64_INDEX(x) ((((ullong_t)x) >> 30) & 0x1ff)
+#define PDE64_INDEX(x) ((((ullong_t)x) >> 21) & 0x1ff)
+#define PTE64_INDEX(x) ((((ullong_t)x) >> 12) & 0x1ff)
+
+
/* Gets the base address needed for a Page Table entry */
/* Deprecate these :*/
-#define PD32_BASE_ADDR(x) (((uint_t)x) >> 12)
-#define PT32_BASE_ADDR(x) (((uint_t)x) >> 12)
-#define PD32_4MB_BASE_ADDR(x) (((uint_t)x) >> 22)
-
-#define PML4E64_BASE_ADDR(x) (((ullong_t)x) >> 12)
-#define PDPE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
-#define PDE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
-#define PTE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
-/* Accessor functions for the page table structures */
-#define PDE32_T_ADDR(x) (((x).pt_base_addr) << 12)
-#define PTE32_T_ADDR(x) (((x).page_base_addr) << 12)
-#define PDE32_4MB_T_ADDR(x) (((x).page_base_addr) << 22)
-
+/*
+ #define PD32_BASE_ADDR(x) (((uint_t)x) >> 12)
+ #define PT32_BASE_ADDR(x) (((uint_t)x) >> 12)
+ #define PD32_4MB_BASE_ADDR(x) (((uint_t)x) >> 22)
+
+ #define PML4E64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+ #define PDPE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+ #define PDE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+ #define PTE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+
+ // Accessor functions for the page table structures
+ #define PDE32_T_ADDR(x) (((x).pt_base_addr) << 12)
+ #define PTE32_T_ADDR(x) (((x).page_base_addr) << 12)
+ #define PDE32_4MB_T_ADDR(x) (((x).page_base_addr) << 22)
+*/
/* Replace The above with these... */
-#define PAGE_BASE_ADDR(x) (((uint_t)x) >> 12)
-#define LARGE_PAGE_BASE_ADDR(x) (((uint_t)x) >> 22)
-#define BASE_TO_PAGE_ADDR(x) (((uint_t)x) << 12)
-#define LARGE_BASE_TO_PAGE_ADDR(x) (((uint_t)x) << 22)
+#define PAGE_BASE_ADDR(x) ((x) >> 12)
+#define PAGE_BASE_ADDR_2MB(x) ((x) >> 21)
+#define PAGE_BASE_ADDR_4MB(x) ((x) >> 22)
+#define BASE_TO_PAGE_ADDR(x) (((addr_t)x) << 12)
+#define BASE_TO_PAGE_ADDR_2MB(x) (((addr_t)x) << 21)
+#define BASE_TO_PAGE_ADDR_4MB(x) (((addr_t)x) << 22)
+/* *** */
+
+/* Deprecated */
+/*
+ #define PT32_PAGE_OFFSET(x) (((uint_t)x) & 0xfff)
+ #define PD32_4MB_PAGE_OFFSET(x) (((uint_t)x) & 0x003fffff)
+
+ #define PT32_PAGE_ADDR(x) (((uint_t)x) & 0xfffff000)
+ #define PD32_4MB_PAGE_ADDR(x) (((uint_t)x) & 0xffc00000)
+
+ #define PT32_PAGE_POWER 12
+ #define PAGE_ALIGNED_ADDR(x) (((uint_t) (x)) >> 12)
+ //#define PAGE_ADDR(x) (PAGE_ALIGNED_ADDR(x) << 12)
+ #define PAGE_POWER 12
+ #define PAGE_SIZE 4096
+*/
+/* use these instead */
+#define PAGE_OFFSET(x) ((x) & 0xfff)
+#define PAGE_OFFSET_2MB(x) ((x) & 0x1fffff)
+#define PAGE_OFFSET_4MB(x) ((x) & 0x3fffff)
+#define PAGE_POWER 12
+#define PAGE_POWER_2MB 22
+#define PAGE_POWER_4MB 21
-#define PT32_PAGE_ADDR(x) (((uint_t)x) & 0xfffff000)
-#define PT32_PAGE_OFFSET(x) (((uint_t)x) & 0xfff)
-#define PT32_PAGE_POWER 12
+// We shift instead of mask because we don't know the address size
+#define PAGE_ADDR(x) (((x) >> PAGE_POWER) << PAGE_POWER)
+#define PAGE_ADDR_2MB(x) (((x) >> PAGE_POWER_2MB) << PAGE_POWER_2MB)
+#define PAGE_ADDR_4MB(x) (((x) >> PAGE_POWER_4MB) << PAGE_POWER_4MB)
-#define PD32_4MB_PAGE_ADDR(x) (((uint_t)x) & 0xffc00000)
-#define PD32_4MB_PAGE_OFFSET(x) (((uint_t)x) & 0x003fffff)
+#define PAGE_SIZE 4096
+#define PAGE_SIZE_2MB (4096 * 512)
#define PAGE_SIZE_4MB (4096 * 1024)
-/* The following should be phased out */
-#define PAGE_OFFSET(x) ((((uint_t)x) & 0xfff))
-#define PAGE_ALIGNED_ADDR(x) (((uint_t) (x)) >> 12)
-#define PAGE_ADDR(x) (PAGE_ALIGNED_ADDR(x) << 12)
-#define PAGE_POWER 12
-#define PAGE_SIZE 4096
-/* ** */
+
+/* *** */
+
-#define CR3_TO_PDE32(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xfffff000)))
-#define CR3_TO_PDPTRE(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xffffffe0)))
-#define CR3_TO_PML4E64(cr3) (V3_VAddr((void *)(((ullong_t)cr3) & 0x000ffffffffff000LL)))
+#define CR3_TO_PDE32_PA(cr3) ((addr_t)(((ulong_t)cr3) & 0xfffff000))
+#define CR3_TO_PDPTRE_PA(cr3) ((addr_t)(((ulong_t)cr3) & 0xffffffe0))
+#define CR3_TO_PML4E64_PA(cr3) ((addr_t)(((ullong_t)cr3) & 0x000ffffffffff000LL))
+
+#define CR3_TO_PDE32_VA(cr3) ((pde32_t *)V3_VAddr((void *)(addr_t)(((ulong_t)cr3) & 0xfffff000)))
+#define CR3_TO_PDPTRE_VA(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xffffffe0)))
+#define CR3_TO_PML4E64_VA(cr3) ((pml4e64_t *)V3_VAddr((void *)(addr_t)(((ullong_t)cr3) & 0x000ffffffffff000LL)))
-void delete_page_tables_pde32(pde32_t * pde);
-
+void delete_page_tables_32(pde32_t * pde);
+void delete_page_tables_32PAE(pdpe32pae_t * pdpe);
+void delete_page_tables_64(pml4e64_t * pml4);
pde32_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry);
int pte32_lookup(pte32_t * pte, addr_t addr, addr_t * entry);
struct guest_info;
pde32_t * create_passthrough_pts_32(struct guest_info * guest_info);
-pdpe32pae_t * create_passthrough_pts_PAE32(struct guest_info * guest_info);
+pdpe32pae_t * create_passthrough_pts_32PAE(struct guest_info * guest_info);
pml4e64_t * create_passthrough_pts_64(struct guest_info * info);
+//#include <palacios/vm_guest.h>
void PrintDebugPageTables(pde32_t * pde);
+void PrintPageTree(v3_vm_cpu_mode_t cpu_mode, addr_t virtual_addr, addr_t cr3);
+void PrintPageTree_64(addr_t virtual_addr, pml4e64_t * pml);
void PrintPT32(addr_t starting_address, pte32_t * pte);