]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
ArmPlatformPkg/ArmJunoDxe: don't register OnEndOfDxe event on rev R0
[mirror_edk2.git] / ArmPlatformPkg / ArmJunoPkg / Drivers / ArmJunoDxe / ArmJunoDxe.c
CommitLineData
9f38945f
OM
1/** @file\r
2*\r
21a76332 3* Copyright (c) 2013-2015, ARM Limited. All rights reserved.\r
9f38945f
OM
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 "ArmJunoDxeInternal.h"\r
c1fee786 16#include <ArmPlatform.h>\r
6d60dfea 17\r
a8675a19 18#include <IndustryStandard/Pci.h>\r
6d60dfea 19#include <Protocol/DevicePathFromText.h>\r
a8675a19 20#include <Protocol/PciIo.h>\r
1bb1f35f 21#include <Protocol/PciRootBridgeIo.h>\r
6d60dfea 22\r
1bb1f35f 23#include <Guid/EventGroup.h>\r
6d60dfea
OM
24#include <Guid/GlobalVariable.h>\r
25\r
9f38945f 26#include <Library/ArmShellCmdLib.h>\r
21a76332 27#include <Library/AcpiLib.h>\r
6d60dfea
OM
28#include <Library/BaseMemoryLib.h>\r
29#include <Library/DevicePathLib.h>\r
30#include <Library/MemoryAllocationLib.h>\r
59a169e8 31#include <Library/NonDiscoverableDeviceRegistrationLib.h>\r
6d60dfea 32#include <Library/UefiRuntimeServicesTableLib.h>\r
c1fee786
RC
33#include <Library/IoLib.h>\r
34#include <Library/PrintLib.h>\r
35\r
c1fee786 36\r
05e56470
OM
37// This GUID must match the FILE_GUID in ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf\r
38STATIC CONST EFI_GUID mJunoAcpiTableFile = { 0xa1dd808e, 0x1e95, 0x4399, { 0xab, 0xc0, 0x65, 0x3c, 0x82, 0xe8, 0x53, 0x0c } };\r
39\r
1bb1f35f
OM
40typedef struct {\r
41 ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
b5ec7f3c 42 PCI_DEVICE_PATH PciDevicePath;\r
1bb1f35f
OM
43 EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
44} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;\r
45\r
46STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciRootComplexDevicePath = {\r
47 {\r
48 { ACPI_DEVICE_PATH,\r
49 ACPI_DP,\r
50 { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\r
51 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) }\r
52 },\r
53 EISA_PNP_ID (0x0A03),\r
54 0\r
55 },\r
b5ec7f3c
OM
56 {\r
57 { HARDWARE_DEVICE_PATH,\r
58 HW_PCI_DP,\r
59 { (UINT8) (sizeof (PCI_DEVICE_PATH)),\r
60 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) }\r
61 },\r
62 0,\r
63 0\r
64 },\r
1bb1f35f
OM
65 {\r
66 END_DEVICE_PATH_TYPE,\r
67 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
68 { END_DEVICE_PATH_LENGTH, 0 }\r
69 }\r
70};\r
71\r
e0ae2761
OM
72EFI_EVENT mAcpiRegistration = NULL;\r
73\r
a8675a19
DE
74/**\r
75 This function reads PCI ID of the controller.\r
76\r
77 @param[in] PciIo PCI IO protocol handle\r
78 @param[in] PciId Looking for specified PCI ID Vendor/Device\r
79**/\r
80STATIC\r
81EFI_STATUS\r
82ReadMarvellYoukonPciId (\r
83 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
84 IN UINT32 PciId\r
85 )\r
86{\r
87 UINT32 DevicePciId;\r
88 EFI_STATUS Status;\r
89\r
90 Status = PciIo->Pci.Read (\r
91 PciIo,\r
92 EfiPciIoWidthUint32,\r
93 PCI_VENDOR_ID_OFFSET,\r
94 1,\r
95 &DevicePciId);\r
96 if (EFI_ERROR (Status)) {\r
97 return Status;\r
98 }\r
99\r
100 if (DevicePciId != PciId) {\r
101 return EFI_NOT_FOUND;\r
102 }\r
103\r
104 return EFI_SUCCESS;\r
105}\r
106\r
107/**\r
108 This function searches for Marvell Yukon NIC on the Juno\r
109 platform and returns PCI IO protocol handle for the controller.\r
110\r
111 @param[out] PciIo PCI IO protocol handle\r
112**/\r
113STATIC\r
114EFI_STATUS\r
115GetMarvellYukonPciIoProtocol (\r
116 OUT EFI_PCI_IO_PROTOCOL **PciIo\r
117 )\r
118{\r
119 UINTN HandleCount;\r
120 EFI_HANDLE *HandleBuffer;\r
121 UINTN HIndex;\r
122 EFI_STATUS Status;\r
123\r
124 Status = gBS->LocateHandleBuffer (\r
125 ByProtocol,\r
126 &gEfiPciIoProtocolGuid,\r
127 NULL,\r
128 &HandleCount,\r
129 &HandleBuffer);\r
130 if (EFI_ERROR (Status)) {\r
131 return (Status);\r
132 }\r
133\r
134 for (HIndex = 0; HIndex < HandleCount; ++HIndex) {\r
135 // If PciIo opened with EFI_OPEN_PROTOCOL_GET_PROTOCOL, the CloseProtocol() is not required\r
136 Status = gBS->OpenProtocol (\r
137 HandleBuffer[HIndex],\r
138 &gEfiPciIoProtocolGuid,\r
139 (VOID **) PciIo,\r
140 NULL,\r
141 NULL,\r
142 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
143 if (EFI_ERROR (Status)) {\r
144 continue;\r
145 }\r
146\r
147 Status = ReadMarvellYoukonPciId (*PciIo, JUNO_MARVELL_YUKON_ID);\r
148 if (EFI_ERROR (Status)) {\r
149 continue;\r
150 } else {\r
151 break;\r
152 }\r
153 }\r
154\r
155 gBS->FreePool (HandleBuffer);\r
156\r
157 return Status;\r
158}\r
159\r
160/**\r
161 This function restore the original controller attributes\r
162\r
163 @param[in] PciIo PCI IO protocol handle\r
164 @param[in] PciAttr PCI controller attributes.\r
165 @param[in] AcpiResDescriptor ACPI 2.0 resource descriptors for the BAR\r
166**/\r
167STATIC\r
168VOID\r
169RestorePciDev (\r
170 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
171 IN UINT64 PciAttr\r
172 )\r
173{\r
174 PciIo->Attributes (\r
175 PciIo,\r
176 EfiPciIoAttributeOperationSet,\r
177 PciAttr,\r
178 NULL\r
179 );\r
180}\r
181\r
182/**\r
183 This function returns PCI MMIO base address for a controller\r
184\r
185 @param[in] PciIo PCI IO protocol handle\r
186 @param[out] PciRegBase PCI base MMIO address\r
187**/\r
188STATIC\r
189EFI_STATUS\r
190BarIsDeviceMemory (\r
191 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
192 OUT UINT32 *PciRegBase\r
193 )\r
194{\r
195 EFI_STATUS Status;\r
196 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AcpiResDescriptor;\r
197 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AcpiCurrentDescriptor;\r
198\r
199 // Marvell Yukon's Bar0 provides base memory address for control registers\r
200 Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX0, NULL, (VOID**)&AcpiResDescriptor);\r
201 if (EFI_ERROR (Status)) {\r
202 return Status;\r
203 }\r
204\r
205 AcpiCurrentDescriptor = AcpiResDescriptor;\r
206\r
207 // Search for a memory type descriptor\r
208 while (AcpiCurrentDescriptor->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
209\r
210 // Check if Bar is memory type one and fetch a base address\r
211 if (AcpiCurrentDescriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR &&\r
212 AcpiCurrentDescriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM &&\r
213 !(AcpiCurrentDescriptor->SpecificFlag & ACPI_SPECFLAG_PREFETCHABLE)) {\r
214 *PciRegBase = AcpiCurrentDescriptor->AddrRangeMin;\r
215 break;\r
216 } else {\r
217 Status = EFI_UNSUPPORTED;\r
218 }\r
219\r
220 AcpiCurrentDescriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (AcpiCurrentDescriptor + 1);\r
221 }\r
222\r
223 gBS->FreePool (AcpiResDescriptor);\r
224\r
225 return Status;\r
226}\r
227\r
228/**\r
229 This function provides PCI MMIO base address, old PCI controller attributes.\r
230\r
231 @param[in] PciIo PCI IO protocol handle\r
232 @param[out] PciRegBase PCI base MMIO address\r
233 @param[out] OldPciAttr Old PCI controller attributes.\r
234**/\r
235STATIC\r
236EFI_STATUS\r
237InitPciDev (\r
238 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
239 OUT UINT32 *PciRegBase,\r
240 OUT UINT64 *OldPciAttr\r
241 )\r
242{\r
243 UINT64 AttrSupports;\r
244 EFI_STATUS Status;\r
245\r
246 // Get controller's current attributes\r
247 Status = PciIo->Attributes (\r
248 PciIo,\r
249 EfiPciIoAttributeOperationGet,\r
250 0,\r
251 OldPciAttr);\r
252 if (EFI_ERROR (Status)) {\r
253 return Status;\r
254 }\r
255\r
256 // Fetch supported attributes\r
257 Status = PciIo->Attributes (\r
258 PciIo,\r
259 EfiPciIoAttributeOperationSupported,\r
260 0,\r
261 &AttrSupports);\r
262 if (EFI_ERROR (Status)) {\r
263 return Status;\r
264 }\r
265\r
266 // Enable EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_MEMORY and\r
267 // EFI_PCI_IO_ATTRIBUTE_BUS_MASTER bits in the PCI Config Header\r
268 AttrSupports &= EFI_PCI_DEVICE_ENABLE;\r
269 Status = PciIo->Attributes (\r
270 PciIo,\r
271 EfiPciIoAttributeOperationEnable,\r
272 AttrSupports,\r
273 NULL);\r
274 if (EFI_ERROR (Status)) {\r
275 return Status;\r
276 }\r
277\r
278 Status = BarIsDeviceMemory (PciIo, PciRegBase);\r
279 if (EFI_ERROR (Status)) {\r
280 RestorePciDev (PciIo, *OldPciAttr);\r
281 }\r
282\r
283 return Status;\r
284}\r
285\r
286/**\r
287 This function reads MAC address from IOFPGA and writes it to Marvell Yukon NIC\r
288\r
289 @param[in] PciRegBase PCI base MMIO address\r
290**/\r
291STATIC\r
292EFI_STATUS\r
293WriteMacAddress (\r
294 IN UINT32 PciRegBase\r
295 )\r
296{\r
297 UINT32 MacHigh;\r
298 UINT32 MacLow;\r
299\r
300 // Read MAC address from IOFPGA\r
301 MacHigh= MmioRead32 (ARM_JUNO_SYS_PCIGBE_H);\r
302 MacLow = MmioRead32 (ARM_JUNO_SYS_PCIGBE_L);\r
303\r
304 // Set software reset control register to protect from deactivation\r
305 // the config write state\r
306 MmioWrite16 (PciRegBase + R_CONTROL_STATUS, CS_RESET_CLR);\r
307\r
308 // Convert to Marvell MAC Address register format\r
309 MacHigh = SwapBytes32 ((MacHigh & 0xFFFF) << 16 |\r
310 (MacLow & 0xFFFF0000) >> 16);\r
311 MacLow = SwapBytes32 (MacLow) >> 16;\r
312\r
313 // Set MAC Address\r
314 MmioWrite8 (PciRegBase + R_TST_CTRL_1, TST_CFG_WRITE_ENABLE);\r
315 MmioWrite32 (PciRegBase + R_MAC, MacHigh);\r
316 MmioWrite32 (PciRegBase + R_MAC_MAINT, MacHigh);\r
317 MmioWrite32 (PciRegBase + R_MAC + R_MAC_LOW, MacLow);\r
318 MmioWrite32 (PciRegBase + R_MAC_MAINT + R_MAC_LOW, MacLow);\r
319 MmioWrite8 (PciRegBase + R_TST_CTRL_1, TST_CFG_WRITE_DISABLE);\r
320\r
321 // Initiate device reset\r
322 MmioWrite16 (PciRegBase + R_CONTROL_STATUS, CS_RESET_SET);\r
323 MmioWrite16 (PciRegBase + R_CONTROL_STATUS, CS_RESET_CLR);\r
324\r
325 return EFI_SUCCESS;\r
326}\r
327\r
328/**\r
329 The function reads MAC address from Juno IOFPGA registers and writes it\r
330 into Marvell Yukon NIC.\r
331**/\r
332STATIC\r
333EFI_STATUS\r
334ArmJunoSetNicMacAddress ()\r
335{\r
336 UINT64 OldPciAttr;\r
337 EFI_PCI_IO_PROTOCOL* PciIo;\r
338 UINT32 PciRegBase;\r
339 EFI_STATUS Status;\r
340\r
341 Status = GetMarvellYukonPciIoProtocol (&PciIo);\r
342 if (EFI_ERROR (Status)) {\r
343 return Status;\r
344 }\r
345\r
346 Status = InitPciDev (PciIo, &PciRegBase, &OldPciAttr);\r
347 if (EFI_ERROR (Status)) {\r
348 return Status;\r
349 }\r
350\r
351 Status = WriteMacAddress (PciRegBase);\r
352\r
353 RestorePciDev (PciIo, OldPciAttr);\r
354\r
355 return EFI_SUCCESS;\r
356}\r
357\r
1bb1f35f
OM
358/**\r
359 Notification function of the event defined as belonging to the\r
360 EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in\r
361 the entry point of the driver.\r
362\r
363 This function is called when an event belonging to the\r
364 EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an\r
365 event is signalled once at the end of the dispatching of all\r
366 drivers (end of the so called DXE phase).\r
367\r
368 @param[in] Event Event declared in the entry point of the driver whose\r
369 notification function is being invoked.\r
370 @param[in] Context NULL\r
371**/\r
372STATIC\r
373VOID\r
374OnEndOfDxe (\r
375 IN EFI_EVENT Event,\r
376 IN VOID *Context\r
377 )\r
378{\r
379 EFI_DEVICE_PATH_PROTOCOL* PciRootComplexDevicePath;\r
380 EFI_HANDLE Handle;\r
381 EFI_STATUS Status;\r
382\r
383 //\r
384 // PCI Root Complex initialization\r
385 // At the end of the DXE phase, we should get all the driver dispatched.\r
386 // Force the PCI Root Complex to be initialized. It allows the OS to skip\r
387 // this step.\r
388 //\r
389 PciRootComplexDevicePath = (EFI_DEVICE_PATH_PROTOCOL*) &mPciRootComplexDevicePath;\r
390 Status = gBS->LocateDevicePath (&gEfiPciRootBridgeIoProtocolGuid,\r
391 &PciRootComplexDevicePath,\r
392 &Handle);\r
393\r
394 Status = gBS->ConnectController (Handle, NULL, PciRootComplexDevicePath, FALSE);\r
395 ASSERT_EFI_ERROR (Status);\r
a8675a19 396\r
4f869acc
AB
397 Status = ArmJunoSetNicMacAddress ();\r
398 if (EFI_ERROR (Status)) {\r
399 DEBUG ((DEBUG_ERROR, "ArmJunoDxe: Failed to set Marvell Yukon NIC MAC address\n"));\r
2bdfb11d 400 }\r
1bb1f35f
OM
401}\r
402\r
e0ae2761
OM
403STATIC\r
404BOOLEAN\r
405AcpiTableJunoR0Check (\r
406 IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
407 )\r
408{\r
409 return TRUE;\r
410}\r
411\r
412STATIC\r
413BOOLEAN\r
414AcpiTableJunoR1Check (\r
415 IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
416 )\r
417{\r
418 return TRUE;\r
419}\r
420\r
58a4bff0
JL
421STATIC\r
422BOOLEAN\r
423AcpiTableJunoR2Check (\r
424 IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
425 )\r
426{\r
427 return TRUE;\r
428}\r
429\r
430\r
9f38945f
OM
431EFI_STATUS\r
432EFIAPI\r
433ArmJunoEntryPoint (\r
434 IN EFI_HANDLE ImageHandle,\r
435 IN EFI_SYSTEM_TABLE *SystemTable\r
436 )\r
437{\r
7aec2926
RC
438 EFI_STATUS Status;\r
439 EFI_PHYSICAL_ADDRESS HypBase;\r
440 CHAR16 *TextDevicePath;\r
441 UINTN TextDevicePathSize;\r
442 VOID *Buffer;\r
58a4bff0 443 UINT32 JunoRevision;\r
30cfc3d0 444 EFI_EVENT EndOfDxeEvent;\r
9f38945f 445\r
59a169e8
AB
446 //\r
447 // Register the OHCI and EHCI controllers as non-coherent\r
448 // non-discoverable devices.\r
449 //\r
450 Status = RegisterNonDiscoverableMmioDevice (\r
451 NonDiscoverableDeviceTypeOhci,\r
452 NonDiscoverableDeviceDmaTypeNonCoherent,\r
453 NULL,\r
454 NULL,\r
455 1,\r
456 FixedPcdGet32 (PcdSynopsysUsbOhciBaseAddress),\r
457 SIZE_64KB\r
458 );\r
459 ASSERT_EFI_ERROR (Status);\r
460\r
461 Status = RegisterNonDiscoverableMmioDevice (\r
462 NonDiscoverableDeviceTypeEhci,\r
463 NonDiscoverableDeviceDmaTypeNonCoherent,\r
464 NULL,\r
465 NULL,\r
466 1,\r
467 FixedPcdGet32 (PcdSynopsysUsbEhciBaseAddress),\r
468 SIZE_64KB\r
469 );\r
470 ASSERT_EFI_ERROR (Status);\r
9f38945f
OM
471\r
472 //\r
473 // If a hypervisor has been declared then we need to make sure its region is protected at runtime\r
474 //\r
475 // Note: This code is only a workaround for our dummy hypervisor (ArmPkg/Extra/AArch64ToAArch32Shim/)\r
476 // that does not set up (yet) the stage 2 translation table to hide its own memory to EL1.\r
477 //\r
478 if (FixedPcdGet32 (PcdHypFvSize) != 0) {\r
479 // Ensure the hypervisor region is strictly contained into a EFI_PAGE_SIZE-aligned region.\r
480 // The memory must be a multiple of EFI_PAGE_SIZE to ensure we do not reserve more memory than the hypervisor itself.\r
481 // A UEFI Runtime region size granularity cannot be smaller than EFI_PAGE_SIZE. If the hypervisor size is not rounded\r
482 // to this size then there is a risk some non-runtime memory could be visible to the OS view.\r
483 if (((FixedPcdGet32 (PcdHypFvSize) & EFI_PAGE_MASK) == 0) && ((FixedPcdGet32 (PcdHypFvBaseAddress) & EFI_PAGE_MASK) == 0)) {\r
484 // The memory needs to be declared because the DXE core marked it as reserved and removed it from the memory space\r
485 // as it contains the Firmware.\r
486 Status = gDS->AddMemorySpace (\r
487 EfiGcdMemoryTypeSystemMemory,\r
488 FixedPcdGet32 (PcdHypFvBaseAddress), FixedPcdGet32 (PcdHypFvSize),\r
489 EFI_MEMORY_WB | EFI_MEMORY_RUNTIME\r
490 );\r
491 if (!EFI_ERROR (Status)) {\r
492 // We allocate the memory to ensure it is marked as runtime memory\r
493 HypBase = FixedPcdGet32 (PcdHypFvBaseAddress);\r
494 Status = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode,\r
495 EFI_SIZE_TO_PAGES (FixedPcdGet32 (PcdHypFvSize)), &HypBase);\r
496 }\r
497 } else {\r
498 // The hypervisor must be contained into a EFI_PAGE_SIZE-aligned region and its size must also be aligned\r
499 // on a EFI_PAGE_SIZE boundary (ie: 4KB).\r
500 Status = EFI_UNSUPPORTED;\r
501 ASSERT_EFI_ERROR (Status);\r
502 }\r
503\r
504 if (EFI_ERROR (Status)) {\r
505 return Status;\r
506 }\r
507 }\r
508\r
509 // Install dynamic Shell command to run baremetal binaries.\r
510 Status = ShellDynCmdRunAxfInstall (ImageHandle);\r
511 if (EFI_ERROR (Status)) {\r
512 DEBUG ((EFI_D_ERROR, "ArmJunoDxe: Failed to install ShellDynCmdRunAxf\n"));\r
513 }\r
514\r
58a4bff0 515 GetJunoRevision(JunoRevision);\r
c1fee786
RC
516\r
517 //\r
e0ae2761 518 // Try to install the ACPI Tables\r
c1fee786 519 //\r
58a4bff0 520 if (JunoRevision == JUNO_REVISION_R0) {\r
e0ae2761 521 Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR0Check);\r
58a4bff0 522 } else if (JunoRevision == JUNO_REVISION_R1) {\r
e0ae2761 523 Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR1Check);\r
58a4bff0
JL
524 } else if (JunoRevision == JUNO_REVISION_R2) {\r
525 Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR2Check);\r
e0ae2761 526 }\r
e0ae2761 527\r
58a4bff0 528 ASSERT_EFI_ERROR (Status);\r
c1fee786 529\r
e0ae2761 530 //\r
58a4bff0 531 // Setup R1/R2 options if not already done.\r
e0ae2761 532 //\r
58a4bff0 533 if (JunoRevision != JUNO_REVISION_R0) {\r
ad7d95ea
OM
534 // Enable PCI enumeration\r
535 PcdSetBool (PcdPciDisableBusEnumeration, FALSE);\r
e0ae2761 536\r
4f869acc
AB
537 //\r
538 // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.\r
539 // The "OnEndOfDxe()" function is declared as the call back function.\r
540 // It will be called at the end of the DXE phase when an event of the\r
541 // same group is signalled to inform about the end of the DXE phase.\r
542 // Install the INSTALL_FDT_PROTOCOL protocol.\r
543 //\r
544 Status = gBS->CreateEventEx (\r
545 EVT_NOTIFY_SIGNAL,\r
546 TPL_CALLBACK,\r
547 OnEndOfDxe,\r
548 NULL,\r
549 &gEfiEndOfDxeEventGroupGuid,\r
550 &EndOfDxeEvent\r
551 );\r
552\r
e0ae2761
OM
553 // Declare the related ACPI Tables\r
554 EfiCreateProtocolNotifyEvent (\r
555 &gEfiAcpiTableProtocolGuid,\r
556 TPL_CALLBACK,\r
557 AcpiPciNotificationEvent,\r
558 NULL,\r
559 &mAcpiRegistration\r
560 );\r
7aec2926
RC
561 }\r
562\r
c1fee786
RC
563 //\r
564 // Set up the device path to the FDT.\r
565 //\r
1f40f535 566 TextDevicePath = (CHAR16*)FixedPcdGetPtr (PcdJunoFdtDevicePath);\r
7aec2926
RC
567 if (TextDevicePath != NULL) {\r
568 TextDevicePathSize = StrSize (TextDevicePath);\r
569 Buffer = PcdSetPtr (PcdFdtDevicePaths, &TextDevicePathSize, TextDevicePath);\r
570 Status = (Buffer != NULL) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
571 } else {\r
572 Status = EFI_NOT_FOUND;\r
573 }\r
574\r
05e56470 575 if (EFI_ERROR (Status)) {\r
7aec2926
RC
576 DEBUG (\r
577 (EFI_D_ERROR,\r
578 "ArmJunoDxe: Setting of FDT device path in PcdFdtDevicePaths failed - %r\n", Status)\r
579 );\r
05e56470
OM
580 return Status;\r
581 }\r
21a76332 582\r
c1fee786
RC
583 return Status;\r
584}\r