--- /dev/null
+rombios:000f0000
+vgabios:000c0000
\ No newline at end of file
 
 #ifndef __VM_H
 #define __VM_H
 
+#define MAGIC_CODE 0xf1e2d3c4
+
+struct layout_region {
+  ulong_t length;
+  ulong_t final_addr;
+};
+
+struct guest_mem_layout {
+  ulong_t magic;
+  ulong_t num_regions;
+  struct layout_region regions[0];
+};
+
+
 int RunVMM(struct Boot_Info * bootInfo);
 
 
 
 
 
 struct shadow_page_state;
-
+struct shadow_map;
 
 typedef enum {SHADOW_PAGING, NESTED_PAGING} vm_page_mode_t;
 typedef enum {REAL, PROTECTED, PROTECTED_PG, PROTECTED_PAE, PROTECTED_PAE_PG, LONG, LONG_PG} vm_cpu_mode_t;
   ullong_t rip;
 
 
-  shadow_map_t mem_map;
+  struct shadow_map mem_map;
 
   
   vm_page_mode_t page_mode;
 
 
 #include <palacios/vmm_types.h>
 
+
 typedef ulong_t addr_t;
 
+struct guest_info;
+
+
 /*
 
         Guest                  Shadow                 Host
 
 
 
-typedef struct shadow_map {
+struct shadow_map {
   uint_t num_regions;
 
   shadow_region_t * head;
-} shadow_map_t;
+};
 
 
 void init_shadow_region(shadow_region_t * entry,
                           guest_region_type_t  guest_region_type,
                           host_region_type_t   host_region_type);
 
+/*
 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);
+*/
+
+int add_shadow_region_passthrough(struct guest_info * guest_info, 
+                                 addr_t guest_addr_start,
+                                 addr_t guest_addr_end,
+                                 addr_t host_addr_start);
+
+void init_shadow_map(struct shadow_map * map);
+void free_shadow_map(struct shadow_map * map);
 
-shadow_region_t * get_shadow_region_by_addr(shadow_map_t * map, addr_t guest_addr);
+shadow_region_t * get_shadow_region_by_addr(struct shadow_map * map, addr_t guest_addr);
 
-shadow_region_t * get_shadow_region_by_index(shadow_map_t * map, uint_t index);
+shadow_region_t * get_shadow_region_by_index(struct shadow_map * map, uint_t index);
 
-host_region_type_t lookup_shadow_map_addr(shadow_map_t * map, addr_t guest_addr, addr_t * host_addr);
+host_region_type_t lookup_shadow_map_addr(struct shadow_map * map, addr_t guest_addr, addr_t * host_addr);
 
 
 // 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);
+int add_shadow_region(struct shadow_map * map, shadow_region_t * entry);
 
 // Semantics:
 // Deletions result in splitting
-int delete_shadow_region(shadow_map_t * map,
+int delete_shadow_region(struct shadow_map * map,
                             addr_t guest_start, 
                             addr_t guest_end);
 
 
-void print_shadow_map(shadow_map_t * map);
+void print_shadow_map(struct shadow_map * map);
 
 
 
 
 #include <palacios/vmm.h>
 #include <geekos/debug.h>
 #include <geekos/serial.h>
-
+#include <geekos/vm.h>
+#include <geekos/screen.h>
 
 #define SPEAKER_PORT 0x61
 
 }
 
 
+char * bochs_debug_buf = NULL;
+int bochs_debug_offset = 0;
+
+
+int IO_BOCHS_debug(ushort_t port, void * src, uint_t length) {
+  if (!bochs_debug_buf) {
+    bochs_debug_buf = (char*)Malloc(1024);
+  }
+
+  bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
+
+  if ((*(char*)src == '\n') ||  (bochs_debug_offset == 1023)) {
+    SerialPrint("BOCHS>%s", bochs_debug_buf);
+    memset(bochs_debug_buf, 0, 1024);
+    bochs_debug_offset = 0;
+  }
+
+  return length;
+}
+
 
 int IO_Write_to_Serial(ushort_t port, void * src, uint_t length) {
-  PrintBoth("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
+ SerialPrint("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
   switch (length) {
 
   case 1:
-    PrintBoth(">0x%.2x\n", *(char*)src);
+    SerialPrint(">0x%.2x\n", *(char*)src);
     break;
   case 2:
-    PrintBoth(">0x%.4x\n", *(ushort_t*)src);
+    SerialPrint(">0x%.4x\n", *(ushort_t*)src);
     break;
   case 4:
-    PrintBoth(">0x%.8x\n", *(uint_t*)src);
+    SerialPrint(">0x%.8x\n", *(uint_t*)src);
     break;
   default:
     break;
     memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
     memset(&vm_info, 0, sizeof(struct guest_info));
 
-    os_hooks.print_debug = &PrintBoth;
+    os_hooks.print_debug = &SerialPrint;
     os_hooks.print_info = &Print;
     os_hooks.print_trace = &SerialPrint;
     os_hooks.allocate_pages = &Allocate_VMM_Pages;
       //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
       //      add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
       
-      shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
-      init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
-                                 0x100000, HOST_REGION_PHYSICAL_MEMORY);
-      add_shadow_region(&(vm_info.mem_map),ent);
+      /*
+       shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
+       init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
+       0x100000, HOST_REGION_PHYSICAL_MEMORY);
+       add_shadow_region(&(vm_info.mem_map),ent);
+      */
+
+      add_shadow_region_passthrough(&vm_info, 0x0, 0x100000, 0x100000);
 
       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial);
       
       /*
-      vm_info.cr0 = 0;
-      vm_info.cs.base=0xf000;
-      vm_info.cs.limit=0xffff;
+       vm_info.cr0 = 0;
+       vm_info.cs.base=0xf000;
+       vm_info.cs.limit=0xffff;
       */
       //vm_info.rip = 0xfff0;
 
       vm_info.rip = 0;
       vm_info.vm_regs.rsp = 0x0;
     } else {
-      shadow_region_t *ent = Malloc(sizeof(shadow_region_t));
-      /*
-       init_shadow_region_physical(ent,0xf0000,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
-       0x100000, HOST_REGION_PHYSICAL_MEMORY);
-       add_shadow_region(&(vm_info.mem_map),ent);
-       ent = Malloc(sizeof(shadow_region_t));
-      */
-      void * guest_mem = Allocate_VMM_Pages(256);
+      int i;
+      void * region_start;
 
+ 
       PrintDebug("Guest Size: %lu\n", bootInfo->guest_size);
 
-      memcpy((void *)(guest_mem + 0xf0000), (void *)0x100000, bootInfo->guest_size);
+      struct guest_mem_layout * layout = (struct guest_mem_layout *)0x100000;
+
+      if (layout->magic != MAGIC_CODE) {
+       PrintDebug("Layout Magic Mismatch (0x%x)\n", layout->magic);
+      }
+
+      PrintDebug("%d layout regions\n", layout->num_regions);
 
+      region_start = (void *)&(layout->regions[layout->num_regions]);
 
-      SerialMemDump((unsigned char *)(guest_mem + 0xffff0), 16);
+      PrintDebug("region start = 0x%x\n", region_start);
 
-      init_shadow_region_physical(ent, 0x0, 0x100000, GUEST_REGION_PHYSICAL_MEMORY, 
-                                 (addr_t)guest_mem, HOST_REGION_PHYSICAL_MEMORY);
-      add_shadow_region(&(vm_info.mem_map),ent);
+      for (i = 0; i < layout->num_regions; i++) {
+       struct layout_region * reg = &(layout->regions[i]);
+       uint_t num_pages = (reg->length / PAGE_SIZE) + ((reg->length % PAGE_SIZE) ? 1 : 0);
+       void * guest_mem = Allocate_VMM_Pages(num_pages);
+
+       PrintDebug("Layout Region %d bytes\n", reg->length);
+       memcpy(guest_mem, region_start, reg->length);
+       
+       SerialMemDump((unsigned char *)(guest_mem), 16);
+
+       add_shadow_region_passthrough(&vm_info, reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
+
+       PrintDebug("Adding Shadow Region (0x%x-0x%x) -> 0x%x\n", reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), guest_mem);
+
+       region_start += reg->length;
+      }
+      
+      add_shadow_region_passthrough(&vm_info, 0x0, 0xa0000, (addr_t)Allocate_VMM_Pages(160));
+      add_shadow_region_passthrough(&vm_info, 0xa0000, 0xc0000, 0xa0000); 
+      if (add_shadow_region_passthrough(&vm_info, 0xc7000, 0xf0000, (addr_t)Allocate_VMM_Pages(41)) == -1) {
+       PrintDebug("Error adding shadow region\n");
+      }
+
+      print_shadow_map(&(vm_info.mem_map));
 
       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial);
       hook_io_port(&(vm_info.io_map), 0xa0, &IO_Read, &IO_Write_to_Serial);
       hook_io_port(&(vm_info.io_map), 0xa1, &IO_Read, &IO_Write_to_Serial);
 
+      hook_io_port(&(vm_info.io_map), 0x400, &IO_Read, &IO_Write_to_Serial);
+      hook_io_port(&(vm_info.io_map), 0x401, &IO_Read, &IO_Write_to_Serial);
+      hook_io_port(&(vm_info.io_map), 0x402, &IO_Read, &IO_BOCHS_debug);
+      hook_io_port(&(vm_info.io_map), 0x403, &IO_Read, &IO_Write_to_Serial);
+
       vm_info.rip = 0xfff0;
       vm_info.vm_regs.rsp = 0x0;
     }
     PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.vm_regs.rsp);
     (vmm_ops).init_guest(&vm_info);
     PrintBoth("Starting Guest\n");
+    Clear_Screen();
     (vmm_ops).start_guest(&vm_info);
 
     return 0;
 
 
   while (1) {
 
-    PrintDebug("SVM Launch Args (vmcb=%x), (info=%x), (vm_regs=%x)\n", info->vmm_data,  &(info->vm_regs));
-    PrintDebug("Launching to RIP: %x\n", info->rip);
+    //PrintDebug("SVM Launch Args (vmcb=%x), (info=%x), (vm_regs=%x)\n", info->vmm_data,  &(info->vm_regs));
+    //PrintDebug("Launching to RIP: %x\n", info->rip);
     safe_svm_launch((vmcb_t*)(info->vmm_data), &(info->vm_regs));
     //launch_svm((vmcb_t*)(info->vmm_data));
-    PrintDebug("SVM Returned\n");
+    //PrintDebug("SVM Returned\n");
 
     if (handle_svm_exit(info) != 0) {
       // handle exit code....
   // guest_state->cr0 = 0x00000001;    // PE 
   ctrl_area->guest_ASID = 1;
 
-
   ctrl_area->exceptions.ex_names.de = 1;
   ctrl_area->exceptions.ex_names.df = 1;
   ctrl_area->exceptions.ex_names.pf = 1;
   ctrl_area->exceptions.ex_names.of = 1;
   ctrl_area->exceptions.ex_names.nmi = 1;
 
+  vm_info.vm_regs.rdx = 0x00000f00;
+
+  guest_state->cr0 = 0x60000010;
+
   guest_state->cs.selector = 0xf000;
-  guest_state->cs.limit=~0u;
-  guest_state->cs.base = guest_state->cs.selector<<4;
+  guest_state->cs.limit=0xffff;
+  guest_state->cs.base = 0x0000000f0000LL;
   guest_state->cs.attrib.raw = 0xf3;
 
   
     struct vmcb_selector * seg = segregs[i];
     
     seg->selector = 0x0000;
-    seg->base = seg->selector << 4;
+    //    seg->base = seg->selector << 4;
+    seg->base = 0x00000000;
     seg->attrib.raw = 0xf3;
     seg->limit = ~0u;
   }
   
+  guest_state->gdtr.limit = 0x0000ffff;
+  guest_state->gdtr.base = 0x0000000000000000LL;
+  guest_state->idtr.limit = 0x0000ffff;
+  guest_state->idtr.base = 0x0000000000000000LL;
+
+  guest_state->ldtr.selector = 0x0000;
+  guest_state->ldtr.limit = 0x0000ffff;
+  guest_state->ldtr.base = 0x0000000000000000LL;
+  guest_state->tr.selector = 0x0000;
+  guest_state->tr.limit = 0x0000ffff;
+  guest_state->tr.base = 0x0000000000000000LL;
+
+
+  guest_state->dr6 = 0x00000000ffff0ff0LL;
+  guest_state->dr7 = 0x0000000000000400LL;
+
   if (vm_info.io_map.num_ports > 0) {
     vmm_io_hook_t * iter;
     addr_t io_port_bitmap;
     ctrl_area->instrs.instrs.IOIO_PROT = 1;
   }
 
-  ctrl_area->instrs.instrs.INTR = 1;
+  //ctrl_area->instrs.instrs.INTR = 1;
 
 
 
 
     guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
 
-    //PrintDebugPageTables((pde32_t*)(vm_info.shdw_pg_state.shadow_cr3.e_reg.low));
+    PrintDebugPageTables((pde32_t*)(vm_info.shdw_pg_state.shadow_cr3.e_reg.low));
 
     ctrl_area->cr_reads.crs.cr3 = 1;
     ctrl_area->cr_writes.crs.cr3 = 1;
 
   info->vm_regs.rsp = guest_state->rsp;
 
 
-  PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
-  PrintDebug("RIP: %x\n", guest_state->rip);
+
   
 
 
   exit_code = guest_ctrl->exit_code;
   
   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
-  PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
-
-  PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
-  PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
-
-  PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
-  PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
 
   
   if (exit_code == VMEXIT_IOIO) {
     char buf[15];
     addr_t host_addr;
 
+
+    PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
+    PrintDebug("RIP: %x\n", guest_state->rip);
+    PrintDebug("RIP Linear: %x\n", rip_addr);
+    
+    PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
+    
+    PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
+    PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
+    
+    PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
+    PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
+
+    
+
     if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
       PrintDebug("Could not translate guest_state->rip to host address\n");
       return -1;
 
     PrintTraceMemDump(buf, 15);
 
+    while(1);
+
   }
 
 
 
     return -1;
   }
 
-  PrintDebug("IN on  port %d (0x%x)\n", io_info->port, io_info->port);
+  //PrintDebug("IN on  port %d (0x%x)\n", io_info->port, io_info->port);
 
   if (io_info->sz8) { 
     read_size = 1;
     return -1;
   }
 
-  PrintDebug("INS on  port %d (0x%x)\n", io_info->port, io_info->port);
+  //PrintDebug("INS on  port %d (0x%x)\n", io_info->port, io_info->port);
 
   if (io_info->sz8) { 
     read_size = 1;
     return -1;
   }
 
-  PrintDebug("OUT on  port %d (0x%x)\n", io_info->port, io_info->port);
+  //PrintDebug("OUT on  port %d (0x%x)\n", io_info->port, io_info->port);
 
   if (io_info->sz8) { 
     write_size = 1;
     return -1;
   }
 
-  PrintDebug("OUTS on  port %d (0x%x)\n", io_info->port, io_info->port);
+  //PrintDebug("OUTS on  port %d (0x%x)\n", io_info->port, io_info->port);
 
   if (io_info->sz8) { 
     write_size = 1;
 
   entry->next=entry->prev = NULL;
 }
 
-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)
+int add_shadow_region_passthrough( struct guest_info *  guest_info,
+                                  addr_t               guest_addr_start,
+                                  addr_t               guest_addr_end,
+                                  addr_t               host_addr_start)
 {
-  init_shadow_region(entry, guest_addr_start, guest_addr_end, guest_region_type, host_region_type);
+  shadow_region_t * entry = os_hooks->malloc(sizeof(shadow_region_t));
+
+  init_shadow_region(entry, guest_addr_start, guest_addr_end, 
+                    GUEST_REGION_PHYSICAL_MEMORY, HOST_REGION_PHYSICAL_MEMORY);
   entry->host_addr.phys_addr.host_start = host_addr_start;
 
+  return add_shadow_region(&(guest_info->mem_map), entry);
 }
-                   
 
-void init_shadow_map(shadow_map_t * map) {
+
+
+
+void init_shadow_map(struct shadow_map * map) {
   map->num_regions = 0;
 
   map->head = NULL;
 }
 
 
-void free_shadow_map(shadow_map_t * map) {
+void free_shadow_map(struct shadow_map * map) {
   shadow_region_t * cursor = map->head;
   shadow_region_t * tmp = NULL;
 
 
 
 
-int add_shadow_region(shadow_map_t * map,
+int add_shadow_region(struct shadow_map * map,
                      shadow_region_t * region) 
 {
   shadow_region_t * cursor = map->head;
 
+  PrintDebug("Adding Shadow Region: (0x%x-0x%x)\n", region->guest_start, region->guest_end);
+
   if ((!cursor) || (cursor->guest_start >= region->guest_end)) {
     region->prev = NULL;
     region->next = cursor;
       map->num_regions++;
       
       return 0;
-    } else if (cursor->next->guest_end < region->guest_start) {
+    } else if (cursor->next->guest_end <= region->guest_start) {
       cursor = cursor->next;
     } else {
+      PrintDebug("WTF?\n");
       // This cannot happen!
       // we should panic here
       return -1;
 }
 
 
-int delete_shadow_region(shadow_map_t * map,
+int delete_shadow_region(struct shadow_map * map,
                         addr_t guest_start,
                         addr_t guest_end) {
   return -1;
 
 
 
-shadow_region_t *get_shadow_region_by_index(shadow_map_t *  map,
+shadow_region_t *get_shadow_region_by_index(struct shadow_map *  map,
                                               uint_t index) {
   shadow_region_t * reg = map->head;
   uint_t i = 0;
 }
 
 
-shadow_region_t * get_shadow_region_by_addr(shadow_map_t * map,
+shadow_region_t * get_shadow_region_by_addr(struct shadow_map * map,
                                               addr_t addr) {
   shadow_region_t * reg = map->head;
 
 
 
 
-host_region_type_t lookup_shadow_map_addr(shadow_map_t * map, addr_t guest_addr, addr_t * host_addr) {
+host_region_type_t lookup_shadow_map_addr(struct shadow_map * map, addr_t guest_addr, addr_t * host_addr) {
   shadow_region_t * reg = get_shadow_region_by_addr(map, guest_addr);
 
   if (!reg) {
 }
 
 
-void print_shadow_map(shadow_map_t * map) {
+void print_shadow_map(struct shadow_map * map) {
   shadow_region_t * cur = map->head;
   int i = 0;
 
 
 pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info) {
   ullong_t current_page_addr = 0;
   int i, j;
-  shadow_map_t * map = &(guest_info->mem_map);
+  struct shadow_map * map = &(guest_info->mem_map);
 
 
   pde32_t * pde = os_hooks->allocate_pages(1);
   int i;
 
   PrintDebug("Page Directory at %p:\n", pde);
-  for (i = 0; (i < MAX_PDE32_ENTRIES) && pde[i].present; i++) { 
-    PrintPDE32((void*)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+  for (i = 0; (i < MAX_PDE32_ENTRIES); i++) { 
+    if ( pde[i].present) {
+      PrintPDE32((void*)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+    }
   }
 }
 
   int i;
 
   PrintDebug("Page Table at %p:\n", pte);
-  for (i = 0; (i < MAX_PTE32_ENTRIES) && pte[i].present; i++) { 
-    PrintPTE32(starting_address + (PAGE_SIZE * i), &(pte[i]));
+  for (i = 0; (i < MAX_PTE32_ENTRIES) ; i++) { 
+    if (pte[i].present) {
+      PrintPTE32(starting_address + (PAGE_SIZE * i), &(pte[i]));
+    }
   }
 }
 
   
   PrintDebug("Dumping the pages starting with the pde page at %p\n", pde);
 
-  for (i = 0; (i < MAX_PDE32_ENTRIES) && pde[i].present; i++) { 
-    PrintPDE32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
-    PrintPT32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (void *)(pde[i].pt_base_addr << PAGE_POWER));
+  for (i = 0; (i < MAX_PDE32_ENTRIES); i++) { 
+    if (pde[i].present) {
+      PrintPDE32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+      PrintPT32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (void *)(pde[i].pt_base_addr << PAGE_POWER));
+    }
   }
 }