summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/vmm_lapic.c
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2013-12-16 19:59:31 +0000
committerneel <neel@FreeBSD.org>2013-12-16 19:59:31 +0000
commite62c100b9074abf0c5045dbae2bfcc173275a3ef (patch)
tree8ec9e1a8b6bf2777a53d91e51e51248ba5823e74 /sys/amd64/vmm/vmm_lapic.c
parent2977cb4d97c105f640bb6bcf17b86d9d91295a99 (diff)
downloadFreeBSD-src-e62c100b9074abf0c5045dbae2bfcc173275a3ef.zip
FreeBSD-src-e62c100b9074abf0c5045dbae2bfcc173275a3ef.tar.gz
Add an API to deliver message signalled interrupts to vcpus. This allows
callers treat the MSI 'addr' and 'data' fields as opaque and also lets bhyve implement multiple destination modes: physical, flat and clustered. Submitted by: Tycho Nightingale (tycho.nightingale@pluribusnetworks.com) Reviewed by: grehan@
Diffstat (limited to 'sys/amd64/vmm/vmm_lapic.c')
-rw-r--r--sys/amd64/vmm/vmm_lapic.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/sys/amd64/vmm/vmm_lapic.c b/sys/amd64/vmm/vmm_lapic.c
index 13fab8c..96234a1 100644
--- a/sys/amd64/vmm/vmm_lapic.c
+++ b/sys/amd64/vmm/vmm_lapic.c
@@ -38,9 +38,18 @@ __FBSDID("$FreeBSD$");
#include <machine/vmm.h>
#include "vmm_ipi.h"
+#include "vmm_ktr.h"
#include "vmm_lapic.h"
#include "vlapic.h"
+/*
+ * Some MSI message definitions
+ */
+#define MSI_X86_ADDR_MASK 0xfff00000
+#define MSI_X86_ADDR_BASE 0xfee00000
+#define MSI_X86_ADDR_RH 0x00000008 /* Redirection Hint */
+#define MSI_X86_ADDR_LOG 0x00000004 /* Destination Mode */
+
int
lapic_pending_intr(struct vm *vm, int cpu)
{
@@ -80,6 +89,44 @@ lapic_set_intr(struct vm *vm, int cpu, int vector, bool level)
return (0);
}
+int
+lapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg)
+{
+ int delmode, vec;
+ uint32_t dest;
+ bool phys;
+
+ VM_CTR2(vm, "lapic MSI addr: %#lx msg: %#lx", addr, msg);
+
+ if ((addr & MSI_X86_ADDR_MASK) != MSI_X86_ADDR_BASE) {
+ VM_CTR1(vm, "lapic MSI invalid addr %#lx", addr);
+ return (-1);
+ }
+
+ /*
+ * Extract the x86-specific fields from the MSI addr/msg
+ * params according to the Intel Arch spec, Vol3 Ch 10.
+ *
+ * The PCI specification does not support level triggered
+ * MSI/MSI-X so ignore trigger level in 'msg'.
+ *
+ * The 'dest' is interpreted as a logical APIC ID if both
+ * the Redirection Hint and Destination Mode are '1' and
+ * physical otherwise.
+ */
+ dest = (addr >> 12) & 0xff;
+ phys = ((addr & (MSI_X86_ADDR_RH | MSI_X86_ADDR_LOG)) !=
+ (MSI_X86_ADDR_RH | MSI_X86_ADDR_LOG));
+ delmode = msg & APIC_DELMODE_MASK;
+ vec = msg & 0xff;
+
+ VM_CTR3(vm, "lapic MSI %s dest %#x, vec %d",
+ phys ? "physical" : "logical", dest, vec);
+
+ vlapic_deliver_intr(vm, LAPIC_TRIG_EDGE, dest, phys, delmode, vec);
+ return (0);
+}
+
static boolean_t
x2apic_msr(u_int msr)
{
OpenPOWER on IntegriCloud