summaryrefslogtreecommitdiffstats
path: root/src/occ_405/homer.c
blob: adcccaedb1dbce8a28cd8fc651999775d45ec9a9 (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/occ_405/homer.c $                                         */
/*                                                                        */
/* OpenPOWER OnChipController Project                                     */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2011,2019                        */
/* [+] 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                                                     */

// Description: HOMER specific functions.

#include "ssx.h"
#include <errl.h>
#include <occ_service_codes.h>
#include <occ_common.h>
#include <homer.h>

/*
 * Function Specification
 *
 * Name: homer_hd_map_read_unmap
 *
 * Description: Wrapper function for reading the host data area of the homer.
 *              The caller passes in an ID indication what they want to read,
 *              this function checks the version of the host data area and
 *              returns the data to the location pointed to by the pointer
 *              argument, it is the callers responsibility to guarantee that
 *              there is enough space to receive the returned data.
 *              Note that this function will map the HOMER host data section to
 *              the normally reserved address 0 and unmap the data before
 *              returning to the caller.
 *              If an ssx error is returned from the map or unmap request the
 *              ssx return code will be returned in the ssx rc output word.
 *
 * End Function Specification
 */

// NOTE: Optimization of O1 is needed for this function due to the l_bootLoaderHeader pointer
// pointing to a 0 address (which is considered NULL by the compiler) and thus with newer
// gcc compilers (4.9.0 and above), a new optimization flag issolate-erroneous-paths-dereference
// the compiler will set a trap in the code that will stop it from running.
// Setting the Optimization to 1 will disable this flag when compiling with gcc 4.9 and above.

homer_rc_t __attribute__((optimize("O1"))) homer_hd_map_read_unmap(const homer_read_var_t  i_id,
                                   void                    * const o_host_data,
                                   int                     * const o_ssx_rc)
{
#if PPC405_MMU_SUPPORT
    Ppc405MmuMap l_mmuMapHomer = 0;
#endif

    homer_rc_t l_rc = HOMER_SUCCESS;
    occHostConfigDataArea_t *l_hdcfg_data = (occHostConfigDataArea_t *) HOMER_HD_ADDRESS;

    // Validate the pointers
    if (!o_host_data || !o_ssx_rc || ((uint32_t)o_host_data % 4))
    {
        l_rc = HOMER_BAD_PARM;
    }
    else
    {
        *o_ssx_rc = SSX_OK;

#if PPC405_MMU_SUPPORT

        /*
         * Map to mainstore at HOMER host data offset. The first parameter is
         * the effective address where the data can be accessed once mapped, the
         * second parameter is the real address in main memory (PBA adjusted)
         * where the data is located.
         */
        *o_ssx_rc = ppc405_mmu_map((SsxAddress)l_hdcfg_data,
                                   (SsxAddress)(HOMER_HD_ADDRESS),
                                   sizeof(occHostConfigDataArea_t),
                                   0,
                                   0,
                                   &l_mmuMapHomer);
#endif
        if (SSX_OK != *o_ssx_rc)
        {
            l_rc = HOMER_SSX_MAP_ERR;
        }
        else
        {
            // Check version, if ok handle ID requested. We need to support
            // current version as well as older ones
            if (HOMER_VERSION_P9 != l_hdcfg_data->version)
            {
                l_rc = HOMER_UNSUPPORTED_HD_VERSION;
            }
            else
            {
                // HOMER_VERSION_P9 == l_hdcfg_data->version
                switch (i_id)
                {
                case HOMER_VERSION:
                    *(uint32_t *)o_host_data = l_hdcfg_data->version;
                    break;
                case HOMER_NEST_FREQ:
                    *(uint32_t *)o_host_data = l_hdcfg_data->nestFrequency;
                    break;
                case HOMER_INT_TYPE:
                    *(uint32_t *)o_host_data = l_hdcfg_data->occInterruptType;
                    break;
                case HOMER_FIR_MASTER:
                    *(uint32_t *)o_host_data = l_hdcfg_data->firMaster;
                    break;
                case HOMER_FIR_PARMS:
                    memcpy(o_host_data, &(l_hdcfg_data->firParms[0]), HOMER_FIR_PARM_SIZE);
                    break;
                case HOMER_SMF_MODE:
                    *(uint32_t *)o_host_data = l_hdcfg_data->smfMode;
                    break;
                default:
                    l_rc = HOMER_UNKNOWN_ID;
                    break;
                }
            }
#if PPC405_MMU_SUPPORT
            // Unmap the HOMER before returning to caller
            *o_ssx_rc = ppc405_mmu_unmap(&l_mmuMapHomer);
            if ((SSX_OK != *o_ssx_rc) && (HOMER_SUCCESS == l_rc))
            {
                l_rc = HOMER_SSX_UNMAP_ERR;
            }
#endif
        }
    }

    return l_rc;
}
// End of homer_hd_map_read_unmap


/*
 * Function Specification
 *
 * Name: homer_log_access_error
 *
 * Description: Utility function to log an error that occurred while accessing
 *              the HOMER.
 *
 * End Function Specification
 */
void homer_log_access_error(const homer_rc_t i_homer_rc,
                            const int i_ssx_rc,
                            const uint32_t i_usr_data2)
{
    // Catch and log the homer error
    if (HOMER_SUCCESS != i_homer_rc)
    {
        // We could potentially have both an internal error dealing with the
        // homer and an SSX error, for example we could find an unsupported
        // version number in the homer and then have an ssx error trying to
        // unmap the homer address space.  This check catches all those cases.
        if (SSX_OK != i_ssx_rc)
        {
            /* @
             * @errortype
             * @moduleid    MAIN_MID
             * @reasoncode  SSX_GENERIC_FAILURE
             * @userdata1   HOMER and SSX return codes
             * @userdata2   Host interrupt type used
             * @userdata4   ERC_HOMER_MAIN_SSX_ERROR
             * @devdesc     An SSX error occurred mapping the HOMER host data
             *              into the OCC address space. User word 1 contains
             *              both the internal and SSX return codes returned
             *              by the method used to access the HOMER data.
             */
            errlHndl_t l_err = createErrl(MAIN_MID,                 //modId
                                          SSX_GENERIC_FAILURE,      //reasoncode
                                          ERC_HOMER_MAIN_SSX_ERROR, //Extended reason code
                                          ERRL_SEV_PREDICTIVE,      //Severity
                                          NULL,                     //Trace Buf
                                          DEFAULT_TRACE_SIZE,       //Trace Size
                                          (i_homer_rc << 16) | (0xFFFF & (uint32_t)i_ssx_rc), //userdata1
                                          i_usr_data2);             //userdata2
            commitErrl(&l_err);
        }
        else
        {
            /* @
             * @errortype
             * @moduleid    MAIN_MID
             * @reasoncode  INTERNAL_FAILURE
             * @userdata1   HOMER return code
             * @userdata2   Default host interrupt type used.
             * @userdata4   ERC_HOMER_MAIN_ACCESS_ERROR
             * @devdesc     Error accessing initialization data
             */
            errlHndl_t l_err = createErrl(MAIN_MID,                 //modId
                                          INTERNAL_FAILURE,         //reasoncode
                                          ERC_HOMER_MAIN_ACCESS_ERROR,//Extended reason code
                                          ERRL_SEV_INFORMATIONAL,   //Severity
                                          NULL,                     //Trace Buf
                                          DEFAULT_TRACE_SIZE,       //Trace Size
                                          i_homer_rc,               //userdata1
                                          i_usr_data2);             //userdata2
            commitErrl(&l_err);
        }
    }
}
// End of homer_log_access_error

// End of homer.c
OpenPOWER on IntegriCloud