]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.c
EmbeddedPkg: add base DtPlatformDtbLoaderLib implementation
[mirror_edk2.git] / EmbeddedPkg / Drivers / DtPlatformDxe / DtPlatformDxe.c
CommitLineData
779cc439
AB
1/** @file\r
2*\r
3* Copyright (c) 2017, Linaro, Ltd. All rights reserved.\r
4*\r
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12*\r
13**/\r
14\r
15#include <Library/BaseLib.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/DevicePathLib.h>\r
18#include <Library/DxeServicesLib.h>\r
19#include <Library/HiiLib.h>\r
20#include <Library/MemoryAllocationLib.h>\r
21#include <Library/UefiBootServicesTableLib.h>\r
22#include <Library/UefiDriverEntryPoint.h>\r
23#include <Library/UefiRuntimeServicesTableLib.h>\r
24\r
25#include "DtPlatformDxe.h"\r
26\r
27extern UINT8 DtPlatformHiiBin[];\r
28extern UINT8 DtPlatformDxeStrings[];\r
29\r
30typedef struct {\r
31 VENDOR_DEVICE_PATH VendorDevicePath;\r
32 EFI_DEVICE_PATH_PROTOCOL End;\r
33} HII_VENDOR_DEVICE_PATH;\r
34\r
35STATIC HII_VENDOR_DEVICE_PATH mDtPlatformDxeVendorDevicePath = {\r
36 {\r
37 {\r
38 HARDWARE_DEVICE_PATH,\r
39 HW_VENDOR_DP,\r
40 {\r
41 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
42 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
43 }\r
44 },\r
45 DT_PLATFORM_FORMSET_GUID\r
46 },\r
47 {\r
48 END_DEVICE_PATH_TYPE,\r
49 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
50 {\r
51 (UINT8) (END_DEVICE_PATH_LENGTH),\r
52 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
53 }\r
54 }\r
55};\r
56\r
57STATIC\r
58EFI_STATUS\r
59InstallHiiPages (\r
60 VOID\r
61 )\r
62{\r
63 EFI_STATUS Status;\r
64 EFI_HII_HANDLE HiiHandle;\r
65 EFI_HANDLE DriverHandle;\r
66\r
67 DriverHandle = NULL;\r
68 Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,\r
69 &gEfiDevicePathProtocolGuid,\r
70 &mDtPlatformDxeVendorDevicePath,\r
71 NULL);\r
72 if (EFI_ERROR (Status)) {\r
73 return Status;\r
74 }\r
75\r
76 HiiHandle = HiiAddPackages (&gDtPlatformFormSetGuid,\r
77 DriverHandle,\r
78 DtPlatformDxeStrings,\r
79 DtPlatformHiiBin,\r
80 NULL);\r
81\r
82 if (HiiHandle == NULL) {\r
83 gBS->UninstallMultipleProtocolInterfaces (DriverHandle,\r
84 &gEfiDevicePathProtocolGuid,\r
85 &mDtPlatformDxeVendorDevicePath,\r
86 NULL);\r
87 return EFI_OUT_OF_RESOURCES;\r
88 }\r
89 return EFI_SUCCESS;\r
90}\r
91\r
92/**\r
93 The entry point for DtPlatformDxe driver.\r
94\r
95 @param[in] ImageHandle The image handle of the driver.\r
96 @param[in] SystemTable The system table.\r
97\r
98 @retval EFI_ALREADY_STARTED The driver already exists in system.\r
99 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of\r
100 resources.\r
101 @retval EFI_SUCCES All the related protocols are installed on\r
102 the driver.\r
103\r
104**/\r
105EFI_STATUS\r
106EFIAPI\r
107DtPlatformDxeEntryPoint (\r
108 IN EFI_HANDLE ImageHandle,\r
109 IN EFI_SYSTEM_TABLE *SystemTable\r
110 )\r
111{\r
112 EFI_STATUS Status;\r
113 DT_ACPI_VARSTORE_DATA DtAcpiPref;\r
114 UINTN BufferSize;\r
115 VOID *Dtb;\r
116 UINTN DtbSize;\r
117 VOID *DtbCopy;\r
118\r
119 //\r
120 // Check whether a DTB blob is included in the firmware image.\r
121 //\r
122 Dtb = NULL;\r
123 Status = GetSectionFromAnyFv (&gDtPlatformDefaultDtbFileGuid,\r
124 EFI_SECTION_RAW, 0, &Dtb, &DtbSize);\r
125 if (EFI_ERROR (Status)) {\r
126 DEBUG ((DEBUG_WARN, "%a: no DTB blob found, defaulting to ACPI\n",\r
127 __FUNCTION__));\r
128 DtAcpiPref.Pref = DT_ACPI_SELECT_ACPI;\r
129 } else {\r
130 //\r
131 // Get the current DT/ACPI preference from the DtAcpiPref variable.\r
132 //\r
133 BufferSize = sizeof (DtAcpiPref);\r
134 Status = gRT->GetVariable(DT_ACPI_VARIABLE_NAME, &gDtPlatformFormSetGuid,\r
135 NULL, &BufferSize, &DtAcpiPref);\r
136 if (EFI_ERROR (Status)) {\r
137 DEBUG ((DEBUG_WARN, "%a: no DT/ACPI preference found, defaulting to DT\n",\r
138 __FUNCTION__));\r
139 DtAcpiPref.Pref = DT_ACPI_SELECT_DT;\r
140 }\r
141 }\r
142\r
143 if (!EFI_ERROR (Status) &&\r
144 DtAcpiPref.Pref != DT_ACPI_SELECT_ACPI &&\r
145 DtAcpiPref.Pref != DT_ACPI_SELECT_DT) {\r
146 DEBUG ((DEBUG_WARN, "%a: invalid value for %s, defaulting to DT\n",\r
147 __FUNCTION__, DT_ACPI_VARIABLE_NAME));\r
148 DtAcpiPref.Pref = DT_ACPI_SELECT_DT;\r
149 Status = EFI_INVALID_PARAMETER; // trigger setvar below\r
150 }\r
151\r
152 //\r
153 // Write the newly selected default value back to the variable store.\r
154 //\r
155 if (EFI_ERROR (Status)) {\r
156 Status = gRT->SetVariable(DT_ACPI_VARIABLE_NAME, &gDtPlatformFormSetGuid,\r
157 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
158 sizeof (DtAcpiPref), &DtAcpiPref);\r
159 if (EFI_ERROR (Status)) {\r
160 return Status;\r
161 }\r
162 }\r
163\r
164 if (DtAcpiPref.Pref == DT_ACPI_SELECT_ACPI) {\r
165 //\r
166 // ACPI was selected: install the gEdkiiPlatformHasAcpiGuid GUID as a\r
167 // NULL protocol to unlock dispatch of ACPI related drivers.\r
168 //\r
169 Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,\r
170 &gEdkiiPlatformHasAcpiGuid, NULL, NULL);\r
171 if (EFI_ERROR (Status)) {\r
172 DEBUG ((DEBUG_ERROR,\r
173 "%a: failed to install gEdkiiPlatformHasAcpiGuid as a protocol\n",\r
174 __FUNCTION__));\r
175 return Status;\r
176 }\r
177 } else if (DtAcpiPref.Pref == DT_ACPI_SELECT_DT) {\r
178 //\r
179 // DT was selected: copy the blob into newly allocated memory and install\r
180 // a reference to it as the FDT configuration table.\r
181 //\r
182 DtbCopy = AllocateCopyPool (DtbSize, Dtb);\r
183 if (DtbCopy == NULL) {\r
184 return EFI_OUT_OF_RESOURCES;\r
185 }\r
186 Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DtbCopy);\r
187 if (EFI_ERROR (Status)) {\r
188 DEBUG ((DEBUG_ERROR, "%a: failed to install FDT configuration table\n",\r
189 __FUNCTION__));\r
190 FreePool (DtbCopy);\r
191 return Status;\r
192 }\r
193 } else {\r
194 ASSERT (FALSE);\r
195 }\r
196\r
197 //\r
198 // No point in installing the HII pages if ACPI is the only description\r
199 // we have\r
200 //\r
201 if (Dtb == NULL) {\r
202 return EFI_SUCCESS;\r
203 }\r
204\r
205 //\r
206 // Note that we don't uninstall the gEdkiiPlatformHasAcpiGuid protocol nor\r
207 // the FDT configuration table if the following call fails. While that will\r
208 // cause loading of this driver to fail, proceeding with ACPI and DT both\r
209 // disabled will guarantee a failed boot, and so it is better to leave them\r
210 // installed in that case.\r
211 //\r
212 return InstallHiiPages ();\r
213}\r