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