/** @file ;****************************************************************************** ;* Copyright (c) 2012 - 2021, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include #include #include #include #include #include #include #include #include #include typedef enum { SMM_RESET_ADDR, X_PM1A_EVT_BLK, X_PM1B_EVT_BLK, X_PM1A_CNT_BLK, X_PM1B_CNT_BLK, X_PM2_CNT_BLK, X_PM_TMR_BLK, X_GPE0_BLK, X_GPE1_BLK, MAX_FACP_GAS_DATA_NUM } FACP_GAS_DATA_NUM; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE AddrOfAllGASData[MAX_FACP_GAS_DATA_NUM] = {0}; EFI_STATUS Acpi30FacpUpdateForGASData ( IN EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer3 ) { UINTN Index; for (Index = 0; Index < MAX_FACP_GAS_DATA_NUM; Index++) { // // To update some items about GAS definition. // switch (Index) { // // To Update SpaceId, BitWidth and Address // case SMM_RESET_ADDR : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO; AddrOfAllGASData[Index].RegisterBitWidth = 0x08; // 8 Bits AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = PcdGet16 (PcdSoftwareSmiPort); break; case X_PM1A_EVT_BLK : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO; AddrOfAllGASData[Index].RegisterBitWidth = ((*AddrOfFadtPointer3)->Pm1EvtLen) * 8; // Translate Byte to Bit AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = (*AddrOfFadtPointer3)->Pm1aEvtBlk; break; case X_PM1A_CNT_BLK : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO; AddrOfAllGASData[Index].RegisterBitWidth = ((*AddrOfFadtPointer3)->Pm1CntLen) * 8; // Translate Byte to Bit AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = (*AddrOfFadtPointer3)->Pm1aCntBlk; break; case X_PM2_CNT_BLK : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO; AddrOfAllGASData[Index].RegisterBitWidth = ((*AddrOfFadtPointer3)->Pm2CntLen) * 8; // Translate Byte to Bit AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = (*AddrOfFadtPointer3)->Pm2CntBlk; break; case X_PM_TMR_BLK : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO; AddrOfAllGASData[Index].RegisterBitWidth = ((*AddrOfFadtPointer3)->PmTmrLen) * 8; // Translate Byte to Bit AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = (*AddrOfFadtPointer3)->PmTmrBlk; break; case X_GPE0_BLK : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO; AddrOfAllGASData[Index].RegisterBitWidth = ((*AddrOfFadtPointer3)->Gpe0BlkLen) * 8; // Translate Byte to Bit AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = (*AddrOfFadtPointer3)->Gpe0Blk; break; default : AddrOfAllGASData[Index].AddressSpaceId = EFI_ACPI_3_0_UNDEFINED; AddrOfAllGASData[Index].RegisterBitWidth = 0; AddrOfAllGASData[Index].RegisterBitOffset = 0; AddrOfAllGASData[Index].Address = 0; break; } switch (AddrOfAllGASData[Index].RegisterBitWidth) { // // To Update Access Size Type. // case 8: AddrOfAllGASData[Index].AccessSize = EFI_ACPI_3_0_BYTE; break; case 16: AddrOfAllGASData[Index].AccessSize = EFI_ACPI_3_0_WORD; break; case 32: AddrOfAllGASData[Index].AccessSize = EFI_ACPI_3_0_DWORD; break; case 64: AddrOfAllGASData[Index].AccessSize = EFI_ACPI_3_0_QWORD; break; default : AddrOfAllGASData[Index].AccessSize = EFI_ACPI_3_0_UNDEFINED; break; } // // Follow ACPI 4.8.4.1 General-Purpose Event Register Blocks // Each register in the block is accessed as a byte // if ((Index == X_GPE0_BLK) || (Index == X_GPE1_BLK)) { AddrOfAllGASData[Index].AccessSize = EFI_ACPI_3_0_BYTE; } } return EFI_SUCCESS; } EFI_STATUS AcpiFacp30AboveCommonUpdate ( IN EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer3 ) { Acpi30FacpUpdateForGASData (AddrOfFadtPointer3); (* AddrOfFadtPointer3)->Flags |= EFI_ACPI_3_0_RESET_REG_SUP; (* AddrOfFadtPointer3)->ResetReg = AddrOfAllGASData[SMM_RESET_ADDR]; (* AddrOfFadtPointer3)->ResetValue = SMM_OS_RESET_SMI_VALUE; (* AddrOfFadtPointer3)->XPm1aEvtBlk = AddrOfAllGASData[X_PM1A_EVT_BLK]; (* AddrOfFadtPointer3)->XPm1bEvtBlk = AddrOfAllGASData[X_PM1B_EVT_BLK]; (* AddrOfFadtPointer3)->XPm1aCntBlk = AddrOfAllGASData[X_PM1A_CNT_BLK]; (* AddrOfFadtPointer3)->XPm1bCntBlk = AddrOfAllGASData[X_PM1B_CNT_BLK]; (* AddrOfFadtPointer3)->XPm2CntBlk = AddrOfAllGASData[X_PM2_CNT_BLK]; (* AddrOfFadtPointer3)->XPmTmrBlk = AddrOfAllGASData[X_PM_TMR_BLK]; (* AddrOfFadtPointer3)->XGpe0Blk = AddrOfAllGASData[X_GPE0_BLK]; (* AddrOfFadtPointer3)->XGpe1Blk = AddrOfAllGASData[X_GPE1_BLK]; return EFI_SUCCESS; } EFI_STATUS Acpi63FacpUpdateCommon ( IN EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer63 ) { (*AddrOfFadtPointer63)->Header.Revision = EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; (*AddrOfFadtPointer63)->Header.Length = sizeof(EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE); (*AddrOfFadtPointer63)->MinorVersion = EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION; return AcpiFacp30AboveCommonUpdate ( (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **)(UINTN)AddrOfFadtPointer63); } EFI_STATUS Acpi62FacpUpdateCommon ( IN EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer62 ) { (*AddrOfFadtPointer62)->Header.Revision = EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; (*AddrOfFadtPointer62)->Header.Length = sizeof(EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE); (*AddrOfFadtPointer62)->MinorVersion = EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION; return AcpiFacp30AboveCommonUpdate ( (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **)(UINTN)AddrOfFadtPointer62); } EFI_STATUS Acpi61FacpUpdateCommon ( IN EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer61 ) { (*AddrOfFadtPointer61)->Header.Revision = EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; (*AddrOfFadtPointer61)->Header.Length = sizeof(EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE); (*AddrOfFadtPointer61)->MinorVersion = EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION; return AcpiFacp30AboveCommonUpdate ( (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **)(UINTN)AddrOfFadtPointer61); } EFI_STATUS Acpi60FacpUpdateCommon ( IN EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer6 ) { (*AddrOfFadtPointer6)->Header.Revision = EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; (*AddrOfFadtPointer6)->Header.Length = sizeof(EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE); return AcpiFacp30AboveCommonUpdate ( (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **)(UINTN)AddrOfFadtPointer6); } EFI_STATUS Acpi50FacpUpdateCommon ( IN EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer5 ) { (*AddrOfFadtPointer5)->Header.Revision = EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; (*AddrOfFadtPointer5)->Header.Length = sizeof(EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE); return AcpiFacp30AboveCommonUpdate ((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **)(UINTN)AddrOfFadtPointer5); } EFI_STATUS Acpi30FacpUpdateCommon ( IN EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer3 ) { (*AddrOfFadtPointer3)->Header.Revision = EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; (*AddrOfFadtPointer3)->Header.Length = sizeof(EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE); return AcpiFacp30AboveCommonUpdate (AddrOfFadtPointer3); } EFI_STATUS Acpi10FacpUpdateCommon ( IN EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE **AddrOfFadtPointer1, IN OUT EFI_ACPI_COMMON_HEADER *Table ) { (*AddrOfFadtPointer1)->IntModel = 0x01; // INT_MODEL; (*AddrOfFadtPointer1)->Reserved1 = 0; // RESERVED; (*AddrOfFadtPointer1)->Reserved4 = 0; // RESERVED; (*AddrOfFadtPointer1)->Reserved5 = 0; // RESERVED; (*AddrOfFadtPointer1)->Header.Revision = EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION; Table->Length = sizeof(EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE); return EFI_SUCCESS; } /** Update FACP table content 1. RESET Register content, system will always trigger SW SMI for OS reset (For ACPI 2.0/3.0 or above) 2. Update RTC wakeup support flag according to setup variable setting 3. Update 8042 support flag according to KBC exist or not. @param Table The table to update @param SetupVariable SETUP Variable pointer @return EFI_SUCCESS Update table success **/ EFI_STATUS FacpUpdateCommon ( IN OUT EFI_ACPI_COMMON_HEADER *Table ) { EFI_STATUS Status; EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer63; EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer62; EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer61; EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer6; EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer5; EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer3; EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer1; EFI_CPU_IO2_PROTOCOL *CpuIo; UINT8 Value; KERNEL_CONFIGURATION SetupVariable; FadtPointer1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE*) Table; FadtPointer3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE*) Table; FadtPointer5 = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE*) Table; FadtPointer6 = (EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE*) Table; FadtPointer61 = (EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE*) Table; FadtPointer62 = (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE*) Table; FadtPointer63 = (EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE*) Table; Status = GetKernelConfiguration (&SetupVariable); if (EFI_ERROR (Status)) { SetupVariable.AcpiVer = 3; SetupVariable.FacpRTCS4Wakeup = 1; SetupVariable.WakeOnPME = 1; } if (SetupVariable.AcpiVer == 7) { Acpi63FacpUpdateCommon (&FadtPointer63); } else if (SetupVariable.AcpiVer == 6) { Acpi62FacpUpdateCommon (&FadtPointer62); } else if (SetupVariable.AcpiVer == 5) { Acpi61FacpUpdateCommon (&FadtPointer61); } else if (SetupVariable.AcpiVer == 4) { Acpi60FacpUpdateCommon (&FadtPointer6); } else if (SetupVariable.AcpiVer == 3) { Acpi50FacpUpdateCommon (&FadtPointer5); } else if ((SetupVariable.AcpiVer == 1) || (SetupVariable.AcpiVer == 2)) { Acpi30FacpUpdateCommon (&FadtPointer3); } else { Acpi10FacpUpdateCommon (&FadtPointer1, Table); } if (SetupVariable.FacpRTCS4Wakeup) { FadtPointer3->Flags |= EFI_ACPI_3_0_RTC_S4; } else { FadtPointer3->Flags &= ~EFI_ACPI_3_0_RTC_S4; } if (SetupVariable.WakeOnPME) { FadtPointer3->Flags &= ~EFI_ACPI_3_0_PCI_EXP_WAK; // PCI Express* Wake Disable(PCIEXPWAK_DIS) } else { FadtPointer3->Flags |= EFI_ACPI_3_0_PCI_EXP_WAK; } // //IaPcBootArch is only available in ACPI3.0 FACP // if (SetupVariable.AcpiVer >= 1) { Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)&CpuIo); if (!EFI_ERROR (Status)) { Value = 00; // Make the default "legacy". If this function fails, we will assume KBC present. CpuIo->Io.Read ( CpuIo, EfiCpuIoWidthUint8, 0x64, 1, &Value ); if (Value == 0xFF) { FadtPointer3->IaPcBootArch &= ~EFI_ACPI_3_0_8042; // No KBC, clear 8042 flag. } else { FadtPointer3->IaPcBootArch |= EFI_ACPI_3_0_8042; // KBC found, set 8042 flag. } } } return EFI_SUCCESS; }