3 * Copyright (c) 2017, Linaro, Ltd. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/DevicePathLib.h>
18 #include <Library/DtPlatformDtbLoaderLib.h>
19 #include <Library/HiiLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiDriverEntryPoint.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
25 #include "DtPlatformDxe.h"
27 extern UINT8 DtPlatformHiiBin
[];
28 extern UINT8 DtPlatformDxeStrings
[];
31 VENDOR_DEVICE_PATH VendorDevicePath
;
32 EFI_DEVICE_PATH_PROTOCOL End
;
33 } HII_VENDOR_DEVICE_PATH
;
35 STATIC HII_VENDOR_DEVICE_PATH mDtPlatformDxeVendorDevicePath
= {
41 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
42 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
45 DT_PLATFORM_FORMSET_GUID
49 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
51 (UINT8
) (END_DEVICE_PATH_LENGTH
),
52 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
64 EFI_HII_HANDLE HiiHandle
;
65 EFI_HANDLE DriverHandle
;
68 Status
= gBS
->InstallMultipleProtocolInterfaces (&DriverHandle
,
69 &gEfiDevicePathProtocolGuid
,
70 &mDtPlatformDxeVendorDevicePath
,
72 if (EFI_ERROR (Status
)) {
76 HiiHandle
= HiiAddPackages (&gDtPlatformFormSetGuid
,
82 if (HiiHandle
== NULL
) {
83 gBS
->UninstallMultipleProtocolInterfaces (DriverHandle
,
84 &gEfiDevicePathProtocolGuid
,
85 &mDtPlatformDxeVendorDevicePath
,
87 return EFI_OUT_OF_RESOURCES
;
93 The entry point for DtPlatformDxe driver.
95 @param[in] ImageHandle The image handle of the driver.
96 @param[in] SystemTable The system table.
98 @retval EFI_ALREADY_STARTED The driver already exists in system.
99 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of
101 @retval EFI_SUCCES All the related protocols are installed on
107 DtPlatformDxeEntryPoint (
108 IN EFI_HANDLE ImageHandle
,
109 IN EFI_SYSTEM_TABLE
*SystemTable
113 DT_ACPI_VARSTORE_DATA DtAcpiPref
;
119 Status
= DtPlatformLoadDtb (&Dtb
, &DtbSize
);
120 if (EFI_ERROR (Status
)) {
122 "%a: no DTB blob could be loaded, defaulting to ACPI (Status == %r)\n",
123 __FUNCTION__
, Status
));
124 DtAcpiPref
.Pref
= DT_ACPI_SELECT_ACPI
;
127 // Get the current DT/ACPI preference from the DtAcpiPref variable.
129 BufferSize
= sizeof (DtAcpiPref
);
130 Status
= gRT
->GetVariable(DT_ACPI_VARIABLE_NAME
, &gDtPlatformFormSetGuid
,
131 NULL
, &BufferSize
, &DtAcpiPref
);
132 if (EFI_ERROR (Status
)) {
133 DEBUG ((DEBUG_WARN
, "%a: no DT/ACPI preference found, defaulting to DT\n",
135 DtAcpiPref
.Pref
= DT_ACPI_SELECT_DT
;
139 if (!EFI_ERROR (Status
) &&
140 DtAcpiPref
.Pref
!= DT_ACPI_SELECT_ACPI
&&
141 DtAcpiPref
.Pref
!= DT_ACPI_SELECT_DT
) {
142 DEBUG ((DEBUG_WARN
, "%a: invalid value for %s, defaulting to DT\n",
143 __FUNCTION__
, DT_ACPI_VARIABLE_NAME
));
144 DtAcpiPref
.Pref
= DT_ACPI_SELECT_DT
;
145 Status
= EFI_INVALID_PARAMETER
; // trigger setvar below
149 // Write the newly selected default value back to the variable store.
151 if (EFI_ERROR (Status
)) {
152 Status
= gRT
->SetVariable(DT_ACPI_VARIABLE_NAME
, &gDtPlatformFormSetGuid
,
153 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
154 sizeof (DtAcpiPref
), &DtAcpiPref
);
155 if (EFI_ERROR (Status
)) {
160 if (DtAcpiPref
.Pref
== DT_ACPI_SELECT_ACPI
) {
162 // ACPI was selected: install the gEdkiiPlatformHasAcpiGuid GUID as a
163 // NULL protocol to unlock dispatch of ACPI related drivers.
165 Status
= gBS
->InstallMultipleProtocolInterfaces (&ImageHandle
,
166 &gEdkiiPlatformHasAcpiGuid
, NULL
, NULL
);
167 if (EFI_ERROR (Status
)) {
169 "%a: failed to install gEdkiiPlatformHasAcpiGuid as a protocol\n",
173 } else if (DtAcpiPref
.Pref
== DT_ACPI_SELECT_DT
) {
175 // DT was selected: copy the blob into newly allocated memory and install
176 // a reference to it as the FDT configuration table.
178 Status
= gBS
->InstallConfigurationTable (&gFdtTableGuid
, Dtb
);
179 if (EFI_ERROR (Status
)) {
180 DEBUG ((DEBUG_ERROR
, "%a: failed to install FDT configuration table\n",
189 // No point in installing the HII pages if ACPI is the only description
197 // Note that we don't uninstall the gEdkiiPlatformHasAcpiGuid protocol nor
198 // the FDT configuration table if the following call fails. While that will
199 // cause loading of this driver to fail, proceeding with ACPI and DT both
200 // disabled will guarantee a failed boot, and so it is better to leave them
201 // installed in that case.
203 return InstallHiiPages ();