diff options
Diffstat (limited to 'DuetPkg/BootSector/efi64.S')
-rw-r--r-- | DuetPkg/BootSector/efi64.S | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/DuetPkg/BootSector/efi64.S b/DuetPkg/BootSector/efi64.S new file mode 100644 index 0000000000..b7b3384291 --- /dev/null +++ b/DuetPkg/BootSector/efi64.S @@ -0,0 +1,786 @@ +#------------------------------------------------------------------------------ +#* +#* 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: + .stack: + .code: + .org 0x21000 + +.equ DEFAULT_HANDLER_SIZE, INT1 - INT0 + +.macro jmpCommonIdtEntry + # 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... + .byte 0xe9 # jmp 16 bit relative + .long commonIdtEntry - . - 4 # offset to jump to +.endm + + +Start: + + movl $0x001fffe8,%esp # make final stack aligned + + # set OSFXSR and OSXMMEXCPT because some code will use XMM register + .byte 0xf + .byte 0x20 + .byte 0xe0 +# mov rax, cr4 + btsl $9,%eax + btsl $0xa,%eax + .byte 0xf + .byte 0x22 + .byte 0xe0 +# mov cr4, rax + + call ClearScreen + + # Populate IDT with meaningful offsets for exception handlers... + sidt Idtr + + + movl Halt, %eax + movl %eax,%ebx # use bx to copy 15..0 to descriptors + shrl $16,%eax # use ax to copy 31..16 to descriptors + # 63..32 of descriptors is 0 + movl $0x78,%ecx # 78h IDT entries to initialize with unique entry points (exceptions) + movl (Idtr + 2), %esi + movl (%esi),%edi + +LOOP_1: # loop through all IDT entries exception handlers and initialize to default handler + movw %bx, (%edi) # write bits 15..0 of offset
+ movw $0x38, 2(%edi) # SYS_CODE_SEL64 from GDT
+ movw $(0x0e00 | 0x8000), 4(%edi) # type = 386 interrupt gate, present
+ movw %ax, 6(%edi) # write bits 31..16 of offset + movl $0, 8(%edi) # write bits 31..16 of offset
+ addl $16, %edi # move up to next descriptor
+ addw DEFAULT_HANDLER_SIZE, %bx # move to next entry point
+ loopl LOOP_1 # 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 + + movl $0x22000,%esi # esi = 22000 + movl 0x14(%esi),%eax # eax = [22014] + addl %eax,%esi # esi = 22000 + [22014] = Base of EFILDR.C + movl 0x3c(%esi),%ebp # ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C + addl %esi,%ebp + movl 0x30(%ebp),%edi # edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore) + movl 0x28(%ebp),%eax # eax = [[22000 + [22014] + 3c] + 24] = EntryPoint + addl %edi,%eax # eax = ImageBase + EntryPoint + movl %ebx, EfiLdrOffset + movl %eax, (%ebx) # Modify far jump instruction for correct entry point + + movw 6(%ebp), %bx # bx = Number of sections + xorl %eax,%eax + movw 0x14(%ebp), %ax # ax = Optional Header Size + addl %eax,%ebp + addl $0x18,%ebp # ebp = Start of 1st Section + +SectionLoop: + pushl %esi # Save Base of EFILDR.C + pushl %edi # Save ImageBase + addl 0x14(%ebp),%esi # esi = Base of EFILDR.C + PointerToRawData + addl 0x0c(%ebp),%edi # edi = ImageBase + VirtualAddress + movl 0x10(%ebp),%ecx # ecs = SizeOfRawData + + cld + shrl $2,%ecx + rep + movsl + + popl %edi # Restore ImageBase + popl %esi # Restore Base of EFILDR.C + + addw $0x28,%bp # ebp = ebp + 028h = Pointer to next section record + .byte 0x66 + .byte 0xff + .byte 0xcb +# dec bx + cmpw $0,%bx + jne SectionLoop + + movl (Idtr), %eax # get size of IDT + movzx (%edx), %eax + .byte 0xff + .byte 0xc0 +# inc eax + addl 2(%edx), %eax # add to base of IDT to get location of memory map... + xorl %ecx,%ecx + movl %eax,%ecx # put argument to RCX + + .byte 0x48 + .byte 0xc7 + .byte 0xc0 +EfiLdrOffset: + .long 0x00401000 # Offset of EFILDR +# mov rax, 401000h + .byte 0x50 +# push rax + +# ret + .byte 0xc3 + +# db "**** DEFAULT IDT ENTRY ***",0 + .align 0x2 +Halt: +INT0: + pushl $0x0 # push error code place holder on the stack + pushl $0x0 + jmpCommonIdtEntry +# db 0e9h ; jmp 16 bit reletive +# dd commonIdtEntry - $ - 4 ; offset to jump to + +INT1: + pushl $0x0 # push error code place holder on the stack + pushl $0x1 + jmpCommonIdtEntry + +INT2: + pushl $0x0 # push error code place holder on the stack + pushl $0x2 + jmpCommonIdtEntry + +INT3: + pushl $0x0 # push error code place holder on the stack + pushl $0x3 + jmpCommonIdtEntry + +INT4: + pushl $0x0 # push error code place holder on the stack + pushl $0x4 + jmpCommonIdtEntry + +INT5: + pushl $0x0 # push error code place holder on the stack + pushl $0x5 + jmpCommonIdtEntry + +INT6: + pushl $0x0 # push error code place holder on the stack + pushl $0x6 + jmpCommonIdtEntry + +INT7: + pushl $0x0 # push error code place holder on the stack + pushl $0x7 + jmpCommonIdtEntry + +INT8: +# Double fault causes an error code to be pushed so no phony push necessary + nop + nop + pushl $0x8 + jmpCommonIdtEntry + +INT9: + pushl $0x0 # push error code place holder on the stack + pushl $0x9 + jmpCommonIdtEntry + +INT10: +# Invalid TSS causes an error code to be pushed so no phony push necessary + nop + nop + pushl $10 + jmpCommonIdtEntry + +INT11: +# Segment Not Present causes an error code to be pushed so no phony push necessary + nop + nop + pushl $11 + jmpCommonIdtEntry + +INT12: +# Stack fault causes an error code to be pushed so no phony push necessary + nop + nop + pushl $12 + jmpCommonIdtEntry + +INT13: +# GP fault causes an error code to be pushed so no phony push necessary + nop + nop + pushl $13 + jmpCommonIdtEntry + +INT14: +# Page fault causes an error code to be pushed so no phony push necessary + nop + nop + pushl $14 + jmpCommonIdtEntry + +INT15: + pushl $0x0 # push error code place holder on the stack + pushl $15 + jmpCommonIdtEntry + +INT16: + pushl $0x0 # push error code place holder on the stack + pushl $16 + jmpCommonIdtEntry + +INT17: +# Alignment check causes an error code to be pushed so no phony push necessary + nop + nop + pushl $17 + jmpCommonIdtEntry + +INT18: + pushl $0x0 # push error code place holder on the stack + pushl $18 + jmpCommonIdtEntry + +INT19: + pushl $0x0 # push error code place holder on the stack + pushl $19 + jmpCommonIdtEntry + +INTUnknown: +.rept (0x78 - 20) + pushl $0x0 # push error code place holder on the stack +# push xxh ; push vector number + .byte 0x6a + .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number + jmpCommonIdtEntry +.endr + +commonIdtEntry: + pushl %eax + pushl %ecx + pushl %edx + pushl %ebx + pushl %esp + pushl %ebp + pushl %esi + pushl %edi + .byte 0x41 + .byte 0x50 +# push r8 + .byte 0x41 + .byte 0x51 +# push r9 + .byte 0x41 + .byte 0x52 +# push r10 + .byte 0x41 + .byte 0x53 +# push r11 + .byte 0x41 + .byte 0x54 +# push r12 + .byte 0x41 + .byte 0x55 +# push r13 + .byte 0x41 + .byte 0x56 +# push r14 + .byte 0x41 + .byte 0x57 +# push r15 + .byte 0x48 + movl %esp,%ebp +# 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 String1, %esi + call PrintString + .byte 0x48 + movl 16*8(%ebp),%eax ## move Int number into RAX + .byte 0x48 + cmpl $18,%eax + ja PrintDefaultString +PrintExceptionString: + shll $3,%eax ## multiply by 8 to get offset from StringTable to actual string address + addl StringTable, %eax + movl (%eax),%esi + jmp PrintTheString +PrintDefaultString: + movl IntUnknownString, %esi + # patch Int number + movl %eax,%edx + call A2C + movb %al,1(%esi) + movl %edx,%eax + shrl $4,%eax + call A2C + movb %al,(%esi) +PrintTheString: + call PrintString + movl String2, %esi + call PrintString + .byte 0x48 + movl 19*8(%ebp),%eax # CS + call PrintQword + movb $':', %al + movb %al, (%edi) + addl $2,%edi + .byte 0x48 + movl 18*8(%ebp),%eax # RIP + call PrintQword + movl String3, %esi + call PrintString + + movl $0xb8140,%edi + + movl StringRax, %esi + call PrintString + .byte 0x48 + movl 15*8(%ebp),%eax + call PrintQword + + movl StringRcx, %esi + call PrintString + .byte 0x48 + movl 14*8(%ebp),%eax + call PrintQword + + movl StringRdx, %esi + call PrintString + .byte 0x48 + movl 13*8(%ebp),%eax + call PrintQword + + movl $0xb81e0,%edi + + movl StringRbx, %esi + call PrintString + .byte 0x48 + movl 12*8(%ebp),%eax + call PrintQword + + movl StringRsp, %esi + call PrintString + .byte 0x48 + movl 21*8(%ebp),%eax + call PrintQword + + movl StringRbp, %esi + call PrintString + .byte 0x48 + movl 10*8(%ebp),%eax + call PrintQword + + movl $0xb8280,%edi + + movl StringRsi, %esi + call PrintString + .byte 0x48 + movl 9*8(%ebp),%eax + call PrintQword + + movl StringRdi, %esi + call PrintString + .byte 0x48 + movl 8*8(%ebp),%eax + call PrintQword + + movl StringEcode, %esi + call PrintString + .byte 0x48 + movl 17*8(%ebp),%eax + call PrintQword + + movl $0xb8320,%edi + + movl StringR8, %esi + call PrintString + .byte 0x48 + movl 7*8(%ebp),%eax + call PrintQword + + movl StringR9, %esi + call PrintString + .byte 0x48 + movl 6*8(%ebp),%eax + call PrintQword + + movl StringR10, %esi + call PrintString + .byte 0x48 + movl 5*8(%ebp),%eax + call PrintQword + + movl $0xb83c0,%edi + + movl StringR11, %esi + call PrintString + .byte 0x48 + movl 4*8(%ebp),%eax + call PrintQword + + movl StringR12, %esi + call PrintString + .byte 0x48 + movl 3*8(%ebp),%eax + call PrintQword + + movl StringR13, %esi + call PrintString + .byte 0x48 + movl 2*8(%ebp),%eax + call PrintQword + + movl $0xb8460,%edi + + movl StringR14, %esi + call PrintString + .byte 0x48 + movl 1*8(%ebp),%eax + call PrintQword + + movl StringR15, %esi + call PrintString + .byte 0x48 + movl 0*8(%ebp),%eax + call PrintQword + + movl StringSs, %esi + call PrintString + .byte 0x48 + movl 22*8(%ebp),%eax + call PrintQword + + movl $0xb8500,%edi + + movl StringRflags, %esi + call PrintString + .byte 0x48 + movl 20*8(%ebp),%eax + call PrintQword + + movl $0xb8640,%edi + + movl %ebp,%esi + addl $23*8,%esi + movl $4,%ecx + + +OuterLoop: + pushl %ecx + movl $4,%ecx + .byte 0x48 + movl %edi,%edx + +InnerLoop: + .byte 0x48 + movl (%esi),%eax + call PrintQword + addl $8,%esi + mov $0x00, %al + movb %al,(%edi) + addl $2,%edi + loop InnerLoop + + popl %ecx + addl $0xa0,%edx + movl %edx,%edi + loop OuterLoop + + + movl $0xb8960,%edi + + .byte 0x48 + movl 18*8(%ebp),%eax # RIP + subl $8*8,%eax + .byte 0x48 + movl %eax,%esi # esi = rip - 8 QWORD linear (total 16 QWORD) + + movl $4,%ecx + +OuterLoop1: + pushl %ecx + movl $4,%ecx + movl %edi,%edx + +InnerLoop1: + .byte 0x48 + movl (%esi),%eax + call PrintQword + addl $8,%esi + movb $0x00, %al + movb %al,(%edi) + addl $2,%edi + loop InnerLoop1 + + popl %ecx + addl $0xa0,%edx + movl %edx,%edi + loop OuterLoop1 + + + + #wbinvd +LN_C1:
+ jmp LN_C1 + +# +# return +# + movl %ebp,%esp +# mov rsp, rbp + .byte 0x41 + .byte 0x5f +# pop r15 + .byte 0x41 + .byte 0x5e +# pop r14 + .byte 0x41 + .byte 0x5d +# pop r13 + .byte 0x41 + .byte 0x5c +# pop r12 + .byte 0x41 + .byte 0x5b +# pop r11 + .byte 0x41 + .byte 0x5a +# pop r10 + .byte 0x41 + .byte 0x59 +# pop r9 + .byte 0x41 + .byte 0x58 +# pop r8 + popl %edi + popl %esi + popl %ebp + popl %eax # esp + popl %ebx + popl %edx + popl %ecx + popl %eax + + .byte 0x48 + .byte 0x83 + .byte 0xc4 + .byte 0x10 +# add esp, 16 ; error code and INT number + + .byte 0x48 + .byte 0xcf +# iretq + +PrintString: + pushl %eax +LN_C2: + movb (%esi), %al + cmpb $0,%al + je LN_C3 + movb %al, (%edi) + .byte 0xff + .byte 0xc6 +# inc esi + addl $2,%edi + jmp LN_C2 +LN_C3: + popl %eax + ret + +## RAX contains qword to print +## RDI contains memory location (screen location) to print it to +PrintQword: + pushl %ecx + pushl %ebx + pushl %eax + + .byte 0x48 + .byte 0xc7 + .byte 0xc1 + .long 16 +# mov rcx, 16 +looptop: + .byte 0x48 + roll $4,%eax + movb %al,%bl + andb $0xf,%bl + addb $'0', %bl + cmpb $'9', %bl + jle @f + addb $7,%bl +@@: + movb %bl, (%edi) + addl $2,%edi + loop looptop + #wbinvd + + popl %eax + popl %ebx + popl %ecx + ret + +ClearScreen: + pushl %eax + pushl %ecx + + movb $0x00, %al + movb $0xc,%ah + movl $0xb8000,%edi + movl $80*24,%ecx +LN_C4: + movw %ax, (%edi) + addl $2,%edi + loop LN_C4 + movl $0xb8000,%edi + + popl %ecx + popl %eax + + ret + +A2C: + andb $0xf,%al + addb $'0', %al + cmpb $'9', %al + jle @f + addb $7,%al +LN_C5: + ret + +String1: .asciz "*** INT " + +Int0String: .asciz "00h Divide by 0 -"
+Int1String: .asciz "01h Debug exception -"
+Int2String: .asciz "02h NMI -"
+Int3String: .asciz "03h Breakpoint -"
+Int4String: .asciz "04h Overflow -"
+Int5String: .asciz "05h Bound -"
+Int6String: .asciz "06h Invalid opcode -"
+Int7String: .asciz "07h Device not available -"
+Int8String: .asciz "08h Double fault -"
+Int9String: .asciz "09h Coprocessor seg overrun (reserved) -"
+Int10String: .asciz "0Ah Invalid TSS -"
+Int11String: .asciz "0Bh Segment not present -"
+Int12String: .asciz "0Ch Stack fault -"
+Int13String: .asciz "0Dh General protection fault -"
+Int14String: .asciz "0Eh Page fault -"
+Int15String: .asciz "0Fh (Intel reserved) -"
+Int16String: .asciz "10h Floating point error -"
+Int17String: .asciz "11h Alignment check -"
+Int18String: .asciz "12h Machine check -"
+Int19String: .asciz "13h SIMD Floating-Point Exception -"
+IntUnknownString: .asciz "??h Unknown interrupt -" + +StringTable: .long Int0String, Int1String, Int2String, Int3String, \
+ Int4String, Int5String, Int6String, Int7String, \
+ Int8String, Int9String, Int10String, Int11String, \
+ Int12String, Int13String, Int14String, Int15String,\
+ Int16String, Int17String, Int18String, Int19String + +String2: .asciz " HALT!! *** (" +String3: .asciz ")" +StringRax: .asciz "RAX=" +StringRcx: .asciz " RCX=" +StringRdx: .asciz " RDX=" +StringRbx: .asciz "RBX=" +StringRsp: .asciz " RSP=" +StringRbp: .asciz " RBP=" +StringRsi: .asciz "RSI=" +StringRdi: .asciz " RDI=" +StringEcode: .asciz " ECODE=" +StringR8: .asciz "R8 =" +StringR9: .asciz " R9 =" +StringR10: .asciz " R10=" +StringR11: .asciz "R11=" +StringR12: .asciz " R12=" +StringR13: .asciz " R13=" +StringR14: .asciz "R14=" +StringR15: .asciz " R15=" +StringSs: .asciz " SS =" +StringRflags: .asciz "RFLAGS=" + +Idtr: .float 0 + .float 0 + + .org 0x21ffe +BlockSignature: + .word 0xaa55 + |