From: Jason1 Lin <jason1....@intel.com> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3959
As per FIT BIOS Specification 1.2 Rules, the size bytes (3 bytes) / reserved byte (1 byte) / CheckSum byte (1 byte) in type 2 are must-be-zero (MBZ). These bytes could be override for the other usages. This change is used to support the Type 02 (ACM) Ver. 0x200. Command: [-S <StartupAcmAddress StartupAcmSize>|<StartupAcmGuid>] [-I <StartupAcmFMS StartupAcmFMSMask>] [-V <StartupAcmVersion>] Signed-off-by: Jason1 Lin <jason1....@intel.com> Cc: Bob Feng <bob.c.f...@intel.com> Cc: Liming Gao <gaolim...@byosoft.com.cn> Cc: Yuwei Chen <yuwei.c...@intel.com> Cc: Isaac W Oram <isaac.w.o...@intel.com> Cc: Rangasai V Chaganty <rangasai.v.chaga...@intel.com> Cc: Dakota Chiang <dakota.chi...@intel.com> --- Silicon/Intel/Tools/FitGen/FitGen.c | 183 ++++++++++++++++++-- Silicon/Intel/Tools/FitGen/FitGen.h | 2 +- 2 files changed, 165 insertions(+), 20 deletions(-) diff --git a/Silicon/Intel/Tools/FitGen/FitGen.c b/Silicon/Intel/Tools/FitGen/FitGen.c index 01b4f82518..577ce48b10 100644 --- a/Silicon/Intel/Tools/FitGen/FitGen.c +++ b/Silicon/Intel/Tools/FitGen/FitGen.c @@ -55,6 +55,7 @@ typedef struct { #define ACM_MODULE_FLAG_PREPRODUCTION 0x4000 #define ACM_MODULE_FLAG_DEBUG_SIGN 0x8000 +#define NIBBLES_TO_BYTE(A, B) (UINT8)(((A & (0x0F)) << 4) | (B & 0x0F)) typedef struct { UINT16 ModuleType; @@ -149,6 +150,20 @@ typedef struct { ACM_PROCESSOR_ID ProcessorID[1]; } PROCESSOR_ID_LIST; +typedef union { + struct { + UINT32 Stepping : 4; + UINT32 Model : 4; + UINT32 Family : 4; + UINT32 Type : 2; + UINT32 Reserved1 : 2; + UINT32 ExtendedModel : 4; + UINT32 ExtendedFamily: 8; + UINT32 Reserved2 : 4; + } Bits; + UINT32 Uint32; +} PROCESSOR_ID; + #pragma pack () @@ -210,6 +225,7 @@ typedef struct { #define DEFAULT_FIT_TABLE_POINTER_OFFSET 0x40 #define DEFAULT_FIT_ENTRY_VERSION 0x0100 +#define STARTUP_ACM_FIT_ENTRY_200_VERSION 0x0200 #define TOP_FLASH_ADDRESS (gFitTableContext.TopFlashAddressRemapValue) @@ -247,6 +263,8 @@ typedef struct { UINT8 *Buffer; // Used by OptionalModule only UINT32 Size; UINT32 Version; // Used by OptionalModule and PortModule only + UINT32 FMS; // Used by Entry Type 02 (ACM) Ver. 0x200 only + UINT32 FMSMask; // Used by Entry Type 02 (ACM) Ver. 0x200 only } FIT_TABLE_CONTEXT_ENTRY; typedef struct { @@ -262,7 +280,7 @@ typedef struct { UINT32 GlobalVersion; UINT32 FitHeaderVersion; FIT_TABLE_CONTEXT_ENTRY StartupAcm[MAX_STARTUP_ACM_ENTRY]; - UINT32 StartupAcmVersion; + UINT32 StartupAcmVersion[MAX_STARTUP_ACM_ENTRY]; FIT_TABLE_CONTEXT_ENTRY DiagnstAcm; UINT32 DiagnstAcmVersion; FIT_TABLE_CONTEXT_ENTRY BiosModule[MAX_BIOS_MODULE_ENTRY]; @@ -341,7 +359,7 @@ Returns: "\t[-L <MicrocodeSlotSize> <MicrocodeFfsGuid>]\n" "\t[-LF <MicrocodeSlotSize>]\n" "\t[-I <BiosInfoGuid>]\n" - "\t[-S <StartupAcmAddress StartupAcmSize>|<StartupAcmGuid>] [-V <StartupAcmVersion>]\n" + "\t[-S <StartupAcmAddress StartupAcmSize>|<StartupAcmGuid>] [-I <StartupAcmFMS StartupAcmFMSMask>] [-V <StartupAcmVersion>]\n" "\t[-U <DiagnstAcmAddress>|<DiagnstAcmGuid>]\n" "\t[-B <BiosModuleAddress BiosModuleSize>] [-B ...] [-V <BiosModuleVersion>]\n" "\t[-M <MicrocodeAddress MicrocodeSize>] [-M ...]|[-U <MicrocodeFv MicrocodeBase>|<MicrocodeRegionOffset MicrocodeRegionSize>|<MicrocodeGuid>] [-V <MicrocodeVersion>]\n" @@ -356,8 +374,11 @@ Returns: printf ("\tFitTablePointerOffset - FIT table pointer offset. 0x%x as default. 0x18 for current soon to be obsoleted CPUs. User can set both.\n", DEFAULT_FIT_TABLE_POINTER_OFFSET); printf ("\tBiosInfoGuid - Guid of BiosInfo Module. If this module exists, StartupAcm/Bios/Microcode can be optional.\n"); printf ("\tStartupAcmAddress - Address of StartupAcm.\n"); - printf ("\tStartupAcmSize - Size of StartupAcm.\n"); + printf ("\tStartupAcmSize - The maximum size value that could place the StartupAcm in.\n"); printf ("\tStartupAcmGuid - Guid of StartupAcm Module, if StartupAcm is in a BiosModule, it will be excluded form that.\n"); + printf ("\tStartupAcmFMS - Value of PROCESSOR ID (Family/Model/Stepping value called \"FMS\") - see detail on FIT spec (1.3).\n"); + printf ("\tStartupAcmFMSMask - Value use for uCode (if it recognizes 0x200 Type2 entry) to do bitmask logic operation with CPU processor ID.\n"); + printf ("\t If the result match to StartupAcmFMS, corresponding ACM will be loaded - see detail on FIT spec (1.3).\n"); printf ("\tDiagnstAcmAddress - Address of DiagnstAcm.\n"); printf ("\tDiagnstAcmGuid - Guid of DiagnstAcm Module, if DiagnstAcm is in a BiosModule, it will be excluded from that.\n"); printf ("\tBiosModuleAddress - Address of BiosModule. User should ensure there is no overlap.\n"); @@ -1155,6 +1176,9 @@ Returns: Error (NULL, 0, 0, "-I Parameter incorrect, too many StartupAcm!", NULL); return 0; } + // + // NOTE: BIOS INFO structure only support the default FIT entry format. + // gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Type = FIT_TABLE_TYPE_STARTUP_ACM; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Address = (UINT32)BiosInfoStruct[BiosInfoIndex].Address; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size = (UINT32)BiosInfoStruct[BiosInfoIndex].Size; @@ -1392,7 +1416,37 @@ Returns: gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size = FileSize; // - // 1.1 StartupAcm version + // 1.1 Support 0x200 StartupAcm Information + // With the -I parameter should assign the type 2 entry with 0x200 version format + // + if ((Index + 1 >= argc) || + ((strcmp (argv[Index], "-I") != 0) && + (strcmp (argv[Index], "-i") != 0)) ) { + // + // Bypass + // + gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = gFitTableContext.GlobalVersion; + } else { + if (Index + 2 >= argc) { + // + // Should get two input value, but not sufficient + // + Error (NULL, 0, 0, "-I Parameter incorrect, Require two inputs value!", NULL); + return 0; + } else { + // + // With the -I parameter should assign the type 2 entry version as 0x200 format + // + gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = STARTUP_ACM_FIT_ENTRY_200_VERSION; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMS = (UINT32)xtoi (argv[Index + 1]); + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMSMask = (UINT32)xtoi (argv[Index + 2]); + + Index += 3; + } + } + + // + // 1.2 StartupAcm version // if ((Index + 1 >= argc) || ((strcmp (argv[Index], "-V") != 0) && @@ -1400,18 +1454,17 @@ Returns: // // Bypass // - gFitTableContext.StartupAcmVersion = gFitTableContext.GlobalVersion; } else { // // Get offset from parameter // - gFitTableContext.StartupAcmVersion = xtoi (argv[Index + 1]); + gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = xtoi (argv[Index + 1]); Index += 2; } gFitTableContext.StartupAcmNumber ++; gFitTableContext.FitEntryNumber ++; - } + }; // // 1.5. DiagnosticsAcm @@ -2185,7 +2238,7 @@ Returns: printf ("Total FIT Entry number: 0x%x\n", gFitTableContext.FitEntryNumber); printf ("FitHeader version: 0x%04x\n", gFitTableContext.FitHeaderVersion); for (Index = 0; Index < gFitTableContext.StartupAcmNumber; Index++) { - printf ("StartupAcm[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, gFitTableContext.StartupAcm[Index].Address, gFitTableContext.StartupAcm[Index].Size, gFitTableContext.StartupAcmVersion); + printf ("StartupAcm[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, gFitTableContext.StartupAcm[Index].Address, gFitTableContext.StartupAcm[Index].Size, gFitTableContext.StartupAcmVersion[Index]); } if (gFitTableContext.DiagnstAcm.Address != 0) { printf ("DiagnosticAcm - (0x%08x, 0x%08x, 0x%04x)\n", gFitTableContext.DiagnstAcm.Address, gFitTableContext.DiagnstAcm.Size, gFitTableContext.DiagnstAcmVersion); @@ -2774,6 +2827,8 @@ Returns: UINTN SubIndex; FIT_TABLE_CONTEXT_ENTRY TempContextEntry; FIRMWARE_INTERFACE_TABLE_ENTRY TempTableEntry; + PROCESSOR_ID FMS; + PROCESSOR_ID FMSMask; // // 1. FitPointer @@ -2825,16 +2880,30 @@ Returns: // 4. StartupAcm // for (Index = 0; Index < gFitTableContext.StartupAcmNumber; Index++) { - FitEntrySizeValue = 0; // gFitTableContext.StartupAcm.Size / 16 - FitEntry[FitIndex].Address = gFitTableContext.StartupAcm[Index].Address; - FitEntry[FitIndex].Size[0] = (UINT8)FitEntrySizeValue; - FitEntry[FitIndex].Size[1] = (UINT8)(FitEntrySizeValue >> 8); - FitEntry[FitIndex].Size[2] = (UINT8)(FitEntrySizeValue >> 16); - FitEntry[FitIndex].Rsvd = 0; - FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcmVersion; - FitEntry[FitIndex].Type = FIT_TABLE_TYPE_STARTUP_ACM; - FitEntry[FitIndex].C_V = 0; - FitEntry[FitIndex].Checksum = 0; + if (gFitTableContext.StartupAcmVersion[Index] == STARTUP_ACM_FIT_ENTRY_200_VERSION) { + FMS.Uint32 = gFitTableContext.StartupAcm[Index].FMS; + FMSMask.Uint32 = gFitTableContext.StartupAcm[Index].FMSMask; + FitEntry[FitIndex].Address = gFitTableContext.StartupAcm[Index].Address; + FitEntry[FitIndex].Size[0] = NIBBLES_TO_BYTE (FMS.Bits.Family, FMS.Bits.Model); + FitEntry[FitIndex].Size[1] = NIBBLES_TO_BYTE (FMS.Bits.ExtendedModel, FMS.Bits.Type); + FitEntry[FitIndex].Size[2] = NIBBLES_TO_BYTE (FMSMask.Bits.Family, FMSMask.Bits.Model); + FitEntry[FitIndex].Rsvd = NIBBLES_TO_BYTE (FMSMask.Bits.ExtendedModel, FMSMask.Bits.Type); + FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcmVersion[Index]; + FitEntry[FitIndex].Type = FIT_TABLE_TYPE_STARTUP_ACM; + FitEntry[FitIndex].C_V = 0; + FitEntry[FitIndex].Checksum = NIBBLES_TO_BYTE (FMSMask.Bits.ExtendedFamily, FMS.Bits.ExtendedFamily); + } else { + FitEntrySizeValue = 0; // gFitTableContext.StartupAcm.Size / 16 + FitEntry[FitIndex].Address = gFitTableContext.StartupAcm[Index].Address; + FitEntry[FitIndex].Size[0] = (UINT8)FitEntrySizeValue; + FitEntry[FitIndex].Size[1] = (UINT8)(FitEntrySizeValue >> 8); + FitEntry[FitIndex].Size[2] = (UINT8)(FitEntrySizeValue >> 16); + FitEntry[FitIndex].Rsvd = 0; + FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcmVersion[Index]; + FitEntry[FitIndex].Type = FIT_TABLE_TYPE_STARTUP_ACM; + FitEntry[FitIndex].C_V = 0; + FitEntry[FitIndex].Checksum = 0; + } FitIndex++; } @@ -3135,6 +3204,69 @@ Returns: return FvRecoveryFileSize; } +void +GetFMSFromFitEntry ( + IN FIRMWARE_INTERFACE_TABLE_ENTRY FitEntry, + IN OUT PROCESSOR_ID *FMS, + IN OUT PROCESSOR_ID *FMSMask + ) +/*++ + +Routine Description: + + Get FMS information from FIT Entry. + + Note: Since FIT entry not record all the processor ID information. + The value would not the same as the real value. + + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + | Byte | 15 | 14 | 13:12 | 11 | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + |Bit Fields| [7:4] | [3:0] | [7:7] | [6:0] | [7:4] | [3:0] | [7:4] | [3:0] | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + | Ver. 100 | Checksum | C_V | Type | Version | Reserved | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + | Ver. 200 | FMSMask | FMS | C_V | Type | Version | FMSMask | FMSMask | + | | ExtFamily | ExtFamily | | | | ExtModel | Type | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + | Byte | 10 | 9 | 8 | 7:0 | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + |Bit Fields| [7:4] | [3:0] | [7:4] | [3:0] | [7:4] | [3:0] | [7:4] | [3:0] | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + | Ver. 100 | Size[2] | Size[1] | Size[0] | Address | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + | Ver. 200 | FMSMask | FMSMask | FMS | FMS | FMS | FMS | Address | + | | Family | Model | ExtModel | Type | Family | Model | | + +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + + +Arguments: + + FitEntry - FIT entry information. + FMS - Processor ID information. + FMSMask - Processor ID mask information. + +Returns: + None + +--*/ +{ + + FMS->Bits.Family = (FitEntry.Size[0] & 0xF0) >> 4; + FMS->Bits.Model = (FitEntry.Size[0] & 0x0F); + FMS->Bits.ExtendedModel = (FitEntry.Size[1] & 0xF0) >> 4; + FMS->Bits.Type = (FitEntry.Size[1] & 0x0F); + FMS->Bits.ExtendedFamily = (FitEntry.Checksum & 0x0F); + + FMSMask->Bits.Family = (FitEntry.Size[2] & 0xF0) >> 4; + FMSMask->Bits.Model = (FitEntry.Size[2] & 0x0F); + FMSMask->Bits.ExtendedModel = (FitEntry.Rsvd & 0xF0) >> 4; + FMSMask->Bits.Type = (FitEntry.Rsvd & 0x0F); + FMSMask->Bits.ExtendedFamily = (FitEntry.Checksum & 0xF0) >> 4; +} + UINT32 GetFitEntryInfo ( IN UINT8 *FvBuffer, @@ -3161,6 +3293,11 @@ Returns: UINT32 FitEntrySizeValue; UINT32 FitIndex; UINT32 FitTableOffset; + PROCESSOR_ID FMS; + PROCESSOR_ID FMSMask; + + FMS.Uint32 = 0; + FMSMask.Uint32 = 0; // // 1. FitPointer @@ -3202,7 +3339,15 @@ Returns: break; case FIT_TABLE_TYPE_STARTUP_ACM: gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Address = (UINT32)FitEntry[FitIndex].Address; - gFitTableContext.StartupAcmVersion = FitEntry[FitIndex].Version; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size = FitEntrySizeValue; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Type = FitEntry[FitIndex].Type; + gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = FitEntry[FitIndex].Version; + if (gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] == STARTUP_ACM_FIT_ENTRY_200_VERSION) { + GetFMSFromFitEntry (FitEntry[FitIndex], &FMS, &FMSMask); + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMS = FMS.Uint32; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMSMask = FMSMask.Uint32; + } + gFitTableContext.StartupAcmNumber++; break; case FIT_TABLE_TYPE_BIOS_MODULE: gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Address = (UINT32)FitEntry[FitIndex].Address; diff --git a/Silicon/Intel/Tools/FitGen/FitGen.h b/Silicon/Intel/Tools/FitGen/FitGen.h index b7de0a6b2d..80a1423ceb 100644 --- a/Silicon/Intel/Tools/FitGen/FitGen.h +++ b/Silicon/Intel/Tools/FitGen/FitGen.h @@ -31,7 +31,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // Utility version information // #define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 65 +#define UTILITY_MINOR_VERSION 66 #define UTILITY_DATE __DATE__ // -- 2.37.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90990): https://edk2.groups.io/g/devel/message/90990 Mute This Topic: https://groups.io/mt/92111642/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-