diff options
author | Konstantin Aladyshev <aladyshev22@gmail.com> | 2017-08-01 15:26:30 +0300 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2017-08-04 15:26:39 +0000 |
commit | c4f60f33bd4ac3aa1adee05b4e91969c5327b09c (patch) | |
tree | 1131cd8bff50ae420c6745ddc2f85dc08e39e83a | |
parent | 1cda0d0e50cd39b7376d316bb19b2437852436ba (diff) | |
download | coreboot-c4f60f33bd4ac3aa1adee05b4e91969c5327b09c.tar.xz |
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>
3 files changed, 90 insertions, 48 deletions
diff --git a/src/vendorcode/amd/agesa/f15/Proc/Mem/Feat/DMI/mfDMI.c b/src/vendorcode/amd/agesa/f15/Proc/Mem/Feat/DMI/mfDMI.c index 3138f3f2ec..1247e2f915 100644 --- a/src/vendorcode/amd/agesa/f15/Proc/Mem/Feat/DMI/mfDMI.c +++ b/src/vendorcode/amd/agesa/f15/Proc/Mem/Feat/DMI/mfDMI.c @@ -315,7 +315,10 @@ MemFDMISupport3 ( 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) { DmiTable[DimmIndex].MemorySize = (UINT16) DimmSize; } else { @@ -335,21 +338,32 @@ MemFDMISupport3 ( DmiTable[DimmIndex].DimmPresent = 1; // 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); - Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) + (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]) ; - if (Value32 <= 938) { - 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 + + // If SPD is wrong, division by 0 in DIMM speed calculation could reboot CPU + // So avoid it by this check + if ((SpdDataStructure[DimmIndex].Data[11]==0) || + ((SpdDataStructure[DimmIndex].Data[9] & 0xF) == 0)) { + DmiTable[DimmIndex].Speed = 0; // Unknown + } else { + MTB_ps = ((INT32) SpdDataStructure[DimmIndex].Data[10] * 1000) / + SpdDataStructure[DimmIndex].Data[11]; + FTB_ps = (SpdDataStructure[DimmIndex].Data[9] >> 4) / + (SpdDataStructure[DimmIndex].Data[9] & 0xF); + Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) + + (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]); + if (Value32 <= 938) { + 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) diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/Mem/Feat/DMI/mfDMI.c b/src/vendorcode/amd/agesa/f15tn/Proc/Mem/Feat/DMI/mfDMI.c index 6620030518..2090e11616 100644 --- a/src/vendorcode/amd/agesa/f15tn/Proc/Mem/Feat/DMI/mfDMI.c +++ b/src/vendorcode/amd/agesa/f15tn/Proc/Mem/Feat/DMI/mfDMI.c @@ -330,7 +330,10 @@ MemFDMISupport3 ( 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) { DmiTable[DimmIndex].MemorySize = (UINT16) DimmSize; } else { @@ -354,21 +357,32 @@ MemFDMISupport3 ( } // 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); - Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) + (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]) ; - if (Value32 <= 938) { - 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 + + // If SPD is wrong, division by 0 in DIMM speed calculation could reboot CPU + // So avoid it by this check + if ((SpdDataStructure[DimmIndex].Data[11]==0) || + ((SpdDataStructure[DimmIndex].Data[9] & 0xF) == 0)) { + DmiTable[DimmIndex].Speed = 0; // Unknown + } else { + MTB_ps = ((INT32) SpdDataStructure[DimmIndex].Data[10] * 1000) / + SpdDataStructure[DimmIndex].Data[11]; + FTB_ps = (SpdDataStructure[DimmIndex].Data[9] >> 4) / + (SpdDataStructure[DimmIndex].Data[9] & 0xF); + Value32 = (MTB_ps * SpdDataStructure[DimmIndex].Data[12]) + + (FTB_ps * (INT8) SpdDataStructure[DimmIndex].Data[34]); + if (Value32 <= 938) { + 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) diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c index 57cc491e56..856a21af33 100644 --- a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c @@ -380,7 +380,10 @@ MemFDMISupport3 ( 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) { DmiPhysicalDimmInfoTable->MemorySize = (UINT16) DimmSize; } else { @@ -409,21 +412,32 @@ MemFDMISupport3 ( } // Speed (offset 15h) - MTB_ps = ((INT32) SpdDataStructure->Data[10] * 1000) / SpdDataStructure->Data[11]; - FTB_ps = (SpdDataStructure->Data[9] >> 4) / (SpdDataStructure->Data[9] & 0xF); - Value32 = (MTB_ps * SpdDataStructure->Data[12]) + (FTB_ps * (INT8) SpdDataStructure->Data[34]) ; - if (Value32 <= 938) { - 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 + + // If SPD is wrong, division by 0 in DIMM speed calculation could reboot CPU + // So avoid it by this check + if ((SpdDataStructure->Data[11]==0) || + ((SpdDataStructure->Data[9] & 0xF) == 0)) { + DmiPhysicalDimmInfoTable->Speed = 0; // Unknown + } else { + MTB_ps = ((INT32) SpdDataStructure->Data[10] * 1000) / + SpdDataStructure->Data[11]; + FTB_ps = (SpdDataStructure->Data[9] >> 4) / + (SpdDataStructure->Data[9] & 0xF); + Value32 = (MTB_ps * SpdDataStructure->Data[12]) + + (FTB_ps * (INT8) SpdDataStructure->Data[34]); + if (Value32 <= 938) { + 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) |