TianoCore EDK2 master
Loading...
Searching...
No Matches
SpmiGenerator.c
Go to the documentation of this file.
1
13#include <Library/DebugLib.h>
15#include <Protocol/AcpiTable.h>
16
17// Module specific include files.
18#include <AcpiTableGenerator.h>
25
40 );
41
47 );
48
55 ),
63 0x00,
65 0x01,
67 0x0200,
69 0x00,
71 0x00,
73 0x00,
75 0x00,
77 0x00,
79 { 0, 0,0, 0, 0 },
81 {
82 { 0x00 }
83 },
85 0x00
86};
87
110STATIC
112EFIAPI
118 )
119{
120 EFI_STATUS Status;
124
125 ASSERT (This != NULL);
126 ASSERT (AcpiTableInfo != NULL);
127 ASSERT (CfgMgrProtocol != NULL);
128 ASSERT (Table != NULL);
129 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
130 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
131
132 if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
133 (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
134 {
135 DEBUG ((
136 DEBUG_ERROR,
137 "ERROR: SPMI: Requested table revision = %d, is not supported."
138 "Supported table revision: Minimum = %d, Maximum = %d\n",
139 AcpiTableInfo->AcpiTableRevision,
140 This->MinAcpiTableRevision,
141 This->AcpiTableRevision
142 ));
143 return EFI_INVALID_PARAMETER;
144 }
145
146 *Table = NULL;
147
148 Status = GetEArchCommonObjSpmiInterfaceInfo (
149 CfgMgrProtocol,
151 &SpmiInfo,
152 NULL
153 );
154 if (EFI_ERROR (Status)) {
155 DEBUG ((
156 DEBUG_ERROR,
157 "ERROR: SPMI: Failed to retrieve interface type and base address.\n"
158 ));
159 return Status;
160 }
161
164 (SpmiInfo->InterfaceType > EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF))
165 {
166 DEBUG ((
167 DEBUG_ERROR,
168 "ERROR: SPMI: The Interface Type is invalid. Type = %d\n",
169 SpmiInfo->InterfaceType
170 ));
171 return EFI_INVALID_PARAMETER;
172 }
173
175 if ((SpmiInfo->InterfaceType == EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF) &&
176 (SpmiInfo->BaseAddress.AddressSpaceId != EFI_ACPI_6_5_SMBUS))
177 {
178 DEBUG ((
179 DEBUG_ERROR,
180 "ERROR: SPMI: Invalid Address Space ID for SSIF. ID = %d\n",
181 SpmiInfo->BaseAddress.AddressSpaceId
182 ));
183 return EFI_INVALID_PARAMETER;
184 }
185
187 if ((SpmiInfo->InterfaceType != EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF) &&
188 ((SpmiInfo->BaseAddress.AddressSpaceId != EFI_ACPI_6_5_SYSTEM_MEMORY) &&
189 (SpmiInfo->BaseAddress.AddressSpaceId != EFI_ACPI_6_5_SYSTEM_IO)))
190 {
191 DEBUG ((
192 DEBUG_ERROR,
193 "ERROR: SPMI: Invalid Address Space ID. ID = %d\n",
194 SpmiInfo->BaseAddress.AddressSpaceId
195 ));
196 return EFI_INVALID_PARAMETER;
197 }
198
199 Status = GetEArchCommonObjSpmiInterruptDeviceInfo (
200 CfgMgrProtocol,
202 &SpmiIntrDeviceInfo,
203 NULL
204 );
205 if (!EFI_ERROR (Status)) {
207 if ((SpmiIntrDeviceInfo->InterruptType >> 2) != 0 ) {
208 DEBUG ((
209 DEBUG_ERROR,
210 "ERROR: SPMI: The Interrupt Type has non-zero reserved bits. InterruptType = 0x%x\n",
211 SpmiIntrDeviceInfo->InterruptType
212 ));
213 return EFI_INVALID_PARAMETER;
214 }
215
216 if (SpmiInfo->InterfaceType == EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF) {
218 if ((SpmiIntrDeviceInfo->InterruptType & BIT0) != 0) {
219 DEBUG ((
220 DEBUG_ERROR,
221 "ERROR: SPMI: The Interrupt Type bit0 should be zero for SSIF interface type.\n"
222 ));
223 return EFI_INVALID_PARAMETER;
224 }
225
227 if ((SpmiIntrDeviceInfo->PciDeviceFlag & BIT0) != 0) {
228 DEBUG ((
229 DEBUG_ERROR,
230 "ERROR: SPMI: PCI Device Flag is invalid for SSIF interface type.\n"
231 ));
232 return EFI_INVALID_PARAMETER;
233 }
234 }
235
237 if ((SpmiIntrDeviceInfo->Gpe != 0) &&
238 ((SpmiIntrDeviceInfo->InterruptType & BIT0) == 0))
239 {
240 DEBUG ((
241 DEBUG_ERROR,
242 "ERROR: SPMI: The Interrupt Type bit0 should be set if a GPE number is provided.\n"
243 ));
244 return EFI_INVALID_PARAMETER;
245 }
246
248 if ((SpmiIntrDeviceInfo->GlobalSystemInterrupt != 0) &&
249 ((SpmiIntrDeviceInfo->InterruptType & BIT1) == 0))
250 {
251 DEBUG ((
252 DEBUG_ERROR,
253 "ERROR: SPMI: Invalid interrupt type = 0x%x for GSI 0x%x\n",
254 SpmiIntrDeviceInfo->InterruptType,
255 SpmiIntrDeviceInfo->GlobalSystemInterrupt
256 ));
257 return EFI_INVALID_PARAMETER;
258 }
259
260 AcpiSpmi.InterruptType = SpmiIntrDeviceInfo->InterruptType;
261 AcpiSpmi.Gpe = SpmiIntrDeviceInfo->Gpe;
262 AcpiSpmi.PciDeviceFlag = SpmiIntrDeviceInfo->PciDeviceFlag;
263 AcpiSpmi.GlobalSystemInterrupt = SpmiIntrDeviceInfo->GlobalSystemInterrupt;
264 AcpiSpmi.DeviceId.Uid = SpmiIntrDeviceInfo->DeviceId;
265 } else {
266 DEBUG ((
267 DEBUG_INFO,
268 "INFO: SPMI: The platform does not provide interrupt and PCI device information.\n"
269 ));
270 DEBUG ((
271 DEBUG_INFO,
272 "Using default values (0) for the interrupt and PCI device information.\n"
273 ));
274 }
275
277 Status = IpmiGetDeviceId (&DeviceId);
278 if (!EFI_ERROR (Status) && (DeviceId.CompletionCode == IPMI_COMP_CODE_NORMAL)) {
279 AcpiSpmi.SpecificationRevision = DeviceId.SpecificationVersion & 0xF0;
280 AcpiSpmi.SpecificationRevision |= (DeviceId.SpecificationVersion & 0xF) << 8;
281 }
282
283 AcpiSpmi.InterfaceType = SpmiInfo->InterfaceType;
284 CopyMem (
285 &AcpiSpmi.BaseAddress,
286 &SpmiInfo->BaseAddress,
288 );
289
290 Status = AddAcpiHeader (
291 CfgMgrProtocol,
292 This,
293 (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpmi,
294 AcpiTableInfo,
296 );
297 if (EFI_ERROR (Status)) {
298 DEBUG ((
299 DEBUG_ERROR,
300 "ERROR: SPMI: Failed to add ACPI header. Status = %r\n",
301 Status
302 ));
303 }
304
305 *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpmi;
306 return Status;
307}
308
311#define SPMI_GENERATOR_REVISION CREATE_REVISION (1, 0)
312
315STATIC
316CONST
318 // Generator ID
320 // Generator Description
321 L"ACPI.STD.SPMI.GENERATOR",
322 // ACPI Table Signature
324 // ACPI Table Revision supported by this Generator
326 // Minimum supported ACPI Table Revision
328 // Creator ID
330 // Creator Revision
332 // Build Table function
334 // Free Resource function
335 NULL,
336 // Extended build function not needed
337 NULL,
338 // Extended build function not implemented by the generator.
339 // Hence extended free resource function is not required.
340 NULL
341};
342
354EFIAPI
356 IN EFI_HANDLE ImageHandle,
357 IN EFI_SYSTEM_TABLE *SystemTable
358 )
359{
360 EFI_STATUS Status;
361
363 DEBUG ((DEBUG_INFO, "SPMI: Register Generator. Status = %r\n", Status));
364 ASSERT_EFI_ERROR (Status);
365 return Status;
366}
367
378EFIAPI
380 IN EFI_HANDLE ImageHandle,
381 IN EFI_SYSTEM_TABLE *SystemTable
382 )
383{
384 EFI_STATUS Status;
385
387 DEBUG ((DEBUG_INFO, "SPMI: Deregister Generator. Status = %r\n", Status));
388 ASSERT_EFI_ERROR (Status);
389 return Status;
390}
#define EFI_ACPI_6_5_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE
Definition: Acpi65.h:3292
EFI_STATUS EFIAPI RegisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
EFI_STATUS EFIAPI DeregisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId)
#define TABLE_GENERATOR_CREATOR_ID
@ EStdAcpiTableIdSpmi
SPMI Generator.
#define ACPI_HEADER(Signature, Type, Revision)
@ EArchCommonObjSpmiInterfaceInfo
27 - SPMI Interface Info
@ EArchCommonObjSpmiInterruptDeviceInfo
28 - SPMI Interrupt and Device Info
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type)
@ EObjNameSpaceArchCommon
Arch Common Objects Namespace.
EFI_STATUS EFIAPI IpmiGetDeviceId(OUT IPMI_GET_DEVICE_ID_RESPONSE *DeviceId)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_ACPI_SPMI_INTERFACE_TYPE_KCS
#define EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_5_TABLE_REVISION
EFI_STATUS EFIAPI AcpiSpmiLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC CONST ACPI_TABLE_GENERATOR SpmiGenerator
#define SPMI_GENERATOR_REVISION
EFI_STATUS EFIAPI AcpiSpmiLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS EFIAPI BuildSpmiTable(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
#define CM_NULL_TOKEN
EFI_STATUS EFIAPI AddAcpiHeader(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST ACPI_TABLE_GENERATOR *CONST Generator, IN OUT EFI_ACPI_DESCRIPTION_HEADER *CONST AcpiHeader, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST UINT32 Length)
Definition: TableHelper.c:114
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE BaseAddress
EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_TABLE_DEVICE_ID DeviceId