@@ -59,6 +59,7 @@ errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS] = {
59
59
};
60
60
61
61
extern uint8_t G_occ_interrupt_type ;
62
+ extern bool G_fir_collection_required ;
62
63
63
64
void hexDumpLog ( errlHndl_t i_log );
64
65
@@ -354,18 +355,30 @@ void addTraceToErrl(
354
355
void * l_traceAddr = io_err ;
355
356
uint16_t l_actualSizeOfUsrDtls = 0 ;
356
357
pore_status_t l_gpe0_status ;
358
+ ocb_oisr0_t l_oisr0_status ;
357
359
static bool L_gpe_halt_traced = FALSE;
360
+ static bool L_sys_checkstop_traced = FALSE;
358
361
359
362
360
363
// check if GPE was frozen due to a checkstop
361
364
l_gpe0_status .value = in64 (PORE_GPE0_STATUS );
362
365
if (l_gpe0_status .fields .freeze_action && !L_gpe_halt_traced )
363
366
{
364
367
L_gpe_halt_traced = TRUE;
365
- TRAC_ERR ("addTraceToErrl: OCC GPE halted due to checkstop. GPE0 status[0x%08x%08x]" ,
366
- l_gpe0_status .words .high_order , l_gpe0_status .words .low_order );
368
+ TRAC_IMP ("addTraceToErrl: Frozen GPE0 detected. GPE0 status[0x%08x%08x]" ,
369
+ l_gpe0_status .words .high_order ,
370
+ l_gpe0_status .words .low_order );
367
371
}
368
372
373
+ // Check if there is a system checkstop
374
+ l_oisr0_status .value = in32 (OCB_OISR0 );
375
+ if (l_oisr0_status .fields .check_stop && !L_sys_checkstop_traced )
376
+ {
377
+ L_sys_checkstop_traced = TRUE;
378
+ TRAC_IMP ("addTraceToErrl: System checkstop detected" );
379
+ }
380
+
381
+
369
382
// 1. Check if error log is not null
370
383
// 2. error log is not invalid
371
384
// 3. error log has not been commited
@@ -520,16 +533,20 @@ void reportErrorLog( errlHndl_t i_err, uint16_t i_entrySize )
520
533
i_err -> iv_userDetails .iv_modId , i_err -> iv_reasonCode ,
521
534
i_err -> iv_userDetails .iv_userData1 , i_err -> iv_userDetails .iv_userData2 );
522
535
523
- // If this system is using PSIHB complex, send an interrupt to Host so that
524
- // Host can inform HTMGT to collect the error log
525
- if (G_occ_interrupt_type == PSIHB_INTERRUPT )
536
+ // Defer the interrupt if FIR collection is required
537
+ if (!G_fir_collection_required )
526
538
{
527
- // From OCC OpenPower Interface v1.1, OCC needs to set bits 0 and 1 of
528
- // the OCB_OCCMISC register
529
- l_reg .fields .core_ext_intr = 1 ;
530
- l_reg .fields .reason_intr = 1 ;
539
+ // If this system is using PSIHB complex, send an interrupt to Host so that
540
+ // Host can inform HTMGT to collect the error log
541
+ if (G_occ_interrupt_type == PSIHB_INTERRUPT )
542
+ {
543
+ // From OCC OpenPower Interface v1.1, OCC needs to set bits 0 and 1 of
544
+ // the OCB_OCCMISC register
545
+ l_reg .fields .core_ext_intr = 1 ;
546
+ l_reg .fields .reason_intr = 1 ;
531
547
532
- out32 (OCB_OCCMISC_OR , l_reg .value );
548
+ out32 (OCB_OCCMISC_OR , l_reg .value );
549
+ }
533
550
}
534
551
}
535
552
@@ -544,16 +561,33 @@ void reportErrorLog( errlHndl_t i_err, uint16_t i_entrySize )
544
561
void commitErrl ( errlHndl_t * io_err )
545
562
{
546
563
pore_status_t l_gpe0_status ;
564
+ ocb_oisr0_t l_oisr0_status ;
565
+ static bool L_log_commits_suspended_by_safe_mode = FALSE;
547
566
548
- if ( io_err != NULL )
567
+ if (! L_log_commits_suspended_by_safe_mode && io_err != NULL )
549
568
{
550
569
// check if handle is valid and is NOT empty
551
570
if ((* io_err != NULL ) && ( * io_err != INVALID_ERR_HNDL ))
552
571
{
553
- // check if GPE was frozen due to a checkstop
572
+ // Check if the GPE is frozen or if a system
573
+ // checkstop has occurred
554
574
l_gpe0_status .value = in64 (PORE_GPE0_STATUS );
555
- if (l_gpe0_status .fields .freeze_action )
575
+ l_oisr0_status .value = in32 (OCB_OISR0 );
576
+
577
+ if (l_gpe0_status .fields .freeze_action
578
+ ||
579
+ l_oisr0_status .fields .check_stop )
556
580
{
581
+ if (l_gpe0_status .fields .freeze_action )
582
+ {
583
+ TRAC_IMP ("Frozen GPE0 detected by commitErrl" );
584
+ }
585
+
586
+ if (l_oisr0_status .fields .check_stop )
587
+ {
588
+ TRAC_IMP ("System checkstop detected by commitErrl" );
589
+ }
590
+
557
591
//Go to the reset state to minimize errors
558
592
reset_state_request (RESET_REQUESTED_DUE_TO_ERROR );
559
593
@@ -565,6 +599,14 @@ void commitErrl( errlHndl_t *io_err )
565
599
566
600
//set callouts to 0
567
601
(* io_err )-> iv_numCallouts = 0 ;
602
+
603
+ TRAC_IMP ("SAFE mode required, suspending error log commits. FIR capture required." );
604
+
605
+ // Suspend all error log commits
606
+ L_log_commits_suspended_by_safe_mode = TRUE;
607
+
608
+ // Motivate FIR data collection
609
+ G_fir_collection_required = TRUE;
568
610
}
569
611
570
612
// if reset action bit is set force severity to unrecoverable and
0 commit comments