49ba9447 |
1 | /** @file |
2 | Main SEC phase code. Transitions to PEI. |
3 | |
56d7640a |
4 | Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR> |
49ba9447 |
5 | |
56d7640a |
6 | This program and the accompanying materials |
49ba9447 |
7 | are licensed and made available under the terms and conditions of the BSD License |
8 | which accompanies this distribution. The full text of the license may be found at |
9 | http://opensource.org/licenses/bsd-license.php |
10 | |
11 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, |
12 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. |
13 | |
14 | **/ |
15 | |
16 | #include <PiPei.h> |
17 | #include <Library/BaseLib.h> |
18 | #include <Library/DebugLib.h> |
19 | #include <Library/BaseMemoryLib.h> |
c1c2669c |
20 | #include <Library/PeimEntryPoint.h> |
49ba9447 |
21 | #include <Library/PeiServicesLib.h> |
22 | #include <Ppi/TemporaryRamSupport.h> |
23 | #include <Library/PcdLib.h> |
284af948 |
24 | #include <Library/UefiCpuLib.h> |
49ba9447 |
25 | |
26 | #include "SecMain.h" |
27 | |
28 | EFI_STATUS |
29 | EFIAPI |
30 | TemporaryRamMigration ( |
31 | IN CONST EFI_PEI_SERVICES **PeiServices, |
32 | IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, |
33 | IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, |
34 | IN UINTN CopySize |
35 | ); |
36 | |
37 | STATIC TEMPORARY_RAM_SUPPORT_PPI mTempRamSupportPpi = { |
38 | (TEMPORARY_RAM_MIGRATION) TemporaryRamMigration |
39 | }; |
40 | |
41 | STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = { |
42 | { |
43 | (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), |
44 | &gEfiTemporaryRamSupportPpiGuid, |
45 | &mTempRamSupportPpi |
46 | }, |
47 | }; |
48 | |
49 | |
50 | VOID |
51 | InitializeIdtPtr ( |
52 | IN VOID* IdtPtr |
53 | ) |
54 | { |
55 | IA32_DESCRIPTOR IdtDescriptor; |
56 | |
57 | IdtDescriptor.Base = (UINTN)IdtPtr; |
58 | IdtDescriptor.Limit = (UINT16) 0; |
59 | AsmWriteIdtr (&IdtDescriptor); |
60 | } |
61 | |
62 | VOID |
63 | EFIAPI |
64 | SecCoreStartupWithStack ( |
c1c2669c |
65 | IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, |
0913fadc |
66 | IN VOID *TopOfCurrentStack |
49ba9447 |
67 | ) |
68 | { |
69 | EFI_SEC_PEI_HAND_OFF *SecCoreData; |
70 | UINT8 *BottomOfTempRam; |
71 | UINT8 *TopOfTempRam; |
72 | UINTN SizeOfTempRam; |
73 | VOID *IdtPtr; |
0913fadc |
74 | VOID *PeiCoreEntryPoint; |
49ba9447 |
75 | |
c1c2669c |
76 | DEBUG ((EFI_D_INFO, |
77 | "SecCoreStartupWithStack(0x%x, 0x%x)\n", |
78 | (UINT32)(UINTN)BootFv, |
79 | (UINT32)(UINTN)TopOfCurrentStack |
80 | )); |
81 | |
82 | ProcessLibraryConstructorList (NULL, NULL); |
83 | |
284af948 |
84 | // |
85 | // Initialize floating point operating environment |
86 | // to be compliant with UEFI spec. |
87 | // |
88 | InitializeFloatingPointUnits (); |
89 | |
49ba9447 |
90 | BottomOfTempRam = (UINT8*)(UINTN) INITIAL_TOP_OF_STACK; |
91 | SizeOfTempRam = (UINTN) SIZE_64KB; |
92 | TopOfTempRam = BottomOfTempRam + SizeOfTempRam; |
93 | |
94 | // |
95 | // |-------------| |
96 | // | SecCoreData | 4k |
97 | // |-------------| |
98 | // | Heap | 28k |
99 | // |-------------| |
100 | // | Stack | 32k |
101 | // |-------------| <---- INITIAL_TOP_OF_STACK |
102 | // |
103 | |
104 | // |
105 | // Bind this information into the SEC hand-off state |
106 | // |
107 | SecCoreData = (EFI_SEC_PEI_HAND_OFF*)((UINTN) TopOfTempRam - SIZE_4KB); |
108 | SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); |
109 | |
49ba9447 |
110 | SecCoreData->TemporaryRamBase = (VOID*) BottomOfTempRam; |
111 | SecCoreData->TemporaryRamSize = SizeOfTempRam; |
112 | |
113 | SecCoreData->PeiTemporaryRamSize = 28 * SIZE_1KB; |
114 | SecCoreData->PeiTemporaryRamBase = (VOID*)((UINTN)SecCoreData - SecCoreData->PeiTemporaryRamSize); |
115 | |
116 | SecCoreData->StackBase = SecCoreData->TemporaryRamBase; |
117 | SecCoreData->StackSize = (UINTN)SecCoreData->PeiTemporaryRamBase - (UINTN)SecCoreData->TemporaryRamBase; |
118 | |
119 | // |
120 | // Initialize the IDT Pointer, since IA32 & X64 architectures |
121 | // use it to store the PEI Services pointer. |
122 | // |
123 | IdtPtr = (VOID*)((UINT8*)SecCoreData + sizeof (*SecCoreData) + sizeof (UINTN)); |
124 | IdtPtr = ALIGN_POINTER(IdtPtr, 16); |
125 | InitializeIdtPtr (IdtPtr); |
126 | |
c1c2669c |
127 | FindPeiCoreEntryPoint (&BootFv, &PeiCoreEntryPoint); |
128 | |
129 | SecCoreData->BootFirmwareVolumeBase = BootFv; |
cb0a4290 |
130 | SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength; |
0913fadc |
131 | |
132 | if (PeiCoreEntryPoint != NULL) { |
133 | DEBUG ((EFI_D_INFO, |
134 | "Calling PEI Core entry point at 0x%x\n", |
135 | PeiCoreEntryPoint |
136 | )); |
137 | // |
138 | // Transfer control to the PEI Core |
139 | // |
140 | PeiSwitchStacks ( |
141 | (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint, |
142 | SecCoreData, |
143 | (VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &mPrivateDispatchTable), |
144 | NULL, |
145 | TopOfCurrentStack, |
146 | (VOID *)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize) |
147 | ); |
148 | } |
49ba9447 |
149 | |
150 | // |
0913fadc |
151 | // If we get here, then either we couldn't locate the PEI Core, or |
152 | // the PEI Core returned. |
153 | // |
154 | // Both of these errors are unrecoverable. |
49ba9447 |
155 | // |
156 | ASSERT (FALSE); |
157 | CpuDeadLoop (); |
158 | } |
159 | |
160 | EFI_STATUS |
161 | EFIAPI |
162 | TemporaryRamMigration ( |
163 | IN CONST EFI_PEI_SERVICES **PeiServices, |
164 | IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, |
165 | IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, |
166 | IN UINTN CopySize |
167 | ) |
168 | { |
169 | DEBUG ((EFI_D_ERROR, "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", (UINTN)TemporaryMemoryBase, (UINTN)PermanentMemoryBase, CopySize)); |
170 | |
171 | // |
172 | // Migrate the whole temporary memory to permenent memory. |
173 | // |
174 | CopyMem((VOID*)(UINTN)PermanentMemoryBase, (VOID*)(UINTN)TemporaryMemoryBase, CopySize); |
175 | |
176 | // |
177 | // SecSwitchStack function must be invoked after the memory migration |
178 | // immediatly, also we need fixup the stack change caused by new call into |
179 | // permenent memory. |
180 | // |
181 | SecSwitchStack ( |
182 | (UINTN) TemporaryMemoryBase, |
183 | (UINTN) PermanentMemoryBase, |
184 | CopySize |
185 | ); |
186 | |
187 | return EFI_SUCCESS; |
188 | } |
189 | |