summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/dram_initialization/proc_setup_bars/mss_setup_bars.C
blob: 854d4d79a8fe4735b512ae5a63228542d14a18eb (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/hwpf/hwp/dram_initialization/proc_setup_bars/mss_setup_bars.C $ */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2012,2014              */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// $Id: mss_setup_bars.C,v 1.40 2014/04/15 16:05:47 jdsloat Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2012
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//------------------------------------------------------------------------------
// *!
// *! TITLE       : mss_setup_bars.C
// *! DESCRIPTION : Program MCS base address registers (BARs) (FAPI)
// *!
// *! OWNER NAME  : Girisankar Paulraj      Email: gpaulraj@in.ibm.com
// *! OWNER NAME  : Mark Bellows            Email: bellows@us.ibm.com
// *!
//------------------------------------------------------------------------------
// CHANGE HISTORY:
//------------------------------------------------------------------------------
// Version:|  Author: |  Date:  | Comment:
//---------|----------|---------|-----------------------------------------------
// 1.39    | gpaulraj | 04/08/14| 5/5 FW review feedback - gerrit process - SW251227
// 1.33    |          | 03/09/14| RAS review
//  1.32   | gpaulraj | 08/16/13| fixed code
//  1.31   | gpaulraj | 08/13/13| fix HW259884 Mirror BAR Scom Parity Error
//  1.30   | gpaulraj | 08/13/13| added fix HW259884 Mirror BAR Scom Parity Error
//  1.29   | gpaulraj | 08/12/13| fixed mirror BAR issues
//  1.27   | jmcgill  | 05/21/13| address FW review issues
//  1.26   | jmcgill  | 04/22/13| rewrite to line up with attribute changes
//  1.23   | bellows  | 12/04/12| more updates
//  1.22   | gpaulraj | 10/03/12| review updates
//  1.21   | gpaulraj | 10/02/12| review updates
//  1.19   | bellows  | 09/25/12| review updates
//  1.18   | bellows  | 09/06/12| updates suggested by Van
//  1.17   | bellows  | 08/31/12| use the final 32bit attribute
//  1.16   | bellows  | 08/29/12| remove compile error, use 32bit group info
//         |          |         | as a temporary fix
//  1.10   | bellows  | 07/16/12| added in Id tag
//  1.4    | bellows  | 06-05-12| Updates to Match First Configuration, work for
//         |          |         | P8 and Murano
//  1.3    | gpaulraj | 05-22-12| 2MCS/group supported for 128GB CDIMM
//  1.2    | gpaulraj | 05-07-12| 256 group configuration in
//  1.1    | gpaulraj | 03-19-12| First drop for centaur
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//  Includes
//------------------------------------------------------------------------------

#include <mss_setup_bars.H>


//------------------------------------------------------------------------------
//  Function definitions
//------------------------------------------------------------------------------

extern "C" {


const int SETUP_BARS_MBA_SIZE_MCS=8;
const int SETUP_BARS_MBA_SIZE_PORT=2;
struct MssSetupBarsSizeInfo{
   uint8_t MBA_size[SETUP_BARS_MBA_SIZE_MCS][SETUP_BARS_MBA_SIZE_PORT]; // mcs, mba pairs, port, dimm
   uint32_t MCS_size[SETUP_BARS_MBA_SIZE_MCS];
};

//------------------------------------------------------------------------------
// function: write non-mirrored BAR registers (MCFGP/MCFGPA) for a single MCS
// parameters: i_mcs_target      => MCS chiplet target
//             i_pri_valid       => true if MCS primary non-mirrored BAR
//                                  should be marked valid
//             i_group_member_id => group member ID (only valid if
//                                  i_pri_valid=true)
//             i_group_data      => MSS_MCS_GROUP_32 attribute data
//                                  for member group (only valid if
//                                  i_pri_valid=true)
// returns: FAPI_RC_SUCCESS if all register writes are successful,
//          else failing return code
//------------------------------------------------------------------------------
fapi::ReturnCode mss_setup_bars_init_nm_bars(
    const fapi::Target& i_mcs_target,
    bool i_pri_valid,
    uint32_t i_group_member_id,
    uint32_t i_group_data[])
{
    fapi::ReturnCode rc;
    uint32_t rc_ecmd = 0;

    ecmdDataBufferBase MCFGP(64);
    ecmdDataBufferBase MCFGPA(64);

    // Defect HW259884 (AddNote by retter) P8 Lab Brazos: Mirror BAR Scom Parity Error - workaround
    ecmdDataBufferBase MCIFIR(64);
    ecmdDataBufferBase MCIFIRMASK(64);
    ecmdDataBufferBase MCSMODE4(64);

    do
    {
        rc = fapiGetScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiGetScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
        // Mask MCIFIR bit 25
        rc_ecmd |= MCIFIRMASK.setBit(25);
        if (rc_ecmd)
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error 0x%X setting up MCIFIRMASK data buffer",
                         rc_ecmd);
             rc.setEcmdError(rc_ecmd);
             break;
        }
        rc = fapiPutScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }

        // establish base content for MCFGP register
        rc_ecmd |= MCFGP.setBit(MCFGP_ENABLE_RCMD0_BIT);
        rc_ecmd |= MCFGP.setBit(MCFGP_ENABLE_RCMD1_BIT);
        rc_ecmd |= MCFGP.setBit(MCFGP_RSVD_1_BIT);
        rc_ecmd |= MCFGP.setBit(MCFGP_ENABLE_FASTPATH_BIT);

        // check buffer manipulation return codes
        if (rc_ecmd)
        {
            FAPI_ERR("mss_setup_bars_init_nm_bars: Error 0x%X setting up MCFGP base data buffer",
                     rc_ecmd);
            rc.setEcmdError(rc_ecmd);
            break;
        }

        if (i_pri_valid)
        {
            // MCFGPQ_VALID
            rc_ecmd |= MCFGP.setBit(MCFGP_VALID_BIT);
            // MCFGPQ_MCS_UNITS_PER_GROUP
            rc_ecmd |= MCFGP.insertFromRight(
                i_group_data[MSS_MCS_GROUP_32_MCS_IN_GROUP_INDEX] / 2,
                MCFGP_MCS_UNITS_PER_GROUP_START_BIT,
                (MCFGP_MCS_UNITS_PER_GROUP_END_BIT-
                 MCFGP_MCS_UNITS_PER_GROUP_START_BIT)+1);
            // MCFGPQ_GROUP_MEMBER_IDENTIFICATION
            rc_ecmd |= MCFGP.insertFromRight(
                i_group_member_id,
                MCFGP_GROUP_MEMBER_ID_START_BIT,
                (MCFGP_GROUP_MEMBER_ID_END_BIT-
                 MCFGP_GROUP_MEMBER_ID_START_BIT)+1);
            // MCFGPQ_GROUP_SIZE
            rc_ecmd |= MCFGP.insertFromRight(
                (i_group_data[MSS_MCS_GROUP_32_SIZE_INDEX]/4)-1,
                MCFGP_GROUP_SIZE_START_BIT,
                (MCFGP_GROUP_SIZE_END_BIT-
                 MCFGP_GROUP_SIZE_START_BIT)+1);

            // MCFGPQ_BASE_ADDRESS_OF_GROUP
            rc_ecmd |= MCFGP.insertFromRight(
                i_group_data[MSS_MCS_GROUP_32_BASE_INDEX] >> 2,
                MCFGP_BASE_ADDRESS_START_BIT,
                (MCFGP_BASE_ADDRESS_END_BIT-
                 MCFGP_BASE_ADDRESS_START_BIT)+1);

            // check buffer manipulation return codes
            if (rc_ecmd)
            {
                FAPI_ERR("mss_setup_bars_init_nm_bars: Error 0x%X setting up MCFGP data buffer",
                         rc_ecmd);
                rc.setEcmdError(rc_ecmd);
                break;
            }

            bool alt_valid = i_group_data[MSS_MCS_GROUP_32_ALT_VALID_INDEX];
            if (alt_valid)
            {
                if (i_group_data[MSS_MCS_GROUP_32_ALT_BASE_INDEX] !=
                    (i_group_data[MSS_MCS_GROUP_32_BASE_INDEX] +
                     (i_group_data[MSS_MCS_GROUP_32_SIZE_INDEX]/2)))
                {
                    FAPI_ERR("mss_setup_bars_init_nm_bars: Invalid non-mirrored alternate BAR configuration");
                    const uint32_t & ALT_BASE_INDEX = i_group_data[MSS_MCS_GROUP_32_ALT_BASE_INDEX];
                    const uint32_t & BASE_INDEX = i_group_data[MSS_MCS_GROUP_32_BASE_INDEX];
	            const uint32_t & SIZE_INDEX= i_group_data[MSS_MCS_GROUP_32_SIZE_INDEX];
                    FAPI_SET_HWP_ERROR(rc,
                                       RC_MSS_SETUP_BARS_NM_ALT_BAR_ERR);
                    break;
                }

                // MCFGPAQ_VALID
                rc_ecmd |= MCFGPA.setBit(MCFGPA_VALID_BIT);

                // MCFGPAQ_GROUP_SIZE
                rc_ecmd |= MCFGPA.insertFromRight(
                    (i_group_data[MSS_MCS_GROUP_32_ALT_SIZE_INDEX]/4)-1,
                    MCFGPA_GROUP_SIZE_START_BIT,
                    (MCFGPA_GROUP_SIZE_END_BIT-
                     MCFGPA_GROUP_SIZE_START_BIT)+1);

                // MCFGPAQ_BASE_ADDRESS_OF_GROUP
                rc_ecmd |= MCFGPA.insertFromRight(
                    i_group_data[MSS_MCS_GROUP_32_ALT_BASE_INDEX] >> 2,
                    MCFGPA_BASE_ADDRESS_START_BIT,
                    (MCFGPA_BASE_ADDRESS_END_BIT-
                     MCFGPA_BASE_ADDRESS_START_BIT)+1);

                // check buffer manipulation return codes
                if (rc_ecmd)
                {
                    FAPI_ERR("mss_setup_bars_init_nm_bars: Error 0x%X setting up MCFGPA data buffer",
                             rc_ecmd);
                    rc.setEcmdError(rc_ecmd);
                    break;
                }
            }
        }

        // write registers
        rc = fapiPutScom(i_mcs_target, MCS_MCFGP_0x02011800, MCFGP);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCFGP_0x02011800)");
            break;
        }

        rc = fapiPutScom(i_mcs_target, MCS_MCFGPA_0x02011814, MCFGPA);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCFGPA_0x02011814)");
            break;
        }

        rc = fapiGetScom(i_mcs_target, MCS_MCSMODE4_0x0201181A, MCSMODE4);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiGetScom (MCS_MCSMODE4_0x0201181A");
             break;
        }
        // set MCSMODE4 bit 0
        rc_ecmd |= MCSMODE4.setBit(0);
        rc = fapiPutScom(i_mcs_target, MCS_MCSMODE4_0x0201181A, MCSMODE4);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCSMODE4_0x0201181A");
             break;
        }
        // Clear MCSMODE4 bit 0
        rc_ecmd |= MCSMODE4.clearBit(0);
        rc = fapiPutScom(i_mcs_target, MCS_MCSMODE4_0x0201181A, MCSMODE4);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCSMODE4_0x0201181A");
             break;
        }

        rc = fapiGetScom(i_mcs_target, MCS_MCIFIR_0x02011840, MCIFIR);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiGetScom (MCS_MCIFIR_0x02011840");
             break;
        }
        // Reset MCIFIR bit 25
        rc_ecmd |= MCIFIR.clearBit(25);
        rc = fapiPutScom(i_mcs_target, MCS_MCIFIR_0x02011840, MCIFIR);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCIFIR_0x02011840");
             break;
        }

        rc = fapiGetScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiGetScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
        // Unmask MCIFIR bit 25
        rc_ecmd |= MCIFIRMASK.clearBit(25);
        rc = fapiPutScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_nm_bars: Error from fapiPutScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
    } while(0);

    return rc;
}


//------------------------------------------------------------------------------
// function: write mirrored BAR registers (MCFGPM/MCFGPMA) for a single MCS
// parameters: i_mcs_target => MCS chiplet target
//             i_pri_valid  => true if MCS primary mirrored BAR
//                             should be marked valid
//             i_group_data => MSS_MCS_GROUP_32 attribute data
//                             for member group (only valid if
//                             i_pri_valid=true)
// returns: FAPI_RC_SUCCESS if all register writes are successful,
//          else failing return code
//------------------------------------------------------------------------------
fapi::ReturnCode mss_setup_bars_init_m_bars(
    const fapi::Target& i_mcs_target,
    bool i_pri_valid,
    uint32_t i_group_data[])
{
    fapi::ReturnCode rc;
    uint32_t rc_ecmd = 0;

    ecmdDataBufferBase MCFGPM(64);
    ecmdDataBufferBase MCFGPMA(64);

    // Defect HW259884 (AddNote by retter) P8 Lab Brazos: Mirror BAR Scom Parity Error - workaround
    ecmdDataBufferBase MCIFIR(64);
    ecmdDataBufferBase MCIFIRMASK(64);
    ecmdDataBufferBase MCSMODE4(64);
    do
    {

        rc = fapiGetScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiGetScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
        // Mask MCIFIR bit 25
        rc_ecmd |= MCIFIRMASK.setBit(25);
        if (rc_ecmd)
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error 0x%X setting up MCIFIRMASK data buffer",
                         rc_ecmd);
             rc.setEcmdError(rc_ecmd);
             break;
        }
        rc = fapiPutScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
        if (i_pri_valid)
        {

            // MCFGPMQ_VALID
            rc_ecmd |= MCFGPM.setBit(MCFGPM_VALID_BIT);
            // MCFGPMQ_GROUP_SIZE
            rc_ecmd |= MCFGPM.insertFromRight(
                (i_group_data[MSS_MCS_GROUP_32_SIZE_INDEX]/4)-1,
                MCFGPM_GROUP_SIZE_START_BIT,
                (MCFGPM_GROUP_SIZE_END_BIT-
                 MCFGPM_GROUP_SIZE_START_BIT)+1);

            // MCFGPMQ_BASE_ADDRESS_OF_GROUP
            rc_ecmd |= MCFGPM.insertFromRight(
                i_group_data[MSS_MCS_GROUP_32_BASE_INDEX] >> 2,
                MCFGPM_BASE_ADDRESS_START_BIT,
                (MCFGPM_BASE_ADDRESS_END_BIT-
                 MCFGPM_BASE_ADDRESS_START_BIT)+1);

            // check buffer manipulation return codes
            if (rc_ecmd)
            {
                FAPI_ERR("mss_setup_bars_init_m_bars: Error 0x%X setting up MCFGPM data buffer",
                         rc_ecmd);
                rc.setEcmdError(rc_ecmd);
                break;
            }

            bool alt_valid = i_group_data[MSS_MCS_GROUP_32_ALT_VALID_INDEX];
            if (alt_valid)
            {
                // MCFGPMAQ_VALID
                rc_ecmd |= MCFGPMA.setBit(MCFGPMA_VALID_BIT);

                // MCFGPMAQ_GROUP_SIZE
                rc_ecmd |= MCFGPMA.insertFromRight(
                    (i_group_data[MSS_MCS_GROUP_32_ALT_SIZE_INDEX]/4)-1,
                    MCFGPMA_GROUP_SIZE_START_BIT,
                    (MCFGPMA_GROUP_SIZE_END_BIT-
                     MCFGPMA_GROUP_SIZE_START_BIT)+1);

                // MCFGPMAQ_BASE_ADDRESS_OF_GROUP
                rc_ecmd |= MCFGPMA.insertFromRight(
                    i_group_data[MSS_MCS_GROUP_32_ALT_BASE_INDEX] >> 2,
                    MCFGPMA_BASE_ADDRESS_START_BIT,
                    (MCFGPMA_BASE_ADDRESS_END_BIT-
                     MCFGPMA_BASE_ADDRESS_START_BIT)+1);

                if (i_group_data[MSS_MCS_GROUP_32_ALT_BASE_INDEX] !=
                    (i_group_data[MSS_MCS_GROUP_32_BASE_INDEX] +
                     (i_group_data[MSS_MCS_GROUP_32_SIZE_INDEX]/2)))
                {
                    FAPI_ERR("mss_setup_bars_init_m_bars: Invalid mirrored alternate BAR configuration");
                    const uint32_t & ALT_BASE_INDEX = i_group_data[MSS_MCS_GROUP_32_ALT_BASE_INDEX];
		    const uint32_t & BASE_INDEX = i_group_data[MSS_MCS_GROUP_32_BASE_INDEX];
		    const uint32_t & SIZE_INDEX= i_group_data[MSS_MCS_GROUP_32_SIZE_INDEX];
                    FAPI_SET_HWP_ERROR(rc,
                                       RC_MSS_SETUP_BARS_M_ALT_BAR_ERR);
                    break;
                }
            }

            // check buffer manipulation return codes
            if (rc_ecmd)
            {
                FAPI_ERR("mss_setup_bars_init_m_bars: Error 0x%X setting up MCFGPMA data buffer",
                         rc_ecmd);
                rc.setEcmdError(rc_ecmd);
                break;
            }
        }

        // write registers
        rc = fapiPutScom(i_mcs_target, MCS_MCFGPM_0x02011801, MCFGPM);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCFGPM_0x02011801)");
            break;
        }
        rc = fapiPutScom(i_mcs_target, MCS_MCFGPMA_0x02011815, MCFGPMA);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCFGPMA_0x02011815");
            break;
        }

        rc = fapiGetScom(i_mcs_target, MCS_MCSMODE4_0x0201181A, MCSMODE4);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiGetScom (MCS_MCSMODE4_0x0201181A");
             break;
        }
        // set MCSMODE4 bit 0
        rc_ecmd |= MCSMODE4.setBit(0);
        rc = fapiPutScom(i_mcs_target, MCS_MCSMODE4_0x0201181A, MCSMODE4);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCSMODE4_0x0201181A");
             break;
        }
        // Clear MCSMODE4 bit 0
        rc_ecmd |= MCSMODE4.clearBit(0);
        rc = fapiPutScom(i_mcs_target, MCS_MCSMODE4_0x0201181A, MCSMODE4);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCSMODE4_0x0201181A");
             break;
        }

        rc = fapiGetScom(i_mcs_target, MCS_MCIFIR_0x02011840, MCIFIR);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiGetScom (MCS_MCIFIR_0x02011840");
             break;
        }
        // Reset MCIFIR bit 25
        rc_ecmd |= MCIFIR.clearBit(25);
        rc = fapiPutScom(i_mcs_target, MCS_MCIFIR_0x02011840, MCIFIR);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCIFIR_0x02011840");
             break;
        }

        rc = fapiGetScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiGetScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
        // Unmask MCIFIR bit 25
        rc_ecmd |= MCIFIRMASK.clearBit(25);
        rc = fapiPutScom(i_mcs_target, MCS_MCIFIRMASK_0x02011843, MCIFIRMASK);
        if (!rc.ok())
        {
             FAPI_ERR("mss_setup_bars_init_m_bars: Error from fapiPutScom (MCS_MCIFIRMASK_0x02011843");
             break;
        }
    } while(0);

    return rc;
}


//------------------------------------------------------------------------------
// function: mss_setup_bars_mcs_size
//------------------------------------------------------------------------------
fapi::ReturnCode mss_setup_bars_mcs_size(  const fapi::Target & i_target,std::vector<fapi::Target> & i_associated_centaurs, MssSetupBarsSizeInfo & io_sizeInfo)
{
      fapi::ReturnCode rc;
      uint8_t centaur;
      uint8_t mba_i;
      uint8_t mba=0;
      uint8_t dimm=0;
      uint32_t cenpos;
      uint32_t procpos;
      uint8_t port;
       uint32_t l_unit_pos =0;
       uint8_t min_group = 1;
      uint8_t mba_pos[2][2] = { {0, 0},{0,0}};
      std::vector<fapi::Target> l_mba_chiplets;
      uint8_t cen_count=0;
      rc = FAPI_ATTR_GET(ATTR_POS,&i_target, procpos);
      if(rc) return rc;
      for(centaur= 0; centaur < i_associated_centaurs.size(); centaur++) {
        mba=0;port=0;dimm=0;
        fapi::Target & centaur_t = i_associated_centaurs[centaur];
        rc = FAPI_ATTR_GET(ATTR_POS,&centaur_t, cenpos);
        if(rc) return rc;
        if(cenpos>=procpos*8 && cenpos<(procpos*8+8)){
                FAPI_INF("... working on centaur %d", cenpos);
                io_sizeInfo.MCS_size[cenpos - procpos * 8]=0;
                rc = fapiGetChildChiplets(i_associated_centaurs[centaur], fapi::TARGET_TYPE_MBA_CHIPLET, l_mba_chiplets);
                if(rc) return rc;
                for(mba_i=0; mba_i<l_mba_chiplets.size(); mba_i++) {

                  rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mba_chiplets[mba_i], mba);
                  if(rc) return rc;
                  FAPI_INF("... working on mba %d", mba);
                  rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &l_mba_chiplets[mba_i],mba_pos);
                  if(rc) return rc;
                  for(port = 0; port<2; port++)
                  {	
                    for(dimm=0; dimm<2; dimm++) {
                       io_sizeInfo.MCS_size[cenpos - procpos * 8]+=mba_pos[port][dimm];
                       io_sizeInfo.MBA_size[cenpos - procpos * 8][mba] += mba_pos[port][dimm];
                    }
                  }

                  FAPI_INF(" Cen Pos %d mba %d DIMM SIZE %d \n",cenpos,mba, io_sizeInfo.MBA_size[cenpos - procpos * 8][mba]);
                  FAPI_INF(" Cen Pos %d MBA SIZE %d %d  %d %d \n",cenpos, mba_pos[0][0],mba_pos[0][1],mba_pos[1][0],mba_pos[1][1]);
                  FAPI_INF(" MCS SIZE %d\n",io_sizeInfo.MCS_size[cenpos - procpos * 8]);
            }
            cen_count++;l_unit_pos++;
        }
      }
      FAPI_INF("attr_mss_setting %d and  no  of MBAs   %d \n",min_group,l_unit_pos);
     return rc;
}

//------------------------------------------------------------------------------
// function: mss_setup_bars HWP entry point
//           NOTE: see comments above function prototype in header
//------------------------------------------------------------------------------
fapi::ReturnCode mss_setup_bars(const fapi::Target& i_pu_target,   std::vector<fapi::Target> & i_associated_centaurs)
{
    fapi::ReturnCode rc;
    std::vector<fapi::Target> l_mcs_chiplets;
    uint32_t group_data[16][16];
    uint8_t M_valid;
    MssSetupBarsSizeInfo sizeInfo;
    do
    {

        rc= mss_setup_bars_mcs_size(i_pu_target,i_associated_centaurs, sizeInfo);
        // obtain group configuration attribute for this chip
        rc = FAPI_ATTR_GET(ATTR_MSS_MCS_GROUP_32, &i_pu_target, group_data);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars: Error reading ATTR_MSS_MCS_GROUP_32");
            break;
        }
        rc = FAPI_ATTR_GET(ATTR_MRW_ENHANCED_GROUPING_NO_MIRRORING, NULL, M_valid);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars: Error reading ATTR_MRW_ENHANCED_GROUPING_NO_MIRRORING");
            break;
        }


         //check if all the grouped mcs are valid
         for (size_t i = MSS_MCS_GROUP_32_NM_START_INDEX;
                (i <= MSS_MCS_GROUP_32_NM_END_INDEX);
                i++)
           {
               // only process valid groups
               if (group_data[i][MSS_MCS_GROUP_32_SIZE_INDEX] == 0)
               {
                   continue;
               }

               uint32_t mcs_in_group = group_data[i][MSS_MCS_GROUP_32_MCS_IN_GROUP_INDEX];

               uint32_t mcs_sz = group_data[i][0];
               for (size_t j = MSS_MCS_GROUP_32_MEMBERS_START_INDEX;
                    (j < MSS_MCS_GROUP_32_MEMBERS_START_INDEX+mcs_in_group);
                    j++)
               {
                    if(mcs_sz !=  sizeInfo.MCS_size[group_data[i][j]])
                    {
                          FAPI_INF(" Group %d will not be configured as MCS %d is not valid grouped size is %d , present MCS size is %d \n",i,group_data[i][j],mcs_sz, sizeInfo.MCS_size[group_data[i][j]]);
                          for(uint8_t k; k<32;k++) { group_data[i][k]=0; }
                     }
               }
           }
        // get child MCS chiplets
        rc = fapiGetChildChiplets(i_pu_target,
                                  fapi::TARGET_TYPE_MCS_CHIPLET,
                                  l_mcs_chiplets,
                                  fapi::TARGET_STATE_FUNCTIONAL);
        if (!rc.ok())
        {
            FAPI_ERR("mss_setup_bars: Error from fapiGetChildChiplets");
            break;
        }

        // loop through & set configuration of each MCS chiplet
        for (std::vector<fapi::Target>::iterator iter = l_mcs_chiplets.begin();
             iter != l_mcs_chiplets.end();
             iter++)
        {
            // obtain MCS chip unit number
            uint8_t mcs_pos = 0x0;
            rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*iter), mcs_pos);
            if (!rc.ok())
            {
                FAPI_ERR("mss_setup_bars: Error reading ATTR_CHIP_UNIT_POS");
                break;
            }

            // determine non-mirrored member group
            bool nm_bar_valid = false;
            uint8_t nm_bar_group_index = 0x0;
            uint8_t nm_bar_group_member_id = 0x0;
            for (size_t i = MSS_MCS_GROUP_32_NM_START_INDEX;
                 (i <= MSS_MCS_GROUP_32_NM_END_INDEX);
                 i++)
            {
                // only process valid groups
                if (group_data[i][MSS_MCS_GROUP_32_SIZE_INDEX] == 0)
                {
                    continue;
                }

                uint32_t mcs_in_group = group_data[i][MSS_MCS_GROUP_32_MCS_IN_GROUP_INDEX];


                for (size_t j = MSS_MCS_GROUP_32_MEMBERS_START_INDEX;
                     (j < MSS_MCS_GROUP_32_MEMBERS_START_INDEX+mcs_in_group);
                     j++)
                {
                    if (mcs_pos == group_data[i][j])
                    {
                        if (nm_bar_valid)
                        {
                            const uint8_t& MCS_POS = mcs_pos;
                            const uint8_t& GROUP_INDEX_A = nm_bar_group_index;
                            const uint8_t& GROUP_INDEX_B = i;
                            FAPI_ERR("mss_setup_bars: MCS %d is listed as a member in multiple non-mirrored groups",
                                     mcs_pos);
                            FAPI_SET_HWP_ERROR(
                                rc,
                                RC_MSS_SETUP_BARS_MULTIPLE_GROUP_ERR);
                            break;
                        }
                        nm_bar_valid = true;
                        nm_bar_group_index = i;
                        nm_bar_group_member_id =
                            j-MSS_MCS_GROUP_32_MEMBERS_START_INDEX;
                    }
                }
                if (!rc.ok())
                {
                    break;
                }
            }
            if (!rc.ok())
            {
                break;
            }

            // write non-mirrored BARs based on group configuration
            rc = mss_setup_bars_init_nm_bars(
                *iter,
                nm_bar_valid,
                nm_bar_group_member_id,
                group_data[nm_bar_group_index]);
            if (!rc.ok())
            {
                FAPI_ERR("mss_setup_bars: Error from mss_setup_bars_init_nm_bars");
                break;
            }

            // determine mirrored member group
            if(M_valid)
	    {
            	bool m_bar_valid = false;
            	uint8_t m_bar_group_index = 0x0;
            	for (size_t i = MSS_MCS_GROUP_32_M_START_INDEX;
                 (i <= MSS_MCS_GROUP_32_M_END_INDEX);
                 i++)
            	{
                	// only process valid groups
                	if (group_data[i-8][MSS_MCS_GROUP_32_SIZE_INDEX] == 0)
                	{
                    	continue;
                	}

                	uint32_t mcs_in_group = group_data[i-8][MSS_MCS_GROUP_32_MCS_IN_GROUP_INDEX];
                	for (size_t j = MSS_MCS_GROUP_32_MEMBERS_START_INDEX;
                    	 (j < MSS_MCS_GROUP_32_MEMBERS_START_INDEX+mcs_in_group);
                    	 j++)
                	{
                    	if (mcs_pos == group_data[i-8][j])
                    	{
                        	if (m_bar_valid)
                        	{
                            	const uint8_t& MCS_POS = mcs_pos;
                            	const uint8_t& GROUP_INDEX_A = m_bar_group_index;
                            	const uint8_t& GROUP_INDEX_B = i;
                            	FAPI_ERR("mss_setup_bars: MCS %d is listed as a member in multiple mirrored groups",
                                     mcs_pos);
                            	FAPI_SET_HWP_ERROR(
                                	rc,
                                 RC_MSS_SETUP_BARS_MULTIPLE_GROUP_ERR);
                            	break;
                       	        }
                        	m_bar_valid = true;
                        	m_bar_group_index = i;
                    	}
                	}
            	    if (!rc.ok())
            	    {
                	    break;
            	    }
            	}
            	if (!rc.ok())
            	{
                	break;
            	}
            	// write mirrored BARs based on group configuration
            	rc = mss_setup_bars_init_m_bars(
                	*iter,
                	m_bar_valid,
                	group_data[m_bar_group_index]);
            	if (!rc.ok())
            	{
                	FAPI_ERR("mss_setup_bars: Error from mss_setup_bars_init_m_bars");
               		 break;
            	}
            }
            // write attribute signifying BARs are valid & MSS inits are finished
            uint8_t final = 1;
            rc = FAPI_ATTR_SET(ATTR_MSS_MEM_IPL_COMPLETE, &i_pu_target, final);
            if (!rc.ok())
            {
               	FAPI_ERR("mss_setup_bars: Error from FAPI_ATTR_SET (ATTR_MSS_MEM_IPL_COMPLETE)");
               	break;
            }

        }
    } while(0);

    return rc;
}


} // extern "C"
OpenPOWER on IntegriCloud