From fd59dbd74e335c9337f4c2fedf76575a454f4e19 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Fri, 26 Jun 2015 12:17:48 -0500
Subject: [PATCH 077/143] northbridge/amd/amdmct/mct_ddr3: Fix null pointer
 access and related hangs

Change-Id: Iaf826b6a0c8e929372519f6d97933515a80f0b39
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/northbridge/amd/amdmct/mct_ddr3/mct_d.c  |   58 ++++++++++++++------------
 src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c |    8 ++--
 2 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index 6448eb4..2009fd3 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -826,7 +826,7 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
 			/* RDIMM */
 			/* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */
 			if (MaxDimmsInstallable == 1) {
-				rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+				rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 				if (MemClkFreq == 0x4) {
 					/* DDR3-667 */
@@ -850,8 +850,8 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
 					calibration_code |= 0x22 << 16;
 				}
 			} else if (MaxDimmsInstallable == 2) {
-				rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[0];
-				rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+				rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
+				rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 				if (dimm_count == 1) {
 					/* 1 DIMM detected */
@@ -875,8 +875,8 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
 					}
 				} else if (dimm_count == 2) {
 					/* 2 DIMMs detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[0];
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 					if (MemClkFreq == 0x4) {
 						/* DDR3-667 */
@@ -943,8 +943,8 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
 					}
 				} else if (dimm_count == 2) {
 					/* 2 DIMMs detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[0];
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 					if (MemClkFreq == 0x4) {
 						/* DDR3-667 */
@@ -1065,7 +1065,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
 			/* UDIMM */
 			/* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */
 			if (MaxDimmsInstallable == 1) {
-				rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+				rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 				if (MemClkFreq == 0x4) {
 					/* DDR3-667 */
@@ -1098,7 +1098,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
 			} else if (MaxDimmsInstallable == 2) {
 				if (dimm_count == 1) {
 					/* 1 DIMM detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 					if (MemClkFreq == 0x4) {
 						/* DDR3-667 */
@@ -1127,8 +1127,8 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
 					}
 				} else if (dimm_count == 2) {
 					/* 2 DIMMs detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[0];
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 					if (MemClkFreq == 0x4) {
 						/* DDR3-667 */
@@ -1196,7 +1196,7 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc
 			/* UDIMM */
 			/* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */
 			if (MaxDimmsInstallable == 1) {
-				rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+				rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 				if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
 					|| (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) {
@@ -1212,7 +1212,7 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc
 			} else if (MaxDimmsInstallable == 2) {
 				if (dimm_count == 1) {
 					/* 1 DIMM detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 					if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
 						|| (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) {
@@ -1227,8 +1227,8 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc
 					}
 				} else if (dimm_count == 2) {
 					/* 2 DIMMs detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[0];
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 
 					if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
 						|| (MemClkFreq == 0xa)) {
@@ -5853,14 +5853,18 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 		uint8_t write_odt_delay;
 		uint8_t read_odt_delay;
 
+		/* NOTE
+		 * Rank count per DIMM and DCT is encoded by pDCTstat->DimmRanks[(<dimm number> * 2) + dct]
+		 */
+
 		/* Select appropriate ODT pattern for installed DIMMs
 		 * Refer to the Fam15h BKDG Rev. 3.14, page 149 onwards
 		 */
-		if (pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_REGISTERED]) {
+		if (pDCTstat->Status & (1 << SB_Registered)) {
 			if (MaxDimmsInstallable == 2) {
 				if (dimm_count == 1) {
 					/* 1 DIMM detected */
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 					if (rank_count_dimm1 == 1) {
 						odt_pattern_0 = 0x00000000;
 						odt_pattern_1 = 0x00000000;
@@ -5885,8 +5889,8 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 					}
 				} else {
 					/* 2 DIMMs detected */
-					rank_count_dimm0 = pDCTstat->C_DCTPtr[dct]->DimmRanks[0];
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 					if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
 						odt_pattern_0 = 0x00000000;
 						odt_pattern_1 = 0x01010202;
@@ -5924,7 +5928,7 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 				odt_pattern_2 = 0x00000000;
 				odt_pattern_3 = 0x00000000;
 			}
-		} else if (pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_LOAD_REDUCED]) {
+		} else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
 			/* TODO
 			 * Load reduced dimms UNIMPLEMENTED
 			 */
@@ -5936,7 +5940,7 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 			if (MaxDimmsInstallable == 2) {
 				if (dimm_count == 1) {
 					/* 1 DIMM detected */
-					rank_count_dimm1 = pDCTstat->C_DCTPtr[dct]->DimmRanks[1];
+					rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
 					if (rank_count_dimm1 == 1) {
 						odt_pattern_0 = 0x00000000;
 						odt_pattern_1 = 0x00000000;
@@ -5972,7 +5976,7 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 			}
 		}
 
-		if (pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_LOAD_REDUCED]) {
+		if (pDCTstat->Status & (1 << SB_LoadReduced)) {
 			/* TODO
 			 * Load reduced dimms UNIMPLEMENTED
 			 */
@@ -6032,11 +6036,11 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 			/* Select appropriate ODT pattern for installed DIMMs
 			 * Refer to the Fam10h BKDG Rev. 3.62, page 120 onwards
 			 */
-			if (pDCTstat->C_DCTPtr[i]->Status[DCT_STATUS_REGISTERED]) {
+			if (pDCTstat->Status & (1 << SB_Registered)) {
 				if (MaxDimmsInstallable == 2) {
 					if (dimm_count == 1) {
 						/* 1 DIMM detected */
-						rank_count_dimm1 = pDCTstat->C_DCTPtr[i]->DimmRanks[1];
+						rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + i];
 						if (rank_count_dimm1 == 1) {
 							odt_pattern_0 = 0x00000000;
 							odt_pattern_1 = 0x00000000;
@@ -6061,8 +6065,8 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 						}
 					} else {
 						/* 2 DIMMs detected */
-						rank_count_dimm0 = pDCTstat->C_DCTPtr[i]->DimmRanks[0];
-						rank_count_dimm1 = pDCTstat->C_DCTPtr[i]->DimmRanks[1];
+						rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + i];
+						rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + i];
 						if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
 							odt_pattern_0 = 0x00000000;
 							odt_pattern_1 = 0x01010202;
@@ -6104,7 +6108,7 @@ static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat,
 				if (MaxDimmsInstallable == 2) {
 					if (dimm_count == 1) {
 						/* 1 DIMM detected */
-						rank_count_dimm1 = pDCTstat->C_DCTPtr[i]->DimmRanks[1];
+						rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + i];
 						if (rank_count_dimm1 == 1) {
 							odt_pattern_0 = 0x00000000;
 							odt_pattern_1 = 0x00000000;
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
index 380c5f2..c7d7463 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
@@ -38,10 +38,9 @@ static uint8_t fam15_dimm_dic(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_
 static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
 {
 	uint8_t term = 0;
-	sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
-	uint8_t number_of_dimms = pDCTData->MaxDimmsInstalled;
+	uint8_t number_of_dimms = pDCTstat->MAdimms[dct];
 	uint8_t frequency_index;
-	uint8_t rank_count = pDCTData->DimmRanks[dimm];
+	uint8_t rank_count = pDCTstat->DimmRanks[(dimm * 2) + dct];
 
 	if (is_fam15h())
 		frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f;
@@ -101,8 +100,7 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d
 static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
 {
 	uint8_t term = 0;
-	sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
-	uint8_t number_of_dimms = pDCTData->MaxDimmsInstalled;
+	uint8_t number_of_dimms = pDCTstat->MAdimms[dct];
 	uint8_t frequency_index;
 
 	if (is_fam15h())
-- 
1.7.9.5

