]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
QuarkSocPkg: QNCInit/Dxe: remove set but unused variables
[mirror_edk2.git] / QuarkSocPkg / QuarkNorthCluster / QNCInit / Dxe / QNCInit.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2QuarkNcSocId module initialization module\r
3\r
4Copyright (c) 2013-2015 Intel Corporation.\r
5\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15#include "CommonHeader.h"\r
16\r
17#include "LegacyRegion.h"\r
18#include "DxeQNCSmbus.h"\r
19\r
20#include "QNCInit.h"\r
21\r
22//\r
23// Definitions\r
24//\r
25#define QNC_RESERVED_ITEM_IO 0\r
26#define QNC_RESERVED_ITEM_MEMORYIO 1\r
27#define DXE_DEVICE_DISABLED 0\r
28#define DXE_DEVICE_ENABLED 1\r
29\r
30typedef struct _QNC_SPACE_TABLE_ITEM {\r
31 UINTN IoOrMemory;\r
32 UINTN Type;\r
33 EFI_PHYSICAL_ADDRESS BaseAddress;\r
34 UINT64 Length;\r
35 UINTN Alignment;\r
36 BOOLEAN RuntimeOrNot;\r
37} QNC_SPACE_TABLE_ITEM;\r
38\r
39typedef struct {\r
40 ACPI_CPU_DATA AcpuCpuData;\r
41 MTRR_SETTINGS MtrrTable;\r
42 IA32_DESCRIPTOR GdtrProfile;\r
43 IA32_DESCRIPTOR IdtrProfile;\r
44 CPU_REGISTER_TABLE RegisterTable;\r
45 CPU_REGISTER_TABLE PreSmmInitRegisterTable;\r
46} ACPI_CPU_DATA_EX;\r
47\r
48//\r
49// Spaces to be reserved in GCD\r
50// Expand it to add more\r
51//\r
52const QNC_SPACE_TABLE_ITEM mQNCReservedSpaceTable[] = {\r
53 {\r
54 QNC_RESERVED_ITEM_MEMORYIO,\r
55 EfiGcdMemoryTypeMemoryMappedIo,\r
56 FixedPcdGet64 (PcdIoApicBaseAddress),\r
57 FixedPcdGet64 (PcdIoApicSize),\r
58 0,\r
59 FALSE\r
60 },\r
61 {\r
62 QNC_RESERVED_ITEM_MEMORYIO,\r
63 EfiGcdMemoryTypeMemoryMappedIo,\r
64 FixedPcdGet64 (PcdHpetBaseAddress),\r
65 FixedPcdGet64 (PcdHpetSize),\r
66 0,\r
67 FALSE\r
68 }\r
69};\r
70\r
71//\r
72// Global variable for ImageHandle of QNCInit driver\r
73//\r
74EFI_HANDLE gQNCInitImageHandle;\r
75QNC_DEVICE_ENABLES mQNCDeviceEnables;\r
76\r
77\r
78VOID\r
79QNCInitializeResource (\r
80 VOID\r
81 );\r
82\r
83EFI_STATUS\r
84InitializeQNCPolicy (\r
85 VOID\r
86 );\r
87\r
88/**\r
89 Allocate EfiACPIMemoryNVS below 4G memory address.\r
90\r
91 This function allocates EfiACPIMemoryNVS below 4G memory address.\r
92\r
93 @param Size Size of memory to allocate.\r
94\r
95 @return Allocated address for output.\r
96\r
97**/\r
98VOID *\r
99AllocateAcpiNvsMemoryBelow4G (\r
100 IN UINTN Size\r
101 )\r
102{\r
103 UINTN Pages;\r
104 EFI_PHYSICAL_ADDRESS Address;\r
105 EFI_STATUS Status;\r
106 VOID* Buffer;\r
107\r
108 Pages = EFI_SIZE_TO_PAGES (Size);\r
109 Address = 0xffffffff;\r
110\r
111 Status = gBS->AllocatePages (\r
112 AllocateMaxAddress,\r
113 EfiACPIMemoryNVS,\r
114 Pages,\r
115 &Address\r
116 );\r
117 if (EFI_ERROR (Status)) {\r
118 return NULL;\r
119 }\r
120\r
121 Buffer = (VOID *) (UINTN) Address;\r
122 ZeroMem (Buffer, Size);\r
123\r
124 return Buffer;\r
125}\r
126\r
127/**\r
128 Prepare ACPI NVS memory below 4G memory for use of S3 resume.\r
129\r
130 This function allocates ACPI NVS memory below 4G memory for use of S3 resume,\r
131 and saves data into the memory region.\r
132\r
133**/\r
134VOID\r
135SaveCpuS3Data (\r
136 VOID\r
137 )\r
138{\r
139 EFI_STATUS Status;\r
140 ACPI_CPU_DATA_EX *AcpiCpuDataEx;\r
141 ACPI_CPU_DATA *AcpiCpuData;\r
142 UINTN GdtSize;\r
143 UINTN IdtSize;\r
144 VOID *Gdt;\r
145 VOID *Idt;\r
146\r
147 //\r
148 // Allocate ACPI NVS memory below 4G memory for use of S3 resume.\r
149 //\r
150 AcpiCpuDataEx = AllocateAcpiNvsMemoryBelow4G (sizeof (ACPI_CPU_DATA_EX));\r
151 AcpiCpuData = &AcpiCpuDataEx->AcpuCpuData;\r
152\r
153 //\r
154 //\r
155 //\r
156 AcpiCpuData->NumberOfCpus = 1;\r
157 AcpiCpuData->StackSize = PcdGet32 (PcdCpuApStackSize);\r
158 AcpiCpuData->ApMachineCheckHandlerBase = 0;\r
159 AcpiCpuData->ApMachineCheckHandlerSize = 0;\r
160 AcpiCpuData->GdtrProfile = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->GdtrProfile;\r
161 AcpiCpuData->IdtrProfile = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->IdtrProfile;\r
162 AcpiCpuData->MtrrTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->MtrrTable;\r
163 AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->RegisterTable;\r
164 AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->PreSmmInitRegisterTable;\r
165\r
166 //\r
167 // Allocate stack space for all CPUs\r
168 //\r
169 AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateAcpiNvsMemoryBelow4G (AcpiCpuData->NumberOfCpus * AcpiCpuData->StackSize);\r
170\r
171 //\r
172 // Get MTRR settings from currently executing CPU\r
173 //\r
174 MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);\r
175\r
176 //\r
177 // Get the BSP's data of GDT and IDT\r
178 //\r
179 AsmReadGdtr ((IA32_DESCRIPTOR *) &AcpiCpuDataEx->GdtrProfile);\r
180 AsmReadIdtr ((IA32_DESCRIPTOR *) &AcpiCpuDataEx->IdtrProfile);\r
181\r
182 //\r
183 // Allocate GDT and IDT in ACPI NVS and copy in current GDT and IDT contents\r
184 //\r
185 GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;\r
186 IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;\r
187 Gdt = AllocateAcpiNvsMemoryBelow4G (GdtSize + IdtSize);\r
188 Idt = (VOID *)((UINTN)Gdt + GdtSize);\r
189 CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize);\r
190 CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize);\r
191 AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt;\r
192 AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt;\r
193\r
194 //\r
195 // No RegisterTable entries\r
196 //\r
197 AcpiCpuDataEx->RegisterTable.TableLength = 0;\r
198\r
199 //\r
200 // No PreSmmInitRegisterTable entries\r
201 //\r
202 AcpiCpuDataEx->PreSmmInitRegisterTable.TableLength = 0;\r
203\r
204 //\r
205 // Set the base address of CPU S3 data to PcdCpuS3DataAddress\r
206 //\r
207 Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);\r
208 ASSERT_EFI_ERROR (Status);\r
209}\r
210\r
211/**\r
212 The entry function for QNCInit driver.\r
213\r
214 This function just call initialization function for PciHostBridge,\r
215 LegacyRegion and QNCSmmAccess module.\r
216\r
217 @param ImageHandle The driver image handle for GmchInit driver\r
218 @param SystemTable The pointer to System Table\r
219\r
220 @retval EFI_SUCCESS Success to initialize every module for GMCH driver.\r
221 @return EFI_STATUS The status of initialization work.\r
222\r
223**/\r
224EFI_STATUS\r
225EFIAPI\r
226QNCInit (\r
227 IN EFI_HANDLE ImageHandle,\r
228 IN EFI_SYSTEM_TABLE *SystemTable\r
229 )\r
230{\r
231 EFI_STATUS Status;\r
232\r
233 S3BootScriptSaveInformationAsciiString (\r
234 "QNCInitDxeEntryBegin"\r
235 );\r
236\r
237 gQNCInitImageHandle = ImageHandle;\r
238\r
239 mQNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);\r
240\r
241\r
242 //\r
243 // Initialize PCIE root ports\r
244 //\r
245 Status = QncInitRootPorts ();\r
246 if (EFI_ERROR (Status)) {\r
247 DEBUG ((EFI_D_ERROR, "QNC Root Port initialization is failed!\n"));\r
248 return Status;\r
249 }\r
250\r
251 Status = LegacyRegionInit ();\r
252 if (EFI_ERROR (Status)) {\r
253 DEBUG ((EFI_D_ERROR, "QNC LegacyRegion initialization is failed!\n"));\r
254 return Status;\r
255 }\r
256\r
257\r
258 Status = InitializeQNCPolicy ();\r
259 if (EFI_ERROR (Status)) {\r
260 DEBUG ((EFI_D_ERROR, "QNC Policy initialization is failed!\n"));\r
261 return Status;\r
262 }\r
263\r
264 Status = InitializeQNCSmbus (ImageHandle,SystemTable);\r
265 if (EFI_ERROR (Status)) {\r
266 DEBUG ((EFI_D_ERROR, "QNC Smbus driver is failed!\n"));\r
267 return Status;\r
268 }\r
269\r
270 QNCInitializeResource ();\r
271\r
272 SaveCpuS3Data ();\r
273\r
274 S3BootScriptSaveInformationAsciiString (\r
275 "QNCInitDxeEntryEnd"\r
276 );\r
277\r
278 return EFI_SUCCESS;\r
279}\r
280\r
281\r
282/**\r
283 Reserve I/O or memory space in GCD\r
284\r
285 @param IoOrMemory Switch of I/O or memory.\r
286 @param GcdType Type of the space.\r
287 @param BaseAddress Base address of the space.\r
288 @param Length Length of the space.\r
289 @param Alignment Align with 2^Alignment\r
290 @param RuntimeOrNot For runtime usage or not\r
291 @param ImageHandle Handle for the image of this driver.\r
292\r
293 @retval EFI_SUCCESS Reserve successful\r
294**/\r
295EFI_STATUS\r
296QNCReserveSpaceInGcd(\r
297 IN UINTN IoOrMemory,\r
298 IN UINTN GcdType,\r
299 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
300 IN UINT64 Length,\r
301 IN UINTN Alignment,\r
302 IN BOOLEAN RuntimeOrNot,\r
303 IN EFI_HANDLE ImageHandle\r
304 )\r
305{\r
306 EFI_STATUS Status;\r
307\r
308 if (IoOrMemory == QNC_RESERVED_ITEM_MEMORYIO) {\r
309 Status = gDS->AddMemorySpace (\r
310 GcdType,\r
311 BaseAddress,\r
312 Length,\r
313 EFI_MEMORY_UC\r
314 );\r
315 if (EFI_ERROR (Status)) {\r
316 DEBUG ((\r
317 EFI_D_ERROR,\r
318 "Failed to add memory space :0x%x 0x%x\n",\r
319 BaseAddress,\r
320 Length\r
321 ));\r
322 }\r
323 ASSERT_EFI_ERROR (Status);\r
324 Status = gDS->AllocateMemorySpace (\r
325 EfiGcdAllocateAddress,\r
326 GcdType,\r
327 Alignment,\r
328 Length,\r
329 &BaseAddress,\r
330 ImageHandle,\r
331 NULL\r
332 );\r
333 ASSERT_EFI_ERROR (Status);\r
334 if (RuntimeOrNot) {\r
335 Status = gDS->SetMemorySpaceAttributes (\r
336 BaseAddress,\r
337 Length,\r
338 EFI_MEMORY_RUNTIME | EFI_MEMORY_UC\r
339 );\r
340 ASSERT_EFI_ERROR (Status);\r
341 }\r
342 } else {\r
343 Status = gDS->AddIoSpace (\r
344 GcdType,\r
345 BaseAddress,\r
346 Length\r
347 );\r
348 ASSERT_EFI_ERROR (Status);\r
349 Status = gDS->AllocateIoSpace (\r
350 EfiGcdAllocateAddress,\r
351 GcdType,\r
352 Alignment,\r
353 Length,\r
354 &BaseAddress,\r
355 ImageHandle,\r
356 NULL\r
357 );\r
358 ASSERT_EFI_ERROR (Status);\r
359 }\r
360 return Status;\r
361}\r
362\r
363\r
364/**\r
365 Initialize the memory and io resource which belong to QNC.\r
366 1) Report and allocate all BAR's memory to GCD.\r
367 2) Report PCI memory and I/O space to GCD.\r
368 3) Set memory attribute for <1M memory space.\r
369**/\r
370VOID\r
371QNCInitializeResource (\r
372 )\r
373{\r
374 EFI_PHYSICAL_ADDRESS BaseAddress;\r
375 EFI_STATUS Status;\r
376 UINT64 ExtraRegionLength;\r
377 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;\r
378 UINTN Index;\r
379\r
380 // Report TSEG range\r
381 // This range maybe has been reportted in PEI phase via Resource Hob.\r
382 //\r
383 QNCGetTSEGMemoryRange (&BaseAddress, &ExtraRegionLength);\r
384 if (ExtraRegionLength != 0) {\r
385 Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &Descriptor);\r
386 if (Status == EFI_NOT_FOUND) {\r
387 Status = gDS->AddMemorySpace (\r
388 EfiGcdMemoryTypeReserved,\r
389 BaseAddress,\r
390 ExtraRegionLength,\r
391 EFI_MEMORY_UC\r
392 );\r
393 }\r
394 }\r
395\r
396 //\r
397 // < 1M resource setting. The memory ranges <1M has been added into GCD via\r
398 // resource hob produced by PEI phase. Here will set memory attribute of these\r
399 // ranges for DXE phase.\r
400 //\r
401\r
402 //\r
403 // Dos Area (0 ~ 0x9FFFFh)\r
404 //\r
405 Status = gDS->GetMemorySpaceDescriptor (0, &Descriptor);\r
406 DEBUG ((\r
407 EFI_D_INFO,\r
408 "DOS Area Memory: base = 0x%x, length = 0x%x, attribute = 0x%x\n",\r
409 Descriptor.BaseAddress,\r
410 Descriptor.Length,\r
411 Descriptor.Attributes\r
412 ));\r
413 ASSERT_EFI_ERROR (Status);\r
414 Status = gDS->SetMemorySpaceAttributes(\r
415 0,\r
416 0xA0000,\r
417 EFI_MEMORY_WB\r
418 );\r
419 ASSERT_EFI_ERROR (Status);\r
420\r
421 //\r
422 // Default SMRAM UnCachable until SMBASE relocated.\r
423 //\r
424 Status = gDS->SetMemorySpaceAttributes(\r
425 0x30000,\r
426 0x10000,\r
427 EFI_MEMORY_UC\r
428 );\r
429 ASSERT_EFI_ERROR (Status);\r
430\r
431 //\r
432 // Default SMM ABSEG area. (0xA0000 ~ 0xBFFFF)\r
433 //\r
434 Status = gDS->GetMemorySpaceDescriptor (0xA0000, &Descriptor);\r
435 DEBUG ((\r
436 EFI_D_INFO,\r
437 "ABSEG Memory: base = 0x%x, length = 0x%x, attribute = 0x%x\n",\r
438 Descriptor.BaseAddress,\r
439 Descriptor.Length,\r
440 Descriptor.Attributes\r
441 ));\r
442 ASSERT_EFI_ERROR (Status);\r
443 Status = gDS->SetMemorySpaceAttributes(\r
444 0xA0000,\r
445 0x20000,\r
446 EFI_MEMORY_UC\r
447 );\r
448 ASSERT_EFI_ERROR (Status);\r
449\r
450 //\r
451 // Expansion BIOS area.\r
452 //\r
453 Status = gDS->GetMemorySpaceDescriptor (0xC0000, &Descriptor);\r
454 DEBUG ((\r
455 EFI_D_INFO,\r
456 "Memory base = 0x%x, length = 0x%x, attribute = 0x%x\n",\r
457 Descriptor.BaseAddress,\r
458 Descriptor.Length,\r
459 Descriptor.Attributes\r
460 ));\r
461 ASSERT_EFI_ERROR (Status);\r
462 Status = gDS->SetMemorySpaceAttributes(\r
463 0xC0000,\r
464 0x30000,\r
465 EFI_MEMORY_UC\r
466 );\r
467 ASSERT_EFI_ERROR (Status);\r
468\r
469 //\r
470 // Report other IO resources from mQNCReservedSpaceTable in GCD\r
471 //\r
472 for (Index = 0; Index < sizeof (mQNCReservedSpaceTable) / sizeof (QNC_SPACE_TABLE_ITEM); Index++) {\r
473 Status = QNCReserveSpaceInGcd (\r
474 mQNCReservedSpaceTable[Index].IoOrMemory,\r
475 mQNCReservedSpaceTable[Index].Type,\r
476 mQNCReservedSpaceTable[Index].BaseAddress,\r
477 mQNCReservedSpaceTable[Index].Length,\r
478 mQNCReservedSpaceTable[Index].Alignment,\r
479 mQNCReservedSpaceTable[Index].RuntimeOrNot,\r
480 gQNCInitImageHandle\r
481 );\r
482 ASSERT_EFI_ERROR (Status);\r
483 }\r
484\r
485 //\r
486 // Report unused PCIe config space as reserved.\r
487 //\r
488 if (PcdGet64 (PcdPciExpressSize) < SIZE_256MB) {\r
489 Status = QNCReserveSpaceInGcd (\r
490 QNC_RESERVED_ITEM_MEMORYIO,\r
491 EfiGcdMemoryTypeMemoryMappedIo,\r
492 (PcdGet64(PcdPciExpressBaseAddress) + PcdGet64(PcdPciExpressSize)),\r
493 (SIZE_256MB - PcdGet64(PcdPciExpressSize)),\r
494 0,\r
495 FALSE,\r
496 gQNCInitImageHandle\r
497 );\r
498 ASSERT_EFI_ERROR (Status);\r
499 }\r
500}\r
501\r
502/**\r
503 Use the platform PCD to initialize devices in the QNC\r
504\r
505 @param ImageHandle Handle for the image of this driver.\r
506 @retval EFI_SUCCESS Initialize successful\r
507**/\r
508EFI_STATUS\r
509InitializeQNCPolicy (\r
510 )\r
511{\r
9b6bbcdb
MK
512 UINT32 PciD31F0RegBase; // LPC\r
513\r
9b6bbcdb
MK
514 PciD31F0RegBase = PciDeviceMmBase (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC);\r
515\r
516 //\r
517 // Disable for smbus\r
518 //\r
519 if (mQNCDeviceEnables.Bits.Smbus == DXE_DEVICE_DISABLED) {\r
520 S3MmioAnd32 (PciD31F0RegBase + R_QNC_LPC_SMBUS_BASE, (~B_QNC_LPC_SMBUS_BASE_EN));\r
521 }\r
522\r
523 return EFI_SUCCESS;\r
524}\r