OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
SmbiosPatch.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
17#include <Protocol/PciRootBridgeIo.h>
18
19#include <Guid/AppleVariable.h>
20#include <Guid/OcVariable.h>
21#include <Guid/SmBios.h>
22
23#include <Library/BaseMemoryLib.h>
24#include <Library/BaseOverflowLib.h>
25#include <Library/DebugLib.h>
26#include <Library/MemoryAllocationLib.h>
27#include <Library/OcCpuLib.h>
28#include <Library/OcSmbiosLib.h>
29#include <Library/OcMemoryLib.h>
30#include <Library/OcMiscLib.h>
31#include <Library/OcFileLib.h>
32#include <Library/OcStringLib.h>
34#include <Library/UefiLib.h>
35#include <Library/UefiBootServicesTableLib.h>
36#include <Library/UefiRuntimeServicesTableLib.h>
37
39#include <IndustryStandard/Pci.h>
40
41#include "DebugSmbios.h"
42#include "SmbiosInternal.h"
43
45
46STATIC SMBIOS_TABLE_ENTRY_POINT *mOriginalSmbios;
47STATIC SMBIOS_TABLE_3_0_ENTRY_POINT *mOriginalSmbios3;
49STATIC UINT32 mOriginalTableSize;
50
51#define SMBIOS_OVERRIDE_S(Table, Field, Original, Value, Index, Fallback) \
52 do { \
53 CONST CHAR8 *RealValue__ = (Value); \
54 if (RealValue__ == NULL && ((Original).Raw) != NULL && (Original).Raw + (Original).Standard.Hdr->Length \
55 >= ((UINT8 *)&((Original).Field) + sizeof (SMBIOS_TABLE_STRING))) { \
56 RealValue__ = SmbiosGetString ((Original), ((Original).Field)); \
57 } \
58 (((Table)->CurrentPtr).Field) = SmbiosOverrideString ( \
59 (Table), \
60 RealValue__ != NULL ? RealValue__ : (Fallback), \
61 (Index) \
62 ); \
63 } while (0)
64
65#define SMBIOS_OVERRIDE_V(Table, Field, Original, Value, Fallback) \
66 do { \
67 if ((Value) != NULL) { \
68 CopyMem (&(((Table)->CurrentPtr).Field), (Value), sizeof ((((Table)->CurrentPtr).Field))); \
69 } else if ((Original).Raw != NULL && (Original).Raw + (Original).Standard.Hdr->Length \
70 >= ((UINT8 *)&((Original).Field) + sizeof ((((Table)->CurrentPtr).Field)))) { \
71 CopyMem (&(((Table)->CurrentPtr).Field), &((Original).Field), sizeof ((((Table)->CurrentPtr).Field))); \
72 } else if ((Fallback) != NULL) { \
73 CopyMem (&(((Table)->CurrentPtr).Field), (Fallback), sizeof ((((Table)->CurrentPtr).Field))); \
74 } else { \
75 /* No ZeroMem call as written area is guaranteed to be 0 */ \
76 } \
77 } while (0)
78
79#define SMBIOS_ACCESSIBLE(Table, Field) \
80 (((UINT8 *) &(Table).Field - (Table).Raw + sizeof ((Table).Field)) <= (Table).Standard.Hdr->Length)
81
82STATIC
85 IN SMBIOS_TYPE Type,
86 IN UINT16 Index
87 )
88{
89 if (mOriginalTable.Raw == NULL) {
90 return mOriginalTable;
91 }
92
94}
95
96STATIC
97UINT16
99 IN SMBIOS_TYPE Type
100 )
101{
102 if (mOriginalTable.Raw == NULL) {
103 return 0;
104 }
105
107}
108
109STATIC
110BOOLEAN
113 )
114{
115 return Original.Raw != NULL
116 && SMBIOS_ACCESSIBLE (Original, Standard.Type17->FormFactor)
117 && Original.Standard.Type17->FormFactor != 0;
118}
119
120STATIC
121UINT8
123 IN OC_SMBIOS_DATA *Data,
125 )
126{
127 BOOLEAN IsAutomatic;
128
129 IsAutomatic = !Data->ForceMemoryFormFactor;
130
131 if (IsAutomatic) {
132 //
133 // Try to use the original value if valid first.
134 //
135 if (SmbiosHasValidOemFormFactor (Original)) {
136 return Original.Standard.Type17->FormFactor;
137 }
138
139 //
140 // If not, use the value from database.
141 //
142 if (Data->MemoryFormFactor != NULL) {
143 return *Data->MemoryFormFactor;
144 }
145 }
146
147 //
148 // Under non-Automatic mode, simply use the value from config.
149 //
150 if (Data->MemoryFormFactor != NULL) {
151 return *Data->MemoryFormFactor;
152 }
153
154 //
155 // If the value is not available from config, then try to use the original value.
156 //
157 if (SmbiosHasValidOemFormFactor (Original)) {
158 return Original.Standard.Type17->FormFactor;
159 }
160
161 //
162 // If not valid at all, fall back on the failsafe.
163 //
164 return MemoryFormFactorUnknown;
165}
166
175STATIC
176BOOLEAN
178 IN OUT OC_SMBIOS_TABLE *Table,
179 IN OC_SMBIOS_DATA *Data
180 )
181{
183 UINT8 MinLength;
184 UINT8 StringIndex;
185 CHAR8 *Vendor;
186 BOOLEAN IsApple;
187
188 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BIOS_INFORMATION, 1);
189 MinLength = sizeof (*Original.Standard.Type0);
190 StringIndex = 0;
191
192 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_BIOS_INFORMATION, MinLength, 1))) {
193 return FALSE;
194 }
195
196 SMBIOS_OVERRIDE_S (Table, Standard.Type0->Vendor, Original, Data->BIOSVendor, &StringIndex, NULL);
197 SMBIOS_OVERRIDE_S (Table, Standard.Type0->BiosVersion, Original, Data->BIOSVersion, &StringIndex, NULL);
198 //
199 // Leave BiosSegment as 0 to ensure checks for IODeviceTree:/rom@0 or IODeviceTree:/rom@e0000 are met.
200 //
201 SMBIOS_OVERRIDE_S (Table, Standard.Type0->BiosReleaseDate, Original, Data->BIOSReleaseDate, &StringIndex, NULL);
202 SMBIOS_OVERRIDE_V (Table, Standard.Type0->BiosSize, Original, NULL, NULL);
203 SMBIOS_OVERRIDE_V (Table, Standard.Type0->BiosCharacteristics, Original, NULL, NULL);
204 SMBIOS_OVERRIDE_V (Table, Standard.Type0->BIOSCharacteristicsExtensionBytes, Original, NULL, NULL);
205 SMBIOS_OVERRIDE_V (Table, Standard.Type0->SystemBiosMajorRelease, Original, NULL, NULL);
206 SMBIOS_OVERRIDE_V (Table, Standard.Type0->SystemBiosMinorRelease, Original, NULL, NULL);
207 SMBIOS_OVERRIDE_V (Table, Standard.Type0->EmbeddedControllerFirmwareMajorRelease, Original, NULL, NULL);
208 SMBIOS_OVERRIDE_V (Table, Standard.Type0->EmbeddedControllerFirmwareMinorRelease, Original, NULL, NULL);
209
210 IsApple = FALSE;
211
212 Vendor = SmbiosGetString (Table->CurrentPtr, (Table->CurrentPtr).Standard.Type0->Vendor);
213
214 if ((Vendor != NULL) && (AsciiStrStr (Vendor, "Apple") != NULL)) {
215 IsApple = TRUE;
216 }
217
218 DEBUG ((DEBUG_INFO, "OCSMB: Post-override BIOS vendor %a %d\n", Vendor, IsApple));
219
220 SmbiosFinaliseStruct (Table);
221
222 return IsApple;
223}
224
230STATIC
231VOID
233 IN OUT OC_SMBIOS_TABLE *Table,
234 IN OC_SMBIOS_DATA *Data
235 )
236{
238 UINT8 MinLength;
239 UINT8 StringIndex;
240
241 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
242 MinLength = sizeof (*Original.Standard.Type1);
243 StringIndex = 0;
244
245 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_INFORMATION, MinLength, 1))) {
246 return;
247 }
248
249 SMBIOS_OVERRIDE_S (Table, Standard.Type1->Manufacturer, Original, Data->SystemManufacturer, &StringIndex, NULL);
250 SMBIOS_OVERRIDE_S (Table, Standard.Type1->ProductName, Original, Data->SystemProductName, &StringIndex, NULL);
251 SMBIOS_OVERRIDE_S (Table, Standard.Type1->Version, Original, Data->SystemVersion, &StringIndex, NULL);
252 SMBIOS_OVERRIDE_S (Table, Standard.Type1->SerialNumber, Original, Data->SystemSerialNumber, &StringIndex, NULL);
253 SMBIOS_OVERRIDE_V (Table, Standard.Type1->Uuid, Original, Data->SystemUUID, NULL);
254 SMBIOS_OVERRIDE_V (Table, Standard.Type1->WakeUpType, Original, NULL, NULL);
255 SMBIOS_OVERRIDE_S (Table, Standard.Type1->SKUNumber, Original, Data->SystemSKUNumber, &StringIndex, NULL);
256 SMBIOS_OVERRIDE_S (Table, Standard.Type1->Family, Original, Data->SystemFamily, &StringIndex, NULL);
257
258 SmbiosFinaliseStruct (Table);
259}
260
266STATIC
267VOID
269 IN OUT OC_SMBIOS_TABLE *Table,
270 IN OC_SMBIOS_DATA *Data
271 )
272{
274 UINT8 MinLength;
275 UINT8 StringIndex;
276
277 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BASEBOARD_INFORMATION, 1);
278 MinLength = sizeof (*Original.Standard.Type2);
279 StringIndex = 0;
280
281 //
282 // Hack for EDK 2 not using flexible array members adding extra data at struct end.
283 //
284 MinLength -= sizeof (Original.Standard.Type2->ContainedObjectHandles[0]);
286 sizeof (Original.Standard.Type2->ContainedObjectHandles) == sizeof (UINT16),
287 "Please remove this hack, the structure should have been fixed by now."
288 );
289
290 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_BASEBOARD_INFORMATION, MinLength, 1))) {
291 return;
292 }
293
294 SMBIOS_OVERRIDE_S (Table, Standard.Type2->Manufacturer, Original, Data->BoardManufacturer, &StringIndex, NULL);
295 SMBIOS_OVERRIDE_S (Table, Standard.Type2->ProductName, Original, Data->BoardProduct, &StringIndex, NULL);
296 SMBIOS_OVERRIDE_S (Table, Standard.Type2->Version, Original, Data->BoardVersion, &StringIndex, NULL);
297 SMBIOS_OVERRIDE_S (Table, Standard.Type2->SerialNumber, Original, Data->BoardSerialNumber, &StringIndex, NULL);
298 SMBIOS_OVERRIDE_S (Table, Standard.Type2->AssetTag, Original, Data->BoardAssetTag, &StringIndex, NULL);
299 SMBIOS_OVERRIDE_V (Table, Standard.Type2->FeatureFlag, Original, NULL, NULL);
300 SMBIOS_OVERRIDE_S (Table, Standard.Type2->LocationInChassis, Original, Data->BoardLocationInChassis, &StringIndex, NULL);
301 Table->CurrentPtr.Standard.Type2->ChassisHandle = OcSmbiosSystemEnclosureHandle;
302 SMBIOS_OVERRIDE_V (Table, Standard.Type2->BoardType, Original, Data->BoardType, NULL);
303
304 //
305 // Leave NumberOfContainedObjectHandles as 0, just like Apple does.
306 //
307
308 SmbiosFinaliseStruct (Table);
309}
310
316STATIC
317VOID
319 IN OUT OC_SMBIOS_TABLE *Table,
320 IN OC_SMBIOS_DATA *Data
321 )
322{
324 UINT8 MinLength;
325 UINT8 StringIndex;
326
327 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_ENCLOSURE, 1);
328 MinLength = sizeof (*Original.Standard.Type3);
329 StringIndex = 0;
330
331 //
332 // Hack for EDK 2 not using flexible array members adding extra data at struct end.
333 //
334 MinLength -= sizeof (Original.Standard.Type3->ContainedElements[0]);
336 sizeof (Original.Standard.Type3->ContainedElements) == sizeof (UINT8)*3,
337 "Please remove this hack, the structure should have been fixed by now."
338 );
339
340 //
341 // Another hack for omitted SKUNumber after flexible array.
342 // Note, Apple just ignores this field and just writes Type3 as is.
343 //
344 MinLength += sizeof (SMBIOS_TABLE_STRING);
346 sizeof (*Original.Standard.Type3) == sizeof (UINT8) * 0x18,
347 "The structure has changed, please fix this up."
348 );
349
350 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_ENCLOSURE, MinLength, 1))) {
351 return;
352 }
353
354 SMBIOS_OVERRIDE_S (Table, Standard.Type3->Manufacturer, Original, Data->ChassisManufacturer, &StringIndex, NULL);
355 SMBIOS_OVERRIDE_V (Table, Standard.Type3->Type, Original, Data->ChassisType, NULL);
356 SMBIOS_OVERRIDE_S (Table, Standard.Type3->Version, Original, Data->ChassisVersion, &StringIndex, NULL);
357 SMBIOS_OVERRIDE_S (Table, Standard.Type3->SerialNumber, Original, Data->ChassisSerialNumber, &StringIndex, NULL);
358 SMBIOS_OVERRIDE_S (Table, Standard.Type3->AssetTag, Original, Data->ChassisAssetTag, &StringIndex, NULL);
359 SMBIOS_OVERRIDE_V (Table, Standard.Type3->BootupState, Original, NULL, NULL);
360 SMBIOS_OVERRIDE_V (Table, Standard.Type3->PowerSupplyState, Original, NULL, NULL);
361 SMBIOS_OVERRIDE_V (Table, Standard.Type3->ThermalState, Original, NULL, NULL);
362 SMBIOS_OVERRIDE_V (Table, Standard.Type3->SecurityStatus, Original, NULL, NULL);
363 SMBIOS_OVERRIDE_V (Table, Standard.Type3->OemDefined, Original, NULL, NULL);
364 SMBIOS_OVERRIDE_V (Table, Standard.Type3->Height, Original, NULL, NULL);
365 SMBIOS_OVERRIDE_V (Table, Standard.Type3->NumberofPowerCords, Original, NULL, NULL);
366
367 //
368 // Leave ContainedElementCount and ContainedElementRecordLength 0.
369 // Also do not assign anything to SKUNumber.
370 //
371
372 SmbiosFinaliseStruct (Table);
373}
374
383STATIC
384VOID
386 IN OUT OC_SMBIOS_TABLE *Table,
387 IN OC_SMBIOS_DATA *Data,
388 IN OUT UINT16 *Index,
389 IN SMBIOS_HANDLE OriginalHandle,
390 OUT SMBIOS_HANDLE *NewHandle
391 )
392{
394 UINT16 NumberEntries;
395 UINT16 EntryNo;
396 UINT8 MinLength;
397 UINT8 StringIndex;
398
399 //
400 // A handle of 0xFFFF indicates no cache data present.
401 //
402 *NewHandle = 0xFFFF;
403 if (OriginalHandle == 0xFFFF) {
404 return;
405 }
406
407 NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_CACHE_INFORMATION);
408
409 DEBUG ((DEBUG_INFO, "OCSMB: Number of CPU cache entries is %u\n", (UINT32)NumberEntries));
410
411 //
412 // Locate original cache data specified by the handle.
413 //
414 for (EntryNo = 1; EntryNo <= NumberEntries; ++EntryNo) {
415 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_CACHE_INFORMATION, EntryNo);
416 if ( (Original.Raw == NULL)
417 || !SMBIOS_ACCESSIBLE (Original, Standard.Type7->CacheConfiguration)
418 || (Original.Standard.Type7->Hdr.Handle != OriginalHandle))
419 {
420 continue;
421 }
422
423 MinLength = sizeof (*Original.Standard.Type7);
424 StringIndex = 0;
425
426 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_CACHE_INFORMATION, MinLength, *Index))) {
427 return;
428 }
429
430 SMBIOS_OVERRIDE_S (Table, Standard.Type7->SocketDesignation, Original, NULL, &StringIndex, NULL);
431 SMBIOS_OVERRIDE_V (Table, Standard.Type7->CacheConfiguration, Original, NULL, NULL);
432 SMBIOS_OVERRIDE_V (Table, Standard.Type7->MaximumCacheSize, Original, NULL, NULL);
433 SMBIOS_OVERRIDE_V (Table, Standard.Type7->InstalledSize, Original, NULL, NULL);
434 SMBIOS_OVERRIDE_V (Table, Standard.Type7->SupportedSRAMType, Original, NULL, NULL);
435 SMBIOS_OVERRIDE_V (Table, Standard.Type7->CurrentSRAMType, Original, NULL, NULL);
436 SMBIOS_OVERRIDE_V (Table, Standard.Type7->CacheSpeed, Original, NULL, NULL);
437 SMBIOS_OVERRIDE_V (Table, Standard.Type7->ErrorCorrectionType, Original, NULL, NULL);
438 SMBIOS_OVERRIDE_V (Table, Standard.Type7->SystemCacheType, Original, NULL, NULL);
439 SMBIOS_OVERRIDE_V (Table, Standard.Type7->Associativity, Original, NULL, NULL);
440
441 //
442 // MaximumCacheSize2 and InstalledSize2 are to be set to the same values
443 // as MaximumCacheSize and InstalledSize if the cache size is under 2047MB.
444 //
445 if (!SMBIOS_ACCESSIBLE (Original, Standard.Type7->MaximumCacheSize2)) {
446 Table->CurrentPtr.Standard.Type7->MaximumCacheSize2 = Table->CurrentPtr.Standard.Type7->MaximumCacheSize & 0x7FFF;
447 Table->CurrentPtr.Standard.Type7->MaximumCacheSize2 |= Table->CurrentPtr.Standard.Type7->MaximumCacheSize & BIT15 ? BIT31 : 0;
448 Table->CurrentPtr.Standard.Type7->InstalledSize2 = Table->CurrentPtr.Standard.Type7->InstalledSize & 0x7FFF;
449 Table->CurrentPtr.Standard.Type7->InstalledSize2 |= Table->CurrentPtr.Standard.Type7->InstalledSize & BIT15 ? BIT31 : 0;
450 } else {
451 SMBIOS_OVERRIDE_V (Table, Standard.Type7->MaximumCacheSize2, Original, NULL, NULL);
452 SMBIOS_OVERRIDE_V (Table, Standard.Type7->InstalledSize2, Original, NULL, NULL);
453 }
454
455 *NewHandle = Table->CurrentPtr.Standard.Hdr->Handle;
456 (*Index)++;
457 SmbiosFinaliseStruct (Table);
458 }
459}
460
467STATIC
468VOID
470 IN OUT OC_SMBIOS_TABLE *Table,
471 IN OC_SMBIOS_DATA *Data,
472 IN OC_CPU_INFO *CpuInfo
473 )
474{
476 UINT16 NumberEntries;
477 UINT16 EntryNo;
478 UINT8 MinLength;
479 UINT8 StringIndex;
480 UINT8 TmpCount;
481 UINT16 MhzSpeed;
482
483 SMBIOS_HANDLE HandleL1Cache;
484 SMBIOS_HANDLE HandleL2Cache;
485 SMBIOS_HANDLE HandleL3Cache;
486 UINT16 CacheIndex;
487
488 NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_PROCESSOR_INFORMATION);
489 CacheIndex = 0;
490
491 for (EntryNo = 1; EntryNo <= NumberEntries; EntryNo++) {
492 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_PROCESSOR_INFORMATION, EntryNo);
493 if (Original.Raw == NULL) {
494 continue;
495 }
496
497 //
498 // Create cache tables.
499 //
500 PatchCacheInformation (Table, Data, &CacheIndex, Original.Standard.Type4->L1CacheHandle, &HandleL1Cache);
501 PatchCacheInformation (Table, Data, &CacheIndex, Original.Standard.Type4->L2CacheHandle, &HandleL2Cache);
502 PatchCacheInformation (Table, Data, &CacheIndex, Original.Standard.Type4->L3CacheHandle, &HandleL3Cache);
503
504 MinLength = sizeof (*Original.Standard.Type4);
505 StringIndex = 0;
506
507 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PROCESSOR_INFORMATION, MinLength, EntryNo))) {
508 continue;
509 }
510
511 SMBIOS_OVERRIDE_S (Table, Standard.Type4->Socket, Original, NULL, &StringIndex, NULL);
512 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorType, Original, NULL, NULL);
513 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorFamily, Original, NULL, NULL);
514 SMBIOS_OVERRIDE_S (Table, Standard.Type4->ProcessorManufacturer, Original, NULL, &StringIndex, NULL);
515 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorId, Original, NULL, NULL);
516 SMBIOS_OVERRIDE_S (Table, Standard.Type4->ProcessorVersion, Original, NULL, &StringIndex, NULL);
517 SMBIOS_OVERRIDE_V (Table, Standard.Type4->Voltage, Original, NULL, NULL);
518 Table->CurrentPtr.Standard.Type4->ExternalClock = CpuInfo->ExternalClock;
519
520 MhzSpeed = OcCpuFrequencyToDisplayFrequency (CpuInfo->CPUFrequency);
521
522 DEBUG ((DEBUG_INFO, "OCSMB: CPU%u display frequency is %uMHz\n", EntryNo, MhzSpeed));
523
524 Table->CurrentPtr.Standard.Type4->MaxSpeed = MhzSpeed;
525 Table->CurrentPtr.Standard.Type4->CurrentSpeed = Table->CurrentPtr.Standard.Type4->MaxSpeed;
526
527 SMBIOS_OVERRIDE_V (Table, Standard.Type4->Status, Original, NULL, NULL);
528 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorUpgrade, Original, NULL, NULL);
529
530 Table->CurrentPtr.Standard.Type4->L1CacheHandle = HandleL1Cache;
531 Table->CurrentPtr.Standard.Type4->L2CacheHandle = HandleL2Cache;
532 Table->CurrentPtr.Standard.Type4->L3CacheHandle = HandleL3Cache;
533
534 SMBIOS_OVERRIDE_S (Table, Standard.Type4->SerialNumber, Original, NULL, &StringIndex, NULL);
535 //
536 // Most bootloaders set this to ProcessorVersion, yet Apple does not care and has UNKNOWN.
537 //
538 SMBIOS_OVERRIDE_S (Table, Standard.Type4->AssetTag, Original, NULL, &StringIndex, NULL);
539 SMBIOS_OVERRIDE_S (Table, Standard.Type4->PartNumber, Original, NULL, &StringIndex, NULL);
540
541 TmpCount = (UINT8)(CpuInfo->CoreCount < 256 ? CpuInfo->CoreCount : 0xFF);
542 SMBIOS_OVERRIDE_V (Table, Standard.Type4->CoreCount, Original, NULL, &TmpCount);
543 SMBIOS_OVERRIDE_V (Table, Standard.Type4->EnabledCoreCount, Original, NULL, &TmpCount);
544 TmpCount = (UINT8)(CpuInfo->ThreadCount < 256 ? CpuInfo->ThreadCount : 0xFF);
545 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ThreadCount, Original, NULL, &TmpCount);
546 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorCharacteristics, Original, NULL, NULL);
547 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorFamily2, Original, NULL, NULL);
548 SMBIOS_OVERRIDE_V (Table, Standard.Type4->CoreCount2, Original, NULL, &CpuInfo->CoreCount);
549 SMBIOS_OVERRIDE_V (Table, Standard.Type4->EnabledCoreCount2, Original, NULL, &CpuInfo->CoreCount);
550 SMBIOS_OVERRIDE_V (Table, Standard.Type4->ThreadCount2, Original, NULL, &CpuInfo->ThreadCount);
551
552 SmbiosFinaliseStruct (Table);
553 }
554}
555
561STATIC
562VOID
564 IN OUT OC_SMBIOS_TABLE *Table,
565 IN OC_SMBIOS_DATA *Data
566 )
567{
569 UINT16 NumberEntries;
570 UINT16 EntryNo;
571 UINT8 MinLength;
572 UINT8 StringIndex;
573
574 NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION);
575
576 for (EntryNo = 1; EntryNo <= NumberEntries; EntryNo++) {
577 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, EntryNo);
578 if (Original.Raw == NULL) {
579 continue;
580 }
581
582 MinLength = sizeof (*Original.Standard.Type8);
583 StringIndex = 0;
584
585 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, MinLength, EntryNo))) {
586 continue;
587 }
588
589 SMBIOS_OVERRIDE_S (Table, Standard.Type8->InternalReferenceDesignator, Original, NULL, &StringIndex, NULL);
590 SMBIOS_OVERRIDE_V (Table, Standard.Type8->InternalConnectorType, Original, NULL, NULL);
591 SMBIOS_OVERRIDE_S (Table, Standard.Type8->ExternalReferenceDesignator, Original, NULL, &StringIndex, NULL);
592 SMBIOS_OVERRIDE_V (Table, Standard.Type8->ExternalConnectorType, Original, NULL, NULL);
593 SMBIOS_OVERRIDE_V (Table, Standard.Type8->PortType, Original, NULL, NULL);
594
595 SmbiosFinaliseStruct (Table);
596 }
597}
598
604STATIC
605VOID
607 IN OUT OC_SMBIOS_TABLE *Table,
608 IN OC_SMBIOS_DATA *Data
609 )
610{
612 UINT16 NumberEntries;
613 UINT16 EntryNo;
614 UINT8 MinLength;
615 UINT8 StringIndex;
616 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
617 EFI_STATUS Status;
618 UINT64 PciAddress;
619 UINT8 SecSubBus;
620 UINT16 ClassCode;
621 CONST CHAR8 *SlotDesignation;
622
623 Status = gBS->LocateProtocol (
625 NULL,
626 (VOID **)&PciRootBridgeIo
627 );
628 if (EFI_ERROR (Status)) {
629 PciRootBridgeIo = NULL;
630 }
631
632 NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_SYSTEM_SLOTS);
633
634 for (EntryNo = 1; EntryNo <= NumberEntries; EntryNo++) {
635 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_SLOTS, EntryNo);
636 if (Original.Raw == NULL) {
637 continue;
638 }
639
640 MinLength = sizeof (*Original.Standard.Type9);
641 StringIndex = 0;
642
643 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_SLOTS, MinLength, EntryNo))) {
644 continue;
645 }
646
647 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotType, Original, NULL, NULL);
648 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotDataBusWidth, Original, NULL, NULL);
649 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotLength, Original, NULL, NULL);
650 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotID, Original, NULL, NULL);
651 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotType, Original, NULL, NULL);
652 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotCharacteristics1, Original, NULL, NULL);
653 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotCharacteristics2, Original, NULL, NULL);
654 SMBIOS_OVERRIDE_V (Table, Standard.Type9->SegmentGroupNum, Original, NULL, NULL);
655 SMBIOS_OVERRIDE_V (Table, Standard.Type9->BusNum, Original, NULL, NULL);
656 SMBIOS_OVERRIDE_V (Table, Standard.Type9->DevFuncNum, Original, NULL, NULL);
657
658 //
659 // Correct SlotDesignation and CurrentUsage if PCI protocol is available.
660 //
661
662 if (PciRootBridgeIo == NULL) {
663 SMBIOS_OVERRIDE_S (Table, Standard.Type9->SlotDesignation, Original, NULL, &StringIndex, NULL);
664 SMBIOS_OVERRIDE_V (Table, Standard.Type9->CurrentUsage, Original, NULL, NULL);
665 } else {
666 SlotDesignation = NULL;
667 Table->CurrentPtr.Standard.Type9->CurrentUsage = SlotUsageAvailable;
668
669 if (Table->CurrentPtr.Standard.Type9->BusNum != 0) {
670 PciAddress = EFI_PCI_ADDRESS (
671 BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 3, 7),
672 Table->CurrentPtr.Standard.Type9->BusNum,
673 BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 0, 2),
674 0
675 );
676 } else {
677 PciAddress = EFI_PCI_ADDRESS (
678 Table->CurrentPtr.Standard.Type9->BusNum,
679 BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 3, 7),
680 BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 0, 2),
681 0
682 );
683 }
684
685 SecSubBus = MAX_UINT8;
686 ClassCode = MAX_UINT16;
687 Status = PciRootBridgeIo->Pci.Read (
688 PciRootBridgeIo,
689 EfiPciWidthUint8,
690 PciAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET,
691 1,
692 &SecSubBus
693 );
694
695 if (!EFI_ERROR (Status) && (SecSubBus != MAX_UINT8)) {
696 Status = PciRootBridgeIo->Pci.Read (
697 PciRootBridgeIo,
698 EfiPciWidthUint16,
699 EFI_PCI_ADDRESS (SecSubBus, 0, 0, 0) + 10,
700 1,
701 &ClassCode
702 );
703 }
704
705 if (!EFI_ERROR (Status) && (ClassCode != MAX_UINT16)) {
706 Table->CurrentPtr.Standard.Type9->CurrentUsage = SlotUsageAvailable;
707 if (ClassCode == 0x0280) {
708 SlotDesignation = "AirPort";
709 } else if (ClassCode == 0x0108) {
710 //
711 // FIXME: Expand checks since not all nvme uses m.2 slot
712 //
713 SlotDesignation = "M.2";
714 }
715 }
716
717 SMBIOS_OVERRIDE_S (Table, Standard.Type9->SlotDesignation, Original, SlotDesignation, &StringIndex, NULL);
718 }
719
720 SmbiosFinaliseStruct (Table);
721 }
722}
723
729STATIC
730VOID
732 IN OUT OC_SMBIOS_TABLE *Table,
733 IN OC_SMBIOS_DATA *Data,
735 IN UINT16 Index,
736 OUT SMBIOS_HANDLE *Handle
737 )
738{
739 UINT8 MinLength;
740
742 MinLength = sizeof (*Original.Standard.Type16);
743
744 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, MinLength, Index))) {
745 return;
746 }
747
748 SMBIOS_OVERRIDE_V (Table, Standard.Type16->Location, Original, NULL, NULL);
749 SMBIOS_OVERRIDE_V (Table, Standard.Type16->Use, Original, NULL, NULL);
750 SMBIOS_OVERRIDE_V (Table, Standard.Type16->MemoryErrorCorrection, Original, NULL, NULL);
751 SMBIOS_OVERRIDE_V (Table, Standard.Type16->MaximumCapacity, Original, NULL, NULL);
752 //
753 // Do not support memory error information. 0xFFFF indicates no errors previously detected.
754 //
755 Table->CurrentPtr.Standard.Type16->MemoryErrorInformationHandle = 0xFFFF;
756 SMBIOS_OVERRIDE_V (Table, Standard.Type16->NumberOfMemoryDevices, Original, NULL, NULL);
757 SMBIOS_OVERRIDE_V (Table, Standard.Type16->ExtendedMaximumCapacity, Original, NULL, NULL);
758
759 //
760 // Return assigned handle
761 //
762 *Handle = Table->CurrentPtr.Standard.Hdr->Handle;
763
764 SmbiosFinaliseStruct (Table);
765}
766
772STATIC
773VOID
775 IN OUT OC_SMBIOS_TABLE *Table,
776 IN OC_SMBIOS_DATA *Data,
777 OUT SMBIOS_HANDLE *Handle
778 )
779{
780 UINT8 MinLength;
781
783 MinLength = sizeof (*Table->CurrentPtr.Standard.Type16);
784
785 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, MinLength, 1))) {
786 return;
787 }
788
789 Table->CurrentPtr.Standard.Type16->Location = MemoryArrayLocationSystemBoard;
790 Table->CurrentPtr.Standard.Type16->Use = MemoryArrayUseSystemMemory;
791 Table->CurrentPtr.Standard.Type16->MemoryErrorCorrection = *Data->MemoryErrorCorrection;
792 //
793 // Do not support memory error information. 0xFFFF indicates no errors previously detected.
794 //
795 Table->CurrentPtr.Standard.Type16->MemoryErrorInformationHandle = 0xFFFF;
796 Table->CurrentPtr.Standard.Type16->NumberOfMemoryDevices = Data->MemoryDevicesCount;
797
798 //
799 // Sizes over 2TB need to use the Extended Maximum Capacity field which is represented in bytes.
800 // Maximum Capacity is represented in KB.
801 //
802 if (*Data->MemoryMaxCapacity < SIZE_2TB) {
803 Table->CurrentPtr.Standard.Type16->MaximumCapacity = (UINT32)(*Data->MemoryMaxCapacity / SIZE_1KB);
804 Table->CurrentPtr.Standard.Type16->ExtendedMaximumCapacity = 0;
805 } else {
806 Table->CurrentPtr.Standard.Type16->MaximumCapacity = SIZE_2TB / SIZE_1KB;
807 Table->CurrentPtr.Standard.Type16->ExtendedMaximumCapacity = *Data->MemoryMaxCapacity;
808 }
809
810 //
811 // Return assigned handle
812 //
813 *Handle = Table->CurrentPtr.Standard.Hdr->Handle;
814
815 SmbiosFinaliseStruct (Table);
816}
817
823STATIC
824VOID
826 IN OUT OC_SMBIOS_TABLE *Table,
827 IN OC_SMBIOS_DATA *Data,
828 IN SMBIOS_HANDLE MemoryArrayHandle,
830 IN UINT16 Index,
831 OUT SMBIOS_HANDLE *Handle
832 )
833{
834 UINT8 MinLength;
835 UINT8 StringIndex;
836 UINT8 FormFactor;
837
839 MinLength = sizeof (*Original.Standard.Type17);
840 StringIndex = 0;
841 FormFactor = SmbiosGetFormFactor (Data, Original);
842
843 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_DEVICE, MinLength, Index))) {
844 return;
845 }
846
847 //
848 // External handles are set below.
849 //
850 SMBIOS_OVERRIDE_V (Table, Standard.Type17->TotalWidth, Original, NULL, NULL);
851 SMBIOS_OVERRIDE_V (Table, Standard.Type17->DataWidth, Original, NULL, NULL);
852 SMBIOS_OVERRIDE_V (Table, Standard.Type17->Size, Original, NULL, NULL);
853 SMBIOS_OVERRIDE_V (Table, Standard.Type17->FormFactor, Original, &FormFactor, NULL);
854 SMBIOS_OVERRIDE_V (Table, Standard.Type17->DeviceSet, Original, NULL, NULL);
855 SMBIOS_OVERRIDE_S (Table, Standard.Type17->DeviceLocator, Original, NULL, &StringIndex, NULL);
856 SMBIOS_OVERRIDE_S (Table, Standard.Type17->BankLocator, Original, NULL, &StringIndex, NULL);
857 SMBIOS_OVERRIDE_V (Table, Standard.Type17->MemoryType, Original, NULL, NULL);
858 SMBIOS_OVERRIDE_V (Table, Standard.Type17->TypeDetail, Original, NULL, NULL);
859 SMBIOS_OVERRIDE_V (Table, Standard.Type17->Speed, Original, NULL, NULL);
860
861 //
862 // Assign the parent memory array handle.
863 // Do not support memory error information. 0xFFFF indicates no errors previously detected.
864 //
865 Table->CurrentPtr.Standard.Type17->MemoryArrayHandle = MemoryArrayHandle;
866 Table->CurrentPtr.Standard.Type17->MemoryErrorInformationHandle = 0xFFFF;
867
868 //
869 // Some machines may have NULL values for these fields, which will cause SPMemoryReporter
870 // crashes or ??? to be displayed in About This Mac. Fallback to "Unknown" for such fields.
871 // If there is no stick in the slot, the Manufacturer value must be "NO DIMM", this
872 // is checked in System Profiler, at least by iMacPro1,1 (see ExpansionSlotSupport.framework).
873 //
874 if (Table->CurrentPtr.Standard.Type17->Size > 0) {
875 SMBIOS_OVERRIDE_S (Table, Standard.Type17->Manufacturer, Original, NULL, &StringIndex, "Unknown");
876 SMBIOS_OVERRIDE_S (Table, Standard.Type17->SerialNumber, Original, NULL, &StringIndex, "Unknown");
877 SMBIOS_OVERRIDE_S (Table, Standard.Type17->AssetTag, Original, NULL, &StringIndex, "Unknown");
878 SMBIOS_OVERRIDE_S (Table, Standard.Type17->PartNumber, Original, NULL, &StringIndex, "Unknown");
879 } else {
880 SmbiosOverrideString (Table, "NO DIMM", &StringIndex);
881 Table->CurrentPtr.Standard.Type17->Manufacturer = StringIndex;
882 Table->CurrentPtr.Standard.Type17->SerialNumber = StringIndex;
883 Table->CurrentPtr.Standard.Type17->AssetTag = StringIndex;
884 Table->CurrentPtr.Standard.Type17->PartNumber = StringIndex;
885 }
886
887 SMBIOS_OVERRIDE_V (Table, Standard.Type17->Attributes, Original, NULL, NULL);
888 SMBIOS_OVERRIDE_V (Table, Standard.Type17->ExtendedSize, Original, NULL, NULL);
889 SMBIOS_OVERRIDE_V (Table, Standard.Type17->ConfiguredMemoryClockSpeed, Original, NULL, NULL);
890 SMBIOS_OVERRIDE_V (Table, Standard.Type17->MinimumVoltage, Original, NULL, NULL);
891 SMBIOS_OVERRIDE_V (Table, Standard.Type17->MaximumVoltage, Original, NULL, NULL);
892 SMBIOS_OVERRIDE_V (Table, Standard.Type17->ConfiguredVoltage, Original, NULL, NULL);
893
894 //
895 // Return assigned handle
896 //
897 *Handle = Table->CurrentPtr.Standard.Hdr->Handle;
898
899 SmbiosFinaliseStruct (Table);
900}
901
907STATIC
908VOID
910 IN OUT OC_SMBIOS_TABLE *Table,
911 IN OC_SMBIOS_DATA *Data,
912 IN OC_SMBIOS_MEMORY_DEVICE_DATA *DeviceData,
913 IN SMBIOS_HANDLE MemoryArrayHandle,
914 IN UINT16 Index,
915 OUT SMBIOS_HANDLE *Handle
916 )
917{
918 UINT8 MinLength;
919 UINT8 StringIndex;
920
922 MinLength = sizeof (*Table->CurrentPtr.Standard.Type17);
923 StringIndex = 0;
924
925 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_DEVICE, MinLength, Index))) {
926 return;
927 }
928
929 Table->CurrentPtr.Standard.Type17->TotalWidth = *Data->MemoryTotalWidth;
930 Table->CurrentPtr.Standard.Type17->DataWidth = *Data->MemoryDataWidth;
931 Table->CurrentPtr.Standard.Type17->FormFactor = *Data->MemoryFormFactor;
932 Table->CurrentPtr.Standard.Type17->MemoryType = *Data->MemoryType;
933 Table->CurrentPtr.Standard.Type17->TypeDetail = *((MEMORY_DEVICE_TYPE_DETAIL *)Data->MemoryTypeDetail);
934 Table->CurrentPtr.Standard.Type17->Speed = *DeviceData->Speed;
935
936 //
937 // Sizes over 32GB-1MB need to be represented in the Extended Size field.
938 // Both will be represented in MB.
939 //
940 if ((UINT64)(*DeviceData->Size) * SIZE_1MB < SIZE_32GB - SIZE_1MB) {
941 Table->CurrentPtr.Standard.Type17->Size = (UINT16)*DeviceData->Size;
942 Table->CurrentPtr.Standard.Type17->ExtendedSize = 0;
943 } else {
944 Table->CurrentPtr.Standard.Type17->Size = 0x7FFF;
945 Table->CurrentPtr.Standard.Type17->ExtendedSize = *DeviceData->Size;
946 }
947
948 SmbiosOverrideString (Table, DeviceData->AssetTag, &StringIndex);
949 Table->CurrentPtr.Standard.Type17->AssetTag = StringIndex;
950 SmbiosOverrideString (Table, DeviceData->BankLocator, &StringIndex);
951 Table->CurrentPtr.Standard.Type17->BankLocator = StringIndex;
952 SmbiosOverrideString (Table, DeviceData->DeviceLocator, &StringIndex);
953 Table->CurrentPtr.Standard.Type17->DeviceLocator = StringIndex;
954 SmbiosOverrideString (Table, DeviceData->Manufacturer, &StringIndex);
955 Table->CurrentPtr.Standard.Type17->Manufacturer = StringIndex;
956 SmbiosOverrideString (Table, DeviceData->PartNumber, &StringIndex);
957 Table->CurrentPtr.Standard.Type17->PartNumber = StringIndex;
958 SmbiosOverrideString (Table, DeviceData->SerialNumber, &StringIndex);
959 Table->CurrentPtr.Standard.Type17->SerialNumber = StringIndex;
960
961 //
962 // Assign the parent memory array handle.
963 // Do not support memory error information. 0xFFFF indicates no errors previously detected.
964 //
965 Table->CurrentPtr.Standard.Type17->MemoryArrayHandle = MemoryArrayHandle;
966 Table->CurrentPtr.Standard.Type17->MemoryErrorInformationHandle = 0xFFFF;
967
968 //
969 // Return assigned handle
970 //
971 *Handle = Table->CurrentPtr.Standard.Hdr->Handle;
972
973 SmbiosFinaliseStruct (Table);
974}
975
981STATIC
982VOID
984 IN OUT OC_SMBIOS_TABLE *Table,
985 IN OC_SMBIOS_DATA *Data,
986 IN SMBIOS_HANDLE MemoryArrayHandle,
988 IN UINT16 Index,
989 IN OUT OC_SMBIOS_MAPPING *Mapping,
990 IN OUT UINT16 *MappingNum
991 )
992{
993 UINT8 MinLength;
994
995 MinLength = sizeof (*Original.Standard.Type19);
996
997 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, MinLength, Index))) {
998 return;
999 }
1000
1001 SMBIOS_OVERRIDE_V (Table, Standard.Type19->StartingAddress, Original, NULL, NULL);
1002 SMBIOS_OVERRIDE_V (Table, Standard.Type19->EndingAddress, Original, NULL, NULL);
1003 Table->CurrentPtr.Standard.Type19->MemoryArrayHandle = MemoryArrayHandle;
1004 SMBIOS_OVERRIDE_V (Table, Standard.Type19->PartitionWidth, Original, NULL, NULL);
1005 SMBIOS_OVERRIDE_V (Table, Standard.Type19->ExtendedStartingAddress, Original, NULL, NULL);
1006 SMBIOS_OVERRIDE_V (Table, Standard.Type19->ExtendedEndingAddress, Original, NULL, NULL);
1007
1008 if (*MappingNum < OC_SMBIOS_MAX_MAPPING) {
1009 Mapping[*MappingNum].Old = Original.Standard.Hdr->Handle;
1010 Mapping[*MappingNum].New = Table->CurrentPtr.Standard.Hdr->Handle;
1011 (*MappingNum)++;
1012 } else {
1013 //
1014 // The value is reasonably large enough for this to never happen, yet just in case.
1015 //
1016 DEBUG ((DEBUG_WARN, "OCSMB: OC_SMBIOS_MAX_MAPPING exceeded\n"));
1017 }
1018
1019 SmbiosFinaliseStruct (Table);
1020}
1021
1027STATIC
1028VOID
1030 IN OUT OC_SMBIOS_TABLE *Table,
1031 IN OC_SMBIOS_DATA *Data,
1033 IN UINT16 Index,
1034 IN SMBIOS_HANDLE MemoryDeviceHandle,
1035 IN OC_SMBIOS_MAPPING *Mapping,
1036 IN UINT16 MappingNum
1037 )
1038{
1039 UINT8 MinLength;
1040 UINT16 MapIndex;
1041
1042 MinLength = sizeof (*Original.Standard.Type20);
1043
1044 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS, MinLength, Index))) {
1045 return;
1046 }
1047
1048 SMBIOS_OVERRIDE_V (Table, Standard.Type20->StartingAddress, Original, NULL, NULL);
1049 SMBIOS_OVERRIDE_V (Table, Standard.Type20->EndingAddress, Original, NULL, NULL);
1050 Table->CurrentPtr.Standard.Type20->MemoryDeviceHandle = MemoryDeviceHandle;
1051
1052 Table->CurrentPtr.Standard.Type20->MemoryArrayMappedAddressHandle = 0xFFFF;
1053 if ((Original.Raw != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type20->MemoryArrayMappedAddressHandle)) {
1054 for (MapIndex = 0; MapIndex < MappingNum; MapIndex++) {
1055 if (Mapping[MapIndex].Old == Original.Standard.Type20->MemoryArrayMappedAddressHandle) {
1056 Table->CurrentPtr.Standard.Type20->MemoryArrayMappedAddressHandle = Mapping[MapIndex].New;
1057 break;
1058 }
1059 }
1060 }
1061
1062 SMBIOS_OVERRIDE_V (Table, Standard.Type20->PartitionRowPosition, Original, NULL, NULL);
1063 SMBIOS_OVERRIDE_V (Table, Standard.Type20->InterleavePosition, Original, NULL, NULL);
1064 SMBIOS_OVERRIDE_V (Table, Standard.Type20->InterleavedDataDepth, Original, NULL, NULL);
1065 SMBIOS_OVERRIDE_V (Table, Standard.Type20->ExtendedStartingAddress, Original, NULL, NULL);
1066 SMBIOS_OVERRIDE_V (Table, Standard.Type20->ExtendedEndingAddress, Original, NULL, NULL);
1067
1068 SmbiosFinaliseStruct (Table);
1069}
1070
1076STATIC
1077VOID
1079 IN OUT OC_SMBIOS_TABLE *Table,
1080 IN OC_SMBIOS_DATA *Data
1081 )
1082{
1084 UINT8 MinLength;
1085 UINT8 StringIndex;
1086
1087 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_PORTABLE_BATTERY, 1);
1088 MinLength = sizeof (*Original.Standard.Type22);
1089 StringIndex = 0;
1090
1091 //
1092 // Do not add batteries where it does not exist (e.g. desktop).
1093 //
1094 if (Original.Raw == NULL) {
1095 return;
1096 }
1097
1098 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PORTABLE_BATTERY, MinLength, 1))) {
1099 return;
1100 }
1101
1102 SMBIOS_OVERRIDE_S (Table, Standard.Type22->Location, Original, NULL, &StringIndex, NULL);
1103 SMBIOS_OVERRIDE_S (Table, Standard.Type22->Manufacturer, Original, NULL, &StringIndex, NULL);
1104 SMBIOS_OVERRIDE_S (Table, Standard.Type22->ManufactureDate, Original, NULL, &StringIndex, NULL);
1105 SMBIOS_OVERRIDE_S (Table, Standard.Type22->SerialNumber, Original, NULL, &StringIndex, NULL);
1106 SMBIOS_OVERRIDE_S (Table, Standard.Type22->DeviceName, Original, NULL, &StringIndex, NULL);
1107 SMBIOS_OVERRIDE_V (Table, Standard.Type22->DeviceChemistry, Original, NULL, NULL);
1108 SMBIOS_OVERRIDE_V (Table, Standard.Type22->DeviceCapacity, Original, NULL, NULL);
1109 SMBIOS_OVERRIDE_V (Table, Standard.Type22->DesignVoltage, Original, NULL, NULL);
1110 SMBIOS_OVERRIDE_S (Table, Standard.Type22->SBDSVersionNumber, Original, NULL, &StringIndex, NULL);
1111 SMBIOS_OVERRIDE_V (Table, Standard.Type22->MaximumErrorInBatteryData, Original, NULL, NULL);
1112 SMBIOS_OVERRIDE_V (Table, Standard.Type22->SBDSSerialNumber, Original, NULL, NULL);
1113 SMBIOS_OVERRIDE_V (Table, Standard.Type22->SBDSManufactureDate, Original, NULL, NULL);
1114 SMBIOS_OVERRIDE_S (Table, Standard.Type22->SBDSDeviceChemistry, Original, NULL, &StringIndex, NULL);
1115 SMBIOS_OVERRIDE_V (Table, Standard.Type22->DesignCapacityMultiplier, Original, NULL, NULL);
1116 SMBIOS_OVERRIDE_V (Table, Standard.Type22->OEMSpecific, Original, NULL, NULL);
1117
1118 SmbiosFinaliseStruct (Table);
1119}
1120
1126STATIC
1127VOID
1129 IN OUT OC_SMBIOS_TABLE *Table,
1130 IN OC_SMBIOS_DATA *Data
1131 )
1132{
1134 UINT8 MinLength;
1135
1136 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, 1);
1137 MinLength = sizeof (*Original.Standard.Type32);
1138
1139 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, MinLength, 1))) {
1140 return;
1141 }
1142
1143 SMBIOS_OVERRIDE_V (Table, Standard.Type32->Reserved, Original, NULL, NULL);
1144 SMBIOS_OVERRIDE_V (Table, Standard.Type32->BootStatus, Original, NULL, NULL);
1145
1146 SmbiosFinaliseStruct (Table);
1147}
1148
1155STATIC
1156VOID
1158 IN OUT OC_SMBIOS_TABLE *Table,
1159 IN OC_SMBIOS_DATA *Data,
1160 IN BOOLEAN HasAppleSMBIOS
1161 )
1162{
1164 UINT8 MinLength;
1165
1166 UINT32 FirmwareFeatures;
1167 UINT32 FirmwareFeaturesMask;
1170
1171 if (HasAppleSMBIOS) {
1173 } else {
1174 Original.Raw = NULL;
1175 }
1176
1177 MinLength = sizeof (*Table->CurrentPtr.Type128);
1178
1179 if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_FIRMWARE_INFORMATION, MinLength, 1))) {
1180 return;
1181 }
1182
1183 FirmwareFeatures = (UINT32)BitFieldRead64 (Data->FirmwareFeatures, 0, 31);
1184 FirmwareFeaturesMask = (UINT32)BitFieldRead64 (Data->FirmwareFeaturesMask, 0, 31);
1185 ExtendedFirmwareFeatures = (UINT32)BitFieldRead64 (Data->FirmwareFeatures, 32, 63);
1186 ExtendedFirmwareFeaturesMask = (UINT32)BitFieldRead64 (Data->FirmwareFeaturesMask, 32, 63);
1187
1188 SMBIOS_OVERRIDE_V (Table, Type128->FirmwareFeatures, Original, Data->FirmwareFeatures == 0 ? NULL : &FirmwareFeatures, NULL);
1189 SMBIOS_OVERRIDE_V (Table, Type128->FirmwareFeaturesMask, Original, Data->FirmwareFeaturesMask == 0 ? NULL : &FirmwareFeaturesMask, NULL);
1190 SMBIOS_OVERRIDE_V (Table, Type128->ExtendedFirmwareFeatures, Original, Data->FirmwareFeatures == 0 ? NULL : &ExtendedFirmwareFeatures, NULL);
1191 SMBIOS_OVERRIDE_V (Table, Type128->ExtendedFirmwareFeaturesMask, Original, Data->FirmwareFeaturesMask == 0 ? NULL : &ExtendedFirmwareFeaturesMask, NULL);
1192
1193 SmbiosFinaliseStruct (Table);
1194}
1195
1202STATIC
1203VOID
1205 IN OUT OC_SMBIOS_TABLE *Table,
1206 IN OC_SMBIOS_DATA *Data,
1207 IN OC_CPU_INFO *CpuInfo
1208 )
1209{
1211 UINT8 MinLength;
1212
1213 Original.Raw = NULL;
1214 MinLength = sizeof (*Table->CurrentPtr.Type131);
1215
1216 if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_PROCESSOR_TYPE, MinLength, 1))) {
1217 return;
1218 }
1219
1220 SMBIOS_OVERRIDE_V (Table, Type131->ProcessorType.Type, Original, Data->ProcessorType, &CpuInfo->AppleProcessorType);
1221
1222 SmbiosFinaliseStruct (Table);
1223}
1224
1231STATIC
1232VOID
1234 IN OUT OC_SMBIOS_TABLE *Table,
1235 IN OC_SMBIOS_DATA *Data,
1236 IN OC_CPU_INFO *CpuInfo
1237 )
1238{
1239 #ifndef OC_PROVIDE_APPLE_PROCESSOR_BUS_SPEED
1240 //
1241 // This table is not added in all modern Macs.
1242 //
1243 (VOID)Table;
1244 (VOID)Data;
1245 (VOID)CpuInfo;
1246 #else
1247 UINT8 MinLength;
1248
1249 MinLength = sizeof (*Table->CurrentPtr.Type132);
1250
1251 if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_PROCESSOR_BUS_SPEED, MinLength, 1))) {
1252 return;
1253 }
1254
1255 Table->CurrentPtr.Type132->ProcessorBusSpeed = CpuInfo->ExternalClock * 4;
1256
1257 SmbiosFinaliseStruct (Table);
1258 #endif
1259}
1260
1267STATIC
1268VOID
1270 IN OUT OC_SMBIOS_TABLE *Table,
1271 IN OC_SMBIOS_DATA *Data,
1272 IN BOOLEAN HasAppleSMBIOS
1273 )
1274{
1276 UINT8 MinLength;
1277
1278 if (HasAppleSMBIOS) {
1280 } else {
1281 Original.Raw = NULL;
1282 }
1283
1284 //
1285 // Older Macs do not support PlatformFeature table.
1286 //
1287 if ((Data->PlatformFeature == NULL) && (Original.Raw == NULL)) {
1288 return;
1289 }
1290
1291 MinLength = sizeof (*Table->CurrentPtr.Type133);
1292
1293 if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_PLATFORM_FEATURE, MinLength, 1))) {
1294 return;
1295 }
1296
1297 SMBIOS_OVERRIDE_V (Table, Type133->PlatformFeature, Original, Data->PlatformFeature, NULL);
1298
1299 SmbiosFinaliseStruct (Table);
1300}
1301
1308STATIC
1309VOID
1311 IN OUT OC_SMBIOS_TABLE *Table,
1312 IN OC_SMBIOS_DATA *Data,
1313 IN BOOLEAN HasAppleSMBIOS
1314 )
1315{
1317 UINT8 MinLength;
1318
1319 if (HasAppleSMBIOS) {
1321 } else {
1322 Original.Raw = NULL;
1323 }
1324
1325 //
1326 // Newer Macs do not support SmcVersion table.
1327 //
1328 if ((Data->SmcVersion == NULL) && (Original.Raw == NULL)) {
1329 return;
1330 }
1331
1332 MinLength = sizeof (*Table->CurrentPtr.Type134);
1333
1334 if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_SMC_INFORMATION, MinLength, 1))) {
1335 return;
1336 }
1337
1338 SMBIOS_OVERRIDE_V (Table, Type134->SmcVersion, Original, Data->SmcVersion, NULL);
1339
1340 SmbiosFinaliseStruct (Table);
1341}
1342
1348STATIC
1349VOID
1351 IN OUT OC_SMBIOS_TABLE *Table,
1352 IN OC_SMBIOS_DATA *Data
1353 )
1354{
1355 UINT8 MinLength;
1356
1357 MinLength = sizeof (*Table->CurrentPtr.Standard.Type127);
1358
1359 if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_END_OF_TABLE, MinLength, 1))) {
1360 return;
1361 }
1362
1363 SmbiosFinaliseStruct (Table);
1364}
1365
1371STATIC
1372EFI_STATUS
1374 BOOLEAN Unlock
1375 )
1376{
1377 EFI_STATUS Status;
1378
1379 //
1380 // Not needed for mOriginalSmbios3.
1381 //
1382 if (mOriginalSmbios == NULL) {
1383 return EFI_SUCCESS;
1384 }
1385
1386 if (Unlock) {
1387 if (((UINTN)mOriginalSmbios) < BASE_1MB) {
1388 //
1389 // Enable write access to DMI anchor
1390 //
1391 Status = LegacyRegionUnlock (
1392 (UINT32)((UINTN)mOriginalSmbios & 0xFFFF8000ULL),
1393 EFI_PAGE_SIZE
1394 );
1395
1396 if (EFI_ERROR (Status)) {
1397 DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionUnlock DMI anchor failure - %r\n", Status));
1398 return Status;
1399 }
1400 }
1401
1402 if (((UINTN)mOriginalSmbios->TableAddress) < BASE_1MB) {
1403 //
1404 // Enable write access to DMI table
1405 //
1406 Status = LegacyRegionUnlock (
1407 (UINT32)((UINTN)mOriginalSmbios->TableAddress & 0xFFFF8000ULL),
1408 EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (mOriginalSmbios->TableLength))
1409 );
1410
1411 if (EFI_ERROR (Status)) {
1412 DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionUnlock DMI table failure - %r\n", Status));
1413 return Status;
1414 }
1415 }
1416 } else {
1417 if ((UINTN)mOriginalSmbios->TableAddress < BASE_1MB) {
1418 //
1419 // Lock write access To DMI table
1420 //
1421 Status = LegacyRegionLock (
1422 (UINT32)((UINTN)mOriginalSmbios->TableAddress & 0xFFFF8000ULL),
1423 EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (mOriginalSmbios->TableLength))
1424 );
1425
1426 if (EFI_ERROR (Status)) {
1427 DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionLock DMI table failure - %r\n", Status));
1428 return Status;
1429 }
1430 }
1431
1432 if ((UINTN)mOriginalSmbios < BASE_1MB) {
1433 //
1434 // Lock write access To DMI anchor
1435 //
1436 Status = LegacyRegionLock (
1437 (UINT32)((UINTN)mOriginalSmbios & 0xFFFF8000ULL),
1438 EFI_PAGE_SIZE
1439 );
1440
1441 if (EFI_ERROR (Status)) {
1442 DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionLock DMI anchor failure - %r\n", Status));
1443 return Status;
1444 }
1445 }
1446 }
1447
1448 return EFI_SUCCESS;
1449}
1450
1451EFI_STATUS
1453 IN OUT OC_SMBIOS_TABLE *SmbiosTable
1454 )
1455{
1456 EFI_STATUS Status;
1457
1458 mOriginalSmbios = NULL;
1459 mOriginalSmbios3 = NULL;
1461 mOriginalTable.Raw = NULL;
1462 ZeroMem (SmbiosTable, sizeof (*SmbiosTable));
1463 SmbiosTable->Handle = OcSmbiosAutomaticHandle;
1464
1465 Status = EfiGetSystemConfigurationTable (
1467 (VOID **)&mOriginalSmbios
1468 );
1469
1470 //
1471 // Perform basic sanity checks. We assume EfiGetSystemConfigurationTable returns trusted data
1472 // in terms of file size at the very least, but try to detect potential issues.
1473 //
1474 if (!EFI_ERROR (Status)) {
1475 if (mOriginalSmbios->EntryPointLength < sizeof (SMBIOS_TABLE_ENTRY_POINT)) {
1476 DEBUG ((
1477 DEBUG_WARN,
1478 "OCSMB: SmbiosLookupHost entry is too small - %u/%u bytes\n",
1479 mOriginalSmbios->EntryPointLength,
1480 (UINT32)sizeof (SMBIOS_TABLE_ENTRY_POINT)
1481 ));
1482 mOriginalSmbios = NULL;
1483 } else if ((mOriginalSmbios->TableAddress == 0) || (mOriginalSmbios->TableLength == 0)) {
1485 sizeof (mOriginalSmbios->TableLength) == sizeof (UINT16)
1486 && SMBIOS_TABLE_MAX_LENGTH == MAX_UINT16,
1487 "mOriginalTable->TableLength may exceed SMBIOS_TABLE_MAX_LENGTH"
1488 );
1489 DEBUG ((
1490 DEBUG_WARN,
1491 "OCSMB: SmbiosLookupHost entry has invalid table - %08X of %u bytes\n",
1492 mOriginalSmbios->TableAddress,
1493 mOriginalSmbios->TableLength
1494 ));
1495 mOriginalSmbios = NULL;
1496 }
1497 } else {
1498 DEBUG ((DEBUG_WARN, "OCSMB: SmbiosLookupHost failed to lookup SMBIOSv1 - %r\n", Status));
1499 }
1500
1501 //
1502 // Do similar checks on SMBIOSv3.
1503 //
1504 Status = EfiGetSystemConfigurationTable (
1506 (VOID **)&mOriginalSmbios3
1507 );
1508
1509 if (!EFI_ERROR (Status)) {
1510 if (mOriginalSmbios3->EntryPointLength < sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)) {
1511 DEBUG ((
1512 DEBUG_INFO,
1513 "OCSMB: SmbiosLookupHost v3 entry is too small - %u/%u bytes\n",
1514 mOriginalSmbios3->EntryPointLength,
1515 (UINT32)sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)
1516 ));
1517 mOriginalSmbios3 = NULL;
1518 } else if ((mOriginalSmbios3->TableAddress == 0) || (mOriginalSmbios3->TableMaximumSize == 0)) {
1520 sizeof (mOriginalSmbios3->TableMaximumSize) == sizeof (UINT32)
1521 && SMBIOS_3_0_TABLE_MAX_LENGTH == MAX_UINT32,
1522 "mOriginalSmbios3->TableMaximumSize may exceed SMBIOS_3_0_TABLE_MAX_LENGTH"
1523 );
1524 DEBUG ((
1525 DEBUG_INFO,
1526 "OCSMB: SmbiosLookupHost v3 entry has invalid table - %016LX of %u bytes\n",
1527 mOriginalSmbios3->TableAddress,
1528 mOriginalSmbios3->TableMaximumSize
1529 ));
1530 mOriginalSmbios3 = NULL;
1531 }
1532 } else {
1533 DEBUG ((DEBUG_INFO, "OCSMB: SmbiosLookupHost failed to lookup SMBIOSv3 - %r\n", Status));
1534 }
1535
1536 //
1537 // TODO: I think we may want to try harder.
1538 //
1539
1540 if (mOriginalSmbios != NULL) {
1541 mOriginalTableSize = mOriginalSmbios->TableLength;
1542 mOriginalTable.Raw = (UINT8 *)(UINTN)mOriginalSmbios->TableAddress;
1543 } else if (mOriginalSmbios3 != NULL) {
1544 mOriginalTableSize = mOriginalSmbios3->TableMaximumSize;
1545 mOriginalTable.Raw = (UINT8 *)(UINTN)mOriginalSmbios3->TableAddress;
1546 }
1547
1548 if (mOriginalSmbios != NULL) {
1549 DEBUG ((
1550 DEBUG_INFO,
1551 "OCSMB: Found DMI Anchor %p v%u.%u Table Address %08LX Length %04X\n",
1553 mOriginalSmbios->MajorVersion,
1554 mOriginalSmbios->MinorVersion,
1555 (UINT64)mOriginalSmbios->TableAddress,
1556 mOriginalSmbios->TableLength
1557 ));
1558 }
1559
1560 if (mOriginalSmbios3 != NULL) {
1561 DEBUG ((
1562 DEBUG_INFO,
1563 "OCSMB: Found DMI Anchor %p v%u.%u Table Address %08LX Length %04X\n",
1565 mOriginalSmbios3->MajorVersion,
1566 mOriginalSmbios3->MinorVersion,
1567 mOriginalSmbios3->TableAddress,
1568 mOriginalSmbios3->TableMaximumSize
1569 ));
1570 }
1571
1572 Status = SmbiosExtendTable (SmbiosTable, 1);
1573 if (EFI_ERROR (Status)) {
1574 DEBUG ((DEBUG_VERBOSE, "OCSMB: SmbiosLookupHost failed to initialise smbios table - %r\n", Status));
1575 }
1576
1577 return Status;
1578}
1579
1580VOID
1582 IN OUT OC_SMBIOS_TABLE *Table
1583 )
1584{
1585 if (Table->Table != NULL) {
1586 FreePool (Table->Table);
1587 }
1588
1589 ZeroMem (Table, sizeof (*Table));
1590}
1591
1592STATIC
1593EFI_STATUS
1595 IN UINT16 TableLength,
1596 IN OUT SMBIOS_TABLE_ENTRY_POINT **TableEntryPoint,
1597 IN OUT SMBIOS_TABLE_3_0_ENTRY_POINT **TableEntryPoint3,
1598 IN OUT VOID **TableAddress,
1599 IN OUT VOID **TableAddress3
1600 )
1601{
1602 UINT16 TablePages;
1603 EFI_STATUS Status;
1604 EFI_PHYSICAL_ADDRESS TmpAddr;
1605
1606 TablePages = EFI_SIZE_TO_PAGES (TableLength);
1607 *TableEntryPoint = NULL;
1608 *TableEntryPoint3 = NULL;
1609 *TableAddress = NULL;
1610 *TableAddress3 = NULL;
1611
1612 TmpAddr = (BASE_4GB - 1);
1613 Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, TablePages, &TmpAddr);
1614 if (!EFI_ERROR (Status)) {
1615 *TableAddress = (VOID *)(UINTN)TmpAddr;
1616 TmpAddr = (BASE_4GB - 1);
1617 Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, 1, &TmpAddr);
1618 if (!EFI_ERROR (Status)) {
1619 *TableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)TmpAddr;
1620 if (mOriginalSmbios3 != NULL) {
1621 TmpAddr = (BASE_4GB - 1);
1622 Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, 1, &TmpAddr);
1623 if (!EFI_ERROR (Status)) {
1624 *TableEntryPoint3 = (SMBIOS_TABLE_3_0_ENTRY_POINT *)(UINTN)TmpAddr;
1625 *TableAddress3 = *TableAddress;
1626 }
1627 }
1628 }
1629 }
1630
1631 if (EFI_ERROR (Status)) {
1632 DEBUG ((
1633 DEBUG_WARN,
1634 "OCSMB: SmbiosTableAllocate aborts as it cannot allocate SMBIOS pages with %d %d %d - %r\n",
1635 *TableEntryPoint != NULL,
1636 *TableAddress != NULL,
1637 *TableEntryPoint3 != NULL,
1638 Status
1639 ));
1640 if (*TableEntryPoint != NULL) {
1641 FreePages (*TableEntryPoint, 1);
1642 }
1643
1644 if (*TableEntryPoint3 != NULL) {
1645 FreePages (*TableEntryPoint3, 1);
1646 }
1647
1648 if (*TableAddress != NULL) {
1649 FreePages (*TableAddress, TablePages);
1650 }
1651
1652 return Status;
1653 }
1654
1655 ZeroMem (*TableAddress, TablePages * EFI_PAGE_SIZE);
1656 ZeroMem (*TableEntryPoint, EFI_PAGE_SIZE);
1657 if (mOriginalSmbios3 != NULL) {
1658 ZeroMem (*TableEntryPoint3, EFI_PAGE_SIZE);
1659 }
1660
1661 return EFI_SUCCESS;
1662}
1663
1664STATIC
1665EFI_STATUS
1667 IN OUT OC_SMBIOS_TABLE *SmbiosTable,
1668 IN OC_SMBIOS_UPDATE_MODE Mode
1669 )
1670{
1671 EFI_STATUS Status;
1672 UINT16 TableLength;
1673 SMBIOS_TABLE_ENTRY_POINT *TableEntryPoint;
1674 SMBIOS_TABLE_3_0_ENTRY_POINT *TableEntryPoint3;
1675 VOID *TableAddress;
1676 VOID *TableAddress3;
1677
1678 ASSERT (
1679 Mode == OcSmbiosUpdateCreate
1680 || Mode == OcSmbiosUpdateOverwrite
1681 || Mode == OcSmbiosUpdateCustom
1683 );
1684
1685 //
1686 // We check maximum table size during table extension, so this cast is valid.
1687 //
1688 TableLength = (UINT16)(SmbiosTable->CurrentPtr.Raw - SmbiosTable->Table);
1689
1690 DEBUG ((
1691 DEBUG_INFO,
1692 "OCSMB: Applying %u (%d) prev %p (%u/%u), %p (%u/%u)\n",
1693 (UINT32)TableLength,
1694 Mode,
1696 (UINT32)(mOriginalSmbios != NULL ? mOriginalSmbios->TableLength : 0),
1697 (UINT32)(mOriginalSmbios != NULL ? mOriginalSmbios->EntryPointLength : 0),
1699 (UINT32)(mOriginalSmbios3 != NULL ? mOriginalSmbios3->TableMaximumSize : 0),
1700 (UINT32)(mOriginalSmbios3 != NULL ? mOriginalSmbios3->EntryPointLength : 0)
1701 ));
1702
1703 if ((Mode == OcSmbiosUpdateTryOverwrite) || (Mode == OcSmbiosUpdateOverwrite)) {
1704 Status = SmbiosHandleLegacyRegion (TRUE);
1705
1706 if (EFI_ERROR (Status)) {
1707 DEBUG ((DEBUG_WARN, "OCSMB: Apply(%u) cannot handle legacy region - %r\n", Mode, Status));
1708 if (Mode == OcSmbiosUpdateOverwrite) {
1709 return Status;
1710 }
1711
1712 //
1713 // Fallback to create mode.
1714 //
1715 Mode = OcSmbiosUpdateCreate;
1716 } else if ( (mOriginalSmbios == NULL) || (TableLength > mOriginalSmbios->TableLength)
1717 || (mOriginalSmbios->EntryPointLength < sizeof (SMBIOS_TABLE_ENTRY_POINT)))
1718 {
1719 DEBUG ((
1720 DEBUG_WARN,
1721 "OCSMB: Apply(%u) cannot update old SMBIOS (%p, %u, %u) with %u\n",
1722 Mode,
1724 mOriginalSmbios != NULL ? mOriginalSmbios->TableLength : 0,
1725 mOriginalSmbios != NULL ? mOriginalSmbios->EntryPointLength : 0,
1726 TableLength
1727 ));
1728 if (Mode == OcSmbiosUpdateOverwrite) {
1729 return EFI_OUT_OF_RESOURCES;
1730 }
1731
1732 //
1733 // Fallback to create mode.
1734 //
1735 Mode = OcSmbiosUpdateCreate;
1736 } else if ((mOriginalSmbios3 != NULL) && ( (TableLength > mOriginalSmbios3->TableMaximumSize)
1737 || (mOriginalSmbios3->EntryPointLength < sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT))))
1738 {
1739 DEBUG ((
1740 DEBUG_INFO,
1741 "OCSMB: Apply(%u) cannot fit SMBIOSv3 (%p, %u, %u) with %u\n",
1742 Mode,
1744 mOriginalSmbios3->EntryPointLength,
1745 mOriginalSmbios3->TableMaximumSize,
1746 TableLength
1747 ));
1748 if (Mode == OcSmbiosUpdateOverwrite) {
1749 return EFI_OUT_OF_RESOURCES;
1750 }
1751
1752 Mode = OcSmbiosUpdateCreate;
1753 } else {
1755 }
1756 }
1757
1759
1760 if (Mode != OcSmbiosUpdateOverwrite) {
1761 Status = SmbiosTableAllocate (
1762 TableLength,
1763 &TableEntryPoint,
1764 &TableEntryPoint3,
1765 &TableAddress,
1766 &TableAddress3
1767 );
1768 if (EFI_ERROR (Status)) {
1769 return Status;
1770 }
1771 } else {
1772 TableEntryPoint = mOriginalSmbios;
1773 TableEntryPoint3 = mOriginalSmbios3;
1774 TableAddress = (VOID *)(UINTN)TableEntryPoint->TableAddress;
1775 ZeroMem (TableEntryPoint, sizeof (SMBIOS_TABLE_ENTRY_POINT));
1776 ZeroMem (TableAddress, TableEntryPoint->TableLength);
1777 if (TableEntryPoint3 != NULL) {
1778 TableAddress3 = (VOID *)(UINTN)TableEntryPoint3->TableAddress;
1779 ZeroMem (TableEntryPoint3, sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT));
1780 ZeroMem (TableAddress3, TableEntryPoint3->TableMaximumSize);
1781 } else {
1782 TableAddress3 = NULL;
1783 }
1784 }
1785
1786 CopyMem (
1787 TableAddress,
1788 SmbiosTable->Table,
1789 TableLength
1790 );
1791
1792 if ((TableAddress3 != NULL) && (TableAddress3 != TableAddress)) {
1793 CopyMem (
1794 TableAddress3,
1795 SmbiosTable->Table,
1796 TableLength
1797 );
1798 }
1799
1800 TableEntryPoint->AnchorString[0] = (UINT8)'_';
1801 TableEntryPoint->AnchorString[1] = (UINT8)'S';
1802 TableEntryPoint->AnchorString[2] = (UINT8)'M';
1803 TableEntryPoint->AnchorString[3] = (UINT8)'_';
1804 TableEntryPoint->EntryPointLength = sizeof (SMBIOS_TABLE_ENTRY_POINT);
1805 TableEntryPoint->MajorVersion = 3;
1806 TableEntryPoint->MinorVersion = 2;
1807 TableEntryPoint->MaxStructureSize = SmbiosTable->MaxStructureSize;
1808 TableEntryPoint->IntermediateAnchorString[0] = (UINT8)'_';
1809 TableEntryPoint->IntermediateAnchorString[1] = (UINT8)'D';
1810 TableEntryPoint->IntermediateAnchorString[2] = (UINT8)'M';
1811 TableEntryPoint->IntermediateAnchorString[3] = (UINT8)'I';
1812 TableEntryPoint->IntermediateAnchorString[4] = (UINT8)'_';
1813 TableEntryPoint->TableLength = TableLength;
1814 TableEntryPoint->TableAddress = (UINT32)(UINTN)TableAddress;
1815 TableEntryPoint->NumberOfSmbiosStructures = SmbiosTable->NumberOfStructures;
1816 TableEntryPoint->SmbiosBcdRevision = 0x32;
1817 TableEntryPoint->IntermediateChecksum = CalculateCheckSum8 (
1818 (UINT8 *)TableEntryPoint + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString),
1819 TableEntryPoint->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)
1820 );
1821 TableEntryPoint->EntryPointStructureChecksum = CalculateCheckSum8 (
1822 (UINT8 *)TableEntryPoint,
1823 TableEntryPoint->EntryPointLength
1824 );
1825
1826 if (TableEntryPoint3 != NULL) {
1827 TableEntryPoint3->AnchorString[0] = (UINT8)'_';
1828 TableEntryPoint3->AnchorString[1] = (UINT8)'S';
1829 TableEntryPoint3->AnchorString[2] = (UINT8)'M';
1830 TableEntryPoint3->AnchorString[3] = (UINT8)'3';
1831 TableEntryPoint3->AnchorString[4] = (UINT8)'_';
1832 TableEntryPoint3->EntryPointLength = sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT);
1833 TableEntryPoint3->MajorVersion = 3;
1834 TableEntryPoint3->MinorVersion = 2;
1835 TableEntryPoint3->EntryPointRevision = 1;
1836 TableEntryPoint3->TableMaximumSize = TableLength;
1837 TableEntryPoint3->TableAddress = (UINT64)(UINTN)TableAddress;
1838 TableEntryPoint3->EntryPointStructureChecksum = CalculateCheckSum8 (
1839 (UINT8 *)TableEntryPoint3,
1840 TableEntryPoint3->EntryPointLength
1841 );
1842 }
1843
1844 DEBUG ((
1845 DEBUG_INFO,
1846 "OCSMB: Patched %p v%d.%d Table Address %08LX Length %04X %X %X\n",
1847 TableEntryPoint,
1848 TableEntryPoint->MajorVersion,
1849 TableEntryPoint->MinorVersion,
1850 (UINT64)TableEntryPoint->TableAddress,
1851 TableEntryPoint->TableLength,
1852 TableEntryPoint->EntryPointStructureChecksum,
1853 TableEntryPoint->IntermediateChecksum
1854 ));
1855
1856 if (Mode == OcSmbiosUpdateOverwrite) {
1858 } else {
1859 if (TableEntryPoint3 != NULL) {
1860 Status = gBS->InstallConfigurationTable (
1862 TableEntryPoint3
1863 );
1864
1865 if (EFI_ERROR (Status)) {
1866 DEBUG ((DEBUG_WARN, "OCSMB: Failed to install v3 table - %r\n", Status));
1867 }
1868 }
1869
1870 Status = gBS->InstallConfigurationTable (
1872 TableEntryPoint
1873 );
1874
1875 if (EFI_ERROR (Status)) {
1876 DEBUG ((DEBUG_WARN, "OCSMB: Failed to install v1 table - %r\n", Status));
1877 return Status;
1878 }
1879 }
1880
1881 return EFI_SUCCESS;
1882}
1883
1884VOID
1886 IN CONST UINT8 *SmcRevision,
1887 OUT UINT8 *SmcVersion
1888 )
1889{
1890 UINT8 Temp;
1891 UINT8 Index;
1892
1894
1895 Temp = SmcRevision[0];
1896 Index = 0;
1897
1898 if (Temp < 0x10) {
1899 SmcVersion[Index] = (Temp + 0x30);
1900 ++Index;
1901 } else {
1902 SmcVersion[Index] = ((Temp >> 4) | 0x30);
1903 ++Index;
1904
1905 SmcVersion[Index + 1] = ((Temp & 0x0F) | 0x30);
1906 ++Index;
1907 }
1908
1909 SmcVersion[Index] = 0x2E;
1910 ++Index;
1911
1912 Temp = SmcRevision[1];
1913
1914 if (Temp < 0x10) {
1915 SmcVersion[Index] = (Temp + 0x30);
1916 ++Index;
1917 } else {
1918 SmcVersion[Index] = ((Temp >> 4) | 0x30);
1919 ++Index;
1920
1921 SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
1922 ++Index;
1923 }
1924
1925 Temp = SmcRevision[2];
1926
1927 if ((Temp & 0xF0) != 0) {
1928 if (Temp >= 0xA0) {
1929 SmcVersion[Index] = ((Temp >> 4) + 0x37);
1930 ++Index;
1931 } else {
1932 SmcVersion[Index] = ((Temp >> 4) | 0x30);
1933 ++Index;
1934 }
1935
1936 Temp &= 0x0F;
1937
1938 if (Temp >= 0x0A) {
1939 SmcVersion[Index] = (Temp + 0x37);
1940 ++Index;
1941 } else {
1942 SmcVersion[Index] = (Temp | 0x30);
1943 ++Index;
1944 }
1945 } else {
1946 if (Temp >= 0x0A) {
1947 SmcVersion[Index] = (Temp + 0x37);
1948 ++Index;
1949 } else {
1950 SmcVersion[Index] = (Temp + 0x30);
1951 ++Index;
1952 }
1953 }
1954
1955 Temp = SmcRevision[3];
1956
1957 if (Temp < 0x10) {
1958 SmcVersion[Index] = (Temp + 0x30);
1959 ++Index;
1960 } else {
1961 SmcVersion[Index] = ((Temp >> 4) | 0x30);
1962 ++Index;
1963
1964 SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
1965 ++Index;
1966 }
1967
1968 Temp = SmcRevision[4];
1969
1970 if (Temp < 0x10) {
1971 SmcVersion[Index] = (Temp + 0x30);
1972 ++Index;
1973 } else {
1974 SmcVersion[Index] = ((Temp >> 4) | 0x30);
1975 ++Index;
1976
1977 SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
1978 ++Index;
1979 }
1980
1981 Temp = SmcRevision[5];
1982
1983 if (Temp < 0x10) {
1984 SmcVersion[Index] = (Temp + 0x30);
1985 ++Index;
1986 } else {
1987 SmcVersion[Index] = ((Temp >> 4) | 0x30);
1988 ++Index;
1989
1990 SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
1991 ++Index;
1992 }
1993}
1994
1997 IN CONST CHAR8 *UpdateMode
1998 )
1999{
2000 if (AsciiStrCmp (UpdateMode, "TryOverwrite") == 0) {
2002 }
2003
2004 if (AsciiStrCmp (UpdateMode, "Create") == 0) {
2005 return OcSmbiosUpdateCreate;
2006 }
2007
2008 if (AsciiStrCmp (UpdateMode, "Overwrite") == 0) {
2010 }
2011
2012 if (AsciiStrCmp (UpdateMode, "Custom") == 0) {
2013 return OcSmbiosUpdateCustom;
2014 }
2015
2016 DEBUG ((DEBUG_INFO, "OCSMB: Invalid SMBIOS update mode %a\n", UpdateMode));
2017 return OcSmbiosUpdateCreate;
2018}
2019
2020EFI_STATUS
2022 IN OUT OC_SMBIOS_TABLE *SmbiosTable,
2023 IN OC_SMBIOS_DATA *Data,
2024 IN OC_SMBIOS_UPDATE_MODE Mode,
2025 IN OC_CPU_INFO *CpuInfo
2026 )
2027{
2028 EFI_STATUS Status;
2029
2031 APPLE_SMBIOS_STRUCTURE_POINTER MemoryArrayAddress;
2032 APPLE_SMBIOS_STRUCTURE_POINTER MemoryDeviceInfo;
2033 APPLE_SMBIOS_STRUCTURE_POINTER MemoryDeviceAddress;
2034 SMBIOS_HANDLE MemoryArrayHandle;
2035 SMBIOS_HANDLE MemoryDeviceHandle;
2036 UINT16 NumMemoryArrays;
2037 UINT16 NumMemoryArrayMapped;
2038 UINT16 NumMemoryDevices;
2039 UINT16 NumMemoryDeviceMapped;
2040 UINT16 MemoryArrayNo;
2041 UINT16 MemoryArrayMappedNo;
2042 UINT16 MemoryDeviceNo;
2043 UINT16 MemoryDeviceMappedNo;
2044 UINT16 MemoryArrayNewIndex;
2045 UINT16 MemoryArrayMappedNewIndex;
2046 UINT16 MemoryDeviceNewIndex;
2047 UINT16 MemoryDeviceMappedNewIndex;
2048 OC_SMBIOS_MAPPING *Mapping;
2049 UINT16 MappingNum;
2050
2051 BOOLEAN HasAppleSMBIOS;
2052
2053 ASSERT (Data != NULL);
2054
2055 Mapping = AllocatePool (OC_SMBIOS_MAX_MAPPING * sizeof (*Mapping));
2056 if (Mapping == NULL) {
2057 DEBUG ((DEBUG_WARN, "OCSMB: Cannot allocate mapping table\n"));
2058 return EFI_OUT_OF_RESOURCES;
2059 }
2060
2061 MappingNum = 0;
2062
2063 HasAppleSMBIOS = PatchBiosInformation (SmbiosTable, Data);
2064 PatchSystemInformation (SmbiosTable, Data);
2065 PatchBaseboardInformation (SmbiosTable, Data);
2066 PatchSystemEnclosure (SmbiosTable, Data);
2067 PatchProcessorInformation (SmbiosTable, Data, CpuInfo);
2068 PatchSystemPorts (SmbiosTable, Data);
2069 PatchSystemSlots (SmbiosTable, Data);
2070
2071 //
2072 // Create new memory tables if custom memory is desired.
2073 // Otherwise we'll patch the existing memory information.
2074 //
2075 if (Data->HasCustomMemory) {
2077 SmbiosTable,
2078 Data,
2079 &MemoryArrayHandle
2080 );
2081
2082 //
2083 // Generate new memory device tables (type 17) for this memory array.
2084 //
2085 for (MemoryDeviceNo = 0; MemoryDeviceNo < Data->MemoryDevicesCount; MemoryDeviceNo++) {
2087 SmbiosTable,
2088 Data,
2089 &Data->MemoryDevices[MemoryDeviceNo],
2090 MemoryArrayHandle,
2091 MemoryDeviceNo + 1,
2092 &MemoryDeviceHandle
2093 );
2094 }
2095 } else {
2096 NumMemoryArrays = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY);
2097 NumMemoryArrayMapped = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS);
2098 NumMemoryDevices = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_MEMORY_DEVICE);
2099 NumMemoryDeviceMapped = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS);
2100
2101 MemoryArrayNewIndex = 1;
2102 MemoryArrayMappedNewIndex = 1;
2103 MemoryDeviceNewIndex = 1;
2104 MemoryDeviceMappedNewIndex = 1;
2105
2106 for (MemoryArrayNo = 0; MemoryArrayNo < NumMemoryArrays; MemoryArrayNo++) {
2107 MemoryArray = SmbiosGetOriginalStructure (SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, MemoryArrayNo + 1);
2108
2109 //
2110 // We want to exclude any non-system memory tables, such as system ROM flash areas.
2111 //
2112 if ( (MemoryArray.Raw == NULL)
2113 || (MemoryArray.Standard.Type16->Use != MemoryArrayUseSystemMemory))
2114 {
2115 continue;
2116 }
2117
2118 //
2119 // Generate new type 16 table for memory array.
2120 //
2122 SmbiosTable,
2123 Data,
2124 MemoryArray,
2125 MemoryArrayNewIndex,
2126 &MemoryArrayHandle
2127 );
2128 MemoryArrayNewIndex++;
2129
2130 //
2131 // Generate new memory mapped address tables (type 19) for this memory array.
2132 //
2133 for (MemoryArrayMappedNo = 0; MemoryArrayMappedNo < NumMemoryArrayMapped; MemoryArrayMappedNo++) {
2134 MemoryArrayAddress = SmbiosGetOriginalStructure (SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, MemoryArrayMappedNo + 1);
2135
2136 if ( (MemoryArrayAddress.Raw == NULL)
2137 || (MemoryArrayAddress.Standard.Type19->MemoryArrayHandle != MemoryArray.Standard.Type16->Hdr.Handle))
2138 {
2139 continue;
2140 }
2141
2143 SmbiosTable,
2144 Data,
2145 MemoryArrayHandle,
2146 MemoryArrayAddress,
2147 MemoryArrayMappedNewIndex,
2148 Mapping,
2149 &MappingNum
2150 );
2151 MemoryArrayMappedNewIndex++;
2152 }
2153
2154 //
2155 // Generate new memory device tables (type 17) for this memory array.
2156 //
2157 for (MemoryDeviceNo = 0; MemoryDeviceNo < NumMemoryDevices; MemoryDeviceNo++) {
2158 MemoryDeviceInfo = SmbiosGetOriginalStructure (SMBIOS_TYPE_MEMORY_DEVICE, MemoryDeviceNo + 1);
2159
2160 if ( (MemoryDeviceInfo.Raw == NULL)
2161 || (MemoryDeviceInfo.Standard.Type17->MemoryArrayHandle != MemoryArray.Standard.Type16->Hdr.Handle))
2162 {
2163 continue;
2164 }
2165
2167 SmbiosTable,
2168 Data,
2169 MemoryArrayHandle,
2170 MemoryDeviceInfo,
2171 MemoryDeviceNewIndex,
2172 &MemoryDeviceHandle
2173 );
2174 MemoryDeviceNewIndex++;
2175
2176 //
2177 // Generate a memory device mapping table (type 20) for each occupied memory device.
2178 //
2179 for (MemoryDeviceMappedNo = 0; MemoryDeviceMappedNo < NumMemoryDeviceMapped; MemoryDeviceMappedNo++) {
2180 MemoryDeviceAddress = SmbiosGetOriginalStructure (SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS, MemoryDeviceMappedNo + 1);
2181
2182 if ( (MemoryDeviceAddress.Raw != NULL)
2183 && SMBIOS_ACCESSIBLE (MemoryDeviceAddress, Standard.Type20->MemoryDeviceHandle)
2184 && (MemoryDeviceAddress.Standard.Type20->MemoryDeviceHandle ==
2185 MemoryDeviceInfo.Standard.Type17->Hdr.Handle))
2186 {
2188 SmbiosTable,
2189 Data,
2190 MemoryDeviceAddress,
2191 MemoryDeviceMappedNewIndex,
2192 MemoryDeviceHandle,
2193 Mapping,
2194 MappingNum
2195 );
2196 MemoryDeviceMappedNewIndex++;
2197 }
2198 }
2199 }
2200 }
2201 }
2202
2203 PatchPortableBatteryDevice (SmbiosTable, Data);
2204 PatchBootInformation (SmbiosTable, Data);
2205 CreateAppleProcessorType (SmbiosTable, Data, CpuInfo);
2206 CreateAppleProcessorSpeed (SmbiosTable, Data, CpuInfo);
2207 CreateOrPatchAppleFirmwareVolume (SmbiosTable, Data, HasAppleSMBIOS);
2208 CreateOrPatchApplePlatformFeature (SmbiosTable, Data, HasAppleSMBIOS);
2209 CreateOrPatchAppleSmcInformation (SmbiosTable, Data, HasAppleSMBIOS);
2210 CreateSmBiosEndOfTable (SmbiosTable, Data);
2211
2212 FreePool (Mapping);
2213
2214 Status = SmbiosTableApply (SmbiosTable, Mode);
2215
2216 return Status;
2217}
2218
2219VOID
2221 IN OC_SMBIOS_TABLE *SmbiosTable,
2222 OUT CHAR8 *ProductName OPTIONAL,
2223 OUT CHAR8 *SerialNumber OPTIONAL,
2224 OUT EFI_GUID *SystemUuid OPTIONAL,
2225 OUT CHAR8 *Mlb OPTIONAL,
2226 OUT UINT8 *Rom OPTIONAL,
2227 IN BOOLEAN UuidIsRawEncoded,
2228 IN BOOLEAN UseVariableStorage
2229 )
2230{
2231 EFI_STATUS Status;
2232 CONST CHAR8 *SmProductName;
2233 CONST CHAR8 *SmManufacturer;
2234 CONST CHAR8 *SmBoard;
2235 CONST CHAR8 *SmTmp;
2236 UINTN Index;
2237 UINTN TmpSize;
2238 UINT32 MinCount;
2239 UINT32 MaxCount;
2240 UINT8 *UuidWalker;
2242
2243 SmProductName = NULL;
2244 SmManufacturer = NULL;
2245 SmBoard = NULL;
2246
2247 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
2248 if (Original.Raw != NULL) {
2249 if (SMBIOS_ACCESSIBLE (Original, Standard.Type1->ProductName)) {
2250 SmProductName = SmbiosGetString (Original, Original.Standard.Type1->ProductName);
2251 if ((SmProductName != NULL) && (ProductName != NULL)) {
2252 Status = AsciiStrCpyS (ProductName, OC_OEM_NAME_MAX, SmProductName);
2253 if (EFI_ERROR (Status)) {
2254 DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS product name %a\n", SmProductName));
2255 }
2256 }
2257 }
2258
2259 if ((SerialNumber != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type1->SerialNumber)) {
2260 SmTmp = SmbiosGetString (Original, Original.Standard.Type1->SerialNumber);
2261 if (SmTmp != NULL) {
2262 Status = AsciiStrCpyS (SerialNumber, OC_OEM_SERIAL_MAX, SmTmp);
2263 if (EFI_ERROR (Status)) {
2264 DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS product serial %a\n", SmTmp));
2265 }
2266 }
2267 }
2268
2269 if ((SystemUuid != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type1->Uuid)) {
2270 MinCount = 0;
2271 MaxCount = 0;
2272 UuidWalker = (UINT8 *)&Original.Standard.Type1->Uuid;
2273 for (Index = 0; Index < sizeof (Original.Standard.Type1->Uuid); ++Index) {
2274 if (UuidWalker[Index] == 0x00) {
2275 ++MinCount;
2276 } else if (UuidWalker[Index] == 0xFF) {
2277 ++MaxCount;
2278 }
2279 }
2280
2281 if ((MinCount < 4) && (MaxCount < 4)) {
2282 CopyGuid (SystemUuid, &Original.Standard.Type1->Uuid);
2283 //
2284 // Convert LE to RAW (assuming SMBIOS stores in LE format).
2285 //
2286 if (!UuidIsRawEncoded) {
2287 SystemUuid->Data1 = SwapBytes32 (SystemUuid->Data1);
2288 SystemUuid->Data2 = SwapBytes16 (SystemUuid->Data2);
2289 SystemUuid->Data3 = SwapBytes16 (SystemUuid->Data3);
2290 }
2291 } else {
2292 DEBUG ((
2293 DEBUG_WARN,
2294 "OCSMB: Ignoring UUID %g due to low entropy\n",
2295 &Original.Standard.Type1->Uuid
2296 ));
2297 }
2298 }
2299 }
2300
2301 Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BASEBOARD_INFORMATION, 1);
2302 if (Original.Raw != NULL) {
2303 if (SMBIOS_ACCESSIBLE (Original, Standard.Type2->Manufacturer)) {
2304 SmManufacturer = SmbiosGetString (Original, Original.Standard.Type2->Manufacturer);
2305 }
2306
2307 if (SMBIOS_ACCESSIBLE (Original, Standard.Type2->ProductName)) {
2308 SmBoard = SmbiosGetString (Original, Original.Standard.Type2->ProductName);
2309 }
2310
2311 if ((Mlb != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type2->SerialNumber)) {
2312 SmTmp = SmbiosGetString (Original, Original.Standard.Type2->SerialNumber);
2313 if (SmTmp != NULL) {
2314 Status = AsciiStrCpyS (Mlb, OC_OEM_SERIAL_MAX, SmTmp);
2315 if (EFI_ERROR (Status)) {
2316 DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS board serial %a\n", SmTmp));
2317 }
2318 }
2319 }
2320 }
2321
2322 if (Mlb != NULL) {
2323 TmpSize = OC_OEM_SERIAL_MAX - 1;
2324 Status = gRT->GetVariable (
2325 L"MLB",
2327 NULL,
2328 &TmpSize,
2329 Mlb
2330 );
2331 if (!EFI_ERROR (Status)) {
2332 ZeroMem (Mlb + TmpSize, OC_OEM_SERIAL_MAX - TmpSize);
2333 DEBUG ((DEBUG_INFO, "OCSMB: MLB from NVRAM took precedence: %a\n", Mlb));
2334 }
2335 }
2336
2337 if (SerialNumber != NULL) {
2338 TmpSize = OC_OEM_SERIAL_MAX - 1;
2339 Status = gRT->GetVariable (
2340 L"SSN",
2342 NULL,
2343 &TmpSize,
2344 SerialNumber
2345 );
2346 if (!EFI_ERROR (Status)) {
2347 ZeroMem (SerialNumber + TmpSize, OC_OEM_SERIAL_MAX - TmpSize);
2348 DEBUG ((DEBUG_INFO, "OCSMB: SSN from NVRAM took precedence: %a\n", SerialNumber));
2349 }
2350 }
2351
2352 if (Rom != NULL) {
2353 TmpSize = OC_OEM_ROM_MAX;
2354 Status = gRT->GetVariable (
2355 L"ROM",
2357 NULL,
2358 &TmpSize,
2359 Rom
2360 );
2361 if (!EFI_ERROR (Status) && (TmpSize != OC_OEM_ROM_MAX)) {
2362 ZeroMem (Rom, OC_OEM_ROM_MAX);
2363 }
2364 }
2365
2366 if (SystemUuid != NULL) {
2367 TmpSize = sizeof (EFI_GUID);
2368 Status = gRT->GetVariable (
2369 L"system-id",
2371 NULL,
2372 &TmpSize,
2373 SystemUuid
2374 );
2375 if (!EFI_ERROR (Status) && (TmpSize == sizeof (EFI_GUID))) {
2376 DEBUG ((DEBUG_INFO, "OCSMB: UUID from NVRAM took precedence: %g\n", SystemUuid));
2377 } else if (TmpSize != sizeof (EFI_GUID)) {
2378 ZeroMem (SystemUuid, sizeof (EFI_GUID));
2379 }
2380 }
2381
2382 DEBUG ((
2383 DEBUG_INFO,
2384 "OCSMB: Current SMBIOS %a (%a made by %a)\n",
2385 SmProductName,
2386 SmBoard,
2387 SmManufacturer
2388 ));
2389
2390 if ((ProductName != NULL) && (SmProductName != NULL)) {
2391 Status = AsciiStrCpyS (ProductName, OC_OEM_NAME_MAX, SmProductName);
2392 if (EFI_ERROR (Status)) {
2393 DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS product name %a\n", SmProductName));
2394 }
2395 }
2396
2397 if (UseVariableStorage) {
2398 if (SmProductName != NULL) {
2399 Status = OcSetSystemVariable (
2401 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
2402 AsciiStrLen (SmProductName),
2403 (VOID *)SmProductName,
2404 NULL
2405 );
2406 if (EFI_ERROR (Status)) {
2407 DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM product\n"));
2408 }
2409 }
2410
2411 if ((SmManufacturer != NULL) && (SmBoard != NULL)) {
2412 Status = OcSetSystemVariable (
2414 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
2415 AsciiStrLen (SmManufacturer),
2416 (VOID *)SmManufacturer,
2417 NULL
2418 );
2419 if (EFI_ERROR (Status)) {
2420 DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board manufacturer - %r\n", Status));
2421 }
2422
2423 Status = OcSetSystemVariable (
2425 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
2426 AsciiStrLen (SmBoard),
2427 (VOID *)SmBoard,
2428 NULL
2429 );
2430 if (EFI_ERROR (Status)) {
2431 DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board - %r\n", Status));
2432 }
2433 }
2434 }
2435}
UINT8 Vendor[11]
This is always 0x43f and can be used to identify an Apple Remote.
Definition AppleNec.h:64
#define APPLE_SMBIOS_SMC_VERSION_SIZE
Definition AppleSmBios.h:29
#define APPLE_SMBIOS_TYPE_PROCESSOR_BUS_SPEED
Definition AppleSmBios.h:23
#define APPLE_SMBIOS_TYPE_FIRMWARE_INFORMATION
Definition AppleSmBios.h:20
UINT8 SmcVersion[APPLE_SMBIOS_SMC_VERSION_SIZE]
UINT32 FirmwareFeatures
Definition AppleSmBios.h:54
#define APPLE_SMBIOS_TYPE_PROCESSOR_TYPE
Definition AppleSmBios.h:22
#define APPLE_SMBIOS_TYPE_SMC_INFORMATION
Definition AppleSmBios.h:25
UINT32 FirmwareFeaturesMask
Definition AppleSmBios.h:55
#define APPLE_SMBIOS_TYPE_PLATFORM_FEATURE
Definition AppleSmBios.h:24
UINT32 ExtendedFirmwareFeaturesMask
Definition AppleSmBios.h:59
UINT32 ExtendedFirmwareFeatures
Definition AppleSmBios.h:58
EFI_GUID gAppleVendorVariableGuid
STATIC_ASSERT(BYTES_PER_PIXEL==sizeof(UINT32), "Non 4-byte pixels are unsupported!")
EFI_BOOT_SERVICES * gBS
UINT16 OcCpuFrequencyToDisplayFrequency(IN UINT64 Frequency)
#define OC_OEM_ROM_MAX
#define OC_OEM_NAME_MAX
#define OC_OEM_SERIAL_MAX
EFI_STATUS LegacyRegionLock(IN UINT32 LegacyAddress, IN UINT32 LegacyLength)
EFI_STATUS LegacyRegionUnlock(IN UINT32 LegacyAddress, IN UINT32 LegacyLength)
EFI_GUID gOcCustomSmbiosTableGuid
EFI_GUID gOcCustomSmbios3TableGuid
enum OC_SMBIOS_UPDATE_MODE_ OC_SMBIOS_UPDATE_MODE
@ OcSmbiosUpdateOverwrite
@ OcSmbiosUpdateTryOverwrite
@ OcSmbiosUpdateCustom
@ OcSmbiosUpdateCreate
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
#define OC_OEM_PRODUCT_VARIABLE_NAME
Definition OcVariable.h:60
#define OC_OEM_BOARD_VARIABLE_NAME
Definition OcVariable.h:70
#define OC_OEM_VENDOR_VARIABLE_NAME
Definition OcVariable.h:65
EFI_STATUS OcSetSystemVariable(IN CHAR16 *VariableName, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data, IN EFI_GUID *VendorGuid OPTIONAL)
CHAR8 * SmbiosGetString(IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable, IN SMBIOS_TABLE_STRING String)
EFI_STATUS SmbiosExtendTable(IN OUT OC_SMBIOS_TABLE *Table, IN UINT32 Size)
EFI_STATUS SmbiosInitialiseStruct(IN OUT OC_SMBIOS_TABLE *Table, IN SMBIOS_TYPE Type, IN UINT8 MinLength, IN UINT16 Index)
APPLE_SMBIOS_STRUCTURE_POINTER SmbiosGetStructureOfType(IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable, IN UINT32 SmbiosTableSize, IN SMBIOS_TYPE Type, IN UINT16 Index)
UINT8 SmbiosOverrideString(IN OC_SMBIOS_TABLE *Table, IN CONST CHAR8 *Override OPTIONAL, IN UINT8 *Index)
VOID SmbiosFinaliseStruct(IN OUT OC_SMBIOS_TABLE *Table)
UINT16 SmbiosGetStructureCount(IN APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable, IN UINT32 SmbiosTableSize, IN SMBIOS_TYPE Type)
#define OC_SMBIOS_MAX_MAPPING
@ OcSmbiosSystemEnclosureHandle
@ OcSmbiosInvalidHandle
@ OcSmbiosAutomaticHandle
OC_SMBIOS_UPDATE_MODE OcSmbiosGetUpdateMode(IN CONST CHAR8 *UpdateMode)
STATIC VOID PatchPortableBatteryDevice(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC APPLE_SMBIOS_STRUCTURE_POINTER SmbiosGetOriginalStructure(IN SMBIOS_TYPE Type, IN UINT16 Index)
Definition SmbiosPatch.c:84
STATIC UINT8 SmbiosGetFormFactor(IN OC_SMBIOS_DATA *Data, IN APPLE_SMBIOS_STRUCTURE_POINTER Original)
VOID OcSmbiosExtractOemInfo(IN OC_SMBIOS_TABLE *SmbiosTable, OUT CHAR8 *ProductName OPTIONAL, OUT CHAR8 *SerialNumber OPTIONAL, OUT EFI_GUID *SystemUuid OPTIONAL, OUT CHAR8 *Mlb OPTIONAL, OUT UINT8 *Rom OPTIONAL, IN BOOLEAN UuidIsRawEncoded, IN BOOLEAN UseVariableStorage)
VOID OcSmbiosTableFree(IN OUT OC_SMBIOS_TABLE *Table)
STATIC VOID PatchSystemInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC SMBIOS_TABLE_3_0_ENTRY_POINT * mOriginalSmbios3
Definition SmbiosPatch.c:47
STATIC EFI_STATUS SmbiosHandleLegacyRegion(BOOLEAN Unlock)
STATIC VOID PatchMemoryDevice(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN SMBIOS_HANDLE MemoryArrayHandle, IN APPLE_SMBIOS_STRUCTURE_POINTER Original, IN UINT16 Index, OUT SMBIOS_HANDLE *Handle)
EFI_STATUS OcSmbiosCreate(IN OUT OC_SMBIOS_TABLE *SmbiosTable, IN OC_SMBIOS_DATA *Data, IN OC_SMBIOS_UPDATE_MODE Mode, IN OC_CPU_INFO *CpuInfo)
#define SMBIOS_OVERRIDE_S(Table, Field, Original, Value, Index, Fallback)
Definition SmbiosPatch.c:51
STATIC VOID CreateAppleProcessorType(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN OC_CPU_INFO *CpuInfo)
#define SMBIOS_ACCESSIBLE(Table, Field)
Definition SmbiosPatch.c:79
STATIC SMBIOS_TABLE_ENTRY_POINT * mOriginalSmbios
Definition SmbiosPatch.c:46
STATIC BOOLEAN SmbiosHasValidOemFormFactor(IN APPLE_SMBIOS_STRUCTURE_POINTER Original)
#define SMBIOS_OVERRIDE_V(Table, Field, Original, Value, Fallback)
Definition SmbiosPatch.c:65
STATIC VOID PatchMemoryMappedDevice(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN APPLE_SMBIOS_STRUCTURE_POINTER Original, IN UINT16 Index, IN SMBIOS_HANDLE MemoryDeviceHandle, IN OC_SMBIOS_MAPPING *Mapping, IN UINT16 MappingNum)
STATIC APPLE_SMBIOS_STRUCTURE_POINTER mOriginalTable
Definition SmbiosPatch.c:48
STATIC EFI_STATUS SmbiosTableAllocate(IN UINT16 TableLength, IN OUT SMBIOS_TABLE_ENTRY_POINT **TableEntryPoint, IN OUT SMBIOS_TABLE_3_0_ENTRY_POINT **TableEntryPoint3, IN OUT VOID **TableAddress, IN OUT VOID **TableAddress3)
STATIC VOID CreateSmBiosEndOfTable(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC VOID PatchSystemPorts(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC VOID PatchBaseboardInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC EFI_STATUS SmbiosTableApply(IN OUT OC_SMBIOS_TABLE *SmbiosTable, IN OC_SMBIOS_UPDATE_MODE Mode)
STATIC VOID CreateMemoryDevice(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN OC_SMBIOS_MEMORY_DEVICE_DATA *DeviceData, IN SMBIOS_HANDLE MemoryArrayHandle, IN UINT16 Index, OUT SMBIOS_HANDLE *Handle)
EFI_STATUS OcSmbiosTablePrepare(IN OUT OC_SMBIOS_TABLE *SmbiosTable)
STATIC VOID CreateMemoryArray(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, OUT SMBIOS_HANDLE *Handle)
STATIC VOID CreateOrPatchAppleSmcInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN BOOLEAN HasAppleSMBIOS)
STATIC VOID CreateOrPatchApplePlatformFeature(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN BOOLEAN HasAppleSMBIOS)
STATIC VOID PatchBootInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC VOID CreateAppleProcessorSpeed(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN OC_CPU_INFO *CpuInfo)
STATIC VOID PatchSystemSlots(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC VOID PatchMemoryArray(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN APPLE_SMBIOS_STRUCTURE_POINTER Original, IN UINT16 Index, OUT SMBIOS_HANDLE *Handle)
STATIC UINT16 SmbiosGetOriginalStructureCount(IN SMBIOS_TYPE Type)
Definition SmbiosPatch.c:98
STATIC VOID PatchMemoryMappedAddress(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN SMBIOS_HANDLE MemoryArrayHandle, IN APPLE_SMBIOS_STRUCTURE_POINTER Original, IN UINT16 Index, IN OUT OC_SMBIOS_MAPPING *Mapping, IN OUT UINT16 *MappingNum)
STATIC VOID PatchCacheInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN OUT UINT16 *Index, IN SMBIOS_HANDLE OriginalHandle, OUT SMBIOS_HANDLE *NewHandle)
STATIC UINT32 mOriginalTableSize
Definition SmbiosPatch.c:49
STATIC VOID PatchProcessorInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN OC_CPU_INFO *CpuInfo)
STATIC VOID PatchSystemEnclosure(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC BOOLEAN PatchBiosInformation(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data)
STATIC VOID CreateOrPatchAppleFirmwareVolume(IN OUT OC_SMBIOS_TABLE *Table, IN OC_SMBIOS_DATA *Data, IN BOOLEAN HasAppleSMBIOS)
VOID OcSmbiosGetSmcVersion(IN CONST UINT8 *SmcRevision, OUT UINT8 *SmcVersion)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
EFI_GUID gEfiPciRootBridgeIoProtocolGuid
EFI_GUID gEfiSmbios3TableGuid
EFI_GUID gEfiSmbiosTableGuid
#define ASSERT(x)
Definition coder.h:55
SMBIOS_STRUCTURE_POINTER Standard