Skip to content

Commit 52ce39b

Browse files
committed
PCIBridge: Fix extended registers not being read/written correctly
1 parent 62cb589 commit 52ce39b

File tree

2 files changed

+50
-23
lines changed

2 files changed

+50
-23
lines changed

Changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
MacHyperVSupport Changelog
22
============================
3+
#### v0.9.6
4+
- Fixed extended registers not being correctly read/written
5+
36
#### v0.9.5
47
- Fixed no packets being received on certain older versions of Hyper-V
58
- Added support for promiscuous mode

MacHyperVSupport/PCIBridge/HyperVPCIBridge.cpp

+47-23
Original file line numberDiff line numberDiff line change
@@ -86,37 +86,50 @@ bool HyperVPCIBridge::configure(IOService *provider) {
8686
}
8787

8888
UInt32 HyperVPCIBridge::configRead32(IOPCIAddressSpace space, UInt8 offset) {
89-
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset);
90-
89+
UInt32 offset32 = offset | (space.es.registerNumExtended << 8);
90+
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset32);
91+
9192
if (space.es.deviceNum != 0 || space.es.functionNum != 0) {
9293
return 0xFFFFFFFF;
9394
}
94-
95-
return readPCIConfig(offset, sizeof (UInt32));
95+
96+
//
97+
// Perform 32-bit extended read.
98+
//
99+
return readPCIConfig(offset32, sizeof (UInt32));
96100
}
97101

98102
void HyperVPCIBridge::configWrite32(IOPCIAddressSpace space, UInt8 offset, UInt32 data) {
99-
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset);
100-
103+
UInt32 offset32 = offset | (space.es.registerNumExtended << 8);
104+
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset32);
105+
101106
if (space.es.deviceNum != 0 || space.es.functionNum != 0) {
102107
return;
103108
}
104-
105-
writePCIConfig(offset, sizeof (UInt32), data);
109+
110+
//
111+
// Perform 32-bit extended write.
112+
//
113+
writePCIConfig(offset32, sizeof (UInt32), data);
106114
}
107115

108116
UInt16 HyperVPCIBridge::configRead16(IOPCIAddressSpace space, UInt8 offset) {
109-
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset);
110-
117+
UInt32 offset32 = offset | (space.es.registerNumExtended << 8);
118+
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset32);
119+
111120
if (space.es.deviceNum != 0 || space.es.functionNum != 0) {
112121
return 0xFFFF;
113122
}
114-
115-
return (UInt16)readPCIConfig(offset, sizeof (UInt16));
123+
124+
//
125+
// Perform 16-bit extended read.
126+
//
127+
return (UInt16)readPCIConfig(offset32, sizeof (UInt16));
116128
}
117129

118130
void HyperVPCIBridge::configWrite16(IOPCIAddressSpace space, UInt8 offset, UInt16 data) {
119-
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset);
131+
UInt32 offset32 = offset | (space.es.registerNumExtended << 8);
132+
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset32);
120133

121134
if (space.es.deviceNum != 0 || space.es.functionNum != 0) {
122135
return;
@@ -126,7 +139,7 @@ void HyperVPCIBridge::configWrite16(IOPCIAddressSpace space, UInt8 offset, UInt1
126139
// Hook writes to MSI or MSI-X control register.
127140
// This is the final step in configuring interrupts by IOPCIFamily.
128141
//
129-
if (!interruptConfigured && offset == msiCap + 0x2 && data & 0x1) {
142+
if (!interruptConfigured && offset32 == msiCap + 0x2 && data & 0x1) {
130143
HVDBGLOG("Original value: 0x%X", data);
131144

132145
if (isMsiX) {
@@ -163,28 +176,39 @@ void HyperVPCIBridge::configWrite16(IOPCIAddressSpace space, UInt8 offset, UInt1
163176
interruptConfigured = true;
164177
}
165178
} else {
166-
writePCIConfig(offset, sizeof (UInt16), data);
179+
//
180+
// Perform 16-bit extended write.
181+
//
182+
writePCIConfig(offset32, sizeof (UInt16), data);
167183
}
168184
}
169185

170186
UInt8 HyperVPCIBridge::configRead8(IOPCIAddressSpace space, UInt8 offset) {
171-
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset);
172-
187+
UInt32 offset32 = offset | (space.es.registerNumExtended << 8);
188+
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset32);
189+
173190
if (space.es.deviceNum != 0 || space.es.functionNum != 0) {
174191
return 0xFF;
175192
}
176-
177-
return (UInt8)readPCIConfig(offset, sizeof (UInt8));
193+
194+
//
195+
// Perform 8-bit extended read.
196+
//
197+
return (UInt8)readPCIConfig(offset32, sizeof (UInt8));
178198
}
179199

180200
void HyperVPCIBridge::configWrite8(IOPCIAddressSpace space, UInt8 offset, UInt8 data) {
181-
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset);
182-
201+
UInt32 offset32 = offset | (space.es.registerNumExtended << 8);
202+
HVDBGLOG("Bus: %u, device: %u, function: %u, offset %X", space.es.busNum, space.es.deviceNum, space.es.functionNum, offset32);
203+
183204
if (space.es.deviceNum != 0 || space.es.functionNum != 0) {
184205
return;
185206
}
186-
187-
writePCIConfig(offset, sizeof (UInt8), data);
207+
208+
//
209+
// Perform 8-bit extended write.
210+
//
211+
writePCIConfig(offset32, sizeof (UInt8), data);
188212
}
189213

190214
bool HyperVPCIBridge::publishNub(IOPCIDevice *nub, UInt32 index) {

0 commit comments

Comments
 (0)