x86: Simplify architecture defined exception handling in irq_llsr()

Instead of using switch..case for architecture defined exceptions,
simply unify the handling by printing a message of exception name,
followed by registers dump then halt the CPU.

With this unification, it also fixes the wrong exception numbers
for #MF/#AC/#MC/#XM which should be 16/17/18/19 not 15/16/17/18.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index 043a8d4..853c82f 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -32,6 +32,41 @@
 	"pushl $"#x"\n" \
 	"jmp irq_common_entry\n"
 
+static char *exceptions[] = {
+	"Divide Error",
+	"Debug",
+	"NMI Interrupt",
+	"Breakpoint",
+	"Overflow",
+	"BOUND Range Exceeded",
+	"Invalid Opcode (Undefined Opcode)",
+	"Device Not Avaiable (No Math Coprocessor)",
+	"Double Fault",
+	"Coprocessor Segment Overrun",
+	"Invalid TSS",
+	"Segment Not Present",
+	"Stack Segment Fault",
+	"Gerneral Protection",
+	"Page Fault",
+	"Reserved",
+	"x87 FPU Floating-Point Error",
+	"Alignment Check",
+	"Machine Check",
+	"SIMD Floating-Point Exception",
+	"Virtualization Exception",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved"
+};
+
 static void dump_regs(struct irq_regs *regs)
 {
 	unsigned long cs, eip, eflags;
@@ -112,6 +147,13 @@
 	}
 }
 
+static void do_exception(struct irq_regs *regs)
+{
+	printf("%s\n", exceptions[regs->irq_id]);
+	dump_regs(regs);
+	hang();
+}
+
 struct idt_entry {
 	u16	base_low;
 	u16	selector;
@@ -228,111 +270,10 @@
 	 * Order Number: 253665-029US, November 2008
 	 * Table 6-1. Exceptions and Interrupts
 	 */
-	switch (regs->irq_id) {
-	case 0x00:
-		printf("Divide Error (Division by zero)\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x01:
-		printf("Debug Interrupt (Single step)\n");
-		dump_regs(regs);
-		break;
-	case 0x02:
-		printf("NMI Interrupt\n");
-		dump_regs(regs);
-		break;
-	case 0x03:
-		printf("Breakpoint\n");
-		dump_regs(regs);
-		break;
-	case 0x04:
-		printf("Overflow\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x05:
-		printf("BOUND Range Exceeded\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x06:
-		printf("Invalid Opcode (UnDefined Opcode)\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x07:
-		printf("Device Not Available (No Math Coprocessor)\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x08:
-		printf("Double fault\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x09:
-		printf("Co-processor segment overrun\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x0a:
-		printf("Invalid TSS\n");
-		dump_regs(regs);
-		break;
-	case 0x0b:
-		printf("Segment Not Present\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x0c:
-		printf("Stack Segment Fault\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x0d:
-		printf("General Protection\n");
-		dump_regs(regs);
-		break;
-	case 0x0e:
-		printf("Page fault\n");
-		dump_regs(regs);
-		hang();
-		break;
-	case 0x0f:
-		printf("Floating-Point Error (Math Fault)\n");
-		dump_regs(regs);
-		break;
-	case 0x10:
-		printf("Alignment check\n");
-		dump_regs(regs);
-		break;
-	case 0x11:
-		printf("Machine Check\n");
-		dump_regs(regs);
-		break;
-	case 0x12:
-		printf("SIMD Floating-Point Exception\n");
-		dump_regs(regs);
-		break;
-	case 0x13:
-	case 0x14:
-	case 0x15:
-	case 0x16:
-	case 0x17:
-	case 0x18:
-	case 0x19:
-	case 0x1a:
-	case 0x1b:
-	case 0x1c:
-	case 0x1d:
-	case 0x1e:
-	case 0x1f:
-		printf("Reserved Exception\n");
-		dump_regs(regs);
-		break;
-
-	default:
+	if (regs->irq_id < 32) {
+		/* Architecture defined exception */
+		do_exception(regs);
+	} else {
 		/* Hardware or User IRQ */
 		do_irq(regs->irq_id);
 	}