mirror of https://github.com/acidanthera/audk.git
582 lines
17 KiB
NASM
582 lines
17 KiB
NASM
;------------------------------------------------------------------------------
|
|
;*
|
|
;* Copyright 2006, Intel Corporation
|
|
;* All rights reserved. This program and the accompanying materials
|
|
;* are licensed and made available under the terms and conditions of the BSD License
|
|
;* which accompanies this distribution. The full text of the license may be found at
|
|
;* http://opensource.org/licenses/bsd-license.php
|
|
;*
|
|
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
;*
|
|
;* efi32.asm
|
|
;*
|
|
;* Abstract:
|
|
;*
|
|
;------------------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Now in 32-bit protected mode.
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
.486
|
|
.model flat
|
|
.stack
|
|
.code
|
|
org 21000h
|
|
|
|
DEFAULT_HANDLER_SIZE EQU INT1 - INT0
|
|
|
|
JmpCommonIdtEntry macro
|
|
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
|
; using a 8 bit reletive jump when the entries are
|
|
; within 255 bytes of the common entry. This must
|
|
; be done to maintain the consistency of the size
|
|
; of entry points...
|
|
db 0e9h ; jmp 16 bit relative
|
|
dd commonIdtEntry - $ - 4 ; offset to jump to
|
|
endm
|
|
|
|
|
|
Start:
|
|
mov ds,ax
|
|
mov es,ax
|
|
mov fs,ax
|
|
mov gs,ax
|
|
mov ss,ax
|
|
mov esp,0001ffff0h
|
|
|
|
call ClearScreen
|
|
|
|
; Populate IDT with meaningful offsets for exception handlers...
|
|
sidt fword ptr [Idtr] ; get fword address of IDT
|
|
|
|
mov eax, offset Halt
|
|
mov ebx, eax ; use bx to copy 15..0 to descriptors
|
|
shr eax, 16 ; use ax to copy 31..16 to descriptors
|
|
mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
|
|
mov esi, [offset Idtr + 2]
|
|
mov edi, [esi]
|
|
|
|
@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
|
mov word ptr [edi], bx ; write bits 15..0 of offset
|
|
mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
|
|
mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
|
mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
|
add edi, 8 ; move up to next descriptor
|
|
add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
|
|
loop @b ; loop back through again until all descriptors are initialized
|
|
|
|
;; at this point edi contains the offset of the descriptor for INT 20
|
|
;; and bx contains the low 16 bits of the offset of the default handler
|
|
;; so initialize all the rest of the descriptors with these two values...
|
|
; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
|
|
;@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
|
; mov word ptr [edi], bx ; write bits 15..0 of offset
|
|
; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
|
|
; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
|
; mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
|
; add edi, 8 ; move up to next descriptor
|
|
; loop @b ; loop back through again until all descriptors are initialized
|
|
|
|
|
|
;; DUMP location of IDT and several of the descriptors
|
|
; mov ecx, 8
|
|
; mov eax, [offset Idtr + 2]
|
|
; mov eax, [eax]
|
|
; mov edi, 0b8000h
|
|
; call PrintDword
|
|
; mov esi, eax
|
|
; mov edi, 0b80a0h
|
|
; jmp OuterLoop
|
|
|
|
;;
|
|
;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
|
|
; mov eax, 011111111h
|
|
; mov ebx, 022222222h
|
|
; mov ecx, 033333333h
|
|
; mov edx, 044444444h
|
|
; mov ebp, 055555555h
|
|
; mov esi, 066666666h
|
|
; mov edi, 077777777h
|
|
; push 011111111h
|
|
; push 022222222h
|
|
; push 033333333h
|
|
; int 119
|
|
|
|
|
|
mov esi,022000h ; esi = 22000
|
|
mov eax,[esi+014h] ; eax = [22014]
|
|
add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
|
|
mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
|
|
add ebp,esi
|
|
mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
|
|
mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
|
|
add eax,edi ; eax = ImageBase + EntryPoint
|
|
mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
|
|
|
|
mov bx,word ptr[ebp+6] ; bx = Number of sections
|
|
xor eax,eax
|
|
mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
|
|
add ebp,eax
|
|
add ebp,018h ; ebp = Start of 1st Section
|
|
|
|
SectionLoop:
|
|
push esi ; Save Base of EFILDR.C
|
|
push edi ; Save ImageBase
|
|
add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
|
|
add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
|
|
mov ecx,[ebp+010h] ; ecs = SizeOfRawData
|
|
|
|
cld
|
|
shr ecx,2
|
|
rep movsd
|
|
|
|
pop edi ; Restore ImageBase
|
|
pop esi ; Restore Base of EFILDR.C
|
|
|
|
add bp,028h ; ebp = ebp + 028h = Pointer to next section record
|
|
dec bx
|
|
cmp bx,0
|
|
jne SectionLoop
|
|
|
|
movzx eax, word ptr [Idtr] ; get size of IDT
|
|
inc eax
|
|
add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
|
|
push eax ; push memory map location on stack for call to EFILDR...
|
|
|
|
push eax ; push return address (useless, just for stack balance)
|
|
db 0b8h
|
|
EfiLdrOffset:
|
|
dd 000401000h ; Offset of EFILDR
|
|
; mov eax, 401000h
|
|
push eax
|
|
ret
|
|
|
|
; db "**** DEFAULT IDT ENTRY ***",0
|
|
align 02h
|
|
Halt:
|
|
INT0:
|
|
push 0h ; push error code place holder on the stack
|
|
push 0h
|
|
JmpCommonIdtEntry
|
|
; db 0e9h ; jmp 16 bit reletive
|
|
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
|
|
|
INT1:
|
|
push 0h ; push error code place holder on the stack
|
|
push 1h
|
|
JmpCommonIdtEntry
|
|
|
|
INT2:
|
|
push 0h ; push error code place holder on the stack
|
|
push 2h
|
|
JmpCommonIdtEntry
|
|
|
|
INT3:
|
|
push 0h ; push error code place holder on the stack
|
|
push 3h
|
|
JmpCommonIdtEntry
|
|
|
|
INT4:
|
|
push 0h ; push error code place holder on the stack
|
|
push 4h
|
|
JmpCommonIdtEntry
|
|
|
|
INT5:
|
|
push 0h ; push error code place holder on the stack
|
|
push 5h
|
|
JmpCommonIdtEntry
|
|
|
|
INT6:
|
|
push 0h ; push error code place holder on the stack
|
|
push 6h
|
|
JmpCommonIdtEntry
|
|
|
|
INT7:
|
|
push 0h ; push error code place holder on the stack
|
|
push 7h
|
|
JmpCommonIdtEntry
|
|
|
|
INT8:
|
|
; Double fault causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 8h
|
|
JmpCommonIdtEntry
|
|
|
|
INT9:
|
|
push 0h ; push error code place holder on the stack
|
|
push 9h
|
|
JmpCommonIdtEntry
|
|
|
|
INT10:
|
|
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 10
|
|
JmpCommonIdtEntry
|
|
|
|
INT11:
|
|
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 11
|
|
JmpCommonIdtEntry
|
|
|
|
INT12:
|
|
; Stack fault causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 12
|
|
JmpCommonIdtEntry
|
|
|
|
INT13:
|
|
; GP fault causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 13
|
|
JmpCommonIdtEntry
|
|
|
|
INT14:
|
|
; Page fault causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 14
|
|
JmpCommonIdtEntry
|
|
|
|
INT15:
|
|
push 0h ; push error code place holder on the stack
|
|
push 15
|
|
JmpCommonIdtEntry
|
|
|
|
INT16:
|
|
push 0h ; push error code place holder on the stack
|
|
push 16
|
|
JmpCommonIdtEntry
|
|
|
|
INT17:
|
|
; Alignment check causes an error code to be pushed so no phony push necessary
|
|
nop
|
|
nop
|
|
push 17
|
|
JmpCommonIdtEntry
|
|
|
|
INT18:
|
|
push 0h ; push error code place holder on the stack
|
|
push 18
|
|
JmpCommonIdtEntry
|
|
|
|
INT19:
|
|
push 0h ; push error code place holder on the stack
|
|
push 19
|
|
JmpCommonIdtEntry
|
|
|
|
INTUnknown:
|
|
REPEAT (78h - 20)
|
|
push 0h ; push error code place holder on the stack
|
|
; push xxh ; push vector number
|
|
db 06ah
|
|
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
|
JmpCommonIdtEntry
|
|
ENDM
|
|
|
|
commonIdtEntry:
|
|
pushad
|
|
mov ebp, esp
|
|
;;
|
|
;; At this point the stack looks like this:
|
|
;;
|
|
;; eflags
|
|
;; Calling CS
|
|
;; Calling EIP
|
|
;; Error code or 0
|
|
;; Int num or 0ffh for unknown int num
|
|
;; eax
|
|
;; ecx
|
|
;; edx
|
|
;; ebx
|
|
;; esp
|
|
;; ebp
|
|
;; esi
|
|
;; edi <------- ESP, EBP
|
|
;;
|
|
|
|
call ClearScreen
|
|
mov esi, offset String1
|
|
call PrintString
|
|
mov eax, [ebp + 32] ;; move Int number into EAX
|
|
cmp eax, 19
|
|
ja PrintDefaultString
|
|
PrintExceptionString:
|
|
shl eax, 2 ;; multiply by 4 to get offset from StringTable to actual string address
|
|
add eax, offset StringTable
|
|
mov esi, [eax]
|
|
jmp PrintTheString
|
|
PrintDefaultString:
|
|
mov esi, offset IntUnknownString
|
|
; patch Int number
|
|
mov edx, eax
|
|
call A2C
|
|
mov [esi + 1], al
|
|
mov eax, edx
|
|
shr eax, 4
|
|
call A2C
|
|
mov [esi], al
|
|
PrintTheString:
|
|
call PrintString
|
|
mov esi, offset String2
|
|
call PrintString
|
|
mov eax, [ebp+44] ; CS
|
|
call PrintDword
|
|
mov al, ':'
|
|
mov byte ptr [edi], al
|
|
add edi, 2
|
|
mov eax, [ebp+40] ; EIP
|
|
call PrintDword
|
|
mov esi, offset String3
|
|
call PrintString
|
|
|
|
mov edi, 0b8140h
|
|
|
|
mov esi, offset StringEax ; eax
|
|
call PrintString
|
|
mov eax, [ebp+28]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEbx ; ebx
|
|
call PrintString
|
|
mov eax, [ebp+16]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEcx ; ecx
|
|
call PrintString
|
|
mov eax, [ebp+24]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEdx ; edx
|
|
call PrintString
|
|
mov eax, [ebp+20]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEcode ; error code
|
|
call PrintString
|
|
mov eax, [ebp+36]
|
|
call PrintDword
|
|
|
|
mov edi, 0b81e0h
|
|
|
|
mov esi, offset StringEsp ; esp
|
|
call PrintString
|
|
mov eax, [ebp+12]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEbp ; ebp
|
|
call PrintString
|
|
mov eax, [ebp+8]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEsi ; esi
|
|
call PrintString
|
|
mov eax, [ebp+4]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEdi ; edi
|
|
call PrintString
|
|
mov eax, [ebp]
|
|
call PrintDword
|
|
|
|
mov esi, offset StringEflags ; eflags
|
|
call PrintString
|
|
mov eax, [ebp+48]
|
|
call PrintDword
|
|
|
|
mov edi, 0b8320h
|
|
|
|
mov esi, ebp
|
|
add esi, 52
|
|
mov ecx, 8
|
|
|
|
|
|
OuterLoop:
|
|
push ecx
|
|
mov ecx, 8
|
|
mov edx, edi
|
|
|
|
InnerLoop:
|
|
mov eax, [esi]
|
|
call PrintDword
|
|
add esi, 4
|
|
mov al, ' '
|
|
mov [edi], al
|
|
add edi, 2
|
|
loop InnerLoop
|
|
|
|
pop ecx
|
|
add edx, 0a0h
|
|
mov edi, edx
|
|
loop OuterLoop
|
|
|
|
|
|
mov edi, 0b8960h
|
|
|
|
mov eax, [ebp+40] ; EIP
|
|
sub eax, 32 * 4
|
|
mov esi, eax ; esi = eip - 32 DWORD linear (total 64 DWORD)
|
|
|
|
mov ecx, 8
|
|
|
|
OuterLoop1:
|
|
push ecx
|
|
mov ecx, 8
|
|
mov edx, edi
|
|
|
|
InnerLoop1:
|
|
mov eax, [esi]
|
|
call PrintDword
|
|
add esi, 4
|
|
mov al, ' '
|
|
mov [edi], al
|
|
add edi, 2
|
|
loop InnerLoop1
|
|
|
|
pop ecx
|
|
add edx, 0a0h
|
|
mov edi, edx
|
|
loop OuterLoop1
|
|
|
|
|
|
|
|
; wbinvd ; Ken: this intruction does not support in early than 486 arch
|
|
@@:
|
|
jmp @b
|
|
;
|
|
; return
|
|
;
|
|
mov esp, ebp
|
|
popad
|
|
add esp, 8 ; error code and INT number
|
|
|
|
iretd
|
|
|
|
|
|
PrintString:
|
|
push eax
|
|
@@:
|
|
mov al, byte ptr [esi]
|
|
cmp al, 0
|
|
je @f
|
|
mov byte ptr [edi], al
|
|
inc esi
|
|
add edi, 2
|
|
jmp @b
|
|
@@:
|
|
pop eax
|
|
ret
|
|
|
|
;; EAX contains dword to print
|
|
;; EDI contains memory location (screen location) to print it to
|
|
PrintDword:
|
|
push ecx
|
|
push ebx
|
|
push eax
|
|
|
|
mov ecx, 8
|
|
looptop:
|
|
rol eax, 4
|
|
mov bl, al
|
|
and bl, 0fh
|
|
add bl, '0'
|
|
cmp bl, '9'
|
|
jle @f
|
|
add bl, 7
|
|
@@:
|
|
mov byte ptr [edi], bl
|
|
add edi, 2
|
|
loop looptop
|
|
;wbinvd
|
|
|
|
pop eax
|
|
pop ebx
|
|
pop ecx
|
|
ret
|
|
|
|
ClearScreen:
|
|
push eax
|
|
push ecx
|
|
|
|
mov al, ' '
|
|
mov ah, 0ch
|
|
mov edi, 0b8000h
|
|
mov ecx, 80 * 24
|
|
@@:
|
|
mov word ptr [edi], ax
|
|
add edi, 2
|
|
loop @b
|
|
mov edi, 0b8000h
|
|
|
|
pop ecx
|
|
pop eax
|
|
|
|
ret
|
|
|
|
A2C:
|
|
and al, 0fh
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle @f
|
|
add al, 7
|
|
@@:
|
|
ret
|
|
|
|
String1 db "*** INT ",0
|
|
|
|
Int0String db "00h Divide by 0 -",0
|
|
Int1String db "01h Debug exception -",0
|
|
Int2String db "02h NMI -",0
|
|
Int3String db "03h Breakpoint -",0
|
|
Int4String db "04h Overflow -",0
|
|
Int5String db "05h Bound -",0
|
|
Int6String db "06h Invalid opcode -",0
|
|
Int7String db "07h Device not available -",0
|
|
Int8String db "08h Double fault -",0
|
|
Int9String db "09h Coprocessor seg overrun (reserved) -",0
|
|
Int10String db "0Ah Invalid TSS -",0
|
|
Int11String db "0Bh Segment not present -",0
|
|
Int12String db "0Ch Stack fault -",0
|
|
Int13String db "0Dh General protection fault -",0
|
|
Int14String db "0Eh Page fault -",0
|
|
Int15String db "0Fh (Intel reserved) -",0
|
|
Int16String db "10h Floating point error -",0
|
|
Int17String db "11h Alignment check -",0
|
|
Int18String db "12h Machine check -",0
|
|
Int19String db "13h SIMD Floating-Point Exception -",0
|
|
IntUnknownString db "??h Unknown interrupt -",0
|
|
|
|
StringTable dd offset Int0String, offset Int1String, offset Int2String, offset Int3String,
|
|
offset Int4String, offset Int5String, offset Int6String, offset Int7String,
|
|
offset Int8String, offset Int9String, offset Int10String, offset Int11String,
|
|
offset Int12String, offset Int13String, offset Int14String, offset Int15String,
|
|
offset Int16String, offset Int17String, offset Int18String, offset Int19String
|
|
|
|
String2 db " HALT!! *** (",0
|
|
String3 db ")",0
|
|
StringEax db "EAX=",0
|
|
StringEbx db " EBX=",0
|
|
StringEcx db " ECX=",0
|
|
StringEdx db " EDX=",0
|
|
StringEcode db " ECODE=",0
|
|
StringEsp db "ESP=",0
|
|
StringEbp db " EBP=",0
|
|
StringEsi db " ESI=",0
|
|
StringEdi db " EDI=",0
|
|
StringEflags db " EFLAGS=",0
|
|
|
|
Idtr df 0
|
|
|
|
org 21ffeh
|
|
BlockSignature:
|
|
dw 0aa55h
|
|
|
|
end
|