summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/vmm_lapic.c
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2012-09-21 03:09:23 +0000
committerneel <neel@FreeBSD.org>2012-09-21 03:09:23 +0000
commitc0caea8c2fc75a9ca5f5a67dd11462ef6542afc2 (patch)
tree8fa2cb11965c87d24885e442e87e35ee181ef393 /sys/amd64/vmm/vmm_lapic.c
parent6c5ad005bed33e80c94460b6694d199348dac472 (diff)
downloadFreeBSD-src-c0caea8c2fc75a9ca5f5a67dd11462ef6542afc2.zip
FreeBSD-src-c0caea8c2fc75a9ca5f5a67dd11462ef6542afc2.tar.gz
Restructure the x2apic access code in preparation for supporting memory mapped
access to the local apic. The vlapic code is now aware of the mode that the guest is using to access the local apic. Reviewed by: grehan@
Diffstat (limited to 'sys/amd64/vmm/vmm_lapic.c')
-rw-r--r--sys/amd64/vmm/vmm_lapic.c78
1 files changed, 66 insertions, 12 deletions
diff --git a/sys/amd64/vmm/vmm_lapic.c b/sys/amd64/vmm/vmm_lapic.c
index 4aca087..13550b4 100644
--- a/sys/amd64/vmm/vmm_lapic.c
+++ b/sys/amd64/vmm/vmm_lapic.c
@@ -33,20 +33,18 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/smp.h>
+#include <x86/specialreg.h>
+
#include <machine/vmm.h>
#include "vmm_ipi.h"
#include "vmm_lapic.h"
#include "vlapic.h"
-int
-lapic_write(struct vm *vm, int cpu, u_int offset, uint64_t val)
+static int
+lapic_write(struct vlapic *vlapic, u_int offset, uint64_t val)
{
int handled;
- struct vlapic *vlapic;
-
- vlapic = vm_lapic(vm, cpu);
-
if (vlapic_op_mem_write(vlapic, offset, DWORD, val) == 0)
handled = 1;
else
@@ -55,15 +53,11 @@ lapic_write(struct vm *vm, int cpu, u_int offset, uint64_t val)
return (handled);
}
-int
-lapic_read(struct vm *vm, int cpu, u_int offset, uint64_t *rv)
+static int
+lapic_read(struct vlapic *vlapic, u_int offset, uint64_t *rv)
{
int handled;
- struct vlapic *vlapic;
-
- vlapic = vm_lapic(vm, cpu);
-
if (vlapic_op_mem_read(vlapic, offset, DWORD, rv) == 0)
handled = 1;
else
@@ -120,3 +114,63 @@ lapic_timer_tick(struct vm *vm, int cpu)
vlapic_timer_tick(vlapic);
}
+
+static boolean_t
+x2apic_msr(u_int msr)
+{
+ if (msr >= 0x800 && msr <= 0xBFF)
+ return (TRUE);
+ else
+ return (FALSE);
+}
+
+static u_int
+x2apic_msr_to_regoff(u_int msr)
+{
+
+ return ((msr - 0x800) << 4);
+}
+
+boolean_t
+lapic_msr(u_int msr)
+{
+
+ if (x2apic_msr(msr) || (msr == MSR_APICBASE))
+ return (TRUE);
+ else
+ return (FALSE);
+}
+
+int
+lapic_rdmsr(struct vm *vm, int cpu, u_int msr, uint64_t *rval)
+{
+ int handled;
+ struct vlapic *vlapic;
+
+ vlapic = vm_lapic(vm, cpu);
+
+ if (msr == MSR_APICBASE) {
+ *rval = vlapic_get_apicbase(vlapic);
+ handled = 1;
+ } else
+ handled = lapic_read(vlapic, x2apic_msr_to_regoff(msr), rval);
+
+ return (handled);
+}
+
+int
+lapic_wrmsr(struct vm *vm, int cpu, u_int msr, uint64_t val)
+{
+ int handled;
+ struct vlapic *vlapic;
+
+ vlapic = vm_lapic(vm, cpu);
+
+ if (msr == MSR_APICBASE) {
+ vlapic_set_apicbase(vlapic, val);
+ handled = 1;
+ } else
+ handled = lapic_write(vlapic, x2apic_msr_to_regoff(msr), val);
+
+ return (handled);
+}
OpenPOWER on IntegriCloud