2 Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Guid/NonDiscoverableDevice.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/DevicePathLib.h>
15 #include <Library/MemoryAllocationLib.h>
16 #include <Library/NonDiscoverableDeviceRegistrationLib.h>
17 #include <Library/UefiBootServicesTableLib.h>
19 #include <Protocol/DevicePath.h>
20 #include <Protocol/NonDiscoverableDevice.h>
23 Get Guid form the type of non-discoverable device.
25 @param[in] Type The type of non-discoverable device.
27 @retval Return the Guid.
33 IN NON_DISCOVERABLE_DEVICE_TYPE Type
37 case NonDiscoverableDeviceTypeAhci
:
38 return &gEdkiiNonDiscoverableAhciDeviceGuid
;
40 case NonDiscoverableDeviceTypeAmba
:
41 return &gEdkiiNonDiscoverableAmbaDeviceGuid
;
43 case NonDiscoverableDeviceTypeEhci
:
44 return &gEdkiiNonDiscoverableEhciDeviceGuid
;
46 case NonDiscoverableDeviceTypeNvme
:
47 return &gEdkiiNonDiscoverableNvmeDeviceGuid
;
49 case NonDiscoverableDeviceTypeOhci
:
50 return &gEdkiiNonDiscoverableOhciDeviceGuid
;
52 case NonDiscoverableDeviceTypeSdhci
:
53 return &gEdkiiNonDiscoverableSdhciDeviceGuid
;
55 case NonDiscoverableDeviceTypeUfs
:
56 return &gEdkiiNonDiscoverableUfsDeviceGuid
;
58 case NonDiscoverableDeviceTypeUhci
:
59 return &gEdkiiNonDiscoverableUhciDeviceGuid
;
61 case NonDiscoverableDeviceTypeXhci
:
62 return &gEdkiiNonDiscoverableXhciDeviceGuid
;
71 VENDOR_DEVICE_PATH Vendor
;
74 EFI_DEVICE_PATH_PROTOCOL End
;
75 } NON_DISCOVERABLE_DEVICE_PATH
;
79 Register a non-discoverable MMIO device.
81 @param[in] Type The type of non-discoverable device
82 @param[in] DmaType Whether the device is DMA coherent
83 @param[in] InitFunc Initialization routine to be invoked when
85 @param[in,out] Handle The handle onto which to install the
86 non-discoverable device protocol.
87 If Handle is NULL or *Handle is NULL, a
88 new handle will be allocated.
89 @param[in] NumMmioResources The number of UINTN base/size pairs that
90 follow, each describing an MMIO region
92 @param[in] ... The variable argument list which contains the
93 info about MmioResources.
95 @retval EFI_SUCCESS The registration succeeded.
96 @retval EFI_INVALID_PARAMETER An invalid argument was given
97 @retval Other The registration failed.
102 RegisterNonDiscoverableMmioDevice (
103 IN NON_DISCOVERABLE_DEVICE_TYPE Type
,
104 IN NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType
,
105 IN NON_DISCOVERABLE_DEVICE_INIT InitFunc
,
106 IN OUT EFI_HANDLE
*Handle OPTIONAL
,
107 IN UINTN NumMmioResources
,
111 NON_DISCOVERABLE_DEVICE
*Device
;
112 NON_DISCOVERABLE_DEVICE_PATH
*DevicePath
;
113 EFI_HANDLE LocalHandle
;
118 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
119 EFI_ACPI_END_TAG_DESCRIPTOR
*End
;
122 if (Type
>= NonDiscoverableDeviceTypeMax
||
123 DmaType
>= NonDiscoverableDeviceDmaTypeMax
||
124 NumMmioResources
== 0) {
125 return EFI_INVALID_PARAMETER
;
128 if (Handle
== NULL
) {
129 Handle
= &LocalHandle
;
133 AllocSize
= sizeof *Device
+
134 NumMmioResources
* sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
135 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
);
136 Device
= (NON_DISCOVERABLE_DEVICE
*)AllocateZeroPool (AllocSize
);
137 if (Device
== NULL
) {
138 return EFI_OUT_OF_RESOURCES
;
141 Device
->Type
= GetGuidFromType (Type
);
142 ASSERT (Device
->Type
!= NULL
);
144 Device
->DmaType
= DmaType
;
145 Device
->Initialize
= InitFunc
;
146 Device
->Resources
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)(Device
+ 1);
148 VA_START (Args
, NumMmioResources
);
149 for (Index
= 0; Index
< NumMmioResources
; Index
++) {
150 Desc
= &Device
->Resources
[Index
];
151 Base
= VA_ARG (Args
, UINTN
);
152 Size
= VA_ARG (Args
, UINTN
);
154 Desc
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
155 Desc
->Len
= sizeof *Desc
- 3;
156 Desc
->AddrRangeMin
= Base
;
157 Desc
->AddrLen
= Size
;
158 Desc
->AddrRangeMax
= Base
+ Size
- 1;
159 Desc
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
160 Desc
->AddrSpaceGranularity
= ((EFI_PHYSICAL_ADDRESS
)Base
+ Size
> SIZE_4GB
) ? 64 : 32;
161 Desc
->AddrTranslationOffset
= 0;
165 End
= (EFI_ACPI_END_TAG_DESCRIPTOR
*)&Device
->Resources
[NumMmioResources
];
167 End
->Desc
= ACPI_END_TAG_DESCRIPTOR
;
170 DevicePath
= (NON_DISCOVERABLE_DEVICE_PATH
*)CreateDeviceNode (
171 HARDWARE_DEVICE_PATH
,
173 sizeof (*DevicePath
));
174 if (DevicePath
== NULL
) {
175 Status
= EFI_OUT_OF_RESOURCES
;
179 CopyGuid (&DevicePath
->Vendor
.Guid
, &gEdkiiNonDiscoverableDeviceProtocolGuid
);
182 // Use the base address and type of the first region to
183 // make the device path unique
185 DevicePath
->BaseAddress
= Device
->Resources
[0].AddrRangeMin
;
186 DevicePath
->ResourceType
= Device
->Resources
[0].ResType
;
188 SetDevicePathNodeLength (&DevicePath
->Vendor
,
189 sizeof (*DevicePath
) - sizeof (DevicePath
->End
));
190 SetDevicePathEndNode (&DevicePath
->End
);
192 Status
= gBS
->InstallMultipleProtocolInterfaces (Handle
,
193 &gEdkiiNonDiscoverableDeviceProtocolGuid
, Device
,
194 &gEfiDevicePathProtocolGuid
, DevicePath
,
196 if (EFI_ERROR (Status
)) {
202 FreePool (DevicePath
);