diff options
author | neel <neel@FreeBSD.org> | 2013-11-25 19:04:51 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2013-11-25 19:04:51 +0000 |
commit | 89dbc92028f9ab8548675d88e47f08f520ecde12 (patch) | |
tree | 5d29fe534d31ddc45fa2bf63ae3f535aec050003 /sys/amd64/vmm/vmm.c | |
parent | 2f61636cf871204be51aed93531356162b74c261 (diff) | |
download | FreeBSD-src-89dbc92028f9ab8548675d88e47f08f520ecde12.zip FreeBSD-src-89dbc92028f9ab8548675d88e47f08f520ecde12.tar.gz |
Add HPET device emulation to bhyve.
bhyve supports a single timer block with 8 timers. The timers are all 32-bit
and capable of being operated in periodic mode. All timers support interrupt
delivery using MSI. Timers 0 and 1 also support legacy interrupt routing.
At the moment the timers are not connected to any ioapic pins but that will
be addressed in a subsequent commit.
This change is based on a patch from Tycho Nightingale (tycho.nightingale@pluribusnetworks.com).
Diffstat (limited to 'sys/amd64/vmm/vmm.c')
-rw-r--r-- | sys/amd64/vmm/vmm.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 40254c6..3e52a8e 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include "vmm_host.h" #include "vmm_mem.h" #include "vmm_util.h" +#include "vhpet.h" #include "vioapic.h" #include "vlapic.h" #include "vmm_msr.h" @@ -108,6 +109,7 @@ struct mem_seg { struct vm { void *cookie; /* processor-specific data */ void *iommu; /* iommu-specific data */ + struct vhpet *vhpet; /* virtual HPET */ struct vioapic *vioapic; /* virtual ioapic */ struct vmspace *vmspace; /* guest's address space */ struct vcpu vcpu[VM_MAXCPU]; @@ -304,6 +306,7 @@ vm_create(const char *name, struct vm **retvm) strcpy(vm->name, name); vm->cookie = VMINIT(vm, vmspace_pmap(vmspace)); vm->vioapic = vioapic_init(vm); + vm->vhpet = vhpet_init(vm); for (i = 0; i < VM_MAXCPU; i++) { vcpu_init(vm, i); @@ -337,6 +340,9 @@ vm_destroy(struct vm *vm) if (vm->iommu != NULL) iommu_destroy_domain(vm->iommu); + vhpet_cleanup(vm->vhpet); + vioapic_cleanup(vm->vioapic); + for (i = 0; i < vm->num_mem_segs; i++) vm_free_mem_seg(vm, &vm->mem_segs[i]); @@ -345,8 +351,6 @@ vm_destroy(struct vm *vm) for (i = 0; i < VM_MAXCPU; i++) vcpu_cleanup(&vm->vcpu[i]); - vioapic_cleanup(vm->vioapic); - VMSPACE_FREE(vm->vmspace); VMCLEANUP(vm->cookie); @@ -967,13 +971,16 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, boolean_t *retu) if (vmm_decode_instruction(vm, vcpuid, gla, vie) != 0) return (EFAULT); - /* return to userland unless this is a local apic access */ + /* return to userland unless this is an in-kernel emulated device */ if (gpa >= DEFAULT_APIC_BASE && gpa < DEFAULT_APIC_BASE + PAGE_SIZE) { mread = lapic_mmio_read; mwrite = lapic_mmio_write; } else if (gpa >= VIOAPIC_BASE && gpa < VIOAPIC_BASE + VIOAPIC_SIZE) { mread = vioapic_mmio_read; mwrite = vioapic_mmio_write; + } else if (gpa >= VHPET_BASE && gpa < VHPET_BASE + VHPET_SIZE) { + mread = vhpet_mmio_read; + mwrite = vhpet_mmio_write; } else { *retu = TRUE; return (0); @@ -1169,6 +1176,13 @@ vm_ioapic(struct vm *vm) return (vm->vioapic); } +struct vhpet * +vm_hpet(struct vm *vm) +{ + + return (vm->vhpet); +} + boolean_t vmm_is_pptdev(int bus, int slot, int func) { |