]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
Add CPU DXE driver for IA32 & X64 processor architectures.
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / Ia32 / CpuAsm.S
diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
new file mode 100755 (executable)
index 0000000..69fe215
--- /dev/null
@@ -0,0 +1,395 @@
+#
+# ConvertAsm.py: Automatically generated from CpuAsm.asm
+#
+#      TITLE   CpuAsm.asm:
+
+#------------------------------------------------------------------------------
+#*
+#*   Copyright 2006 - 2009, 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.
+#*
+#*    CpuAsm.S
+#*
+#*   Abstract:
+#*
+#------------------------------------------------------------------------------
+
+
+#.MMX
+#.XMM
+
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
+
+
+#
+# point to the external interrupt vector table
+#
+ExternalVectorTablePtr:
+    .byte      0, 0, 0, 0
+
+.intel_syntax
+ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
+ASM_PFX(InitializeExternalVectorTablePtr):
+    mov     eax, [esp+4]
+    mov     ExternalVectorTablePtr, eax
+    ret
+
+#------------------------------------------------------------------------------
+# VOID
+# SetCodeSelector (
+#   UINT16 Selector
+#   );
+#------------------------------------------------------------------------------
+.intel_syntax
+ASM_GLOBAL ASM_PFX(SetCodeSelector)
+ASM_PFX(SetCodeSelector):
+    mov     %ecx, [%esp+4]
+    sub     %esp, 0x10
+    lea     %eax, setCodeSelectorLongJump
+    mov     [%esp], %eax
+    mov     [%esp+4], %cx
+    jmp     fword ptr [%esp]
+setCodeSelectorLongJump:
+    add     %esp, 0x10
+    ret
+
+#------------------------------------------------------------------------------
+# VOID
+# SetDataSelectors (
+#   UINT16 Selector
+#   );
+#------------------------------------------------------------------------------
+.intel_syntax
+ASM_GLOBAL ASM_PFX(SetDataSelectors)
+ASM_PFX(SetDataSelectors):
+    mov     %ecx, [%esp+4]
+    mov     %ss, %cx
+    mov     %ds, %cx
+    mov     %es, %cx
+    mov     %fs, %cx
+    mov     %gs, %cx
+    ret
+
+#---------------------------------------;
+# CommonInterruptEntry                  ;
+#---------------------------------------;
+# The follow algorithm is used for the common interrupt routine.
+
+.intel_syntax
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
+ASM_PFX(CommonInterruptEntry):
+    cli
+    #
+    # All interrupt handlers are invoked through interrupt gates, so
+    # IF flag automatically cleared at the entry point
+    #
+
+    #
+    # Calculate vector number
+    #
+    # Get the return address of call, actually, it is the
+    # address of vector number.
+    #
+    xchg    ecx, [esp]
+    mov     cx, [ecx]
+    and     ecx, 0x0FFFF
+    cmp     ecx, 32         # Intel reserved vector for exceptions?
+    jae     NoErrorCode
+    bt      ASM_PFX(mErrorCodeFlag), ecx
+    jc      HasErrorCode
+
+NoErrorCode:
+
+    #
+    # Stack:
+    # +---------------------+
+    # +    EFlags           +
+    # +---------------------+
+    # +    CS               +
+    # +---------------------+
+    # +    EIP              +
+    # +---------------------+
+    # +    ECX              +
+    # +---------------------+ <-- ESP
+    #
+    # Registers:
+    #   ECX - Vector Number
+    #
+
+    #
+    # Put Vector Number on stack
+    #
+    push    ecx
+
+    #
+    # Put 0 (dummy) error code on stack, and restore ECX
+    #
+    xor     ecx, ecx  # ECX = 0
+    xchg    ecx, [esp+4]
+
+    jmp     ErrorCodeAndVectorOnStack
+
+HasErrorCode:
+
+    #
+    # Stack:
+    # +---------------------+
+    # +    EFlags           +
+    # +---------------------+
+    # +    CS               +
+    # +---------------------+
+    # +    EIP              +
+    # +---------------------+
+    # +    Error Code       +
+    # +---------------------+
+    # +    ECX              +
+    # +---------------------+ <-- ESP
+    #
+    # Registers:
+    #   ECX - Vector Number
+    #
+
+    #
+    # Put Vector Number on stack and restore ECX
+    #
+    xchg    ecx, [esp]
+
+    #
+    # Fall through to join main routine code
+    # at ErrorCodeAndVectorOnStack
+    #
+CommonInterruptEntry_al_0000:
+    jmp CommonInterruptEntry_al_0000
+
+ErrorCodeAndVectorOnStack:
+    push    ebp
+    mov     ebp, esp
+
+    #
+    # Stack:
+    # +---------------------+
+    # +    EFlags           +
+    # +---------------------+
+    # +    CS               +
+    # +---------------------+
+    # +    EIP              +
+    # +---------------------+
+    # +    Error Code       +
+    # +---------------------+
+    # +    Vector Number    +
+    # +---------------------+
+    # +    EBP              +
+    # +---------------------+ <-- EBP
+    #
+
+    #
+    # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+    # is 16-byte aligned
+    #
+    and     esp, 0x0fffffff0
+    sub     esp, 12
+
+#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+    push    eax
+    push    ecx
+    push    edx
+    push    ebx
+    lea     ecx, [ebp + 6 * 4]
+    push    ecx                          # ESP
+    push    dword ptr [ebp]              # EBP
+    push    esi
+    push    edi
+
+#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
+    mov     eax, ss
+    push    eax
+    movzx   eax, word ptr [ebp + 4 * 4]
+    push    eax
+    mov     eax, ds
+    push    eax
+    mov     eax, es
+    push    eax
+    mov     eax, fs
+    push    eax
+    mov     eax, gs
+    push    eax
+
+#; UINT32  Eip;
+    mov     eax, [ebp + 3 * 4]
+    push    eax
+
+#; UINT32  Gdtr[2], Idtr[2];
+    sub     esp, 8
+    sidt    [esp]
+    mov     eax, [esp + 2]
+    xchg    eax, [esp]
+    and     eax, 0x0FFFF
+    mov     [esp+4], eax
+
+    sub     esp, 8
+    sgdt    [esp]
+    mov     eax, [esp + 2]
+    xchg    eax, [esp]
+    and     eax, 0x0FFFF
+    mov     [esp+4], eax
+
+#; UINT32  Ldtr, Tr;
+    xor     eax, eax
+    str     ax
+    push    eax
+    sldt    ax
+    push    eax
+
+#; UINT32  EFlags;
+    mov     eax, [ebp + 5 * 4]
+    push    eax
+
+#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
+    mov     eax, cr4
+    or      eax, 0x208
+    mov     cr4, eax
+    push    eax
+    mov     eax, cr3
+    push    eax
+    mov     eax, cr2
+    push    eax
+    xor     eax, eax
+    push    eax
+    mov     eax, cr0
+    push    eax
+
+#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+    mov     eax, dr7
+    push    eax
+#; clear Dr7 while executing debugger itself
+    xor     eax, eax
+    mov     dr7, eax
+
+    mov     eax, dr6
+    push    eax
+#; insure all status bits in dr6 are clear...
+    xor     eax, eax
+    mov     dr6, eax
+
+    mov     eax, dr3
+    push    eax
+    mov     eax, dr2
+    push    eax
+    mov     eax, dr1
+    push    eax
+    mov     eax, dr0
+    push    eax
+
+#; FX_SAVE_STATE_IA32 FxSaveState;
+    sub     esp, 512
+    mov     edi, esp
+    .byte      0x0f, 0x0ae, 0x07 #fxsave [edi]
+
+#; UINT32  ExceptionData;
+    push    dword ptr [ebp + 2 * 4]
+
+#; call into exception handler
+    mov     eax, ExternalVectorTablePtr  # get the interrupt vectors base
+    or      eax, eax                        # NULL?
+    jz      nullExternalExceptionHandler
+
+    mov     ecx, [ebp + 4]
+    mov     eax, [eax + ecx * 4]
+    or      eax, eax                        # NULL?
+    jz      nullExternalExceptionHandler
+
+#; Prepare parameter and call
+    mov     edx, esp
+    push    edx
+    mov     edx, dword ptr [ebp + 1 * 4]
+    push    edx
+
+    #
+    # Call External Exception Handler
+    #
+    call    eax
+    add     esp, 8
+
+nullExternalExceptionHandler:
+
+    cli
+#; UINT32  ExceptionData;
+    add     esp, 4
+
+#; FX_SAVE_STATE_IA32 FxSaveState;
+    mov     esi, esp
+    .byte      0x0f, 0x0ae, 0x0e # fxrstor [esi]
+    add     esp, 512
+
+#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+    pop     eax
+    mov     dr0, eax
+    pop     eax
+    mov     dr1, eax
+    pop     eax
+    mov     dr2, eax
+    pop     eax
+    mov     dr3, eax
+#; skip restore of dr6.  We cleared dr6 during the context save.
+    add     esp, 4
+    pop     eax
+    mov     dr7, eax
+
+#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
+    pop     eax
+    mov     cr0, eax
+    add     esp, 4    # not for Cr1
+    pop     eax
+    mov     cr2, eax
+    pop     eax
+    mov     cr3, eax
+    pop     eax
+    mov     cr4, eax
+
+#; UINT32  EFlags;
+    pop     dword ptr [ebp + 5 * 4]
+
+#; UINT32  Ldtr, Tr;
+#; UINT32  Gdtr[2], Idtr[2];
+#; Best not let anyone mess with these particular registers...
+    add     esp, 24
+
+#; UINT32  Eip;
+    pop     dword ptr [ebp + 3 * 4]
+
+#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
+#; NOTE - modified segment registers could hang the debugger...  We
+#;        could attempt to insulate ourselves against this possibility,
+#;        but that poses risks as well.
+#;
+    pop     gs
+    pop     fs
+    pop     es
+    pop     ds
+    pop     dword ptr [ebp + 4 * 4]
+    pop     ss
+
+#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+    pop     edi
+    pop     esi
+    add     esp, 4   # not for ebp
+    add     esp, 4   # not for esp
+    pop     ebx
+    pop     edx
+    pop     ecx
+    pop     eax
+
+    mov     esp, ebp
+    pop     ebp
+    add     esp, 8
+    iretd
+
+
+#END
+