Skip to content

Commit

Permalink
Add API to get OCMB's mmio information, used to build HDAT
Browse files Browse the repository at this point in the history
This API will take in an OCMB TARGETING::Target and return a vector
of structs where each struct contains information about a memory mapped
io space associated with the OCMB target. This commit also moves the
function that sets up the runtime target ID attribute on all the targets
from the populate runtime code to host discover targets, which is much
earlier in the IPL.

Change-Id: Id0b1a0ba532a10435f983f72ec769fed3e7320a5
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/89959
Reviewed-by: Jayashankar Padath <jayashankar.padath@in.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
  • Loading branch information
crgeddes authored and dcrowell77 committed Feb 28, 2020
1 parent 288f7ba commit 7866a7c
Show file tree
Hide file tree
Showing 10 changed files with 552 additions and 61 deletions.
3 changes: 2 additions & 1 deletion src/include/usr/isteps/istep06list.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* Contributors Listed Below - COPYRIGHT 2012,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -235,6 +235,7 @@ const DepModInfo g_istep06Dependancies = {
DEP_LIB(libimageprocs.so),
DEP_LIB(libp9_cpuWkup.so),
DEP_LIB(libisteps_nest.so),
DEP_LIB(libruntime.so),
NULL
}
};
Expand Down
35 changes: 32 additions & 3 deletions src/include/usr/targeting/common/hbrt_target.H
Expand Up @@ -25,20 +25,49 @@
#ifndef __HBRT_TARGET_H
#define __HBRT_TARGET_H

#include <errl/errlentry.H>
#include <targeting/common/error.H>

namespace TARGETING
{
typedef uint64_t rtChipId_t;

struct ocmbMmioAddressRange_t {
rtChipId_t hbrtId; // Keep hbrtId as the first member of this struct
// there is some tricky casting that depends on this
uint64_t mmioBaseAddr;
uint64_t mmioEndAddr;
uint8_t accessSize;

ocmbMmioAddressRange_t() :
hbrtId(0), mmioBaseAddr(0), mmioEndAddr(0), accessSize(4)
{}

ocmbMmioAddressRange_t(uint64_t id, uint64_t start_addr, uint64_t end_addr, uint8_t io_size) :
hbrtId(id), mmioBaseAddr(start_addr), mmioEndAddr(end_addr), accessSize(io_size)
{}
} __attribute__((packed));

/**
* @brief Convert a TARGETING::Target to an unit ID that can be used
* in calls to the runtime host
* @param[in] The HB TARGETING::Target
* @param[out] Sapphire target id
* @param[out] Hypervisor target id
* @return an error handle on error
*/
errlHndl_t getRtTarget(const TARGETING::Target* i_target,
rtChipId_t &o_targetId);
rtChipId_t &o_targetId);

/**
* @brief Takes a TARGETING::Target and passes back a vector of ocmbMmioAddressRange_t
* structs, one for each memory mapped i/o space associated with a given memory
* target.
* @param[in] The HB Memory TARGETING::Target
* @param[out] Vector of structs representing the mmio spaces associated with
* the given memory target
* @return an error handle on error
*/
errlHndl_t getMemTargetMmioInfo ( TARGETING::Target * i_memTarget,
std::vector<TARGETING::ocmbMmioAddressRange_t>& o_ocmbMmioSpaces);

}

Expand Down
16 changes: 15 additions & 1 deletion src/usr/isteps/istep06/host_discover_targets.C
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
Expand Down Expand Up @@ -55,6 +55,7 @@
#endif
#include <fapi2/plat_hwp_invoker.H>
#include <fapi2/target.H>
#include <runtime/customize_attrs_for_payload.H>

//SBE interfacing
#include <sbeio/sbeioif.H>
Expand Down Expand Up @@ -681,6 +682,19 @@ void* host_discover_targets( void *io_pArgs )
errlCommit( l_err, ISTEP_COMP_ID );
}

// Now that we have all of the targets set up we can assign HBRT ids
// to all of the targets. These are the IDs the Hypervisors use to ID
// a given target. We set them up now because we want to make sure the
// attribute is set long before HDAT code consumes them.
l_err = RUNTIME::configureHbrtHypIds(TARGETING::is_phyp_load());
if(l_err)
{
// Create IStep error log and cross reference occurred error
l_stepError.addErrorDetails( l_err );
// Commit Error
errlCommit (l_err, ISTEP_COMP_ID);
}

TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"host_discover_targets exit" );

Expand Down
39 changes: 21 additions & 18 deletions src/usr/mmio/mmio.C
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -105,7 +105,7 @@ errlHndl_t mmioSetup()
l_mcTarget->getAttr<ATTR_CHIP_UNIT>();

// Get the base BAR address for OpenCapi Memory Interfaces (OMIs) of this Memory Controller (MC)
auto l_omiBaseAddr =
auto l_mcBaseOffset =
l_mcTarget->getAttr<ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET>();

// Build up the full address with group/chip address considerations
Expand All @@ -115,21 +115,21 @@ errlHndl_t mmioSetup()
l_parentChip->getAttr<ATTR_PROC_EFF_FABRIC_GROUP_ID>();
uint8_t l_chipId =
l_parentChip->getAttr<ATTR_PROC_EFF_FABRIC_CHIP_ID>();
uint64_t l_realAddr = computeMemoryMapOffset( MMIO_BASE,
uint64_t l_physMcAddr = computeMemoryMapOffset( MMIO_BASE,
l_groupId,
l_chipId );

// Apply the MMIO base offset so we get the final address
l_realAddr += l_omiBaseAddr;
l_physMcAddr += l_mcBaseOffset;

// Map the device with a kernel call, each device, the MC, is 32 GB
uint64_t l_virtAddr = reinterpret_cast<uint64_t>
(mmio_dev_map(reinterpret_cast<void *>(l_realAddr),
uint64_t l_virtMcAddr = reinterpret_cast<uint64_t>
(mmio_dev_map(reinterpret_cast<void *>(l_physMcAddr),
THIRTYTWO_GB));

TRACFCOMP ( g_trac_mmio, "MC%.02X (0x%.08X) MMIO BAR PHYSICAL ADDR = 0x%lX VIRTUAL ADDR = 0x%lX" ,
l_mcChipUnit ? 0x23 : 0x01, get_huid(l_mcTarget),
l_realAddr, l_virtAddr);
l_physMcAddr, l_virtMcAddr);

// set VM_ADDR on each OCMB
TargetHandleList l_omiTargetList;
Expand Down Expand Up @@ -160,22 +160,23 @@ errlHndl_t mmioSetup()
// +-----+--------------------+------+-----------------------------------------+------+-------

// Calculate CNFG space BAR to write to OCMB attribute
uint64_t l_currentOmiOffset = (( l_omiPosRelativeToMc / 2) * 8 * GIGABYTE) +
uint64_t l_omiOffsetRelativeToMc = (( l_omiPosRelativeToMc / 2) * 8 * GIGABYTE) +
(( l_omiPosRelativeToMc % 2) * 2 * GIGABYTE);

// Calculated real address for this OMI is (BAR from MC attribute) + (currentOmiOffset)
uint64_t l_calulatedRealAddr = l_omiBaseAddr + l_currentOmiOffset;
// Calculate the MC mmio offset + the current OMI offset and this should match
// the ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET value set on the OMI target
uint64_t l_totalMmioOffset = l_mcBaseOffset + l_omiOffsetRelativeToMc;

// Grab bar value from attribute to verify it matches
// our calculations
auto l_omiBarAttrVal = l_omiTarget->
auto l_omiOffsetAttrVal = l_omiTarget->
getAttr<ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET>();

if(l_omiBarAttrVal != l_calulatedRealAddr)
if(l_omiOffsetAttrVal != l_totalMmioOffset)
{
TRACFCOMP(g_trac_mmio,
"Discrepancy found between calculated OMI MMIO bar offset and what we found in ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET");
TRACFCOMP(g_trac_mmio, "Calculated Offset: 0x%lX, Attribute Value : 0x%lX", l_calulatedRealAddr, l_omiBarAttrVal);
TRACFCOMP(g_trac_mmio, "Calculated Offset: 0x%lX, Attribute Value : 0x%lX", l_totalMmioOffset, l_omiOffsetAttrVal);

/*@
* @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
Expand All @@ -191,8 +192,8 @@ errlHndl_t mmioSetup()
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MMIO::MOD_MMIO_SETUP,
MMIO::RC_BAR_OFFSET_MISMATCH,
l_calulatedRealAddr,
l_omiBarAttrVal,
l_totalMmioOffset,
l_omiOffsetAttrVal,
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
l_err->collectTrace( MMIO_COMP_NAME);
ERRORLOG::ErrlUserDetailsTarget(l_omiTarget).addToLog(l_err);
Expand All @@ -201,9 +202,9 @@ errlHndl_t mmioSetup()
}


uint64_t l_currentOmiVirtAddr = l_virtAddr + l_currentOmiOffset;
uint64_t l_currentOmiVirtAddr = l_virtMcAddr + l_omiOffsetRelativeToMc;

// set VM_ADDR the associated OCMB
// set ATTR_MMIO_VM_ADDR and ATTR_MMIO_PHYS_ADDR the associated OCMB
TargetHandleList l_ocmbTargetList;
getChildAffinityTargets(l_ocmbTargetList, l_omiTarget,
CLASS_CHIP, TYPE_OCMB_CHIP);
Expand All @@ -215,10 +216,12 @@ errlHndl_t mmioSetup()
" address is 0x%lX",
get_huid(l_ocmbTargetList[0]),
l_currentOmiVirtAddr,
l_calulatedRealAddr | MMIO_BASE );
l_physMcAddr + l_omiOffsetRelativeToMc );

l_ocmbTargetList[0]->
setAttr<ATTR_MMIO_VM_ADDR>(l_currentOmiVirtAddr);
l_ocmbTargetList[0]->
setAttr<ATTR_MMIO_PHYS_ADDR>(l_physMcAddr + l_omiOffsetRelativeToMc);
}
}
} while(0);
Expand Down
28 changes: 0 additions & 28 deletions src/usr/runtime/populate_hbruntime.C
Expand Up @@ -1107,21 +1107,6 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node)
assert(l_sys != nullptr,
"populate_HbRsvMem: top level target nullptr" );

// Configure the ATTR_HBRT_HYP_ID attributes so that runtime code and
// whichever hypervisor is loaded can reference equivalent targets
// When populating hbRuntimeData, we make IPC calls if we are running
// on a multi-node configuration. The message handler for that IPC call,
// calls populateHbRsvMem. We want to setup hbrt target types for all
// the nodes. That's why, we moved this call here instead of directly
// calling it from istep21.
l_elog = RUNTIME::configureHbrtHypIds(TARGETING::is_phyp_load());
if (l_elog)
{
TRACFCOMP(g_trac_runtime, ERR_MRK"populate_HbRsvMem> i_nodeId=%d"
" configureHbrtHypIds failed");
break;
}

// Wipe out our cache of the NACA/SPIRA pointers
RUNTIME::rediscover_hdat();

Expand Down Expand Up @@ -3483,19 +3468,6 @@ errlHndl_t populate_hbRuntimeData( void )
}
else
{
//When PAYLOAD_KIND = NONE (aka simics)
//Configure the ATTR_HBRT_HYP_ID attributes
//When PAYLOAD_KIND is set, we call this function from
//populate_HbRsvMem as that function is also executed on slave
//nodes in a multi-node config. But, moving it there removes
//this call in simics case. Therefore, adding it here.
l_elog = RUNTIME::configureHbrtHypIds(TARGETING::is_phyp_load());
if (l_elog)
{
TRACFCOMP(g_trac_runtime, ERR_MRK"populate_HbRsvMem> i_nodeId=%d"
" configureHbrtHypIds failed");
break;
}
// still fill in HB DATA for testing
uint64_t l_startAddr = cpu_spr_value(CPU_SPR_HRMOR) +
VMM_HB_DATA_TOC_START_OFFSET;
Expand Down
64 changes: 59 additions & 5 deletions src/usr/targeting/common/hbrt_target.C
Expand Up @@ -22,6 +22,8 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

#include <limits.h>
#include <targeting/common/hbrt_target.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/targreasoncodes.H>
Expand Down Expand Up @@ -60,11 +62,10 @@ errlHndl_t getRtTarget(
auto huid = get_huid(i_pTarget);
auto targetingTargetType =
i_pTarget->getAttr<TARGETING::ATTR_TYPE>();
TRACFCOMP(g_trac_targeting, ERR_MRK
"Targeting target type of 0x%08X not supported. "
"HUID: 0x%08X",
targetingTargetType,
huid);
TARG_ERR("getRtTarget: Targeting target type of 0x%08X not supported. "
"HUID: 0x%08X",
targetingTargetType,
huid);
/*@
* @errortype
* @moduleid TARG_RT_GET_RT_TARGET
Expand Down Expand Up @@ -98,4 +99,57 @@ errlHndl_t getRtTarget(
return pError;
}

errlHndl_t getMemTargetMmioInfo ( TARGETING::Target * i_memTarget,
std::vector<TARGETING::ocmbMmioAddressRange_t>& o_ocmbMmioSpaces)
{
errlHndl_t l_err;

do{
TARGETING::ocmbMmioAddressRange_t l_tmpRange;
TARGETING::ATTR_TYPE_type l_targetType = i_memTarget->getAttr<TARGETING::ATTR_TYPE>();

assert(l_targetType == TARGETING::TYPE_OCMB_CHIP,
"Target type % passed to getMemTargetMmioInfo."
" Currently this function only supports TYPE_OCMB_CHIP",
l_targetType);

// We need to store in a local variable initially because we cannot
// pass a ptr to the getRtTarget member of the packed ocmbMmioAddressRange_t struct
rtChipId_t l_hbrtId;
l_err = TARGETING::getRtTarget(i_memTarget, l_hbrtId);
if(l_err)
{
break;
}
l_tmpRange.hbrtId = l_hbrtId;

TARGETING::ATTR_MMIO_PHYS_ADDR_type l_ocmbBaseMmioPhysAddr =
i_memTarget->getAttr<TARGETING::ATTR_MMIO_PHYS_ADDR>();

assert(l_ocmbBaseMmioPhysAddr != 0,
"0 returned for physical address of OCMB's MMIO space. MMIO map probably isn't set up yet.");

// CONFIG space ( 2 GB )
l_tmpRange.mmioBaseAddr = l_ocmbBaseMmioPhysAddr;
l_tmpRange.mmioEndAddr = l_tmpRange.mmioBaseAddr + (2 * GIGABYTE) - 1;
l_tmpRange.accessSize = 4;
o_ocmbMmioSpaces.push_back(l_tmpRange);

// Microchip Scom Access Space ( 128 MB )
l_tmpRange.mmioBaseAddr = l_ocmbBaseMmioPhysAddr + (4 * GIGABYTE);
l_tmpRange.mmioEndAddr = l_tmpRange.mmioBaseAddr + (128 * MEGABYTE) - 1;
l_tmpRange.accessSize = 4;
o_ocmbMmioSpaces.push_back(l_tmpRange);

// IBM Scom Access Space ( 16 MB )
l_tmpRange.mmioBaseAddr = l_ocmbBaseMmioPhysAddr + (4 * GIGABYTE) + (128 * MEGABYTE);
l_tmpRange.mmioEndAddr = l_tmpRange.mmioBaseAddr + (16 * MEGABYTE) - 1;
l_tmpRange.accessSize = 8;
o_ocmbMmioSpaces.push_back(l_tmpRange);

}while(0);

return l_err;
}

}
15 changes: 15 additions & 0 deletions src/usr/targeting/common/xmltohb/attribute_types_hb.xml
Expand Up @@ -935,6 +935,21 @@
<writeable/>
</attribute>

<attribute>
<id>MMIO_PHYS_ADDR</id>
<description>
Physical memory address this device has been mapped to.
</description>
<simpleType>
<uint64_t>
<default>0</default>
</uint64_t>
</simpleType>
<persistency>volatile-zeroed</persistency>
<readable/>
<writeable/>
</attribute>

<attribute>
<id>MMIO_VM_ADDR</id>
<description>
Expand Down
4 changes: 4 additions & 0 deletions src/usr/targeting/common/xmltohb/target_types_hb.xml
Expand Up @@ -92,6 +92,10 @@
<attribute>
<id>IBSCOM_MUTEX</id>
</attribute>
<attribute>
<default>0</default>
<id>MMIO_PHYS_ADDR</id>
</attribute>
<attribute>
<default>0</default>
<id>MMIO_VM_ADDR</id>
Expand Down
7 changes: 5 additions & 2 deletions src/usr/targeting/test/makefile
Expand Up @@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
# Contributors Listed Below - COPYRIGHT 2011,2019
# Contributors Listed Below - COPYRIGHT 2011,2020
# [+] International Business Machines Corp.
#
#
Expand Down Expand Up @@ -55,7 +55,10 @@ HWPF_REL_PATH = ${ROOTPATH}/src/include/usr/hwpf
EXTRAINCDIR += \
$(addprefix ${HWPF_REL_PATH}/, ${HWPF_INC_DIRS}) \
${ROOTPATH}/src/include/usr/ecmddatabuffer \
../
../ \
${ROOTPATH}/obj/genfiles/ \
${ROOTPATH}/src/import/hwpf/fapi2/include/ \
${ROOTPATH}/src/include/usr/fapi2/

# Generate the test suite

Expand Down

0 comments on commit 7866a7c

Please sign in to comment.