efi32.S revision ccec4c39691f3e2bc3108ef82f744b278b59fda3
1#------------------------------------------------------------------------------ 2#* 3#* Copyright 2006, Intel Corporation 4#* All rights reserved. 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#* efi32.asm 13#* 14#* Abstract: 15#* 16#------------------------------------------------------------------------------ 17 18############################################################################## 19# Now in 32-bit protected mode. 20############################################################################## 21 22 .486: 23 #.MODEL flat 24 .stack: 25 .code: 26 .org 0x21000 27 28.equ DEFAULT_HANDLER_SIZE, INT1 - INT0 29 30.macro jmpCommonIdtEntry 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 .byte 0xe9 # jmp 16 bit relative 37 .long commonIdtEntry - . - 4 # A problem 38.endm 39 40Start: 41 movw %ax, %ds 42 movw %ax, %es 43 movw %ax, %fs 44 movw %ax, %gs 45 movw %ax, %ss 46 movl $0x001ffff0, %esp 47 48 call ClearScreen 49 50 # Populate IDT with meaningful offsets for exception handlers... 51 sidt Idtr 52 53 movl Halt, %eax 54 movl %eax, %ebx # use bx to copy 15..0 to descriptors 55 shrl $16, %eax # use ax to copy 31..16 to descriptors 56 movl $0x78, %ecx # 78h IDT entries to initialize with unique entry points (exceptions) 57 movl (Idtr + 2), %esi 58 movl (%esi), %edi 59 60LOOP_1: # loop through all IDT entries exception handlers and initialize to default handler 61 movw %bx, (%edi) # write bits 15..0 of offset 62 movw $0x20, 2(%edi) # SYS_CODE_SEL from GDT 63 movw $(0x0e00 | 0x8000), 4(%edi) # type = 386 interrupt gate, present 64 movw %ax, 6(%edi) # write bits 31..16 of offset 65 addl $8, %edi # move up to next descriptor 66 addw DEFAULT_HANDLER_SIZE, %bx # move to next entry point 67 loopl LOOP_1 # loop back through again until all descriptors are initialized 68 69 ## at this point edi contains the offset of the descriptor for INT 20 70 ## and bx contains the low 16 bits of the offset of the default handler 71 ## so initialize all the rest of the descriptors with these two values... 72# mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h) 73#@@: ; loop through all IDT entries exception handlers and initialize to default handler 74# mov word ptr [edi], bx ; write bits 15..0 of offset 75# mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT 76# mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present 77# mov word ptr [edi+6], ax ; write bits 31..16 of offset 78# add edi, 8 ; move up to next descriptor 79# loop @b ; loop back through again until all descriptors are initialized 80 81 82## DUMP location of IDT and several of the descriptors 83# mov ecx, 8 84# mov eax, [offset Idtr + 2] 85# mov eax, [eax] 86# mov edi, 0b8000h 87# call PrintDword 88# mov esi, eax 89# mov edi, 0b80a0h 90# jmp OuterLoop 91 92## 93## just for fun, let's do a software interrupt to see if we correctly land in the exception handler... 94# mov eax, 011111111h 95# mov ebx, 022222222h 96# mov ecx, 033333333h 97# mov edx, 044444444h 98# mov ebp, 055555555h 99# mov esi, 066666666h 100# mov edi, 077777777h 101# push 011111111h 102# push 022222222h 103# push 033333333h 104# int 119 105 106 107 movl $0x22000, %esi # esi = 22000 108 movl 0x14(%esi), %eax # eax = [22014] 109 addl %eax, %esi # esi = 22000 + [22014] = Base of EFILDR.C 110 movl 0x3c(%esi), %ebp # ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C 111 addl %esi, %ebp 112 movl 0x34(%ebp), %edi # edi = [[22000 + [22014] + 3c] + 30] = ImageBase 113 movl 0x28(%ebp), %eax # eax = [[22000 + [22014] + 3c] + 24] = EntryPoint 114 addl %edi, %eax # eax = ImageBase + EntryPoint 115 movl %eax, EfiLdrOffset # Modify far jump instruction for correct entry point 116 117 movw 6(%ebp), %bx # bx = Number of sections 118 xorl %eax, %eax 119 movw 0x14(%ebp), %ax # ax = Optional Header Size 120 addl %eax, %ebp 121 addl $0x18, %ebp # ebp = Start of 1st Section 122 123SectionLoop: 124 pushl %esi # Save Base of EFILDR.C 125 pushl %edi # Save ImageBase 126 addl 0x14(%ebp), %esi # esi = Base of EFILDR.C + PointerToRawData 127 addl 0x0c(%ebp), %edi # edi = ImageBase + VirtualAddress 128 movl 0x10(%ebp), %ecx # ecs = SizeOfRawData 129 130 cld 131 shrl $2, %ecx 132 rep 133 movsl 134 135 popl %edi # Restore ImageBase 136 popl %esi # Restore Base of EFILDR.C 137 138 addw $0x28, %bp # ebp = ebp + 028h = Pointer to next section record 139 decw %bx 140 cmpw $0, %bx 141 jne SectionLoop 142 143 movzwl Idtr, %eax # get size of IDT 144 incl %eax 145 addl Idtr + 2, %eax # add to base of IDT to get location of memory map... 146 pushl %eax # push memory map location on stack for call to EFILDR... 147 148 pushl %eax # push return address (useless, just for stack balance) 149 .byte 0xb8 150EfiLdrOffset: 151 .long 0x00401000 # Offset of EFILDR 152# mov eax, 401000h 153 pushl %eax 154 ret 155 156# db "**** DEFAULT IDT ENTRY ***",0 157 .align 0x2 158Halt: 159INT0: 160 pushl $0x0 # push error code place holder on the stack 161 pushl $0x0 162 jmpCommonIdtEntry 163# db 0e9h ; jmp 16 bit reletive 164# dd commonIdtEntry - $ - 4 ; offset to jump to 165 166INT1: 167 pushl $0x0 # push error code place holder on the stack 168 pushl $0x1 169 jmpCommonIdtEntry 170 171INT2: 172 pushl $0x0 # push error code place holder on the stack 173 pushl $0x2 174 jmpCommonIdtEntry 175 176INT3: 177 pushl $0x0 # push error code place holder on the stack 178 pushl $0x3 179 jmpCommonIdtEntry 180 181INT4: 182 pushl $0x0 # push error code place holder on the stack 183 pushl $0x4 184 jmpCommonIdtEntry 185 186INT5: 187 pushl $0x0 # push error code place holder on the stack 188 pushl $0x5 189 jmpCommonIdtEntry 190 191INT6: 192 pushl $0x0 # push error code place holder on the stack 193 pushl $0x6 194 jmpCommonIdtEntry 195 196INT7: 197 pushl $0x0 # push error code place holder on the stack 198 pushl $0x7 199 jmpCommonIdtEntry 200 201INT8: 202# Double fault causes an error code to be pushed so no phony push necessary 203 nop 204 nop 205 pushl $0x8 206 jmpCommonIdtEntry 207 208INT9: 209 pushl $0x0 # push error code place holder on the stack 210 pushl $0x9 211 jmpCommonIdtEntry 212 213INT10: 214# Invalid TSS causes an error code to be pushed so no phony push necessary 215 nop 216 nop 217 pushl $10 218 jmpCommonIdtEntry 219 220INT11: 221# Segment Not Present causes an error code to be pushed so no phony push necessary 222 nop 223 nop 224 pushl $11 225 jmpCommonIdtEntry 226 227INT12: 228# Stack fault causes an error code to be pushed so no phony push necessary 229 nop 230 nop 231 pushl $12 232 jmpCommonIdtEntry 233 234INT13: 235# GP fault causes an error code to be pushed so no phony push necessary 236 nop 237 nop 238 pushl $13 239 jmpCommonIdtEntry 240 241INT14: 242# Page fault causes an error code to be pushed so no phony push necessary 243 nop 244 nop 245 pushl $14 246 jmpCommonIdtEntry 247 248INT15: 249 pushl $0x0 # push error code place holder on the stack 250 pushl $15 251 jmpCommonIdtEntry 252 253INT16: 254 pushl $0x0 # push error code place holder on the stack 255 pushl $16 256 jmpCommonIdtEntry 257 258INT17: 259# Alignment check causes an error code to be pushed so no phony push necessary 260 nop 261 nop 262 pushl $17 263 jmpCommonIdtEntry 264 265INT18: 266 pushl $0x0 # push error code place holder on the stack 267 pushl $18 268 jmpCommonIdtEntry 269 270INT19: 271 pushl $0x0 # push error code place holder on the stack 272 pushl $19 273 jmpCommonIdtEntry 274 275INTUnknown: 276.rept (0x78 - 20) 277 pushl $0x0 # push error code place holder on the stack 278# push $0xxx # push vector number 279 .byte 0x6a 280 .long ( . - INTUnknown - 3 ) / 9 + 20 # vector number 281 jmpCommonIdtEntry 282.endr 283 284commonIdtEntry: 285 pushal 286 movl %esp, %ebp 287## 288## At this point the stack looks like this: 289## 290## eflags 291## Calling CS 292## Calling EIP 293## Error code or 0 294## Int num or 0ffh for unknown int num 295## eax 296## ecx 297## edx 298## ebx 299## esp 300## ebp 301## esi 302## edi <------- ESP, EBP 303## 304 305 call ClearScreen 306 movl String1, %esi 307 call PrintString 308 movl 32(%ebp), %eax ## move Int number into EAX 309 cmpl $19, %eax 310 ja PrintDefaultString 311PrintExceptionString: 312 shll $2, %eax ## multiply by 4 to get offset from StringTable to actual string address 313 addl StringTable, %eax 314 movl (%eax), %esi 315 jmp PrintTheString 316PrintDefaultString: 317 movl IntUnknownString, %esi 318 # patch Int number 319 movl %eax, %edx 320 call A2C 321 movb %al, 1(%esi) 322 movl %edx, %eax 323 shrl $4, %eax 324 call A2C 325 movb %al, (%esi) 326PrintTheString: 327 call PrintString 328 movl String2, %esi 329 call PrintString 330 movl 44(%ebp), %eax # CS 331 call PrintDword 332 movb ':', %al 333 movb %al, (%edi) 334 addl $2, %edi 335 movl 40(%ebp), %eax # EIP 336 call PrintDword 337 movl String3, %esi 338 call PrintString 339 340 movl $0xb8140, %edi 341 342 movl StringEax, %esi # eax 343 call PrintString 344 movl 28(%ebp), %eax 345 call PrintDword 346 347 movl StringEbx, %esi # ebx 348 call PrintString 349 movl 16(%ebp), %eax 350 call PrintDword 351 352 movl StringEcx, %esi # ecx 353 call PrintString 354 movl 24(%ebp), %eax 355 call PrintDword 356 357 movl StringEdx, %esi # edx 358 call PrintString 359 movl 20(%ebp), %eax 360 call PrintDword 361 362 movl StringEcode, %esi # error code 363 call PrintString 364 movl 36(%ebp), %eax 365 call PrintDword 366 367 movl $0xb81e0, %edi 368 369 movl StringEsp, %esi # esp 370 call PrintString 371 movl 12(%ebp), %eax 372 call PrintDword 373 374 movl StringEbp, %esi # ebp 375 call PrintString 376 movl 8(%ebp), %eax 377 call PrintDword 378 379 movl StringEsi, %esi # esi 380 call PrintString 381 movl 4(%ebp), %eax 382 call PrintDword 383 384 movl StringEdi, %esi # edi 385 call PrintString 386 movl (%ebp), %eax 387 call PrintDword 388 389 movl StringEflags, %esi # eflags 390 call PrintString 391 movl 48(%ebp), %eax 392 call PrintDword 393 394 movl $0xb8320, %edi 395 396 movl %ebp, %esi 397 addl $52, %esi 398 movl $8, %ecx 399 400 401OuterLoop: 402 pushl %ecx 403 movl $8, %ecx 404 movl %edi, %edx 405 406InnerLoop: 407 movl (%esi), %eax 408 call PrintDword 409 addl $4, %esi 410 movb ' ', %al 411 movb %al, (%edi) 412 addl $2, %edi 413 loop InnerLoop 414 415 popl %ecx 416 addl $0xa0, %edx 417 movl %edx, %edi 418 loop OuterLoop 419 420 421 movl $0xb8960, %edi 422 423 movl 40(%ebp), %eax # EIP 424 subl $32*4, %eax 425 movl %eax, %esi # esi = eip - 32 DWORD linear (total 64 DWORD) 426 427 movl $8, %ecx 428 429OuterLoop1: 430 pushl %ecx 431 movl $8, %ecx 432 movl %edi, %edx 433 434InnerLoop1: 435 movl (%esi), %eax 436 call PrintDword 437 addl $4, %esi 438 movb ' ', %al 439 movb %al, (%edi) 440 addl $2, %edi 441 loop InnerLoop1 442 443 popl %ecx 444 addl $0xa0, %edx 445 movl %edx, %edi 446 loop OuterLoop1 447 448 449 450# wbinvd ; this intruction does not support in early than 486 arch 451LN_C1: 452 jmp LN_C1 453# 454# return 455# 456 movl %ebp, %esp 457 popal 458 addl $8, %esp # error code and INT number 459 460 iretl 461 462 463PrintString: 464 pushl %eax 465LN_C2: 466 movb (%esi), %al 467 cmpb $0, %al 468 je LN_C3 469 movb %al, (%edi) 470 incl %esi 471 addl $2, %edi 472 jmp LN_C2 473LN_C3: 474 popl %eax 475 ret 476 477## EAX contains dword to print 478## EDI contains memory location (screen location) to print it to 479PrintDword: 480 pushl %ecx 481 pushl %ebx 482 pushl %eax 483 484 movl $8, %ecx 485looptop: 486 roll $4, %eax 487 movb %al, %bl 488 andb $0xf, %bl 489 addb '0', %bl 490 cmpb '9', %bl 491 jle LN_C4 492 addb $7, %bl 493LN_C4: 494 movb %bl, (%edi) 495 addl $2, %edi 496 loop looptop 497 #wbinvd 498 499 popl %eax 500 popl %ebx 501 popl %ecx 502 ret 503 504ClearScreen: 505 pushl %eax 506 pushl %ecx 507 508 movb ' ', %al 509 movb $0xc, %ah 510 movl $0xb8000, %edi 511 movl $80*24, %ecx 512LN_C5: 513 movw %ax, (%edi) 514 addl $2, %edi 515 loop LN_C5 516 movl $0xb8000, %edi 517 518 popl %ecx 519 popl %eax 520 521 ret 522 523A2C: 524 andb $0xf, %al 525 addb '0', %al 526 cmpb '9', %al 527 jle LN_C6 528 addb $7, %al 529LN_C6: 530 ret 531 532String1: .asciz "*** INT " 533 534Int0String: .asciz "00h Divide by 0 -" 535Int1String: .asciz "01h Debug exception -" 536Int2String: .asciz "02h NMI -" 537Int3String: .asciz "03h Breakpoint -" 538Int4String: .asciz "04h Overflow -" 539Int5String: .asciz "05h Bound -" 540Int6String: .asciz "06h Invalid opcode -" 541Int7String: .asciz "07h Device not available -" 542Int8String: .asciz "08h Double fault -" 543Int9String: .asciz "09h Coprocessor seg overrun (reserved) -" 544Int10String: .asciz "0Ah Invalid TSS -" 545Int11String: .asciz "0Bh Segment not present -" 546Int12String: .asciz "0Ch Stack fault -" 547Int13String: .asciz "0Dh General protection fault -" 548Int14String: .asciz "0Eh Page fault -" 549Int15String: .asciz "0Fh (Intel reserved) -" 550Int16String: .asciz "10h Floating point error -" 551Int17String: .asciz "11h Alignment check -" 552Int18String: .asciz "12h Machine check -" 553Int19String: .asciz "13h SIMD Floating-Point Exception -" 554IntUnknownString: .asciz "??h Unknown interrupt -" 555 556StringTable: .long Int0String, Int1String, Int2String, Int3String, \ 557 Int4String, Int5String, Int6String, Int7String, \ 558 Int8String, Int9String, Int10String, Int11String, \ 559 Int12String, Int13String, Int14String, Int15String,\ 560 Int16String, Int17String, Int18String, Int19String 561 562String2: .asciz " HALT!! *** (" 563String3: .asciz ")" 564StringEax: .asciz "EAX=" 565StringEbx: .asciz "EBX=" 566StringEcx: .asciz "ECX=" 567StringEdx: .asciz "EDX=" 568StringEcode: .asciz "ECODE=" 569StringEsp: .asciz "ESP=" 570StringEbp: .asciz "EBP=" 571StringEsi: .asciz "ESI=" 572StringEdi: .asciz "EDI=" 573StringEflags: .asciz "EFLAGS=" 574 575Idtr: .float 0 576 577 .org 0x21ffe 578BlockSignature: 579 .word 0xaa55 580 581 582