summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/dram_initialization/proc_throttle_sync/proc_throttle_sync.C
blob: 4f6f189538c47bf55d5905b80f961def1ea94766 (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/hwpf/hwp/dram_initialization/proc_throttle_sync/proc_throttle_sync.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2013,2014                        */
/* [+] 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                                                     */
// $Id: proc_throttle_sync.C,v 1.6 2013/12/19 22:22:03 bellows Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_throttle_sync.C,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2013
// *! All Rights Reserved -- Property of IBM
// *! ***  ***
// *!  Licensed material - Program property of IBM
// *!  Refer to copyright instructions form no. G120-2083
// *! Created on Tue Nov 12 2013 at 13:42:15
//------------------------------------------------------------------------------
// *! TITLE       : proc_throttle_sync
// *! DESCRIPTION : see additional comments below
// *! OWNER NAME  :  Bellows Mark D.Email: bellows@us.ibm.com
// *! BACKUP NAME :                 Email: ______@us.ibm.com

// *! ADDITIONAL COMMENTS :
//
//------------------------------------------------------------------------------
// Don't forget to create CVS comments when you check in your changes!
//------------------------------------------------------------------------------
// CHANGE HISTORY:
//------------------------------------------------------------------------------
// Version:|  Author: |  Date:  | Comment:
//---------|----------|---------|-----------------------------------------------
//   1.6   | bellows  |19-DEC-13| Fixed the minor (not functional) setting of rc_ecmd = for next set of data buffer commands
//   1.5   | bellows  |13-DEC-13| One missed firmware review comment
//   1.4   | bellows  |13-DEC-13| Firmware review updates
//   1.3   | bellows  |06-DEC-13| Handle the MCS functional but no centaur case
//   1.2   | bellows  |25-NOV-13| Functional Debug Performed
//   1.1   | bellows  |12-NOV-13| Created.
#include <fapi.H>
#include <proc_throttle_sync.H>
#include <p8_scom_addresses.H>

extern "C" {

  using namespace fapi;

  const uint32_t MAX_SYNC_RETRIES = 1000;
// run on one processor
  ReturnCode proc_throttle_sync(fapi::Target & i_target_proc) {

    ReturnCode rc;
    ecmdDataBufferBase mask_buffer_64(64);
    ecmdDataBufferBase data_buffer_64(64);
    uint8_t l_attr_cen_ec_throttle_sync_possible;
    uint32_t rc_ecmd;
    uint8_t l_proc_attached_centaurs=0;
    uint8_t l_summary_sync_possible=true;
    uint32_t i=0;
    std::vector<fapi::Target> l_target_attached_mcs;
    fapi::Target cen_target;

    do {
    // determine how far into the IPL we have gone
      rc = fapiGetChildChiplets( i_target_proc, TARGET_TYPE_MCS_CHIPLET, l_target_attached_mcs );
      if (rc)
      {
        FAPI_ERR("Failed to find attached mcs\n");
        break;
      }

// find the one mcs
// also form the centaur vector
      uint8_t theonemcs=0xff; // index into the MCS vector for the one MCS
      uint8_t l_functional;
      uint8_t unit_num[8];
      uint8_t pos_attr_data;

      for(i=0; i<8; i++) unit_num[i]=0xff;
      for(i=0; i < l_target_attached_mcs.size(); i++) {
        FAPI_INF("working on mcs %s\n", l_target_attached_mcs[i].toEcmdString());

        rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_target_attached_mcs[i], pos_attr_data);
        if(rc) {
          FAPI_ERR("ERROR: Unable to get ATTR_CHIP_UNIT_POS\n");
          break;
        }


        rc = fapiGetOtherSideOfMemChannel( l_target_attached_mcs[i], cen_target );
        if (rc)
        {
          FAPI_INF("--> this mcs does not have an attached centaur!\n");
          rc=fapi::FAPI_RC_SUCCESS;
        }
        else {
          unit_num[pos_attr_data] = i; // save in index back into the uint_num array

          cen_target.setType(TARGET_TYPE_MEMBUF_CHIP);

          // find out if this centaur can do a sync.  They should all be the same.  Give up if any aren't
          // capable
          rc = FAPI_ATTR_GET(ATTR_CEN_EC_THROTTLE_SYNC_POSSIBLE, &cen_target, l_attr_cen_ec_throttle_sync_possible);
          if(rc) break;

          if( ! l_attr_cen_ec_throttle_sync_possible) { // one or more are not DD2
            FAPI_INF("--> the attached centaur is not capable of this type of sync\n");
            l_summary_sync_possible=false;
          }

          // all functional centaurs form a vector to do a sync on
          rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &cen_target,   l_functional);
          if(rc) {
            FAPI_ERR("Could not get ATTR_FUNCTIONAL");
            break;
          }
          if(l_functional) {
            l_proc_attached_centaurs |= ( 0x80 >> pos_attr_data );
          }
        }

      }



      if(l_summary_sync_possible) {
        FAPI_INF("--> Because sync possible, running procedure\n");

// SYNC PROCEDURE:
// 1.) Determined the MCS to be the master
//      Choose MC2.MCS0, since its on both Murano and Venice.
//      However, if its deconfigured then the code will have to determine the next master per processor chip.
//  [ This is determined by the platform.  The suggestion is to use MC2.MCS0, but if that is not available, pick a different one ]
      // select the one
        if(unit_num[4] != 0xFF) theonemcs=unit_num[4];
        else if(unit_num[5] != 0xFF) theonemcs=unit_num[5];
        else if(unit_num[6] != 0xFF) theonemcs=unit_num[6];
        else if(unit_num[7] != 0xFF) theonemcs=unit_num[7];
        else if(unit_num[0] != 0xFF) theonemcs=unit_num[0];
        else if(unit_num[1] != 0xFF) theonemcs=unit_num[1];
        else if(unit_num[2] != 0xFF) theonemcs=unit_num[2];
        else if(unit_num[3] != 0xFF) theonemcs=unit_num[3];
        else {
          FAPI_IMP("Did not find a valid MCS on this processor %s\n", i_target_proc.toEcmdString());
          break;
        }

        FAPI_INF("--> the one mcs is %s\n", l_target_attached_mcs[theonemcs].toEcmdString() );
// 2.) Select which MCS to be the targets per processor.  You'll want to select the configured MCS's with Centaur attached, but it might still work if you select all of them.
//       Bits 0:7 of MCSYNC Register (Scom addr 201180B) are the select bits.  These bits should be set on the master only.  They tell the master, which targets to send the sync commands.
//
// 	Here's the mapping, if you wish to select the configured MCS's only.  The red MCS's below are only on Venice chips.
// 	Bit 0: MC0.MCS0
// 	Bit 1: MC0.MCS1
// 	Bit 2: MC1.MCS0
// 	Bit 3: MC1.MCS1
// 	Bit 4: MC2.MCS0
// 	Bit 5: MC2.MCS1
// 	Bit 6: MC3.MCS0
// 	Bit 7: MC3.MCS1
        bool l_sync_complete=false;
        uint32_t l_tries=0;
        while ( l_sync_complete == false && l_tries < 1000 ) {
          rc_ecmd = ECMD_DBUF_SUCCESS;
          FAPI_INF("--> Doing the sync sequence try is %d\n", l_tries );
          rc_ecmd |= data_buffer_64.clearBit(0,64);
          rc_ecmd |= mask_buffer_64.clearBit(0,64);

          FAPI_INF("--> the vector of attached centaurs is %02x\n", l_proc_attached_centaurs );
          for(i=0; i<8; i++) {
            if((l_proc_attached_centaurs>>(7-i)) & 0x1) {
              rc_ecmd |= data_buffer_64.setBit(i);
            }
            rc_ecmd |= mask_buffer_64.setBit(i);
          }

// 3.) Setup the sync commands to issue to centaur on the master MCS
//      Bit 12 of MCSYNC Register is N/M Sync (Scom addr 201180B)
//      Bit 15 of MCSYNC Register is PC Sync (Scom addr 201180B)

          rc_ecmd |= data_buffer_64.setBit(12);
          rc_ecmd |= mask_buffer_64.setBit(12);
          rc_ecmd |= data_buffer_64.setBit(15);
          rc_ecmd |= mask_buffer_64.setBit(15);
          if(rc_ecmd) {
            rc.setEcmdError(rc_ecmd);
            break;
          }
          rc = fapiPutScomUnderMask(l_target_attached_mcs[theonemcs], MCS_MCSYNC_0x0201180B, data_buffer_64, mask_buffer_64);
          if(rc) break;

// 4.) Generate the Sync Command to Centaur from the master MCS
//      Bit 0 of MCS Mode3 Register (Scom addr 201180A)
//      (This bit needs a reset before another set, it does not reset automatically)
          rc_ecmd = data_buffer_64.clearBit(0,64);
          rc_ecmd |= data_buffer_64.setBit(0);
          rc_ecmd |= mask_buffer_64.clearBit(0,64);
          rc_ecmd |= mask_buffer_64.setBit(0);
          if(rc_ecmd) {
            rc.setEcmdError(rc_ecmd);
            break;
          }

          rc = fapiPutScomUnderMask(l_target_attached_mcs[theonemcs], MCS_MODE3_REGISTER_0x0201180A, data_buffer_64, mask_buffer_64);
          if(rc) break;

          // this resets the before mentioned bit
          rc_ecmd = data_buffer_64.clearBit(0);
          if(rc_ecmd) {
            rc.setEcmdError(rc_ecmd);
            break;
          }
          rc = fapiPutScomUnderMask(l_target_attached_mcs[theonemcs], MCS_MODE3_REGISTER_0x0201180A, data_buffer_64, mask_buffer_64);
          if(rc) break;

// 5.) Read the SYNC status register on the master MCS
//      Bits 1:7 of MCS Mode3 Register (Scom addr 201180A)
//     If any status bit is set, this indicates that a replay has occurred on the DMI channel, repeat steps 3 and 4 above.
// (actually to build the register back up, we go to step 2 to pick up the centaurs again)
          rc = fapiGetScom(l_target_attached_mcs[theonemcs], MCS_MODE3_REGISTER_0x0201180A, data_buffer_64);
          if(rc) break;

          if(data_buffer_64.isBitClear(1,7) == true) {
            l_sync_complete=true;
          }
          else {
            l_tries++;
            FAPI_INF("--> Not all ready, reissue the sync,  tries are %d\n", l_tries );
            l_sync_complete=false;
          }
        }
        if(rc) break;
        if (l_tries == MAX_SYNC_RETRIES) {
          FAPI_ERR("This processor did not see a successful MCSYNC\n");
          FAPI_SET_HWP_ERROR(rc, RC_PROC_MCSYNC_THERMAL_RETRY_EXCEEDED);
          break;
        }
        FAPI_INF("--> Success in running the sync sequence tries were %d\n", l_tries );

      }
    } while(0);

    return rc;
  }

} // extern "C"
OpenPOWER on IntegriCloud