summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H10
-rw-r--r--src/include/usr/pnor/pnorif.H49
-rw-r--r--src/usr/hwas/hwasPlatDeconfigGard.C32
-rw-r--r--src/usr/pnor/pnor_common.C7
-rw-r--r--src/usr/pnor/pnor_common.H4
-rw-r--r--src/usr/pnor/pnorrp.C204
-rw-r--r--src/usr/pnor/pnorrp.H38
7 files changed, 292 insertions, 52 deletions
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index 823f439e8..148f916f2 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -43,8 +43,10 @@ namespace PNOR
MOD_PNORRP_WRITETODEVICE = 0x08, /**< PnorRP::writeToDevice */
MOD_PNORRP_DIDSTARTUPFAIL = 0x09, /**< didStartupFail(rc) */
MOD_PNORRP_FLUSH = 0x0A, /**< mm_remove_pages */
- MOD_PNORRP_FIXECC = 0x0B, /**< fixECC */
- MOD_PNORRP_FINDTOC = 0x0C, /**< findTOC */
+ MOD_PNORRP_FIXECC = 0x0B, /**< PnorRP::fixECC */
+ MOD_PNORRP_FINDTOC = 0x0C, /**< PnorRP::findTOC */
+ MOD_PNORRP_GETSIDEINFO = 0x0D, /**< PnorRP::getSideInfo */
+ MOD_PNORRP_SETSIDEINFO = 0x0E, /**< PnorRP::setSideInfo */
// pnorvalid.C
MOD_PNORVALID_MAIN = 0x0E, /**< validateAltMaster */
@@ -145,6 +147,10 @@ namespace PNOR
RC_PARTITION_TABLE_CORRUPTED = PNOR_COMP_ID | 0x25,
//termination_rc
RC_FINDTOC_FAILED = PNOR_COMP_ID | 0x26,
+ RC_INVALID_PNOR_SIDE = PNOR_COMP_ID | 0x27,
+ //termination_rc
+ RC_INVALID_WORKING_TOC = PNOR_COMP_ID | 0x28,
+ RC_INVALID_TOC = PNOR_COMP_ID | 0x29,
};
enum UserDetailsTypes
diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H
index 722946628..e12ccf122 100644
--- a/src/include/usr/pnor/pnorif.H
+++ b/src/include/usr/pnor/pnorif.H
@@ -30,6 +30,7 @@
#include <builtins.h>
#include <errl/errlentry.H>
#include <utility>
+#include <config.h>
namespace PNOR
{
@@ -90,6 +91,46 @@ struct SectionInfo_t
};
/**
+ * PNOR Sides
+ */
+enum SideId
+{
+ WORKING = 0,
+#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
+ ALTERNATE = 1,
+#endif
+ NUM_SIDES,
+ INVALID_SIDE = NUM_SIDES,
+ FIRST_SIDE = WORKING,
+};
+
+/**
+ * Information about a side of PNOR
+ */
+struct SideInfo_t
+{
+ SideId id; /**< Side ID */
+ char side; /**< name of the side either A or B */
+ bool isGolden; /**< True if side is golden */
+ bool isGuardPresent; /**< True if guard section is present */
+ bool hasOtherSide; /**< True if a valid alternate side exists*/
+ uint64_t primaryTOC; /**< Address of the primary TOC */
+ uint64_t backupTOC; /**< Address of the backup TOC */
+ uint64_t hbbAddress; /**< HBB Address associated with this side */
+ uint64_t hbbMmioOffset; /**< HBB MMIO Offset associated with hbbAddress*/
+};
+
+/**
+ * @brief Returns information about a given side of pnor
+ *
+ * @param[in] i_side PNOR side
+ * @param[out] o_info side information
+ *
+ * @return errlHndl_t Error log if request was invalid
+ */
+errlHndl_t getSideInfo (SideId i_side, SideInfo_t& o_info);
+
+/**
* @brief Return the size and address of a given section of PNOR data
*
* @param[in] i_section PNOR section
@@ -144,14 +185,6 @@ errlHndl_t clearSection(PNOR::SectionId i_section);
*/
errlHndl_t validateAltMaster( void );
-//@ TODO RTC: 120061 add golden info
-//@ TODO RTC: 109703 make golden changes for informing OPAL
-struct TocInfo_t
-{
- std::pair<uint64_t, uint64_t> activeTocOffsets;
- std::pair<uint64_t, uint64_t> altTocOffsets;
-};
-
/** @brief PNOR::TEST section offsets for test cases to prevent
* concurrency problems
*/
diff --git a/src/usr/hwas/hwasPlatDeconfigGard.C b/src/usr/hwas/hwasPlatDeconfigGard.C
index 52eb1b04c..452a9e7aa 100644
--- a/src/usr/hwas/hwasPlatDeconfigGard.C
+++ b/src/usr/hwas/hwasPlatDeconfigGard.C
@@ -270,7 +270,7 @@ errlHndl_t DeconfigGard::platCreateGardRecord(
}
l_pErr = _GardRecordIdSetup(iv_platDeconfigGard);
- if (l_pErr && iv_platDeconfigGard)
+ if (l_pErr || !iv_platDeconfigGard)
{
break;
}
@@ -490,16 +490,26 @@ errlHndl_t getGardSectionInfo(PNOR::SectionInfo_t& o_sectionInfo)
if (l_errl)
{
g_GardSectionInfo.size = 0;
-// @TODO RTC: 120061 - replace config flag with a pnor interface call to say if
-// there is a guard section on the current (active) side
-// of pnor
-#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
- HWAS_INF("getGardSectionInfo: No guard section disabling guard support");
- delete l_errl;
- l_errl = NULL;
-#else
- HWAS_ERR("getGardSectionInfo:getSectionInfo failed");
-#endif
+
+ PNOR::SideInfo_t l_sideInfo;
+ errlHndl_t l_tempErr = PNOR::getSideInfo(PNOR::WORKING,l_sideInfo);
+ if (l_tempErr)
+ {
+ HWAS_ERR("getGardSectionInfo: getSideInfo failed");
+ errlCommit (l_errl,HWAS_COMP_ID);
+ l_errl = l_tempErr;
+ }
+ if (!l_sideInfo.isGuardPresent)
+ {
+ HWAS_INF("getGardSectionInfo: No guard section disabling guard"
+ " support");
+ delete l_errl;
+ l_errl = NULL;
+ }
+ else
+ {
+ HWAS_ERR("getGardSectionInfo:getSectionInfo failed");
+ }
}
else
{
diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C
index 6844984e5..c14e41b6c 100644
--- a/src/usr/pnor/pnor_common.C
+++ b/src/usr/pnor/pnor_common.C
@@ -148,8 +148,11 @@ errlHndl_t PNOR::mmioToPhysicalOffset(uint64_t& o_hbbAddress)
void PNOR::physicalToMmioOffset(uint64_t i_hbbAddress,
uint64_t& o_mmioOffset)
{
- o_mmioOffset = (PNOR::LPC_SFC_MMIO_OFFSET + i_hbbAddress +
- ((PNOR::PNOR_SIZE - i_hbbAddress)/9)) & 0xFFFFFFF;
+ //Left shifting 32-bits because SCOMS store a 64-bit value
+ //and HBB Offset is stored in the higher 32-bits
+ o_mmioOffset = ((PNOR::LPC_SFC_MMIO_OFFSET + i_hbbAddress +
+ ((PNOR::PNOR_SIZE - i_hbbAddress)/9)) |
+ PNOR::LPC_FW_SPACE) << 32;
}
/*
diff --git a/src/usr/pnor/pnor_common.H b/src/usr/pnor/pnor_common.H
index b1106237a..dd7ab2ea1 100644
--- a/src/usr/pnor/pnor_common.H
+++ b/src/usr/pnor/pnor_common.H
@@ -131,6 +131,10 @@ namespace PNOR {
// for the SBE to work so we can rely on that same assertion
/**< Offset to direct read space, from FW base */
LPC_SFC_MMIO_OFFSET = LPC_TOP_OF_FLASH_OFFSET-PNOR_SIZE+1,
+
+ //@TODO: RTC:124503 - delete the following line and call the LPC
+ //interface instead
+ LPC_FW_SPACE = 0xF0000000,
};
}
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index aad312b38..8c8f9a407 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -45,6 +45,7 @@
#include <util/align.H>
#include <config.h>
#include "pnor_common.H"
+#include <hwas/common/hwasCallout.H>
extern trace_desc_t* g_trac_pnor;
@@ -70,6 +71,15 @@ TASK_ENTRY_MACRO( PnorRP::init );
********************/
/**
+ * @brief Returns information about a given side of PNOR
+ */
+errlHndl_t PNOR::getSideInfo( PNOR::SideId i_side,
+ PNOR::SideInfo_t& o_info)
+{
+ return Singleton<PnorRP>::instance().getSideInfo(i_side,o_info);
+}
+
+/**
* @brief Return the size and address of a given section of PNOR data
*/
errlHndl_t PNOR::getSectionInfo( PNOR::SectionId i_section,
@@ -280,6 +290,12 @@ void PnorRP::initDaemon()
TRACFCOMP(g_trac_pnor, ERR_MRK"PnorRP::initDaemon: Failed to readTOC");
break;
}
+ l_errhdl = PnorRP::setSideInfo ();
+ if(l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor, "PnorRP::initDaemon> setSideInfo failed");
+ break;
+ }
// start task to wait on the queue
task_create( wait_for_message, NULL );
@@ -301,6 +317,39 @@ void PnorRP::initDaemon()
TRACUCOMP(g_trac_pnor, "< PnorRP::initDaemon" );
}
+errlHndl_t PnorRP::getSideInfo( PNOR::SideId i_side,
+ PNOR::SideInfo_t& o_info)
+{
+ errlHndl_t l_err = NULL;
+ do
+ {
+ //check to make sure side id is valid
+ if (i_side != PNOR::INVALID_SIDE)
+ {
+ memcpy (&o_info, &iv_side[i_side], sizeof(SideInfo_t));
+ }
+ else
+ {
+ TRACFCOMP(g_trac_pnor, "Side:%d is currently not supported",
+ (int)i_side);
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_GETSIDEINFO
+ * @reasoncode PNOR::RC_INVALID_PNOR_SIDE
+ * @userdata1 Requested SIDE
+ * @userdata2 0
+ * @devdesc PnorRP::getSideInfo> Side not supported
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ PNOR::MOD_PNORRP_GETSIDEINFO,
+ PNOR::RC_INVALID_PNOR_SIDE,
+ TO_UINT64(i_side),
+ 0,true);
+ break;
+ }
+ } while (0);
+ return l_err;
+}
/**
* @brief Return the size and address of a given section of PNOR data
@@ -591,17 +640,17 @@ errlHndl_t PnorRP::findTOC()
if (l_isActiveTOC)
{
- iv_activeTocOffsets.first = l_toc;
- iv_activeTocOffsets.second = l_backupTOC;
- iv_altTocOffsets.first = l_otherPrimaryTOC;
- iv_altTocOffsets.second = l_otherBackupTOC;
+ iv_TocOffset[WORKING].first = l_toc;
+ iv_TocOffset[WORKING].second = l_backupTOC;
+ iv_TocOffset[ALTERNATE].first = l_otherPrimaryTOC;
+ iv_TocOffset[ALTERNATE].second = l_otherBackupTOC;
}
else if (l_isOtherActiveTOC)
{
- iv_activeTocOffsets.first = l_otherPrimaryTOC;
- iv_activeTocOffsets.second = l_otherBackupTOC;
- iv_altTocOffsets.first = l_toc;
- iv_altTocOffsets.second = l_backupTOC;
+ iv_TocOffset[WORKING].first = l_otherPrimaryTOC;
+ iv_TocOffset[WORKING].second = l_otherBackupTOC;
+ iv_TocOffset[ALTERNATE].first = l_toc;
+ iv_TocOffset[ALTERNATE].second = l_backupTOC;
}
else
{
@@ -611,16 +660,17 @@ errlHndl_t PnorRP::findTOC()
INITSERVICE::doShutdown(PNOR::RC_PARTITION_TABLE_CORRUPTED);
}
TRACFCOMP(g_trac_pnor,"findTOC>activePrimary:0x%X,activeBackup:0x%X"
- "altPrimary:0x%X, altBackup:0x%X",iv_activeTocOffsets.first,
- iv_activeTocOffsets.second, iv_altTocOffsets.first,
- iv_altTocOffsets.second);
+ "altPrimary:0x%X, altBackup:0x%X",iv_TocOffset[WORKING].first,
+ iv_TocOffset[WORKING].second, iv_TocOffset[ALTERNATE].first,
+ iv_TocOffset[ALTERNATE].second);
#else
if (l_isActiveTOC)
{
- iv_activeTocOffsets.first = l_toc;
- iv_activeTocOffsets.second = l_backupTOC;
- TRACFCOMP(g_trac_pnor, "findTOC> activePrimary:0x%X, activeBackup:0x%X",
- iv_activeTocOffsets.first, iv_activeTocOffsets.second);
+ iv_TocOffset[WORKING].first = l_toc;
+ iv_TocOffset[WORKING].second = l_backupTOC;
+ TRACFCOMP(g_trac_pnor, "findTOC> activePrimary:0x%X, "
+ "activeBackup:0x%X", iv_TocOffset[WORKING].first,
+ iv_TocOffset[WORKING].second);
}
else
{
@@ -665,9 +715,9 @@ errlHndl_t PnorRP::readTOC()
memset(toc0Buffer, 0xFF, PAGESIZE);
memset(toc1Buffer, 0xFF, PAGESIZE);
- if (iv_activeTocOffsets.first != INVALID_OFFSET)
+ if (iv_TocOffset[WORKING].first != INVALID_OFFSET)
{
- l_errhdl = readFromDevice(iv_activeTocOffsets.first, 0, false,
+ l_errhdl = readFromDevice(iv_TocOffset[WORKING].first, 0, false,
toc0Buffer, fatal_error );
if (l_errhdl)
{
@@ -676,9 +726,9 @@ errlHndl_t PnorRP::readTOC()
}
}
- if (iv_activeTocOffsets.second != INVALID_OFFSET)
+ if (iv_TocOffset[WORKING].second != INVALID_OFFSET)
{
- l_errhdl = readFromDevice(iv_activeTocOffsets.second, 0, false,
+ l_errhdl = readFromDevice(iv_TocOffset[WORKING].second, 0, false,
toc1Buffer, fatal_error );
if (l_errhdl)
{
@@ -710,6 +760,118 @@ errlHndl_t PnorRP::readTOC()
return l_errhdl;
}
+errlHndl_t PnorRP::setSideInfo ()
+{
+ uint64_t l_chip = 0;
+ uint64_t l_fatalError = 0;
+ uint8_t* l_tocBuffer = new uint8_t [PAGESIZE];
+ ffs_hdr* l_ffs_hdr = 0;
+ errlHndl_t l_err = NULL;
+ for (SideId i = FIRST_SIDE; i < NUM_SIDES; i = (SideId)(i+1))
+ {
+ //id
+ iv_side[i].id = (SideId)i;
+
+ //get a valid TOC
+ uint64_t l_primaryTOC = iv_TocOffset[i].first;
+ uint64_t l_backupTOC = iv_TocOffset[i].second;
+
+ uint64_t l_validTOC = (l_primaryTOC != INVALID_OFFSET) ? l_primaryTOC :
+ ((l_backupTOC != INVALID_OFFSET) ? l_backupTOC :
+ INVALID_OFFSET);
+ if(l_validTOC == INVALID_OFFSET)
+ {
+ if (i == WORKING)
+ {
+ TRACFCOMP(g_trac_pnor, "setSideInfo: No valid TOC found for"
+ "working side");
+ INITSERVICE::doShutdown(PNOR::RC_INVALID_WORKING_TOC);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_pnor,"setSideInfo: No valid TOC found for"
+ " side: %d", i);
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_SETSIDEINFO
+ * @reasoncode PNOR::RC_INVALID_TOC
+ * @userdata1 Side Id
+ * @userdata2[00:31] primary toc
+ * @userdata2[32:63] backup toc
+ * @devdesc PnorRP::setSideInfo> No valid TOCs found
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ PNOR::MOD_PNORRP_SETSIDEINFO,
+ PNOR::RC_INVALID_TOC,
+ i,TWO_UINT32_TO_UINT64(l_primaryTOC,l_backupTOC),
+ true);
+ l_err->addPartCallout(
+ TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
+ HWAS::PNOR_PART_TYPE,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ break;
+ }
+ }
+
+ iv_side[i].primaryTOC = l_primaryTOC;
+ iv_side[i].backupTOC = l_backupTOC;
+
+ l_err = readFromDevice(l_validTOC,l_chip,
+ false, l_tocBuffer,l_fatalError);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_pnor, "setSideInfo: readFromDevice failed"
+ " while reading a valid TOC");
+ break;
+ }
+ l_ffs_hdr = (ffs_hdr*)l_tocBuffer;
+
+ //isGolden
+ //Entry 0 is the "part" partition
+ //Need to read from the ffs hdr instead of the TOC because
+ //TOC has no knowledge of other side
+ ffs_entry* cur_entry = (&l_ffs_hdr->entries[0]);
+ ffs_hb_user_t* ffsUserData = (ffs_hb_user_t*)&(cur_entry->user);
+ iv_side[i].isGolden = (ffsUserData->miscFlags & FFS_MISC_GOLDEN);
+
+ //isGuardPresent
+ uint64_t l_secOffset = INVALID_OFFSET;
+ findPhysicalOffset (l_ffs_hdr, "GUARD", l_secOffset);
+ iv_side[i].isGuardPresent = (l_secOffset != INVALID_OFFSET);
+
+ //isOtherSide
+ iv_side[i].hasOtherSide = false;
+#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
+ iv_side[i].hasOtherSide =
+ ((iv_TocOffset[(i+1)%NUM_SIDES].first != INVALID_OFFSET) ||
+ (iv_TocOffset[(i+1)%NUM_SIDES].second != INVALID_OFFSET));
+#endif
+
+ //hbbAddress
+ l_secOffset = INVALID_OFFSET;
+ findPhysicalOffset (l_ffs_hdr, "HBB", l_secOffset);
+ iv_side[i].hbbAddress = l_secOffset;
+
+ //mmioOffset
+ uint64_t l_mmioOffset;
+ physicalToMmioOffset(l_secOffset, l_mmioOffset);
+ iv_side[i].hbbMmioOffset = l_mmioOffset;
+
+ //char side
+ iv_side[i].side =(ALIGN_DOWN_X(l_secOffset,32*MEGABYTE) == 0) ? 'A':'B';
+
+ TRACFCOMP(g_trac_pnor, "setSideInfo: sideId:%d, isGolden:%d, "
+ "isGuardPresent:%d, hasOtherSide:%d, primaryTOC: 0x%x, backupTOC"
+ ":0x%X, HBB:0x%X, MMIO:0x%X",i, iv_side[i].isGolden,
+ iv_side[i].isGuardPresent,iv_side[i].hasOtherSide,
+ iv_side[i].primaryTOC, iv_side[i].backupTOC,
+ iv_side[i].hbbAddress, iv_side[i].hbbMmioOffset);
+ }
+ return l_err;
+}
/**
* @brief Message receiver
*/
@@ -1271,6 +1433,6 @@ errlHndl_t PnorRP::fixECC (PNOR::SectionId i_section)
uint64_t PnorRP::getTocOffset(TOCS i_toc) const
{
// Can use a ternary operator because there are only 2 TOCs per side
- return (i_toc == TOC_0) ? iv_activeTocOffsets.first :
- iv_activeTocOffsets.second;
+ return (i_toc == TOC_0) ? iv_TocOffset[WORKING].first :
+ iv_TocOffset[WORKING].second;
}
diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H
index 27e52732f..1a9b04ff6 100644
--- a/src/usr/pnor/pnorrp.H
+++ b/src/usr/pnor/pnorrp.H
@@ -48,6 +48,16 @@ class PnorRP
static void init( errlHndl_t &io_rtaskRetErrl );
/**
+ * @brief Returns information about a given side of pnor
+ * (Called by an external interface PNOR::getSideInfo())
+ * @param[in] i_side PNOR side
+ * @param[out] o_info side information
+ *
+ * @return errlHndl_t Error log if request was invalid
+ */
+ errlHndl_t getSideInfo (PNOR::SideId i_side, PNOR::SideInfo_t& o_info);
+
+ /**
* @brief Return the size and address of a given section of PNOR data
* Called by external PNOR::getSectionInfo()
*
@@ -78,9 +88,9 @@ class PnorRP
errlHndl_t fixECC(PNOR::SectionId i_section);
/**
- * @brief Get TOC offset of specified TOC on active side
+ * @brief Get TOC offset of specified TOC and side
*
- * @param[in] i_toc TOC offset desired on active side
+ * @param[in] i_toc TOC id of the TOC requested
*
* @return uint64_t TOC offset
*/
@@ -100,12 +110,12 @@ class PnorRP
private:
- // TOC 0 and 1 offsets of both PNOR sides. The active PNOR side determined
- // by the Seeprom the SBE booted from
- std::pair<uint64_t, uint64_t> iv_activeTocOffsets;
-#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
- std::pair<uint64_t, uint64_t> iv_altTocOffsets;
-#endif
+ /*
+ * Stores primary and backup TOCs for each side of PNOR
+ */
+ typedef std::pair<uint64_t, uint64_t> TocOffsets_t;
+ TocOffsets_t iv_TocOffset [PNOR::NUM_SIDES];
+
enum
{
BASE_VADDR = VMM_VADDR_PNOR_RP, /**< 2GB = 0x80000000*/
@@ -127,6 +137,11 @@ class PnorRP
};
/**
+ * Stores information about all sides of PNOR
+ */
+ PNOR::SideInfo_t iv_side[PNOR::NUM_SIDES];
+
+ /**
* Cached copy of section data
*/
PNOR::SectionData_t iv_TOC[PNOR::NUM_SECTIONS+1];
@@ -161,6 +176,13 @@ class PnorRP
*/
errlHndl_t findTOC();
+ /*
+ * @brief determines the sides information and fills the class variable
+ * iv_side
+ * @return Error
+ */
+ errlHndl_t setSideInfo();
+
/**
* @brief Verify both TOC's and store section information from one of the
* verified TOC's. Additionally set each section permissions
OpenPOWER on IntegriCloud