summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authortychon <tychon@FreeBSD.org>2014-06-06 16:18:37 +0000
committertychon <tychon@FreeBSD.org>2014-06-06 16:18:37 +0000
commitad10fea609d98871d5562600606c69555fa736ec (patch)
tree6181e54f4aa83ec5cad0294901e478db5bd5f783 /usr.sbin
parent55c24573f460d0fcac60de72255fff1745dd4302 (diff)
downloadFreeBSD-src-ad10fea609d98871d5562600606c69555fa736ec.zip
FreeBSD-src-ad10fea609d98871d5562600606c69555fa736ec.tar.gz
Some devices (e.g. Intel AHCI and NICs) support quad-word access to
register pairs where two 32-bit registers make up a larger logical size. Support those access by splitting the quad-word into two double-words. Reviewed by: grehan
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/pci_emul.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index e7f4894..4682590 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -375,10 +375,27 @@ pci_emul_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr,
offset = addr - pdi->pi_bar[bidx].addr;
- if (dir == MEM_F_WRITE)
- (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset, size, *val);
- else
- *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx, offset, size);
+ if (dir == MEM_F_WRITE) {
+ if (pdi->pi_bar[bidx].type == PCIBAR_MEM32 && size == 8) {
+ (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset,
+ 4, *val & 0xffffffff);
+ (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset + 4,
+ 4, *val >> 32);
+ } else {
+ (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset,
+ size, *val);
+ }
+ } else {
+ if (pdi->pi_bar[bidx].type == PCIBAR_MEM32 && size == 8) {
+ *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx,
+ offset, 4);
+ *val |= (*pe->pe_barread)(ctx, vcpu, pdi, bidx,
+ offset + 4, 4) << 32;
+ } else {
+ *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx,
+ offset, size);
+ }
+ }
return (0);
}
OpenPOWER on IntegriCloud