2 Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Guid/NonDiscoverableDevice.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/DevicePathLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/NonDiscoverableDeviceRegistrationLib.h>
23 #include <Library/UefiBootServicesTableLib.h>
25 #include <Protocol/DevicePath.h>
26 #include <Protocol/NonDiscoverableDevice.h>
29 Get Guid form the type of non-discoverable device.
31 @param[in] Type The type of non-discoverable device.
33 @retval Return the Guid.
39 IN NON_DISCOVERABLE_DEVICE_TYPE Type
43 case NonDiscoverableDeviceTypeAhci
:
44 return &gEdkiiNonDiscoverableAhciDeviceGuid
;
46 case NonDiscoverableDeviceTypeAmba
:
47 return &gEdkiiNonDiscoverableAmbaDeviceGuid
;
49 case NonDiscoverableDeviceTypeEhci
:
50 return &gEdkiiNonDiscoverableEhciDeviceGuid
;
52 case NonDiscoverableDeviceTypeNvme
:
53 return &gEdkiiNonDiscoverableNvmeDeviceGuid
;
55 case NonDiscoverableDeviceTypeOhci
:
56 return &gEdkiiNonDiscoverableOhciDeviceGuid
;
58 case NonDiscoverableDeviceTypeSdhci
:
59 return &gEdkiiNonDiscoverableSdhciDeviceGuid
;
61 case NonDiscoverableDeviceTypeUfs
:
62 return &gEdkiiNonDiscoverableUfsDeviceGuid
;
64 case NonDiscoverableDeviceTypeUhci
:
65 return &gEdkiiNonDiscoverableUhciDeviceGuid
;
67 case NonDiscoverableDeviceTypeXhci
:
68 return &gEdkiiNonDiscoverableXhciDeviceGuid
;
77 VENDOR_DEVICE_PATH Vendor
;
80 EFI_DEVICE_PATH_PROTOCOL End
;
81 } NON_DISCOVERABLE_DEVICE_PATH
;
85 Register a non-discoverable MMIO device.
87 @param[in] Type The type of non-discoverable device
88 @param[in] DmaType Whether the device is DMA coherent
89 @param[in] InitFunc Initialization routine to be invoked when
91 @param[in,out] Handle The handle onto which to install the
92 non-discoverable device protocol.
93 If Handle is NULL or *Handle is NULL, a
94 new handle will be allocated.
95 @param[in] NumMmioResources The number of UINTN base/size pairs that
96 follow, each describing an MMIO region
98 @param[in] ... The variable argument list which contains the
99 info about MmioResources.
101 @retval EFI_SUCCESS The registration succeeded.
102 @retval EFI_INVALID_PARAMETER An invalid argument was given
103 @retval Other The registration failed.
108 RegisterNonDiscoverableMmioDevice (
109 IN NON_DISCOVERABLE_DEVICE_TYPE Type
,
110 IN NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType
,
111 IN NON_DISCOVERABLE_DEVICE_INIT InitFunc
,
112 IN OUT EFI_HANDLE
*Handle OPTIONAL
,
113 IN UINTN NumMmioResources
,
117 NON_DISCOVERABLE_DEVICE
*Device
;
118 NON_DISCOVERABLE_DEVICE_PATH
*DevicePath
;
119 EFI_HANDLE LocalHandle
;
124 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
125 EFI_ACPI_END_TAG_DESCRIPTOR
*End
;
128 if (Type
>= NonDiscoverableDeviceTypeMax
||
129 DmaType
>= NonDiscoverableDeviceDmaTypeMax
||
130 NumMmioResources
== 0) {
131 return EFI_INVALID_PARAMETER
;
134 if (Handle
== NULL
) {
135 Handle
= &LocalHandle
;
139 AllocSize
= sizeof *Device
+
140 NumMmioResources
* sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
141 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
);
142 Device
= (NON_DISCOVERABLE_DEVICE
*)AllocateZeroPool (AllocSize
);
143 if (Device
== NULL
) {
144 return EFI_OUT_OF_RESOURCES
;
147 Device
->Type
= GetGuidFromType (Type
);
148 ASSERT (Device
->Type
!= NULL
);
150 Device
->DmaType
= DmaType
;
151 Device
->Initialize
= InitFunc
;
152 Device
->Resources
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)(Device
+ 1);
154 VA_START (Args
, NumMmioResources
);
155 for (Index
= 0; Index
< NumMmioResources
; Index
++) {
156 Desc
= &Device
->Resources
[Index
];
157 Base
= VA_ARG (Args
, UINTN
);
158 Size
= VA_ARG (Args
, UINTN
);
160 Desc
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
161 Desc
->Len
= sizeof *Desc
- 3;
162 Desc
->AddrRangeMin
= Base
;
163 Desc
->AddrLen
= Size
;
164 Desc
->AddrRangeMax
= Base
+ Size
- 1;
165 Desc
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
166 Desc
->AddrSpaceGranularity
= ((EFI_PHYSICAL_ADDRESS
)Base
+ Size
> SIZE_4GB
) ? 64 : 32;
167 Desc
->AddrTranslationOffset
= 0;
171 End
= (EFI_ACPI_END_TAG_DESCRIPTOR
*)&Device
->Resources
[NumMmioResources
];
173 End
->Desc
= ACPI_END_TAG_DESCRIPTOR
;
176 DevicePath
= (NON_DISCOVERABLE_DEVICE_PATH
*)CreateDeviceNode (
177 HARDWARE_DEVICE_PATH
,
179 sizeof (*DevicePath
));
180 if (DevicePath
== NULL
) {
181 Status
= EFI_OUT_OF_RESOURCES
;
185 CopyGuid (&DevicePath
->Vendor
.Guid
, &gEdkiiNonDiscoverableDeviceProtocolGuid
);
188 // Use the base address and type of the first region to
189 // make the device path unique
191 DevicePath
->BaseAddress
= Device
->Resources
[0].AddrRangeMin
;
192 DevicePath
->ResourceType
= Device
->Resources
[0].ResType
;
194 SetDevicePathNodeLength (&DevicePath
->Vendor
,
195 sizeof (*DevicePath
) - sizeof (DevicePath
->End
));
196 SetDevicePathEndNode (&DevicePath
->End
);
198 Status
= gBS
->InstallMultipleProtocolInterfaces (Handle
,
199 &gEdkiiNonDiscoverableDeviceProtocolGuid
, Device
,
200 &gEfiDevicePathProtocolGuid
, DevicePath
,
202 if (EFI_ERROR (Status
)) {
208 FreePool (DevicePath
);