From c4f60f33bd4ac3aa1adee05b4e91969c5327b09c Mon Sep 17 00:00:00 2001 From: Konstantin Aladyshev Date: Tue, 1 Aug 2017 15:26:30 +0300 Subject: AGESA f15 f15tn f16kb: Add extra checks for incorrect SPD data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make DMI data calculation fail-safe to incorrect SPD data. Change-Id: Ica92850cc77e1f7cbf3e7e44717de42a03b93bbe Signed-off-by: Konstantin Aladyshev Reviewed-on: https://review.coreboot.org/20839 Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel --- .../amd/agesa/f15/Proc/Mem/Feat/DMI/mfDMI.c | 46 ++++++++++++++-------- .../amd/agesa/f15tn/Proc/Mem/Feat/DMI/mfDMI.c | 46 ++++++++++++++-------- .../amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c | 46 ++++++++++++++-------- 3 files changed, 90 insertions(+), 48 deletions(-) (limited to 'src/vendorcode/amd/agesa') 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) -- cgit v1.2.3