summaryrefslogtreecommitdiffstats
path: root/src/usr/isteps/istep06/host_init_fsi.C
blob: c8ec1d0652375411ee53e9c1b26fb3cdc51b882f (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep06/host_init_fsi.C $                      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,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                                                     */

#include <stdint.h>
#include <list>
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <fsi/fsiif.H>
#include <i2c/i2cif.H>
#include <i2c/tpmddif.H>
#include <initservice/taskargs.H>
#include <initservice/isteps_trace.H>
#include <initservice/initserviceif.H>
#include <isteps/hwpisteperror.H>
#include <attributeenums.H>
#include <secureboot/trustedbootif.H>
#include <config.h>

//Targeting
#include    <targeting/common/commontargeting.H>
#include    <targeting/common/util.H>
#include    <targeting/common/utilFilter.H>
#include    <targeting/common/target.H>

using namespace TARGETING;
using namespace I2C;
using namespace TRUSTEDBOOT;

namespace ISTEP_06
{

/* @brief Find Processor I2C Engines Connected to TPMs
 *
 * This helper function loops through all of the TPMs in the system
 * blueprint and finds all of the Processors that serve as their I2C
 * Masters.  It then keeps track of which processor I2C engine(s) are
 * used.
 *
 * @return i2cEngineSelect - bit-wise enum indicating which processor engine(s)
 *                           were found
 */
i2cEngineSelect find_proc_i2c_engines_for_tpm ( void )
{
    int engineSelect = static_cast<int>(I2C_ENGINE_SELECT_NONE);

#ifdef CONFIG_TPMDD
    // Get all TPMs to setup our array
    TargetHandleList tpmList;
    getTPMs(tpmList,TPM_FILTER::ALL_IN_BLUEPRINT);

    TPMDD::tpm_info_t tpmData;
    for (auto tpm : tpmList)
    {
        memset(&tpmData, 0, sizeof(tpmData));
        errlHndl_t readErr = tpmReadAttributes(tpm,
                                               tpmData,
                                               TPMDD::TPM_LOCALITY_0);

        if (nullptr != readErr)
        {
            // We are just looking for configured TPMs here
            //  so we ignore any errors
            delete readErr;
            readErr = nullptr;
        }
        else
        {
            // If TPM is connected to a processor then keep track
            // of what engine needs to be reset
            if (tpmData.i2cTarget->getAttr<ATTR_TYPE>() == TYPE_PROC)
            {
                engineSelect |= static_cast<int>(i2cEngineToEngineSelect(tpmData.engine));
            }
        }
    }

    // There should only be 1 such bus per processor.  So if we found multiple
    // engines then we know that there are different proc/engine combinations
    // and we'd need a I2C reset intferace to support that.  This check here
    // makes sure we add that support when its necessary.
    assert(__builtin_popcount(engineSelect)==1, "find_proc_i2c_engines_for_tpm: Only one engine should be found");

#endif
    return static_cast<i2cEngineSelect>(engineSelect);
}


void* host_init_fsi( void *io_pArgs )
{
    errlHndl_t l_err = NULL;
    ISTEP_ERROR::IStepError l_stepError;

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_init_fsi entry" );
    do
    {
        l_err = FSI::initializeHardware( );
        if (l_err)
        {
            // This error should get returned
            l_stepError.addErrorDetails(l_err);
            errlCommit( l_err, ISTEP_COMP_ID );
            break;
        }

        // Reset all I2C Masters if FSP is not running
        if ( !INITSERVICE::spBaseServicesEnabled() )
        {
            l_err = i2cResetActiveMasters(I2C_ALL, false);
            if (l_err)
            {
                // Commit this error
                errlCommit( l_err, ISTEP_COMP_ID );
            }
        }
        // FSP cannot access I2C buses where the TPMs and PCIe Hot Plug
        // devices are due to a lack of a FSI connection to this bus.
        // Therefore, reset all host-mode I2C engines connected to these buses
        else
        {
            l_err = i2cResetActiveMasters(
                             I2C_PROC_HOST,
                             false,
                             find_proc_i2c_engines_for_tpm());
            if (l_err)
            {
                // Commit this error
                errlCommit( l_err, ISTEP_COMP_ID );
            }
        }

    } while (0);

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_init_fsi exit" );
    return l_stepError.getErrorHandle();
}

};
OpenPOWER on IntegriCloud