summaryrefslogtreecommitdiffstats
path: root/src/usr/errl/plugins/errludwofdata.H
blob: f792c5485df5eaba380380050e220d8712b3d43e (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/errl/plugins/errludwofdata.H $                        */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017,2018                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef ERRL_UDWOFDATA_H
#define ERRL_UDWOFDATA_H

/**
 *  @file errludwofdata.H
 *
 *  Defines the ErrlUserDetailsWofData class that parses the
 *  WOF data user detail section of an error log
 */

#include "errluserdetails.H"
#include <targeting/common/target.H>

namespace ERRORLOG
{

/**
 * @class ErrlUserDetailsParserWofData
 *
 * Parses WOF data user detail in an error log
 */
class ErrlUserDetailsParserWofData :public ErrlUserDetailsParser
{
public:
    /**
     *  @brief Constructor
     */
    ErrlUserDetailsParserWofData() {}

    /**
     *  @brief Destructor
     */
    virtual ~ErrlUserDetailsParserWofData() {}

    /**
     *  @brief Parses WOF detail data from an error log
     *
     *  @param  i_version Version of the data
     *  @param  i_parser  ErrlUsrParser object for outputting information
     *  @param  i_pBuffer Pointer to buffer containing WOF detail data
     *  @param  i_buflen  Length of the buffer
     */
    virtual void parse(errlver_t i_version,
                       ErrlUsrParser & i_parser,
                       void * i_pBuffer,
                       const uint32_t i_buflen) const
    {
        // From src/usr/fapi2/plat_wof_access.C
        typedef struct
        {
          uint8_t  core_count;
          uint8_t  mode;
          uint16_t socket_power_w;
          uint16_t sort_power_freq_mhz;
        } wofTableCompareData_t;

        // From src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h
        typedef enum
        {
            WOF_MODE_UNKNOWN = 0,
            WOF_MODE_NOMINAL = 1,
            WOF_MODE_TURBO   = 2
        } WOF_MODE;

        uint16_t tableEntries = 0;

        // Format of WofData error buffer:
        // uint16_t - # of table entries (including search for table)
        // wofTableCompareData_t - Searched for this table
        // wofTableCompareData_t - last table rejected for possible match
        // ...
        // wofTableCompareData_t - 1st table rejected for possible match
        // NOTE: format must match
        //       addWofCompareDataToErrl() in plat_wof_access.C
        if ((NULL != i_pBuffer) && (i_buflen >= sizeof(tableEntries)))
        {
          tableEntries = ntohs(*(reinterpret_cast<uint16_t*>(i_pBuffer)));
        }

        // How many entries are really present in this buffer?
        uint16_t actualTableCount = (i_buflen - sizeof(tableEntries)) /
                                     sizeof(wofTableCompareData_t);

        // sanity check to verify we are getting all the table data
        if (tableEntries != actualTableCount)
        {
          i_parser.PrintString("**************************************","");
          i_parser.PrintNumber("Total entries calculated", "%d",
                               actualTableCount);
          i_parser.PrintNumber("Total entries expected", "%d",
                               tableEntries);
          i_parser.PrintString("**************************************","");

          tableEntries = actualTableCount;  // don't go over buffer length
        }

        // Verify the buffer contains at least the specified number of entries
        if ( (i_buflen - sizeof(tableEntries) -
              tableEntries * sizeof(wofTableCompareData_t)) >= 0 )
        {
            i_parser.PrintString("---------------------------------------",
                                 "---------------------------------------");
            i_parser.PrintNumber("Total WOF Tables compared", "%d",
                                 tableEntries-1);

            // point to start of table compare data
            void * i_pTableData = (uint8_t*)i_pBuffer + sizeof(tableEntries);
            wofTableCompareData_t* outputDataPtr =
                              static_cast<wofTableCompareData_t*>(i_pTableData);
            for ( uint32_t tableEntry = 0; tableEntry < tableEntries;
                  ++tableEntry )
            {
              if (tableEntry == 0)
              {
                i_parser.PrintString("---------------------------------------",
                                     "---------------------------------------");
                i_parser.PrintString("Searched for this table",
                                     "Tried to match this:");
              }
              else
              {
                i_parser.PrintString("---------------------------------------",
                                     "---------------------------");
                i_parser.PrintNumber("WOF Table", "#%d", tableEntry);
              }

              i_parser.PrintNumber( "Core Count", "%d",
                                    outputDataPtr->core_count );

              switch(outputDataPtr->mode)
              {
                  case WOF_MODE_UNKNOWN:
                  {
                      i_parser.PrintString( "Mode", "Any" );
                      break;
                  }
                  case WOF_MODE_NOMINAL:
                  {
                      i_parser.PrintString( "Mode", "Nominal" );
                      break;
                  }
                  case WOF_MODE_TURBO:
                  {
                      i_parser.PrintString( "Mode", "Turbo" );
                      break;
                  }
                  default:
                  {
                      i_parser.PrintNumber( "Mode", "UNKNOWN: 0x%X",
                                            outputDataPtr->mode );
                      break;
                  }
              }
              i_parser.PrintNumber("Socket Power (Watts)", "%d",
                                    ntohs(outputDataPtr->socket_power_w));
              i_parser.PrintNumber("Sort Power Freq (MHz)", "%d",
                                    ntohs(outputDataPtr->sort_power_freq_mhz));
              outputDataPtr++; // go to next table entry
            }
        }
        else
        {
            i_parser.PrintString("Unable to parse too small buffer","");
            i_parser.PrintNumber("WOF Buffer length", "0x%X", i_buflen);
            i_parser.PrintNumber("Total entry count", "0x%X", tableEntries);
            i_parser.PrintString("Expected buffer format:",
                        "uint16_t count, match this entry, unmatched entries");
            i_parser.PrintNumber("Each entry size", "%d",
                                sizeof(wofTableCompareData_t));
            i_parser.PrintHexDump(i_pBuffer, i_buflen);
        }
    }

private:
    // Disabled
    ErrlUserDetailsParserWofData(const ErrlUserDetailsParserWofData &);
    ErrlUserDetailsParserWofData & operator=(
        const ErrlUserDetailsParserWofData &);
};

}

#endif
OpenPOWER on IntegriCloud