]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuDxe: introduce EFI_MP_SERVICES_PROTOCOL
[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 EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
28 NULL, // GetNumberOfProcessors,
29 NULL, // GetProcessorInfo,
30 NULL, // StartupAllAPs,
31 NULL, // StartupThisAP,
32 NULL, // SwitchBSP,
33 NULL, // EnableDisableAP,
34 NULL // WhoAmI
35 };
36
37 /**
38 Application Processors do loop routine
39 after switch to its own stack.
40
41 @param Context1 A pointer to the context to pass into the function.
42 @param Context2 A pointer to the context to pass into the function.
43
44 **/
45 VOID
46 ProcessorToIdleState (
47 IN VOID *Context1, OPTIONAL
48 IN VOID *Context2 OPTIONAL
49 )
50 {
51 DEBUG ((DEBUG_INFO, "Ap apicid is %d\n", GetApicId ()));
52
53 AsmApDoneWithCommonStack ();
54
55 CpuSleep ();
56 CpuDeadLoop ();
57 }
58
59 /**
60 Application Processor C code entry point.
61
62 **/
63 VOID
64 EFIAPI
65 ApEntryPointInC (
66 VOID
67 )
68 {
69 mNumberOfProcessors++;
70 mApStackStart = (UINT8*)mApStackStart + gApStackSize;
71
72 SwitchStack (
73 (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
74 NULL,
75 NULL,
76 mApStackStart);
77 }
78
79
80 /**
81 Initialize Multi-processor support.
82
83 **/
84 VOID
85 InitializeMpSupport (
86 VOID
87 )
88 {
89 gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
90 if (gMaxLogicalProcessorNumber < 1) {
91 DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
92 return;
93 }
94
95 if (gMaxLogicalProcessorNumber == 1) {
96 return;
97 }
98
99 gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);
100 ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);
101
102 mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
103 ASSERT (mApStackStart != NULL);
104
105 //
106 // the first buffer of stack size used for common stack, when the amount of AP
107 // more than 1, we should never free the common stack which maybe used for AP reset.
108 //
109 mCommonStack = mApStackStart;
110 mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;
111 mApStackStart = mTopOfApCommonStack;
112
113 mNumberOfProcessors = 1;
114
115 if (mNumberOfProcessors == 1) {
116 FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
117 return;
118 }
119
120 if (mNumberOfProcessors < gMaxLogicalProcessorNumber) {
121 FreePages (mApStackStart, EFI_SIZE_TO_PAGES ((gMaxLogicalProcessorNumber - mNumberOfProcessors) *
122 gApStackSize));
123 }
124 }