blob: e532c20fc7d52b12ed1db75984f0388d2e031a7d [file]
/*
* Copyright 2017, Data61
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
* ABN 41 687 119 230.
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(DATA61_GPL)
*/
#include <stdio.h>
#include <stdlib.h>
#include <sel4/sel4.h>
#include <sel4vm/guest_vm.h>
#include <sel4vm/arch/vmcs_fields.h>
#include "guest_state.h"
#include "vmcs.h"
/*init the vmcs structure for a guest os thread*/
void vm_vmcs_init_guest(vm_vcpu_t *vcpu)
{
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_ES_SELECTOR, 2 << 3);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_CS_SELECTOR, BIT(3));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SS_SELECTOR, 2 << 3);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_DS_SELECTOR, 2 << 3);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_FS_SELECTOR, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_GS_SELECTOR, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_LDTR_SELECTOR, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_TR_SELECTOR, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_ES_LIMIT, ~0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_CS_LIMIT, ~0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SS_LIMIT, ~0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_DS_LIMIT, ~0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_FS_LIMIT, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_GS_LIMIT, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_LDTR_LIMIT, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_TR_LIMIT, 0x0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_GDTR_LIMIT, 0x0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_IDTR_LIMIT, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_ES_ACCESS_RIGHTS, 0xC093);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_CS_ACCESS_RIGHTS, 0xC09B);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SS_ACCESS_RIGHTS, 0xC093);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_DS_ACCESS_RIGHTS, 0xC093);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_FS_ACCESS_RIGHTS, BIT(16));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_GS_ACCESS_RIGHTS, BIT(16));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_LDTR_ACCESS_RIGHTS, BIT(16));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_TR_ACCESS_RIGHTS, 0x8B);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SYSENTER_CS, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_CR0_MASK, vcpu->vcpu_arch.guest_state->virt.cr.cr0_mask);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_CR4_MASK, vcpu->vcpu_arch.guest_state->virt.cr.cr4_mask);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_CR0_READ_SHADOW, vcpu->vcpu_arch.guest_state->virt.cr.cr0_shadow);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_CR4_READ_SHADOW, vcpu->vcpu_arch.guest_state->virt.cr.cr4_shadow);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_ES_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_CS_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SS_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_DS_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_FS_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_GS_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_LDTR_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_TR_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_GDTR_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_IDTR_BASE, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_RFLAGS, BIT(1));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SYSENTER_ESP, 0);
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_SYSENTER_EIP, 0);
vcpu->vcpu_arch.guest_state->machine.control_ppc = VMX_CONTROL_PPC_HLT_EXITING | VMX_CONTROL_PPC_CR3_LOAD_EXITING |
VMX_CONTROL_PPC_CR3_STORE_EXITING;
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_PRIMARY_PROCESSOR_CONTROLS,
vcpu->vcpu_arch.guest_state->machine.control_ppc);
vm_vmcs_read(vcpu->vcpu.cptr, VMX_CONTROL_ENTRY_INTERRUPTION_INFO, &vcpu->vcpu_arch.guest_state->machine.control_entry);
#ifdef CONFIG_LIB_VM_VMX_TIMER_DEBUG
/* Enable pre-emption timer */
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_PIN_EXECUTION_CONTROLS, BIT(6));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_CONTROL_EXIT_CONTROLS, BIT(22));
vm_vmcs_write(vcpu->vcpu.cptr, VMX_GUEST_VMX_PREEMPTION_TIMER_VALUE, CONFIG_LIB_VM_VMX_TIMER_TIMEOUT);
#endif
}