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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 DEFAULT_HANDLER_SIZE EQU INT1 - INT0
30 JmpCommonIdtEntry macro
31 ; jmp commonIdtEntry - this must be hand coded to keep the assembler from
32 ; using a 8 bit reletive jump when the entries are
33 ; within 255 bytes of the common entry. This must
34 ; be done to maintain the consistency of the size
36 db 0e9h ; jmp 16 bit reletive
37 dd commonIdtEntry - $ - 4 ; offset to jump to
43 mov esp,0001fffe8h ; make final stack aligned
45 ; set OSFXSR and OSXMMEXCPT because some code will use XMM register
59 ; Populate IDT with meaningful offsets for exception handlers...
61 sidt fword ptr [eax] ; get fword address of IDT
64 mov ebx, eax ; use bx to copy 15..0 to descriptors
65 shr eax, 16 ; use ax to copy 31..16 to descriptors
66 ; 63..32 of descriptors is 0
67 mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
68 mov esi, [offset Idtr + 2]
71 @@: ; loop through all IDT entries exception handlers and initialize to default handler
72 mov word ptr [edi], bx ; write bits 15..0 of offset
73 mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
74 mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
75 mov word ptr [edi+6], ax ; write bits 31..16 of offset
76 mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
77 add edi, 16 ; move up to next descriptor
78 add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
79 loop @b ; loop back through again until all descriptors are initialized
81 ;; at this point edi contains the offset of the descriptor for INT 20
82 ;; and bx contains the low 16 bits of the offset of the default handler
83 ;; so initialize all the rest of the descriptors with these two values...
84 ; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
85 ;@@: ; loop through all IDT entries exception handlers and initialize to default handler
86 ; mov word ptr [edi], bx ; write bits 15..0 of offset
87 ; mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
88 ; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
89 ; mov word ptr [edi+6], ax ; write bits 31..16 of offset
90 ; mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
91 ; add edi, 16 ; move up to next descriptor
92 ; loop @b ; loop back through again until all descriptors are initialized
95 ;; DUMP location of IDT and several of the descriptors
97 ; mov eax, [offset Idtr + 2]
106 ;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
107 ; mov eax, 011111111h
108 ; mov ebx, 022222222h
109 ; mov ecx, 033333333h
110 ; mov edx, 044444444h
111 ; mov ebp, 055555555h
112 ; mov esi, 066666666h
113 ; mov edi, 077777777h
119 mov esi,022000h ; esi = 22000
120 mov eax,[esi+014h] ; eax = [22014]
121 add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
122 mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
124 mov edi,[ebp+030h] ; edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore)
125 mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
126 add eax,edi ; eax = ImageBase + EntryPoint
127 mov ebx, offset EfiLdrOffset
128 mov dword ptr [ebx],eax ; Modify far jump instruction for correct entry point
130 mov bx,word ptr[ebp+6] ; bx = Number of sections
132 mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
134 add ebp,018h ; ebp = Start of 1st Section
137 push esi ; Save Base of EFILDR.C
138 push edi ; Save ImageBase
139 add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
140 add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
141 mov ecx,[ebp+010h] ; ecs = SizeOfRawData
147 pop edi ; Restore ImageBase
148 pop esi ; Restore Base of EFILDR.C
150 add bp,028h ; ebp = ebp + 028h = Pointer to next section record
159 movzx eax, word ptr [edx] ; get size of IDT
163 add eax, dword ptr [edx + 2] ; add to base of IDT to get location of memory map...
165 mov ecx, eax ; put argument to RCX
171 dd 000401000h ; Offset of EFILDR
179 ; db "**** DEFAULT IDT ENTRY ***",0
183 push 0h ; push error code place holder on the stack
186 ; db 0e9h ; jmp 16 bit reletive
187 ; dd commonIdtEntry - $ - 4 ; offset to jump to
190 push 0h ; push error code place holder on the stack
195 push 0h ; push error code place holder on the stack
200 push 0h ; push error code place holder on the stack
205 push 0h ; push error code place holder on the stack
210 push 0h ; push error code place holder on the stack
215 push 0h ; push error code place holder on the stack
220 push 0h ; push error code place holder on the stack
225 ; Double fault causes an error code to be pushed so no phony push necessary
232 push 0h ; 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 push 0h ; push error code place holder on the stack
277 push 0h ; push error code place holder on the stack
282 ; Alignment check causes an error code to be pushed so no phony push necessary
289 push 0h ; push error code place holder on the stack
294 push 0h ; push error code place holder on the stack
300 push 0h ; push error code place holder on the stack
301 ; push xxh ; push vector number
303 db ( $ - 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
373 mov esi, offset String1
376 mov eax, [ebp + 16*8] ;; move Int number into RAX
379 ja PrintDefaultString
380 PrintExceptionString:
381 shl eax, 3 ;; multiply by 8 to get offset from StringTable to actual string address
382 add eax, offset StringTable
386 mov esi, offset IntUnknownString
397 mov esi, offset String2
400 mov eax, [ebp+19*8] ; CS
403 mov byte ptr [edi], al
406 mov eax, [ebp+18*8] ; RIP
408 mov esi, offset String3
413 mov esi, offset StringRax ; rax
419 mov esi, offset StringRcx ; rcx
425 mov esi, offset StringRdx ; rdx
433 mov esi, offset StringRbx ; rbx
439 mov esi, offset StringRsp ; rsp
445 mov esi, offset StringRbp ; rbp
453 mov esi, offset StringRsi ; rsi
459 mov esi, offset StringRdi ; rdi
465 mov esi, offset StringEcode ; error code
473 mov esi, offset StringR8 ; r8
479 mov esi, offset StringR9 ; r9
485 mov esi, offset StringR10 ; r10
493 mov esi, offset StringR11 ; r11
499 mov esi, offset StringR12 ; r12
505 mov esi, offset StringR13 ; r13
513 mov esi, offset StringR14 ; r14
519 mov esi, offset StringR15 ; r15
525 mov esi, offset StringSs ; ss
533 mov esi, offset StringRflags ; rflags
571 mov eax, [ebp+18*8] ; RIP
574 mov esi, eax ; esi = rip - 8 QWORD linear (total 16 QWORD)
646 ; add esp, 16 ; error code and INT number
655 mov al, byte ptr [esi]
658 mov byte ptr [edi], al
668 ;; RAX contains qword to print
669 ;; RDI contains memory location (screen location) to print it to
690 mov byte ptr [edi], bl
709 mov word ptr [edi], ax
728 String1 db "*** INT ",0
730 Int0String db "00h Divide by 0 -",0
731 Int1String db "01h Debug exception -",0
732 Int2String db "02h NMI -",0
733 Int3String db "03h Breakpoint -",0
734 Int4String db "04h Overflow -",0
735 Int5String db "05h Bound -",0
736 Int6String db "06h Invalid opcode -",0
737 Int7String db "07h Device not available -",0
738 Int8String db "08h Double fault -",0
739 Int9String db "09h Coprocessor seg overrun (reserved) -",0
740 Int10String db "0Ah Invalid TSS -",0
741 Int11String db "0Bh Segment not present -",0
742 Int12String db "0Ch Stack fault -",0
743 Int13String db "0Dh General protection fault -",0
744 Int14String db "0Eh Page fault -",0
745 Int15String db "0Fh (Intel reserved) -",0
746 Int16String db "10h Floating point error -",0
747 Int17String db "11h Alignment check -",0
748 Int18String db "12h Machine check -",0
749 Int19String db "13h SIMD Floating-Point Exception -",0
750 IntUnknownString db "??h Unknown interrupt -",0
752 StringTable dq offset Int0String, offset Int1String, offset Int2String, offset Int3String,
753 offset Int4String, offset Int5String, offset Int6String, offset Int7String,
754 offset Int8String, offset Int9String, offset Int10String, offset Int11String,
755 offset Int12String, offset Int13String, offset Int14String, offset Int15String,
756 offset Int16String, offset Int17String, offset Int18String, offset Int19String
758 String2 db " HALT!! *** (",0
760 StringRax db "RAX=",0
761 StringRcx db " RCX=",0
762 StringRdx db " RDX=",0
763 StringRbx db "RBX=",0
764 StringRsp db " RSP=",0
765 StringRbp db " RBP=",0
766 StringRsi db "RSI=",0
767 StringRdi db " RDI=",0
768 StringEcode db " ECODE=",0
770 StringR9 db " R9 =",0
771 StringR10 db " R10=",0
772 StringR11 db "R11=",0
773 StringR12 db " R12=",0
774 StringR13 db " R13=",0
775 StringR14 db "R14=",0
776 StringR15 db " R15=",0
777 StringSs db " SS =",0
778 StringRflags db "RFLAGS=",0