1 /** @file 2 3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 4 5 This program and the accompanying materials are licensed and made available under 7 the terms and conditions of the BSD License that accompanies this distribution. 9 The full text of the license may be found at 11 http://opensource.org/licenses/bsd-license.php. 13 15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 21 23 24 Module Name: 25 26 SetupInfoRecords.c 27 28 Abstract: 29 30 This is the filter driver to retrieve data hub entries. 31 32 Revision History: 33 --*/ 34 35 #include "PlatformSetupDxe.h" 36 #include <Protocol/LegacyBios.h> 37 #include <Protocol/PciRootBridgeIo.h> 38 #include <Protocol/SimpleNetwork.h> 39 #include <Protocol/DevicePath.h> 40 #include <Protocol/DiskInfo.h> 41 #include <Protocol/IdeControllerInit.h> 42 #include <Protocol/MpService.h> 43 #include <Protocol/PchPlatformPolicy.h> 44 #include <Protocol/CpuIo2.h> 45 #include <Protocol/Smbios.h> 46 #include <IndustryStandard/SmBios.h> 47 #include <Library/IoLib.h> 48 #include <Library/I2CLib.h> 49 #include <Guid/GlobalVariable.h> 50 51 #include "Valleyview.h" 52 #include "VlvAccess.h" 53 #include "PchAccess.h" 54 #include "SetupMode.h" 55 #include "PchCommonDefinitions.h" 56 #include <PlatformBaseAddresses.h> 57 58 59 typedef struct { 60 UINT8 ID; 61 CHAR8 String[16]; 62 } VLV_REV; 63 64 typedef struct { 65 UINT8 RevId; 66 CHAR8 String[16]; 67 } SB_REV; 68 69 // 70 // Silicon Steppings 71 // 72 SB_REV SBRevisionTable[] = { 73 {V_PCH_LPC_RID_0, "(A0 Stepping)"}, 74 {V_PCH_LPC_RID_1, "(A0 Stepping)"}, 75 {V_PCH_LPC_RID_2, "(A1 Stepping)"}, 76 {V_PCH_LPC_RID_3, "(A1 Stepping)"}, 77 {V_PCH_LPC_RID_4, "(B0 Stepping)"}, 78 {V_PCH_LPC_RID_5, "(B0 Stepping)"}, 79 {V_PCH_LPC_RID_6, "(B1 Stepping)"}, 80 {V_PCH_LPC_RID_7, "(B1 Stepping)"}, 81 {V_PCH_LPC_RID_8, "(B2 Stepping)"}, 82 {V_PCH_LPC_RID_9, "(B2 Stepping)"}, 83 {V_PCH_LPC_RID_A, "(B3 Stepping)"}, 84 {V_PCH_LPC_RID_B, "(B3 Stepping)"}, 85 {V_PCH_LPC_RID_C, "(C0 Stepping)"}, 86 {V_PCH_LPC_RID_D, "(C0 Stepping)"} 87 }; 88 89 #define LEFT_JUSTIFY 0x01 90 #define PREFIX_SIGN 0x02 91 #define PREFIX_BLANK 0x04 92 #define COMMA_TYPE 0x08 93 #define LONG_TYPE 0x10 94 #define PREFIX_ZERO 0x20 95 96 #define ICH_REG_REV 0x08 97 #define MSR_IA32_PLATFORM_ID 0x17 98 99 100 BOOLEAN mSetupInfoDone = FALSE; 101 UINT8 mUseProductKey = 0; 102 EFI_EXP_BASE10_DATA mProcessorFrequency; 103 EFI_EXP_BASE10_DATA mProcessorFsbFrequency; 104 105 EFI_GUID mProcessorProducerGuid; 106 EFI_HII_HANDLE mHiiHandle; 107 EFI_PLATFORM_CPU_INFO mPlatformCpuInfo; 108 SYSTEM_CONFIGURATION mSystemConfiguration; 109 EFI_PLATFORM_INFO_HOB *mPlatformInfo; 110 111 112 #define memset SetMem 113 114 UINT16 mMemorySpeed = 0xffff; 115 EFI_PHYSICAL_ADDRESS mMemorySizeChannelASlot0 = 0; 116 UINT16 mMemorySpeedChannelASlot0 = 0xffff; 117 EFI_PHYSICAL_ADDRESS mMemorySizeChannelASlot1 = 0; 118 UINT16 mMemorySpeedChannelASlot1 = 0xffff; 119 EFI_PHYSICAL_ADDRESS mMemorySizeChannelBSlot0 = 0; 120 UINT16 mMemorySpeedChannelBSlot0 = 0xffff; 121 EFI_PHYSICAL_ADDRESS mMemorySizeChannelBSlot1 = 0; 122 UINT16 mMemorySpeedChannelBSlot1 = 0xffff; 123 EFI_PHYSICAL_ADDRESS mMemorySizeChannelCSlot0 = 0; 124 UINT16 mMemorySpeedChannelCSlot0 = 0xffff; 125 EFI_PHYSICAL_ADDRESS mMemorySizeChannelCSlot1 = 0; 126 UINT16 mMemorySpeedChannelCSlot1 = 0xffff; 127 UINTN mMemoryMode = 0xff; 128 129 #define CHARACTER_NUMBER_FOR_VALUE 30 130 typedef struct { 131 EFI_STRING_TOKEN MemoryDeviceLocator; 132 EFI_STRING_TOKEN MemoryBankLocator; 133 EFI_STRING_TOKEN MemoryManufacturer; 134 EFI_STRING_TOKEN MemorySerialNumber; 135 EFI_STRING_TOKEN MemoryAssetTag; 136 EFI_STRING_TOKEN MemoryPartNumber; 137 EFI_INTER_LINK_DATA MemoryArrayLink; 138 EFI_INTER_LINK_DATA MemorySubArrayLink; 139 UINT16 MemoryTotalWidth; 140 UINT16 MemoryDataWidth; 141 UINT64 MemoryDeviceSize; 142 EFI_MEMORY_FORM_FACTOR MemoryFormFactor; 143 UINT8 MemoryDeviceSet; 144 EFI_MEMORY_ARRAY_TYPE MemoryType; 145 EFI_MEMORY_TYPE_DETAIL MemoryTypeDetail; 146 UINT16 MemorySpeed; 147 EFI_MEMORY_STATE MemoryState; 148 } EFI_MEMORY_ARRAY_LINK; 149 150 151 typedef struct { 152 EFI_PHYSICAL_ADDRESS MemoryArrayStartAddress; 153 EFI_PHYSICAL_ADDRESS MemoryArrayEndAddress; 154 EFI_INTER_LINK_DATA PhysicalMemoryArrayLink; 155 UINT16 MemoryArrayPartitionWidth; 156 } EFI_MEMORY_ARRAY_START_ADDRESS; 157 158 159 typedef enum { 160 PCH_SATA_MODE_IDE = 0, 161 PCH_SATA_MODE_AHCI, 162 PCH_SATA_MODE_RAID, 163 PCH_SATA_MODE_MAX 164 } PCH_SATA_MODE; 165 166 /** 167 Acquire the string associated with the Index from smbios structure and return it. 168 The caller is responsible for free the string buffer. 169 170 @param OptionalStrStart The start position to search the string 171 @param Index The index of the string to extract 172 @param String The string that is extracted 173 174 @retval EFI_SUCCESS The function returns EFI_SUCCESS always. 175 176 **/ 177 EFI_STATUS 178 GetOptionalStringByIndex ( 179 IN CHAR8 *OptionalStrStart, 180 IN UINT8 Index, 181 OUT CHAR16 **String 182 ) 183 { 184 UINTN StrSize; 185 186 if (Index == 0) { 187 *String = AllocateZeroPool (sizeof (CHAR16)); 188 return EFI_SUCCESS; 189 } 190 191 StrSize = 0; 192 do { 193 Index--; 194 OptionalStrStart += StrSize; 195 StrSize = AsciiStrSize (OptionalStrStart); 196 } while (OptionalStrStart[StrSize] != 0 && Index != 0); 197 198 if ((Index != 0) || (StrSize == 1)) { 199 // 200 // Meet the end of strings set but Index is non-zero, or 201 // Find an empty string 202 // 203 return EFI_NOT_FOUND; 204 } else { 205 *String = AllocatePool (StrSize * sizeof (CHAR16)); 206 AsciiStrToUnicodeStr (OptionalStrStart, *String); 207 } 208 209 return EFI_SUCCESS; 210 } 211 212 /** 213 VSPrint worker function that prints a Value as a decimal number in Buffer 214 215 @param Buffer Location to place ascii decimal number string of Value. 216 @param Value Decimal value to convert to a string in Buffer. 217 @param Flags Flags to use in printing decimal string, see file header for details. 218 @param Width Width of hex value. 219 220 Number of characters printed. 221 222 **/ 223 UINTN 224 EfiValueToString ( 225 IN OUT CHAR16 *Buffer, 226 IN INT64 Value, 227 IN UINTN Flags, 228 IN UINTN Width 229 ) 230 { 231 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE]; 232 CHAR16 *TempStr; 233 CHAR16 *BufferPtr; 234 UINTN Count; 235 UINTN ValueCharNum; 236 UINTN Remainder; 237 CHAR16 Prefix; 238 UINTN Index; 239 BOOLEAN ValueIsNegative; 240 UINT64 TempValue; 241 242 TempStr = TempBuffer; 243 BufferPtr = Buffer; 244 Count = 0; 245 ValueCharNum = 0; 246 ValueIsNegative = FALSE; 247 248 if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) { 249 Width = CHARACTER_NUMBER_FOR_VALUE - 1; 250 } 251 252 if (Value < 0) { 253 Value = -Value; 254 ValueIsNegative = TRUE; 255 } 256 257 do { 258 TempValue = Value; 259 Value = (INT64)DivU64x32 ((UINT64)Value, 10); 260 Remainder = (UINTN)((UINT64)TempValue - 10 * Value); 261 *(TempStr++) = (CHAR16)(Remainder + '0'); 262 ValueCharNum++; 263 Count++; 264 if ((Flags & COMMA_TYPE) == COMMA_TYPE) { 265 if (ValueCharNum % 3 == 0 && Value != 0) { 266 *(TempStr++) = ','; 267 Count++; 268 } 269 } 270 } while (Value != 0); 271 272 if (ValueIsNegative) { 273 *(TempStr++) = '-'; 274 Count++; 275 } 276 277 if ((Flags & PREFIX_ZERO) && !ValueIsNegative) { 278 Prefix = '0'; 279 } else { 280 Prefix = ' '; 281 } 282 283 Index = Count; 284 if (!(Flags & LEFT_JUSTIFY)) { 285 for (; Index < Width; Index++) { 286 *(TempStr++) = Prefix; 287 } 288 } 289 290 // 291 // Reverse temp string into Buffer. 292 // 293 if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) { 294 TempStr = TempBuffer + Width; 295 } 296 Index = 0; 297 while (TempStr != TempBuffer) { 298 *(BufferPtr++) = *(--TempStr); 299 Index++; 300 } 301 302 *BufferPtr = 0; 303 return Index; 304 } 305 306 static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', 307 L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' }; 308 309 /** 310 VSPrint worker function that prints a Value as a hex number in Buffer 311 312 @param Buffer Location to place ascii hex string of Value. 313 @param Value Hex value to convert to a string in Buffer. 314 @param Flags Flags to use in printing Hex string, see file header for details. 315 @param Width Width of hex value. 316 317 @retval Number of characters printed. 318 319 **/ 320 UINTN 321 EfiValueToHexStr ( 322 IN OUT CHAR16 *Buffer, 323 IN UINT64 Value, 324 IN UINTN Flags, 325 IN UINTN Width 326 ) 327 { 328 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE]; 329 CHAR16 *TempStr; 330 CHAR16 Prefix; 331 CHAR16 *BufferPtr; 332 UINTN Count; 333 UINTN Index; 334 335 TempStr = TempBuffer; 336 BufferPtr = Buffer; 337 338 // 339 // Count starts at one since we will null terminate. Each iteration of the 340 // loop picks off one nibble. Oh yea TempStr ends up backwards 341 // 342 Count = 0; 343 344 if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) { 345 Width = CHARACTER_NUMBER_FOR_VALUE - 1; 346 } 347 348 do { 349 Index = ((UINTN)Value & 0xf); 350 *(TempStr++) = mHexStr[Index]; 351 Value = RShiftU64 (Value, 4); 352 Count++; 353 } while (Value != 0); 354 355 if (Flags & PREFIX_ZERO) { 356 Prefix = '0'; 357 } else { 358 Prefix = ' '; 359 } 360 361 Index = Count; 362 if (!(Flags & LEFT_JUSTIFY)) { 363 for (; Index < Width; Index++) { 364 *(TempStr++) = Prefix; 365 } 366 } 367 368 // 369 // Reverse temp string into Buffer. 370 // 371 if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) { 372 TempStr = TempBuffer + Width; 373 } 374 Index = 0; 375 while (TempStr != TempBuffer) { 376 *(BufferPtr++) = *(--TempStr); 377 Index++; 378 } 379 380 *BufferPtr = 0; 381 return Index; 382 } 383 384 /*++ 385 Converts MAC address to Unicode string. 386 The value is 64-bit and the resulting string will be 12 387 digit hex number in pairs of digits separated by dashes. 388 389 @param String string that will contain the value 390 @param MacAddr add argument and description to function comment 391 @param AddrSize add argument and description to function comment 392 393 **/ 394 CHAR16 * 395 StrMacToString ( 396 OUT CHAR16 *String, 397 IN EFI_MAC_ADDRESS *MacAddr, 398 IN UINT32 AddrSize 399 ) 400 { 401 UINT32 i; 402 403 for (i = 0; i < AddrSize; i++) { 404 405 EfiValueToHexStr ( 406 &String[2 * i], 407 MacAddr->Addr[i] & 0xFF, 408 PREFIX_ZERO, 409 2 410 ); 411 } 412 413 // 414 // Terminate the string. 415 // 416 String[2 * AddrSize] = L'\0'; 417 418 return String; 419 } 420 421 VOID UpdateLatestBootTime() { 422 UINTN VarSize; 423 EFI_STATUS Status; 424 UINT64 TimeValue; 425 CHAR16 Buffer[40]; 426 if (mSystemConfiguration.LogBootTime != 1) { 427 return; 428 } 429 VarSize = sizeof(TimeValue); 430 Status = gRT->GetVariable( 431 BOOT_TIME_NAME, 432 &gEfiNormalSetupGuid, 433 NULL, 434 &VarSize, 435 &TimeValue 436 ); 437 if (EFI_ERROR(Status)) { 438 return; 439 } 440 UnicodeSPrint (Buffer, sizeof (Buffer), L"%d ms", (UINT32)TimeValue); 441 HiiSetString(mHiiHandle,STRING_TOKEN(STR_LOG_BOOT_TIME_VALUE), Buffer, NULL); 442 } 443 444 /** 445 Get Cache Type for the specified Cache. This function is invoked when there is data records 446 available in the Data Hub. 447 448 Get Cache Type function arguments: 449 450 @param Instance The instance number of the subclass with the same ProducerName.. 451 @param SubInstance The instance number of the RecordType for the same Instance. 452 @param CacheType Cache type, see definition of EFI_CACHE_TYPE_DATA. 453 454 @retval EFI_STATUS 455 456 **/ 457 EFI_STATUS 458 GetCacheType( 459 IN UINT16 Instance, 460 IN UINT16 SubInstance, 461 IN EFI_CACHE_TYPE_DATA* CacheType) 462 { 463 EFI_STATUS Status; 464 EFI_DATA_HUB_PROTOCOL *DataHub; 465 EFI_DATA_RECORD_HEADER *Record; 466 UINT64 MonotonicCount; 467 EFI_CACHE_VARIABLE_RECORD* CacheVariableRecord; 468 EFI_SUBCLASS_TYPE1_HEADER *DataHeader; 469 470 Status = gBS->LocateProtocol ( 471 &gEfiDataHubProtocolGuid, 472 NULL, 473 (void **)&DataHub 474 ); 475 ASSERT_EFI_ERROR(Status); 476 477 // 478 // Get all available data records from data hub 479 // 480 MonotonicCount = 0; 481 Record = NULL; 482 483 do { 484 Status = DataHub->GetNextRecord ( 485 DataHub, 486 &MonotonicCount, 487 NULL, 488 &Record 489 ); 490 if (!EFI_ERROR(Status)) { 491 if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) { 492 DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1); 493 494 if(CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) && 495 (DataHeader->RecordType == CacheTypeRecordType) && 496 (DataHeader->Instance == Instance) && 497 (DataHeader->SubInstance == SubInstance)) { 498 CacheVariableRecord = (EFI_CACHE_VARIABLE_RECORD *)(DataHeader + 1); 499 if(CacheType){ 500 *CacheType = CacheVariableRecord->CacheType; 501 return EFI_SUCCESS; 502 } 503 } 504 } 505 } 506 } while(!EFI_ERROR(Status) && (MonotonicCount != 0)); 507 508 return EFI_NOT_FOUND; 509 } 510 511 /** 512 Setup data filter function. This function is invoked when there is data records 513 available in the Data Hub. 514 515 516 Standard event notification function arguments: 517 @param Event The event that is signaled. 518 @param Context Not used here. 519 520 @retval EFI_STATUS 521 522 **/ 523 VOID 524 PrepareSetupInformation ( 525 ) 526 { 527 528 EFI_STATUS Status; 529 EFI_DATA_HUB_PROTOCOL *DataHub; 530 EFI_DATA_RECORD_HEADER *Record; 531 UINT8 *SrcData; 532 UINT32 SrcDataSize; 533 EFI_SUBCLASS_TYPE1_HEADER *DataHeader; 534 CHAR16 *NewString; 535 CHAR16 *NewString2; 536 CHAR16 *NewStringToken; 537 STRING_REF TokenToUpdate; 538 EFI_PROCESSOR_VERSION_DATA *ProcessorVersion; 539 UINTN Index; 540 UINT16 EeState; 541 UINTN DataOutput; 542 543 EFI_PROCESSOR_MICROCODE_REVISION_DATA *CpuUcodeRevisionData; 544 EFI_MEMORY_ARRAY_START_ADDRESS *MemoryArray; 545 EFI_MEMORY_ARRAY_LINK *MemoryArrayLink; 546 UINT64 MonotonicCount; 547 548 CHAR16 Version[100]; //Assuming that strings are < 100 UCHAR 549 CHAR16 ReleaseDate[100]; //Assuming that strings are < 100 UCHAR 550 CHAR16 ReleaseTime[100]; //Assuming that strings are < 100 UCHAR 551 552 NewString = AllocateZeroPool (0x100); 553 NewString2 = AllocateZeroPool (0x100); 554 SetMem(Version, sizeof(Version), 0); 555 SetMem(ReleaseDate, sizeof(ReleaseDate), 0); 556 SetMem(ReleaseTime, sizeof(ReleaseTime), 0); 557 558 // 559 // Initialize EE state for not to show EE related setup options 560 // 561 EeState = 0; 562 563 // 564 // Get the Data Hub Protocol. Assume only one instance 565 // 566 Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (void **)&DataHub); 567 ASSERT_EFI_ERROR(Status); 568 569 // 570 // Get all available data records from data hub 571 // 572 MonotonicCount = 0; 573 Record = NULL; 574 575 do { 576 Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record); 577 if (!EFI_ERROR(Status)) { 578 if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) { 579 DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1); 580 SrcData = (UINT8 *)(DataHeader + 1); 581 SrcDataSize = Record->RecordSize - Record->HeaderSize - sizeof (EFI_SUBCLASS_TYPE1_HEADER); 582 583 // 584 // Processor 585 // 586 if (CompareGuid(&Record->DataRecordGuid, &gEfiProcessorSubClassGuid)) { 587 CopyMem (&mProcessorProducerGuid, &Record->ProducerName, sizeof(EFI_GUID)); 588 switch (DataHeader->RecordType) { 589 case ProcessorCoreFrequencyRecordType: 590 CopyMem(&mProcessorFrequency, SrcData, sizeof(EFI_EXP_BASE10_DATA)); 591 Index = EfiValueToString ( 592 NewString, 593 ConvertBase10ToRaw ((EFI_EXP_BASE10_DATA *)SrcData)/1000000000, 594 PREFIX_ZERO, 595 0 596 ); 597 StrCat (NewString, L"."); 598 EfiValueToString ( 599 NewString + Index + 1, 600 ((ConvertBase10ToRaw ((EFI_EXP_BASE10_DATA *)SrcData)%1000000000)/10000000), 601 PREFIX_ZERO, 602 0 603 ); 604 StrCat (NewString, L" GHz"); 605 TokenToUpdate = (STRING_REF)STR_PROCESSOR_SPEED_VALUE; 606 HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL); 607 break; 608 609 case ProcessorVersionRecordType: 610 ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData; 611 NewStringToken = HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL); 612 TokenToUpdate = (STRING_REF)STR_PROCESSOR_VERSION_VALUE; 613 HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL); 614 break; 615 case CpuUcodeRevisionDataRecordType: 616 CpuUcodeRevisionData = (EFI_PROCESSOR_MICROCODE_REVISION_DATA *) SrcData; 617 if (CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber != 0) { 618 EfiValueToHexStr ( 619 NewString, 620 CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber, 621 PREFIX_ZERO, 622 8 623 ); 624 TokenToUpdate = (STRING_REF)STR_PROCESSOR_MICROCODE_VALUE; 625 HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL); 626 } 627 break; 628 default: 629 break; 630 } 631 632 // 633 // Cache 634 // 635 } else if (CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) && 636 (DataHeader->RecordType == CacheSizeRecordType)) { 637 if (DataHeader->SubInstance == EFI_CACHE_L1) { 638 EFI_CACHE_TYPE_DATA CacheType; 639 if (EFI_SUCCESS == GetCacheType(DataHeader->Instance, DataHeader->SubInstance,&CacheType)){ 640 if (CacheType == EfiCacheTypeData) { 641 TokenToUpdate = (STRING_REF)STR_PROCESSOR_L1_DATA_CACHE_VALUE; 642 } else if (CacheType == EfiCacheTypeInstruction) { 643 TokenToUpdate = (STRING_REF)STR_PROCESSOR_L1_INSTR_CACHE_VALUE; 644 } else { 645 continue; 646 } 647 } else { 648 continue; 649 } 650 } 651 else if (DataHeader->SubInstance == EFI_CACHE_L2) { 652 TokenToUpdate = (STRING_REF)STR_PROCESSOR_L2_CACHE_VALUE; 653 } else { 654 continue; 655 } 656 if (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData)) { 657 DataOutput = ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10; 658 EfiValueToString (NewString, DataOutput, PREFIX_ZERO, 0); 659 660 StrCat (NewString, L" KB"); 661 if (DataHeader->SubInstance == EFI_CACHE_L3) { 662 HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL); 663 } else if(DataHeader->SubInstance == EFI_CACHE_L2 && mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage > 1){ 664 // 665 // Show XxL2 string 666 // 667 EfiValueToString ( 668 NewString2, 669 mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage, 670 PREFIX_ZERO, 671 0 672 ); 673 StrCat(NewString2, L"x "); 674 StrCat(NewString2, NewString); 675 HiiSetString(mHiiHandle, TokenToUpdate, NewString2, NULL); 676 } else { 677 HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL); 678 } 679 } 680 681 // 682 // Memory 683 // 684 } else if (CompareGuid(&Record->DataRecordGuid, &gEfiMemorySubClassGuid)) { 685 switch (DataHeader->RecordType) { 686 case EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER: 687 MemoryArrayLink = (EFI_MEMORY_ARRAY_LINK *)SrcData; 688 689 if (MemoryArrayLink->MemorySpeed > 0) { 690 // 691 // Save the lowest speed memory module 692 // 693 if (MemoryArrayLink->MemorySpeed < mMemorySpeed) { 694 mMemorySpeed = MemoryArrayLink->MemorySpeed; 695 } 696 switch (DataHeader->SubInstance) { 697 case 1: 698 mMemorySpeedChannelASlot0 = MemoryArrayLink->MemorySpeed; 699 mMemorySizeChannelASlot0 = MemoryArrayLink->MemoryDeviceSize; 700 break; 701 case 2: 702 mMemorySpeedChannelASlot1 = MemoryArrayLink->MemorySpeed; 703 mMemorySizeChannelASlot1 = MemoryArrayLink->MemoryDeviceSize; 704 break; 705 case 3: 706 mMemorySpeedChannelBSlot0 = MemoryArrayLink->MemorySpeed; 707 mMemorySizeChannelBSlot0 = MemoryArrayLink->MemoryDeviceSize; 708 break; 709 case 4: 710 mMemorySpeedChannelBSlot1 = MemoryArrayLink->MemorySpeed; 711 mMemorySizeChannelBSlot1 = MemoryArrayLink->MemoryDeviceSize; 712 break; 713 case 5: 714 mMemorySpeedChannelCSlot0 = MemoryArrayLink->MemorySpeed; 715 mMemorySizeChannelCSlot0 = MemoryArrayLink->MemoryDeviceSize; 716 break; 717 case 6: 718 mMemorySpeedChannelCSlot1 = MemoryArrayLink->MemorySpeed; 719 mMemorySizeChannelCSlot1 = MemoryArrayLink->MemoryDeviceSize; 720 break; 721 default: 722 break; 723 } 724 } 725 break; 726 727 case EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER: 728 MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS *)SrcData; 729 if (MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress) { 730 DataOutput = (UINTN)RShiftU64((MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1), 20); 731 EfiValueToString (NewString, DataOutput / 1024, PREFIX_ZERO, 0); 732 if(DataOutput % 1024) { 733 StrCat (NewString, L"."); 734 DataOutput = ((DataOutput % 1024) * 1000) / 1024; 735 while(!(DataOutput % 10)) 736 DataOutput = DataOutput / 10; 737 EfiValueToString (NewString2, DataOutput, PREFIX_ZERO, 0); 738 StrCat (NewString, NewString2); 739 } 740 StrCat (NewString, L" GB"); 741 TokenToUpdate = (STRING_REF)STR_TOTAL_MEMORY_SIZE_VALUE; 742 HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL); 743 } 744 break; 745 746 default: 747 break; 748 } 749 } 750 } 751 } 752 } while (!EFI_ERROR(Status) && (MonotonicCount != 0)); 753 754 Status = GetBiosVersionDateTime ( 755 Version, 756 ReleaseDate, 757 ReleaseTime 758 ); 759 760 DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n", Version, ReleaseDate, ReleaseTime)); 761 if (!EFI_ERROR (Status)) { 762 UINTN Length = 0; 763 CHAR16 *BuildDateTime; 764 765 Length = StrLen(ReleaseDate) + StrLen(ReleaseTime); 766 767 BuildDateTime = AllocateZeroPool ((Length+2) * sizeof(CHAR16)); 768 StrCpy (BuildDateTime, ReleaseDate); 769 StrCat (BuildDateTime, L" "); 770 StrCat (BuildDateTime, ReleaseTime); 771 772 TokenToUpdate = (STRING_REF)STR_BIOS_VERSION_VALUE; 773 DEBUG ((EFI_D_ERROR, "update STR_BIOS_VERSION_VALUE\n")); 774 HiiSetString(mHiiHandle, TokenToUpdate, Version, NULL); 775 776 TokenToUpdate = (STRING_REF)STR_BIOS_BUILD_TIME_VALUE; 777 DEBUG ((EFI_D_ERROR, "update STR_BIOS_BUILD_TIME_VALUE\n")); 778 HiiSetString(mHiiHandle, TokenToUpdate, BuildDateTime, NULL); 779 } 780 781 // 782 // Calculate and update memory speed display in Main Page 783 // 784 // 785 // Update the overall memory speed 786 // 787 if (mMemorySpeed != 0xffff) { 788 EfiValueToString (NewString, mMemorySpeed, PREFIX_ZERO, 0); 789 StrCat (NewString, L" MHz"); 790 791 TokenToUpdate = (STRING_REF)STR_SYSTEM_MEMORY_SPEED_VALUE; 792 HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL); 793 } 794 795 gBS->FreePool(NewString); 796 gBS->FreePool(NewString2); 797 798 return; 799 } 800 801 /** 802 803 Routine Description: update the SETUP info for "Additional Information" which is SMBIOS info. 804 805 @retval EFI_STATUS 806 807 **/ 808 EFI_STATUS 809 UpdateAdditionalInformation ( 810 ) 811 { 812 EFI_STATUS Status; 813 UINT64 MonotonicCount; 814 EFI_DATA_HUB_PROTOCOL *DataHub; 815 EFI_DATA_RECORD_HEADER *Record; 816 EFI_SUBCLASS_TYPE1_HEADER *DataHeader; 817 EFI_MISC_SYSTEM_MANUFACTURER *SystemManufacturer; 818 UINTN Size; 819 EFI_SMBIOS_PROTOCOL *Smbios; 820 EFI_SMBIOS_HANDLE SmbiosHandle; 821 EFI_SMBIOS_TABLE_HEADER *SmbiosRecord; 822 SMBIOS_TABLE_TYPE0 *Type0Record; 823 UINT8 StrIndex; 824 CHAR16 *BiosVersion = NULL; 825 CHAR16 *IfwiVersion = NULL; 826 UINT16 SearchIndex; 827 EFI_STRING_ID TokenToUpdate; 828 829 Status = gBS->LocateProtocol ( 830 &gEfiDataHubProtocolGuid, 831 NULL, 832 (void **)&DataHub 833 ); 834 835 ASSERT_EFI_ERROR(Status); 836 837 Size = 3; 838 839 MonotonicCount = 0; 840 Record = NULL; 841 do { 842 Status = DataHub->GetNextRecord ( 843 DataHub, 844 &MonotonicCount, 845 NULL, 846 &Record 847 ); 848 if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) { 849 DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1); 850 851 if (CompareGuid(&Record->DataRecordGuid, &gEfiMiscSubClassGuid) && 852 (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)) { 853 // 854 // System Information 855 // 856 SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER *)(DataHeader + 1); 857 858 #if defined( RVP_SUPPORT ) && RVP_SUPPORT 859 // 860 // UUID (System Information) 861 // 862 SMBIOSString = EfiLibAllocateZeroPool (0x100); 863 GuidToString ( &SystemManufacturer->SystemUuid, SMBIOSString, 0x00 ); 864 865 TokenToUpdate = (STRING_REF)STR_SYSTEM_UUID_VALUE; 866 HiiSetString(mHiiHandle, TokenToUpdate, SMBIOSString, NULL); 867 868 gBS->FreePool(SMBIOSString); 869 #endif 870 } 871 } 872 } while (!EFI_ERROR(Status) && (MonotonicCount != 0)); 873 874 Status = gBS->LocateProtocol ( 875 &gEfiSmbiosProtocolGuid, 876 NULL, 877 (VOID **) &Smbios 878 ); 879 ASSERT_EFI_ERROR (Status); 880 881 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; 882 do { 883 Status = Smbios->GetNext ( 884 Smbios, 885 &SmbiosHandle, 886 NULL, 887 &SmbiosRecord, 888 NULL 889 ); 890 if (SmbiosRecord->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) { 891 Type0Record = (SMBIOS_TABLE_TYPE0 *) SmbiosRecord; 892 StrIndex = Type0Record->BiosVersion; 893 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &BiosVersion); 894 TokenToUpdate = STRING_TOKEN (STR_BIOS_VERSION_VALUE); 895 for (SearchIndex = 0x0; SearchIndex < SMBIOS_STRING_MAX_LENGTH; SearchIndex++) { 896 if (BiosVersion[SearchIndex] == 0x0020) { 897 BiosVersion[SearchIndex] = 0x0000; 898 IfwiVersion = (CHAR16 *)(&BiosVersion[SearchIndex+1]); 899 break; 900 } else if (BiosVersion[SearchIndex] == 0x0000) { 901 break; 902 } 903 } 904 HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL); 905 906 // 907 // Check IfwiVersion, to avoid no IFWI version in SMBIOS Type 0 strucntion 908 // 909 if(IfwiVersion) { 910 TokenToUpdate = STRING_TOKEN (STR_IFWI_VERSION_VALUE); 911 HiiSetString (mHiiHandle, TokenToUpdate, IfwiVersion, NULL); 912 } 913 } 914 } while (!EFI_ERROR(Status)); 915 916 UpdateLatestBootTime(); 917 918 return EFI_SUCCESS; 919 } 920 921 VOID 922 UpdateCPUInformation () 923 { 924 CHAR16 Buffer[40]; 925 UINT16 FamilyId; 926 UINT8 Model; 927 UINT8 SteppingId; 928 UINT8 ProcessorType; 929 EFI_STATUS Status; 930 EFI_MP_SERVICES_PROTOCOL *MpService; 931 UINTN MaximumNumberOfCPUs; 932 UINTN NumberOfEnabledCPUs; 933 UINT32 Buffer32 = 0xFFFFFFFF; // Keep buffer with unknown device 934 935 EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType); 936 937 // 938 //we need raw Model data 939 // 940 Model = Model & 0xf; 941 942 // 943 //Family/Model/Step 944 // 945 UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId, Model, SteppingId); 946 HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_ID_VALUE), Buffer, NULL); 947 948 Status = gBS->LocateProtocol ( 949 &gEfiMpServiceProtocolGuid, 950 NULL, 951 (void **)&MpService 952 ); 953 if (!EFI_ERROR (Status)) { 954 // 955 // Determine the number of processors 956 // 957 MpService->GetNumberOfProcessors ( 958 MpService, 959 &MaximumNumberOfCPUs, 960 &NumberOfEnabledCPUs 961 ); 962 UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", MaximumNumberOfCPUs); 963 HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_CORE_VALUE), Buffer, NULL); 964 } 965 // 966 // Update Mobile / Desktop / Tablet SKU 967 // 968 Buffer32 =(UINT32) RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07; 969 970 switch(Buffer32){ 971 case 0x0: 972 UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - ISG SKU SOC", Buffer32); 973 break; 974 case 0x01: 975 UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC", Buffer32); 976 break; 977 case 0x02: 978 UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Desktop SKU SOC", Buffer32); 979 break; 980 case 0x03: 981 UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC", Buffer32); 982 break; 983 default: 984 UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Unknown SKU SOC", Buffer32); 985 break; 986 } 987 HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_SKU_VALUE), Buffer, NULL); 988 989 } 990 991 992 EFI_STATUS 993 SearchChildHandle( 994 EFI_HANDLE Father, 995 EFI_HANDLE *Child 996 ) 997 { 998 EFI_STATUS Status; 999 UINTN HandleIndex; 1000 EFI_GUID **ProtocolGuidArray = NULL; 1001 UINTN ArrayCount; 1002 UINTN ProtocolIndex; 1003 UINTN OpenInfoCount; 1004 UINTN OpenInfoIndex; 1005 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL; 1006 UINTN mHandleCount; 1007 EFI_HANDLE *mHandleBuffer= NULL; 1008 1009 // 1010 // Retrieve the list of all handles from the handle database 1011 // 1012 Status = gBS->LocateHandleBuffer ( 1013 AllHandles, 1014 NULL, 1015 NULL, 1016 &mHandleCount, 1017 &mHandleBuffer 1018 ); 1019 1020 for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) 1021 { 1022 // 1023 // Retrieve the list of all the protocols on each handle 1024 // 1025 Status = gBS->ProtocolsPerHandle ( 1026 mHandleBuffer[HandleIndex], 1027 &ProtocolGuidArray, 1028 &ArrayCount 1029 ); 1030 if (!EFI_ERROR (Status)) 1031 { 1032 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) 1033 { 1034 Status = gBS->OpenProtocolInformation ( 1035 mHandleBuffer[HandleIndex], 1036 ProtocolGuidArray[ProtocolIndex], 1037 &OpenInfo, 1038 &OpenInfoCount 1039 ); 1040 if (!EFI_ERROR (Status)) 1041 { 1042 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) 1043 { 1044 if(OpenInfo[OpenInfoIndex].AgentHandle == Father) 1045 { 1046 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) 1047 { 1048 *Child = mHandleBuffer[HandleIndex]; 1049 Status = EFI_SUCCESS; 1050 goto TryReturn; 1051 } 1052 } 1053 } 1054 Status = EFI_NOT_FOUND; 1055 } 1056 } 1057 if(OpenInfo != NULL) 1058 { 1059 FreePool(OpenInfo); 1060 OpenInfo = NULL; 1061 } 1062 } 1063 FreePool (ProtocolGuidArray); 1064 ProtocolGuidArray = NULL; 1065 } 1066 TryReturn: 1067 if(OpenInfo != NULL) 1068 { 1069 FreePool (OpenInfo); 1070 OpenInfo = NULL; 1071 } 1072 if(ProtocolGuidArray != NULL) 1073 { 1074 FreePool(ProtocolGuidArray); 1075 ProtocolGuidArray = NULL; 1076 } 1077 if(mHandleBuffer != NULL) 1078 { 1079 FreePool (mHandleBuffer); 1080 mHandleBuffer = NULL; 1081 } 1082 return Status; 1083 } 1084 1085 EFI_STATUS 1086 JudgeHandleIsPCIDevice( 1087 EFI_HANDLE Handle, 1088 UINT8 Device, 1089 UINT8 Funs 1090 ) 1091 { 1092 EFI_STATUS Status; 1093 EFI_DEVICE_PATH *DPath; 1094 EFI_DEVICE_PATH *DevicePath; 1095 1096 Status = gBS->HandleProtocol ( 1097 Handle, 1098 &gEfiDevicePathProtocolGuid, 1099 (VOID **) &DPath 1100 ); 1101 if(!EFI_ERROR(Status)) 1102 { 1103 DevicePath = DPath; 1104 while(!IsDevicePathEnd(DPath)) 1105 { 1106 if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) 1107 { 1108 PCI_DEVICE_PATH *PCIPath; 1109 1110 PCIPath = (PCI_DEVICE_PATH*) DPath; 1111 DPath = NextDevicePathNode(DPath); 1112 if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) 1113 { 1114 return EFI_SUCCESS; 1115 } 1116 } 1117 else 1118 { 1119 DPath = NextDevicePathNode(DPath); 1120 } 1121 } 1122 } 1123 return EFI_UNSUPPORTED; 1124 } 1125 1126 EFI_STATUS 1127 GetDriverName( 1128 EFI_HANDLE Handle, 1129 CHAR16 *Name 1130 ) 1131 { 1132 EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL; 1133 EFI_STATUS Status; 1134 UINT32 Version; 1135 UINT16 *Ptr; 1136 Status = gBS->OpenProtocol( 1137 Handle, 1138 &gEfiDriverBindingProtocolGuid, 1139 (VOID**)&BindHandle, 1140 NULL, 1141 NULL, 1142 EFI_OPEN_PROTOCOL_GET_PROTOCOL 1143 ); 1144 1145 if (EFI_ERROR(Status)) 1146 { 1147 return EFI_NOT_FOUND; 1148 } 1149 1150 Version = BindHandle->Version; 1151 Ptr = (UINT16*)&Version; 1152 UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr)); 1153 1154 return EFI_SUCCESS; 1155 } 1156 1157 EFI_STATUS 1158 GetGOPDriverName( 1159 CHAR16 *Name 1160 ) 1161 { 1162 UINTN HandleCount; 1163 EFI_HANDLE *Handles= NULL; 1164 UINTN Index; 1165 EFI_STATUS Status; 1166 EFI_HANDLE Child = 0; 1167 1168 Status = gBS->LocateHandleBuffer( 1169 ByProtocol, 1170 &gEfiDriverBindingProtocolGuid, 1171 NULL, 1172 &HandleCount, 1173 &Handles 1174 ); 1175 for (Index = 0; Index < HandleCount ; Index++) 1176 { 1177 Status = SearchChildHandle(Handles[Index], &Child); 1178 if(!EFI_ERROR(Status)) 1179 { 1180 Status = JudgeHandleIsPCIDevice( 1181 Child, 1182 0x02, 1183 0x00 1184 ); 1185 if(!EFI_ERROR(Status)) 1186 { 1187 return GetDriverName(Handles[Index], Name); 1188 } 1189 } 1190 } 1191 return EFI_UNSUPPORTED; 1192 } 1193 1194 EFI_STATUS 1195 UpdatePlatformInformation ( 1196 ) 1197 { 1198 UINT32 MicroCodeVersion; 1199 CHAR16 Buffer[40]; 1200 UINT8 IgdVBIOSRevH; 1201 UINT8 IgdVBIOSRevL; 1202 UINT16 EDX; 1203 EFI_IA32_REGISTER_SET RegSet; 1204 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL; 1205 EFI_STATUS Status; 1206 UINT8 CpuFlavor=0; 1207 EFI_PEI_HOB_POINTERS GuidHob; 1208 EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL; 1209 UINTN NumHandles; 1210 EFI_HANDLE *HandleBuffer; 1211 UINTN Index; 1212 DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; 1213 UINTN PciD31F0RegBase; 1214 UINT8 count; 1215 UINT8 Data8; 1216 UINT8 PIDData8; 1217 1218 CHAR16 Name[40]; 1219 UINT32 MrcVersion; 1220 1221 // 1222 // Get the HOB list. If it is not present, then ASSERT. 1223 // 1224 GuidHob.Raw = GetHobList (); 1225 if (GuidHob.Raw != NULL) { 1226 if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) { 1227 mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid); 1228 } 1229 } 1230 1231 // 1232 //VBIOS version 1233 // 1234 Status = gBS->LocateProtocol( 1235 &gEfiLegacyBiosProtocolGuid, 1236 NULL, 1237 (void **)&LegacyBios 1238 ); 1239 if (!EFI_ERROR (Status)) { 1240 RegSet.X.AX = 0x5f01; 1241 Status = LegacyBios->Int86 (LegacyBios, 0x10, &RegSet); 1242 ASSERT_EFI_ERROR(Status); 1243 1244 // 1245 // simulate AMI int15 (ax=5f01) handler 1246 // check NbInt15.asm in AMI code for asm edition 1247 // 1248 EDX = (UINT16)((RegSet.E.EBX >> 16) & 0xffff); 1249 IgdVBIOSRevH = (UINT8)(((EDX & 0x0F00) >> 4) | (EDX & 0x000F)); 1250 IgdVBIOSRevL = (UINT8)(((RegSet.X.BX & 0x0F00) >> 4) | (RegSet.X.BX & 0x000F)); 1251 1252 if (IgdVBIOSRevH==0 && IgdVBIOSRevL==0){ 1253 HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), L"N/A", NULL); 1254 } else { 1255 UnicodeSPrint (Buffer, sizeof (Buffer), L"%02X%02X", IgdVBIOSRevH,IgdVBIOSRevL); 1256 HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), Buffer, NULL); 1257 } 1258 } 1259 1260 Status = GetGOPDriverName(Name); 1261 1262 if (!EFI_ERROR(Status)) 1263 { 1264 HiiSetString(mHiiHandle, STRING_TOKEN(STR_GOP_VALUE), Name, NULL); 1265 } 1266 1267 1268 // 1269 // CpuFlavor 1270 // ISG-DC Tablet 000 1271 // VLV-QC Tablet 001 1272 // VLV-QC Desktop 010 1273 // VLV-QC Notebook 011 1274 // 1275 CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07; 1276 1277 switch(CpuFlavor){ 1278 case 0x0: 1279 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet", CpuFlavor); 1280 break; 1281 case 0x01: 1282 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor); 1283 break; 1284 case 0x02: 1285 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop", CpuFlavor); 1286 break; 1287 case 0x03: 1288 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor); 1289 break; 1290 default: 1291 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor); 1292 break; 1293 } 1294 HiiSetString(mHiiHandle,STRING_TOKEN(STR_CPU_FLAVOR_VALUE), Buffer, NULL); 1295 1296 if ( NULL != mPlatformInfo) { 1297 // 1298 //BoardId 1299 // 1300 switch(mPlatformInfo->BoardId){ 1301 case 0x2: 1302 UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE RVP(%02x)", mPlatformInfo->BoardId); 1303 break; 1304 1305 case 0x4: 1306 UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFRD(%02x)", mPlatformInfo->BoardId); 1307 break; 1308 1309 case 0x5: 1310 UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY ROCK RVP DDR3L (%02x)", mPlatformInfo->BoardId); 1311 break; 1312 1313 case 0x20: 1314 UnicodeSPrint (Buffer, sizeof (Buffer), L"BAYLEY BAY (%02x)", mPlatformInfo->BoardId); 1315 break; 1316 1317 case 0x30: 1318 UnicodeSPrint (Buffer, sizeof (Buffer), L"BAKER SPORT (%02x)", mPlatformInfo->BoardId); 1319 break; 1320 1321 case 0x0: 1322 UnicodeSPrint (Buffer, sizeof (Buffer), L"ALPINE VALLEY (%x)", mPlatformInfo->BoardId); 1323 break; 1324 1325 case 0x3: 1326 UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFD8 (%x)", mPlatformInfo->BoardId); 1327 break; 1328 1329 default: 1330 UnicodeSPrint (Buffer, sizeof (Buffer), L"Unknown BOARD (%02x)", mPlatformInfo->BoardId); 1331 break; 1332 } 1333 HiiSetString(mHiiHandle,STRING_TOKEN(STR_BOARD_ID_VALUE), Buffer, NULL); 1334 1335 1336 // 1337 // Get Board FAB ID Info from protocol, update into the NVS area. 1338 // bit0~bit3 are for Fab ID, 0x0F means unknow FAB. 1339 // 1340 if(mPlatformInfo->BoardRev == 0x0F) { 1341 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", L"Unknown FAB"); 1342 HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer, NULL); 1343 } else { 1344 UnicodeSPrint (Buffer, sizeof (Buffer), L"%2x", mPlatformInfo->BoardRev); 1345 HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer, NULL); 1346 } 1347 } 1348 1349 // 1350 //Update MRC Version 1351 // 1352 MrcVersion = 0x00000000; 1353 MrcVersion &= 0xffff; 1354 Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0); 1355 StrCat (Buffer, L"."); 1356 EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0); 1357 EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0); 1358 HiiSetString(mHiiHandle,STRING_TOKEN(STR_MRC_VERSION_VALUE), Buffer, NULL); 1359 1360 // 1361 //Update Soc Version 1362 // 1363 1364 // 1365 // Retrieve all instances of PCH Platform Policy protocol 1366 // 1367 Status = gBS->LocateHandleBuffer ( 1368 ByProtocol, 1369 &gDxePchPlatformPolicyProtocolGuid, 1370 NULL, 1371 &NumHandles, 1372 &HandleBuffer 1373 ); 1374 if (!EFI_ERROR (Status)) { 1375 // 1376 // Find the matching PCH Policy protocol 1377 // 1378 for (Index = 0; Index < NumHandles; Index++) { 1379 Status = gBS->HandleProtocol ( 1380 HandleBuffer[Index], 1381 &gDxePchPlatformPolicyProtocolGuid, 1382 (void **)&PchPlatformPolicy 1383 ); 1384 if (!EFI_ERROR (Status)) { 1385 PciD31F0RegBase = MmPciAddress ( 1386 0, 1387 PchPlatformPolicy->BusNumber, 1388 PCI_DEVICE_NUMBER_PCH_LPC, 1389 PCI_FUNCTION_NUMBER_PCH_LPC, 1390 0 1391 ); 1392 1393 Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC); 1394 count = sizeof (SBRevisionTable) / sizeof (SBRevisionTable[0]); 1395 for (Index = 0; Index < count; Index++) { 1396 if(Data8 == SBRevisionTable[Index].RevId) { 1397 UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String); 1398 HiiSetString(mHiiHandle,STRING_TOKEN(STR_SOC_VALUE), Buffer, NULL); 1399 break; 1400 } 1401 } 1402 break; 1403 } 1404 } 1405 } 1406 1407 // 1408 // Microcode Revision 1409 // 1410 EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0); 1411 EfiCpuid (EFI_CPUID_VERSION_INFO, NULL); 1412 MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32); 1413 UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion); 1414 HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_MICROCODE_VALUE), Buffer, NULL); 1415 1416 // 1417 // Punit Version 1418 // 1419 Data8 = 0; 1420 UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8); 1421 HiiSetString(mHiiHandle,STRING_TOKEN(STR_PUNIT_FW_VALUE), Buffer, NULL); 1422 1423 // 1424 // PMC Version 1425 // 1426 Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF); 1427 PIDData8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF); 1428 UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X",PIDData8, Data8); 1429 HiiSetString(mHiiHandle,STRING_TOKEN(STR_PMC_FW_VALUE), Buffer, NULL); 1430 1431 return EFI_SUCCESS; 1432 } 1433 1434 /** 1435 1436 Update SATA Drivesize Strings for Setup and Boot order 1437 1438 @param NewString - pointer to string. 1439 @param DeviceSpeed - speed of drive. 1440 1441 **/ 1442 VOID 1443 GetDeviceSpeedString ( 1444 CHAR16 *NewString, 1445 IN UINTN DeviceSpeed 1446 ) 1447 { 1448 if (DeviceSpeed == 0x01) { 1449 StrCat (NewString, L"1.5Gb/s"); 1450 } else if (DeviceSpeed == 0x02) { 1451 StrCat (NewString, L"3.0Gb/s"); 1452 } else if (DeviceSpeed == 0x03) { 1453 StrCat (NewString, L"6.0Gb/s"); 1454 } else if (DeviceSpeed == 0x0) { 1455 1456 } 1457 } 1458 1459 UINT8 1460 GetChipsetSataPortSpeed ( 1461 UINTN PortNum 1462 ) 1463 { 1464 UINT32 DeviceSpeed; 1465 UINT8 DeviceConfigStatus; 1466 UINT32 IdeAhciBar; 1467 EFI_PHYSICAL_ADDRESS MemBaseAddress = 0; 1468 UINT8 FunNum; 1469 EFI_STATUS Status; 1470 UINT32 DwordReg; 1471 1472 1473 DeviceSpeed = 0x01; // generation 1 1474 1475 1476 // 1477 // Allocate the AHCI BAR 1478 // 1479 FunNum = PCI_FUNCTION_NUMBER_PCH_SATA; 1480 MemBaseAddress = 0x0ffffffff; 1481 Status = gDS->AllocateMemorySpace ( 1482 EfiGcdAllocateMaxAddressSearchBottomUp, 1483 EfiGcdMemoryTypeMemoryMappedIo, 1484 N_PCH_SATA_ABAR_ALIGNMENT, // 2^11: 2K Alignment 1485 V_PCH_SATA_ABAR_LENGTH, // 2K Length 1486 &MemBaseAddress, 1487 mImageHandle, 1488 NULL 1489 ); 1490 IdeAhciBar = MmioRead32 ( 1491 MmPciAddress ( 1492 0, 1493 0, 1494 PCI_DEVICE_NUMBER_PCH_SATA, 1495 FunNum, 1496 R_PCH_SATA_ABAR 1497 ) 1498 ); 1499 IdeAhciBar &= 0xFFFFF800; 1500 DeviceConfigStatus = 0; 1501 if (IdeAhciBar == 0) { 1502 DeviceConfigStatus = 1; 1503 IdeAhciBar = (UINT32)MemBaseAddress; 1504 MmioWrite32 ( 1505 MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_ABAR), 1506 IdeAhciBar 1507 ); 1508 MmioOr16 ( 1509 MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_COMMAND), 1510 B_PCH_SATA_COMMAND_MSE 1511 ); 1512 } 1513 1514 if (mSystemConfiguration.SataType == PCH_SATA_MODE_IDE){ 1515 // 1516 // Program the "Ports Implemented Register" 1517 // 1518 MmioAndThenOr32 (IdeAhciBar + R_PCH_SATA_AHCI_PI, (UINT32)~(B_PCH_SATA_PORT0_IMPLEMENTED + B_PCH_SATA_PORT1_IMPLEMENTED), (UINT32)(B_PCH_SATA_PORT0_IMPLEMENTED + B_PCH_SATA_PORT1_IMPLEMENTED)); 1519 DwordReg = MmioRead32 (IdeAhciBar + R_PCH_SATA_AHCI_PI); 1520 } 1521 1522 switch (PortNum) 1523 { 1524 case 0: 1525 DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar + R_PCH_SATA_AHCI_P0SSTS); 1526 break; 1527 case 1: 1528 DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar + R_PCH_SATA_AHCI_P1SSTS); 1529 break; 1530 } 1531 1532 if (MemBaseAddress) { 1533 gDS->FreeMemorySpace ( 1534 MemBaseAddress, 1535 V_PCH_SATA_ABAR_LENGTH 1536 ); 1537 } 1538 1539 if (DeviceConfigStatus) { 1540 IdeAhciBar = 0; 1541 MmioWrite32 ( 1542 MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_ABAR), 1543 IdeAhciBar 1544 ); 1545 } 1546 1547 DeviceSpeed = (UINT8)((DeviceSpeed >> 4) & 0x0F); 1548 1549 return (UINT8)DeviceSpeed; 1550 } 1551 1552 /** 1553 1554 IDE data filter function. 1555 1556 **/ 1557 void 1558 IdeDataFilter (void) 1559 { 1560 EFI_STATUS Status; 1561 UINTN HandleCount; 1562 EFI_HANDLE *HandleBuffer; 1563 EFI_DISK_INFO_PROTOCOL *DiskInfo; 1564 EFI_DEVICE_PATH_PROTOCOL *DevicePath, *DevicePathNode; 1565 PCI_DEVICE_PATH *PciDevicePath; 1566 UINTN Index; 1567 UINT8 Index1; 1568 UINT32 BufferSize; 1569 UINT32 DriveSize; 1570 UINT32 IdeChannel; 1571 UINT32 IdeDevice; 1572 EFI_ATA_IDENTIFY_DATA *IdentifyDriveInfo; 1573 CHAR16 *NewString; 1574 CHAR16 SizeString[20]; 1575 STRING_REF NameToUpdate; 1576 CHAR8 StringBuffer[0x100]; 1577 UINT32 DeviceSpeed; 1578 UINTN PortNumber; 1579 1580 // 1581 // Assume no line strings is longer than 256 bytes. 1582 // 1583 NewString = AllocateZeroPool (0x100); 1584 PciDevicePath = NULL; 1585 1586 // 1587 // Fill IDE Infomation 1588 // 1589 Status = gBS->LocateHandleBuffer ( 1590 ByProtocol, 1591 &gEfiDiskInfoProtocolGuid, 1592 NULL, 1593 &HandleCount, 1594 &HandleBuffer 1595 ); 1596 1597 if (EFI_ERROR (Status)) { 1598 return; 1599 } 1600 1601 for (Index = 0; Index < HandleCount; Index++) { 1602 1603 Status = gBS->HandleProtocol ( 1604 HandleBuffer[Index], 1605 &gEfiDevicePathProtocolGuid, 1606 (VOID*)&DevicePath 1607 ); 1608 ASSERT_EFI_ERROR (Status); 1609 1610 DevicePathNode = DevicePath; 1611 while (!IsDevicePathEnd (DevicePathNode) ) { 1612 if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) && 1613 ( DevicePathSubType (DevicePathNode) == HW_PCI_DP)) { 1614 PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode; 1615 break; 1616 } 1617 DevicePathNode = NextDevicePathNode (DevicePathNode); 1618 } 1619 1620 if (PciDevicePath == NULL) { 1621 continue; 1622 } 1623 1624 // 1625 // Check for onboard IDE 1626 // 1627 if (PciDevicePath->Device== PCI_DEVICE_NUMBER_PCH_SATA) { 1628 Status = gBS->HandleProtocol ( 1629 HandleBuffer[Index], 1630 &gEfiDiskInfoProtocolGuid, 1631 (void **)&DiskInfo 1632 ); 1633 ASSERT_EFI_ERROR (Status); 1634 1635 Status = DiskInfo->WhichIde ( 1636 DiskInfo, 1637 &IdeChannel, 1638 &IdeDevice 1639 ); 1640 ASSERT_EFI_ERROR (Status); 1641 1642 IdentifyDriveInfo = AllocatePool (sizeof(EFI_ATA_IDENTIFY_DATA)); 1643 1644 BufferSize = sizeof(EFI_ATA_IDENTIFY_DATA); 1645 Status = DiskInfo->Identify ( 1646 DiskInfo, 1647 IdentifyDriveInfo, 1648 &BufferSize 1649 ); 1650 ASSERT_EFI_ERROR(Status); 1651 1652 // 1653 // Onboard SATA Devices 1654 // 1655 if (PciDevicePath->Function == PCI_FUNCTION_NUMBER_PCH_SATA) { 1656 if (IdeChannel == 0 && IdeDevice == 0) { 1657 NameToUpdate = (STRING_REF)STR_SATA0_NAME; 1658 } else if (IdeChannel == 1 && IdeDevice == 0) { 1659 NameToUpdate = (STRING_REF)STR_SATA1_NAME; 1660 } else { 1661 continue; 1662 } 1663 } else { 1664 continue; 1665 } 1666 1667 ZeroMem(StringBuffer, sizeof(StringBuffer)); 1668 CopyMem( 1669 StringBuffer, 1670 (CHAR8 *)&IdentifyDriveInfo->ModelName, 1671 sizeof(IdentifyDriveInfo->ModelName) 1672 ); 1673 SwapEntries(StringBuffer); 1674 AsciiToUnicode(StringBuffer, NewString); 1675 1676 // 1677 // Chap it off after 16 characters 1678 // 1679 NewString[16] = 0; 1680 1681 // 1682 // For HardDisk append the size. Otherwise display atapi 1683 // 1684 if ((IdentifyDriveInfo->config & 0x8000) == 00) { 1685 // 1686 // 48 bit address feature set is supported, get maximum capacity 1687 // 1688 if ((IdentifyDriveInfo->command_set_supported_83 & 0x0400) == 0) { 1689 DriveSize = (((((IdentifyDriveInfo->user_addressable_sectors_hi << 16) + 1690 IdentifyDriveInfo->user_addressable_sectors_lo) / 1000) * 512) / 1000); 1691 } else { 1692 DriveSize = IdentifyDriveInfo->maximum_lba_for_48bit_addressing[0]; 1693 for (Index1 = 1; Index1 < 4; Index1++) { 1694 // 1695 // Lower byte goes first: word[100] is the lowest word, word[103] is highest 1696 // 1697 DriveSize |= LShiftU64(IdentifyDriveInfo->maximum_lba_for_48bit_addressing[Index1], 16 * Index1); 1698 } 1699 DriveSize = (UINT32) DivU64x32(MultU64x32(DivU64x32(DriveSize, 1000), 512), 1000); 1700 } 1701 1702 StrCat (NewString, L"("); 1703 EfiValueToString (SizeString, DriveSize/1000, PREFIX_BLANK, 0); 1704 StrCat (NewString, SizeString); 1705 StrCat (NewString, L"."); 1706 EfiValueToString (SizeString, (DriveSize%1000)/100, PREFIX_BLANK, 0); 1707 StrCat (NewString, SizeString); 1708 StrCat (NewString, L"GB"); 1709 } else { 1710 StrCat (NewString, L"(ATAPI"); 1711 } 1712 1713 // 1714 // Update SPEED. 1715 // 1716 PortNumber = (IdeDevice << 1) + IdeChannel; 1717 DeviceSpeed = GetChipsetSataPortSpeed(PortNumber); 1718 1719 if (DeviceSpeed) { 1720 StrCat (NewString, L"-"); 1721 GetDeviceSpeedString( NewString, DeviceSpeed); 1722 } 1723 1724 StrCat (NewString, L")"); 1725 1726 HiiSetString(mHiiHandle, NameToUpdate, NewString, NULL); 1727 1728 } 1729 } 1730 1731 if (HandleBuffer != NULL) { 1732 gBS->FreePool (HandleBuffer); 1733 } 1734 1735 gBS->FreePool(NewString); 1736 1737 return; 1738 } 1739 1740 1741 VOID 1742 EFIAPI 1743 SetupInfo (void) 1744 { 1745 EFI_STATUS Status; 1746 UINTN VarSize; 1747 EFI_PEI_HOB_POINTERS GuidHob; 1748 1749 if (mSetupInfoDone) { 1750 return; 1751 } 1752 1753 VarSize = sizeof(SYSTEM_CONFIGURATION); 1754 Status = gRT->GetVariable( 1755 NORMAL_SETUP_NAME, 1756 &gEfiNormalSetupGuid, 1757 NULL, 1758 &VarSize, 1759 &mSystemConfiguration 1760 ); 1761 1762 if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { 1763 //The setup variable is corrupted 1764 VarSize = sizeof(SYSTEM_CONFIGURATION); 1765 Status = gRT->GetVariable( 1766 L"SetupRecovery", 1767 &gEfiNormalSetupGuid, 1768 NULL, 1769 &VarSize, 1770 &mSystemConfiguration 1771 ); 1772 ASSERT_EFI_ERROR (Status); 1773 } 1774 1775 // 1776 // Update HOB variable for PCI resource information 1777 // Get the HOB list. If it is not present, then ASSERT. 1778 // 1779 GuidHob.Raw = GetHobList (); 1780 if (GuidHob.Raw != NULL) { 1781 if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) { 1782 mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid); 1783 } 1784 } 1785 1786 1787 PrepareSetupInformation(); 1788 UpdateAdditionalInformation (); 1789 UpdatePlatformInformation(); 1790 UpdateCPUInformation(); 1791 IdeDataFilter(); 1792 mSetupInfoDone = TRUE; 1793 1794 return; 1795 } 1796 1797 1798 #define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot" 1799 1800 VOID 1801 CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr) 1802 { 1803 EFI_STATUS Status; 1804 UINT8 SecureBoot; 1805 UINTN DataSize; 1806 1807 1808 DataSize = sizeof(SecureBoot); 1809 Status = gRT->GetVariable ( 1810 EFI_SECURE_BOOT_MODE_NAME, 1811 &gEfiGlobalVariableGuid, 1812 NULL, 1813 &DataSize, 1814 &SecureBoot 1815 ); 1816 1817 if (EFI_ERROR(Status)) { 1818 SystemConfigPtr->SecureBoot = 0; 1819 } else { 1820 SystemConfigPtr->SecureBoot = SecureBoot; 1821 } 1822 } 1823 1824 1825 // 1826 // "SecureBootEnable" variable for the Secure boot feature enable/disable. 1827 // 1828 #define EFI_SECURE_BOOT_ENABLE_NAME L"SecureBootEnable" 1829 extern EFI_GUID gEfiSecureBootEnableDisableGuid; 1830 1831 1832 VOID 1833 CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr) 1834 { 1835 EFI_STATUS Status; 1836 UINT8 SecureBootCfg; 1837 BOOLEAN SecureBootNotFound; 1838 UINTN DataSize; 1839 1840 1841 // 1842 // Secure Boot configuration changes 1843 // 1844 DataSize = sizeof(SecureBootCfg); 1845 SecureBootNotFound = FALSE; 1846 Status = gRT->GetVariable ( 1847 EFI_SECURE_BOOT_ENABLE_NAME, 1848 &gEfiSecureBootEnableDisableGuid, 1849 NULL, 1850 &DataSize, 1851 &SecureBootCfg 1852 ); 1853 1854 if (EFI_ERROR(Status)) { 1855 SecureBootNotFound = TRUE; 1856 } 1857 if (SecureBootNotFound) { 1858 Status = gRT->GetVariable ( 1859 EFI_SECURE_BOOT_ENABLE_NAME, 1860 &gEfiSecureBootEnableDisableGuid, 1861 NULL, 1862 &DataSize, 1863 &SecureBootCfg 1864 ); 1865 ASSERT_EFI_ERROR(Status); 1866 } 1867 if ((SecureBootCfg) != SystemConfigPtr->SecureBoot) { 1868 SecureBootCfg = !SecureBootCfg; 1869 Status = gRT->SetVariable ( 1870 EFI_SECURE_BOOT_ENABLE_NAME, 1871 &gEfiSecureBootEnableDisableGuid, 1872 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1873 sizeof (UINT8), 1874 &SecureBootCfg 1875 ); 1876 } 1877 1878 } 1879 1880 VOID 1881 ConfirmSecureBootTest() 1882 { 1883 1884 } 1885 1886