3 * Copyright 2006, Intel Corporation
4 * All rights reserved. This program and the accompanying materials
5 * are licensed and made available under the terms and conditions of the BSD License
6 * which accompanies this distribution. The full text of the license may be found at
7 * http://opensource.org/licenses/bsd-license.php
9 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 .globl ASM_PFX(SystemTimerHandler)
19 .globl ASM_PFX(SystemExceptionHandler)
20 .globl ASM_PFX(mExceptionCodeSize)
21 .globl ASM_PFX(InitDescriptor)
22 .globl ASM_PFX(InstallInterruptHandler)
24 ASM_PFX(mExceptionCodeSize): .long 9
32 ASM_PFX(InitDescriptor):
39 * InstallInterruptHandler (
41 * VOID (*Handler)(VOID)
44 ASM_PFX(InstallInterruptHandler):
48 cli # turn off interrupts
49 subl $6, %esp # open some space on the stack
51 sidt %es:(%edi) # get fword address of IDT
52 movl %es:2(%edi), %edi # move offset of IDT into EDI
53 addl $6, %esp # correct stack
54 mov 4(%ebp), %eax # Get vector number
55 shll $3, %eax # multiply by 8 to get offset
56 addl %eax, %edi # add to IDT base to get entry
57 movl 8(%ebp), %eax # load new address into IDT entry
58 movw %ax, %es:(%edi) # write bits 15..0 of offset
59 shrl $16, %eax # use ax to copy 31..16 to descriptors
60 movw %ax, %es:6(%edi) # write bits 31..16 of offset
61 popfl # restore flags (possible enabling interrupts)
65 .macro JmpCommonIdtEntry errno, vector
66 /* jmp commonIdtEntry - this must be hand coded to keep the assembler from
67 * using a 8 bit reletive jump when the entries are
68 * within 255 bytes of the common entry. This must
69 * be done to maintain the consistency of the size
74 #.byte 0e9h # jmp 16 bit reletive
75 #.long commonIdtEntry - $ - $4 # offset to jump to
80 ASM_PFX(SystemExceptionHandler):
82 JmpCommonIdtEntry errno=0,vector=0
84 JmpCommonIdtEntry errno=0,vector=1
86 JmpCommonIdtEntry errno=0,vector=2
88 JmpCommonIdtEntry errno=0,vector=3
90 JmpCommonIdtEntry errno=0,vector=4
92 JmpCommonIdtEntry errno=0,vector=5
94 JmpCommonIdtEntry errno=0,vector=6
96 JmpCommonIdtEntry errno=0,vector=7
98 # Double fault causes an error code to be pushed so no phony pushl necessary
104 JmpCommonIdtEntry errno=0,vector=9
106 # Invalid TSS causes an error code to be pushed so no phony pushl necessary
112 # Segment Not Present causes an error code to be pushed so no phony pushl necessary
118 # Stack fault causes an error code to be pushed so no phony pushl necessary
124 # GP fault causes an error code to be pushed so no phony pushl necessary
130 # Page fault causes an error code to be pushed so no phony pushl necessary
136 JmpCommonIdtEntry errno=0,vector=15
138 JmpCommonIdtEntry errno=0,vector=16
140 # Alignment check causes an error code to be pushed so no phony pushl necessary
146 JmpCommonIdtEntry errno=0,vector=18
148 JmpCommonIdtEntry errno=0,vector=19
150 JmpCommonIdtEntry errno=0,vector=20
151 JmpCommonIdtEntry errno=0,vector=21
152 JmpCommonIdtEntry errno=0,vector=22
153 JmpCommonIdtEntry errno=0,vector=23
154 JmpCommonIdtEntry errno=0,vector=24
155 JmpCommonIdtEntry errno=0,vector=25
156 JmpCommonIdtEntry errno=0,vector=26
157 JmpCommonIdtEntry errno=0,vector=27
158 JmpCommonIdtEntry errno=0,vector=28
159 JmpCommonIdtEntry errno=0,vector=29
160 JmpCommonIdtEntry errno=0,vector=30
161 JmpCommonIdtEntry errno=0,vector=31
163 ASM_PFX(SystemTimerHandler):
164 JmpCommonIdtEntry errno=0,vector=ASM_PFX(mTimerVector)
167 # +---------------------+
169 # +---------------------+
171 # +---------------------+
173 # +---------------------+
175 # +---------------------+
177 # +---------------------+
179 # +---------------------+ <-- EBP
186 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
189 andl $0xfffffff0, %esp
192 ## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax#
203 ## UINT32 Gs, Fs, Es, Ds, Cs, Ss#
206 movzwl 16(%ebp), %eax
220 ## UINT32 Gdtr[2], Idtr[2]#
236 ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4#
250 ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#
253 ## clear Dr7 while executing debugger itself
259 ## insure all status bits in dr6 are clear...
272 ## FX_SAVE_STATE_IA32 FxSaveState#
275 #.byte 0f, 0ae, 00000111y #fxsave [edi]
278 ## UINT32 ExceptionData#
281 ## Prepare parameter and call
288 call ASM_PFX(TimerHandler)
291 call ASM_PFX(ExceptionHandler)
296 ## UINT32 ExceptionData#
299 ## FX_SAVE_STATE_IA32 FxSaveState#
301 #db 0fh, 0aeh, 00001110y # fxrstor [esi]
305 ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#
314 ## skip restore of dr6. We cleared dr6 during the context save.
319 ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4#
322 addl $4, %esp # not for Cr1
334 ## UINT32 Gdtr[2], Idtr[2]#
335 ## Best not let anyone mess with these particular registers...
341 ## UINT32 Gs, Fs, Es, Ds, Cs, Ss#
342 ## NOTE - modified segment registers could hang the debugger... We
343 ## could attempt to insulate ourselves against this possibility,
344 ## but that poses risks as well.
353 ## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax#
356 addl $4, %esp # not for ebp
357 addl $4, %esp # not for esp
369 ##############################################################################
371 ##############################################################################
378 ##############################################################################
379 # global descriptor table (GDT)
380 ##############################################################################
385 .quad 0x0 // null descriptor
386 .quad 0x00cf92000000ffff // linear data segment descriptor
387 .quad 0x00cf9a000000ffff // linear code segment descriptor
388 .quad 0x00cf92000000ffff // system data segment descriptor
389 .quad 0x00cf9a000000ffff // system code segment descriptor
390 .quad 0x0 // spare segment descriptor
397 .word IDT_END - IDT_BASE - 1 # IDT limit
400 ##############################################################################
401 # interrupt descriptor table (IDT)
403 # Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
404 # mappings. This implementation only uses the system timer and all other
405 # IRQs will remain masked. The descriptors for vectors 33+ are provided
407 ##############################################################################
415 # divide by zero (INT 0)
416 DIV_ZERO_SEL equ $-IDT_BASE
418 dw SYS_CODE_SEL # selector 15:0
419 db 0 # 0 for interrupt gate
420 db 0eh OR 80h # type = 386 interrupt gate, present
423 # debug exception (INT 1)
424 DEBUG_EXCEPT_SEL equ $-IDT_BASE
426 dw SYS_CODE_SEL # selector 15:0
427 db 0 # 0 for interrupt gate
428 db 0eh OR 80h # type = 386 interrupt gate, present
432 NMI_SEL equ $-IDT_BASE
434 dw SYS_CODE_SEL # selector 15:0
435 db 0 # 0 for interrupt gate
436 db 0eh OR 80h # type = 386 interrupt gate, present
439 # soft breakpoint (INT 3)
440 BREAKPOINT_SEL equ $-IDT_BASE
442 dw SYS_CODE_SEL # selector 15:0
443 db 0 # 0 for interrupt gate
444 db 0eh OR 80h # type = 386 interrupt gate, present
448 OVERFLOW_SEL equ $-IDT_BASE
450 dw SYS_CODE_SEL # selector 15:0
451 db 0 # 0 for interrupt gate
452 db 0eh OR 80h # type = 386 interrupt gate, present
455 # bounds check (INT 5)
456 BOUNDS_CHECK_SEL equ $-IDT_BASE
458 dw SYS_CODE_SEL # selector 15:0
459 db 0 # 0 for interrupt gate
460 db 0eh OR 80h # type = 386 interrupt gate, present
463 # invalid opcode (INT 6)
464 INVALID_OPCODE_SEL equ $-IDT_BASE
466 dw SYS_CODE_SEL # selector 15:0
467 db 0 # 0 for interrupt gate
468 db 0eh OR 80h # type = 386 interrupt gate, present
471 # device not available (INT 7)
472 DEV_NOT_AVAIL_SEL equ $-IDT_BASE
474 dw SYS_CODE_SEL # selector 15:0
475 db 0 # 0 for interrupt gate
476 db 0eh OR 80h # type = 386 interrupt gate, present
479 # double fault (INT 8)
480 DOUBLE_FAULT_SEL equ $-IDT_BASE
482 dw SYS_CODE_SEL # selector 15:0
483 db 0 # 0 for interrupt gate
484 db 0eh OR 80h # type = 386 interrupt gate, present
487 # Coprocessor segment overrun - reserved (INT 9)
488 RSVD_INTR_SEL1 equ $-IDT_BASE
490 dw SYS_CODE_SEL # selector 15:0
491 db 0 # 0 for interrupt gate
492 db 0eh OR 80h # type = 386 interrupt gate, present
495 # invalid TSS (INT 0ah)
496 INVALID_TSS_SEL equ $-IDT_BASE
498 dw SYS_CODE_SEL # selector 15:0
499 db 0 # 0 for interrupt gate
500 db 0eh OR 80h # type = 386 interrupt gate, present
503 # segment not present (INT 0bh)
504 SEG_NOT_PRESENT_SEL equ $-IDT_BASE
506 dw SYS_CODE_SEL # selector 15:0
507 db 0 # 0 for interrupt gate
508 db 0eh OR 80h # type = 386 interrupt gate, present
511 # stack fault (INT 0ch)
512 STACK_FAULT_SEL equ $-IDT_BASE
514 dw SYS_CODE_SEL # selector 15:0
515 db 0 # 0 for interrupt gate
516 db 0eh OR 80h # type = 386 interrupt gate, present
519 # general protection (INT 0dh)
520 GP_FAULT_SEL equ $-IDT_BASE
522 dw SYS_CODE_SEL # selector 15:0
523 db 0 # 0 for interrupt gate
524 db 0eh OR 80h # type = 386 interrupt gate, present
527 # page fault (INT 0eh)
528 PAGE_FAULT_SEL equ $-IDT_BASE
530 dw SYS_CODE_SEL # selector 15:0
531 db 0 # 0 for interrupt gate
532 db 0eh OR 80h # type = 386 interrupt gate, present
535 # Intel reserved - do not use (INT 0fh)
536 RSVD_INTR_SEL2 equ $-IDT_BASE
538 dw SYS_CODE_SEL # selector 15:0
539 db 0 # 0 for interrupt gate
540 db 0eh OR 80h # type = 386 interrupt gate, present
543 # floating point error (INT 10h)
544 FLT_POINT_ERR_SEL equ $-IDT_BASE
546 dw SYS_CODE_SEL # selector 15:0
547 db 0 # 0 for interrupt gate
548 db 0eh OR 80h # type = 386 interrupt gate, present
551 # alignment check (INT 11h)
552 ALIGNMENT_CHECK_SEL equ $-IDT_BASE
554 dw SYS_CODE_SEL # selector 15:0
555 db 0 # 0 for interrupt gate
556 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
559 # machine check (INT 12h)
560 MACHINE_CHECK_SEL equ $-IDT_BASE
562 dw SYS_CODE_SEL # selector 15:0
563 db 0 # 0 for interrupt gate
564 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
567 # SIMD floating-point exception (INT 13h)
568 SIMD_EXCEPTION_SEL equ $-IDT_BASE
570 dw SYS_CODE_SEL # selector 15:0
571 db 0 # 0 for interrupt gate
572 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
577 dw SYS_CODE_SEL # selector 15:0
578 db 0 # 0 for interrupt gate
579 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
583 # 72 unspecified descriptors
586 # IRQ 0 (System timer) - (INT 68h)
587 IRQ0_SEL equ $-IDT_BASE
589 dw SYS_CODE_SEL # selector 15:0
590 db 0 # 0 for interrupt gate
591 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
594 # IRQ 1 (8042 Keyboard controller) - (INT 69h)
595 IRQ1_SEL equ $-IDT_BASE
597 dw SYS_CODE_SEL # selector 15:0
598 db 0 # 0 for interrupt gate
599 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
602 # Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
603 IRQ2_SEL equ $-IDT_BASE
605 dw SYS_CODE_SEL # selector 15:0
606 db 0 # 0 for interrupt gate
607 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
610 # IRQ 3 (COM 2) - (INT 6bh)
611 IRQ3_SEL equ $-IDT_BASE
613 dw SYS_CODE_SEL # selector 15:0
614 db 0 # 0 for interrupt gate
615 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
618 # IRQ 4 (COM 1) - (INT 6ch)
619 IRQ4_SEL equ $-IDT_BASE
621 dw SYS_CODE_SEL # selector 15:0
622 db 0 # 0 for interrupt gate
623 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
626 # IRQ 5 (LPT 2) - (INT 6dh)
627 IRQ5_SEL equ $-IDT_BASE
629 dw SYS_CODE_SEL # selector 15:0
630 db 0 # 0 for interrupt gate
631 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
634 # IRQ 6 (Floppy controller) - (INT 6eh)
635 IRQ6_SEL equ $-IDT_BASE
637 dw SYS_CODE_SEL # selector 15:0
638 db 0 # 0 for interrupt gate
639 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
642 # IRQ 7 (LPT 1) - (INT 6fh)
643 IRQ7_SEL equ $-IDT_BASE
645 dw SYS_CODE_SEL # selector 15:0
646 db 0 # 0 for interrupt gate
647 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
650 # IRQ 8 (RTC Alarm) - (INT 70h)
651 IRQ8_SEL equ $-IDT_BASE
653 dw SYS_CODE_SEL # selector 15:0
654 db 0 # 0 for interrupt gate
655 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
659 IRQ9_SEL equ $-IDT_BASE
661 dw SYS_CODE_SEL # selector 15:0
662 db 0 # 0 for interrupt gate
663 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
667 IRQ10_SEL equ $-IDT_BASE
669 dw SYS_CODE_SEL # selector 15:0
670 db 0 # 0 for interrupt gate
671 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
675 IRQ11_SEL equ $-IDT_BASE
677 dw SYS_CODE_SEL # selector 15:0
678 db 0 # 0 for interrupt gate
679 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
682 # IRQ 12 (PS/2 mouse) - (INT 74h)
683 IRQ12_SEL equ $-IDT_BASE
685 dw SYS_CODE_SEL # selector 15:0
686 db 0 # 0 for interrupt gate
687 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
690 # IRQ 13 (Floating point error) - (INT 75h)
691 IRQ13_SEL equ $-IDT_BASE
693 dw SYS_CODE_SEL # selector 15:0
694 db 0 # 0 for interrupt gate
695 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
698 # IRQ 14 (Secondary IDE) - (INT 76h)
699 IRQ14_SEL equ $-IDT_BASE
701 dw SYS_CODE_SEL # selector 15:0
702 db 0 # 0 for interrupt gate
703 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present
706 # IRQ 15 (Primary IDE) - (INT 77h)
707 IRQ15_SEL equ $-IDT_BASE
709 dw SYS_CODE_SEL # selector 15:0
710 db 0 # 0 for interrupt gate
711 db 0eh OR 80h # (10001110)type = 386 interrupt gate, present