# Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.11 $
+# $Revision: 1.12 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
        bget.c malloc.c \
        synch.c kthread.c \
        serial.c  reboot.c \
-        paging.c vmx.c vmcs_gen.c vmcs.c\
-        svm.c vmm.c vmm_util.c \
+        paging.c vmx.c vmcs_gen.c vmcs.c \
+        svm.c vmm.c vmm_util.c vmm_stubs.c \
        debug.c\
        main.c
 
 
 #ifndef __SVM_H
 #define __SVM_H
 
+#include <geekos/vmm_util.h>
 #include <geekos/vmm.h>
 
 #define CPUID_FEATURE_IDS 0x80000001
 #define SVM_SMM_CTL_MSR_rsm_cycle 0x00000010
 
 #define SVM_VM_HSAVE_PA_MSR      0xc0010117
+
 #define SVM_KEY_MSR              0xc0010118
 
 /******/
 
 
 
 
+#define VMCB_CTRL_AREA_OFFSET                   0x0
+#define VMCB_STATE_SAVE_AREA_OFFSET             0x400
+
+
+#define GET_VMCB_CTRL_AREA(page)         (page + VMCB_CONTROL_AREA_OFFSET)
+#define GET_VMCB_SAVE_STATE_AREA(page)   (page + VMCB_STATE_SAVE_AREA_OFFSET)
+
 
 #if __TINYC__
 #define PACKED
 
 
 union Exception_Vectors {
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uint_t ex0         : 1        PACKED;
     uint_t ex1         : 1        PACKED;
 
 
 union Instr_Intercepts {
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uint_t INTR        : 1        PACKED;
     uint_t NMI         : 1        PACKED;
 };
 
 union SVM_Instr_Intercepts { 
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uint_t VMRUN      : 1         PACKED;
     uint_t VMMCALL    : 1         PACKED;
     uint_t MONITOR    : 1         PACKED;
     uint_t MWAIT_always : 1       PACKED;
     uint_t MWAIT_if_armed : 1     PACKED;
-    ulong_t reserved  : 19        PACKED;
+    uint_t reserved  : 19         PACKED;  // Should be 0
   } instrs;
 };
 
 
 union Guest_Control {
-  ulong_t bitmap                  PACKED;
+  uint_t bitmap                  PACKED;
   struct {
     uchar_t V_TPR                 PACKED;
     uint_t V_IRQ      : 1         PACKED;
-    uint_t rsvd1      : 7         PACKED;
+    uint_t rsvd1      : 7         PACKED;  // Should be 0
     uint_t V_INTR_PRIO : 4        PACKED;
     uint_t V_IGN_TPR  : 1         PACKED;
-    uint_t rsvd2      : 3         PACKED;
+    uint_t rsvd2      : 3         PACKED;  // Should be 0
     uint_t V_INTR_MASKING : 1     PACKED;
-    uint_t rsvd3      : 7         PACKED;
+    uint_t rsvd3      : 7         PACKED;  // Should be 0
     uchar_t V_INTR_VECTOR         PACKED;
-    uint_t rsvd4      : 24        PACKED;
+    uint_t rsvd4      : 24        PACKED;  // Should be 0
   } ctrls;
 };
 
 
 typedef struct VMCB_Control_Area {
   // offset 0x0
-  union Ctrl_Registers cr_reads        PACKED;
-  union Ctrl_Registers cr_writes       PACKED;
-  union Debug_Registers dr_reads       PACKED;
-  union Debug_Registers dr_writes      PACKED;
-  union Exception_Vectors exceptions   PACKED;
-  union Instr_Intercepts instrs        PACKED;
+  union Ctrl_Registers cr_reads         PACKED;
+  union Ctrl_Registers cr_writes        PACKED;
+  union Debug_Registers dr_reads        PACKED;
+  union Debug_Registers dr_writes       PACKED;
+  union Exception_Vectors exceptions    PACKED;
+  union Instr_Intercepts instrs         PACKED;
   union SVM_Instr_Intercepts svm_instrs PACKED;
 
-  uchar_t rsvd1[43]                    PACKED;
+  uchar_t rsvd1[43]                     PACKED;  // Should be 0
 
   // offset 0x040
-  ullong_t IOPM_BASE_PA                PACKED;
-  ullong_t MSRPM_BASE_PA               PACKED;
-  ullong_t TSC_OFFSET                  PACKED;
+  ullong_t IOPM_BASE_PA                 PACKED;
+  ullong_t MSRPM_BASE_PA                PACKED;
+  ullong_t TSC_OFFSET                   PACKED;
 
-  ulong_t guest_ASID                   PACKED;
-  uchar_t TLB_CONTROL                  PACKED;
+  uint_t guest_ASID                     PACKED;
+  uchar_t TLB_CONTROL                   PACKED;
 
-  uchar_t rsvd2[3]                     PACKED;
+  uchar_t rsvd2[3]                      PACKED;  // Should be 0
 
-  union Guest_Control guest_ctrl       PACKED;
+  union Guest_Control guest_ctrl        PACKED;
   
-  ulong_t interrupt_shadow  : 1        PACKED;
-  ulong_t rsvd3             : 31       PACKED;
-  ulong_t rsvd4                        PACKED;
+  uint_t interrupt_shadow  : 1          PACKED;
+  uint_t rsvd3             : 31         PACKED;  // Should be 0
+  uint_t rsvd4                          PACKED;  // Should be 0
 
-  ullong_t exit_code                   PACKED;
-  ullong_t exit_info1                  PACKED;
-  ullong_t exit_info2                  PACKED;
+  ullong_t exit_code                    PACKED;
+  ullong_t exit_info1                   PACKED;
+  ullong_t exit_info2                   PACKED;
 
   /* This could be a typo in the manual....
    * It doesn't actually say that there is a reserved bit
    * But it does say that the EXITINTINFO field is in bits 63-1
    * ALL other occurances mention a 1 bit reserved field
    */
-  ulong_t rsvd5             : 1        PACKED;
-  ullong_t exit_int_info    : 63       PACKED;
+  uint_t rsvd5             : 1          PACKED;
+  ullong_t exit_int_info   : 63         PACKED;
   /* ** */
 
-  ulong_t NP_ENABLE         : 1        PACKED;
-  ullong_t rsvd6            : 63       PACKED;
+  uint_t NP_ENABLE         : 1          PACKED;
+  ullong_t rsvd6           : 63         PACKED;  // Should be 0 
 
-  uchar_t rsvd7[15]                    PACKED;
+  uchar_t rsvd7[15]                     PACKED;  // Should be 0
 
   // Offset 0xA8
-  ullong_t EVENTINJ                    PACKED;
+  ullong_t EVENTINJ                     PACKED;
 
 
   /* This could be a typo in the manual....
    * But it does say that the EXITINTINFO field is in bits 63-1
    * ALL other occurances mention a 1 bit reserved field
    */
-  ulong_t rsvd8             : 1        PACKED;
-  ullong_t N_CR3            : 63       PACKED;
+  uint_t rsvd8              : 1         PACKED;
+  ullong_t N_CR3            : 63        PACKED;
   /* ** */
 
-  ulong_t LBR_VIRTUALIZATION_ENABLE  : 1  PACKED;
-  ullong_t rsvd9            : 63       PACKED;
+  uint_t LBR_VIRTUALIZATION_ENABLE : 1  PACKED;
+  ullong_t rsvd9            : 63        PACKED;   // Should be 0
 
 } vmcb_ctrl_t;
 
 struct vmcb_selector {
   ushort_t selector                   PACKED;
   ushort_t attrib                     PACKED;
-  ulong_t  limit                      PACKED;
+  uint_t  limit                       PACKED;
   ullong_t base                       PACKED;
 }
 
 
-
-
-
-
-
 typedef struct VMCB_State_Save_Area {
   struct vmcb_selector es            PACKED; // only lower 32 bits of base are implemented
   struct vmcb_selector cs            PACKED; // only lower 32 bits of base are implemented
   uchar_t cpl                        PACKED; // if the guest is real-mode then the CPL is forced to 0
                                              // if the guest is virtual-mode then the CPL is forced to 3
 
-  ulong_t rsvd2                      PACKED;
+  uint_t rsvd2                       PACKED;
 
   // offset 0x0d0
   ullong_t efer                      PACKED;
   uchar_t rsvd6[31]                  PACKED;
 
   //offset 0x268
-  ullong_t g_pat                     PACKED; // Guest PAT                          -- only used if nested paging is enabled
-  ullong_t dbgctl                    PACKED; // Guest DBGCTL MSR                   -- only used if the LBR registers are virtualized
-  ullong_t br_from                   PACKED; // Guest LastBranchFromIP MSR         -- only used if the LBR registers are virtualized
-  ullong_t br_to                     PACKED; // Guest LastBranchToIP MSR           -- only used if the LBR registers are virtualized
-  ullong_t lastexcpfrom              PACKED; // Guest LastExceptionFromIP MSR      -- only used if the LBR registers are virtualized
-  ullong_t lastexcpto                PACKED; // Guest LastExceptionToIP MSR        -- only used if the LBR registers are virtualized
+  ullong_t g_pat                     PACKED; // Guest PAT                     
+                                             //   -- only used if nested paging is enabled
+  ullong_t dbgctl                    PACKED; // Guest DBGCTL MSR               
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t br_from                   PACKED; // Guest LastBranchFromIP MSR
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t br_to                     PACKED; // Guest LastBranchToIP MSR   
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t lastexcpfrom              PACKED; // Guest LastExceptionFromIP MSR
+                                             //   -- only used if the LBR registers are virtualized
+  ullong_t lastexcpto                PACKED; // Guest LastExceptionToIP MSR 
+                                             //   -- only used if the LBR registers are virtualized
 
 } vmcb_saved_state_t;
 
 
 
 
 
-
 #define VMM_INVALID_CPU 0
 #define VMM_VMX_CPU 1
 #define VMM_SVM_CPU 2
   void (*print_info)(const char * format, ...);
   void (*print_debug)(const char * format, ...);
   void (*print_trace)(const char * format, ...);
+  
+  void *(*Allocate_Pages)(int numPages);
+  void (*Free_Page)(void * page); 
 };
 
 
 
--- /dev/null
+#ifndef __VMM_STUBS_H
+#define __VMM_STUBS_H
+
+
+#include <geekos/mem.h>
+
+
+void * Allocate_VMM_Pages(int num_pages);
+void Free_VMM_Page(void * page);
+
+
+
+
+#endif
 
 
 
 
+//#define PAGE_SIZE 4096
+
+typedef union reg_ex {
+  ullong_t r_reg;
+  struct {
+    uint_t low;
+    uint_t high;
+  } e_reg;
+
+} reg_ex_t;
+
+
+
 void PrintTraceHex(unsigned char x);
 
 void PrintTraceMemDump(unsigned char * start, int n);
 
  * 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.11 $
+ * $Revision: 1.12 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 #include <geekos/gdt.h>
 
 #include <geekos/vmm_sizes.h>
+#include <geekos/vmm_stubs.h>
 
 /*
   static inline unsigned int cpuid_ecx(unsigned int op)
 
 
 
-extern uint_t VMCS_STORE();
-extern uint_t VMCS_READ();
-
 
 
 void Buzzer(ulong_t arg) {
 
 
 
+
+
 void Hello(ulong_t arg)
 {
   char *b="hello ";
 }
 */
 
+
+
 int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
 {
   uint_t address;
   os_hooks.print_debug = &PrintBoth;
   os_hooks.print_info = &Print;
   os_hooks.print_trace = &SerialPrint;
+  os_hooks.Allocate_Pages = &Allocate_VMM_Pages;
+  os_hooks.Free_Page = &Free_VMM_Page;
 
   Init_VMM(&os_hooks);
 
 
 #include <geekos/svm.h>
 
 
+extern struct vmm_os_hooks * os_hooks;
+
 extern uint_t cpuid_ecx(uint_t op);
 extern uint_t cpuid_edx(uint_t op);
-extern void Get_MSR(uint_t MSR, ulong_t * high_byte, ulong_t * low_byte); 
-extern void Set_MSR(uint_t MSR, ulong_t high_byte, ulong_t low_byte);
+extern void Get_MSR(uint_t MSR, uint_t * high_byte, uint_t * low_byte); 
+extern void Set_MSR(uint_t MSR, uint_t high_byte, uint_t low_byte);
 
 /* Checks machine SVM capability */
 /* Implemented from: AMD Arch Manual 3, sect 15.4 */ 
 int is_svm_capable() {
   uint_t ret =  cpuid_ecx(CPUID_FEATURE_IDS);
-  ulong_t vm_cr_low = 0, vm_cr_high = 0;
+  uint_t vm_cr_low = 0, vm_cr_high = 0;
 
 
   if ((ret & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
   return 0;
 }
 
+
+
 void Init_SVM() {
-  ulong_t msr_val_low = 0, msr_val_high = 0;
+  reg_ex_t msr;
+  void * host_state;
+
 
-  Get_MSR(EFER_MSR, &msr_val_high, &msr_val_low);
-  msr_val_low |= EFER_MSR_svm_enable;
-  Set_MSR(EFER_MSR, 0, msr_val_low);
+  // setup 
+  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);
   
-  PrintDebug("SVM Inited\n");
+  PrintDebug("SVM Enabled\n");
+
+
+  // Setup the host state save area
+  host_state = os_hooks->Allocate_Pages(1);
+  
+  msr.e_reg.high = 0;
+  msr.e_reg.low = (uint_t)host_state;
+
+  Set_MSR(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
+
 
   return;
 }
+
+
+
+
+void Allocate_VMCB() {
+  void * vmcb_page = os_hooks->Allocate_Pages(1);
+
+
+  memset(vmcb_page, 0, 4096);
+}
 
--- /dev/null
+#include <geekos/vmm_stubs.h>
+
+
+
+void * Allocate_VMM_Pages(int num_pages) {
+  return Alloc_Page();
+}
+
+
+
+
+void Free_VMM_Page(void * page) {
+  Free_Page(page);
+}
 
   uint_t reserved =0;
   union VMX_MSR msr;
 
-  PrintTrace("SetCtrlBitsCorrectly(%x,%x)\n",msrno,vmcsno);
+  PrintTrace("SetCtrlBitsCorrectly(%x,%x)\n", msrno, vmcsno);
   Get_MSR(msrno, &msr.regs.high, &msr.regs.low);
   PrintTrace("MSR %x = %x : %x \n", msrno, msr.regs.high, msr.regs.low);
   reserved = msr.regs.low;
 
 static int PanicUnhandledVMExit(struct VM *vm)
 {
-  Print("Panicking due to VMExit with reason %u\n",vm->vmcs.exitInfoFields.reason);
-  PrintTrace("Panicking due to VMExit with reason %u\n",vm->vmcs.exitInfoFields.reason);
+  PrintInfo("Panicking due to VMExit with reason %u\n", vm->vmcs.exitInfoFields.reason);
+  PrintTrace("Panicking due to VMExit with reason %u\n", vm->vmcs.exitInfoFields.reason);
   PrintTrace_VMCS_ALL();
   PrintTrace_VMX_Regs(&(vm->registers));
   VMXPanic();
   address=GetLinearIP(vm);
 
   PrintTrace("Handling Input/Output Instruction Exit\n");
-  if (SERIAL_PRINT_DEBUG && 1000>=SERIAL_PRINT_DEBUG_LEVEL) {
-      PrintTrace_VMX_Regs(regs);
-  }
-  PrintTrace("Qualifications=0x%x\n",exitinfo->qualification);
-  PrintTrace("Reason=0x%x\n",exitinfo->reason);
+
+  PrintTrace_VMX_Regs(regs);
+
+  PrintTrace("Qualifications=0x%x\n", exitinfo->qualification);
+  PrintTrace("Reason=0x%x\n", exitinfo->reason);
   PrintTrace("IO Port: 0x%x (%d)\n", qual->port, qual->port);
-  PrintTrace("Instruction Info=%x\n",exitinfo->instrInfo);
+  PrintTrace("Instruction Info=%x\n", exitinfo->instrInfo);
   PrintTrace("%x : %s %s %s instruction of length %d for %d bytes from/to port 0x%x\n",
                   address,
                   qual->dir == 0 ? "output" : "input",
                   qual->accessSize==0 ? 1 : qual->accessSize==1 ? 2 : 4,
                   qual->port);
 
-  if (qual->port==PIC_MASTER_CMD_ISR_PORT ||
-      qual->port==PIC_MASTER_IMR_PORT ||
-      qual->port==PIC_SLAVE_CMD_ISR_PORT ||
-      qual->port==PIC_SLAVE_IMR_PORT) {
+  if ((qual->port == PIC_MASTER_CMD_ISR_PORT) ||
+      (qual->port == PIC_MASTER_IMR_PORT)     ||
+      (qual->port == PIC_SLAVE_CMD_ISR_PORT)  ||
+      (qual->port == PIC_SLAVE_IMR_PORT)) {
     PrintTrace( "PIC Access\n");
   }
                   
 
-  if (qual->dir==1 && qual->REP==0 && qual->string==0) { 
+  if ((qual->dir == 1) && (qual->REP == 0) && (qual->string == 0)) { 
     char byte = In_Byte(qual->port);
 
     vm->vmcs.guestStateArea.rip += exitinfo->instrLength;
     regs->eax = (regs->eax & 0xffffff00) | byte;
-    PrintTrace("Returning 0x%x in eax\n",(regs->eax));
+    PrintTrace("Returning 0x%x in eax\n", (regs->eax));
   }
 
   if (qual->dir==0 && qual->REP==0 && qual->string==0) { 
   //  tmpReg = 0x4100;
   tmpReg = 0xffffffff;
   if (VMCS_WRITE(EXCEPTION_BITMAP,&tmpReg ) != VMX_SUCCESS) {
-    Print("Bitmap error\n");
+    PrintInfo("Bitmap error\n");
   }
 
   ConfigureExits(vm);
 
   *(ulong_t*)region = basicMSR.vmxBasic.revision;
 
-  Print("VMX revision: 0x%lu\n", *(ulong_t *)region);
+  PrintInfo("VMX revision: 0x%lu\n", *(ulong_t *)region);
 
   return region;
 }