mce.c 7.19 KB
Newer Older
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*
 * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <common/bl_common.h>
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <common/debug.h>
#include <denver.h>
#include <mce.h>
#include <mce_private.h>
#include <mmio.h>
#include <string.h>
#include <errno.h>
#include <tegra_def.h>
#include <tegra_platform.h>

/*******************************************************************************
 * Common handler for all MCE commands
 ******************************************************************************/
int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
			uint64_t arg2)
{
	uint64_t ret64 = 0, arg3, arg4, arg5;
	int ret = 0;
	mca_cmd_t mca_cmd;
	uncore_perfmon_req_t req;
	cpu_context_t *ctx = cm_get_context(NON_SECURE);
	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);

	assert(ctx);
	assert(gp_regs);

	switch (cmd) {
	case MCE_CMD_ENTER_CSTATE:
		/* NVG */
		break;

	case MCE_CMD_UPDATE_CSTATE_INFO:
		/*
		 * get the parameters required for the update cstate info
		 * command
		 */
		arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
		arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
		arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);

		/* NVG */

		write_ctx_reg(gp_regs, CTX_GPREG_X4, arg3);
		write_ctx_reg(gp_regs, CTX_GPREG_X5, arg4);
		write_ctx_reg(gp_regs, CTX_GPREG_X6, arg5);

		break;

	case MCE_CMD_UPDATE_CROSSOVER_TIME:
		/* NVG */

		break;

	case MCE_CMD_READ_CSTATE_STATS:
		/* NVG */

		/* update context to return cstate stats value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
		write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64);

		break;

	case MCE_CMD_WRITE_CSTATE_STATS:
		/* NVG */

		break;

	case MCE_CMD_IS_CCX_ALLOWED:
		/* NVG */

		/* update context to return CCx status value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret);

		break;

	case MCE_CMD_IS_SC7_ALLOWED:
		/* NVG */

		/* update context to return SC7 status value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret);
		write_ctx_reg(gp_regs, CTX_GPREG_X3, ret);

		break;

	case MCE_CMD_ONLINE_CORE:
		/* NVG */

		break;

	case MCE_CMD_CC3_CTRL:
		/* NVG */

		break;

	case MCE_CMD_ECHO_DATA:
		/* issue NVG to echo data */

		/* update context to return if echo'd data matched source */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64 == arg0);
		write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64 == arg0);

		break;

	case MCE_CMD_READ_VERSIONS:
		/* get the MCE firmware version */

		/*
		 * version = minor(63:32) | major(31:0). Update context
		 * to return major and minor version number.
		 */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64);
		write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32));

		break;

	case MCE_CMD_ENUM_FEATURES:
		break;

	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
		/* NVG */

		break;

	case MCE_CMD_ROC_FLUSH_CACHE:
		/* NVG */

		break;

	case MCE_CMD_ROC_CLEAN_CACHE:
		/* NVG */

		break;

	case MCE_CMD_ENUM_READ_MCA:
		memcpy(&mca_cmd, &arg0, sizeof(arg0));

		/* NVG */

		/* update context to return MCA data/error */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
		write_ctx_reg(gp_regs, CTX_GPREG_X2, arg1);
		write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64);

		break;

	case MCE_CMD_ENUM_WRITE_MCA:
		memcpy(&mca_cmd, &arg0, sizeof(arg0));

		/* NVG */

		/* update context to return MCA error */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
		write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64);

		break;

	case MCE_CMD_ENABLE_LATIC:
		/*
		 * This call is not for production use. The constant value,
		 * 0xFFFF0000, is specific to allowing for enabling LATIC on
		 * pre-production parts for the chip verification harness.
		 *
		 * Enabling LATIC allows S/W to read the MINI ISPs in the
		 * CCPLEX. The ISMs are used for various measurements relevant
		 * to particular locations in the Silicon. They are small
		 * counters which can be polled to determine how fast a
		 * particular location in the Silicon is.
		 */
		/* NVG */

		break;

	case MCE_CMD_UNCORE_PERFMON_REQ:
		memcpy(&req, &arg0, sizeof(arg0));
		/* NVG */

		/* update context to return data */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1);
		break;

	case MCE_CMD_MISC_CCPLEX:
		/* NVG */

		break;

	default:
		ERROR("unknown MCE command (%lld)\n", cmd);
		return EINVAL;
	}

	return ret;
}

/*******************************************************************************
 * Handler to update the reset vector for CPUs
 ******************************************************************************/
int mce_update_reset_vector(void)
{
	return 0;
}

static int mce_update_ccplex_gsc(/* GSC ID */)
{
	return 0;
}

/*******************************************************************************
 * Handler to update carveout values for Video Memory Carveout region
 ******************************************************************************/
int mce_update_gsc_videomem(void)
{
	return mce_update_ccplex_gsc();
}

/*******************************************************************************
 * Handler to update carveout values for TZDRAM aperture
 ******************************************************************************/
int mce_update_gsc_tzdram(void)
{
	return mce_update_ccplex_gsc();
}

/*******************************************************************************
 * Handler to update carveout values for TZ SysRAM aperture
 ******************************************************************************/
int mce_update_gsc_tzram(void)
{
	return mce_update_ccplex_gsc();
}

/*******************************************************************************
 * Handler to shutdown/reset the entire system
 ******************************************************************************/
__dead2 void mce_enter_ccplex_state(uint32_t state_idx)
{
	/* sanity check state value */

	/* enter ccplex power state */

	/* wait till the CCPLEX powers down */
	for (;;)
		;

	panic();
}

/*******************************************************************************
 * Handler to issue the UPDATE_CSTATE_INFO request
 ******************************************************************************/
void mce_update_cstate_info(mce_cstate_info_t *cstate)
{
	/* issue the UPDATE_CSTATE_INFO request */
	/* NVG */
}

/*******************************************************************************
 * Handler to read the MCE firmware version and check if it is compatible
 * with interface header the BL3-1 was compiled against
 ******************************************************************************/
void mce_verify_firmware_version(void)
{
	uint64_t version;
	uint32_t major, minor;

	/*
	 * MCE firmware is not running on simulation platforms.
	 */
	if (tegra_platform_is_linsim() || tegra_platform_is_virt_dev_kit())
		return;

	/* get a pointer to the CPU's arch_mce_ops_t struct */

	/*
	 * Read the MCE firmware version and extract the major and minor
	 * version fields
	 */
	version = 0;
	major = (uint32_t)version;
	minor = (uint32_t)(version >> 32);

	INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
		0, 0);

	/*
	 * Verify that the MCE firmware version and the interface header
	 * match
	 */
	if (major != 0) {
		ERROR("MCE major version mismatch\n");
		panic();
	}

	if (minor < 0) {
		ERROR("MCE minor version mismatch\n");
		panic();
	}
}