]> git.proxmox.com Git - mirror_edk2.git/blobdiff - DuetPkg/BootSector/efi32.asm
Porting Duet module from EDKI to EDKII
[mirror_edk2.git] / DuetPkg / BootSector / efi32.asm
diff --git a/DuetPkg/BootSector/efi32.asm b/DuetPkg/BootSector/efi32.asm
new file mode 100644 (file)
index 0000000..d956022
--- /dev/null
@@ -0,0 +1,581 @@
+;------------------------------------------------------------------------------\r
+;*\r
+;*   Copyright 2006, Intel Corporation                                                         \r
+;*   All rights reserved. This program and the accompanying materials                          \r
+;*   are licensed and made available under the terms and conditions of the BSD License         \r
+;*   which accompanies this distribution.  The full text of the license may be found at        \r
+;*   http://opensource.org/licenses/bsd-license.php                                            \r
+;*                                                                                             \r
+;*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+;*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+;*   \r
+;*    efi32.asm\r
+;*  \r
+;*   Abstract:\r
+;*\r
+;------------------------------------------------------------------------------\r
+\r
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
+; Now in 32-bit protected mode.\r
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
+\r
+        .486\r
+        .model  flat        \r
+        .stack\r
+        .code\r
+        org 21000h\r
+        \r
+DEFAULT_HANDLER_SIZE EQU INT1 - INT0\r
+\r
+JmpCommonIdtEntry  macro\r
+    ; jmp     commonIdtEntry - this must be hand coded to keep the assembler from\r
+    ;                          using a 8 bit reletive jump when the entries are\r
+    ;                          within 255 bytes of the common entry.  This must\r
+    ;                          be done to maintain the consistency of the size\r
+    ;                          of entry points...\r
+    db      0e9h                        ; jmp 16 bit relative \r
+    dd      commonIdtEntry - $ - 4      ;  offset to jump to\r
+endm    \r
+\r
+        \r
+Start:  \r
+    mov     ds,ax\r
+    mov     es,ax\r
+    mov     fs,ax\r
+    mov     gs,ax\r
+    mov     ss,ax\r
+    mov     esp,0001ffff0h\r
+\r
+    call    ClearScreen\r
+\r
+    ; Populate IDT with meaningful offsets for exception handlers...\r
+    sidt    fword ptr [Idtr]             ; get fword address of IDT\r
+\r
+    mov     eax, offset Halt\r
+    mov     ebx, eax                    ; use bx to copy 15..0 to descriptors\r
+    shr     eax, 16                     ; use ax to copy 31..16 to descriptors \r
+    mov     ecx, 78h                    ; 78h IDT entries to initialize with unique entry points (exceptions)\r
+    mov     esi, [offset Idtr + 2]\r
+    mov     edi, [esi]\r
+    \r
+@@:                                             ; loop through all IDT entries exception handlers and initialize to default handler\r
+    mov     word ptr [edi], bx                  ; write bits 15..0 of offset\r
+    mov     word ptr [edi+2], 20h               ; SYS_CODE_SEL from GDT\r
+    mov     word ptr [edi+4], 0e00h OR 8000h    ; type = 386 interrupt gate, present\r
+    mov     word ptr [edi+6], ax                ; write bits 31..16 of offset\r
+    add     edi, 8                              ; move up to next descriptor\r
+    add     bx, DEFAULT_HANDLER_SIZE            ; move to next entry point\r
+    loop    @b                                  ; loop back through again until all descriptors are initialized\r
+    \r
+    ;; at this point edi contains the offset of the descriptor for INT 20\r
+    ;; and bx contains the low 16 bits of the offset of the default handler\r
+    ;; so initialize all the rest of the descriptors with these two values...\r
+;    mov     ecx, 101                            ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)\r
+;@@:                                             ; loop through all IDT entries exception handlers and initialize to default handler\r
+;    mov     word ptr [edi], bx                  ; write bits 15..0 of offset\r
+;    mov     word ptr [edi+2], 20h               ; SYS_CODE_SEL from GDT\r
+;    mov     word ptr [edi+4], 0e00h OR 8000h    ; type = 386 interrupt gate, present\r
+;    mov     word ptr [edi+6], ax                ; write bits 31..16 of offset\r
+;    add     edi, 8                              ; move up to next descriptor\r
+;    loop    @b                                  ; loop back through again until all descriptors are initialized\r
+    \r
+    \r
+;;  DUMP    location of IDT and several of the descriptors\r
+;    mov     ecx, 8\r
+;    mov     eax, [offset Idtr + 2]\r
+;    mov     eax, [eax]\r
+;    mov     edi, 0b8000h\r
+;    call    PrintDword\r
+;    mov     esi, eax\r
+;    mov     edi, 0b80a0h\r
+;    jmp     OuterLoop\r
+    \r
+;;    \r
+;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...\r
+;    mov     eax, 011111111h\r
+;    mov     ebx, 022222222h\r
+;    mov     ecx, 033333333h\r
+;    mov     edx, 044444444h\r
+;    mov     ebp, 055555555h\r
+;    mov     esi, 066666666h\r
+;    mov     edi, 077777777h\r
+;    push    011111111h\r
+;    push    022222222h\r
+;    push    033333333h\r
+;    int     119\r
+\r
+    \r
+    mov     esi,022000h                 ; esi = 22000\r
+    mov     eax,[esi+014h]              ; eax = [22014]\r
+    add     esi,eax                     ; esi = 22000 + [22014] = Base of EFILDR.C\r
+    mov     ebp,[esi+03ch]              ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C\r
+    add     ebp,esi\r
+    mov     edi,[ebp+034h]              ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase\r
+    mov     eax,[ebp+028h]              ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint\r
+    add     eax,edi                     ; eax = ImageBase + EntryPoint\r
+    mov     dword ptr [EfiLdrOffset],eax   ; Modify far jump instruction for correct entry point\r
+\r
+    mov     bx,word ptr[ebp+6]          ; bx = Number of sections\r
+    xor     eax,eax\r
+    mov     ax,word ptr[ebp+014h]       ; ax = Optional Header Size\r
+    add     ebp,eax\r
+    add     ebp,018h                    ; ebp = Start of 1st Section\r
+\r
+SectionLoop:\r
+    push    esi                         ; Save Base of EFILDR.C\r
+    push    edi                         ; Save ImageBase\r
+    add     esi,[ebp+014h]              ; esi = Base of EFILDR.C + PointerToRawData\r
+    add     edi,[ebp+00ch]              ; edi = ImageBase + VirtualAddress\r
+    mov     ecx,[ebp+010h]              ; ecs = SizeOfRawData\r
+\r
+    cld\r
+    shr     ecx,2\r
+    rep     movsd\r
+\r
+    pop     edi                         ; Restore ImageBase\r
+    pop     esi                         ; Restore Base of EFILDR.C\r
+\r
+    add     bp,028h                     ; ebp = ebp + 028h = Pointer to next section record\r
+    dec     bx\r
+    cmp     bx,0\r
+    jne     SectionLoop\r
+\r
+    movzx   eax, word ptr [Idtr]         ; get size of IDT\r
+    inc     eax\r
+    add     eax, dword ptr [Idtr + 2]    ; add to base of IDT to get location of memory map...\r
+    push    eax                         ; push memory map location on stack for call to EFILDR...\r
+\r
+    push    eax                         ; push return address (useless, just for stack balance)\r
+    db      0b8h\r
+EfiLdrOffset:\r
+    dd      000401000h                  ; Offset of EFILDR\r
+; mov eax, 401000h\r
+    push    eax\r
+    ret\r
+\r
+;    db      "**** DEFAULT IDT ENTRY ***",0\r
+    align 02h\r
+Halt:\r
+INT0:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    0h\r
+    JmpCommonIdtEntry\r
+;    db      0e9h                        ; jmp 16 bit reletive \r
+;    dd      commonIdtEntry - $ - 4      ;  offset to jump to\r
+    \r
+INT1:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    1h\r
+    JmpCommonIdtEntry\r
+    \r
+INT2:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    2h\r
+    JmpCommonIdtEntry\r
+    \r
+INT3:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    3h\r
+    JmpCommonIdtEntry\r
+    \r
+INT4:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    4h\r
+    JmpCommonIdtEntry\r
+    \r
+INT5:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    5h\r
+    JmpCommonIdtEntry\r
+    \r
+INT6:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    6h\r
+    JmpCommonIdtEntry\r
+    \r
+INT7:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    7h\r
+    JmpCommonIdtEntry\r
+    \r
+INT8:\r
+;   Double fault causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    8h\r
+    JmpCommonIdtEntry\r
+    \r
+INT9:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    9h\r
+    JmpCommonIdtEntry\r
+    \r
+INT10:\r
+;   Invalid TSS causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    10\r
+    JmpCommonIdtEntry\r
+    \r
+INT11:\r
+;   Segment Not Present causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    11\r
+    JmpCommonIdtEntry\r
+    \r
+INT12:\r
+;   Stack fault causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    12\r
+    JmpCommonIdtEntry\r
+    \r
+INT13:\r
+;   GP fault causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    13\r
+    JmpCommonIdtEntry\r
+    \r
+INT14:\r
+;   Page fault causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    14\r
+    JmpCommonIdtEntry\r
+    \r
+INT15:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    15\r
+    JmpCommonIdtEntry\r
+    \r
+INT16:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    16\r
+    JmpCommonIdtEntry\r
+    \r
+INT17:\r
+;   Alignment check causes an error code to be pushed so no phony push necessary\r
+    nop\r
+    nop\r
+    push    17\r
+    JmpCommonIdtEntry\r
+    \r
+INT18:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    18\r
+    JmpCommonIdtEntry\r
+    \r
+INT19:\r
+    push    0h      ; push error code place holder on the stack\r
+    push    19\r
+    JmpCommonIdtEntry\r
+\r
+INTUnknown:\r
+REPEAT  (78h - 20)\r
+    push    0h      ; push error code place holder on the stack\r
+;    push    xxh     ; push vector number\r
+    db      06ah\r
+    db      ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number\r
+    JmpCommonIdtEntry\r
+ENDM\r
+\r
+commonIdtEntry:\r
+    pushad\r
+    mov     ebp, esp\r
+;;\r
+;;  At this point the stack looks like this:\r
+;;\r
+;;      eflags\r
+;;      Calling CS\r
+;;      Calling EIP\r
+;;      Error code or 0\r
+;;      Int num or 0ffh for unknown int num\r
+;;      eax\r
+;;      ecx\r
+;;      edx\r
+;;      ebx\r
+;;      esp\r
+;;      ebp\r
+;;      esi\r
+;;      edi <------- ESP, EBP\r
+;;      \r
+\r
+    call    ClearScreen\r
+    mov     esi, offset String1\r
+    call    PrintString\r
+    mov     eax, [ebp + 32]     ;; move Int number into EAX \r
+    cmp     eax, 19\r
+    ja      PrintDefaultString\r
+PrintExceptionString:\r
+    shl     eax, 2              ;; multiply by 4 to get offset from StringTable to actual string address\r
+    add     eax, offset StringTable\r
+    mov     esi, [eax]\r
+    jmp     PrintTheString\r
+PrintDefaultString:\r
+    mov     esi, offset IntUnknownString\r
+    ; patch Int number\r
+    mov     edx, eax\r
+    call    A2C\r
+    mov     [esi + 1], al\r
+    mov     eax, edx\r
+    shr     eax, 4\r
+    call    A2C\r
+    mov     [esi], al\r
+PrintTheString:        \r
+    call    PrintString\r
+    mov     esi, offset String2\r
+    call    PrintString\r
+    mov     eax, [ebp+44]          ; CS\r
+    call    PrintDword\r
+    mov     al, ':'\r
+    mov     byte ptr [edi], al\r
+    add     edi, 2\r
+    mov     eax, [ebp+40]          ; EIP\r
+    call    PrintDword\r
+    mov     esi, offset String3\r
+    call    PrintString\r
+    \r
+    mov     edi, 0b8140h\r
+    \r
+    mov     esi, offset StringEax     ; eax\r
+    call    PrintString\r
+    mov     eax, [ebp+28]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEbx     ; ebx\r
+    call    PrintString\r
+    mov     eax, [ebp+16]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEcx     ; ecx\r
+    call    PrintString\r
+    mov     eax, [ebp+24]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEdx     ; edx\r
+    call    PrintString\r
+    mov     eax, [ebp+20]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEcode   ; error code\r
+    call    PrintString\r
+    mov     eax, [ebp+36]\r
+    call    PrintDword\r
+    \r
+    mov     edi, 0b81e0h\r
+    \r
+    mov     esi, offset StringEsp     ; esp\r
+    call    PrintString\r
+    mov     eax, [ebp+12]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEbp     ; ebp\r
+    call    PrintString\r
+    mov     eax, [ebp+8]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEsi     ; esi\r
+    call    PrintString\r
+    mov     eax, [ebp+4]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEdi    ; edi\r
+    call    PrintString\r
+    mov     eax, [ebp]\r
+    call    PrintDword\r
+    \r
+    mov     esi, offset StringEflags ; eflags\r
+    call    PrintString\r
+    mov     eax, [ebp+48]\r
+    call    PrintDword\r
+    \r
+    mov     edi, 0b8320h\r
+\r
+    mov     esi, ebp\r
+    add     esi, 52\r
+    mov     ecx, 8\r
+\r
+    \r
+OuterLoop:\r
+    push    ecx\r
+    mov     ecx, 8\r
+    mov     edx, edi\r
+\r
+InnerLoop:\r
+    mov     eax, [esi]\r
+    call    PrintDword\r
+    add     esi, 4\r
+    mov     al, ' '\r
+    mov     [edi], al\r
+    add     edi, 2\r
+    loop    InnerLoop\r
+\r
+    pop     ecx\r
+    add     edx, 0a0h\r
+    mov     edi, edx\r
+    loop    OuterLoop\r
+\r
+\r
+    mov     edi, 0b8960h\r
+\r
+    mov     eax, [ebp+40]  ; EIP\r
+    sub     eax, 32 * 4\r
+    mov     esi, eax        ; esi = eip - 32 DWORD linear (total 64 DWORD)\r
+\r
+    mov     ecx, 8\r
+    \r
+OuterLoop1:\r
+    push    ecx\r
+    mov     ecx, 8\r
+    mov     edx, edi\r
+\r
+InnerLoop1:\r
+    mov     eax, [esi]\r
+    call    PrintDword\r
+    add     esi, 4\r
+    mov     al, ' '\r
+    mov     [edi], al\r
+    add     edi, 2\r
+    loop    InnerLoop1\r
+\r
+    pop     ecx\r
+    add     edx, 0a0h\r
+    mov     edi, edx\r
+    loop    OuterLoop1\r
+\r
+\r
+\r
+;    wbinvd ; Ken: this intruction does not support in early than 486 arch\r
+@@:    \r
+    jmp     @b\r
+;\r
+; return\r
+;\r
+    mov     esp, ebp\r
+    popad\r
+    add     esp, 8 ; error code and INT number\r
+    \r
+    iretd\r
+\r
+\r
+PrintString:\r
+    push    eax\r
+@@:\r
+    mov     al, byte ptr [esi]\r
+    cmp     al, 0\r
+    je      @f\r
+    mov     byte ptr [edi], al\r
+    inc     esi\r
+    add     edi, 2\r
+    jmp     @b\r
+@@:\r
+    pop     eax\r
+    ret\r
+        \r
+;; EAX contains dword to print\r
+;; EDI contains memory location (screen location) to print it to\r
+PrintDword:\r
+    push    ecx\r
+    push    ebx\r
+    push    eax\r
+    \r
+    mov     ecx, 8\r
+looptop:\r
+    rol     eax, 4\r
+    mov     bl, al\r
+    and     bl, 0fh\r
+    add     bl, '0'\r
+    cmp     bl, '9'\r
+    jle     @f\r
+    add     bl, 7\r
+@@:\r
+    mov     byte ptr [edi], bl\r
+    add     edi, 2\r
+    loop    looptop\r
+    wbinvd\r
+    \r
+    pop     eax\r
+    pop     ebx\r
+    pop     ecx\r
+    ret\r
+\r
+ClearScreen:\r
+    push    eax\r
+    push    ecx\r
+    \r
+    mov     al, ' '\r
+    mov     ah, 0ch\r
+    mov     edi, 0b8000h\r
+    mov     ecx, 80 * 24\r
+@@:\r
+    mov     word ptr [edi], ax\r
+    add     edi, 2\r
+    loop    @b\r
+    mov     edi, 0b8000h\r
+    \r
+    pop     ecx\r
+    pop     eax\r
+\r
+    ret                \r
+        \r
+A2C:\r
+    and     al, 0fh\r
+    add     al, '0'\r
+    cmp     al, '9'\r
+    jle     @f\r
+    add     al, 7\r
+@@:\r
+    ret\r
+        \r
+String1           db  "*** INT ",0\r
+\r
+Int0String        db  "00h Divide by 0 -",0\r
+Int1String        db  "01h Debug exception -",0\r
+Int2String        db  "02h NMI -",0\r
+Int3String        db  "03h Breakpoint -",0\r
+Int4String        db  "04h Overflow -",0\r
+Int5String        db  "05h Bound -",0\r
+Int6String        db  "06h Invalid opcode -",0\r
+Int7String        db  "07h Device not available -",0\r
+Int8String        db  "08h Double fault -",0\r
+Int9String        db  "09h Coprocessor seg overrun (reserved) -",0\r
+Int10String       db  "0Ah Invalid TSS -",0\r
+Int11String       db  "0Bh Segment not present -",0\r
+Int12String       db  "0Ch Stack fault -",0\r
+Int13String       db  "0Dh General protection fault -",0\r
+Int14String       db  "0Eh Page fault -",0\r
+Int15String       db  "0Fh (Intel reserved) -",0\r
+Int16String       db  "10h Floating point error -",0\r
+Int17String       db  "11h Alignment check -",0\r
+Int18String       db  "12h Machine check -",0\r
+Int19String       db  "13h SIMD Floating-Point Exception -",0\r
+IntUnknownString  db  "??h Unknown interrupt -",0\r
+\r
+StringTable       dd  offset Int0String, offset Int1String, offset Int2String, offset Int3String, \r
+                      offset Int4String, offset Int5String, offset Int6String, offset Int7String,\r
+                      offset Int8String, offset Int9String, offset Int10String, offset Int11String,\r
+                      offset Int12String, offset Int13String, offset Int14String, offset Int15String,\r
+                      offset Int16String, offset Int17String, offset Int18String, offset Int19String\r
+\r
+String2           db  " HALT!! *** (",0\r
+String3           db  ")",0\r
+StringEax         db  "EAX=",0\r
+StringEbx         db  " EBX=",0\r
+StringEcx         db  " ECX=",0\r
+StringEdx         db  " EDX=",0\r
+StringEcode       db  " ECODE=",0\r
+StringEsp         db  "ESP=",0\r
+StringEbp         db  " EBP=",0\r
+StringEsi         db  " ESI=",0\r
+StringEdi         db  " EDI=",0\r
+StringEflags      db  " EFLAGS=",0\r
+\r
+Idtr        df  0\r
+\r
+    org 21ffeh\r
+BlockSignature:\r
+    dw      0aa55h\r
+    \r
+    end\r