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