From: Jordan Justen <[email protected]>

TODO: Port to MASM
TODO: Remove unused GNU Assembler

The AP startup code simply jumps into this code with the CpuDxe driver
without setting up a stack for the processor.

Therefore, this code must setup the stack before calling into C code.

This is the basic flow:
* AP enters CpuDxe driver code (AsmApEntryPoint) without stack
  - AP grabs a lock
  - AP sets up stack
  - AP calls CpuMp.c:ApEntryPointInC
  - If ApEntryPointInC returns, the lock is freed, and another AP may
    run
  - The AP C code may call AsmApDoneWithCommonStack to indicate that
    the AP is no longer using the stack, and another may therefore
    proceed to use the stack and then call ApEntryPointInC

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <[email protected]>
---
 UefiCpuPkg/CpuDxe/CpuDxe.inf      |  2 ++
 UefiCpuPkg/CpuDxe/CpuMp.c         |  4 +++
 UefiCpuPkg/CpuDxe/CpuMp.h         | 13 ++++++++
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.S    | 62 +++++++++++++++++++++++++++++++++++++
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm | 64 +++++++++++++++++++++++++++++++++++++++
 UefiCpuPkg/CpuDxe/X64/MpAsm.S     | 62 +++++++++++++++++++++++++++++++++++++
 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm  | 64 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 271 insertions(+)
 create mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.S
 create mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
 create mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.S
 create mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index e49548f..d1903b0 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -53,11 +53,13 @@
   Ia32/CpuAsm.asm | MSFT
   Ia32/CpuAsm.asm | INTEL
   Ia32/CpuAsm.S   | GCC
+  Ia32/MpAsm.nasm
 
 [Sources.X64]
   X64/CpuAsm.asm | MSFT
   X64/CpuAsm.asm | INTEL
   X64/CpuAsm.S   | GCC
+  X64/MpAsm.nasm
 
 [Protocols]
   gEfiCpuArchProtocolGuid                       ## PRODUCES
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index a33265d..8cf711a 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -15,6 +15,10 @@
 #include "CpuDxe.h"
 #include "CpuMp.h"
 
+VOID *mCommonStack = 0;
+VOID *mTopOfApCommonStack = 0;
+
+
 /**
   Application Processor C code entry point
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index f42fcdc..687ddb9 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -23,5 +23,18 @@ VOID InitializeMpSupport (
   VOID
   );
 
+/**
+  The AP entry point that the Startup-IPI target code will jump to.
+
+  The processor jumps to this code in flat mode, but the processor's
+  stack is not initialized.
+
+**/
+VOID
+EFIAPI
+AsmApEntryPoint (
+  VOID
+  );
+
 #endif // _CPU_MP_H_
 
diff --git a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.S b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.S
new file mode 100644
index 0000000..2b3d298
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.S
@@ -0,0 +1,62 @@
+#
+#
+# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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.
+#
+#
+
+
+#
+# point to the external interrupt vector table
+#
+ApStackLock:
+    .long   0
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# AsmApEntryPoint (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmApEntryPoint)
+ASM_PFX(AsmApEntryPoint):
+    cli
+AsmApEntryPointAcquireLock:
+lock btsl   $0, ApStackLock
+    pause
+    jc      AsmApEntryPointAcquireLock
+
+    movl    (ASM_PFX(mTopOfApCommonStack)), %esp
+    call    ASM_PFX(ApEntryPointInC)
+
+    cli
+
+lock btcl   $0, ApStackLock
+
+    movl    $0x100, %eax
+AsmApEntryPointShareLock:
+    pause
+    decl    %eax
+    jnz     AsmApEntryPointShareLock
+
+    jmp     ASM_PFX(AsmApEntryPoint)
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# AsmApDoneWithCommonStack (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmApDoneWithCommonStack)
+ASM_PFX(AsmApDoneWithCommonStack):
+lock btcl   $0, ApStackLock
+    ret
+
diff --git a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm 
b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
new file mode 100644
index 0000000..2ecaa7f
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+; 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.
+;
+;------------------------------------------------------------------------------
+
+extern ASM_PFX(mTopOfApCommonStack)
+extern ASM_PFX(ApEntryPointInC)
+
+;
+; point to the external interrupt vector table
+;
+ApStackLock:
+    dd      0
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApEntryPoint (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApEntryPoint)
+ASM_PFX(AsmApEntryPoint):
+    cli
+AsmApEntryPointAcquireLock:
+lock bts    dword [ApStackLock], 0
+    pause
+    jc      AsmApEntryPointAcquireLock
+
+    mov     esp, [ASM_PFX(mTopOfApCommonStack)]
+    call    ASM_PFX(ApEntryPointInC)
+
+    cli
+
+lock btc    dword [ApStackLock], 0
+
+    mov     eax, 0x100
+AsmApEntryPointShareLock:
+    pause
+    dec     eax
+    jnz     AsmApEntryPointShareLock
+
+    jmp     ASM_PFX(AsmApEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApDoneWithCommonStack (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApDoneWithCommonStack)
+ASM_PFX(AsmApDoneWithCommonStack):
+lock btc    dword [ApStackLock], 0
+    ret
+
diff --git a/UefiCpuPkg/CpuDxe/X64/MpAsm.S b/UefiCpuPkg/CpuDxe/X64/MpAsm.S
new file mode 100644
index 0000000..cfad551
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/X64/MpAsm.S
@@ -0,0 +1,62 @@
+#
+#
+# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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.
+#
+#
+
+
+#
+# point to the external interrupt vector table
+#
+ApStackLock:
+    .long   0
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# AsmApEntryPoint (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmApEntryPoint)
+ASM_PFX(AsmApEntryPoint):
+    cli
+AsmApEntryPointAcquireLock:
+lock btsl   $0, ApStackLock
+    pause
+    jc      AsmApEntryPointAcquireLock
+
+    movq    (ASM_PFX(mTopOfApCommonStack)), %rsp
+    call    ASM_PFX(ApEntryPointInC)
+
+    cli
+
+lock btcl   $0, ApStackLock
+
+    movl    $0x100, %eax
+AsmApEntryPointShareLock:
+    pause
+    decl    %eax
+    jnz     AsmApEntryPointShareLock
+
+    jmp     ASM_PFX(AsmApEntryPoint)
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# AsmApDoneWithCommonStack (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmApDoneWithCommonStack)
+ASM_PFX(AsmApDoneWithCommonStack):
+lock btcl   $0, ApStackLock
+    ret
+
diff --git a/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm b/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
new file mode 100644
index 0000000..2323443
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+; 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.
+;
+;------------------------------------------------------------------------------
+
+extern ASM_PFX(mTopOfApCommonStack)
+extern ASM_PFX(ApEntryPointInC)
+
+;
+; point to the external interrupt vector table
+;
+ApStackLock:
+    dd      0
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApEntryPoint (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApEntryPoint)
+ASM_PFX(AsmApEntryPoint):
+    cli
+AsmApEntryPointAcquireLock:
+lock bts    dword [ApStackLock], 0
+    pause
+    jc      AsmApEntryPointAcquireLock
+
+    mov     rsp, [ASM_PFX(mTopOfApCommonStack)]
+    call    ASM_PFX(ApEntryPointInC)
+
+    cli
+
+lock btc    dword [ApStackLock], 0
+
+    mov     eax, 0x100
+AsmApEntryPointShareLock:
+    pause
+    dec     eax
+    jnz     AsmApEntryPointShareLock
+
+    jmp     ASM_PFX(AsmApEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApDoneWithCommonStack (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApDoneWithCommonStack)
+ASM_PFX(AsmApDoneWithCommonStack):
+lock btc    dword [ApStackLock], 0
+    ret
+
-- 
1.9.3


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to