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 32-bit protected mode.
20 ##############################################################################
28 .equ DEFAULT_HANDLER_SIZE, INT1 - INT0
30 .macro jmpCommonIdtEntry
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 .byte 0xe9 # jmp 16 bit relative
37 .long commonIdtEntry - . - 4 # A problem
46 movl $0x001ffff0, %esp
50 # Populate IDT with meaningful offsets for exception handlers...
54 movl %eax, %ebx # use bx to copy 15..0 to descriptors
55 shrl $16, %eax # use ax to copy 31..16 to descriptors
56 movl $0x78, %ecx # 78h IDT entries to initialize with unique entry points (exceptions)
60 LOOP_1: # loop through all IDT entries exception handlers and initialize to default handler
61 movw %bx, (%edi) # write bits 15..0 of offset
62 movw $0x20, 2(%edi) # SYS_CODE_SEL from GDT
63 movw $(0x0e00 | 0x8000), 4(%edi) # type = 386 interrupt gate, present
64 movw %ax, 6(%edi) # write bits 31..16 of offset
65 addl $8, %edi # move up to next descriptor
66 addw DEFAULT_HANDLER_SIZE, %bx # move to next entry point
67 loopl LOOP_1 # loop back through again until all descriptors are initialized
69 ## at this point edi contains the offset of the descriptor for INT 20
70 ## and bx contains the low 16 bits of the offset of the default handler
71 ## so initialize all the rest of the descriptors with these two values...
72 # mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
73 #@@: ; loop through all IDT entries exception handlers and initialize to default handler
74 # mov word ptr [edi], bx ; write bits 15..0 of offset
75 # mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
76 # mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
77 # mov word ptr [edi+6], ax ; write bits 31..16 of offset
78 # add edi, 8 ; move up to next descriptor
79 # loop @b ; loop back through again until all descriptors are initialized
82 ## DUMP location of IDT and several of the descriptors
84 # mov eax, [offset Idtr + 2]
93 ## just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
100 # mov edi, 077777777h
107 movl $0x22000, %esi # esi = 22000
108 movl 0x14(%esi), %eax # eax = [22014]
109 addl %eax, %esi # esi = 22000 + [22014] = Base of EFILDR.C
110 movl 0x3c(%esi), %ebp # ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
112 movl 0x34(%ebp), %edi # edi = [[22000 + [22014] + 3c] + 30] = ImageBase
113 movl 0x28(%ebp), %eax # eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
114 addl %edi, %eax # eax = ImageBase + EntryPoint
115 movl %eax, EfiLdrOffset # Modify far jump instruction for correct entry point
117 movw 6(%ebp), %bx # bx = Number of sections
119 movw 0x14(%ebp), %ax # ax = Optional Header Size
121 addl $0x18, %ebp # ebp = Start of 1st Section
124 pushl %esi # Save Base of EFILDR.C
125 pushl %edi # Save ImageBase
126 addl 0x14(%ebp), %esi # esi = Base of EFILDR.C + PointerToRawData
127 addl 0x0c(%ebp), %edi # edi = ImageBase + VirtualAddress
128 movl 0x10(%ebp), %ecx # ecs = SizeOfRawData
135 popl %edi # Restore ImageBase
136 popl %esi # Restore Base of EFILDR.C
138 addw $0x28, %bp # ebp = ebp + 028h = Pointer to next section record
143 movzwl Idtr, %eax # get size of IDT
145 addl Idtr + 2, %eax # add to base of IDT to get location of memory map...
146 pushl %eax # push memory map location on stack for call to EFILDR...
148 pushl %eax # push return address (useless, just for stack balance)
151 .long 0x00401000 # Offset of EFILDR
156 # db "**** DEFAULT IDT ENTRY ***",0
160 pushl $0x0 # push error code place holder on the stack
163 # db 0e9h ; jmp 16 bit reletive
164 # dd commonIdtEntry - $ - 4 ; offset to jump to
167 pushl $0x0 # push error code place holder on the stack
172 pushl $0x0 # push error code place holder on the stack
177 pushl $0x0 # push error code place holder on the stack
182 pushl $0x0 # push error code place holder on the stack
187 pushl $0x0 # push error code place holder on the stack
192 pushl $0x0 # push error code place holder on the stack
197 pushl $0x0 # push error code place holder on the stack
202 # Double fault causes an error code to be pushed so no phony push necessary
209 pushl $0x0 # 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 pushl $0x0 # push error code place holder on the stack
254 pushl $0x0 # push error code place holder on the stack
259 # Alignment check causes an error code to be pushed so no phony push necessary
266 pushl $0x0 # push error code place holder on the stack
271 pushl $0x0 # push error code place holder on the stack
277 pushl $0x0 # push error code place holder on the stack
278 # push $0xxx # push vector number
280 .long ( . - 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
308 movl 32(%ebp), %eax ## move Int number into EAX
310 ja PrintDefaultString
311 PrintExceptionString:
312 shll $2, %eax ## multiply by 4 to get offset from StringTable to actual string address
313 addl StringTable, %eax
317 movl IntUnknownString, %esi
330 movl 44(%ebp), %eax # CS
335 movl 40(%ebp), %eax # EIP
342 movl StringEax, %esi # eax
347 movl StringEbx, %esi # ebx
352 movl StringEcx, %esi # ecx
357 movl StringEdx, %esi # edx
362 movl StringEcode, %esi # error code
369 movl StringEsp, %esi # esp
374 movl StringEbp, %esi # ebp
379 movl StringEsi, %esi # esi
384 movl StringEdi, %esi # edi
389 movl StringEflags, %esi # eflags
423 movl 40(%ebp), %eax # EIP
425 movl %eax, %esi # esi = eip - 32 DWORD linear (total 64 DWORD)
450 # wbinvd ; this intruction does not support in early than 486 arch
458 addl $8, %esp # error code and INT number
477 ## EAX contains dword to print
478 ## EDI contains memory location (screen location) to print it to
532 String1: .asciz "*** INT "
534 Int0String: .asciz "00h Divide by 0 -"
535 Int1String: .asciz "01h Debug exception -"
536 Int2String: .asciz "02h NMI -"
537 Int3String: .asciz "03h Breakpoint -"
538 Int4String: .asciz "04h Overflow -"
539 Int5String: .asciz "05h Bound -"
540 Int6String: .asciz "06h Invalid opcode -"
541 Int7String: .asciz "07h Device not available -"
542 Int8String: .asciz "08h Double fault -"
543 Int9String: .asciz "09h Coprocessor seg overrun (reserved) -"
544 Int10String: .asciz "0Ah Invalid TSS -"
545 Int11String: .asciz "0Bh Segment not present -"
546 Int12String: .asciz "0Ch Stack fault -"
547 Int13String: .asciz "0Dh General protection fault -"
548 Int14String: .asciz "0Eh Page fault -"
549 Int15String: .asciz "0Fh (Intel reserved) -"
550 Int16String: .asciz "10h Floating point error -"
551 Int17String: .asciz "11h Alignment check -"
552 Int18String: .asciz "12h Machine check -"
553 Int19String: .asciz "13h SIMD Floating-Point Exception -"
554 IntUnknownString: .asciz "??h Unknown interrupt -"
556 StringTable: .long Int0String, Int1String, Int2String, Int3String, \
557 Int4String, Int5String, Int6String, Int7String, \
558 Int8String, Int9String, Int10String, Int11String, \
559 Int12String, Int13String, Int14String, Int15String,\
560 Int16String, Int17String, Int18String, Int19String
562 String2: .asciz " HALT!! *** ("
564 StringEax: .asciz "EAX="
565 StringEbx: .asciz "EBX="
566 StringEcx: .asciz "ECX="
567 StringEdx: .asciz "EDX="
568 StringEcode: .asciz "ECODE="
569 StringEsp: .asciz "ESP="
570 StringEbp: .asciz "EBP="
571 StringEsi: .asciz "ESI="
572 StringEdi: .asciz "EDI="
573 StringEflags: .asciz "EFLAGS="