3 * Copyright (c) 2017, Linaro, Ltd. All rights reserved.
5 * SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/DevicePathLib.h>
12 #include <Library/DtPlatformDtbLoaderLib.h>
13 #include <Library/HiiLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16 #include <Library/UefiDriverEntryPoint.h>
17 #include <Library/UefiRuntimeServicesTableLib.h>
19 #include "DtPlatformDxe.h"
21 extern UINT8 DtPlatformHiiBin
[];
22 extern UINT8 DtPlatformDxeStrings
[];
25 VENDOR_DEVICE_PATH VendorDevicePath
;
26 EFI_DEVICE_PATH_PROTOCOL End
;
27 } HII_VENDOR_DEVICE_PATH
;
29 STATIC HII_VENDOR_DEVICE_PATH mDtPlatformDxeVendorDevicePath
= {
35 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
36 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
39 DT_PLATFORM_FORMSET_GUID
43 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
45 (UINT8
) (END_DEVICE_PATH_LENGTH
),
46 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
58 EFI_HII_HANDLE HiiHandle
;
59 EFI_HANDLE DriverHandle
;
62 Status
= gBS
->InstallMultipleProtocolInterfaces (&DriverHandle
,
63 &gEfiDevicePathProtocolGuid
,
64 &mDtPlatformDxeVendorDevicePath
,
66 if (EFI_ERROR (Status
)) {
70 HiiHandle
= HiiAddPackages (&gDtPlatformFormSetGuid
,
76 if (HiiHandle
== NULL
) {
77 gBS
->UninstallMultipleProtocolInterfaces (DriverHandle
,
78 &gEfiDevicePathProtocolGuid
,
79 &mDtPlatformDxeVendorDevicePath
,
81 return EFI_OUT_OF_RESOURCES
;
87 The entry point for DtPlatformDxe driver.
89 @param[in] ImageHandle The image handle of the driver.
90 @param[in] SystemTable The system table.
92 @retval EFI_ALREADY_STARTED The driver already exists in system.
93 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of
95 @retval EFI_SUCCESS All the related protocols are installed on
101 DtPlatformDxeEntryPoint (
102 IN EFI_HANDLE ImageHandle
,
103 IN EFI_SYSTEM_TABLE
*SystemTable
107 DT_ACPI_VARSTORE_DATA DtAcpiPref
;
113 Status
= DtPlatformLoadDtb (&Dtb
, &DtbSize
);
114 if (EFI_ERROR (Status
)) {
116 "%a: no DTB blob could be loaded, defaulting to ACPI (Status == %r)\n",
117 __FUNCTION__
, Status
));
118 DtAcpiPref
.Pref
= DT_ACPI_SELECT_ACPI
;
121 // Get the current DT/ACPI preference from the DtAcpiPref variable.
123 BufferSize
= sizeof (DtAcpiPref
);
124 Status
= gRT
->GetVariable(DT_ACPI_VARIABLE_NAME
, &gDtPlatformFormSetGuid
,
125 NULL
, &BufferSize
, &DtAcpiPref
);
126 if (EFI_ERROR (Status
)) {
127 DEBUG ((DEBUG_WARN
, "%a: no DT/ACPI preference found, defaulting to %a\n",
128 __FUNCTION__
, PcdGetBool (PcdDefaultDtPref
) ? "DT" : "ACPI"));
129 DtAcpiPref
.Pref
= PcdGetBool (PcdDefaultDtPref
) ? DT_ACPI_SELECT_DT
130 : DT_ACPI_SELECT_ACPI
;
134 if (!EFI_ERROR (Status
) &&
135 DtAcpiPref
.Pref
!= DT_ACPI_SELECT_ACPI
&&
136 DtAcpiPref
.Pref
!= DT_ACPI_SELECT_DT
) {
137 DEBUG ((DEBUG_WARN
, "%a: invalid value for %s, defaulting to %a\n",
138 __FUNCTION__
, DT_ACPI_VARIABLE_NAME
,
139 PcdGetBool (PcdDefaultDtPref
) ? "DT" : "ACPI"));
140 DtAcpiPref
.Pref
= PcdGetBool (PcdDefaultDtPref
) ? DT_ACPI_SELECT_DT
141 : DT_ACPI_SELECT_ACPI
;
142 Status
= EFI_INVALID_PARAMETER
; // trigger setvar below
146 // Write the newly selected default value back to the variable store.
148 if (EFI_ERROR (Status
)) {
149 Status
= gRT
->SetVariable(DT_ACPI_VARIABLE_NAME
, &gDtPlatformFormSetGuid
,
150 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
151 sizeof (DtAcpiPref
), &DtAcpiPref
);
152 if (EFI_ERROR (Status
)) {
157 if (DtAcpiPref
.Pref
== DT_ACPI_SELECT_ACPI
) {
159 // ACPI was selected: install the gEdkiiPlatformHasAcpiGuid GUID as a
160 // NULL protocol to unlock dispatch of ACPI related drivers.
162 Status
= gBS
->InstallMultipleProtocolInterfaces (&ImageHandle
,
163 &gEdkiiPlatformHasAcpiGuid
, NULL
, NULL
);
164 if (EFI_ERROR (Status
)) {
166 "%a: failed to install gEdkiiPlatformHasAcpiGuid as a protocol\n",
170 } else if (DtAcpiPref
.Pref
== DT_ACPI_SELECT_DT
) {
172 // DT was selected: copy the blob into newly allocated memory and install
173 // a reference to it as the FDT configuration table.
175 Status
= gBS
->InstallConfigurationTable (&gFdtTableGuid
, Dtb
);
176 if (EFI_ERROR (Status
)) {
177 DEBUG ((DEBUG_ERROR
, "%a: failed to install FDT configuration table\n",
186 // No point in installing the HII pages if ACPI is the only description
194 // Note that we don't uninstall the gEdkiiPlatformHasAcpiGuid protocol nor
195 // the FDT configuration table if the following call fails. While that will
196 // cause loading of this driver to fail, proceeding with ACPI and DT both
197 // disabled will guarantee a failed boot, and so it is better to leave them
198 // installed in that case.
200 return InstallHiiPages ();