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