#include <geekos/ktypes.h>
+typedef ulong_t addr_t;
-typedef unsigned long addr_t;
+/*
+ Guest Shadow Host
+ Virtual Physical Virtual Physical Virtual Physical
+ OK OK
+ OK NOK
+ NOK OK
+ NOK NOK
-typedef struct mem_region {
- addr_t addr;
- uint_t num_pages;
+*/
- struct mem_region * next;
- struct mem_region * prev;
-} mem_region_t;
+// These are the types of physical memory address regions
+// from the perspective of the guest
+typedef enum guest_region_type {
+ GUEST_REGION_PHYSICAL_MEMORY,
+ GUEST_REGION_NOTHING,
+ GUEST_REGION_MEMORY_MAPPED_DEVICE} guest_region_type_t;
+// These are the types of physical memory address regions
+// from the perspective of the HOST
+typedef enum host_region_type {
+ HOST_REGION_PHYSICAL_MEMORY,
+ HOST_REGION_UNALLOCATED,
+ HOST_REGION_NOTHING,
+ HOST_REGION_MEMORY_MAPPED_DEVICE,
+ HOST_REGION_REMOTE,
+ HOST_REGION_SWAPPED,
+} host_region_type_t;
-typedef struct vmm_mem_list {
- uint_t num_pages;
- bool long_mode;
- uint_t num_regions;
- mem_region_t * head;
- // mem_region_t * tail;
-} vmm_mem_list_t;
-
-
-
-/** Memory layout **/
-/* Describes the layout of memory for the guest */
-/* We use this to build the guest page tables */
-
-typedef enum region_type {GUEST, UNMAPPED, SHARED} region_type_t;
+typedef struct shadow_region {
+ guest_region_type_t guest_type;
+ addr_t guest_start;
+ addr_t guest_end;
-typedef struct layout_region {
- addr_t addr;
- uint_t num_pages;
+ host_region_type_t host_type;
+ union host_addr_t {
+ struct physical_addr {
+ addr_t host_start;
+ } phys_addr;
+ // Other addresses, like on disk, etc, would go here
+ } host_addr;
+ struct shadow_region *next, *prev;
+} shadow_region_t;
- region_type_t type;
- addr_t host_addr;
- struct layout_region * next;
- struct layout_region * prev;
-} layout_region_t;
-
-
-typedef struct vmm_mem_layout {
- uint_t num_pages;
+typedef struct shadow_map {
uint_t num_regions;
-
- uint_t num_guest_pages;
-
- layout_region_t * head;
-} vmm_mem_layout_t;
-
-
-/*** FOR THE LOVE OF GOD WRITE SOME UNIT TESTS FOR THIS THING ***/
-void init_mem_list(vmm_mem_list_t * list);
-void free_mem_list(vmm_mem_list_t * list);
+ shadow_region_t * head;
+} shadow_map_t;
-int add_mem_list_pages(vmm_mem_list_t * list, addr_t addr, uint_t num_pages);
-int remove_mem_list_pages(vmm_mem_list_t * list, addr_t addr, uint_t num_pages);
-mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, addr_t addr);
+void init_shadow_region(shadow_region_t * entry,
+ addr_t guest_addr_start,
+ addr_t guest_addr_end,
+ guest_region_type_t guest_region_type,
+ host_region_type_t host_region_type);
-addr_t get_mem_list_addr(vmm_mem_list_t * list, uint_t index);
+void init_shadow_region_physical(shadow_region_t * entry,
+ addr_t guest_addr_start,
+ addr_t guest_addr_end,
+ guest_region_type_t guest_region_type,
+ addr_t host_addr_start,
+ host_region_type_t host_region_type);
+
+void init_shadow_map(shadow_map_t * map);
+void free_shadow_map(shadow_map_t * map);
-void print_mem_list(vmm_mem_list_t * list);
+shadow_region_t * get_shadow_region_by_addr(shadow_map_t * map, addr_t guest_addr);
+shadow_region_t * get_shadow_region_by_index(shadow_map_t * map, uint_t index);
-void init_mem_layout(vmm_mem_layout_t * layout);
-void free_mem_layout(vmm_mem_layout_t * layout);
+int guest_paddr_to_host_paddr(shadow_region_t * entry,
+ addr_t guest_addr,
+ addr_t * host_addr);
-layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, addr_t addr);
-int add_mem_range(vmm_mem_layout_t * layout, layout_region_t * region);
-int add_shared_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages, addr_t host_addr);
-int add_unmapped_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages);
-int add_guest_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages);
+// Semantics:
+// Adding a region that overlaps with an existing region results is undefined
+// and will probably fail
+int add_shadow_region(shadow_map_t * map, shadow_region_t * entry);
+// Semantics:
+// Deletions result in splitting
+int delete_shadow_region(shadow_map_t * map,
+ addr_t guest_start,
+ addr_t guest_end);
-addr_t get_mem_layout_addr(vmm_mem_layout_t * list, uint_t index);
-void print_mem_layout(vmm_mem_layout_t * layout);
+void print_shadow_map(shadow_map_t * map);