1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2008-2011
4  * Graeme Russ, <graeme.russ@gmail.com>
5  *
6  * (C) Copyright 2002
7  * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
8  *
9  * Portions of this file are derived from the Linux kernel source
10  *  Copyright (C) 1991, 1992  Linus Torvalds
11  */
12 
13 #include <common.h>
14 #include <dm.h>
15 #include <efi_loader.h>
16 #include <hang.h>
17 #include <init.h>
18 #include <irq.h>
19 #include <irq_func.h>
20 #include <asm/control_regs.h>
21 #include <asm/global_data.h>
22 #include <asm/i8259.h>
23 #include <asm/interrupt.h>
24 #include <asm/io.h>
25 #include <asm/lapic.h>
26 #include <asm/processor-flags.h>
27 #include <asm/ptrace.h>
28 
29 DECLARE_GLOBAL_DATA_PTR;
30 
31 #define DECLARE_INTERRUPT(x) \
32 	".globl irq_"#x"\n" \
33 	".hidden irq_"#x"\n" \
34 	".type irq_"#x", @function\n" \
35 	"irq_"#x":\n" \
36 	"pushl $"#x"\n" \
37 	"jmp.d32 irq_common_entry\n"
38 
39 static char *exceptions[] = {
40 	"Divide Error",
41 	"Debug",
42 	"NMI Interrupt",
43 	"Breakpoint",
44 	"Overflow",
45 	"BOUND Range Exceeded",
46 	"Invalid Opcode (Undefined Opcode)",
47 	"Device Not Available (No Math Coprocessor)",
48 	"Double Fault",
49 	"Coprocessor Segment Overrun",
50 	"Invalid TSS",
51 	"Segment Not Present",
52 	"Stack Segment Fault",
53 	"General Protection",
54 	"Page Fault",
55 	"Reserved",
56 	"x87 FPU Floating-Point Error",
57 	"Alignment Check",
58 	"Machine Check",
59 	"SIMD Floating-Point Exception",
60 	"Virtualization Exception",
61 	"Reserved",
62 	"Reserved",
63 	"Reserved",
64 	"Reserved",
65 	"Reserved",
66 	"Reserved",
67 	"Reserved",
68 	"Reserved",
69 	"Reserved",
70 	"Reserved",
71 	"Reserved"
72 };
73 
74 /**
75  * show_efi_loaded_images() - show loaded UEFI images
76  *
77  * List all loaded UEFI images.
78  *
79  * @eip:	instruction pointer
80  */
show_efi_loaded_images(uintptr_t eip)81 static void show_efi_loaded_images(uintptr_t eip)
82 {
83 	efi_print_image_infos((void *)eip);
84 }
85 
dump_regs(struct irq_regs * regs)86 static void dump_regs(struct irq_regs *regs)
87 {
88 	unsigned long cs, eip, eflags;
89 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
90 	unsigned long d0, d1, d2, d3, d6, d7;
91 	unsigned long sp;
92 
93 	/*
94 	 * Some exceptions cause an error code to be saved on the current stack
95 	 * after the EIP value. We should extract CS/EIP/EFLAGS from different
96 	 * position on the stack based on the exception number.
97 	 */
98 	switch (regs->irq_id) {
99 	case EXC_DF:
100 	case EXC_TS:
101 	case EXC_NP:
102 	case EXC_SS:
103 	case EXC_GP:
104 	case EXC_PF:
105 	case EXC_AC:
106 		cs = regs->context.ctx2.xcs;
107 		eip = regs->context.ctx2.eip;
108 		eflags = regs->context.ctx2.eflags;
109 		/* We should fix up the ESP due to error code */
110 		regs->esp += 4;
111 		break;
112 	default:
113 		cs = regs->context.ctx1.xcs;
114 		eip = regs->context.ctx1.eip;
115 		eflags = regs->context.ctx1.eflags;
116 		break;
117 	}
118 
119 	printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
120 			(u16)cs, eip, eflags);
121 	if (gd->flags & GD_FLG_RELOC)
122 		printf("Original EIP :[<%08lx>]\n", eip - gd->reloc_off);
123 
124 	printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
125 		regs->eax, regs->ebx, regs->ecx, regs->edx);
126 	printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
127 		regs->esi, regs->edi, regs->ebp, regs->esp);
128 	printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
129 	       (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs,
130 	       (u16)regs->xgs, (u16)regs->xss);
131 
132 	cr0 = read_cr0();
133 	cr2 = read_cr2();
134 	cr3 = read_cr3();
135 	cr4 = read_cr4();
136 
137 	printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
138 			cr0, cr2, cr3, cr4);
139 
140 	d0 = get_debugreg(0);
141 	d1 = get_debugreg(1);
142 	d2 = get_debugreg(2);
143 	d3 = get_debugreg(3);
144 
145 	printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
146 			d0, d1, d2, d3);
147 
148 	d6 = get_debugreg(6);
149 	d7 = get_debugreg(7);
150 	printf("DR6: %08lx DR7: %08lx\n",
151 			d6, d7);
152 
153 	printf("Stack:\n");
154 	sp = regs->esp;
155 
156 	sp += 64;
157 
158 	while (sp > (regs->esp - 16)) {
159 		if (sp == regs->esp)
160 			printf("--->");
161 		else
162 			printf("    ");
163 		printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp));
164 		sp -= 4;
165 	}
166 	show_efi_loaded_images(eip);
167 }
168 
do_exception(struct irq_regs * regs)169 static void do_exception(struct irq_regs *regs)
170 {
171 	printf("%s\n", exceptions[regs->irq_id]);
172 	dump_regs(regs);
173 	hang();
174 }
175 
176 struct idt_entry {
177 	u16	base_low;
178 	u16	selector;
179 	u8	res;
180 	u8	access;
181 	u16	base_high;
182 } __packed;
183 
184 struct idt_entry idt[256] __aligned(16);
185 
186 struct idt_ptr idt_ptr;
187 
load_idt(const struct idt_ptr * dtr)188 static inline void load_idt(const struct idt_ptr *dtr)
189 {
190 	asm volatile("cs lidt %0" : : "m" (*dtr));
191 }
192 
set_vector(u8 intnum,void * routine)193 void set_vector(u8 intnum, void *routine)
194 {
195 	idt[intnum].base_high = (u16)((ulong)(routine) >> 16);
196 	idt[intnum].base_low = (u16)((ulong)(routine) & 0xffff);
197 }
198 
199 /*
200  * Ideally these would be defined static to avoid a checkpatch warning, but
201  * the compiler cannot see them in the inline asm and complains that they
202  * aren't defined
203  */
204 void irq_0(void);
205 void irq_1(void);
206 
cpu_init_interrupts(void)207 int cpu_init_interrupts(void)
208 {
209 	int i;
210 
211 	int irq_entry_size = irq_1 - irq_0;
212 	void *irq_entry = (void *)irq_0;
213 
214 	/* Setup the IDT */
215 	for (i = 0; i < 256; i++) {
216 		idt[i].access = 0x8e;
217 		idt[i].res = 0;
218 		idt[i].selector = X86_GDT_ENTRY_32BIT_CS * X86_GDT_ENTRY_SIZE;
219 		set_vector(i, irq_entry);
220 		irq_entry += irq_entry_size;
221 	}
222 
223 	idt_ptr.size = 256 * 8 - 1;
224 	idt_ptr.address = (unsigned long) idt;
225 
226 	load_idt(&idt_ptr);
227 
228 	return 0;
229 }
230 
interrupt_read_idt(struct idt_ptr * ptr)231 void interrupt_read_idt(struct idt_ptr *ptr)
232 {
233 	asm volatile("sidt %0" : : "m" (*ptr));
234 }
235 
x86_get_idt(void)236 void *x86_get_idt(void)
237 {
238 	return &idt_ptr;
239 }
240 
__do_irq(int irq)241 void __do_irq(int irq)
242 {
243 	printf("Unhandled IRQ : %d\n", irq);
244 }
245 void do_irq(int irq) __attribute__((weak, alias("__do_irq")));
246 
enable_interrupts(void)247 void enable_interrupts(void)
248 {
249 	asm("sti\n");
250 }
251 
disable_interrupts(void)252 int disable_interrupts(void)
253 {
254 	long flags;
255 
256 #if CONFIG_IS_ENABLED(X86_64)
257 	asm volatile ("pushfq ; popq %0 ; cli\n" : "=g" (flags) : );
258 #else
259 	asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : );
260 #endif
261 	return flags & X86_EFLAGS_IF;
262 }
263 
interrupt_init(void)264 int interrupt_init(void)
265 {
266 	struct udevice *dev;
267 	int ret;
268 
269 	if (!ll_boot_init())
270 		return 0;
271 
272 	/* Try to set up the interrupt router, but don't require one */
273 	ret = irq_first_device_type(X86_IRQT_BASE, &dev);
274 	if (ret && ret != -ENODEV)
275 		return ret;
276 
277 	/*
278 	 * When running as an EFI application we are not in control of
279 	 * interrupts and should leave them alone.
280 	 */
281 #ifndef CONFIG_EFI_APP
282 	/* Just in case... */
283 	disable_interrupts();
284 
285 #ifdef CONFIG_I8259_PIC
286 	/* Initialize the master/slave i8259 pic */
287 	i8259_init();
288 #endif
289 
290 #ifdef CONFIG_APIC
291 	lapic_setup();
292 #endif
293 
294 	/* Initialize core interrupt and exception functionality of CPU */
295 	cpu_init_interrupts();
296 
297 	/*
298 	 * It is now safe to enable interrupts.
299 	 *
300 	 * TODO(sjg@chromium.org): But we don't handle these correctly when
301 	 * booted from EFI.
302 	 */
303 	enable_interrupts();
304 #endif
305 
306 	return 0;
307 }
308 
309 /* IRQ Low-Level Service Routine */
irq_llsr(struct irq_regs * regs)310 void irq_llsr(struct irq_regs *regs)
311 {
312 	/*
313 	 * For detailed description of each exception, refer to:
314 	 * Intel® 64 and IA-32 Architectures Software Developer's Manual
315 	 * Volume 1: Basic Architecture
316 	 * Order Number: 253665-029US, November 2008
317 	 * Table 6-1. Exceptions and Interrupts
318 	 */
319 	if (regs->irq_id < 32) {
320 		/* Architecture defined exception */
321 		do_exception(regs);
322 	} else {
323 		/* Hardware or User IRQ */
324 		do_irq(regs->irq_id);
325 	}
326 }
327 
328 /*
329  * OK - This looks really horrible, but it serves a purpose - It helps create
330  * fully relocatable code.
331  *  - The call to irq_llsr will be a relative jump
332  *  - The IRQ entries will be guaranteed to be in order
333  *  Interrupt entries are now very small (a push and a jump) but they are
334  *  now slower (all registers pushed on stack which provides complete
335  *  crash dumps in the low level handlers
336  *
337  * Interrupt Entry Point:
338  *  - Interrupt has caused eflags, CS and EIP to be pushed
339  *  - Interrupt Vector Handler has pushed orig_eax
340  *  - pt_regs.esp needs to be adjusted by 40 bytes:
341  *      12 bytes pushed by CPU (EFLAGSF, CS, EIP)
342  *      4 bytes pushed by vector handler (irq_id)
343  *      24 bytes pushed before SP (SS, GS, FS, ES, DS, EAX)
344  *      NOTE: Only longs are pushed on/popped off the stack!
345  */
346 asm(".globl irq_common_entry\n" \
347 	".hidden irq_common_entry\n" \
348 	".type irq_common_entry, @function\n" \
349 	"irq_common_entry:\n" \
350 	"cld\n" \
351 	"pushl %ss\n" \
352 	"pushl %gs\n" \
353 	"pushl %fs\n" \
354 	"pushl %es\n" \
355 	"pushl %ds\n" \
356 	"pushl %eax\n" \
357 	"movl  %esp, %eax\n" \
358 	"addl  $40, %eax\n" \
359 	"pushl %eax\n" \
360 	"pushl %ebp\n" \
361 	"pushl %edi\n" \
362 	"pushl %esi\n" \
363 	"pushl %edx\n" \
364 	"pushl %ecx\n" \
365 	"pushl %ebx\n" \
366 	"mov   %esp, %eax\n" \
367 	"call irq_llsr\n" \
368 	"popl %ebx\n" \
369 	"popl %ecx\n" \
370 	"popl %edx\n" \
371 	"popl %esi\n" \
372 	"popl %edi\n" \
373 	"popl %ebp\n" \
374 	"popl %eax\n" \
375 	"popl %eax\n" \
376 	"popl %ds\n" \
377 	"popl %es\n" \
378 	"popl %fs\n" \
379 	"popl %gs\n" \
380 	"popl %ss\n" \
381 	"add  $4, %esp\n" \
382 	"iret\n" \
383 	DECLARE_INTERRUPT(0) \
384 	DECLARE_INTERRUPT(1) \
385 	DECLARE_INTERRUPT(2) \
386 	DECLARE_INTERRUPT(3) \
387 	DECLARE_INTERRUPT(4) \
388 	DECLARE_INTERRUPT(5) \
389 	DECLARE_INTERRUPT(6) \
390 	DECLARE_INTERRUPT(7) \
391 	DECLARE_INTERRUPT(8) \
392 	DECLARE_INTERRUPT(9) \
393 	DECLARE_INTERRUPT(10) \
394 	DECLARE_INTERRUPT(11) \
395 	DECLARE_INTERRUPT(12) \
396 	DECLARE_INTERRUPT(13) \
397 	DECLARE_INTERRUPT(14) \
398 	DECLARE_INTERRUPT(15) \
399 	DECLARE_INTERRUPT(16) \
400 	DECLARE_INTERRUPT(17) \
401 	DECLARE_INTERRUPT(18) \
402 	DECLARE_INTERRUPT(19) \
403 	DECLARE_INTERRUPT(20) \
404 	DECLARE_INTERRUPT(21) \
405 	DECLARE_INTERRUPT(22) \
406 	DECLARE_INTERRUPT(23) \
407 	DECLARE_INTERRUPT(24) \
408 	DECLARE_INTERRUPT(25) \
409 	DECLARE_INTERRUPT(26) \
410 	DECLARE_INTERRUPT(27) \
411 	DECLARE_INTERRUPT(28) \
412 	DECLARE_INTERRUPT(29) \
413 	DECLARE_INTERRUPT(30) \
414 	DECLARE_INTERRUPT(31) \
415 	DECLARE_INTERRUPT(32) \
416 	DECLARE_INTERRUPT(33) \
417 	DECLARE_INTERRUPT(34) \
418 	DECLARE_INTERRUPT(35) \
419 	DECLARE_INTERRUPT(36) \
420 	DECLARE_INTERRUPT(37) \
421 	DECLARE_INTERRUPT(38) \
422 	DECLARE_INTERRUPT(39) \
423 	DECLARE_INTERRUPT(40) \
424 	DECLARE_INTERRUPT(41) \
425 	DECLARE_INTERRUPT(42) \
426 	DECLARE_INTERRUPT(43) \
427 	DECLARE_INTERRUPT(44) \
428 	DECLARE_INTERRUPT(45) \
429 	DECLARE_INTERRUPT(46) \
430 	DECLARE_INTERRUPT(47) \
431 	DECLARE_INTERRUPT(48) \
432 	DECLARE_INTERRUPT(49) \
433 	DECLARE_INTERRUPT(50) \
434 	DECLARE_INTERRUPT(51) \
435 	DECLARE_INTERRUPT(52) \
436 	DECLARE_INTERRUPT(53) \
437 	DECLARE_INTERRUPT(54) \
438 	DECLARE_INTERRUPT(55) \
439 	DECLARE_INTERRUPT(56) \
440 	DECLARE_INTERRUPT(57) \
441 	DECLARE_INTERRUPT(58) \
442 	DECLARE_INTERRUPT(59) \
443 	DECLARE_INTERRUPT(60) \
444 	DECLARE_INTERRUPT(61) \
445 	DECLARE_INTERRUPT(62) \
446 	DECLARE_INTERRUPT(63) \
447 	DECLARE_INTERRUPT(64) \
448 	DECLARE_INTERRUPT(65) \
449 	DECLARE_INTERRUPT(66) \
450 	DECLARE_INTERRUPT(67) \
451 	DECLARE_INTERRUPT(68) \
452 	DECLARE_INTERRUPT(69) \
453 	DECLARE_INTERRUPT(70) \
454 	DECLARE_INTERRUPT(71) \
455 	DECLARE_INTERRUPT(72) \
456 	DECLARE_INTERRUPT(73) \
457 	DECLARE_INTERRUPT(74) \
458 	DECLARE_INTERRUPT(75) \
459 	DECLARE_INTERRUPT(76) \
460 	DECLARE_INTERRUPT(77) \
461 	DECLARE_INTERRUPT(78) \
462 	DECLARE_INTERRUPT(79) \
463 	DECLARE_INTERRUPT(80) \
464 	DECLARE_INTERRUPT(81) \
465 	DECLARE_INTERRUPT(82) \
466 	DECLARE_INTERRUPT(83) \
467 	DECLARE_INTERRUPT(84) \
468 	DECLARE_INTERRUPT(85) \
469 	DECLARE_INTERRUPT(86) \
470 	DECLARE_INTERRUPT(87) \
471 	DECLARE_INTERRUPT(88) \
472 	DECLARE_INTERRUPT(89) \
473 	DECLARE_INTERRUPT(90) \
474 	DECLARE_INTERRUPT(91) \
475 	DECLARE_INTERRUPT(92) \
476 	DECLARE_INTERRUPT(93) \
477 	DECLARE_INTERRUPT(94) \
478 	DECLARE_INTERRUPT(95) \
479 	DECLARE_INTERRUPT(97) \
480 	DECLARE_INTERRUPT(96) \
481 	DECLARE_INTERRUPT(98) \
482 	DECLARE_INTERRUPT(99) \
483 	DECLARE_INTERRUPT(100) \
484 	DECLARE_INTERRUPT(101) \
485 	DECLARE_INTERRUPT(102) \
486 	DECLARE_INTERRUPT(103) \
487 	DECLARE_INTERRUPT(104) \
488 	DECLARE_INTERRUPT(105) \
489 	DECLARE_INTERRUPT(106) \
490 	DECLARE_INTERRUPT(107) \
491 	DECLARE_INTERRUPT(108) \
492 	DECLARE_INTERRUPT(109) \
493 	DECLARE_INTERRUPT(110) \
494 	DECLARE_INTERRUPT(111) \
495 	DECLARE_INTERRUPT(112) \
496 	DECLARE_INTERRUPT(113) \
497 	DECLARE_INTERRUPT(114) \
498 	DECLARE_INTERRUPT(115) \
499 	DECLARE_INTERRUPT(116) \
500 	DECLARE_INTERRUPT(117) \
501 	DECLARE_INTERRUPT(118) \
502 	DECLARE_INTERRUPT(119) \
503 	DECLARE_INTERRUPT(120) \
504 	DECLARE_INTERRUPT(121) \
505 	DECLARE_INTERRUPT(122) \
506 	DECLARE_INTERRUPT(123) \
507 	DECLARE_INTERRUPT(124) \
508 	DECLARE_INTERRUPT(125) \
509 	DECLARE_INTERRUPT(126) \
510 	DECLARE_INTERRUPT(127) \
511 	DECLARE_INTERRUPT(128) \
512 	DECLARE_INTERRUPT(129) \
513 	DECLARE_INTERRUPT(130) \
514 	DECLARE_INTERRUPT(131) \
515 	DECLARE_INTERRUPT(132) \
516 	DECLARE_INTERRUPT(133) \
517 	DECLARE_INTERRUPT(134) \
518 	DECLARE_INTERRUPT(135) \
519 	DECLARE_INTERRUPT(136) \
520 	DECLARE_INTERRUPT(137) \
521 	DECLARE_INTERRUPT(138) \
522 	DECLARE_INTERRUPT(139) \
523 	DECLARE_INTERRUPT(140) \
524 	DECLARE_INTERRUPT(141) \
525 	DECLARE_INTERRUPT(142) \
526 	DECLARE_INTERRUPT(143) \
527 	DECLARE_INTERRUPT(144) \
528 	DECLARE_INTERRUPT(145) \
529 	DECLARE_INTERRUPT(146) \
530 	DECLARE_INTERRUPT(147) \
531 	DECLARE_INTERRUPT(148) \
532 	DECLARE_INTERRUPT(149) \
533 	DECLARE_INTERRUPT(150) \
534 	DECLARE_INTERRUPT(151) \
535 	DECLARE_INTERRUPT(152) \
536 	DECLARE_INTERRUPT(153) \
537 	DECLARE_INTERRUPT(154) \
538 	DECLARE_INTERRUPT(155) \
539 	DECLARE_INTERRUPT(156) \
540 	DECLARE_INTERRUPT(157) \
541 	DECLARE_INTERRUPT(158) \
542 	DECLARE_INTERRUPT(159) \
543 	DECLARE_INTERRUPT(160) \
544 	DECLARE_INTERRUPT(161) \
545 	DECLARE_INTERRUPT(162) \
546 	DECLARE_INTERRUPT(163) \
547 	DECLARE_INTERRUPT(164) \
548 	DECLARE_INTERRUPT(165) \
549 	DECLARE_INTERRUPT(166) \
550 	DECLARE_INTERRUPT(167) \
551 	DECLARE_INTERRUPT(168) \
552 	DECLARE_INTERRUPT(169) \
553 	DECLARE_INTERRUPT(170) \
554 	DECLARE_INTERRUPT(171) \
555 	DECLARE_INTERRUPT(172) \
556 	DECLARE_INTERRUPT(173) \
557 	DECLARE_INTERRUPT(174) \
558 	DECLARE_INTERRUPT(175) \
559 	DECLARE_INTERRUPT(176) \
560 	DECLARE_INTERRUPT(177) \
561 	DECLARE_INTERRUPT(178) \
562 	DECLARE_INTERRUPT(179) \
563 	DECLARE_INTERRUPT(180) \
564 	DECLARE_INTERRUPT(181) \
565 	DECLARE_INTERRUPT(182) \
566 	DECLARE_INTERRUPT(183) \
567 	DECLARE_INTERRUPT(184) \
568 	DECLARE_INTERRUPT(185) \
569 	DECLARE_INTERRUPT(186) \
570 	DECLARE_INTERRUPT(187) \
571 	DECLARE_INTERRUPT(188) \
572 	DECLARE_INTERRUPT(189) \
573 	DECLARE_INTERRUPT(190) \
574 	DECLARE_INTERRUPT(191) \
575 	DECLARE_INTERRUPT(192) \
576 	DECLARE_INTERRUPT(193) \
577 	DECLARE_INTERRUPT(194) \
578 	DECLARE_INTERRUPT(195) \
579 	DECLARE_INTERRUPT(196) \
580 	DECLARE_INTERRUPT(197) \
581 	DECLARE_INTERRUPT(198) \
582 	DECLARE_INTERRUPT(199) \
583 	DECLARE_INTERRUPT(200) \
584 	DECLARE_INTERRUPT(201) \
585 	DECLARE_INTERRUPT(202) \
586 	DECLARE_INTERRUPT(203) \
587 	DECLARE_INTERRUPT(204) \
588 	DECLARE_INTERRUPT(205) \
589 	DECLARE_INTERRUPT(206) \
590 	DECLARE_INTERRUPT(207) \
591 	DECLARE_INTERRUPT(208) \
592 	DECLARE_INTERRUPT(209) \
593 	DECLARE_INTERRUPT(210) \
594 	DECLARE_INTERRUPT(211) \
595 	DECLARE_INTERRUPT(212) \
596 	DECLARE_INTERRUPT(213) \
597 	DECLARE_INTERRUPT(214) \
598 	DECLARE_INTERRUPT(215) \
599 	DECLARE_INTERRUPT(216) \
600 	DECLARE_INTERRUPT(217) \
601 	DECLARE_INTERRUPT(218) \
602 	DECLARE_INTERRUPT(219) \
603 	DECLARE_INTERRUPT(220) \
604 	DECLARE_INTERRUPT(221) \
605 	DECLARE_INTERRUPT(222) \
606 	DECLARE_INTERRUPT(223) \
607 	DECLARE_INTERRUPT(224) \
608 	DECLARE_INTERRUPT(225) \
609 	DECLARE_INTERRUPT(226) \
610 	DECLARE_INTERRUPT(227) \
611 	DECLARE_INTERRUPT(228) \
612 	DECLARE_INTERRUPT(229) \
613 	DECLARE_INTERRUPT(230) \
614 	DECLARE_INTERRUPT(231) \
615 	DECLARE_INTERRUPT(232) \
616 	DECLARE_INTERRUPT(233) \
617 	DECLARE_INTERRUPT(234) \
618 	DECLARE_INTERRUPT(235) \
619 	DECLARE_INTERRUPT(236) \
620 	DECLARE_INTERRUPT(237) \
621 	DECLARE_INTERRUPT(238) \
622 	DECLARE_INTERRUPT(239) \
623 	DECLARE_INTERRUPT(240) \
624 	DECLARE_INTERRUPT(241) \
625 	DECLARE_INTERRUPT(242) \
626 	DECLARE_INTERRUPT(243) \
627 	DECLARE_INTERRUPT(244) \
628 	DECLARE_INTERRUPT(245) \
629 	DECLARE_INTERRUPT(246) \
630 	DECLARE_INTERRUPT(247) \
631 	DECLARE_INTERRUPT(248) \
632 	DECLARE_INTERRUPT(249) \
633 	DECLARE_INTERRUPT(250) \
634 	DECLARE_INTERRUPT(251) \
635 	DECLARE_INTERRUPT(252) \
636 	DECLARE_INTERRUPT(253) \
637 	DECLARE_INTERRUPT(254) \
638 	DECLARE_INTERRUPT(255));
639