summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Aladyshev <aladyshev22@gmail.com>2017-08-01 15:26:30 +0300
committerMartin Roth <martinroth@google.com>2017-08-04 15:26:39 +0000
commitc4f60f33bd4ac3aa1adee05b4e91969c5327b09c (patch)
tree1131cd8bff50ae420c6745ddc2f85dc08e39e83a
parent1cda0d0e50cd39b7376d316bb19b2437852436ba (diff)
downloadcoreboot-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>
-rw-r--r--src/vendorcode/amd/agesa/f15/Proc/Mem/Feat/DMI/mfDMI.c46
-rw-r--r--src/vendorcode/amd/agesa/f15tn/Proc/Mem/Feat/DMI/mfDMI.c46
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c46
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)