Skip to content

Commit

Permalink
Update PG detection for new Axone memory targets
Browse files Browse the repository at this point in the history
Add support for presence detection of new OMI, OMIC, and MCC targets.
Detection is done by looking at the MC01, and MC23 PG data.

Change-Id: I2706bb28f64df653546ce22451e690507be09d8e
RTC: 197541
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64966
Tested-by: Jenkins Server <pfd-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>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
  • Loading branch information
crgeddes authored and wghoffa committed Sep 5, 2018
1 parent 2c8610b commit e82098f
Show file tree
Hide file tree
Showing 3 changed files with 271 additions and 13 deletions.
9 changes: 7 additions & 2 deletions src/include/usr/hwas/common/hwasCommon.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* Contributors Listed Below - COPYRIGHT 2012,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -178,7 +178,12 @@ const uint32_t VPD_CP00_PG_XBUS_GOOD_CUMULUS= 0xE00D;
const uint32_t VPD_CP00_PG_XBUS_PG_MASK = 0x00170;
const uint32_t VPD_CP00_PG_XBUS_IOX[3] = {0x0040, 0x0020, 0x0010};

const uint32_t VPD_CP00_PG_MCxx_INDEX[4] = {7, 7, 8, 8}; // by MCS
const uint32_t VPD_CP00_PG_MC01_INDEX = 7;
const uint32_t VPD_CP00_PG_MC23_INDEX = 8;
const uint32_t VPD_CP00_PG_MCxx_INDEX[4] = {VPD_CP00_PG_MC01_INDEX,
VPD_CP00_PG_MC01_INDEX,
VPD_CP00_PG_MC23_INDEX,
VPD_CP00_PG_MC23_INDEX}; // by MCS
// Nimbus:
// all good - 3:VITAL, 4:PRV, 5:MC01, 6:IOM01+, 7:IOM23+, 14:PLLMEM
// all good - 3:VITAL, 4:PRV, 5:MC23, 6:IOM45+, 7:IOM67+, 14:PLLMEM
Expand Down
45 changes: 34 additions & 11 deletions src/usr/hwas/common/hwas.C
Original file line number Diff line number Diff line change
Expand Up @@ -1422,35 +1422,58 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
l_descFunctional = false;
}
}
else // MC/MI/DMI is found on Cumulus chips
// MC/MI/DMI is found on Cumulus chips
else // MC/MI/MCC/OMI/OMIC is found on Axone chips
if ((i_desc->getAttr<ATTR_TYPE>() == TYPE_MC) ||
(i_desc->getAttr<ATTR_TYPE>() == TYPE_MI) ||
(i_desc->getAttr<ATTR_TYPE>() == TYPE_DMI))
(i_desc->getAttr<ATTR_TYPE>() == TYPE_DMI) ||
(i_desc->getAttr<ATTR_TYPE>() == TYPE_MCC) ||
(i_desc->getAttr<ATTR_TYPE>() == TYPE_OMIC) ||
(i_desc->getAttr<ATTR_TYPE>() == TYPE_OMI))
{
ATTR_CHIP_UNIT_type index =
i_desc->getAttr<ATTR_CHIP_UNIT>();

// ** Cumulus **
// 2 MCs/chip, 2 MIs/MC, 2 DMIs/MI
// ** Axone **
// 2 MCs/chip, 2 MIs/MC, 2 MCCs/MI, 2 OMIs/MCC
// 3 OMICs/MC
size_t indexMC = 0;
size_t indexMI = 0;

if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MC)
{
indexMC = index;
indexMI = index * 2;
indexMC = index;
}
else
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MI)
{
indexMI = index;
indexMC = index / 2;
indexMC = index / 2;
}
else
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_DMI)
{
indexMI = index / 2;
indexMC = index / 4;
}
else
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCC)
{
indexMC = index / 4;
}
else
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_OMIC)
{
indexMC = index / 3;
}
else
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_OMI)
{
indexMC = index / 8;
}

// if indexMC == 1 , then use MC23 PG Index
// if indexMC == 0 , then use MC01 PG Index
size_t mcPgIndex = indexMC ? VPD_CP00_PG_MC23_INDEX : VPD_CP00_PG_MC01_INDEX;

// Check MCS01 bit in N3 entry if first MC
if ((0 == indexMC) &&
Expand Down Expand Up @@ -1483,14 +1506,14 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
}
else
// Check bits in MCxx entry except those in partial good region
if (i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMI]] !=
if (i_pgData[mcPgIndex] !=
VPD_CP00_PG_MCxx_GOOD)
{
HWAS_INF("pDesc %.8X - MC%d pgData[%d]: "
"actual 0x%04X, expected 0x%04X - bad",
i_desc->getAttr<ATTR_HUID>(), indexMC,
VPD_CP00_PG_MCxx_INDEX[indexMI],
i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMI]],
mcPgIndex,
i_pgData[mcPgIndex],
VPD_CP00_PG_MCxx_GOOD);
l_descFunctional = false;
}
Expand Down
230 changes: 230 additions & 0 deletions src/usr/hwas/test/hwas1test.H
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,236 @@ public:
}

break;
case TYPE_OMI:
{
TS_INFO( "testHWASisDescFunctional: "
"OMI%d is not functional", l_chipUnit);

size_t indexMC = l_chipUnit / 8;
size_t mcPgIndex = indexMC ? VPD_CP00_PG_MC23_INDEX : VPD_CP00_PG_MC01_INDEX;

if (indexMC)
{
pgData[VPD_CP00_PG_N1_INDEX] |=
(uint16_t)VPD_CP00_PG_N1_MCS23;
}
else
{
pgData[VPD_CP00_PG_N3_INDEX] |=
(uint16_t)VPD_CP00_PG_N3_MCS01;
}

if (isDescFunctional(pDesc, pgData))
{
TS_FAIL("testHWASisDescFunctional>"
"functional = 0x%x, should be false, "
"N1/N3 for OMI%d = 0x%04x.",
isDescFunctional(pDesc, pgData),
l_chipUnit,
indexMC
? pgData[VPD_CP00_PG_N1_INDEX]
: pgData[VPD_CP00_PG_N3_INDEX]);
}

if (indexMC)
{
pgData[VPD_CP00_PG_N1_INDEX] =
(uint16_t)VPD_CP00_PG_N1_GOOD;
}
else
{
pgData[VPD_CP00_PG_N3_INDEX] =
(uint16_t)VPD_CP00_PG_N3_GOOD;
}

for (l_mask = 0x8000;
l_mask > 0;
l_mask >>= 1)
{
if (pgData[mcPgIndex] & l_mask)
{
// Turn off a bit that should be on
pgData[mcPgIndex] &= ~l_mask;
}
else
{
// Turn on a bit that should be off
pgData[mcPgIndex] |= l_mask;
}

if (isDescFunctional(pDesc, pgData))
{
TS_FAIL("testHWASisDescFunctional>"
"functional = 0x%x, should be false, "
"MC%s for OMI%d = 0x%04x, "
"mask = 0x%04x.",
isDescFunctional(pDesc, pgData),
indexMC ? "01" : "23",
l_chipUnit,
pgData[mcPgIndex],
l_mask);
}

// Restore the "all good" data
pgData[mcPgIndex] = (uint16_t)VPD_CP00_PG_MCxx_GOOD;
}

break;
}

case TYPE_OMIC:
{
TS_INFO( "testHWASisDescFunctional: "
"OMIC%d is not functional", l_chipUnit);

size_t indexMC = l_chipUnit / 3;
size_t mcPgIndex = indexMC ? VPD_CP00_PG_MC23_INDEX : VPD_CP00_PG_MC01_INDEX;

if (indexMC)
{
pgData[VPD_CP00_PG_N1_INDEX] |=
(uint16_t)VPD_CP00_PG_N1_MCS23;
}
else
{
pgData[VPD_CP00_PG_N3_INDEX] |=
(uint16_t)VPD_CP00_PG_N3_MCS01;
}

if (isDescFunctional(pDesc, pgData))
{
TS_FAIL("testHWASisDescFunctional>"
"functional = 0x%x, should be false, "
"N1/N3 for OMIC%d = 0x%04x.",
isDescFunctional(pDesc, pgData),
l_chipUnit,
indexMC
? pgData[VPD_CP00_PG_N1_INDEX]
: pgData[VPD_CP00_PG_N3_INDEX]);
}

if (indexMC)
{
pgData[VPD_CP00_PG_N1_INDEX] =
(uint16_t)VPD_CP00_PG_N1_GOOD;
}
else
{
pgData[VPD_CP00_PG_N3_INDEX] =
(uint16_t)VPD_CP00_PG_N3_GOOD;
}

for (l_mask = 0x8000;
l_mask > 0;
l_mask >>= 1)
{
if (pgData[mcPgIndex] & l_mask)
{
// Turn off a bit that should be on
pgData[mcPgIndex] &= ~l_mask;
}
else
{
// Turn on a bit that should be off
pgData[mcPgIndex] |= l_mask;
}

if (isDescFunctional(pDesc, pgData))
{
TS_FAIL("testHWASisDescFunctional>"
"functional = 0x%x, should be false, "
"MC%s for OMIC%d = 0x%04x, "
"mask = 0x%04x.",
isDescFunctional(pDesc, pgData),
indexMC ? "01" : "23",
l_chipUnit,
pgData[mcPgIndex],
l_mask);
}

// Restore the "all good" data
pgData[mcPgIndex] = (uint16_t)VPD_CP00_PG_MCxx_GOOD;
}

break;
}

case TYPE_MCC:
{
TS_INFO( "testHWASisDescFunctional: "
"MCC%d is not functional", l_chipUnit);

size_t indexMC = l_chipUnit / 4;
size_t mcPgIndex = indexMC ? VPD_CP00_PG_MC23_INDEX : VPD_CP00_PG_MC01_INDEX;

if (indexMC)
{
pgData[VPD_CP00_PG_N1_INDEX] |=
(uint16_t)VPD_CP00_PG_N1_MCS23;
}
else
{
pgData[VPD_CP00_PG_N3_INDEX] |=
(uint16_t)VPD_CP00_PG_N3_MCS01;
}

if (isDescFunctional(pDesc, pgData))
{
TS_FAIL("testHWASisDescFunctional>"
"functional = 0x%x, should be false, "
"N1/N3 for MCC%d = 0x%04x.",
isDescFunctional(pDesc, pgData),
l_chipUnit,
indexMC
? pgData[VPD_CP00_PG_N1_INDEX]
: pgData[VPD_CP00_PG_N3_INDEX]);
}

if (indexMC)
{
pgData[VPD_CP00_PG_N1_INDEX] =
(uint16_t)VPD_CP00_PG_N1_GOOD;
}
else
{
pgData[VPD_CP00_PG_N3_INDEX] =
(uint16_t)VPD_CP00_PG_N3_GOOD;
}

for (l_mask = 0x8000;
l_mask > 0;
l_mask >>= 1)
{
if (pgData[mcPgIndex] & l_mask)
{
// Turn off a bit that should be on
pgData[mcPgIndex] &= ~l_mask;
}
else
{
// Turn on a bit that should be off
pgData[mcPgIndex] |= l_mask;
}

if (isDescFunctional(pDesc, pgData))
{
TS_FAIL("testHWASisDescFunctional>"
"functional = 0x%x, should be false, "
"MC%s for MCC%d = 0x%04x, "
"mask = 0x%04x.",
isDescFunctional(pDesc, pgData),
indexMC ? "01" : "23",
l_chipUnit,
pgData[mcPgIndex],
l_mask);
}

// Restore the "all good" data
pgData[mcPgIndex] = (uint16_t)VPD_CP00_PG_MCxx_GOOD;
}
break;
}


case TYPE_OBUS_BRICK:
{
Expand Down

0 comments on commit e82098f

Please sign in to comment.