Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Added memory ranges
Jack Lange [Mon, 3 Mar 2008 17:36:14 +0000 (17:36 +0000)]
12 files changed:
palacios/build/Makefile
palacios/include/geekos/svm.h
palacios/include/geekos/vmm.h
palacios/include/geekos/vmm_mem.h
palacios/include/geekos/vmm_stubs.h
palacios/include/geekos/vmm_util.h
palacios/src/geekos/main.c
palacios/src/geekos/svm.c
palacios/src/geekos/svm_lowlevel.asm
palacios/src/geekos/vmm.c
palacios/src/geekos/vmm_mem.c
palacios/src/geekos/vmm_stubs.c

index 7bf6dc7..c3712a2 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.13 $
+# $Revision: 1.14 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
@@ -269,21 +269,6 @@ pxe:       fd.img
        $(PAD) /tftpboot/vmm.img 1474560
 
 
-pxe-discovery-pdinda:  fd.img
-       cp fd.img geekos.img
-       $(PAD) geekos.img 1474560
-       /usr/local/vmm-util/pxe_cp geekos.img
-       /usr/local/vmm-util/tty_perm pdinda
-       echo "Copied file to PXE boot area and set serial permissions for pdinda"
-
-
-pxe-discovery-bjp600:  fd.img
-       cp fd.img geekos.img
-       $(PAD) geekos.img 1474560
-       /usr/local/vmm-util/pxe_cp geekos.img
-       /usr/local/vmm-util/tty_perm bjp600
-       echo "Copied file to PXE boot area and set serial permissions for pdinda"
-
 
 # Floppy boot sector (first stage boot loader).
 geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm vm_kernel
@@ -351,6 +336,11 @@ vm_kernel: force
        @echo "VM kernel lives at 0x100000 and is" `$(NUMSECS) vm_kernel` "sectors long"
 
 
+
+vmm_mem_test: geekos/vmm_mem.c
+       $(HOST_CC) -o mem_test -DVMM_MEM_TEST -I../include ../src/geekos/vmm_mem.c 
+
+
 # Clean build directories of generated files
 clean :
        for d in geekos common libc user tools; do \
index 5ebed66..3854220 100644 (file)
@@ -221,7 +221,7 @@ void Init_VMCB(vmcb_t * vmcb, guest_info_t vm_info);
 int init_svm_guest(struct guest_info *info);
 int start_svm_guest(struct guest_info * info);
 
-int handle_svm_exit();
+int handle_svm_exit(struct VMM_GPRs gprs);
 
 
 #endif
index 8f0dfbc..3b0b1e0 100644 (file)
@@ -39,7 +39,7 @@
 
 
 
-// We need to check the hook structure at runtime to ensure its SAFE
+/* This clearly won't work, we need some way to get a return value out of it */
 #define VMMMalloc(size)                                 \
   do {                                                 \
     extern struct vmm_os_hooks * os_hooks;             \
   } while (0)                                          \
 
 
+// We need to check the hook structure at runtime to ensure its SAFE
+#define VMMFree(addr)                                  \
+  do {                                                 \
+    extern struct vmm_os_hooks * os_hooks;             \
+    if ((os_hooks) && (os_hooks)->free) {              \
+      (os_hooks)->free(addr);                          \
+    }                                                  \
+  } while (0)                                          \
+
+
 /* ** */
 
 
@@ -62,8 +72,8 @@ typedef struct guest_info {
   ullong_t rip;
   ullong_t rsp;
 
-  vmm_mem_map_t mem_map;
-  // preallocation map
+  vmm_mem_list_t mem_list;
+  vmm_mem_layout_t mem_layout;
   // device_map
 
   void * vmm_data;
index f938b3e..32a254c 100644 (file)
@@ -5,30 +5,80 @@
 #include <geekos/ktypes.h>
 
 
+
+
 typedef struct mem_region {
   ullong_t addr;
-  uint_t numPages;
+  uint_t num_pages;
 
   struct mem_region * next;
   struct mem_region * prev;
 } mem_region_t;
 
 
-typedef struct vmm_mem_map {
+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_map_t;
+  //  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 layout_region {
+  ullong_t addr;
+  uint_t num_pages;
+
+  region_type_t type;
+
+  ullong_t host_addr;
+
+  struct layout_region * next;
+  struct layout_region * prev;
+  
+
+} layout_region_t;
+
+
+typedef struct vmm_mem_layout {
+  uint_t num_pages;
+  uint_t num_regions;
+
+  layout_region_t * head;
+  //layout_region_t * tail;
+
+} 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);
+
+int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages);
+int remove_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages);
+
+mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, ullong_t addr);
 
 
-void init_mem_map(vmm_mem_map_t * map);
 
-void add_mem_map_pages(vmm_mem_map_t * map, ullong_t addr, uint_t numPages);
-int remove_mem_map_pages(vmm_mem_map_t * map, ullong_t addr, uint_t numPages);
+void init_mem_laout(vmm_mem_layout_t * layout);
+void free_mem_layout(vmm_mem_layout_t * layout);
 
+layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, ullong_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, ullong_t addr, uint_t num_pages, ullong_t host_addr);
+int add_unmapped_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages);
+int add_guest_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages);
 
 #endif
index b964280..db960a3 100644 (file)
@@ -3,11 +3,14 @@
 
 
 #include <geekos/mem.h>
+#include <geekos/malloc.h>
 
 
 void * Allocate_VMM_Pages(int num_pages);
 void Free_VMM_Page(void * page);
 
+void * VMM_Malloc(uint_t size);
+void VMM_Free(void * addr);
 
 
 
index 5fb0aea..402d2c6 100644 (file)
@@ -5,7 +5,8 @@
 
 
 
-//#define PAGE_SIZE 4096
+
+#define PAGE_SIZE 4096
 
 typedef union reg_ex {
   ullong_t r_reg;
@@ -18,6 +19,20 @@ typedef union reg_ex {
 
 
 
+// These are the GPRs layed out according to 'pusha'
+struct VMM_GPRs {
+  uint_t edi;
+  uint_t esi;
+  uint_t ebp;
+  uint_t esp;
+  uint_t ebx;
+  uint_t edx;
+  uint_t ecx;
+  uint_t eax;
+};
+
+
+
 void PrintTraceHex(unsigned char x);
 
 void PrintTraceMemDump(unsigned char * start, int n);
index e92e70d..734d9e1 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
  * Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $Revision: 1.14 $
+ * $Revision: 1.15 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -26,6 +26,7 @@
 #include <geekos/mem.h>
 #include <geekos/paging.h>
 #include <geekos/ide.h>
+#include <geekos/malloc.h>
 
 #include <geekos/debug.h>
 #include <geekos/vmm.h>
@@ -337,7 +338,10 @@ void Main(struct Boot_Info* bootInfo)
     os_hooks.print_trace = &SerialPrint;
     os_hooks.Allocate_Pages = &Allocate_VMM_Pages;
     os_hooks.Free_Page = &Free_VMM_Page;
-    
+    os_hooks.malloc = &VMM_Malloc;
+    os_hooks.free = &VMM_Free;
+
+
     Init_VMM(&os_hooks, &vmm_ops);
   
 
index 28ef40e..9f30c49 100644 (file)
@@ -48,7 +48,7 @@ void Init_SVM(struct vmm_ctrl_ops * vmm_ops) {
   void * host_state;
 
 
-  // setup 
+  // Enable SVM on the CPU
   Get_MSR(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
   msr.e_reg.low |= EFER_MSR_svm_enable;
   Set_MSR(EFER_MSR, 0, msr.e_reg.low);
@@ -113,6 +113,16 @@ int start_svm_guest(struct guest_info *info) {
 
 
 
+/** 
+ *  We handle the svm exits here
+ *  This function should probably be moved to another file to keep things managable....
+ */
+int handle_svm_exit(struct VMM_GPRs guest_gprs) {
+
+  return 0;
+}
+
+
 vmcb_t * Allocate_VMCB() {
   vmcb_t * vmcb_page = (vmcb_t*)os_hooks->Allocate_Pages(1);
 
index c468c5a..57ea853 100644 (file)
@@ -9,6 +9,8 @@
 
 
 
+EXTERN handle_svm_exit
+
 EXPORT launch_svm
 
 
@@ -60,4 +62,30 @@ launch_svm:
 ;  ret
 ;
 ;
-;
\ No newline at end of file
+;
+
+
+
+;; Need to check this..
+;; Since RAX/EAX is saved in the VMCB, we should probably just 
+;;      do our own replacement for pusha/popa that excludes [e|r]ax
+safe_svm_launch:
+       push    ebp
+       mov     ebp, esp
+       pushf
+       pusha
+
+.vmm_loop:
+       mov     eax, [ebp + 8]
+       vmrun
+       pusha
+       call    handle_svm_exit
+       and     eax, eax
+       popa                    ;; restore the guest GPRs, (DOES THIS AFFECT E/RFLAGS?)
+       jz      .vmm_loop
+
+       ;; HOW DO WE GET THE RETURN VALUE OF HANDLE_SVM_EXIT BACK TO THE CALLER
+       popf
+       popa
+       pop     ebp
+       ret
\ No newline at end of file
index 9350cf0..ab9a5f6 100644 (file)
@@ -12,8 +12,6 @@ struct vmm_os_hooks * os_hooks = NULL;
 
 
 
-
-
 void Init_VMM(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops) {
   vmm_cpu_type = VMM_INVALID_CPU;
 
@@ -35,6 +33,3 @@ void Init_VMM(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops) {
     PrintDebug("CPU has no virtualization Extensions\n");
   }
 }
-
-
-
index 0bd908e..bba8333 100644 (file)
 #include <geekos/vmm_mem.h>
 #include <geekos/vmm.h>
-
+#include <geekos/vmm_util.h>
 
 extern struct vmm_os_hooks * os_hooks;
 
 
-void init_mem_map(vmm_mem_map_t * map) {
-  map->num_pages = 0;
-  map->long_mode = false;
+void init_mem_list(vmm_mem_list_t * list) {
+  list->num_pages = 0;
+  list->long_mode = false;
   
-  map->num_regions = 0;
-  map->head = NULL;
-  map->tail = NULL;
+  list->num_regions = 0;
+  list->head = NULL;
+}
+
+
+void free_mem_list(vmm_mem_list_t * list) {
+  mem_region_t * cursor = list->head;
+  mem_region_t * tmp = NULL;
+
+  while(cursor) {
+    tmp = cursor;
+    cursor = cursor->next;
+    VMMFree(tmp);
+  }
+
+  VMMFree(list);
+}
+
+/*** FOR THE LOVE OF GOD WRITE SOME UNIT TESTS FOR THIS THING ***/
+
+
+
+// Scan the current list, and extend an existing region if one exists
+// Otherwise create a new region and merge it into the correct location in the list
+//
+// We scan to find the position at which to add the new region and insert it
+// Then we clean up any region following the new region that overlaps
+// 
+// JRL: This is pretty hairy...
+int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages) {
+
+  uint_t num_new_pages = num_pages;
+  ullong_t new_end = addr + (num_pages * PAGE_SIZE);
+
+  mem_region_t * cursor = get_mem_list_cursor(list, addr);
+
+
+
+  // PrintDebug("Adding: 0x%x - 0x%x\n", addr, num_pages * PAGE_SIZE);
+
+  // Make a new region at the head of the list
+  if (cursor == NULL) {
+    cursor = os_hooks->malloc(sizeof(mem_region_t));
+
+    cursor->prev = NULL;
+    cursor->addr = addr;
+    cursor->num_pages = num_pages;
+
+    cursor->next = list->head;
+    list->head = cursor;
+
+    if (cursor->next) {
+      cursor->next->prev = cursor;
+    }
+
+    list->num_regions++;
+  } else {
+    ullong_t cursor_end = cursor->addr + (cursor->num_pages * PAGE_SIZE);
+
+    if (addr > cursor_end) {
+      // address falls after cursor region
+      
+      mem_region_t * new_region = os_hooks->malloc(sizeof(mem_region_t));
+
+      new_region->prev = cursor;
+      new_region->next = cursor->next;
+
+      if (cursor->next) {
+       cursor->next->prev = new_region;
+      }
+      cursor->next = new_region;
+
+      new_region->addr = addr;
+      new_region->num_pages = num_pages;
+
+      list->num_regions++;
+
+      cursor = new_region;
+    } else if ((addr >= cursor->addr) && 
+              (addr <= cursor_end)) {
+      // address falls inside the cursor region
+
+
+      // The region has already been added
+      if (new_end <= cursor_end) {
+       return -1;
+      }
+
+      // We need to extend the old region
+      num_new_pages = (new_end - cursor_end) / PAGE_SIZE;
+      cursor->num_pages += num_new_pages;
+
+    }
+  }
+    
+  // Clean up any overlaps that follow
+  while ((cursor->next) && (cursor->next->addr <= new_end)) {
+    mem_region_t * overlap = cursor->next;
+    ullong_t overlap_end = overlap->addr + (overlap->num_pages * PAGE_SIZE);
+    
+    cursor->next = overlap->next;
+    if (overlap->next) {
+      overlap->next->prev = cursor;
+    }
+    
+    if (overlap_end > new_end) {
+      uint_t extension = (overlap_end - new_end) / PAGE_SIZE;
+
+      cursor->num_pages += extension;
+      num_new_pages -= (overlap->num_pages - extension);
+    } else {
+      num_new_pages -= overlap->num_pages;
+    }
+    
+    VMMFree(overlap);
+    
+    list->num_regions--;
+  }
+
+
+  list->num_pages += num_new_pages;
+
+  return 0;
+}
+
+
+/* this function returns a pointer to the location in the memory list that 
+ * corresponds to addr.
+ * Rules: 
+ *     IF addr is in a region, a ptr to that region is returned
+ *     IF addr is not in a region, a ptr to the previous region is returned
+ *     IF addr is before all regions, returns NULL
+ *     IF list is empty, returns NULL
+ */
+mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, ullong_t addr) {
+  mem_region_t * prev_region = list->head;
+
+  while (prev_region != NULL) {
+    if ( (addr >= prev_region->addr) && 
+        (addr <= (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) ) {
+      return prev_region;
+    } else if (addr < prev_region->addr) {
+      // If this region is the current head, then this should return NULL
+      return prev_region->prev;
+    } else if (addr > (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) {
+      if (prev_region->next) {
+       prev_region = prev_region->next;
+      } else {
+       return prev_region;
+      }
+    }
+  }
+
+  return prev_region;
+}
+
+
+
+void init_mem_layout(vmm_mem_layout_t * layout) {
+  layout->num_pages = 0;
+  layout->num_regions = 0;
+
+  layout->head = NULL;
+}
+
+
+void free_mem_layout(vmm_mem_layout_t * layout) {
+  layout_region_t * cursor = layout->head;
+  layout_region_t * tmp = NULL;
+
+  while(cursor) {
+    tmp = cursor;
+    cursor = cursor->next;
+    VMMFree(tmp);
+  }
+
+  VMMFree(layout);
+
+}
+
+
+/* this function returns a pointer to the location in the layout list that 
+ * corresponds to addr.
+ * Rules: 
+ *     IF addr is in a region, a ptr to that region is returned
+ *     IF addr is not in a region, a ptr to the previous region is returned
+ *     IF addr is before all regions, returns NULL
+ *     IF list is empty, returns NULL
+ */
+layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, ullong_t addr) {
+  layout_region_t * prev_region = layout->head;
+
+
+  while (prev_region != NULL) {
+    if ( (addr >= prev_region->addr) && 
+        (addr <= (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) ) {
+      return prev_region;
+    } else if (addr < prev_region->addr) {
+      // If this region is the current head, then this should return NULL
+      return prev_region->prev;
+    } else if (addr > (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) {
+      if (prev_region->next) {
+       prev_region = prev_region->next;
+      } else {
+       return prev_region;
+      }
+    }
+  }
+
+  return prev_region;
+}
+
+
+/* This is slightly different semantically from the mem list, in that we don't allow overlaps
+ * we could probably allow overlappig regions of the same type... but I'll let someone else deal with that
+ */
+int add_mem_range(vmm_mem_layout_t * layout, layout_region_t * region) {
+  layout_region_t * cursor = get_layout_cursor(layout, region->addr);
+
+  if (cursor == NULL) {
+    if (layout->head) {
+      if (layout->head->addr < region->addr + (region->num_pages * PAGE_SIZE)) {
+       // overlaps not allowed
+       return -1;
+      }
+      layout->head->prev = region;
+    }
+
+    region->prev = NULL;
+    region->next = layout->head;
+    layout->head = region;
+    
+    layout->num_regions++;
+    layout->num_pages += region->num_pages;
+  } else if ((region->addr >= cursor->addr) && 
+            (region->addr <= cursor->addr + (cursor->num_pages * PAGE_SIZE))) {
+    // overlaps not allowed
+    return -1;
+  } else if (region->addr > cursor->addr + (cursor->num_pages * PAGE_SIZE)) {
+    // add region to layout
+    region->next = cursor->next;
+    region->prev = cursor;
+    
+    if (region->next) {
+      region->next->prev = region;
+    }
+    cursor->next = region;
+
+    layout->num_regions++;
+    layout->num_pages += region->num_pages;
+  } else {
+    return -1;
+  }
+
+
+  return 0;
 }
 
 
-void add_mem_map_pages(vmm_mem_map_t * map, ullong_t addr, uint_t numPages) {
+
+
+
+int add_shared_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages, ullong_t host_addr) {
+  layout_region_t * shared_region = os_hooks->malloc(sizeof(layout_region_t));
+
+  shared_region->next = NULL;
+  shared_region->prev = NULL;
+  shared_region->addr = addr;
+  shared_region->num_pages = num_pages;
+  shared_region->type = SHARED;
+  shared_region->host_addr = host_addr;
+
+  return add_mem_range(layout, shared_region);
+}
+
+int add_unmapped_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages) {
+  layout_region_t * unmapped_region = os_hooks->malloc(sizeof(layout_region_t));
   
+  unmapped_region->next = NULL;
+  unmapped_region->prev = NULL;
+  unmapped_region->addr = addr;
+  unmapped_region->num_pages = num_pages;
+  unmapped_region->type = UNMAPPED;
+  unmapped_region->host_addr = 0;
+
+  return add_mem_range(layout, unmapped_region);
+}
+
+int add_guest_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages) {
+  layout_region_t * guest_region = os_hooks->malloc(sizeof(layout_region_t));
+
+  guest_region->next = NULL;
+  guest_region->prev = NULL;
+  guest_region->addr = addr;
+  guest_region->num_pages = num_pages;
+  guest_region->type = GUEST;
+  guest_region->host_addr = 0;
+
+  return add_mem_range(layout, guest_region);
+}
+
+
+
+
+
+void print_mem_list(vmm_mem_list_t * list) {
+  mem_region_t * cur = list->head;
+  int i = 0;
+
+  PrintDebug("Memory Region List (regions: %d) (pages: %d)\n", list->num_regions, list->num_pages);
+
+  while (cur) {
+    PrintDebug("%d: 0x%x - 0x%x\n", i, cur->addr, cur->addr + (cur->num_pages * PAGE_SIZE));
+    cur = cur->next;
+    i++;
+  }
+  PrintDebug("\n");
+}
+
+
+
+void print_mem_layout(vmm_mem_layout_t * layout) {
+  layout_region_t * cur = layout->head;
+  int i = 0;
+
+  PrintDebug("Memory Layout (regions: %d) (pages: %d)\n", layout->num_regions, layout->num_pages);
+
+  while (cur) {
+    PrintDebug("%d: 0x%x - 0x%x\n", i, cur->addr, cur->addr + (cur->num_pages * PAGE_SIZE));
+    cur = cur->next;
+    i++;
+  }
+  PrintDebug("\n");
+}
+
+
+
+#ifdef VMM_MEM_TEST
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+
+
+
+struct vmm_os_hooks * os_hooks;
+
+void * TestMalloc(uint_t size) {
+  return malloc(size);
+}
+
+void TestPrint(const char * fmt, ...) {
+  va_list args;
+
+  va_start(args, fmt);
+  vprintf(fmt, args);
+  va_end(args);
+}
+
+int mem_list_add_test_1() {
+  vmm_mem_list_t list;
+  uint_t offset = 0;
+
+  init_mem_list(&list);
+
+  offset = PAGE_SIZE * 6;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
+  add_mem_list_pages(&list, PAGE_SIZE * 6, 10);
+  print_mem_list(&list);
+
+
+  offset = 0;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
+  add_mem_list_pages(&list, 0, 4);
+  print_mem_list(&list);
+
+  offset = PAGE_SIZE * 20;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
+  add_mem_list_pages(&list, PAGE_SIZE * 20, 1);
+  print_mem_list(&list);
+
+
+  offset = PAGE_SIZE * 10;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
+  add_mem_list_pages(&list, PAGE_SIZE * 10, 30);
+  print_mem_list(&list);
+
+  return 0;
+}
+
+
+int mem_layout_add_test_1() {
+  vmm_mem_layout_t layout;
+  uint_t offset = 0;
+
+  init_mem_layout(&layout);
+
+  offset = PAGE_SIZE * 6;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
+  add_guest_mem_range(&layout, PAGE_SIZE * 6, 10);
+  print_mem_layout(&layout);
+
+
+  offset = 0;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
+  add_guest_mem_range(&layout, 0, 4);
+  print_mem_layout(&layout);
+
+  offset = PAGE_SIZE * 20;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
+  add_guest_mem_range(&layout, PAGE_SIZE * 20, 1);
+  print_mem_layout(&layout);
+
+
+  offset = PAGE_SIZE * 10;
+  PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
+  add_guest_mem_range(&layout, PAGE_SIZE * 10, 30);
+  print_mem_layout(&layout);
+
+  return 0;
+}
+
+
+
+int main(int argc, char ** argv) {
+  struct vmm_os_hooks dummy_hooks;
+  os_hooks = &dummy_hooks;
+
+  os_hooks->malloc = &TestMalloc;
+  os_hooks->free = &free;
+  os_hooks->print_debug = &TestPrint;
+
 
+  printf("mem_list_add_test_1: %d\n", mem_list_add_test_1());
+  printf("layout_add_test_t: %d\n", mem_layout_add_test_1());
 
+  return 0;
 }
+#endif
index 51f5801..fb52584 100644 (file)
@@ -6,9 +6,16 @@ void * Allocate_VMM_Pages(int num_pages) {
   return Alloc_Page();
 }
 
+void Free_VMM_Page(void * page) {
+  Free_Page(page);
+}
 
 
+void * VMM_Malloc(uint_t size) {
+  return Malloc((ulong_t) size);
+}
 
-void Free_VMM_Page(void * page) {
-  Free_Page(page);
+
+void VMM_Free(void * addr) {
+  Free(addr);
 }