IpmiPpi.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /** @file
  2. This file provides IPMI PPI implementation.
  3. Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <PiPei.h>
  7. #include <Library/DebugLib.h>
  8. #include <Library/BaseMemoryLib.h>
  9. #include <Library/MemoryAllocationLib.h>
  10. #include <Library/ManageabilityTransportLib.h>
  11. #include <Library/ManageabilityTransportIpmiLib.h>
  12. #include <Library/ManageabilityTransportHelperLib.h>
  13. #include <Library/PeiServicesLib.h>
  14. #include <Ppi/IpmiPpi.h>
  15. #include "IpmiProtocolCommon.h"
  16. #include "IpmiPpiInternal.h"
  17. /**
  18. This service enables submitting commands via Ipmi.
  19. @param[in] This This point for PEI_IPMI_PPI structure.
  20. @param[in] NetFunction Net function of the command.
  21. @param[in] Command IPMI Command.
  22. @param[in] RequestData Command Request Data.
  23. @param[in] RequestDataSize Size of Command Request Data.
  24. @param[out] ResponseData Command Response Data. The completion code is the first byte of response data.
  25. @param[in, out] ResponseDataSize Size of Command Response Data.
  26. @retval EFI_SUCCESS The command byte stream was successfully submit to the device and a response was successfully received.
  27. @retval EFI_NOT_FOUND The command was not successfully sent to the device or a response was not successfully received from the device.
  28. @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi command access.
  29. @retval EFI_DEVICE_ERROR Ipmi Device hardware error.
  30. @retval EFI_TIMEOUT The command time out.
  31. @retval EFI_UNSUPPORTED The command was not successfully sent to the device.
  32. @retval EFI_OUT_OF_RESOURCES The resource allocation is out of resource or data size error.
  33. **/
  34. EFI_STATUS
  35. EFIAPI
  36. PeiIpmiSubmitCommand (
  37. IN PEI_IPMI_PPI *This,
  38. IN UINT8 NetFunction,
  39. IN UINT8 Command,
  40. IN UINT8 *RequestData,
  41. IN UINT32 RequestDataSize,
  42. OUT UINT8 *ResponseData,
  43. IN OUT UINT32 *ResponseDataSize
  44. )
  45. {
  46. EFI_STATUS Status;
  47. PEI_IPMI_PPI_INTERNAL *PeiIpmiPpiinternal;
  48. PeiIpmiPpiinternal = MANAGEABILITY_IPMI_PPI_INTERNAL_FROM_LINK(This);
  49. Status = CommonIpmiSubmitCommand (
  50. PeiIpmiPpiinternal->TransportToken,
  51. NetFunction,
  52. Command,
  53. RequestData,
  54. RequestDataSize,
  55. ResponseData,
  56. ResponseDataSize
  57. );
  58. return Status;
  59. }
  60. /**
  61. The entry point of the Ipmi PPI PEIM.
  62. @param FileHandle Handle of the file being invoked.
  63. @param PeiServices Describes the list of possible PEI Services.
  64. @retval EFI_SUCCESS Indicates that Ipmi initialization completed successfully.
  65. @retval Others Indicates that Ipmi initialization could not complete successfully.
  66. **/
  67. EFI_STATUS
  68. EFIAPI
  69. PeiIpmiEntry (
  70. IN EFI_PEI_FILE_HANDLE FileHandle,
  71. IN CONST EFI_PEI_SERVICES **PeiServices
  72. )
  73. {
  74. EFI_STATUS Status;
  75. CHAR16 *TransportName;
  76. PEI_IPMI_PPI_INTERNAL *PeiIpmiPpiinternal;
  77. EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
  78. MANAGEABILITY_TRANSPORT_CAPABILITY TransportCapability;
  79. MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS TransportAdditionalStatus;
  80. MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION HardwareInformation;
  81. PeiIpmiPpiinternal = (PEI_IPMI_PPI_INTERNAL *)AllocateZeroPool (sizeof(PEI_IPMI_PPI_INTERNAL));
  82. if (PeiIpmiPpiinternal == NULL) {
  83. DEBUG ((DEBUG_ERROR, "%a: Not enough memory for PEI_IPMI_PPI_INTERNAL.\n", __FUNCTION__));
  84. return EFI_OUT_OF_RESOURCES;
  85. }
  86. PpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)AllocateZeroPool (sizeof(EFI_PEI_PPI_DESCRIPTOR));
  87. if (PpiDescriptor == NULL) {
  88. DEBUG ((DEBUG_ERROR, "%a: Not enough memory for EFI_PEI_PPI_DESCRIPTOR.\n", __FUNCTION__));
  89. return EFI_OUT_OF_RESOURCES;
  90. }
  91. PeiIpmiPpiinternal->Signature = MANAGEABILITY_IPMI_PPI_INTERNAL_SIGNATURE;
  92. PeiIpmiPpiinternal->PeiIpmiPpi.IpmiSubmitCommand = PeiIpmiSubmitCommand;
  93. PpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  94. PpiDescriptor->Guid = &gPeiIpmiPpiGuid;
  95. PpiDescriptor->Ppi = &PeiIpmiPpiinternal->PeiIpmiPpi;
  96. GetTransportCapability (&TransportCapability);
  97. Status = HelperAcquireManageabilityTransport (
  98. &gManageabilityProtocolIpmiGuid,
  99. &PeiIpmiPpiinternal->TransportToken
  100. );
  101. if (EFI_ERROR (Status)) {
  102. DEBUG ((DEBUG_ERROR, "%a: Failed to acquire transport interface for IPMI protocol - %r\n", __FUNCTION__, Status));
  103. return Status;
  104. }
  105. TransportName = HelperManageabilitySpecName (PeiIpmiPpiinternal->TransportToken->Transport->ManageabilityTransportSpecification);
  106. DEBUG ((DEBUG_INFO, "%a: IPMI protocol over %s.\n", __FUNCTION__, TransportName));
  107. //
  108. // Setup hardware information according to the transport interface.
  109. Status = SetupIpmiTransportHardwareInformation (
  110. PeiIpmiPpiinternal->TransportToken,
  111. &HardwareInformation
  112. );
  113. if (EFI_ERROR (Status)) {
  114. if (Status == EFI_UNSUPPORTED) {
  115. DEBUG ((DEBUG_ERROR, "%a: No hardware information of %s transport interface.\n", __FUNCTION__, TransportName));
  116. }
  117. return Status;
  118. }
  119. //
  120. // Initial transport interface with the hardware information assigned.
  121. Status = HelperInitManageabilityTransport (
  122. PeiIpmiPpiinternal->TransportToken,
  123. HardwareInformation,
  124. &TransportAdditionalStatus
  125. );
  126. if (EFI_ERROR (Status)) {
  127. return Status;
  128. }
  129. //
  130. // Install IPMI PPI.
  131. //
  132. Status = PeiServicesInstallPpi (PpiDescriptor);
  133. if (EFI_ERROR (Status)) {
  134. DEBUG ((DEBUG_ERROR, "%a: Failed to install IPMI PPI - %r\n", __FUNCTION__, Status));
  135. }
  136. return Status;
  137. }