summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2009-05-27 21:09:47 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2009-05-27 21:09:47 +0000
commita47463f28382bffcedacde0d96965977261d114a (patch)
treeb526ec8f21e4a8a958957ccedb5eb1e0a56c45f7 /UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
parente50466da24377199d405f9ee6ac44b293f4548ae (diff)
downloadedk2-a47463f28382bffcedacde0d96965977261d114a.tar.gz
edk2-a47463f28382bffcedacde0d96965977261d114a.tar.bz2
edk2-a47463f28382bffcedacde0d96965977261d114a.zip
Add CPU DXE driver for IA32 & X64 processor architectures.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8395 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S')
-rwxr-xr-xUefiCpuPkg/CpuDxe/Ia32/CpuAsm.S395
1 files changed, 395 insertions, 0 deletions
diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
new file mode 100755
index 0000000000..69fe215637
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
@@ -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
+