diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2012-09-07 15:39:08 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-10-10 14:17:00 -0500 |
commit | 3536e96bd3a1d490cec900617fab6703fb7798ea (patch) | |
tree | de8f6a5988bdb935ba8691fb0747c305c395ccef /src/usr/runtime/populate_attributes.C | |
parent | c093ffb2f52adae60468cfa466e9939ad9026a62 (diff) | |
download | talos-hostboot-3536e96bd3a1d490cec900617fab6703fb7798ea.tar.gz talos-hostboot-3536e96bd3a1d490cec900617fab6703fb7798ea.zip |
Populate Attributes for HostServices
Inside the start payload istep a set of FAPI attributes will
be read and copied into a specified location of mainstore so
that HostServices runtime code can access them.
There are 4 files that will be shared with HostServices code:
- attribute_structs.H : common structures used to define data
- hsvc_sysdata.C : list of required system attributes
- hsvc_procdata.C : list of required proc attributes
- hsvc_exdata.C : list of required ex attributes
RTC: 41242
Change-Id: I3af3b2bf99b4dbedb6efeb2cb35e49ba066a9c19
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1893
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/runtime/populate_attributes.C')
-rw-r--r-- | src/usr/runtime/populate_attributes.C | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/src/usr/runtime/populate_attributes.C b/src/usr/runtime/populate_attributes.C new file mode 100644 index 000000000..ed100dd9b --- /dev/null +++ b/src/usr/runtime/populate_attributes.C @@ -0,0 +1,456 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/runtime/populate_attributes.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ + +/** + * @file populate_attributes.C + * + * @brief Populate attributes for runtime HostServices code + */ + +#include <trace/interface.H> +#include <errl/errlentry.H> +#include <fapi.H> +#include <fapiAttributeIds.H> +#include <targeting/common/target.H> +#include <targeting/common/targetservice.H> +#include <targeting/common/utilFilter.H> +#include <runtime/runtime_reasoncodes.H> +#include "common/hsvc_attribute_structs.H" +//#include <arch/ppc.H> //for MAGIC_INSTRUCTION + +trace_desc_t *g_trac_runtime = NULL; +TRAC_INIT(&g_trac_runtime, "RUNTIME", 4096); + +/** + * @brief Read a FAPI attribute and stick it into mainstore + */ +#define HSVC_LOAD_ATTR(__fid) \ + fapi::__fid##_Type result_##__fid; \ + _rc = FAPI_ATTR_GET( __fid, _target, result_##__fid ); \ + if( _rc ) { \ + TRACFCOMP( g_trac_runtime, "Error reading %d, rc=0x%X", fapi::__fid, _rc ); \ + _failed_attribute = fapi::__fid; \ + break; \ + } \ + TRACFCOMP( g_trac_runtime, "> %d: 0x%x=%X @ %p", *_num_attr, fapi::__fid, result_##__fid, _output_ptr ); \ + _cur_header = &(_all_headers[(*_num_attr)]); \ + _cur_header->id = fapi::__fid; \ + _cur_header->sizeBytes = sizeof(fapi::__fid##_Type); \ + _cur_header->offset = (_output_ptr - _beginning); \ + memcpy( _output_ptr, &result_##__fid, sizeof(fapi::__fid##_Type) ); \ + _output_ptr += sizeof(fapi::__fid##_Type); \ + (*_num_attr)++; + +/** + * @brief Read a Privileged FAPI attribute and stick it into mainstore + */ +#define HSVC_LOAD_ATTR_P(__fid) \ + fapi::__fid##_Type result_##__fid; \ + _rc = FAPI_ATTR_GET_PRIVILEGED( __fid, _target, result_##__fid ); \ + if( _rc ) { \ + TRACFCOMP( g_trac_runtime, "Error reading %d, rc=0x%X", fapi::__fid, _rc ); \ + _failed_attribute = fapi::__fid; \ + break; \ + } \ + TRACFCOMP( g_trac_runtime, "> %d: 0x%x=%X @ %p", *_num_attr, fapi::__fid, result_##__fid, _output_ptr ); \ + _cur_header = &(_all_headers[(*_num_attr)]); \ + _cur_header->id = fapi::__fid; \ + _cur_header->sizeBytes = sizeof(fapi::__fid##_Type); \ + _cur_header->offset = (_output_ptr - _beginning); \ + memcpy( _output_ptr, &result_##__fid, sizeof(fapi::__fid##_Type) ); \ + _output_ptr += sizeof(fapi::__fid##_Type); \ + (*_num_attr)++; + +/** + * @brief Read the HUID attribute from targeting and stick it into mainstore + */ +#define ADD_HUID(__targ) \ + _huid_temp = TARGETING::get_huid(__targ); \ + TRACFCOMP( g_trac_runtime, "> HUID=%.8X @ %p", _huid_temp, _output_ptr ); \ + _cur_header = &(_all_headers[(*_num_attr)]); \ + _cur_header->id = HSVC_HUID; \ + _cur_header->sizeBytes = sizeof(uint32_t); \ + _cur_header->offset = (_output_ptr - _beginning); \ + memcpy( _output_ptr, &_huid_temp, sizeof(uint32_t) ); \ + _output_ptr += sizeof(uint32_t); \ + (*_num_attr)++; + +/** + * @brief Read the PHYS_PATH attribute from targeting and stick it into mainstore + */ +#define ADD_PHYS_PATH(__targ) \ + { TARGETING::AttributeTraits<TARGETING::ATTR_PHYS_PATH>::Type pathPhys; \ + _rc = !(__targ->tryGetAttr<TARGETING::ATTR_PHYS_PATH>(pathPhys)); \ + _cur_header = &(_all_headers[(*_num_attr)]); \ + _cur_header->id = HSVC_PHYS_PATH; \ + _cur_header->sizeBytes = sizeof(uint8_t) + (sizeof(pathPhys[0]) * pathPhys.size()); \ + _cur_header->offset = (_output_ptr - _beginning); \ + memcpy( _output_ptr, &pathPhys, _cur_header->sizeBytes ); \ + _output_ptr += _cur_header->sizeBytes; \ + (*_num_attr)++; } + +/** + * @brief Insert a terminator into the attribute list + */ +#define EMPTY_ATTRIBUTE \ + _cur_header = &(_all_headers[(*_num_attr)]); \ + _cur_header->id = hsvc_attr_header_t::NO_ATTRIBUTE; \ + _cur_header->sizeBytes = 0; \ + _cur_header->offset = 0; + + +namespace RUNTIME +{ + +// This is the data that will be in the 'System Attribute Data' +// section of HDAT +struct system_data_t +{ + enum { + MAX_ATTRIBUTES = 20 + }; + + // header data that HostServices uses + hsvc_system_data_t hsvc; + + // actual data content + hsvc_attr_header_t attrHeaders[MAX_ATTRIBUTES]; + char attributes[MAX_ATTRIBUTES*sizeof(uint32_t)]; +}; + +// This is the data that will be in the 'Node Attribute Data' +// section of HDAT, there will be 1 of these per physical +// drawer/book/octant/blade +struct node_data_t +{ + enum { + MAX_PROCS = 8, + MAX_PROCS_RSV = 16, //leave space for double + MAX_EX_PER_PROC = 16, + MAX_EX_RSV = MAX_PROCS_RSV*MAX_EX_PER_PROC, + NUM_PROC_ATTRIBUTES = 100, + NUM_EX_ATTRIBUTES = 10, + MAX_ATTRIBUTES = MAX_PROCS_RSV*NUM_PROC_ATTRIBUTES + + MAX_PROCS_RSV*MAX_EX_PER_PROC*NUM_EX_ATTRIBUTES + }; + + // header data that HostServices uses + hsvc_node_data_t hsvc; + + // actual data content + hsvc_proc_header_t procs[MAX_PROCS_RSV]; + hsvc_ex_header_t ex[MAX_PROCS_RSV*MAX_EX_PER_PROC]; + hsvc_attr_header_t procAttrHeaders[MAX_PROCS_RSV][NUM_PROC_ATTRIBUTES]; + hsvc_attr_header_t exAttrHeaders[MAX_PROCS_RSV*MAX_EX_PER_PROC][NUM_EX_ATTRIBUTES]; + char attributes[MAX_ATTRIBUTES*sizeof(uint32_t)]; +}; + + +//@fixme RTC:49509 +// Steal the unused fake pnor space until we have mainstore +#define SYSTEM_DATA_POINTER (5*MEGABYTE) +#define NODE_DATA_POINTER (5*MEGABYTE+512*KILOBYTE) + + +/** + * @brief Populate system attributes for HostServices + */ +errlHndl_t populate_system_attributes( void ) +{ + errlHndl_t errhdl = NULL; + + // These variables are used by the HSVC_LOAD_ATTR macros directly + uint64_t _failed_attribute = 0; //attribute we failed on + int _rc = 0; //result from FAPI_ATTR_GET + + do { + TRACFCOMP( g_trac_runtime, "-SYSTEM-" ); + + // allocate memory and fill it with some junk data + system_data_t* sys_data = reinterpret_cast<system_data_t*>(SYSTEM_DATA_POINTER); + memset( sys_data, 'A', sizeof(system_data_t) ); + + // These variables are used by the HSVC_LOAD_ATTR macros directly + uint64_t* _num_attr = NULL; //pointer to numAttr in struct + char* _output_ptr = NULL; //next memory location to copy attr data into + char* _beginning = NULL; //position zero for offset calculation + hsvc_attr_header_t* _all_headers = NULL; //array of attribute headers + fapi::Target* _target = NULL; //target for FAPI_ATTR_GET + hsvc_attr_header_t* _cur_header = NULL; //temp variable + uint32_t _huid_temp = 0; //temp variable + + // Prepare the vars for the HSVC_LOAD_ATTR macros + _beginning = reinterpret_cast<char*>(sys_data); + _output_ptr = sys_data->attributes; + _all_headers = sys_data->attrHeaders; + _num_attr = &(sys_data->hsvc.numAttr); + _target = NULL; //system queries use NULL target + + // Grab a system object to work with + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + + // Fill in the metadata + sys_data->hsvc.offset = reinterpret_cast<uint64_t>(sys_data->attrHeaders) + - reinterpret_cast<uint64_t>(sys_data); + sys_data->hsvc.nodePresent = 0x8000000000000000; + sys_data->hsvc.numAttr = 0; + + // Fill up the attributes + ADD_HUID( sys ); // for debug + ADD_PHYS_PATH( sys ); + // Use a generated file for the list of attributes to load + #include "common/hsvc_sysdata.C" + + // Add an empty attribute header to signal the end + EMPTY_ATTRIBUTE; + + TRACFCOMP( g_trac_runtime, "Run: system_cmp0.memory_ln4->image.save attributes.sys.bin 0x%X %d", sys_data, sizeof(system_data_t) ); + + //@todo - Walk through attribute headers to look for duplicates? + } while(0); + + // Handle any errors from FAPI_ATTR_GET + if( _rc ) + { + /*@ + * @errortype + * @reasoncode RUNTIME::RC_ATTR_GET_FAIL + * @moduleid RUNTIME::MOD_RUNTIME_POP_SYS_ATTR + * @userdata1 Return code from FAPI_ATTR_GET + * @userdata2 FAPI Attribute Id that failed + * @devdesc Error retrieving FAPI attribute + */ + errhdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_RUNTIME_POP_SYS_ATTR, + RUNTIME::RC_ATTR_GET_FAIL, + _rc, + _failed_attribute ); + + } + + return errhdl; +} + +/** + * @brief Populate node attributes for HostServices + */ +errlHndl_t populate_node_attributes( uint64_t i_nodeNum ) +{ + errlHndl_t errhdl = NULL; + + // These variables are used by the HSVC_LOAD_ATTR macros directly + uint64_t _failed_attribute = 0; //attribute we failed on + int _rc = 0; //result from FAPI_ATTR_GET + + do { + TRACFCOMP( g_trac_runtime, "-NODE-" ); + + // allocate memory and fill it with some junk data + node_data_t* node_data = reinterpret_cast<node_data_t*>(NODE_DATA_POINTER); + memset( node_data, 'A', sizeof(node_data) ); + + // These variables are used by the HSVC_LOAD_ATTR macros directly + uint64_t* _num_attr = NULL; //pointer to numAttr in struct + char* _output_ptr = NULL; //next memory location to copy attr data into + char* _beginning = NULL; //position zero for offset calculation + hsvc_attr_header_t* _all_headers = NULL; //array of attribute headers + fapi::Target* _target = NULL; //target for FAPI_ATTR_GET + hsvc_attr_header_t* _cur_header = NULL; //temp variable + uint32_t _huid_temp = 0; //temp variable + + // Prepare the vars for the HSVC_LOAD_ATTR macros + _beginning = reinterpret_cast<char*>(node_data); + _output_ptr = node_data->attributes; + + // indices for ex_header and proc_header + size_t next_proc = 0; + size_t next_ex = 0; + + // Fill in the metadat + node_data->hsvc.numTargets = 0; + node_data->hsvc.procOffset = reinterpret_cast<uint64_t>(node_data->procs) - reinterpret_cast<uint64_t>(node_data); + + // Get the list of processors + TARGETING::TargetHandleList all_procs; + TARGETING::getAllChips( all_procs, TARGETING::TYPE_PROC, false ); + + // Loop around all of the proc chips + for( size_t p = 0; p < all_procs.size(); p++ ) + { + // Cast to a FAPI type of target. + fapi::Target fapi_proc( fapi::TARGET_TYPE_PROC_CHIP, + reinterpret_cast<void *> + (const_cast<TARGETING::Target*>(all_procs[p])) ); + + // Compute the processor id to match what HDAT uses + uint64_t node_id = + all_procs[p]->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>(); + uint64_t chip_id = + all_procs[p]->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>(); + uint32_t procid = (node_id << 3) | (chip_id); //NNNCCC + TRACFCOMP( g_trac_runtime, "PROC:%d (%.8X)", procid, TARGETING::get_huid(all_procs[p]) ); + + // Fill in the metadata + node_data->procs[p].procid = procid; + node_data->procs[p].offset = reinterpret_cast<uint64_t>(&(node_data->procAttrHeaders[p][0])) - reinterpret_cast<uint64_t>(node_data); + node_data->procs[p].numAttr = 0; + (node_data->hsvc.numTargets)++; + + // Prepare the variables for the HSVC_LOAD_ATTR calls + _all_headers = &(node_data->procAttrHeaders[p][0]); + _num_attr = &(node_data->procs[p].numAttr); + _target = &fapi_proc; + + // Fill up the attributes + ADD_HUID( (all_procs[p]) ); // for debug + ADD_PHYS_PATH( (all_procs[p]) ); + // Use a generated file for the list of attributes to load + #include "common/hsvc_procdata.C" + + // Add an empty attribute header to signal the end + EMPTY_ATTRIBUTE; + + + // Loop around all of the EX chiplets for this proc + TARGETING::TargetHandleList all_ex; + TARGETING::getChildChiplets( all_ex, all_procs[p], + TARGETING::TYPE_EX, false ); + for( size_t e = 0; e < all_ex.size(); e++ ) + { + uint32_t chiplet = all_ex[e]->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + TRACFCOMP( g_trac_runtime, "EX:p%d c%d(%.8X)", procid, chiplet, get_huid(all_ex[e]) ); + + // Fill in the metadata + (node_data->hsvc.numTargets)++; + node_data->ex[next_ex].parent_procid = procid; + node_data->ex[next_ex].chiplet = chiplet; + node_data->ex[next_ex].offset = reinterpret_cast<uint64_t>(&(node_data->exAttrHeaders[next_ex][0])) - reinterpret_cast<uint64_t>(node_data); + node_data->hsvc.exOffset = reinterpret_cast<uint64_t>(node_data->ex) - reinterpret_cast<uint64_t>(node_data); + node_data->ex[next_ex].numAttr = 0; + + // Cast to a FAPI type of target. + fapi::Target fapi_ex( fapi::TARGET_TYPE_EX_CHIPLET, + reinterpret_cast<void *> + (const_cast<TARGETING::Target*>(all_ex[e])) ); + + // Prepare the variables for the HSVC_LOAD_ATTR calls + _all_headers = &(node_data->exAttrHeaders[next_ex][0]); + _num_attr = &(node_data->ex[next_ex].numAttr); + _target = &fapi_ex; + + // Fill up the attributes + ADD_HUID( (all_ex[e]) ); // for debug + ADD_PHYS_PATH( (all_ex[e]) ); + // Use a generated file for the list of attributes to load + #include "common/hsvc_exdata.C" + + // Add an empty attribute header to signal the end + EMPTY_ATTRIBUTE; + + next_ex++; + } + + next_proc++; + } + + // Add an empty Proc marker at the end + node_data->procs[next_proc].procid = hsvc_proc_header_t::NO_PROC; + node_data->procs[next_proc].offset = 0; + node_data->procs[next_proc].numAttr = 0; + (node_data->hsvc.numTargets)++; + + // Add an empty EX marker at the end + node_data->ex[next_ex].parent_procid = hsvc_ex_header_t::NO_PROC; + node_data->ex[next_ex].chiplet = hsvc_ex_header_t::NO_CHIPLET; + node_data->ex[next_ex].numAttr = 0; + + TRACFCOMP( g_trac_runtime, "Run: system_cmp0.memory_ln4->image.save attributes.node.bin 0x%X %d", node_data, sizeof(node_data_t) ); + } while(0); + + // Handle any errors from FAPI_ATTR_GET + if( _rc ) + { + /*@ + * @errortype + * @reasoncode RUNTIME::RC_ATTR_GET_FAIL + * @moduleid RUNTIME::MOD_RUNTIME_POP_NODE_ATTR + * @userdata1 Return code from FAPI_ATTR_GET + * @userdata2 FAPI Attribute Id that failed + * @devdesc Error retrieving FAPI attribute + */ + errhdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_RUNTIME_POP_NODE_ATTR, + RUNTIME::RC_ATTR_GET_FAIL, + _rc, + _failed_attribute ); + + } + + return errhdl; +} + +/** + * @brief Populate attributes for HostServices + */ +errlHndl_t populate_attributes( void ) +{ + errlHndl_t errhdl = NULL; + + do { + //@todo : Remove this before RTC:49137 is merged, fix with RTC:49509 + // Skip this in VPO + if( TARGETING::is_vpo() ) + { + TRACFCOMP( g_trac_runtime, "Skipping RUNTIME::populate_attributes in VPO mode" ); + break; + } + + errhdl = populate_system_attributes(); + if( errhdl ) + { + break; + } + + // Loop through all nodes + for( TARGETING::TargetService::iterator it = TARGETING::targetService().begin(); + it != TARGETING::targetService().end(); ++it ) + { + if( (*it)->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_NODE ) + { + //@todo: RTC:50866 : Need an attribute for node position + errhdl = populate_node_attributes(0); + if( errhdl ) + { + break; + } + } + } + + } while(0); + + return errhdl; +} + +} //namespace RUNTIME |