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 **/ 27 28 #include "CommonHeader.h" 29 30 #include "Platform.h" 31 #include <Library/PciCf8Lib.h> 32 #include "PlatformBaseAddresses.h" 33 #include "PchAccess.h" 34 #include <Guid/PlatformInfo.h> 35 #include "Platform.h" 36 #include "PchCommonDefinitions.h" 37 #include <Ppi/MfgMemoryTest.h> 38 #include <Guid/SetupVariable.h> 39 #include <Guid/Vlv2Variable.h> 40 #include <Ppi/fTPMPolicy.h> 41 42 // 43 // Start::Alpine Valley platform 44 // 45 enum { 46 SMBUS_READ_BYTE, 47 SMBUS_WRITE_BYTE, 48 SMBUS_READ_BLOCK, 49 SMBUS_WRITE_BLOCK 50 }; 51 52 #define EC_BASE 0xE0000000 53 54 // 55 // DEVICE 0 (Memroy Controller Hub) 56 // 57 #define MC_BUS 0x00 58 #define MC_DEV 0x00 59 #define MC_FUN 0x00 60 #define MC_DEV_FUN (MC_DEV << 3) 61 #define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN) 62 63 // 64 // SysCtl SMBus address and block size 65 // 66 #define AV_SC_SMBUS_ADDRESS 0x60 67 #define AV_SC_BYTE_LEN 1 68 #define AV_SC_BLOCK_LEN 4 69 #define AV_SC_SMBUS_WRCMD 1 70 #define AV_SC_SMBUS_RDCMD 0 71 72 // 73 // SysCtl registers offset 74 // 75 #define AV_SC_REG_PLATFORM_ID 24 // 0x18 76 #define AV_SC_REG_BOARD_ID 28 // 0x1C 77 #define AV_SC_REG_FAB_ID 32 // 0x20 78 #define AV_SC_REG_ECO_ID 68 // 0x44 79 #define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90 80 #define AV_SC_REG_SODIMM_CONFIG 36 81 82 // 83 // ID values 84 // 85 #define AV_SC_PLATFORM_ID_TABLET 0 86 #define AV_SC_PLATFORM_ID_NETBOOK 2 87 #define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD 88 #define AV_SC_BOARD_ID_AV_SVP 1492 89 90 #define BUS_TRIES 3 // How many times to retry on Bus Errors 91 92 #define GTT_SIZE_1MB 1 93 #define GTT_SIZE_2MB 2 94 95 #define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \ 96 MmioRead16(PciExpressBase + \ 97 (UINTN)(Bus << 20) + \ 98 (UINTN)(Device << 15) + \ 99 (UINTN)(Function << 12) + \ 100 (UINTN)(Register)) 101 #define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \ 102 MmioWrite16(PciExpressBase + \ 103 (UINTN)(Bus << 20) + \ 104 (UINTN)(Device << 15) + \ 105 (UINTN)(Function << 12) + \ 106 (UINTN)(Register), \ 107 (UINT16)Data) 108 109 110 // 111 //Memory Test Manufacturing mode 112 // 113 UINT32 DataPatternForMemoryTest[] = { 114 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 115 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 116 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 117 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555 118 }; 119 #define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32)) 120 121 // 122 //Memory Test Manufacturing mode 123 // 124 // 125 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory 126 // 127 BOOLEAN ImageInMemory = FALSE; 128 129 EFI_STATUS 130 EFIAPI 131 Stall ( 132 IN CONST EFI_PEI_SERVICES **PeiServices, 133 IN CONST EFI_PEI_STALL_PPI *This, 134 IN UINTN Microseconds 135 ); 136 137 EFI_STATUS 138 EFIAPI 139 MfgMemoryTest ( 140 IN CONST EFI_PEI_SERVICES **PeiServices, 141 IN PEI_MFG_MEMORY_TEST_PPI *This, 142 IN UINT32 BeginAddress, 143 IN UINT32 MemoryLength 144 ); 145 146 static EFI_PEI_STALL_PPI mStallPpi = { 147 PEI_STALL_RESOLUTION, 148 Stall 149 }; 150 151 static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = { 152 MfgMemoryTest 153 }; 154 155 static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi[] = { 156 { 157 EFI_PEI_PPI_DESCRIPTOR_PPI, 158 &gEfiPeiStallPpiGuid, 159 &mStallPpi 160 }, 161 { 162 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, 163 &gPeiMfgMemoryTestPpiGuid, 164 &mPeiMfgMemoryTestPpi 165 } 166 }; 167 168 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = { 169 { 170 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 171 &gEfiPeiMemoryDiscoveredPpiGuid, 172 MemoryDiscoveredPpiNotifyCallback 173 } 174 }; 175 176 EFI_STATUS 177 EFIAPI 178 InstallMonoStatusCode ( 179 IN EFI_FFS_FILE_HEADER *FfsHeader, 180 IN CONST EFI_PEI_SERVICES **PeiServices 181 ); 182 183 184 EFI_STATUS 185 ReadPlatformIds ( 186 IN CONST EFI_PEI_SERVICES **PeiServices, 187 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob 188 ); 189 190 // 191 // Start::Alpine Valley platform 192 // 193 EFI_STATUS 194 PeiSmbusExec ( 195 UINT16 SmbusBase, 196 UINT8 SlvAddr, 197 UINT8 Operation, 198 UINT8 Offset, 199 UINT8 *Length, 200 UINT8 *Buffer 201 ); 202 203 204 /** 205 206 Detemine Turbot board 207 @return 0: Not Turbot board 208 1: Turbot board 209 210 **/ 211 UINT32 212 DetermineTurbotBoard ( 213 void 214 ) 215 { 216 UINTN PciD31F0RegBase = 0; 217 UINT32 GpioValue = 0; 218 UINT32 TmpVal = 0; 219 UINT32 MmioConf0 = 0; 220 UINT32 MmioPadval = 0; 221 UINT32 PConf0Offset = 0x200; //GPIO_S5_4 pad_conf0 register offset 222 UINT32 PValueOffset = 0x208; //GPIO_S5_4 pad_value register offset 223 UINT32 SSUSOffset = 0x2000; 224 UINT32 IoBase = 0; 225 226 DEBUG ((EFI_D_ERROR, "DetermineTurbotBoard() Entry\n")); 227 PciD31F0RegBase = MmPciAddress (0, 228 0, 229 PCI_DEVICE_NUMBER_PCH_LPC, 230 PCI_FUNCTION_NUMBER_PCH_LPC, 231 0 232 ); 233 IoBase = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR; 234 235 MmioConf0 = IoBase + SSUSOffset + PConf0Offset; 236 MmioPadval = IoBase + SSUSOffset + PValueOffset; 237 //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4 238 DEBUG ((EFI_D_ERROR, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0, MmioPadval)); 239 240 MmioWrite32 (MmioConf0, 0x2003CC00); 241 242 TmpVal = MmioRead32 (MmioPadval); 243 TmpVal &= ~0x6; //Clear bit 1:2 244 TmpVal |= 0x2; // Set the pin as GPI 245 MmioWrite32 (MmioPadval, TmpVal); 246 247 GpioValue = MmioRead32 (MmioPadval); 248 249 DEBUG ((EFI_D_ERROR, "Gpio_S5_4 value is 0x%x\n", GpioValue)); 250 return (GpioValue & 0x1); 251 } 252 253 254 255 EFI_STATUS 256 FtpmPolicyInit ( 257 IN CONST EFI_PEI_SERVICES **PeiServices, 258 IN SYSTEM_CONFIGURATION *pSystemConfiguration 259 ) 260 { 261 EFI_STATUS Status; 262 EFI_PEI_PPI_DESCRIPTOR *mFtpmPolicyPpiDesc; 263 SEC_FTPM_POLICY_PPI *mFtpmPolicyPpi; 264 265 266 DEBUG((EFI_D_INFO, "FtpmPolicyInit Entry \n")); 267 268 if (NULL == PeiServices || NULL == pSystemConfiguration) { 269 DEBUG((EFI_D_ERROR, "Input error. \n")); 270 return EFI_INVALID_PARAMETER; 271 } 272 273 Status = (*PeiServices)->AllocatePool( 274 PeiServices, 275 sizeof (EFI_PEI_PPI_DESCRIPTOR), 276 (void **)&mFtpmPolicyPpiDesc 277 ); 278 ASSERT_EFI_ERROR (Status); 279 280 Status = (*PeiServices)->AllocatePool( 281 PeiServices, 282 sizeof (SEC_FTPM_POLICY_PPI), 283 (void **)&mFtpmPolicyPpi 284 ); 285 ASSERT_EFI_ERROR (Status); 286 287 // 288 // Initialize PPI 289 // 290 (*PeiServices)->SetMem ((VOID *)mFtpmPolicyPpi, sizeof (SEC_FTPM_POLICY_PPI), 0); 291 mFtpmPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; 292 mFtpmPolicyPpiDesc->Guid = &gSeCfTPMPolicyPpiGuid; 293 mFtpmPolicyPpiDesc->Ppi = mFtpmPolicyPpi; 294 295 296 DEBUG((EFI_D_INFO, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration->fTPM)); 297 if(pSystemConfiguration->fTPM == 1) { 298 mFtpmPolicyPpi->fTPMEnable = TRUE; 299 } else { 300 mFtpmPolicyPpi->fTPMEnable = FALSE; 301 } 302 303 Status = (*PeiServices)->InstallPpi( 304 PeiServices, 305 mFtpmPolicyPpiDesc 306 ); 307 ASSERT_EFI_ERROR (Status); 308 309 DEBUG((EFI_D_INFO, "FtpmPolicyInit done \n")); 310 311 return EFI_SUCCESS; 312 } 313 314 315 /** 316 This routine attempts to acquire the SMBus 317 318 @retval FAILURE as failed 319 @retval SUCCESS as passed 320 321 **/ 322 EFI_STATUS 323 AcquireBus ( 324 UINT16 SmbusBase 325 ) 326 { 327 UINT8 StsReg; 328 329 StsReg = 0; 330 StsReg = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS); 331 if (StsReg & B_PCH_SMBUS_IUS) { 332 return EFI_DEVICE_ERROR; 333 } else if (StsReg & B_PCH_SMBUS_HBSY) { 334 // 335 // Clear Status Register and exit 336 // 337 // Wait for HSTS.HBSY to be clear 338 // 339 do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); } while ((StsReg & B_PCH_SMBUS_HBSY) != 0); 340 341 // 342 // Clear all status bits 343 // 344 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE); 345 return EFI_SUCCESS; 346 } else { 347 // 348 // Clear out any odd status information (Will Not Clear In Use) 349 // 350 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg); 351 return EFI_SUCCESS; 352 } 353 } 354 // 355 // End::Alpine Valley platform 356 // 357 358 /** 359 This function checks the memory range in PEI. 360 361 @param PeiServices Pointer to PEI Services. 362 @param This Pei memory test PPI pointer. 363 @param BeginAddress Beginning of the memory address to be checked. 364 @param MemoryLength Bytes of memory range to be checked. 365 @param Operation Type of memory check operation to be performed. 366 @param ErrorAddress Return the address of the error memory address. 367 368 @retval EFI_SUCCESS The operation completed successfully. 369 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory. 370 371 **/ 372 EFI_STATUS 373 EFIAPI 374 MfgMemoryTest ( 375 IN CONST EFI_PEI_SERVICES **PeiServices, 376 IN PEI_MFG_MEMORY_TEST_PPI *This, 377 IN UINT32 BeginAddress, 378 IN UINT32 MemoryLength 379 ) 380 { 381 UINT32 i; 382 UINT32 memAddr; 383 UINT32 readData; 384 UINT32 xorData; 385 UINT32 TestFlag = 0; 386 memAddr = BeginAddress; 387 388 // 389 //Output Message for MFG 390 // 391 DEBUG ((EFI_D_ERROR, "MFGMODE SET\n")); 392 393 // 394 //Writting the pattern in defined location. 395 // 396 while (memAddr < (BeginAddress+MemoryLength)) { 397 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) { 398 if (memAddr > (BeginAddress+MemoryLength -4)) { 399 memAddr = memAddr + 4; 400 break; 401 } 402 *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i]; 403 memAddr = memAddr + 4; 404 } 405 } 406 407 // 408 //Verify the pattern. 409 // 410 memAddr = BeginAddress; 411 while (memAddr < (BeginAddress+MemoryLength)) { 412 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) { 413 if (memAddr > (BeginAddress+MemoryLength -4)) { 414 memAddr = memAddr + 4; 415 break; 416 } 417 readData = *((volatile UINT32*) memAddr); 418 xorData = readData ^ DataPatternForMemoryTest[i]; 419 420 // 421 // If xorData is nonzero, this particular memAddr has a failure. 422 // 423 if (xorData != 0x00000000) { 424 DEBUG ((EFI_D_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i])); 425 DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData)); 426 DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr)); 427 TestFlag = 1; 428 } 429 memAddr = memAddr + 4; 430 } 431 } 432 if (TestFlag) { 433 return EFI_DEVICE_ERROR; 434 } 435 436 // 437 //Output Message for MFG 438 // 439 DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n")); 440 return EFI_SUCCESS; 441 } 442 443 BOOLEAN 444 IsRtcUipAlwaysSet ( 445 IN CONST EFI_PEI_SERVICES **PeiServices 446 ) 447 { 448 449 EFI_PEI_STALL_PPI *StallPpi; 450 UINTN Count; 451 452 (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi); 453 454 for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500) 455 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA); 456 if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0) { 457 return FALSE; 458 } 459 460 StallPpi->Stall (PeiServices, StallPpi, 3000); 461 } 462 463 return TRUE; 464 } 465 466 EFI_STATUS 467 RtcPowerFailureHandler ( 468 IN CONST EFI_PEI_SERVICES **PeiServices 469 ) 470 { 471 472 UINT16 DataUint16; 473 UINT8 DataUint8; 474 BOOLEAN RtcUipIsAlwaysSet; 475 DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1); 476 RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices); 477 if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) { 478 // 479 // Execute the sequence below. This will ensure that the RTC state machine has been initialized. 480 // 481 // Step 1. 482 // BIOS clears this bit by writing a '0' to it. 483 // 484 if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) { 485 // 486 // Set to invalid date in order to reset the time to 487 // BIOS build time later in the boot (SBRUN.c file). 488 // 489 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR); 490 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF); 491 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH); 492 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF); 493 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH); 494 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF); 495 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK); 496 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF); 497 498 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM); 499 IoWrite8 (R_PCH_RTC_TARGET2, 0x00); 500 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM); 501 IoWrite8 (R_PCH_RTC_TARGET2, 0x00); 502 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM); 503 IoWrite8 (R_PCH_RTC_TARGET2, 0x00); 504 } 505 506 // 507 // Step 2. 508 // Set RTC Register 0Ah[6:4] to '110' or '111'. 509 // 510 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA); 511 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US)); 512 513 // 514 // Step 3. 515 // Set RTC Register 0Bh[7]. 516 // 517 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB); 518 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET); 519 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB); 520 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8); 521 522 // 523 // Step 4. 524 // Set RTC Register 0Ah[6:4] to '010'. 525 // 526 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA); 527 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US)); 528 529 // 530 // Step 5. 531 // Clear RTC Register 0Bh[7]. 532 // 533 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB); 534 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET); 535 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB); 536 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8); 537 } 538 539 return EFI_SUCCESS; 540 } 541 542 543 VOID 544 PchBaseInit ( 545 VOID 546 ) 547 { 548 // 549 // Program ACPI Power Management I/O Space Base Address 550 // 551 MmioWrite16 ( 552 MmPciAddress (0, 553 DEFAULT_PCI_BUS_NUMBER_PCH, 554 PCI_DEVICE_NUMBER_PCH_LPC, 555 PCI_FUNCTION_NUMBER_PCH_LPC, 556 R_PCH_LPC_ACPI_BASE 557 ), 558 (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN) 559 ); 560 561 // 562 // Program GPIO Base Address 563 // 564 MmioWrite16 ( 565 MmPciAddress (0, 566 DEFAULT_PCI_BUS_NUMBER_PCH, 567 PCI_DEVICE_NUMBER_PCH_LPC, 568 PCI_FUNCTION_NUMBER_PCH_LPC, 569 R_PCH_LPC_GPIO_BASE 570 ), 571 (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN) 572 ); 573 574 // 575 // Set PMC Base Address 576 // 577 MmioWrite32 ( 578 MmPciAddress (0, 579 DEFAULT_PCI_BUS_NUMBER_PCH, 580 PCI_DEVICE_NUMBER_PCH_LPC, 581 PCI_FUNCTION_NUMBER_PCH_LPC, 582 R_PCH_LPC_PMC_BASE 583 ), 584 (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN) 585 ); 586 587 // 588 // Set IO Base Address 589 // 590 MmioWrite32 ( 591 MmPciAddress (0, 592 DEFAULT_PCI_BUS_NUMBER_PCH, 593 PCI_DEVICE_NUMBER_PCH_LPC, 594 PCI_FUNCTION_NUMBER_PCH_LPC, 595 R_PCH_LPC_IO_BASE 596 ), 597 (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN) 598 ); 599 600 // 601 // Set ILB Base Address 602 // 603 MmioWrite32 ( 604 MmPciAddress (0, 605 DEFAULT_PCI_BUS_NUMBER_PCH, 606 PCI_DEVICE_NUMBER_PCH_LPC, 607 PCI_FUNCTION_NUMBER_PCH_LPC, 608 R_PCH_LPC_ILB_BASE 609 ), 610 (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN) 611 ); 612 613 // 614 // Set PUnit Base Address 615 // 616 MmioWrite32 ( 617 MmPciAddress (0, 618 DEFAULT_PCI_BUS_NUMBER_PCH, 619 PCI_DEVICE_NUMBER_PCH_LPC, 620 PCI_FUNCTION_NUMBER_PCH_LPC, 621 R_PCH_LPC_PUNIT_BASE 622 ), 623 (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN) 624 ); 625 626 // 627 // Set SPI Base Address 628 // 629 MmioWrite32 ( 630 MmPciAddress (0, 631 DEFAULT_PCI_BUS_NUMBER_PCH, 632 PCI_DEVICE_NUMBER_PCH_LPC, 633 PCI_FUNCTION_NUMBER_PCH_LPC, 634 R_PCH_LPC_SPI_BASE 635 ), 636 (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN) 637 ); 638 639 // 640 // Set Root Complex Base Address 641 // 642 MmioWrite32 ( 643 MmPciAddress (0, 644 DEFAULT_PCI_BUS_NUMBER_PCH, 645 PCI_DEVICE_NUMBER_PCH_LPC, 646 PCI_FUNCTION_NUMBER_PCH_LPC, 647 R_PCH_LPC_RCBA 648 ), 649 (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN) 650 ); 651 652 // 653 // Set MPHY Base Address 654 // 655 MmioWrite32 ( 656 MmPciAddress (0, 657 DEFAULT_PCI_BUS_NUMBER_PCH, 658 PCI_DEVICE_NUMBER_PCH_LPC, 659 PCI_FUNCTION_NUMBER_PCH_LPC, 660 R_PCH_LPC_MPHY_BASE 661 ), 662 (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN) 663 ); 664 MmioWrite16 ( 665 MmPciAddress (0, 666 DEFAULT_PCI_BUS_NUMBER_PCH, 667 PCI_DEVICE_NUMBER_PCH_SMBUS, 668 PCI_FUNCTION_NUMBER_PCH_SMBUS, 669 R_PCH_SMBUS_BASE 670 ), 671 (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR) 672 ); 673 674 MmioOr8 ( 675 MmPciAddress (0, 676 DEFAULT_PCI_BUS_NUMBER_PCH, 677 PCI_DEVICE_NUMBER_PCH_SMBUS, 678 PCI_FUNCTION_NUMBER_PCH_SMBUS, 679 R_PCH_SMBUS_PCICMD 680 ), 681 B_PCH_SMBUS_PCICMD_IOSE 682 ); 683 684 } 685 686 /** 687 This is the entrypoint of PEIM 688 689 @param FileHandle Handle of the file being invoked. 690 @param PeiServices Describes the list of possible PEI Services. 691 692 @retval EFI_SUCCESS if it completed successfully. 693 **/ 694 EFI_STATUS 695 EFIAPI 696 PeiInitPlatform ( 697 IN EFI_PEI_FILE_HANDLE FileHandle, 698 IN CONST EFI_PEI_SERVICES **PeiServices 699 ) 700 { 701 UINTN SmbusRegBase; 702 EFI_PLATFORM_INFO_HOB PlatformInfo; 703 EFI_STATUS Status= EFI_SUCCESS; 704 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable = NULL; 705 UINTN VariableSize; 706 SYSTEM_CONFIGURATION SystemConfiguration; 707 UINT32 GGC = 0; 708 709 EFI_PEI_PPI_DESCRIPTOR *mVlvMmioPolicyPpiDesc; 710 VLV_MMIO_POLICY_PPI *mVlvMmioPolicyPpi; 711 712 ZeroMem (&PlatformInfo, sizeof(PlatformInfo)); 713 714 Status = InstallMonoStatusCode(FileHandle, PeiServices); 715 ASSERT_EFI_ERROR (Status); 716 717 718 // 719 // Initialize Stall PPIs 720 // 721 Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]); 722 ASSERT_EFI_ERROR (Status); 723 724 Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]); 725 ASSERT_EFI_ERROR (Status); 726 SmbusRegBase = PchPciDeviceMmBase ( 727 DEFAULT_PCI_BUS_NUMBER_PCH, 728 PCI_DEVICE_NUMBER_PCH_SMBUS, 729 PCI_FUNCTION_NUMBER_PCH_SMBUS 730 ); 731 // 732 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves 733 // 734 MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS); 735 736 MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE); 737 738 PchBaseInit(); 739 740 // 741 //Todo: confirm if we need program 8254 742 // 743 // Setting 8254 744 // Program timer 1 as refresh timer 745 // 746 IoWrite8 (0x43, 0x54); 747 IoWrite8 (0x41, 0x12); 748 749 // 750 // RTC power failure handling 751 // 752 RtcPowerFailureHandler (PeiServices); 753 754 755 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210; 756 757 VariableSize = sizeof (SYSTEM_CONFIGURATION); 758 ZeroMem (&SystemConfiguration, VariableSize); 759 760 // 761 // Obtain variable services 762 // 763 Status = (*PeiServices)->LocatePpi( 764 PeiServices, 765 &gEfiPeiReadOnlyVariable2PpiGuid, 766 0, 767 NULL, 768 (void **)&Variable 769 ); 770 ASSERT_EFI_ERROR(Status); 771 Status = Variable->GetVariable ( 772 Variable, 773 L"Setup", 774 &gEfiSetupVariableGuid, 775 NULL, 776 &VariableSize, 777 &SystemConfiguration 778 ); 779 if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) { 780 //The setup variable is corrupted 781 VariableSize = sizeof(SYSTEM_CONFIGURATION); 782 Status = Variable->GetVariable( 783 Variable, 784 L"SetupRecovery", 785 &gEfiSetupVariableGuid, 786 NULL, 787 &VariableSize, 788 &SystemConfiguration 789 ); 790 ASSERT_EFI_ERROR (Status); 791 } 792 793 if (EFI_ERROR (Status)) { 794 GGC = ((2 << 3) | 0x200); 795 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC); 796 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50); 797 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3)); 798 } else { 799 if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) { 800 GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) | 801 (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200); 802 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC); 803 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50); 804 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3)); 805 } 806 } 807 808 // 809 // Initialize PlatformInfo HOB 810 // 811 Status = ReadPlatformIds(PeiServices, &PlatformInfo); 812 ASSERT_EFI_ERROR (Status); 813 814 // 815 // 0 -> Disable , 1 -> Enable 816 // 817 if(SystemConfiguration.CfioPnpSettings == 1) { 818 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n")); 819 PlatformInfo.CfioEnabled = 1; 820 } else { 821 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n")); 822 PlatformInfo.CfioEnabled = 0; 823 } 824 825 // 826 // Build HOB for PlatformInfo 827 // 828 BuildGuidDataHob ( 829 &gEfiPlatformInfoGuid, 830 &PlatformInfo, 831 sizeof (EFI_PLATFORM_INFO_HOB) 832 ); 833 834 835 #ifdef FTPM_ENABLE 836 Status = FtpmPolicyInit(PeiServices, &SystemConfiguration); 837 if (EFI_ERROR (Status)) { 838 DEBUG((EFI_D_ERROR, "fTPM init failed.\n")); 839 } 840 #endif 841 842 843 // 844 // Set the new boot mode for MRC 845 // 846 #ifdef NOCS_S3_SUPPORT 847 Status = UpdateBootMode (PeiServices); 848 ASSERT_EFI_ERROR (Status); 849 #endif 850 851 DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n")); 852 853 // 854 // Setup MMIO size 855 // 856 Status = (*PeiServices)->AllocatePool( 857 PeiServices, 858 sizeof (EFI_PEI_PPI_DESCRIPTOR), 859 (void **)&mVlvMmioPolicyPpiDesc 860 ); 861 ASSERT_EFI_ERROR (Status); 862 Status = (*PeiServices)->AllocatePool( 863 PeiServices, 864 sizeof (VLV_MMIO_POLICY_PPI), 865 (void **)&mVlvMmioPolicyPpi 866 ); 867 ASSERT_EFI_ERROR (Status); 868 (*PeiServices)->SetMem ( 869 (VOID *)mVlvMmioPolicyPpi, 870 sizeof (VLV_MMIO_POLICY_PPI), 871 0 872 ); 873 mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; 874 mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid; 875 mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi; 876 switch (SystemConfiguration.MmioSize) { 877 case 0: // 768MB 878 mVlvMmioPolicyPpi->MmioSize = 0x300; 879 break; 880 case 1: // 1GB 881 mVlvMmioPolicyPpi->MmioSize = 0x400; 882 break; 883 case 2: // 1.25GB 884 mVlvMmioPolicyPpi->MmioSize = 0x500; 885 break; 886 case 3: // 1.5GB 887 mVlvMmioPolicyPpi->MmioSize = 0x600; 888 break; 889 case 4: // 2GB 890 mVlvMmioPolicyPpi->MmioSize = 0x800; 891 break; 892 default: 893 mVlvMmioPolicyPpi->MmioSize = 0x800; 894 break; 895 } 896 Status = (*PeiServices)->InstallPpi( 897 PeiServices, 898 mVlvMmioPolicyPpiDesc 899 ); 900 ASSERT_EFI_ERROR (Status); 901 902 return Status; 903 } 904 905 EFI_STATUS 906 ReadPlatformIds ( 907 IN CONST EFI_PEI_SERVICES **PeiServices, 908 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob 909 ) 910 { 911 { 912 EFI_STATUS Status = EFI_SUCCESS; 913 UINT8 FabId = 0; 914 UINTN DataSize; 915 EFI_PLATFORM_INFO_HOB TmpHob; 916 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar; 917 UINT32 CompatibleBoard = 0; 918 919 Status = (**PeiServices).LocatePpi ( 920 PeiServices, 921 &gEfiPeiReadOnlyVariable2PpiGuid, 922 0, 923 NULL, 924 (void **)&PeiVar 925 ); 926 ASSERT_EFI_ERROR (Status); 927 928 DataSize = sizeof (EFI_PLATFORM_INFO_HOB); 929 Status = PeiVar->GetVariable ( 930 PeiVar, 931 L"PlatformInfo", 932 &gEfiVlv2VariableGuid, 933 NULL, 934 &DataSize, 935 &TmpHob 936 ); 937 938 if (Status == EFI_SUCCESS) { 939 PlatformInfoHob->BoardId = TmpHob.BoardId; 940 PlatformInfoHob->MemCfgID = TmpHob.MemCfgID; 941 PlatformInfoHob->BoardRev = TmpHob.BoardRev; 942 PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor; 943 return Status; 944 } 945 946 CompatibleBoard = DetermineTurbotBoard(); 947 if (1 == CompatibleBoard) { 948 PlatformInfoHob->BoardId = BOARD_ID_MINNOW2_TURBOT; 949 DEBUG ((EFI_D_INFO, "I'm MinnowBoard Turbot!\n")); 950 } else { 951 PlatformInfoHob->BoardId = BOARD_ID_MINNOW2; 952 DEBUG ((EFI_D_INFO, "I'm MinnowBoard Max!\n")); 953 } 954 955 956 PlatformInfoHob->MemCfgID = 0; 957 PlatformInfoHob->BoardRev = FabId + 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)... 958 PlatformInfoHob->PlatformFlavor = FlavorMobile; 959 } 960 961 return EFI_SUCCESS; 962 } 963 964 // 965 // Start::Alpine Valley platform 966 // 967 /** 968 This routine reads SysCtl registers 969 970 @param SmbusBase SMBUS Base Address 971 @param SlvAddr Targeted Smbus Slave device address 972 @param Operation Which SMBus protocol will be used 973 @param Offset Offset of the register 974 @param Length Number of bytes 975 @param Buffer Buffer contains values read from registers 976 977 @retval SUCCESS as passed 978 @retval Others as failed 979 980 **/ 981 EFI_STATUS 982 PeiSmbusExec ( 983 UINT16 SmbusBase, 984 UINT8 SlvAddr, 985 UINT8 Operation, 986 UINT8 Offset, 987 UINT8 *Length, 988 UINT8 *Buffer 989 ) 990 { 991 EFI_STATUS Status=EFI_SUCCESS; 992 UINT8 AuxcReg; 993 UINT8 SmbusOperation = 0; 994 UINT8 StsReg; 995 UINT8 SlvAddrReg; 996 UINT8 HostCmdReg; 997 UINT8 BlockCount = 0; 998 BOOLEAN BufferTooSmall; 999 UINT8 Index; 1000 UINT8 *CallBuffer; 1001 UINT8 RetryCount = BUS_TRIES; 1002 1003 // 1004 // MrcSmbusExec supports byte and block read. 1005 // Only allow Byte or block access 1006 // 1007 if (!((*Length == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN))) { 1008 return EFI_INVALID_PARAMETER; 1009 } 1010 1011 // 1012 // See if its ok to use the bus based upon INUSE_STS bit. 1013 // 1014 Status = AcquireBus (SmbusBase); 1015 ASSERT_EFI_ERROR(Status); 1016 1017 CallBuffer = Buffer; 1018 1019 // 1020 //SmbStatus Bits of interest 1021 //[6] = IUS (In Use Status) 1022 //[4] = FAIL 1023 //[3] = BERR (Bus Error = transaction collision) 1024 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error) 1025 //[1] = INTR (Successful completion of last command) 1026 //[0] = HOST BUSY 1027 // 1028 // 1029 // This is the main operation loop. If the operation results in a Smbus 1030 // collision with another master on the bus, it attempts the requested 1031 // transaction again at least BUS_TRIES attempts. 1032 // 1033 while (RetryCount--) { 1034 // 1035 // Operation Specifics (pre-execution) 1036 // 1037 Status = EFI_SUCCESS; 1038 SlvAddrReg = SlvAddr; 1039 HostCmdReg = Offset; 1040 AuxcReg = 0; 1041 1042 switch (Operation) { 1043 1044 case SMBUS_WRITE_BYTE: 1045 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]); 1046 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA; 1047 break; 1048 1049 case SMBUS_READ_BYTE: 1050 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA; 1051 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ; 1052 if (*Length < 1) { 1053 Status = EFI_INVALID_PARAMETER; 1054 } 1055 *Length = 1; 1056 break; 1057 1058 case SMBUS_WRITE_BLOCK: 1059 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK; 1060 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length); 1061 BlockCount = (UINT8) (*Length); 1062 if ((*Length < 1) || (*Length > 32)) { 1063 Status = EFI_INVALID_PARAMETER; 1064 break; 1065 } 1066 AuxcReg |= B_PCH_SMBUS_E32B; 1067 break; 1068 1069 case SMBUS_READ_BLOCK: 1070 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK; 1071 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ; 1072 if ((*Length < 1) || (*Length > 32)) { 1073 Status = EFI_INVALID_PARAMETER; 1074 break; 1075 } 1076 AuxcReg |= B_PCH_SMBUS_E32B; 1077 break; 1078 1079 default: 1080 Status = EFI_INVALID_PARAMETER; 1081 break; 1082 } 1083 1084 // 1085 // Set Auxiliary Control register 1086 // 1087 IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg); 1088 1089 // 1090 // Reset the pointer of the internal buffer 1091 // 1092 IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL); 1093 1094 // 1095 // Now that the 32 byte buffer is turned on, we can write th block data 1096 // into it 1097 // 1098 if (Operation == SMBUS_WRITE_BLOCK) { 1099 for (Index = 0; Index < BlockCount; Index++) { 1100 // 1101 // Write next byte 1102 // 1103 IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]); 1104 } 1105 } 1106 1107 // 1108 // Set SMBus slave address for the device to read 1109 // 1110 IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg); 1111 1112 // 1113 // 1114 // Set Command register for the offset to read 1115 // 1116 IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg ); 1117 1118 // 1119 // Set Control Register to Set "operation command" protocol and start bit 1120 // 1121 IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START)); 1122 1123 // 1124 // Wait for IO to complete 1125 // 1126 do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg & (BIT4|BIT3|BIT2|BIT1)) == 0); 1127 1128 if (StsReg & B_PCH_SMBUS_DERR) { 1129 Status = EFI_DEVICE_ERROR; 1130 break; 1131 } else if (StsReg & B_PCH_SMBUS_BERR) { 1132 // 1133 // Clear the Bus Error for another try 1134 // 1135 Status = EFI_DEVICE_ERROR; 1136 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR); 1137 1138 // 1139 // Clear Status Registers 1140 // 1141 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); 1142 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE); 1143 1144 continue; 1145 } 1146 1147 // 1148 // successfull completion 1149 // Operation Specifics (post-execution) 1150 // 1151 switch (Operation) { 1152 1153 case SMBUS_READ_BYTE: 1154 CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0)); 1155 break; 1156 1157 case SMBUS_WRITE_BLOCK: 1158 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS); 1159 break; 1160 1161 case SMBUS_READ_BLOCK: 1162 BufferTooSmall = FALSE; 1163 1164 // 1165 // Find out how many bytes will be in the block 1166 // 1167 BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0)); 1168 if (*Length < BlockCount) { 1169 BufferTooSmall = TRUE; 1170 } else { 1171 for (Index = 0; Index < BlockCount; Index++) { 1172 // 1173 // Read the byte 1174 // 1175 CallBuffer[Index] = (UINT8)IoRead8 (SmbusBase+R_PCH_SMBUS_HBD); 1176 } 1177 } 1178 1179 *Length = BlockCount; 1180 if (BufferTooSmall) { 1181 Status = EFI_BUFFER_TOO_SMALL; 1182 } 1183 break; 1184 1185 default: 1186 break; 1187 }; 1188 1189 if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) { 1190 // 1191 // Clear the Bus Error for another try 1192 // 1193 Status = EFI_DEVICE_ERROR; 1194 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR); 1195 1196 continue; 1197 } else { 1198 break; 1199 } 1200 } 1201 1202 // 1203 // Clear Status Registers and exit 1204 // 1205 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); 1206 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE); 1207 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0); 1208 return Status; 1209 } 1210 // 1211 // End::Alpine Valley platform 1212 // 1213 1214