]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
QuarkPlatformPkg/PlatformInit: Fix recovery detection issues
[mirror_edk2.git] / QuarkPlatformPkg / Platform / Pei / PlatformInit / MemoryCallback.c
CommitLineData
b303605e
MK
1/** @file\r
2This file includes a memory call back function notified when MRC is done,\r
3following action is performed in this file,\r
4 1. ICH initialization after MRC.\r
5 2. SIO initialization.\r
6 3. Install ResetSystem and FinvFv PPI.\r
7 4. Set MTRR for PEI\r
8 5. Create FV HOB and Flash HOB\r
9\r
a9054761 10Copyright (c) 2013 - 2016, Intel Corporation.\r
b303605e
MK
11\r
12This program and the accompanying materials\r
13are licensed and made available under the terms and conditions of the BSD License\r
14which accompanies this distribution. The full text of the license may be found at\r
15http://opensource.org/licenses/bsd-license.php\r
16\r
17THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
18WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
19\r
20**/\r
21\r
22\r
23#include "CommonHeader.h"\r
24\r
25#include "PlatformEarlyInit.h"\r
26\r
27extern EFI_PEI_PPI_DESCRIPTOR mPpiStall[];\r
28\r
29EFI_PEI_RESET_PPI mResetPpi = { ResetSystem };\r
30\r
31EFI_PEI_PPI_DESCRIPTOR mPpiList[1] = {\r
32 {\r
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
34 &gEfiPeiResetPpiGuid,\r
35 &mResetPpi\r
36 }\r
37};\r
38\r
39/**\r
40 This function reset the entire platform, including all processor and devices, and\r
41 reboots the system.\r
42\r
43 @param PeiServices General purpose services available to every PEIM.\r
44\r
45 @retval EFI_SUCCESS if it completed successfully.\r
46**/\r
47EFI_STATUS\r
48EFIAPI\r
49ResetSystem (\r
50 IN CONST EFI_PEI_SERVICES **PeiServices\r
51 )\r
52{\r
53 ResetCold();\r
54 return EFI_SUCCESS;\r
55}\r
56\r
57/**\r
58 This function provides a blocking stall for reset at least the given number of microseconds\r
59 stipulated in the final argument.\r
60\r
61 @param PeiServices General purpose services available to every PEIM.\r
62\r
63 @param this Pointer to the local data for the interface.\r
64\r
65 @param Microseconds number of microseconds for which to stall.\r
66\r
67 @retval EFI_SUCCESS the function provided at least the required stall.\r
68**/\r
69EFI_STATUS\r
70EFIAPI\r
71Stall (\r
72 IN CONST EFI_PEI_SERVICES **PeiServices,\r
73 IN CONST EFI_PEI_STALL_PPI *This,\r
74 IN UINTN Microseconds\r
75 )\r
76{\r
77 MicroSecondDelay (Microseconds);\r
78 return EFI_SUCCESS;\r
79}\r
80\r
81\r
82/**\r
83 This function will be called when MRC is done.\r
84\r
85 @param PeiServices General purpose services available to every PEIM.\r
86\r
87 @param NotifyDescriptor Information about the notify event..\r
88\r
89 @param Ppi The notify context.\r
90\r
91 @retval EFI_SUCCESS If the function completed successfully.\r
92**/\r
93EFI_STATUS\r
94EFIAPI\r
95MemoryDiscoveredPpiNotifyCallback (\r
96 IN EFI_PEI_SERVICES **PeiServices,\r
97 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
98 IN VOID *Ppi\r
99 )\r
100{\r
101 EFI_STATUS Status;\r
102 EFI_BOOT_MODE BootMode;\r
103 UINT64 MemoryLength;\r
104 EFI_SMRAM_DESCRIPTOR *SmramDescriptor;\r
105 UINTN NumSmramRegions;\r
106 UINT32 RmuMainBaseAddress;\r
107 UINT32 RegData32;\r
108 UINT8 CpuAddressWidth;\r
109 UINT32 RegEax;\r
110 MTRR_SETTINGS MtrrSettings;\r
a9054761
MK
111 EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;\r
112 UINT8 MorControl;\r
113 UINTN DataSize;\r
b303605e
MK
114\r
115 DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));\r
116\r
117 NumSmramRegions = 0;\r
118 SmramDescriptor = NULL;\r
119 RmuMainBaseAddress = 0;\r
120\r
121 PERF_START (NULL, "SetCache", NULL, 0);\r
122\r
123 InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);\r
124 ASSERT (SmramDescriptor != NULL);\r
125 ASSERT (RmuMainBaseAddress != 0);\r
126\r
127 MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;\r
128\r
129 Status = PeiServicesGetBootMode (&BootMode);\r
130 ASSERT_EFI_ERROR (Status);\r
131\r
132 //\r
133 // Get current MTRR settings\r
134 //\r
135 MtrrGetAllMtrrs (&MtrrSettings);\r
136\r
137 //\r
138 // Set all DRAM cachability to CacheWriteBack\r
139 //\r
140 Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);\r
141 ASSERT_EFI_ERROR (Status);\r
142\r
143 //\r
144 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE\r
145 // Workaround to make default SMRAM UnCachable\r
146 //\r
147 Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);\r
148 ASSERT_EFI_ERROR (Status);\r
149\r
150 //\r
151 // Set new MTRR settings\r
152 //\r
153 MtrrSetAllMtrrs (&MtrrSettings);\r
154\r
155 PERF_END (NULL, "SetCache", NULL, 0);\r
156\r
a9054761
MK
157 //\r
158 // Get necessary PPI\r
159 //\r
160 Status = PeiServicesLocatePpi (\r
161 &gEfiPeiReadOnlyVariable2PpiGuid, // GUID\r
162 0, // INSTANCE\r
163 NULL, // EFI_PEI_PPI_DESCRIPTOR\r
164 (VOID **)&VariableServices // PPI\r
165 );\r
166 ASSERT_EFI_ERROR (Status);\r
167\r
168 //\r
169 // Detect MOR request by the OS.\r
170 //\r
171 MorControl = 0;\r
172 DataSize = sizeof (MorControl);\r
173 Status = VariableServices->GetVariable (\r
174 VariableServices,\r
175 MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
176 &gEfiMemoryOverwriteControlDataGuid,\r
177 NULL,\r
178 &DataSize,\r
179 &MorControl\r
180 );\r
181 //\r
182 // If OS requested a memory overwrite perform it now for Embedded SRAM\r
183 //\r
184 if (MOR_CLEAR_MEMORY_VALUE (MorControl)) {\r
185 DEBUG ((EFI_D_INFO, "Clear Embedded SRAM per MOR request.\n"));\r
186 if (PcdGet32 (PcdESramMemorySize) > 0) {\r
187 if (PcdGet32 (PcdEsramStage1Base) == 0) {\r
188 //\r
189 // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.\r
190 // Clear byte at 0 and start clear operation at address 1.\r
191 //\r
192 *(UINT8 *)(0) = 0;\r
193 ZeroMem ((VOID *)1, (UINTN)PcdGet32 (PcdESramMemorySize) - 1);\r
194 } else {\r
195 ZeroMem (\r
196 (VOID *)(UINTN)PcdGet32 (PcdEsramStage1Base),\r
197 (UINTN)PcdGet32 (PcdESramMemorySize)\r
198 );\r
199 }\r
200 }\r
201 }\r
202\r
b303605e
MK
203 //\r
204 // Install PeiReset for PeiResetSystem service\r
205 //\r
206 Status = PeiServicesInstallPpi (&mPpiList[0]);\r
207 ASSERT_EFI_ERROR (Status);\r
208\r
209 //\r
210 // Do QNC initialization after MRC\r
211 //\r
212 PeiQNCPostMemInit ();\r
213\r
214 Status = PeiServicesInstallPpi (&mPpiStall[0]);\r
215 ASSERT_EFI_ERROR (Status);\r
216\r
217 //\r
218 // Set E000/F000 Routing\r
219 //\r
220 RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);\r
221 RegData32 |= (BIT2|BIT1);\r
222 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);\r
223\r
224 if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
225 Status = PeimInitializeRecovery (PeiServices);\r
226 ASSERT_EFI_ERROR (Status);\r
227 } else if (BootMode == BOOT_ON_S3_RESUME) {\r
228 return EFI_SUCCESS;\r
229 } else {\r
230 PeiServicesInstallFvInfoPpi (\r
231 NULL,\r
232 (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),\r
233 PcdGet32 (PcdFlashFvMainSize),\r
234 NULL,\r
235 NULL\r
236 );\r
237\r
238 //\r
239 // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV\r
240 // and produce Load File Protocols for UEFI Applications in this FV.\r
241 //\r
242 BuildFvHob (\r
243 PcdGet32 (PcdFlashFvMainBase),\r
244 PcdGet32 (PcdFlashFvMainSize)\r
245 );\r
246\r
247 //\r
248 // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV\r
249 // and produce Load File Protocols for UEFI Applications in this FV.\r
250 //\r
251 BuildFvHob (\r
252 PcdGet32 (PcdFlashFvPayloadBase),\r
253 PcdGet32 (PcdFlashFvPayloadSize)\r
254 );\r
255 }\r
256\r
257 //\r
258 // Build flash HOB, it's going to be used by GCD and E820 building\r
259 // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)\r
260 //\r
261 BuildResourceDescriptorHob (\r
262 EFI_RESOURCE_FIRMWARE_DEVICE,\r
263 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
264 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
265 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
266 (SIZE_4GB - SIZE_8MB),\r
267 SIZE_8MB\r
268 );\r
269\r
270 //\r
271 // Create a CPU hand-off information\r
272 //\r
273 CpuAddressWidth = 32;\r
274 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
275 if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {\r
276 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);\r
277 CpuAddressWidth = (UINT8) (RegEax & 0xFF);\r
278 }\r
279 DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));\r
280\r
281 BuildCpuHob (CpuAddressWidth, 16);\r
282\r
283 ASSERT_EFI_ERROR (Status);\r
284\r
285 return Status;\r
286}\r