diff options
Diffstat (limited to 'src/usr/vpd/rtvpd_load.C')
-rw-r--r-- | src/usr/vpd/rtvpd_load.C | 103 |
1 files changed, 79 insertions, 24 deletions
diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C index dbe31f79f..837d9477b 100644 --- a/src/usr/vpd/rtvpd_load.C +++ b/src/usr/vpd/rtvpd_load.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* [+] 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. */ @@ -101,46 +103,99 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & o_vpd_addr) { errlHndl_t err = NULL; - uint64_t vpd_addr = TARGETING::get_top_mem_addr(); - - assert (vpd_addr != 0, - "bld_devtree: Top of memory was 0!"); - - vpd_addr -= VMM_RT_VPD_OFFSET; + do + { + uint64_t vpd_addr = TARGETING::get_top_mem_addr(); - o_vpd_addr = vpd_addr; + assert (vpd_addr != 0, + "bld_devtree: Top of memory was 0!"); - uint8_t * vpd_ptr = reinterpret_cast<uint8_t*>(vpd_addr); + vpd_addr -= VMM_RT_VPD_OFFSET; - void * vptr = mm_block_map(vpd_ptr, VMM_RT_VPD_SIZE); + o_vpd_addr = vpd_addr; - assert(vptr != NULL,"bld_devtree: Could not map VPD memory"); + uint8_t * vpd_ptr = reinterpret_cast<uint8_t*>(vpd_addr); - vpd_ptr = static_cast<uint8_t*>(vptr); + void * vptr = mm_block_map(vpd_ptr, VMM_RT_VPD_SIZE); - err = bld_vpd_image(PNOR::DIMM_JEDEC_VPD, - vpd_ptr, - VMM_DIMM_JEDEC_VPD_SIZE); + assert(vptr != NULL,"bld_devtree: Could not map VPD memory"); - vpd_ptr += VMM_DIMM_JEDEC_VPD_SIZE; + vpd_ptr = static_cast<uint8_t*>(vptr); + err = bld_vpd_image(PNOR::DIMM_JEDEC_VPD, + vpd_ptr, + VMM_DIMM_JEDEC_VPD_SIZE); + if(err) + { + break; + } - if(!err) - { + vpd_ptr += VMM_DIMM_JEDEC_VPD_SIZE; err = bld_vpd_image(PNOR::MODULE_VPD, vpd_ptr, VMM_MODULE_VPD_SIZE); + if(err) + { + break; + } vpd_ptr += VMM_MODULE_VPD_SIZE; - } - - if(!err) - { err = bld_vpd_image(PNOR::CENTAUR_VPD, vpd_ptr, VMM_CENTAUR_VPD_SIZE); - } + if(err) + { + break; + } + + mm_block_unmap(vptr); + + // In manufacturing mode the VPD PNOR cache needs to be cleared + // And the VPD ATTR switch and flags need to be reset + // Note: this code should do nothing when not in PNOR caching mode + TARGETING::Target* l_pTopLevel = NULL; + TARGETING::targetService().getTopLevelTarget(l_pTopLevel); + TARGETING::ATTR_MNFG_FLAGS_type l_mnfgFlags = + l_pTopLevel->getAttr<TARGETING::ATTR_MNFG_FLAGS>(); + + // @todo RTC 118752 Use generic mfg-mode attr when available + if (l_mnfgFlags & TARGETING::MNFG_FLAG_SRC_TERM) + { + // Reset the PNOR config flags to HW - MVPD/CVPD/SPD + // Checks for PNOR caching mode before reset + VPD::setVpdConfigFlagsHW(); + if (err) + { + break; + } + + // Find all the targets with VPD switches + for (TARGETING::TargetIterator target = + TARGETING::targetService().begin(); + target != TARGETING::targetService().end(); + ++target) + { + TARGETING::ATTR_VPD_SWITCHES_type l_switch; + if(target->tryGetAttr<TARGETING::ATTR_VPD_SWITCHES>(l_switch)) + { + if (l_switch.pnorCacheValid) + { + // Invalidate the VPD PNOR for this target + // This also clears the VPD ATTR switch + err = VPD::invalidatePnorCache(*target); + if (err) + { + break; + } + } + } + } + if (err) + { + break; + } + } - mm_block_unmap(vptr); + } while( 0 ); return err; } |