void Target::_getAttrPtr( const ATTRIBUTE_ID i_attr, void*& o_pAttr) const { #define TARG_FN "_getAttrPtr()" void* l_pAttr = NULL; // Transform platform neutral pointers into platform specific pointers, and // optimize processing by not having to do the conversion in the loop below // (it's guaranteed that attribute metadata will be in the same contiguous // VMM region) ATTRIBUTE_ID* pAttrId = TARG_TO_PLAT_PTR(iv_pAttrNames); AbstractPointer<void>* ppAttrAddr = TARG_TO_PLAT_PTR(iv_pAttrValues); // Only translate addresses on platforms where addresses are 4 bytes wide // (FSP). The compiler should perform dead code elimination of this path on // platforms with 8 byte wide addresses (Hostboot), since the "if" check can // be statically computed at compile time. if(TARG_ADDR_TRANSLATION_REQUIRED) { pAttrId = static_cast<ATTRIBUTE_ID*>( TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(pAttrId, static_cast<const Target*>(this))); ppAttrAddr = static_cast<AbstractPointer<void>*>( TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(ppAttrAddr, static_cast<const Target*>(this))); } if ((pAttrId != NULL) && (ppAttrAddr != NULL)) { // only check for the attribute if we got a valid address from // the translateAddr function // Search for the attribute ID. ATTRIBUTE_ID* ptr = std::lower_bound(pAttrId, pAttrId+iv_attrs, i_attr); if ((ptr != pAttrId+iv_attrs) && (*ptr == i_attr)) { // Locate the corresponding attribute address l_pAttr = TARG_TO_PLAT_PTR(*(ppAttrAddr+std::distance(pAttrId,ptr))); // Only translate addresses on platforms where addresses are // 4 byte wide (FSP). The compiler should perform dead code // elimination this path on platforms with 8 byte wide // addresses (Hostboot), since the "if" check can be statically // computed at compile time. if(TARG_ADDR_TRANSLATION_REQUIRED) { l_pAttr = TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( l_pAttr, static_cast<const Target*>(this)); } } } o_pAttr = l_pAttr; #undef TARG_FN }
void AttrRP::startup(errlHndl_t& io_taskRetErrl) { errlHndl_t l_errl = NULL; do { TargetingHeader* l_header = reinterpret_cast<TargetingHeader*>( g_hostInterfaces->get_reserved_mem("ibm,hbrt-target-image")); if ((NULL == l_header) || (l_header->eyeCatcher != PNOR_TARG_EYE_CATCHER)) { /*@ * @errortype * @moduleid TARG_MOD_ATTRRP_RT * @reasoncode TARG_RC_BAD_EYECATCH * @userdata1 Observed Header Eyecatch Value * @userdata2 Memory address referenced. * * @devdesc The eyecatch value observed in memory does not * match the expected value of * PNOR_TARG_EYE_CATCHER and therefore the * contents of the Attribute sections are * unable to be parsed. * @custdesc A problem occurred during the IPL of the * system. * The eyecatch value observed in memory does not * match the expected value and therefore the * contents of the attribute sections are unable * to be parsed. */ l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, TARG_MOD_ATTRRP_RT, TARG_RC_BAD_EYECATCH, NULL == l_header ? 0 : l_header->eyeCatcher, reinterpret_cast<uint64_t>(l_header)); break; } // Allocate section structures based on section count in header. iv_sectionCount = l_header->numSections; iv_sections = new AttrRP_Section[iv_sectionCount](); // Find start to the first section: // (header address + size of header + offset in header) TargetingSection* l_section = reinterpret_cast<TargetingSection*>( reinterpret_cast<uint64_t>(l_header) + sizeof(TargetingHeader) + l_header->offsetToSections ); uint64_t l_offset = 0; for (size_t i = 0; i < iv_sectionCount; ++i, ++l_section) { iv_sections[i].type = l_section->sectionType; iv_sections[i].size = l_section->sectionSize; iv_sections[i].vmmAddress = static_cast<uint64_t>( TARG_TO_PLAT_PTR(l_header->vmmBaseAddress)) + l_header->vmmSectionOffset*i; iv_sections[i].pnorAddress = reinterpret_cast<uint64_t>(l_header) + l_offset; l_offset += ALIGN_PAGE(iv_sections[i].size); TRACFCOMP(g_trac_targeting, "Decoded Attribute Section: %d, 0x%lx, 0x%lx, 0x%lx", iv_sections[i].type, iv_sections[i].vmmAddress, iv_sections[i].pnorAddress, iv_sections[i].size); } } while(false); if (l_errl) { l_errl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE); } io_taskRetErrl = l_errl; }