From c69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa Mon Sep 17 00:00:00 2001 From: klu2 Date: Thu, 17 Apr 2008 05:48:13 +0000 Subject: Porting Duet module from EDKI to EDKII git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5076 6f19259b-4bc3-4df7-8a09-765794883524 --- DuetPkg/BootSector/efi64.asm | 787 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 787 insertions(+) create mode 100644 DuetPkg/BootSector/efi64.asm (limited to 'DuetPkg/BootSector/efi64.asm') diff --git a/DuetPkg/BootSector/efi64.asm b/DuetPkg/BootSector/efi64.asm new file mode 100644 index 0000000000..bbf8fee35a --- /dev/null +++ b/DuetPkg/BootSector/efi64.asm @@ -0,0 +1,787 @@ +;------------------------------------------------------------------------------ +;* +;* 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. +;* +;* efi64.asm +;* +;* Abstract: +;* +;------------------------------------------------------------------------------ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Now in 64-bit long 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 reletive + dd commonIdtEntry - $ - 4 ; offset to jump to +endm + + +Start: + + mov esp,0001fffe8h ; make final stack aligned + + ; set OSFXSR and OSXMMEXCPT because some code will use XMM register + db 0fh + db 20h + db 0e0h +; mov rax, cr4 + bts eax, 9 + bts eax, 0ah + db 0fh + db 22h + db 0e0h +; mov cr4, rax + + call ClearScreen + + ; Populate IDT with meaningful offsets for exception handlers... + mov eax, offset Idtr + sidt fword ptr [eax] ; 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 + ; 63..32 of descriptors is 0 + 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], 38h ; SYS_CODE64_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 + mov dword ptr [edi+8], 0 ; write bits 63..32 of offset + add edi, 16 ; 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], 38h ; SYS_CODE64_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 +; mov dword ptr [edi+8], 0 ; write bits 63..32 of offset +; add edi, 16 ; 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 PrintQword +; 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+030h] ; edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore) + mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint + add eax,edi ; eax = ImageBase + EntryPoint + mov ebx, offset EfiLdrOffset + mov dword ptr [ebx],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 + db 66h + db 0ffh + db 0cbh +; dec bx + cmp bx,0 + jne SectionLoop + + mov edx, offset Idtr + movzx eax, word ptr [edx] ; get size of IDT + db 0ffh + db 0c0h +; inc eax + add eax, dword ptr [edx + 2] ; add to base of IDT to get location of memory map... + xor ecx, ecx + mov ecx, eax ; put argument to RCX + + db 48h + db 0c7h + db 0c0h +EfiLdrOffset: + dd 000401000h ; Offset of EFILDR +; mov rax, 401000h + db 50h +; push rax + +; ret + db 0c3h + +; 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: + push eax + push ecx + push edx + push ebx + push esp + push ebp + push esi + push edi + db 41h + db 50h +; push r8 + db 41h + db 51h +; push r9 + db 41h + db 52h +; push r10 + db 41h + db 53h +; push r11 + db 41h + db 54h +; push r12 + db 41h + db 55h +; push r13 + db 41h + db 56h +; push r14 + db 41h + db 57h +; push r15 + db 48h + mov ebp, esp +; mov rbp, rsp + +;; +;; At this point the stack looks like this: +;; +;; Calling SS +;; Calling RSP +;; rflags +;; Calling CS +;; Calling RIP +;; Error code or 0 +;; Int num or 0ffh for unknown int num +;; rax +;; rcx +;; rdx +;; rbx +;; rsp +;; rbp +;; rsi +;; rdi +;; r8 +;; r9 +;; r10 +;; r11 +;; r12 +;; r13 +;; r14 +;; r15 <------- RSP, RBP +;; + + call ClearScreen + mov esi, offset String1 + call PrintString + db 48h + mov eax, [ebp + 16*8] ;; move Int number into RAX + db 48h + cmp eax, 18 + ja PrintDefaultString +PrintExceptionString: + shl eax, 3 ;; multiply by 8 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 + db 48h + mov eax, [ebp+19*8] ; CS + call PrintQword + mov al, ':' + mov byte ptr [edi], al + add edi, 2 + db 48h + mov eax, [ebp+18*8] ; RIP + call PrintQword + mov esi, offset String3 + call PrintString + + mov edi, 0b8140h + + mov esi, offset StringRax ; rax + call PrintString + db 48h + mov eax, [ebp+15*8] + call PrintQword + + mov esi, offset StringRcx ; rcx + call PrintString + db 48h + mov eax, [ebp+14*8] + call PrintQword + + mov esi, offset StringRdx ; rdx + call PrintString + db 48h + mov eax, [ebp+13*8] + call PrintQword + + mov edi, 0b81e0h + + mov esi, offset StringRbx ; rbx + call PrintString + db 48h + mov eax, [ebp+12*8] + call PrintQword + + mov esi, offset StringRsp ; rsp + call PrintString + db 48h + mov eax, [ebp+21*8] + call PrintQword + + mov esi, offset StringRbp ; rbp + call PrintString + db 48h + mov eax, [ebp+10*8] + call PrintQword + + mov edi, 0b8280h + + mov esi, offset StringRsi ; rsi + call PrintString + db 48h + mov eax, [ebp+9*8] + call PrintQword + + mov esi, offset StringRdi ; rdi + call PrintString + db 48h + mov eax, [ebp+8*8] + call PrintQword + + mov esi, offset StringEcode ; error code + call PrintString + db 48h + mov eax, [ebp+17*8] + call PrintQword + + mov edi, 0b8320h + + mov esi, offset StringR8 ; r8 + call PrintString + db 48h + mov eax, [ebp+7*8] + call PrintQword + + mov esi, offset StringR9 ; r9 + call PrintString + db 48h + mov eax, [ebp+6*8] + call PrintQword + + mov esi, offset StringR10 ; r10 + call PrintString + db 48h + mov eax, [ebp+5*8] + call PrintQword + + mov edi, 0b83c0h + + mov esi, offset StringR11 ; r11 + call PrintString + db 48h + mov eax, [ebp+4*8] + call PrintQword + + mov esi, offset StringR12 ; r12 + call PrintString + db 48h + mov eax, [ebp+3*8] + call PrintQword + + mov esi, offset StringR13 ; r13 + call PrintString + db 48h + mov eax, [ebp+2*8] + call PrintQword + + mov edi, 0b8460h + + mov esi, offset StringR14 ; r14 + call PrintString + db 48h + mov eax, [ebp+1*8] + call PrintQword + + mov esi, offset StringR15 ; r15 + call PrintString + db 48h + mov eax, [ebp+0*8] + call PrintQword + + mov esi, offset StringSs ; ss + call PrintString + db 48h + mov eax, [ebp+22*8] + call PrintQword + + mov edi, 0b8500h + + mov esi, offset StringRflags ; rflags + call PrintString + db 48h + mov eax, [ebp+20*8] + call PrintQword + + mov edi, 0b8640h + + mov esi, ebp + add esi, 23*8 + mov ecx, 4 + + +OuterLoop: + push ecx + mov ecx, 4 + db 48h + mov edx, edi + +InnerLoop: + db 48h + mov eax, [esi] + call PrintQword + add esi, 8 + mov al, ' ' + mov [edi], al + add edi, 2 + loop InnerLoop + + pop ecx + add edx, 0a0h + mov edi, edx + loop OuterLoop + + + mov edi, 0b8960h + + db 48h + mov eax, [ebp+18*8] ; RIP + sub eax, 8 * 8 + db 48h + mov esi, eax ; esi = rip - 8 QWORD linear (total 16 QWORD) + + mov ecx, 4 + +OuterLoop1: + push ecx + mov ecx, 4 + mov edx, edi + +InnerLoop1: + db 48h + mov eax, [esi] + call PrintQword + add esi, 8 + mov al, ' ' + mov [edi], al + add edi, 2 + loop InnerLoop1 + + pop ecx + add edx, 0a0h + mov edi, edx + loop OuterLoop1 + + + + wbinvd +@@: + jmp @b + +; +; return +; + mov esp, ebp +; mov rsp, rbp + db 41h + db 5fh +; pop r15 + db 41h + db 5eh +; pop r14 + db 41h + db 5dh +; pop r13 + db 41h + db 5ch +; pop r12 + db 41h + db 5bh +; pop r11 + db 41h + db 5ah +; pop r10 + db 41h + db 59h +; pop r9 + db 41h + db 58h +; pop r8 + pop edi + pop esi + pop ebp + pop eax ; esp + pop ebx + pop edx + pop ecx + pop eax + + db 48h + db 83h + db 0c4h + db 10h +; add esp, 16 ; error code and INT number + + db 48h + db 0cfh +; iretq + +PrintString: + push eax +@@: + mov al, byte ptr [esi] + cmp al, 0 + je @f + mov byte ptr [edi], al + db 0ffh + db 0c6h +; inc esi + add edi, 2 + jmp @b +@@: + pop eax + ret + +;; RAX contains qword to print +;; RDI contains memory location (screen location) to print it to +PrintQword: + push ecx + push ebx + push eax + + db 48h + db 0c7h + db 0c1h + dd 16 +; mov rcx, 16 +looptop: + db 48h + 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 dq 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 +StringRax db "RAX=",0 +StringRcx db " RCX=",0 +StringRdx db " RDX=",0 +StringRbx db "RBX=",0 +StringRsp db " RSP=",0 +StringRbp db " RBP=",0 +StringRsi db "RSI=",0 +StringRdi db " RDI=",0 +StringEcode db " ECODE=",0 +StringR8 db "R8 =",0 +StringR9 db " R9 =",0 +StringR10 db " R10=",0 +StringR11 db "R11=",0 +StringR12 db " R12=",0 +StringR13 db " R13=",0 +StringR14 db "R14=",0 +StringR15 db " R15=",0 +StringSs db " SS =",0 +StringRflags db "RFLAGS=",0 + +Idtr df 0 + df 0 + + org 21ffeh +BlockSignature: + dw 0aa55h + + end -- cgit v1.2.3