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 8a4fc9979..844bc715d 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 55cd38dce..0f0eb5f95 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 000000000..d779c11cd --- /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 + +#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 000000000..d43570666 --- /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 +#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 000000000..edb6a6df1 --- /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 + +#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 000000000..33bae5a8a --- /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 + +#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 c5a1feb9f..f3ba83f69 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 271c25fc7..149474149 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 5bc7623cf..a312c3717 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 c516d6bfa..40fdd7f57 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 45c7e7d4f..d9b6a539b 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();