From a4dcdca7ba4ef771272a1010be0268c8cf697058 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 8 Jan 2017 14:00:48 -0600 Subject: amd/mct/ddr2|ddr3: Refactor persistent members of DCTStatStruc Several members of DCTStatStruc are designed to persist across resets of all other members. Move the persistent members into a substructure in order to simplify the reset logic and avoid compiler warnings / UB. Change-Id: I1139b7b3b167d33d99619338d42fcd26e2581a5d Signed-off-by: Timothy Pearson Reviewed-on: https://review.coreboot.org/18058 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand Reviewed-by: Nico Huber --- src/northbridge/amd/amdmct/mct/mct_d.c | 33 ++++----------- src/northbridge/amd/amdmct/mct/mct_d.h | 57 +++++++++++++++----------- src/northbridge/amd/amdmct/mct/mctdqs_d.c | 6 +-- src/northbridge/amd/amdmct/mct/mctsrc.c | 14 +++---- src/northbridge/amd/amdmct/mct/mctsrc1p.c | 2 +- src/northbridge/amd/amdmct/mct/mctsrc2p.c | 6 +-- src/northbridge/amd/amdmct/mct/mcttmrl.c | 2 +- src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 18 ++------ src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 30 ++++++++------ src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c | 2 +- src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c | 2 +- src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c | 6 +-- 12 files changed, 81 insertions(+), 97 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c index 73aa20b329..909037ff1f 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ b/src/northbridge/amd/amdmct/mct/mct_d.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2015 Timothy Pearson , Raptor Engineering + * Copyright (C) 2015-2017 Timothy Pearson , Raptor Engineering * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -35,6 +35,8 @@ #include "mct_d.h" +#include + static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); static void DQSTiming_D(struct MCTStatStruc *pMCTstat, @@ -459,7 +461,7 @@ static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, } } for (Dir = 0; Dir < 2; Dir++) {//RD/WR - p = pDCTstat->CH_D_DIR_B_DQS[Channel][DIMM][Dir]; + p = pDCTstat->persistentData.CH_D_DIR_B_DQS[Channel][DIMM][Dir]; val = stream_to_int(p); /* CHA Read Data Timing High */ Set_NB32_index_wait(dev, index_reg, index+1, val); val = stream_to_int(p+4); /* CHA Write Data Timing High */ @@ -3598,37 +3600,16 @@ static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { u8 Node; - u32 i; struct DCTStatStruc *pDCTstat; - u32 start, stop; - u8 *p; - u16 host_serv1, host_serv2; /* Initialize Data structures by clearing all entries to 0 */ - p = (u8 *) pMCTstat; - for (i = 0; i < sizeof(struct MCTStatStruc); i++) { - p[i] = 0; - } + memset(pMCTstat, 0x00, sizeof(*pMCTstat)); for (Node = 0; Node < 8; Node++) { pDCTstat = pDCTstatA + Node; - host_serv1 = pDCTstat->HostBiosSrvc1; - host_serv2 = pDCTstat->HostBiosSrvc2; - - p = (u8 *) pDCTstat; - start = 0; - stop = (u32)(&((struct DCTStatStruc *)0)->CH_MaxRdLat[2]); - for (i = start; i < stop; i++) { - p[i] = 0; - } - start = (u32)(&((struct DCTStatStruc *)0)->CH_D_BC_RCVRDLY[2][4]); - stop = sizeof(struct DCTStatStruc); - for (i = start; i < stop; i++) { - p[i] = 0; - } - pDCTstat->HostBiosSrvc1 = host_serv1; - pDCTstat->HostBiosSrvc2 = host_serv2; + /* Clear all entries except persistentData */ + memset(pDCTstat, 0x00, sizeof(*pDCTstat) - sizeof(pDCTstat->persistentData)); } } diff --git a/src/northbridge/amd/amdmct/mct/mct_d.h b/src/northbridge/amd/amdmct/mct/mct_d.h index 75c4d6278e..d13143d979 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.h +++ b/src/northbridge/amd/amdmct/mct/mct_d.h @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2015 Timothy Pearson , Raptor Engineering + * Copyright (C) 2015-2017 Timothy Pearson , Raptor Engineering * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -296,6 +296,34 @@ struct MCTStatStruc { Local DCT Status structure (a structure for each DCT) ===============================================================================*/ +struct DCTPersistentStatStruc { + u8 CH_D_DIR_B_DQS[2][4][2][9]; /* [A/B] [DIMM1-4] [R/W] [DQS] */ + /* CHA DIMM0 Byte 0 - 7 and Check Write DQS Delay*/ + /* CHA DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ + /* CHA DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ + /* CHA DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ + /* CHB DIMM0 Byte 0 - 7 and Check Write DQS Delay*/ + /* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ + /* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ + /* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ + u8 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */ + /* CHA DIMM 0 Receiver Enable Delay*/ + /* CHA DIMM 1 Receiver Enable Delay*/ + /* CHA DIMM 2 Receiver Enable Delay*/ + /* CHA DIMM 3 Receiver Enable Delay*/ + + /* CHB DIMM 0 Receiver Enable Delay*/ + /* CHB DIMM 1 Receiver Enable Delay*/ + /* CHB DIMM 2 Receiver Enable Delay*/ + /* CHB DIMM 3 Receiver Enable Delay*/ + u8 CH_D_BC_RCVRDLY[2][4]; + /* CHA DIMM 0 - 4 Check Byte Receiver Enable Delay*/ + /* CHB DIMM 0 - 4 Check Byte Receiver Enable Delay*/ + u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/ + u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/ +} __attribute__((packed)); + + struct DCTStatStruc { /* A per Node structure*/ /* DCTStatStruct_F - start */ u8 Node_ID; /* Node ID of current controller*/ @@ -445,8 +473,6 @@ struct DCTStatStruc { /* A per Node structure*/ /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/ /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/ uint64_t LogicalCPUID; /* The logical CPUID of the node*/ - u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/ - u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/ u16 DimmQRPresent; /* QuadRank DIMM present?*/ u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/ u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/ @@ -462,28 +488,6 @@ struct DCTStatStruc { /* A per Node structure*/ u16 CH_MaxRdLat[2]; /* Max Read Latency (ns) for DCT 0*/ /* Max Read Latency (ns) for DCT 1*/ - u8 CH_D_DIR_B_DQS[2][4][2][9]; /* [A/B] [DIMM1-4] [R/W] [DQS] */ - /* CHA DIMM0 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHA DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ - /* CHA DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHA DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ - /* CHB DIMM0 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ - /* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ - u8 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */ - /* CHA DIMM 0 Receiver Enable Delay*/ - /* CHA DIMM 1 Receiver Enable Delay*/ - /* CHA DIMM 2 Receiver Enable Delay*/ - /* CHA DIMM 3 Receiver Enable Delay*/ - - /* CHB DIMM 0 Receiver Enable Delay*/ - /* CHB DIMM 1 Receiver Enable Delay*/ - /* CHB DIMM 2 Receiver Enable Delay*/ - /* CHB DIMM 3 Receiver Enable Delay*/ - u8 CH_D_BC_RCVRDLY[2][4]; - /* CHA DIMM 0 - 4 Check Byte Receiver Enable Delay*/ - /* CHB DIMM 0 - 4 Check Byte Receiver Enable Delay*/ u8 DIMMValidDCT[2]; /* DIMM# in DCT0*/ /* DIMM# in DCT1*/ u8 MaxDCTs; /* Max number of DCTs in system*/ @@ -542,6 +546,9 @@ struct DCTStatStruc { /* A per Node structure*/ char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1]; uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED]; uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED]; + + /* NOTE: This must remain the last entry in this structure */ + struct DCTPersistentStatStruc persistentData; } __attribute__((packed)); /*=============================================================================== diff --git a/src/northbridge/amd/amdmct/mct/mctdqs_d.c b/src/northbridge/amd/amdmct/mct/mctdqs_d.c index ec77c490d7..71400071cf 100644 --- a/src/northbridge/amd/amdmct/mct/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct/mctdqs_d.c @@ -351,7 +351,7 @@ static void TrainDQSRdWrPos_D(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "Channel: %02x\n", Channel); for (Receiver = cs_start; Receiver < (cs_start + 2); Receiver += 2) { printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver); - p = pDCTstat->CH_D_DIR_B_DQS[Channel][Receiver >> 1][Dir]; + p = pDCTstat->persistentData.CH_D_DIR_B_DQS[Channel][Receiver >> 1][Dir]; for (i = 0; i < 8; i++) { val = p[i]; printk(BIOS_DEBUG, "%02x ", val); @@ -583,7 +583,7 @@ void StoreDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, if (pDCTstat->Status & (1 << SB_Over400MHz)) dn = ChipSel>>1; /* if odd or even logical DIMM */ - pDCTstat->CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane] = + pDCTstat->persistentData.CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane] = pDCTstat->DQSDelay; } @@ -606,7 +606,7 @@ static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, dn = ChipSel >> 1; /*if odd or even logical DIMM */ pDCTstat->DQSDelay = - pDCTstat->CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane]; + pDCTstat->persistentData.CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane]; } diff --git a/src/northbridge/amd/amdmct/mct/mctsrc.c b/src/northbridge/amd/amdmct/mct/mctsrc.c index 3b7cff87db..60857f4052 100644 --- a/src/northbridge/amd/amdmct/mct/mctsrc.c +++ b/src/northbridge/amd/amdmct/mct/mctsrc.c @@ -476,7 +476,7 @@ static void dqsTrainRcvrEn_SW(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "Channel: %02x\n", Channel); for (Receiver = 0; Receiver < 8; Receiver+=2) { printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver); - p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; for (i = 0; i < 8; i++) { val = p[i]; printk(BIOS_DEBUG, "%02x ", val); @@ -567,7 +567,7 @@ void mct_SetRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u8 RcvrEnDly, for (i = 0; i < 8; i++) { if (FinalValue) { /*calculate dimm offset */ - p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver >> 1]; RcvrEnDly = p[i]; } @@ -719,11 +719,11 @@ static u8 mct_SavePassRcvEnDly_D(struct DCTStatStruc *pDCTstat, /* find desired stack offset according to channel/dimm/byte */ if (Pass == SecondPass) { - // FIXME: SecondPass is never used for Barcelona p = pDCTstat->CH_D_B_RCVRDLY_1[Channel][receiver>>1]; + // FIXME: SecondPass is never used for Barcelona p = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][receiver>>1]; p = 0; // Keep the compiler happy. } else { mask_Saved &= mask_Pass; - p = pDCTstat->CH_D_B_RCVRDLY[Channel][receiver>>1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][receiver>>1]; } for (i = 0; i < 8; i++) { /* cmp per byte lane */ @@ -903,7 +903,7 @@ void SetEccDQSRcvrEn_D(struct DCTStatStruc *pDCTstat, u8 Channel) dev = pDCTstat->dev_dct; index_reg = 0x98 + Channel * 0x100; index = 0x12; - p = pDCTstat->CH_D_BC_RCVRDLY[Channel]; + p = pDCTstat->persistentData.CH_D_BC_RCVRDLY[Channel]; print_debug_dqs("\t\tSetEccDQSRcvrPos: Channel ", Channel, 2); for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) { val = p[ChipSel>>1]; @@ -929,7 +929,7 @@ static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) { if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, ChipSel)) { u8 *p; - p = pDCTstat->CH_D_B_RCVRDLY[Channel][ChipSel>>1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][ChipSel>>1]; /* DQS Delay Value of Data Bytelane * most like ECC byte lane */ @@ -953,7 +953,7 @@ static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, val += val0; } - pDCTstat->CH_D_BC_RCVRDLY[Channel][ChipSel>>1] = val; + pDCTstat->persistentData.CH_D_BC_RCVRDLY[Channel][ChipSel>>1] = val; } } SetEccDQSRcvrEn_D(pDCTstat, Channel); diff --git a/src/northbridge/amd/amdmct/mct/mctsrc1p.c b/src/northbridge/amd/amdmct/mct/mctsrc1p.c index 31a3a5d21f..8ae60253ab 100644 --- a/src/northbridge/amd/amdmct/mct/mctsrc1p.c +++ b/src/northbridge/amd/amdmct/mct/mctsrc1p.c @@ -49,7 +49,7 @@ static u8 mct_Average_RcvrEnDly_1Pass(struct DCTStatStruc *pDCTstat, u8 Channel, u8 val; MaxValue = 0; - p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver >> 1]; for (i = 0; i < 8; i++) { /* get left value from DCTStatStruc.CHA_D0_B0_RCVRDLY*/ diff --git a/src/northbridge/amd/amdmct/mct/mctsrc2p.c b/src/northbridge/amd/amdmct/mct/mctsrc2p.c index 7454f5390a..ab278e9199 100644 --- a/src/northbridge/amd/amdmct/mct/mctsrc2p.c +++ b/src/northbridge/amd/amdmct/mct/mctsrc2p.c @@ -57,7 +57,7 @@ u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, u8 max = 0; u8 val; u8 i; - u8 *p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1]; + u8 *p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; u8 bn; bn = 8; @@ -91,12 +91,12 @@ u8 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, bn = 8; - p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; if (Pass == SecondPass) { /* second pass must average values */ //FIXME: which byte? p_1 = pDCTstat->B_RCVRDLY_1; -// p_1 = pDCTstat->CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; +// p_1 = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; for (i = 0; i < bn; i++) { val = p[i]; /* left edge */ diff --git a/src/northbridge/amd/amdmct/mct/mcttmrl.c b/src/northbridge/amd/amdmct/mct/mcttmrl.c index 67397fc83a..4c6d8e6fee 100644 --- a/src/northbridge/amd/amdmct/mct/mcttmrl.c +++ b/src/northbridge/amd/amdmct/mct/mcttmrl.c @@ -297,7 +297,7 @@ static u32 GetMaxRdLatTestAddr_D(struct MCTStatStruc *pMCTstat, for (d = 0; d < 4; d++) { for (Byte = 0; Byte < bn; Byte++) { u8 tmp; - tmp = pDCTstat->CH_D_B_RCVRDLY[ch][d][Byte]; + tmp = pDCTstat->persistentData.CH_D_B_RCVRDLY[ch][d][Byte]; if (tmp > Max) { Max = tmp; Channel_Max = Channel; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index d1d6e8f455..45b987bd61 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2015-2016 Raptor Engineering, LLC + * Copyright (C) 2015-2017 Raptor Engineering, LLC * Copyright (C) 2010 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -3732,7 +3732,7 @@ static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, 2); /* Pass Second Pass ? */ /* Restore Write levelization training data */ for (ByteLane = 0; ByteLane < 9; ByteLane ++) { - txdqs = pDCTstat->CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane]; + txdqs = pDCTstat->persistentData.CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane]; index = Table_DQSRcvEn_Offset[ByteLane >> 1]; index += (Receiver >> 1) * 3 + 0x10 + 0x20; /* Addl_Index */ val = Get_NB32_index_wait_DCT(dev, Channel, 0x98, index); @@ -7373,23 +7373,13 @@ static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, { uint8_t Node; struct DCTStatStruc *pDCTstat; - uint16_t host_serv1, host_serv2; - uint8_t CH_D_B_TxDqs_bkp[2][4][9]; /* Initialize Data structures by clearing all entries to 0 */ - memset(pMCTstat, 0, sizeof(struct MCTStatStruc)); + memset(pMCTstat, 0, sizeof(*pMCTstat)); for (Node = 0; Node < 8; Node++) { pDCTstat = pDCTstatA + Node; - host_serv1 = pDCTstat->HostBiosSrvc1; - host_serv2 = pDCTstat->HostBiosSrvc2; - memcpy(CH_D_B_TxDqs_bkp, pDCTstat->CH_D_B_TxDqs, sizeof(CH_D_B_TxDqs_bkp)); - - memset(pDCTstat, 0, sizeof(struct DCTStatStruc)); - - pDCTstat->HostBiosSrvc1 = host_serv1; - pDCTstat->HostBiosSrvc2 = host_serv2; - memcpy(pDCTstat->CH_D_B_TxDqs, CH_D_B_TxDqs_bkp, sizeof(pDCTstat->CH_D_B_TxDqs)); + memset(pDCTstat, 0, sizeof(*pDCTstat) - sizeof(pDCTstat->persistentData)); } } diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h index 575a9d61bf..d4b37921c4 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2015-2016 Raptor Engineering, LLC + * Copyright (C) 2015-2017 Raptor Engineering, LLC * Copyright (C) 2010 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -335,6 +335,20 @@ struct amd_spd_node_data { uint8_t nvram_memclk[2]; /* [channel] */ } __attribute__((packed, aligned(4))); +struct DCTPersistentStatStruc { + u8 CH_D_B_TxDqs[2][4][9]; /* [A/B] [DIMM1-4] [DQS] */ + /* CHA DIMM0 Byte 0 - 7 TxDqs */ + /* CHA DIMM0 Byte 0 - 7 TxDqs */ + /* CHA DIMM1 Byte 0 - 7 TxDqs */ + /* CHA DIMM1 Byte 0 - 7 TxDqs */ + /* CHB DIMM0 Byte 0 - 7 TxDqs */ + /* CHB DIMM0 Byte 0 - 7 TxDqs */ + /* CHB DIMM1 Byte 0 - 7 TxDqs */ + /* CHB DIMM1 Byte 0 - 7 TxDqs */ + u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/ + u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/ +} __attribute__((packed, aligned(4))); + struct DCTStatStruc { /* A per Node structure*/ /* DCTStatStruct_F - start */ u8 Node_ID; /* Node ID of current controller */ @@ -485,8 +499,6 @@ struct DCTStatStruc { /* A per Node structure*/ /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/ /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/ uint64_t LogicalCPUID; /* The logical CPUID of the node*/ - u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/ - u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/ u16 DimmQRPresent; /* QuadRank DIMM present?*/ u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/ u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/ @@ -513,15 +525,6 @@ struct DCTStatStruc { /* A per Node structure*/ /* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ /* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ /* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ - u8 CH_D_B_TxDqs[2][4][9]; /* [A/B] [DIMM1-4] [DQS] */ - /* CHA DIMM0 Byte 0 - 7 TxDqs */ - /* CHA DIMM0 Byte 0 - 7 TxDqs */ - /* CHA DIMM1 Byte 0 - 7 TxDqs */ - /* CHA DIMM1 Byte 0 - 7 TxDqs */ - /* CHB DIMM0 Byte 0 - 7 TxDqs */ - /* CHB DIMM0 Byte 0 - 7 TxDqs */ - /* CHB DIMM1 Byte 0 - 7 TxDqs */ - /* CHB DIMM1 Byte 0 - 7 TxDqs */ u16 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */ /* CHA DIMM 0 Receiver Enable Delay*/ /* CHA DIMM 1 Receiver Enable Delay*/ @@ -635,6 +638,9 @@ struct DCTStatStruc { /* A per Node structure*/ uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED]; struct amd_spd_node_data spd_data; + + /* NOTE: This must remain the last entry in this structure */ + struct DCTPersistentStatStruc persistentData; } __attribute__((packed, aligned(4))); struct amd_s3_persistent_mct_channel_data { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c index 69b0104973..bd82a014c6 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c @@ -2301,7 +2301,7 @@ static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat, val = Get_NB32_index_wait_DCT(dev, pDCTstat->Channel, index_reg, index); if (ByteLane < 8) { if (pDCTstat->Direction == DQS_WRITEDIR) { - dqs_delay += pDCTstat->CH_D_B_TxDqs[pDCTstat->Channel][ChipSel>>1][ByteLane]; + dqs_delay += pDCTstat->persistentData.CH_D_B_TxDqs[pDCTstat->Channel][ChipSel>>1][ByteLane]; } else { dqs_delay <<= 1; } diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c index 4c6776dcf9..4fe5ad3d63 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c @@ -66,7 +66,7 @@ static void SetEccWrDQS_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pD if (OddByte) val >>= 16; /* Save WrDqs to stack for later usage */ - pDCTstat->CH_D_B_TxDqs[Channel][DimmNum][ByteLane] = val & 0xFF; + pDCTstat->persistentData.CH_D_B_TxDqs[Channel][DimmNum][ByteLane] = val & 0xFF; EccDQSScale = pDCTstat->CH_EccDQSScale[Channel]; word = pDCTstat->CH_EccDQSLike[Channel]; if ((word & 0xFF) == ByteLane) EccRef1 = val & 0xFF; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c index 7f678248c3..8eeb93ff78 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c @@ -54,7 +54,7 @@ u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, u8 max = 0; u8 val; u8 i; - u8 *p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1]; + u8 *p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; u8 bn; bn = 8; @@ -85,12 +85,12 @@ u16 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, bn = 8; - p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1]; + p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; if (Pass == SecondPass) { /* second pass must average values */ /* FIXME: which byte? */ p_1 = pDCTstat->B_RCVRDLY_1; - /* p_1 = pDCTstat->CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; */ + /* p_1 = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; */ for (i = 0; i < bn; i++) { val = p[i]; /* left edge */ -- cgit v1.2.3