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