hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/** @file
  A Library to support all BMC access via IPMI command during SMM Phase.
 
  @copyright
  Copyright 1999 - 2021 Intel Corporation. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include <PiDxe.h>
#include <Protocol/IpmiTransportProtocol.h>
#include <Library/IpmiBaseLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/DebugLib.h>
 
STATIC IPMI_TRANSPORT     *mIpmiTransport = NULL;
VOID                      *mEfiIpmiProtocolNotifyReg = NULL;
EFI_EVENT                 mEfiIpmiProtocolEvent;
 
/**
  Callback function for locating the IpmiTransport protocol.
 
  @param Protocol     A pointer to EFI_GUID
  @param Interface    A pointer to Interface
  @param Handle       Handle
 
  @retval EFI_SUCCESS:               Callback successfully
 
**/
EFI_STATUS
NotifyIpmiTransportCallback (
  IN CONST EFI_GUID                *Protocol,
  IN VOID                          *Interface,
  IN EFI_HANDLE                    Handle
  )
{
  EFI_STATUS  Status;
  Status = EFI_SUCCESS;
  if (mIpmiTransport == NULL) {
    Status = gSmst->SmmLocateProtocol (
                      &gSmmIpmiTransportProtocolGuid,
                      NULL,
                      (VOID **) &mIpmiTransport
                      );
  }
 
  return Status;
}
 
/**
  Routine to send commands to BMC.
 
  @retval EFI_SUCCESS:        Always return success
 
**/
EFI_STATUS
InitializeIpmiBase (
  VOID
  )
{
  EFI_STATUS  Status;
  if (mIpmiTransport == NULL) {
    Status = gSmst->SmmLocateProtocol (
                      &gSmmIpmiTransportProtocolGuid,
                      NULL,
                      (VOID **) &mIpmiTransport
                      );
    if (EFI_ERROR (Status)) {
      Status = gSmst->SmmRegisterProtocolNotify (
                        &gSmmIpmiTransportProtocolGuid,
                        (EFI_SMM_NOTIFY_FN) NotifyIpmiTransportCallback,
                        &mEfiIpmiProtocolNotifyReg
                        );
    }
    ASSERT_EFI_ERROR (Status);
    if (Status != EFI_SUCCESS) {
      return Status;
    }
  }
 
  return EFI_SUCCESS;
}
 
/**
  Routine to send commands to BMC.
 
  @param NetFunction       - Net function of the command
  @param Command           - IPMI Command
  @param CommandData       - Command Data
  @param CommandDataSize   - Size of CommandData
  @param ResponseData      - Response Data
  @param ResponseDataSize  - Response Data Size
 
  @retval EFI_SUCCESS:               Get successfully
  @retval EFI_NOT_AVAILABLE_YET
 
**/
EFI_STATUS
IpmiSubmitCommand (
  IN UINT8        NetFunction,
  IN UINT8        Command,
  IN UINT8        *CommandData,
  IN UINT32       CommandDataSize,
  OUT UINT8       *ResponseData,
  IN OUT UINT32   *ResponseDataSize
  )
/*++
 
Routine Description:
 
  Routine to send commands to BMC
 
Arguments:
 
  NetFunction       - Net function of the command
  Command           - IPMI Command
  CommandData       - Command Data
  CommandDataSize   - Size of CommandData
  ResponseData      - Response Data
  ResponseDataSize  - Response Data Size
 
Returns:
 
  EFI_NOT_AVAILABLE_YET - IpmiTransport Protocol is not installed yet
 
--*/
{
  EFI_STATUS  Status;
 
  Status = gSmst->SmmLocateProtocol (&gSmmIpmiTransportProtocolGuid, NULL, (VOID **) &mIpmiTransport);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }
 
  Status = mIpmiTransport->IpmiSubmitCommand (
                             mIpmiTransport,
                             NetFunction,
                             0,
                             Command,
                             CommandData,
                             CommandDataSize,
                             ResponseData,
                             ResponseDataSize
                             );
  return Status;
}
 
/**
  Routine to send commands to BMC.
 
  @param BmcStatus                   The ConnectAllComplete EFI Event.
  @param ComAddress                  Event context pass to create function
 
  @retval EFI_SUCCESS:               Get successfully
  @retval EFI_NOT_AVAILABLE_YET
 
**/
EFI_STATUS
GetBmcStatus (
  OUT BMC_STATUS                       *BmcStatus,
  OUT SM_COM_ADDRESS                   *ComAddress
  )
{
  EFI_STATUS  Status;
 
  Status = gSmst->SmmLocateProtocol (&gSmmIpmiTransportProtocolGuid, NULL, (VOID **) &mIpmiTransport);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }
 
  Status = mIpmiTransport->GetBmcStatus (
                             mIpmiTransport,
                             BmcStatus,
                             ComAddress
                             );
  return Status;
}