AGESA f15 f15tn f16kb: Add extra checks for incorrect SPD data

Make DMI data calculation fail-safe to incorrect SPD data.

Change-Id: Ica92850cc77e1f7cbf3e7e44717de42a03b93bbe
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
Reviewed-on: https://review.coreboot.org/20839
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
This commit is contained in:
Konstantin Aladyshev 2017-08-01 15:26:30 +03:00 committed by Martin Roth
parent 1cda0d0e50
commit c4f60f33bd
3 changed files with 90 additions and 48 deletions

View File

@ -315,7 +315,10 @@ MemFDMISupport3 (
DmiTable[DimmIndex].Attributes = 4; // Quad Rank Dimm DmiTable[DimmIndex].Attributes = 4; // Quad Rank Dimm
} }
DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank); if ((!BusWidth) || (!Width) || (!Rank))
DimmSize = 0xFFFF; // size is unknown
else
DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank);
if (DimmSize < 0x7FFF) { if (DimmSize < 0x7FFF) {
DmiTable[DimmIndex].MemorySize = (UINT16) DimmSize; DmiTable[DimmIndex].MemorySize = (UINT16) DimmSize;
} else { } else {
@ -335,21 +338,32 @@ MemFDMISupport3 (
DmiTable[DimmIndex].DimmPresent = 1; DmiTable[DimmIndex].DimmPresent = 1;
// Speed (offset 15h) // Speed (offset 15h)
MTB_ps = ((INT32) SpdDataStructure[DimmIndex].Data[10] * 1000) / SpdDataStructure[DimmIndex].Data[11];
FTB_ps = (SpdDataStructure[DimmIndex].Data[9] >> 4) / (SpdDataStructure[DimmIndex].Data[9] & 0xF); // If SPD is wrong, division by 0 in DIMM speed calculation could reboot CPU
Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) + (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]) ; // So avoid it by this check
if (Value32 <= 938) { if ((SpdDataStructure[DimmIndex].Data[11]==0) ||
DmiTable[DimmIndex].Speed = 1067; // DDR3-2133 ((SpdDataStructure[DimmIndex].Data[9] & 0xF) == 0)) {
} else if (Value32 <= 1071) { DmiTable[DimmIndex].Speed = 0; // Unknown
DmiTable[DimmIndex].Speed = 933; // DDR3-1866 } else {
} else if (Value32 <= 1250) { MTB_ps = ((INT32) SpdDataStructure[DimmIndex].Data[10] * 1000) /
DmiTable[DimmIndex].Speed = 800; // DDR3-1600 SpdDataStructure[DimmIndex].Data[11];
} else if (Value32 <= 1500) { FTB_ps = (SpdDataStructure[DimmIndex].Data[9] >> 4) /
DmiTable[DimmIndex].Speed = 667; // DDR3-1333 (SpdDataStructure[DimmIndex].Data[9] & 0xF);
} else if (Value32 <= 1875) { Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) +
DmiTable[DimmIndex].Speed = 533; // DDR3-1066 (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]);
} else if (Value32 <= 2500) { if (Value32 <= 938) {
DmiTable[DimmIndex].Speed = 400; // DDR3-800 DmiTable[DimmIndex].Speed = 1067; // DDR3-2133
} else if (Value32 <= 1071) {
DmiTable[DimmIndex].Speed = 933; // DDR3-1866
} else if (Value32 <= 1250) {
DmiTable[DimmIndex].Speed = 800; // DDR3-1600
} else if (Value32 <= 1500) {
DmiTable[DimmIndex].Speed = 667; // DDR3-1333
} else if (Value32 <= 1875) {
DmiTable[DimmIndex].Speed = 533; // DDR3-1066
} else if (Value32 <= 2500) {
DmiTable[DimmIndex].Speed = 400; // DDR3-800
}
} }
// Manufacturer (offset 17h) // Manufacturer (offset 17h)

View File

@ -330,7 +330,10 @@ MemFDMISupport3 (
DmiTable[DimmIndex].Attributes = 4; // Quad Rank Dimm DmiTable[DimmIndex].Attributes = 4; // Quad Rank Dimm
} }
DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank); if ((!BusWidth) || (!Width) || (!Rank))
DimmSize = 0xFFFF; // size is unknown
else
DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank);
if (DimmSize < 0x7FFF) { if (DimmSize < 0x7FFF) {
DmiTable[DimmIndex].MemorySize = (UINT16) DimmSize; DmiTable[DimmIndex].MemorySize = (UINT16) DimmSize;
} else { } else {
@ -354,21 +357,32 @@ MemFDMISupport3 (
} }
// Speed (offset 15h) // Speed (offset 15h)
MTB_ps = ((INT32) SpdDataStructure[DimmIndex].Data[10] * 1000) / SpdDataStructure[DimmIndex].Data[11];
FTB_ps = (SpdDataStructure[DimmIndex].Data[9] >> 4) / (SpdDataStructure[DimmIndex].Data[9] & 0xF); // If SPD is wrong, division by 0 in DIMM speed calculation could reboot CPU
Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) + (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]) ; // So avoid it by this check
if (Value32 <= 938) { if ((SpdDataStructure[DimmIndex].Data[11]==0) ||
DmiTable[DimmIndex].Speed = 1067; // DDR3-2133 ((SpdDataStructure[DimmIndex].Data[9] & 0xF) == 0)) {
} else if (Value32 <= 1071) { DmiTable[DimmIndex].Speed = 0; // Unknown
DmiTable[DimmIndex].Speed = 933; // DDR3-1866 } else {
} else if (Value32 <= 1250) { MTB_ps = ((INT32) SpdDataStructure[DimmIndex].Data[10] * 1000) /
DmiTable[DimmIndex].Speed = 800; // DDR3-1600 SpdDataStructure[DimmIndex].Data[11];
} else if (Value32 <= 1500) { FTB_ps = (SpdDataStructure[DimmIndex].Data[9] >> 4) /
DmiTable[DimmIndex].Speed = 667; // DDR3-1333 (SpdDataStructure[DimmIndex].Data[9] & 0xF);
} else if (Value32 <= 1875) { Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) +
DmiTable[DimmIndex].Speed = 533; // DDR3-1066 (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]);
} else if (Value32 <= 2500) { if (Value32 <= 938) {
DmiTable[DimmIndex].Speed = 400; // DDR3-800 DmiTable[DimmIndex].Speed = 1067; // DDR3-2133
} else if (Value32 <= 1071) {
DmiTable[DimmIndex].Speed = 933; // DDR3-1866
} else if (Value32 <= 1250) {
DmiTable[DimmIndex].Speed = 800; // DDR3-1600
} else if (Value32 <= 1500) {
DmiTable[DimmIndex].Speed = 667; // DDR3-1333
} else if (Value32 <= 1875) {
DmiTable[DimmIndex].Speed = 533; // DDR3-1066
} else if (Value32 <= 2500) {
DmiTable[DimmIndex].Speed = 400; // DDR3-800
}
} }
// Manufacturer (offset 17h) // Manufacturer (offset 17h)

View File

@ -380,7 +380,10 @@ MemFDMISupport3 (
DmiPhysicalDimmInfoTable->Attributes = 4; // Quad Rank Dimm DmiPhysicalDimmInfoTable->Attributes = 4; // Quad Rank Dimm
} }
DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank); if ((!BusWidth) || (!Width) || (!Rank))
DimmSize = 0xFFFF; // size is unknown
else
DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank);
if (DimmSize < 0x7FFF) { if (DimmSize < 0x7FFF) {
DmiPhysicalDimmInfoTable->MemorySize = (UINT16) DimmSize; DmiPhysicalDimmInfoTable->MemorySize = (UINT16) DimmSize;
} else { } else {
@ -409,21 +412,32 @@ MemFDMISupport3 (
} }
// Speed (offset 15h) // Speed (offset 15h)
MTB_ps = ((INT32) SpdDataStructure->Data[10] * 1000) / SpdDataStructure->Data[11];
FTB_ps = (SpdDataStructure->Data[9] >> 4) / (SpdDataStructure->Data[9] & 0xF); // If SPD is wrong, division by 0 in DIMM speed calculation could reboot CPU
Value32 = (MTB_ps * SpdDataStructure->Data[12]) + (FTB_ps * (INT8) SpdDataStructure->Data[34]) ; // So avoid it by this check
if (Value32 <= 938) { if ((SpdDataStructure->Data[11]==0) ||
DmiPhysicalDimmInfoTable->Speed = 1067; // DDR3-2133 ((SpdDataStructure->Data[9] & 0xF) == 0)) {
} else if (Value32 <= 1071) { DmiPhysicalDimmInfoTable->Speed = 0; // Unknown
DmiPhysicalDimmInfoTable->Speed = 933; // DDR3-1866 } else {
} else if (Value32 <= 1250) { MTB_ps = ((INT32) SpdDataStructure->Data[10] * 1000) /
DmiPhysicalDimmInfoTable->Speed = 800; // DDR3-1600 SpdDataStructure->Data[11];
} else if (Value32 <= 1500) { FTB_ps = (SpdDataStructure->Data[9] >> 4) /
DmiPhysicalDimmInfoTable->Speed = 667; // DDR3-1333 (SpdDataStructure->Data[9] & 0xF);
} else if (Value32 <= 1875) { Value32 = (MTB_ps * SpdDataStructure->Data[12]) +
DmiPhysicalDimmInfoTable->Speed = 533; // DDR3-1066 (FTB_ps * (INT8) SpdDataStructure->Data[34]);
} else if (Value32 <= 2500) { if (Value32 <= 938) {
DmiPhysicalDimmInfoTable->Speed = 400; // DDR3-800 DmiPhysicalDimmInfoTable->Speed = 1067; // DDR3-2133
} else if (Value32 <= 1071) {
DmiPhysicalDimmInfoTable->Speed = 933; // DDR3-1866
} else if (Value32 <= 1250) {
DmiPhysicalDimmInfoTable->Speed = 800; // DDR3-1600
} else if (Value32 <= 1500) {
DmiPhysicalDimmInfoTable->Speed = 667; // DDR3-1333
} else if (Value32 <= 1875) {
DmiPhysicalDimmInfoTable->Speed = 533; // DDR3-1066
} else if (Value32 <= 2500) {
DmiPhysicalDimmInfoTable->Speed = 400; // DDR3-800
}
} }
// Manufacturer (offset 17h) // Manufacturer (offset 17h)