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
|
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/occ/homer.c $ */
/* */
/* OpenPOWER OnChipController Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2015 */
/* [+] 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)
{
Ppc405MmuMap l_mmuMapHomer = 0;
homer_rc_t l_rc = HOMER_SUCCESS;
occHostConfigDataArea_t *l_hdcfg_data = 0x00000000;
// 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,
HOMER_HD_OFFSET,
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_MIN > l_hdcfg_data->version)
||
(HOMER_VERSION_MAX < l_hdcfg_data->version))
{
l_rc = HOMER_UNSUPPORTED_HD_VERSION;
}
else
{
// Version guaranteed to be within supported range
// HOMER Version 1 support
if (HOMER_VERSION_1 == 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;
default:
l_rc = HOMER_UNKNOWN_ID;
break;
}
}
else if (HOMER_VERSION_2 == 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;
default:
l_rc = HOMER_UNKNOWN_ID;
break;
}
}
else if (HOMER_VERSION_3 == 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;
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
|