summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/plat/fapiPlatHwpInvoker.C
blob: 5bd13d0ce279faa0556466aab79e20f1e36306ea (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
/**
 *  @file fapiPlatHwpInvoker.C
 *
 *  @brief Implements the platform specific HW Procedure invoker functions.
 */

#include <fapiPlatHwpInvoker.H>
#include <fapiHwpExecutor.H>
#include <fapiReturnCode.H>
#include <fapiPlatTrace.H>
#include <fapiErrorInfo.H>
#include <fapiPlatReasonCodes.H>
#include <fapiCollectFfdc.H>
#include <errl/errlentry.H>

namespace fapi
{

//******************************************************************************
// rcToErrl function. Converts an error fapi::ReturnCode into a errlHndl_t
//******************************************************************************
errlHndl_t rcToErrl(ReturnCode i_rc)
{
    errlHndl_t l_err = NULL;

    // Find out which component of the HWPF created the error
    ReturnCode::returnCodeCreator l_creator = i_rc.getCreator();

    if (l_creator == ReturnCode::CREATOR_PLAT)
    {
        // PLAT error. Release the errlHndl_t
        FAPI_ERR("rcToErrl: 0x%x is PLAT error", static_cast<uint32_t>(i_rc));
        l_err = reinterpret_cast<errlHndl_t> (i_rc.releasePlatData());
    }
    else if (l_creator == ReturnCode::CREATOR_HWP)
    {
        // HWP Error. Create an error log
        // TODO What should the severity be? Should it be in the error record
        /*@
         * @errortype
         * @moduleid     MOD_RC_TO_ERRL
         * @reasoncode   RC_HWP_ERROR
         * @userdata1    Return Code Value
         * @devdesc      Error from HWP
         */
        l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                        MOD_RC_TO_ERRL,
                                        RC_HWP_ERROR,
                                        static_cast<uint32_t>(i_rc));

        // Add any HWP FFDC stored in the ReturnCode to the error log
        uint32_t l_sz = 0;
        const void * l_pHwpFfdc = i_rc.getHwpFfdc(l_sz);

        if (l_sz)
        {
            // TODO Which comp id and section numbers should be used and how
            // will FFDC be parsed?
            FAPI_ERR("rcToErrl: Adding %d bytes of HWP FFDC to log", l_sz);
            l_err->addFFDC(HWPF_COMP_ID, l_pHwpFfdc, l_sz);
        }

        // Get the error info record from the Error Info Repository
        ErrorInfoRecord l_record;
        ErrorInfoRepository::Instance().find(i_rc, l_record);

        if (l_record.iv_rc == i_rc)
        {
            // Error Info Record found
            const char * l_pDescription = l_record.getDescription();

            if (l_pDescription)
            {
                FAPI_ERR("rcToErrl: HWP error record found for 0x%x: %s",
                         static_cast<uint32_t>(i_rc), l_pDescription);
            }
            else
            {
                FAPI_ERR("rcToErrl: HWP error record found for 0x%x: no "
                         "description", static_cast<uint32_t>(i_rc));
            }

            // Extract the Error Target (the Target of the failing HWP)
            Target * l_pErrTarget = i_rc.getErrTarget();

            if (l_pErrTarget == NULL)
            {
                FAPI_ERR("rcToErrl: HWP error record contains no error target");
            }
            else
            {
                // TODO Iterate through callouts, adding each callout to the
                // error log

                // Iterate through FFDC sections, collecting and adding FFDC to
                // the error log
                for(ErrorInfoRecord::ErrorInfoFfdcItr_t l_itr =
                        l_record.iv_ffdcs.begin();
                    l_itr != l_record.iv_ffdcs.end(); ++l_itr)
                {
                    // Get the FFDC HWP Token, this identifies the FFDC HWP to
                    // call to get FFDC
                    FfdcHwpToken l_token = (*l_itr).iv_ffdcHwpToken;

                    // Figure out which target to collect FFDC from
                    Target * l_pFfdcTarget = NULL;

                    if ((*l_itr).iv_targetType == l_pErrTarget->getType())
                    {
                        // The target type to collect FFDC from is the same as
                        // the Error Target. Collect FFDC from the error target
                        l_pFfdcTarget = l_pErrTarget;
                    }
                    else
                    {
                        // The target type to collect FFDC from is different
                        // from the Error Target. Figure out the target to
                        // collect FFDC from using the record's iv_targetPos 
                        // (relative to the Error Target)
                        // TODO
                        FAPI_ERR("rcToErrl: Collection of FFDC from non Error "
                                 "Target TBD");
                    }

                    if (l_pFfdcTarget)
                    {
                        // Collect FFDC
                        uint8_t * l_pFfdc = NULL;
                        uint32_t l_size = 0;

                        ReturnCode l_rc = fapiCollectFfdc(l_token,
                                                          *l_pFfdcTarget,
                                                          l_pFfdc, l_size);

                        if (l_rc)
                        {
                            // Error collecting FFDC, just ignore
                            FAPI_ERR("rcToErrl: Error collecting FFDC. "
                                     "Token: %d", l_token);
                        }
                        else
                        {
                            // Add FFDC to error log and delete
                            // TODO Which comp id and section numbers should be
                            // used and how will FFDC be parsed?
                            FAPI_ERR("rcToErrl: Adding %d bytes of FFDC to "
                                     "log. Token: %d", l_size, l_token);
                            l_err->addFFDC(HWPF_COMP_ID, l_pFfdc, l_size);
                            delete [] l_pFfdc;
                            l_pFfdc = NULL;
                        }
                    }
                }
            }
        }
        else
        {
            // Error Info Record not found. Should not happen
            FAPI_ERR("rcToErrl: HWP error record not found for 0x%x",
                     static_cast<uint32_t>(i_rc));
        }
    }
    else
    {
        // FAPI error.
        FAPI_ERR("rcToErrl: 0x%x is FAPI error", static_cast<uint32_t>(i_rc));
        /*@
         * @errortype
         * @moduleid     MOD_RC_TO_ERRL
         * @reasoncode   RC_FAPI_ERROR
         * @userdata1    Return Code Value
         * @devdesc      FAPI Error
         */
        l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                        MOD_RC_TO_ERRL,
                                        RC_FAPI_ERROR,
                                        static_cast<uint32_t>(i_rc));
    }

    return l_err;
}

//******************************************************************************
// invokeHwpInitialTest function
//******************************************************************************
errlHndl_t invokeHwpInitialTest(TARGETING::Target* i_target)
{
    FAPI_DBG(ENTER_MRK "invokeHwpInitialTest");

    errlHndl_t l_err = NULL;

    // Create a generic Target object
    Target l_target(TARGET_TYPE_PROC_CHIP, reinterpret_cast<void *> (i_target));

    //@todo
    // Double check to see if any locking is needed here.
    // Lower XSCOM already has a mutex lock.

    // Call the HWP executor macro
    ReturnCode l_rc;
    FAPI_EXEC_HWP(l_rc, hwpInitialTest, l_target);

    if (l_rc != FAPI_RC_SUCCESS)
    {
        FAPI_ERR("invokeHwpInitialTest: Error (0x%x) from "
                 "exechwpInitialTest",
                 static_cast<uint32_t> (l_rc));
        l_err = rcToErrl(l_rc);
    }
    else
    {
        FAPI_INF("Success in call to exechwpInitialTest");
    }

    FAPI_DBG(EXIT_MRK "invokeHwpInitialTest");

    return l_err;
}

//******************************************************************************
// invokeHwpTestError function
//******************************************************************************
errlHndl_t invokeHwpTestError(TARGETING::Target* i_target)
{
    FAPI_DBG(ENTER_MRK "invokeHwpTestError");

    errlHndl_t l_err = NULL;

    // Create a generic Target object
    Target l_target(TARGET_TYPE_PROC_CHIP, reinterpret_cast<void *> (i_target));

    // Call the HWP executor macro
    ReturnCode l_rc;
    FAPI_EXEC_HWP(l_rc, hwpTestError, l_target);

    if (l_rc != FAPI_RC_SUCCESS)
    {
        FAPI_INF("invokeHwpTestError: Expected error (0x%x) from HWP",
                 static_cast<uint32_t> (l_rc));
        l_err = rcToErrl(l_rc);
    }
    else
    {
        FAPI_ERR("Success from HWP");
    }

    FAPI_DBG(EXIT_MRK "invokeHwpTestError");

    return l_err;
}

} // End namespace
OpenPOWER on IntegriCloud