]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciDriverOverride.c
CommitLineData
9060e3ec 1/** @file\r
fcdfcdbf 2 Functions implementation for Bus Specific Driver Override protocol.\r
9060e3ec 3\r
fcdfcdbf 4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
9060e3ec 6\r
7**/\r
8\r
9#include "PciBus.h"\r
10\r
11/**\r
12 Initializes a PCI Driver Override Instance.\r
13\r
14 @param PciIoDevice PCI Device instance.\r
15\r
16**/\r
17VOID\r
18InitializePciDriverOverrideInstance (\r
1436aea4 19 IN OUT PCI_IO_DEVICE *PciIoDevice\r
9060e3ec 20 )\r
21{\r
22 PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
23}\r
24\r
b5cbef4e
RN
25/**\r
26 Find the image handle whose path equals to ImagePath.\r
27\r
28 @param ImagePath Image path.\r
29\r
30 @return Image handle.\r
31**/\r
32EFI_HANDLE\r
33LocateImageHandle (\r
1436aea4 34 IN EFI_DEVICE_PATH_PROTOCOL *ImagePath\r
b5cbef4e
RN
35 )\r
36{\r
1436aea4
MK
37 EFI_STATUS Status;\r
38 EFI_HANDLE *Handles;\r
39 UINTN Index;\r
40 UINTN HandleNum;\r
41 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
42 UINTN ImagePathSize;\r
43 EFI_HANDLE ImageHandle;\r
b5cbef4e
RN
44\r
45 Status = gBS->LocateHandleBuffer (\r
46 ByProtocol,\r
47 &gEfiLoadedImageDevicePathProtocolGuid,\r
48 NULL,\r
49 &HandleNum,\r
50 &Handles\r
51 );\r
52 if (EFI_ERROR (Status)) {\r
53 return NULL;\r
54 }\r
55\r
56 ImageHandle = NULL;\r
57 ImagePathSize = GetDevicePathSize (ImagePath);\r
58\r
59 for (Index = 0; Index < HandleNum; Index++) {\r
1436aea4 60 Status = gBS->HandleProtocol (Handles[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **)&DevicePath);\r
b5cbef4e
RN
61 if (EFI_ERROR (Status)) {\r
62 continue;\r
63 }\r
1436aea4 64\r
b5cbef4e
RN
65 if ((ImagePathSize == GetDevicePathSize (DevicePath)) &&\r
66 (CompareMem (ImagePath, DevicePath, ImagePathSize) == 0)\r
1436aea4
MK
67 )\r
68 {\r
b5cbef4e
RN
69 ImageHandle = Handles[Index];\r
70 break;\r
71 }\r
72 }\r
73\r
74 FreePool (Handles);\r
75 return ImageHandle;\r
76}\r
9060e3ec 77\r
78/**\r
79 Uses a bus specific algorithm to retrieve a driver image handle for a controller.\r
80\r
81 @param This A pointer to the EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL instance.\r
82 @param DriverImageHandle On input, a pointer to the previous driver image handle returned\r
83 by GetDriver(). On output, a pointer to the next driver\r
84 image handle. Passing in a NULL, will return the first driver\r
85 image handle.\r
86\r
87 @retval EFI_SUCCESS A bus specific override driver is returned in DriverImageHandle.\r
88 @retval EFI_NOT_FOUND The end of the list of override drivers was reached.\r
89 A bus specific override driver is not returned in DriverImageHandle.\r
90 @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a\r
91 previous call to GetDriver().\r
92\r
93**/\r
94EFI_STATUS\r
95EFIAPI\r
96GetDriver (\r
1436aea4
MK
97 IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
98 IN OUT EFI_HANDLE *DriverImageHandle\r
9060e3ec 99 )\r
100{\r
101 PCI_IO_DEVICE *PciIoDevice;\r
b5cbef4e
RN
102 LIST_ENTRY *Link;\r
103 PCI_DRIVER_OVERRIDE_LIST *Override;\r
104 BOOLEAN ReturnNext;\r
9060e3ec 105\r
b5cbef4e 106 Override = NULL;\r
9060e3ec 107 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);\r
1436aea4 108 ReturnNext = (BOOLEAN)(*DriverImageHandle == NULL);\r
b5cbef4e 109 for ( Link = GetFirstNode (&PciIoDevice->OptionRomDriverList)\r
1436aea4
MK
110 ; !IsNull (&PciIoDevice->OptionRomDriverList, Link)\r
111 ; Link = GetNextNode (&PciIoDevice->OptionRomDriverList, Link)\r
112 )\r
113 {\r
b5cbef4e 114 Override = DRIVER_OVERRIDE_FROM_LINK (Link);\r
9060e3ec 115\r
b5cbef4e
RN
116 if (ReturnNext) {\r
117 if (Override->DriverImageHandle == NULL) {\r
118 Override->DriverImageHandle = LocateImageHandle (Override->DriverImagePath);\r
9060e3ec 119 }\r
120\r
b5cbef4e
RN
121 if (Override->DriverImageHandle == NULL) {\r
122 //\r
123 // The Option ROM identified by Override->DriverImagePath is not loaded.\r
124 //\r
125 continue;\r
126 } else {\r
127 *DriverImageHandle = Override->DriverImageHandle;\r
128 return EFI_SUCCESS;\r
129 }\r
9060e3ec 130 }\r
131\r
b5cbef4e
RN
132 if (*DriverImageHandle == Override->DriverImageHandle) {\r
133 ReturnNext = TRUE;\r
134 }\r
9060e3ec 135 }\r
136\r
b5cbef4e
RN
137 ASSERT (IsNull (&PciIoDevice->OptionRomDriverList, Link));\r
138 //\r
139 // ReturnNext indicates a handle match happens.\r
140 // If all nodes are checked without handle match happening,\r
141 // the DriverImageHandle should be a invalid handle.\r
142 //\r
143 if (ReturnNext) {\r
144 return EFI_NOT_FOUND;\r
145 } else {\r
146 return EFI_INVALID_PARAMETER;\r
147 }\r
9060e3ec 148}\r
149\r
150/**\r
151 Add an overriding driver image.\r
152\r
153 @param PciIoDevice Instance of PciIo device.\r
b5cbef4e
RN
154 @param DriverImageHandle Image handle of newly added driver image.\r
155 @param DriverImagePath Device path of newly added driver image.\r
9060e3ec 156\r
157 @retval EFI_SUCCESS Successfully added driver.\r
158 @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.\r
159 @retval other Some error occurred when locating gEfiLoadedImageProtocolGuid.\r
160\r
161**/\r
162EFI_STATUS\r
163AddDriver (\r
1436aea4
MK
164 IN PCI_IO_DEVICE *PciIoDevice,\r
165 IN EFI_HANDLE DriverImageHandle,\r
166 IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath\r
9060e3ec 167 )\r
168{\r
1436aea4 169 PCI_DRIVER_OVERRIDE_LIST *Node;\r
9060e3ec 170\r
b5cbef4e
RN
171 //\r
172 // Caller should pass in either Image Handle or Image Path, but not both.\r
173 //\r
174 ASSERT ((DriverImageHandle == NULL) || (DriverImagePath == NULL));\r
9060e3ec 175\r
b5cbef4e 176 Node = AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
9060e3ec 177 if (Node == NULL) {\r
178 return EFI_OUT_OF_RESOURCES;\r
179 }\r
180\r
181 Node->Signature = DRIVER_OVERRIDE_SIGNATURE;\r
182 Node->DriverImageHandle = DriverImageHandle;\r
b5cbef4e 183 Node->DriverImagePath = DuplicateDevicePath (DriverImagePath);\r
9060e3ec 184\r
b5cbef4e 185 InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link);\r
9060e3ec 186\r
1436aea4 187 PciIoDevice->BusOverride = TRUE;\r
9060e3ec 188 return EFI_SUCCESS;\r
189}\r