]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.c
EmbeddedPkg: Fix various typos
[mirror_edk2.git] / EmbeddedPkg / Drivers / DtPlatformDxe / DtPlatformDxe.c
1 /** @file
2 *
3 * Copyright (c) 2017, Linaro, Ltd. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause-Patent
6 *
7 **/
8
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>
18
19 #include "DtPlatformDxe.h"
20
21 extern UINT8 DtPlatformHiiBin[];
22 extern UINT8 DtPlatformDxeStrings[];
23
24 typedef struct {
25 VENDOR_DEVICE_PATH VendorDevicePath;
26 EFI_DEVICE_PATH_PROTOCOL End;
27 } HII_VENDOR_DEVICE_PATH;
28
29 STATIC HII_VENDOR_DEVICE_PATH mDtPlatformDxeVendorDevicePath = {
30 {
31 {
32 HARDWARE_DEVICE_PATH,
33 HW_VENDOR_DP,
34 {
35 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
36 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
37 }
38 },
39 DT_PLATFORM_FORMSET_GUID
40 },
41 {
42 END_DEVICE_PATH_TYPE,
43 END_ENTIRE_DEVICE_PATH_SUBTYPE,
44 {
45 (UINT8) (END_DEVICE_PATH_LENGTH),
46 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
47 }
48 }
49 };
50
51 STATIC
52 EFI_STATUS
53 InstallHiiPages (
54 VOID
55 )
56 {
57 EFI_STATUS Status;
58 EFI_HII_HANDLE HiiHandle;
59 EFI_HANDLE DriverHandle;
60
61 DriverHandle = NULL;
62 Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,
63 &gEfiDevicePathProtocolGuid,
64 &mDtPlatformDxeVendorDevicePath,
65 NULL);
66 if (EFI_ERROR (Status)) {
67 return Status;
68 }
69
70 HiiHandle = HiiAddPackages (&gDtPlatformFormSetGuid,
71 DriverHandle,
72 DtPlatformDxeStrings,
73 DtPlatformHiiBin,
74 NULL);
75
76 if (HiiHandle == NULL) {
77 gBS->UninstallMultipleProtocolInterfaces (DriverHandle,
78 &gEfiDevicePathProtocolGuid,
79 &mDtPlatformDxeVendorDevicePath,
80 NULL);
81 return EFI_OUT_OF_RESOURCES;
82 }
83 return EFI_SUCCESS;
84 }
85
86 /**
87 The entry point for DtPlatformDxe driver.
88
89 @param[in] ImageHandle The image handle of the driver.
90 @param[in] SystemTable The system table.
91
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
94 resources.
95 @retval EFI_SUCCESS All the related protocols are installed on
96 the driver.
97
98 **/
99 EFI_STATUS
100 EFIAPI
101 DtPlatformDxeEntryPoint (
102 IN EFI_HANDLE ImageHandle,
103 IN EFI_SYSTEM_TABLE *SystemTable
104 )
105 {
106 EFI_STATUS Status;
107 DT_ACPI_VARSTORE_DATA DtAcpiPref;
108 UINTN BufferSize;
109 VOID *Dtb;
110 UINTN DtbSize;
111
112 Dtb = NULL;
113 Status = DtPlatformLoadDtb (&Dtb, &DtbSize);
114 if (EFI_ERROR (Status)) {
115 DEBUG ((DEBUG_WARN,
116 "%a: no DTB blob could be loaded, defaulting to ACPI (Status == %r)\n",
117 __FUNCTION__, Status));
118 DtAcpiPref.Pref = DT_ACPI_SELECT_ACPI;
119 } else {
120 //
121 // Get the current DT/ACPI preference from the DtAcpiPref variable.
122 //
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 DT\n",
128 __FUNCTION__));
129 DtAcpiPref.Pref = DT_ACPI_SELECT_DT;
130 }
131 }
132
133 if (!EFI_ERROR (Status) &&
134 DtAcpiPref.Pref != DT_ACPI_SELECT_ACPI &&
135 DtAcpiPref.Pref != DT_ACPI_SELECT_DT) {
136 DEBUG ((DEBUG_WARN, "%a: invalid value for %s, defaulting to DT\n",
137 __FUNCTION__, DT_ACPI_VARIABLE_NAME));
138 DtAcpiPref.Pref = DT_ACPI_SELECT_DT;
139 Status = EFI_INVALID_PARAMETER; // trigger setvar below
140 }
141
142 //
143 // Write the newly selected default value back to the variable store.
144 //
145 if (EFI_ERROR (Status)) {
146 Status = gRT->SetVariable(DT_ACPI_VARIABLE_NAME, &gDtPlatformFormSetGuid,
147 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
148 sizeof (DtAcpiPref), &DtAcpiPref);
149 if (EFI_ERROR (Status)) {
150 goto FreeDtb;
151 }
152 }
153
154 if (DtAcpiPref.Pref == DT_ACPI_SELECT_ACPI) {
155 //
156 // ACPI was selected: install the gEdkiiPlatformHasAcpiGuid GUID as a
157 // NULL protocol to unlock dispatch of ACPI related drivers.
158 //
159 Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
160 &gEdkiiPlatformHasAcpiGuid, NULL, NULL);
161 if (EFI_ERROR (Status)) {
162 DEBUG ((DEBUG_ERROR,
163 "%a: failed to install gEdkiiPlatformHasAcpiGuid as a protocol\n",
164 __FUNCTION__));
165 goto FreeDtb;
166 }
167 } else if (DtAcpiPref.Pref == DT_ACPI_SELECT_DT) {
168 //
169 // DT was selected: copy the blob into newly allocated memory and install
170 // a reference to it as the FDT configuration table.
171 //
172 Status = gBS->InstallConfigurationTable (&gFdtTableGuid, Dtb);
173 if (EFI_ERROR (Status)) {
174 DEBUG ((DEBUG_ERROR, "%a: failed to install FDT configuration table\n",
175 __FUNCTION__));
176 goto FreeDtb;
177 }
178 } else {
179 ASSERT (FALSE);
180 }
181
182 //
183 // No point in installing the HII pages if ACPI is the only description
184 // we have
185 //
186 if (Dtb == NULL) {
187 return EFI_SUCCESS;
188 }
189
190 //
191 // Note that we don't uninstall the gEdkiiPlatformHasAcpiGuid protocol nor
192 // the FDT configuration table if the following call fails. While that will
193 // cause loading of this driver to fail, proceeding with ACPI and DT both
194 // disabled will guarantee a failed boot, and so it is better to leave them
195 // installed in that case.
196 //
197 return InstallHiiPages ();
198
199 FreeDtb:
200 if (Dtb != NULL) {
201 FreePool (Dtb);
202 }
203
204 return Status;
205 }