+/*
+ * Called from locore on a special reserved stack after a machine-check
+ */
+void
+panic_machine_check(int code)
+{
+ struct i386_tss *my_ktss = current_ktss();
+
+ /* Set postcode (DEBUG only) */
+ postcode(PANIC_MACHINE_CHECK);
+
+ /*
+ * Break kprintf lock in case of recursion,
+ * and record originally faulted instruction address.
+ */
+ kprintf_break_lock();
+
+ /*
+ * Dump the contents of the machine check MSRs (if any).
+ */
+ mca_dump();
+
+ /*
+ * And that's all folks, we don't attempt recovery...
+ */
+ panic("Machine-check (CPU:%d, thread:%p, code:0x%x),"
+ "registers:\n"
+ "CR0: 0x%08x, CR2: 0x%08x, CR3: 0x%08x, CR4: 0x%08x\n"
+ "EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n"
+ "ESP: 0x%08x, EBP: 0x%08x, ESI: 0x%08x, EDI: 0x%08x\n"
+ "EFL: 0x%08x, EIP: 0x%08x\n",
+ cpu_number(), current_thread(), code,
+ get_cr0(), get_cr2(), get_cr3(), get_cr4(),
+ my_ktss->eax, my_ktss->ebx, my_ktss->ecx, my_ktss->edx,
+ my_ktss->esp, my_ktss->ebp, my_ktss->esi, my_ktss->edi,
+ my_ktss->eflags, my_ktss->eip);
+}
+
+void
+panic_double_fault64(x86_saved_state_t *esp)
+{
+ /* Set postcode (DEBUG only) */
+ postcode(PANIC_DOUBLE_FAULT);
+
+ /*
+ * Break kprintf lock in case of recursion,
+ * and record originally faulted instruction address.
+ */
+ kprintf_break_lock();
+
+ /*
+ * Dump the interrupt stack frame at last kernel entry.
+ */
+ if (is_saved_state64(esp)) {
+ x86_saved_state64_t *ss64p = saved_state64(esp);
+ panic("Double fault (CPU:%d, thread:%p, trapno:0x%x, err:0x%qx),"
+ "registers:\n"
+ "CR0: 0x%08x, CR2: 0x%08x, CR3: 0x%08x, CR4: 0x%08x\n"
+ "RAX: 0x%016qx, RBX: 0x%016qx, RCX: 0x%016qx, RDX: 0x%016qx\n"
+ "RSP: 0x%016qx, RBP: 0x%016qx, RSI: 0x%016qx, RDI: 0x%016qx\n"
+ "R8: 0x%016qx, R9: 0x%016qx, R10: 0x%016qx, R11: 0x%016qx\n"
+ "R12: 0x%016qx, R13: 0x%016qx, R14: 0x%016qx, R15: 0x%016qx\n"
+ "RFL: 0x%016qx, RIP: 0x%016qx, CR2: 0x%016qx\n",
+ cpu_number(), current_thread(), ss64p->isf.trapno, ss64p->isf.err,
+ get_cr0(), get_cr2(), get_cr3(), get_cr4(),
+ ss64p->rax, ss64p->rbx, ss64p->rcx, ss64p->rdx,
+ ss64p->isf.rsp, ss64p->rbp, ss64p->rsi, ss64p->rdi,
+ ss64p->r8, ss64p->r9, ss64p->r10, ss64p->r11,
+ ss64p->r12, ss64p->r13, ss64p->r14, ss64p->r15,
+ ss64p->isf.rflags, ss64p->isf.rip, ss64p->cr2);
+ } else {
+ x86_saved_state32_t *ss32p = saved_state32(esp);
+ panic("Double fault (CPU:%d, thread:%p, trapno:0x%x, err:0x%x),"
+ "registers:\n"
+ "CR0: 0x%08x, CR2: 0x%08x, CR3: 0x%08x, CR4: 0x%08x\n"
+ "EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n"
+ "ESP: 0x%08x, EBP: 0x%08x, ESI: 0x%08x, EDI: 0x%08x\n"
+ "EFL: 0x%08x, EIP: 0x%08x\n",
+ cpu_number(), current_thread(), ss32p->trapno, ss32p->err,
+ get_cr0(), get_cr2(), get_cr3(), get_cr4(),
+ ss32p->eax, ss32p->ebx, ss32p->ecx, ss32p->edx,
+ ss32p->uesp, ss32p->ebp, ss32p->esi, ss32p->edi,
+ ss32p->efl, ss32p->eip);
+ }
+}
+
+/*
+ * Machine check handler for 64-bit.
+ */
+void
+panic_machine_check64(x86_saved_state_t *esp)
+{
+ /* Set postcode (DEBUG only) */
+ postcode(PANIC_MACHINE_CHECK);
+
+ /*
+ * Break kprintf lock in case of recursion,
+ * and record originally faulted instruction address.
+ */
+ kprintf_break_lock();
+
+ /*
+ * Dump the contents of the machine check MSRs (if any).
+ */
+ mca_dump();
+
+ /*
+ * And that's all folks, we don't attempt recovery...
+ */
+ if (is_saved_state64(esp)) {
+ x86_saved_state64_t *ss64p = saved_state64(esp);
+ panic("Machine Check (CPU:%d, thread:%p, trapno:0x%x, err:0x%qx),"
+ "registers:\n"
+ "CR0: 0x%08x, CR2: 0x%08x, CR3: 0x%08x, CR4: 0x%08x\n"
+ "RAX: 0x%016qx, RBX: 0x%016qx, RCX: 0x%016qx, RDX: 0x%016qx\n"
+ "RSP: 0x%016qx, RBP: 0x%016qx, RSI: 0x%016qx, RDI: 0x%016qx\n"
+ "R8: 0x%016qx, R9: 0x%016qx, R10: 0x%016qx, R11: 0x%016qx\n"
+ "R12: 0x%016qx, R13: 0x%016qx, R14: 0x%016qx, R15: 0x%016qx\n"
+ "RFL: 0x%016qx, RIP: 0x%016qx\n",
+ cpu_number(), current_thread(), ss64p->isf.trapno, ss64p->isf.err,
+ get_cr0(), get_cr2(), get_cr3(), get_cr4(),
+ ss64p->rax, ss64p->rbx, ss64p->rcx, ss64p->rdx,
+ ss64p->isf.rsp, ss64p->rbp, ss64p->rsi, ss64p->rdi,
+ ss64p->r8, ss64p->r9, ss64p->r10, ss64p->r11,
+ ss64p->r12, ss64p->r13, ss64p->r14, ss64p->r15,
+ ss64p->isf.rflags, ss64p->isf.rip);
+ } else {
+ x86_saved_state32_t *ss32p = saved_state32(esp);
+ panic("Machine Check (CPU:%d, thread:%p, trapno:0x%x, err:0x%x),"
+ "registers:\n"
+ "CR0: 0x%08x, CR2: 0x%08x, CR3: 0x%08x, CR4: 0x%08x\n"
+ "EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n"
+ "ESP: 0x%08x, EBP: 0x%08x, ESI: 0x%08x, EDI: 0x%08x\n"
+ "EFL: 0x%08x, EIP: 0x%08x\n",
+ cpu_number(), current_thread(), ss32p->trapno, ss32p->err,
+ get_cr0(), get_cr2(), get_cr3(), get_cr4(),
+ ss32p->eax, ss32p->ebx, ss32p->ecx, ss32p->edx,
+ ss32p->uesp, ss32p->ebp, ss32p->esi, ss32p->edi,
+ ss32p->efl, ss32p->eip);
+ }
+}
+