summaryrefslogtreecommitdiffstats
path: root/src/usr/devtree/bld_devtree.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/devtree/bld_devtree.C')
-rw-r--r--src/usr/devtree/bld_devtree.C2378
1 files changed, 0 insertions, 2378 deletions
diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C
deleted file mode 100644
index 61fc5656b..000000000
--- a/src/usr/devtree/bld_devtree.C
+++ /dev/null
@@ -1,2378 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/devtree/bld_devtree.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
-/* [+] Google Inc. */
-/* [+] 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 <trace/interface.H>
-#include <errl/errlentry.H>
-#include <targeting/common/target.H>
-#include <targeting/common/targetservice.H>
-#include <targeting/common/utilFilter.H>
-#include <targeting/attrrp.H>
-#include <devtree/devtree_reasoncodes.H>
-#include <devtree/devtreeif.H>
-#include "devtree.H"
-#include <sys/mmio.h> //THIRTYTWO_GB
-#include <vpd/vpd_if.H>
-#include <stdio.h>
-#include <pnor/pnorif.H>
-#include <sys/mm.h>
-#include <util/align.H>
-#include <vector>
-#include <vfs/vfs.H>
-#include <fsi/fsiif.H>
-#include <config.h>
-#include <devicefw/userif.H>
-#include <vpd/pvpdenums.H>
-#include <i2c/i2cif.H>
-#include <i2c/eepromif.H>
-#include <intr/interrupt.H>
-#include <i2c/tpmddif.H>
-#include <secureboot/trustedbootif.H>
-#include <secureboot/service.H>
-#include <ipmi/ipmisensor.H>
-
-//@TODO RTC:143092
-//#include <fapi.H>
-//#include <fapiPlatHwpInvoker.H> // for fapi::fapiRcToErrl()
-#include <vpd/mvpdenums.H>
-#include <arch/pirformat.H>
-
-trace_desc_t *g_trac_devtree = NULL;
-TRAC_INIT(&g_trac_devtree, "DEVTREE", 4096);
-
-namespace DEVTREE
-{
-using namespace TARGETING;
-
-typedef std::pair<uint64_t,uint64_t> homerAddr_t;
-
-enum BuildConstants
-{
- DEVTREE_DATA_ADDR =0xFF00000, /*256MB - 1MB*/
- DEVTREE_SPACE_SIZE =0x40000, /*256KB*/
- XSCOM_NODE_SHIFT =38, /*Node pos is 25, so 63-25=38*/
- XSCOM_CHIP_SHIFT =35, /*Chip pos is 28, so 63-28=35*/
- CHIPID_NODE_SHIFT =3, /*CHIPID is NNNNCCC, shift 3*/
- CHIPID_PROC_MASK =0x7, /*CHIPID is NNNNCCC, shift 3*/
- PHB0_MASK =0x80,
- MAX_PHBs =4, /*Max PHBs per chip is 4*/
- THREADPERCORE =8, /*8 threads per core*/
- MHZ =1000000,
-
- /* The Cache unit address (and reg property) is mostly free-for-all
- * as long as there is no collisions. On HDAT machines we use the
- * following encoding which I encourage you to also follow to limit
- * surprises:
- *
- * L2 : (0x20 << 24) | PIR (PIR is PIR value of thread 0 of core)
- * L3 : (0x30 << 24) | PIR
- * L3.5 : (0x35 << 24) | PIR */
- L2_HDR = (0x20 << 24),
- L3_HDR = (0x30 << 24),
- CEN_ID_SHIFT = 4,
- CEN_ID_TAG = 0x80000000,
-};
-
-// Opal will set this FIR bit any time a non-checkstop hardware error
-// leads to a crash. PRD will use this FIR bit to analyze appropriately.
-void bld_swCheckstopFir (devTree * i_dt, dtOffset_t & i_parentNode)
-{
- const uint32_t PBEASTFIR_OR = 0x02010c82;
- const uint32_t PBEASTFIR_MASK_AND = 0x02010c84;
- const uint32_t PBEASTFIR_ACT0 = 0x02010c86;
- const uint32_t PBEASTFIR_ACT1 = 0x02010c87;
- uint64_t BIT_31_MASK = 0xfffffffeffffffff;
- uint64_t l_data = 0;
- size_t opsize = sizeof(uint64_t);
-
- errlHndl_t l_errl = NULL;
-
- do
- {
- // unmask all functional proc chip targets
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TYPE_PROC);
-
- for (size_t proc = 0; proc < l_procTargetList.size(); proc++)
- {
- TARGETING::Target * l_proc = l_procTargetList[proc];
-
- // clear PBEASTFIR_ACT0 bit 31
- l_errl = deviceRead( l_proc,
- &l_data,
- opsize,
- DEVICE_SCOM_ADDRESS(PBEASTFIR_ACT0) );
- if (l_errl) break;
- l_data &= BIT_31_MASK;
- l_errl = deviceWrite( l_proc,
- &l_data,
- opsize,
- DEVICE_SCOM_ADDRESS(PBEASTFIR_ACT0) );
- if (l_errl) break;
-
- // clear PBEASTFIR_ACT1 bit 31
- l_errl = deviceRead( l_proc,
- &l_data,
- opsize,
- DEVICE_SCOM_ADDRESS(PBEASTFIR_ACT1) );
- if (l_errl) break;
- l_data &= BIT_31_MASK;
- l_errl = deviceWrite( l_proc,
- &l_data,
- opsize,
- DEVICE_SCOM_ADDRESS(PBEASTFIR_ACT1) );
- if (l_errl) break;
-
- // clear PBEASTFIR_MASK bit 31 using the AND register
- l_errl = deviceWrite( l_proc,
- &BIT_31_MASK,
- opsize,
- DEVICE_SCOM_ADDRESS(PBEASTFIR_MASK_AND) );
- if (l_errl) break;
- }
-
- // add devtree property
- uint32_t cellProperties [2] = {PBEASTFIR_OR,31}; // PBEASTFIR[31]
- i_dt->addPropertyCells32(i_parentNode,
- "ibm,sw-checkstop-fir",
- cellProperties, 2);
- } while (0);
-
- if (l_errl) // commit error and keep going
- {
- errlCommit(l_errl, DEVTREE_COMP_ID);
- }
-}
-
-//@todo-RTC:123043 -- Should use the functions in RT_TARG
-uint32_t getProcChipId(const TARGETING::Target * i_pProc)
-{
- uint32_t l_fabId = i_pProc->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();
- uint32_t l_procPos = i_pProc->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
- return ( (l_fabId << CHIPID_NODE_SHIFT) + l_procPos);
-}
-
-//@todo-RTC:123043 -- Should use the functions in RT_TARG
-uint32_t getMembChipId(const TARGETING::Target * i_pMemb)
-{
- PredicateCTM l_mcs(CLASS_UNIT,TYPE_MCS, MODEL_NA);
- TargetHandleList mcs_list;
- targetService().getAssociated(mcs_list,
- i_pMemb,
- TargetService::PARENT_BY_AFFINITY,
- TargetService::ALL,
- &l_mcs);
-
- if( mcs_list.size() != 1 )
- {
- //should never happen
- return 0;
- }
- Target* l_parentMCS = *(mcs_list.begin());
- uint32_t l_procId = getProcChipId(getParentChip(l_parentMCS));
- uint32_t l_membId = CEN_ID_TAG | (l_procId << CEN_ID_SHIFT);
- l_membId |= l_parentMCS->getAttr<ATTR_CHIP_UNIT>();
- return l_membId;
-}
-
-uint64_t getOccCommonAddr()
-{
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
- uint64_t l_physAddr = sys->getAttr<ATTR_OCC_COMMON_AREA_PHYS_ADDR>();
- return l_physAddr;
-}
-
-homerAddr_t getHomerPhysAddr(const TARGETING::Target * i_pProc)
-{
- uint64_t l_homerPhysAddrBase = i_pProc->getAttr<ATTR_HOMER_PHYS_ADDR>();
- uint8_t l_Pos = i_pProc->getAttr<ATTR_POSITION>();
-
- TRACFCOMP( g_trac_devtree, "proc ChipID [%X] HOMER is at %.16X"
- " instance %d",
- getProcChipId(i_pProc), l_homerPhysAddrBase, l_Pos );
-
- return homerAddr_t(l_homerPhysAddrBase, l_Pos);
-}
-
-void add_i2c_info( const TARGETING::Target* i_targ,
- devTree* i_dt,
- dtOffset_t i_node,
- uint64_t i_xscomAddr)
-{
- TRACFCOMP(g_trac_devtree,"add_i2c_info(%X)",TARGETING::get_huid(i_targ));
-
- //get list of all I2C Masters
- std::list<I2C::MasterInfo_t> l_i2cInfo;
- I2C::getMasterInfo( i_targ, l_i2cInfo );
-
- //find all of the EEPROMs connected via i2c
- std::list<EEPROM::EepromInfo_t> l_eepromInfo;
- EEPROM::getEEPROMs( l_eepromInfo );
-
-#ifdef CONFIG_TPMDD
- TPMDD::tpm_info_t tpmInfo;
- errlHndl_t err = NULL;
- //find all TPMs
- TARGETING::TargetHandleList tpmList;
- TRUSTEDBOOT::getTPMs(tpmList);
-#endif
-
- //add any other i2c devices here as needed, e.g. TPM, etc
-
- //figure out what kind of chip we're talking about
- TARGETING::TYPE l_master_type = i_targ->getAttr<TARGETING::ATTR_TYPE>();
- const char* l_masterName = "ibm,unknown";
- const char* l_chipname = "xx";
- uint32_t l_chipid = 0x0;
- if( l_master_type == TARGETING::TYPE_PROC )
- {
- l_masterName = "ibm,power8-i2cm";
- l_chipid = getProcChipId(i_targ);
- l_chipname = "p8";
- }
- else if( l_master_type == TARGETING::TYPE_MEMBUF )
- {
- l_masterName = "ibm,centaur-i2cm";
- l_chipid = getMembChipId(i_targ);
- l_chipname = "cen";
- }
-
- //compatible devices to make Opal/Linux happy
- static const struct
- {
- const char* name;
- size_t byteSize;
- size_t addrBytes;
- } atmel_ids[] = {
- { "atmel,24c128", 16*KILOBYTE, 2 },
- { "atmel,24c256", 32*KILOBYTE, 2 },
- { "atmel,24c02", 256, 1 },
-
- //Currently our minimum is 1KB, even for the 256 byte SPD
- { "atmel,24c02", 1*KILOBYTE, 1 },
- };
-
- /*
- Devtree hierarchy is like so
- i2cm@12345 {
- i2c-bus@0 {
- eeprom@12 {
- }
- }
- i2c-bus@1 {
- eeprom@12 {
- }
- eeprom@34 {
- }
- }
- }
- */
- for( std::list<I2C::MasterInfo_t>::iterator i2cm = l_i2cInfo.begin();
- i2cm != l_i2cInfo.end();
- ++i2cm )
- {
- /*
- i2cm@a0020 {
- reg = <0xa0020 0x20>; << scom address space
- chip-engine# = <0x1>; << i2c engine
- compatible = "ibm,power8-i2cm"; << what Opal wants
- clock-frequency = <0x2faf080>; << local bus in Hz
- #address-cells = <0x1>;
- phandle = <0x10000062>; << auto-filled
- #size-cells = <0x0>;
- linux,phandle = <0x10000062>; << Opal fills in
- }
- */
- dtOffset_t l_i2cNode = i_dt->addNode(i_node,
- "i2cm", i2cm->scomAddr);
- uint32_t l_i2cProp[2] = {
- static_cast<uint32_t>(i2cm->scomAddr),
- 0x20 }; //0x20 is number of scom regs per engine
- i_dt->addPropertyCells32(l_i2cNode, "reg", l_i2cProp, 2);
- i_dt->addPropertyCell32(l_i2cNode, "chip-engine#", i2cm->engine);
- const char* l_i2cCompatStrs[] = {l_masterName, NULL};
- i_dt->addPropertyStrings(l_i2cNode, "compatible", l_i2cCompatStrs);
- i_dt->addPropertyCell32(l_i2cNode, "clock-frequency", i2cm->freq);
- i_dt->addPropertyCell32(l_i2cNode, "#address-cells", 1);
- i_dt->addPropertyCell32(l_i2cNode, "#size-cells", 0);
-
-
- /*I2C busses*/
- std::list<EEPROM::EepromInfo_t>::iterator eep = l_eepromInfo.begin();
- while( eep != l_eepromInfo.end() )
- {
- // ignore the devices that aren't on the current target
- if( eep->i2cMaster != i_targ )
- {
- eep = l_eepromInfo.erase(eep);
- continue;
- }
- // skip the devices that are on a different engine
- else if( eep->engine != i2cm->engine )
- {
- ++eep;
- continue;
- }
-
- /*
- i2c-bus@0 {
- reg = <0x0>;
- bus-frequency = <0x61a80>;
- compatible = "ibm,power8-i2c-port", << Opal fills in
- "ibm,opal-i2c"; << Opal fills in
- ibm,opal-id = <0x1>; << Opal fills in
- ibm,port-name = "p8_00000000_e1p0"; << chip_chipid_eng_port
- #address-cells = <0x1>;
- phandle = <0x10000063>; << auto-filled
- #size-cells = <0x0>;
- linux,phandle = <0x10000063>;
- }
- */
- dtOffset_t l_busNode = i_dt->addNode( l_i2cNode,
- "i2c-bus", eep->port );
- i_dt->addPropertyCell32(l_busNode, "reg", eep->port);
- i_dt->addPropertyCell32(l_busNode, "bus-frequency", eep->busFreq);
- i_dt->addPropertyCell32(l_busNode, "#address-cells", 1);
- i_dt->addPropertyCell32(l_busNode, "#size-cells", 0);
- char portname[20];
- sprintf( portname, "%s_%.8X_e%dp%d",
- l_chipname,
- l_chipid,
- eep->engine,
- eep->port );
- i_dt->addPropertyString(l_busNode,
- "ibm,port-name",
- portname);
-
- // find any other devices on the same port so we can add them
- // all at once
- EEPROM::EepromInfo_t cur_eep = *eep;
- std::list<EEPROM::EepromInfo_t>::iterator eep2 = eep;
- while( eep2 != l_eepromInfo.end() )
- {
- // skip the devices for other busses
- if( !((cur_eep.i2cMaster == eep2->i2cMaster)
- && (cur_eep.engine == eep2->engine)
- && (cur_eep.port == eep2->port)) )
- {
- ++eep2;
- continue;
- }
-
- /*
- eeprom@50 {
- reg = <0x50>; << right-justified 7-bit addr
- label = "system-vpd"; << arbitrary name
- compatible = "atmel,24c64"; << use table above
- status = "ok"; << Opal fills in
- phandle = <0x10000065>; << auto-filled
- linux,phandle = <0x10000065>; << Opal fills in
- }
- */
- dtOffset_t l_eepNode = i_dt->addNode( l_busNode,
- "eeprom",
- eep2->devAddr >> 1 );
- i_dt->addPropertyCell32(l_eepNode, "reg", eep2->devAddr >> 1);
- char l_label[30];
- TARGETING::TYPE l_type = TARGETING::TYPE_NA;
- l_type = eep2->assocTarg->getAttr<TARGETING::ATTR_TYPE>();
- if( (l_type == TARGETING::TYPE_SYS)
- || (l_type == TARGETING::TYPE_NODE) )
- {
- sprintf( l_label, "system-vpd" );
- }
- else if( l_type == TARGETING::TYPE_PROC )
- {
- const char* l_type = "vpd";
- switch( eep2->device )
- {
- case(EEPROM::VPD_PRIMARY):
- l_type = "proc-vpd";
- break;
- case(EEPROM::VPD_BACKUP):
- l_type = "proc-vpd-backup";
- break;
- case(EEPROM::SBE_PRIMARY):
- l_type = "sbe0";
- break;
- case(EEPROM::SBE_BACKUP):
- l_type = "sbe1";
- break;
- default:
- break;
- }
- sprintf( l_label, "%s-%d",
- l_type,
- eep2->assocTarg
- ->getAttr<TARGETING::ATTR_POSITION>() );
- }
- else if( l_type == TARGETING::TYPE_MEMBUF )
- {
- sprintf( l_label, "memb-vpd-%d",
- eep2->assocTarg
- ->getAttr<TARGETING::ATTR_POSITION>() );
- }
- else if( l_type == TARGETING::TYPE_DIMM )
- {
- sprintf( l_label, "dimm-spd-%d",
- eep2->assocTarg
- ->getAttr<TARGETING::ATTR_POSITION>() );
- }
- else
- {
- sprintf( l_label, "unknown" );
- }
- i_dt->addPropertyString(l_eepNode, "label", l_label);
-
- // fill in atmel compatible
- const char* l_compat = "unknown";
- bool l_foundit = false;
- for( size_t a = 0;
- a < (sizeof(atmel_ids)/sizeof(atmel_ids[0]));
- a++ )
- {
- if( (atmel_ids[a].byteSize == (KILOBYTE*eep2->sizeKB))
- || (atmel_ids[a].addrBytes == eep2->addrBytes) )
- {
- l_compat = atmel_ids[a].name;
- l_foundit = true;
- break;
- }
- }
- if( !l_foundit )
- {
- TRACFCOMP( g_trac_devtree, "Could not find matching eeprom device for %s : size=%d,addr=%d", l_label, eep2->sizeKB, eep2->addrBytes );
- }
- i_dt->addPropertyString(l_eepNode, "compatible", l_compat);
-
- // need to increment the outer loop if we're going to
- // remove the element it points to
- if( eep == eep2 )
- {
- ++eep;
- }
- // now remove the device we added so we don't add it again
- eep2 = l_eepromInfo.erase(eep2);
- }
- } // end eeprom iter
-
-
-#ifdef CONFIG_TPMDD
- for(auto pTpm : tpmList)
- {
- // Lookup i2c info for the TPM
- err = TPMDD::tpmReadAttributes(pTpm, tpmInfo,
- TPMDD::TPM_LOCALITY_0);
- if (NULL != err)
- {
- // Unable to get info we skip this guy
- delete err;
- continue;
- }
-
- // ignore the devices that aren't on the current target
- if( tpmInfo.i2cTarget != i_targ )
- {
- continue;
- }
- // skip the devices that are on a different engine
- else if( tpmInfo.engine != i2cm->engine )
- {
- continue;
- }
-
- /*
- i2c-bus@0 {
- reg = <0x0>;
- bus-frequency = <0x61a80>;
- compatible = "ibm,power8-i2c-port", << Opal fills in
- "ibm,opal-i2c"; << Opal fills in
- ibm,opal-id = <0x1>; << Opal fills in
- ibm,port-name = "p8_00000000_e1p0"; << chip_chipid_eng_port
- #address-cells = <0x1>;
- phandle = <0x10000063>; << auto-filled
- #size-cells = <0x0>;
- linux,phandle = <0x10000063>;
- }
- */
- dtOffset_t l_busNode = i_dt->addNode( l_i2cNode,
- "i2c-bus", tpmInfo.port);
- i_dt->addPropertyCell32(l_busNode, "reg", tpmInfo.port);
- i_dt->addPropertyCell32(l_busNode, "bus-frequency",
- tpmInfo.busFreq);
- i_dt->addPropertyCell32(l_busNode, "#address-cells", 1);
- i_dt->addPropertyCell32(l_busNode, "#size-cells", 0);
- char portname[20];
- sprintf( portname, "%s_%.8X_e%dp%d",
- l_chipname,
- l_chipid,
- tpmInfo.engine,
- tpmInfo.port );
- i_dt->addPropertyString(l_busNode,
- "ibm,port-name",
- portname);
-
-
- /*
- tpm@50 {
- reg = <0x50>; << right-justified 7-bit addr
- label = "tpm"; << arbitrary name
- compatible = "nuvoton,npct650", "nuvoton,npct601";
- << from i2c driver
- status = "ok"; << Opal fills in
- phandle = <0x10000065>; << auto-filled
- linux,phandle = <0x10000065>; << Opal fills in
- linux,sml-size = <size of buffer allocated for event log>
- linux,sml-base = <ptr to event log>
- }
- */
- dtOffset_t l_tpmNode = i_dt->addNode( l_busNode,
- "tpm",
- tpmInfo.devAddr >> 1 );
-
- i_dt->addPropertyCell32(l_tpmNode, "reg",
- tpmInfo.devAddr >> 1);
- char l_label[30];
- switch (pTpm->getAttr<TARGETING::ATTR_TPM_ROLE>())
- {
- case TARGETING::TPM_ROLE_TPM_PRIMARY:
- sprintf( l_label, "tpm" );
- break;
- case TARGETING::TPM_ROLE_TPM_BACKUP:
- sprintf( l_label, "tpm-backup" );
- break;
- default:
- break;
- }
- i_dt->addPropertyString(l_tpmNode, "label", l_label);
-
- // fill in nuvoton compatible
- const char* l_compat[] = {"nuvoton,npct650",
- "nuvoton,npct601", NULL};
- i_dt->addPropertyStrings(l_tpmNode, "compatible", l_compat);
-
- // Placeholders for the tpm log which will be filled in later
- // We store info away so we can look up this devtree node later
- TRUSTEDBOOT::setTpmDevtreeInfo(pTpm, i_xscomAddr, i2cm->scomAddr);
- i_dt->addPropertyCell32(l_tpmNode, "linux,sml-size", 0);
- i_dt->addPropertyCell64(l_tpmNode, "linux,sml-base", 0);
- } // end TPM iter
-#endif
-
-
- } // end i2cm iter
-}
-
-
-void bld_getSideInfo(PNOR::SideId i_side,
- uint32_t o_TOCaddress[2],
- uint8_t & o_count,
- bool & o_isGolden)
-{
- errlHndl_t errhdl = NULL;
- PNOR::SideInfo_t l_info;
-
- o_count = 0;
- o_isGolden = false;
-
- errhdl = getSideInfo (i_side, l_info);
- if (!errhdl)
- {
- // return the valid TOC offsets & count of valid TOCs
- if (PNOR::INVALID_OFFSET != l_info.primaryTOC)
- {
- o_TOCaddress[o_count++] = l_info.primaryTOC;
- }
- if (PNOR::INVALID_OFFSET != l_info.backupTOC)
- {
- o_TOCaddress[o_count++] = l_info.backupTOC;
- }
- o_isGolden = l_info.isGolden;
- }
- else
- {
- // commit error and return 0 TOC offsets
- errlCommit(errhdl, DEVTREE_COMP_ID);
- }
-
- return;
-}
-
-void bld_fdt_pnor(devTree * i_dt,
- dtOffset_t i_parentNode)
-{
- do
- {
- uint32_t l_active[2] = {PNOR::INVALID_OFFSET,PNOR::INVALID_OFFSET};
- uint32_t l_golden[2] = {PNOR::INVALID_OFFSET,PNOR::INVALID_OFFSET};
- uint8_t l_count = 0;
- bool l_isGolden = false;
- bool l_goldenFound = false;
- uint8_t l_goldenCount = 0;
- PNOR::PnorInfo_t l_pnorInfo;
-
- //Get pnor address and size
- getPnorInfo (l_pnorInfo);
-
- dtOffset_t l_pnorNode = i_dt->addNode(i_parentNode,
- "pnor",
- l_pnorInfo.mmioOffset);
-
- const uint8_t l_isaLinkage = 0; // 0==Mem
- uint32_t pnor_prop[3] = {l_isaLinkage,
- l_pnorInfo.mmioOffset,
- l_pnorInfo.flashSize};
- i_dt->addPropertyCells32(l_pnorNode, "reg", pnor_prop, 3);
-
- //Add Working/Active parition
- bld_getSideInfo(PNOR::WORKING,l_active,l_count,l_isGolden);
- if (l_count) // valid TOCs present
- {
- i_dt->addPropertyCells32(l_pnorNode,
- "active-image-tocs", l_active, l_count);
- // capture golden
- if (l_isGolden)
- {
- l_golden[0] = l_active[0];
- l_golden[1] = l_active[1];
- l_goldenCount = l_count;
- l_goldenFound = true;
- }
- }
-
-#if CONFIG_PNOR_TWO_SIDE_SUPPORT
- //Add Alternate parition
- uint32_t l_alternate[2] = {PNOR::INVALID_OFFSET,PNOR::INVALID_OFFSET};
-
- bld_getSideInfo(PNOR::ALTERNATE,l_alternate,l_count,l_isGolden);
- if (l_count) // valid TOCs present
- {
- i_dt->addPropertyCells32(l_pnorNode,
- "alternate-image-tocs",l_alternate,l_count);
- // capture golden
- if (l_isGolden)
- {
- l_golden[0] = l_alternate[0];
- l_golden[1] = l_alternate[1];
- l_goldenCount = l_count;
- l_goldenFound = true;
- }
- }
-#endif
-
- //Include golden if there is one
- if (l_goldenFound)
- {
- i_dt->addPropertyCells32(l_pnorNode,
- "golden-image-tocs",l_golden,l_goldenCount);
- }
-
- } while (0);
-
- return;
-}
-
-void bld_xscom_node(devTree * i_dt, dtOffset_t & i_parentNode,
- const TARGETING::Target * i_pProc,
- uint32_t i_chipid,
- bool i_smallTree)
-{
- const char* xscomNodeName = "xscom";
- const char* todNodeName = "chiptod";
- const char* pciNodeName = "pbcq";
-
- /**********************************************************/
- /* Xscom node */
- /**********************************************************/
- uint64_t l_xscomAddr =
- i_pProc->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
-
- dtOffset_t xscomNode = i_dt->addNode(i_parentNode, xscomNodeName,
- l_xscomAddr);
-
- i_dt->addPropertyCell32(xscomNode, "#address-cells", 1);
- i_dt->addPropertyCell32(xscomNode, "#size-cells", 1);
- i_dt->addProperty(xscomNode, "scom-controller");
- const char* xscom_compatStrs[] = {"ibm,xscom","ibm,power8-xscom",NULL};
- i_dt->addPropertyStrings(xscomNode, "compatible", xscom_compatStrs);
-
- i_dt->addPropertyCell32(xscomNode, "ibm,chip-id", i_chipid);
-
- uint64_t xscom_prop[2] = { l_xscomAddr, THIRTYTWO_GB};
- i_dt->addPropertyCells64(xscomNode, "reg", xscom_prop, 2);
-
- // Do not need anything else for small tree
- if (i_smallTree)
- {
- return;
- }
-
- // Add proc chip ECIDs
- ATTR_ECID_type ecid;
- i_pProc->tryGetAttr<ATTR_ECID>(ecid);
- char ecid_ascii[33];
- sprintf(ecid_ascii, "%.16llX%.16llX", ecid[0], ecid[1]);
- i_dt->addPropertyString(xscomNode, "ecid", ecid_ascii);
- CPPASSERT(sizeof(ATTR_ECID_type) == 16);
-
- /*PSI Host Bridge*/
- uint32_t l_psiInfo = 0x2010900; /*PSI Host Bridge Scom addr*/
- dtOffset_t psiNode = i_dt->addNode(xscomNode, "psihb", l_psiInfo);
- const char* psi_compatStrs[] = {"ibm,power8-psihb-x",
- "ibm,psihb-x", NULL};
- i_dt->addPropertyStrings(psiNode, "compatible", psi_compatStrs);
- uint32_t psi_prop[2] = { l_psiInfo, 0x20 }; //# of scoms in range
- i_dt->addPropertyCells32(psiNode, "reg", psi_prop, 2);
- i_dt->addPropertyString(psiNode, "status", "ok");
-
- /*ChipTod*/
- uint32_t l_todInfo = 0x40000; /*Chip tod Scom addr*/
- dtOffset_t todNode = i_dt->addNode(xscomNode, todNodeName, l_todInfo);
- const char* tod_compatStrs[] = {"ibm,power-chiptod",
- "ibm,power8-chiptod", NULL};
- i_dt->addPropertyStrings(todNode, "compatible", tod_compatStrs);
- uint32_t tod_prop[2] = { l_todInfo, 0x34 }; //# of scoms in range
- i_dt->addPropertyCells32(todNode, "reg", tod_prop, 2);
-
- //Mark TOD pri/sec
- uint8_t l_role = i_pProc->getAttr<ATTR_TOD_ROLE>();
- if(l_role & TARGETING::TOD_ROLE_PRIMARY)
- {
- i_dt->addProperty(todNode, "primary");
- }
- if(l_role & TARGETING::TOD_ROLE_SECONDARY)
- {
- i_dt->addProperty(todNode, "secondary");
- }
-
- if(i_chipid == 0x0) //Master chip
- {
- uint32_t l_lpcInfo = 0xB0020; /*ECCB FW addr*/
- dtOffset_t lpcNode = i_dt->addNode(xscomNode,"isa",l_lpcInfo);
- i_dt->addPropertyString(lpcNode, "compatible", "ibm,power8-lpc");
- uint32_t lpc_prop[2] = { l_lpcInfo, 0x4 }; //# of scoms in range
- i_dt->addPropertyCells32(lpcNode, "reg", lpc_prop, 2);
- i_dt->addPropertyCell32(lpcNode, "#address-cells", 2);
- i_dt->addPropertyCell32(lpcNode, "#size-cells", 1);
-
- bld_fdt_pnor (i_dt, lpcNode);
-
- }
-
- /*NX*/
- uint32_t l_nxInfo = 0x2010000; /*NX Scom addr*/
- dtOffset_t nxNode = i_dt->addNode(xscomNode, "nx", l_nxInfo);
- const char* nx_compatStrs[] = {"ibm,power-nx",
- "ibm,power8-nx", NULL};
- i_dt->addPropertyStrings(nxNode, "compatible", nx_compatStrs);
- uint32_t nx_prop[2] = { l_nxInfo, 0x4000 }; //# of scoms in range
- i_dt->addPropertyCells32(nxNode, "reg", nx_prop, 2);
-
-
- /*PCIE*/
- uint8_t l_phbActive =
- i_pProc->getAttr<TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE>();
-
- TRACFCOMP( g_trac_devtree, "Chip %X PHB Active mask %X",
- i_chipid, l_phbActive);
-
- for(uint32_t l_phb =0; l_phb < MAX_PHBs; l_phb++)
- {
- if(!(l_phbActive & (PHB0_MASK>>l_phb)))
- {
- continue;
- }
-
- TRACFCOMP( g_trac_devtree, "Adding PHB %d", l_phb);
-
- /*PHB is active, add to Xscom map*/
- uint32_t l_peInfo = 0x02012000 + (l_phb * 0x400);
- uint32_t l_pciInfo = 0x09012000 + (l_phb * 0x400);
- uint32_t l_spciInfo = 0x09013c00 + (l_phb * 0x40);
- dtOffset_t pcieNode = i_dt->addNode(xscomNode,pciNodeName,l_peInfo);
- const char* pcie_compatStrs[] = {"ibm,power8-pbcq", NULL};
- i_dt->addPropertyStrings(pcieNode, "compatible", pcie_compatStrs);
- uint32_t pcie_prop[6] = { l_peInfo, 0x20, //# of scoms in range
- l_pciInfo, 0x5, //# of scoms in range
- l_spciInfo, 0x15}; //# of scoms in range
- i_dt->addPropertyCells32(pcieNode, "reg", pcie_prop, 6);
- i_dt->addPropertyCell32(pcieNode, "ibm,phb-index", l_phb);
- i_dt->addProperty(pcieNode, "ibm,use-ab-detect");
- }
-
- /*I2C Masters*/
- add_i2c_info( i_pProc, i_dt, xscomNode, l_xscomAddr );
-
-}
-
-uint32_t bld_l3_node(devTree * i_dt, dtOffset_t & i_parentNode,
- uint32_t i_pir)
-{
- uint32_t l3Id = i_pir | L3_HDR;
-
- /* Build L3 Cache information */
- dtOffset_t l3Node = i_dt->addNode(i_parentNode, "l3-cache",l3Id);
- i_dt->addPropertyString(l3Node, "device_type", "cache");
- i_dt->addPropertyCell32(l3Node, "reg", l3Id);
- i_dt->addProperty(l3Node, "cache-unified");
- i_dt->addPropertyCell32(l3Node, "d-cache-sets", 0x8);
- i_dt->addPropertyCell32(l3Node, "i-cache-sets", 0x8);
- i_dt->addPropertyCell32(l3Node, "d-cache-size", 0x800000); //8MB
- i_dt->addPropertyCell32(l3Node, "i-cache-size", 0x800000); //8MB
- i_dt->addPropertyString(l3Node, "status", "okay");
-
- return i_dt->getPhandle(l3Node);
-}
-
-uint32_t bld_l2_node(devTree * i_dt, dtOffset_t & i_parentNode,
- uint32_t i_pir, uint32_t i_nextCacheHandle)
-{
- uint32_t l2Id = i_pir | L2_HDR;
-
- /* Build l2 Cache information */
- dtOffset_t l2Node = i_dt->addNode(i_parentNode, "l2-cache",l2Id);
- i_dt->addPropertyString(l2Node, "device_type", "cache");
- i_dt->addPropertyCell32(l2Node, "reg", l2Id);
- i_dt->addProperty(l2Node, "cache-unified");
- i_dt->addPropertyCell32(l2Node, "d-cache-sets", 0x8);
- i_dt->addPropertyCell32(l2Node, "i-cache-sets", 0x8);
- i_dt->addPropertyCell32(l2Node, "d-cache-size", 0x80000); //512KB
- i_dt->addPropertyCell32(l2Node, "i-cache-size", 0x80000); //512KB
- i_dt->addPropertyString(l2Node, "status", "okay");
- i_dt->addPropertyCell32(l2Node, "next-level-cache", i_nextCacheHandle);
-
-
- return i_dt->getPhandle(l2Node);
-}
-
-uint32_t bld_cpu_node(devTree * i_dt, dtOffset_t & i_parentNode,
- const TARGETING::Target * i_ex,
- PIR_t i_pir, uint32_t i_chipId,
- uint32_t i_nextCacheHandle)
-{
- /*
- * The following node must exist for each *core* in the system. The unit
- * address (number after the @) is the hexadecimal HW CPU number (PIR value)
- * of thread 0 of that core.
- */
-
- uint32_t paFeatures[2] = { 0x0600f63f, 0xc70080c0 };
- uint32_t pageSizes[4] = { 0xc, 0x10, 0x18, 0x22 };
- uint32_t segmentSizes[4] = { 0x1c, 0x28, 0xffffffff, 0xffffffff };
- uint32_t segmentPageSizes[] =
- {
- 12, 0x0, 3, /* 4k SLB page size, L,LP = 0,x1, 3 page size encodings */
- 12, 0x0, /* 4K PTE page size, L,LP = 0,x0 */
- 16, 0x7, /* 64K PTE page size, L,LP = 1,x7 */
- 24, 0x38, /* 16M PTE page size, L,LP = 1,x38 */
- 16, 0x110, 2, /* 64K SLB page size, L,LP = 1,x1, 2 page size encodings*/
- 16, 0x1, /* 64K PTE page size, L,LP = 1,x1 */
- 24, 0x8, /* 16M PTE page size, L,LP = 1,x8 */
- 20, 0x130, 1, /* 1M SLB page size, L,LP = 1,x3, 1 page size encoding */
- 20, 0x2, /* 1M PTE page size, L,LP = 1,x2 */
- 24, 0x100, 1, /* 16M SLB page size, L,LP = 1,x0, 1 page size encoding */
- 24, 0x0, /* 16M PTE page size, L,LP = 1,x0 */
- 34, 0x120, 1, /* 16G SLB page size, L,LP = 1,x2, 1 page size encoding */
- 34, 0x3 /* 16G PTE page size, L,LP = 1,x3 */
- };
-
-
- dtOffset_t cpuNode = i_dt->addNode(i_parentNode, "PowerPC,POWER8",
- i_pir.word);
- i_dt->addPropertyString(cpuNode, "device_type", "cpu");
- i_dt->addProperty(cpuNode, "64-bit");
- i_dt->addProperty(cpuNode, "32-64-bridge");
- i_dt->addProperty(cpuNode, "graphics");
- i_dt->addProperty(cpuNode, "general-purpose");
- i_dt->addPropertyString(cpuNode, "status", "okay");
- i_dt->addPropertyCell32(cpuNode, "reg", i_pir.word);
- i_dt->addPropertyCell32(cpuNode, "ibm,pir", i_pir.word);
- i_dt->addPropertyCell32(cpuNode, "ibm,chip-id", i_chipId);
-
- uint32_t numThreads = 0;
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
- uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>();
-
- uint32_t interruptServerNum[THREADPERCORE];
- for(size_t i = 0; i < THREADPERCORE ; i++)
- {
- if (en_threads & (0x8000000000000000 >> i))
- {
- i_pir.threadId = i;
- interruptServerNum[numThreads++] = i_pir.word;
- }
- }
- i_dt->addPropertyCells32(cpuNode, "ibm,ppc-interrupt-server#s",
- interruptServerNum, numThreads);
-
- /* Fill in the actual PVR of chip -- it is only a 32 bit reg*/
- uint32_t l_pvr = mmio_pvr_read() & 0xFFFFFFFF;
- i_dt->addPropertyCell32(cpuNode, "cpu-version", l_pvr);
-
- i_dt->addPropertyCells32(cpuNode, "ibm,processor-segment-sizes",
- segmentSizes,
- sizeof(segmentSizes) / sizeof(uint32_t));
- i_dt->addPropertyCells32(cpuNode, "ibm,processor-page-sizes",
- pageSizes,
- sizeof(pageSizes) / sizeof(uint32_t));
- i_dt->addPropertyCells32(cpuNode, "ibm,segment-page-sizes",
- segmentPageSizes,
- sizeof(segmentPageSizes)/sizeof(uint32_t));
- i_dt->addPropertyCells32(cpuNode, "ibm,pa-features",
- paFeatures,
- sizeof(paFeatures)/sizeof(uint32_t));
-
- i_dt->addPropertyCell32(cpuNode, "ibm,slb-size", 32);
- i_dt->addPropertyCell32(cpuNode, "ibm,dfp", 1);
- i_dt->addPropertyCell32(cpuNode, "ibm,vmx", 2);
- i_dt->addPropertyCell32(cpuNode, "ibm,purr", 1);
- i_dt->addPropertyCell32(cpuNode, "ibm,spurr", 1);
-
- //Set core clock freq
- uint64_t freq = 0;
-
-#ifdef CONFIG_HTMGT
- if(sys->getAttr<TARGETING::ATTR_HTMGT_SAFEMODE>())
- {
- // Safe mode on, OCC failed to load. Set safe freq
- freq = sys->getAttr<TARGETING::ATTR_BOOT_FREQ_MHZ>();
- }
- else
- {
- // Safe mode off, set nominal freq
- freq = sys->getAttr<TARGETING::ATTR_NOMINAL_FREQ_MHZ>();
- }
-#elif CONFIG_SET_NOMINAL_PSTATE
- // Set nominal core freq if CONFIG_SET_NOMINAL_PSTATE is enabled
- freq = sys->getAttr<TARGETING::ATTR_NOMINAL_FREQ_MHZ>();
-#else
- // Else, set safe core freq
- freq = sys->getAttr<TARGETING::ATTR_BOOT_FREQ_MHZ>();
-#endif
-
- freq *= MHZ;
-
- uint32_t ex_freq[2] = {static_cast<uint32_t>(freq >> 32),
- static_cast<uint32_t>(freq & 0xFFFFFFFF)};
- if(ex_freq[0] == 0) //Only create if fits into 32 bits
- {
- i_dt->addPropertyCell32(cpuNode, "clock-frequency", ex_freq[1]);
- }
- i_dt->addPropertyCells32(cpuNode, "ibm,extended-clock-frequency",
- ex_freq, 2);
-
- uint32_t timebase_freq[2] = {0, 512000000};
- i_dt->addPropertyCell32(cpuNode, "timebase-frequency", timebase_freq[1]);
- i_dt->addPropertyCells32(cpuNode, "ibm,extended-timebase-frequency",
- timebase_freq, 2);
-
-
- i_dt->addPropertyCell32(cpuNode, "reservation-granule-size", 0x80);
- i_dt->addPropertyCell32(cpuNode, "d-tlb-size", 0x800);
- i_dt->addPropertyCell32(cpuNode, "i-tlb-size", 0x0);
- i_dt->addPropertyCell32(cpuNode, "tlb-size", 0x800);
- i_dt->addPropertyCell32(cpuNode, "d-tlb-sets", 0x4);
- i_dt->addPropertyCell32(cpuNode, "i-tlb-sets", 0x0);
- i_dt->addPropertyCell32(cpuNode, "tlb-sets", 0x4);
- i_dt->addPropertyCell32(cpuNode, "d-cache-block-size", 0x80);
- i_dt->addPropertyCell32(cpuNode, "i-cache-block-size", 0x80);
- i_dt->addPropertyCell32(cpuNode, "d-cache-size", 0x10000);
- i_dt->addPropertyCell32(cpuNode, "i-cache-size", 0x8000);
- i_dt->addPropertyCell32(cpuNode, "i-cache-sets", 0x4);
- i_dt->addPropertyCell32(cpuNode, "d-cache-sets", 0x8);
- i_dt->addPropertyCell64(cpuNode, "performance-monitor", 0x1);
- i_dt->addPropertyCell32(cpuNode, "next-level-cache", i_nextCacheHandle);
-
- return i_dt->getPhandle(cpuNode);
-}
-
-uint32_t bld_intr_node(devTree * i_dt, dtOffset_t & i_parentNode,
- const TARGETING::Target * i_ex,
- PIR_t i_pir)
-
-{
- /*
- * Interrupt presentation controller (ICP) nodes
- *
- * There is some flexibility as to how many of these are presents since
- * a given node can represent multiple ICPs. When generating from HDAT we
- * chose to create one per core
- */
-
- uint64_t l_ibase = INTR::getIntpAddr(i_ex, 0); //IBASE ADDRESS
-
- dtOffset_t intNode = i_dt->addNode(i_parentNode, "interrupt-controller",
- l_ibase);
-
- const char* intr_compatStrs[] = {"ibm,ppc-xicp", "ibm,power8-xicp",NULL};
- i_dt->addPropertyStrings(intNode, "compatible", intr_compatStrs);
- i_dt->addProperty(intNode,"interrupt-controller");
- i_dt->addPropertyCell32(intNode, "#address-cells", 0);
- i_dt->addPropertyCell32(intNode, "#interrupt-cells", 1);
- i_dt->addPropertyString(intNode, "device_type",
- "PowerPC-External-Interrupt-Presentation");
-
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
- uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>();
- uint32_t numThreads = 0;
-
- uint64_t intr_prop[THREADPERCORE][2];
- for(size_t i=0; i < THREADPERCORE; i++)
- {
- if (en_threads & (0x8000000000000000 >> i))
- {
- intr_prop[numThreads][0] = INTR::getIntpAddr(i_ex, i);
- intr_prop[numThreads][1] = 0x1000;
- numThreads++;
- }
- }
- i_dt->addPropertyCells64(intNode, "reg",
- reinterpret_cast<uint64_t*>(intr_prop),
- numThreads * 2);
-
- uint32_t int_serv[2] = { i_pir.word, numThreads};
- i_dt->addPropertyCells32(intNode, "ibm,interrupt-server-ranges",
- int_serv, 2);
-
- return i_dt->getPhandle(intNode);
-}
-
-
-void add_reserved_mem(devTree * i_dt,
- std::vector<homerAddr_t>& i_homerAddr,
- uint64_t i_extraAddr[],
- uint64_t i_extraSize[],
- const char* i_extraStr[],
- uint64_t i_extraCnt)
-{
- /*
- * TODO RTC: 131056 remove non-node reserved memory entries
- * - reserved-names and reserved-ranges
- * - reserved map ??
- * hints are provided for the scope of code to remove
- * The reserved-names and reserve-ranges properties work hand in hand.
- * The first one is a list of strings providing a "name" for each entry
- * in the second one using the traditional "vendor,name" format.
- *
- * The reserved-ranges property contains a list of ranges, each in the
- * form of 2 cells of address and 2 cells of size (64-bit x2 so each
- * entry is 4 cells) indicating regions of memory that are reserved
- * and must not be overwritten by skiboot or subsequently by the Linux
- * Kernel.
- *
- * Corresponding entries must also be created in the "reserved map" part
- * of the flat device-tree (which is a binary list in the header of the
- * fdt).
- * **** remove to here
- *
- * Reserved memory is passed in a node-based format. An instance
- * number distinquishes homer regions.
- *
- * Unless a component (skiboot or Linux) specifically knows about a region
- * (usually based on its name) and decides to change or remove it, all
- * these regions are passed as-is to Linux and to subsequent kernels
- * across kexec and are kept preserved.
- */
-
- dtOffset_t rootNode = i_dt->findNode("/");
-
- size_t l_num = i_homerAddr.size();
-
- // 131056: Won't need these
- const char* homerStr = "ibm,slw-occ-image";
- const char* reserve_strs[l_num+i_extraCnt+1];
- uint64_t ranges[l_num+i_extraCnt][2];
- uint64_t cell_count = sizeof(ranges) / sizeof(uint64_t);
- uint64_t res_mem_addrs[l_num+i_extraCnt];
- uint64_t res_mem_sizes[l_num+i_extraCnt];
-
- // create the nodes for the node based format
- dtOffset_t rootMemNode = i_dt->addNode(rootNode, "ibm,hostboot");
- i_dt->addPropertyCell32(rootMemNode, "#address-cells", 2);
- i_dt->addPropertyCell32(rootMemNode, "#size-cells", 2);
- dtOffset_t reservedMemNode = i_dt->addNode(rootMemNode, "reserved-memory");
- i_dt->addPropertyCell32(reservedMemNode, "#address-cells", 2);
- i_dt->addPropertyCell32(reservedMemNode, "#size-cells", 2);
- i_dt->addProperty(reservedMemNode, "ranges");
-
- for(size_t i = 0; i<l_num; i++)
- {
- uint64_t l_homerAddr = i_homerAddr[i].first;
- uint64_t l_homerInstance = i_homerAddr[i].second;
- TRACFCOMP( g_trac_devtree, "Reserved Region %s @ %lx, %lx instance %d",
- homerStr,
- l_homerAddr,
- VMM_HOMER_INSTANCE_SIZE,
- l_homerInstance);
-
- // 131056: Won't need these
- reserve_strs[i] = homerStr;
- ranges[i][0] = l_homerAddr;
- ranges[i][1] = VMM_HOMER_INSTANCE_SIZE;
- res_mem_addrs[i] = l_homerAddr;
- res_mem_sizes[i] = VMM_HOMER_INSTANCE_SIZE;
-
- // add node style inclulding homer instance.
- dtOffset_t homerNode = i_dt->addNode(reservedMemNode,
- "ibm,homer-image",
- l_homerAddr);
- uint64_t propertyCells[2]={l_homerAddr, VMM_HOMER_INSTANCE_SIZE};
- i_dt->addPropertyCells64(homerNode, "reg", propertyCells, 2);
- const char* propertyStrs[] = {"ibm,homer-image", NULL};
- i_dt->addPropertyStrings(homerNode, "ibm,prd-label",propertyStrs);
- i_dt->addPropertyCell32(homerNode, "ibm,prd-instance",
- l_homerInstance);
- }
-
- for(size_t i = 0; i < i_extraCnt; i++)
- {
- if (i_extraAddr[i])
- {
- TRACFCOMP( g_trac_devtree, "Reserved Region %s @ %lx, %lx",
- i_extraStr[i], i_extraAddr[i], i_extraSize[i]);
-
- // 131056: Won't need these
- reserve_strs[l_num] = i_extraStr[i];
- ranges[l_num][0] = i_extraAddr[i];
- ranges[l_num][1] = i_extraSize[i];
- res_mem_addrs[l_num] = i_extraAddr[i];
- res_mem_sizes[l_num] = i_extraSize[i];
- l_num++;
-
- // add node style entry
- dtOffset_t extraNode = i_dt->addNode(reservedMemNode,
- i_extraStr[i],
- i_extraAddr[i]);
- uint64_t propertyCells[2]={i_extraAddr[i],i_extraSize[i]};
- i_dt->addPropertyCells64(extraNode, "reg", propertyCells, 2);
- const char* propertyStrs[] = {i_extraStr[i], NULL};
- i_dt->addPropertyStrings(extraNode, "ibm,prd-label",propertyStrs);
- }
- else
- {
- cell_count -= sizeof(ranges[0]) / sizeof(uint64_t);
- }
- }
- // add node style occ common node
- const char* occStr = "ibm,occ-common-area";
- uint64_t l_occCommonPhysAddr = getOccCommonAddr();
- uint64_t l_occCommonPhysSize = VMM_OCC_COMMON_SIZE;
- TRACFCOMP( g_trac_devtree, "Reserved Region %s @ %lx, %lx",
- occStr, l_occCommonPhysAddr, l_occCommonPhysSize);
- dtOffset_t occNode = i_dt->addNode(reservedMemNode,
- occStr,
- l_occCommonPhysAddr);
- uint64_t propertyCells[2]={l_occCommonPhysAddr, l_occCommonPhysSize};
- i_dt->addPropertyCells64(occNode, "reg", propertyCells, 2);
- const char* propertyStrs[] = {occStr, NULL};
- i_dt->addPropertyStrings(occNode, "ibm,prd-label",propertyStrs);
-
- // 131056: Won't need the rest
- reserve_strs[l_num] = NULL;
- i_dt->addPropertyStrings(rootNode, "reserved-names", reserve_strs);
- i_dt->addPropertyCells64(rootNode, "reserved-ranges",
- reinterpret_cast<uint64_t*>(ranges),
- cell_count);
-
- // added per comment from Dean Sanner
- // cell_count has limit of DT_MAX_MEM_RESERVE = 16. Is this enough
- // for all processors + 1 vpd area + 1 target area?
- i_dt->populateReservedMem(res_mem_addrs, res_mem_sizes, cell_count);
-}
-
-void load_hbrt_image(uint64_t& io_address)
-{
- errlHndl_t l_errl = NULL;
-
- do
- {
-
- PNOR::SectionInfo_t l_pnorInfo;
- l_errl = getSectionInfo( PNOR::HB_RUNTIME , l_pnorInfo);
- if (l_errl) { break; }
-
- // Find start of image.
- // For Secureboot we might need to deal with the header but
- // for now that is hidden by the PNOR-RP.
- uint64_t image_start = l_pnorInfo.vaddr;
-
- // The "VFS_LAST_ADDRESS" variable is 2 pages in.
- uint64_t vfs_last_address =
- *reinterpret_cast<uint64_t*>(image_start + 2*PAGE_SIZE);
-
- // At the end of the image are the relocations, get the number.
- uint64_t relocate_count =
- *reinterpret_cast<uint64_t*>(image_start + vfs_last_address);
-
- // Sum up the total size.
- uint64_t image_size = vfs_last_address +
- (relocate_count+1)*sizeof(uint64_t);
-
- TRACFCOMP(g_trac_devtree, "HBRT image: start = %lx, size = %lx",
- image_start, image_size);
- io_address -= ALIGN_PAGE(image_size);
- // Align to 64KB for Opal
- io_address = ALIGN_DOWN_X(io_address,64*KILOBYTE);
-
- // Copy image.
- void* memArea = mm_block_map(reinterpret_cast<void*>(io_address),
- ALIGN_PAGE(image_size));
- memcpy(memArea, reinterpret_cast<void*>(image_start), image_size);
- mm_block_unmap(memArea);
-
- } while (0);
-
- if (l_errl)
- {
- io_address = 0;
- errlCommit(l_errl, DEVTREE_COMP_ID);
- }
-}
-
-void load_tpmlog(devTree * i_dt, uint64_t& io_address)
-{
-
- do
- {
-#ifdef CONFIG_TPMDD
- errlHndl_t l_errl = NULL;
-
- // TPM log
- TARGETING::TargetHandleList tpmList;
- TRUSTEDBOOT::getTPMs(tpmList);
-
- size_t l_allocatedSize = 0;
- uint32_t* l_propAllocSize = NULL;
- uint64_t* l_propAddr = NULL;
- TPMDD::tpm_info_t l_tpmInfo;
- uint64_t l_scomAddr = 0;
- uint32_t l_masterOffset = 0;
- uint8_t l_i2cBus = 0;
- uint8_t l_tpmAddr = 0;
- char l_nodePath[100];
- dtOffset_t l_tpmNode;
-
- for(auto pTpm : tpmList)
- {
-
- l_errl = TRUSTEDBOOT::getTpmLogDevtreeInfo(pTpm,
- io_address,
- l_allocatedSize,
- l_scomAddr,
- l_masterOffset);
-
- if (l_errl)
- {
- errlCommit(l_errl, DEVTREE_COMP_ID);
- continue;
- }
-
- // We need to build the devtree path to find this TPM node
- // Lookup i2c info for the TPM
- l_errl = TPMDD::tpmReadAttributes(pTpm, l_tpmInfo,
- TPMDD::TPM_LOCALITY_0);
- if (l_errl)
- {
- errlCommit(l_errl, DEVTREE_COMP_ID);
- continue;
- }
-
- l_i2cBus = l_tpmInfo.port;
- l_tpmAddr = l_tpmInfo.devAddr >> 1;
-
- sprintf(l_nodePath, "/xscom@%lx/i2cm@%x/i2c-bus@%x/tpm@%x",
- l_scomAddr, l_masterOffset, l_i2cBus, l_tpmAddr);
-
- TRACFCOMP(g_trac_devtree,"Searching for TPM Node %s",
- l_nodePath);
- l_tpmNode = i_dt->findNode(l_nodePath);
-
- l_propAllocSize = reinterpret_cast<uint32_t*>(
- i_dt->findProperty(l_tpmNode,
- "linux,sml-size"));
- l_propAddr = reinterpret_cast<uint64_t*>(
- i_dt->findProperty(l_tpmNode,
- "linux,sml-base"));
-
- if (NULL == l_propAllocSize ||
- NULL == l_propAddr)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Unable to find "
- "sml TPM properties");
- continue;
- }
-
- // Store the values in the devtree nodes
- *l_propAllocSize = l_allocatedSize;
- *l_propAddr = io_address;
- }
-#endif
-
- } while (0);
-
-}
-
-errlHndl_t bld_fdt_system(devTree * i_dt, bool i_smallTree)
-{
- errlHndl_t errhdl = NULL;
-
- dtOffset_t rootNode = i_dt->findNode("/");
-
- //Common settings
- /* Define supported power states -- options:
- nap, deep-sleep, fast-sleep, rvwinkle*/
- const char* pmode_compatStrs[] = {"nap", "fast-sleep", "rvwinkle", NULL};
- i_dt->addPropertyStrings(rootNode, "ibm,enabled-idle-states",
- pmode_compatStrs);
-
- // Nothing to do for small trees currently.
- if (!i_smallTree)
- {
- /* Add devtree property for checkstop escalation */
- bld_swCheckstopFir(i_dt,rootNode);
-
- //===== compatible =====
- /* Fetch the MRW-defined compatible model from attributes */
- ATTR_OPAL_MODEL_type l_model = {0};
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
- sys->tryGetAttr<TARGETING::ATTR_OPAL_MODEL>(l_model);
-
- /* Add compatibility value */
- const char* l_compats[] = { "ibm,powernv", l_model, NULL };
- i_dt->addPropertyStrings(rootNode, "compatible", l_compats);
-
- //===== model =====
- /* Add system model value
- Depending on the vintage of the planar VPD, there are 3 places
- we need to look for this data.
- 1) OSYS:MM
- 2) OPFR:DR
- 3) Default to 'unknown'
- */
- bool foundvpd = false;
- TARGETING::TargetHandleList l_nodeTargetList;
- PredicateCTM predNode(CLASS_ENC, TYPE_NODE);
- PredicateHwas predFunctional;
- predFunctional.functional(true);
- PredicatePostfixExpr nodeCheckExpr;
- nodeCheckExpr.push(&predNode).push(&predFunctional).And();
-
- targetService().getAssociated(l_nodeTargetList, sys,
- TargetService::CHILD, TargetService::IMMEDIATE,
- &nodeCheckExpr);
-
- //if can't find a node for the PVPD, default to unknown
- if (l_nodeTargetList.size())
- {
- TARGETING::Target * l_pNode = l_nodeTargetList[0];
- size_t vpdSize = 0x0;
-
- // Note: First read with NULL for o_buffer sets vpdSize to the
- // correct length
- errhdl = deviceRead( l_pNode,
- NULL,
- vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS,
- PVPD::MM ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get OSYS:MM size for HUID=0x%.8X",
- TARGETING::get_huid(l_pNode));
-
- // Try the OPFR record
- errlHndl_t opfr_errhdl = deviceRead( l_pNode,
- NULL,
- vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OPFR,
- PVPD::DR ));
- if(opfr_errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get OPFR:DR size for HUID=0x%.8X",
- TARGETING::get_huid(l_pNode));
- delete opfr_errhdl; //delete OPFR log, VPD is just bad
- }
- else
- {
- delete errhdl; //ignore lack of OSYS due to older vpd
- errhdl = NULL;
- char drBuf[vpdSize+1];
- memset(&drBuf, 0x0, (vpdSize+1)); //null terminated str
- errhdl = deviceRead( l_pNode,
- reinterpret_cast<void*>( &drBuf ),
- vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OPFR,
- PVPD::DR ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read OPFR:DR for HUID=0x%.8X",
- TARGETING::get_huid(l_pNode));
- }
- else
- {
- foundvpd = true;
- i_dt->addPropertyString(rootNode, "model", drBuf);
- }
- }
- }
- else
- {
- char mmBuf[vpdSize+1];
- memset(&mmBuf, 0x0, (vpdSize+1)); //ensure null terminated str
- errhdl = deviceRead( l_pNode,
- reinterpret_cast<void*>( &mmBuf ),
- vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS,
- PVPD::MM ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read OSYS:MM for HUID=0x%.8X",
- TARGETING::get_huid(l_pNode));
- }
- else
- {
- foundvpd = true;
- i_dt->addPropertyString(rootNode, "model", mmBuf);
- }
- }
- }
-
- // just commit any errors we get, this isn't critical
- if( errhdl )
- {
- errlCommit(errhdl, DEVTREE_COMP_ID); //commit original OSYS log
- }
-
- if( !foundvpd ) //chassis info not found, default to unknown
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" VPD not found, model defaulted to unknown");
- i_dt->addPropertyString(rootNode, "model", "unknown");
- }
-
- //===== system-id =====
- /* Add system-id value
- 1) OSYS:SS
- 2) Default to 'unavailable'
- */
- foundvpd = false;
- if( l_nodeTargetList.size() )
- {
- TARGETING::Target * l_pNode = l_nodeTargetList[0];
- size_t vpdSize = 0x0;
-
- // Note: First read with NULL for o_buffer sets vpdSize to the
- // correct length
- errhdl = deviceRead( l_pNode,
- NULL,
- vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS,
- PVPD::SS ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get OSYS:SS size for HUID=0x%.8X",
- TARGETING::get_huid(l_pNode));
- // Note - not supporting old vpd versions without OSYS here
- }
- else
- {
- char ssBuf[vpdSize+1];
- memset(&ssBuf, 0x0, (vpdSize+1)); //ensure null terminated str
- errhdl = deviceRead( l_pNode,
- reinterpret_cast<void*>( &ssBuf ),
- vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS,
- PVPD::SS ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read OSYS:SS for HUID=0x%.8X",
- TARGETING::get_huid(l_pNode));
- }
- else
- {
- foundvpd = true;
- i_dt->addPropertyString(rootNode, "system-id", ssBuf);
- }
- }
- }
- // just delete any errors we get, this isn't critical
- if( errhdl )
- {
- // since there are old parts out in the wild without
- // this data, we can't log an error
- delete errhdl;
- errhdl = NULL;
- }
- if( !foundvpd ) //serial number not found, default to unavailable
- {
- i_dt->addPropertyString(rootNode, "system-id", "unavailable");
- }
- }
-
- return errhdl;
-}
-
-
-errlHndl_t bld_fdt_cpu(devTree * i_dt,
- std::vector<homerAddr_t>& o_homerRegions,
- bool i_smallTree)
-{
- errlHndl_t errhdl = NULL;
-
- /* Find the / node and add a cpus node under it. */
- dtOffset_t rootNode = i_dt->findNode("/");
- dtOffset_t cpusNode = NULL;
- if (!i_smallTree)
- {
- cpusNode = i_dt->addNode(rootNode, "cpus");
-
- /* Add the # address & size cell properties to /cpus. */
- i_dt->addPropertyCell32(cpusNode, "#address-cells", 1);
- i_dt->addPropertyCell32(cpusNode, "#size-cells", 0);
- }
-
- // Get all functional proc chip targets
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TYPE_PROC);
-
- for (size_t proc = 0; (!errhdl) && (proc < l_procTargetList.size()); proc++)
- {
- const TARGETING::Target * l_pProc = l_procTargetList[proc];
-
- uint32_t l_chipid = getProcChipId(l_pProc);
-
- // For small tree, only add xscom if master processor
- TARGETING::Target* l_pMasterProc = NULL;
- TARGETING::targetService().masterProcChipTargetHandle(l_pMasterProc);
- if((!i_smallTree) || (l_pProc == l_pMasterProc) )
- {
- bld_xscom_node(i_dt, rootNode, l_pProc, l_chipid, i_smallTree);
- }
- if (i_smallTree) // nothing else for small tree
- {
- continue;
- }
-
- //Each processor will have a HOMER image that needs
- //to be reserved -- save it away
- o_homerRegions.push_back(getHomerPhysAddr(l_pProc));
-
- TARGETING::TargetHandleList l_corelist;
- getChildChiplets( l_corelist, l_pProc, TYPE_CORE );
- for (size_t core = 0; core < l_corelist.size(); core++)
- {
- const TARGETING::Target * l_core = l_corelist[core];
- if(l_core->getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true)
- {
- continue; //Not functional
- }
-
- /* Proc ID Reg is GG GGCC CPPP PPTT Where
- GGGG is Group number
- CCC is Chip
- PPPPP is the core number
- TT is Thread num
- */
- uint32_t l_coreNum = l_core->getAttr<TARGETING::ATTR_CHIP_UNIT>();
- PIR_t pir(0);
- pir.groupId = PIR_t::groupFromChipId(l_chipid);
- pir.chipId = PIR_t::chipFromChipId(l_chipid);
- pir.coreId = l_coreNum;
-
- TRACFCOMP( g_trac_devtree, "Added pir[%x] chipid 0x%x core %d",
- pir.word, l_chipid, l_coreNum );
-
- cpusNode = i_dt->findNode("/cpus");
-
- uint32_t l3pHandle = bld_l3_node(i_dt, cpusNode, pir.word);
- uint32_t l2pHandle = bld_l2_node(i_dt, cpusNode, pir.word,
- l3pHandle);
- bld_cpu_node(i_dt, cpusNode, l_core, pir, l_chipid, l2pHandle);
-
- rootNode = i_dt->findNode("/");
- bld_intr_node(i_dt, rootNode, l_core, pir);
- }
- }
-
- return errhdl;
-}
-
-errlHndl_t bld_fdt_reserved_mem(devTree * i_dt,
- std::vector<homerAddr_t>& i_homerRegions,
- bool i_smallTree)
-{
- errlHndl_t errhdl = NULL;
-
- // VPD
- uint64_t l_vpd_addr = 0;
-
- errhdl = VPD::vpd_load_rt_image(l_vpd_addr);
-
- // Targeting
- uint64_t l_targ_addr = l_vpd_addr;
- TARGETING::AttrRP::save(l_targ_addr);
-
- // HBRT image
- uint64_t l_hbrt_addr = l_targ_addr;
- load_hbrt_image(l_hbrt_addr);
-
-#ifdef CONFIG_TPMDD
- // TPM log
- uint64_t l_tpmlog_addr = l_hbrt_addr;
- uint64_t l_tpmlog_size = 0;
- load_tpmlog(i_dt, l_tpmlog_addr);
- l_tpmlog_size = l_hbrt_addr - l_tpmlog_addr;
- if (0 == l_tpmlog_size)
- {
- l_tpmlog_addr = 0;
- }
-#endif
-
- uint64_t l_extra_addrs[] = { l_vpd_addr, l_targ_addr, l_hbrt_addr
-#ifdef CONFIG_TPMDD
- ,l_tpmlog_addr
-#endif
- };
- uint64_t l_extra_sizes[] = { VMM_RT_VPD_SIZE,
- l_vpd_addr - l_targ_addr,
- l_targ_addr - l_hbrt_addr
-#ifdef CONFIG_TPMDD
- ,l_tpmlog_size
-#endif
- };
- const char* l_extra_addrs_str[] =
- { "ibm,hbrt-vpd-image" ,
- "ibm,hbrt-target-image",
- "ibm,hbrt-code-image"
-#ifdef CONFIG_TPMDD
- ,"ibm,tpmlog"
-#endif
- };
- size_t l_extra_addr_cnt = sizeof(l_extra_addrs) / sizeof(uint64_t);
-
- //Add in reserved memory for HOMER images and HBRT sections.
- add_reserved_mem(i_dt,
- i_homerRegions,
- l_extra_addrs,
- l_extra_sizes,
- l_extra_addrs_str,
- l_extra_addr_cnt);
-
- return errhdl;
-
-}
-
-errlHndl_t bld_fdt_mem(devTree * i_dt, bool i_smallTree)
-{
- // Nothing to do for small trees currently.
- if (i_smallTree) { return NULL; }
-
- errlHndl_t errhdl = NULL;
- bool rc;
-
- /*
- * The "memory" nodes represent physical memory in the system. They
- * do not represent DIMMs, memory controllers or Centaurs, thus will
- * be expressed separately.
- *
- * In order to be able to handle affinity propertly, we require that
- * a memory node is created for each range of memory that has a different
- * "affinity", which in practice means for each chip since we don't
- * support memory interleaved across multiple chips on P8.
- *
- * Additionally, it is *not* required that one chip = one memory node,
- * it is perfectly acceptable to break down the memory of one chip into
- * multiple memory nodes (typically skiboot does that if the two MCs
- * are not interlaved).
- */
-
- do
- {
- /* Find the / node and add a memory node(s) under it. */
- dtOffset_t rootNode = i_dt->findNode("/");
-
- // Grab a system object to work with
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
-
- // Get all functional proc chip targets
- TARGETING::TargetHandleList l_cpuTargetList;
- getAllChips(l_cpuTargetList, TYPE_PROC);
-
- for ( size_t proc = 0;
- (!errhdl) && (proc < l_cpuTargetList.size()); proc++ )
- {
- const TARGETING::Target * l_pProc = l_cpuTargetList[proc];
-
- uint64_t l_bases[8] = {0,};
- uint64_t l_sizes[8] = {0,};
- rc = l_pProc->tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_bases);
- if(!rc)
- {
- /*@
- * @errortype
- * @reasoncode DEVTREE::RC_ATTR_MEMBASE_GET_FAIL
- * @moduleid DEVTREE::MOD_DEVTREE_BLD_MEM
- * @userdata1 Return code from ATTR_GET
- * @userdata2 Attribute Id that failed
- * @devdesc Error retrieving attribute
- */
- errhdl=new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MOD_DEVTREE_BLD_MEM,
- RC_ATTR_MEMBASE_GET_FAIL,
- rc,
- ATTR_PROC_MEM_BASES);
- break;
- }
-
- rc = l_pProc->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>(l_sizes);
- if(!rc)
- {
- /*@
- * @errortype
- * @reasoncode DEVTREE::RC_ATTR_MEMSIZE_GET_FAIL
- * @moduleid DEVTREE::MOD_DEVTREE_BLD_MEM
- * @userdata1 Return code from ATTR_GET
- * @userdata2 Attribute Id that failed
- * @devdesc Error retrieving attribute
- */
- errhdl=new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MOD_DEVTREE_BLD_MEM,
- RC_ATTR_MEMSIZE_GET_FAIL,
- rc,
- ATTR_PROC_MEM_SIZES);
- break;
- }
-
- for (size_t i=0; i< 8; i++)
- {
- if(l_sizes[i]) //non zero means that there is memory present
- {
- dtOffset_t memNode = i_dt->addNode(rootNode, "memory",
- l_bases[i]);
- i_dt->addPropertyString(memNode, "device_type","memory");
- uint64_t propertyCells[2] = {l_bases[i],l_sizes[i]};
- i_dt->addPropertyCells64(memNode, "reg", propertyCells, 2);
-
- //Add the attached proc chip for affinity
- i_dt->addPropertyCell32(memNode, "ibm,chip-id",
- getProcChipId(l_pProc));
-
- }
- }
- }
-
- /***************************************************************/
- /* Now loop on all the centaurs in the system and add their */
- /* inband scom address */
- /***************************************************************/
- rootNode = i_dt->findNode("/");
-
- // Get all functional memb chip targets
- TARGETING::TargetHandleList l_memBufList;
- getAllChips(l_memBufList, TYPE_MEMBUF);
-
- for ( size_t memb = 0;
- (!errhdl) && (memb < l_memBufList.size()); memb++ )
- {
- TARGETING::Target * l_pMemB = l_memBufList[memb];
-
- //Get MMIO Offset from parent MCS attribute.
- PredicateCTM l_mcs(CLASS_UNIT,TYPE_MCS, MODEL_NA);
-
- TargetHandleList mcs_list;
- targetService().getAssociated(mcs_list,
- l_pMemB,
- TargetService::PARENT_BY_AFFINITY,
- TargetService::ALL,
- &l_mcs);
-
- if( mcs_list.size() != 1 )
- {
- //This error should have already been caught in
- //the inband Scom DD.... going to skip creating node
- //if true
- TRACFCOMP(g_trac_devtree,ERR_MRK" MCS for 0x%x not found",
- TARGETING::get_huid(l_pMemB));
- continue;
- }
- Target* parentMCS = *(mcs_list.begin());
- uint64_t l_ibscomBase =
- parentMCS->getAttr<ATTR_IBSCOM_MCS_BASE_ADDR>();
-
-
- dtOffset_t membNode = i_dt->addNode(rootNode, "memory-buffer",
- l_ibscomBase);
- uint64_t propertyCells[2] = {l_ibscomBase,THIRTYTWO_GB};
- i_dt->addPropertyCells64(membNode, "reg", propertyCells, 2);
- i_dt->addPropertyCell32(membNode, "#address-cells", 1);
- i_dt->addPropertyCell32(membNode, "#size-cells", 1);
-
- uint32_t l_ec = l_pMemB->getAttr<ATTR_EC>();
- char cenVerStr[32];
- snprintf(cenVerStr, 32, "ibm,centaur-v%.2x", l_ec);
- const char* intr_compatStrs[] = {"ibm,centaur", cenVerStr,NULL};
- i_dt->addPropertyStrings(membNode, "compatible", intr_compatStrs);
-
-
- if(l_pMemB->
- getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useInbandScom == 0x0)
- {
- i_dt->addProperty(membNode,"use-fsi");
- }
-
- //Add the attached proc chip for affinity
- uint32_t l_procId = getProcChipId(getParentChip(parentMCS));
- i_dt->addPropertyCell32(membNode, "ibm,fsi-master-chip-id",
- l_procId);
-
- uint32_t l_cenId = getMembChipId(l_pMemB);
- i_dt->addPropertyCell32(membNode, "ibm,chip-id",l_cenId);
-
- //Add the CMFSI (which CMFSI 0 or 1) and port
- FSI::FsiLinkInfo_t linkinfo;
- FSI::getFsiLinkInfo( l_pMemB, linkinfo );
- uint32_t cmfsiCells[2] =
- {linkinfo.mPort,linkinfo.link};
- i_dt->addPropertyCells32(membNode, "ibm,fsi-master-port",
- cmfsiCells, 2);
-
- //Add any I2C devices hanging off this chip
- add_i2c_info( l_pMemB, i_dt, membNode, l_ibscomBase);
-
- // Add membuf ECIDs
- ATTR_ECID_type ecid;
- l_pMemB->tryGetAttr<ATTR_ECID>(ecid);
- char ecid_ascii[33];
- sprintf(ecid_ascii, "%.16llX%.16llX", ecid[0], ecid[1]);
- i_dt->addPropertyString(membNode, "ecid", ecid_ascii);
- CPPASSERT(sizeof(ATTR_ECID_type) == 16);
- }
-
-
- }while(0);
- return errhdl;
-}
-
-
-#ifdef CONFIG_BMC_IPMI
-enum
-{
- ENTITY_ID_MASK = 0x00FF,
- SENSOR_TYPE_MASK = 0xFF00,
-};
-
-/* create a node for each IPMI sensor in the system, the sensor unit number
- corresponds to the BMC assigned sensor number */
-uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_parentNode,
- const uint16_t sensorData[],
- uint32_t instance, uint32_t chipId )
-{
-
- SENSOR::sensorReadingType readType;
-
- // pass in the sensor name to get back the supported offsets and the event
- // reading type for this sensor.
- uint32_t offsets = SENSOR::getSensorOffsets(
- static_cast<TARGETING::SENSOR_NAME>(
- sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET]),
- readType);
-
- const uint16_t sensorNumber = sensorData[
- TARGETING::IPMI_SENSOR_ARRAY_NUMBER_OFFSET];
-
- // the sensor name is a combination of the sensor type + entity ID
- const uint16_t sensorType = (
- sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET]
- & SENSOR_TYPE_MASK) >> 8;
-
- const uint16_t entityId =
- sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET] & ENTITY_ID_MASK;
-
- /* Build sensor node based on sensor number */
- dtOffset_t sensorNode = i_dt->addNode(i_parentNode, "sensor", sensorNumber);
-
- /* compatibility strings -- currently only one */
- const char* compatStr[] = {"ibm,ipmi-sensor", NULL};
-
- i_dt->addPropertyStrings(sensorNode, "compatible", compatStr);
-
- i_dt->addPropertyCell32(sensorNode, "reg", sensorNumber);
-
- // add sensor type
- i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-type", sensorType);
- i_dt->addPropertyCell32(sensorNode, "ipmi-entity-id", entityId);
- i_dt->addPropertyCell32(sensorNode, "ipmi-entity-instance", instance);
- i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-offsets", offsets);
- i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-reading-type", readType);
-
- // currently we only add the chip ID to the OCC sensor
- if(chipId != 0xFF )
- {
- i_dt->addPropertyCell32(sensorNode, "ibm,chip-id", chipId);
- }
-
- /* return the phandle for this sensor */
- return i_dt->getPhandle(sensorNode);
-}
-
-
-// build the sensor node for a given target
-uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_sensorNode,
- TARGETING::Target * i_pTarget )
-{
-
- AttributeTraits<ATTR_IPMI_SENSORS>::Type l_sensors;
- uint16_t array_rows = (sizeof(l_sensors)/sizeof(l_sensors[0]));
-
- /* if there is an IPMI_SENSORS attribute, parse it and create a node
- * for each sensor */
- if ( i_pTarget->tryGetAttr<ATTR_IPMI_SENSORS>(l_sensors) )
- {
- uint32_t chipId = 0xFF;
-
- AttributeTraits<ATTR_IPMI_INSTANCE>::Type l_instance;
-
- l_instance = i_pTarget->getAttr<TARGETING::ATTR_IPMI_INSTANCE>();
-
- // add the chip id to the OCC sensor since OPAL needs it to figure out
- // which OCC it is.
- if( TARGETING::TYPE_OCC == i_pTarget->getAttr<TARGETING::ATTR_TYPE>())
- {
- ConstTargetHandle_t proc = getParentChip(i_pTarget);
-
- chipId = getProcChipId( proc );
- }
-
- for(uint16_t i=0; i< array_rows; i++)
- {
- /* if the sensor number is 0xFF move on */
- if( l_sensors[i][IPMI_SENSOR_ARRAY_NUMBER_OFFSET] != 0xFF )
- {
- /* use this row to create the next sensor node - ignoring
- * return value for now */
- bld_sensor_node(i_dt, i_sensorNode, l_sensors[i],
- l_instance , chipId );
- }
- else
- {
- /* move on to the next target */
- break;
- }
- }
- }
-
- // return the phandle
- return i_dt->getPhandle(i_sensorNode);
-}
-
-
-/*
-* The "sensors" node contains sub-nodes for each of the IPMI sensors known to
-* the BMC.
-*/
-errlHndl_t bld_fdt_sensors(devTree * i_dt, const dtOffset_t & i_parentNode,
- const bool i_smallTree)
-{
- errlHndl_t errhdl = NULL;
-
- /* Nothing to do for small trees currently. */
- if (i_smallTree) { return NULL; }
-
- const char* sensorNodeName = "sensors";
-
- /* add the Sensors node to the BMC node */
- dtOffset_t sensorNode = i_dt->addNode(i_parentNode, sensorNodeName);
-
- i_dt->addPropertyString(sensorNode, "name", sensorNodeName );
-
- /* Add the # address & size cell properties to /sensors node. */
- i_dt->addPropertyCell32(sensorNode, "#address-cells", 1);
- i_dt->addPropertyCell32(sensorNode, "#size-cells", 0);
-
- /* loop through all the targets and get the IPMI sensor data if it
- exists */
- for (TargetIterator itr = TARGETING::targetService().begin();
- itr != TARGETING::targetService().end(); ++itr)
- {
- /* create node entries for this targets sensors if they exist
- * ignoring return value for now */
- bld_sensor_node(i_dt, sensorNode, *itr );
- }
-
- return errhdl;
-}
-
-/* add the BMC node to the device tree, this node will hold any BMC info needed
- in the device tree */
-errlHndl_t bld_fdt_bmc(devTree * i_dt, bool i_smallTree)
-{
- errlHndl_t errhdl = NULL;
-
- /* Nothing to do for small trees currently. */
- if (i_smallTree) { return NULL; }
-
- /* Find the root node. */
- dtOffset_t rootNode = i_dt->findNode("/");
-
- const char* bmcNodeName = "bmc";
-
- /* add the BMC node under the root node */
- dtOffset_t bmcNode = i_dt->addNode(rootNode, bmcNodeName);
-
- /* Add the # address & size cell properties to /bmc node. */
- i_dt->addPropertyCell32(bmcNode, "#address-cells", 1);
- i_dt->addPropertyCell32(bmcNode, "#size-cells", 0);
-
- i_dt->addPropertyString(bmcNode, "name", bmcNodeName );
-
- /* create a node to hold the sensors */
- errhdl = bld_fdt_sensors( i_dt, bmcNode, i_smallTree );
-
- return errhdl;
-}
-#endif
-
-errlHndl_t bld_fdt_vpd(devTree * i_dt, bool i_smallTree)
-{
- // Nothing to do for small trees currently.
- if (i_smallTree) { return NULL; }
-
- errlHndl_t errhdl = NULL;
- size_t vpdSize;
-
- do
- {
- /* Find the / node and add a vpd node under it. */
- dtOffset_t rootNode = i_dt->findNode("/");
- dtOffset_t vpdNode = i_dt->addNode(rootNode, "vpd");
-
- // Grab a system object to work with
- TARGETING::Target* sys = NULL;
- TARGETING::targetService().getTopLevelTarget(sys);
-
-
- /***************************************************************/
- /* Add the ibm,vpd for all functional procs */
- /***************************************************************/
- // Add vpd (VINI record) for all functional procs
- // and #V for all functional cores
- TARGETING::TargetHandleList l_cpuTargetList;
- getAllChips(l_cpuTargetList, TYPE_PROC);
-
- for ( size_t proc = 0;
- (!errhdl) && (proc < l_cpuTargetList.size()); proc++ )
- {
- TARGETING::Target * l_pProc = l_cpuTargetList[proc];
-
- uint32_t l_procId = getProcChipId(l_pProc);
- dtOffset_t procNode = i_dt->addNode(vpdNode, "processor",
- l_procId);
-
- // Read entire VINI record to stuff in devtree
- // Note: First read with NULL for o_buffer sets vpdSize to the
- // correct length
- errhdl = deviceRead( l_pProc,
- NULL,
- vpdSize,
- DEVICE_MVPD_ADDRESS( MVPD::VINI,
- MVPD::FULL_RECORD ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get VINI size for HUID=0x%.8X",
- TARGETING::get_huid(l_pProc));
- break;
- }
-
- uint8_t viniBuf[vpdSize];
-
- errhdl = deviceRead( l_pProc,
- reinterpret_cast<void*>( &viniBuf ),
- vpdSize,
- DEVICE_MVPD_ADDRESS( MVPD::VINI,
- MVPD::FULL_RECORD ));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read VINI for HUID=0x%.8X",
- TARGETING::get_huid(l_pProc));
- break;
- }
-
- //Add the proc chips vpd
- i_dt->addPropertyBytes(procNode, "ibm,vpd", viniBuf, vpdSize);
-
- /***************************************************************/
- /* Add the #V bucket for each functional core */
- /***************************************************************/
-
- //@TODO RTC:143092
-#if 0
- TARGETING::TargetHandleList l_corelist;
- fapi::Target l_pFapiProc(fapi::TARGET_TYPE_PROC_CHIP,
- (const_cast<TARGETING::Target*>(l_pProc) ));
-
- getChildChiplets( l_corelist, l_pProc, TYPE_CORE );
- for (size_t core = 0; core < l_corelist.size(); core++)
- {
- const TARGETING::Target * l_core = l_corelist[core];
-
- uint32_t l_coreNum =
- l_core->getAttr<TARGETING::ATTR_CHIP_UNIT>();
- PIR_t pir(0);
- pir.groupId = PIR_t::groupFromChipId(l_procId);
- pir.chipId = PIR_t::chipFromChipId(l_procId);
- pir.coreId = l_coreNum;
-
- // Get #V bucket data
- uint32_t l_record = (uint32_t) MVPD::LRP0 + l_coreNum;
- fapi::voltageBucketData_t l_poundVdata = {0};
- fapi::ReturnCode l_rc = fapiGetPoundVBucketData(l_pFapiProc,
- l_record,
- l_poundVdata);
- if(l_rc)
- {
- TRACFCOMP( g_trac_devtree,ERR_MRK"Error getting #V data for HUID:"
- "0x%08X",
- l_pProc->getAttr<TARGETING::ATTR_HUID>());
-
- // Convert fapi returnCode to Error handle
- errhdl = fapiRcToErrl(l_rc);
- break;
- }
-
- //Add the attached core
- dtOffset_t coreNode = i_dt->addNode(procNode, "cpu",
- pir.word);
-
- i_dt->addPropertyBytes(coreNode, "frequency,voltage",
- reinterpret_cast<uint8_t*>( &l_poundVdata),
- sizeof(fapi::voltageBucketData_t));
- }
- if(errhdl)
- {
- break;
- }
-#endif
- }
- if(errhdl)
- {
- break;
- }
-
-#if 0 //TODO RTC123250 -- re-enable once fixed
- /***************************************************************/
- /* Now loop on all the dimms in the system and add their spd */
- /***************************************************************/
-
- // Get all functional dimm targets
- TARGETING::TargetHandleList l_dimmList;
- getAllLogicalCards(l_dimmList, TYPE_DIMM);
- size_t spdSize;
-
- for ( size_t dimm = 0;
- (!errhdl) && (dimm < l_dimmList.size()); dimm++ )
- {
- TARGETING::Target * l_pDimm = l_dimmList[dimm];
- uint32_t l_huid = TARGETING::get_huid(l_pDimm);
-
- dtOffset_t dimmNode = i_dt->addNode(vpdNode, "dimm",
- l_huid);
-
- // Read entire SPD record to stuff in devtree
- // Note: First read with NULL for o_buffer sets spdSize to the
- // correct length
- errhdl = deviceRead( l_pDimm,
- NULL,
- spdSize,
- DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get SPD size for HUID=0x%.8X",
- TARGETING::get_huid(l_pDimm));
- break;
- }
-
- uint8_t spdBuf[spdSize];
-
- errhdl = deviceRead( l_pDimm,
- reinterpret_cast<void*>( &spdBuf ),
- spdSize,
- DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD));
-
- if(errhdl)
- {
- TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read SPD for HUID=0x%.8X",
- TARGETING::get_huid(l_pDimm));
- break;
- }
-
- //Add the dimm spd
- i_dt->addPropertyBytes(dimmNode, "spd", spdBuf, spdSize);
- }
- if(errhdl)
- {
- break;
- }
-#endif
-
- }while(0);
-
- return errhdl;
-}
-
-errlHndl_t bld_fdt_secureboot(devTree * i_dt, bool i_smallTree)
-{
- // Nothing to do for small trees currently.
- if (i_smallTree) { return NULL; }
-
- errlHndl_t errhdl = NULL;
-
- do
- {
- /* Find the / node and add a secureboot node under it. */
- dtOffset_t rootNode = i_dt->findNode("/");
-
- dtOffset_t secBootNode = i_dt->addNode(rootNode, "ibm,secureboot");
- sha2_hash_t hw_key_hash;
- SECUREBOOT::getHwKeyHash(hw_key_hash);
-
- i_dt->addPropertyBytes(secBootNode, "hw-key-hash",
- reinterpret_cast<uint8_t*>(hw_key_hash),
- sizeof(hw_key_hash));
-
- i_dt->addPropertyString(secBootNode, "hash-algo", "sha512");
-
- /* compatibility strings -- currently only one */
- const char* compatStr[] = {"ibm,secureboot-v1", NULL};
- i_dt->addPropertyStrings(secBootNode, "compatible", compatStr);
-
- if (SECUREBOOT::enabled())
- {
- i_dt->addProperty(secBootNode, "secure-enabled");
- }
-#ifdef CONFIG_TPMDD
- if (TRUSTEDBOOT::enabled())
- {
- i_dt->addProperty(secBootNode, "trusted-enabled");
- }
-#endif
-
- } while(0);
-
- return errhdl;
-}
-
-errlHndl_t build_flatdevtree( uint64_t i_dtAddr, size_t i_dtSize,
- bool i_smallTree )
-{
- errlHndl_t errhdl = NULL;
- devTree * dt = &Singleton<devTree>::instance();
- bool devTreeVirtual = true;
-
- do
- {
- if (0 == i_dtAddr)
- {
- i_dtAddr = DEVTREE_DATA_ADDR;
- i_dtSize = DEVTREE_SPACE_SIZE;
- devTreeVirtual = false;
- }
-
- TRACFCOMP( g_trac_devtree, "---devtree init---" );
- dt->initialize(i_dtAddr, i_dtSize, devTreeVirtual);
- errhdl = bld_fdt_system(dt, i_smallTree);
- if (errhdl)
- {
- break;
- }
-
- std::vector<homerAddr_t> l_homerRegions;
-
- TRACFCOMP( g_trac_devtree, "---devtree cpu ---" );
- errhdl = bld_fdt_cpu(dt, l_homerRegions, i_smallTree);
- if(errhdl)
- {
- break;
- }
-
-#ifndef CONFIG_DISABLE_HOSTBOOT_RUNTIME
- TRACFCOMP( g_trac_devtree, "---devtree reserved mem ---" );
- errhdl = bld_fdt_reserved_mem(dt, l_homerRegions, i_smallTree);
- if(errhdl)
- {
- break;
- }
-#endif
- TRACFCOMP( g_trac_devtree, "---devtree mem ---" );
- errhdl = bld_fdt_mem(dt, i_smallTree);
- if(errhdl)
- {
- break;
- }
-
-#ifdef CONFIG_BMC_IPMI
- TRACFCOMP( g_trac_devtree, "---devtree BMC ---" );
- errhdl = bld_fdt_bmc(dt, i_smallTree);
- if(errhdl)
- {
- break;
- }
-#endif
-
- TRACFCOMP( g_trac_devtree, "---devtree vpd ---" );
- errhdl = bld_fdt_vpd(dt, i_smallTree);
- if(errhdl)
- {
- break;
- }
-
- TRACFCOMP( g_trac_devtree, "---devtree secureboot ---" );
- errhdl = bld_fdt_secureboot(dt, i_smallTree);
- if(errhdl)
- {
- break;
- }
- }while(0);
-
- return errhdl;
-}
-
-
-uint64_t get_flatdevtree_phys_addr()
-{
- return Singleton<devTree>::instance().getBlobPhys();
-}
-
-}
OpenPOWER on IntegriCloud