summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/Acpi
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2015-01-26 08:05:04 +0000
committerlersek <lersek@Edk2>2015-01-26 08:05:04 +0000
commitf798e8bff773c833837c71fa806a7604fff7b503 (patch)
tree36a172c39e5031d22d612d6233fe173a584c3722 /MdeModulePkg/Universal/Acpi
parent38bd44b8e1f0d650094edbd8cc918ce135a330a7 (diff)
downloadedk2-platforms-f798e8bff773c833837c71fa806a7604fff7b503.tar.xz
MdeModulePkg: Acpi: enforce exclusion between FirmwareCtrl and XFirmwareCtrl
The code in AcpiTableDxe handles the installation of FADT and FACS in both possible orders. In the [FADT, FACS] installation order, the FACS is at once linked into the FADT. In the [FACS, FADT] installation order, the FACS is stashed temporarily, and it is linked into the FADT when the FADT is installed later. According to the ACPI specification, *at most one* of FADT.FirmwareCtrl and FADT.XFirmwareCtrl may be nonzero. The code is aware of this requirement, and it never sets both of them to nonzero values at once. However, the code doesn't expect the following: - The caller first installs the FACS, which is stashed. The address that is saved happens to fall below 4GB. - The caller then installs a FADT, with a zero FirmwareCtrl field, and a nonzero (pre-populated) XFirmwareCtrl field. In this case the code sets FADT.FirmwareCtrl to the less-than-4GB address of the stashed FACS, and leaves the different nonzero value in FADT.XFirmwareCtrl. This violates the ACPI specification. Prevent this by always zeroing the field that we do *not* set. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jiewen Yao <Jiewen.Yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16659 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/Acpi')
-rw-r--r--MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
index 76f2199c96..247c398c4f 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
@@ -621,6 +621,7 @@ AddTableToList (
//
if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;
+ ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
} else {
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;
CopyMem (
@@ -628,6 +629,7 @@ AddTableToList (
&Buffer64,
sizeof (UINT64)
);
+ AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
}
AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;
@@ -750,6 +752,7 @@ AddTableToList (
//
if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;
+ ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
} else {
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;
CopyMem (
@@ -757,6 +760,7 @@ AddTableToList (
&Buffer64,
sizeof (UINT64)
);
+ AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
}
//