diff options
author | Chris Cain <cjcain@us.ibm.com> | 2018-11-08 17:20:05 -0600 |
---|---|---|
committer | Christopher J. Cain <cjcain@us.ibm.com> | 2018-11-27 13:40:18 -0600 |
commit | 98ccba678ad49a876b73bb36bffbbec2b90faac4 (patch) | |
tree | 79e041a8c6dbdba181d54d9443d469b368edbb58 /src | |
parent | 1904821d627918e9b50658df255ffdb199868e3e (diff) | |
download | talos-occ-98ccba678ad49a876b73bb36bffbbec2b90faac4.tar.gz talos-occ-98ccba678ad49a876b73bb36bffbbec2b90faac4.zip |
Support for PGPE error handling
Change-Id: I979f699eb9f72c0a4087e5f5af533ee3d221a4c5
RTC: 197062
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/68569
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/pstate_pgpe_occ_api.h | 127 | ||||
-rwxr-xr-x | src/occ_405/cmdh/cmdh_fsp_cmds.c | 160 | ||||
-rwxr-xr-x | src/occ_405/cmdh/cmdh_fsp_cmds.h | 4 | ||||
-rwxr-xr-x | src/occ_405/errl/errl.c | 7 | ||||
-rwxr-xr-x | src/occ_405/errl/errl.h | 8 | ||||
-rwxr-xr-x | src/occ_405/main.c | 17 | ||||
-rwxr-xr-x | src/occ_405/timer/timer.c | 20 |
7 files changed, 200 insertions, 143 deletions
diff --git a/src/include/pstate_pgpe_occ_api.h b/src/include/pstate_pgpe_occ_api.h index bd70283..28cd47d 100644 --- a/src/include/pstate_pgpe_occ_api.h +++ b/src/include/pstate_pgpe_occ_api.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -61,14 +61,15 @@ enum MESSAGE_ID_IPI2HI // #define PGPE_RC_SUCCESS 0x01 #define PGPE_WOF_RC_NOT_ENABLED 0x10 -#define PGPE_RC_PSTATES_DISABLED 0x11 -#define PGPE_RC_REQ_PSTATE_ALREADY_STARTED 0x12 -#define PGPE_RC_REQ_PSTATE_ALREADY_SUSPENDED 0x13 +#define PGPE_RC_PSTATES_NOT_STARTED 0x11 #define PGPE_RC_OCC_NOT_PMCR_OWNER 0x14 +#define PGPE_RC_PM_COMPLEX_SUSPEND_SAFE_MODE 0x15 // Active quad mismatch with requested active quads. PGPE did not switch // to using the new VFRT. The original VFRT is still being used. #define PGPE_WOF_RC_VFRT_QUAD_MISMATCH 0x20 #define PGPE_RC_REQ_WHILE_PENDING_ACK 0x21 +#define PGPE_RC_NULL_VFRT_POINTER 0x22 +#define PGPE_RC_INVALID_PMCR_OWNER 0x23 // // PMCR Owner @@ -138,7 +139,7 @@ typedef struct ipcmsg_wof_vfrt uint8_t active_quads; // OCC updated with the Active Quads that it // is using for its Ceff calculations uint8_t pad; - HomerVFRTLayout_t* homer_vfrt_ptr; // Voltage Frequency Ratio Table + HomerVFRTLayout_t* homer_vfrt_ptr; } ipcmsg_wof_vfrt_t; @@ -167,9 +168,6 @@ typedef struct typedef struct { - /// Number of Pstate Table entries - uint32_t entries; - /// Internal VDD voltage ID at the output of the PFET header OCCPstateTable_entry_t table[MAX_OCC_PSTATE_TABLE_ENTRIES]; @@ -179,83 +177,6 @@ typedef struct // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- -// Start FFDC - -/// Scopes of the First Failure Data Capture (FFDC) registers -enum scope_type -{ - FFDC_CHIP = 0, // Address is chip scope (eg absolute) - FFDC_QUAD = 1, // Address + 0x01000000*quad for good quads from 0 to 5 - FFDC_CORE = 2, // Address + 0x01000000*core for good cores from 0 to 23 - FFDC_CME = 3 // Address if EX is even; Address + 0x400*EX for EX odd for good Exs from 0 to 11 -}; - -/// Address types of First Failure Data Capture (FFDC) register addresses -enum scope_type1 -{ - FFDC_OCI = 0, // Address is an OCI address - FFDC_SCOM = 1 // Address is a SCOM address -}; - -/// Register definition of the Hcode FFDC register list -#define MAX_FFDC_REG_LIST 12 -typedef struct -{ - uint32_t address; - /* union address_attribute - { - uint32_t value; - struct - { - uint32_t address_type : 16; - uint32_t scope : 16; - } attr; - }*/ -} Hcode_FFDC_entry_t; - -/// Hcode FFDC register list -typedef struct -{ - /// Number of FFDC address list entries - uint32_t list_entries; - - /// FFDC Address list - Hcode_FFDC_entry_t list[MAX_FFDC_REG_LIST]; -} Hcode_FFDC_list_t; - - - -/// Hcode FFDC register list -/// @todo RTC: 161183 Fill out the rest of this FFDC list -/// @note The reserved FFDC space for registers and traces set aside in the -/// OCC is 1KB. On the register side, the following list will generate -/// 12B of content (4B address, 8B data) x the good entries per scope. -/// CHIP scope are not dependent on partial good or currently active and will -/// take 12B x 8 = 96B. CME scope entries will, at maximum, generate 12B x -/// 12 CMEs x 4 SCOMs = 576B.. The overall totla for registers is 96 + 576 -/// -/*typedef struct Hcode_FFDC_list -{ - - {PERV_TP_OCC_SCOM_OCCLFIR, FFDC_SCOM, FFDC_CHIP }, // OCC LFIR - {PU_PBAFIR, FFDC_SCOM, FFDC_CHIP }, // PBA LFIR - {EX_CME_SCOM_LFIR, FFDC_SCOM, FFDC_CME }, // CME LFIR - {PU_GPE3_GPEDBG_OCI, FFDC_OCI, FFDC_CHIP }, // SGPE XSR, SPRG0 - {PU_GPE3_GPEDDR_OCI, FFDC_OCI, FFDC_CHIP }, // SGPE IR, EDR - {PU_GPE3_PPE_XIDBGPRO, FFDC_OCI, FFDC_CHIP }, // SGPE XSR, IAR - {PU_GPE2_GPEDBG_OCI, FFDC_OCI, FFDC_CHIP }, // PGPE XSR, SPRG0 - {PU_GPE2_GPEDDR_OCI, FFDC_OCI, FFDC_CHIP }, // PGPE IR, EDR - {PU_GPE2_PPE_XIDBGPRO, FFDC_OCI, FFDC_CHIP }, // PGPE XSR, IAR - {EX_PPE_XIRAMDBG, FFDC_SCOM, FFDC_CME }, // CME XSR, SPRG0 - {EX_PPE_XIRAMEDR, FFDC_SCOM, FFDC_CME }, // CME IR, EDR - {EX_PPE_XIDBGPRO, FFDC_SCOM, FFDC_CME }, // CME XSR, IAR - -};*/ - -// End FFDC -// ----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------------- // Start Quad State typedef union quad_state0 @@ -335,6 +256,32 @@ typedef union requested_active_quads // End Quad State // ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// Start Error Log Table + +#define MAX_HCODE_ELOG_ENTRIES 16 + +typedef union hcode_elog_entry +{ + uint64_t value; + struct { + uint8_t id; + uint8_t source; + uint16_t length; + uint32_t address; + } fields; +} hcode_elog_entry_t; + +typedef struct pgpe_error_table +{ + uint32_t magic; // "ELTC" (Error Log Table of Contents) + uint8_t total_log_slots; + uint8_t reserved[3]; + hcode_elog_entry_t elog[MAX_HCODE_ELOG_ENTRIES]; +} pgpe_error_table_t; + +// End Error Log Table +// ----------------------------------------------------------------------------- typedef struct { @@ -356,8 +303,14 @@ typedef struct ///Requested Active Quads requested_active_quads_t req_active_quads; - /// FFDC Address list - Hcode_FFDC_list_t ffdc_list; + // PGPE Produced WOF Values + uint64_t pgpe_produced_wof_values[2]; + + // Reserved + uint64_t reserved; + + // Error Log Table + pgpe_error_table_t pgpe_error_table; /// Pstate Table OCCPstateTable_t pstate_table; diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c index 000ede9..47cb457 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c @@ -62,6 +62,7 @@ extern GpeRequest G_epow_gpio_detected_req; extern opal_proc_voting_reason_t G_amec_opal_proc_throt_reason; +extern bool G_htmgt_notified_of_error; // This table contains tunable parameter information that can be exposed to // customers (only Master OCC should access/control this table) @@ -104,6 +105,7 @@ uint8_t G_apss_ch_to_function[MAX_APSS_ADC_CHANNELS] = {0}; ERRL_RC cmdh_poll_v20 (cmdh_fsp_rsp_t * i_rsp_ptr); +#define MAX_CONSECUTIVE_HCODE_ELOGS 2 // Function Specification // @@ -144,6 +146,7 @@ errlHndl_t cmdh_tmgt_poll (const cmdh_fsp_cmd_t * i_cmd_ptr, return l_errlHndl; } + // Function Specification // // Name: cmdh_poll_v20 @@ -157,6 +160,7 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr) int k = 0, l_max_sensors = 0; int l_err_hist_idx = 0, l_sens_list_idx = 0; cmdh_poll_sensor_db_t l_sensorHeader; + static unsigned int L_num_hcode_elogs = 0; // Set pointer to start of o_rsp_ptr cmdh_poll_resp_v20_fixed_t * l_poll_rsp = (cmdh_poll_resp_v20_fixed_t *) o_rsp_ptr; @@ -224,30 +228,71 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr) l_poll_rsp->ips_status.word = 0; l_poll_rsp->ips_status.ips_enabled = G_ips_config_data.iv_ipsEnabled; l_poll_rsp->ips_status.ips_active = AMEC_mst_get_ips_active_status(); - // Byte 8: - l_poll_rsp->errl_id = getOldestErrlID(); - // Byte 9 - 12: - l_poll_rsp->errl_address = getErrlOCIAddrByID(l_poll_rsp->errl_id); - // Byte 13 - 14: - l_poll_rsp->errl_length = getErrlLengthByID(l_poll_rsp->errl_id); - - //If errl_id is not 0, then neither address or length should be zero. - //This should not happen, but if it does tmgt will create an error log that - //includes the data at the errl slot address given that can be used for debug. - //NOTE: One cause for a false errlog id is corruption of data in one errl slot - // due to writing data greater than the size of the previous slot. For - // example writing the CallHome errorlog (3kb) into a regular sized (2kb) slot. - // Make sure to verify the order of the memory allocation for the errl slots. + // Error Log: + bool check_405_elogs = true; + // if (405 has no elogs) OR (have not hit max consecutive hcode elogs) + if ((getOldestErrlID() == 0) || (L_num_hcode_elogs < MAX_CONSECUTIVE_HCODE_ELOGS)) + { + // Check for HCODE errors + hcode_elog_entry_t elog_entry; + unsigned int index = 0; + for (; index < G_hcode_elog_table_slots; ++index) + { + elog_entry.value = in64(&G_hcode_elog_table[index]); + if (elog_entry.value != 0) + { // Found HCODE elog + if (elog_entry.fields.source != ERRL_SOURCE_405) + { + ++L_num_hcode_elogs; + // Byte 8: + l_poll_rsp->errl_id = elog_entry.fields.id; + // Byte 9 - 12: + l_poll_rsp->errl_address = elog_entry.fields.address; + // Byte 13 - 14: + l_poll_rsp->errl_length = elog_entry.fields.length; + // Byte 15: + l_poll_rsp->errl_source = elog_entry.fields.source; + check_405_elogs = false; + break; + } + else + { + TRAC_ERR("cmdh_poll_v20: ignoring HCODE error with 405 source (id:0x%02X, len:0x%04X, address:0x%08X)", + elog_entry.fields.id, elog_entry.fields.length, elog_entry.fields.address); + // Zero out error log entry in list so hcode can reuse + out64(&G_hcode_elog_table[index], 0); + G_htmgt_notified_of_error = false; + } + } + } + } + if (check_405_elogs) + { // No, HCODE errors, check/add any 405 elog + L_num_hcode_elogs = 0; + // Byte 8: + l_poll_rsp->errl_id = getOldestErrlID(); + // Byte 9 - 12: + l_poll_rsp->errl_address = getErrlOCIAddrByID(l_poll_rsp->errl_id); + // Byte 13 - 14: + l_poll_rsp->errl_length = getErrlLengthByID(l_poll_rsp->errl_id); + // Byte 15: + l_poll_rsp->errl_source = ERRL_SOURCE_405; + } + //If errl_id is not 0, then neither address or length should be zero. + //This should not happen, but if it does TMGT will create an error log that + //includes the data at the errl slot address given that can be used for debug. + //NOTE: One cause for a false errlog id is corruption of data in one errl slot + // due to writing data greater than the size of the previous slot. For + // example writing the CallHome errorlog (3kb) into a regular sized (2kb) slot. + // Make sure to verify the order of the memory allocation for the errl slots. if ( (l_poll_rsp->errl_id != 0) && ((l_poll_rsp->errl_address == 0) || (l_poll_rsp->errl_length == 0))) { - TRAC_ERR("An error ID has been sent via poll but the address or size is 0. " - "ErrlId:0x%X, sz:0x%X, address:0x%X.", - l_poll_rsp->errl_id, l_poll_rsp->errl_length, l_poll_rsp->errl_address); + TRAC_ERR("cmdh_poll_v20: error log sent with bad data " + "(id:0x%02X, source:0x%02X, len:0x%04X, address:0x%08X)", + l_poll_rsp->errl_id, l_poll_rsp->errl_source, l_poll_rsp->errl_length, l_poll_rsp->errl_address); } - // Byte 15: reserved. - // Byte 16: GPU Configuration l_poll_rsp->gpu_presence = (uint8_t)G_first_proc_gpu_config; @@ -1043,37 +1088,52 @@ errlHndl_t cmdh_clear_elog (const cmdh_fsp_cmd_t * i_cmd_ptr, switch(l_elog_source) { case ERRL_SOURCE_405: - // Get Errl Array index - l_SlotNum = getErrSlotNumByErrId(l_elog_id); - - // Get ERRL address - l_oci_address = (errlHndl_t)getErrSlotOCIAddr(l_SlotNum); - - if ((l_oci_address != NULL) && - (l_oci_address != INVALID_ERR_HNDL)) - { - // clear only one Errl by ID - l_err = deleteErrl(&l_oci_address); - } - else - { - CMDH_TRAC_ERR("cmdh_clear_elog: 405 error log ID[0x%02X] not found", l_elog_id); - l_rc = ERRL_RC_INVALID_DATA; - } - - break; - - case ERRL_SOURCE_PGPE: - case ERRL_SOURCE_XGPE: - // TBD - CMDH_TRAC_INFO("cmdh_clear_elog: Cleared PM Hcode elog id 0x%02X from source 0x%02X", - l_elog_id, l_elog_source); - break; - - default: - CMDH_TRAC_ERR("cmdh_clear_elog: Invalid error log source 0x%02X", l_elog_source); - l_rc = ERRL_RC_INVALID_DATA; - break; + // Get Errl Array index + l_SlotNum = getErrSlotNumByErrId(l_elog_id); + + // Get ERRL address + l_oci_address = (errlHndl_t)getErrSlotOCIAddr(l_SlotNum); + + if ((l_oci_address != NULL) && + (l_oci_address != INVALID_ERR_HNDL)) + { + // clear only one Errl by ID + l_err = deleteErrl(&l_oci_address); + } + else + { + CMDH_TRAC_ERR("cmdh_clear_elog: 405 error log ID[0x%02X] not found", l_elog_id); + l_rc = ERRL_RC_INVALID_DATA; + } + break; + + default: // non-405 error log + { + unsigned int index = 0; + for (; index < G_hcode_elog_table_slots; ++index) + { + hcode_elog_entry_t elog_entry; + elog_entry.value = in64(&G_hcode_elog_table[index]); + if ((elog_entry.fields.id == l_elog_id) && (elog_entry.fields.source == l_elog_source)) + { + CMDH_TRAC_INFO("cmdh_clear_elog: Clearing HCODE elog id 0x%02X from source 0x%02X", + l_elog_id, l_elog_source); + + // Zero out error log entry in list so hcode can reuse + out64(&G_hcode_elog_table[index], 0); + break; + } + } + if (index == G_hcode_elog_table_slots) + { + // Did not find matching entry in hcode table for non-405 error + CMDH_TRAC_ERR("cmdh_clear_elog: Could not find elog id 0x%02X with source 0x%02X", + l_elog_id, l_elog_source); + l_rc = ERRL_RC_INVALID_DATA; + } + G_htmgt_notified_of_error = false; + } + break; } }while(0); diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.h b/src/occ_405/cmdh/cmdh_fsp_cmds.h index db00dfe..00e6f42 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.h +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.h @@ -160,8 +160,8 @@ typedef struct __attribute__ ((packed)) cmdh_poll_resp_v20 uint32_t errl_address; // BYTES 13 - 14: Error Log Length uint16_t errl_length; - // BYTE 15: Reserved - uint8_t _reserved_15; + // BYTE 15: Error Log Source + uint8_t errl_source; // BYTE 16: GPU Configuration uint8_t gpu_presence; // BYTES 17 - 32 (16 bytes): OCC Code Level - ASCII string of OCC build level currently running. diff --git a/src/occ_405/errl/errl.c b/src/occ_405/errl/errl.c index 9f659d1..e40a9c6 100755 --- a/src/occ_405/errl/errl.c +++ b/src/occ_405/errl/errl.c @@ -64,6 +64,9 @@ errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS] = { (errlHndl_t) G_callslot }; +hcode_elog_entry_t *G_hcode_elog_table = NULL; +uint32_t G_hcode_elog_table_slots = 0; + // Array of error counters that are only cleared on OCC reset uint8_t G_error_history[ERR_HISTORY_SIZE] = {0}; @@ -749,9 +752,9 @@ void reportErrorLog( errlHndl_t i_err, uint16_t i_entrySize ) // Defer the interrupt if FIR collection is required if (!G_fir_collection_required) { - // If this system is using PSIHB complex, send an interrupt to Host so that + // If this system is not FSP, send an interrupt to Host so that // Host can inform HTMGT to collect the error log - if (G_occ_interrupt_type == PSIHB_INTERRUPT) + if (G_occ_interrupt_type != FSP_SUPPORTED_OCC) { notify_host(INTR_REASON_HTMGT_SERVICE_REQUIRED); } diff --git a/src/occ_405/errl/errl.h b/src/occ_405/errl/errl.h index 183b35d..e249ef0 100755 --- a/src/occ_405/errl/errl.h +++ b/src/occ_405/errl/errl.h @@ -28,6 +28,7 @@ #include <occ_common.h> #include <trac_interface.h> +#include <pstate_pgpe_occ_api.h> // Used as default for invalid slot number static const uint8_t ERRL_INVALID_SLOT = 0xFF; @@ -127,6 +128,7 @@ typedef enum ERRL_USR_DTL_HISTORY_DATA = 0x04, ERRL_USR_DTL_WOF_DATA = 0x05, ERRL_USR_DTL_PGPE_PK_TRACE = 0x06, + ERRL_USR_DTL_PGPE_DATA = 0x07, } ERRL_USR_DETAIL_TYPE; // These are the possible OCC States. @@ -283,6 +285,12 @@ extern uint8_t G_occErrIdCounter; extern errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS]; +// Shared SRAM offset to access the HCODE Error Log Table +#define HCODE_ELOG_TABLE_SRAM_OFFSET 0x40 +#define HCODE_ELOG_TABLE_MAGIC_NUMBER 0x454C5443 // "ELTC" +extern hcode_elog_entry_t *G_hcode_elog_table; +extern uint32_t G_hcode_elog_table_slots; + typedef enum { ERRH_AVSBUS_VDD_CURRENT = 0x01, ERRH_AVSBUS_VDD_VOLTAGE = 0x02, diff --git a/src/occ_405/main.c b/src/occ_405/main.c index 241f627..5e4a0c8 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -62,6 +62,7 @@ #include "pgpe_service_codes.h" #include <common.h> #include "p9_memmap_occ_sram.h" +#include "pstate_pgpe_occ_api.h" // Used to indicate if OCC was started during IPL, in which case OCC's only // job is to look for checkstops. This flag is set by hostboot in OCC's header @@ -521,8 +522,20 @@ bool read_pgpe_header(void) G_pgpe_header.wof_tables_addr = in32(PGPE_HEADER_ADDR + PGPE_WOF_TBLS_ADDR_OFFSET); G_pgpe_header.wof_tables_length = in32(PGPE_HEADER_ADDR + PGPE_WOF_TBLS_LEN_OFFSET); - MAIN_TRAC_IMP("Shared SRAM Address[0x%08x], PGPE Beacon Address[0x%08x]", - G_pgpe_header.shared_sram_addr, G_pgpe_header.beacon_sram_addr); + const uint32_t hcode_elog_table_addr = G_pgpe_header.shared_sram_addr + HCODE_ELOG_TABLE_SRAM_OFFSET; + if (HCODE_ELOG_TABLE_MAGIC_NUMBER == in32(hcode_elog_table_addr)) + { + G_hcode_elog_table_slots = (in32(hcode_elog_table_addr + 4) >> 24); + G_hcode_elog_table = (hcode_elog_entry_t*)(hcode_elog_table_addr + 8); + } + else + { + G_hcode_elog_table_slots = 0; + G_hcode_elog_table = 0; + } + + MAIN_TRAC_IMP("Shared SRAM Address[0x%08x], PGPE Beacon Address[0x%08x], HCODE Elog Table [0x%08X] (%d slots)", + G_pgpe_header.shared_sram_addr, G_pgpe_header.beacon_sram_addr, G_hcode_elog_table, G_hcode_elog_table_slots); MAIN_TRAC_IMP("WOF Tables Main Memory Address[0x%08x], Len[0x%08x], " "Req Active Quads Address[0x%08x], " "WOF State address[0x%08x]", diff --git a/src/occ_405/timer/timer.c b/src/occ_405/timer/timer.c index be5abbe..0dd6861 100755 --- a/src/occ_405/timer/timer.c +++ b/src/occ_405/timer/timer.c @@ -38,6 +38,7 @@ #include <pgpe_shared.h> #include <sensor.h> #include <amec_sensors_centaur.h> +#include <common.h> //*************************************************************************/ // Externs @@ -76,6 +77,8 @@ SSX_IRQ_FAST2FULL(ocbTHndler, ocbTHndlerFull); // Globals //*************************************************************************/ bool G_wdog_enabled = false; +extern uint8_t G_occ_interrupt_type; +bool G_htmgt_notified_of_error = false; // memory deadman is a per port timer that the MCU uses to verify that // the memory's power and thermal are properly monitored. The memory deadman @@ -222,6 +225,7 @@ void init_mem_deadman_reset_task(void) // Verify PGPE is still functional by reading PGPE Beacon from // SRAM if after 8ms (2 consecutive checks) there is no change // to the PGPE Beacon count then log an error and request reset. +// 4. Check for PGPE error in shared SRAM // // End Function Specification #define TASK_PGPE_BEACON_RUN_TICK_COUNT 8 @@ -259,6 +263,22 @@ void task_poke_watchdogs(struct task * i_self) L_check_pgpe_beacon_count++; } } + +// 4. Check if PGPE has an error to report (non-FSP systems) + if ((G_occ_interrupt_type != FSP_SUPPORTED_OCC) && (G_htmgt_notified_of_error == false)) + { + unsigned int index = 0; + for (; index < G_hcode_elog_table_slots; ++index) + { + if (in64(&G_hcode_elog_table[index]) != 0) + { + // Found HCODE elog + notify_host(INTR_REASON_HTMGT_SERVICE_REQUIRED); + G_htmgt_notified_of_error = true; + break; + } + } + } } // Function Specification |