]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuDxe: Switch Ap Stack to NewStack
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuMp.c
1 /** @file
2 CPU DXE Module.
3
4 Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "CpuDxe.h"
16 #include "CpuMp.h"
17
18 UINTN gMaxLogicalProcessorNumber;
19 UINTN gApStackSize;
20
21 VOID *mCommonStack = 0;
22 VOID *mTopOfApCommonStack = 0;
23 VOID *mApStackStart = 0;
24
25 volatile UINTN mNumberOfProcessors;
26
27 /**
28 Application Processors do loop routine
29 after switch to its own stack.
30
31 @param Context1 A pointer to the context to pass into the function.
32 @param Context2 A pointer to the context to pass into the function.
33
34 **/
35 VOID
36 ProcessorToIdleState (
37 IN VOID *Context1, OPTIONAL
38 IN VOID *Context2 OPTIONAL
39 )
40 {
41 DEBUG ((DEBUG_INFO, "Ap apicid is %d\n", GetApicId ()));
42
43 AsmApDoneWithCommonStack ();
44
45 CpuSleep ();
46 CpuDeadLoop ();
47 }
48
49 /**
50 Application Processor C code entry point.
51
52 **/
53 VOID
54 EFIAPI
55 ApEntryPointInC (
56 VOID
57 )
58 {
59 mNumberOfProcessors++;
60 mApStackStart = (UINT8*)mApStackStart + gApStackSize;
61
62 SwitchStack (
63 (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
64 NULL,
65 NULL,
66 mApStackStart);
67 }
68
69
70 /**
71 Initialize Multi-processor support.
72
73 **/
74 VOID
75 InitializeMpSupport (
76 VOID
77 )
78 {
79 gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
80 if (gMaxLogicalProcessorNumber < 1) {
81 DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
82 return;
83 }
84
85 if (gMaxLogicalProcessorNumber == 1) {
86 return;
87 }
88
89 gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);
90 ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);
91
92 mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
93 ASSERT (mApStackStart != NULL);
94
95 //
96 // the first buffer of stack size used for common stack, when the amount of AP
97 // more than 1, we should never free the common stack which maybe used for AP reset.
98 //
99 mCommonStack = mApStackStart;
100 mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;
101 mApStackStart = mTopOfApCommonStack;
102
103 mNumberOfProcessors = 1;
104
105 if (mNumberOfProcessors == 1) {
106 FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
107 return;
108 }
109
110 if (mNumberOfProcessors < gMaxLogicalProcessorNumber) {
111 FreePages (mApStackStart, EFI_SIZE_TO_PAGES ((gMaxLogicalProcessorNumber - mNumberOfProcessors) *
112 gApStackSize));
113 }
114 }