text: /*
   * @XMHF_LICENSE_HEADER_START@
   *
   * eXtensible, Modular Hypervisor Framework (XMHF)
   * Copyright (c) 2009-2012 Carnegie Mellon University
   * Copyright (c) 2010-2012 VDG Inc.
   * All Rights Reserved.
   *
   * Developed by: XMHF Team
   *               Carnegie Mellon University / CyLab
   *               VDG Inc.
   *               http://xmhf.org
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * Neither the names of Carnegie Mellon or VDG Inc, nor the names of
   * its contributors may be used to endorse or promote products derived
   * from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
   * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
   * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
   * @XMHF_LICENSE_HEADER_END@
   */
  
  /*
   * EMHF base platform component interface, x86 vmx backend
   * VMCS to memory interface
   * author: amit vasudevan (amitvasudevan@acm.org)
   */
  
  #include <xmhf.h>
  
  //---putVMCS--------------------------------------------------------------------
  // routine takes vcpu vmcsfields and stores it in the CPU VMCS 
  void emhf_baseplatform_arch_x86vmx_putVMCS(VCPU *vcpu){
      unsigned int i;
      for(i=0; i < g_vmx_vmcsrwfields_encodings_count; i++){
        u32 *field = (u32 *)((u32)&vcpu->vmcs + (u32)g_vmx_vmcsrwfields_encodings[i].fieldoffset);
        u32 fieldvalue = *field;
        //printf("\nvmwrite: enc=0x%08x, value=0x%08x", vmcsrwfields_encodings[i].encoding, fieldvalue);
        if(!__vmx_vmwrite(g_vmx_vmcsrwfields_encodings[i].encoding, fieldvalue)){
          printf("\nCPU(0x%02x): VMWRITE failed. HALT!", vcpu->id);
          HALT();
        }
      }
  }
  
  //---getVMCS--------------------------------------------------------------------
  // routine takes CPU VMCS and stores it in vcpu vmcsfields  
  void emhf_baseplatform_arch_x86vmx_getVMCS(VCPU *vcpu){
    unsigned int i;
    for(i=0; i < g_vmx_vmcsrwfields_encodings_count; i++){
        u32 *field = (u32 *)((u32)&vcpu->vmcs + (u32)g_vmx_vmcsrwfields_encodings[i].fieldoffset);
        __vmx_vmread(g_vmx_vmcsrwfields_encodings[i].encoding, field);
    }  
    for(i=0; i < g_vmx_vmcsrofields_encodings_count; i++){
        u32 *field = (u32 *)((u32)&vcpu->vmcs + (u32)g_vmx_vmcsrofields_encodings[i].fieldoffset);
        __vmx_vmread(g_vmx_vmcsrofields_encodings[i].encoding, field);
    }  
  }
  
  //--debug: dumpVMCS dumps VMCS contents-----------------------------------------
  void emhf_baseplatform_arch_x86vmx_dumpVMCS(VCPU *vcpu){
    		printf("\nGuest State follows:");
  		printf("\nguest_CS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_CS_selector);
  		printf("\nguest_DS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_DS_selector);
  		printf("\nguest_ES_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_ES_selector);
  		printf("\nguest_FS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_FS_selector);
  		printf("\nguest_GS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_GS_selector);
  		printf("\nguest_SS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_SS_selector);
  		printf("\nguest_TR_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_TR_selector);
  		printf("\nguest_LDTR_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_LDTR_selector);
  		printf("\nguest_CS_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_CS_access_rights);
  		printf("\nguest_DS_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_DS_access_rights);
  		printf("\nguest_ES_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_ES_access_rights);
  		printf("\nguest_FS_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_FS_access_rights);
  		printf("\nguest_GS_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_GS_access_rights);
  		printf("\nguest_SS_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_SS_access_rights);
  		printf("\nguest_TR_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_TR_access_rights);
  		printf("\nguest_LDTR_access_rights=0x%08lx", 
  			(unsigned long)vcpu->vmcs.guest_LDTR_access_rights);
  
  		printf("\nguest_CS_base/limit=0x%08lx/0x%04x", 
  			(unsigned long)vcpu->vmcs.guest_CS_base, (unsigned short)vcpu->vmcs.guest_CS_limit);
  		printf("\nguest_DS_base/limit=0x%08lx/0x%04x", 
  			(unsigned long)vcpu->vmcs.guest_DS_base, (unsigned short)vcpu->vmcs.guest_DS_limit);
  		printf("\nguest_ES_base/limit=0x%08lx/0x%04x", 
  			(unsigned long)vcpu->vmcs.guest_ES_base, (unsigned short)vcpu->vmcs.guest_ES_limit);
  		printf("\nguest_FS_base/limit=0x%08lx/0x%04x", 
  			(unsigned long)vcpu->vmcs.guest_FS_base, (unsigned short)vcpu->vmcs.guest_FS_limit);
  		printf("\nguest_GS_base/limit=0x%08lx/0x%04x", 
  			(unsigned long)vcpu->vmcs.guest_GS_base, (unsigned short)vcpu->vmcs.guest_GS_limit);
  		printf("\nguest_SS_base/limit=0x%08lx/0x%04x", 
  			(unsigned long)vcpu->vmcs.guest_SS_base, (unsigned short)vcpu->vmcs.guest_SS_limit);
  		printf("\nguest_GDTR_base/limit=0x%08lx/0x%04x",
  			(unsigned long)vcpu->vmcs.guest_GDTR_base, (unsigned short)vcpu->vmcs.guest_GDTR_limit);		
  		printf("\nguest_IDTR_base/limit=0x%08lx/0x%04x",
  			(unsigned long)vcpu->vmcs.guest_IDTR_base, (unsigned short)vcpu->vmcs.guest_IDTR_limit);		
  		printf("\nguest_TR_base/limit=0x%08lx/0x%04x",
  			(unsigned long)vcpu->vmcs.guest_TR_base, (unsigned short)vcpu->vmcs.guest_TR_limit);		
  		printf("\nguest_LDTR_base/limit=0x%08lx/0x%04x",
  			(unsigned long)vcpu->vmcs.guest_LDTR_base, (unsigned short)vcpu->vmcs.guest_LDTR_limit);		
  
  		printf("\nguest_CR0=0x%08lx, guest_CR4=0x%08lx, guest_CR3=0x%08lx",
  			(unsigned long)vcpu->vmcs.guest_CR0, (unsigned long)vcpu->vmcs.guest_CR4,
  			(unsigned long)vcpu->vmcs.guest_CR3);
  		printf("\nguest_RSP=0x%08lx", (unsigned long)vcpu->vmcs.guest_RSP);
  		printf("\nguest_RIP=0x%08lx", (unsigned long)vcpu->vmcs.guest_RIP);
  		printf("\nguest_RFLAGS=0x%08lx", (unsigned long)vcpu->vmcs.guest_RFLAGS);
  }
  