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_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 +++--- 5 files changed, 27 insertions(+), 31 deletions(-) (limited to 'src/northbridge/amd/amdmct/mct_ddr3') 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