Skip to content

Commit

Permalink
Support EXP_FW_LOG command to get Explorer Firmware logs
Browse files Browse the repository at this point in the history
Includes framework to add explorer error logs to an error.
Tests the ekb RC path and the hostboot way to add these
logs.  Tests are disabled until simics supports the new command.

Change-Id: I03b735342251b6c9e078a3e5b412e5a9f88e1e6b
RTC:205128
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/82362
Reviewed-by: Christian R Geddes <crgeddes@us.ibm.com>
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: Glenn Miles <milesg@ibm.com>
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
  • Loading branch information
mderkse1 authored and dcrowell77 committed Sep 25, 2019
1 parent 56574b6 commit 8e6285e
Show file tree
Hide file tree
Showing 13 changed files with 1,047 additions and 10 deletions.
8 changes: 7 additions & 1 deletion src/include/usr/expscom/expscom_reasoncodes.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -43,6 +43,12 @@ namespace EXPSCOM
RC_INVALID_OPTYPE = EXPSCOM_COMP_ID | 0x03,
RC_INVALID_ADDRESS = EXPSCOM_COMP_ID | 0x04,
};

enum UserDetailsTypes
{
EXPSCOM_UDT_ACTIVE_LOG = 0x01,
EXPSCOM_UDT_SAVED_LOG = 0x02,
};
};

#endif
216 changes: 216 additions & 0 deletions src/usr/expaccess/errlud_expscom.C
@@ -0,0 +1,216 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/expaccess/errlud_expscom.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] 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 */
/**
* @file errlud_expscom.C
* @brief Utility to add Explorer logs to your hostboot error
*/
#include "errlud_expscom.H"
#include "expscom_trace.H"
#include <errl/hberrltypes.H> // pelSectionHeader_t
#include <exp_fw_log_data.H> // explorer log gathering tools
#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP
#include <expscom/expscom_reasoncodes.H> // user-detail subsections
#include <errl/errlmanager.H> // errlCommit

using namespace EXPSCOM;

// Main function to add Explorer logs to a HB error log
bool EXPSCOM::expAddLog( const exp_log_type i_type,
TARGETING::Target * i_ocmb,
errlHndl_t & io_errl )
{
bool l_logsAdded = false;
explog_section_header_t l_header; // use 0 defaults

// Meta data included with each section
const uint32_t META_SECTION_SIZE = sizeof(l_header) +
sizeof(ERRORLOG::pelSectionHeader_t);

// @todo RTC 214628
// Hopefully create a way to tell how much room is left in io_errl
uint32_t l_bytesAvailableInLog = 4 * KILOBYTE;

if (l_bytesAvailableInLog > META_SECTION_SIZE)
{
errlHndl_t l_errl = nullptr;
std::vector<uint8_t>l_error_log_data; // explorer error entry data
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(i_ocmb);

// Make HWP call to grab explorer error log data
if (i_type == EXPSCOM::ACTIVE_LOG)
{
TRACFCOMP( g_trac_expscom, INFO_MRK "FAPI_INVOKE_HWP exp_active_error_log");
FAPI_INVOKE_HWP( l_errl, exp_active_log,
l_fapi_ocmb_target, l_error_log_data );
}
else
{
TRACFCOMP( g_trac_expscom, INFO_MRK "FAPI_INVOKE_HWP exp_saved_error_log");
FAPI_INVOKE_HWP( l_errl, exp_saved_log,
l_fapi_ocmb_target, l_error_log_data );
}

if (l_errl)
{
// Unable to grab explorer error log data
TRACFCOMP( g_trac_expscom, ERR_MRK "Unable to grab explorer error log data");
l_errl->collectTrace(EXPSCOM_COMP_NAME);

// This error is not a system critical failure, should be just noted
l_errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);

// Associate this error with the original explorer failure log
l_errl->plid(io_errl->plid());
errlCommit(l_errl, EXPSCOM_COMP_ID);
}
else
{
// Cycle through data and add sections to io_errl
// Most recent error log entries are at the end of the data returned
// so need to work backwards from the end
l_header.error_data_size = FIRST_EXPLORER_DATA_SECTION_SIZE;
uint32_t l_explorer_bytes_left = l_error_log_data.size();
uint8_t * l_end_ptr = l_error_log_data.data() + l_explorer_bytes_left;

// while explorer data to append
while (l_explorer_bytes_left && l_bytesAvailableInLog)
{
// Can we add a full packet size of error data?
if (l_bytesAvailableInLog > (l_header.error_data_size + META_SECTION_SIZE))
{
// Check if we don't have full packet of explorer error data
if (l_explorer_bytes_left < l_header.error_data_size)
{
// Reduce the packet size to include the last of explorer error data
l_header.error_data_size = l_explorer_bytes_left;
}
}
else if ( l_bytesAvailableInLog > META_SECTION_SIZE ) // Any room left for another section?
{
// Is there enough explorer error data for room available?
if ( l_explorer_bytes_left >=
(l_bytesAvailableInLog - META_SECTION_SIZE) )
{
// Not enough room is available for all the remaining explorer error data
// Use up the rest of the space available
l_header.error_data_size = l_bytesAvailableInLog - META_SECTION_SIZE;
}
else
{
// Room is available but not enough explorer data for full packet size
// Reduce the packet size to include the last of explorer error data
l_header.error_data_size = l_explorer_bytes_left;
}
}
else
{
// No more space available in hostboot error log
break;
}

// Offset into explorer error log data returned
l_header.offset_exp_log = l_explorer_bytes_left -
l_header.error_data_size;

// Add the section entry to the HWP error log
if ( i_type == EXPSCOM::ACTIVE_LOG )
{
ExpscomActiveLogUD(l_header, (l_end_ptr - l_header.error_data_size)).
addToLog(io_errl);
}
else
{
ExpscomSavedLogUD(l_header, (l_end_ptr - l_header.error_data_size)).
addToLog(io_errl);
}
l_logsAdded = true;

// Update to next packet of Explorer error log data
l_end_ptr -= l_header.error_data_size; // update to always be the tail of data to add
l_header.packet_num++;
l_explorer_bytes_left -= l_header.error_data_size;
l_bytesAvailableInLog -= (META_SECTION_SIZE + l_header.error_data_size);
l_header.error_data_size = FOLLOWING_EXPLORER_DATA_SECTION_SIZE;
}
}
}
else
{
TRACFCOMP( g_trac_expscom, INFO_MRK
"expAddErrorLog: Unable to add any %d type error logs,"
" only have %d bytes available in log", i_type, l_bytesAvailableInLog );
}
return l_logsAdded;
}

//------------------------------------------------------------------------------
// Expscom Active Log User Details
//------------------------------------------------------------------------------
ExpscomActiveLogUD::ExpscomActiveLogUD(
const explog_section_header_t & i_header_info,
const uint8_t * i_data_portion )
{
// Set up Ud instance variables
iv_CompId = EXPSCOM_COMP_ID;
iv_Version = 1;
iv_SubSection = EXPSCOM_UDT_ACTIVE_LOG;

uint8_t * l_pBuf = reallocUsrBuf( sizeof(i_header_info) +
i_header_info.error_data_size );

memcpy(l_pBuf, &i_header_info, sizeof(i_header_info));
l_pBuf += sizeof(i_header_info);
memcpy(l_pBuf, i_data_portion, i_header_info.error_data_size);
l_pBuf += i_header_info.error_data_size;
}

ExpscomActiveLogUD::~ExpscomActiveLogUD()
{
}

//------------------------------------------------------------------------------
// Expscom Saved Log User Details
//------------------------------------------------------------------------------
ExpscomSavedLogUD::ExpscomSavedLogUD(
const explog_section_header_t & i_header_info,
const uint8_t * i_data_portion )
{
// Set up Ud instance variables
iv_CompId = EXPSCOM_COMP_ID;
iv_Version = 1;
iv_SubSection = EXPSCOM_UDT_SAVED_LOG;

uint8_t * l_pBuf = reallocUsrBuf( sizeof(i_header_info) +
i_header_info.error_data_size );

memcpy(l_pBuf, &i_header_info, sizeof(i_header_info));
l_pBuf += sizeof(i_header_info);
memcpy(l_pBuf, i_data_portion, i_header_info.error_data_size);
l_pBuf += i_header_info.error_data_size;
}

ExpscomSavedLogUD::~ExpscomSavedLogUD()
{
}
160 changes: 160 additions & 0 deletions src/usr/expaccess/errlud_expscom.H
@@ -0,0 +1,160 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/expaccess/errlud_expscom.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] 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 */

#ifndef __ERRLUD_EXPSCOM_H
#define __ERRLUD_EXPSCOM_H

/**
* @file errlud_expscom.H
* @brief Utility functions to add Explorer logs to your hostboot error
*/
#include <stdint.h>

#include <errl/errluserdetails.H>

// targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>

namespace EXPSCOM
{
/**
* @brief Enum for what kind of Explorer log
*/
enum exp_log_type : uint8_t
{
ACTIVE_LOG = 1, // RAM error section
SAVED_LOG = 2 // SPI flash error section
};

/**
* @brief Adds Explorer log data to platform log
* Grabs explorer error log based on type and then breaks that data
* into smaller user-data sections adding them to the platform log.
* Note: First section will be the smallest and contain the most recent
* trace data. Probably contains most relevent traces, so try to make
* always fit in the error log.
* @param i_type - what kind of explorer error log to add
* @param i_ocmb - Explorer target
* @param io_errl - Platform error log to add logs into
* @return true if explorer error data added, else false
*/
bool expAddLog( const exp_log_type i_type,
TARGETING::Target * i_ocmb,
errlHndl_t & io_errl );



/**
* @brief Header data of every explorer error log user-data section
*/
struct explog_section_header_t
{
uint16_t packet_num; // ordering byte (0 = first packet)
uint32_t offset_exp_log; // offset where data portion started in full explorer log
uint16_t error_data_size; // size of data portion following header

explog_section_header_t()
: packet_num(0),
offset_exp_log(0),
error_data_size(0)
{}
} __attribute__((__packed__));

// Break large explorer log data into smaller error sections
// to avoid dropping important debug data.
// Make most important first section smaller so this won't get dropped
const uint16_t FIRST_EXPLORER_DATA_SECTION_SIZE = 0x0100;
const uint16_t FOLLOWING_EXPLORER_DATA_SECTION_SIZE = 0x0200;


/**
* @class ExpscomActiveLogUD
*
* Adds Explorer Active log information to an error log as user detail
* Data is from Explorer RAM
*
*/
class ExpscomActiveLogUD : public ERRORLOG::ErrlUserDetails
{
public:
/**
* @brief Constructor
*
* @param i_header_info Meta information added to beginning of section
* @param i_data_portion Pointer to portion of Active log data
*
*/
ExpscomActiveLogUD( const explog_section_header_t & i_header_info,
const uint8_t * i_data_portion );

/**
* @brief Destructor
*/
virtual ~ExpscomActiveLogUD();

// Disabled
ExpscomActiveLogUD() = delete;
ExpscomActiveLogUD(ExpscomActiveLogUD &) = delete;
ExpscomActiveLogUD & operator=(ExpscomActiveLogUD &) = delete;
};




/**
* @class ExpscomSavedLogUD
*
* Adds Explorer Saved log information to an error log as user detail
* Data is from Explorer SPI flash
*
*/
class ExpscomSavedLogUD : public ERRORLOG::ErrlUserDetails
{
public:
/**
* @brief Constructor
*
* @param i_header_info Meta information added to beginning of section
* @param i_data_portion Pointer to portion of Saved error data
*
*/
ExpscomSavedLogUD( const explog_section_header_t & i_header_info,
const uint8_t * i_data_portion );

/**
* @brief Destructor
*/
virtual ~ExpscomSavedLogUD();

// Disabled
ExpscomSavedLogUD() = delete;
ExpscomSavedLogUD(ExpscomSavedLogUD &) = delete;
ExpscomSavedLogUD & operator=(ExpscomSavedLogUD &) = delete;
};

}

#endif

0 comments on commit 8e6285e

Please sign in to comment.