#include <vm/pmap.h>
#include <machine/bus.h>
+#include <machine/cpu.h>
#include <machine/intr.h>
#include "pic_if.h"
uint64_t active_irq;
while (1) {
- active_irq = gic_icc_read(IAR1);
+ if (CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1) {
+ /*
+ * Hardware: Cavium ThunderX
+ * Chip revision: Pass 1.0 (early version)
+ * Pass 1.1 (production)
+ * ERRATUM: 22978, 23154
+ */
+ __asm __volatile(
+ "nop;nop;nop;nop;nop;nop;nop;nop; \n"
+ "mrs %0, ICC_IAR1_EL1 \n"
+ "nop;nop;nop;nop; \n"
+ "dsb sy \n"
+ : "=&r" (active_irq));
+ } else {
+ active_irq = gic_icc_read(IAR1);
+ }
if (__predict_false(active_irq == ICC_IAR1_EL1_SPUR))
break;
#define CPU_PART_CORTEX_A53 0xD03
#define CPU_PART_CORTEX_A57 0xD07
+#define CPU_REV_THUNDER_1_0 0x00
+#define CPU_REV_THUNDER_1_1 0x01
+
#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
#define CPU_MATCH_RAW(mask, devid) \
(((mask) & PCPU_GET(midr)) == ((mask) & (devid)))
+/*
+ * Chip-specific errata. This defines are intended to be
+ * booleans used within if statements. When an appropriate
+ * kernel option is disabled, these defines must be defined
+ * as 0 to allow the compiler to remove a dead code thus
+ * produce better optimized kernel image.
+ */
+/*
+ * Vendor: Cavium
+ * Chip: ThunderX
+ * Revision(s): Pass 1.0, Pass 1.1
+ */
+#ifdef THUNDERX_PASS_1_1_ERRATA
+#define CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1 \
+ (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK | CPU_REV_MASK, \
+ CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, CPU_REV_THUNDER_1_0) || \
+ CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK | CPU_REV_MASK, \
+ CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, CPU_REV_THUNDER_1_1))
+#else
+#define CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1 0
+#endif
+
+
extern char btext[];
extern char etext[];