Skip to content

Commit a3740c8

Browse files
committed
PCIBridge: Add support for device property injection
1 parent c0344f9 commit a3740c8

File tree

10 files changed

+373
-20
lines changed

10 files changed

+373
-20
lines changed

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ MacHyperVSupport Changelog
33
#### v0.9.7
44
- Fixed disks on a passed-in PCI device not being usable
55
- Improved PCI interrupt handling to support both MSI and MSI-X
6+
- Added support for device property injection on PCI devices
67

78
#### v0.9.6
89
- Fixed extended registers not being correctly read/written

MacHyperVSupport.xcodeproj/project.pbxproj

+8
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@
143143
41BF4621288CDF1200813670 /* HyperVNetwork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B41BDB26C74B4C00926A0D /* HyperVNetwork.cpp */; };
144144
41BF4622288CDF1200813670 /* HyperVNetworkRNDIS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41B41BE626CDC42D00926A0D /* HyperVNetworkRNDIS.cpp */; };
145145
41BF4623288CDF1200813670 /* HyperVPCIBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F9B8EE2849792200E0DCB2 /* HyperVPCIBridge.cpp */; };
146+
41CF8A6F2ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41CF8A6E2ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp */; };
147+
41CF8A702ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41CF8A6E2ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp */; };
146148
41E2EC78263F894300BBE18F /* HyperVControllerInterrupts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E2EC77263F894300BBE18F /* HyperVControllerInterrupts.cpp */; };
147149
41E5E20C28C5766700E6E84F /* HyperVController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E5E20A28C5766700E6E84F /* HyperVController.cpp */; };
148150
41E5E20D28C5766700E6E84F /* HyperVController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E5E20A28C5766700E6E84F /* HyperVController.cpp */; };
@@ -349,6 +351,8 @@
349351
41BE4113263EDEA10018C52B /* libkmod.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libkmod.a; path = MacKernelSDK/Library/x86_64/libkmod.a; sourceTree = "<group>"; };
350352
41BF462A288CDF1200813670 /* MacHyperVSupportMonterey.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacHyperVSupportMonterey.kext; sourceTree = BUILT_PRODUCTS_DIR; };
351353
41C604AB28B2F87600FB77ED /* HyperV-versions.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "HyperV-versions.md"; sourceTree = "<group>"; };
354+
41CF8A6E2ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HyperVPCIBridgeDevProps.cpp; sourceTree = "<group>"; };
355+
41CF8A712ADB8DD2002AC7A4 /* DevicePathPropertyDatabase.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DevicePathPropertyDatabase.hpp; sourceTree = "<group>"; };
352356
41E2EC77263F894300BBE18F /* HyperVControllerInterrupts.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HyperVControllerInterrupts.cpp; sourceTree = "<group>"; };
353357
41E5E20A28C5766700E6E84F /* HyperVController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HyperVController.cpp; sourceTree = "<group>"; };
354358
41E5E20B28C5766700E6E84F /* HyperVController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = HyperVController.hpp; sourceTree = "<group>"; };
@@ -822,8 +826,10 @@
822826
41F9B8ED284978EF00E0DCB2 /* PCIBridge */ = {
823827
isa = PBXGroup;
824828
children = (
829+
41CF8A712ADB8DD2002AC7A4 /* DevicePathPropertyDatabase.hpp */,
825830
41F9B8EE2849792200E0DCB2 /* HyperVPCIBridge.cpp */,
826831
41F9B8EF2849792200E0DCB2 /* HyperVPCIBridge.hpp */,
832+
41CF8A6E2ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp */,
827833
41F9B8F7284983FF00E0DCB2 /* HyperVPCIBridgePrivate.cpp */,
828834
41F9B8FA2849846700E0DCB2 /* HyperVPCIBridgeRegs.hpp */,
829835
);
@@ -1234,6 +1240,7 @@
12341240
416E429D265751CC006DED6D /* HyperVVMBusDevicePrivate.cpp in Sources */,
12351241
41F2E44B2666F37B00CE26CE /* HyperVPCIProvider.cpp in Sources */,
12361242
41F9B8FF284BA20700E0DCB2 /* HyperVModuleDevice.cpp in Sources */,
1243+
41CF8A6F2ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp in Sources */,
12371244
4191F6F528F4E71A00809232 /* HyperVTimeSyncUserClient.cpp in Sources */,
12381245
418F843D2648BA38003F8520 /* HyperVStorage.cpp in Sources */,
12391246
41F2E42D2665B64D00CE26CE /* HyperVPlatformProvider.cpp in Sources */,
@@ -1279,6 +1286,7 @@
12791286
41BF461A288CDF1200813670 /* HyperVVMBusDevicePrivate.cpp in Sources */,
12801287
41BF461B288CDF1200813670 /* HyperVPCIProvider.cpp in Sources */,
12811288
41BF461C288CDF1200813670 /* HyperVModuleDevice.cpp in Sources */,
1289+
41CF8A702ADB89A9002AC7A4 /* HyperVPCIBridgeDevProps.cpp in Sources */,
12821290
4191F6F628F4E71A00809232 /* HyperVTimeSyncUserClient.cpp in Sources */,
12831291
41BF461D288CDF1200813670 /* HyperVStorage.cpp in Sources */,
12841292
41BF461E288CDF1200813670 /* HyperVPlatformProvider.cpp in Sources */,

MacHyperVSupport/Controller/HyperV.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ typedef enum : UInt32 {
3232

3333
#define kHyperVHypercallRetryCount 100
3434

35+
inline void
36+
guid_unparse(const uuid_t uu, uuid_string_t out) {
37+
snprintf(out,
38+
sizeof(uuid_string_t),
39+
"%02x%02x%02x%02x-"
40+
"%02x%02x-"
41+
"%02x%02x-"
42+
"%02x%02x-"
43+
"%02x%02x%02x%02x%02x%02x",
44+
uu[3], uu[2], uu[1], uu[0],
45+
uu[5], uu[4],
46+
uu[7], uu[6],
47+
uu[8], uu[9],
48+
uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
49+
}
50+
3551
#if DEBUG
3652
//
3753
// Debug logging function.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//
2+
// DevicePathPropertyDatabase.hpp
3+
// Device Path Property Database definitions
4+
//
5+
// Copyright © 2023 Goldfish64. All rights reserved.
6+
//
7+
8+
#ifndef DevicePathPropertyDatabase_h
9+
#define DevicePathPropertyDatabase_h
10+
11+
#define EFI_DEVICE_PATH_PROPERTY_DATABASE_VERSION 1
12+
13+
/**
14+
This protocol can be used on any device handle to obtain generic path/location
15+
information concerning the physical device or logical device. If the handle does
16+
not logically map to a physical device, the handle may not necessarily support
17+
the device path protocol. The device path describes the location of the device
18+
the handle is for. The size of the Device Path can be determined from the structures
19+
that make up the Device Path.
20+
**/
21+
#define HARDWARE_DEVICE_PATH 0x01
22+
#define HW_VENDOR_DP 0x04
23+
24+
#define END_DEVICE_PATH 0x7F
25+
#define END_DEVICE_PATH_SUBTYPE 0xFF
26+
27+
//
28+
// Generic EFI device path node.
29+
//
30+
typedef struct {
31+
UInt8 type;
32+
UInt8 subType;
33+
UInt8 length[2];
34+
} EfiDevicePathProtocol;
35+
36+
//
37+
// Hyper-V vendor-specific EFI device path node.
38+
//
39+
typedef struct {
40+
EfiDevicePathProtocol header;
41+
42+
uuid_t vendorGuid;
43+
uuid_t deviceTypeGuid;
44+
uuid_t instanceGuid;
45+
} HyperVDevPropEfiDevicePathProtocol;
46+
47+
//
48+
// Device path property data set.
49+
// There should be a pair of these for each property present,
50+
// one for the property name (in unicode) and one for the data.
51+
//
52+
typedef struct {
53+
UInt32 Size;
54+
UInt8 Data[];
55+
} EfiDevicePathPropertyData;
56+
57+
//
58+
// Device path property node header.
59+
//
60+
typedef struct {
61+
UInt32 Size;
62+
UInt32 NumberOfProperties;
63+
} EfiDevicePathPropertyBufferNodeHeader;
64+
65+
//
66+
// Device path property node.
67+
//
68+
typedef struct {
69+
EfiDevicePathPropertyBufferNodeHeader Hdr;
70+
HyperVDevPropEfiDevicePathProtocol DevicePath; // Variable length
71+
//EfiDevicePathPropertyData Data; // Variable length
72+
} EfiDevicePathPropertyBufferNode;
73+
74+
//
75+
// Device path property buffer.
76+
//
77+
typedef struct {
78+
UInt32 Size;
79+
UInt32 Version;
80+
UInt32 NumberOfNodes;
81+
82+
EfiDevicePathPropertyBufferNode Nodes[]; // Each node is variable in length.
83+
} EfiDevicePathPropertyBuffer;
84+
85+
#endif

MacHyperVSupport/PCIBridge/HyperVPCIBridge.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,14 @@ void HyperVPCIBridge::configWrite8(IOPCIAddressSpace space, UInt8 offset, UInt8
264264
//
265265
writePCIConfig(offset32, sizeof (UInt8), data);
266266
}
267+
268+
bool HyperVPCIBridge::initializeNub(IOPCIDevice *nub, OSDictionary *from) {
269+
//
270+
// Merge any injected properties into device tree.
271+
//
272+
IOReturn status = mergePropertiesFromDT(nub->getFunctionNumber(), from);
273+
if (status != kIOReturnSuccess) {
274+
return false;
275+
}
276+
return super::initializeNub(nub, from);
277+
}

MacHyperVSupport/PCIBridge/HyperVPCIBridge.hpp

+20-4
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,42 @@ class HyperVPCIBridge : public HV_PCIBRIDGE_CLASS {
4545
UInt32 _pciFunctionsCount = 0;
4646
HyperVPCIFunctionDescription *_pciFunctions = nullptr;
4747

48+
//
49+
// Packet handling.
50+
//
4851
bool wakePacketHandler(VMBusPacketHeader *pktHeader, UInt32 pktHeaderLength, UInt8 *pktData, UInt32 pktDataLength);
4952
void handlePacket(VMBusPacketHeader *pktHeader, UInt32 pktHeaderLength, UInt8 *pktData, UInt32 pktDataLength);
5053
void handleIncomingPCIMessage(HyperVPCIBridgeIncomingMessageHeader *pciMsgHeader, UInt32 msgSize);
5154

55+
//
56+
// PCI bus setup.
57+
//
5258
IOReturn connectPCIBus();
5359
IOReturn negotiateProtocolVersion();
5460
IOReturn allocatePCIConfigWindow();
5561
IOReturn queryBusRelations();
5662
IOReturn enterPCID0();
5763
IOReturn queryResourceRequirements();
5864
IOReturn sendResourcesAssigned(UInt32 slot);
59-
65+
6066
inline UInt64 getBarSize(UInt64 barValue) {
6167
if (barValue < UINT32_MAX) {
6268
barValue |= 0xFFFFFFFF00000000;
6369
}
6470
return roundup((1 + ~(barValue & kHyperVPCIBarMemoryMask)), PAGE_SIZE);
6571
}
66-
72+
73+
//
74+
// Device properties handling.
75+
//
76+
IOReturn mergePropertiesFromDT(UInt32 slot, OSDictionary *dict);
77+
78+
//
79+
// PCI config space read/write.
80+
//
6781
UInt32 readPCIConfig(UInt32 offset, UInt8 size);
6882
void writePCIConfig(UInt32 offset, UInt8 size, UInt32 value);
69-
83+
7084
public:
7185
//
7286
// IOService overrides.
@@ -97,11 +111,13 @@ class HyperVPCIBridge : public HV_PCIBRIDGE_CLASS {
97111
HVDBGLOG("start");
98112
return _pciBusNumber;
99113
}
100-
114+
101115
UInt8 lastBusNum() APPLE_KEXT_OVERRIDE {
102116
HVDBGLOG("start");
103117
return _pciBusNumber;
104118
}
119+
120+
bool initializeNub(IOPCIDevice *nub, OSDictionary *from) APPLE_KEXT_OVERRIDE;
105121
};
106122

107123
#endif

0 commit comments

Comments
 (0)