summaryrefslogtreecommitdiff
path: root/Core/EM/ACPI/AcpiCore.c
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/ACPI/AcpiCore.c
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/ACPI/AcpiCore.c')
-rw-r--r--Core/EM/ACPI/AcpiCore.c4475
1 files changed, 4475 insertions, 0 deletions
diff --git a/Core/EM/ACPI/AcpiCore.c b/Core/EM/ACPI/AcpiCore.c
new file mode 100644
index 0000000..7cb3366
--- /dev/null
+++ b/Core/EM/ACPI/AcpiCore.c
@@ -0,0 +1,4475 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/ACPI/AcpiCore.c 9 4/16/14 6:17a Chaseliu $
+//
+// $Revision: 9 $
+//
+// $Date: 4/16/14 6:17a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/ACPI/AcpiCore.c $
+//
+// 9 4/16/14 6:17a Chaseliu
+// sync to ACPI module 48
+//
+// 8 9/18/13 4:06a Thomaschen
+// Update for ACPI module labeled 47.
+//
+// 108 3/14/14 10:42a Oleksiyy
+// [TAG] EIP121819
+// [Category] Improvement
+// [Description] Add FID acpi table. filling of Tbl_IDs up to date.
+// [Files] AcpiCore.c.
+//
+// 107 3/03/14 5:02p Oleksiyy
+// [TAG] EIP154308
+// [Category] Improvement
+// [Description] Aptio 4: Intel Doc #542550 4h) FirmwarePerformance EFI
+// variable contains address of FPDT ACPI table.
+// [Files] AcpiCore.c and S3Resume.c
+//
+// 106 1/23/14 5:38p Oleksiyy
+// [TAG] EIP113941
+// [Category] New Feature
+// [Description] Time and Alarm ACPI device implemented.
+// [Files] AcpiCore.c
+// ACPICORE.CIF
+//
+// 105 10/28/13 12:05p Oleksiyy
+// [TAG] EIP121819
+// [Category] Improvement
+// [Description] Add FID acpi table.
+// [Files] AcpiCore.c, AcpiCore.h
+//
+// 104 10/04/13 11:55a Oleksiyy
+// [TAG] EIP138574
+// [Category] Improvement
+// [Description] Assert in LockLegacyRes removed.
+// [Files] AcpiCore.c
+//
+// 103 8/12/13 4:07p Oleksiyy
+// [TAG] EIP132574
+// [Category] Improvement
+// [Description] When checking address range && replaced with & to save
+// memory.
+// [Files] AcpiCore.c
+//
+// 102 8/01/13 6:00p Oleksiyy
+// [TAG] EIP130457
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang up 78h and BSOD issue after enter OS when
+// enable X64 support
+// [RootCause] hen only RSDT is validayted by OS and DSDT was located
+// above 4Gig and then typecasted to UINT32 addres info was lost.
+// [Solution] Allocate memory for DSDT always under 4 Gig.
+// [Files] AcpiCore.c
+//
+// 101 6/03/13 5:05p Oleksiyy
+// [TAG] EIP125666
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Wrong typecasting in Registernotify function.
+// [RootCause] Wrong typecasting in Registernotify function.
+// [Solution] Typecastnig removed.
+// [Files] AcpiCore.c
+//
+// 100 12/13/12 11:59a Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 99 11/19/12 6:01p Oleksiyy
+// [TAG] EIP101547
+// [Category] New Feature
+// [Description] Support Uninstalling MADT with ACPI Table Protocol
+// [Files] AcpiCore.c
+//
+// 98 6/12/12 3:17p Oleksiyy
+// TAG] EIP90322
+// [Category] Improvement
+// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to
+// AmiLib.h.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 97 6/12/12 11:16a Oleksiyy
+// [TAG] EIP88889
+// [Category] Improvement
+// [Description] FACP ver 5.0 structure added, FPDT mesurment accuracy
+// improved.
+// [Files] ACPI50.h, ACPI.sdl, AcpiCore.c, S3Resume.c, Image.c,
+// EfiLib.c
+//
+// 96 5/22/12 4:33p Oleksiyy
+// [TAG] EIP90322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail, improper variable FPDT_Variable in
+// ACPI module
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 95 5/04/12 10:48a Oleksiyy
+// [TAG] EIP88478
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ACPI error when booting to Windows with 4G+ memory
+// [RootCause] "x64_BUILD_SUPPORT" not defined
+// [Solution] Change to EFIx64 identifier.
+// [Files] AcpiCore.c
+//
+// 94 4/12/12 11:53a Oleksiyy
+// [TAG] EIP86325
+// [Category] Improvement
+// [Description] Disabling PciExpNative in BIOS setup doesn't cause bit
+// 4 in IAPC_BOOT_ARCH to be set.
+// Bit preservation is added.
+// [Files] AcpiCore.c
+//
+// 93 12/05/11 4:24p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Increasing of whole table length after adding FPDT was
+// skiped by mistake. Fixed
+// [Files] AcpiCore.c.
+//
+// 92 11/28/11 5:34p Oleksiyy
+// [TAG] EIP76419
+// [Category] Improvement
+// [Description] TPL level chang to TPL_APPLICATION removed in ACPI
+// Table Protocol functions
+// [Files] AcpiCore.c
+//
+// 90 11/11/11 5:10p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added. FirmPerfDataTab.h renamed to ACPI50.h
+// [Files] AcpiCore.c, EfiLib.c, S3Resume.c and ACPI50.h added.
+//
+// 89 11/08/11 4:52p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added.
+// [Files] AcpiCore.c, AmiDxeLib.h, CSM.c, DxeMain.c, EfiLib.c,
+// Image.c, S3Resume.c and FirmPerfDataTab.h
+//
+// 88 10/25/11 5:54p Oleksiyy
+// [TAG] EIP71540
+// [Category] Improvement
+// [Description] Fix of "any amount of spaces in table IDs replaced with
+// only one".
+// [Files] ACPI.mak and AcpiCore.c
+//
+// 87 9/30/11 4:23p Oleksiyy
+// [TAG] EIP71374
+// [Category] Improvement
+// [Description] ACPI sleep state setup option update.
+// [Files] ACPI.sd, ACPI.uni and AcpiCore.c
+//
+// 86 8/30/11 4:04p Oleksiyy
+// [TAG] EIP67951
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BGRT Table does not exist in XSDT
+// [RootCause] Due to bug in OEM Activation routine last table in XSDT
+// was deleted.
+// [Solution] Wrong else statment fixed.
+// [Files] AcpiCore.c
+//
+// 85 7/19/11 11:31a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 84 6/10/11 5:10p Oleksiyy
+// [TAG] EIP60372
+// [Category] Improvement
+// [Description] Conformance fix in Uninstall Table function.
+// [Files] AcpiCore.c
+//
+// 83 5/27/11 5:32p Felixp
+// Enhancement: AcpiInstallAcpiTable/ AcpiUninstallAcpiTable are updated.
+// CONST qualifier is added to the parameters to match the specification.
+//
+// 82 5/20/11 2:39p Oleksiyy
+// [TAG] EIP60633
+// [Category] New Feature
+// [Description] Acpi part of Microsoft OEM Activation 3.0
+// [Files] AcpiCore.c
+//
+// 81 5/18/11 5:15p Oleksiyy
+// [TAG] EIP60634
+// [Category] Improvement
+// [Description] Small fix in Install table functionality
+// [Files] AcpiCore.c
+//
+// 80 5/14/11 2:47p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+// 79 4/06/11 6:01p Markw
+// [TAG] EIP53334
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] CPU module provide NMI information if protocol
+// available. This is to properly support x2APIC NMI structures.
+// [Files] AcpiCore.c
+//
+// 78 3/16/11 12:07p Oleksiyy
+// [TAG] EIP56178
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Assert on Legacy free systems
+// [RootCause] The function LockLegacyRes() will assert if it cannot
+// find any handles that have the gEfiAmiSioProtocolGuid installed on
+// them.
+// [Solution] Assert removed from LockLegacyRes function.
+// [Files] AcpiCore.c
+//
+// 77 3/03/11 6:09p Oleksiyy
+// [TAG] EIP55071
+// [Category] New Feature
+// [Description] APIC/SAPIC Differentiation Algorithm Not Working for
+// AMD I/O APIC
+// Sdl tokens are added to set set IOAPIC/IOSAPIC and LAPIC/LSAPIC
+// revision BOUNDARY.
+// [Files] ACPI.sdl and AcpiCore.c
+//
+// 76 1/03/11 10:46a Oleksiyy
+// [TAG] EIP49202
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang at CKP 0x9A
+// [RootCause] System hang at CKP 0x9A if memory is up to 4GB or above
+// and token "x64_BUILD" = 0, "DEBUG_MODE" = 1.
+// [Solution] gRsdtPtrStr typecasted to UINTN before typecasting to
+// EFI_PHYSICAL_ADDRESS.
+// [Files] AcpiCore.c
+//
+// 75 12/23/10 12:02p Oleksiyy
+// [TAG] EIP50019
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Add support for all fields of ACPI_IA_BOOT_ARCH flag in
+// FACP
+// [RootCause] All values of ACPI_IA_BOOT_ARCH flag, added in ACPI 4
+// spec, is cleared during updating of LEGACY_DEVICES and 8042 fields in
+// CollectAmlUpdInfo routine.
+// [Solution] AcpiCore.c file modified to preserve values of
+// ACPI_IA_BOOT_ARCH flag set in sdl file.
+// [Files] AcpiCore.c and ACPI.sdl
+//
+// 74 12/17/10 5:14p Oleksiyy
+// [TAG] EIP50325
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Incorrect order of MADT entries for Agesa projects
+// [RootCause] Dummy entries placed before active cores in MADT table
+// [Solution] Token SKIP_DUMMY_LAPICS should be added to any .sdl file
+// to force AcpiCore not to create dummy lapics entires for processors
+// that are absent, but could be hot plugged.
+// Also, BuildLapic function changed and now dummy lapics will have higher
+// Id.
+// [Files] AcpiCore.c
+//
+// 73 10/11/10 5:52p Oleksiyy
+// Healp builder error - Function Header Fixed.
+//
+// 72 10/01/10 11:55a Oleksiyy
+// Issue Number: 45160
+//
+// Category: Improvement
+//
+// Description: AcpiSupportSetAcpiTable function was modified to checksum
+// table, after it was changed by OemAcpiSetPlatformId hook, if Checksum
+// parameter of SetAcpiTable function is FALSE, but table was correctly
+// checksumed before call to OemAcpiSetPlatformId hook.
+//
+// Files: AcpiCore.c
+//
+// 71 9/27/10 11:56a Oleksiyy
+// Issue Number: 44740
+//
+// Category: Improvement
+//
+// Description: Functionality to Publish all tables, added on ReadyToBoot
+// through EFI_ACPI_SUPPORT_PROTOCOL, automatically
+// is added.
+//
+// Files: AcpiCore.c
+//
+// 70 5/25/10 11:07a Oleksiyy
+// Assert in publish tables fixed
+//
+// 69 4/28/10 2:46p Oleksiyy
+// EIP 35563 "Force to ACPI ver. 1.1" ACPI setup menu (default is OFF)
+// added. If Enabled - only Tables for ver. 1.1 will be builded (FACP,
+// FACS,
+// RSDT (no XSDT), and MADT) al other tables added by means of
+// ACPI protocols not modified.
+// EIP 37874 - ACPI_APIC_TBL token added if OFF - MADT will not
+// created (PIC mode).
+//
+// 68 4/05/10 4:46p Oleksiyy
+// EIP 37055 - TPL check added. + Some spelling issues fixed.
+//
+// 67 2/19/10 12:24p Oleksiyy
+// EIP 35099: Functionality to lock legacy resources from OS added,
+// based on setup question. Default value controlled by
+// DEFAULT_ACPI_LOCK_LEGACY_DEV SDL token and "OFF".
+//
+// 66 2/02/10 2:45p Oleksiyy
+// EIP 32520 Update AML part function is changed to perform update
+// before publishing table. Freepool assert when trying to delete old
+// DSDT fixed.
+//
+// 65 12/08/09 11:41a Oleksiyy
+// Minor bug fix in typecasting
+//
+// 64 11/24/09 5:20p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support.
+//
+// 63 9/28/09 6:32p Yakovlevs
+// Changes to support Multy Root resource reporting features.
+// All PCI ROOT resource reporting features moved to PciHootBridge.c.
+//
+// 62 9/25/09 11:24a Oleksiyy
+// EIP 26777: RSDP Revision fixed
+//
+// 61 8/20/09 3:02p Oleksiyy
+// EIP 25407: 32 bit mode bug fix
+//
+// 60 8/11/09 3:39p Markw
+// EIP #24914 - Add local x2APIC support.
+//
+// 59 5/27/09 5:39p Yakovlevs
+// Fixed inconsistancy in SetAcpiTable Routine.
+//
+// 58 5/26/09 1:44p Yakovlevs
+// Fixed Issues in Pointers handling in SetAcpiTable fubction
+//
+// 57 5/18/09 10:09a Yakovlevs
+// Fixed issue in sorting IOAPICs entries.
+//
+// 56 5/15/09 12:49p Yakovlevs
+// Fixed logic in IOAPIC discovery ordering.
+//
+// 55 5/14/09 5:36p Yakovlevs
+// Minor bug fixes and Improvements see release notes for Label 31
+//
+// 54 5/08/09 1:15p Yakovlevs
+// Made ACPI Driver use AMI Board Info Protocol if available without
+// breaking compatibility.
+//
+// 53 5/07/09 5:46p Markw
+// Use #ifdef ACPI_INFO2_PROTOCOL_PUBLISHED to exclude code that uses ACPI
+// INFO 2 for CPUs that provide the header files.
+//
+// 52 5/04/09 5:48p Markw
+// EIP #17903 Use AmiCpuInfo2 Protocol if available. Small bug fixes from
+// last update.
+//
+// 51 4/30/09 5:51p Markw
+// EIP #17903 Use AmiCpuInfo2 Protocol if available. This provides correct
+// ordering for Nehalem in APIC table.
+//
+// 50 4/27/09 5:39p Oleksiyy
+// EIP 21205 - Win XP (SP2) instalation problem fix. Added compatibility
+// fields in FACP Ver 1.
+//
+// 49 4/14/09 11:13a Oleksiyy
+// Removed one ASSERT.
+//
+// 48 3/27/09 4:09p Oleksiyy
+// Code clean-up.
+//
+// 47 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 2/18/09 3:51p Oleksiyy
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <AcpiCore.c>
+//
+// Description: Main ACPI Driver File. It has ACPI Driver entry point,
+// ACPISupport Protocol and ACPITable Protocol.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#if PI_SPECIFICATION_VERSION >= 0x10014
+#include <Protocol\SuperIo.h>
+#else
+#include <Protocol\AmiSio.h>
+#endif
+#include <Protocol\DevicePath.h>
+#include <AMIHobs.h>
+#include <token.h>
+#include <Dxe.h>
+#include <AcpiRes.h>
+#include "AcpiCore.h"
+#include <Setup.h>
+#include "AcpiOemElinks.h"
+#include "ACPI50.h"
+#include <Ppi\FwVersion.h>
+#if ATAD_SUPPORT == 1
+#include "AtadSmi.h"
+#endif
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+#include <Protocol\AmiCpuInfo2.h>
+#endif
+
+
+#include <Protocol\AmiBoardInfo.h>
+#include <Protocol/Cpu.h>
+ // [EIP106575], [EIP106731]>
+#include <Protocol/MpService.h>
+ // <[EIP106575], [EIP106731]
+EFI_GUID gAmiBoardInfoGuid = AMI_BOARD_INFO_PROTOCOL_GUID;
+AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfoProtocol=NULL;
+
+//--------------------------------------
+//Some Global vars
+EFI_GUID gDsdt11Guid = EFI_ACPI_DSDT_V_1_1_GUID;
+EFI_GUID gDsdt20Guid = EFI_ACPI_DSDT_V_2_0_GUID;
+//EFI_GUID gDPProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+//EFI_GUID gSioProtocolGuid = EFI_AMI_SIO_PROTOCOL_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+AMI_CPU_INFO_2_PROTOCOL* gAmiCpu2Info;
+EFI_GUID gAmiCpuInfo2ProtocolGuid = AMI_CPU_INFO_2_PROTOCOL_GUID;
+#endif
+
+ACPI_DB gAcpiData = {0, 0, NULL, 0};
+FACS_20 *gFacs, *gxFacs;
+RSDT_PTR_20 *gRsdtPtrStr = NULL;
+UINTN gAcpiTblPages = 0;
+ACPI_AML_UPD_INFO *gAuiGlob = NULL;
+UINT16 gAcpiIaBootArch=0xFFFF;
+EFI_EVENT gEvtReadyToBoot;
+EFI_GUID gAcpi11TAbleGuid = EFI_ACPI_11_TABLE_GUID;
+EFI_GUID gAcpi20TAbleGuid = EFI_ACPI_20_TABLE_GUID;
+BOOLEAN gX2Apic = FALSE;
+UINT8 gForceAcpi1 = 0, gPublishedOnReadyToBoot = 0, gMaxLapic = 0;
+
+//Here goes Interrupt Source Override MADT entry parameter table
+//Generated From Information on IRQ_XX_OVERRIDE_ENABLE SDL tokens
+ISO_PARAMETER_TABLE IsoTbl[]=
+{
+//UINT8 PicIrq; UINT8 Flags; UINT16 ApicInt
+#if IRQ_00_OVERRIDE_ENABLE == 1
+ { 0x00, (IRQ_00_TRIGGER_MODE<<2)|IRQ_00_POLARITY, IRQ_00_APIC_INT },
+#else
+ { 0xFF, 0, 0 },
+#endif
+#if IRQ_01_OVERRIDE_ENABLE == 1
+ { 0x01, (IRQ_01_TRIGGER_MODE<<2)|IRQ_01_POLARITY, IRQ_01_APIC_INT },
+#else
+ { 0xFF, 0, 1 },
+#endif
+//just dummy entry instead of IRQ2 to keep array consistent
+ { 0xFF, 0, 2 },
+#if IRQ_03_OVERRIDE_ENABLE == 1
+ { 0x03, (IRQ_03_TRIGGER_MODE<<2)|IRQ_03_POLARITY, IRQ_03_APIC_INT },
+#else
+ { 0xFF, 0, 3 },
+#endif
+#if IRQ_04_OVERRIDE_ENABLE == 1
+ { 0x04, (IRQ_04_TRIGGER_MODE<<2)|IRQ_04_POLARITY, IRQ_04_APIC_INT },
+#else
+ { 0xFF, 0, 4 },
+#endif
+#if IRQ_05_OVERRIDE_ENABLE == 1
+ { 0x05, (IRQ_05_TRIGGER_MODE<<2)|IRQ_05_POLARITY, IRQ_05_APIC_INT },
+#else
+ { 0xFF, 0, 5 },
+#endif
+#if IRQ_06_OVERRIDE_ENABLE == 1
+ { 0x06, (IRQ_06_TRIGGER_MODE<<2)|IRQ_06_POLARITY, IRQ_06_APIC_INT },
+#else
+ { 0xFF, 0, 6 },
+#endif
+#if IRQ_07_OVERRIDE_ENABLE == 1
+ { 0x07, (IRQ_07_TRIGGER_MODE<<2)|IRQ_07_POLARITY, IRQ_07_APIC_INT },
+#else
+ { 0xFF, 0, 7 },
+#endif
+
+#if IRQ_08_OVERRIDE_ENABLE == 1
+ { 0x08, (IRQ_08_TRIGGER_MODE<<2)|IRQ_08_POLARITY, IRQ_08_APIC_INT },
+#else
+ { 0xFF, 0, 8 },
+#endif
+#if IRQ_09_OVERRIDE_ENABLE == 1
+ { 0x09, (IRQ_09_TRIGGER_MODE<<2)|IRQ_09_POLARITY, IRQ_09_APIC_INT },
+#else
+ { 0xFF, 0, 9 },
+#endif
+#if IRQ_10_OVERRIDE_ENABLE == 1
+ { 0x0A, (IRQ_10_TRIGGER_MODE<<2)|IRQ_10_POLARITY, IRQ_10_APIC_INT },
+#else
+ { 0xFF, 0, 10 },
+#endif
+#if IRQ_11_OVERRIDE_ENABLE == 1
+ { 0x0B, (IRQ_11_TRIGGER_MODE<<2)|IRQ_11_POLARITY, IRQ_11_APIC_INT },
+#else
+ { 0xFF, 0, 11 },
+#endif
+#if IRQ_12_OVERRIDE_ENABLE == 1
+ { 0x0C, (IRQ_12_TRIGGER_MODE<<2)|IRQ_12_POLARITY, IRQ_12_APIC_INT },
+#else
+ { 0xFF, 0, 12 },
+#endif
+#if IRQ_13_OVERRIDE_ENABLE == 1
+ { 0x0D, (IRQ_13_TRIGGER_MODE<<2)|IRQ_13_POLARITY, IRQ_13_APIC_INT },
+#else
+ { 0xFF, 0, 13 },
+#endif
+#if IRQ_14_OVERRIDE_ENABLE == 1
+ { 0x0E, (IRQ_14_TRIGGER_MODE<<2)|IRQ_14_POLARITY, IRQ_14_APIC_INT },
+#else
+ { 0xFF, 0, 14 },
+#endif
+#if IRQ_15_OVERRIDE_ENABLE == 1
+ { 0x0F, (IRQ_15_TRIGGER_MODE<<2)|IRQ_15_POLARITY, IRQ_15_APIC_INT },
+#else
+ { 0xFF, 0, 15 },
+#endif
+};
+
+static UINTN IsoCnt=sizeof(IsoTbl)/sizeof(ISO_PARAMETER_TABLE);
+
+EFI_STATUS MpsTableBuilderInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+MADT_ENTRY_HEADER * BuildLocalApicNmi(
+ IN BOOLEAN X2Apic,
+ IN UINT32 ProcessorId,
+ IN UINT8 LapicInitIn,
+ IN UINT16 Flags
+ );
+
+UINT8 ACPI_OEM_ID[6] = ACPI_OEM_ID_MAK; //"A M I"; //add 0 at the end.OemId 6 bytes
+UINT8 ACPI_OEM_TBL_ID[8] = ACPI_OEM_TBL_ID_MAK; //"ALASKA"; //add 0 at the end.OemTableId 8 bytes
+
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+#define EFI_OA3_MSDM_VARIABLE L"OA3MSDMvariable"
+
+typedef struct _EFI_OA3_MSDM_STRUCTURE {
+ EFI_PHYSICAL_ADDRESS XsdtAddress;
+ EFI_PHYSICAL_ADDRESS MsdmAddress;
+ EFI_PHYSICAL_ADDRESS ProductKeyAddress;
+} EFI_OA3_MSDM_STRUCTURE;
+
+BOOLEAN gOA3Variable = FALSE;
+EFI_OA3_MSDM_STRUCTURE gMsdmVariable;
+#endif
+
+#if ATAD_SUPPORT == 1
+ VOID *AtadBuffPtr = NULL;
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemCopy
+//
+// Description: This routine copies data from source to destination.
+//
+// Input:
+// fpSrc - Pointer to the source.
+// fpDest - Pointer to the destination.
+// wSize - Number of bytes to copy.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+MemCopy (
+ UINT8* fpSrc,
+ UINT8* fpDest,
+ UINT32 dSize)
+{
+ UINT32 dCount;
+
+ //
+ // Check for pointer validity
+ //
+ if ((fpSrc) && (fpDest))
+ {
+ for (dCount = 0; dCount < dSize; dCount++)
+ {
+ fpDest[dCount] = fpSrc[dCount];
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrepareHdr20
+//
+// Description:
+// This function creates ACPI table v 2.0+ header with specified signature
+//
+// Input:
+// IN UINT32 TblSig - ACPI table signature
+// IN OUT ACPI_HDR* HdrPtr - Pointer to memory, where the header should be placed
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void PrepareHdr20(UINT32 TblSig, ACPI_HDR *HeaderPtr, UINTN Vers)
+{
+ UINTN i;
+ EFI_STATUS Status;
+
+ if (HeaderPtr==NULL) return;
+
+ HeaderPtr->Signature=TblSig;
+
+ //Check what Revision# header needs depends on TABLE we're building
+ switch (TblSig)
+ {
+ case RSDT_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+1;
+ break;
+
+ case XSDT_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+2;
+ break;
+
+ case FACP_SIG:
+ HeaderPtr->Revision=ACPI_REV3;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+3;
+
+ if (Vers > 2)
+ {
+
+ HeaderPtr->Revision=ACPI_REV4;
+ HeaderPtr->CreatorRev++;
+ }
+
+ break;
+ case APIC_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+4;
+
+ if (Vers > 2)
+ {
+
+ HeaderPtr->Revision=ACPI_REV2;
+ HeaderPtr->CreatorRev++;
+ }
+
+ if (Vers > 3)HeaderPtr->Revision=ACPI_REV3;
+
+ break;
+ case SBST_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ break;
+ case SPCR_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ break;
+ case ECDT_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ break;
+ //case DSDT_SIG:
+ //HeaderPtr->CreatorRev=CREATOR_REV_MS+5;
+ //HeaderPtr->Revision=ACPI_REV2;
+ break;
+ }
+
+ //instead of puting fixed revision number
+ //HeaderPtr->Revision=ACPI_REV2;
+
+ //Dont' touch Creator ID and Creator Revision;
+ if (TblSig != DSDT_SIG)
+ {
+ if (TblSig == RSDT_SIG)
+ HeaderPtr->CreatorId = CREATOR_ID_MS;
+ else
+ HeaderPtr->CreatorId = CREATOR_ID_AMI;
+
+ HeaderPtr->CreatorRev = CREATOR_REV_MS;
+ HeaderPtr->OemRev = ACPI_OEM_REV;
+ }
+
+ //Get the platform specific OEM_IDs
+ Status=OemAcpiSetPlatformId(HeaderPtr);
+
+ //if platform does not support OEM_ID overwrite
+ if (EFI_ERROR(Status))
+ {
+ for (i=0; i<6; i++) HeaderPtr->OemId[i]=ACPI_OEM_ID[i];
+
+ for (i=0; i<8; i++) HeaderPtr->OemTblId[i]=ACPI_OEM_TBL_ID[i];
+ }
+
+} //PrepareHdr20
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrepareHdr1
+//
+// Description:
+// This function creates ACPI V1 table header with specified signature
+//
+// Input:
+// IN UINT32 TblSig - ACPI table signature
+// IN OUT ACPI_HDR* HdrPtr - Pointer to memory, where the header should be placed
+//
+// Output:
+// VOID
+//
+// Notes:
+// Depends on type of memory provided, ACPI table header can be in 32 or 64 bit
+// format
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void PrepareHdr1(UINT32 TblSig, ACPI_HDR* HdrPtr)
+{
+ UINTN i;
+ EFI_STATUS Status;
+
+ if (HdrPtr==NULL) return;
+
+ HdrPtr->Signature = TblSig;
+ HdrPtr->Revision = ACPI_REV1;
+
+ //Dont' touch Creator ID and Creator Revision;
+ if (TblSig != DSDT_SIG)
+ {
+ if (TblSig == RSDT_SIG)
+ HdrPtr->CreatorId = CREATOR_ID_MS;
+ else
+ HdrPtr->CreatorId = CREATOR_ID_AMI;
+
+ HdrPtr->CreatorRev = CREATOR_REV_MS;
+ HdrPtr->OemRev = ACPI_OEM_REV;
+ }
+
+ //Get the platform specific OEM_IDs
+ Status=OemAcpiSetPlatformId(HdrPtr);
+
+ //if platform does not support OEM_ID overwrite
+ if (EFI_ERROR(Status))
+ {
+ for (i=0; i<6; i++) HdrPtr->OemId[i]=ACPI_OEM_ID[i];
+
+ for (i=0; i<8; i++) HdrPtr->OemTblId[i]=ACPI_OEM_TBL_ID[i];
+ }
+
+}//PrepareHdr1
+
+
+
+ // [EIP106575], [EIP106731]>
+EFI_STATUS
+GetNanoFreqCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN VarSize = sizeof (UINT32);
+ EFI_FPDT_STRUCTURE *FpdtVar;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+
+ pBS->CloseEvent(Event);
+
+ Status = pRS->GetVariable(
+ EFI_FPDT_VARIABLE, \
+ &gAmiGlobalVariableGuid,
+ NULL, \
+ &VarSize, \
+ &FpdtVar );
+ if (EFI_ERROR (Status)) {
+ TRACE((-1,"Acpi BuildFPDT: No Cpu Protocol was found.\n"));
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (
+ &gEfiCpuArchProtocolGuid,
+ NULL,
+ &Cpu
+ );
+ if (!EFI_ERROR (Status)) {
+
+ UINT64 CurrentTicker, TimerPeriod;
+
+ Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod);
+
+ if (!EFI_ERROR (Status))
+ FpdtVar->NanoFreq = TimerPeriod;
+
+ if (FpdtVar->NanoFreq == 0) {
+ IoWrite8(0x80, 0xEE);
+ while(1);
+ }
+
+ } else {
+
+ TRACE((-1,"Acpi BuildFPDT: No Cpu Protocol was found.\n"));
+ return Status;
+
+ }
+
+ Status = pRS->SetVariable(
+ L"FPDT_Variable", \
+ &gAmiGlobalVariableGuid, \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+ EFI_VARIABLE_RUNTIME_ACCESS, \
+ sizeof(UINT32), \
+ &FpdtVar );
+
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+ // <[EIP106575], [EIP106731]
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFPDT
+//
+// Description: This function allocates memory for and fills FPDT struscure. It also
+// creates Variable with the addres od S3 and Normal Boot performance srtuctures
+// to be filled later.
+// Input:
+// IN UINTN TablVer - Version of FACP table
+// IN OUT **ACPI_HDR TablPtr - Pointer to memory, where the FACP table will resides.
+// Filled by this procedure
+// Output:
+// EFI_STATUS:
+// EFI_OUT_OF_RESOURCES - Memory for the table could not be allocated
+// EFI_SUCCESS - Table was successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildFPDT (IN UINTN TablVer, OUT ACPI_HDR **TablPtr)
+
+{
+ UINT8 *TempPtr;
+ PERF_TAB_HEADER *S3PerfRecHdr, *BasBootPerfRecHdr;
+ BASIC_S3_RESUME_PERF_REC *S3PerfRec;
+ BASIC_BOOT_PERF_REC *BasBootPerfRec;
+ UINTN RecordsSize;
+ FPDT_50 *FPDT;
+ EFI_STATUS Status;
+ EFI_FPDT_STRUCTURE *FpdtVar, *OldFpdtVarAddress;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+ UINTN VarSize = sizeof (UINT32);
+ // [EIP106575], [EIP106731]>
+ VOID *Registration;
+ EFI_EVENT Event;
+ // <[EIP106575], [EIP106731]
+
+//-----------------------------
+
+ if (TablVer<1 || TablVer>4) return EFI_INVALID_PARAMETER;
+ RecordsSize = (sizeof(EFI_FPDT_STRUCTURE) + sizeof(PERF_TAB_HEADER)*2 +
+ sizeof(BASIC_S3_RESUME_PERF_REC)+
+ sizeof(BASIC_BOOT_PERF_REC));
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, RecordsSize, &TempPtr);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+#ifdef EFIx64
+ if (((UINT64)TempPtr) & 0xffffffff00000000)
+ {
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+ Status = pBS->FreePool(TempPtr);
+ ASSERT_EFI_ERROR(Status);
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiRuntimeServicesData, 1, &Memory);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ TempPtr = (UINT8*)Memory;
+ }
+#endif
+ pBS->SetMem(TempPtr, RecordsSize, 0);
+
+ *TablPtr = MallocZ (sizeof(FPDT_50));
+
+ if ((*TablPtr)==NULL)
+ {
+ ASSERT(*TablPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FpdtVar = (EFI_FPDT_STRUCTURE*) TempPtr;
+ TempPtr += sizeof(EFI_FPDT_STRUCTURE);
+ S3PerfRecHdr = (PERF_TAB_HEADER*) TempPtr;
+ TempPtr += sizeof(PERF_TAB_HEADER);
+ S3PerfRec = (BASIC_S3_RESUME_PERF_REC*)TempPtr;
+ TempPtr += sizeof(BASIC_S3_RESUME_PERF_REC);
+ BasBootPerfRecHdr = (PERF_TAB_HEADER*) TempPtr;
+ TempPtr += sizeof(PERF_TAB_HEADER);
+ BasBootPerfRec = (BASIC_BOOT_PERF_REC*)TempPtr;
+
+ S3PerfRecHdr->Signature = 0x54503353;// `S3PT'
+ S3PerfRecHdr->Length = sizeof(PERF_TAB_HEADER) + sizeof(BASIC_S3_RESUME_PERF_REC);
+
+ S3PerfRec->Header.PerfRecType = 0;
+ S3PerfRec->Header.RecLength = sizeof(BASIC_S3_RESUME_PERF_REC);
+ S3PerfRec->Header.Revision = 1;
+
+ BasBootPerfRecHdr->Signature = 0x54504246;// `FBPT'
+ BasBootPerfRecHdr->Length = sizeof(PERF_TAB_HEADER) + sizeof(BASIC_BOOT_PERF_REC);
+
+ BasBootPerfRec->Header.PerfRecType = 2;
+ BasBootPerfRec->Header.RecLength = sizeof(BASIC_BOOT_PERF_REC);
+ BasBootPerfRec->Header.Revision = 2;
+
+ FPDT = (FPDT_50*)*TablPtr;
+ PrepareHdr20(FPDT_SIG, (ACPI_HDR*)FPDT, TablVer);
+ FPDT->Header.Length = sizeof(FPDT_50);
+ FPDT->Header.Revision = 1;
+ FPDT->BasS3Rec.PerfRecType = 1;
+ FPDT->BasS3Rec.Length = sizeof(FPDT_PERF_RECORD);
+ FPDT->BasS3Rec.Revision = 1;
+ FPDT->BasS3Rec.Pointer = (EFI_PHYSICAL_ADDRESS)((UINTN)S3PerfRecHdr);
+
+ FPDT->BasBootRec.PerfRecType = 0;
+ FPDT->BasBootRec.Length = sizeof(FPDT_PERF_RECORD);
+ FPDT->BasBootRec.Revision = 1;
+ FPDT->BasBootRec.Pointer = (EFI_PHYSICAL_ADDRESS)((UINTN)BasBootPerfRecHdr);
+
+ FPDT->Header.Checksum = ChsumTbl((UINT8*)FPDT, FPDT->Header.Length);
+
+ Status = pBS->LocateProtocol (
+ &gEfiCpuArchProtocolGuid,
+ NULL,
+ &Cpu
+ );
+ if (!EFI_ERROR (Status))
+ {
+ UINT64 CurrentTicker, TimerPeriod;
+ Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod);
+ if (!EFI_ERROR (Status))
+ FpdtVar->NanoFreq = TimerPeriod;
+
+ } else {
+ Status = pBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ GetNanoFreqCallback,
+ NULL,
+ &Event
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = pBS->RegisterProtocolNotify (
+ &gEfiMpServiceProtocolGuid,
+ Event,
+ &Registration
+ );
+ }
+ }
+ // <[EIP106575], [EIP106731]
+
+ // Get Cpu Frequency
+
+ FpdtVar->S3Pointer = FPDT->BasS3Rec.Pointer;
+ FpdtVar->BasBootPointer = FPDT->BasBootRec.Pointer;
+ Status = pRS->SetVariable(
+ EFI_FPDT_VARIABLE,
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(UINT32),
+ &FpdtVar
+ );
+ Status = pRS->GetVariable(
+ L"FPDT_Variable_NV", &gAmiGlobalVariableGuid,
+ NULL, &VarSize, &OldFpdtVarAddress
+ );
+ if (EFI_ERROR(Status) || (FpdtVar != OldFpdtVarAddress))
+ {
+ Status = pRS->SetVariable(
+ L"FPDT_Variable_NV",
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32),
+ &FpdtVar
+ );
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFIDT
+//
+// Description: This function allocates memory for and fills FIDT struscure.
+//
+// Input:
+// IN OUT **ACPI_HDR TablPtr - Pointer to memory, where the FACP table will resides.
+// Filled by this procedure
+// Output:
+// EFI_STATUS:
+// EFI_OUT_OF_RESOURCES - Memory for the table could not be allocated
+// EFI_SUCCESS - Table was successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildFIDT (IN OUT ACPI_HDR **TablPtr)
+
+{
+
+ FW_VERSION *FidPtr = NULL;
+ UINTN FidLen = 0;
+ ACPI_HDR *FidTblHdr;
+ EFI_GUID FwGuid = FW_VERSION_GUID;
+ UINT8 i;
+ CHAR8 CoreMajVer [3] = THREE_CHAR_ARRAY(CORE_MAJOR_VERSION);
+ CHAR8 CoreMinVer [3] = THREE_CHAR_ARRAY(CORE_MINOR_VERSION);
+ CHAR8 ProjMajVer [3] = THREE_CHAR_ARRAY(PROJECT_MAJOR_VERSION);
+ CHAR8 ProjMinVer [3] = THREE_CHAR_ARRAY(PROJECT_MINOR_VERSION);
+
+ FidLen = sizeof(ACPI_HDR) + sizeof(FW_VERSION);
+ *TablPtr = MallocZ (FidLen);
+ if ((*TablPtr)==NULL)
+ {
+ ASSERT(*TablPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FidTblHdr = (ACPI_HDR*)*TablPtr;
+ PrepareHdr20(FIDT_SIG, FidTblHdr, 4);
+ FidTblHdr->Length = (UINT32)FidLen;
+ FidTblHdr->Revision = 1;
+
+ FidPtr = (FW_VERSION*) ((UINT8*)FidTblHdr + sizeof(ACPI_HDR));
+
+ Strcpy (FidPtr->FirmwareID, CONVERT_TO_STRING($FID));
+ FidPtr->StructVersion = 4;
+ FidPtr->Size = sizeof(FW_VERSION);
+ Strcpy (FidPtr->BiosTag, CONVERT_TO_STRING(BIOS_TAG));
+ FidPtr->FirmwareGuid = FwGuid;
+ MemCpy(FidPtr->CoreMajorVersion, CoreMajVer, 3);
+ MemCpy(FidPtr->CoreMinorVersion, CoreMinVer, 3);
+ MemCpy(FidPtr->ProjectMajorVersion, ProjMajVer, 3);
+ MemCpy(FidPtr->ProjectMinorVersion, ProjMinVer, 3);
+
+ FidPtr->SignOnStringId = 0xffff;
+
+ for (i=0; i<6; i++) FidPtr->OemId[i]=ACPI_OEM_ID[i];
+
+ for (i=0; i<8; i++) FidPtr->OemTableId[i]=ACPI_OEM_TBL_ID[i];
+
+ FidTblHdr->Checksum = ChsumTbl((UINT8*)FidTblHdr, FidTblHdr->Length);
+
+
+
+ //TRACE((TRACE_ALWAYS, "FIDT Created.\n"));
+
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFacpiAll (NUINT TablVer, VOID *TablPtr)
+//
+// Description: This function allocates memory for and fills FACP table v 1.1+ with
+// predefined values from SDL tokens
+// Input:
+// IN UINTN TablVer - Version of FACP table
+// IN OUT **ACPI_HDR TablPtr - Pointer to memory, where the FACP table will resides.
+// Filled by this procedure
+// Output:
+// EFI_STATUS:
+// EFI_OUT_OF_RESOURCES - Memory for the table could not be allocated
+// EFI_SUCCESS - Table was successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS BuildFacpiAll (IN UINTN TablVer, OUT ACPI_HDR **TablPtr)
+
+{
+ FACP_50 *facp;
+ ACPI_HDR *FACP_Hdr;
+ UINT32 SizeOfFacp = sizeof(FACP_20);
+//-----------------------------
+
+ if (TablVer<1 || TablVer>4) return EFI_INVALID_PARAMETER;
+
+ if (TablVer == 1) SizeOfFacp = 0x84;// size of compatability 1.1 structure
+ if (ACPI_BUILD_TABLES_5_0 == 1) SizeOfFacp = sizeof(FACP_50);
+ *TablPtr = MallocZ (SizeOfFacp);
+ if ((*TablPtr)==NULL)
+ {
+ ASSERT(*TablPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FACP_Hdr = *TablPtr;
+
+ if (TablVer == 1)
+ {
+ PrepareHdr20(FACP_SIG, FACP_Hdr, 2);
+ FACP_Hdr->Revision = ACPI_REV2;// compatability 1.1 structure
+ }
+
+ else
+ PrepareHdr20(FACP_SIG, FACP_Hdr, TablVer);
+
+ facp = (PFACP_50) *TablPtr;
+
+ facp->Reserved1 = ACPI_INT_MODEL;
+
+ facp->PM_PPROF = ACPI_PM_PROFILE;
+ facp->SCI_INT = ACPI_SCI_INT;
+ facp->SMI_CMD = SW_SMI_IO_ADDRESS;
+ facp->ACPI_ENABLE_CMD = SW_SMI_ACPI_ENABLE;
+ facp->ACPI_DISABLE_CMD = SW_SMI_ACPI_DISABLE;
+ facp->S4BIOS_REQ = SW_SMI_S4BIOS;
+
+ facp->PSTATE_CNT = SW_SMI_PSTATE_CNT;
+
+ if (PM1A_EVT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1a_EVT_BLK = 0;
+ else
+ facp->PM1a_EVT_BLK = PM1A_EVT_BLK_ADDRESS;
+
+ if (PM1B_EVT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1b_EVT_BLK = 0;
+ else
+ facp->PM1b_EVT_BLK = PM1B_EVT_BLK_ADDRESS;
+
+ if (PM1A_CNT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1a_CNT_BLK = 0;
+ else
+ facp->PM1a_CNT_BLK = PM1A_CNT_BLK_ADDRESS;
+
+ if (PM1B_CNT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1b_CNT_BLK = 0;
+ else
+ facp->PM1b_CNT_BLK = PM1B_CNT_BLK_ADDRESS;
+
+ if (PM2_CNT_BLK_ADDRESS > 0xffffffff)
+ facp->PM2_CNT_BLK = 0;
+ else
+ facp->PM2_CNT_BLK = PM2_CNT_BLK_ADDRESS;
+
+ if (PM_TMR_BLK_ADDRESS > 0xffffffff)
+ facp->PM_TMR_BLK = 0;
+ else
+ facp->PM_TMR_BLK = PM_TMR_BLK_ADDRESS;
+
+ if (GPE0_BLK_ADDRESS > 0xffffffff)
+ facp->GPE0_BLK = 0;
+ else
+ facp->GPE0_BLK = GPE0_BLK_ADDRESS;
+
+ if (GPE1_BLK_ADDRESS > 0xffffffff)
+ facp->GPE1_BLK = 0;
+ else
+ facp->GPE1_BLK = GPE1_BLK_ADDRESS;
+
+ facp->GPE0_BLK_LEN = GPE0_BLK_LENGTH;
+ facp->GPE1_BLK_LEN = GPE1_BLK_LENGTH;
+ facp->GPE1_BASE = GPE1_BASE_OFFSET;
+ facp->PM1_EVT_LEN = PM1_EVT_LENGTH;
+ facp->PM1_CNT_LEN = PM1_CNT_LENGTH;
+ facp->PM2_CNT_LEN = PM2_CNT_LENGTH;
+ facp->PM_TM_LEN = PM_TMR_LENGTH;
+
+ facp->CST_CNT = SW_SMI_CST_CNT;
+ facp->P_LVL2_LAT = P_LVL2_LAT_VAL;
+ facp->P_LVL3_LAT = P_LVL3_LAT_VAL;
+ facp->FLUSH_SIZE = FLUSH_SIZE_VAL;
+ facp->FLUSH_STRIDE = FLUSH_STRIDE_VAL;
+ facp->DUTY_OFFSET = DUTY_OFFSET_VAL;
+ facp->DUTY_WIDTH = DUTY_WIDTH_VAL;
+ facp->DAY_ALRM = ACPI_ALARM_DAY_CMOS;
+ facp->MON_ALRM = ACPI_ALARM_MONTH_CMOS;
+ facp->CENTURY = ACPI_CENTURY_CMOS;
+ facp->IAPC_BOOT_ARCH = ACPI_IA_BOOT_ARCH;
+
+ //--------Filling Flags for V.1----------------------
+
+ facp->FLAGS = 0;
+
+ if (FACP_FLAG_WBINVD) facp->FLAGS = 1;
+
+ if (FACP_FLAG_WBINVD_FLUSH) facp->FLAGS |= 1<<1;
+
+ if (FACP_FLAG_PROC_C1) facp->FLAGS |= 1<<2;
+
+ if (FACP_FLAG_P_LVL2_UP) facp->FLAGS |= 1<<3;
+
+ if (FACP_FLAG_PWR_BUTTON) facp->FLAGS |= 1<<4;
+
+ if (FACP_FLAG_SLP_BUTTON) facp->FLAGS |= 1<<5;
+
+ if (FACP_FLAG_FIX_RTC) facp->FLAGS |= 1<<6;
+
+ if (FACP_FLAG_RTC_S4) facp->FLAGS |= 1<<7;
+
+ if (FACP_FLAG_TMR_VAL_EXT) facp->FLAGS |= 1<<8;
+
+ if (FACP_FLAG_DCK_CAP) facp->FLAGS |= 1<<9;
+
+
+ //--------Filling Flags for V.2 and GAS compat structure for v.1----------------------
+
+ if (FACP_FLAG_RESET_REG_SUP) facp->FLAGS |= 1<<10;
+
+ if (FACP_FLAG_SEALED_CASE) facp->FLAGS |= 1<<11;
+
+ if (FACP_FLAG_HEADLESS) facp->FLAGS |= 1<<12;
+
+ if (FACP_FLAG_CPU_SW_SLP) facp->FLAGS |= 1<<13;
+
+#if ACPI_BUILD_TABLES_3_0
+
+ if (FACP_FLAG_USE_PLATFORM_CLOCK) facp->FLAGS |= 1<<15;
+
+ if (FACP_FLAG_S4_RTC_STS_VALID) facp->FLAGS |= 1<<16;
+
+ if (FACP_FLAG_REMOTE_POWER_ON_CAPABLE) facp->FLAGS |= 1<<17;
+
+ if (TablVer > 2)
+ {
+ if (FACP_FLAG_FORCE_APIC_CLUSTER_MODEL) facp->FLAGS |= 1<<18;
+
+ if (FACP_FLAG_FORCE_APIC_PHYSICAL_DESTINATION_MODE) facp->FLAGS |= 1<<19;
+
+ if (FACP_FLAG_PCI_EXP_WAK) facp->FLAGS |= 1<<14;
+ }
+
+#endif
+
+ // RESET_REG GAS_20 structure and value
+ facp->RESET_REG.AddrSpcID = ACPI_RESET_REG_TYPE;
+ facp->RESET_REG.RegBitWidth = ACPI_RESET_REG_BITWIDTH;
+ facp->RESET_REG.RegBitOffs = ACPI_RESET_REG_BITOFFSET;
+ facp->RESET_REG.Address = ACPI_RESET_REG_ADDRESS;
+ facp->RESET_VAL = ACPI_RESET_REG_VALUE;
+
+ if (ACPI_RESET_REG_ADDRESS)
+ {
+ // Set FACP flag
+ facp->FLAGS |= 1<<10;
+ }
+
+ if (TablVer == 1)
+ {
+ facp->Header.Length = 0x84;
+ facp->Header.Checksum = 0;
+ facp->Header.Checksum = ChsumTbl((UINT8*)facp, facp->Header.Length);
+ return EFI_SUCCESS;
+ }
+
+ //--------This is all for V.1-----------------------
+
+ // PM1a_EVT_BLK GAS_20 structure
+ facp->X_PM1a_EVT_BLK.AddrSpcID = PM1A_EVT_BLK_TYPE;
+ facp->X_PM1a_EVT_BLK.RegBitWidth= PM1A_EVT_BLK_BITWIDTH;
+ facp->X_PM1a_EVT_BLK.RegBitOffs = PM1A_EVT_BLK_BITOFFSET;
+ facp->X_PM1a_EVT_BLK.AccessSize = 2;
+ facp->X_PM1a_EVT_BLK.Address = PM1A_EVT_BLK_ADDRESS;
+
+ // PM1a_CNT_BLK GAS_20 structure
+ facp->X_PM1a_CNT_BLK.AddrSpcID = PM1A_CNT_BLK_TYPE;
+ facp->X_PM1a_CNT_BLK.RegBitWidth= PM1A_CNT_BLK_BITWIDTH;
+ facp->X_PM1a_CNT_BLK.RegBitOffs = PM1A_CNT_BLK_BITOFFSET;
+ facp->X_PM1a_CNT_BLK.AccessSize = 2;
+ facp->X_PM1a_CNT_BLK.Address = PM1A_CNT_BLK_ADDRESS;
+
+ // PM1b_EVT_BLK GAS_20 structure
+ facp->X_PM1b_EVT_BLK.AddrSpcID = PM1B_EVT_BLK_TYPE;
+ facp->X_PM1b_EVT_BLK.RegBitWidth= PM1B_EVT_BLK_BITWIDTH;
+ facp->X_PM1b_EVT_BLK.RegBitOffs = PM1B_EVT_BLK_BITOFFSET;
+ facp->X_PM1b_EVT_BLK.AccessSize = 2;
+ facp->X_PM1b_EVT_BLK.Address = PM1B_EVT_BLK_ADDRESS;
+
+ // PM1b_CNT_BLK GAS_20 structure
+ facp->X_PM1b_CNT_BLK.AddrSpcID = PM1B_CNT_BLK_TYPE;
+ facp->X_PM1b_CNT_BLK.RegBitWidth= PM1B_CNT_BLK_BITWIDTH;
+ facp->X_PM1b_CNT_BLK.RegBitOffs = PM1B_CNT_BLK_BITOFFSET;
+ facp->X_PM1b_CNT_BLK.AccessSize = 2;
+ facp->X_PM1b_CNT_BLK.Address = PM1B_CNT_BLK_ADDRESS;
+
+ // PM1b_CNT_BLK GAS_20 structure
+ facp->X_PM2_CNT_BLK.AddrSpcID = PM2_CNT_BLK_TYPE;
+ facp->X_PM2_CNT_BLK.RegBitWidth = PM2_CNT_BLK_BITWIDTH;
+ facp->X_PM2_CNT_BLK.RegBitOffs = PM2_CNT_BLK_BITOFFSET;
+ facp->X_PM2_CNT_BLK.AccessSize = 1;
+ facp->X_PM2_CNT_BLK.Address = PM2_CNT_BLK_ADDRESS;
+
+ facp->X_PM_TMR_BLK.AddrSpcID = PM_TMR_BLK_TYPE;
+ facp->X_PM_TMR_BLK.RegBitWidth = PM_TMR_BLK_BITWIDTH;
+ facp->X_PM_TMR_BLK.RegBitOffs = PM_TMR_BLK_BITOFFSET;
+ facp->X_PM_TMR_BLK.AccessSize = 3;
+ facp->X_PM_TMR_BLK.Address = PM_TMR_BLK_ADDRESS;
+
+ facp->X_GPE0_BLK.AddrSpcID = GPE0_BLK_TYPE;
+ facp->X_GPE0_BLK.RegBitWidth = GPE0_BLK_BITWIDTH;
+ facp->X_GPE0_BLK.RegBitOffs = GPE0_BLK_BITOFFSET;
+ facp->X_GPE0_BLK.AccessSize = 1;
+ facp->X_GPE0_BLK.Address = GPE0_BLK_ADDRESS;
+
+ facp->X_GPE1_BLK.AddrSpcID = GPE1_BLK_TYPE;
+ facp->X_GPE1_BLK.RegBitWidth = GPE1_BLK_BITWIDTH;
+ facp->X_GPE1_BLK.RegBitOffs = GPE1_BLK_BITOFFSET;
+ facp->X_GPE1_BLK.AccessSize = 1;
+ facp->X_GPE1_BLK.Address = GPE1_BLK_ADDRESS;
+
+ if (ACPI_BUILD_TABLES_5_0 == 1)
+ {
+#if HW_REDUCED_ACPI
+
+ facp->FLAGS |= 1<<20;
+
+ facp->SLEEP_CONTROL_REG.AddrSpcID = SLEEP_CONTROL_REG_TYPE;
+ facp->SLEEP_CONTROL_REG.RegBitWidth = SLEEP_CONTROL_REG_BITWIDTH;
+ facp->SLEEP_CONTROL_REG.RegBitOffs = SLEEP_CONTROL_REG_BITOFFSET;
+ facp->SLEEP_CONTROL_REG.AccessSize = SLEEP_CONTROL_REG_ACCESS_SIZE;
+ facp->SLEEP_CONTROL_REG.Address = SLEEP_CONTROL_REG_ADDRESS;
+
+ facp->SLEEP_STATUS_REG.AddrSpcID = SLEEP_STATUS_REG_TYPE;
+ facp->SLEEP_STATUS_REG.RegBitWidth = SLEEP_STATUS_REG_BITWIDTH;
+ facp->SLEEP_STATUS_REG.RegBitOffs = SLEEP_STATUS_REG_BITOFFSET;
+ facp->SLEEP_STATUS_REG.AccessSize = SLEEP_STATUS_REG_ACCESS_SIZE;
+ facp->SLEEP_STATUS_REG.Address = SLEEP_STATUS_REG_ADDRESS;
+#endif
+
+ if (LOW_POWER_S0_IDLE_CAPABLE) facp->FLAGS |= 1<<21;
+ facp->Header.Revision = 5; // ACPI 5.0 revision
+ }
+ facp->Header.Length = SizeOfFacp;
+ facp->Header.Checksum = 0;
+ facp->Header.Checksum = ChsumTbl((UINT8*)facp, facp->Header.Length);
+
+ return EFI_SUCCESS;
+
+}// end of BuildFacpiAll
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapic
+//
+// Description: Allocates memory for and builds LAPIC entry for MADT table
+//
+// Input: IN CPUINFO *CpuInfo - Pointer to a block of information about cpu
+// passed through cpu info HOB, if NULL - it is a
+// dummy entry.
+// IN UINTN CpuCount - Number of the cpu
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+MADT_ENTRY_HEADER *BuildLapic(IN CPUINFO *CpuInfo, IN UINT32 CpuId)
+{
+ LAPIC_H32 *LapicPtr;
+ LapicPtr = MallocZ(sizeof(LAPIC_H32));
+ ASSERT (LapicPtr);
+
+ if (!LapicPtr) return NULL;
+
+ LapicPtr->Header.Type = (UINT8) AT_LAPIC; //Type 0 - indicating LAPIC Entry
+ LapicPtr->Header.Length = (UINT8) sizeof(LAPIC_H32);
+ LapicPtr->CpuId = CpuId;
+
+ if (CpuInfo != NULL) // This is not a dummy entry
+ {
+ LapicPtr->LapicId = (UINT8) CpuInfo->ApicId;
+ if (gMaxLapic < LapicPtr->LapicId) gMaxLapic = LapicPtr->LapicId;
+ LapicPtr->Flags = (CpuInfo->Valid) ? FL_ENABLE : 0;
+ }
+
+ else // Tis is a dummy entry for not installed processor
+ {
+ LapicPtr->LapicId = ++gMaxLapic;
+ LapicPtr->Flags = 0;
+ }
+
+ return (MADT_ENTRY_HEADER*) LapicPtr;
+
+}// end of BuildLapic
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLx2Apic
+//
+// Description: Allocates memory for and builds Local x2APIC entry for MADT table
+//
+// Input:
+// IN UINT32 ApicId - Apic Id of processor.
+// IN UINT32 Uid - UID of processor.
+// IN UINT32 Flags - Flags of entry.
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LX2APIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+MADT_ENTRY_HEADER *BuildLx2Apic(IN UINT32 ApicId, IN UINT32 Uid, IN UINT32 Flags)
+{
+ LX2APIC *Lx2ApicPtr;
+ Lx2ApicPtr = MallocZ(sizeof(LX2APIC));
+ ASSERT (Lx2ApicPtr);
+
+ if (!Lx2ApicPtr) return NULL;
+
+ Lx2ApicPtr->Header.Type = (UINT8) AT_LX2APIC; //Type A - indicating LX2APIC Entry
+ Lx2ApicPtr->Header.Length = (UINT8) sizeof(LX2APIC);
+ Lx2ApicPtr->ApicId = ApicId;
+ Lx2ApicPtr->Flags = Flags;
+ Lx2ApicPtr->Uid = Uid;
+ return (MADT_ENTRY_HEADER*) Lx2ApicPtr;
+}// end of BuildLx2Apic
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLsapic
+//
+// Description: Allocates memory for and builds LSAPIC entry for MADT table
+//
+//
+// Input: IN CPUINFO *CpuInfo - Pointer to a block of information about cpu
+// passed through cpu info HOB
+// IN UINT32 CpuCount - Number of the cpu
+// IN UINTN Ver - Version of MADT table
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+MADT_ENTRY_HEADER *BuildLsapic(IN CPUINFO *CpuInfo, IN UINT32 CpuId, IN UINTN Ver)
+{
+ LSAPIC_H20 *LsapicPtr;
+
+ if (Ver < 3)
+ LsapicPtr = MallocZ(sizeof(LSAPIC_H20));
+ else
+ LsapicPtr = MallocZ(sizeof(LSAPIC_H30));
+
+ ASSERT (LsapicPtr);
+
+ if (!LsapicPtr) return NULL;
+
+ LsapicPtr->Header.Type = (UINT8) AT_LSAPIC; //Type 7 - indicating LSAPIC Entry
+
+ if (Ver < 3)
+ LsapicPtr->Header.Length = (UINT8) sizeof(LSAPIC_H20);
+ else
+ LsapicPtr->Header.Length = (UINT8) sizeof(LSAPIC_H30);
+
+ LsapicPtr->CpuId = CpuId;
+ LsapicPtr->LsapicId = (UINT8) CpuInfo->ApicId;
+ LsapicPtr->LsapicEid = (UINT8) CpuInfo->ApicEId;
+ LsapicPtr->Flags = (CpuInfo->Valid) ? FL_ENABLE : 0;
+ return (MADT_ENTRY_HEADER*) LsapicPtr;
+
+}// end of BuildLsapic LapicPtr
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildIoapicIosapic
+//
+// Description:
+// This function will probe IndReg and DataReg of discovered IOxAPIC base address
+// and allocate memory for and builds Ioapic/Iosapic entry for MADT table
+//
+// Input:
+// IN UINT64 BaseAddr - Base Addrerss where IOxApic presence detected
+// IN OUT UINT64 *VecBase - pointer to the System Vector Base variable that
+// needs to be updated with IOAPIC.MAXREDIR# by this function
+//
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the Ioapic/Iosapi entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#pragma optimize( "", off )
+MADT_ENTRY_HEADER *BuildIoapicIosapic(IN UINT32 BaseAddr, OUT UINT32 *VecBase)
+{
+ UINT32 Tmp;
+ UINT32 volatile *DatPtr;
+ UINT8 volatile *IdxPtr;
+ UINT32 IoapicId;
+ UINT32 IoapicVer;
+ IOAPIC_H20 *IoapicPtr;
+ IOSAPIC_H20 *IosapicPtr;
+
+//==============================
+ //Read IOAPIC.ID reg and figure out
+ //1.How many INTINs it has
+ //2.What ID did BIOS gave to it
+ IdxPtr=(UINT8*)(BaseAddr + IOA_IND_REG_OFFS);
+ DatPtr=(UINT32*)(BaseAddr + IOA_DAT_REG_OFFS);
+
+ *IdxPtr = IOA_ID_IND; // bits 27..24=IOAPIC_ID
+
+ Tmp = *DatPtr;
+
+ IoapicId = ((Tmp&0x0f000000)>>24);
+
+ *IdxPtr = IOA_VER_IND; // IOAPIC_VER register
+
+ Tmp=*DatPtr;
+
+ IoapicVer=(Tmp&0xff);
+
+ if (IoapicVer < IO_APIC_VERSION_PARAMETER) // This is Ioapic
+ {
+ IoapicPtr = MallocZ(sizeof(IOAPIC_H20));
+ ASSERT (IoapicPtr);
+
+ if (!IoapicPtr) return NULL;
+
+ IoapicPtr->Header.Type = (UINT8) AT_IOAPIC; // 1 - For IOAPIC Structure
+ IoapicPtr->Header.Length = (UINT8) sizeof (IOAPIC_H20);
+ IoapicPtr->IoapicAddress = (UINT32) BaseAddr;
+ IoapicPtr->IoapicId = (UINT8) IoapicId;
+ IoapicPtr->SysVectBase = (UINT32) *VecBase;
+ //Adjust VecBase with current Max Redirection value
+ (*VecBase)+=((UINT32)((Tmp&0x00ff0000)>>16))+1;
+ return (MADT_ENTRY_HEADER*) IoapicPtr;
+ }
+
+ else // This is Iosapic
+ {
+ IosapicPtr = MallocZ(sizeof(IOSAPIC_H20));
+ ASSERT (IosapicPtr);
+
+ if (!IosapicPtr) return NULL;
+
+ IosapicPtr->Header.Type = (UINT8) AT_IOSAPIC; // 6 - For IOSAPIC Structure
+ IosapicPtr->Header.Length = (UINT8) sizeof (IOSAPIC_H20);
+ IosapicPtr->IosapicAddress = (UINT64) BaseAddr;
+ IosapicPtr->IoapicId = (UINT8) IoapicId;
+ IosapicPtr->SysVectBase = (UINT32) *VecBase;
+ //Adjust VecBase with current Max Redirection value
+ (*VecBase)+=((UINT32)((Tmp&0x00ff0000)>>16))+1;
+ return (MADT_ENTRY_HEADER*) IosapicPtr;
+ }
+
+}// End of BuildIoapicIosapic
+#pragma optimize( "", on )
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildIoapicManualy
+//
+// Description: Allocates memory for and builds LAPIC entry for MADT table filled with
+// Dummy information
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MADT_ENTRY_HEADER *BuildIoapicManualy()
+{
+ IOAPIC_H20 *IoapicPtr;
+
+ IoapicPtr = MallocZ(sizeof(IOAPIC_H20));
+ ASSERT (IoapicPtr);
+
+ if (!IoapicPtr) return NULL;
+
+ IoapicPtr->Header.Type = (UINT8) AT_IOAPIC; // 1 - For IOAPIC Structure
+ IoapicPtr->Header.Length = (UINT8) sizeof (IOAPIC_H20);
+ IoapicPtr->IoapicAddress = (UINT32) APCB;
+ IoapicPtr->IoapicId = (UINT8) 0;
+ IoapicPtr->SysVectBase = (UINT32) 0;
+ return (MADT_ENTRY_HEADER*) IoapicPtr;
+
+
+}// end of BuildIoapicManualy
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddIsoFromTbl
+//
+// Description: Allocates memory for and builds ISO entry for MADT table, based
+// on INTERRUPT SOURCE OVERRIDE info from predifined table
+//
+// Input: UINTN IsoTblNumb - Number of entry in ISO table for which an entry should
+// be build.
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the ISO entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MADT_ENTRY_HEADER *BuildIsoFromTbl (UINTN IsoTblNumb)
+{
+ ISO_H20 *IsoPtr;
+
+ IsoPtr = MallocZ(sizeof(ISO_H20));
+ ASSERT (IsoPtr);
+
+ if (!IsoPtr) return NULL;
+
+ IsoPtr->Header.Type = AT_ISO; // 2 - For ISO structure
+ IsoPtr->Header.Length = sizeof(ISO_H20);
+ IsoPtr->Bus = 0;
+ IsoPtr->Source = (UINT8) IsoTbl[IsoTblNumb].PicIrq;
+ IsoPtr->GlobalSysVect = (UINT32) IsoTbl[IsoTblNumb].ApicInt;
+ IsoPtr->Flags = (UINT16) IsoTbl[IsoTblNumb].Flags;
+ return (MADT_ENTRY_HEADER*) IsoPtr;
+}//end of BuildIsoFromTbl
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapicsFromHob
+//
+// Description:
+// Build Local Apic Entries from HOB.
+//
+// Input:
+// IN UINTN TableVer - ACPI Spec. Version
+// IN OUT MADT_ENTRIES *MadtTblEntries - MADT Table Entry list.
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_UNSUPPORTED - CPU info hob not found
+// EFI_INVALID_PARAMETER - invalid ACPI version
+// EFI_SUCCESS - MADT table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildLapicsFromHob(
+ IN UINTN TablVer,
+ IN OUT MADT_ENTRIES *MadtTblEntries
+)
+{
+ UINT32 NumbOfCPUs, DummyCPUs = 0, i;
+ static EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ UINT32 CpuCount, LastItem = 1;
+ CPUINFO_HOB *CpuInfoHob;
+ CPUINFO *CpuInfo = NULL;
+ MADT_ENTRY_HEADER *HdrPtr;
+ EFI_STATUS Status;
+
+ CpuInfoHob = (CPUINFO_HOB*)GetEfiConfigurationTable(pST,&HobListGuid);
+
+ if (CpuInfoHob == NULL) Status = EFI_UNSUPPORTED;
+ else Status = FindNextHobByGuid(&CpuInfoHobGuid,(VOID**)&CpuInfoHob);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ NumbOfCPUs = CpuInfoHob->CpuCount;
+
+#if defined SKIP_DUMMY_LAPICS && SKIP_DUMMY_LAPICS==1
+// If SKIP_DUMMY_LAPICS defined and 1 - somebody want to skip creation of dummy lapics
+// So do nothing there
+#else
+#if NCPU != 0
+DummyCPUs = NCPU; // NCPU - maximum poccesoros supported by platform - so we need to create dummy entries for
+#endif // all processors that are not present, but could be hotpluged.
+#endif
+
+//---Creating LAPIC or/and LSAPIC Entries----------------
+ if (DummyCPUs <= NumbOfCPUs) DummyCPUs = NumbOfCPUs;
+
+ for (CpuCount=0; CpuCount < DummyCPUs; CpuCount++)
+ {
+ if (CpuCount < NumbOfCPUs)
+ {
+ CpuInfo = &(CpuInfoHob->Cpuinfo[CpuCount]);
+
+ if (CpuInfo->ApicVer < LOCAL_APIC_VERSION_PARAMETER)
+ HdrPtr = BuildLapic(CpuInfo, CpuCount + 1); //Id must match processor object, so add 1 to Cpu Count.
+ else
+ HdrPtr = BuildLsapic(CpuInfo, CpuCount + 1, TablVer); //Id must match processor object, so add 1 to Cpu Count.
+ }
+
+ else HdrPtr = BuildLapic(NULL, CpuCount + 1); // Just add dummy entry
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries->MadtEntCount == 0) // Adding entries in groving LapicId/LsapicId value order
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);// First entry
+ else
+ {
+ for (i = (LastItem - 1); i < MadtTblEntries->MadtEntCount; i++) // No need to handle LSAPIC entry in different way
+ {
+ if (((LAPIC_H32*)HdrPtr)->LapicId < ((LAPIC_H32*)MadtTblEntries->MadtEntries[i])->LapicId) break; // LapicId and LsapicId filds are on the same place in bouth structures
+ } // found entry with bigger LapicId/LsapicId
+
+ if (i == MadtTblEntries->MadtEntCount)
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);
+ else
+ Status = InsertItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr, i);
+ }
+
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapicsFromProtocol
+//
+// Description:
+// Build Local Apic Entries from Protocol.
+//
+// Input:
+// IN UINTN TableVer - ACPI Spec. Version
+// IN OUT MADT_ENTRIES *MadtTblEntries - MADT Table Entry list.
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_UNSUPPORTED - CPU info hob not found
+// EFI_INVALID_PARAMETER - invalid ACPI version
+// EFI_SUCCESS - MADT table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+
+EFI_STATUS BuildLapicsFromProtocol(
+ IN UINTN TablVer,
+ IN OUT MADT_ENTRIES *MadtTblEntries
+)
+{
+ EFI_STATUS Status;
+ MADT_ENTRY_HEADER *HdrPtr;
+ ACPI_PROCESSOR_INFO *AcpiProcInfo;
+ UINT32 NumEntries;
+ UINT32 Index;
+ CPUINFO CpuInfo;
+
+ if (gAmiCpu2Info->ProtocolVer < 1) return EFI_UNSUPPORTED;
+
+ Status = gAmiCpu2Info->GetAcpiInfo(
+ gAmiCpu2Info, (VOID**) &AcpiProcInfo, &NumEntries
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ for (Index = 0; Index < NumEntries; ++Index)
+ {
+ //Note: Only some ACPI_PROCESSOR_INFO fields may only valid for some minimum ACPI_PROCESSOR_INFO.Length.
+ //The ACPI_PROCESSOR_INFO may have additional fields added in later version. Please see comments in
+ //AmiCpuInfo2.h file.
+ if (AcpiProcInfo->Type == ACPI_PROCESSOR_INFO_TYPE)
+ {
+ if (AcpiProcInfo->Length >= 60 && AcpiProcInfo->LocalApicType == ACPI_PROC_INFO_x2APIC)
+ {
+ HdrPtr = BuildLx2Apic(AcpiProcInfo->ApicId, AcpiProcInfo->ProcId, 1);
+ gX2Apic = TRUE;
+ }
+
+ else
+ {
+ //This current implementation only supports 8 bit APIC Id and 8-bit extended Id.
+ CpuInfo.Valid = (BOOLEAN)AcpiProcInfo->Enable;
+ CpuInfo.ApicId = (UINT8)AcpiProcInfo->ApicId;
+ CpuInfo.ApicEId = (UINT8)(AcpiProcInfo->ApicId >> 8);
+ CpuInfo.ApicVer = (UINT8)AcpiProcInfo->ApicVer;
+
+ //Produce entry.
+ if (AcpiProcInfo->ApicVer < LOCAL_APIC_VERSION_PARAMETER)
+ HdrPtr = BuildLapic(&CpuInfo, AcpiProcInfo->ProcId);
+ else
+ HdrPtr = BuildLsapic(&CpuInfo, AcpiProcInfo->ProcId, TablVer);
+ }
+
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ }
+
+ //An earlier version ACPI_PROCESSOR_INFO with a smaller structure may be have been published,
+ //so use length field.
+ AcpiProcInfo = (ACPI_PROCESSOR_INFO*)((UINT8*)AcpiProcInfo + AcpiProcInfo->Length);
+ }
+
+ return EFI_SUCCESS;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapicNmiFromProtocol
+//
+// Description:
+// Build Local Apic NMI Entries from Protocol.
+//
+// Input:
+// IN OUT MADT_ENTRIES *MadtTblEntries - MADT Table Entry list.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if AMI_CPU_INFO_2_PROTOCOL_VERSION >= 3
+EFI_STATUS BuildLapicNmiFromProtocol(
+ IN OUT MADT_ENTRIES *MadtTblEntries
+)
+{
+ EFI_STATUS Status;
+ MADT_ENTRY_HEADER *HdrPtr;
+ ACPI_PROCESSOR_INFO *AcpiProcInfo;
+ UINT32 NumEntries;
+ UINT32 Index;
+
+ if (gAmiCpu2Info->ProtocolVer < 1) return EFI_UNSUPPORTED;
+
+ Status = gAmiCpu2Info->GetAcpiInfo(
+ gAmiCpu2Info, (VOID**) &AcpiProcInfo, &NumEntries
+ );
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = EFI_NOT_FOUND;
+
+ for (Index = 0; Index < NumEntries; ++Index)
+ {
+ //Note: Only some ACPI_PROCESSOR_INFO fields may only valid for some minimum ACPI_PROCESSOR_INFO.Length.
+ //The ACPI_PROCESSOR_INFO may have additional fields added in later version. Please see comments in
+ //AmiCpuInfo2.h file.
+ if (AcpiProcInfo->Type == ACPI_PROCESSOR_INFO_TYPE)
+ {
+ if (AcpiProcInfo->Length >= 72 && AcpiProcInfo->ProduceNmi == TRUE)
+ {
+ HdrPtr = BuildLocalApicNmi(
+ AcpiProcInfo->LocalApicType == ACPI_PROC_INFO_x2APIC,
+ AcpiProcInfo->ProcId,
+ AcpiProcInfo->LintnPin,
+ AcpiProcInfo->NmiFlags
+ );
+
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+ //An earlier version ACPI_PROCESSOR_INFO with a smaller structure may be have been published,
+ //so use length field.
+ AcpiProcInfo = (ACPI_PROCESSOR_INFO*)((UINT8*)AcpiProcInfo + AcpiProcInfo->Length);
+ }
+ return Status;
+}
+
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLocalApicNmi
+//
+// Description: Allocates memory for and builds local APIC or local x2APIC NMI entry
+//
+// Input:
+// IN UINT32 ProcessorId - MADT NMI entry processor id or UID
+// IN UINT8 LapicInitIn - MADT Local (x2)apic NMI Pin
+// IN UINT16 Flags - MADT Local (x2) apic flags
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC NMI entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MADT_ENTRY_HEADER * BuildLocalApicNmi(IN BOOLEAN X2Apic, IN UINT32 ProcessorId, IN UINT8 LapicInitIn, IN UINT16 Flags)
+{
+ MADT_ENTRY_HEADER *HdrPtr;
+
+ if (X2Apic)
+ {
+ HdrPtr = MallocZ(sizeof(LX2APIC_NMI));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return NULL;
+
+ ((LX2APIC_NMI*) HdrPtr)->Header.Type = AT_LX2APIC_NMI; //Type 10 - indicating Local x2APIC NMI Entry.
+ ((LX2APIC_NMI*) HdrPtr)->Header.Length = sizeof(LX2APIC_NMI);
+ ((LX2APIC_NMI*) HdrPtr)->Flags = Flags;
+ ((LX2APIC_NMI*) HdrPtr)->Uid = ProcessorId;
+ ((LX2APIC_NMI*) HdrPtr)->LapicIntin = LapicInitIn;
+ }
+ else
+ {
+ HdrPtr = MallocZ(sizeof(LNMI_H20));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return NULL;
+
+ ((LNMI_H20*) HdrPtr)->Header.Type = AT_LAPIC_NMI; //Type 4 - indicating LAPIC NMIs Entry
+ ((LNMI_H20*) HdrPtr)->Header.Length = sizeof(LNMI_H20);
+ ((LNMI_H20*) HdrPtr)->Flags = Flags;
+ ((LNMI_H20*) HdrPtr)->CPU_ID = (UINT8)ProcessorId;
+ ((LNMI_H20*) HdrPtr)->LapicIntin = LapicInitIn;
+ }
+
+ return HdrPtr;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildMadtAll
+//
+// Description: Creates MADT entries, stores them as T_ITEM_LIST, calculates
+// space needed, allocates memory and builds MADT table from entries
+//
+// Input:
+// IN UINTN TablVer - ACPI Spec. Version
+// OUT ACPI_HDR **TablPtr - Pointer, to the MADT table, filled by this function
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_UNSUPPORTED - CPU info hob not found
+// EFI_INVALID_PARAMETER - invalid ACPI version
+// EFI_SUCCESS - MADT table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildMadtAll(IN UINTN TablVer, OUT ACPI_HDR **TablPtr)
+{
+ UINTN LastItem;
+ EFI_STATUS Status;
+ MADT_ENTRIES MadtTblEntries = {0, 0, NULL};
+ MADT_ENTRY_HEADER *HdrPtr;
+ UINT32 IoapicVbase = 0, AllStrLength = 0, IoapicAddr = 0;
+ UINT8 *DestinPtr;
+ UINTN i, j;
+ UINTN IoApicCnt=0;
+
+//--------------------------------
+ if (TablVer<1 || TablVer>4) return EFI_INVALID_PARAMETER;
+
+//-------Build LAPIC or/and LSAPIC Entries.
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ // Update for Haswell CPU Refcode. >>>
+ Status = pBS->LocateProtocol(&gAmiCpuInfo2ProtocolGuid, NULL, &gAmiCpu2Info);
+ // <<< Update for Haswell CPU Refcode.
+ Status = EFI_UNSUPPORTED;
+
+ //First try to build Local APIC information from the protocol.
+ if (gAmiCpu2Info != NULL)
+ {
+ Status = BuildLapicsFromProtocol(TablVer, &MadtTblEntries);
+ }
+
+ //If protocol fails, try CPU INFO HOB.
+ if (EFI_ERROR(Status))
+ {
+
+#endif
+ Status = BuildLapicsFromHob(TablVer, &MadtTblEntries);
+ ASSERT_EFI_ERROR(Status);
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ }
+
+#endif
+ //Set Marker at last item before IOAPIC/IOsAPIC entries
+ LastItem = MadtTblEntries.MadtEntCount;
+
+//The folloving code may enable IOAPIC Devices found on PCI BUS
+//This IOAPICs might use their ABARs to clame MMIO in FEC0_0000 space.
+//So we need to run this code prior if we don't want to miss any IOAPICs.
+//--------------------------------------------------------------------
+#if PCI_BUS_APIC_AUTODETECT == 1
+ {
+ EFI_HANDLE *pHandleBuffer;
+ UINTN NumberOfHandles;
+ UINT8 PciData[4];
+ EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+ EFI_PCI_IO_PROTOCOL *pPciIoProtocol;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &PciIoProtocolGuid,
+ NULL, &NumberOfHandles, &pHandleBuffer);
+
+ //The protocol might not be available when function runs first time.
+ //we will rerun it on READY_TO_BOOT event again.
+ if (!EFI_ERROR(Status))
+ {
+
+ for (i = 0; i < NumberOfHandles; i++)
+ {
+ Status = pBS->HandleProtocol(pHandleBuffer[i], &PciIoProtocolGuid,
+ (VOID**)&pPciIoProtocol);
+
+ if (EFI_ERROR(Status))
+ continue;
+
+ //read class code information at 0x8 offset in PCI header
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x8, 1, &PciData[0]);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) //problem
+ continue;
+
+ //if IO APIC device
+ if ((PciData[3] == 0x8) && (PciData[2] == 0) && (PciData[1] >= 0x10))
+ {
+ UINT64 Attr=0, OldAttr=0;
+ //----------------------
+ //1. make sure it is Enabled and Decoding it's resources
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationGet, Attr, &OldAttr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSupported, 0, &Attr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSet, Attr&(EFI_PCI_DEVICE_ENABLE), NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+
+ //2. collect info
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x10, 1, (VOID*)&IoapicAddr);
+ //problem or mapped to default address range
+ ASSERT_EFI_ERROR(Status);
+
+ if ( ! (EFI_ERROR(Status) || (IoapicAddr == 0)) )
+ {
+ HdrPtr = BuildIoapicIosapic(IoapicAddr, &IoapicVbase);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries.MadtEntCount == LastItem) // Adding entries in groving IOapicId/IOsapicId value order
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);// First entry
+ }
+
+ else
+ {
+ for (j = (LastItem); j < MadtTblEntries.MadtEntCount; j++) // No need to handle LSAPIC entry in different way
+ {
+ // IOapicId and IOsapicId filds are on the same place in bouth structures
+ if (((IOAPIC_H32*)HdrPtr)->IoapicId < ((IOAPIC_H32*)MadtTblEntries.MadtEntries[j])->IoapicId) break;
+ } // found entry with bigger IOapicId/IOsapicId
+
+ if (j == MadtTblEntries.MadtEntCount)
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ }
+
+ else
+ {
+ Status = InsertItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr, j);
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ IoApicCnt++;
+ }
+ }//if( ! (EFI_ERROR(Status) || (IoapicAddr == 0)) )
+
+#if PCI_BUS_APIC_LEAVE_ENABLE != 0
+ //Restore attributes of the device
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSet, OldAttr, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+#endif
+ }//if((PciData[3] == 0x8) && (PciData[2] == 0) && (PciData[1] >= 0x10))
+ }//for(i = 0; i < NumberOfHandles; i++)
+
+ pBS->FreePool(pHandleBuffer);
+ }//if(!EFI_ERROR(Status))
+ }
+#endif //PCI_BUS_APIC_AUTODETECT == 1
+
+//--------------------------------------------------------------------
+//---Creating IOAPIC or/and IOSAPIC Entries
+#if (APCB != 0)
+ IoapicAddr = APCB;
+#else
+ IoapicAddr = IOA_BASE_BOT;
+#endif
+
+#if FEC00000_APIC_AUTODETECT == 1
+
+ //trying to check if something alive present at 0xFEC00000..0xFED00000
+ for ( ; IoapicAddr < IOA_BASE_TOP; IoapicAddr += 0x1000)
+ { //If so read IOAPIC.ID reg and figure out
+ //1.How many INTINs it has
+ //2.What ID BIOS give to it
+ if (*((UINT8 *)(IoapicAddr + IOA_IND_REG_OFFS)) != 0xFF)
+ {
+ HdrPtr = BuildIoapicIosapic(IoapicAddr, &IoapicVbase);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries.MadtEntCount == LastItem) // Adding entries in groving IOapicId/IOsapicId value order
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);// First entry
+ else
+ {
+ for (j = (LastItem); j < MadtTblEntries.MadtEntCount; j++)
+ { // No need to handle LSAPIC entry in different way
+ if (((IOAPIC_H32*)HdrPtr)->IoapicId < ((IOAPIC_H32*)MadtTblEntries.MadtEntries[j])->IoapicId) break; // IOapicId and IOsapicId filds are on the same place in bouth structures
+ } // found entry with bigger IOapicId/IOsapicId
+
+ if (j == MadtTblEntries.MadtEntCount)
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ }
+
+ else
+ {
+ Status = InsertItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr, j);
+ }
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ IoApicCnt++;
+ }
+ }
+
+#endif //FEC00000_APIC_AUTODETECT == 1
+
+//---------------------------------------------------------------------
+
+#if USE_BOARD_INFO_APIC_DATA == 1
+ {
+ AMI_APIC_INFO *BrdApicInfo;
+ BOOLEAN Present;
+
+ //-----------------
+ for (i=0; i<(gAmiBoardInfoProtocol->ApicInfoLength/sizeof(AMI_APIC_INFO)); i++)
+ {
+
+ BrdApicInfo=&gAmiBoardInfoProtocol->ApicInfoTable[i];
+
+ //This is a special case it could be a duplicate entries in MadtTblEntries[]
+ //if other options of IOAPIC/IOsAPIC detection was on.
+ //So check if IOAPIC/IOsAPIC entries with the same properties already present in DB.
+ for (j=(LastItem),Present=FALSE; j < MadtTblEntries.MadtEntCount; j++)
+ {
+ HdrPtr=MadtTblEntries.MadtEntries[j];
+
+ if (HdrPtr->Type==AT_IOAPIC)
+ {
+ IOAPIC_H20 *apic=(IOAPIC_H20*)HdrPtr;
+
+ //----------------------
+ if (BrdApicInfo->ApicAddress.ADDRESS == apic->IoapicAddress)
+ {
+ Present = TRUE;
+ break;
+ }
+ }
+
+ else //Nothing else should not be here except IOAPIC or IOSAPIC entries
+ {
+ IOSAPIC_H20 *sapic=(IOSAPIC_H20*)HdrPtr;
+
+ //----------------------
+ if ((UINT64)BrdApicInfo->ApicAddress.ADDRESS == sapic->IosapicAddress)
+ {
+ Present = TRUE;
+ break;
+ }
+ }
+ }
+
+ //Entry with this address already present in MadtTblEntries array
+ if (Present) continue;
+
+ //Looks like it is a new IOAPIC/IOSAPIC entry!
+ //Check if something alive at this address
+ if (*((UINT8 *)BrdApicInfo->ApicAddress.ADDRESS) != 0xFF)
+ {
+ IoapicAddr=BrdApicInfo->ApicAddress.ADDRESS;
+ HdrPtr = BuildIoapicIosapic(IoapicAddr, &IoapicVbase);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries.MadtEntCount == LastItem) // Adding entries in groving IOapicId/IOsapicId value order
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);// First entry
+ else
+ {
+ for (j = (LastItem); j < MadtTblEntries.MadtEntCount; j++)
+ { // No need to handle LSAPIC entry in different way
+ if (((IOAPIC_H32*)HdrPtr)->IoapicId < ((IOAPIC_H32*)MadtTblEntries.MadtEntries[j])->IoapicId) break; // IOapicId and IOsapicId filds are on the same place in bouth structures
+ } // found entry with bigger IOapicId/IOsapicId
+
+ if (j == MadtTblEntries.MadtEntCount)
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ }
+
+ else
+ {
+ Status = InsertItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr, j);
+ }
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ IoApicCnt++;
+ }
+ } // if(...i<(gAmiBoardInfoProtocol->ApicInfoLength/sizeof(AMI_APIC_INFO))
+ }
+#endif //USE_BOARD_INFO_APIC_DATA ==1
+
+//-------------------------------------------------------------------------------------------
+ if (!IoApicCnt)
+ {
+ HdrPtr = BuildIoapicManualy();
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ IoapicVbase = (UINT32) 1;
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ }
+
+
+//-------Build ISO Structure----------------------------
+ for (i=0; i<IsoCnt; i++)
+ {
+ if (IsoTbl[i].PicIrq == 0xFF) continue; //no override for this entry
+
+ HdrPtr = BuildIsoFromTbl(i);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+//-------Build NMIs Structure---------------------------
+ Status = EFI_UNSUPPORTED;
+#if AMI_CPU_INFO_2_PROTOCOL_VERSION >= 3
+ //First try to build Local APIC information from the protocol.
+ if (gAmiCpu2Info != NULL)
+ {
+ Status = BuildLapicNmiFromProtocol(&MadtTblEntries);
+ }
+#endif
+
+ if (EFI_ERROR(Status))
+ {
+#if (NMIs_QUANTITY > 0)
+
+ HdrPtr = MallocZ(sizeof(NMI_H20));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ ((NMI_H20*) HdrPtr)->Header.Type = (UINT8) AT_NMI; //Type 3 - indicating NMIs Entry
+ ((NMI_H20*) HdrPtr)->Header.Length = (UINT8) sizeof(NMI_H20);
+ ((NMI_H20*) HdrPtr)->Flags = (UINT16)((NMI_0_TRIGGER_MODE<<2) | NMI_0_POLARITY);
+ ((NMI_H20*) HdrPtr)->GlobalSysVect = (UINT32) NMI_GLOBAL_SYS_INT_0;
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+#if (NMIs_QUANTITY > 1)
+ HdrPtr = MallocZ(sizeof(NMIH_20));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ ((NMI_H20*) HdrPtr)->Header.Type = (UINT8) AT_NMI; //Type 3 - indicating NMIs Entry
+ ((NMI_H20*) HdrPtr)->Header.Length = (UINT8) sizeof(NMI_H20);
+ ((NMI_H20*) HdrPtr)->Flags = (UINT16)((NMI_1_TRIGGER_MODE<<2) | NMI_1_POLARITY);
+ ((NMI_H20*) HdrPtr)->GlobalSysVect = (UINT32) NMI_GLOBAL_SYS_INT_1;
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+#endif
+
+//---Porting Hook 1 ------ If NMIs_QUANTITY > 2 - Add more structures
+#endif
+//--------Build LAPIC NMI-------------------------
+
+#if (LAPIC_QUANTITY > 0)
+
+ if (LAPIC_0_INT_TYPE == 1) // This is NMI - so build a table for it
+ {
+ HdrPtr = BuildLocalApicNmi(gX2Apic ? TRUE : FALSE, 0xffffffff, LAPIC_0_DEST_LINTIN, (LAPIC_0_TRIGGER_MODE<<2) | LAPIC_0_POLARITY);
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+#if (LAPIC_QUANTITY > 1)
+
+ if (LAPIC_1_INT_TYPE == 1) // This is NMI - so build a table for it
+ {
+ HdrPtr = BuildLocalApicNmi(gX2Apic ? TRUE : FALSE, 0xffffffff, LAPIC_1_DEST_LINTIN, (LAPIC_1_TRIGGER_MODE<<2) | LAPIC_1_POLARITY);
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+#endif
+#if (LAPIC_QUANTITY > 2)
+
+ if (LAPIC_2_INT_TYPE == 1) // This is NMI - so build a table for it
+ {
+ HdrPtr = BuildLocalApicNmi(gX2Apic ? TRUE : FALSE, 0xffffffff, LAPIC_2_DEST_LINTIN, (LAPIC_2_TRIGGER_MODE<<2) | LAPIC_2_POLARITY);
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+#endif
+//------Porting Hook 2----If LAPIC_QUANTITY > 3 - Add more structures
+#endif
+ }
+
+//---Tis ia all for Ver 1 - building a table----------------------
+//----Here starts entries for V 2 and 3 which are empty for now----------------------------------
+//
+// Here entries for LAPIC Address overrride structure and Platforme interrupt source structure
+//
+
+ for (i = 0; i < MadtTblEntries.MadtEntCount; i++)
+ {
+
+ AllStrLength += MadtTblEntries.MadtEntries[i]->Length;
+ }
+
+ *TablPtr = MallocZ(sizeof(APIC_20H) + (UINTN) AllStrLength);
+ ASSERT (*TablPtr);
+
+ if (!(*TablPtr)) return EFI_OUT_OF_RESOURCES;
+
+ if (TablVer == 1) PrepareHdr1 (APIC_SIG, (PACPI_HDR) *TablPtr);
+ else PrepareHdr20 (APIC_SIG, (PACPI_HDR) *TablPtr, TablVer);
+
+ (*TablPtr)->Length = (sizeof(APIC_20H) + AllStrLength);
+ ((APIC_20H*)*TablPtr)->LAPIC_Address = LOCAL_APIC_BASE;
+ ((APIC_20H*)*TablPtr)->Flags = ACPI_APIC_FLAGS;
+ DestinPtr = ((UINT8*) *TablPtr + sizeof(APIC_20H));
+
+ for (i = 0; i < MadtTblEntries.MadtEntCount; i++)
+ {
+
+ MemCopy ((UINT8*)MadtTblEntries.MadtEntries[i], DestinPtr, (UINT32) MadtTblEntries.MadtEntries[i]->Length);
+ DestinPtr += MadtTblEntries.MadtEntries[i]->Length;
+ pBS->FreePool((VOID*)MadtTblEntries.MadtEntries[i]);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ (*TablPtr)->Checksum = 0;
+ (*TablPtr)->Checksum = ChsumTbl((UINT8*)*TablPtr, (*TablPtr)->Length);
+
+ return EFI_SUCCESS;
+}// end of BuildMadtAll-----------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFacs
+//
+// Description: Allocates ACPI NVS memory and builds FACS table from values,
+// defined by SDL tokens
+//
+// Input: none
+//
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_SUCCESS - FACS table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildFacs ()
+{
+ EFI_STATUS Status;
+ UINTN Size;
+
+
+ if (gForceAcpi1) Size = sizeof(FACS_20);
+ else Size = sizeof(FACS_20)*2;
+ Status = pBS->AllocatePool(EfiACPIMemoryNVS, Size+64, &gFacs);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+#ifdef EFIx64
+
+ if (((UINT64)gFacs) & 0xffffffff00000000)
+ {
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+ Status = pBS->FreePool(gFacs);
+ ASSERT_EFI_ERROR(Status);
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, 1, &Memory);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ (UINTN) gFacs = Memory;
+ }
+
+#endif
+ (UINTN) gFacs += 64;
+ (UINTN) gFacs &= (~0x3F);
+ pBS->SetMem(gFacs, Size, 0);
+ gFacs->Signature=(UINT32)FACS_SIG;
+ gFacs->Length=sizeof(FACS_20);
+ gFacs->Flags=FACS_FLAG_S4BIOS;
+
+ if (gForceAcpi1) return EFI_SUCCESS;
+
+ (UINTN) gxFacs = (UINTN) gFacs + sizeof(FACS_20);
+ gxFacs->Signature=(UINT32)FACS_SIG;
+ gxFacs->Length=sizeof(FACS_20);
+
+ if (ACPI_BUILD_TABLES_4_0 != 1)
+ {
+ gxFacs->Flags=FACS_FLAG_S4BIOS;
+ gxFacs->Version=ACPI_REV1;
+ }
+
+ else
+ {
+ gxFacs->Flags = FACS_FLAG_S4BIOS | (FACS_FLAG_64BIT_WAKE_SUPPORTED << 1);
+ gxFacs->Version=ACPI_REV2;
+ }
+
+
+
+
+ return EFI_SUCCESS;
+}// end of BuildFacs ---------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDsdtFv
+//
+// Description:
+// This function finds DSDT table in firmvare volume
+//
+// Input:
+// OUT ACPI_HDR **Dsdt1 - pointer to memory where DSDT v1.1 table will be stored
+// OUT ACPI_HDR **Dsdt2 - pointer to memory where DSDT v2.0+ table will be stored
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ABORTED - ACPI storage file not found
+// EFI_NOT_FOUND - DSDT table not found in firmware volume
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetDsdtFv(OUT ACPI_HDR **Dsdt1, OUT ACPI_HDR **Dsdt2)
+{
+
+ //In current AmiBoardInfo implementation separate instance of
+ //DSDT for ACPI version 1.1b DOES OT SUPPORTED!
+ *Dsdt1=NULL;
+ *Dsdt2 = Malloc(((ACPI_HDR*)gAmiBoardInfoProtocol->BoardAcpiInfo)->Length);
+ ASSERT(*Dsdt2);
+ if (((UINT64)*Dsdt2) & 0xffffffff00000000)
+ {
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+
+ Status = pBS->FreePool(*Dsdt2);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(((ACPI_HDR*)gAmiBoardInfoProtocol->BoardAcpiInfo)->Length),
+ &Memory);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ *Dsdt2 = (ACPI_HDR *)((UINTN)Memory);
+ }
+
+ if (*Dsdt2==NULL) return EFI_OUT_OF_RESOURCES;
+
+ pBS->CopyMem(*Dsdt2, gAmiBoardInfoProtocol->BoardAcpiInfo,
+ ((ACPI_HDR*)gAmiBoardInfoProtocol->BoardAcpiInfo)->Length);
+
+
+ if ((*Dsdt1 == NULL) && (*Dsdt2 == NULL))
+ {
+ TRACE((-1,"Acpi: No DSDT was FOUND: Status=EFI_NOT_FOUND\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //PrepareHdr1(DSDT_SIG, (ACPI_HDR*)(*Dsdt1));
+ PrepareHdr20(DSDT_SIG, (ACPI_HDR*)(*Dsdt2),2);
+
+ return EFI_SUCCESS;
+
+}// end of GetDsdtFv -----------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateFacp
+//
+// Description: This function Updates FACP with the new values for DSDT and Facs
+// pointers
+//
+// Input: FACS_20* gFacs1 - Pointer to gFacs Table for V 1
+// FACS_20* gFacs2 - Pointer to gFacs Table for V 2 or 3
+//
+// Output: EFI_SUCCESS - Function executed successfully
+// EFI_ABORTED - Error
+//
+//
+// Modifies gAcpiData
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateFacp () //(FACS_20 *gFacs1, FACS_20 *gFacs2)
+{
+ ACPI_HDR *Facp1 = NULL, *Facp2 = NULL, *Dsdt1 = NULL, *Dsdt2 = NULL;
+ UINTN i;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Facp1 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 1.1
+ else
+ Facp2 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 2+
+ }
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Dsdt1 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 1.1
+ else
+ Dsdt2 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 2+
+ }
+ }
+
+ if (Dsdt1 == NULL) Dsdt1 = Dsdt2; // The same DSDT for V1.1
+
+ if (Dsdt2 == NULL) Dsdt2 = Dsdt1; // The same DSDT for V2
+
+ if ((Facp1 == NULL) || (Dsdt1 == NULL)) Status = EFI_ABORTED;
+ if ((Facp2 == NULL) && (!gForceAcpi1)) Status = EFI_ABORTED;
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return Status;
+
+//--- Updating FACP for V1.1 and 2+---------------------------
+ ((FACP32*) Facp1)->FIRMWARE_CTRL = (UINT32) gFacs;
+ ((FACP32*) Facp1)->DSDT = (UINT32) Dsdt1;
+
+
+ Facp1->Checksum = 0;
+ Facp1->Checksum = ChsumTbl((UINT8*)Facp1, Facp1->Length);
+ if (gForceAcpi1) return Status;
+ if (ACPI_BUILD_TABLES_4_0 == 1) ((FACP_20*) Facp2)->FIRMWARE_CTRL = (UINT32) gxFacs;
+ else ((FACP_20*) Facp2)->FIRMWARE_CTRL = (UINT32) gFacs;
+
+ ((FACP_20*) Facp2)->DSDT = (UINT32) Dsdt1;
+
+ if (ACPI_BUILD_TABLES_4_0 != 1)((FACP_20*) Facp2)->X_FIRMWARE_CTRL = (UINT64) ((UINTN) gxFacs);
+
+ ((FACP_20*) Facp2)->X_DSDT = (UINT64) ((UINTN)Dsdt2);
+ Facp2->Checksum = 0;
+ Facp2->Checksum = ChsumTbl((UINT8*)Facp2, Facp2->Length);
+ return Status;
+}// end of UpdateFacp
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindAcpiTblByHandle
+//
+// Description: Finds ACPI table by Handle and returns its entry number in
+// gAcpiData structure
+//
+// Input: UINTN *Handle - Handle (pointer to ACPI table header)
+//
+//
+// Output: UINTN - Entry number in gAcpiData structure
+// ACPI_TABLE_NOT_FOUND if not found
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN FindAcpiTblByHandle (UINTN *Handle)
+{
+ UINTN i;
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if (*Handle == (UINTN)gAcpiData.AcpiEntries[i]->BtHeaderPtr) // Handle is the address of ACPI table
+ {
+ return i;
+ }
+ }
+
+ return ACPI_TABLE_NOT_FOUND;
+}// end of FindAcpiTblByHandle
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBtTable
+//
+// Description: Founds ACPI Table with defined Signature (Sig) and Version in gAcpiData structure.
+//
+//
+// Input: OUT ACPI_TBL_ITEM **TblPtr - pointer to the ACPI entrie in gAcpiData,
+// modifided by this function
+// IN UINT32 Sig - Signature of a table to search for
+// IN EFI_ACPI_TABLE_VERSION - Version of a table to be found
+//
+// Output: EFI_SUCCESS - table with corresponding signature was found
+// EFI_NOT_FOUND - otherwise
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetBtTable (OUT ACPI_TBL_ITEM **TblPtr, IN UINT32 Sig, IN EFI_ACPI_TABLE_VERSION Versiov)
+{
+ UINTN i;
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if ((gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == Sig)
+ && (gAcpiData.AcpiEntries[i]->AcpiTblVer & Versiov))
+ {
+ *TblPtr = gAcpiData.AcpiEntries[i];
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}// end of GetBtTable
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DispatchSdtNotify
+//
+// Description: Checks if Notify function(s) present dispatches it.
+//
+//
+// Input: EFI_ACPI_SDT_HEADER *TableHeaderPtr - pointer to the ACPI Table header,
+// modifided by this function
+// Output: EFI_STATAUS - From the function dispatched.
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DispatchSdtNotify(ACPI_TBL_ITEM* TableItemPtr){
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN i;
+//--------
+ for(i=0;i<gAcpiData.NotifyFnCount; i++){
+ Status=gAcpiData.AcpiNotifyFn[i]((EFI_ACPI_SDT_HEADER*)TableItemPtr->BtHeaderPtr,TableItemPtr->AcpiTblVer,(UINTN)TableItemPtr);
+
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillAcpiStr
+//
+// Description: Copys table from position pointed by FromPtr to a position pointed
+// by ToPtr (which is in EfiACPIReclaimMemory) and fills RSDT and XSDT
+// pointers with ToPtr value
+//
+//
+// Input: RSDT32 *RsdtPtr - pionter to RSDT
+// XSDT_20 *XsdtPtr - pionter to XSDT
+// VOID *FromPtr - pointer to a table which should be copyed
+// VOID *ToPtr - pointer to EfiACPIReclaimMemory where table should be placed
+//
+// Output: UINT8* - Pointer to the next avaiable space in allocated EfiACPIReclaimMemory
+// right after copyed table (alligned already)
+// If NUUL - Invalid parameters.
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 *FillAcpiStr (RSDT32 *RsdtPtr, XSDT_20 *XsdtPtr, VOID *FromPtr, VOID *ToPtr)
+{
+ UINT8 *NextPtr;
+ UINTN i;
+
+
+ if ((RsdtPtr == NULL) && (XsdtPtr == NULL)) return NULL;
+
+ if ((FromPtr == NULL) || (ToPtr == NULL)) ASSERT(0);
+
+ pBS->CopyMem(ToPtr, FromPtr, ((ACPI_HDR*)FromPtr)->Length);
+
+ if (RsdtPtr != NULL)
+ {
+ for (i = 0; RsdtPtr->Ptrs[i] != 0; i++); // Find first unfilled (last) entry in RSDT
+
+ RsdtPtr->Ptrs[i] = (UINT32) ToPtr;
+ }
+
+ if (XsdtPtr != NULL)
+ {
+ for (i = 0; XsdtPtr->Ptrs[i] != 0; i++); // Find first unfilled (last) entry in XSDT
+
+ XsdtPtr->Ptrs[i] = (UINT64) ((UINTN)ToPtr);
+ }
+
+ NextPtr = (UINT8*) ((UINT8*)ToPtr+((ACPI_HDR*)ToPtr)->Length + 7);
+ (UINTN) NextPtr &= (~0x7);
+
+ return NextPtr;
+
+}//end of FillAcpiStr
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PublishTbl
+//
+// Description: Creates or rewrites RSDT_PTR structure and copys tables, stored
+// in gAcpiData structure in allocated EfiACPIReclaimMemory.
+//
+//
+// Input: IN UINTN RsdtBuild - if 1 - Build RSDT and copy tables of Ver 1.1
+// IN UINTN XsdtBuild - if 1 - Build XSDT and copy tables of Ver 2+
+//
+// Output: EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_ABORTED - invalid parameters
+// EFI_SUCCESS - RSDT_PTR structure was successfully build
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PublishTbl (IN UINTN RsdtBuild, IN UINTN XsdtBuild)
+{
+ ACPI_HDR *Facp = NULL, *FacpX = NULL, *Dsdt = NULL, *DsdtX = NULL;
+ RSDT32 *Rsdt = NULL;
+ XSDT_20 *Xsdt = NULL;
+ UINTN i, j, RsdtCnt = 0, XsdtCnt = 0, SpaceNeeded = 0, RsdtSize = 0, XsdtSize = 0, Skip;
+ EFI_STATUS Status;
+ UINT8 *Ptr = NULL, *Dummy = NULL, OneDsdt = 0;
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+
+ if (((RsdtBuild == 0) && (XsdtBuild == 0)) || (RsdtBuild > 1 ) || (XsdtBuild > 1)) return EFI_ABORTED;
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if (!gOA3Variable)
+ {
+ UINTN SizeOfMsdm = sizeof(EFI_OA3_MSDM_STRUCTURE);
+ //Looking for Var which signals that MSDM table may be updated on runtime
+ Status = pRS->GetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &gAmiGlobalVariableGuid,
+ NULL,
+ &SizeOfMsdm,
+ &gMsdmVariable
+ );
+ if (Status == EFI_SUCCESS)
+ {
+ gOA3Variable = TRUE;
+ XsdtCnt++; // Reserving Entry for MSDM (OEM Activation)
+ }
+ }
+ else XsdtCnt++;
+#endif
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer < EFI_ACPI_TABLE_VERSION_1_0B) continue;
+
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ RsdtCnt ++;
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ Facp = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ Dsdt = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ }
+
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer > EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ XsdtCnt ++;
+ RsdtCnt ++;
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ {
+ FacpX = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ //if (Facp != NULL) RsdtCnt --;
+ //continue;
+ }
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ {
+ DsdtX = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ }
+
+ for (j = 0; j < gAcpiData.AcpiEntCount; j++)
+ {
+ if (j == i) continue;
+
+ if ((gAcpiData.AcpiEntries[j]->BtHeaderPtr->Signature == gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature)
+ && (gAcpiData.AcpiEntries[j]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)) RsdtCnt --;
+ }
+ }
+ }
+
+ if ((Dsdt == NULL) || (DsdtX == NULL)) OneDsdt = 1;
+
+ if (Dsdt == NULL) Dsdt = DsdtX;
+
+ if (DsdtX == NULL) DsdtX = Dsdt;
+
+ RsdtSize = RsdtBuild * (sizeof(ACPI_HDR) + (RsdtCnt-1) * sizeof(UINT32) + 7); //DSDT does not goes in RSDT (RsdtCnt-1)
+
+ XsdtSize = XsdtBuild * (sizeof(ACPI_HDR) + (XsdtCnt-1) * sizeof(UINT64) + 7); //DSDT does not goes in XSDT (XsdtCnt-1)
+ SpaceNeeded = sizeof(RSDT_PTR_20) + RsdtSize + XsdtSize + gAcpiData.AcpiLength + (gAcpiData.AcpiEntCount + 1) * 8;
+
+ if (gRsdtPtrStr != NULL)
+ {
+ Status = pBS->FreePages((EFI_PHYSICAL_ADDRESS)(UINTN) gRsdtPtrStr, gAcpiTblPages);
+ ASSERT_EFI_ERROR(Status);
+ }
+ /*
+ Status = pBS->AllocatePool(EfiACPIReclaimMemory, SpaceNeeded, (VOID**)&gRsdtPtrStr);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ */
+ gAcpiTblPages = EFI_SIZE_TO_PAGES(SpaceNeeded);
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if (gOA3Variable)
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, gAcpiTblPages , &Memory);
+ else
+#endif
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiACPIReclaimMemory, gAcpiTblPages , &Memory);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gRsdtPtrStr = (RSDT_PTR_20*)Memory;
+
+ pBS->SetMem(gRsdtPtrStr, SpaceNeeded, 0);
+
+ if (RsdtBuild)
+ {
+ Dummy = (UINT8*) ((UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + 7);
+ (UINTN) Dummy &= (~0x7);
+ Rsdt = (RSDT32*) Dummy;
+ Ptr = (UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + RsdtSize + XsdtSize + 7;
+ (UINTN) Ptr &= (~0x7);
+ Dummy = FillAcpiStr (Rsdt, NULL, (VOID*) Facp, (VOID*) Ptr);// The first table in RSDT must be Facp
+ Facp = (ACPI_HDR*) Ptr;
+ Ptr = Dummy;
+ pBS->CopyMem((VOID*)Ptr, (VOID*)Dsdt, Dsdt->Length);
+
+ if (Dsdt == DsdtX) Dsdt = DsdtX = (ACPI_HDR*) Ptr;
+ else Dsdt = (ACPI_HDR*) Ptr;
+
+ Ptr += (Dsdt->Length + 7);
+ (UINTN) Ptr &= (~0x7);
+ ((FACP32*)Facp)->FIRMWARE_CTRL = (UINT32) gFacs;
+ ((FACP32*)Facp)->DSDT = (UINT32) Dsdt;
+ Facp->Checksum = 0;
+ Facp->Checksum = ChsumTbl((UINT8*)Facp, Facp->Length);
+ }
+
+ if ((XsdtBuild) && (!gForceAcpi1))
+ {
+ Dummy = (UINT8*) ((UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + RsdtSize + 7);
+ (UINTN) Dummy &= (~0x7);
+ Xsdt = (XSDT_20*) Dummy;
+
+ if (Ptr == NULL)
+ {
+ Ptr = (UINT8*) ((UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + RsdtSize + XsdtSize + 7);
+ //else Ptr += (((ACPI_HDR*)Ptr)->Length + 7);
+ (UINTN) Ptr &= (~0x7);
+ }
+
+ Dummy = FillAcpiStr (NULL, Xsdt, (VOID*) FacpX,( VOID*) Ptr);
+ FacpX = (ACPI_HDR*) Ptr;
+ Ptr = Dummy;
+
+ if ((!OneDsdt) || (!RsdtBuild))
+ {
+ pBS->CopyMem((VOID*)Ptr, (VOID*)DsdtX, DsdtX->Length);
+ DsdtX = (ACPI_HDR*) Ptr;
+ Ptr += (DsdtX->Length + 7);
+ (UINTN) Ptr &= (~0x7);
+ }
+
+ if (ACPI_BUILD_TABLES_4_0 == 1) ((FACP_20*)FacpX)->FIRMWARE_CTRL = (UINT32) gxFacs;
+ else ((FACP_20*)FacpX)->FIRMWARE_CTRL = (UINT32) gFacs;
+
+ ((FACP_20*)FacpX)->DSDT = (UINT32) Dsdt;
+
+ if (ACPI_BUILD_TABLES_4_0 != 1)((FACP_20*)FacpX)->X_FIRMWARE_CTRL = (UINT64) ((UINTN)gxFacs);
+
+ ((FACP_20*)FacpX)->X_DSDT = (UINT64) ((UINTN)DsdtX);
+ FacpX->Checksum = 0;
+ FacpX->Checksum = ChsumTbl((UINT8*)FacpX, FacpX->Length);
+ }
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if ((gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG) ||
+ (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG) ||
+ (gAcpiData.AcpiEntries[i]->AcpiTblVer < EFI_ACPI_TABLE_VERSION_1_0B)) continue;
+
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ Dummy = FillAcpiStr (Rsdt, NULL, (VOID*) gAcpiData.AcpiEntries[i]->BtHeaderPtr,( VOID*) Ptr);
+
+ if (Dummy != NULL) Ptr = Dummy;
+ }
+
+ else
+ {
+ Skip = 0;
+
+ for (j = 0; j < gAcpiData.AcpiEntCount; j++)
+ {
+ if (j == i) continue;
+
+ if ((gAcpiData.AcpiEntries[j]->BtHeaderPtr->Signature == gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature)
+ && (gAcpiData.AcpiEntries[j]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)) Skip = 1;
+ }
+
+ if (Skip) Dummy = FillAcpiStr (NULL, Xsdt, (VOID*) gAcpiData.AcpiEntries[i]->BtHeaderPtr,( VOID*) Ptr);
+ else Dummy = FillAcpiStr (Rsdt, Xsdt, (VOID*) gAcpiData.AcpiEntries[i]->BtHeaderPtr,( VOID*) Ptr);
+
+ if (Dummy != NULL) Ptr = Dummy;
+ }
+ }
+
+ if (Ptr > ((UINT8*)gRsdtPtrStr + SpaceNeeded)) Status = EFI_OUT_OF_RESOURCES;
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ gRsdtPtrStr->Signature = RSDP_SIG;
+
+ if ((!XsdtBuild) || (gForceAcpi1)) gRsdtPtrStr->Revision = 0; //Reserved in ver 1
+ else gRsdtPtrStr->Revision = ACPI_REV2; // 2 for ver 2 and 3
+
+ gRsdtPtrStr->Length = sizeof(RSDT_PTR_20);//this is the length of entire structure
+
+ for (i=0; i<6; i++) gRsdtPtrStr->OEMID[i]=ACPI_OEM_ID[i];
+
+ gRsdtPtrStr->RsdtAddr = (UINT32) Rsdt;
+ gRsdtPtrStr->XsdtAddr = (UINT64) ((UINTN)Xsdt);
+ gRsdtPtrStr->Checksum = ChsumTbl((UINT8*)gRsdtPtrStr, 20);
+ gRsdtPtrStr->XtdChecksum = ChsumTbl((UINT8*)gRsdtPtrStr, sizeof (RSDT_PTR_20));
+
+ if (RsdtBuild)
+ {
+ PrepareHdr1 (RSDT_SIG, (ACPI_HDR*) Rsdt);
+ Rsdt->Header.Length = (UINT32) (RsdtSize - 7);
+ Rsdt->Header.Checksum = 0;
+ Rsdt->Header.Checksum = ChsumTbl((UINT8*)Rsdt, Rsdt->Header.Length);
+ Status = pBS->InstallConfigurationTable(&gAcpi11TAbleGuid, (VOID*) gRsdtPtrStr);
+ TRACE((-1,"Installing ACPI 1.1: %r, %X\n",Status,gRsdtPtrStr));////-----------------------------------------
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ if (XsdtBuild)
+ {
+ if (ACPI_BUILD_TABLES_3_0 == 1) PrepareHdr20 (XSDT_SIG, (ACPI_HDR*) Xsdt, 3);
+ else PrepareHdr20 (XSDT_SIG, (ACPI_HDR*) Xsdt, 2);
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if (gOA3Variable)
+ Xsdt->Header.Length = (UINT32) (XsdtSize - sizeof(UINT64) - 7);//one reserved position for MSDM
+ else
+#endif
+ Xsdt->Header.Length = (UINT32) (XsdtSize - 7);
+ Xsdt->Header.Checksum = 0;
+ Xsdt->Header.Checksum = ChsumTbl((UINT8*)Xsdt, Xsdt->Header.Length);
+// if (RsdtBuild) Status = pBS->InstallConfigurationTable(&gAcpi11TAbleGuid, NULL); // Delete V1.1 entry - Only one
+ Status = pBS->InstallConfigurationTable(&gAcpi20TAbleGuid, (VOID*) gRsdtPtrStr);
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if ((Xsdt != NULL) && gOA3Variable)
+ {
+ gMsdmVariable.XsdtAddress = (EFI_PHYSICAL_ADDRESS) Xsdt;
+ Status = pRS->SetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(EFI_OA3_MSDM_STRUCTURE),
+ &gMsdmVariable
+ );
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+ return EFI_SUCCESS;
+
+}// end of PublishTbl
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateAml
+//
+// Description:
+// This function updates AML objects with values provided in ACPI_AML_UPD_INFO
+// structure
+//
+// Input:
+// IN ACPI_AML_UPD_INFO *AmlUpdInfo - pointer to ACPI_AML_UPD_INFO structure
+//
+// Output:
+// EFI_SUCCESS - AML objects updated successfully
+// EFI_ERROR - some error occured during update process
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateAml(ACPI_AML_UPD_INFO *AmlUpdInfo)
+{
+ UINTN i;
+ ACPI_HDR *Dsdt;
+ EFI_STATUS Status = 0;
+
+//-------------------------
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i) Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt1Addr;
+ else Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt2Addr;
+
+ if (Dsdt)
+ {
+ //Update TOPM Object
+ Status = UpdateAslNameObject(Dsdt, "TOPM", AmlUpdInfo->TopOfMemory);
+ ASSERT_EFI_ERROR (Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ //Update ROMS Object
+ //Status = UpdateNameObject(Dsdt, AML_NAME_ROMS, AmlUpdInfo->RomStart);
+ //ASSERT_EFI_ERROR(Status)
+ //if(EFI_ERROR(Status)) return Status;
+//TODO: IOST and SSx Objects update
+ //Update IOST Object
+ Status = UpdateAslNameObject(Dsdt, "IOST", (UINT64)AmlUpdInfo->SioDevStatusVar.DEV_STATUS);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = UpdateAslNameObject(Dsdt, "SS4", (UINT64)AmlUpdInfo->SS4);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+#if ATAD_SUPPORT == 1
+ if (AtadBuffPtr)
+ {
+ TRACE((-1, "AtadBuffPtr=0x%lX ", (UINT64)AtadBuffPtr));
+ Status = UpdateAslNameObject(Dsdt, "ATBF", (UINT64)AtadBuffPtr);
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR(Status))
+ Status = UpdateAslNameObject(Dsdt, "BUFU", 1);
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif
+
+ Status = UpdateAslNameObject(Dsdt, "SS3", (UINT64)AmlUpdInfo->SS3);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = UpdateAslNameObject(Dsdt, "SS2", (UINT64)AmlUpdInfo->SS2);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = UpdateAslNameObject(Dsdt, "SS1", (UINT64)AmlUpdInfo->SS1);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Dsdt->Checksum = 0;
+ Dsdt->Checksum = ChsumTbl((UINT8*)Dsdt, Dsdt->Length);
+ }
+ }
+
+ return Status;
+
+
+}//end of UpdateAml
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LockLegacyRes
+//
+// Description:
+// This function Hides Legacy Resources from OS by destroing _PRS method
+// in each Legacy Device ASL Object in DSDT
+//
+// Input:
+// IN ACPI_AML_UPD_INFO *AmlUpdInfo - pointer to ACPI_AML_UPD_INFO structure
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LockLegacyRes (ACPI_AML_UPD_INFO *AmlUpdInfo)
+
+{
+
+ UINTN HandleCnt, j, i;
+ EFI_HANDLE *HandleBuffer = NULL;
+ SPIO_DEV *SpIoDev;
+ ASL_OBJ_INFO AslObj={0};
+ ACPI_HDR *Dsdt;
+ EFI_STATUS Status = 0;
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ EFI_SIO_DATA *EfiSioData;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiSioProtocolGuid, NULL, &HandleCnt, &HandleBuffer);
+#else
+ AMI_SIO_PROTOCOL *AmiSio;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiAmiSioProtocolGuid, NULL, &HandleCnt, &HandleBuffer);
+#endif
+ //Locate all handles for SIO
+
+ if ((EFI_ERROR(Status)) || (HandleBuffer == NULL)) return;
+
+ for (j = 0; j < HandleCnt; j++)
+ {
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ Status = pBS->HandleProtocol(HandleBuffer[j], &gEfiSioProtocolGuid, &EfiSioData);
+#else
+ Status = pBS->HandleProtocol(HandleBuffer[j], &gEfiAmiSioProtocolGuid, &AmiSio);
+#endif
+ if (EFI_ERROR(Status)) continue;
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ SpIoDev = EfiSioData->Owner;
+#else
+ SpIoDev = (SPIO_DEV*)(UINTN)AmiSio;
+#endif
+ if (SpIoDev->DeviceInfo->AslName[0])
+// TRACE ((-1,"Found SIO Protocol. Name: %s\n",(UINT32)SpIoDev->DeviceInfo->AslName));
+ // If this device has ASL Name and is present in DSDT
+ {
+ for (i = 0; i < 2; i++)
+ {
+ if (i) Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt1Addr;
+ else Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt2Addr;
+
+ if (Dsdt)
+ {
+// TRACE ((-1,"Looking DSDT for Name: %s\n", SpIoDev->DeviceInfo->AslName));
+ Status = GetAslObj((UINT8*)Dsdt+sizeof(ACPI_HDR),
+ Dsdt->Length-sizeof(ACPI_HDR)-1, &SpIoDev->DeviceInfo->AslName[0],
+ otDevice, &AslObj);
+ // Get Asl object associated with this Legacy device
+ ASSERT_EFI_ERROR(Status);
+
+// TRACE ((-1,"Going to hide object Data statr= %x, Length= %x\n",AslObj.DataStart, AslObj.Length));
+ if (!EFI_ERROR(Status)) HideAslMethodFromOs (&AslObj, "_PRS");
+
+ // Lock this Device by destroing _PRS method of this object
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i) Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt1Addr;
+ else Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt2Addr;
+
+ if (Dsdt)
+ {
+ Dsdt->Checksum = 0;
+ Dsdt->Checksum = ChsumTbl((UINT8*)Dsdt, Dsdt->Length);
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectAmlUpdInfo
+//
+// Description:
+// This function will be called when ReadyToBoot event will be signaled and
+// will update IO devices status and then update AML binary. It allso publish all
+// ACPI tables.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CollectAmlUpdInfo(EFI_EVENT Event, VOID *Context)
+{
+ ACPI_AML_UPD_INFO *Aui=Context;
+ FACP_20 *xFacp = NULL;
+// ACPI_HDR *Dsdt1 = NULL, *Dsdt2 = NULL;
+// FACP32 *Facp = NULL;
+ FACP_20 *Facp = NULL;
+ UINTN i;
+ EFI_STATUS Status;
+ SETUP_DATA *SetupData=NULL;
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+//-------------------------------------------
+ //Init Setup Sleep States with Default Values;
+ TRACE((-1,"IN Collect AML Info: %x\n",0));
+
+ //we need to recreate MADT table instances on READY_TO_BOOT event.
+ for (i=0; i<gAcpiData.AcpiEntCount; i++)
+ {
+ ACPI_TBL_ITEM *AcpiTable = gAcpiData.AcpiEntries[i];
+ UINTN AcpiVer;
+ //-------------------------------------------
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Facp = (FACP_20*) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 1.1
+ else
+ xFacp = (FACP_20*) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 2+
+ }
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Aui->Dsdt1Addr = (UINT64) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 1.1
+ else
+ Aui->Dsdt2Addr = (UINT64) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 2+
+ }
+
+ if (AcpiTable->BtHeaderPtr->Signature == APIC_SIG )
+ {
+
+ switch (AcpiTable->AcpiTblVer)
+ {
+ case EFI_ACPI_TABLE_VERSION_1_0B: AcpiVer=1; break;
+ case EFI_ACPI_TABLE_VERSION_2_0: AcpiVer=2; break;
+ case EFI_ACPI_TABLE_VERSION_3_0: AcpiVer=3; break;
+ case EFI_ACPI_TABLE_VERSION_4_0: AcpiVer=4; break;
+ default: AcpiVer=0;
+ }
+
+ gAcpiData.AcpiLength -= AcpiTable->BtHeaderPtr->Length;
+
+ pBS->FreePool(AcpiTable->BtHeaderPtr);
+ AcpiTable->BtHeaderPtr=NULL;
+
+
+ Status = BuildMadtAll (AcpiVer, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return;
+
+ gAcpiData.AcpiLength += AcpiTable->BtHeaderPtr->Length;
+ }
+ }
+
+
+ ASSERT_EFI_ERROR(Status);
+ TRACE((-1,"IN Collect AML Info after PT: %x\n",Status));
+
+ Aui->SS1=DEFAULT_SS1;
+ Aui->SS2=DEFAULT_SS2;
+ Aui->SS3=DEFAULT_SS3;
+ Aui->SS4=DEFAULT_SS4;
+
+ Status = GetEfiVariable(L"Setup",&gSetupGuid,NULL,&i,&SetupData);
+
+ if (!EFI_ERROR(Status))
+ {
+ //Such Variable exists so use customer choices
+ if (!SetupData->AcpiAuto)
+ {
+ Aui->SS4=SetupData->AcpiHibernate;
+
+ switch (SetupData->AcpiSleepState)
+ {
+ case 0:
+ Aui->SS3=0;
+ Aui->SS1=0;
+ break;
+ case 1:
+ Aui->SS1=1;
+ Aui->SS3=0;
+ break;
+ case 2:
+ Aui->SS3=1;
+ Aui->SS1=0;
+ break;
+ case 3:
+ Aui->SS3=1;
+ Aui->SS1=1;
+ break;
+ }
+ }
+ }
+
+//TODO//TODO//TODO//TODO//TODO
+// Check Setup options (if any) to enable/disable some onboard devices
+//TODO//TODO//TODO//TODO//TODO
+
+ Status = pRS->GetVariable(SIO_DEV_STATUS_VAR_NAME, &SioDevStatusVarGuid, NULL,
+ &SioDevStatusVarSize, &Aui->SioDevStatusVar.DEV_STATUS);
+
+ if (EFI_ERROR(Status)) Aui->SioDevStatusVar.DEV_STATUS = 0;
+ gAcpiIaBootArch &= (~((UINT16)(IA_LEGACY | IA_8042)));// clear first 2 bits of gAcpiIaBootArch,
+ // while preserving others. This 2 bits will be updated later.
+
+ //Dynamically update IA_PC_BOOT_ARCHITECTURE flag based on SIO_DEV_STATUS_VAR
+ if (
+ (Aui->SioDevStatusVar.SerialA == 1 ) ||
+ (Aui->SioDevStatusVar.SerialB == 1 ) ||
+ (Aui->SioDevStatusVar.Lpt == 1 ) ||
+ (Aui->SioDevStatusVar.Fdd == 1 ) ||
+ (Aui->SioDevStatusVar.Game1 == 1 ) ||
+ (Aui->SioDevStatusVar.Game2 == 1 )
+ )
+ gAcpiIaBootArch |= IA_LEGACY;
+
+ if (
+ (Aui->SioDevStatusVar.Key60_64 == 1) ||
+ (Aui->SioDevStatusVar.Ps2Mouse == 1) ||
+ (Aui->SioDevStatusVar.Ec62_66 == 1)
+ )
+ gAcpiIaBootArch |= IA_8042;
+
+
+ if ( xFacp != NULL)
+ {
+ xFacp->IAPC_BOOT_ARCH &= gAcpiIaBootArch;
+ xFacp->Header.Checksum = 0;
+ xFacp->Header.Checksum = ChsumTbl((UINT8*)&xFacp->Header, xFacp->Header.Length);
+ }
+
+ if ((UINT8*) xFacp != (UINT8*) Facp)
+ {
+ //ACPI v1.0b don't have IAPC_BOOT_ARCH flag field!
+ //Legacy free extension has but.. 1.1b Legacy free extension has. REV==2 and higher
+ if (Facp->Header.Revision > ACPI_REV1)
+ {
+ Facp->IAPC_BOOT_ARCH &= gAcpiIaBootArch;
+ Facp->Header.Checksum = 0;
+ Facp->Header.Checksum = ChsumTbl((UINT8*)&Facp->Header, Facp->Header.Length);
+ }
+ }
+
+ Status=UpdateAml(Aui);
+ ASSERT_EFI_ERROR(Status);
+
+ if (SetupData->AcpiLockLegacyRes) LockLegacyRes (Aui); // LockLegacyDev
+
+ if (!gForceAcpi1) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (1, 0);
+ ASSERT_EFI_ERROR(Status);
+ gPublishedOnReadyToBoot = 1;
+// pBS->CloseEvent()
+// pBS->FreePool(Aui);
+}// end of CollectAmlUpdInfo
+
+
+//#pragma warning ( pop )
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// ACPI SUPPORT PPROTOCOL function Implementation
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiSupportGetAcpiTable
+//
+// Description:
+// This function returns ACPI table
+//
+// Input:
+// IN EFI_ACPI_SUPPORT_PROTOCOL *This - pointer to EFI_ACPI_SUPPORT_PROTOCOL instance
+// IN INTN Index - Index of ACPI table to return
+// OUT VOID **Table - Pointer where to place found table
+// OUT EFI_ACPI_TABLE_VERSION Version - requested ACPI table version
+// OUT UINTN *Handle - requested ACPI table handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to allocate table
+// EFI_INVALID_PARAMETER - invalid EFI_ACPI_SUPPORT_PROTOCOL pointer
+// EFI_NOT_FOUND - requested ACPI table not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiSupportGetAcpiTable (
+ IN EFI_ACPI_SUPPORT_PROTOCOL *This,
+ IN INTN Index,
+ OUT VOID **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *Handle )
+{
+ ACPI_HDR *HdrPtr;
+ VOID *Ptr;
+ UINTN i;
+
+//----------------------
+
+ if (This!=&gAcpiData.AcpiSupportProtocol) return EFI_INVALID_PARAMETER;
+
+ if (Index > ((INTN)gAcpiData.AcpiEntCount - 1)) return EFI_NOT_FOUND;
+
+ for (i = Index; i < (UINTN) gAcpiData.AcpiEntCount; i++)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer < ACPI_TABLE_NOT_REMOVABLE)
+ {
+ // means this table was added by EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable
+ // So it is illegal for EFI_ACPI_SUPPORT_PROTOCOL to receive a Handle for it
+ HdrPtr = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ Ptr = Malloc(HdrPtr->Length);
+ ASSERT(Ptr);
+
+ if (!Ptr) return EFI_OUT_OF_RESOURCES;
+
+ *Version = gAcpiData.AcpiEntries[i]->AcpiTblVer;
+ *Handle = (UINTN) HdrPtr;
+ pBS->CopyMem(Ptr, HdrPtr, HdrPtr->Length);
+ *Table = Ptr;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}//end of AcpiSupportGetAcpiTable
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiSupportSetAcpiTable
+//
+// Description:
+// This function allows to add, remove of modify ACPI table
+//
+// Input:
+// IN EFI_ACPI_SUPPORT_PROTOCOL *This - pointer to EFI_ACPI_SUPPORT_PROTOCOL instance
+// IN OPTIONAL VOID *Table - Pointer to update data. If NULL, corresponded table
+// should be removed
+// IN BOOLEAN Checksum - if TRUE, function will recalculate checksum before adding table
+// IN EFI_ACPI_TABLE_VERSION Version - requested ACPI table version
+// IN OUT UINTN *Handle - requested ACPI table handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+// EFI_INVALID_PARAMETER - invalid EFI_ACPI_SUPPORT_PROTOCOL pointer or ACPI table
+// content
+// EFI_ABORTED - provided ACPI table already present
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiSupportSetAcpiTable(
+ IN EFI_ACPI_SUPPORT_PROTOCOL *This,
+ IN VOID *Table OPTIONAL,
+ IN BOOLEAN Checksum,
+ IN EFI_ACPI_TABLE_VERSION Version,
+ IN OUT UINTN *Handle )
+{
+ ACPI_TBL_ITEM *AcpiTableAdded = NULL, *TblDummy = NULL;
+ ACPI_HDR *Hdr1 = NULL, *Hdr2 = NULL, *Dsdt = NULL, *XtDsdt = NULL;
+ VOID *Ptr = NULL;
+ EFI_ACPI_TABLE_VERSION XtDsdtVer = 0, DsdtVer = 0, MultyVer = 0;
+ EFI_STATUS Status = 0;
+ UINTN TblNum = ACPI_TABLE_NOT_FOUND;
+ BOOLEAN CorrectFacp = FALSE, WasChecksummed = FALSE;
+
+
+ //Handle == NULL Table != NULL add the table
+ //Handle != NULL Table != NULL replace the table
+ //Handle != NULL Table == NULL remove the table
+//-----------------------------------------------------------------------------------
+ if ((This != &gAcpiData.AcpiSupportProtocol) || (Handle==NULL) || (*Handle == 0 && Table == NULL )) //---------------------------------------------------------------
+ {
+ Status = EFI_INVALID_PARAMETER;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ TRACE((-1, "ACPI: SetAcpiTable() Table=0x%X; Handle=0x%X; *Handle=0x%X\n", Table, Handle, *Handle));
+ if (Table != NULL)
+ {
+ Hdr1 = (ACPI_HDR*) Table;
+
+ //Check is we are getting a "special" table that needs a specific care
+ if (Hdr1->Signature == FACS_SIG)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Hdr1->Signature == FACP_SIG)
+ {
+ if (*Handle == 0) // --- Do not delete or add FACP - only replace it
+ {
+ Status = GetBtTable(&TblDummy, FACP_SIG, ( EFI_ACPI_TABLE_VERSION_X ));
+ ASSERT_EFI_ERROR(Status); // --- Or if new version > 2 and old version of FACP = 2
+ // --- And action = add table - replace old one with the new one
+ if (EFI_ERROR (Status))
+ {
+ return EFI_ABORTED;
+ }
+
+ if (TblDummy->AcpiTblVer >= Version)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ else
+ {
+ *Handle = (UINTN)TblDummy->BtHeaderPtr;
+ CorrectFacp = TRUE;
+ }
+ }
+ }
+
+ if (Hdr1->Signature == DSDT_SIG)
+ {
+
+ //Just in case reset
+ TblDummy=NULL;
+
+ if (*Handle == 0) // --- Do not delete or add DSDT - only replace it
+ {
+ Status = GetBtTable(&TblDummy, DSDT_SIG, (EFI_ACPI_TABLE_VERSION_X));
+
+ // --- Or if new version > 2 and old version of FACP = 2
+ if (!EFI_ERROR (Status)) // --- And action = add table - replace old one with the new one
+ {
+ XtDsdt = TblDummy->BtHeaderPtr;
+ XtDsdtVer = TblDummy->AcpiTblVer;
+ }
+
+ Status = GetBtTable(&TblDummy, DSDT_SIG, EFI_ACPI_TABLE_VERSION_1_0B);
+
+ if (!EFI_ERROR (Status))
+ {
+ Dsdt = TblDummy->BtHeaderPtr;
+ DsdtVer = TblDummy->AcpiTblVer;
+ }
+
+ if ((Version == EFI_ACPI_TABLE_VERSION_1_0B) && DsdtVer)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ else
+ {
+ if ((Version > DsdtVer) && (Version > XtDsdtVer))
+ {
+ if (XtDsdtVer)
+ *Handle = (UINTN) XtDsdt;
+ }
+
+ else
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ CorrectFacp = TRUE;
+ }
+
+ if (Version == EFI_ACPI_TABLE_VERSION_NONE)
+ Status = pBS->AllocatePool(EfiACPIMemoryNVS, Hdr1->Length, &Ptr);
+ else
+ Ptr = Malloc(Hdr1->Length);
+
+ ASSERT(Ptr);
+
+ if (Ptr==NULL)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ pBS->CopyMem(Ptr, Hdr1, Hdr1->Length);
+ AcpiTableAdded = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTableAdded);
+
+ if (!AcpiTableAdded)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AcpiTableAdded->AcpiTblVer = Version;
+ AcpiTableAdded->BtHeaderPtr = (ACPI_HDR*) Ptr;
+ if (!Checksum)
+ if (!ChsumTbl((UINT8*)Ptr, ((ACPI_HDR*) Ptr)->Length))
+ WasChecksummed = TRUE;
+ //If table was checksumed and Checksum parameter of SetTable function was not set
+ //to TRUE in next string OemAcpiSetPlatformId may modify the table - let's
+ //remember was it checksumed or not
+
+ if (EFI_ERROR(OemAcpiSetPlatformId ((ACPI_HDR*) Ptr))) WasChecksummed = FALSE;
+ //If OemAcpiSetPlatformId did not modifies table - reset WasChecksummed to FALSE
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ Status = DispatchSdtNotify(AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status))
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+
+ if (Version != EFI_ACPI_TABLE_VERSION_NONE)
+ gAcpiData.AcpiLength += ((ACPI_HDR*) Ptr)->Length;
+
+ if (Checksum || WasChecksummed)
+ {
+ ((ACPI_HDR*) Ptr)->Checksum = 0;
+ ((ACPI_HDR*) Ptr)->Checksum = ChsumTbl((UINT8*)Ptr, ((ACPI_HDR*) Ptr)->Length);
+ }
+ }
+
+ if (*Handle)
+ {
+ Status=EFI_SUCCESS;
+
+ TRACE((-1, "ACPI: SetAcpiTable() Hnd!=0, Removing Tbl. Ver=0x%X, ",Version));
+
+ Hdr2 = (ACPI_HDR*)(*Handle);
+
+ //Check is we are getting a "special" table that needs a specific care
+ if (Hdr2->Signature == FACS_SIG)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Hdr2->Signature == FACP_SIG) && (!Table))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Hdr2->Signature == DSDT_SIG) && (!Table))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TblNum = FindAcpiTblByHandle (Handle);
+ TRACE((-1, "TblNum=0x%X ", TblNum));
+
+ if (TblNum == ACPI_TABLE_NOT_FOUND) Status=EFI_INVALID_PARAMETER;
+
+ TRACE((-1,"Status = %r\n", Status));
+
+ // Table with this Handle does not exist
+ if (EFI_ERROR(Status))
+ {
+ return Status;
+ }
+
+ //if sombody is trying to replace or delete table with version
+ //which is a combination of bits (for example V1 and 2 or V2 and 3, etc)
+ if ((Version != gAcpiData.AcpiEntries[TblNum]->AcpiTblVer) && (Version != ACPI_TABLE_NOT_REMOVABLE))
+ {
+ MultyVer = gAcpiData.AcpiEntries[TblNum]->AcpiTblVer;
+
+ if ((MultyVer == EFI_ACPI_TABLE_VERSION_1_0B) ||
+ (MultyVer == EFI_ACPI_TABLE_VERSION_2_0) ||
+ (MultyVer == EFI_ACPI_TABLE_VERSION_3_0) || (MultyVer == EFI_ACPI_TABLE_VERSION_4_0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ else MultyVer ^= Version;
+ }
+
+ if (Version != EFI_ACPI_TABLE_VERSION_NONE)
+ gAcpiData.AcpiLength -= gAcpiData.AcpiEntries[TblNum]->BtHeaderPtr->Length;
+
+ Status = DeleteItemLst((T_ITEM_LIST*) &gAcpiData, TblNum, TRUE);
+ TRACE((-1,"ACPI: Deleting Table From Storage: Status = %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status))
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (MultyVer)
+ {
+ AcpiTableAdded = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTableAdded);
+
+ if (!AcpiTableAdded)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AcpiTableAdded->AcpiTblVer = MultyVer;
+
+ AcpiTableAdded->BtHeaderPtr = Hdr2;
+ OemAcpiSetPlatformId(Hdr2);
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ Status = DispatchSdtNotify(AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ if (EFI_ERROR(Status))
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[TblNum]->BtHeaderPtr->Length;
+ }
+
+ else pBS->FreePool(Hdr2);
+ }
+
+ //Update Handle with New Table Instance.
+ *Handle=(UINTN)Ptr;
+
+ if (CorrectFacp)
+ {
+ Status = UpdateFacp ();
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ TRACE((-1,"ACPI: SetAcpiTable() Exiting... Status = %r\n", Status));
+
+ if (gPublishedOnReadyToBoot)
+ {
+ if (!gForceAcpi1) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (1, 0);
+ }
+ TRACE((-1,"ACPI: PublishTables in SetAcpiTable() Status = %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+//--- !!!!!!!!!!!!!!!!!!!!!!!!!! Version none Done ???? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+}// end of AcpiSupportSetAcpiTable
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiSupportPublishTables
+//
+// Description: Causes one or more versions of the ACPI tables to be published in
+// the EFI system configuration tables.
+//
+// Input:
+// IN EFI_ACPI_SUPPORT_PROTOCOL *This - pointer to EFI_ACPI_SUPPORT_PROTOCOL instance
+// IN EFI_ACPI_TABLE_VERSION Version - ACPI table version
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ABORTED - invalid EFI_ACPI_SUPPORT_PROTOCOL pointer or
+// an error occurred and the function could not complete successfully.
+// EFI_UNSUPPORTED - passed ACPI table version invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiSupportPublishTables(
+ IN EFI_ACPI_SUPPORT_PROTOCOL *This,
+ IN EFI_ACPI_TABLE_VERSION Version )
+{
+ EFI_STATUS Status;
+
+ if ((Version < EFI_ACPI_TABLE_VERSION_1_0B) || (Version > EFI_ACPI_TABLE_VERSION_ALL) || (This!=&gAcpiData.AcpiSupportProtocol))
+ return EFI_UNSUPPORTED;
+ if (Version == EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ if ((gRsdtPtrStr != NULL) && (gRsdtPtrStr->XsdtAddr != 0)) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (1, 0);
+ }
+
+ if ((Version > EFI_ACPI_TABLE_VERSION_1_0B) && (!gForceAcpi1))
+ {
+ if ((gRsdtPtrStr != NULL) && (gRsdtPtrStr->RsdtAddr != 0)) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (0, 1);
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) return EFI_ABORTED;
+ else return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiInstallAcpiTable
+//
+// Description: Installs an ACPI table into the RSDT/XSDT.
+//
+// Input:
+// IN EFI_ACPI_TABLE_PROTOCOL *This - A pointer to a EFI_ACPI_TABLE_PROTOCOL.
+// IN VOID *AcpiTableBuffer - A pointer to a buffer containing the ACPI table to be installed.
+// IN UINTN AcpiTableBufferSize - Specifies the size, in bytes, of the AcpiTableBuffer buffer.
+// OUT UINTN *TableKey - Returns a key to refer to the ACPI table.
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Either AcpiTableBuffer is NULL, TableKey is NULL, or
+// AcpiTableBufferSize and the size field embedded in the ACPI
+// table pointed to by AcpiTableBuffer are not in sync
+// EFI_OUT_OF_RESOURCES - Insufficient resources exist to complete the request.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AcpiInstallAcpiTable(
+ IN CONST EFI_ACPI_TABLE_PROTOCOL *This,
+ IN CONST VOID *AcpiTableBuffer,
+ IN UINTN AcpiTableBufferSize,
+ OUT UINTN *TableKey)
+{
+ EFI_STATUS Status;
+ UINTN IntTableKey = 0;
+ // Update for LPT PCH Refcode. >>>
+ EFI_ACPI_TABLE_VERSION AcpiVersion = ACPI_TABLE_NOT_REMOVABLE;
+ UINTN TblNum = ACPI_TABLE_NOT_FOUND;
+ // <<< Update for LPT PCH Refcode.
+
+
+ if ((AcpiTableBuffer == NULL) || (AcpiTableBufferSize != (UINTN)((ACPI_HDR*)AcpiTableBuffer)->Length)
+ || (TableKey == NULL)) return EFI_INVALID_PARAMETER;
+ // Update for LPT PCH Refcode. >>>
+ if (*TableKey != 0)
+ {
+ TblNum = FindAcpiTblByHandle(TableKey);
+ if (TblNum != ACPI_TABLE_NOT_FOUND)
+ {
+ AcpiVersion = gAcpiData.AcpiEntries[TblNum]->AcpiTblVer;
+ IntTableKey = *TableKey;
+ }
+ }
+
+ Status = AcpiSupportSetAcpiTable(&gAcpiData.AcpiSupportProtocol,
+ (VOID*)AcpiTableBuffer,
+ TRUE,
+ // This is the mark, that means, that this table was added by the new protocol
+ AcpiVersion,
+ &IntTableKey);
+ ASSERT_EFI_ERROR(Status);
+ // <<< Update for LPT PCH Refcode.
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ *TableKey = IntTableKey;
+
+ if (!gForceAcpi1) Status = PublishTbl (1, 1);
+ else PublishTbl (1, 0);
+ return Status;
+}// end of AcpiInstallAcpiTable
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiUninstallAcpiTable
+//
+// Description: Function allows a caller to remove an ACPI table.
+//
+// Input:
+// IN EFI_ACPI_TABLE_PROTOCOL *This - A pointer to a EFI_ACPI_TABLE_PROTOCOL.
+// IN UINTN *TableKey - Specifies the table to uninstall. The key was returned from
+// InstallAcpiTable().
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_NOT_FOUND - TableKey does not refer to a valid key for a table entry.
+// EFI_OUT_OF_RESOURCES - Insufficient resources exist to complete the request.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiUninstallAcpiTable(
+ IN CONST EFI_ACPI_TABLE_PROTOCOL *This,
+ IN UINTN TableKey)
+{
+ EFI_STATUS Status;
+
+ Status = AcpiSupportSetAcpiTable(&gAcpiData.AcpiSupportProtocol,
+ NULL,
+ FALSE,
+ // This is the mark, that means, that this table was added by the new protocol
+ ACPI_TABLE_NOT_REMOVABLE,
+ &TableKey);
+ if (EFI_ERROR(Status))
+ return (EFI_NOT_FOUND);
+ else
+ return Status;
+}//end of AcpiUninstallAcpiTable
+
+
+//
+// ACPI SDT Protocol functions implementation.
+//
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAcpiTable2
+//
+// Description:
+// Returns a requested ACPI table.
+// The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
+// with the Index that was input. The following structures are not considered elements in the list of
+// ACPI tables:
+// - Root System Description Pointer (RSD_PTR)
+// - Root System Description Table (RSDT)
+// - Extended System Description Table (XSDT)
+// Version is updated with a bit map containing all the versions of ACPI of which the table is a
+// member.
+//
+// Input:
+// Index The zero-based index of the table to retrieve.
+// Table Pointer for returning the table buffer.
+// Version On return, updated with the ACPI versions to which this table belongs. Type
+// EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
+// EFI_ACPI_SDT_PROTOCOL.
+// TableKey On return, points to the table key for the specified ACPI system definition table. This
+// is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
+// Output:
+// EFI_SUCCESS The function completed successfully.
+// EFI_NOT_FOUND The requested index is too large and a table was not found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetAcpiTable2 (
+ IN UINTN Index,
+ OUT EFI_ACPI_SDT_HEADER **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *TableKey)
+{
+
+ return AcpiSupportGetAcpiTable (&gAcpiData.AcpiSupportProtocol, Index,
+ Table, Version,TableKey);
+
+}
+
+EFI_STATUS RegisterNotify(
+ IN BOOLEAN Register,
+ IN EFI_ACPI_NOTIFICATION_FN Notification)
+{
+ if(Notification == NULL) return EFI_INVALID_PARAMETER;
+
+ if(Register){
+ return AppendItemLst((T_ITEM_LIST*)&gAcpiData.NotifyInitCount, Notification);
+ } else {
+ UINTN i;
+ //-----------------
+ for(i=0; i<gAcpiData.NotifyFnCount; i++){
+ if(gAcpiData.AcpiNotifyFn[i]==Notification){
+ return DeleteItemLst((T_ITEM_LIST*)&gAcpiData.NotifyInitCount,i,FALSE);
+ }
+ }
+ //can't found matching notify function.
+ return EFI_INVALID_PARAMETER;
+ }
+}
+#endif
+
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// Driver entry point
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiNewCoreEntry
+//
+// Description:
+// This function is ACPI driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, ACPI_SUPPORT_PROTOCOL installed
+// EFI_ABORTED - Dsdt table not found or table publishing failed
+// EFI_ALREADY_STARTED - driver already started
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+// Notes:
+// This function also creates ReadyToBoot event to update AML objects before booting
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiNewCoreEntry (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ ACPI_HDR *Dsdt1Ptr = NULL, *Dsdt2Ptr = NULL;
+ VOID *DummyPtr;
+ static EFI_GUID Acpisupguid = EFI_ACPI_SUPPORT_GUID;
+ static EFI_GUID AcpiTableProtocolGuid = EFI_ACPI_TABLE_PROTOCOL_GUID;
+ UINTN AcpiVer;
+ EFI_ACPI_TABLE_VERSION EfiAcpiVer;
+ ACPI_TBL_ITEM *AcpiTable = NULL;
+#if FORCE_TO_ACPI1_SETUP_ENABLE
+ SETUP_DATA *SetupData = NULL;
+ UINTN SetupSize = 0;
+#endif
+//------------------------
+ InitAmiLib(ImageHandle,SystemTable);
+ PROGRESS_CODE(DXE_ACPI_INIT);
+ TRACE((-1,"IN ACPI Start: %x\n", Status));
+ //it must be ony one instance of this protocol
+ Status = pBS->LocateProtocol(&Acpisupguid,NULL,&DummyPtr);
+
+ if (!EFI_ERROR(Status)) return EFI_ALREADY_STARTED;
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ //Use AMI_CPU_INFO_2_PROTOCOL if published.
+ Status = pBS->LocateProtocol(&gAmiCpuInfo2ProtocolGuid, NULL, &gAmiCpu2Info);
+
+ if (EFI_ERROR(Status)) gAmiCpu2Info = NULL;
+
+#endif
+
+
+ Status = pBS->LocateProtocol(&gAmiBoardInfoGuid, NULL,(VOID**)&gAmiBoardInfoProtocol);
+
+ if (EFI_ERROR(Status))
+ {
+ gAmiBoardInfoProtocol = NULL;
+ TRACE((-1, "ACPI: Can't find AMI Board Info Protocol %r EXITING!",Status));
+ return Status;
+ }
+
+
+
+ AcpiVer = 2;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_2_0;
+
+ if (ACPI_BUILD_TABLES_3_0 == 1)
+ {
+ AcpiVer = 3;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_3_0;
+ }
+
+ if (ACPI_BUILD_TABLES_4_0 == 1)
+ {
+ AcpiVer = 4;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_4_0;
+ }
+#if ATAD_SUPPORT == 1
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, 4, &AtadBuffPtr);
+ if (!EFI_ERROR(Status) && AtadBuffPtr)
+ {
+ EFI_GUID AtadSmiGuid = ATAD_SMI_GUID;
+ UINTN AtadVarSize = sizeof(AtadBuffPtr);
+ Status = pRS->SetVariable ( L"AtadSmiBuffer",
+ &AtadSmiGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ AtadVarSize,
+ &AtadBuffPtr );
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#endif
+
+#if FORCE_TO_ACPI1_SETUP_ENABLE
+ Status = GetEfiVariable(L"Setup",&gSetupGuid,NULL,&SetupSize,&SetupData);
+ ASSERT_EFI_ERROR(Status);
+ if (!EFI_ERROR (Status))
+ if (SetupData->ForceToAcpi1 ==1)
+ {
+ AcpiVer = gForceAcpi1 = 1;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ }
+#endif
+ Status = BuildFacs ();
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ Status = BuildFacpiAll (1, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ if (!gForceAcpi1)
+ {
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ Status = BuildFacpiAll (AcpiVer, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+ TRACE((-1,"IN ACPI 1: %x\n", Status));
+
+ Status = GetDsdtFv(&Dsdt1Ptr, &Dsdt2Ptr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_ABORTED;
+
+ if ((Dsdt2Ptr != NULL) && (Dsdt1Ptr != NULL))
+ {
+ TRACE((-1,"DSDT1 addres 0x%X; -> %r \n", Dsdt1Ptr, Status));
+ TRACE((-1,"DSDT2 addres 0x%X; -> %r \n", Dsdt2Ptr, Status));
+
+ Dsdt1Ptr->Checksum = 0;
+ Dsdt2Ptr->Checksum = 0;
+ Dsdt1Ptr->Checksum = ChsumTbl((UINT8*)Dsdt1Ptr, Dsdt1Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt1Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+
+ Dsdt2Ptr->Checksum = ChsumTbl((UINT8*)Dsdt2Ptr, Dsdt2Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt2Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_2_0;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+
+ if (Dsdt1Ptr == NULL)
+ {
+ TRACE((-1,"DSDT21 addres 0x%lX; -> %r \n", Dsdt2Ptr, Status));
+ Dsdt2Ptr->Checksum = 0;
+ Dsdt2Ptr->Checksum = ChsumTbl((UINT8*)Dsdt2Ptr, Dsdt2Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt2Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_2_0;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+
+ if (Dsdt2Ptr == NULL)
+ {
+ TRACE((-1,"DSDT11 addres 0x%lX; -> %r \n", Dsdt1Ptr, Status));
+ Dsdt1Ptr->Checksum = 0;
+ Dsdt1Ptr->Checksum = ChsumTbl((UINT8*)Dsdt1Ptr, Dsdt1Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt1Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+
+ Status = UpdateFacp ();
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_ABORTED;
+
+#if ACPI_APIC_TBL == 1
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ Status = BuildMadtAll (AcpiVer, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_ABORTED;
+
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+#endif
+
+#if MPS_TABLE_SUPPORT == 1
+ Status = MpsTableBuilderInit(ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR(Status);
+#endif
+//------ Performance Measurment ------------------------------------
+
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (AcpiTable)
+ {
+ Status = BuildFPDT (AcpiVer, &AcpiTable->BtHeaderPtr);
+
+ if (!EFI_ERROR(Status))
+ {
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+ }
+//------ Performance Measurment End --------------------------------
+
+//------ FID Table Start -------------------------------------------
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (AcpiTable)
+ {
+ Status = BuildFIDT (&AcpiTable->BtHeaderPtr);
+
+ if (!EFI_ERROR(Status))
+ {
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+ }
+
+//------ FID Table End --------------------------------------------
+
+ gAuiGlob = MallocZ(sizeof(ACPI_AML_UPD_INFO));
+ ASSERT(gAuiGlob);
+
+
+
+ //free temporary space used during this routine execution ??????
+
+ // ???? Publish all tbls 1,1 ??????
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK, CollectAmlUpdInfo, gAuiGlob, &gEvtReadyToBoot
+ );
+ ASSERT_EFI_ERROR(Status);
+
+
+
+ if (EFI_ERROR(Status))return EFI_ABORTED;
+
+
+ gAcpiData.AcpiSupportProtocol.GetAcpiTable = AcpiSupportGetAcpiTable;
+ gAcpiData.AcpiSupportProtocol.SetAcpiTable = AcpiSupportSetAcpiTable;
+ gAcpiData.AcpiSupportProtocol.PublishTables = AcpiSupportPublishTables;
+
+ gAcpiData.AcpiTableProtocol.InstallAcpiTable = AcpiInstallAcpiTable;
+ gAcpiData.AcpiTableProtocol.UninstallAcpiTable = AcpiUninstallAcpiTable;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ gAcpiData.AcpiSdtProtocol.GetAcpiTable=GetAcpiTable2;
+ gAcpiData.AcpiSdtProtocol.RegisterNotify=RegisterNotify;
+ gAcpiData.AcpiSdtProtocol.Open=Open;
+ gAcpiData.AcpiSdtProtocol.OpenSdt=OpenSdt;
+ gAcpiData.AcpiSdtProtocol.Close=Close;
+ gAcpiData.AcpiSdtProtocol.GetChild=GetChild;
+ gAcpiData.AcpiSdtProtocol.GetOption=GetOption;
+ gAcpiData.AcpiSdtProtocol.SetOption=SetOption;
+ gAcpiData.AcpiSdtProtocol.FindPath=FindPath;
+ gAcpiData.AcpiSdtProtocol.AcpiVersion=EFI_ACPI_TABLE_VERSION_ALL;
+#endif
+
+ gAcpiData.AcpiSupportHandle = NULL;
+ //Instasll ProtocolInterface;
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &gAcpiData.AcpiSupportHandle,
+ &Acpisupguid,
+ &gAcpiData.AcpiSupportProtocol,
+ &AcpiTableProtocolGuid,
+ &gAcpiData.AcpiTableProtocol,
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ &gEfiAcpiSdtProtocolGuid,
+ &gAcpiData.AcpiSdtProtocol,
+#endif
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ //TRACE((-1,"Before PublishTbl: %x\n", Status));
+ //Status = PublishTbl (1, 1);
+ //TRACE((-1,"After PublishTbl: %x\n", Status));
+ return Status;
+
+//return EFI_SUCCESS;
+}
+
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************