]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c
MdeModulePkg/SataControllerDxe: Fix coding style issue
[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
4 This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12**/\r
13\r
14#include <PiDxe.h>\r
15\r
16#include <Guid/NonDiscoverableDevice.h>\r
17\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/DevicePathLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/NonDiscoverableDeviceRegistrationLib.h>\r
23#include <Library/UefiBootServicesTableLib.h>\r
24\r
25#include <Protocol/DevicePath.h>\r
26#include <Protocol/NonDiscoverableDevice.h>\r
27\r
28STATIC\r
29CONST EFI_GUID *\r
30GetGuidFromType (\r
31 IN NON_DISCOVERABLE_DEVICE_TYPE Type\r
32 )\r
33{\r
34 switch (Type) {\r
35 case NonDiscoverableDeviceTypeAhci:\r
36 return &gEdkiiNonDiscoverableAhciDeviceGuid;\r
37\r
38 case NonDiscoverableDeviceTypeAmba:\r
39 return &gEdkiiNonDiscoverableAmbaDeviceGuid;\r
40\r
41 case NonDiscoverableDeviceTypeEhci:\r
42 return &gEdkiiNonDiscoverableEhciDeviceGuid;\r
43\r
44 case NonDiscoverableDeviceTypeNvme:\r
45 return &gEdkiiNonDiscoverableNvmeDeviceGuid;\r
46\r
47 case NonDiscoverableDeviceTypeOhci:\r
48 return &gEdkiiNonDiscoverableOhciDeviceGuid;\r
49\r
50 case NonDiscoverableDeviceTypeSdhci:\r
51 return &gEdkiiNonDiscoverableSdhciDeviceGuid;\r
52\r
53 case NonDiscoverableDeviceTypeUfs:\r
54 return &gEdkiiNonDiscoverableUfsDeviceGuid;\r
55\r
56 case NonDiscoverableDeviceTypeUhci:\r
57 return &gEdkiiNonDiscoverableUhciDeviceGuid;\r
58\r
59 case NonDiscoverableDeviceTypeXhci:\r
60 return &gEdkiiNonDiscoverableXhciDeviceGuid;\r
61\r
62 default:\r
63 return NULL;\r
64 }\r
65}\r
66\r
67#pragma pack (1)\r
68typedef struct {\r
69 VENDOR_DEVICE_PATH Vendor;\r
70 UINT64 BaseAddress;\r
71 UINT8 ResourceType;\r
72 EFI_DEVICE_PATH_PROTOCOL End;\r
73} NON_DISCOVERABLE_DEVICE_PATH;\r
74#pragma pack ()\r
75\r
76/**\r
77 Register a non-discoverable MMIO device\r
78\r
79 @param[in] DeviceType The type of non-discoverable device\r
80 @param[in] DmaType Whether the device is DMA coherent\r
81 @param[in] InitFunc Initialization routine to be invoked when\r
82 the device is enabled\r
83 @param[in,out] Handle The handle onto which to install the\r
84 non-discoverable device protocol.\r
85 If Handle is NULL or *Handle is NULL, a\r
86 new handle will be allocated.\r
87 @param[in] NumMmioResources The number of UINTN base/size pairs that\r
88 follow, each describing an MMIO region\r
89 owned by the device\r
90\r
91 @retval EFI_SUCCESS The registration succeeded.\r
92 @retval EFI_INVALID_PARAMETER An invalid argument was given\r
93 @retval Other The registration failed.\r
94\r
95**/\r
96EFI_STATUS\r
97EFIAPI\r
98RegisterNonDiscoverableMmioDevice (\r
99 IN NON_DISCOVERABLE_DEVICE_TYPE Type,\r
100 IN NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType,\r
101 IN NON_DISCOVERABLE_DEVICE_INIT InitFunc,\r
102 IN OUT EFI_HANDLE *Handle OPTIONAL,\r
103 IN UINTN NumMmioResources,\r
104 ...\r
105 )\r
106{\r
107 NON_DISCOVERABLE_DEVICE *Device;\r
108 NON_DISCOVERABLE_DEVICE_PATH *DevicePath;\r
109 EFI_HANDLE LocalHandle;\r
110 EFI_STATUS Status;\r
111 UINTN AllocSize;\r
112 UINTN Index;\r
113 VA_LIST Args;\r
114 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;\r
115 EFI_ACPI_END_TAG_DESCRIPTOR *End;\r
116 UINTN Base, Size;\r
117\r
118 if (Type >= NonDiscoverableDeviceTypeMax ||\r
119 DmaType >= NonDiscoverableDeviceDmaTypeMax ||\r
120 NumMmioResources == 0) {\r
121 return EFI_INVALID_PARAMETER;\r
122 }\r
123\r
124 if (Handle == NULL) {\r
125 Handle = &LocalHandle;\r
126 LocalHandle = NULL;\r
127 }\r
128\r
129 AllocSize = sizeof *Device +\r
130 NumMmioResources * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) +\r
131 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR);\r
132 Device = (NON_DISCOVERABLE_DEVICE *)AllocateZeroPool (AllocSize);\r
133 if (Device == NULL) {\r
134 return EFI_OUT_OF_RESOURCES;\r
135 }\r
136\r
137 Device->Type = GetGuidFromType (Type);\r
138 ASSERT (Device->Type != NULL);\r
139\r
140 Device->DmaType = DmaType;\r
141 Device->Initialize = InitFunc;\r
142 Device->Resources = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(Device + 1);\r
143\r
144 VA_START (Args, NumMmioResources);\r
145 for (Index = 0; Index < NumMmioResources; Index++) {\r
146 Desc = &Device->Resources [Index];\r
147 Base = VA_ARG (Args, UINTN);\r
148 Size = VA_ARG (Args, UINTN);\r
149\r
150 Desc->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
151 Desc->Len = sizeof *Desc - 3;\r
152 Desc->AddrRangeMin = Base;\r
153 Desc->AddrLen = Size;\r
154 Desc->AddrRangeMax = Base + Size - 1;\r
155 Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
156 Desc->AddrSpaceGranularity = (Base + Size > SIZE_4GB) ? 64 : 32;\r
157 Desc->AddrTranslationOffset = 0;\r
158 }\r
159 VA_END (Args);\r
160\r
161 End = (EFI_ACPI_END_TAG_DESCRIPTOR *)&Device->Resources [NumMmioResources];\r
162\r
163 End->Desc = ACPI_END_TAG_DESCRIPTOR;\r
164 End->Checksum = 0;\r
165\r
166 DevicePath = (NON_DISCOVERABLE_DEVICE_PATH *)CreateDeviceNode (\r
167 HARDWARE_DEVICE_PATH,\r
168 HW_VENDOR_DP,\r
169 sizeof (*DevicePath));\r
170 if (DevicePath == NULL) {\r
171 Status = EFI_OUT_OF_RESOURCES;\r
172 goto FreeDevice;\r
173 }\r
174\r
175 CopyGuid (&DevicePath->Vendor.Guid, &gEdkiiNonDiscoverableDeviceProtocolGuid);\r
176\r
177 //\r
178 // Use the base address and type of the first region to\r
179 // make the device path unique\r
180 //\r
181 DevicePath->BaseAddress = Device->Resources [0].AddrRangeMin;\r
182 DevicePath->ResourceType = Device->Resources [0].ResType;\r
183\r
184 SetDevicePathNodeLength (&DevicePath->Vendor,\r
185 sizeof (*DevicePath) - sizeof (DevicePath->End));\r
186 SetDevicePathEndNode (&DevicePath->End);\r
187\r
188 Status = gBS->InstallMultipleProtocolInterfaces (Handle,\r
189 &gEdkiiNonDiscoverableDeviceProtocolGuid, Device,\r
190 &gEfiDevicePathProtocolGuid, DevicePath,\r
191 NULL);\r
192 if (EFI_ERROR (Status)) {\r
193 goto FreeDevicePath;\r
194 }\r
195 return EFI_SUCCESS;\r
196\r
197FreeDevicePath:\r
198 FreePool (DevicePath);\r
199\r
200FreeDevice:\r
201 FreePool (Device);\r
202\r
203 return Status;\r
204}\r