xref: /aosp_15_r20/external/arm-trusted-firmware/lib/cpus/errata_report.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park /* Runtime firmware routines to report errata status for the current CPU. */
8*54fd6939SJiyong Park 
9*54fd6939SJiyong Park #include <assert.h>
10*54fd6939SJiyong Park #include <stdbool.h>
11*54fd6939SJiyong Park 
12*54fd6939SJiyong Park #include <arch_helpers.h>
13*54fd6939SJiyong Park #include <common/debug.h>
14*54fd6939SJiyong Park #include <lib/cpus/errata_report.h>
15*54fd6939SJiyong Park #include <lib/el3_runtime/cpu_data.h>
16*54fd6939SJiyong Park #include <lib/spinlock.h>
17*54fd6939SJiyong Park 
18*54fd6939SJiyong Park #ifdef IMAGE_BL1
19*54fd6939SJiyong Park # define BL_STRING	"BL1"
20*54fd6939SJiyong Park #elif defined(__aarch64__) && defined(IMAGE_BL31)
21*54fd6939SJiyong Park # define BL_STRING	"BL31"
22*54fd6939SJiyong Park #elif !defined(__aarch64__) && defined(IMAGE_BL32)
23*54fd6939SJiyong Park # define BL_STRING	"BL32"
24*54fd6939SJiyong Park #elif defined(IMAGE_BL2) && BL2_AT_EL3
25*54fd6939SJiyong Park # define BL_STRING "BL2"
26*54fd6939SJiyong Park #else
27*54fd6939SJiyong Park # error This image should not be printing errata status
28*54fd6939SJiyong Park #endif
29*54fd6939SJiyong Park 
30*54fd6939SJiyong Park /* Errata format: BL stage, CPU, errata ID, message */
31*54fd6939SJiyong Park #define ERRATA_FORMAT	"%s: %s: CPU workaround for %s was %s\n"
32*54fd6939SJiyong Park 
33*54fd6939SJiyong Park /*
34*54fd6939SJiyong Park  * Returns whether errata needs to be reported. Passed arguments are private to
35*54fd6939SJiyong Park  * a CPU type.
36*54fd6939SJiyong Park  */
errata_needs_reporting(spinlock_t * lock,uint32_t * reported)37*54fd6939SJiyong Park int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
38*54fd6939SJiyong Park {
39*54fd6939SJiyong Park 	bool report_now;
40*54fd6939SJiyong Park 
41*54fd6939SJiyong Park 	/* If already reported, return false. */
42*54fd6939SJiyong Park 	if (*reported != 0U)
43*54fd6939SJiyong Park 		return 0;
44*54fd6939SJiyong Park 
45*54fd6939SJiyong Park 	/*
46*54fd6939SJiyong Park 	 * Acquire lock. Determine whether status needs reporting, and then mark
47*54fd6939SJiyong Park 	 * report status to true.
48*54fd6939SJiyong Park 	 */
49*54fd6939SJiyong Park 	spin_lock(lock);
50*54fd6939SJiyong Park 	report_now = (*reported == 0U);
51*54fd6939SJiyong Park 	if (report_now)
52*54fd6939SJiyong Park 		*reported = 1;
53*54fd6939SJiyong Park 	spin_unlock(lock);
54*54fd6939SJiyong Park 
55*54fd6939SJiyong Park 	return report_now;
56*54fd6939SJiyong Park }
57*54fd6939SJiyong Park 
58*54fd6939SJiyong Park /*
59*54fd6939SJiyong Park  * Print errata status message.
60*54fd6939SJiyong Park  *
61*54fd6939SJiyong Park  * Unknown: WARN
62*54fd6939SJiyong Park  * Missing: WARN
63*54fd6939SJiyong Park  * Applied: INFO
64*54fd6939SJiyong Park  * Not applied: VERBOSE
65*54fd6939SJiyong Park  */
errata_print_msg(unsigned int status,const char * cpu,const char * id)66*54fd6939SJiyong Park void errata_print_msg(unsigned int status, const char *cpu, const char *id)
67*54fd6939SJiyong Park {
68*54fd6939SJiyong Park 	/* Errata status strings */
69*54fd6939SJiyong Park 	static const char *const errata_status_str[] = {
70*54fd6939SJiyong Park 		[ERRATA_NOT_APPLIES] = "not applied",
71*54fd6939SJiyong Park 		[ERRATA_APPLIES] = "applied",
72*54fd6939SJiyong Park 		[ERRATA_MISSING] = "missing!"
73*54fd6939SJiyong Park 	};
74*54fd6939SJiyong Park 	static const char *const __unused bl_str = BL_STRING;
75*54fd6939SJiyong Park 	const char *msg __unused;
76*54fd6939SJiyong Park 
77*54fd6939SJiyong Park 
78*54fd6939SJiyong Park 	assert(status < ARRAY_SIZE(errata_status_str));
79*54fd6939SJiyong Park 	assert(cpu != NULL);
80*54fd6939SJiyong Park 	assert(id != NULL);
81*54fd6939SJiyong Park 
82*54fd6939SJiyong Park 	msg = errata_status_str[status];
83*54fd6939SJiyong Park 
84*54fd6939SJiyong Park 	switch (status) {
85*54fd6939SJiyong Park 	case ERRATA_NOT_APPLIES:
86*54fd6939SJiyong Park 		VERBOSE(ERRATA_FORMAT, bl_str, cpu, id, msg);
87*54fd6939SJiyong Park 		break;
88*54fd6939SJiyong Park 
89*54fd6939SJiyong Park 	case ERRATA_APPLIES:
90*54fd6939SJiyong Park 		INFO(ERRATA_FORMAT, bl_str, cpu, id, msg);
91*54fd6939SJiyong Park 		break;
92*54fd6939SJiyong Park 
93*54fd6939SJiyong Park 	case ERRATA_MISSING:
94*54fd6939SJiyong Park 		WARN(ERRATA_FORMAT, bl_str, cpu, id, msg);
95*54fd6939SJiyong Park 		break;
96*54fd6939SJiyong Park 
97*54fd6939SJiyong Park 	default:
98*54fd6939SJiyong Park 		WARN(ERRATA_FORMAT, bl_str, cpu, id, "unknown");
99*54fd6939SJiyong Park 		break;
100*54fd6939SJiyong Park 	}
101*54fd6939SJiyong Park }
102