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