summaryrefslogtreecommitdiffstats
path: root/src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C
blob: 993e8c5baa0a07843e6690f68cc482f64ced7c8a (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
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C $       */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,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                                                     */
/**
 *  @file call_proc_cen_ref_clk_enable.C
 *
 *  Support file for IStep: slave_sbe
 *   Slave SBE
 *
 *  HWP_IGNORE_VERSION_CHECK
 */

/******************************************************************************/
// Includes
/******************************************************************************/
#include <stdint.h>
#include <trace/interface.H>
#include <initservice/taskargs.H>
#include <errl/errlentry.H>
#include <initservice/isteps_trace.H>
#include <initservice/initserviceif.H>
#include <initservice/initsvcreasoncodes.H>
#include <sys/time.h>
#include <devicefw/userif.H>
#include <i2c/i2cif.H>
#include <p9_cen_ref_clk_enable.H>

//  targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
#include <targeting/namedtarget.H>
#include <targeting/attrsync.H>

//  fapi support
#include <fapi2.H>
#include <plat_hwp_invoker.H>
#include <isteps/hwpisteperror.H>

#include <errl/errludtarget.H>

// Note: The following secureboot-related includes will be kept separate from
// any other includes in this file in spite of the resulting duplicate includes.
// This will make it easier going forward to relocate the code that requires
// these includes. In the past isteps have been moved around, causing the
// security code below to slip farther away from the SBE update step. For
// maximal security, we want the secure boot code to happen immediately after
// SBE update and keeping the code relocateable facilitates this.

// begin includes for post sbe secureboot steps
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <isteps/istep_reasoncodes.H>
#include <initservice/initserviceif.H>

// targeting support
#include <targeting/common/target.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
#include <errl/errludtarget.H>
#include <attributetraits.H>

#include <util/align.H>
#include <util/algorithm.H>

// Fapi Support
#include <fapi2.H>
#include <target_types.H>
#include <plat_hwp_invoker.H>
#include <attributeenums.H>
#include <istepHelperFuncs.H>

//HWP
#include <p9_update_security_ctrl.H>

#ifdef CONFIG_AXONE
#include <p9a_ocmb_enable.H>
#include <exp_check_for_ready.H>
#endif

// secureboot
#include <secureboot/service.H>
#include <secureboot/settings.H>
#include <i2c/eepromif.H>
#include <sbe/sbeif.H>
#include "../../secureboot/common/errlud_secure.H"
#include <sbe/sbe_update.H>

#ifdef CONFIG_SECUREBOOT
#include <secureboot/service.H>
#include <scom/centaurScomCache.H>
#endif

// end includes for post sbe secureboot steps

const uint64_t MS_TO_WAIT_FIRST = 2500; //(2.5 s)
const uint64_t MS_TO_WAIT_OTHERS= 100; //(100 ms)

using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace ERRORLOG;
using namespace TARGETING;

namespace ISTEP_10
{

#ifdef CONFIG_SECUREBOOT
/**
 * @brief This structure associates SBE HW keys' hashes with names and SBE sides
 */
struct HashNode
{
    uint8_t* hash; /** SBE HW keys' hash for the named side */
    const char* name; /** Name of the side: either primary or backup */
    uint8_t side; /** A uint8_t value of 0 for primary or 1 for backup */
    HashNode(uint8_t* i_hash,
             const char* i_name,
             uint8_t i_side) : hash(i_hash), name(i_name), side(i_side)
    {
    }
};

/**
 * @brief This union simplifies bitwise operations for tracking the four
 * conditions of mismatch when matching security settings of a slave processor
 * with that of the master processor.
 */
union Mismatches
{
    uint8_t val;
    struct {
        uint8_t reserved : 4; /** unused */
        uint8_t sabmis : 1; /** Value of 1 indicates the SAB bit didn't match,
                             *  0 otherwise.
                             */
        uint8_t smdmis : 1; /** Value of 1 indicates the SMD bit did not match,
                             *  0 otherwise.
                             */
        uint8_t primis : 1; /** Value of 1 indicates the primary SBE HW key's
                             *  did not match, 0 otherwise.
                             */
        uint8_t bacmis : 1; /** Value of 1 indicates the backup SBE HW key's
                             *  did not match, 0 otherwise.
                             */
    };
};

/** @brief Handle a processor security error.
 *  @par Detailed Description:
 *      Puts all the error handling for mismatched processor security
 *      settings in one place in order to minimize code footprint. This
 *      highly-specialized function is not intended for public consumption.
 *  @param[in] i_pProc The target processor whose secure processor settings are
 *      exhibiting a problem. Must not be null.
 *  @param[in] i_rc The reason code of the error to be handled.
 *  @param[in] i_hashes A vector containing hash/string/side triples, where
 *      the string indicates the name of the hash, and the side refers to the
 *      SBE side that the hash was taken from.
 *  @param[in] i_plid If non zero this plid from a previous error will be linked
 *      To the error created by this function, ignored otherwise.
 *  @param[in] i_continue A boolean indicating whether hostboot should continue
 *      booting (and deconfigure the processor) or stop the IPL.
 *  @param[in] i_mismatches A bitstring of mismatch bits of type Mismatches
 *      corresponding to a mismatch of the SAB or SMD register or primary or
 *      secondary SBE HW Keys' Hash between the supplied target and the master
 *      processor. Optional parameter is for the RC_PROC_SECURITY_STATE_MISMATCH
 *      case only and must be left as default (value of 0) for all other cases.
 */
void handleProcessorSecurityError(TARGETING::Target* i_pProc,
                ISTEP::istepReasonCode i_rc,
                const std::vector<HashNode>& i_hashes,
                uint16_t i_plid,
                bool i_continue,
                Mismatches i_mismatches={0})
{
    using namespace ISTEP;

    // stop the caller from passing a null target
    assert(i_pProc != nullptr, "Bug! Target pointer must not be null");

    // make sure that caller is using the Mismatches parameter at the right time
    assert( (i_rc!=RC_PROC_SECURITY_STATE_MISMATCH && !i_mismatches.val) ||
            (i_rc==RC_PROC_SECURITY_STATE_MISMATCH && i_mismatches.val),
            "Mismatches parameter is for RC_PROC_SECURITY_STATE_MISMATCH only");

    ERRORLOG::errlSeverity_t l_severity = ERRORLOG::ERRL_SEV_UNRECOVERABLE;

    if (i_rc==RC_MASTER_PROC_SBE_KEYS_HASH_MISMATCH ||
        i_rc==RC_PROC_SECURITY_STATE_MISMATCH)
    {
        if (i_rc==RC_PROC_SECURITY_STATE_MISMATCH)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    ERR_MRK"handleProcessorSecurityError: processor state doesn't match master for processor tgt=0x%X",
                    TARGETING::get_huid(i_pProc));

            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "SMD is a %smatch", i_mismatches.smdmis? "mis": "");
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "SAB is a %smatch", i_mismatches.sabmis? "mis": "");
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Primary SBE hash is a %smatch",
                    i_mismatches.primis? "mis": "");
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Backup SBE hash is a %smatch",
                    i_mismatches.bacmis? "mis": "");
        }
        else  // master proc sbe keys' hash mismatch
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                ERR_MRK"handleProcessorSecurityError: Master processor sbe keys' hash doesn't match master backup sbe key's hash");
        }

        // Log as informational if secure boot is disabled
        if (!SECUREBOOT::enabled())
        {
            l_severity = ERRORLOG::ERRL_SEV_INFORMATIONAL;
        }
    }
    else
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "handleProcessorSecurityError: Istep error occurred, reason code 0x%X"
            ,i_rc);
        TRACDCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            ERR_MRK"handleProcessorSecurityError: %s fail",
        i_rc==RC_MASTER_PROC_PRIMARY_HASH_READ_FAIL?"Master primary hash read":
        i_rc==RC_MASTER_PROC_BACKUP_HASH_READ_FAIL?"Master backup hash read":
        i_rc==RC_MASTER_PROC_CBS_CONTROL_READ_FAIL?"Master CBS control read":
        i_rc==RC_MASTER_GET_SBE_BOOT_SEEPROM_FAIL?"Master get SBE boot Seeprom":
        i_rc==RC_SLAVE_PROC_PRIMARY_HASH_READ_FAIL?"Slave primary hash read":
        i_rc==RC_SLAVE_PROC_BACKUP_HASH_READ_FAIL?"Slave backup hash read":
        i_rc==RC_SLAVE_PROC_CBS_CONTROL_READ_FAIL?"Slave CBS control read":
        i_rc==RC_SLAVE_GET_SBE_BOOT_SEEPROM_FAIL?"Slave get SBE Boot Seeprom":
        "unknown");
    }

    auto err = new ERRORLOG::ErrlEntry(l_severity,
                ISTEP::MOD_VALIDATE_SECURITY_SETTINGS,
                i_rc,
                TARGETING::get_huid(i_pProc),
                TO_UINT64(i_mismatches.val),
                true);

    // if a plid was given, link it to the new error.
    if (i_plid)
    {
        err->plid(i_plid);
    }

    err->collectTrace(ISTEP_COMP_NAME);

    ERRORLOG::ErrlUserDetailsTarget(i_pProc).addToLog(err);

    // Add Security related user details
    SECUREBOOT::addSecureUserDetailsToErrlog(err);

    // add hashes to log and traces
    for(auto& hsh : i_hashes)
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK"handleProcessorSecurityError: %s hash: ", hsh.name);
        TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace,
                "Data = ",
                reinterpret_cast<void*>(hsh.hash),
                SHA512_DIGEST_LENGTH);
        SECUREBOOT::UdTargetHwKeyHash(
                i_pProc,
                hsh.side,
                hsh.hash).addToLog(err);
    }

    if (i_continue)
    {
         err->addHwCallout(i_pProc,
                HWAS::SRCI_PRIORITY_LOW,
                    (i_mismatches.val && // for any mismatch
                    i_rc != RC_MASTER_PROC_SBE_KEYS_HASH_MISMATCH) ?
                    HWAS::NO_DECONFIG: // don't deconfig the processor
                    HWAS::DELAYED_DECONFIG,
                HWAS::GARD_NULL);
    }

    // save off reason code before committing
    const auto l_reason = err->reasonCode();

    ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

    if (!i_continue)
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Terminating because future security cannot be guaranteed.");
        INITSERVICE::doShutdown(l_reason);
    }
}
#endif

//*****************************************************************************
// validateSecuritySettings()
//*****************************************************************************
/*
 * @brief Lock the SUL bit and enforce synchronized processor security states
 */
void validateSecuritySettings()
{
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                ENTER_MRK"validateSecuritySettings");

    errlHndl_t err = nullptr;

    // Before update procedure, trace security settings
    err = SECUREBOOT::traceSecuritySettings();
    if (err)
    {
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                   "validateSecuritySettings: Error back from "
                   "SECUREBOOT::traceSecuritySettings: rc=0x%X, plid=0x%X",
                   ERRL_GETRC_SAFE(err), ERRL_GETPLID_SAFE(err));

        // Commit log, but continue
        ERRORLOG::errlCommit( err, SECURE_COMP_ID );
    }

    // Always lock SBE SEEPROM
    bool l_force = true;

    TARGETING::TargetHandleList l_procList;
    getAllChips(l_procList,TARGETING::TYPE_PROC,true);

    // call p9_update_security_ctrl.C HWP
    do {

    if (!SECUREBOOT::enabled() && !l_force)
    {
        break;
    }

    TARGETING::TargetHandleList l_tpmList;
    getAllChips(l_tpmList,TARGETING::TYPE_TPM,false);

    // loop through the processors
    auto pProcItr = l_procList.begin();
    while (pProcItr != l_procList.end())
    {
        bool l_notInMrw = true;
        TARGETING::Target* l_tpm = nullptr;

        // check if processor has a TPM according to the mrw

        // for each TPM in the list compare i2c master path with
        // the path of the current processor
        for (auto itpm : l_tpmList)
        {
            auto l_physPath = (*pProcItr)->getAttr<TARGETING::ATTR_PHYS_PATH>();

            auto l_tpmInfo = itpm->getAttr<TARGETING::ATTR_TPM_INFO>();

            if (l_tpmInfo.i2cMasterPath == l_physPath)
            {
                l_notInMrw = false;
                l_tpm = itpm;
                break;
            }
        }

        if (l_notInMrw)
        {
            uint8_t l_protectTpm = 1;
            (*pProcItr)->setAttr<
                TARGETING::ATTR_SECUREBOOT_PROTECT_DECONFIGURED_TPM
                                                                >(l_protectTpm);
        }

        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapiTarg(*pProcItr);

        FAPI_INVOKE_HWP(err, p9_update_security_ctrl, l_fapiTarg, l_force);

        if (err)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                ERR_MRK"validateSecuritySettings - "
                "p9_update_security_ctrl failed for processor tgt=0x%X, "
                "TPM tgt=0x%X. Deconfiguring processor because future "
                "security cannot be guaranteed.",
                TARGETING::get_huid(*pProcItr),
                TARGETING::get_huid(l_tpm));

            // save the plid from the error before commiting
            const auto plid = err->plid();

            ERRORLOG::ErrlUserDetailsTarget(*pProcItr).addToLog(err);

            // commit this error log first before creating the new one
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

            /*@
             * @errortype
             * @reasoncode       ISTEP::RC_UPDATE_SECURITY_CTRL_HWP_FAIL
             * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
             * @severity         ERRL_SEV_UNRECOVERABLE
             * @userdata1        Processor Target
             * @userdata2        TPM Target
             * @devdesc          Failed to set SEEPROM lock and/or TPM deconfig
             *                   protection for this processor, so we cannot
             *                   guarrantee platform secuirty for this processor
             * @custdesc         Platform security problem detected
            */
            err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                ISTEP::MOD_VALIDATE_SECURITY_SETTINGS,
                ISTEP::RC_UPDATE_SECURITY_CTRL_HWP_FAIL,
                TARGETING::get_huid(*pProcItr),
                TARGETING::get_huid(l_tpm),
                true);

            err->addHwCallout(*pProcItr,
                            HWAS::SRCI_PRIORITY_LOW,
                            HWAS::DELAYED_DECONFIG,
                            HWAS::GARD_NULL);

            err->collectTrace(ISTEP_COMP_NAME);

            // pass on the plid from the previous error log to the new one
            err->plid(plid);

            ERRORLOG::ErrlUserDetailsTarget(*pProcItr).addToLog(err);

            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

            // remove the deconfigured processor from the list so that we can
            // reuse this list later to enforce processor security state below
            pProcItr = l_procList.erase(pProcItr);

            // we don't break here. we need to continue on to the next
            // processor and run the HWP on that one
        }
        else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                "p9_update_security_ctrl successful for proc: 0x%X tpm: 0x%X",
                TARGETING::get_huid(*pProcItr),
                TARGETING::get_huid(l_tpm));
            // only move on to the next processor if we didn't erase the
            // current one, since erasing the current one automatically gives us
            // the next one
            ++pProcItr;
        }
    }

    } while(0);
    // end of p9_update_security_ctrl procedure

    #ifdef CONFIG_SECUREBOOT
    // Enforce Synchronized Proc Security State
    do {

    uint64_t l_mainCbs = 0;

    // we need to know if we're in manufacturing mode to do some logic later
    TARGETING::Target* sys = nullptr;
    (void) targetService().getTopLevelTarget(sys);
    assert(sys, "validateSecuritySettings() system target is null");
    const auto mnfg_flags = sys->getAttr<ATTR_MNFG_FLAGS>();
    bool mnfg_mode = false;
    if(mnfg_flags & MNFG_FLAG_SRC_TERM)
    {
        mnfg_mode = true;
    }

    // a list of hashes we will be using to match primary to backups and
    // masters to slaves
    std::vector<HashNode> l_hashes;

    // master processor primary hash
    SHA512_t l_masterHash = {0};

    // master processor backup hash
    SHA512_t l_backupHash = {0};

    // slave processor primary hash (reset each time through the loop)
    SHA512_t l_slaveHashPri = {0};

    // slave processor backup hash (reset each time through the loop)
    SHA512_t l_slaveHashBac = {0};

    // nodes for the hashes vector only to be added to vector as needed
    auto l_master = HashNode(l_masterHash, "master primary", SBE::SBE_SEEPROM0);
    auto l_backup = HashNode(l_backupHash, "master backup", SBE::SBE_SEEPROM1);
    auto l_slave = HashNode(l_slaveHashPri, "slave primary", SBE::SBE_SEEPROM0);
    auto l_slaveb = HashNode(l_slaveHashBac, "slave backup", SBE::SBE_SEEPROM1);
    // obtain the master processor target
    TARGETING::Target* mProc = nullptr;
    err = TARGETING::targetService().queryMasterProcChipTargetHandle(mProc);
    if (err)
    {
        // if this happens we are in big trouble
        const auto rc = err->reasonCode();
        ERRORLOG::errlCommit(err, ISTEP_COMP_ID);
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Terminating because future security cannot be guaranteed.");
        INITSERVICE::doShutdown(rc);
        break;
    }

    // read the CBS control register of the main processor
    // (has SAB/SMD bits)
    err = SECUREBOOT::getProcCbsControlRegister(l_mainCbs, mProc);
    if (err)
    {
        const auto plid = err->plid();
        ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

        /*@
         * @errortype
         * @reasoncode       ISTEP::RC_MASTER_PROC_CBS_CONTROL_READ_FAIL
         * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
         * @userdata1        Master Processor Target
         * @devdesc          Unable to read the master processor CBS control
         *                   register
         * @custdesc         Platform security problem detected
         */
        handleProcessorSecurityError(mProc,
                                  ISTEP::RC_MASTER_PROC_CBS_CONTROL_READ_FAIL,
                                  l_hashes,
                                  plid,
                                  false); // stop IPL and deconfig processor
        break;
    }

    SBE::sbeSeepromSide_t bootSide = SBE::SBE_SEEPROM_INVALID;
    err = SBE::getSbeBootSeeprom(mProc, bootSide);
    if (err)
    {
        const auto plid = err->plid();
        ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

        /*@
         * @errortype
         * @reasoncode       ISTEP::RC_MASTER_GET_SBE_BOOT_SEEPROM_FAIL
         * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
         * @userdata1        Master Processor Target
         * @devdesc          Unable to get the master SBE boot seeprom side
         *
         * @custdesc         Platform security problem detected
         */
        handleProcessorSecurityError(mProc,
                              ISTEP::RC_MASTER_GET_SBE_BOOT_SEEPROM_FAIL,
                              l_hashes,
                              plid,
                              false); // stop IPL and deconfig processor
        break;
    }

    bool primaryReadFailAllowed = false;

    // read the primary sbe HW keys' hash for the master processor
    err = SBE::getHwKeyHashFromSbeImage(
                                     mProc,
                                     EEPROM::SBE_PRIMARY,
                                     bootSide,
                                     l_masterHash);

    if (err)
    {
        if (!mnfg_mode && bootSide != SBE::SBE_SEEPROM0)
        {
            primaryReadFailAllowed = true;
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "It's a non-mnfg boot and we failed to read the master primary HW SBE Keys' hash from seeprom 0. Ignoring the error since we didn't boot from that seeprom");
            err->collectTrace(ISTEP_COMP_NAME);
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);
        }
        else
        {
            const auto plid = err->plid();
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

            /*@
             * @errortype
             * @reasoncode      ISTEP::RC_MASTER_PROC_PRIMARY_HASH_READ_FAIL
             * @moduleid        ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
             * @userdata1       Master Processor Target
             * @devdesc         Unable to read the master processor primary hash
             *                  from the SBE
             * @custdesc         Platform security problem detected
             */
            handleProcessorSecurityError(mProc,
                                  ISTEP::RC_MASTER_PROC_PRIMARY_HASH_READ_FAIL,
                                  l_hashes,
                                  plid,
                                  false); // stop IPL and deconfig processor
        }
    }

    bool backupReadFailAllowed = false;

    // read the backup sbe HW keys' hash for the master processor
    err = SBE::getHwKeyHashFromSbeImage(
                                      mProc,
                                      EEPROM::SBE_BACKUP,
                                      bootSide,
                                      l_backupHash);

    if (err)
    {
        if (!mnfg_mode && bootSide != SBE::SBE_SEEPROM1)
        {
            backupReadFailAllowed = true;
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "It's a non-mnfg boot and we failed to read the master backup HW SBE Keys' hash from seeprom 1. Ignoring the error since we didn't boot from that seeprom");
            err->collectTrace(ISTEP_COMP_NAME);
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);
        }
        else
        {
            const auto plid = err->plid();
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

            /*@
             * @errortype
             * @reasoncode       ISTEP::RC_MASTER_PROC_BACKUP_HASH_READ_FAIL
             * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
             * @userdata1        Processor Target
             * @devdesc          Unable to read the master processor backup hash
             *                   from the SBE
             * @custdesc         Platform security problem detected
             */
            handleProcessorSecurityError(mProc,
                                  ISTEP::RC_MASTER_PROC_BACKUP_HASH_READ_FAIL,
                                  l_hashes,
                                  plid,
                                  false); // stop IPL and deconfig processor
            break;
        }
    }

    // make sure the master processor primary and backup SBE HW keys' hashes
    // match each other.
    if (primaryReadFailAllowed)
    {
        memcpy(l_masterHash, l_backupHash, SHA512_DIGEST_LENGTH);
    }
    else if (backupReadFailAllowed)
    {
        memcpy(l_backupHash, l_masterHash, SHA512_DIGEST_LENGTH);
    }
    else if(memcmp(l_masterHash,l_backupHash, SHA512_DIGEST_LENGTH)!=0)
    {
        // add only the hashes relevant to the error to hashes vector
        l_hashes.push_back(l_master);
        l_hashes.push_back(l_backup);

       bool l_continue = !SECUREBOOT::enabled();
        /*@
         * @errortype
         * @reasoncode       ISTEP::RC_MASTER_PROC_SBE_KEYS_HASH_MISMATCH
         * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
         * @severity         ERRL_SEV_UNRECOVERABLE
         * @userdata1        Master Processor Target
         * @devdesc          The primary SBE HW Keys' hash does not match the
         *                   the backup SBE HW Keys' hash, so we cannot
         *                   guarrantee platform security for the system
         * @custdesc         Platform security problem detected
         */
        handleProcessorSecurityError(mProc,
                                  ISTEP::RC_MASTER_PROC_SBE_KEYS_HASH_MISMATCH,
                                  l_hashes,
                                  0,
                                  l_continue); // stop IPL if secureboot enabled

        break;
    }
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
        "Master Primary SBE HW keys' hash successfully matches backup.");

    for(auto pProc : l_procList)
    {
        uint64_t l_procCbs = 0;

        if (mProc == pProc)
        {
            // skip the master processor
            continue;
        }

        // start with empty slave hashes each time through the loop
        memset(l_slaveHashPri,0,SHA512_DIGEST_LENGTH);
        memset(l_slaveHashBac,0,SHA512_DIGEST_LENGTH);

        // read the CBS control register of the current processor
        err = SECUREBOOT::getProcCbsControlRegister(l_procCbs, pProc);
        if (err)
        {
            const auto plid = err->plid();
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

            /*@
             * @errortype
             * @reasoncode       ISTEP::RC_SLAVE_PROC_CBS_CONTROL_READ_FAIL
             * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
             * @userdata1        Slave Processor Target
             * @devdesc          Unable to read the slave processor CBS control
             *                   register
             *
             * @custdesc         Platform security problem detected
             */
            handleProcessorSecurityError(pProc,
                                  ISTEP::RC_SLAVE_PROC_CBS_CONTROL_READ_FAIL,
                                  l_hashes,
                                  plid,
                                  true); // deconfigure proc and move on
            continue;
        }

        bootSide = SBE::SBE_SEEPROM_INVALID;
        err = getSbeBootSeeprom(pProc, bootSide, false);
        if (err)
        {
            const auto plid = err->plid();
            ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

            /*@
             * @errortype
             * @reasoncode       ISTEP::RC_SLAVE_GET_SBE_BOOT_SEEPROM_FAIL
             * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
             * @userdata1        Slave Processor Target
             * @devdesc          Unable to get the slave SBE boot seeprom side
             *
             * @custdesc         Platform security problem detected
             */
            handleProcessorSecurityError(pProc,
                                  ISTEP::RC_SLAVE_GET_SBE_BOOT_SEEPROM_FAIL,
                                  l_hashes,
                                  plid,
                                  true); // deconfigure proc and move on
            continue;
        }

        bool skipPrimaryMatch = false;

        // read the primary sbe HW keys' hash for the current processor
        err = SBE::getHwKeyHashFromSbeImage(
                                         pProc,
                                         EEPROM::SBE_PRIMARY,
                                         bootSide,
                                         l_slaveHashPri);

        if (err)
        {

            if (!mnfg_mode && bootSide != SBE::SBE_SEEPROM0)
            {
                skipPrimaryMatch = true;
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "It's a non-mnfg boot and we failed to read the HW SBE Keys' hash from seeprom 0, HUID:0x%.8X. Ignoring the error since we didn't boot from that seeprom", TARGETING::get_huid(pProc));
                err->collectTrace(ISTEP_COMP_NAME);
                ERRORLOG::errlCommit(err, ISTEP_COMP_ID);
            }
            else
            {
                const auto plid = err->plid();
                ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

                /*@
                 * @errortype
                 * @reasoncode       ISTEP::RC_SLAVE_PROC_PRIMARY_HASH_READ_FAIL
                 * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
                 * @userdata1        Slave Processor Target
                 * @devdesc          Unable to read the slave processor primary
                 *                   hash from the SBE
                 * @custdesc         Platform security problem detected
                 */
                handleProcessorSecurityError(pProc,
                                  ISTEP::RC_SLAVE_PROC_PRIMARY_HASH_READ_FAIL,
                                  l_hashes,
                                  plid,
                                  true); // deconfigure proc and move on
                continue;
            }
        }

        bool skipBackupMatch = false;

        // read the backup sbe HW keys' hash for the current processor
        err = SBE::getHwKeyHashFromSbeImage(
                                         pProc,
                                         EEPROM::SBE_BACKUP,
                                         bootSide,
                                         l_slaveHashBac);
        if (err)
        {
            if (!mnfg_mode && bootSide != SBE::SBE_SEEPROM1)
            {
                skipBackupMatch = true;
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "It's a non-mnfg boot and we failed to read the HW SBE Keys' hash from seeprom 1, HUID:0x%.8X Ignoring the error since we didn't boot from that seeprom", TARGETING::get_huid(pProc));
                err->collectTrace(ISTEP_COMP_NAME);
                ERRORLOG::errlCommit(err, ISTEP_COMP_ID);
            }
            else
            {
                const auto plid = err->plid();
                ERRORLOG::errlCommit(err, ISTEP_COMP_ID);

                /*@
                 * @errortype
                 * @reasoncode       ISTEP::RC_SLAVE_PROC_BACKUP_HASH_READ_FAIL
                 * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
                 * @userdata1        Slave Processor Target
                 * @devdesc          Unable to read the slave processor backup
                 *                   hash from the SBE
                 * @custdesc         Platform security problem detected
                 */
                handleProcessorSecurityError(pProc,
                                  ISTEP::RC_SLAVE_PROC_BACKUP_HASH_READ_FAIL,
                                  l_hashes,
                                  plid,
                                  true); // deconfigure proc and move on

                continue;
            }
        }

        // If the current processor has a key or SAB mismatch
        // then throw a terminate error. For SMD mismatch we throw
        // an informational error
        Mismatches l_mismatches = {0};

        // SAB bit mismatch
        l_mismatches.sabmis =
                      (SECUREBOOT::ProcCbsControl::SabBit & l_mainCbs) !=
                       (SECUREBOOT::ProcCbsControl::SabBit & l_procCbs);

        // Jumper state mismatch
        l_mismatches.smdmis =
                (SECUREBOOT::ProcCbsControl::JumperStateBit & l_mainCbs) !=
                 (SECUREBOOT::ProcCbsControl::JumperStateBit & l_procCbs);

        // primary sbe hash mismatch
        if (!skipPrimaryMatch)
        {
            l_mismatches.primis = memcmp(l_slaveHashPri,
                                         l_masterHash,
                                         SHA512_DIGEST_LENGTH) != 0;
        }

        // backup sbe hash mismatch
        if (!skipBackupMatch)
        {
            l_mismatches.bacmis = memcmp(l_slaveHashBac,
                                         l_masterHash,
                                         SHA512_DIGEST_LENGTH) != 0;
        }

        // only provide the relevant hashes for error handling cases
        if(l_mismatches.primis || l_mismatches.bacmis)
        {
            l_hashes.push_back(l_master);
        }
        if(l_mismatches.primis)
        {
            l_hashes.push_back(l_slave);
        }
        if(l_mismatches.bacmis)
        {
            l_hashes.push_back(l_slaveb);
        }

        // if there was any mismatch
        if (l_mismatches.val)
        {
            auto l_continue = true;
            // do not continue booting if there is a SAB mismatch under any
            // circumstance
            if (l_mismatches.sabmis)
            {
                l_continue = false;
            }
            // In secure mode, do not continue booting when SBE HW keys' hashes
            // are mismatched
            if ((l_mismatches.primis || l_mismatches.bacmis)
                 && SECUREBOOT::enabled())
            {
                l_continue = false;
            }

            /*@
             * @errortype
             * @reasoncode       ISTEP::RC_PROC_SECURITY_STATE_MISMATCH
             * @moduleid         ISTEP::MOD_VALIDATE_SECURITY_SETTINGS
             * @userdata1        Processor Target
             * @userdata2[60:60] SAB bit mismatch
             * @userdata2[61:61] Jumper (SMD) bit mismatch
             * @userdata2[62:62] Primary SBE hash mismatch
             * @userdata2[63:63] Backup SBE hash mismatch
             * @devdesc          Mismatch processor state was detected for this
             *                   processor, so we cannot guarrantee platform
             *                   security for the system
             * @custdesc         Platform security problem detected
             */
            handleProcessorSecurityError(pProc,
                                  ISTEP::RC_PROC_SECURITY_STATE_MISMATCH,
                                  l_hashes,
                                  0,
                                  l_continue,
                                  l_mismatches);

            // In non-secure mode, look for other inconsistencies and log the
            // issues
            if (l_continue)
            {
                continue;
            }
            // In secure mode,  stop checking for proc security state mismatches
            // as soon as a mismatch has been found
            break;
        }

    }

    } while(0);

    #endif // CONFIG_SECUREBOOT

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                EXIT_MRK"validateSecuritySettings");
}

uint8_t getMembufsAttachedBitMask( TARGETING::Target * i_procChipHandle  );
void fenceAttachedMembufs( TARGETING::Target * i_procChipHandle  );

//******************************************************************************
// call_proc_cen_ref_clock_enable
//******************************************************************************
void* call_proc_cen_ref_clk_enable(void *io_pArgs )
{
    errlHndl_t  l_errl = NULL;

    IStepError  l_stepError;

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_proc_cen_ref_clock_enable enter" );

    validateSecuritySettings();

#ifdef CONFIG_SECUREBOOT
    if(SECUREBOOT::enabled())
    {
        SECUREBOOT::CENTAUR_SECURITY::ScomCache& centaurCache =
            SECUREBOOT::CENTAUR_SECURITY::ScomCache::getInstance();
        centaurCache.init();
        centaurCache.enableCache();
    }
#endif

    TARGETING::TargetHandleList functionalProcChipList;

    getAllChips(functionalProcChipList, TYPE_PROC, true);

    // loop thru the list of processors
    for (TARGETING::TargetHandleList::const_iterator
            l_proc_iter = functionalProcChipList.begin();
            l_proc_iter != functionalProcChipList.end();
            ++l_proc_iter)
    {
        //Raise fences on centaurs to prevent FSP from analyzing
        // if HB TIs for recoverable errors
        fenceAttachedMembufs( *l_proc_iter );

        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                "START: p9_cen_ref_clk_enable started on target HUID %.8X",
                TARGETING::get_huid( *l_proc_iter ) );

        // Cumulus only
        fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapiProcTarget( *l_proc_iter );

        // Invoke the HWP passing in the proc target
        // Cumulus only
        FAPI_INVOKE_HWP(l_errl,
                        p9_cen_ref_clk_enable,
                        l_fapiProcTarget);

        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "ERROR : proc_cen_ref_clk_enable"
                    "failed, returning errorlog" );

            // capture the target data in the elog
            ErrlUserDetailsTarget( *l_proc_iter ).addToLog( l_errl );

            // Create IStep error log and cross ref error that occurred
            l_stepError.addErrorDetails( l_errl );

            // Commit error log
            errlCommit( l_errl, HWPF_COMP_ID );
        }
        else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "SUCCESS : proc_cen_ref_clk_enable"
                    "completed ok");
        }

#ifdef CONFIG_AXONE
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "START : p9a_ocmb_enable"
                    "starting on 0x%.08X", TARGETING::get_huid( *l_proc_iter ));

        // Invoke the HWP passing in the proc target
        // HWP loops on child OCMB targets
        FAPI_INVOKE_HWP(l_errl,
                        p9a_ocmb_enable,
                        l_fapiProcTarget);

        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "ERROR : p9a_ocmb_enable"
                    "failed, committing errorlog" );

            // capture the target data in the elog
            ErrlUserDetailsTarget( *l_proc_iter ).addToLog( l_errl );

            // Create IStep error log and cross ref error that occurred
            l_stepError.addErrorDetails( l_errl );

            // Commit error log
            errlCommit( l_errl, HWPF_COMP_ID );
        }
        else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "SUCCESS : p9a_ocmb_enable"
                    "completed ok on 0x%.08X", TARGETING::get_huid( *l_proc_iter ));
        }

        TARGETING::TargetHandleList l_functionalOcmbChipList;
        getChildAffinityTargets( l_functionalOcmbChipList,
                                 const_cast<TARGETING::Target*>(*l_proc_iter),
                                 TARGETING::CLASS_CHIP,
                                 TARGETING::TYPE_OCMB_CHIP,
                                 true);

        for (const auto & l_ocmb : l_functionalOcmbChipList)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                        "Start : exp_check_for_ready "
                        "for 0x%.08X", TARGETING::get_huid(l_ocmb));

            fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(l_ocmb);
            FAPI_INVOKE_HWP(l_errl,
                            exp_check_for_ready,
                            l_fapi_ocmb_target);

            if (l_errl)
            {
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                          "ERROR : exp_check_for_ready"
                          "failed for target 0x%.08X , committing errorlog", TARGETING::get_huid(l_ocmb) );

                // capture the target data in the elog
                ErrlUserDetailsTarget( l_ocmb ).addToLog( l_errl );

                // Create IStep error log and cross ref error that occurred
                l_stepError.addErrorDetails( l_errl );

                // Commit error log
                errlCommit( l_errl, HWPF_COMP_ID );
            }
            else
            {
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                          "SUCCESS : exp_check_for_ready "
                          "completed ok");

                size_t size = 0;

                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                          "Read IDEC from OCMB 0x%.8X",
                          TARGETING::get_huid(l_ocmb));

                // This write gets translated into a read of the explorer chip
                // in the device driver. First, a read of the chip's IDEC
                // register occurs then ATTR_EC, ATTR_HDAT_EC, and ATTR_CHIP_ID
                // are set with the values found in that register. So, this
                // deviceWrite functions more as a setter for an OCMB target's
                // attributes.
                // Pass 2 as a va_arg to signal the ocmbIDEC function to execute
                // phase 2 of it's read process.
                const uint64_t Phase2 = 2;
                l_errl = DeviceFW::deviceWrite(l_ocmb,
                                   nullptr,
                                   size,
                                   DEVICE_IDEC_ADDRESS(),
                                   Phase2);
                if (l_errl)
                {
                    // read of ID/EC failed even though we THOUGHT we were
                    // present.
                    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                              "OCMB 0x%.8X - read IDEC failed (eid 0x%X) - bad",
                              TARGETING::get_huid(l_ocmb), l_errl->eid());

                    // commit the error but keep going
                    errlCommit(l_errl, HWAS_COMP_ID);
                    // l_errl is now nullptr
                }
            }
        }
#endif

    }   // endfor

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_proc_cen_ref_clock_enable exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_stepError.getErrorHandle();
}

//******************************************************************************
// getMembufsAttachedBitMask - helper function for hwp proc_cen_ref_clk_enable
//******************************************************************************
uint8_t getMembufsAttachedBitMask( TARGETING::Target * i_procTarget  )
{
    const uint8_t DMI_WITH_ATTACHED_CENTAUR_MASK = 0x80;

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Finding functional membuf chips downstream from "
            "proc chip with HUID of 0x%08X",
            i_procTarget->getAttr<TARGETING::ATTR_HUID>());

    uint8_t l_attachedMembufs = 0;

    // Get list of functional membuf chips downstream from the given
    // proc chip
    TARGETING::TargetHandleList functionalMembufChipList;

    getChildAffinityTargets( functionalMembufChipList,
                      const_cast<TARGETING::Target*>(i_procTarget ),
                      TARGETING::CLASS_CHIP,
                      TARGETING::TYPE_MEMBUF,
                      true);

    // loop through the functional membufs
    for(TARGETING::TargetHandleList::const_iterator pTargetItr
                            = functionalMembufChipList.begin();
                            pTargetItr != functionalMembufChipList.end();
                            pTargetItr++)
    {
        // Find each functional membuf chip's upstream functional DMI
        // unit, if any, and accumulate it into the attached membuf
        // chips mask
        TARGETING::TargetHandleList functionalDmiUnitList;

        getParentAffinityTargets( functionalDmiUnitList, *pTargetItr,
                                  TARGETING::CLASS_UNIT, TARGETING::TYPE_DMI,
                                  true );

        if(functionalDmiUnitList.empty())
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Functional membuf chip with HUID of 0x%08X "
                    "is not attached to an upstream functional DMI",
                    (*pTargetItr)->getAttr<
                    TARGETING::ATTR_HUID>());
            continue;
        }

        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                "Found functional DMI unit with HUID of 0x%08X "
                "upstream from functional membuf chip with HUID of 0x%08X",
                ((*functionalDmiUnitList.begin())->getAttr<
                 TARGETING::ATTR_CHIP_UNIT>()),
                (*pTargetItr)->getAttr<
                TARGETING::ATTR_HUID>());
        l_attachedMembufs |=
            ((DMI_WITH_ATTACHED_CENTAUR_MASK) >>
             ((*functionalDmiUnitList.begin())->getAttr<
              TARGETING::ATTR_CHIP_UNIT>()));
    }

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Proc chip with HUID of 0x%08X has attached membuf "
            "mask (l_attachedMembufs) of 0x%02X",
            i_procTarget->getAttr<TARGETING::ATTR_HUID>(),
            l_attachedMembufs);

    // return the bitmask
    return l_attachedMembufs;

}

//******************************************************************************
// fenceAttachedMembufs - helper function for hwp proc_cen_ref_clk_enable
//******************************************************************************
void fenceAttachedMembufs( TARGETING::Target * i_procTarget  )
{
     errlHndl_t  l_errl = NULL;

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Fencing attached (present) membuf chips downstream from "
            "proc chip with HUID of 0x%08X",
            i_procTarget->getAttr<TARGETING::ATTR_HUID>());


    // Get list of membuf chips downstream from the given proc chip
    TARGETING::TargetHandleList MembufChipList;

    getChildAffinityTargetsByState( MembufChipList,
                      const_cast<TARGETING::Target*>(i_procTarget ),
                      TARGETING::CLASS_CHIP,
                      TARGETING::TYPE_MEMBUF,
                      TARGETING::UTIL_FILTER_PRESENT);

    // loop through the membufs
    for(TARGETING::TargetHandleList::const_iterator pTargetItr
                            = MembufChipList.begin();
                            pTargetItr != MembufChipList.end();
                            pTargetItr++)
    {
        //Get CFAM "1012" -- FSI GP3 and set bits 23-27 (various fence bits)
        //Note 1012 is ecmd addressing, real address is 0x1048 (byte)
        uint64_t l_addr = 0x1048;
        const uint32_t l_fence_bits= 0x000001F0;
        uint32_t l_data = 0;
        size_t l_size = sizeof(uint32_t);
        l_errl = deviceRead(*pTargetItr,
                         &l_data,
                         l_size,
                         DEVICE_FSI_ADDRESS(l_addr));
        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
             "Failed getcfam 1012 to HUID 0x%08X, ignoring, skipping",
             (*pTargetItr)->getAttr<TARGETING::ATTR_HUID>());
            delete l_errl;
            l_errl = NULL;
            continue;
        }

        l_data |= l_fence_bits;

        l_errl = deviceWrite(*pTargetItr,
                         &l_data,
                         l_size,
                         DEVICE_FSI_ADDRESS(l_addr));
        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                      "Failed putcfam 1012 to HUID 0x%08X, ignoring, skipping",
                      (*pTargetItr)->getAttr<TARGETING::ATTR_HUID>());
            delete l_errl;
            l_errl = NULL;
            continue;
        }
    }

}

}
OpenPOWER on IntegriCloud