]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / NonDiscoverableDeviceRegistrationLib / NonDiscoverableDeviceRegistrationLib.c
CommitLineData
1652dc21
AB
1/** @file\r
2 Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>\r
3\r
9d510e61 4 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1652dc21
AB
5\r
6**/\r
7\r
8#include <PiDxe.h>\r
9\r
10#include <Guid/NonDiscoverableDevice.h>\r
11\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/DevicePathLib.h>\r
15#include <Library/MemoryAllocationLib.h>\r
16#include <Library/NonDiscoverableDeviceRegistrationLib.h>\r
17#include <Library/UefiBootServicesTableLib.h>\r
18\r
19#include <Protocol/DevicePath.h>\r
20#include <Protocol/NonDiscoverableDevice.h>\r
21\r
9a882490
DB
22/**\r
23 Get Guid form the type of non-discoverable device.\r
24\r
25 @param[in] Type The type of non-discoverable device.\r
26\r
27 @retval Return the Guid.\r
28\r
29**/\r
1652dc21
AB
30STATIC\r
31CONST EFI_GUID *\r
32GetGuidFromType (\r
33 IN NON_DISCOVERABLE_DEVICE_TYPE Type\r
34 )\r
35{\r
36 switch (Type) {\r
1436aea4
MK
37 case NonDiscoverableDeviceTypeAhci:\r
38 return &gEdkiiNonDiscoverableAhciDeviceGuid;\r
1652dc21 39\r
1436aea4
MK
40 case NonDiscoverableDeviceTypeAmba:\r
41 return &gEdkiiNonDiscoverableAmbaDeviceGuid;\r
1652dc21 42\r
1436aea4
MK
43 case NonDiscoverableDeviceTypeEhci:\r
44 return &gEdkiiNonDiscoverableEhciDeviceGuid;\r
1652dc21 45\r
1436aea4
MK
46 case NonDiscoverableDeviceTypeNvme:\r
47 return &gEdkiiNonDiscoverableNvmeDeviceGuid;\r
1652dc21 48\r
1436aea4
MK
49 case NonDiscoverableDeviceTypeOhci:\r
50 return &gEdkiiNonDiscoverableOhciDeviceGuid;\r
1652dc21 51\r
1436aea4
MK
52 case NonDiscoverableDeviceTypeSdhci:\r
53 return &gEdkiiNonDiscoverableSdhciDeviceGuid;\r
1652dc21 54\r
1436aea4
MK
55 case NonDiscoverableDeviceTypeUfs:\r
56 return &gEdkiiNonDiscoverableUfsDeviceGuid;\r
1652dc21 57\r
1436aea4
MK
58 case NonDiscoverableDeviceTypeUhci:\r
59 return &gEdkiiNonDiscoverableUhciDeviceGuid;\r
1652dc21 60\r
1436aea4
MK
61 case NonDiscoverableDeviceTypeXhci:\r
62 return &gEdkiiNonDiscoverableXhciDeviceGuid;\r
1652dc21 63\r
1436aea4
MK
64 default:\r
65 return NULL;\r
1652dc21
AB
66 }\r
67}\r
68\r
69#pragma pack (1)\r
70typedef struct {\r
1436aea4
MK
71 VENDOR_DEVICE_PATH Vendor;\r
72 UINT64 BaseAddress;\r
73 UINT8 ResourceType;\r
74 EFI_DEVICE_PATH_PROTOCOL End;\r
1652dc21
AB
75} NON_DISCOVERABLE_DEVICE_PATH;\r
76#pragma pack ()\r
77\r
78/**\r
9a882490 79 Register a non-discoverable MMIO device.\r
1652dc21 80\r
9a882490 81 @param[in] Type The type of non-discoverable device\r
1652dc21
AB
82 @param[in] DmaType Whether the device is DMA coherent\r
83 @param[in] InitFunc Initialization routine to be invoked when\r
84 the device is enabled\r
85 @param[in,out] Handle The handle onto which to install the\r
86 non-discoverable device protocol.\r
87 If Handle is NULL or *Handle is NULL, a\r
88 new handle will be allocated.\r
89 @param[in] NumMmioResources The number of UINTN base/size pairs that\r
90 follow, each describing an MMIO region\r
91 owned by the device\r
9a882490
DB
92 @param[in] ... The variable argument list which contains the\r
93 info about MmioResources.\r
1652dc21
AB
94\r
95 @retval EFI_SUCCESS The registration succeeded.\r
96 @retval EFI_INVALID_PARAMETER An invalid argument was given\r
97 @retval Other The registration failed.\r
98\r
99**/\r
100EFI_STATUS\r
101EFIAPI\r
102RegisterNonDiscoverableMmioDevice (\r
103 IN NON_DISCOVERABLE_DEVICE_TYPE Type,\r
104 IN NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType,\r
105 IN NON_DISCOVERABLE_DEVICE_INIT InitFunc,\r
106 IN OUT EFI_HANDLE *Handle OPTIONAL,\r
107 IN UINTN NumMmioResources,\r
108 ...\r
109 )\r
110{\r
1436aea4
MK
111 NON_DISCOVERABLE_DEVICE *Device;\r
112 NON_DISCOVERABLE_DEVICE_PATH *DevicePath;\r
113 EFI_HANDLE LocalHandle;\r
114 EFI_STATUS Status;\r
115 UINTN AllocSize;\r
116 UINTN Index;\r
117 VA_LIST Args;\r
118 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;\r
119 EFI_ACPI_END_TAG_DESCRIPTOR *End;\r
120 UINTN Base, Size;\r
121\r
122 if ((Type >= NonDiscoverableDeviceTypeMax) ||\r
123 (DmaType >= NonDiscoverableDeviceDmaTypeMax) ||\r
124 (NumMmioResources == 0))\r
125 {\r
1652dc21
AB
126 return EFI_INVALID_PARAMETER;\r
127 }\r
128\r
129 if (Handle == NULL) {\r
1436aea4 130 Handle = &LocalHandle;\r
1652dc21
AB
131 LocalHandle = NULL;\r
132 }\r
133\r
134 AllocSize = sizeof *Device +\r
135 NumMmioResources * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) +\r
136 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR);\r
137 Device = (NON_DISCOVERABLE_DEVICE *)AllocateZeroPool (AllocSize);\r
138 if (Device == NULL) {\r
139 return EFI_OUT_OF_RESOURCES;\r
140 }\r
141\r
142 Device->Type = GetGuidFromType (Type);\r
143 ASSERT (Device->Type != NULL);\r
144\r
1436aea4 145 Device->DmaType = DmaType;\r
1652dc21 146 Device->Initialize = InitFunc;\r
1436aea4 147 Device->Resources = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(Device + 1);\r
1652dc21
AB
148\r
149 VA_START (Args, NumMmioResources);\r
150 for (Index = 0; Index < NumMmioResources; Index++) {\r
1436aea4 151 Desc = &Device->Resources[Index];\r
1652dc21
AB
152 Base = VA_ARG (Args, UINTN);\r
153 Size = VA_ARG (Args, UINTN);\r
154\r
155 Desc->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
156 Desc->Len = sizeof *Desc - 3;\r
157 Desc->AddrRangeMin = Base;\r
158 Desc->AddrLen = Size;\r
159 Desc->AddrRangeMax = Base + Size - 1;\r
160 Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
b494cf96 161 Desc->AddrSpaceGranularity = ((EFI_PHYSICAL_ADDRESS)Base + Size > SIZE_4GB) ? 64 : 32;\r
1652dc21
AB
162 Desc->AddrTranslationOffset = 0;\r
163 }\r
1436aea4 164\r
1652dc21
AB
165 VA_END (Args);\r
166\r
1436aea4 167 End = (EFI_ACPI_END_TAG_DESCRIPTOR *)&Device->Resources[NumMmioResources];\r
1652dc21
AB
168\r
169 End->Desc = ACPI_END_TAG_DESCRIPTOR;\r
170 End->Checksum = 0;\r
171\r
172 DevicePath = (NON_DISCOVERABLE_DEVICE_PATH *)CreateDeviceNode (\r
173 HARDWARE_DEVICE_PATH,\r
174 HW_VENDOR_DP,\r
1436aea4
MK
175 sizeof (*DevicePath)\r
176 );\r
1652dc21
AB
177 if (DevicePath == NULL) {\r
178 Status = EFI_OUT_OF_RESOURCES;\r
179 goto FreeDevice;\r
180 }\r
181\r
182 CopyGuid (&DevicePath->Vendor.Guid, &gEdkiiNonDiscoverableDeviceProtocolGuid);\r
183\r
184 //\r
185 // Use the base address and type of the first region to\r
186 // make the device path unique\r
187 //\r
1436aea4
MK
188 DevicePath->BaseAddress = Device->Resources[0].AddrRangeMin;\r
189 DevicePath->ResourceType = Device->Resources[0].ResType;\r
1652dc21 190\r
1436aea4
MK
191 SetDevicePathNodeLength (\r
192 &DevicePath->Vendor,\r
193 sizeof (*DevicePath) - sizeof (DevicePath->End)\r
194 );\r
1652dc21
AB
195 SetDevicePathEndNode (&DevicePath->End);\r
196\r
1436aea4
MK
197 Status = gBS->InstallMultipleProtocolInterfaces (\r
198 Handle,\r
199 &gEdkiiNonDiscoverableDeviceProtocolGuid,\r
200 Device,\r
201 &gEfiDevicePathProtocolGuid,\r
202 DevicePath,\r
203 NULL\r
204 );\r
1652dc21
AB
205 if (EFI_ERROR (Status)) {\r
206 goto FreeDevicePath;\r
207 }\r
1436aea4 208\r
1652dc21
AB
209 return EFI_SUCCESS;\r
210\r
211FreeDevicePath:\r
212 FreePool (DevicePath);\r
213\r
214FreeDevice:\r
215 FreePool (Device);\r
216\r
217 return Status;\r
218}\r