diff options
author | neel <neel@FreeBSD.org> | 2013-12-16 19:59:31 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2013-12-16 19:59:31 +0000 |
commit | e62c100b9074abf0c5045dbae2bfcc173275a3ef (patch) | |
tree | 8ec9e1a8b6bf2777a53d91e51e51248ba5823e74 /sys/amd64/vmm/vmm_lapic.c | |
parent | 2977cb4d97c105f640bb6bcf17b86d9d91295a99 (diff) | |
download | FreeBSD-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.c | 47 |
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) { |