VOID ClearP2PBusMaster( ) { UINT8 Command; UINT8 Index; for (Index = 0; Index < sizeof(mPciBm)/sizeof(EFI_PCI_BUS_MASTER); Index++) { Command = MmioRead8 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, mPciBm[Index].Device, mPciBm[Index].Function, PCI_COMMAND_OFFSET ) ); Command &= ~EFI_PCI_COMMAND_BUS_MASTER; MmioWrite8 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, mPciBm[Index].Device, mPciBm[Index].Function, PCI_COMMAND_OFFSET ), Command ); } }
VOID EFIAPI PlatformSpecificInit ( VOID ) { UINTN XhciPciMmBase; EFI_PHYSICAL_ADDRESS XhciMemBaseAddress; XhciPciMmBase = MmPciAddress ( 0, 0, xhci_path.Device, xhci_path.Function, 0 ); XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA; DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress)); MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800); return; }
VOID XhciSwitchSwid(BOOLEAN enable) { UINTN XhciPciMmBase; EFI_PHYSICAL_ADDRESS XhciMemBaseAddress; UINT32 DualRoleCfg0; UINT32 DualRoleCfg1; XhciPciMmBase = MmPciAddress (0, 0, xhci_path.Device, xhci_path.Function, 0); XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA; DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress)); DualRoleCfg0 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0)); if (enable) { DualRoleCfg0 = DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20); DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n", DualRoleCfg0)); } else { DualRoleCfg0 = DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 20); DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n", DualRoleCfg0)); } MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0); DualRoleCfg1 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG1)); DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1)); }
/** USB initialization before boot to OS @param[in] UsbConfig The PCH Platform Policy for USB configuration **/ VOID UsbInitAtBoot ( IN PCH_USB_CONFIG *UsbConfig ) { UINTN XhciPciMmBase; UINT32 XhciMmioBase; DEBUG ((EFI_D_INFO, "UsbInitAtBoot() - Start\n")); if ((UsbConfig->SsicPortSettings[0].Enable == PCH_DEVICE_DISABLE) && (UsbConfig->SsicPortSettings[1].Enable == PCH_DEVICE_DISABLE)) { DEBUG ((EFI_D_INFO, "UsbInitAtBoot() - SsicPortSettings[0] & SsicPortSettings[1] - Disabled\n")); XhciPciMmBase = MmPciAddress ( 0, 0, PCI_DEVICE_NUMBER_PCH_XHCI, PCI_FUNCTION_NUMBER_PCH_XHCI, 0 ); XhciMmioBase = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE) & B_PCH_XHCI_MEM_BASE_BA; // // SSIC port 0: PORT_UNUSED=1 PROG_DONE=1 // SSIC port 1: PORT_UNUSED=0 PROG_DONE=1 // // // Set Port 0 un-used // MmioOr32 ( (XhciMmioBase + 0x880C), (UINT32) (BIT31) ); // // Clear Port 1 un-used // MmioAnd32 ( (XhciMmioBase + 0x883C), (UINT32) ~(BIT31) ); // // Set PROG_DONE bit, // xHCIBAR + 0x880C [30] = 1b and xHCIBAR + 0x883C [30] = 1b. // MmioOr32 ( (XhciMmioBase + 0x880C), (UINT32) (BIT30) ); MmioOr32 ( (XhciMmioBase + 0x883C), (UINT32) (BIT30) ); } DEBUG ((EFI_D_INFO, "UsbInitAtBoot() - End\n")); }
UINT32 DetermineCompatibleBoard ( void ) { UINTN PciD31F0RegBase = 0; UINT32 GpioValue = 0; UINT32 TmpVal = 0; UINT32 MmioConf0 = 0; UINT32 MmioPadval = 0; UINT32 PConf0Offset = 0x200; //GPIO_S5_4 pad_conf0 register offset UINT32 PValueOffset = 0x208; //GPIO_S5_4 pad_value register offset UINT32 SSUSOffset = 0x2000; UINT32 IoBase = 0; DEBUG ((EFI_D_ERROR, "DetermineCompatibleBoard() Entry\n")); PciD31F0RegBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0 ); IoBase = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR; MmioConf0 = IoBase + SSUSOffset + PConf0Offset; MmioPadval = IoBase + SSUSOffset + PValueOffset; //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4 DEBUG ((EFI_D_ERROR, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0, MmioPadval)); MmioWrite32 (MmioConf0, 0x2003CC00); TmpVal = MmioRead32 (MmioPadval); TmpVal &= ~0x6; //Clear bit 1:2 TmpVal |= 0x2; // Set the pin as GPI MmioWrite32 (MmioPadval, TmpVal); GpioValue = MmioRead32 (MmioPadval); DEBUG ((EFI_D_ERROR, "Gpio_S5_4 value is 0x%x\n", GpioValue)); return (GpioValue & 0x1); }
EFI_STATUS SaveRuntimeScriptTable ( VOID ) { SMM_PCI_IO_ADDRESS PciAddress; UINT32 Data32; UINT16 Data16; UINT8 Data8; UINT8 Mask; UINTN Index; UINTN Offset; UINT8 RegTable[] = { // //Bus , Dev, Func, DMI // 0x00 , 0x00, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0, // //Bus , Dev, Func, LPC device // 0x00 , 0x1F, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x00 , 0x08, 0x00, 0x07, 0x00, 0x00, 0x90, 0x00, // //Bus , Dev, Func, PCIE device // 0x00 , 0x1C, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0xC0 , 0x83, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, PCIE device // 0x00 , 0x1C, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x03 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, SATA device // 0x00 , 0x13, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0xf4 , 0xab, 0x27, 0x10, 0xf1, 0x1d, 0x00, 0x40, // //Bus , Dev, Func, EHCI device // 0x00 , 0x1D, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x10 , 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // //Bus , Dev, Func, SMBUS device // 0x00 , 0x1f, 0x03, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x10 , 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, SMBUS device // 0x00 , 0x1f, 0x03, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, VGA bus1 // 0x01 , 0x00, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x58 , 0x81, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00, // //Bus , Dev, Func, VGA bus1 // 0x01 , 0x00, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, VGA bus1 function 1 // 0x01 , 0x00, 0x01, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x51 , 0x80, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, VGA bus1 function 1 // 0x01 , 0x00, 0x01, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, IGD bus0 function 0 // 0x00 , 0x02, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x42 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, // //Bus , Dev, Func, USB bus0 function 0 // 0x00 , 0x16, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // //Bus , Dev, Func, HD Audio bus0 function 0 // 0x00 , 0x1B, 0x00, // //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF // 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, // //0xFF indicates the end of the table // 0xFF }; // // These registers have to set in byte order // UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings // // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM // and vital to S3 resume. That's why we put save code here // PciAddress.Bus = 0; PciAddress.Device = 0; PciAddress.Function = 0; PciAddress.ExtendedRegister = 0; for (Index = 0; Index < 2; Index++) { // // Read SRAM setting from Pci(0, 0, 0) // PciAddress.Register = ExtReg[Index]; Data8 = MmioRead8 ( MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register ) ); // // Save latest settings to runtime script table // S3BootScriptSavePciCfgWrite( S3BootScriptWidthUint8, *(UINT64*)&PciAddress, 1, &Data8 ); } // // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM // and vital to S3 resume. That's why we put save code here // Index = 0; while (RegTable[Index] != 0xFF) { PciAddress.Bus = RegTable[Index++]; PciAddress.Device = RegTable[Index++]; PciAddress.Function = RegTable[Index++]; PciAddress.Register = 0; PciAddress.ExtendedRegister = 0; Data16 = MmioRead16 ( MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register ) ); if (Data16 == 0xFFFF) { Index+=8; continue; } for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) { if (Mask == 0x00) { Mask = 0x01; } if (RegTable[Index + Offset/32] & Mask ) { PciAddress.Register = (UINT8)Offset; Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)); // // Save latest settings to runtime script table // S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, *(UINT64*)&PciAddress, 1, &Data32 ); } } Index += 8; } // // Save I/O ports to S3 script table // // // Selftest KBC // Data8 = 0xAA; S3BootScriptSaveIoWrite ( S3BootScriptWidthUint8, 0x64, (UINTN)1, &Data8 ); Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN); S3BootScriptSaveIoWrite ( S3BootScriptWidthUint32, (mAcpiBaseAddr + R_PCH_SMI_EN), 1, &Data32 ); // // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path. // Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT); S3BootScriptSaveIoWrite ( S3BootScriptWidthUint16, mAcpiBaseAddr + R_PCH_TCO_CNT, 1, &Data16 ); return EFI_SUCCESS; }
/** Do any final initialization on SATA controller @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance @param[in] IsSetS3BootScript Is this function called for S3 boot script save @retval EFI_SUCCESS The function completed successfully **/ EFI_STATUS ConfigureSataAtBoot ( IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy, IN BOOLEAN IsSetS3BootScript ) { UINT8 Index; UINT32 AhciBar; UINTN PciD19F0RegBase; UINT16 SataModeSelect; UINT32 PxSctlDet; UINT32 PxCmdSud; UINT32 OrgCmdWord; UINT32 Data32And; UINT32 Data32Or; DEBUG ((EFI_D_INFO, "ConfigureSataAtBoot() Start\n")); // // eSATA port support only up to Gen2 // PciD19F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, 0); // // Make sure SATA device exists. // if (MmioRead16 (PciD19F0RegBase + R_PCH_SATA_ID) != 0xFFFF) { SataModeSelect = MmioRead16 (PciD19F0RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK; if ((SataModeSelect == V_PCH_SATA_MAP_SMS_AHCI) || (SataModeSelect == V_PCH_SATA_MAP_SMS_RAID)) { AhciBar = MmioRead32 (PciD19F0RegBase + R_PCH_SATA_ABAR) & B_PCH_SATA_ABAR_BA; // // Make sure the AhciBar is valid. // if ((AhciBar != 0x00000000) && (AhciBar != B_PCH_SATA_ABAR_BA)) { // // Keep original CMD word, and enable MSE // OrgCmdWord = MmioRead32 (PciD19F0RegBase + R_PCH_SATA_COMMAND); if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) { Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) B_PCH_SATA_COMMAND_MSE; if (!IsSetS3BootScript) { MmioOr32 ((PciD19F0RegBase + R_PCH_SATA_COMMAND), Data32Or); } else { // // Set S3 Boot Script // S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (PciD19F0RegBase + R_PCH_SATA_COMMAND), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } for (Index = 0; Index < PCH_AHCI_MAX_PORTS; Index++) { if (PchPlatformPolicy->SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) { PxSctlDet = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))) & B_PCH_SATA_AHCI_PXSCTL_DET; PxCmdSud = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))) & B_PCH_SATA_AHCI_PxCMD_SUD; // // Limit speed to Gen2 // Data32And = (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD); Data32Or = (UINT32) V_PCH_SATA_AHCI_PXSCTL_SPD_2; if (!IsSetS3BootScript) { MmioAndThenOr32 ( (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), Data32And, Data32Or ); } else { // // Set S3 Boot Script // S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } // // If port is not offline, and it's spin up, need to port reset. // After port reset, clear the SERR. // - Set DET=1, and then set DET=0. // - Finally, set FRE=1. // if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_0) && (PxCmdSud == B_PCH_SATA_AHCI_PxCMD_SUD)) { if (!IsSetS3BootScript) { MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_1); PchPmTimerStall (1000); MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET)); MmioWrite32 (AhciBar + (R_PCH_SATA_AHCI_P0SERR + (0x80 * Index)), (UINT32)~0u); MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), B_PCH_SATA_AHCI_PxCMD_FRE); } else { // // Set S3 Boot Script // Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) V_PCH_SATA_AHCI_PXSCTL_DET_1; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); S3BootScriptSaveStall (1000); Data32And = (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET); Data32Or = (UINT32) 0x00000000; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) 0xFFFFFFFF; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SERR + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) B_PCH_SATA_AHCI_PxCMD_FRE; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } // // If port is offline, and it's not spin up, meets the power bug. // Need to do the W/A to spin up the port and then spin down. // Then entering back to offline and listen. // - Set DET=0, SUD=1, and then set SUD=0, DET=4. // if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_4) && (PxCmdSud == 0)) { if (!IsSetS3BootScript) { MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET)); MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), B_PCH_SATA_AHCI_PxCMD_SUD); PchPmTimerStall (1000); MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PxCMD_SUD)); MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_4); } else { // // Set S3 Boot Script // Data32And = (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET); Data32Or = (UINT32) 0x00000000; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) B_PCH_SATA_AHCI_PxCMD_SUD; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); S3BootScriptSaveStall (1000); Data32And = (UINT32) ~(B_PCH_SATA_AHCI_PxCMD_SUD); Data32Or = (UINT32) 0x00000000; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) V_PCH_SATA_AHCI_PXSCTL_DET_4; S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } } } // // Restore original CMD word. // if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) { Data32And = (UINT32) 0xFFFFFFFF; Data32Or = (UINT32) OrgCmdWord; if (!IsSetS3BootScript) { MmioWrite32 ((PciD19F0RegBase + R_PCH_SATA_COMMAND), Data32Or); } else { S3BootScriptSaveMemReadWrite ( EfiBootScriptWidthUint32, (UINTN) (PciD19F0RegBase + R_PCH_SATA_COMMAND), &Data32Or, /// Data to be ORed &Data32And /// Data to be ANDed ); } } } // AhciBar is vaild } // SATA mode is AHCI or RAID } // if D19F0 is existed DEBUG ((EFI_D_INFO, "ConfigureSataAtBoot() End\n")); return EFI_SUCCESS; }
/** Perform flash write operation with progress indicator. The start and end completion percentage values are passed into this function. If the requested flash write operation is broken up, then completion percentage between the start and end values may be passed to the provided Progress function. The caller of this function is required to call the Progress function for the start and end completion percentage values. This allows the Progress, StartPercentage, and EndPercentage parameters to be ignored if the requested flash write operation can not be broken up @param[in] FirmwareType The type of firmware. @param[in] FlashAddress The address of flash device to be accessed. @param[in] FlashAddressType The type of flash device address. @param[in] Buffer The pointer to the data buffer. @param[in] Length The length of data buffer in bytes. @param[in] Progress A function used report the progress of the firmware update. This is an optional parameter that may be NULL. @param[in] StartPercentage The start completion percentage value that may be used to report progress during the flash write operation. @param[in] EndPercentage The end completion percentage value that may be used to report progress during the flash write operation. @retval EFI_SUCCESS The operation returns successfully. @retval EFI_WRITE_PROTECTED The flash device is read only. @retval EFI_UNSUPPORTED The flash device access is unsupported. @retval EFI_INVALID_PARAMETER The input parameter is not valid. **/ EFI_STATUS EFIAPI PerformFlashWriteWithProgress ( IN PLATFORM_FIRMWARE_TYPE FirmwareType, IN EFI_PHYSICAL_ADDRESS FlashAddress, IN FLASH_ADDRESS_TYPE FlashAddressType, IN VOID *Buffer, IN UINTN Length, IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OPTIONAL IN UINTN StartPercentage, IN UINTN EndPercentage ) { EFI_STATUS Status = EFI_SUCCESS; UINTN Index; EFI_PHYSICAL_ADDRESS Address; UINTN CountOfBlocks; EFI_TPL OldTpl; BOOLEAN FlashError; UINT8 *Buf; UINTN LpcBaseAddress; UINT8 Data8Or; UINT8 Data8And; UINT8 BiosCntl; Index = 0; Address = 0; CountOfBlocks = 0; FlashError = FALSE; Buf = Buffer; DEBUG((DEBUG_INFO | DEBUG_ERROR, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length)); if (FlashAddressType == FlashAddressTypeRelativeAddress) { FlashAddress = FlashAddress + mInternalFdAddress; } CountOfBlocks = (UINTN) (Length / BLOCK_SIZE); Address = FlashAddress; LpcBaseAddress = MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0 ); BiosCntl = MmioRead8 (LpcBaseAddress + R_PCH_LPC_BIOS_CNTL); if ((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) { /// /// Clear SMM_BWP bit (D31:F0:RegDCh[5]) /// Data8And = (UINT8) ~B_PCH_LPC_BIOS_CNTL_SMM_BWP; Data8Or = 0x00; MmioAndThenOr8 ( LpcBaseAddress + R_PCH_LPC_BIOS_CNTL, Data8And, Data8Or ); DEBUG((DEBUG_INFO, "PerformFlashWrite Clear SMM_BWP bit\n")); } // // Raise TPL to TPL_NOTIFY to block any event handler, // while still allowing RaiseTPL(TPL_NOTIFY) within // output driver during Print() // OldTpl = gBS->RaiseTPL (TPL_NOTIFY); for (Index = 0; Index < CountOfBlocks; Index++) { if (Progress != NULL) { Progress (StartPercentage + ((Index * (EndPercentage - StartPercentage)) / CountOfBlocks)); } // // Handle block based on address and contents. // if (!EFI_ERROR (InternalCompareBlock (Address, Buf))) { DEBUG((DEBUG_INFO, "Skipping block at 0x%lx (already programmed)\n", Address)); } else { // // Make updating process uninterruptable, // so that the flash memory area is not accessed by other entities // which may interfere with the updating process // Status = InternalEraseBlock (Address); if (EFI_ERROR(Status)) { gBS->RestoreTPL (OldTpl); FlashError = TRUE; goto Done; } Status = InternalWriteBlock ( Address, Buf, (UINT32)(Length > BLOCK_SIZE ? BLOCK_SIZE : Length) ); if (EFI_ERROR(Status)) { gBS->RestoreTPL (OldTpl); FlashError = TRUE; goto Done; } } // // Move to next block to update. // Address += BLOCK_SIZE; Buf += BLOCK_SIZE; if (Length > BLOCK_SIZE) { Length -= BLOCK_SIZE; } else { Length = 0; } } gBS->RestoreTPL (OldTpl); Done: if ((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) { // // Restore original control setting // MmioWrite8 (LpcBaseAddress + R_PCH_LPC_BIOS_CNTL, BiosCntl); } if (Progress != NULL) { Progress (EndPercentage); } return EFI_SUCCESS; }
VOID PchBaseInit ( VOID ) { // // Program ACPI Power Management I/O Space Base Address // MmioWrite16 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_ACPI_BASE ), (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN) ); // // Program GPIO Base Address // MmioWrite16 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_GPIO_BASE ), (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN) ); // // Set PMC Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_PMC_BASE ), (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN) ); // // Set IO Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_IO_BASE ), (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN) ); // // Set ILB Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_ILB_BASE ), (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN) ); // // Set PUnit Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_PUNIT_BASE ), (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN) ); // // Set SPI Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_SPI_BASE ), (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN) ); // // Set Root Complex Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_RCBA ), (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN) ); // // Set MPHY Base Address // MmioWrite32 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_MPHY_BASE ), (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN) ); MmioWrite16 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS, PCI_FUNCTION_NUMBER_PCH_SMBUS, R_PCH_SMBUS_BASE ), (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR) ); MmioOr8 ( MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS, PCI_FUNCTION_NUMBER_PCH_SMBUS, R_PCH_SMBUS_PCICMD ), B_PCH_SMBUS_PCICMD_IOSE ); }
/** Initializes the host controller to execute I2C commands. @param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device. @return EFI_SUCCESS Opcode initialization on the I2C host controller completed. @return EFI_DEVICE_ERROR Device error, operation failed. **/ EFI_STATUS I2CInit ( UINT8 I2cControllerIndex, UINT16 SlaveAddress ) { EFI_STATUS Status; UINT32 NumTries = 0; UINTN I2CBaseAddress; UINT16 I2cMode; UINTN PciMmBase=0; PciMmBase = MmPciAddress ( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, (I2cControllerIndex + 1), 0 ); I2CBaseAddress = I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR); // // Verify the parameters // if (1023 < SlaveAddress ) { Status = EFI_INVALID_PARAMETER; DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status)); return Status; } if(I2CBaseAddress == (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE)) { return EFI_SUCCESS; } ProgramPciLpssI2C(); I2CBaseAddress = (UINT32) (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE); DEBUG ((EFI_D_ERROR, "I2CBaseAddress = 0x%x \n",I2CBaseAddress)); NumTries = 10000; // 1 seconds while ((1 == ( I2CLibPeiMmioRead32 ( I2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) { MicroSecondDelay(10); NumTries --; if(0 == NumTries) return EFI_DEVICE_ERROR; } Status = I2cDisable (I2cControllerIndex); DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status)); I2cBusFrequencySet(I2CBaseAddress, 400 * 1000, &I2cMode);//Set I2cMode I2CLibPeiMmioWrite16(I2CBaseAddress + R_IC_INTR_MASK, 0x0); if (0x7F < SlaveAddress) { SlaveAddress = (SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER; } I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TAR, (UINT16) SlaveAddress ); I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_RX_TL, 0); I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TX_TL, 0 ); I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_CON, I2cMode); Status = I2cEnable(I2cControllerIndex); DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status)); I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT ); return EFI_SUCCESS; }
/** Programe all I2C controllers on LPSS. I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc.. @param VOID @return EFI_SUCCESS **/ EFI_STATUS ProgramPciLpssI2C ( VOID ) { UINT32 PmcBase; UINT32 DevID; UINTN PciMmBase=0; UINTN Index; UINTN Bar0; UINTN Bar1; DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() Start\n")); // // Set the VLV Function Disable Register to ZERO // PmcBase = I2CLibPeiMmioRead32(PciD31F0RegBase + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR; if(I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& (B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)) { I2CLibPeiMmioWrite32( PmcBase+R_PCH_PMC_FUNC_DIS, I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& \ ~(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 \ | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 \ | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6|B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7) ); DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n")); } for(Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) { PciMmBase = MmPciAddress ( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, Index, 0 ); DevID = I2CLibPeiMmioRead32(PciMmBase); Bar0 = PEI_TEPM_LPSS_DMA_BAR + (Index * PCI_CONFIG_SPACE_SIZE); Bar1 = Bar0 + 0x8000; DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device Function=%x DevID=%08x\n", Index, DevID)); // // Check if device present // if (DevID != 0xFFFFFFFF) { if(!(I2CLibPeiMmioRead32 (PciMmBase + R_PCH_LPSS_I2C_STSCMD) & B_PCH_LPSS_I2C_STSCMD_MSE)) { // // Program BAR 0 // I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32)(Bar0 & B_PCH_LPSS_I2C_BAR_BA)); DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR))); // // Program BAR 1 // I2CLibPeiMmioWrite32 ((UINTN)(PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32)(Bar1 & B_PCH_LPSS_I2C_BAR1_BA)); DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32(PciMmBase+R_PCH_LPSS_I2C_BAR1))); // // Bus Master Enable & Memory Space Enable // I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32)(B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE)); } // // Release Resets // I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPIO_I2C_MEM_RESETS, (B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB)); // // Activate Clocks // I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPSS_I2C_MEM_PCP, 0x80020003);//No use for A0 DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n")); } } DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n")); return EFI_SUCCESS; }
EFI_STATUS UpdatePlatformInformation ( CHAR16 *SECVer, CHAR16 *uCodeVer, CHAR16 *GOPVer, CHAR16 *MrcVer, CHAR16 *PmcVer, CHAR16 *UlpmcVer, CHAR16 *PunitVer, CHAR16 *SocVer, CHAR16 *BoardVer, CHAR16 *FabVer, CHAR16 *CpuFlavorString, CHAR16 *BiosVer, CHAR16 *PmicVer, CHAR16 *TouchVer, CHAR16 *SecureBootMode, CHAR16 *BootModeString, CHAR16 *SpeedStepMode, CHAR16 *MaxCState, CHAR16 *CpuTurbo, CHAR16 *GfxTurbo, CHAR16 *S0ix, CHAR16 *RC6 ) { UINT32 MicroCodeVersion; CHAR16 Buffer[SMBIOS_STRING_MAX_LENGTH + 2]; EFI_STATUS Status; UINT8 CpuFlavor=0; EFI_PEI_HOB_POINTERS GuidHob; EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL; UINTN NumHandles; EFI_HANDLE *HandleBuffer; UINTN Index; DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; UINTN PciD31F0RegBase; UINT8 count; UINT8 Data8; UINT8 Data8_1; CHAR16 Name[40]; UINT32 MrcVersion; CHAR16 *Version; SYSTEM_CONFIGURATION SystemConfiguration; EFI_BOOT_MODE BootMode; UINTN VarSize; EFI_PLATFORM_INFO_HOB *mPlatformInfo; Version = AllocateZeroPool (SMBIOS_STRING_MAX_LENGTH + 2); // // Get the System configuration // CopyMem (&SystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof(SYSTEM_CONFIGURATION)); // // Get the HOB list. If it is not present, then ASSERT. // mPlatformInfo = PcdGetPtr (PcdPlatformInfo); GetSeCVersion (SECVer); Status = GetBiosVersionDateTime (Version, NULL, NULL); UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", Version); FreePool(Version); StrCpy (BiosVer, Buffer); Status = TGetGOPDriverName(Name); if(!EFI_ERROR(Status)) { StrCpy (GOPVer, Name); } // //CpuFlavor // //CHV //CHV-DC Tablet 000 //CHV-QC Notebook 001 //CHV-QC Desktop 010 //CPU flavor CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07; switch(CpuFlavor){ case 0x0: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-DC Tablet", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; case 0x01: #if (TABLET_PF_ENABLE == 1) UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Tablet", CpuFlavor); #else UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Notebook", CpuFlavor); #endif StrCpy (CpuFlavorString, Buffer); break; case 0x02: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Desktop", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; case 0x03: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Notebook", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; default: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; } if ( NULL != mPlatformInfo) { // // Board Id // UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardId); StrCpy (BoardVer, Buffer); // // FAB ID // UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->FABID); StrCpy (FabVer, Buffer); } // //Update MRC Version // MrcVersion = MmioRead32 (MmPciAddress (0, 0, 0, 0, 0xF0)); MrcVersion &= 0xffff; Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0); StrCat (Buffer, L"."); EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0); EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0); StrCpy (MrcVer, Buffer); // //Update Soc Version // // // Retrieve all instances of PCH Platform Policy protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gDxePchPlatformPolicyProtocolGuid, NULL, &NumHandles, &HandleBuffer ); if (!EFI_ERROR (Status)) { // // Find the matching PCH Policy protocol // for (Index = 0; Index < NumHandles; Index++) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gDxePchPlatformPolicyProtocolGuid, &PchPlatformPolicy ); if (!EFI_ERROR (Status)) { PciD31F0RegBase = MmPciAddress ( 0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0 ); Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC) & B_PCH_LPC_RID_STEPPING_MASK; count = sizeof (SBRevisionTable) / sizeof (SBRevisionTable[0]); for (Index = 0; Index < count; Index++) { if(Data8 == SBRevisionTable[Index].RevId) { UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String); StrCpy (SocVer, Buffer); break; } } break; } } } // // Microcode Revision // EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0); EfiCpuid (EFI_CPUID_VERSION_INFO, NULL); MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32); UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion); StrCpy (uCodeVer, Buffer); // //Secure boot // Data8 = SystemConfiguration.SecureBoot; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (SecureBootMode, Buffer); // //Bootmode // BootMode = GetBootModeHob(); UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", BootMode); StrCpy (BootModeString, Buffer); // //SpeedStep // Data8 = SystemConfiguration.EnableGv; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (SpeedStepMode, Buffer); // //CPU Turbo // Data8 = SystemConfiguration.TurboModeEnable; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (CpuTurbo, Buffer); // //CState // Data8 = SystemConfiguration.MaxCState; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (MaxCState, Buffer); // //GFX Turbo // Data8 = SystemConfiguration.IgdTurboEnabled; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (GfxTurbo, Buffer); // //S0ix // Data8 = SystemConfiguration.S0ix; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (S0ix, Buffer); // //RC6 // Data8 = SystemConfiguration.EnableRenderStandby; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (RC6, Buffer); // // Punit Version // Data8 = (UINT8) EfiReadMsr (0x667); UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8); StrCpy (PunitVer, Buffer); // // PMC Version // Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF); Data8_1 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF); UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X", Data8_1, Data8); StrCpy (PmcVer, Buffer); TGetTouchFirmwareVersion(TouchVer); return EFI_SUCCESS; }
/** This function get I2Cx controller base address (BAR0). @param I2cControllerIndex Bus Number of I2C controller. @return I2C BAR. **/ UINTN GetI2cBarAddr( IN UINT8 I2cControllerIndex ) { EFI_STATUS Status; EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; UINTN AcpiBaseAddr; UINTN PciMmBase=0; ASSERT(gBS!=NULL); Status = gBS->LocateProtocol ( &gEfiGlobalNvsAreaProtocolGuid, NULL, &GlobalNvsArea ); // // PCI mode from PEI ( Global NVS is not ready). // if (EFI_ERROR(Status)) { DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status)); // // Global NVS is not ready. // return 0; } AcpiBaseAddr = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]); // //PCI mode from DXE (global NVS protocal) to LPSS OnReadytoBoot(swith to ACPI). // if(AcpiBaseAddr==0) { PciMmBase = MmPciAddress ( mLpssPciDeviceList[I2cControllerIndex + 1].Segment, mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum, 0 ); DEBUG((EFI_D_ERROR, "\nGetI2cBarAddr() I2C Device %x %x %x PciMmBase:%x\n", \ mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, \ mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, \ mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum, PciMmBase)); if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) { if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) { // // Get the address allocted. // mLpssPciDeviceList[I2cControllerIndex + 1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR); mLpssPciDeviceList[I2cControllerIndex + 1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1); } } AcpiBaseAddr =mLpssPciDeviceList[I2cControllerIndex+1].Bar0; } // // ACPI mode from BDS: LPSS OnReadytoBoot // else { DEBUG ((EFI_D_INFO, "GetI2cBarAddr() NVS Varialable is updated by this LIB or LPSS \n")); } DEBUG ((EFI_D_INFO, "GetI2cBarAddr() I2cControllerIndex+1 0x%x AcpiBaseAddr:0x%x \n", (I2cControllerIndex + 1), AcpiBaseAddr)); return AcpiBaseAddr; }
/** This function enables I2C controllers. @param I2cControllerIndex Bus Number of I2C controllers. @return Result of the I2C initialization. **/ EFI_STATUS ProgramPciLpssI2C ( IN UINT8 I2cControllerIndex ) { UINT32 PmcBase; UINTN PciMmBase=0; EFI_STATUS Status; EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; UINT32 PmcFunctionDsiable[]= { B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6, B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7 }; DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n")); // // Set the VLV Function Disable Register to ZERO // PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR; if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2cControllerIndex]) { DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is disabled\n",I2cControllerIndex)); return EFI_NOT_READY; } DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C()------------I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS))); { PciMmBase = MmPciAddress ( mLpssPciDeviceList[I2cControllerIndex+1].Segment, mLpssPciDeviceList[I2cControllerIndex+1].BusNum, mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, 0 ); DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device %x %x %x PciMmBase:%x\n", \ mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \ mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \ mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase)); if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) { if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) { // // Get the address allocted. // mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR); mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1); DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0, mLpssPciDeviceList[I2cControllerIndex+1].Bar1)); } else { // // Program BAR 0 // ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar0) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0)); MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA)); // // Program BAR 1 // ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar1) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0)); MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA)); // // Bus Master Enable & Memory Space Enable // MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32) (B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE)); ASSERT (MmioRead32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 0xFFFFFFFF); } // // Release Resets // MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB)); // // Activate Clocks // MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0 DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n")); } // // BDS: already switched to ACPI mode // else { ASSERT(gBS!=NULL); Status = gBS->LocateProtocol ( &gEfiGlobalNvsAreaProtocolGuid, NULL, &GlobalNvsArea ); if (EFI_ERROR(Status)) { DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status)); // // gEfiGlobalNvsAreaProtocolGuid is not ready. // return 0; } mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]); DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x \n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0)); } } DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n")); return EFI_SUCCESS; }