summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2013-10-09 23:53:21 +0000
committergrehan <grehan@FreeBSD.org>2013-10-09 23:53:21 +0000
commit26296c939c8a5298c4359e40187a22786bb86315 (patch)
treef477d30d76163cb288da0ea06ed4847257f4024b /usr.sbin
parentfe75d5f1628223af17e92f06a8394c9c9aa6aca0 (diff)
downloadFreeBSD-src-26296c939c8a5298c4359e40187a22786bb86315.zip
FreeBSD-src-26296c939c8a5298c4359e40187a22786bb86315.tar.gz
Allow a 4-byte write to PCI config space to overlap
the 2 read-only bytes at the start of a PCI capability. This is the sequence that OpenBSD uses when enabling MSI interrupts, and works fine on real h/w. In bhyve, convert the 4 byte write to a 2-byte write to the r/w area past the first 2 r/o bytes of a capability. Reviewed by: neel Approved by: re@ (blanket)
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/pci_emul.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index a95f261..fe21cee 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -941,10 +941,19 @@ pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val)
assert(offset >= capoff);
/*
- * Capability ID and Next Capability Pointer are readonly
+ * Capability ID and Next Capability Pointer are readonly.
+ * However, some o/s's do 4-byte writes that include these.
+ * For this case, trim the write back to 2 bytes and adjust
+ * the data.
*/
- if (offset == capoff || offset == capoff + 1)
- return;
+ if (offset == capoff || offset == capoff + 1) {
+ if (offset == capoff && bytes == 4) {
+ bytes = 2;
+ offset += 2;
+ val >>= 16;
+ } else
+ return;
+ }
switch (capid) {
case PCIY_MSI:
OpenPOWER on IntegriCloud