1 /** @file 2 This PEIM initialize platform for MRC, following action is performed, 3 1. Initizluize GMCH 4 2. Detect boot mode 5 3. Detect video adapter to determine whether we need pre allocated memory 6 4. Calls MRC to initialize memory and install a PPI notify to do post memory initialization. 7 This file contains the main entrypoint of the PEIM. 8 9 Copyright (c) 2013 - 2016 Intel Corporation. 10 11 This program and the accompanying materials 12 are licensed and made available under the terms and conditions of the BSD License 13 which accompanies this distribution. The full text of the license may be found at 14 http://opensource.org/licenses/bsd-license.php 15 16 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. 18 19 **/ 20 21 22 #include "CommonHeader.h" 23 #include "PlatformEarlyInit.h" 24 #include "PeiFvSecurity.h" 25 26 EFI_STATUS 27 EFIAPI 28 EndOfPeiSignalPpiNotifyCallback ( 29 IN EFI_PEI_SERVICES **PeiServices, 30 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 31 IN VOID *Ppi 32 ); 33 34 // 35 // Function prototypes to routines implemented in other source modules 36 // within this component. 37 // 38 39 EFI_STATUS 40 EFIAPI 41 PlatformErratasPostMrc ( 42 VOID 43 ); 44 45 // 46 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory 47 // 48 BOOLEAN ImageInMemory = FALSE; 49 50 BOARD_LEGACY_GPIO_CONFIG mBoardLegacyGpioConfigTable[] = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION }; 51 UINTN mBoardLegacyGpioConfigTableLen = (sizeof(mBoardLegacyGpioConfigTable) / sizeof(BOARD_LEGACY_GPIO_CONFIG)); 52 BOARD_GPIO_CONTROLLER_CONFIG mBoardGpioControllerConfigTable[] = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION }; 53 UINTN mBoardGpioControllerConfigTableLen = (sizeof(mBoardGpioControllerConfigTable) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG)); 54 UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff}; 55 56 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[1] = { 57 { 58 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 59 &gEfiPeiMasterBootModePpiGuid, 60 NULL 61 } 62 }; 63 64 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = { 65 { 66 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 67 &gEfiPeiMemoryDiscoveredPpiGuid, 68 MemoryDiscoveredPpiNotifyCallback 69 } 70 }; 71 72 EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[1] = { 73 { 74 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 75 &gEfiEndOfPeiSignalPpiGuid, 76 EndOfPeiSignalPpiNotifyCallback 77 } 78 }; 79 80 EFI_PEI_STALL_PPI mStallPpi = { 81 PEI_STALL_RESOLUTION, 82 Stall 83 }; 84 85 EFI_PEI_PPI_DESCRIPTOR mPpiStall[1] = { 86 { 87 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 88 &gEfiPeiStallPpiGuid, 89 &mStallPpi 90 } 91 }; 92 93 /** 94 Set Mac address on chipset ethernet device. 95 96 @param Bus PCI Bus number of chipset ethernet device. 97 @param Device Device number of chipset ethernet device. 98 @param Func PCI Function number of chipset ethernet device. 99 @param MacAddr MAC Address to set. 100 101 **/ 102 VOID 103 EFIAPI 104 SetLanControllerMacAddr ( 105 IN CONST UINT8 Bus, 106 IN CONST UINT8 Device, 107 IN CONST UINT8 Func, 108 IN CONST UINT8 *MacAddr, 109 IN CONST UINT32 Bar0 110 ) 111 { 112 UINT32 Data32; 113 UINT16 PciVid; 114 UINT16 PciDid; 115 UINT32 Addr; 116 UINT32 MacVer; 117 volatile UINT8 *Wrote; 118 UINT32 DevPcieAddr; 119 UINT16 SaveCmdReg; 120 UINT32 SaveBarReg; 121 122 DevPcieAddr = PCI_LIB_ADDRESS ( 123 Bus, 124 Device, 125 Func, 126 0 127 ); 128 129 // 130 // Do nothing if not a supported device. 131 // 132 PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET); 133 PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET); 134 if((PciVid != V_IOH_MAC_VENDOR_ID) || (PciDid != V_IOH_MAC_DEVICE_ID)) { 135 return; 136 } 137 138 // 139 // Save current settings for PCI CMD/BAR registers 140 // 141 SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET); 142 SaveBarReg = PciRead32 (DevPcieAddr + R_IOH_MAC_MEMBAR); 143 144 // 145 // Use predefined temporary memory resource 146 // 147 PciWrite32 ( DevPcieAddr + R_IOH_MAC_MEMBAR, Bar0); 148 PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); 149 150 Addr = Bar0 + R_IOH_MAC_GMAC_REG_8; 151 MacVer = *((volatile UINT32 *) (UINTN)(Addr)); 152 153 DEBUG ((EFI_D_INFO, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:", 154 (UINTN) Bus, 155 (UINTN) Device, 156 (UINTN) Func, 157 (UINTN) MacVer 158 )); 159 160 // 161 // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits. 162 // 163 Addr = Bar0 + R_IOH_MAC_GMAC_REG_17; 164 Data32 = *((UINT32 *) (UINTN)(&MacAddr[0])); 165 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 166 Wrote = (volatile UINT8 *) (UINTN)(Addr); 167 DEBUG ((EFI_D_INFO, "%02x-%02x-%02x-%02x-", 168 (UINTN) Wrote[0], 169 (UINTN) Wrote[1], 170 (UINTN) Wrote[2], 171 (UINTN) Wrote[3] 172 )); 173 174 // 175 // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits 176 // and Address Enable (AE) bit. 177 // 178 Addr = Bar0 + R_IOH_MAC_GMAC_REG_16; 179 Data32 = 180 ((UINT32) MacAddr[4]) | 181 (((UINT32)MacAddr[5]) << 8) | 182 B_IOH_MAC_AE; 183 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 184 Wrote = (volatile UINT8 *) (UINTN)(Addr); 185 186 DEBUG ((EFI_D_INFO, "%02x-%02x\n", (UINTN) Wrote[0], (UINTN) Wrote[1])); 187 188 // 189 // Restore settings for PCI CMD/BAR registers 190 // 191 PciWrite32 ((DevPcieAddr + R_IOH_MAC_MEMBAR), SaveBarReg); 192 PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg); 193 } 194 195 /** 196 Initialize state of I2C GPIO expanders. 197 198 @param PlatformType Platform type for GPIO expander init. 199 200 **/ 201 EFI_STATUS 202 EarlyPlatformConfigGpioExpanders ( 203 IN CONST EFI_PLATFORM_TYPE PlatformType, 204 EFI_BOOT_MODE BootMode 205 ) 206 { 207 EFI_STATUS Status; 208 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress; 209 UINTN Length; 210 UINTN ReadLength; 211 UINT8 Buffer[2]; 212 213 // 214 // Configure GPIO expanders for Galileo Gen 2 215 // Route I2C pins to Arduino header 216 // Set all GPIO expander pins connected to the Reset Button as inputs 217 // 218 if (PlatformType == GalileoGen2) { 219 // 220 // Configure AMUX1_IN (EXP2.P1_4) as an output 221 // 222 PlatformPcal9555GpioSetDir ( 223 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2. 224 12, // P1-4. 225 FALSE // Configure as output 226 ); 227 228 // 229 // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector 230 // 231 PlatformPcal9555GpioSetLevel ( 232 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2. 233 12, // P1-4. 234 FALSE // Set pin low 235 ); 236 237 // 238 // Configure Reset Button(EXP1.P1_7) as an input 239 // 240 PlatformPcal9555GpioSetDir ( 241 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1. 242 15, // P1-7. 243 TRUE 244 ); 245 246 // 247 // Disable pullup on Reset Button(EXP1.P1_7) 248 // 249 PlatformPcal9555GpioDisablePull ( 250 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1. 251 15 // P1-7. 252 ); 253 254 // 255 // Configure Reset Button(EXP2.P1_7) as an input 256 // 257 PlatformPcal9555GpioSetDir ( 258 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2. 259 15, // P1-7. 260 TRUE 261 ); 262 263 // 264 // Disable pullup on Reset Button(EXP2.P1_7) 265 // 266 PlatformPcal9555GpioDisablePull ( 267 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2. 268 15 // P1-7. 269 ); 270 271 if (BootMode != BOOT_IN_RECOVERY_MODE) { 272 // 273 // Read state of Reset Button - EXP2.P1_7 274 // This GPIO is pulled high when the button is not pressed 275 // This GPIO reads low when button is pressed 276 // 277 if (!PlatformPcal9555GpioGetState ( 278 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2 279 15 // P1-7 280 )) { 281 DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n")); 282 283 // 284 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset 285 // 286 QNCAltPortWrite ( 287 QUARK_SCSS_SOC_UNIT_SB_PORT_ID, 288 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, 289 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY 290 ); 291 ResetWarm(); 292 } 293 } 294 } 295 296 // 297 // Configure GPIO expanders for Galileo Gen 2 298 // Set all GPIO expander pins connected to the Reset Button as inputs 299 // Route I2C pins to Arduino header 300 // 301 if (PlatformType == Galileo) { 302 // 303 // Detect the I2C Slave Address of the GPIO Expander 304 // 305 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) { 306 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR; 307 } else { 308 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR; 309 } 310 DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress)); 311 312 // 313 // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector 314 // 315 316 // 317 // Select GPIO Expander GPORT1 318 // 319 Length = 2; 320 Buffer[0] = 0x18; //sub-address 321 Buffer[1] = 0x01; //data 322 Status = I2cWriteMultipleByte ( 323 I2CSlaveAddress, 324 EfiI2CSevenBitAddrMode, 325 &Length, 326 &Buffer 327 ); 328 ASSERT_EFI_ERROR (Status); 329 330 // 331 // Read "Pin Direction" of GPIO Expander GPORT1 332 // 333 Length = 1; 334 ReadLength = 1; 335 Buffer[1] = 0x1C; 336 Status = I2cReadMultipleByte ( 337 I2CSlaveAddress, 338 EfiI2CSevenBitAddrMode, 339 &Length, 340 &ReadLength, 341 &Buffer[1] 342 ); 343 ASSERT_EFI_ERROR (Status); 344 345 // 346 // Configure GPIO Expander GPORT1_BIT5 as an output 347 // 348 Length = 2; 349 Buffer[0] = 0x1C; //sub-address 350 Buffer[1] = (UINT8)(Buffer[1] & (~BIT5)); //data 351 352 Status = I2cWriteMultipleByte ( 353 I2CSlaveAddress, 354 EfiI2CSevenBitAddrMode, 355 &Length, 356 &Buffer 357 ); 358 ASSERT_EFI_ERROR (Status); 359 360 // 361 // Set GPIO Expander GPORT1_BIT5 low 362 // 363 Length = 2; 364 Buffer[0] = 0x09; //sub-address 365 Buffer[1] = (UINT8)(~BIT5); //data 366 367 Status = I2cWriteMultipleByte ( 368 I2CSlaveAddress, 369 EfiI2CSevenBitAddrMode, 370 &Length, 371 &Buffer 372 ); 373 ASSERT_EFI_ERROR (Status); 374 375 // 376 // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs 377 // 378 379 // 380 // Select GPIO Expander GPORT5 381 // 382 Length = 2; 383 Buffer[0] = 0x18; 384 Buffer[1] = 0x05; 385 Status = I2cWriteMultipleByte ( 386 I2CSlaveAddress, 387 EfiI2CSevenBitAddrMode, 388 &Length, 389 &Buffer 390 ); 391 ASSERT_EFI_ERROR (Status); 392 393 // 394 // Read "Pin Direction" of GPIO Expander GPORT5 395 // 396 Length = 1; 397 ReadLength = 1; 398 Buffer[1] = 0x1C; 399 Status = I2cReadMultipleByte ( 400 I2CSlaveAddress, 401 EfiI2CSevenBitAddrMode, 402 &Length, 403 &ReadLength, 404 &Buffer[1] 405 ); 406 ASSERT_EFI_ERROR (Status); 407 408 // 409 // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs 410 // 411 Length = 2; 412 Buffer[0] = 0x1C; 413 Buffer[1] = Buffer[1] | BIT0 | BIT1; 414 Status = I2cWriteMultipleByte ( 415 I2CSlaveAddress, 416 EfiI2CSevenBitAddrMode, 417 &Length, 418 &Buffer 419 ); 420 ASSERT_EFI_ERROR (Status); 421 422 if (BootMode != BOOT_IN_RECOVERY_MODE) { 423 // 424 // Read state of RESET_N_SHLD (GPORT5_BIT0) 425 // 426 Buffer[1] = 5; 427 Length = 1; 428 ReadLength = 1; 429 Status = I2cReadMultipleByte ( 430 I2CSlaveAddress, 431 EfiI2CSevenBitAddrMode, 432 &Length, 433 &ReadLength, 434 &Buffer[1] 435 ); 436 ASSERT_EFI_ERROR (Status); 437 438 // 439 // Return the state of GPORT5_BIT0 440 // 441 if ((Buffer[1] & BIT0) == 0) { 442 DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n")); 443 444 // 445 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset 446 // 447 QNCAltPortWrite ( 448 QUARK_SCSS_SOC_UNIT_SB_PORT_ID, 449 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, 450 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY 451 ); 452 ResetWarm(); 453 } 454 } 455 } 456 457 return EFI_SUCCESS; 458 } 459 460 /** 461 This is the entrypoint of PEIM 462 463 @param FileHandle Handle of the file being invoked. 464 @param PeiServices Describes the list of possible PEI Services. 465 466 @retval EFI_SUCCESS if it completed successfully. 467 **/ 468 EFI_STATUS 469 EFIAPI 470 PeiInitPlatform ( 471 IN EFI_PEI_FILE_HANDLE FileHandle, 472 IN CONST EFI_PEI_SERVICES **PeiServices 473 ) 474 { 475 EFI_STATUS Status; 476 EFI_BOOT_MODE BootMode; 477 EFI_PEI_STALL_PPI *StallPpi; 478 EFI_PEI_PPI_DESCRIPTOR *StallPeiPpiDescriptor; 479 EFI_FV_FILE_INFO FileInfo; 480 EFI_PLATFORM_TYPE PlatformType; 481 482 PlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType); 483 484 // 485 // Initialize Firmware Volume security. 486 // This must be done before any firmware volume accesses (excl. BFV) 487 // 488 Status = PeiInitializeFvSecurity(); 489 ASSERT_EFI_ERROR (Status); 490 491 // 492 // Do any early platform specific initialization. 493 // 494 EarlyPlatformInit (); 495 496 // 497 // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based 498 // to improve recovery performance. 499 // 500 Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo); 501 ASSERT_EFI_ERROR (Status); 502 // 503 // The follow conditional check only works for memory-mapped FFS, 504 // so we ASSERT that the file is really a MM FFS. 505 // 506 ASSERT (FileInfo.Buffer != NULL); 507 if (!(((UINTN) FileInfo.Buffer <= (UINTN) PeiInitPlatform) && 508 ((UINTN) PeiInitPlatform <= (UINTN) FileInfo.Buffer + FileInfo.BufferSize))) { 509 // 510 // Now that module in memory, update the 511 // PPI that describes the Stall to other modules 512 // 513 Status = PeiServicesLocatePpi ( 514 &gEfiPeiStallPpiGuid, 515 0, 516 &StallPeiPpiDescriptor, 517 (VOID **) &StallPpi 518 ); 519 520 if (!EFI_ERROR (Status)) { 521 522 Status = PeiServicesReInstallPpi ( 523 StallPeiPpiDescriptor, 524 &mPpiStall[0] 525 ); 526 } else { 527 528 Status = PeiServicesInstallPpi (&mPpiStall[0]); 529 } 530 return Status; 531 } 532 533 // 534 // Initialize System Phys 535 // 536 537 // Program USB Phy 538 InitializeUSBPhy(); 539 540 // 541 // Do platform specific logic to create a boot mode 542 // 543 Status = UpdateBootMode ((EFI_PEI_SERVICES**)PeiServices, &BootMode); 544 ASSERT_EFI_ERROR (Status); 545 546 // 547 // Signal possible dependent modules that there has been a 548 // final boot mode determination 549 // 550 if (!EFI_ERROR(Status)) { 551 Status = PeiServicesInstallPpi (&mPpiBootMode[0]); 552 ASSERT_EFI_ERROR (Status); 553 } 554 555 if (BootMode != BOOT_ON_S3_RESUME) { 556 QNCClearSmiAndWake (); 557 } 558 559 DEBUG ((EFI_D_INFO, "MRC Entry\n")); 560 MemoryInit ((EFI_PEI_SERVICES**)PeiServices); 561 562 // 563 // Do Early PCIe init. 564 // 565 DEBUG ((EFI_D_INFO, "Early PCIe controller initialization\n")); 566 PlatformPciExpressEarlyInit (PlatformType); 567 568 569 DEBUG ((EFI_D_INFO, "Platform Erratas After MRC\n")); 570 PlatformErratasPostMrc (); 571 572 // 573 // 574 // 575 DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n")); 576 EarlyPlatformConfigGpioExpanders (PlatformType, BootMode); 577 578 // 579 // Now that all of the pre-permanent memory activities have 580 // been taken care of, post a call-back for the permanent-memory 581 // resident services, such as HOB construction. 582 // PEI Core will switch stack after this PEIM exit. After that the MTRR 583 // can be set. 584 // 585 Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]); 586 ASSERT_EFI_ERROR (Status); 587 /* 588 589 if (BootMode != BOOT_ON_S3_RESUME) { 590 Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList); 591 ASSERT_EFI_ERROR (Status); 592 } 593 */ 594 if (BootMode == BOOT_IN_RECOVERY_MODE) { 595 PeiServicesRegisterForShadow (FileHandle); 596 } 597 598 return Status; 599 } 600 601 EFI_STATUS 602 EFIAPI 603 EndOfPeiSignalPpiNotifyCallback ( 604 IN EFI_PEI_SERVICES **PeiServices, 605 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 606 IN VOID *Ppi 607 ) 608 { 609 EFI_STATUS Status; 610 611 DEBUG ((EFI_D_INFO, "End of PEI Signal Callback\n")); 612 613 // 614 // Restore the flash region to be UC 615 // for both normal boot as we build a Resource Hob to 616 // describe this region as UC to DXE core. 617 // 618 WriteBackInvalidateDataCacheRange ( 619 (VOID *) (UINTN) PcdGet32 (PcdFlashAreaBaseAddress), 620 PcdGet32 (PcdFlashAreaSize) 621 ); 622 623 Status = MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress), PcdGet32 (PcdFlashAreaSize), CacheUncacheable); 624 ASSERT_EFI_ERROR (Status); 625 626 return EFI_SUCCESS; 627 } 628 629 /** 630 This function will initialize USB Phy registers associated with QuarkSouthCluster. 631 632 @param VOID No Argument 633 634 @retval EFI_SUCCESS All registers have been initialized 635 **/ 636 VOID 637 EFIAPI 638 InitializeUSBPhy ( 639 VOID 640 ) 641 { 642 UINT32 RegData32; 643 644 /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock 645 * and Port2 as a USB device port, the following sequence must be followed 646 * 647 **/ 648 649 // Sideband register write to USB AFE (Phy) 650 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT); 651 RegData32 &= ~(BIT1); 652 // 653 // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b. 654 // For port 0 & 1 as host and port 2 as device. 655 // 656 RegData32 |= (BIT8 | BIT7); 657 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT, RegData32); 658 659 // 660 // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV. 661 // 662 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG); 663 RegData32 &= ~(BIT10 | BIT9 | BIT8 | BIT7); 664 RegData32 |= (BIT10 | BIT7); 665 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG, RegData32); 666 667 // Sideband register write to USB AFE (Phy) 668 // (pllbypass) to bypass/Disable PLL before switch 669 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2); 670 RegData32 |= BIT29; 671 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32); 672 673 // Sideband register write to USB AFE (Phy) 674 // (coreclksel) to select 120MHz (ickusbcoreclk) clk source. 675 // (Default 0 to select 96MHz (ickusbclk96_npad/ppad)) 676 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1); 677 RegData32 |= BIT1; 678 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32); 679 680 // Sideband register write to USB AFE (Phy) 681 // (divide by 8) to achieve internal 480MHz clock 682 // for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz) 683 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1); 684 RegData32 &= ~(BIT5 | BIT4 | BIT3); 685 RegData32 |= BIT6; 686 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32); 687 688 // Sideband register write to USB AFE (Phy) 689 // Clear (pllbypass) 690 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2); 691 RegData32 &= ~BIT29; 692 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32); 693 694 // Sideband register write to USB AFE (Phy) 695 // Set (startlock) to force the PLL FSM to restart the lock 696 // sequence due to input clock/freq switch. 697 RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2); 698 RegData32 |= BIT24; 699 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32); 700 701 // At this point the PLL FSM and COMP FSM will complete 702 703 } 704 705 /** 706 This function provides early platform Thermal sensor initialisation. 707 **/ 708 VOID 709 EFIAPI 710 EarlyPlatformThermalSensorInit ( 711 VOID 712 ) 713 { 714 DEBUG ((EFI_D_INFO, "Early Platform Thermal Sensor Init\n")); 715 716 // 717 // Set Thermal sensor mode. 718 // 719 QNCThermalSensorSetRatiometricMode (); 720 721 // 722 // Enable RMU Thermal sensor with a Catastrophic Trip point. 723 // 724 QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS); 725 726 // 727 // Lock all RMU Thermal sensor control & trip point registers. 728 // 729 QNCThermalSensorLockAllRegisters (); 730 } 731 732 /** 733 Print early platform info messages includeing the Stage1 module that's 734 running, MFH item list and platform data item list. 735 **/ 736 VOID 737 EFIAPI 738 EarlyPlatformInfoMessages ( 739 VOID 740 ) 741 { 742 DEBUG_CODE_BEGIN (); 743 QUARK_EDKII_STAGE1_HEADER *Edk2ImageHeader; 744 745 // 746 // Find which 'Stage1' image we are running and print the details 747 // 748 Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base); 749 DEBUG ((EFI_D_INFO, "\n************************************************************\n")); 750 751 switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) { 752 case QUARK_STAGE1_BOOT_IMAGE_TYPE: 753 DEBUG ((EFI_D_INFO, "**** Quark EDKII Stage 1 Boot Image %d ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK)))); 754 break; 755 756 case QUARK_STAGE1_RECOVERY_IMAGE_TYPE: 757 DEBUG ((EFI_D_INFO, "**** Quark EDKII Stage 1 Recovery Image %d ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK)))); 758 break; 759 760 default: 761 DEBUG ((EFI_D_INFO, "**** Quark EDKII Unknown Stage 1 Image !!!! ****\n")); 762 break; 763 } 764 DEBUG ( 765 (EFI_D_INFO, 766 "**** Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" , 767 (UINTN) PcdGet32 (PcdFlashFvMainBase), 768 (UINTN) PcdGet32 (PcdFlashFvMainSize) 769 )); 770 771 DEBUG ( 772 (EFI_D_INFO, 773 "**** Quark EDKII Payload Image 0x%08X:0x%08X ****\n" , 774 (UINTN) PcdGet32 (PcdFlashFvPayloadBase), 775 (UINTN) PcdGet32 (PcdFlashFvPayloadSize) 776 )); 777 778 DEBUG ((EFI_D_INFO, "************************************************************\n\n")); 779 780 DEBUG_CODE_END (); 781 } 782 783 /** 784 Check if system reset due to error condition. 785 786 @param ClearErrorBits If TRUE clear error flags and value bits. 787 788 @retval TRUE if system reset due to error condition. 789 @retval FALSE if NO reset error conditions. 790 **/ 791 BOOLEAN 792 CheckForResetDueToErrors ( 793 IN BOOLEAN ClearErrorBits 794 ) 795 { 796 UINT32 RegValue; 797 BOOLEAN ResetDueToError; 798 799 ResetDueToError = FALSE; 800 801 // 802 // Check if RMU reset system due to access violations. 803 // RMU updates a SOC Unit register before resetting the system. 804 // 805 RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW); 806 if ((RegValue & B_CFG_STICKY_RW_VIOLATION) != 0) { 807 ResetDueToError = TRUE; 808 809 DEBUG ( 810 (EFI_D_ERROR, 811 "\nReset due to access violation: %s %s %s %s\n", 812 ((RegValue & B_CFG_STICKY_RW_IMR_VIOLATION) != 0) ? L"'IMR'" : L".", 813 ((RegValue & B_CFG_STICKY_RW_DECC_VIOLATION) != 0) ? L"'DECC'" : L".", 814 ((RegValue & B_CFG_STICKY_RW_SMM_VIOLATION) != 0) ? L"'SMM'" : L".", 815 ((RegValue & B_CFG_STICKY_RW_HMB_VIOLATION) != 0) ? L"'HMB'" : L"." 816 )); 817 818 // 819 // Clear error bits. 820 // 821 if (ClearErrorBits) { 822 RegValue &= ~(B_CFG_STICKY_RW_VIOLATION); 823 QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, RegValue); 824 } 825 } 826 827 return ResetDueToError; 828 } 829 830 /** 831 This function provides early platform initialization. 832 833 @param PlatformInfo Pointer to platform Info structure. 834 835 **/ 836 VOID 837 EFIAPI 838 EarlyPlatformInit ( 839 VOID 840 ) 841 { 842 EFI_PLATFORM_TYPE PlatformType; 843 844 PlatformType = (EFI_PLATFORM_TYPE) PcdGet16 (PcdPlatformType); 845 846 DEBUG ((EFI_D_INFO, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN) PlatformType)); 847 848 // 849 // Check if system reset due to error condition. 850 // 851 if (CheckForResetDueToErrors (TRUE)) { 852 if(FeaturePcdGet (WaitIfResetDueToError)) { 853 DEBUG ((EFI_D_ERROR, "Wait 10 seconds.\n")); 854 MicroSecondDelay(10000000); 855 } 856 } 857 858 // 859 // Display platform info messages. 860 // 861 EarlyPlatformInfoMessages (); 862 863 // 864 // Early Legacy Gpio Init. 865 // 866 EarlyPlatformLegacyGpioInit (PlatformType); 867 868 // 869 // Early platform Legacy GPIO manipulation depending on GPIOs 870 // setup by EarlyPlatformLegacyGpioInit. 871 // 872 EarlyPlatformLegacyGpioManipulation (PlatformType); 873 874 // 875 // Early platform specific GPIO Controller init & manipulation. 876 // Combined for sharing of temp. memory bar. 877 // 878 EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType); 879 880 // 881 // Early Thermal Sensor Init. 882 // 883 EarlyPlatformThermalSensorInit (); 884 885 // 886 // Early Lan Ethernet Mac Init. 887 // 888 EarlyPlatformMacInit ( 889 PcdGetPtr (PcdIohEthernetMac0), 890 PcdGetPtr (PcdIohEthernetMac1) 891 ); 892 } 893 894 /** 895 This function provides early platform Legacy GPIO initialisation. 896 897 @param PlatformType Platform type for GPIO init. 898 899 **/ 900 VOID 901 EFIAPI 902 EarlyPlatformLegacyGpioInit ( 903 IN CONST EFI_PLATFORM_TYPE PlatformType 904 ) 905 { 906 BOARD_LEGACY_GPIO_CONFIG *LegacyGpioConfig; 907 UINT32 NewValue; 908 UINT32 GpioBaseAddress; 909 910 // 911 // Assert if platform type outside table range. 912 // 913 ASSERT ((UINTN) PlatformType < mBoardLegacyGpioConfigTableLen); 914 LegacyGpioConfig = &mBoardLegacyGpioConfigTable[(UINTN) PlatformType]; 915 916 GpioBaseAddress = (UINT32)PcdGet16 (PcdGbaIoBaseAddress); 917 918 NewValue = 0x0; 919 // 920 // Program QNC GPIO Registers. 921 // 922 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellEnable; 923 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL, NewValue ); 924 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellIoSelect; 925 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL, NewValue); 926 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellLvlForInputOrOutput; 927 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL, NewValue); 928 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerPositiveEdge; 929 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL, NewValue ); 930 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerNegativeEdge; 931 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL, NewValue); 932 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellGPEEnable; 933 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL, NewValue); 934 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellSMIEnable; 935 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL, NewValue ); 936 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerStatus; 937 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL, NewValue); 938 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellNMIEnable; 939 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL, NewValue); 940 941 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellEnable; 942 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL, NewValue ); 943 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellIoSelect; 944 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL, NewValue) ; 945 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellLvlForInputOrOutput; 946 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, NewValue); 947 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerPositiveEdge; 948 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL, NewValue ); 949 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerNegativeEdge; 950 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL, NewValue) ; 951 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellGPEEnable; 952 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL, NewValue); 953 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellSMIEnable; 954 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL, NewValue ); 955 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerStatus; 956 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL, NewValue) ; 957 NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellNMIEnable; 958 IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL, NewValue); 959 } 960 961 /** 962 Performs any early platform specific Legacy GPIO manipulation. 963 964 @param PlatformType Platform type GPIO manipulation. 965 966 **/ 967 VOID 968 EFIAPI 969 EarlyPlatformLegacyGpioManipulation ( 970 IN CONST EFI_PLATFORM_TYPE PlatformType 971 ) 972 { 973 if (PlatformType == CrossHill) { 974 975 // 976 // Pull TPM reset low for 80us (equivalent to cold reset, Table 39 977 // Infineon SLB9645 Databook), then pull TPM reset high and wait for 978 // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon 979 // SLB9645 Databook states TPM is ready to receive command after 30ms 980 // but section 4.7 states some TPM commands may take longer to execute 981 // upto 150ms after test). 982 // 983 984 PlatformLegacyGpioSetLevel ( 985 R_QNC_GPIO_RGLVL_RESUME_WELL, 986 PLATFORM_RESUMEWELL_TPM_RST_GPIO, 987 FALSE 988 ); 989 MicroSecondDelay (80); 990 991 PlatformLegacyGpioSetLevel ( 992 R_QNC_GPIO_RGLVL_RESUME_WELL, 993 PLATFORM_RESUMEWELL_TPM_RST_GPIO, 994 TRUE 995 ); 996 MicroSecondDelay (150000); 997 } 998 999 } 1000 1001 /** 1002 Performs any early platform specific GPIO Controller init & manipulation. 1003 1004 @param PlatformType Platform type for GPIO init & manipulation. 1005 1006 **/ 1007 VOID 1008 EFIAPI 1009 EarlyPlatformGpioCtrlerInitAndManipulation ( 1010 IN CONST EFI_PLATFORM_TYPE PlatformType 1011 ) 1012 { 1013 UINT32 IohGpioBase; 1014 UINT32 Data32; 1015 UINT32 Addr; 1016 BOARD_GPIO_CONTROLLER_CONFIG *GpioConfig; 1017 UINT32 DevPcieAddr; 1018 UINT16 SaveCmdReg; 1019 UINT32 SaveBarReg; 1020 UINT16 PciVid; 1021 UINT16 PciDid; 1022 1023 ASSERT ((UINTN) PlatformType < mBoardGpioControllerConfigTableLen); 1024 GpioConfig = &mBoardGpioControllerConfigTable[(UINTN) PlatformType]; 1025 1026 IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase); 1027 1028 DevPcieAddr = PCI_LIB_ADDRESS ( 1029 PcdGet8 (PcdIohGpioBusNumber), 1030 PcdGet8 (PcdIohGpioDevNumber), 1031 PcdGet8 (PcdIohGpioFunctionNumber), 1032 0 1033 ); 1034 1035 // 1036 // Do nothing if not a supported device. 1037 // 1038 PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET); 1039 PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET); 1040 if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) { 1041 return; 1042 } 1043 1044 // 1045 // Save current settings for PCI CMD/BAR registers. 1046 // 1047 SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET); 1048 SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)); 1049 1050 // 1051 // Use predefined temporary memory resource. 1052 // 1053 PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase); 1054 PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); 1055 1056 // 1057 // Gpio Controller Init Tasks. 1058 // 1059 1060 // 1061 // IEN- Interrupt Enable Register 1062 // 1063 Addr = IohGpioBase + GPIO_INTEN; 1064 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1065 Data32 |= (GpioConfig->IntEn & 0x000FFFFF); 1066 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1067 1068 // 1069 // ISTATUS- Interrupt Status Register 1070 // 1071 Addr = IohGpioBase + GPIO_INTSTATUS; 1072 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1073 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1074 1075 // 1076 // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR 1077 // 1078 Addr = IohGpioBase + GPIO_SWPORTA_DR; 1079 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1080 Data32 |= (GpioConfig->PortADR & 0x000FFFFF); 1081 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1082 1083 // 1084 // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input 1085 // 1086 Addr = IohGpioBase + GPIO_SWPORTA_DDR; 1087 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1088 Data32 |= (GpioConfig->PortADir & 0x000FFFFF); 1089 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1090 1091 // 1092 // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked 1093 // 1094 Addr = IohGpioBase + GPIO_INTMASK; 1095 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1096 Data32 |= (GpioConfig->IntMask & 0x000FFFFF); 1097 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1098 1099 // 1100 // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive 1101 // 1102 Addr = IohGpioBase + GPIO_INTTYPE_LEVEL; 1103 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1104 Data32 |= (GpioConfig->IntType & 0x000FFFFF); 1105 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1106 1107 // 1108 // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low 1109 // 1110 Addr = IohGpioBase + GPIO_INT_POLARITY; 1111 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1112 Data32 |= (GpioConfig->IntPolarity & 0x000FFFFF); 1113 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1114 1115 // 1116 // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce 1117 // 1118 Addr = IohGpioBase + GPIO_DEBOUNCE; 1119 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1120 Data32 |= (GpioConfig->Debounce & 0x000FFFFF); 1121 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1122 1123 // 1124 // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk) 1125 // 1126 Addr = IohGpioBase + GPIO_LS_SYNC; 1127 Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8] 1128 Data32 |= (GpioConfig->LsSync & 0x000FFFFF); 1129 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1130 1131 // 1132 // Gpio Controller Manipulation Tasks. 1133 // 1134 1135 if (PlatformType == (EFI_PLATFORM_TYPE) Galileo) { 1136 // 1137 // Reset Cypress Expander on Galileo Platform 1138 // 1139 Addr = IohGpioBase + GPIO_SWPORTA_DR; 1140 Data32 = *((volatile UINT32 *) (UINTN)(Addr)); 1141 Data32 |= BIT4; // Cypress Reset line controlled by GPIO<4> 1142 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1143 1144 Data32 = *((volatile UINT32 *) (UINTN)(Addr)); 1145 Data32 &= ~BIT4; // Cypress Reset line controlled by GPIO<4> 1146 *((volatile UINT32 *) (UINTN)(Addr)) = Data32; 1147 1148 } 1149 1150 // 1151 // Restore settings for PCI CMD/BAR registers 1152 // 1153 PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg); 1154 PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg); 1155 } 1156 1157 /** 1158 Performs any early platform init of SoC Ethernet Mac devices. 1159 1160 @param IohMac0Address Mac address to program into Mac0 device. 1161 @param IohMac1Address Mac address to program into Mac1 device. 1162 1163 **/ 1164 VOID 1165 EFIAPI 1166 EarlyPlatformMacInit ( 1167 IN CONST UINT8 *IohMac0Address, 1168 IN CONST UINT8 *IohMac1Address 1169 ) 1170 { 1171 BOOLEAN SetMacAddr; 1172 1173 // 1174 // Set chipset MAC0 address if configured. 1175 // 1176 SetMacAddr = 1177 (CompareMem (ChipsetDefaultMac, IohMac0Address, sizeof (ChipsetDefaultMac))) != 0; 1178 if (SetMacAddr) { 1179 if ((*(IohMac0Address) & BIT0) != 0) { 1180 DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n", 1181 (UINTN) IOH_MAC0_BUS_NUMBER, 1182 (UINTN) IOH_MAC0_DEVICE_NUMBER, 1183 (UINTN) IOH_MAC0_FUNCTION_NUMBER 1184 )); 1185 ASSERT (FALSE); 1186 } else { 1187 SetLanControllerMacAddr ( 1188 IOH_MAC0_BUS_NUMBER, 1189 IOH_MAC0_DEVICE_NUMBER, 1190 IOH_MAC0_FUNCTION_NUMBER, 1191 IohMac0Address, 1192 (UINT32) PcdGet64(PcdIohMac0MmioBase) 1193 ); 1194 } 1195 } else { 1196 DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n", 1197 (UINTN) IOH_MAC0_BUS_NUMBER, 1198 (UINTN) IOH_MAC0_DEVICE_NUMBER, 1199 (UINTN) IOH_MAC0_FUNCTION_NUMBER 1200 )); 1201 } 1202 1203 // 1204 // Set chipset MAC1 address if configured. 1205 // 1206 SetMacAddr = 1207 (CompareMem (ChipsetDefaultMac, IohMac1Address, sizeof (ChipsetDefaultMac))) != 0; 1208 if (SetMacAddr) { 1209 if ((*(IohMac1Address) & BIT0) != 0) { 1210 DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n", 1211 (UINTN) IOH_MAC1_BUS_NUMBER, 1212 (UINTN) IOH_MAC1_DEVICE_NUMBER, 1213 (UINTN) IOH_MAC1_FUNCTION_NUMBER 1214 )); 1215 ASSERT (FALSE); 1216 } else { 1217 SetLanControllerMacAddr ( 1218 IOH_MAC1_BUS_NUMBER, 1219 IOH_MAC1_DEVICE_NUMBER, 1220 IOH_MAC1_FUNCTION_NUMBER, 1221 IohMac1Address, 1222 (UINT32) PcdGet64(PcdIohMac1MmioBase) 1223 ); 1224 } 1225 } else { 1226 DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n", 1227 (UINTN) IOH_MAC1_BUS_NUMBER, 1228 (UINTN) IOH_MAC1_DEVICE_NUMBER, 1229 (UINTN) IOH_MAC1_FUNCTION_NUMBER 1230 )); 1231 } 1232 } 1233 1234