1 ;------------------------------------------------------------------------------
3 ;* Copyright (c) 2006 - 2011, 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
42 mov ax,bx ; flat data descriptor in BX
52 ; Populate IDT with meaningful offsets for exception handlers...
53 sidt fword ptr [Idtr] ; get fword address of IDT
56 mov ebx, eax ; use bx to copy 15..0 to descriptors
57 shr eax, 16 ; use ax to copy 31..16 to descriptors
58 mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
59 mov esi, [offset Idtr + 2]
62 @@: ; loop through all IDT entries exception handlers and initialize to default handler
63 mov word ptr [edi], bx ; write bits 15..0 of offset
64 mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
65 mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
66 mov word ptr [edi+6], ax ; write bits 31..16 of offset
67 add edi, 8 ; move up to next descriptor
68 add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
69 loop @b ; loop back through again until all descriptors are initialized
71 ;; at this point edi contains the offset of the descriptor for INT 20
72 ;; and bx contains the low 16 bits of the offset of the default handler
73 ;; so initialize all the rest of the descriptors with these two values...
74 ; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
75 ;@@: ; loop through all IDT entries exception handlers and initialize to default handler
76 ; mov word ptr [edi], bx ; write bits 15..0 of offset
77 ; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
78 ; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
79 ; mov word ptr [edi+6], ax ; write bits 31..16 of offset
80 ; add edi, 8 ; move up to next descriptor
81 ; loop @b ; loop back through again until all descriptors are initialized
84 ;; DUMP location of IDT and several of the descriptors
86 ; mov eax, [offset Idtr + 2]
95 ;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
100 ; mov ebp, 055555555h
101 ; mov esi, 066666666h
102 ; mov edi, 077777777h
109 mov esi,022000h ; esi = 22000
110 mov eax,[esi+014h] ; eax = [22014]
111 add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
112 mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
114 mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
115 mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
116 add eax,edi ; eax = ImageBase + EntryPoint
117 mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
119 mov bx,word ptr[ebp+6] ; bx = Number of sections
121 mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
123 add ebp,018h ; ebp = Start of 1st Section
126 push esi ; Save Base of EFILDR.C
127 push edi ; Save ImageBase
128 add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
129 add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
130 mov ecx,[ebp+010h] ; ecs = SizeOfRawData
136 pop edi ; Restore ImageBase
137 pop esi ; Restore Base of EFILDR.C
139 add bp,028h ; ebp = ebp + 028h = Pointer to next section record
144 movzx eax, word ptr [Idtr] ; get size of IDT
146 add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
147 push eax ; push memory map location on stack for call to EFILDR...
149 push eax ; push return address (useless, just for stack balance)
152 dd 000401000h ; Offset of EFILDR
157 ; db "**** DEFAULT IDT ENTRY ***",0
161 push 0h ; push error code place holder on the stack
164 ; db 0e9h ; jmp 16 bit reletive
165 ; dd commonIdtEntry - $ - 4 ; offset to jump to
168 push 0h ; push error code place holder on the stack
173 push 0h ; push error code place holder on the stack
178 push 0h ; push error code place holder on the stack
183 push 0h ; push error code place holder on the stack
188 push 0h ; push error code place holder on the stack
193 push 0h ; push error code place holder on the stack
198 push 0h ; push error code place holder on the stack
203 ; Double fault causes an error code to be pushed so no phony push necessary
210 push 0h ; push error code place holder on the stack
215 ; Invalid TSS causes an error code to be pushed so no phony push necessary
222 ; Segment Not Present causes an error code to be pushed so no phony push necessary
229 ; Stack fault causes an error code to be pushed so no phony push necessary
236 ; GP fault causes an error code to be pushed so no phony push necessary
243 ; Page fault causes an error code to be pushed so no phony push necessary
250 push 0h ; push error code place holder on the stack
255 push 0h ; push error code place holder on the stack
260 ; Alignment check causes an error code to be pushed so no phony push necessary
267 push 0h ; push error code place holder on the stack
272 push 0h ; push error code place holder on the stack
278 push 0h ; push error code place holder on the stack
279 ; push xxh ; push vector number
281 db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
289 ;; At this point the stack looks like this:
295 ;; Int num or 0ffh for unknown int num
303 ;; edi <------- ESP, EBP
307 mov esi, offset String1
309 mov eax, [ebp + 32] ;; move Int number into EAX
311 ja PrintDefaultString
312 PrintExceptionString:
313 shl eax, 2 ;; multiply by 4 to get offset from StringTable to actual string address
314 add eax, offset StringTable
318 mov esi, offset IntUnknownString
329 mov esi, offset String2
331 mov eax, [ebp+44] ; CS
334 mov byte ptr [edi], al
336 mov eax, [ebp+40] ; EIP
338 mov esi, offset String3
343 mov esi, offset StringEax ; eax
348 mov esi, offset StringEbx ; ebx
353 mov esi, offset StringEcx ; ecx
358 mov esi, offset StringEdx ; edx
363 mov esi, offset StringEcode ; error code
370 mov esi, offset StringEsp ; esp
375 mov esi, offset StringEbp ; ebp
380 mov esi, offset StringEsi ; esi
385 mov esi, offset StringEdi ; edi
390 mov esi, offset StringEflags ; eflags
424 mov eax, [ebp+40] ; EIP
426 mov esi, eax ; esi = eip - 32 DWORD linear (total 64 DWORD)
451 ; wbinvd ; Ken: this intruction does not support in early than 486 arch
459 add esp, 8 ; error code and INT number
467 mov al, byte ptr [esi]
470 mov byte ptr [edi], al
478 ;; EAX contains dword to print
479 ;; EDI contains memory location (screen location) to print it to
495 mov byte ptr [edi], bl
514 mov word ptr [edi], ax
533 String1 db "*** INT ",0
535 Int0String db "00h Divide by 0 -",0
536 Int1String db "01h Debug exception -",0
537 Int2String db "02h NMI -",0
538 Int3String db "03h Breakpoint -",0
539 Int4String db "04h Overflow -",0
540 Int5String db "05h Bound -",0
541 Int6String db "06h Invalid opcode -",0
542 Int7String db "07h Device not available -",0
543 Int8String db "08h Double fault -",0
544 Int9String db "09h Coprocessor seg overrun (reserved) -",0
545 Int10String db "0Ah Invalid TSS -",0
546 Int11String db "0Bh Segment not present -",0
547 Int12String db "0Ch Stack fault -",0
548 Int13String db "0Dh General protection fault -",0
549 Int14String db "0Eh Page fault -",0
550 Int15String db "0Fh (Intel reserved) -",0
551 Int16String db "10h Floating point error -",0
552 Int17String db "11h Alignment check -",0
553 Int18String db "12h Machine check -",0
554 Int19String db "13h SIMD Floating-Point Exception -",0
555 IntUnknownString db "??h Unknown interrupt -",0
557 StringTable dd offset Int0String, offset Int1String, offset Int2String, offset Int3String,
558 offset Int4String, offset Int5String, offset Int6String, offset Int7String,
559 offset Int8String, offset Int9String, offset Int10String, offset Int11String,
560 offset Int12String, offset Int13String, offset Int14String, offset Int15String,
561 offset Int16String, offset Int17String, offset Int18String, offset Int19String
563 String2 db " HALT!! *** (",0
565 StringEax db "EAX=",0
566 StringEbx db " EBX=",0
567 StringEcx db " ECX=",0
568 StringEdx db " EDX=",0
569 StringEcode db " ECODE=",0
570 StringEsp db "ESP=",0
571 StringEbp db " EBP=",0
572 StringEsi db " ESI=",0
573 StringEdi db " EDI=",0
574 StringEflags db " EFLAGS=",0