summaryrefslogtreecommitdiffstats
path: root/import
diff options
context:
space:
mode:
authorAmit Tendolkar <amit.tendolkar@in.ibm.com>2019-03-13 07:57:13 -0500
committerSumit Kumar <sumit_kumar@in.ibm.com>2019-08-12 04:05:27 -0500
commitbe8d21b411df69ba4fc458ecf96849456d5337b3 (patch)
treec061b32591f28739932a03dce245cd8a8567cff3 /import
parentcfaad693982aa8b33a28e47bb568fc7483c7557c (diff)
downloadtalos-hcode-be8d21b411df69ba4fc458ecf96849456d5337b3.tar.gz
talos-hcode-be8d21b411df69ba4fc458ecf96849456d5337b3.zip
OCC assisted PGPE, SGPE Error Logging
Support basic infrastructure to - create an error log - add trace to the error log - add any user data section to the error log - add callouts to the error log - commit the error log - fix size issues and alignment exceptions - Fixes .. trace buffer parsing, repetitive xgpe logs, added PVR & PIR to log - Fixed severity, removed demo trigger code files RTC: 198654 Change-Id: Ie9842d2631863132ee456d421f0974cf9ade76ce Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/75078 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Gregory S Still <stillgs@us.ibm.com> Reviewed-by: RANGANATHPRASAD G. BRAHMASAMUDRA <prasadbgr@in.ibm.com> Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Diffstat (limited to 'import')
-rw-r--r--import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H5
-rw-r--r--import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk3
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.c605
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.h142
-rw-r--r--import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errldefs.h106
-rw-r--r--import/chips/p9/procedures/ppe_closed/lib/p9_hcd_occ_errldefs.h232
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c5
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c5
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk2
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk2
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C5
11 files changed, 1107 insertions, 5 deletions
diff --git a/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H b/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H
index 8a4fc997..844bc715 100644
--- a/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H
+++ b/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HCODE Project */
/* */
-/* COPYRIGHT 2015,2018 */
+/* COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -76,6 +76,7 @@ HCD_CONST(OCC_SRAM_OCC_REGION_SIZE, (512 * ONE_KB))
HCD_CONST(OCC_SRAM_BEFORE_PGPE_REGION_SIZE_TOTAL,
(OCC_SRAM_IPC_REGION_SIZE + OCC_SRAM_GPE0_REGION_SIZE + OCC_SRAM_GPE1_REGION_SIZE))
+
//--------------------------------------------------------------------------------------
/// PGPE Base
@@ -192,5 +193,7 @@ HCD_CONST( OCC_SRAM_PGPE_TRACE_START,
(OCC_SRAM_PGPE_HEADER_ADDR + PGPE_HEADER_SIZE));
+HCD_CONST(OCC_SRAM_SHARED_DATA_BASE_ADDR,
+ (OCC_SRAM_PGPE_BASE_ADDR + OCC_SRAM_PGPE_REGION_SIZE - PGPE_OCC_SHARED_SRAM_SIZE))
#endif /* __P9_HCD_MEMMAP_OCC_SRAM_H__ */
diff --git a/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk b/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk
index 55cd38dc..0f0eb5f9 100644
--- a/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk
+++ b/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HCODE Project
#
-# COPYRIGHT 2015,2018
+# COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -43,6 +43,7 @@
HCODE_C_SOURCES = \
p9_stop_recovery_trigger.c \
+ p9_hcd_errl.c \
p9_hcd_block_copy.c \
p9_dd1_doorbell_wr.c
diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.c b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.c
new file mode 100755
index 00000000..d779c11c
--- /dev/null
+++ b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.c
@@ -0,0 +1,605 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2016,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 __PPE_CME
+
+#include <stdint.h>
+
+#include "pk.h"
+#include "ppe42_string.h"
+#include "pk_trace.h"
+
+#include "p9_hcd_memmap_occ_sram.H"
+
+#include "pstate_pgpe_occ_api.h"
+#include "p9_hcd_errldefs.h"
+#include "p9_hcd_errl.h"
+
+uint8_t G_errSlotUnrec[ERRL_MAX_ENTRY_SZ] __attribute__ ((aligned (8))) = {0};
+
+// As this is common code across GPEs, the number of error logs supported per
+// severity (and hence total error logs supported) per GPE has to be same.
+// Order of error logs in this table should match relative order per GPE from
+// elog_entry_index
+errlHndl_t G_gpeErrSlots[ERRL_MAX_SLOTS_PER_GPE] =
+{
+ (errlHndl_t)& G_errSlotUnrec
+};
+
+hcode_elog_entry_t* G_occElogTable = NULL; // Ptr to OCC shared data err idx tbl
+hcodeErrlConfigData_t G_errlConfigData = {0};
+hcodeErrlMetadata_t G_errlMetaData = {0};
+
+void initErrLogging (const uint8_t i_errlSource)
+{
+ HcodeOCCSharedData_t* l_occSharedData = (HcodeOCCSharedData_t*)
+ OCC_SRAM_SHARED_DATA_BASE_ADDR;
+
+ G_occElogTable = l_occSharedData->errlog_idx.elog;
+ G_errlConfigData.source = i_errlSource;
+
+ switch (i_errlSource)
+ {
+ case ERRL_SOURCE_PGPE:
+ G_errlConfigData.traceSz = ERRL_TRACE_DATA_SZ_PGPE;
+ break;
+
+ case ERRL_SOURCE_XGPE:
+ G_errlConfigData.traceSz = ERRL_TRACE_DATA_SZ_XGPE;
+ break;
+
+ default:
+ G_errlConfigData.source = ERRL_SOURCE_INVALID;
+ PK_TRACE_ERR ("initErrLogging: Bad Source %d", i_errlSource);
+ break;
+ }
+
+ // Record PPE Processor Version from where errors will be logged
+ // e.g. 0x42090203==PPE42 P9 DD2.3
+ G_errlConfigData.procVersion = mfspr(SPRN_PVR);
+ // Record PPE Instance from which errors will be logged
+ G_errlConfigData.ppeId = (uint16_t)(mfspr(SPRN_PIR)&PIR_PPE_INSTANCE_MASK);
+
+ G_errlMetaData.errId = 0;
+ G_errlMetaData.slotBits = 0;
+ G_errlMetaData.slotMask = ERRL_SLOT_MASK_DEFAULT;
+ G_errlMetaData.errSlot = ERRL_SLOT_INVALID;
+}
+
+// Function Specification
+//
+// Name: getErrSlotNumAndErrId
+//
+// Description: Get Error Slot Number and Error Id
+//
+// End Function Specification
+uint8_t getErrSlotNumAndErrId (
+ ERRL_SEVERITY i_severity,
+ uint8_t* o_errlId,
+ uint64_t* o_timeStamp )
+{
+ uint8_t l_slot = ERRL_SLOT_INVALID;
+ uint8_t l_localSlot = ERRL_SLOT_INVALID;
+ uint8_t l_baseSlot = 0;
+ uint32_t l_slotmask = ERRL_SLOT_MASK_DEFAULT;
+
+ // this logic will evolve once we support other severities
+ // or we could have a map table
+ if (ERRL_SEV_UNRECOVERABLE == i_severity)
+ {
+ switch (G_errlConfigData.source)
+ {
+ case ERRL_SOURCE_PGPE:
+ l_baseSlot = ERRL_SLOT_PGPE_BASE;
+ l_slotmask = ERRL_SLOT_MASK_PGPE_UNREC;
+ break;
+
+ case ERRL_SOURCE_XGPE:
+ l_baseSlot = ERRL_SLOT_XGPE_BASE;
+ l_slotmask = ERRL_SLOT_MASK_XGPE_UNREC;
+ break;
+ }
+ }
+
+ if (ERRL_SLOT_MASK_DEFAULT != l_slotmask)
+ {
+ // 0. Enter Critical Section to be thread-safe
+ PkMachineContext ctx;
+ pk_critical_section_enter (&ctx);
+
+ // 1. Check if a slot is free in the local GPE maintained slotBits
+ uint32_t l_slotBitWord = ~(G_errlMetaData.slotBits | l_slotmask);
+
+ // Count leading 0 bits in l_slotBitWord to get available slot based on
+ // l_slotmask. This logic is extensible to allow for a variable
+ // number of log slots per souce & severity based on proper definitions
+ // in ERRL_SLOT_MASK
+ __asm__ __volatile__ ( "cntlzw %0, %1;" : "=r" (l_slot) :
+ "r" (l_slotBitWord));
+
+ if (MAX_HCODE_ELOG_ENTRIES > l_slot)
+ {
+ // 2. Slot matching source + sev is available in local GPE slotBits
+ // Check that slot is free in the global OCC monitored Error Table
+ if (0 == G_occElogTable[l_slot].dw0.value)
+ {
+ // Matching slot is available in global OCC watched error table
+ // Get the local GPE Table slot
+ l_localSlot = l_slot - l_baseSlot;
+
+ // 3. Check that it does not exceed the local GPE error table
+ if (ERRL_MAX_SLOTS_PER_GPE > l_localSlot)
+ {
+ // 4. Get time stamp & save off timestamp
+ *o_timeStamp = pk_timebase_get();
+
+ // 5. Save global slot details in GPE. We cannot write to
+ // global OCC elog table until error is ready to commit
+ G_errlMetaData.slotBits |= (ERRL_SLOT_SHIFT >> l_slot);
+ G_errlMetaData.slotMask = l_slotmask;
+ G_errlMetaData.errSlot = l_slot;
+
+ // 6. Save off incremented counter which forms error log id
+ // Provide next ErrorId; ErrorId should never be 0.
+ *o_errlId = ((++G_errlMetaData.errId) == 0) ?
+ ++G_errlMetaData.errId :
+ G_errlMetaData.errId;
+ }
+ else
+ {
+ // localSlot cannot exceed local GPE Error Table Size
+ PK_TRACE_ERR ("Slot exceeds max! slot: %d localSlot: %d",
+ l_slot, l_localSlot);
+ l_localSlot = ERRL_SLOT_INVALID;
+ }
+ }
+ else
+ {
+ // Prev error nor yet cleared by OCC, GPE creating errors faster
+ // than OCC is consuming them (globally)
+ PK_TRACE_ERR ("Slot %d not free in global OCC table!", l_slot);
+ }
+ }
+ else
+ {
+ // Slot not available, was available in OCC Error Table,
+ // but already taken in GPE, for an error that should be
+ // commited soon. Multi-threaded GPE producing errors faster than
+ // they are being committed (locally)
+ PK_TRACE_ERR ("Slot %d not free in local GPE!", l_slot);
+ }
+
+ // 7. Exit Critical Section to be thread-safe
+ pk_critical_section_exit (&ctx);
+ }
+ else
+ {
+ PK_TRACE_ERR ("Can't get free slot! Bad Source %d OR Sev %d!",
+ G_errlConfigData.source, i_severity);
+ }
+
+ PK_TRACE_INF ("Sev %d Slot G %d L %d EID 0x%08X",
+ i_severity, l_slot, l_localSlot, *o_errlId);
+
+ return l_localSlot;
+}
+
+// @note i_size is a multiple of 8 bytes
+// Trace Buff Header is a multiple of 8 bytes (56 B currently)
+// Each chunk being copied is a multiple of 8 bytes
+// The Trace Buffer User Data Section Payload start address is 8 B aligned
+uint32_t copyTraceBufferPartial ( void* i_pDst,
+ uint16_t i_size )
+{
+ PK_TRACE_INF (">> copyTraceBufferPartial: size %d bytes", i_size);
+ uint16_t l_bytesCopied = 0;
+ const uint32_t l_trHdrSz = sizeof(PkTraceBuffer) - PK_TRACE_SZ;
+ const uint32_t l_trStateOffset = g_pk_trace_buf.state.offset &
+ PK_TRACE_CB_MASK;
+ uint32_t l_szBytes = l_trHdrSz; // first copy trace header
+ bool l_buffWrapped = false;
+ uint32_t l_offset = l_trHdrSz;
+
+ const uint16_t pk_tr_size = g_pk_trace_buf.size;
+ const uint16_t pk_tr_sz_max = PK_TRACE_SZ;
+ const uint32_t pk_tr_state_offset = g_pk_trace_buf.state.offset;
+
+ if (NULL != i_pDst)
+ {
+ // copy the trace buffer header
+ //PK_TRACE_INF ("Copying Tr Buff Hdr %d bytes", l_szBytes);
+ memcpy ( i_pDst,
+ (void*) &g_pk_trace_buf,
+ l_szBytes );
+ l_bytesCopied = l_szBytes;
+
+ // If size being copied is less than what was in the header, adjust
+ // the necessary fields to suit that partial buffer in new header
+ // Can't do this in PPE due to alignment restrictions .. compensate in
+ // parser world
+#if 0
+
+ if (l_pPkTraceBuf->size > i_size)
+ {
+ l_pPkTraceBuf->size = i_size;
+ l_pPkTraceBuf->state.offset = i_size;
+ }
+
+#endif
+
+ l_szBytes = i_size - l_szBytes; // account for copied trace header bytes
+
+ if (l_trStateOffset >= l_szBytes)
+ {
+ // TEs in requested size fit in -un-wrapped part of buffer
+ l_offset += l_trStateOffset - l_szBytes;
+ }
+ else
+ {
+ // requested size has some TEs in the wrapped part of the buffer
+ // copy wrapped chunk of TEs 1st, then copy the -un-wrapped TEs
+ // so that we have TEs in rev-chrono after both copies
+ l_buffWrapped = true;
+ l_szBytes -= l_trStateOffset;
+ l_offset += PK_TRACE_SZ - l_szBytes;
+ }
+
+ // copy (append to header) the first chunk of TEs
+ //PK_TRACE_INF ("Copying 1st chunk of TEs @ %d %d bytes",
+ // l_offset, l_szBytes);
+ memcpy ( i_pDst + l_bytesCopied,
+ (void*)(&g_pk_trace_buf) + l_offset,
+ l_szBytes );
+ l_bytesCopied += l_szBytes;
+
+ if (l_buffWrapped == true)
+ {
+ // Now copy the -un-wrapped chunk of TEs
+ l_szBytes = l_trStateOffset;
+ l_offset = l_trHdrSz;
+
+ // copy (append to 1st chunk) the 2nd chunk of wrapped trace entries
+ //PK_TRACE_INF ("Copying 2nd chunk of wrapped TEs @%d %d bytes",
+ // l_offset, l_szBytes);
+ memcpy ( i_pDst + l_bytesCopied,
+ (void*)(&g_pk_trace_buf) + l_offset,
+ l_szBytes );
+ l_bytesCopied += l_szBytes;
+ }
+ }
+
+ PK_TRACE_INF ("buf.state.offset %d offset.wrapped %d buf.sz %d buf.max %d",
+ pk_tr_state_offset, l_trStateOffset, pk_tr_size, pk_tr_sz_max);
+
+ PK_TRACE_INF ( "<< copyTraceBufferPartial: size %d copied %d",
+ i_size, l_bytesCopied );
+ return l_bytesCopied;
+}
+
+void reportErrorLog (errlHndl_t i_err)
+{
+ if (NULL != i_err)
+ {
+ if (G_errlMetaData.errId == i_err->iv_entryId)
+ {
+ PK_TRACE_INF ("reportErrorLog: EID 0x%08X", i_err->iv_entryId);
+ hcode_elog_entry_t l_errlEntry;
+
+ l_errlEntry.dw0.fields.errlog_id = i_err->iv_entryId;
+ l_errlEntry.dw0.fields.errlog_len = i_err->iv_userDetails.iv_entrySize;
+ l_errlEntry.dw0.fields.errlog_addr = (uint32_t)i_err;
+ l_errlEntry.dw0.fields.errlog_src = G_errlConfigData.source;
+
+ // Enter Critical Section to be thread-safe
+ PkMachineContext ctx;
+ pk_critical_section_enter (&ctx);
+
+ // OCC Error Table should get updated last as OCC polls on it
+ G_occElogTable[G_errlMetaData.errSlot].dw0.value =
+ l_errlEntry.dw0.value;
+
+ // Free up this slot as available on this GPE's records.
+ // OCC will free up corresponding slot in Shared SRAM space once
+ // the error log is processed
+ G_errlMetaData.slotBits &= G_errlMetaData.slotMask;
+ G_errlMetaData.slotMask = ERRL_SLOT_MASK_DEFAULT;
+ G_errlMetaData.errSlot = ERRL_SLOT_INVALID;
+
+ pk_critical_section_exit (&ctx);
+ }
+ }
+
+ PK_TRACE_INF ("<< reportErrorLog");
+}
+
+// Function Specification
+//
+// Name: createErrl
+//
+// Description: Create an Error Log
+//
+// End Function Specification
+errlHndl_t createErrl(
+ const uint16_t i_modId,
+ const uint8_t i_reasonCode,
+ const uint16_t i_extReasonCode,
+ const ERRL_SEVERITY i_sev,
+ const uint32_t i_userData1,
+ const uint32_t i_userData2,
+ const uint32_t i_userData3 )
+{
+ PK_TRACE_INF ("createErrl: modid %d rc %d sev %d",
+ i_modId, i_reasonCode, i_sev);
+
+ errlHndl_t l_rc = NULL;
+ uint64_t l_time = 0;
+ uint8_t l_id = 0;
+ uint8_t l_errSlot = getErrSlotNumAndErrId( i_sev, &l_id, &l_time);
+
+ if (ERRL_SLOT_INVALID != l_errSlot)
+ {
+ PK_TRACE_INF ("createErrl: EID [%d] Slot [%d]", l_id, l_errSlot);
+
+ // get slot pointer
+ l_rc = G_gpeErrSlots[l_errSlot];
+ // save off entry Id
+ l_rc->iv_entryId = l_id;
+ //Save off version info
+ l_rc->iv_version = ERRL_STRUCT_VERSION_1;
+ l_rc->iv_reasonCode = i_reasonCode;
+ l_rc->iv_extendedRC = i_extReasonCode;
+ l_rc->iv_severity = i_sev;
+ l_rc->iv_numCallouts = 0;
+ l_rc->iv_maxSize = ERRL_MAX_ENTRY_SZ;
+
+ // reset the committed flag indicating reusing slot for new error
+ l_rc->iv_userDetails.iv_committed = 0;
+ // save off default sizes of error log and user data sections
+ l_rc->iv_userDetails.iv_entrySize = sizeof( ErrlEntry_t );
+ l_rc->iv_userDetails.iv_userDetailEntrySize = 0;
+ // save off time
+ l_rc->iv_userDetails.iv_timeStamp = l_time;
+ // save off rest of input parameters
+ l_rc->iv_userDetails.iv_modId = i_modId;
+ l_rc->iv_userDetails.iv_userData1 = i_userData1;
+ l_rc->iv_userDetails.iv_userData2 = i_userData2;
+ l_rc->iv_userDetails.iv_userData3 = i_userData3;
+ l_rc->iv_userDetails.iv_version = ERRL_USR_DTL_STRUCT_VERSION_1;
+
+ // Save other invariants
+ l_rc->iv_userDetails.iv_procVersion = G_errlConfigData.procVersion;
+ l_rc->iv_userDetails.iv_ppeId = G_errlConfigData.ppeId;
+
+ // Default other unused fields
+ l_rc->iv_reserved1 = 0;
+ l_rc->iv_userDetails.iv_reserved4 = 0; // reserved by def
+ l_rc->iv_userDetails.iv_reserved5 = 0; // reuse OCC State
+ l_rc->iv_userDetails.iv_reserved7 = 0; // Alignment
+ }
+
+ PK_TRACE_INF ("<< createErrl EID: 0x%08X",
+ (l_rc != NULL) ? (l_rc->iv_entryId) : 0ull);
+
+ return l_rc;
+}
+
+
+// Function Specification
+//
+// Name: addCalloutToErrl
+//
+// Description: Add a callout to an Error Log
+//
+// End Function Specification
+void addCalloutToErrl(
+ errlHndl_t io_err,
+ const ERRL_CALLOUT_TYPE i_type,
+ const uint64_t i_calloutValue,
+ const ERRL_CALLOUT_PRIORITY i_priority)
+{
+ // 1. check if handle is valid (not null or invalid)
+ // 2. not committed
+ // 3. severity is not informational (unless mfg action flag is set)
+ // 4. callouts still not full
+ if ( (io_err != NULL ) &&
+ (io_err->iv_userDetails.iv_committed == 0) &&
+ (io_err->iv_severity != ERRL_SEV_INFORMATIONAL) &&
+ (io_err->iv_numCallouts < ERRL_MAX_CALLOUTS) )
+ {
+ //set callout type
+ io_err->iv_callouts[ io_err->iv_numCallouts ].iv_type = (uint8_t)i_type;
+
+ //set callout value
+ io_err->iv_callouts[ io_err->iv_numCallouts ].iv_calloutValue = i_calloutValue;
+
+ //set priority
+ io_err->iv_callouts[ io_err->iv_numCallouts].iv_priority = (uint8_t)i_priority;
+
+ //increment actual number of callout
+ io_err->iv_numCallouts++;
+ }
+ else
+ {
+ PK_TRACE_INF ("Callout type 0x%02X was NOT added to elog", i_type);
+ }
+}
+
+
+// Function Specification
+//
+// Name: addUsrDtlsToErrl
+//
+// Description: Add User Details to an Error Log
+// @note i_size should be a multiple of 8 bytes for alignment
+// End Function Specification
+void addUsrDtlsToErrl(
+ errlHndl_t io_err,
+ uint8_t* i_dataPtr,
+ const uint16_t i_size,
+ const uint8_t i_version,
+ const ERRL_USR_DETAIL_TYPE i_type)
+{
+ // 1. check if handle is valid
+ // 2. NOT empty
+ // 3. not committed
+ // 4. size being passed in is valid
+ // 5. data pointer is valid
+ // 6. and we have enough size
+ if ((io_err != NULL ) &&
+ (io_err->iv_userDetails.iv_committed == 0) &&
+ (i_size != 0) &&
+ (i_dataPtr != NULL) &&
+ ((io_err->iv_userDetails.iv_entrySize) < ERRL_MAX_ENTRY_SZ))
+ {
+ //adjust user details entry payload size to available size
+ uint16_t l_availableSize = ERRL_MAX_ENTRY_SZ -
+ (io_err->iv_userDetails.iv_entrySize +
+ sizeof (ErrlUserDetailsEntry_t));
+
+ // Add user details section only if ERRL_USR_DATA_SZ_MIN dwords fit
+ if (l_availableSize >= ERRL_USR_DATA_SZ_MIN)
+ {
+ //local copy of the usr details entry
+ ErrlUserDetailsEntry_t l_usrDtlsEntry;
+
+ l_usrDtlsEntry.iv_type = (uint8_t)i_type;
+ l_usrDtlsEntry.iv_version = i_version;
+ l_usrDtlsEntry.iv_size = (i_size < l_availableSize) ? i_size :
+ l_availableSize;
+
+ void* l_p = io_err;
+
+ // add user detail entry to end of the current error log
+ // copy header of the user detail entry
+ l_p = memcpy (l_p + (io_err->iv_userDetails.iv_entrySize),
+ &l_usrDtlsEntry,
+ sizeof (ErrlUserDetailsEntry_t));
+
+ // If we have more cases of user detail section payloads needing
+ // additional logic to copy the payload, the below if-else could
+ // be moved into a new function
+
+ // copy payload of the user detail entry
+ l_p += sizeof (ErrlUserDetailsEntry_t);
+
+ if (ERRL_USR_DTL_TRACE_DATA == l_usrDtlsEntry.iv_type)
+ {
+ // copy the trace buffer (source data ptr is global)
+ copyTraceBufferPartial (l_p, l_usrDtlsEntry.iv_size);
+ }
+ else
+ {
+ memcpy (l_p, i_dataPtr, l_usrDtlsEntry.iv_size);
+ }
+
+ uint16_t l_totalSizeOfUsrDtls = sizeof (ErrlUserDetailsEntry_t) +
+ l_usrDtlsEntry.iv_size;
+ //update usr data entry size
+ io_err->iv_userDetails.iv_userDetailEntrySize +=
+ l_totalSizeOfUsrDtls;
+ //update error log size
+ io_err->iv_userDetails.iv_entrySize += l_totalSizeOfUsrDtls;
+ }
+ }
+}
+
+
+// Function Specification
+//
+// Name: addTraceToErrl
+//
+// Description: Add trace to an error log
+//
+// End Function Specification
+void addTraceToErrl (errlHndl_t io_err)
+{
+ PkMachineContext ctx;
+
+ pk_critical_section_enter (&ctx);
+
+ addUsrDtlsToErrl (
+ io_err,
+ (uint8_t*) &g_pk_trace_buf,
+ G_errlConfigData.traceSz,
+ ERRL_TRACE_VERSION_1,
+ ERRL_USR_DTL_TRACE_DATA );
+
+ pk_critical_section_exit (&ctx);
+}
+
+// Function Specification
+//
+// Name: commitErrl
+//
+// Description: Commit an Error Log
+//
+// End Function Specification
+void commitErrl (errlHndl_t* io_err)
+{
+ if (NULL != *io_err)
+ {
+ // this is the last common place holder to change or override the error
+ // log fields like actions, severity, callouts, etc. based on generic
+ // handling on cases like xstop, etc., before the error is 'commited'
+ // for OCC to notice and trigger (H)TMGT
+
+ // mark the last callout by zeroing out the next one
+ uint8_t l_lastCallout = (*io_err)->iv_numCallouts;
+
+ if (l_lastCallout < ERRL_MAX_CALLOUTS)
+ {
+ PK_TRACE_INF ("Zeroing last+1 callout %u", l_lastCallout);
+
+ (*io_err)->iv_callouts[l_lastCallout].iv_type = 0;
+ (*io_err)->iv_callouts[l_lastCallout].iv_calloutValue = 0;
+ (*io_err)->iv_callouts[l_lastCallout].iv_priority = 0;
+ }
+
+ // numCallouts must be the max value as defined by the TMGT-OCC spec.
+ (*io_err)->iv_numCallouts = ERRL_MAX_CALLOUTS;
+
+ // calculate checksum & save it off
+ uint32_t l_cnt = 2; // starting point is after checksum field
+ uint32_t l_sum = 0;
+ uint32_t l_size = (*io_err)->iv_userDetails.iv_entrySize;
+ uint8_t* l_p = (uint8_t*)*io_err;
+
+ for( ; l_cnt < l_size ; l_cnt++ )
+ {
+ l_sum += *(l_p + l_cnt);
+ }
+
+ (*io_err)->iv_checkSum = l_sum;
+
+ // save off committed
+ (*io_err)->iv_userDetails.iv_committed = 1;
+
+ // report error to OCC
+ reportErrorLog(*io_err);
+
+ *io_err = (errlHndl_t) NULL;
+ }
+}
+
+#endif // __PPE_CME
diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.h b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.h
new file mode 100755
index 00000000..d4357066
--- /dev/null
+++ b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.h
@@ -0,0 +1,142 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errl.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2016,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 _P9_HCD_ERRL_H
+#define _P9_HCD_ERRL_H
+
+#include <stdbool.h>
+#include "p9_hcd_occ_errldefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// @brief Creates an Error Log in the PPE's local SRAM
+///
+/// @param [in] i_modId Module/function ID where the error log is being created
+/// @param [in] i_reasonCode A unique code identifying the reason of this error
+/// @param [in] i_extReasonCode An extended Reason Code for this error
+/// @param [in] i_sev Severity this Error Log should be created with
+/// @param [in] i_userData1-3 User data to add to the Error Log as a FFDC
+///
+/// @return On Success: A non-NULL handle to the Error Log created
+/// On Failure: NULL
+///
+/// @note: (COMP_ID | i_reasonCode) become bits 16-31 of SRC
+/// @note: (i_modId<<16 | i_extReasonCode) get to user data4 & parsers
+/// @note: Until pending Error Logs are processed and room is created for a new
+/// HCode Error Log in SRAM by OCC/(H)TMGT, attempts to create new Error
+/// Log via createErrl will fail and HCode error logs will be dropped
+
+errlHndl_t createErrl (
+ const uint16_t i_modId,
+ const uint8_t i_reasonCode,
+ const uint16_t i_extReasonCode,
+ const ERRL_SEVERITY i_sev,
+ const uint32_t i_userData1,
+ const uint32_t i_userData2,
+ const uint32_t i_userData3 );
+
+
+/// @brief Adds a callout to the Error Log
+///
+/// @param [inout] io_err A valid error log handle returned via by createErrl
+/// @param [in] i_type Type of the callout (hardware FRU, code, etc.)
+/// @param [in] i_calloutValue Specific instance of the type being called out
+/// @param [in] i_priority Priority of this callout for service action
+///
+/// @return void
+///
+// @note: Callouts help a service engineer isolate the failing part/subsystem
+/// @note: Customer visible errors (Pred/Unrec) need at least 1 callout.
+/// @note: If there is an error adding callout to the Error Log, the callout
+/// will be dropped from the Error Log
+
+/// @TODO via RTC 211557: Support adding callouts to Hcode Error Logs
+/// TMGT adds a Processor callout as default, until this is supported
+
+void addCalloutToErrl (
+ errlHndl_t io_err,
+ const ERRL_CALLOUT_TYPE i_type,
+ const uint64_t i_calloutValue,
+ const ERRL_CALLOUT_PRIORITY i_priority);
+
+
+/// @brief Adds User Details Section to the Error log
+///
+/// @param [inout] io_err A valid error log handle returned via by createErrl
+/// @param [in] i_dataPtr Pointer to the data being added
+/// @param [in] i_size Size of the data being added in bytes
+/// @param [in] i_version Version of the User Details Section Header
+/// @param [in] i_type Type of the user details section being added
+///
+/// @return void
+///
+/// @note: Generic method to add user specific data like traces, dashboard, etc.
+/// @note: i_size must be a multiple of 8 & data must be 8 byte aligned
+/// @note: If there is an error adding user details section to the Error Log,
+/// the user details section will be dropped from the Error Log
+
+void addUsrDtlsToErrl (
+ errlHndl_t io_err,
+ uint8_t* i_dataPtr,
+ const uint16_t i_size,
+ const uint8_t i_version,
+ const ERRL_USR_DETAIL_TYPE i_type);
+
+
+/// @brief Add Trace Data to the Error log
+///
+/// @param [inout] io_err A valid error log handle returned via by createErrl
+///
+/// @return void
+///
+/// @note: Common method to add Hcode traces from PK trace buffer to Error Log
+/// @note: If there is an error adding traces to the Error Log, the trace data
+/// will be dropped from the Error Log
+
+void addTraceToErrl (errlHndl_t io_errl);
+
+
+/// @brief Commit the Error Log to the Error Log Table in OCC Shared SRAM
+///
+/// @param [inout] io_err Input: Pointer to a valid error log handle
+/// Output: NULL
+///
+/// @return void
+///
+/// @note: No further changes can be made to an error log once it is committed
+/// @note: It can take time for OCC & (H)TMGT to consume an error log commited
+/// to the OCC SRAM and convert it to a PEL/SEL
+/// @note: OCC or (H)TMGT being busy or not functional due to other reasons, can
+/// can cause HCode commited errors not converting to PELs/SELs
+
+void commitErrl (errlHndl_t* io_err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_P9_HCD_ERRL_H
diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errldefs.h b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errldefs.h
new file mode 100644
index 00000000..edb6a6df
--- /dev/null
+++ b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errldefs.h
@@ -0,0 +1,106 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/procedures/ppe_closed/lib/p9_hcd_errldefs.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2016,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 _P9_HCD_ERRLDEFS_H
+#define _P9_HCD_ERRLDEFS_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Size of traces to add to ERRL_USR_DTL_TRACE_DATA
+#define ERRL_TRACE_DATA_SZ_PGPE 0x200
+#define ERRL_TRACE_DATA_SZ_XGPE 0x100
+
+// Max number of errorlog slots per GPE
+// Supporting only 1 (unrecoverable) error per GPE due to memory restrictions
+#define ERRL_MAX_SLOTS_PER_GPE 1
+
+// Used for shifting slot bits
+static const uint32_t ERRL_SLOT_SHIFT = 0x80000000;
+
+// These bits are used to acquire a slot number. When used with the global
+// slot bit mask, we are able to get 1 slot for unrecoverable errors,
+// 1 slot for informational logs and so on. This can be trivially extended to
+// multiple slots of the same type of error as well.
+// @note The algorithm to get an error slot assumes the all errors per GPE
+// are ordered sequentially without mixing with errors from other GPEs
+// @note Per current requirement & memory constraints there will only be 1
+// unrecoverable error log per GPE. There could be unused bits until
+// we use informational error logs, etc.
+/* Slot Masks */
+typedef enum
+{
+ ERRL_SLOT_MASK_DEFAULT = 0xFFFFFFFF,
+ ERRL_SLOT_MASK_PGPE_UNREC = 0x7FFFFFFF,
+ ERRL_SLOT_MASK_XGPE_UNREC = 0xBFFFFFFF,
+} ERRL_SLOT_MASK;
+
+// Index into array of error log entries in hcode_error_table_t
+// @note This enum should be in sync with the masks defined by ERRL_SLOT_MASK
+// @note OCC processes entries in hcode_error_table_t from 0 to
+// MAX_HCODE_ELOG_ENTRIES & is agnostic of how hcode orders them
+enum elog_entry_index
+{
+ ERRL_SLOT_PGPE_BASE = 0x00,
+ ERRL_SLOT_PGPE_UNREC = 0x00,
+ ERRL_SLOT_XGPE_BASE = 0x01,
+ ERRL_SLOT_XGPE_UNREC = 0x01,
+ ERRL_SLOT_INVALID = 0xFF, // default invalid
+};
+
+// Structure to house-keep specific error log related metadata until it is
+// commited out to the OCC Shared Data Error Index Table
+typedef struct
+{
+ uint32_t slotBits; // Bits 0:1 flags for slots taken by errors
+ uint32_t slotMask; // Slot mask of the current error being processed
+ uint8_t errId; // Error log id of this error, rolling counter
+ uint8_t errSlot; // Slot number of this error in OCC Shared SRAM
+} hcodeErrlMetadata_t;
+
+// Structure to configure GPE specific metadata for error logging that is
+// common for all errors logged from that GPE
+typedef struct
+{
+ uint32_t procVersion;// PPE Processor Version, from PVR
+ uint16_t ppeId; // PPE Instance Id, from PIR
+ uint16_t traceSz; // Size of ERRL_USR_DTL_TRACE_DATA to add
+ uint8_t source; // Engine creating logs. See ERRL_SOURCE
+} hcodeErrlConfigData_t;
+
+// Initializes attributes of the common error logging framework based on the GPE
+// instance trying to use it.
+// @note APIs in p9_hcd_errl.h should not be used before initializing the
+// error logging framework once
+void initErrLogging (const uint8_t i_errlSource);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _P9_HCD_ERRLDEFS_H
diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_occ_errldefs.h b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_occ_errldefs.h
new file mode 100644
index 00000000..33bae5a8
--- /dev/null
+++ b/import/chips/p9/procedures/ppe_closed/lib/p9_hcd_occ_errldefs.h
@@ -0,0 +1,232 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/procedures/ppe_closed/lib/p9_hcd_occ_errldefs.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* 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 _P9_HCD_OCC_ERRLDEFS_H
+#define _P9_HCD_OCC_ERRLDEFS_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+#ifdef __PPE__
+extern "C" {
+#else
+namespace hcode
+{
+#endif
+#endif
+
+// See TMGT_OCC_INTERFACE_v1_x_y
+//
+// @note
+// - HCode error logs will be read and processed as a contiguous blob of data
+// by Service Processor or Host Firmware components
+// - (H)TMGT as well as parsers will depend on the order as well as size of
+// members in the Error Log Entry for processing and parsing the error log
+// correctly
+// - As a part of the framework, the Error Log Structure is reused and adapted
+// from the TMGT-OCC-Interface specification, all reserved fields should be
+// left unused (zeroed) in the Error Log Entries, to avoid mis-interpretation
+// and unintended actions in firmware (e.g. Resets, Safe Mode)
+
+// Max size of error log (1024 bytes)
+#define ERRL_MAX_ENTRY_SZ 0x400
+
+// Max number of callouts
+#define ERRL_MAX_CALLOUTS 6 // @TODO improve hard restrictions
+
+// Min size (bytes) of user data that can be added, excluding the header
+#define ERRL_USR_DATA_SZ_MIN 128
+
+// These are the possible sources that an error log can be coming from
+typedef enum
+{
+ ERRL_SOURCE_405 = 0x00,
+ ERRL_SOURCE_PGPE = 0x10,
+ ERRL_SOURCE_XGPE = 0x20, // Used by SGPE in P9
+ ERRL_SOURCE_INVALID = 0xFF,
+} ERRL_SOURCE;
+
+// These are the possible severities that an error log can have.
+// Users must ONLY use these enum values for severity.
+// Predictive & Unrecoverable severities are customer visible & will
+// solicit appropriate callouts and documentation
+/* Error Severity */
+typedef enum
+{
+ ERRL_SEV_INFORMATIONAL = 0x00, // unused
+ ERRL_SEV_PREDICTIVE = 0x01, // unused
+ ERRL_SEV_UNRECOVERABLE = 0x02,
+ ERRL_SEV_CALLHOME_DATA = 0x03, // unused
+} ERRL_SEVERITY;
+
+// These are the possible callout priorities that a callout can have.
+// Users must ONLY use these enum values for callout priority
+/* Callout Priority */
+typedef enum
+{
+ ERRL_CALLOUT_PRIORITY_INVALID = 0x00,
+ ERRL_CALLOUT_PRIORITY_LOW = 0x01,
+ ERRL_CALLOUT_PRIORITY_MED = 0x02,
+ ERRL_CALLOUT_PRIORITY_HIGH = 0x03,
+} ERRL_CALLOUT_PRIORITY;
+
+// These are the user detail types that a user details can have.
+// Users must ONLY use these enum values for user detail type.
+// User Detail is expected to be pass-through to the parser.
+/* User Detail Type */
+typedef enum
+{
+ ERRL_USR_DTL_TRACE_DATA = 0x01,
+ ERRL_USR_DTL_DASH_PGPE = 0x02, // @TODO via RTC: 211559
+ ERRL_USR_DTL_DASH_XGPE = 0x03, // @TODO via RTC: 211560
+ ERRL_USR_DTL_BINARY_DATA = 0x04,
+} ERRL_USR_DETAIL_TYPE;
+
+/* Errl Structure Version */
+typedef enum
+{
+ ERRL_STRUCT_VERSION_1 = 0x01,
+} ERRL_STRUCT_VERSION;
+
+/* Errl User Details Version */
+typedef enum
+{
+ ERRL_USR_DTL_STRUCT_VERSION_1 = 0x01,
+} ERRL_USR_DTL_STRUCT_VERSION;
+
+/* Errl Trace Version */
+typedef enum
+{
+ ERRL_TRACE_VERSION_1 = 0x01,
+} ERRL_TRACE_VERSION;
+
+// @TODO via RTC 211557 >> start
+// Hcode related callouts will need some firmware post-processing
+// Callout types will be adapted/extended for Hcode after consulting with FW
+// @note As a placeholder TMGT adds a processor callout if
+// sev!=info && source!=405 && numCallouts==0
+/* Type of Callout */
+typedef enum
+{
+ ERRL_CALLOUT_TYPE_HUID = 0x01, // unused
+ ERRL_CALLOUT_TYPE_COMPONENT_ID = 0x02,
+ ERRL_CALLOUT_TYPE_GPU_ID = 0x03, // unused
+} ERRL_CALLOUT_TYPE;
+
+/* TMGT-OCC Component Ids */
+typedef enum
+{
+ ERRL_COMPONENT_ID_FIRMWARE = 0x01,
+ ERRL_COMPONENT_ID_OVER_TEMPERATURE = 0x04, // unused
+ ERRL_COMPONENT_ID_OVERSUBSCRIPTION = 0x05, // unused
+ ERRL_COMPONENT_ID_NONE = 0xFF,
+} ERRL_COMPONENT_ID;
+// @TODO via RTC 211557 << end
+
+/* Callout Structure */
+struct ErrlCallout
+{
+ uint64_t iv_calloutValue; // Callout Value
+ uint8_t iv_type; // Type of callout (See ERRL_CALLOUT_TYPE)
+ uint8_t iv_priority; // Callout Priority (See ERRL_CALLOUT_PRIORITY)
+ uint8_t iv_reserved3[6]; // PPE alignment restriction
+} __attribute__ ((__packed__));
+
+typedef struct ErrlCallout ErrlCallout_t;
+
+// @note The User Detail Structure consists of the fields below followed
+// by each individual User Details Entry structure & data
+// A data pointer field is NOT defined but rather inferred here. In the
+// error log contents, the user will see all the subsequent fields
+// followed by each User Details Entry structure and its data
+/* User Detail Structure */
+struct ErrlUserDetails
+{
+ uint8_t iv_version; // User Details Version
+ uint8_t iv_reserved4; // Reserved, per definition
+ uint16_t iv_modId; // Module Id
+ uint32_t iv_procVersion; // PPE Processor Version Register (PVR)
+ uint64_t iv_timeStamp; // Time Stamp
+ uint16_t iv_ppeId; // PPE Instance in Chip
+ uint8_t iv_reserved5; // @reuse - OCC State
+ uint8_t iv_committed: 1; // Log Committed?
+ uint8_t iv_reserved6: 7;
+ uint32_t iv_userData1; // User Data Word 1
+ uint32_t iv_userData2; // User Data Word 2
+ uint32_t iv_userData3; // User Data Word 3
+ uint16_t iv_entrySize; // Log Size
+ uint16_t iv_userDetailEntrySize; // User Details Size
+ uint32_t iv_reserved7; // PPE alignment restriction
+} __attribute__ ((__packed__));
+
+typedef struct ErrlUserDetails ErrlUserDetails_t;
+
+// @note The User Detail Entry Structure consists of the fields below followed
+// by the actual data the user is trying to collect.
+// A data pointer field is NOT defined but rather inferred here. In the
+// error log contents, the user will see all the subsequent fields
+// followed by the actual data. For performance as well as alignment
+// requirements in the PPE, all actual data must be 8 byte aligned.
+/* User Detail Entry Structure */
+struct ErrlUserDetailsEntry
+{
+ uint8_t iv_version; // User Details Entry Version
+ uint8_t iv_type; // User Details Entry Type (ERRL_USR_DETAIL_TYPE)
+ uint16_t iv_size; // User Details Entry Size
+ uint32_t iv_reserved10; // PPE alignment restriction
+} __attribute__ ((__packed__));
+
+typedef struct ErrlUserDetailsEntry ErrlUserDetailsEntry_t;
+
+/* Error Log Structure */
+struct ErrlEntry
+{
+ uint16_t iv_checkSum; // Log CheckSum
+ uint8_t iv_version; // Log Version
+ uint8_t iv_entryId; // Log Entry ID
+ uint8_t iv_reasonCode; // Log Reason Code
+ uint8_t iv_severity; // Log Severity (See ERRL_SEVERITY)
+ uint8_t iv_reserved1; // Must be 0, until actions are defined
+ uint8_t iv_numCallouts; // Number of callouts in the log
+ uint16_t iv_extendedRC; // Log Extended Reason Code
+ uint16_t iv_maxSize; // Max possible size of Error Log
+ uint16_t iv_reserved2[2]; // @alignment
+ ErrlCallout_t iv_callouts[ERRL_MAX_CALLOUTS];// Callouts
+ ErrlUserDetails_t iv_userDetails; // User Details section for Log
+} __attribute__ ((__packed__));
+
+typedef struct ErrlEntry ErrlEntry_t;
+
+/* Error Log Handle */
+typedef ErrlEntry_t* errlHndl_t;
+
+#ifdef __cplusplus
+#ifdef __PPE__
+}
+#else
+}
+#endif
+#endif
+
+#endif // _P9_HCD_OCC_ERRLDEFS_H
diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c
index c5a1feb9..f3ba83f6 100644
--- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c
+++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c
@@ -77,4 +77,9 @@ void p9_pgpe_header_init()
&occ_shared_data->req_active_quads;//Requested Active Quads
G_pgpe_header_data->g_pgpe_wof_values_address = (uint32_t)&occ_shared_data->pgpe_wof_values;//Wof Values
+ // Write magic number & total error log slots supported in the shared data
+ // hcode error log table, for OCC to start acting on PGPE and SGPE errors.
+ // Init all error slots to available.
+ occ_shared_data->errlog_idx.dw0.fields.total_log_slots = MAX_HCODE_ELOG_ENTRIES;
+ occ_shared_data->errlog_idx.dw0.fields.magic_word = HCODE_ELOG_TABLE_MAGIC_WORD;
}
diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c
index 271c25fc..14947414 100644
--- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c
+++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c
@@ -32,6 +32,8 @@
#include "occhw_shared_data.h"
#include "p9_hcd_memmap_occ_sram.H"
#include "p9_hcd_memmap_base.H"
+#include "p9_hcd_occ_errldefs.h"
+#include "p9_hcd_errldefs.h"
extern TraceData_t G_pgpe_optrace_data;
@@ -279,6 +281,9 @@ main(int argc, char** argv)
pk_thread_resume(&G_p9_pgpe_thread_process_requests);
pk_thread_resume(&G_p9_pgpe_thread_actuate_pstates);
+ // Initialize the PGPE Error Logging
+ initErrLogging ((uint8_t) ERRL_SOURCE_PGPE);
+
//PGPE Header Init
p9_pgpe_header_init();
diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk
index 5bc7623c..a312c371 100644
--- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk
+++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk
@@ -92,7 +92,7 @@ PSTATE_COMMONFLAGS+= -DUSE_PK_APP_CFG_H=1
PSTATE_COMMONFLAGS+= -D__PPE_PLAT
PSTATE_COMMONFLAGS+= -D__PPE__
PSTATE_COMMONFLAGS+= -D__PK__=1
-PSTATE_COMMONFLAGS+= -DPK_TRACE_SZ=2048
+PSTATE_COMMONFLAGS+= -DPK_TRACE_SZ=1024
PSTATE_COMMONFLAGS+= -DPSTATE_GPE
diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk
index c516d6bf..40fdd7f5 100644
--- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk
+++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk
@@ -94,7 +94,7 @@ $(IMAGE)_COMMONFLAGS+= -DUSE_PK_APP_CFG_H=1
$(IMAGE)_COMMONFLAGS+= -D__PPE_PLAT
$(IMAGE)_COMMONFLAGS+= -D__PK__=1
#$(IMAGE)_COMMONFLAGS+= -fstack-usage
-$(IMAGE)_COMMONFLAGS+= -DPK_TRACE_SZ=2048
+$(IMAGE)_COMMONFLAGS+= -DPK_TRACE_SZ=1024
# add include paths
$(call ADD_PPEIMAGE_INCDIR,$(IMAGE),\
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C
index 45c7e7d4..d9b6a539 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C
@@ -28,7 +28,8 @@
#include "occhw_shared_data.h"
#include "p9_hcd_memmap_occ_sram.H"
#include "p9_hcd_memmap_base.H"
-
+#include "p9_hcd_occ_errldefs.h"
+#include "p9_hcd_errldefs.h"
//We define a global literal for these register addresses
////This way compiler put them in .sdata area, and the address
@@ -222,6 +223,7 @@ main(int argc, char** argv)
PK_PANIC(SGPE_MAIN_FAPI2_INIT_FAILED);
}
+ initErrLogging ((uint8_t) ERRL_SOURCE_XGPE);
p9_sgpe_stop_init();
// Initialize the thread control block for G_p9_sgpe_stop_enter_thread
@@ -258,6 +260,7 @@ main(int argc, char** argv)
OSD_PTR->occ_comp_shr_data.gpe3_data.gpe3_image_header_addr = OCC_SRAM_SGPE_BASE_ADDR + SGPE_HEADER_IMAGE_OFFSET;
OSD_PTR->occ_comp_shr_data.gpe3_data.gpe3_debug_header_addr = OCC_SRAM_SGPE_BASE_ADDR + SGPE_DEBUG_PTRS_OFFSET;
+
// Start running the highest priority thread.
// This function never returns
pk_start_threads();
OpenPOWER on IntegriCloud