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