diff options
Diffstat (limited to 'src/usr/targeting')
| -rw-r--r-- | src/usr/targeting/attrPlatOverride.C | 171 | ||||
| -rw-r--r-- | src/usr/targeting/common/attributeTank.C | 124 | ||||
| -rw-r--r-- | src/usr/targeting/common/target.C | 5 | ||||
| -rw-r--r-- | src/usr/targeting/makefile | 6 | ||||
| -rw-r--r-- | src/usr/targeting/test/testattrtank.H | 224 |
5 files changed, 524 insertions, 6 deletions
diff --git a/src/usr/targeting/attrPlatOverride.C b/src/usr/targeting/attrPlatOverride.C new file mode 100644 index 000000000..7f67ab221 --- /dev/null +++ b/src/usr/targeting/attrPlatOverride.C @@ -0,0 +1,171 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/attrPlatOverride.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include <targeting/attrPlatOverride.H> +#include <hwpf/plat/fapiPlatAttrOverrideSync.H> +#include <targeting/common/trace.H> +#include <targeting/common/targreasoncodes.H> + +namespace TARGETING +{ + +errlHndl_t getAttrOverrides(PNOR::SectionId i_section, + AttributeTank* io_tanks[AttributeTank::TANK_LAYER_LAST], + uint32_t pnorSecOffset) +{ + TRACFCOMP(g_trac_targeting,"attrPlatOverride::getAttrOverrides ENTER"); + + // Create local permanent override tank and array of tanks + AttributeTank l_PermTank; + AttributeTank* l_overTanks[AttributeTank::TANK_LAYER_LAST]; + errlHndl_t l_err = NULL; + + // Local pointer to array containing each tank layer or io_tanks + AttributeTank* *l_pOverTanks; + + // If no attribute tanks specified grab all TankLayers to create attribute + // tanks with in enum order + if (io_tanks == NULL) + { + // All indexes are -1 due to the first enum being TANK_LAYER_NONE, + l_overTanks[AttributeTank::TANK_LAYER_FAPI-1] = + &fapi::theAttrOverrideSync().iv_overrideTank; + l_overTanks[AttributeTank::TANK_LAYER_TARG-1] = + &Target::theTargOverrideAttrTank(); + l_overTanks[AttributeTank::TANK_LAYER_PERM-1] = &l_PermTank; + l_pOverTanks = l_overTanks; + } + else + { + l_pOverTanks = io_tanks; + } + + do + { + // Read PNOR section + PNOR::SectionInfo_t sectionInfo; + l_err = PNOR::getSectionInfo( i_section, sectionInfo ); + // Attr override sections are optional so just delete error and break + if (l_err) + { + delete l_err; + l_err = NULL; + break; + } + + uint32_t l_index = pnorSecOffset; + // Deserialize each section + while (l_index < sectionInfo.size) + { + AttrOverrideSection * l_pAttrOverSec = + reinterpret_cast<AttrOverrideSection *> + (sectionInfo.vaddr + l_index); + + // Reached termination chunck + if (l_pAttrOverSec->iv_layer == AttributeTank::TANK_LAYER_NONE) + { + TRACFCOMP(g_trac_targeting,"attrPlatOverride::getAttrOverrides Reached termination section at chunk (0x%x)", + (sectionInfo.size - l_index)); + break; + } + + // Remaining chunk smaller than AttrOverrideSection, quit + if (sizeof(AttrOverrideSection) > (sectionInfo.size - l_index)) + { + TRACFCOMP(g_trac_targeting,"attrPlatOverride::getAttrOverrides AttrOverrideSection too big for chunk (0x%x)", + (sectionInfo.size - l_index)); + /*@ + * @errortype + * @moduleid TARG_GET_ATTR_OVER + * @reasoncode TARG_RC_ATTR_OVER_PNOR_SEC_SPACE_FAIL + * @userdata1 PNOR Section specified + * @userdata2 Size of AttrOverrideSection + * @devdesc AttrOverrideSection too big to fit in remaining + * chunck of pnor section + */ + l_err = + new ERRORLOG::ErrlEntry + (ERRORLOG::ERRL_SEV_PREDICTIVE, + TARG_GET_ATTR_OVER, + TARG_RC_ATTR_OVER_PNOR_SEC_SPACE_FAIL, + i_section, + sizeof(AttrOverrideSection), + true /*SW callout*/); + break; + } + + l_index += sizeof(AttrOverrideSection); + + // Remaining chunk smaller than serialized chunk size, quit + if (l_pAttrOverSec->iv_size > (sectionInfo.size - l_index)) + { + TRACFCOMP(g_trac_targeting,"attrPlatOverride::getAttrOverrides serialized chunk too big for chunk (0x%x)", + (sectionInfo.size - l_index)); + /*@ + * @errortype + * @moduleid TARG_GET_ATTR_OVER + * @reasoncode TARG_RC_ATTR_OVER_ATTR_DATA_SIZE_FAIL + * @userdata1 PNOR Section specified + * @userdata2 Size of Serialized attribute override + * @devdesc Serialized attribute override chunk too big to + * fit in remaining chunck of pnor section + */ + l_err = + new ERRORLOG::ErrlEntry + (ERRORLOG::ERRL_SEV_PREDICTIVE, + TARG_GET_ATTR_OVER, + TARG_RC_ATTR_OVER_ATTR_DATA_SIZE_FAIL, + i_section, + l_pAttrOverSec->iv_size, + true /*SW callout*/); + break; + } + + // Get the AttributeTank that corresponds to the TankLayer in the + // AttrOverrideSection. Enum starts with TANK_LAYER_NONE so need to + // substract 1 + AttributeTank* l_ptank = l_pOverTanks[l_pAttrOverSec->iv_layer - 1]; + + // Create serialized chunck with AttrOverrideSection data + AttributeTank::AttributeSerializedChunk l_chunk; + l_chunk.iv_size = l_pAttrOverSec->iv_size; + l_chunk.iv_pAttributes = &l_pAttrOverSec->iv_chunk[0]; + + // Deserialize the data with the approriate AttributeTank + l_ptank->deserializeAttributes(l_chunk); + l_index += l_pAttrOverSec->iv_size; + } + + // Write permanent attribute overrides + l_err = l_PermTank.writePermAttributes(); + + } while(0); + + TRACFCOMP(g_trac_targeting,"attrPlatOverride::getAttrOverrides EXIT"); + return l_err; +} + +} // end of namespace + + diff --git a/src/usr/targeting/common/attributeTank.C b/src/usr/targeting/common/attributeTank.C index 76e330e69..0ec8fd761 100644 --- a/src/usr/targeting/common/attributeTank.C +++ b/src/usr/targeting/common/attributeTank.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -29,6 +31,15 @@ #include <string.h> #include <targeting/common/attributeTank.H> #include <targeting/common/trace.H> +#include <targeting/common/predicates/predicatepostfixexpr.H> +#include <targeting/common/predicates/predicatectm.H> +#include <targeting/common/predicates/predicateattrtanktargetpos.H> +#include <targeting/common/iterators/rangefilter.H> +#include <targeting/common/targetservice.H> +#include <targeting/targplatutil.H> +#include <targeting/common/targreasoncodes.H> + + namespace TARGETING { @@ -277,7 +288,6 @@ void AttributeTank::serializeAttributes( uint32_t l_index = 0; AttributesCItr_t l_itr = iv_attributes.begin(); - while (l_itr != iv_attributes.end()) { // Fill up the buffer with as many attributes as possible @@ -467,4 +477,114 @@ AttributeTank::Attribute::~Attribute() iv_pVal = NULL; } +//****************************************************************************** +errlHndl_t AttributeTank::writePermAttributes() +{ + errlHndl_t l_err = NULL; + + for(AttributesCItr_t l_attrIter = iv_attributes.begin(); + l_attrIter != iv_attributes.end(); ++l_attrIter) + { + Attribute* l_attr = *l_attrIter; + AttributeHeader l_attrHdr = l_attr->iv_hdr; + PredicatePostfixExpr l_permAttrOverrides; + + // Predicate to match target type + PredicateCTM l_targetTypeFilter + (CLASS_NA, static_cast<TYPE>(l_attrHdr.iv_targetType)); + + // Predicate to match attribute tank target position + PredicateAttrTankTargetPos l_targetPosFilter(l_attrHdr.iv_pos, + l_attrHdr.iv_unitPos, + l_attrHdr.iv_node); + + l_permAttrOverrides.push(&l_targetTypeFilter) + .push(&l_targetPosFilter).And(); + + // Apply the filter through all targets + TargetRangeFilter l_permTargetList( targetService().begin(), + targetService().end(), + &l_permAttrOverrides); + + // Write permanent attributes to target + for ( ; l_permTargetList; ++l_permTargetList) + { + bool l_success = (*l_permTargetList)->_trySetAttr( + static_cast<ATTRIBUTE_ID>(l_attrHdr.iv_attrId), + l_attrHdr.iv_valSize, + l_attr->iv_pVal ); + + if (l_success) + { + TRACFCOMP(g_trac_targeting, "writePermAttributes: Successful permanent override of Attr ID:0x%X Value:0x%lX applied to target 0x%X", + l_attrHdr.iv_attrId, + *reinterpret_cast<uint64_t *>(l_attr->iv_pVal), + (*l_permTargetList)->getAttr<ATTR_HUID>() ); + } + else + { + uint8_t * io_pAttrData = NULL; + bool l_found = (*l_permTargetList)->_tryGetAttr( + static_cast<ATTRIBUTE_ID>(l_attrHdr.iv_attrId), + l_attrHdr.iv_valSize, + io_pAttrData); + + if (l_found) + { + TRACFCOMP(g_trac_targeting, "writePermAttributes: Value NOT applied to target, override failed for Attr ID:0x%X Value:0x%lX on target 0x%X - current value 0x%lX", + l_attrHdr.iv_attrId, + *reinterpret_cast<uint64_t *>(l_attr->iv_pVal), + (*l_permTargetList)->getAttr<ATTR_HUID>(), + *reinterpret_cast<uint64_t *>(io_pAttrData) ); + /*@ + * @errortype + * @moduleid TARG_WRITE_PERM_ATTR + * @reasoncode TARG_RC_WRITE_PERM_ATTR_FAIL + * @userdata1 Target specified + * @userdata2 Attribute specified + * @devdesc Failure applying given attribute override + * on given target + */ + UTIL::createTracingError( + TARG_WRITE_PERM_ATTR, + TARG_RC_WRITE_PERM_ATTR_FAIL, + (*l_permTargetList)->getAttr<ATTR_HUID>(), + l_attrHdr.iv_attrId, + 0,0, + l_err); + break; + } + else + { + TRACFCOMP(g_trac_targeting, "writePermAttributes: Target does not have attribute, override NOT applied for Attr ID:0x%X on target 0x%X", + l_attrHdr.iv_attrId, + (*l_permTargetList)->getAttr<ATTR_HUID>() ); + /*@ + * @errortype + * @moduleid TARG_WRITE_PERM_ATTR + * @reasoncode TARG_RC_WRITE_PERM_ATTR_TARGET_FAIL + * @userdata1 Target specified + * @userdata2 Attribute specified + * @devdesc Given target does not have given attribute + * to apply override + */ + UTIL::createTracingError( + TARG_WRITE_PERM_ATTR, + TARG_RC_WRITE_PERM_ATTR_TARGET_FAIL, + (*l_permTargetList)->getAttr<ATTR_HUID>(), + l_attrHdr.iv_attrId, + 0,0, + l_err); + break; + } + } + } + if (l_err) + { + break; + } + } + return l_err; +} + } diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 9b011e988..ea79a22a3 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -44,6 +46,7 @@ #include <targeting/common/trace.H> #include <targeting/common/predicates/predicateattrval.H> #include <targeting/common/utilFilter.H> +#include <targeting/common/attributeTank.H> namespace TARGETING { diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile index e0180bc35..36b1d98a1 100644 --- a/src/usr/targeting/makefile +++ b/src/usr/targeting/makefile @@ -5,7 +5,9 @@ # # OpenPOWER HostBoot Project # -# COPYRIGHT International Business Machines Corp. 2011,2014 +# Contributors Listed Below - COPYRIGHT 2011,2014 +# [+] International Business Machines Corp. +# # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -37,6 +39,8 @@ include ${TARGETING_REL_PATH}/hostboot_common.mk ATTR_RP_OBJS += attrrp.o ATTR_RP_OBJS += attrsync.o ATTR_RP_OBJS += targplatutil.o +ATTR_RP_OBJS += attrPlatOverride.o +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi ENTRY_POINT_OBJS += targetservicestart.o diff --git a/src/usr/targeting/test/testattrtank.H b/src/usr/targeting/test/testattrtank.H index fc84fab28..5a7cb8cc7 100644 --- a/src/usr/targeting/test/testattrtank.H +++ b/src/usr/targeting/test/testattrtank.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -32,6 +34,8 @@ #include <cxxtest/TestSuite.H> #include <targeting/common/attributeTank.H> +#include <targeting/attrPlatOverride.H> +#include <pnor/pnorif.H> using namespace TARGETING; @@ -132,7 +136,7 @@ public: TS_FAIL("tankTest2: Error. Attribute not in tank (2)"); break; } - + if (l_tank.attributeExists(1)) { TS_FAIL("tankTest2: Error. Wrong attribute in tank (3)"); @@ -1142,6 +1146,222 @@ public: TS_TRACE("tankTest7 complete" ); } + + /** + * @brief Test BMC Attr Override function + * Set attributes into 3 different tanks for attribute override and + * serialize the data of each tank. Then call getAttrOverrides to + * deserialize each sections data and check that the data is correct + * + */ + void testBMCAttrOverride(void) + { + do + { + errlHndl_t errhdl = NULL; + // Use the TEST partition as scratch space + PNOR::SectionInfo_t info; + errhdl = PNOR::getSectionInfo( PNOR::TEST, info ); + if (errhdl) + { + TS_FAIL("testattrtank::testBMCAttrOverride could not get PNOR test section info"); + break; + } + + // Create local AttributeTanks + AttributeTank l_FapiTank; + AttributeTank l_TargetTank; + AttributeTank l_PermTank; + + // Add ATTR_SCRATCH_UINT64_1 to the Fapi tank + uint64_t l_val = 4; + l_FapiTank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + 0, sizeof(l_val), &l_val); + + // Add ATTR_SCRATCH_UINT64_1 to the Target tank + l_TargetTank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + 0, sizeof(l_val), &l_val); + // Add ATTR_SCRATCH_UINT64_1 to the Perm tank + l_PermTank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + 0, sizeof(l_val), &l_val); + + //////////////////////////////////////////////////////////////////// + // Fapi + + // Serialize all attributes from each tank + AttributeTank::AttributeSerializedChunks_t l_attributes; + l_FapiTank.serializeAttributes(AttributeTank::ALLOC_TYPE_NEW, + 4096, l_attributes); + + // Copy Fapi Override chunk to PNOR + uint32_t l_index = PNOR::pnorTestSec_BMCAttrOverride_offset; + for (AttributeTank::AttributeSerializedChunks_t::iterator + chunkIter = l_attributes.begin(); + chunkIter != l_attributes.end(); + ++chunkIter) + { + AttrOverrideSection * l_pAttrOverSec = + reinterpret_cast<AttrOverrideSection *> + (info.vaddr + l_index); + AttributeTank::AttributeSerializedChunk l_chunk = *chunkIter; + l_pAttrOverSec->iv_layer = AttributeTank::TANK_LAYER_FAPI; + l_pAttrOverSec->iv_size = l_chunk.iv_size; + memcpy(&l_pAttrOverSec->iv_chunk, l_chunk.iv_pAttributes, + l_chunk.iv_size); + l_index += sizeof(AttrOverrideSection)+l_pAttrOverSec->iv_size; + } + + //////////////////////////////////////////////////////////////////// + // Targeting + + // Serialize all attributes from each tank + l_attributes.clear(); + l_TargetTank.serializeAttributes(AttributeTank::ALLOC_TYPE_NEW, + 4096, l_attributes); + + // Copy Target Override chunk to PNOR + for (AttributeTank::AttributeSerializedChunks_t::iterator + chunkIter = l_attributes.begin(); + chunkIter != l_attributes.end(); + ++chunkIter) + { + AttrOverrideSection * l_pAttrOverSec = + reinterpret_cast<AttrOverrideSection *> + (info.vaddr + l_index); + AttributeTank::AttributeSerializedChunk l_chunk = *chunkIter; + l_pAttrOverSec->iv_layer = AttributeTank::TANK_LAYER_TARG; + l_pAttrOverSec->iv_size = l_chunk.iv_size; + memcpy(&l_pAttrOverSec->iv_chunk, l_chunk.iv_pAttributes, + l_chunk.iv_size); + l_index += sizeof(AttrOverrideSection)+l_pAttrOverSec->iv_size; + + } + + //////////////////////////////////////////////////////////////////// + // Permanent + + // Serialize all attributes from each tank + l_attributes.clear(); + l_PermTank.serializeAttributes(AttributeTank::ALLOC_TYPE_NEW, + 4096, l_attributes); + + // Copy Target Override chunk to PNOR + for (AttributeTank::AttributeSerializedChunks_t::iterator + chunkIter = l_attributes.begin(); + chunkIter != l_attributes.end(); + ++chunkIter) + { + AttrOverrideSection * l_pAttrOverSec = + reinterpret_cast<AttrOverrideSection *> + (info.vaddr + l_index); + AttributeTank::AttributeSerializedChunk l_chunk = *chunkIter; + l_pAttrOverSec->iv_layer = AttributeTank::TANK_LAYER_PERM; + l_pAttrOverSec->iv_size = l_chunk.iv_size; + memcpy(&l_pAttrOverSec->iv_chunk, l_chunk.iv_pAttributes, + l_chunk.iv_size); + l_index += sizeof(AttrOverrideSection)+l_pAttrOverSec->iv_size; + + } + + // Add termination section + AttrOverrideSection * l_pAttrOverSecTerm = + reinterpret_cast<AttrOverrideSection *> + (info.vaddr + l_index); + l_pAttrOverSecTerm->iv_layer = AttributeTank::TANK_LAYER_NONE; + l_pAttrOverSecTerm->iv_size = 0; + + // Clear tanks + l_FapiTank.clearAllAttributes(); + l_TargetTank.clearAllAttributes(); + l_PermTank.clearAllAttributes(); + + // Call function that actually reads in attribute overrides + AttributeTank* l_tanks[AttributeTank::TANK_LAYER_LAST]; + l_tanks[AttributeTank::TANK_LAYER_FAPI-1] = &l_FapiTank; + l_tanks[AttributeTank::TANK_LAYER_TARG-1] = &l_TargetTank; + l_tanks[AttributeTank::TANK_LAYER_PERM-1] = &l_PermTank; + errhdl = getAttrOverrides(PNOR::TEST, + l_tanks, + PNOR::pnorTestSec_BMCAttrOverride_offset); + if (errhdl) + { + errlCommit(errhdl, TARG_COMP_ID); + TS_FAIL("testattrtank::testBMCAttrOverride getAttrOverrides() failed"); + break; + } + + //////////////////////////////////////////////////////////////////// + // Check the first attribute made it back into the Fapi tank + l_val = 0; + if (!(l_FapiTank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + &l_val))) + { + TS_FAIL("testattrtank::testBMCAttrOverride: Error. Did not get attr from Fapi Tank"); + break; + } + if (l_val != 4) + { + TS_FAIL("testattrtank::testBMCAttrOverride: Error. Got bad value (0x%X) from Fapi Tank", + l_val); + break; + } + + // Check the first attribute made it back into the Target tank + l_val = 0; + if (!(l_TargetTank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + &l_val))) + { + TS_FAIL("testattrtank::testBMCAttrOverride: Error. Did not get attr from Target Tank"); + break; + } + if (l_val != 4) + { + TS_FAIL("testattrtank::testBMCAttrOverride: Error. Got bad value (0x%X) from Target Tank", + l_val); + break; + } + + // Check the first attribute made it back into the Perm tank + l_val = 0; + if (!(l_PermTank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + &l_val))) + { + TS_FAIL("testattrtank::testBMCAttrOverride: Error. Did not get attr from Perm Tank"); + break; + } + if (l_val != 4) + { + TS_FAIL("testattrtank::testBMCAttrOverride: Error. Got bad value (0x%X) from Perm Tank", + l_val); + break; + } + } while(0); + TRACFCOMP(g_trac_targeting, "testattrtank::testBMCAttrOverride: Success steve"); + } }; #endif |

