summaryrefslogtreecommitdiffstats
path: root/src/include/usr/errl/errlentry.H
blob: fea1a76ef2fc1f9fef93974447755872a556ea26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/errl/errlentry.H $                            */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2011,2019                        */
/* [+] Google Inc.                                                        */
/* [+] 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 ERRLENTRY_H
#define ERRLENTRY_H
/**
 *  @file errlentry.H
 *
 *  @brief  Error Log entry object for Host Boot environment.
 *
 *  This header file contains the definition of error log entry class that
 *  is used to log errors from all firmware running in Host Boot environment.
 *
 */
/**
 * @page    errlog  Error Log
 *
 * @section Base Error Log
 *  See Host Boot Error Logging LLDD, Version 0.7  09/01/2011
 *
 * @section Adding User-Defined error blocks
 *
 *
 */

/*****************************************************************************/
// I n c l u d e s
/*****************************************************************************/
#include <stdint.h>
#include <limits.h>
#include <vector>
#include <errl/hberrltypes.H>
#include <errl/errlsctn.H>
#include <errl/errlprvt.H>
#include <errl/errluh.H>
#include <errl/errlsrc.H>
#include <errl/errlud.H>
#include <hbotcompid.H>
#include <targeting/common/target.H>
#include <attributeenums.H>

namespace ERRORLOGDISPLAY
{
class ErrLogDisplay;
}
namespace ERRORLOG
{
class ErrlEntry;
}
typedef ERRORLOG::ErrlEntry* errlHndl_t;

#include <hwas/common/hwasCallout.H>

namespace ERRORLOG
{

/*****************************************************************************/
// Forward class declarations
/*****************************************************************************/
class ErrlManager;
class ErrlUserDetailsBackTrace;

/**
 *  @brief      Host Boot Error log entry class.
 *  This class contains all of the entry management logic and necessary
 *  information to create a PEL or IPMI event type logs.
 *  A pointer to this class is known as an errlHndl_t (the error log handle)
 *  and it is the data type passed by applications on the stack to convey
 *  a failure.
 */
class ErrlEntry
{

    friend class ErrlManager;
    friend class ERRORLOGDISPLAY::ErrLogDisplay;
    friend class ErrlTest;

public:
    /** Constants to use in constructor */
    static constexpr bool ADD_SW_CALLOUT = true;
    static constexpr bool NO_SW_CALLOUT = false;
    static constexpr bool FORCE_DUMP = true;
    static constexpr bool NO_FORCE_DUMP = false;

    /**
     * @brief   ErrlEntry constructor. Builds an error log with info
     * constructed from the input.
     * Event type, Sub System, SRC type, and Terminate state are defaulted
     * to the most common values for Host Boot environment.  These values
     * can also be set to specific values by users if needed.
     * For available values, see errltypes.H
     * To understand the meaning of these values, refer to the
     * Platform Event Log and SRC PLDD at: https://mcdoc.boeblingen.de.
     * ibm.com/out/out.ViewDocument.php?documentid=1675
     *
     * The backtrace is captured as user detail data. Use removeBackTrace to
     * remove
     *
     * The order of parameters is arranged so that Host Boot error log
     * is as close to SP as possible.
     *
     * @param[in]   i_sev           Log's severity. See errltypes.H for
     *                              available values
     * @param[in]   i_modId         The module (interface) where this log is
     *                              created from.
     * @param[in]   i_reasonCode    Bits 00-07: Component Id
     *                              Bits 08-15: Reason code
     * @param[in]   i_user1         64 bits of user data which are placed
     *                              in the primary SRC
     * @param[in]   i_user2         64 bits of user data which are placed
     *                              in the primary SRC
     * @param[in]   i_hbSwError     if true, will automatically add a HIGH
     *                              severity callout for EPUB_PRC_HB_CODE
     * @param[in]   i_hbDump        if true, will flag error log as a candidate
     *                              for an HB dump if log is committed and is
     *                              used as status for a shutdown
     * @return  None
     */
    ErrlEntry(const errlSeverity_t i_sev,
              const uint8_t i_modId,
              const uint16_t i_reasonCode,
              const uint64_t i_user1 = 0,
              const uint64_t i_user2 = 0,
              const bool i_hbSwError = ErrlEntry::NO_SW_CALLOUT,
              const bool i_hbDump = ErrlEntry::NO_FORCE_DUMP );

    /**
     * @brief   Destructor
     *
     * Releases all resources owned by the handle.  If the log has not
     * been committed, it effectively aborts the log.
     * All logs not committed must be deleted to avoid a resource leak.
     * Committing an error log via ErrlManager will cause ErrlManager
     * to delete the log after saving it.
     *
     * @return  None
     *
     */
    ~ErrlEntry();

    /**
     *  @brief Read the log's severity
     *  The severity of a log determines how severe the
     *  problem is perceived to be.  The severity is
     *  initially set by the parameter in the constructor
     *  and can be changed at any point thereafter.
     *  See errl/errltypes.H
     *
     *  @return Current Log Severity
     *
     */
    errlSeverity_t sev() const { return iv_User.iv_severity; }


    /**
     *  @brief Set the log's severity
     *  The severity of a log determines how severe the
     *  problem is perceived to be.  The severity is
     *  initially set by the parameter in the constructor
     *  and can be changed at any point thereafter, unless the
     *  the severity has been set as "final".
     *
     *  @param[in]  i_sev Severity. See errl/errltypes.H
     *
     *  @return     void
     */
    void setSev(const errlSeverity_t i_sev)
    {
        if (false == iv_sevFinal) // update severity as long as not set "final"
        {
            iv_User.iv_severity = i_sev;
        }
    }

    /**
     *  @brief Set the log's severity "final".
     *  The severity being set will be set as "final" such that it can
     *  not be changed again. Setting a severity as "final" can be used
     *  in the less frequent case that a severity should not be
     *  changed by code at a higher level.
     *
     *  @param[in]  i_sev    Severity. See errl/errltypes.H
     *  @param[in]  i_final  true: If not already "final", sets severity and
     *                             marks the severity as "final"
     *                       false: If not "final", sets severity
     *
     *  @return     void
     */
    void setSev(const errlSeverity_t i_sev,
                bool  i_final)
    {

        if (false == iv_sevFinal) // as long as not already set as "final"
        {
            iv_User.iv_severity = i_sev;  // set severity
            iv_sevFinal = i_final;        // set whether severity is "final"
        }
    }

    /**
     *  @brief Get reason code. See errl/errlreasoncodes.H
     *
     *  @return reason code
     */
    uint16_t reasonCode() const;

    /**
     *  @brief Set reason code
     *
     *  @param[in]  i_reasonCode   The reason code.  The upper byte
     *                             of a reason code is the component ID.
     *                             See errl/errlreasoncodes.H
     *
     *  @return     void
     */
    void setReasonCode( const uint16_t i_reasonCode );

    /**
     *  @brief Get module id.  See errl/errlreasoncodes.H
     *
     *  @return module id
     */
    uint8_t moduleId() const;



    /**
     *  @brief Set module id
     *
     *  @param[in]  i_moduleId  The module ID. See errl/errlreasoncodes.H
     *
     *  @return     void
     */
    void setModuleId( const uint8_t i_moduleId );

    /**
     *  @brief Get the unique error log identifier (EID) of the error log.
     *
     *  @return The error log ID of the error log.
     */
    uint32_t eid() const;

    /**
     *  @brief Get the platform log identifier (PLID) of the error log.
     *  In legacy FSP, you could have one platform log ID such that a series
     *  of entry IDs (EIDs) related to a single PLID.
     *
     *  @return The platform log ID of the error log.
     */
    uint32_t plid() const;

    /**
     *  @brief Set the platform log id for this error log.
     *
     *  @param[in]  i_plid  PLID for error log
     *
     *  @return void
     */
    void plid( uint32_t i_plid);

    /**
     *  @brief Get the event type of the error log.
     *         See errl/errltypes.H
     *  @return errlEventType_t
     *
     */
    errlEventType_t eventType() const { return iv_User.iv_etype; }

    /**
     *  @brief Set the log's event type
     *
     *  @param[in]  i_eventType  Event type. See errl/errltypes.H
     *
     *  @return void
     *
     */
    void setEventType(const errlEventType_t i_eventType)
    {
        iv_User.iv_etype = i_eventType;
    }

    /**
     *  @brief Returns the log's sub system. See errl/errltypes.H
     *
     *  @return epubSubSystem_t
     *
     */
    epubSubSystem_t subSys() const { return iv_User.iv_ssid; }

   /**
     *  @brief Set the log's ePub sub system type.
     *
     *  @param[in]  i_subSys   Subsystem type. See errl/errltypes.H
     *
     *  @return void
     */
    void setSubSys(const epubSubSystem_t i_subSys)
    {
        // hb has ssid defined in two places
        iv_User.iv_ssid = i_subSys;
        iv_Src.iv_ssid  = i_subSys;
    }


    /**
     *  @brief Returns the log's SRC type. See errl/errltypes.H
     *
     *  @return srcType_t
     *
     */
    srcType_t srcType() const;

   /**
     *  @brief Set the log's SRC type
     *
     *  @param[in]  i_srcType   The SRC type for this error log. See
     *                          errl/errltypes.H
     *
     *  @return void
     */
    void setSrcType(const srcType_t i_srcType);

    /**
     *  @brief Returns the log's terminate state type. See
     *  errl/errltypes.H
     *
     *  @return errlTermState_t
     *
     */
    errlTermState_t termState() const;

    /**
     *  @brief Set the log's Terminating state
     *
     *  @param[in] i_termState  See errl/errltypes.H
     *
     *  @return void
     *
     */
    void setTermState(const errlTermState_t i_termState);

    /**
     * @brief Helper function to determine if log is a terminating error
     *
     *
     * @return  returns true if error will result in system termination.
     */
    bool isTerminateLog() const;

    /**
     *  @brief Add data to the iv_Src user data words.
     *
     *  @param[in] i_data - information to add to the user data word 1.
     *
     *  @return void
     *
     */
    void addUserData1( const uint64_t i_data );
    /**
     *  @brief Add data to the iv_Src user data words.
     *
     *  @param[in] i_data - information to add to the user data word 2.
     *
     *  @return void
     *
     */
    void addUserData2( const uint64_t i_data );

    /**
     *  @brief set Deconfigure and GARD bits in Hex Word 5
     *
     *  @return void
     *
     */
    void setDeconfigBit();
    void setGardBit();

    /**
     *  @brief Return iv_Src user data words.
     *
     *  @return data1 word from SRC
     *
     */
    uint64_t getUserData1() const;

    /**
     *  @brief Return iv_Src user data words.
     *
     *  @return data2 word from SRC
     *
     */
    uint64_t getUserData2() const;


   /**
     * @brief Allows the caller to add a chunk of FFDC data in a log
     *
     * @param[in]   i_compId         Component Id of the caller
     * @param[in]   i_dataPtr        Pointer to FFDC data
     * @param[in]   i_ffdcLen        Length of the data in bytes
     * @param[in]   i_ffdcVer        A user supplied identifier which
     *                               classifies the data
     * @param[in]   i_ffdcSubSect    A user supplied sub section identifier
     *                               which classifies the data.  This in
     *                               conjunction with the version can be used
     *                               to decode the data.
     * @param[in]   i_merge          A boolean value (defaults to false if
     *                               parameter is not specified) to indicate
     *                               whether this buffer is merged with the
     *                               previous section iff it matches.
     *
     * @return Pointer to FFDC section if successfully added.
     *         NULL if fails
     */
    ErrlUD * addFFDC(const compId_t i_compId,
                     const void * i_dataPtr,
                     const uint32_t i_ffdcLen,
                     const uint8_t i_ffdcVer,
                     const uint8_t i_ffdcSubSect,
                     bool i_merge = false);

    /**
     * @brief Append more data to an FFDC section.
     *
     * @param[in]   i_pErrlUD        Pointer to the user-define section
     *                               to add data to.  This pointer is
     *                               returned when addFFDC
     *                               function is called earlier.
     * @param[in]   i_dataPtr        Points to data block to be added
     * @param[in]   i_dataLen        Length of data in bytes
     *
     * @return void
     */
    void appendToFFDC( ErrlUD * i_pErrlUD,
                       const void *i_dataPtr,
                       const uint32_t i_dataLen);


    /**
     *  @brief Collect component trace
     *  The trace buffer named is collected and added to the error
     *  log.  The amount of traces is controlled by the i_max parameter.
     *  When zero, or left to default, the full trace buffer is copied.
     *  Otherwise, i_max size must be big enough to hold a trace buffer
     *  header (40 bytes) plus some trace data. For example, a trace
     *  entry with n bytes of data is n+28 bytes in size.
     *
     *  Note that component names given in hbotcompid.H do not necessarily
     *  map to the names of trace buffers created by that component.
     *  Trace buffer names are case insensitive.
     *
     *  @param[in]  i_name          Trace buffer name
     *  @param[in]  i_max           Size of trace to capture.
     *
     *  @note: 'i_max = 0' implies to collect all of the trace available for
     *         that component.  This is actually dangerous in Hostboot because
     *         our trace buffer are not hard-limited.  The default of this
     *         function will be 1K to keep us at a reasonable limit.
     *
     *  @return A Boolean indication of success.  False likely means
     *  the trace buffer name given is not found. However, check the ERRL
     *  trace buffer for the cause of the failure.
     */
    bool collectTrace(const char i_name[],
                      const uint64_t i_max = KILOBYTE);

    /**
     *  @brief Remove the duplicate trace entries from user detail data
     *  When multiple calls to collectTrace() on the same component id occur a
     *  new user detail section is created each time. This function removes the
     *  duplicates created from that process.
     *
     *  @algorithm A high level overview of what the code does is as follows:
     *      * Iterate through the iv_SectionVector which contains all UD
     *        sections and add each trace_bin_entry_t to a vector corresponding
     *        to each component id found in iv_SectionVector.
     *      * For each vector in the map of component id vectors
     *          * sort the collection of traces by timestamp and hash
     *          * call unique where the same timestamp and hash are considered
     *            to be equivalent trace entries to be removed.
     *          * Put all remaining trace entries into a new, consolidated trace
     *            UD section.
     *      * Remove the old trace UD sections from iv_SectionVector
     *      * Add the new consolidated trace UD sections to the iv_SectionVector
     */
    void removeDuplicateTraces(void);

     /**
      *  @brief Remove the back trace user detail data
      *  When an error log is constructed, the back trace is automatically
      *  captured. This function removes the backtrace. This should be used when
      *  a caller knows that the backtrace is of no use and wants to limit the
      *  size of the error log.
      */
    void removeBackTrace();

    /**
     *  @brief remove all deconfigure elements from an errorlog
     */
    void removeDeconfigure(void);

    /**
     *  @brief Add a clock callout.
     *  The i_target is used to identify the actual clock to callout because
     *  some systems have multiple clocks of a given type. This target is
     *  usually a chip target, but can possibly be a unit, depending on
     *  the clock type.
     *
     *  @param[in]  i_target        The hardware target fed by the clock
     *  @param[in]  i_clockType     The hardware clock type
     *  @param[in]  i_priority      Priority of the callout
     *  @param[in]  i_deconfigState Enum indicating whether the failing part
     *                              should be deconfigured.
     *  @param[in]  i_gardErrorType To indicate what type of failure occurred
     *
     *  @return void
     */
    void addClockCallout(const TARGETING::Target *i_target,
                       const HWAS::clockTypeEnum i_clockType,
                       const HWAS::callOutPriority i_priority,
                       const HWAS::DeconfigEnum
                                   i_deconfigState = HWAS::NO_DECONFIG,
                       const HWAS::GARD_ErrorType
                                   i_gardErrorType = HWAS::GARD_NULL);
    /**
     *  @brief Add a part callout.
     *  The i_target is used to identify the associated target. This target
     *  may not be a FRU
     *
     *  @param[in]  i_target        The hardware target that owns this part
     *  @param[in]  i_partType      The hardware part type
     *  @param[in]  i_priority      Priority of the callout
     *  @param[in]  i_deconfigState Enum indicating whether the failing part
     *                              should be deconfigured.
     *  @param[in]  i_gardErrorType To indicate what type of failure occurred
     *
     *  @return void
     */
    void addPartCallout(const TARGETING::Target *i_target,
                       const HWAS::partTypeEnum i_partType,
                       const HWAS::callOutPriority i_priority,
                       const HWAS::DeconfigEnum
                                   i_deconfigState = HWAS::NO_DECONFIG,
                       const HWAS::GARD_ErrorType
                                   i_gardErrorType = HWAS::GARD_NULL);


    /**
     *  @brief Add a bus callout
     *
     *  @param[in]  i_target1       The hardware bus endpoint target1
     *  @param[in]  i_target2       The hardware bus endpoint target2
     *  @param[in]  i_busType       The hardware bus type
     *  @param[in]  i_priority      Priority of the callout
     *  @param[in]  i_flag          Extra flag for callout structure
     *
     *  @return void
     */
    void addBusCallout(const TARGETING::Target *i_target1,
                       const TARGETING::Target *i_target2,
                       const HWAS::busTypeEnum i_busType,
                       const HWAS::callOutPriority i_priority,
                       const HWAS::CalloutFlag_t i_flags = HWAS::FLAG_NONE);

    /**
     *  @brief Add a bus callout with entity paths
     *
     *  @param[in]  i_target1       The PHYS_PATH of HW bus endpoint target1
     *  @param[in]  i_target2       The PHYS_PATH of HW bus endpoint target2
     *  @param[in]  i_busType       The hardware bus type
     *  @param[in]  i_priority      Priority of the callout
     *  @param[in]  i_flag          Extra flag for callout structure
     *
     *  @return void
     */
    void addBusCallout(const TARGETING::EntityPath & i_target1,
                       const TARGETING::EntityPath & i_target2,
                       HWAS::busTypeEnum i_busType,
                       HWAS::callOutPriority i_priority,
                       const HWAS::CalloutFlag_t i_flags = HWAS::FLAG_NONE);


    /**
     *  @brief Add a hardware callout
     *
     *  @param[in]  i_target        The hardware target
     *  @param[in]  i_priority      Priority of the callout
     *  @param [in] i_deconfigState Enum indicating whether the failing part
     *               should be deconfigured.
     *  @param [in] i_gardErrorType to indicate what type of failure occurred
     *
     *  @return void
     */
    void addHwCallout(const TARGETING::Target *i_target,
                        const HWAS::callOutPriority i_priority,
                        const HWAS::DeconfigEnum i_deconfigState,
                        const HWAS::GARD_ErrorType i_gardErrorType);

    /**
     *  @brief Add a procedure ( software ) callout
     *  Adds the given service procedure to the list
     *  of callouts for the log
     *
     *  @param[in]  i_procedure     Procedure identifier.
     *  @param[in]  i_priority      Priority of the callout
     *
     *  @return void
     */
    void addProcedureCallout(const HWAS::epubProcedureID i_procedure,
                             const HWAS::callOutPriority i_priority);


    /**
     *  @brief Add a special sensor callout
     *  Adds the given sensor to the list of callouts for the log
     *
     *  @param[in]  i_sensorID      Sensor ID
     *  @param[in]  i_sensorType    Type of sensor being added
     *  @param[in]  i_priority      Priority of the callout
     *
     *  @return void
     */
    void addSensorCallout(const uint32_t i_sensorID,
                          const HWAS::sensorTypeEnum i_sensorType,
                          const HWAS::callOutPriority i_priority);

    /**
     *  @brief Add an i2c device callout. Use this callout type for i2c devices
     *         that do not have target associated with them.
     *
     *  @param[in]  i_i2cMaster     The i2c master target. Cannot be nullptr.
                                    Cannot be the master sentinel.
     *  @param[in]  i_engine        The i2c device engine
     *  @param[in]  i_port          The i2c device port
     *  @param[in]  i_address       The i2c device address
     *  @param[in]  i_priority      Priority of the callout
     *
     *  @return void
     */
    void addI2cDeviceCallout(const TARGETING::Target *i_i2cMaster,
                             const uint8_t i_engine,
                             const uint8_t i_port,
                             const uint8_t i_address,
                             const HWAS::callOutPriority i_priority);

    /**
     * @brief  Import flattened error log
     *
     * @param[in] i_buffer, pointer to flat data
     * @param[in] i_len length of flattened data
     * @return Status  0==SUCCESS
     */
    uint64_t unflatten( const void * i_buffer, uint64_t i_len);

    /**
    * @brief Return the list of User Detail sections
    *
    * @param[in] i_compId Component id associated with the data to return
    * @param[in] i_subSect Subsection id associated with the data to return
    *
    *            //NOTE: You can pass COMP_ID or subsect 0 into this
    *                    function for wildcard
    *
    * @return vector of void pointers that point to the data buffer inside
    *         of a user details section
    */
    std::vector<void*> getUDSections(compId_t i_compId, uint8_t i_subSect);

    /**
     * @brief set iv_eselCallhomeInfoEvent
     *
     *      When true, send this error as a special callhome
     *                 type of eSEL to the BMC
     *
     * @return nothing
     */
    void setEselCallhomeInfoEvent(bool i_valid);

    /**
     * @brief get iv_eselCallhomeInfoEvent
     *
     * @return true if this log should result in a callhome event type eSEL,
     *         false otherwise
     */
    bool getEselCallhomeInfoEvent();

    /**
     * @brief get iv_doHbDump
     *
     * @return true if this log should result in a HB dump during a shutdown,
     *         false otherwise
     */
    bool getDoHbDump();

private:

     /**
     *  @brief Set the failing subsystem ID in the error log
     *         based on the highest priority callout.
     *
     */
    void setSubSystemIdBasedOnCallouts();

    /**
     *  @brief maps the target type to corresponding subsystem ID
     *
     *  @param[in]  i_target   Target Type.
     *
     *  @return     subsystem ID
     */
    epubSubSystem_t getSubSystem( TARGETING::TYPE i_target ) const;

    /**
     *  @brief maps the procedure to a corresponding subsystem ID
     *
     *  @param[in]  i_procedureId   procedure.
     *
     *  @return     subsystem ID
     */
    epubSubSystem_t getSubSystem( HWAS::epubProcedureID i_procedureId ) const;

    /**
     *  @brief maps a bus type to a subsystem ID
     *
     *  @param[in]  i_busType   Bus Type.
     *
     *  @return     subsystem ID
     */
    epubSubSystem_t getSubSystem( HWAS::busTypeEnum i_busType ) const;

    /**
     *  @brief maps a clock type to a subsystem ID
     *
     *  @param[in]  i_clockType   Bus Type.
     *
     *  @return     subsystem ID
     */
    epubSubSystem_t getSubSystem( HWAS::clockTypeEnum i_clockType ) const;

    /**
     *  @brief maps a part type to a subsystem ID
     *
     *  @param[in]  i_partType   Bus Type.
     *
     *  @return     subsystem ID
     */
    epubSubSystem_t getSubSystem( HWAS::partTypeEnum i_partType ) const;

    /**
     *  @brief maps a sensor type to a subsystem ID
     *
     *  @param[in]  i_sensorType   Sensor Type.
     *
     *  @return     subsystem ID
     */
    epubSubSystem_t getSubSystem( HWAS::sensorTypeEnum i_sensorType ) const;

    /**
     * @brief The ErrlManager will call here to ask the
     * ErrlEntry to assign the time of commit, and to assign
     * the commiter's comp ID.
     * The ErrlManager is the primary user of this call.
     *
     */
    void commit( compId_t i_commiterComp);


    /**
     * @brief The ErrlManager will call here to ask the
     * ErrlEntry to handle deconfigure and GARD callouts
     * The ErrlManager is the primary user of this call.
     *
     */
    void processCallout();


    /**
     * @brief The ErrlManager will call here to ask the
     * ErrlEntry to handle deferred deconfigure callouts
     * The ErrlManager is the primary user of this call.
     *
     */
    void deferredDeconfigure();


    /**
     * @brief Compute the flattened size of an error log.  It is typical
     * to call this function for the size of buffer required, then
     * allocate a buffer, then call flatten().
     * The ErrlManager is the primary user of this call.
     *
     * @return Size in bytes of the flattened data.
     */
    uint64_t flattenedSize();


    /**
     * @brief sort compare function, to be used when flattening an
     * error log
     *
     * @param[in]      i_ud1 - first user-defined section to compare
     * @param[in]      i_ud2 - second user-defined section to compare
     *
     * @return  true if i_ud1 should be first, false otherwise
     */
    static bool udSort(ErrlUD *i_ud1, ErrlUD *i_ud2);

    /**
     * @brief Flatten the data to caller's buffer. The resulting flat
     * data will be in PEL (platform event log) format.
     * The ErrlManager is the primary user of this call.
     *
     * @param[in,out]  o_buffer   Points to data block to be filled
     * @param[in]      i_cbBuffer Count of bytes in buffer supplied
     * @param[in]      i_truncate true: truncate the data
     *                              false: error if buffer too small
     *                  NOTE: PH, UH and PS MUST fit
     *
     * @return  Count of bytes copied to caller's
     *          buffer or else zero if it does not fit and i_truncate==false.
     */
    uint64_t flatten( void * o_buffer, const uint64_t i_cbBuffer,
            const bool i_truncate = false);

    /**
     * @brief Called by commit(), this function creates a
     * user details section which contains the Hostboot
     * build ID and adds this to the current error log being
     * processed.
     */
    void addHbBuildId();

    /**
     *  @brief Called by commit(), this function creates a user details section
     *  which contains the version info for each of the fw components in an
     *  OpenPOWER System and adds it to the current error log being processed.
     *  Note: This function only executes on a BMC based system.
     */
    void addVersionInfo(void);

    /**
     * @brief called by addHwCallout to retrieve various pieces of card
     *  and/or chip data, e.g. part number, serial number, ecid.
     *
     * @param[in]       i_target        The target to get the numbers for
     */
    void addPartIdInfoToErrLog(const TARGETING::Target * i_target);

#ifdef CONFIG_BMC_IPMI
    /**
     * @brief called by addHwCallout to retrieve the FRU ID and sensor ID
     * from the current target. If the current target does not contain
     * ATTR_FRU_ID, find the first parent that does and add the attribute
     * to the error log.
     *
     * @param[in]       i_target        The target to get the IDs for
     * @param[in]       i_priority      This target's callout priority
     */
    void addSensorDataToErrLog(TARGETING::Target * i_target,
                               HWAS::callOutPriority i_priority );
#endif

    /**
     * @brief set iv_skipShowingLogs
     *
     * @return nothing
     */
    void setSkipShowingLog(bool i_showLog);

    /**
     * @brief get iv_skipShowingLogs
     *
     * @return true if the log should be skipped, false otherwise
     */
    bool getSkipShowingLog();


    /**
     * @brief Sets internal flag to indicate if this log should be
     *    saved to PNOR and sent to the BMC
     *
     * @return nothing
     */
    void checkHiddenLogsEnable( );

    /**
     * @brief Check if the severity of this log indicates it is
     *   customer visible, note this ignores any override flags that
     *   might change standard behavior
     *
     *  INFORMATIONAL = false
     *  RECOVERED = false
     *  PREDICTIVE = true
     *  UNRECOVERABLE = true
     *  CRITICAL_SYS_TERM = true
     *
     * @return true if log is visible
     */
    bool isSevVisible( void );


    /**
      * @brief   Disabled copy constructor and assignment operator
      */
    ErrlEntry(const ErrlEntry& i_right);
    ErrlEntry& operator=(const ErrlEntry& i_right);



private:
    // Data Members
    ErrlPrvt        iv_Private;    // private header object
    ErrlUH          iv_User;       // user header object
    ErrlSrc         iv_Src;        // primary SRC section
    std::vector<ErrlUD*> iv_SectionVector;  // list of user defined sections
    std::vector<uint64_t> iv_btAddrs;    // list of addresses for the backtrace
    ErrlUserDetailsBackTrace * iv_pBackTrace; // Pointer to back trace

    // termstate will not be flattend into PEL, its only used by
    // hostboot.
    errlTermState_t iv_termState;

    // when true, the severity has been set "final" and can not be changed.
    bool iv_sevFinal;

    //when true, the current error log will not be saved to PNOR, sent to the
    //BMC, or displayed in the console
    bool iv_skipShowingLog;

    // when true, send this special type of eSEL to the BMC
    // This is used to send OCC informational errors up to BMC
    bool iv_eselCallhomeInfoEvent;

    // when true, if error log is committed, then the error log is tracked so
    // doShutdown can request that a HB dump be done.
    bool iv_doHbDump;


};





//-----------------------------------------------------------------------
// In-line functions
//-----------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

inline uint32_t ErrlEntry::eid() const
{
    return iv_Private.iv_eid;
}

inline uint32_t ErrlEntry::plid() const
{
    return iv_Private.iv_plid;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::plid( uint32_t i_plid)
{
    iv_Private.iv_plid = i_plid;
}


////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline uint8_t ErrlEntry::moduleId() const
{
    return iv_Src.iv_modId;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setModuleId( const uint8_t i_moduleId )
{
    iv_Src.iv_modId = i_moduleId;
    return;
}




////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline errlTermState_t ErrlEntry::termState() const
{
    return iv_termState;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setTermState(const errlTermState_t i_termState)
{
    iv_termState = i_termState;
    return;
}


////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setReasonCode( const uint16_t i_reasonCode )
{
    iv_Src.iv_reasonCode = i_reasonCode;
    return;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::addUserData1( const uint64_t i_data )
{
    iv_Src.iv_user1 = i_data;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::addUserData2( const uint64_t i_data )
{
    iv_Src.iv_user2 = i_data;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setDeconfigBit()
{
    iv_Src.iv_deconfig = true;
}
inline void ErrlEntry::setGardBit()
{
    iv_Src.iv_gard = true;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline uint64_t ErrlEntry::getUserData1() const
{
    return iv_Src.iv_user1;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline uint64_t ErrlEntry::getUserData2() const
{
    return iv_Src.iv_user2;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline uint16_t ErrlEntry::reasonCode() const
{
    return iv_Src.iv_reasonCode;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline srcType_t ErrlEntry::srcType() const
{
    return iv_Src.iv_srcType;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setSrcType(const srcType_t i_srcType)
{
    iv_Src.iv_srcType = i_srcType;
    return;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setSkipShowingLog(bool i_showLog)
{
    iv_skipShowingLog = i_showLog;
    return;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline bool ErrlEntry::getSkipShowingLog()
{
    return iv_skipShowingLog;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setEselCallhomeInfoEvent(bool i_valid)
{
    iv_eselCallhomeInfoEvent = i_valid;
    return;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline bool ErrlEntry::getEselCallhomeInfoEvent()
{
    return iv_eselCallhomeInfoEvent;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline bool ErrlEntry::getDoHbDump()
{
    return iv_doHbDump;
}

} // End namespace


/**
 * Retrieve the RC inside an error log, or return zero if the log is NULL
 */
#define ERRL_GETRC_SAFE(errhdl) (errhdl == NULL ? 0 : errhdl->reasonCode())

/**
 * Retrieve the PLID inside an error log, or return zero if the log is NULL
 */
#define ERRL_GETPLID_SAFE(errhdl) (errhdl == NULL ? 0 : errhdl->plid())

/**
 * Retrieve the EID inside an error log, or return zero if the log is NULL
 */
#define ERRL_GETEID_SAFE(errhdl) (errhdl == NULL ? 0 : errhdl->eid())

#endif //ERRLENTRY_H
OpenPOWER on IntegriCloud