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