+static void
+panic_display_hung_cpus_help(void)
+{
+#if defined(__arm64__)
+ const uint32_t pcsr_offset = 0x90;
+
+ /*
+ * Print some info that might help in cases where nothing
+ * else does
+ */
+ const ml_topology_info_t *info = ml_get_topology_info();
+ if (info) {
+ unsigned i, retry;
+
+ for (i = 0; i < info->num_cpus; i++) {
+ if (info->cpus[i].cpu_UTTDBG_regs) {
+ volatile uint64_t *pcsr = (volatile uint64_t*)(info->cpus[i].cpu_UTTDBG_regs + pcsr_offset);
+ volatile uint32_t *pcsrTrigger = (volatile uint32_t*)pcsr;
+ uint64_t pc = 0;
+
+ // a number of retries are needed till this works
+ for (retry = 1024; retry && !pc; retry--) {
+ //a 32-bit read is required to make a PC sample be produced, else we'll only get a zero
+ (void)*pcsrTrigger;
+ pc = *pcsr;
+ }
+
+ //postprocessing (same as astris does)
+ if (pc >> 48) {
+ pc |= 0xffff000000000000ull;
+ }
+ paniclog_append_noflush("CORE %u recently retired instr at 0x%016llx\n", i, pc);
+ }
+ }
+ }
+#endif //defined(__arm64__)
+}
+