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