]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
QuarkPlatformPkg: Add new package for Galileo boards
[mirror_edk2.git] / QuarkPlatformPkg / Acpi / Dxe / AcpiPlatform / AcpiPlatform.c
1 /** @file
2 ACPI Platform Driver
3
4 Copyright (c) 2013-2015 Intel Corporation.
5
6 This program and the accompanying materials
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 <Protocol/AcpiTable.h>
17 #include <IndustryStandard/Pci22.h>
18 #include "AcpiPlatform.h"
19
20 //
21 // Global Variable
22 //
23 EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea;
24 EFI_ACPI_SDT_PROTOCOL *mAcpiSdt;
25
26 EFI_ACPI_HANDLE mDsdtHandle = NULL;
27
28
29 EFI_STATUS
30 LocateSupportProtocol (
31 IN EFI_GUID *Protocol,
32 OUT VOID **Instance,
33 IN UINT32 Type
34 )
35 /*++
36
37 Routine Description:
38
39 Locate the first instance of a protocol. If the protocol requested is an
40 FV protocol, then it will return the first FV that contains the ACPI table
41 storage file.
42
43 Arguments:
44
45 Protocol The protocol to find.
46 Instance Return pointer to the first instance of the protocol
47
48 Returns:
49
50 EFI_SUCCESS The function completed successfully.
51 EFI_NOT_FOUND The protocol could not be located.
52 EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
53
54 --*/
55 {
56 EFI_STATUS Status;
57 EFI_HANDLE *HandleBuffer;
58 UINTN NumberOfHandles;
59 EFI_FV_FILETYPE FileType;
60 UINT32 FvStatus;
61 EFI_FV_FILE_ATTRIBUTES Attributes;
62 UINTN Size;
63 UINTN i;
64
65 FvStatus = 0;
66
67 //
68 // Locate protocol.
69 //
70 Status = gBS->LocateHandleBuffer (
71 ByProtocol,
72 Protocol,
73 NULL,
74 &NumberOfHandles,
75 &HandleBuffer
76 );
77 if (EFI_ERROR (Status)) {
78
79 //
80 // Defined errors at this time are not found and out of resources.
81 //
82 return Status;
83 }
84
85
86
87 //
88 // Looking for FV with ACPI storage file
89 //
90
91 for (i = 0; i < NumberOfHandles; i++) {
92 //
93 // Get the protocol on this handle
94 // This should not fail because of LocateHandleBuffer
95 //
96 Status = gBS->HandleProtocol (
97 HandleBuffer[i],
98 Protocol,
99 Instance
100 );
101 ASSERT_EFI_ERROR (Status);
102
103 if (!Type) {
104 //
105 // Not looking for the FV protocol, so find the first instance of the
106 // protocol. There should not be any errors because our handle buffer
107 // should always contain at least one or LocateHandleBuffer would have
108 // returned not found.
109 //
110 break;
111 }
112
113 //
114 // See if it has the ACPI storage file
115 //
116
117 Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL*) (*Instance))->ReadFile (*Instance,
118 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
119 NULL,
120 &Size,
121 &FileType,
122 &Attributes,
123 &FvStatus
124 );
125
126 //
127 // If we found it, then we are done
128 //
129 if (Status == EFI_SUCCESS) {
130 break;
131 }
132 }
133
134 //
135 // Our exit status is determined by the success of the previous operations
136 // If the protocol was found, Instance already points to it.
137 //
138
139 //
140 // Free any allocated buffers
141 //
142 gBS->FreePool (HandleBuffer);
143
144 return Status;
145 }
146
147
148 VOID
149 DsdtTableUpdate (
150 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
151 IN OUT EFI_ACPI_TABLE_VERSION *Version
152 )
153 /*++
154
155 Routine Description:
156
157 Update the DSDT table
158
159 Arguments:
160
161 Table - The table to be set
162 Version - Version to publish
163
164 Returns:
165
166 None
167
168 --*/
169 {
170
171 UINT8 *CurrPtr;
172 UINT8 *DsdtPointer;
173 UINT32 *Signature;
174 UINT8 *Operation;
175 UINT32 *Address;
176 UINT16 *Size;
177 //
178 // Loop through the ASL looking for values that we must fix up.
179 //
180 CurrPtr = (UINT8 *) TableHeader;
181 for (DsdtPointer = CurrPtr;
182 DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
183 DsdtPointer++
184 )
185 {
186 Signature = (UINT32 *) DsdtPointer;
187 switch (*Signature) {
188 //
189 // MNVS operation region
190 //
191 case (SIGNATURE_32 ('M', 'N', 'V', 'S')):
192 //
193 // Conditional match. For Region Objects, the Operator will always be the
194 // byte immediately before the specific name. Therefore, subtract 1 to check
195 // the Operator.
196 //
197 Operation = DsdtPointer - 1;
198 if (*Operation == AML_OPREGION_OP) {
199 Address = (UINT32 *) (DsdtPointer + 6);
200 *Address = (UINT32) (UINTN) mGlobalNvsArea.Area;
201 Size = (UINT16 *) (DsdtPointer + 11);
202 *Size = sizeof (EFI_GLOBAL_NVS_AREA);
203 }
204 break;
205
206 //
207 // Update processor PBLK register I/O base address
208 //
209 case (SIGNATURE_32 ('P', 'R', 'I', 'O')):
210 //
211 // Conditional match. Update the following ASL code:
212 // Processor (CPU0, 0x01, 0x4F495250, 0x06) {}
213 // The 3rd parameter will be updated to the actual PBLK I/O base address.
214 // the Operator.
215 //
216 Operation = DsdtPointer - 8;
217 if ((*Operation == AML_EXT_OP) && (*(Operation + 1) == AML_EXT_PROCESSOR_OP)) {
218 *(UINT32 *)DsdtPointer = PcdGet16(PcdPmbaIoBaseAddress);
219 }
220 break;
221 default:
222 break;
223 }
224 }
225 }
226
227
228 VOID
229 ApicTableUpdate (
230 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
231 IN OUT EFI_ACPI_TABLE_VERSION *Version
232 )
233 /*++
234
235 Routine Description:
236
237 Update the processors information in the APIC table
238
239 Arguments:
240
241 Table - The table to be set
242 Version - Version to publish
243
244 Returns:
245
246 None
247
248 --*/
249 {
250 EFI_STATUS Status;
251 EFI_MP_SERVICES_PROTOCOL *MpService;
252 UINT8 *CurrPtr;
253 UINT8 *EndPtr;
254 UINT8 CurrIoApic;
255 UINT8 CurrProcessor;
256 UINTN NumberOfCPUs;
257 UINTN NumberOfEnabledCPUs;
258 UINTN BufferSize;
259 EFI_PROCESSOR_INFORMATION MpContext;
260 ACPI_APIC_STRUCTURE_PTR *ApicPtr;
261
262 CurrIoApic = 0;
263 CurrProcessor = 0;
264 //
265 // Find the MP Protocol. This is an MP platform, so MP protocol must be
266 // there.
267 //
268 Status = gBS->LocateProtocol (
269 &gEfiMpServiceProtocolGuid,
270 NULL,
271 (VOID**)&MpService
272 );
273 if (EFI_ERROR (Status)) {
274 //
275 // Failed to get MP information, doesn't publish the invalid table
276 //
277 *Version = EFI_ACPI_TABLE_VERSION_NONE;
278 return;
279 }
280
281 //
282 // Determine the number of processors
283 //
284 MpService->GetNumberOfProcessors (
285 MpService,
286 &NumberOfCPUs,
287 &NumberOfEnabledCPUs
288 );
289
290 CurrPtr = (UINT8*) &(TableHeader[1]);
291 CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag
292 EndPtr = (UINT8*) TableHeader;
293 EndPtr = EndPtr + TableHeader->Length;
294
295 while (CurrPtr < EndPtr) {
296
297 ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr;
298 switch (ApicPtr->AcpiApicCommon.Type) {
299
300 case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC:
301 BufferSize = sizeof (EFI_PROCESSOR_INFORMATION);
302 ApicPtr->AcpiLocalApic.Flags = 0;
303 ApicPtr->AcpiLocalApic.ApicId = 0;
304 Status = MpService->GetProcessorInfo (
305 MpService,
306 CurrProcessor,
307 &MpContext
308 );
309
310 if (!EFI_ERROR (Status)) {
311 if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) {
312 ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED;
313 }
314 ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId;
315 }
316 CurrProcessor++;
317 break;
318
319 case EFI_ACPI_1_0_IO_APIC:
320 //
321 // IO APIC entries can be patched here
322 //
323 if (CurrIoApic == 0) {
324 //
325 // Update SOC internel IOAPIC base
326 //
327 ApicPtr->AcpiIoApic.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId);
328 ApicPtr->AcpiIoApic.IoApicAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);
329 ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0;
330 } else {
331 //
332 // Porting is required to update other IOAPIC entries if available
333 //
334 ASSERT (0);
335 }
336 CurrIoApic++;
337 break;
338
339 default:
340 break;
341 };
342 CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
343 }
344 }
345
346 VOID
347 AcpiUpdateTable (
348 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
349 IN OUT EFI_ACPI_TABLE_VERSION *Version
350 )
351 /*++
352
353 Routine Description:
354
355 Set the correct table revision upon the setup value
356
357 Arguments:
358
359 Table - The table to be set
360 Version - Version to publish
361
362 Returns:
363
364 None
365
366 --*/
367
368 {
369 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader1;
370 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader2;
371 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader3;
372 EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *AllocationStructurePtr;
373
374 if (TableHeader != NULL && Version != NULL) {
375
376 *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
377 //
378 // Here we use all 3.0 signature because all version use same signature if they supported
379 //
380 switch (TableHeader->Signature) {
381 //
382 // "APIC" Multiple APIC Description Table
383 //
384 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
385 ApicTableUpdate (TableHeader, Version);
386 break;
387 //
388 // "DSDT" Differentiated System Description Table
389 //
390 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
391 DsdtTableUpdate (TableHeader, Version);
392 break;
393
394 //
395 // "FACP" Fixed ACPI Description Table (FADT)
396 //
397 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
398 *Version = EFI_ACPI_TABLE_VERSION_NONE;
399 if (TableHeader->Revision == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
400 *Version = EFI_ACPI_TABLE_VERSION_1_0B;
401 FadtHeader1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
402 FadtHeader1->SmiCmd = PcdGet16(PcdSmmActivationPort);
403 FadtHeader1->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
404 FadtHeader1->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
405 FadtHeader1->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
406 FadtHeader1->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);
407 } else if (TableHeader->Revision == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
408 *Version = EFI_ACPI_TABLE_VERSION_2_0;
409 FadtHeader2 = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
410 FadtHeader2->SmiCmd = PcdGet16(PcdSmmActivationPort);
411 FadtHeader2->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
412 FadtHeader2->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
413 FadtHeader2->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
414 FadtHeader2->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);
415 FadtHeader2->XPm1aEvtBlk.Address = FadtHeader2->Pm1aEvtBlk;
416 FadtHeader2->XPm1aCntBlk.Address = FadtHeader2->Pm1aCntBlk;
417 FadtHeader2->XPmTmrBlk.Address = FadtHeader2->PmTmrBlk;
418 FadtHeader2->XGpe0Blk.Address = FadtHeader2->Gpe0Blk;
419 } else if (TableHeader->Revision == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
420 *Version = EFI_ACPI_TABLE_VERSION_3_0;
421 FadtHeader3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
422 FadtHeader3->SmiCmd = PcdGet16(PcdSmmActivationPort);
423 FadtHeader3->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
424 FadtHeader3->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
425 FadtHeader3->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
426 FadtHeader3->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);
427 FadtHeader3->XPm1aEvtBlk.Address = FadtHeader3->Pm1aEvtBlk;
428 FadtHeader3->XPm1aCntBlk.Address = FadtHeader3->Pm1aCntBlk;
429 FadtHeader3->XPmTmrBlk.Address = FadtHeader3->PmTmrBlk;
430 FadtHeader3->XGpe0Blk.Address = FadtHeader3->Gpe0Blk;
431 }
432 break;
433 //
434 // "FACS" Firmware ACPI Control Structure
435 //
436 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
437 break;
438 //
439 // "SSDT" Secondary System Description Table
440 //
441 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
442 break;
443 //
444 // "HPET" IA-PC High Precision Event Timer Table
445 //
446 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
447 //
448 // If HPET is disabled in setup, don't publish the table.
449 //
450 if (mGlobalNvsArea.Area->HpetEnable == 0) {
451 *Version = EFI_ACPI_TABLE_VERSION_NONE;
452 }
453 ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) TableHeader)->BaseAddressLower32Bit.Address
454 = PcdGet64 (PcdHpetBaseAddress);
455 break;
456 //
457 // "SPCR" Serial Port Concole Redirection Table
458 //
459 case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
460 break;
461 //
462 // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
463 //
464 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
465 AllocationStructurePtr = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *)
466 ((UINT8 *)TableHeader + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER));
467 AllocationStructurePtr->BaseAddress = PcdGet64(PcdPciExpressBaseAddress);
468 break;
469 // Lakeport platform doesn't support the following table
470 /*
471 //
472 // "ECDT" Embedded Controller Boot Resources Table
473 //
474 case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE:
475 break;
476 //
477 // "PSDT" Persistent System Description Table
478 //
479 case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
480 break;
481 //
482 // "SBST" Smart Battery Specification Table
483 //
484 case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE:
485 break;
486 //
487 // "SLIT" System Locality Information Table
488 //
489 case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
490 break;
491 //
492 // "SRAT" Static Resource Affinity Table
493 //
494 case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE:
495 break;
496 //
497 // "XSDT" Extended System Description Table
498 //
499 case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
500 break;
501 //
502 // "BOOT" MS Simple Boot Spec
503 //
504 case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE:
505 break;
506 //
507 // "CPEP" Corrected Platform Error Polling Table
508 //
509 case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE:
510 break;
511 //
512 // "DBGP" MS Debug Port Spec
513 //
514 case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE:
515 break;
516 //
517 // "ETDT" Event Timer Description Table
518 //
519 case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE:
520 break;
521 //
522 // "SPMI" Server Platform Management Interface Table
523 //
524 case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE:
525 break;
526 //
527 // "TCPA" Trusted Computing Platform Alliance Capabilities Table
528 //
529 case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:
530 break;
531 */
532 default:
533 break;
534 }
535 }
536 }
537
538 //
539 // Description:
540 // Entrypoint of Acpi Platform driver
541 // In:
542 // ImageHandle
543 // SystemTable
544 // Out:
545 // EFI_SUCCESS
546 // EFI_LOAD_ERROR
547 // EFI_OUT_OF_RESOURCES
548 //
549
550 EFI_STATUS
551 AcpiPlatformEntryPoint (
552 IN EFI_HANDLE ImageHandle,
553 IN EFI_SYSTEM_TABLE *SystemTable
554 )
555 {
556 EFI_STATUS Status;
557 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
558 EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
559 INTN Instance;
560 EFI_ACPI_COMMON_HEADER *CurrentTable;
561 UINTN TableHandle;
562 UINT32 FvStatus;
563 UINTN Size;
564 EFI_ACPI_TABLE_VERSION Version;
565 QNC_DEVICE_ENABLES QNCDeviceEnables;
566 EFI_HANDLE Handle;
567 UINTN Index;
568 PCI_DEVICE_INFO *PciDeviceInfo;
569 EFI_ACPI_HANDLE PciRootHandle;
570 BOOLEAN UpdatePRT;
571 BOOLEAN UpdatePRW;
572 PCI_DEVICE_SETTING *mConfigData;
573
574 DEBUG((DEBUG_INFO, "ACPI Platform start...\n"));
575
576 Instance = 0;
577 TableHandle = 0;
578 CurrentTable = NULL;
579 mConfigData = NULL;
580 QNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);
581
582 //
583 // Initialize the EFI Driver Library
584 //
585
586 ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);
587
588 Status = gBS->AllocatePool (
589 EfiACPIMemoryNVS,
590 sizeof (EFI_GLOBAL_NVS_AREA),
591 (VOID**)&mGlobalNvsArea.Area
592 );
593
594 Handle = NULL;
595 Status = gBS->InstallProtocolInterface (
596 &Handle,
597 &gEfiGlobalNvsAreaProtocolGuid,
598 EFI_NATIVE_INTERFACE,
599 &mGlobalNvsArea
600 );
601
602 ASSERT_EFI_ERROR (Status);
603 if (!EFI_ERROR (Status)) {
604 SetMem (
605 mGlobalNvsArea.Area,
606 sizeof (EFI_GLOBAL_NVS_AREA),
607 0
608 );
609 }
610
611 //
612 // Initialize the data. Eventually, this will be controlled by setup options.
613 //
614 mGlobalNvsArea.Area->HpetEnable = PcdGetBool (PcdHpetEnable);
615 mGlobalNvsArea.Area->Pm1blkIoBaseAddress = PcdGet16(PcdPm1blkIoBaseAddress);
616 mGlobalNvsArea.Area->PmbaIoBaseAddress = PcdGet16(PcdPmbaIoBaseAddress);
617 mGlobalNvsArea.Area->Gpe0blkIoBaseAddress = PcdGet16(PcdGpe0blkIoBaseAddress);
618 mGlobalNvsArea.Area->GbaIoBaseAddress = PcdGet16(PcdGbaIoBaseAddress);
619 mGlobalNvsArea.Area->SmbaIoBaseAddress = PcdGet16(PcdSmbaIoBaseAddress);
620 mGlobalNvsArea.Area->WdtbaIoBaseAddress = PcdGet16(PcdWdtbaIoBaseAddress);
621 mGlobalNvsArea.Area->HpetBaseAddress = (UINT32)PcdGet64(PcdHpetBaseAddress);
622 mGlobalNvsArea.Area->HpetSize = (UINT32)PcdGet64(PcdHpetSize);
623 mGlobalNvsArea.Area->PciExpressBaseAddress= (UINT32)PcdGet64(PcdPciExpressBaseAddress);
624 mGlobalNvsArea.Area->PciExpressSize = (UINT32)PcdGet64(PcdPciExpressSize);
625 mGlobalNvsArea.Area->RcbaMmioBaseAddress = (UINT32)PcdGet64(PcdRcbaMmioBaseAddress);
626 mGlobalNvsArea.Area->RcbaMmioSize = (UINT32)PcdGet64(PcdRcbaMmioSize);
627 mGlobalNvsArea.Area->IoApicBaseAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);
628 mGlobalNvsArea.Area->IoApicSize = (UINT32)PcdGet64(PcdIoApicSize);
629 mGlobalNvsArea.Area->TpmPresent = (UINT32)(FALSE);
630 mGlobalNvsArea.Area->DBG2Present = (UINT32)(FALSE);
631 mGlobalNvsArea.Area->PlatformType = (UINT32)PcdGet16 (PcdPlatformType);
632
633 //
634 // Configure platform IO expander I2C Slave Address.
635 //
636 if (mGlobalNvsArea.Area->PlatformType == Galileo) {
637 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
638 mGlobalNvsArea.Area->AlternateSla = FALSE;
639 } else {
640 mGlobalNvsArea.Area->AlternateSla = TRUE;
641 }
642 }
643
644 //
645 // Find the AcpiTable protocol
646 //
647 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
648 if (EFI_ERROR (Status)) {
649 return EFI_ABORTED;
650 }
651
652 //
653 // Initialize MADT table
654 //
655 Status = MadtTableInitialize (&CurrentTable, &Size);
656 ASSERT_EFI_ERROR (Status);
657 //
658 // Perform any table specific updates.
659 //
660 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);
661
662 //
663 // Update the check sum
664 // It needs to be zeroed before the checksum calculation
665 //
666 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
667 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
668 CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
669
670 //
671 // Add the table
672 //
673 TableHandle = 0;
674 Status = AcpiTable->InstallAcpiTable (
675 AcpiTable,
676 CurrentTable,
677 CurrentTable->Length,
678 &TableHandle
679 );
680 ASSERT_EFI_ERROR (Status);
681 CurrentTable = NULL;
682
683 //
684 // Init Pci Device PRT PRW information structure from PCD
685 //
686 mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));
687 ASSERT_EFI_ERROR (mConfigData);
688 InitPciDeviceInfoStructure (mConfigData);
689 //
690 // Get the Acpi SDT protocol for manipulation on acpi table
691 //
692 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);
693 ASSERT_EFI_ERROR (Status);
694 //
695 // Locate the firmware volume protocol
696 //
697 Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
698 if (EFI_ERROR (Status)) {
699 return EFI_ABORTED;
700 }
701 //
702 // Read tables from the storage file.
703 //
704
705 while (Status == EFI_SUCCESS) {
706
707 Status = FwVol->ReadSection (
708 FwVol,
709 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
710 EFI_SECTION_RAW,
711 Instance,
712 (VOID**)&CurrentTable,
713 &Size,
714 &FvStatus
715 );
716
717 if (!EFI_ERROR(Status)) {
718 //
719 // Perform any table specific updates.
720 //
721 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);
722
723 //
724 // Update the check sum
725 // It needs to be zeroed before the checksum calculation
726 //
727 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
728 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
729 CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
730
731 //
732 // Add the table
733 //
734 TableHandle = 0;
735 Status = AcpiTable->InstallAcpiTable (
736 AcpiTable,
737 CurrentTable,
738 ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,
739 &TableHandle
740 );
741 if (EFI_ERROR(Status)) {
742 return EFI_ABORTED;
743 }
744 //
745 // If this table is the DSDT table, then update the _PRT and _PRW based on
746 // the settings from pcds
747 //
748 if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
749 //
750 // Create the root handle for DSDT table
751 //
752 Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);
753 ASSERT_EFI_ERROR (Status);
754
755 PciRootHandle = NULL;
756 PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);
757 ASSERT (PciRootHandle != NULL);
758
759 PciDeviceInfo = NULL;
760 for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {
761 PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);
762
763 //
764 // Check whether this is a valid item
765 //
766 if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {
767
768 //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));
769
770 UpdatePRT = FALSE;
771 UpdatePRW = FALSE;
772
773 SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);
774 //
775 // Check whether there is any valid pci routing item
776 //
777 if (UpdatePRT) {
778 //
779 // Update the pci routing information
780 //
781 //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
782 SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);
783 }
784 //
785 // Check whether there is any valid pci routing item
786 //
787 if (UpdatePRW) {
788 //
789 // Update the pci wakeup information
790 //
791 //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
792 SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);
793 }
794 }
795 }
796 Status = mAcpiSdt->Close (PciRootHandle);
797 ASSERT_EFI_ERROR (Status);
798 //
799 // Mark the root handle as modified , let SDT protocol recaculate the checksum
800 //
801 ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;
802 Status = mAcpiSdt->Close (mDsdtHandle);
803 ASSERT_EFI_ERROR (Status);
804 }
805 //
806 // Increment the instance
807 //
808 Instance++;
809 CurrentTable = NULL;
810 }
811 }
812
813 gBS->FreePool (mConfigData);
814 return EFI_SUCCESS;
815 }