1 #------------------------------------------------------------------------------
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.
16 #------------------------------------------------------------------------------
18 ##############################################################################
19 # Now in 64-bit long mode.
20 ##############################################################################
27 .equ DEFAULT_HANDLER_SIZE, INT1 - INT0
29 .macro jmpCommonIdtEntry
30 # jmp commonIdtEntry - this must be hand coded to keep the assembler from
31 # using a 8 bit reletive jump when the entries are
32 # within 255 bytes of the common entry. This must
33 # be done to maintain the consistency of the size
35 .byte 0xe9 # jmp 16 bit relative
36 .long commonIdtEntry - . - 4 # offset to jump to
42 movl $0x001fffe8,%esp # make final stack aligned
44 # set OSFXSR and OSXMMEXCPT because some code will use XMM register
58 # Populate IDT with meaningful offsets for exception handlers...
63 movl %eax,%ebx # use bx to copy 15..0 to descriptors
64 shrl $16,%eax # use ax to copy 31..16 to descriptors
65 # 63..32 of descriptors is 0
66 movl $0x78,%ecx # 78h IDT entries to initialize with unique entry points (exceptions)
70 LOOP_1: # loop through all IDT entries exception handlers and initialize to default handler
71 movw %bx, (%edi) # write bits 15..0 of offset
72 movw $0x38, 2(%edi) # SYS_CODE_SEL64 from GDT
73 movw $(0x0e00 | 0x8000), 4(%edi) # type = 386 interrupt gate, present
74 movw %ax, 6(%edi) # write bits 31..16 of offset
75 movl $0, 8(%edi) # write bits 31..16 of offset
76 addl $16, %edi # move up to next descriptor
77 addw DEFAULT_HANDLER_SIZE, %bx # move to next entry point
78 loopl LOOP_1 # loop back through again until all descriptors are initialized
80 ## at this point edi contains the offset of the descriptor for INT 20
81 ## and bx contains the low 16 bits of the offset of the default handler
82 ## so initialize all the rest of the descriptors with these two values...
83 # mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
84 #@@: ; loop through all IDT entries exception handlers and initialize to default handler
85 # mov word ptr [edi], bx ; write bits 15..0 of offset
86 # mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
87 # mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
88 # mov word ptr [edi+6], ax ; write bits 31..16 of offset
89 # mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
90 # add edi, 16 ; move up to next descriptor
91 # loop @b ; loop back through again until all descriptors are initialized
94 ## DUMP location of IDT and several of the descriptors
96 # mov eax, [offset Idtr + 2]
105 ## just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
106 # mov eax, 011111111h
107 # mov ebx, 022222222h
108 # mov ecx, 033333333h
109 # mov edx, 044444444h
110 # mov ebp, 055555555h
111 # mov esi, 066666666h
112 # mov edi, 077777777h
118 movl $0x22000,%esi # esi = 22000
119 movl 0x14(%esi),%eax # eax = [22014]
120 addl %eax,%esi # esi = 22000 + [22014] = Base of EFILDR.C
121 movl 0x3c(%esi),%ebp # ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
123 movl 0x30(%ebp),%edi # edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore)
124 movl 0x28(%ebp),%eax # eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
125 addl %edi,%eax # eax = ImageBase + EntryPoint
126 movl %ebx, EfiLdrOffset
127 movl %eax, (%ebx) # Modify far jump instruction for correct entry point
129 movw 6(%ebp), %bx # bx = Number of sections
131 movw 0x14(%ebp), %ax # ax = Optional Header Size
133 addl $0x18,%ebp # ebp = Start of 1st Section
136 pushl %esi # Save Base of EFILDR.C
137 pushl %edi # Save ImageBase
138 addl 0x14(%ebp),%esi # esi = Base of EFILDR.C + PointerToRawData
139 addl 0x0c(%ebp),%edi # edi = ImageBase + VirtualAddress
140 movl 0x10(%ebp),%ecx # ecs = SizeOfRawData
147 popl %edi # Restore ImageBase
148 popl %esi # Restore Base of EFILDR.C
150 addw $0x28,%bp # ebp = ebp + 028h = Pointer to next section record
158 movl (Idtr), %eax # get size of IDT
163 addl 2(%edx), %eax # add to base of IDT to get location of memory map...
165 movl %eax,%ecx # put argument to RCX
171 .long 0x00401000 # Offset of EFILDR
179 # db "**** DEFAULT IDT ENTRY ***",0
183 pushl $0x0 # push error code place holder on the stack
186 # db 0e9h ; jmp 16 bit reletive
187 # dd commonIdtEntry - $ - 4 ; offset to jump to
190 pushl $0x0 # push error code place holder on the stack
195 pushl $0x0 # push error code place holder on the stack
200 pushl $0x0 # push error code place holder on the stack
205 pushl $0x0 # push error code place holder on the stack
210 pushl $0x0 # push error code place holder on the stack
215 pushl $0x0 # push error code place holder on the stack
220 pushl $0x0 # push error code place holder on the stack
225 # Double fault causes an error code to be pushed so no phony push necessary
232 pushl $0x0 # push error code place holder on the stack
237 # Invalid TSS causes an error code to be pushed so no phony push necessary
244 # Segment Not Present causes an error code to be pushed so no phony push necessary
251 # Stack fault causes an error code to be pushed so no phony push necessary
258 # GP fault causes an error code to be pushed so no phony push necessary
265 # Page fault causes an error code to be pushed so no phony push necessary
272 pushl $0x0 # push error code place holder on the stack
277 pushl $0x0 # push error code place holder on the stack
282 # Alignment check causes an error code to be pushed so no phony push necessary
289 pushl $0x0 # push error code place holder on the stack
294 pushl $0x0 # push error code place holder on the stack
300 pushl $0x0 # push error code place holder on the stack
301 # push xxh ; push vector number
303 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
345 ## At this point the stack looks like this:
353 ## Int num or 0ffh for unknown int num
369 ## r15 <------- RSP, RBP
376 movl 16*8(%ebp),%eax ## move Int number into RAX
379 ja PrintDefaultString
380 PrintExceptionString:
381 shll $3,%eax ## multiply by 8 to get offset from StringTable to actual string address
382 addl StringTable, %eax
386 movl IntUnknownString, %esi
400 movl 19*8(%ebp),%eax # CS
406 movl 18*8(%ebp),%eax # RIP
465 movl StringEcode, %esi
533 movl StringRflags, %esi
571 movl 18*8(%ebp),%eax # RIP
574 movl %eax,%esi # esi = rip - 8 QWORD linear (total 16 QWORD)
646 # add esp, 16 ; error code and INT number
668 ## RAX contains qword to print
669 ## RDI contains memory location (screen location) to print it to
728 String1: .asciz "*** INT "
730 Int0String: .asciz "00h Divide by 0 -"
731 Int1String: .asciz "01h Debug exception -"
732 Int2String: .asciz "02h NMI -"
733 Int3String: .asciz "03h Breakpoint -"
734 Int4String: .asciz "04h Overflow -"
735 Int5String: .asciz "05h Bound -"
736 Int6String: .asciz "06h Invalid opcode -"
737 Int7String: .asciz "07h Device not available -"
738 Int8String: .asciz "08h Double fault -"
739 Int9String: .asciz "09h Coprocessor seg overrun (reserved) -"
740 Int10String: .asciz "0Ah Invalid TSS -"
741 Int11String: .asciz "0Bh Segment not present -"
742 Int12String: .asciz "0Ch Stack fault -"
743 Int13String: .asciz "0Dh General protection fault -"
744 Int14String: .asciz "0Eh Page fault -"
745 Int15String: .asciz "0Fh (Intel reserved) -"
746 Int16String: .asciz "10h Floating point error -"
747 Int17String: .asciz "11h Alignment check -"
748 Int18String: .asciz "12h Machine check -"
749 Int19String: .asciz "13h SIMD Floating-Point Exception -"
750 IntUnknownString: .asciz "??h Unknown interrupt -"
752 StringTable: .long Int0String, Int1String, Int2String, Int3String, \
753 Int4String, Int5String, Int6String, Int7String, \
754 Int8String, Int9String, Int10String, Int11String, \
755 Int12String, Int13String, Int14String, Int15String,\
756 Int16String, Int17String, Int18String, Int19String
758 String2: .asciz " HALT!! *** ("
760 StringRax: .asciz "RAX="
761 StringRcx: .asciz " RCX="
762 StringRdx: .asciz " RDX="
763 StringRbx: .asciz "RBX="
764 StringRsp: .asciz " RSP="
765 StringRbp: .asciz " RBP="
766 StringRsi: .asciz "RSI="
767 StringRdi: .asciz " RDI="
768 StringEcode: .asciz " ECODE="
769 StringR8: .asciz "R8 ="
770 StringR9: .asciz " R9 ="
771 StringR10: .asciz " R10="
772 StringR11: .asciz "R11="
773 StringR12: .asciz " R12="
774 StringR13: .asciz " R13="
775 StringR14: .asciz "R14="
776 StringR15: .asciz " R15="
777 StringSs: .asciz " SS ="
778 StringRflags: .asciz "RFLAGS="