errata_report.c 2.1 KB

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