|
@@ -704,3 +704,57 @@ privateer_process_logout_frame(struct el_common *mchk_header, int print)
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+privateer_machine_check(unsigned long vector, unsigned long la_ptr)
|
|
|
+{
|
|
|
+ struct el_common *mchk_header = (struct el_common *)la_ptr;
|
|
|
+ struct el_TITAN_sysdata_mcheck *tmchk =
|
|
|
+ (struct el_TITAN_sysdata_mcheck *)
|
|
|
+ (la_ptr + mchk_header->sys_offset);
|
|
|
+ u64 irqmask;
|
|
|
+ char *saved_err_prefix = err_print_prefix;
|
|
|
+
|
|
|
+#define PRIVATEER_680_INTERRUPT_MASK (0xE00UL)
|
|
|
+#define PRIVATEER_HOTPLUG_INTERRUPT_MASK (0xE00UL)
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Sync the processor.
|
|
|
+ */
|
|
|
+ mb();
|
|
|
+ draina();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only handle system events here.
|
|
|
+ */
|
|
|
+ if (vector != SCB_Q_SYSEVENT)
|
|
|
+ return titan_machine_check(vector, la_ptr);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Report the event - System Events should be reported even if no
|
|
|
+ * error is indicated since the event could indicate the return
|
|
|
+ * to normal status.
|
|
|
+ */
|
|
|
+ err_print_prefix = KERN_CRIT;
|
|
|
+ printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n",
|
|
|
+ err_print_prefix,
|
|
|
+ (unsigned int)vector, (int)smp_processor_id());
|
|
|
+ privateer_process_680_frame(mchk_header, 1);
|
|
|
+ err_print_prefix = saved_err_prefix;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Convert any pending interrupts which report as 680 machine
|
|
|
+ * checks to interrupts.
|
|
|
+ */
|
|
|
+ irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Dispatch the interrupt(s).
|
|
|
+ */
|
|
|
+ titan_dispatch_irqs(irqmask);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Release the logout frame.
|
|
|
+ */
|
|
|
+ wrmces(0x7);
|
|
|
+ mb();
|
|
|
+}
|