1 ;------------------------------------------------------------------------------ 2 ;* 3 ;* Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> 4 ;* 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 8 ;* 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. 11 ;* 12 ;* efi64.asm 13 ;* 14 ;* Abstract: 15 ;* 16 ;------------------------------------------------------------------------------ 17 18 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19 ; Now in 64-bit long mode. 20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21 22 .486 23 .model flat 24 .stack 25 .code 26 org 21000h 27 28 DEFAULT_HANDLER_SIZE EQU INT1 - INT0 29 30 JmpCommonIdtEntry macro 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 35 ; of entry points... 36 db 0e9h ; jmp 16 bit reletive 37 dd commonIdtEntry - $ - 4 ; offset to jump to 38 endm 39 40 41 Start: 42 43 mov esp,0001fffe8h ; make final stack aligned 44 45 ; set OSFXSR and OSXMMEXCPT because some code will use XMM register 46 db 0fh 47 db 20h 48 db 0e0h 49 ; mov rax, cr4 50 bts eax, 9 51 bts eax, 0ah 52 db 0fh 53 db 22h 54 db 0e0h 55 ; mov cr4, rax 56 57 call ClearScreen 58 59 ; Populate IDT with meaningful offsets for exception handlers... 60 mov eax, offset Idtr 61 sidt fword ptr [eax] ; get fword address of IDT 62 63 mov eax, offset Halt 64 mov ebx, eax ; use bx to copy 15..0 to descriptors 65 shr eax, 16 ; use ax to copy 31..16 to descriptors 66 ; 63..32 of descriptors is 0 67 mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions) 68 mov esi, [offset Idtr + 2] 69 mov edi, [esi] 70 71 @@: ; loop through all IDT entries exception handlers and initialize to default handler 72 mov word ptr [edi], bx ; write bits 15..0 of offset 73 mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT 74 mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present 75 mov word ptr [edi+6], ax ; write bits 31..16 of offset 76 mov dword ptr [edi+8], 0 ; write bits 63..32 of offset 77 add edi, 16 ; move up to next descriptor 78 add bx, DEFAULT_HANDLER_SIZE ; move to next entry point 79 loop @b ; loop back through again until all descriptors are initialized 80 81 ;; at this point edi contains the offset of the descriptor for INT 20 82 ;; and bx contains the low 16 bits of the offset of the default handler 83 ;; so initialize all the rest of the descriptors with these two values... 84 ; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h) 85 ;@@: ; loop through all IDT entries exception handlers and initialize to default handler 86 ; mov word ptr [edi], bx ; write bits 15..0 of offset 87 ; mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT 88 ; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present 89 ; mov word ptr [edi+6], ax ; write bits 31..16 of offset 90 ; mov dword ptr [edi+8], 0 ; write bits 63..32 of offset 91 ; add edi, 16 ; move up to next descriptor 92 ; loop @b ; loop back through again until all descriptors are initialized 93 94 95 ;; DUMP location of IDT and several of the descriptors 96 ; mov ecx, 8 97 ; mov eax, [offset Idtr + 2] 98 ; mov eax, [eax] 99 ; mov edi, 0b8000h 100 ; call PrintQword 101 ; mov esi, eax 102 ; mov edi, 0b80a0h 103 ; jmp OuterLoop 104 105 ;; 106 ;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler... 107 ; mov eax, 011111111h 108 ; mov ebx, 022222222h 109 ; mov ecx, 033333333h 110 ; mov edx, 044444444h 111 ; mov ebp, 055555555h 112 ; mov esi, 066666666h 113 ; mov edi, 077777777h 114 ; push 011111111h 115 ; push 022222222h 116 ; push 033333333h 117 ; int 119 118 119 mov esi,022000h ; esi = 22000 120 mov eax,[esi+014h] ; eax = [22014] 121 add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C 122 mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C 123 add ebp,esi 124 mov edi,[ebp+030h] ; edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore) 125 mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint 126 add eax,edi ; eax = ImageBase + EntryPoint 127 mov ebx, offset EfiLdrOffset 128 mov dword ptr [ebx],eax ; Modify far jump instruction for correct entry point 129 130 mov bx,word ptr[ebp+6] ; bx = Number of sections 131 xor eax,eax 132 mov ax,word ptr[ebp+014h] ; ax = Optional Header Size 133 add ebp,eax 134 add ebp,018h ; ebp = Start of 1st Section 135 136 SectionLoop: 137 push esi ; Save Base of EFILDR.C 138 push edi ; Save ImageBase 139 add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData 140 add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress 141 mov ecx,[ebp+010h] ; ecs = SizeOfRawData 142 143 cld 144 shr ecx,2 145 rep movsd 146 147 pop edi ; Restore ImageBase 148 pop esi ; Restore Base of EFILDR.C 149 150 add bp,028h ; ebp = ebp + 028h = Pointer to next section record 151 db 66h 152 db 0ffh 153 db 0cbh 154 ; dec bx 155 cmp bx,0 156 jne SectionLoop 157 158 mov edx, offset Idtr 159 movzx eax, word ptr [edx] ; get size of IDT 160 db 0ffh 161 db 0c0h 162 ; inc eax 163 add eax, dword ptr [edx + 2] ; add to base of IDT to get location of memory map... 164 xor ecx, ecx 165 mov ecx, eax ; put argument to RCX 166 167 db 48h 168 db 0c7h 169 db 0c0h 170 EfiLdrOffset: 171 dd 000401000h ; Offset of EFILDR 172 ; mov rax, 401000h 173 db 50h 174 ; push rax 175 176 ; ret 177 db 0c3h 178 179 ; db "**** DEFAULT IDT ENTRY ***",0 180 align 02h 181 Halt: 182 INT0: 183 push 0h ; push error code place holder on the stack 184 push 0h 185 JmpCommonIdtEntry 186 ; db 0e9h ; jmp 16 bit reletive 187 ; dd commonIdtEntry - $ - 4 ; offset to jump to 188 189 INT1: 190 push 0h ; push error code place holder on the stack 191 push 1h 192 JmpCommonIdtEntry 193 194 INT2: 195 push 0h ; push error code place holder on the stack 196 push 2h 197 JmpCommonIdtEntry 198 199 INT3: 200 push 0h ; push error code place holder on the stack 201 push 3h 202 JmpCommonIdtEntry 203 204 INT4: 205 push 0h ; push error code place holder on the stack 206 push 4h 207 JmpCommonIdtEntry 208 209 INT5: 210 push 0h ; push error code place holder on the stack 211 push 5h 212 JmpCommonIdtEntry 213 214 INT6: 215 push 0h ; push error code place holder on the stack 216 push 6h 217 JmpCommonIdtEntry 218 219 INT7: 220 push 0h ; push error code place holder on the stack 221 push 7h 222 JmpCommonIdtEntry 223 224 INT8: 225 ; Double fault causes an error code to be pushed so no phony push necessary 226 nop 227 nop 228 push 8h 229 JmpCommonIdtEntry 230 231 INT9: 232 push 0h ; push error code place holder on the stack 233 push 9h 234 JmpCommonIdtEntry 235 236 INT10: 237 ; Invalid TSS causes an error code to be pushed so no phony push necessary 238 nop 239 nop 240 push 10 241 JmpCommonIdtEntry 242 243 INT11: 244 ; Segment Not Present causes an error code to be pushed so no phony push necessary 245 nop 246 nop 247 push 11 248 JmpCommonIdtEntry 249 250 INT12: 251 ; Stack fault causes an error code to be pushed so no phony push necessary 252 nop 253 nop 254 push 12 255 JmpCommonIdtEntry 256 257 INT13: 258 ; GP fault causes an error code to be pushed so no phony push necessary 259 nop 260 nop 261 push 13 262 JmpCommonIdtEntry 263 264 INT14: 265 ; Page fault causes an error code to be pushed so no phony push necessary 266 nop 267 nop 268 push 14 269 JmpCommonIdtEntry 270 271 INT15: 272 push 0h ; push error code place holder on the stack 273 push 15 274 JmpCommonIdtEntry 275 276 INT16: 277 push 0h ; push error code place holder on the stack 278 push 16 279 JmpCommonIdtEntry 280 281 INT17: 282 ; Alignment check causes an error code to be pushed so no phony push necessary 283 nop 284 nop 285 push 17 286 JmpCommonIdtEntry 287 288 INT18: 289 push 0h ; push error code place holder on the stack 290 push 18 291 JmpCommonIdtEntry 292 293 INT19: 294 push 0h ; push error code place holder on the stack 295 push 19 296 JmpCommonIdtEntry 297 298 INTUnknown: 299 REPEAT (78h - 20) 300 push 0h ; push error code place holder on the stack 301 ; push xxh ; push vector number 302 db 06ah 303 db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number 304 JmpCommonIdtEntry 305 ENDM 306 307 commonIdtEntry: 308 push eax 309 push ecx 310 push edx 311 push ebx 312 push esp 313 push ebp 314 push esi 315 push edi 316 db 41h 317 db 50h 318 ; push r8 319 db 41h 320 db 51h 321 ; push r9 322 db 41h 323 db 52h 324 ; push r10 325 db 41h 326 db 53h 327 ; push r11 328 db 41h 329 db 54h 330 ; push r12 331 db 41h 332 db 55h 333 ; push r13 334 db 41h 335 db 56h 336 ; push r14 337 db 41h 338 db 57h 339 ; push r15 340 db 48h 341 mov ebp, esp 342 ; mov rbp, rsp 343 344 ;; 345 ;; At this point the stack looks like this: 346 ;; 347 ;; Calling SS 348 ;; Calling RSP 349 ;; rflags 350 ;; Calling CS 351 ;; Calling RIP 352 ;; Error code or 0 353 ;; Int num or 0ffh for unknown int num 354 ;; rax 355 ;; rcx 356 ;; rdx 357 ;; rbx 358 ;; rsp 359 ;; rbp 360 ;; rsi 361 ;; rdi 362 ;; r8 363 ;; r9 364 ;; r10 365 ;; r11 366 ;; r12 367 ;; r13 368 ;; r14 369 ;; r15 <------- RSP, RBP 370 ;; 371 372 call ClearScreen 373 mov esi, offset String1 374 call PrintString 375 db 48h 376 mov eax, [ebp + 16*8] ;; move Int number into RAX 377 db 48h 378 cmp eax, 18 379 ja PrintDefaultString 380 PrintExceptionString: 381 shl eax, 3 ;; multiply by 8 to get offset from StringTable to actual string address 382 add eax, offset StringTable 383 mov esi, [eax] 384 jmp PrintTheString 385 PrintDefaultString: 386 mov esi, offset IntUnknownString 387 ; patch Int number 388 mov edx, eax 389 call A2C 390 mov [esi + 1], al 391 mov eax, edx 392 shr eax, 4 393 call A2C 394 mov [esi], al 395 PrintTheString: 396 call PrintString 397 mov esi, offset String2 398 call PrintString 399 db 48h 400 mov eax, [ebp+19*8] ; CS 401 call PrintQword 402 mov al, ':' 403 mov byte ptr [edi], al 404 add edi, 2 405 db 48h 406 mov eax, [ebp+18*8] ; RIP 407 call PrintQword 408 mov esi, offset String3 409 call PrintString 410 411 mov edi, 0b8140h 412 413 mov esi, offset StringRax ; rax 414 call PrintString 415 db 48h 416 mov eax, [ebp+15*8] 417 call PrintQword 418 419 mov esi, offset StringRcx ; rcx 420 call PrintString 421 db 48h 422 mov eax, [ebp+14*8] 423 call PrintQword 424 425 mov esi, offset StringRdx ; rdx 426 call PrintString 427 db 48h 428 mov eax, [ebp+13*8] 429 call PrintQword 430 431 mov edi, 0b81e0h 432 433 mov esi, offset StringRbx ; rbx 434 call PrintString 435 db 48h 436 mov eax, [ebp+12*8] 437 call PrintQword 438 439 mov esi, offset StringRsp ; rsp 440 call PrintString 441 db 48h 442 mov eax, [ebp+21*8] 443 call PrintQword 444 445 mov esi, offset StringRbp ; rbp 446 call PrintString 447 db 48h 448 mov eax, [ebp+10*8] 449 call PrintQword 450 451 mov edi, 0b8280h 452 453 mov esi, offset StringRsi ; rsi 454 call PrintString 455 db 48h 456 mov eax, [ebp+9*8] 457 call PrintQword 458 459 mov esi, offset StringRdi ; rdi 460 call PrintString 461 db 48h 462 mov eax, [ebp+8*8] 463 call PrintQword 464 465 mov esi, offset StringEcode ; error code 466 call PrintString 467 db 48h 468 mov eax, [ebp+17*8] 469 call PrintQword 470 471 mov edi, 0b8320h 472 473 mov esi, offset StringR8 ; r8 474 call PrintString 475 db 48h 476 mov eax, [ebp+7*8] 477 call PrintQword 478 479 mov esi, offset StringR9 ; r9 480 call PrintString 481 db 48h 482 mov eax, [ebp+6*8] 483 call PrintQword 484 485 mov esi, offset StringR10 ; r10 486 call PrintString 487 db 48h 488 mov eax, [ebp+5*8] 489 call PrintQword 490 491 mov edi, 0b83c0h 492 493 mov esi, offset StringR11 ; r11 494 call PrintString 495 db 48h 496 mov eax, [ebp+4*8] 497 call PrintQword 498 499 mov esi, offset StringR12 ; r12 500 call PrintString 501 db 48h 502 mov eax, [ebp+3*8] 503 call PrintQword 504 505 mov esi, offset StringR13 ; r13 506 call PrintString 507 db 48h 508 mov eax, [ebp+2*8] 509 call PrintQword 510 511 mov edi, 0b8460h 512 513 mov esi, offset StringR14 ; r14 514 call PrintString 515 db 48h 516 mov eax, [ebp+1*8] 517 call PrintQword 518 519 mov esi, offset StringR15 ; r15 520 call PrintString 521 db 48h 522 mov eax, [ebp+0*8] 523 call PrintQword 524 525 mov esi, offset StringSs ; ss 526 call PrintString 527 db 48h 528 mov eax, [ebp+22*8] 529 call PrintQword 530 531 mov edi, 0b8500h 532 533 mov esi, offset StringRflags ; rflags 534 call PrintString 535 db 48h 536 mov eax, [ebp+20*8] 537 call PrintQword 538 539 mov edi, 0b8640h 540 541 mov esi, ebp 542 add esi, 23*8 543 mov ecx, 4 544 545 546 OuterLoop: 547 push ecx 548 mov ecx, 4 549 db 48h 550 mov edx, edi 551 552 InnerLoop: 553 db 48h 554 mov eax, [esi] 555 call PrintQword 556 add esi, 8 557 mov al, ' ' 558 mov [edi], al 559 add edi, 2 560 loop InnerLoop 561 562 pop ecx 563 add edx, 0a0h 564 mov edi, edx 565 loop OuterLoop 566 567 568 mov edi, 0b8960h 569 570 db 48h 571 mov eax, [ebp+18*8] ; RIP 572 sub eax, 8 * 8 573 db 48h 574 mov esi, eax ; esi = rip - 8 QWORD linear (total 16 QWORD) 575 576 mov ecx, 4 577 578 OuterLoop1: 579 push ecx 580 mov ecx, 4 581 mov edx, edi 582 583 InnerLoop1: 584 db 48h 585 mov eax, [esi] 586 call PrintQword 587 add esi, 8 588 mov al, ' ' 589 mov [edi], al 590 add edi, 2 591 loop InnerLoop1 592 593 pop ecx 594 add edx, 0a0h 595 mov edi, edx 596 loop OuterLoop1 597 598 599 600 ;wbinvd 601 @@: 602 jmp @b 603 604 ; 605 ; return 606 ; 607 mov esp, ebp 608 ; mov rsp, rbp 609 db 41h 610 db 5fh 611 ; pop r15 612 db 41h 613 db 5eh 614 ; pop r14 615 db 41h 616 db 5dh 617 ; pop r13 618 db 41h 619 db 5ch 620 ; pop r12 621 db 41h 622 db 5bh 623 ; pop r11 624 db 41h 625 db 5ah 626 ; pop r10 627 db 41h 628 db 59h 629 ; pop r9 630 db 41h 631 db 58h 632 ; pop r8 633 pop edi 634 pop esi 635 pop ebp 636 pop eax ; esp 637 pop ebx 638 pop edx 639 pop ecx 640 pop eax 641 642 db 48h 643 db 83h 644 db 0c4h 645 db 10h 646 ; add esp, 16 ; error code and INT number 647 648 db 48h 649 db 0cfh 650 ; iretq 651 652 PrintString: 653 push eax 654 @@: 655 mov al, byte ptr [esi] 656 cmp al, 0 657 je @f 658 mov byte ptr [edi], al 659 db 0ffh 660 db 0c6h 661 ; inc esi 662 add edi, 2 663 jmp @b 664 @@: 665 pop eax 666 ret 667 668 ;; RAX contains qword to print 669 ;; RDI contains memory location (screen location) to print it to 670 PrintQword: 671 push ecx 672 push ebx 673 push eax 674 675 db 48h 676 db 0c7h 677 db 0c1h 678 dd 16 679 ; mov rcx, 16 680 looptop: 681 db 48h 682 rol eax, 4 683 mov bl, al 684 and bl, 0fh 685 add bl, '0' 686 cmp bl, '9' 687 jle @f 688 add bl, 7 689 @@: 690 mov byte ptr [edi], bl 691 add edi, 2 692 loop looptop 693 ;wbinvd 694 695 pop eax 696 pop ebx 697 pop ecx 698 ret 699 700 ClearScreen: 701 push eax 702 push ecx 703 704 mov al, ' ' 705 mov ah, 0ch 706 mov edi, 0b8000h 707 mov ecx, 80 * 24 708 @@: 709 mov word ptr [edi], ax 710 add edi, 2 711 loop @b 712 mov edi, 0b8000h 713 714 pop ecx 715 pop eax 716 717 ret 718 719 A2C: 720 and al, 0fh 721 add al, '0' 722 cmp al, '9' 723 jle @f 724 add al, 7 725 @@: 726 ret 727 728 String1 db "*** INT ",0 729 730 Int0String db "00h Divide by 0 -",0 731 Int1String db "01h Debug exception -",0 732 Int2String db "02h NMI -",0 733 Int3String db "03h Breakpoint -",0 734 Int4String db "04h Overflow -",0 735 Int5String db "05h Bound -",0 736 Int6String db "06h Invalid opcode -",0 737 Int7String db "07h Device not available -",0 738 Int8String db "08h Double fault -",0 739 Int9String db "09h Coprocessor seg overrun (reserved) -",0 740 Int10String db "0Ah Invalid TSS -",0 741 Int11String db "0Bh Segment not present -",0 742 Int12String db "0Ch Stack fault -",0 743 Int13String db "0Dh General protection fault -",0 744 Int14String db "0Eh Page fault -",0 745 Int15String db "0Fh (Intel reserved) -",0 746 Int16String db "10h Floating point error -",0 747 Int17String db "11h Alignment check -",0 748 Int18String db "12h Machine check -",0 749 Int19String db "13h SIMD Floating-Point Exception -",0 750 IntUnknownString db "??h Unknown interrupt -",0 751 752 StringTable dq offset Int0String, offset Int1String, offset Int2String, offset Int3String, 753 offset Int4String, offset Int5String, offset Int6String, offset Int7String, 754 offset Int8String, offset Int9String, offset Int10String, offset Int11String, 755 offset Int12String, offset Int13String, offset Int14String, offset Int15String, 756 offset Int16String, offset Int17String, offset Int18String, offset Int19String 757 758 String2 db " HALT!! *** (",0 759 String3 db ")",0 760 StringRax db "RAX=",0 761 StringRcx db " RCX=",0 762 StringRdx db " RDX=",0 763 StringRbx db "RBX=",0 764 StringRsp db " RSP=",0 765 StringRbp db " RBP=",0 766 StringRsi db "RSI=",0 767 StringRdi db " RDI=",0 768 StringEcode db " ECODE=",0 769 StringR8 db "R8 =",0 770 StringR9 db " R9 =",0 771 StringR10 db " R10=",0 772 StringR11 db "R11=",0 773 StringR12 db " R12=",0 774 StringR13 db " R13=",0 775 StringR14 db "R14=",0 776 StringR15 db " R15=",0 777 StringSs db " SS =",0 778 StringRflags db "RFLAGS=",0 779 780 Idtr df 0 781 df 0 782 783 org 21ffeh 784 BlockSignature: 785 dw 0aa55h 786 787 end 788