summaryrefslogtreecommitdiffstats
path: root/src/usr/targeting/attrrp.C
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2017-03-06 16:36:11 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-04-16 21:32:17 -0400
commit6677ffcbda04c73a7d3ed1e651e3394c8218e503 (patch)
tree2de578165f3517ecd95dd56548a4e5ebdfa4bb8b /src/usr/targeting/attrrp.C
parent6274618ff6a4b0cd8447c1e31940c66b40fa1c42 (diff)
downloadtalos-hostboot-6677ffcbda04c73a7d3ed1e651e3394c8218e503.tar.gz
talos-hostboot-6677ffcbda04c73a7d3ed1e651e3394c8218e503.zip
Propagate attribute overrides up to the HBRT code
Attribute overrides are stored in a separate tank of memory from the regular attribute values. This tank will be added as an additional reserved memory section for HBRT to consume (only if overrides exist). Also fixed a couple bugs encountered while testing: - No longer crashes if an error is created inside the targeting initialization code. - Added reserved bytes to RHB definition. Change-Id: I5b10f7ad8dfcb58c550868bb83c4d843f48e1aae RTC: 169942 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38547 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/targeting/attrrp.C')
-rwxr-xr-xsrc/usr/targeting/attrrp.C152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C
index cc0cc57c1..f67ac831f 100755
--- a/src/usr/targeting/attrrp.C
+++ b/src/usr/targeting/attrrp.C
@@ -43,9 +43,12 @@
#include <targeting/common/targreasoncodes.H>
#include <targeting/attrrp.H>
#include <targeting/common/trace.H>
+#include <targeting/common/attributeTank.H>
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <sys/misc.h>
+#include <fapi2/plat_attr_override_sync.H>
+#include <targeting/attrPlatOverride.H>
using namespace INITSERVICE;
using namespace ERRORLOG;
@@ -651,6 +654,13 @@ namespace TARGETING
} // end maxSize
+ errlHndl_t AttrRP::saveOverrides( uint8_t* i_dest, size_t& io_size )
+ {
+ // Call save on singleton instance.
+ return Singleton<AttrRP>::instance()._saveOverrides(i_dest,io_size);
+ }
+
+
void* AttrRP::_save(uint64_t& io_addr)
{
TRACDCOMP(g_trac_targeting, "AttrRP::save: top @ 0x%lx", io_addr);
@@ -687,4 +697,146 @@ namespace TARGETING
return region;
}
+
+ errlHndl_t AttrRP::_saveOverrides( uint8_t* i_dest, size_t& io_size )
+ {
+ TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::_saveOverrides: i_dest=%p, io_size=%d", i_dest, io_size );
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ size_t l_maxSize = io_size;
+ io_size = 0;
+
+ // Save the fapi and temp overrides
+ // Note: no need to look at PERM because those were added to
+ // the base targeting model
+
+ size_t l_tankSize = l_maxSize;
+ uint8_t* l_dest = i_dest;
+
+ // FAPI
+ l_err = saveOverrideTank( l_dest,
+ l_tankSize,
+ &fapi2::theAttrOverrideSync().iv_overrideTank,
+ AttributeTank::TANK_LAYER_FAPI );
+ if( l_err )
+ {
+ break;
+ }
+ l_maxSize -= l_tankSize;
+ io_size += l_tankSize;
+
+ // TARGETING
+ l_tankSize = l_maxSize;
+ l_dest = i_dest + io_size;
+ l_err = saveOverrideTank( l_dest,
+ l_tankSize,
+ &Target::theTargOverrideAttrTank(),
+ AttributeTank::TANK_LAYER_TARG );
+ if( l_err )
+ {
+ break;
+ }
+ l_maxSize -= l_tankSize;
+ io_size += l_tankSize;
+ } while(0);
+
+ TRACFCOMP( g_trac_targeting, EXIT_MRK"AttrRP::_saveOverrides: io_size=%d, l_err=%.8X", io_size, ERRL_GETRC_SAFE(l_err) );
+ return l_err;
+ }
+
+ errlHndl_t AttrRP::saveOverrideTank( uint8_t* i_dest,
+ size_t& io_size,
+ AttributeTank* i_tank,
+ AttributeTank::TankLayer i_layer )
+ {
+ TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::saveOverrideTank: i_dest=%p, io_size=%d, i_layer=%d", i_dest, io_size, i_layer );
+ errlHndl_t l_err = nullptr;
+ size_t l_maxSize = io_size;
+ io_size = 0;
+
+ // List of chunks we're going to save away
+ std::vector<AttributeTank::AttributeSerializedChunk> l_chunks;
+ i_tank->serializeAttributes(
+ TARGETING::AttributeTank::ALLOC_TYPE_MALLOC,
+ PAGESIZE, l_chunks );
+
+ // Copy each chunk until we run out of space
+ for( auto l_chunk : l_chunks )
+ {
+ // total size of data plus header for this chunk
+ uint32_t l_chunkSize = l_chunk.iv_size;
+ l_chunkSize += sizeof(AttrOverrideSection);
+ // don't want to double-count the data payload...
+ l_chunkSize -= sizeof(AttrOverrideSection::iv_chunk);
+
+ // look for overflow, but only create 1 error
+ if( (l_err == nullptr)
+ && (io_size + l_chunkSize > l_maxSize) )
+ {
+ TRACFCOMP( g_trac_targeting, ERR_MRK"Size of chunk is too big" );
+ /*@
+ * @errortype
+ * @moduleid TARG_MOD_SAVE_OVERRIDE_TANK
+ * @reasoncode TARG_SPACE_OVERRUN
+ * @userdata1[00:31] Maximum Available size
+ * @userdata1[32:63] Required size
+ * @userdata2[00:31] Chunk Size
+ * @userdata2[32:63] Previous Size
+ *
+ * @devdesc Size of override data exceeds available
+ * buffer space
+ *
+ * @custdesc Internal firmware error applying
+ * custom configuration settings
+ */
+ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TARG_CREATE_VMM_SECTIONS,
+ TARG_RC_MM_PERM_FAIL,
+ TWO_UINT32_TO_UINT64(l_maxSize,
+ io_size + l_chunkSize),
+ TWO_UINT32_TO_UINT64(l_chunkSize,
+ io_size),
+ true /*SW Error */);
+ //deliberately not breaking out here so that we can
+ // compute the required size and free the memory in
+ // one place
+ }
+
+ if( l_err == nullptr )
+ {
+ // fill in the header
+ AttrOverrideSection* l_header =
+ reinterpret_cast<AttrOverrideSection*>(i_dest+io_size);
+ l_header->iv_layer = i_layer;
+ l_header->iv_size = l_chunk.iv_size;
+
+ // add the data
+ memcpy( l_header->iv_chunk,
+ l_chunk.iv_pAttributes,
+ l_chunk.iv_size );
+ }
+
+ io_size += l_chunkSize;
+
+ // freeing data that was allocated by serializeAttributes()
+ free( l_chunk.iv_pAttributes );
+ l_chunk.iv_pAttributes = NULL;
+ }
+
+ // add a terminator at the end since the size might get lost
+ // but only if we found some overrides
+ if( (io_size > 0)
+ && (io_size + sizeof(AttributeTank::TankLayer) < l_maxSize) )
+ {
+ AttrOverrideSection* l_term =
+ reinterpret_cast<AttrOverrideSection*>(i_dest+io_size);
+ l_term->iv_layer = AttributeTank::TANK_LAYER_TERM;
+ io_size += sizeof(AttributeTank::TankLayer);
+ }
+
+ TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::saveOverrideTank: io_size=%d", io_size );
+ return l_err;
+ }
};
OpenPOWER on IntegriCloud