FdtDxe.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /** @file
  2. RISC-V Flattened Device Tree DXE module
  3. The Linux booting protocol on RISC-V requires the id of the booting hart to
  4. be passed as a0. Therefore the EFISTUB needs to get this information. Because
  5. it runs in S-Mode, it cannot get this information from mhartid. Instead we
  6. insert the id into the device tree, that the EFIFSTUB can read from the config table.
  7. Copyright (c) 2021-2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
  8. SPDX-License-Identifier: BSD-2-Clause-Patent
  9. **/
  10. #include <Library/UefiBootServicesTableLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/HobLib.h>
  13. #include <Library/BaseMemoryLib.h>
  14. #include <Library/PcdLib.h>
  15. #include <libfdt.h>
  16. /**
  17. Fix up the device tree with booting hartid for the kernel
  18. @param DtbBlob The device tree. Is extended to fit the hart id.
  19. @param BootingHartId The boot hart ID.
  20. @retval EFI_SUCCESS The device tree was success fixed up with the hart id.
  21. @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation.
  22. **/
  23. EFI_STATUS
  24. EFIAPI
  25. FixDtb (
  26. IN OUT VOID *DtbBlob,
  27. IN UINTN BootingHartId
  28. )
  29. {
  30. fdt32_t Size;
  31. UINT32 ChosenOffset, Err;
  32. DEBUG ((
  33. DEBUG_INFO,
  34. "Fixing up device tree with boot hart id: %d\n",
  35. BootingHartId
  36. ));
  37. Size = fdt_totalsize (DtbBlob);
  38. Err = fdt_open_into (DtbBlob, DtbBlob, Size + 32);
  39. if (Err < 0) {
  40. DEBUG ((
  41. DEBUG_ERROR,
  42. "Device Tree can't be expanded to accommodate new node\n",
  43. __FUNCTION__
  44. ));
  45. return EFI_OUT_OF_RESOURCES;
  46. }
  47. ChosenOffset = fdt_path_offset (DtbBlob, "/chosen");
  48. fdt_setprop_u32 (DtbBlob, ChosenOffset, "boot-hartid", BootingHartId);
  49. return EFI_SUCCESS;
  50. }
  51. /**
  52. Install the FDT passed in HOB into EFI system configuration table.
  53. @retval EFI_SUCCESS Successfully installed fixed up FDT in config table.
  54. @retval EFI_NOT_FOUND Did not find FDT HOB.
  55. @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation.
  56. **/
  57. EFI_STATUS
  58. EFIAPI
  59. InstallFdtFromHob (
  60. VOID
  61. )
  62. {
  63. EFI_STATUS Status;
  64. EFI_HOB_GUID_TYPE *GuidHob;
  65. VOID *DataInHob;
  66. UINTN DataSize;
  67. GuidHob = GetFirstGuidHob (&gFdtHobGuid);
  68. if (GuidHob == NULL) {
  69. DEBUG ((
  70. DEBUG_ERROR,
  71. "Failed to find RISC-V DTB Hob\n",
  72. __FUNCTION__
  73. ));
  74. return EFI_NOT_FOUND;
  75. }
  76. DataInHob = (VOID *)*((UINTN *)GET_GUID_HOB_DATA (GuidHob));
  77. DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
  78. Status = FixDtb (DataInHob, PcdGet32 (PcdBootHartId));
  79. if (EFI_ERROR (Status)) {
  80. return Status;
  81. }
  82. Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DataInHob);
  83. if (EFI_ERROR (Status)) {
  84. DEBUG ((
  85. DEBUG_ERROR,
  86. "%a: failed to install FDT configuration table\n",
  87. __FUNCTION__
  88. ));
  89. }
  90. return Status;
  91. }
  92. /**
  93. Install the FDT from the HOB into the EFI system configuration table.
  94. @param ImageHandle Image handle of this driver.
  95. @param SystemTable Pointer to the System Table.
  96. @retval EFI_SUCCESS FDT successfully installed into config table.
  97. @retval EFI_NOT_FOUND Did not find FDT HOB.
  98. @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation.
  99. **/
  100. EFI_STATUS
  101. EFIAPI
  102. InstallFdt (
  103. IN EFI_HANDLE ImageHandle,
  104. IN EFI_SYSTEM_TABLE *SystemTable
  105. )
  106. {
  107. EFI_STATUS Status;
  108. Status = InstallFdtFromHob ();
  109. return Status;
  110. }