@@ -11,6 +11,7 @@ void do_handle_exception(struct pt_regs *regs);
#endif /* __ASSEMBLY__ */
extern bool cpu_has_hv;
+extern bool cpu_has_heai;
static inline uint64_t mfspr(int nr)
{
@@ -87,6 +87,7 @@ static void cpu_set(int fdtnode, u64 regval, void *info)
}
bool cpu_has_hv;
+bool cpu_has_heai;
static void cpu_init(void)
{
@@ -108,6 +109,18 @@ static void cpu_init(void)
hcall(H_SET_MODE, 0, 4, 0, 0);
#endif
}
+
+ switch (mfspr(SPR_PVR) & PVR_VERSION_MASK) {
+ case PVR_VER_POWER10:
+ case PVR_VER_POWER9:
+ case PVR_VER_POWER8E:
+ case PVR_VER_POWER8NVL:
+ case PVR_VER_POWER8:
+ cpu_has_heai = true;
+ break;
+ default:
+ break;
+ }
}
static void mem_init(phys_addr_t freemem_start)
@@ -31,6 +31,20 @@ static void program_check_handler(struct pt_regs *regs, void *opaque)
regs->nip += 4;
}
+static void heai_handler(struct pt_regs *regs, void *opaque)
+{
+ int *data = opaque;
+
+ if (verbose) {
+ printf("Detected invalid instruction %#018lx: %08x\n",
+ regs->nip, *(uint32_t*)regs->nip);
+ }
+
+ *data = 8; /* Illegal instruction */
+
+ regs->nip += 4;
+}
+
static void alignment_handler(struct pt_regs *regs, void *opaque)
{
int *data = opaque;
@@ -363,6 +377,8 @@ int main(int argc, char **argv)
int i;
handle_exception(0x700, program_check_handler, (void *)&is_invalid);
+ if (cpu_has_heai)
+ handle_exception(0xe40, heai_handler, (void *)&is_invalid);
handle_exception(0x600, alignment_handler, (void *)&alignment);
for (i = 1; i < argc; i++) {