1 ;------------------------------------------------------------------------------
3 ;* Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 ;* 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 32-bit protected 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 relative
37 dd commonIdtEntry - $ - 4 ; offset to jump to
51 ; Populate IDT with meaningful offsets for exception handlers...
52 sidt fword ptr [Idtr] ; get fword address of IDT
55 mov ebx, eax ; use bx to copy 15..0 to descriptors
56 shr eax, 16 ; use ax to copy 31..16 to descriptors
57 mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
58 mov esi, [offset Idtr + 2]
61 @@: ; loop through all IDT entries exception handlers and initialize to default handler
62 mov word ptr [edi], bx ; write bits 15..0 of offset
63 mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
64 mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
65 mov word ptr [edi+6], ax ; write bits 31..16 of offset
66 add edi, 8 ; move up to next descriptor
67 add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
68 loop @b ; loop back through again until all descriptors are initialized
70 ;; at this point edi contains the offset of the descriptor for INT 20
71 ;; and bx contains the low 16 bits of the offset of the default handler
72 ;; so initialize all the rest of the descriptors with these two values...
73 ; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
74 ;@@: ; loop through all IDT entries exception handlers and initialize to default handler
75 ; mov word ptr [edi], bx ; write bits 15..0 of offset
76 ; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
77 ; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
78 ; mov word ptr [edi+6], ax ; write bits 31..16 of offset
79 ; add edi, 8 ; move up to next descriptor
80 ; loop @b ; loop back through again until all descriptors are initialized
83 ;; DUMP location of IDT and several of the descriptors
85 ; mov eax, [offset Idtr + 2]
94 ;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
100 ; mov esi, 066666666h
101 ; mov edi, 077777777h
108 mov esi,022000h ; esi = 22000
109 mov eax,[esi+014h] ; eax = [22014]
110 add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
111 mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
113 mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
114 mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
115 add eax,edi ; eax = ImageBase + EntryPoint
116 mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
118 mov bx,word ptr[ebp+6] ; bx = Number of sections
120 mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
122 add ebp,018h ; ebp = Start of 1st Section
125 push esi ; Save Base of EFILDR.C
126 push edi ; Save ImageBase
127 add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
128 add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
129 mov ecx,[ebp+010h] ; ecs = SizeOfRawData
135 pop edi ; Restore ImageBase
136 pop esi ; Restore Base of EFILDR.C
138 add bp,028h ; ebp = ebp + 028h = Pointer to next section record
143 movzx eax, word ptr [Idtr] ; get size of IDT
145 add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
146 push eax ; push memory map location on stack for call to EFILDR...
148 push eax ; push return address (useless, just for stack balance)
151 dd 000401000h ; Offset of EFILDR
156 ; db "**** DEFAULT IDT ENTRY ***",0
160 push 0h ; push error code place holder on the stack
163 ; db 0e9h ; jmp 16 bit reletive
164 ; dd commonIdtEntry - $ - 4 ; offset to jump to
167 push 0h ; push error code place holder on the stack
172 push 0h ; push error code place holder on the stack
177 push 0h ; push error code place holder on the stack
182 push 0h ; push error code place holder on the stack
187 push 0h ; push error code place holder on the stack
192 push 0h ; push error code place holder on the stack
197 push 0h ; push error code place holder on the stack
202 ; Double fault causes an error code to be pushed so no phony push necessary
209 push 0h ; push error code place holder on the stack
214 ; Invalid TSS causes an error code to be pushed so no phony push necessary
221 ; Segment Not Present causes an error code to be pushed so no phony push necessary
228 ; Stack fault causes an error code to be pushed so no phony push necessary
235 ; GP fault causes an error code to be pushed so no phony push necessary
242 ; Page fault causes an error code to be pushed so no phony push necessary
249 push 0h ; push error code place holder on the stack
254 push 0h ; push error code place holder on the stack
259 ; Alignment check causes an error code to be pushed so no phony push necessary
266 push 0h ; push error code place holder on the stack
271 push 0h ; push error code place holder on the stack
277 push 0h ; push error code place holder on the stack
278 ; push xxh ; push vector number
280 db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
288 ;; At this point the stack looks like this:
294 ;; Int num or 0ffh for unknown int num
302 ;; edi <------- ESP, EBP
306 mov esi, offset String1
308 mov eax, [ebp + 32] ;; move Int number into EAX
310 ja PrintDefaultString
311 PrintExceptionString:
312 shl eax, 2 ;; multiply by 4 to get offset from StringTable to actual string address
313 add eax, offset StringTable
317 mov esi, offset IntUnknownString
328 mov esi, offset String2
330 mov eax, [ebp+44] ; CS
333 mov byte ptr [edi], al
335 mov eax, [ebp+40] ; EIP
337 mov esi, offset String3
342 mov esi, offset StringEax ; eax
347 mov esi, offset StringEbx ; ebx
352 mov esi, offset StringEcx ; ecx
357 mov esi, offset StringEdx ; edx
362 mov esi, offset StringEcode ; error code
369 mov esi, offset StringEsp ; esp
374 mov esi, offset StringEbp ; ebp
379 mov esi, offset StringEsi ; esi
384 mov esi, offset StringEdi ; edi
389 mov esi, offset StringEflags ; eflags
423 mov eax, [ebp+40] ; EIP
425 mov esi, eax ; esi = eip - 32 DWORD linear (total 64 DWORD)
450 ; wbinvd ; Ken: this intruction does not support in early than 486 arch
458 add esp, 8 ; error code and INT number
466 mov al, byte ptr [esi]
469 mov byte ptr [edi], al
477 ;; EAX contains dword to print
478 ;; EDI contains memory location (screen location) to print it to
494 mov byte ptr [edi], bl
513 mov word ptr [edi], ax
532 String1 db "*** INT ",0
534 Int0String db "00h Divide by 0 -",0
535 Int1String db "01h Debug exception -",0
536 Int2String db "02h NMI -",0
537 Int3String db "03h Breakpoint -",0
538 Int4String db "04h Overflow -",0
539 Int5String db "05h Bound -",0
540 Int6String db "06h Invalid opcode -",0
541 Int7String db "07h Device not available -",0
542 Int8String db "08h Double fault -",0
543 Int9String db "09h Coprocessor seg overrun (reserved) -",0
544 Int10String db "0Ah Invalid TSS -",0
545 Int11String db "0Bh Segment not present -",0
546 Int12String db "0Ch Stack fault -",0
547 Int13String db "0Dh General protection fault -",0
548 Int14String db "0Eh Page fault -",0
549 Int15String db "0Fh (Intel reserved) -",0
550 Int16String db "10h Floating point error -",0
551 Int17String db "11h Alignment check -",0
552 Int18String db "12h Machine check -",0
553 Int19String db "13h SIMD Floating-Point Exception -",0
554 IntUnknownString db "??h Unknown interrupt -",0
556 StringTable dd offset Int0String, offset Int1String, offset Int2String, offset Int3String,
557 offset Int4String, offset Int5String, offset Int6String, offset Int7String,
558 offset Int8String, offset Int9String, offset Int10String, offset Int11String,
559 offset Int12String, offset Int13String, offset Int14String, offset Int15String,
560 offset Int16String, offset Int17String, offset Int18String, offset Int19String
562 String2 db " HALT!! *** (",0
564 StringEax db "EAX=",0
565 StringEbx db " EBX=",0
566 StringEcx db " ECX=",0
567 StringEdx db " EDX=",0
568 StringEcode db " ECODE=",0
569 StringEsp db "ESP=",0
570 StringEbp db " EBP=",0
571 StringEsi db " ESI=",0
572 StringEdi db " EDI=",0
573 StringEflags db " EFLAGS=",0