diff options
author | Bill Schwartz <whs@us.ibm.com> | 2013-08-15 16:40:38 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-09-13 12:57:46 -0500 |
commit | fe7854394eb388e40bd94b7b4398003b6ac3b268 (patch) | |
tree | 8dba2bfd9801ff56161a47c954e8784079a6f9f9 /src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C | |
parent | 0b823dd9ef5579112cbbaae770028c75f7d19119 (diff) | |
download | blackbird-hostboot-fe7854394eb388e40bd94b7b4398003b6ac3b268.tar.gz blackbird-hostboot-fe7854394eb388e40bd94b7b4398003b6ac3b268.zip |
VPD Accessor functions for Clock Mapping, DIMM timing and TSYS VPD Attributes
Extend existing CDIMM hwp accessors for MR and MT keywords to add support for
7 new attributes.
Based on vpd level 6.0 with work around driven by vpd version to also support
vpd level 5.3 definition.
FSP change to add cvpd record VINI to PNOR is 897882
Change-Id: I02b3a0ade288c6b75918ad1d99257c5a042fc18d
RTC: 79615
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5805
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C')
-rw-r--r-- | src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C | 146 |
1 files changed, 140 insertions, 6 deletions
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C index 7723d38cf..7e2713e86 100644 --- a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C +++ b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdTermData.C @@ -34,6 +34,7 @@ #include <fapi.H> #include <fapiUtil.H> #include <getMBvpdTermData.H> +#include <getMBvpdPhaseRotatorData.H> extern "C" { @@ -77,6 +78,9 @@ fapi::ReturnCode getMBvpdTermData( mt_keyword * l_pMtBuffer = NULL; // MBvpd MT keyword buffer uint32_t l_MtBufsize = sizeof(mt_keyword); uint32_t l_sizeCheck = 0; //invalid size + // Mask off to isolate vpd offset. MBvpdTermData value is offset into vpd. + // Also protects against indexing out of bounds + uint8_t l_attrOffset = i_attr & TERM_DATA_OFFSET_MASK; FAPI_DBG("getMBvpdTermData: entry attr=0x%02x, size=%d ", i_attr,i_valSize ); @@ -161,6 +165,26 @@ fapi::ReturnCode getMBvpdTermData( l_sizeCheck= sizeof (MBvpdTermDataSize<TERM_DATA_CEN_SLEW_RATE_SPCKE>::Type); break; + case TERM_DATA_CKE_PRI_MAP: + l_sizeCheck= + sizeof (MBvpdTermDataSize<TERM_DATA_CKE_PRI_MAP>::Type); + break; + case TERM_DATA_CKE_PWR_MAP: + l_sizeCheck= + sizeof (MBvpdTermDataSize<TERM_DATA_CKE_PWR_MAP>::Type); + break; + case TERM_DATA_RLO: + l_sizeCheck= + sizeof (MBvpdTermDataSize<TERM_DATA_RLO>::Type); + break; + case TERM_DATA_WLO: + l_sizeCheck= + sizeof (MBvpdTermDataSize<TERM_DATA_WLO>::Type); + break; + case TERM_DATA_GPO: + l_sizeCheck= + sizeof (MBvpdTermDataSize<TERM_DATA_GPO>::Type); + break; default: // Hard to do, but needs to be caught FAPI_ERR("getMBvpdTermData: invalid attribute ID 0x%02x", i_attr); @@ -204,6 +228,75 @@ fapi::ReturnCode getMBvpdTermData( FAPI_DBG("getMBvpdTermData: parent path=%s ", l_mbTarget.toEcmdString() ); + // Check if the old vpd layout is different for this attr + if (TERM_DATA_CHK60 & i_attr) // need to check vpd version for this attr + { + uint16_t l_vpdVersion = 0; + uint32_t l_bufSize = sizeof(l_vpdVersion); + const uint16_t VPD_VERSION_V60=0x3130; // Version 6.0 is ascii "10" + + // get vpd version from record VINI keyword VZ + l_fapirc = fapiGetMBvpdField(fapi::MBVPD_RECORD_VINI, + fapi::MBVPD_KEYWORD_VZ, + l_mbTarget, + reinterpret_cast<uint8_t *>(&l_vpdVersion), + l_bufSize); + if (l_fapirc) + { + FAPI_ERR("getMBvpdTermData: Read of VZ keyword failed"); + break; // break out with fapirc + } + FAPI_DBG("getMBvpdTermData: vpd version=0x%08x", + l_vpdVersion); + + // Check that sufficient size was returned. + if (l_bufSize < sizeof(l_vpdVersion) ) + { + FAPI_ERR("getMBvpdTermData:" + " less keyword data returned than expected %d < %d", + l_bufSize, sizeof(l_vpdVersion)); + const uint32_t & KEYWORD = sizeof(l_vpdVersion); + const uint32_t & RETURNED_SIZE = l_bufSize; + FAPI_SET_HWP_ERROR(l_fapirc,RC_MBVPD_INSUFFICIENT_VPD_RETURNED); + break; // break out with fapirc + } + + // Check if work around needed + if (l_vpdVersion < VPD_VERSION_V60) + { + MBvpdPhaseRotatorData l_phaseRotAttr = PHASE_ROT_INVALID; + + if (TERM_DATA_RLO == i_attr) + { + l_phaseRotAttr = PHASE_ROT_RLO_V53; + } + else if (TERM_DATA_WLO == i_attr) + { + l_phaseRotAttr = PHASE_ROT_WLO_V53; + } + else if (TERM_DATA_GPO == i_attr) + { + l_phaseRotAttr = PHASE_ROT_GPO_V53; + } + else // not expected + { + FAPI_ERR("getMBvpdTermData: invalid attribute ID 0x%02x", + i_attr); + const fapi::MBvpdTermData & ATTR_ID = i_attr; + FAPI_SET_HWP_ERROR(l_fapirc, RC_MBVPD_INVALID_ATTRIBUTE_ID); + break; // break out with fapirc + } + + // Retrieve these attributes from the MR keyword + FAPI_EXEC_HWP(l_fapirc, + getMBvpdPhaseRotatorData, + i_mbaTarget, + l_phaseRotAttr, + *((uint8_t (*)[2])o_pVal)); + break; // break out with Phase Rotator data fapirc + } + } + // Read the MT keyword field l_pMtBuffer = new mt_keyword; @@ -243,7 +336,7 @@ fapi::ReturnCode getMBvpdTermData( for (uint8_t l_j=0; l_j<NUM_DIMMS; l_j++) { (*l_pVal)[l_port][l_j] = l_pMtBuffer-> - mb_mba[l_pos].mba_port[l_port].port_attr[i_attr+l_j]; + mb_mba[l_pos].mba_port[l_port].port_attr[l_attrOffset+l_j]; } } break; @@ -262,7 +355,7 @@ fapi::ReturnCode getMBvpdTermData( for (uint8_t l_k=0; l_k<NUM_RANKS; l_k++) { (*l_pVal)[l_port][l_j][l_k] = l_pMtBuffer-> - mb_mba[l_pos].mba_port[l_port].port_attr[i_attr+(l_j*NUM_RANKS)+l_k]; + mb_mba[l_pos].mba_port[l_port].port_attr[l_attrOffset+(l_j*NUM_RANKS)+l_k]; } } } @@ -272,16 +365,33 @@ fapi::ReturnCode getMBvpdTermData( // need to consider endian since they are word fields case TERM_DATA_CEN_RD_VREF: case TERM_DATA_DRAM_WR_VREF: + case TERM_DATA_CKE_PWR_MAP: { uint32_t (* l_pVal)[2] = (uint32_t (*)[2])o_pVal; for (uint8_t l_port=0; l_port<2;l_port++) { uint32_t * l_pWord = (uint32_t *)&l_pMtBuffer-> - mb_mba[l_pos].mba_port[l_port].port_attr[i_attr]; + mb_mba[l_pos].mba_port[l_port].port_attr[l_attrOffset]; (*l_pVal)[l_port] = FAPI_BE32TOH(*l_pWord); } break; } + // return the uint16_t [2] attributes from the MT keyword buffer + // into the return uint32_t [2] + // need to consider endian since they are word fields + case TERM_DATA_CKE_PRI_MAP: + { + uint32_t (* l_pVal)[2] = (uint32_t (*)[2])o_pVal; + (*l_pVal)[0] = l_pMtBuffer-> + mb_mba[l_pos].mba_port[0].port_attr[l_attrOffset+1]; //LSB + (*l_pVal)[0] |= (l_pMtBuffer-> + mb_mba[l_pos].mba_port[0].port_attr[l_attrOffset]<<8); //MSB + (*l_pVal)[1] = l_pMtBuffer-> + mb_mba[l_pos].mba_port[1].port_attr[l_attrOffset+1]; //LSB + (*l_pVal)[1] |= (l_pMtBuffer-> + mb_mba[l_pos].mba_port[1].port_attr[l_attrOffset]<<8); //MSB + break; + } // return the uint8_t [2] attributes from the MT keyword buffer case TERM_DATA_DRAM_WRDDR4_VREF: case TERM_DATA_CEN_RCV_IMP_DQ_DQS: @@ -295,13 +405,37 @@ fapi::ReturnCode getMBvpdTermData( case TERM_DATA_CEN_SLEW_RATE_ADDR: case TERM_DATA_CEN_SLEW_RATE_CLK: case TERM_DATA_CEN_SLEW_RATE_SPCKE: + case TERM_DATA_RLO: + case TERM_DATA_WLO: + case TERM_DATA_GPO: { uint8_t (* l_pVal)[2] = (uint8_t (*)[2])o_pVal; - for (uint8_t l_port=0; l_port<NUM_PORTS;l_port++) + + // pull data from keyword buffer + uint8_t l_port0 = l_pMtBuffer-> + mb_mba[l_pos].mba_port[0].port_attr[l_attrOffset]; + uint8_t l_port1 = l_pMtBuffer-> + mb_mba[l_pos].mba_port[1].port_attr[l_attrOffset]; + + // isolate special processing flags + uint32_t l_special = i_attr & TERM_DATA_SPECIAL_MASK; + switch (l_special) { - (*l_pVal)[l_port] = l_pMtBuffer-> - mb_mba[l_pos].mba_port[l_port].port_attr[i_attr]; + case TERM_DATA_LOW_NIBBLE: // return low nibble + l_port0 = l_port0 & 0x0F; + l_port1 = l_port1 & 0x0F; + break; + + case TERM_DATA_HIGH_NIBBLE: // return high nibble + l_port0 = ((l_port0 & 0xF0)>>4); + l_port1 = ((l_port1 & 0xF0)>>4); + break; + default: + ; // data is ok directly from keyword buffer } + + (*l_pVal)[0] = l_port0; + (*l_pVal)[1] = l_port1; break; } } |