From 27b044605cd5f6b33a3d231576003850b3fe305b Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Wed, 15 May 2024 09:09:03 -0600 Subject: ArmPkg: Set BIOS Segment to 0 in SMBIOS Type 0 table According to the SMBIOS specification, on UEFI systems the BIOS Segment field in the Type 0 table isn't relevant and should be set to 0. Signed-off-by: Rebecca Cran --- ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf | 1 - ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf index 60d8fe31c2..e8f1011fa1 100644 --- a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf @@ -78,7 +78,6 @@ gArmTokenSpaceGuid.PcdBaseBoardManufacturer gArmTokenSpaceGuid.PcdBaseBoardProductName gArmTokenSpaceGuid.PcdBaseBoardVersion - gArmTokenSpaceGuid.PcdFdBaseAddress [Guids] gEfiGenericVariableGuid diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c index 03f9f07cfa..b1b0d8eb5e 100644 --- a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c @@ -253,7 +253,7 @@ SMBIOS_MISC_TABLE_FUNCTION (MiscBiosVendor) { (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE0)); SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0); - SmbiosRecord->BiosSegment = (UINT16)(FixedPcdGet32 (PcdFdBaseAddress) / SIZE_64KB); + SmbiosRecord->BiosSegment = 0; if (BiosPhysicalSize < SIZE_16MB) { SmbiosRecord->BiosSize = Base2ToByteWith64KUnit (BiosPhysicalSize) - 1; } else { -- cgit From 87f22f4b5c7079efb6c38eb1600e54d7180079a6 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 22 Apr 2024 11:57:57 +0800 Subject: MdeModulePkg: Add gEdkiiS3MtrrSettingGuid Add gEdkiiS3MtrrSettingGuid a new GUID for s3 MTRR setting. This GUID will be used to save MTRR_SETTINGS at EndOfDxe by LockBox and restore at S3 boot PEI phase for s3 usage. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Reviewed-by: Liming Gao Reviewed-by: Jiaxin Wu --- MdeModulePkg/MdeModulePkg.dec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index f7339f0aec..02f330a453 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -4,7 +4,7 @@ # and libraries instances, which are used for those modules. # # Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. -# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2016, Linaro Ltd. All rights reserved.
# (C) Copyright 2016 - 2019 Hewlett Packard Enterprise Development LP
# Copyright (c) 2017, AMD Incorporated. All rights reserved.
@@ -465,6 +465,9 @@ gEdk2JedecSfdpSpiDxeDriverGuid = { 0xBE71701E, 0xB63C, 0x4574, { 0x9C, 0x5C, 0x36, 0x29, 0xE8, 0xEA, 0xC4, 0x14 }} gEdk2JedecSfdpSpiSmmDriverGuid = { 0x95A1E915, 0x195C, 0x477C, { 0x92, 0x6F, 0x7E, 0x24, 0x67, 0xC1, 0xB3, 0x1F }} + ## This GUID will be used to save MTRR_SETTINGS at EndOfDxe by LockBox and restore at S3 boot PEI phase for s3 usage. + gEdkiiS3MtrrSettingGuid = { 0xd77baa84, 0xb332, 0x4463, { 0x9f, 0x1d, 0xce, 0x81, 0x00, 0xfe, 0x7f, 0x35 }} + [Ppis] ## Include/Ppi/FirmwareVolumeShadowPpi.h gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } } -- cgit From 52a4bc65f64209c53acad03a46de851362eae4ca Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 23 Apr 2024 11:10:00 +0800 Subject: OvmfPkg: Save MTRR by lockbox in CpuS3DataDxe Save MTRR by lockbox in CpuS3DataDxe. In S3 boot, The MTRR setting will be restored in S3Resume.c in following patches. Then S3Resume.c will wakeup all APs to load the MTRR setting. This can avoid waking up APs in CpuS3.c. Signed-off-by: Dun Tan Reviewed-by: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Reviewed-by: Ray Ni Reviewed-by: Jiaxin Wu --- OvmfPkg/CpuS3DataDxe/CpuS3Data.c | 13 ++++++++++++- OvmfPkg/CpuS3DataDxe/CpuS3DataDxe.inf | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/CpuS3DataDxe/CpuS3Data.c b/OvmfPkg/CpuS3DataDxe/CpuS3Data.c index 289048b75d..eacdfa12c3 100644 --- a/OvmfPkg/CpuS3DataDxe/CpuS3Data.c +++ b/OvmfPkg/CpuS3DataDxe/CpuS3Data.c @@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not support hot plug CPUs. This module can be copied into a CPU specific package and customized if these additional features are required. -Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2015 - 2020, Red Hat, Inc. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -130,6 +131,16 @@ CpuS3DataOnEndOfDxe ( DEBUG ((DEBUG_VERBOSE, "%a\n", __func__)); MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable); + // + // Save MTRR in lockbox + // + Status = SaveLockBox ( + &gEdkiiS3MtrrSettingGuid, + &AcpiCpuDataEx->MtrrTable, + sizeof (MTRR_SETTINGS) + ); + ASSERT_EFI_ERROR (Status); + // // Close event, so it will not be invoked again. // diff --git a/OvmfPkg/CpuS3DataDxe/CpuS3DataDxe.inf b/OvmfPkg/CpuS3DataDxe/CpuS3DataDxe.inf index 228d5ae1b2..5369613f5d 100644 --- a/OvmfPkg/CpuS3DataDxe/CpuS3DataDxe.inf +++ b/OvmfPkg/CpuS3DataDxe/CpuS3DataDxe.inf @@ -9,7 +9,7 @@ # support hot plug CPUs. This module can be copied into a CPU specific package # and customized if these additional features are required. # -# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2013-2024, Intel Corporation. All rights reserved.
# Copyright (c) 2015-2020, Red Hat, Inc. # # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -46,9 +46,11 @@ MtrrLib UefiBootServicesTableLib UefiDriverEntryPoint + LockBoxLib [Guids] gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event + gEdkiiS3MtrrSettingGuid [Protocols] gEfiMpServiceProtocolGuid ## CONSUMES -- cgit From 32a9ee736e8e4f29360fcb6a1b0790c46dcb0979 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 30 Apr 2024 10:59:53 +0800 Subject: UefiCpuPkg: Add locbox lib instance in DSC Add locbox lib instance in DSC. The SmmLockBoxDxeLib will be consumed by CpuS3DataDxe driver Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/UefiCpuPkg.dsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 3d49f72588..1b52760e1a 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -1,7 +1,7 @@ ## @file # UefiCpuPkg Package # -# Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.
# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -68,6 +68,7 @@ UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf -- cgit From 3a516aa2400426bd1be45e130e28b8ed2d841b01 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 23 Apr 2024 11:18:41 +0800 Subject: UefiCpuPkg: Save MTRR by lockbox in CpuS3DataDxe Save MTRR by lockbox in CpuS3DataDxe. In S3 boot, The MTRR setting will be restored in S3Resume.c in following patches. Then S3Resume.c will wakeup all APs to load the MTRR setting. This can avoid waking up APs in CpuS3.c. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c | 13 ++++++++++++- UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c b/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c index 86ce5303ca..c87f82bc22 100644 --- a/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c +++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c @@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not support hot plug CPUs. This module can be copied into a CPU specific package and customized if these additional features are required. -Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2015, Red Hat, Inc. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -130,6 +131,16 @@ CpuS3DataOnEndOfDxe ( DEBUG ((DEBUG_VERBOSE, "%a\n", __func__)); MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable); + // + // Save MTRR in lockbox + // + Status = SaveLockBox ( + &gEdkiiS3MtrrSettingGuid, + &AcpiCpuDataEx->MtrrTable, + sizeof (MTRR_SETTINGS) + ); + ASSERT_EFI_ERROR (Status); + // // Close event, so it will not be invoked again. // diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf index 510133a614..c690f7df5b 100644 --- a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf +++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf @@ -9,7 +9,7 @@ # support hot plug CPUs. This module can be copied into a CPU specific package # and customized if these additional features are required. # -# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2013-2024, Intel Corporation. All rights reserved.
# Copyright (c) 2015, Red Hat, Inc. # # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -46,9 +46,11 @@ BaseLib MtrrLib MemoryAllocationLib + LockBoxLib [Guids] gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event + gEdkiiS3MtrrSettingGuid [Protocols] gEfiMpServiceProtocolGuid ## CONSUMES -- cgit From ad245ffeff3221a903d073206b4613f29344aa45 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 6 May 2024 13:35:31 +0800 Subject: UefiCpuPkg: LoadMtrrData for all cpu in S3Resume In this commit, S3Resume.c wakeup all Aps to run LoadMtrrData for all cpu before transfer to CpuS3.c in smm cpu driver. The MtrrSetting table can be restored by gEdkiiS3MtrrSettingGuid which is saved by lockbox in PEI phase. This can avoid waking up APs in CpuS3.c. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c | 51 +++++++++++++++++++++- .../Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf | 4 +- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c index 4cf676fb3e..078ae2d72d 100644 --- a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c @@ -4,7 +4,7 @@ This module will execute the boot script saved during last boot and after that, control is passed to OS waking up handler. - Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -938,6 +939,20 @@ S3ResumeExecuteBootScript ( CpuDeadLoop (); } +/** + Sync up the MTRR values for all processors. + + @param[in] MtrrTable Address of MTRR setting. +**/ +VOID +EFIAPI +LoadMtrrData ( + IN VOID *MtrrTable + ) +{ + MtrrSetAllMtrrs (MtrrTable); +} + /** Restores the platform to its preboot configuration for an S3 resume and jumps to the OS waking vector. @@ -990,6 +1005,7 @@ S3RestoreConfig2 ( BOOLEAN InterruptStatus; IA32_CR0 Cr0; EDKII_PEI_MP_SERVICES2_PPI *MpService2Ppi; + MTRR_SETTINGS MtrrTable; TempAcpiS3Context = 0; TempEfiBootScriptExecutorVariable = 0; @@ -1082,6 +1098,39 @@ S3RestoreConfig2 ( Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); } + // + // Get MP Services2 Ppi to pass it to Smm S3. + // + Status = PeiServicesLocatePpi ( + &gEdkiiPeiMpServices2PpiGuid, + 0, + NULL, + (VOID **)&MpService2Ppi + ); + ASSERT_EFI_ERROR (Status); + + // + // Restore MTRR setting + // + VarSize = sizeof (MTRR_SETTINGS); + Status = RestoreLockBox ( + &gEdkiiS3MtrrSettingGuid, + &MtrrTable, + &VarSize + ); + ASSERT_EFI_ERROR (Status); + + // + // Sync up the MTRR values for all processors. + // + Status = MpService2Ppi->StartupAllCPUs ( + MpService2Ppi, + (EFI_AP_PROCEDURE)LoadMtrrData, + 0, + (VOID *)&MtrrTable + ); + ASSERT_EFI_ERROR (Status); + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob); SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf index 9c9b6f3db3..54de8bc91f 100644 --- a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf @@ -5,7 +5,7 @@ # This module will excute the boot script saved during last boot and after that, # control is passed to OS waking up handler. # -# Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2017, AMD Incorporated. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -67,6 +67,7 @@ LocalApicLib ReportStatusCodeLib LockBoxLib + MtrrLib [Guids] gEfiBootScriptExecutorVariableGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox @@ -79,6 +80,7 @@ ## SOMETIMES_PRODUCES ## UNDEFINED # Install PPI ## SOMETIMES_CONSUMES ## UNDEFINED # Used to do smm communication gEdkiiS3SmmInitDoneGuid + gEdkiiS3MtrrSettingGuid [Ppis] gEfiPeiS3Resume2PpiGuid ## PRODUCES -- cgit From db4101c308c76423326606652d9d6ef2f0bc96e7 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 14:39:33 +0800 Subject: UefiCpuPkg: Remove code to load mtrr setting Remove code to load mtrr setting in CpuS3.c. In previous commits, before transferring to CpuS3.c, MTRR setting has been loaded in S3RestoreConfig2() for all CPU. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index d67fb49890..75b8c0d3de 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -1,7 +1,7 @@ /** @file Code for Processor S3 restoration -Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -91,36 +91,6 @@ UINT8 mApHltLoopCodeTemplate[] = { 0xEB, 0xFC // jmp $-2 }; -/** - Sync up the MTRR values for all processors. - - @param MtrrTable Table holding fixed/variable MTRR values to be loaded. -**/ -VOID -EFIAPI -LoadMtrrData ( - EFI_PHYSICAL_ADDRESS MtrrTable - ) - -/*++ - -Routine Description: - - Sync up the MTRR values for all processors. - -Arguments: - -Returns: - None - ---*/ -{ - MTRR_SETTINGS *MtrrSettings; - - MtrrSettings = (MTRR_SETTINGS *)(UINTN)MtrrTable; - MtrrSetAllMtrrs (MtrrSettings); -} - /** Increment semaphore by 1. @@ -554,8 +524,6 @@ InitializeCpuBeforeRebase ( IN BOOLEAN IsBsp ) { - LoadMtrrData (mAcpiCpuData.MtrrTable); - SetRegister (TRUE); ProgramVirtualWireMode (); -- cgit From b7db4d895a8c06d124bec185f824fddfaa556450 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 15:20:36 +0800 Subject: UefiCpuPkg:Set PcdCpuFeaturesInitOnS3Resume to TRUE Set PcdCpuFeaturesInitOnS3Resume to TRUE. So that CpuFeaturesPei PEIM will initialize the CPU registers and perform CPU features initialization. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/UefiCpuPkg.dec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index f86a6d2bcb..73bae90ddb 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -1,7 +1,7 @@ ## @file UefiCpuPkg.dec # This Package provides UEFI compatible CPU modules and libraries. # -# Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.
# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved.
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
# @@ -310,7 +310,7 @@ ## Specifies if CPU features will be initialized during S3 resume. # @Prompt If CPU features will be initialized during S3 resume. - gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume|FALSE|BOOLEAN|0x0000001D + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume|TRUE|BOOLEAN|0x0000001D ## Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency. # TSC Frequency = ECX (core crystal clock frequency) * EBX/EAX. -- cgit From 7421ea1f2a642e8176ee0197e001a686bf139cee Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 14:51:54 +0800 Subject: UefiCpuPkg: Remove code to set register table Remove code to set register table in CpuS3.c. In previous commit, PcdCpuFeaturesInitOnS3Resume has been set to TRUE. So that CpuFeaturesPei PEIM will initialize the CPU registers and perform CPU features initialization. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 423 -------------------------------------- 1 file changed, 423 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 75b8c0d3de..0bc4a3572d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -91,425 +91,6 @@ UINT8 mApHltLoopCodeTemplate[] = { 0xEB, 0xFC // jmp $-2 }; -/** - Increment semaphore by 1. - - @param Sem IN: 32-bit unsigned integer - -**/ -VOID -S3ReleaseSemaphore ( - IN OUT volatile UINT32 *Sem - ) -{ - InterlockedIncrement (Sem); -} - -/** - Decrement the semaphore by 1 if it is not zero. - - Performs an atomic decrement operation for semaphore. - The compare exchange operation must be performed using - MP safe mechanisms. - - @param Sem IN: 32-bit unsigned integer - -**/ -VOID -S3WaitForSemaphore ( - IN OUT volatile UINT32 *Sem - ) -{ - UINT32 Value; - - do { - Value = *Sem; - } while (Value == 0 || - InterlockedCompareExchange32 ( - Sem, - Value, - Value - 1 - ) != Value); -} - -/** - Read / write CR value. - - @param[in] CrIndex The CR index which need to read/write. - @param[in] Read Read or write. TRUE is read. - @param[in,out] CrValue CR value. - - @retval EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED. -**/ -UINTN -ReadWriteCr ( - IN UINT32 CrIndex, - IN BOOLEAN Read, - IN OUT UINTN *CrValue - ) -{ - switch (CrIndex) { - case 0: - if (Read) { - *CrValue = AsmReadCr0 (); - } else { - AsmWriteCr0 (*CrValue); - } - - break; - case 2: - if (Read) { - *CrValue = AsmReadCr2 (); - } else { - AsmWriteCr2 (*CrValue); - } - - break; - case 3: - if (Read) { - *CrValue = AsmReadCr3 (); - } else { - AsmWriteCr3 (*CrValue); - } - - break; - case 4: - if (Read) { - *CrValue = AsmReadCr4 (); - } else { - AsmWriteCr4 (*CrValue); - } - - break; - default: - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -/** - Initialize the CPU registers from a register table. - - @param[in] RegisterTable The register table for this AP. - @param[in] ApLocation AP location info for this ap. - @param[in] CpuStatus CPU status info for this CPU. - @param[in] CpuFlags Flags data structure used when program the register. - - @note This service could be called by BSP/APs. -**/ -VOID -ProgramProcessorRegister ( - IN CPU_REGISTER_TABLE *RegisterTable, - IN EFI_CPU_PHYSICAL_LOCATION *ApLocation, - IN CPU_STATUS_INFORMATION *CpuStatus, - IN PROGRAM_CPU_REGISTER_FLAGS *CpuFlags - ) -{ - CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; - UINTN Index; - UINTN Value; - CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead; - volatile UINT32 *SemaphorePtr; - UINT32 FirstThread; - UINT32 CurrentThread; - UINT32 CurrentCore; - UINTN ProcessorIndex; - UINT32 *ThreadCountPerPackage; - UINT8 *ThreadCountPerCore; - EFI_STATUS Status; - UINT64 CurrentValue; - - // - // Traverse Register Table of this logical processor - // - RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry; - - for (Index = 0; Index < RegisterTable->TableLength; Index++) { - RegisterTableEntry = &RegisterTableEntryHead[Index]; - - // - // Check the type of specified register - // - switch (RegisterTableEntry->RegisterType) { - // - // The specified register is Control Register - // - case ControlRegister: - Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value); - if (EFI_ERROR (Status)) { - break; - } - - if (RegisterTableEntry->TestThenWrite) { - CurrentValue = BitFieldRead64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 - ); - if (CurrentValue == RegisterTableEntry->Value) { - break; - } - } - - Value = (UINTN)BitFieldWrite64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - RegisterTableEntry->Value - ); - ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value); - break; - // - // The specified register is Model Specific Register - // - case Msr: - if (RegisterTableEntry->TestThenWrite) { - Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index); - if (RegisterTableEntry->ValidBitLength >= 64) { - if (Value == RegisterTableEntry->Value) { - break; - } - } else { - CurrentValue = BitFieldRead64 ( - Value, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 - ); - if (CurrentValue == RegisterTableEntry->Value) { - break; - } - } - } - - // - // If this function is called to restore register setting after INIT signal, - // there is no need to restore MSRs in register table. - // - if (RegisterTableEntry->ValidBitLength >= 64) { - // - // If length is not less than 64 bits, then directly write without reading - // - AsmWriteMsr64 ( - RegisterTableEntry->Index, - RegisterTableEntry->Value - ); - } else { - // - // Set the bit section according to bit start and length - // - AsmMsrBitFieldWrite64 ( - RegisterTableEntry->Index, - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - RegisterTableEntry->Value - ); - } - - break; - // - // MemoryMapped operations - // - case MemoryMapped: - AcquireSpinLock (&CpuFlags->MemoryMappedLock); - MmioBitFieldWrite32 ( - (UINTN)(RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32)), - RegisterTableEntry->ValidBitStart, - RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, - (UINT32)RegisterTableEntry->Value - ); - ReleaseSpinLock (&CpuFlags->MemoryMappedLock); - break; - // - // Enable or disable cache - // - case CacheControl: - // - // If value of the entry is 0, then disable cache. Otherwise, enable cache. - // - if (RegisterTableEntry->Value == 0) { - AsmDisableCache (); - } else { - AsmEnableCache (); - } - - break; - - case Semaphore: - // Semaphore works logic like below: - // - // V(x) = LibReleaseSemaphore (Semaphore[FirstThread + x]); - // P(x) = LibWaitForSemaphore (Semaphore[FirstThread + x]); - // - // All threads (T0...Tn) waits in P() line and continues running - // together. - // - // - // T0 T1 ... Tn - // - // V(0...n) V(0...n) ... V(0...n) - // n * P(0) n * P(1) ... n * P(n) - // - ASSERT ( - (ApLocation != NULL) && - (CpuStatus->ThreadCountPerPackage != 0) && - (CpuStatus->ThreadCountPerCore != 0) && - (CpuFlags->CoreSemaphoreCount != NULL) && - (CpuFlags->PackageSemaphoreCount != NULL) - ); - switch (RegisterTableEntry->Value) { - case CoreDepType: - SemaphorePtr = CpuFlags->CoreSemaphoreCount; - ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore; - - CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core; - // - // Get Offset info for the first thread in the core which current thread belongs to. - // - FirstThread = CurrentCore * CpuStatus->MaxThreadCount; - CurrentThread = FirstThread + ApLocation->Thread; - - // - // Different cores may have different valid threads in them. If driver maintail clearly - // thread index in different cores, the logic will be much complicated. - // Here driver just simply records the max thread number in all cores and use it as expect - // thread number for all cores. - // In below two steps logic, first current thread will Release semaphore for each thread - // in current core. Maybe some threads are not valid in this core, but driver don't - // care. Second, driver will let current thread wait semaphore for all valid threads in - // current core. Because only the valid threads will do release semaphore for this - // thread, driver here only need to wait the valid thread count. - // - - // - // First Notify ALL THREADs in current Core that this thread is ready. - // - for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex++) { - S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]); - } - - // - // Second, check whether all VALID THREADs (not all threads) in current core are ready. - // - for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex++) { - S3WaitForSemaphore (&SemaphorePtr[CurrentThread]); - } - - break; - - case PackageDepType: - SemaphorePtr = CpuFlags->PackageSemaphoreCount; - ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage; - // - // Get Offset info for the first thread in the package which current thread belongs to. - // - FirstThread = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount; - // - // Get the possible threads count for current package. - // - CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread; - - // - // Different packages may have different valid threads in them. If driver maintail clearly - // thread index in different packages, the logic will be much complicated. - // Here driver just simply records the max thread number in all packages and use it as expect - // thread number for all packages. - // In below two steps logic, first current thread will Release semaphore for each thread - // in current package. Maybe some threads are not valid in this package, but driver don't - // care. Second, driver will let current thread wait semaphore for all valid threads in - // current package. Because only the valid threads will do release semaphore for this - // thread, driver here only need to wait the valid thread count. - // - - // - // First Notify ALL THREADS in current package that this thread is ready. - // - for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex++) { - S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]); - } - - // - // Second, check whether VALID THREADS (not all threads) in current package are ready. - // - for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex++) { - S3WaitForSemaphore (&SemaphorePtr[CurrentThread]); - } - - break; - - default: - break; - } - - break; - - default: - break; - } - } -} - -/** - - Set Processor register for one AP. - - @param PreSmmRegisterTable Use pre Smm register table or register table. - -**/ -VOID -SetRegister ( - IN BOOLEAN PreSmmRegisterTable - ) -{ - CPU_FEATURE_INIT_DATA *FeatureInitData; - CPU_REGISTER_TABLE *RegisterTable; - CPU_REGISTER_TABLE *RegisterTables; - UINT32 InitApicId; - UINTN ProcIndex; - UINTN Index; - - FeatureInitData = &mAcpiCpuData.CpuFeatureInitData; - - if (PreSmmRegisterTable) { - RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)FeatureInitData->PreSmmInitRegisterTable; - } else { - RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)FeatureInitData->RegisterTable; - } - - if (RegisterTables == NULL) { - return; - } - - InitApicId = GetInitialApicId (); - RegisterTable = NULL; - ProcIndex = (UINTN)-1; - for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) { - if (RegisterTables[Index].InitialApicId == InitApicId) { - RegisterTable = &RegisterTables[Index]; - ProcIndex = Index; - break; - } - } - - ASSERT (RegisterTable != NULL); - - if (FeatureInitData->ApLocation != 0) { - ProgramProcessorRegister ( - RegisterTable, - (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)FeatureInitData->ApLocation + ProcIndex, - &FeatureInitData->CpuStatus, - &mCpuFlags - ); - } else { - ProgramProcessorRegister ( - RegisterTable, - NULL, - &FeatureInitData->CpuStatus, - &mCpuFlags - ); - } -} - /** The function is invoked before SMBASE relocation in S3 path to restores CPU status. @@ -524,8 +105,6 @@ InitializeCpuBeforeRebase ( IN BOOLEAN IsBsp ) { - SetRegister (TRUE); - ProgramVirtualWireMode (); if (!IsBsp) { DisableLvtInterrupts (); @@ -563,8 +142,6 @@ InitializeCpuAfterRebase ( UINTN TopOfStack; UINT8 Stack[128]; - SetRegister (FALSE); - if (mSmmS3ResumeState->MpService2Ppi == 0) { if (IsBsp) { while (mNumberToFinish > 0) { -- cgit From ffb8481ba81b142f85204725344d9517e53fd978 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 11:59:25 +0800 Subject: UefiCpuPkg: Disable PG in IA32 ApLoopCode Disable paging in IA32 RelocateApLoop assembly code to fix the issue that the AP page table is unavailiable after boot OS under IA32 execution mode. This issue exist in IA32 PEI + IA32 DXE normal boot (also S3 boot with IA32 PEI after previous three commits are accepted). In current MpLib code, the IA32 execution mode code did not create page table in reserved memory like what X64 code did. If PcdCpuStackGuard is TRUE, the PG is enabled for AP in current RelocateApLoop assembly code. And the page table for AP is unavailiable after boot OS. This might cause potential issue. So disable PG in IA32 RelocateApLoop. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm index d117f09ef5..c0fe631635 100644 --- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm @@ -1,5 +1,5 @@ ;------------------------------------------------------------------------------ ; -; Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.
+; Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Module Name: @@ -225,6 +225,10 @@ RendezvousFunnelProcEnd: ; specific to SEV-ES support and are not applicable on IA32. ;------------------------------------------------------------------------------------- AsmRelocateApLoopGenericStart: + mov eax, cr0 + btr eax, 31 ; Clear CR0.PG + mov cr0, eax ; Disable paging since the page table might be unavailiable + mov eax, esp mov esp, [eax + 12] ; TopOfApStack push dword [eax] ; push return address for stack trace -- cgit From 68310cd56a9cf0824cf4c70e84eb9736b925dc64 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 11:36:41 +0800 Subject: UefiCpuPkg:Abstract some DxeMpLib code to function Abstract some DxeMpLib code to function in this commit. Some of these internal functions will be moved to common MpLib.c in following commits. Then PeiMpLib can reuse the code. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 222 ++++++++++++++++++++------------ 1 file changed, 140 insertions(+), 82 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index 57ddb86600..5f0a87c024 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -1,7 +1,7 @@ /** @file MP initialize support functions for DXE phase. - Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -422,6 +422,144 @@ RelocateApLoop ( ASSERT (FALSE); } +/** + Allocate buffer for ApLoopCode. + + @param[in] Pages Number of pages to allocate. + @param[in, out] Address Pointer to the allocated buffer. +**/ +VOID +AllocateApLoopCodeBuffer ( + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_STATUS Status; + + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + Pages, + Address + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Remove Nx protection for the range specific by BaseAddress and Length. + + The PEI implementation uses CpuPageTableLib to change the attribute. + The DXE implementation uses gDS to change the attribute. + + @param[in] BaseAddress BaseAddress of the range. + @param[in] Length Length of the range. +**/ +VOID +RemoveNxprotection ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; + + // + // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD + // service. + // + Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemDesc); + if (!EFI_ERROR (Status)) { + gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + MemDesc.Attributes & (~EFI_MEMORY_XP) + ); + } +} + +/** + Prepare ApLoopCode. + + @param[in] CpuMpData Pointer to CpuMpData. +**/ +VOID +PrepareApLoopCode ( + IN CPU_MP_DATA *CpuMpData + ) +{ + EFI_PHYSICAL_ADDRESS Address; + MP_ASSEMBLY_ADDRESS_MAP *AddressMap; + UINT8 *ApLoopFunc; + UINTN ApLoopFuncSize; + UINTN StackPages; + UINTN FuncPages; + IA32_CR0 Cr0; + + AddressMap = &CpuMpData->AddressMap; + if (CpuMpData->UseSevEsAPMethod) { + // + // 64-bit AMD processors with SEV-ES + // + Address = BASE_4GB - 1; + ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev; + ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev; + } else { + // + // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES + // + Address = MAX_ADDRESS; + ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric; + ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric; + } + + // + // Avoid APs access invalid buffer data which allocated by BootServices, + // so we will allocate reserved data for AP loop code. We also need to + // allocate this buffer below 4GB due to APs may be transferred to 32bit + // protected mode on long mode DXE. + // Allocating it in advance since memory services are not available in + // Exit Boot Services callback function. + // + // +------------+ (TopOfApStack) + // | Stack * N | + // +------------+ (stack base, 4k aligned) + // | Padding | + // +------------+ + // | Ap Loop | + // +------------+ ((low address, 4k-aligned) + // + + StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE); + FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize); + + AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address); + ASSERT (Address != 0); + + Cr0.UintN = AsmReadCr0 (); + if (Cr0.Bits.PG != 0) { + // + // Make sure that the buffer memory is executable if NX protection is enabled + // for EfiReservedMemoryType. + // + RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages)); + } + + mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages); + ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); + mReservedApLoop.Data = (VOID *)(UINTN)Address; + ASSERT (mReservedApLoop.Data != NULL); + CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize); + if (!CpuMpData->UseSevEsAPMethod) { + // + // processors without SEV-ES and paging is enabled + // + mApPageTable = CreatePageTable ( + (UINTN)Address, + EFI_PAGES_TO_SIZE (StackPages+FuncPages) + ); + } +} + /** Callback function for ExitBootServices. @@ -477,16 +615,10 @@ InitMpGlobalData ( ) { EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; UINTN Index; EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; UINTN StackBase; CPU_INFO_IN_HOB *CpuInfoInHob; - MP_ASSEMBLY_ADDRESS_MAP *AddressMap; - UINT8 *ApLoopFunc; - UINTN ApLoopFuncSize; - UINTN StackPages; - UINTN FuncPages; SaveCpuMpData (CpuMpData); @@ -541,81 +673,7 @@ InitMpGlobalData ( } } - AddressMap = &CpuMpData->AddressMap; - if (CpuMpData->UseSevEsAPMethod) { - // - // 64-bit AMD processors with SEV-ES - // - Address = BASE_4GB - 1; - ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev; - ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev; - } else { - // - // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES - // - Address = MAX_ADDRESS; - ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric; - ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric; - } - - // - // Avoid APs access invalid buffer data which allocated by BootServices, - // so we will allocate reserved data for AP loop code. We also need to - // allocate this buffer below 4GB due to APs may be transferred to 32bit - // protected mode on long mode DXE. - // Allocating it in advance since memory services are not available in - // Exit Boot Services callback function. - // - // +------------+ (TopOfApStack) - // | Stack * N | - // +------------+ (stack base, 4k aligned) - // | Padding | - // +------------+ - // | Ap Loop | - // +------------+ ((low address, 4k-aligned) - // - - StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE); - FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize); - - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - StackPages + FuncPages, - &Address - ); - ASSERT_EFI_ERROR (Status); - - // - // Make sure that the buffer memory is executable if NX protection is enabled - // for EfiReservedMemoryType. - // - // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD - // service. - // - Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc); - if (!EFI_ERROR (Status)) { - gDS->SetMemorySpaceAttributes ( - Address, - EFI_PAGES_TO_SIZE (FuncPages), - MemDesc.Attributes & (~EFI_MEMORY_XP) - ); - } - - mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages); - ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); - mReservedApLoop.Data = (VOID *)(UINTN)Address; - ASSERT (mReservedApLoop.Data != NULL); - CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize); - if (!CpuMpData->UseSevEsAPMethod) { - // - // processors without SEV-ES - // - mApPageTable = CreatePageTable ( - (UINTN)Address, - EFI_PAGES_TO_SIZE (StackPages+FuncPages) - ); - } + PrepareApLoopCode (CpuMpData); Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, -- cgit From fcd09b1edbd377c174e98bf33ace4fc905d4cf29 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 11:48:15 +0800 Subject: UefiCpuPkg:Move some code in DxeMpLib to common place Move some code in DxeMpLib.C to common MpLib.c. The related code is to relocate Ap to new safe buffer before booting into OS. In next commits, these code also will be used by PeiMpLib. This commit doesn't change any code functionality. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 151 ++------------------------------ UefiCpuPkg/Library/MpInitLib/MpLib.c | 142 ++++++++++++++++++++++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.h | 53 ++++++++++- 3 files changed, 198 insertions(+), 148 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index 5f0a87c024..f9c5c92c22 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -20,15 +20,11 @@ #define AP_SAFE_STACK_SIZE 128 -CPU_MP_DATA *mCpuMpData = NULL; -EFI_EVENT mCheckAllApsEvent = NULL; -EFI_EVENT mMpInitExitBootServicesEvent = NULL; -EFI_EVENT mLegacyBootEvent = NULL; -volatile BOOLEAN mStopCheckAllApsStatus = TRUE; -RELOCATE_AP_LOOP_ENTRY mReservedApLoop; -UINTN mReservedTopOfApStack; -volatile UINT32 mNumberToFinish = 0; -UINTN mApPageTable; +CPU_MP_DATA *mCpuMpData = NULL; +EFI_EVENT mCheckAllApsEvent = NULL; +EFI_EVENT mMpInitExitBootServicesEvent = NULL; +EFI_EVENT mLegacyBootEvent = NULL; +volatile BOOLEAN mStopCheckAllApsStatus = TRUE; // // Begin wakeup buffer allocation below 0x88000 @@ -368,60 +364,6 @@ GetProtectedModeCS ( return Index * 8; } -/** - Do sync on APs. - - @param[in, out] Buffer Pointer to private data buffer. -**/ -VOID -EFIAPI -RelocateApLoop ( - IN OUT VOID *Buffer - ) -{ - CPU_MP_DATA *CpuMpData; - BOOLEAN MwaitSupport; - UINTN ProcessorNumber; - UINTN StackStart; - - MpInitLibWhoAmI (&ProcessorNumber); - CpuMpData = GetCpuMpData (); - MwaitSupport = IsMwaitSupport (); - if (CpuMpData->UseSevEsAPMethod) { - // - // 64-bit AMD processors with SEV-ES - // - StackStart = CpuMpData->SevEsAPResetStackStart; - mReservedApLoop.AmdSevEntry ( - MwaitSupport, - CpuMpData->ApTargetCState, - CpuMpData->PmCodeSegment, - StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, - (UINTN)&mNumberToFinish, - CpuMpData->Pm16CodeSegment, - CpuMpData->SevEsAPBuffer, - CpuMpData->WakeupBuffer - ); - } else { - // - // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES - // - StackStart = mReservedTopOfApStack; - mReservedApLoop.GenericEntry ( - MwaitSupport, - CpuMpData->ApTargetCState, - StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, - (UINTN)&mNumberToFinish, - mApPageTable - ); - } - - // - // It should never reach here - // - ASSERT (FALSE); -} - /** Allocate buffer for ApLoopCode. @@ -477,89 +419,6 @@ RemoveNxprotection ( } } -/** - Prepare ApLoopCode. - - @param[in] CpuMpData Pointer to CpuMpData. -**/ -VOID -PrepareApLoopCode ( - IN CPU_MP_DATA *CpuMpData - ) -{ - EFI_PHYSICAL_ADDRESS Address; - MP_ASSEMBLY_ADDRESS_MAP *AddressMap; - UINT8 *ApLoopFunc; - UINTN ApLoopFuncSize; - UINTN StackPages; - UINTN FuncPages; - IA32_CR0 Cr0; - - AddressMap = &CpuMpData->AddressMap; - if (CpuMpData->UseSevEsAPMethod) { - // - // 64-bit AMD processors with SEV-ES - // - Address = BASE_4GB - 1; - ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev; - ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev; - } else { - // - // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES - // - Address = MAX_ADDRESS; - ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric; - ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric; - } - - // - // Avoid APs access invalid buffer data which allocated by BootServices, - // so we will allocate reserved data for AP loop code. We also need to - // allocate this buffer below 4GB due to APs may be transferred to 32bit - // protected mode on long mode DXE. - // Allocating it in advance since memory services are not available in - // Exit Boot Services callback function. - // - // +------------+ (TopOfApStack) - // | Stack * N | - // +------------+ (stack base, 4k aligned) - // | Padding | - // +------------+ - // | Ap Loop | - // +------------+ ((low address, 4k-aligned) - // - - StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE); - FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize); - - AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address); - ASSERT (Address != 0); - - Cr0.UintN = AsmReadCr0 (); - if (Cr0.Bits.PG != 0) { - // - // Make sure that the buffer memory is executable if NX protection is enabled - // for EfiReservedMemoryType. - // - RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages)); - } - - mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages); - ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); - mReservedApLoop.Data = (VOID *)(UINTN)Address; - ASSERT (mReservedApLoop.Data != NULL); - CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize); - if (!CpuMpData->UseSevEsAPMethod) { - // - // processors without SEV-ES and paging is enabled - // - mApPageTable = CreatePageTable ( - (UINTN)Address, - EFI_PAGES_TO_SIZE (StackPages+FuncPages) - ); - } -} - /** Callback function for ExitBootServices. diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 4bf3dc5fca..f97298887f 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -17,6 +17,11 @@ EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID; EFI_GUID mMpHandOffConfigGuid = MP_HANDOFF_CONFIG_GUID; +RELOCATE_AP_LOOP_ENTRY mReservedApLoop; +UINTN mReservedTopOfApStack; +volatile UINT32 mNumberToFinish = 0; +UINTN mApPageTable; + /** Save the volatile registers required to be restored following INIT IPI. @@ -3240,3 +3245,140 @@ ConfidentialComputingGuestHas ( return (CurrentAttr == Attr); } + +/** + Do sync on APs. + + @param[in, out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +RelocateApLoop ( + IN OUT VOID *Buffer + ) +{ + CPU_MP_DATA *CpuMpData; + BOOLEAN MwaitSupport; + UINTN ProcessorNumber; + UINTN StackStart; + + MpInitLibWhoAmI (&ProcessorNumber); + CpuMpData = GetCpuMpData (); + MwaitSupport = IsMwaitSupport (); + if (CpuMpData->UseSevEsAPMethod) { + // + // 64-bit AMD processors with SEV-ES + // + StackStart = CpuMpData->SevEsAPResetStackStart; + mReservedApLoop.AmdSevEntry ( + MwaitSupport, + CpuMpData->ApTargetCState, + CpuMpData->PmCodeSegment, + StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, + (UINTN)&mNumberToFinish, + CpuMpData->Pm16CodeSegment, + CpuMpData->SevEsAPBuffer, + CpuMpData->WakeupBuffer + ); + } else { + // + // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES + // + StackStart = mReservedTopOfApStack; + mReservedApLoop.GenericEntry ( + MwaitSupport, + CpuMpData->ApTargetCState, + StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, + (UINTN)&mNumberToFinish, + mApPageTable + ); + } + + // + // It should never reach here + // + ASSERT (FALSE); +} + +/** + Prepare ApLoopCode. + + @param[in] CpuMpData Pointer to CpuMpData. +**/ +VOID +PrepareApLoopCode ( + IN CPU_MP_DATA *CpuMpData + ) +{ + EFI_PHYSICAL_ADDRESS Address; + MP_ASSEMBLY_ADDRESS_MAP *AddressMap; + UINT8 *ApLoopFunc; + UINTN ApLoopFuncSize; + UINTN StackPages; + UINTN FuncPages; + IA32_CR0 Cr0; + + AddressMap = &CpuMpData->AddressMap; + if (CpuMpData->UseSevEsAPMethod) { + // + // 64-bit AMD processors with SEV-ES + // + Address = BASE_4GB - 1; + ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev; + ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev; + } else { + // + // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES + // + Address = MAX_ADDRESS; + ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric; + ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric; + } + + // + // Avoid APs access invalid buffer data which allocated by BootServices, + // so we will allocate reserved data for AP loop code. We also need to + // allocate this buffer below 4GB due to APs may be transferred to 32bit + // protected mode on long mode DXE. + // Allocating it in advance since memory services are not available in + // Exit Boot Services callback function. + // + // +------------+ (TopOfApStack) + // | Stack * N | + // +------------+ (stack base, 4k aligned) + // | Padding | + // +------------+ + // | Ap Loop | + // +------------+ ((low address, 4k-aligned) + // + + StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE); + FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize); + + AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address); + ASSERT (Address != 0); + + Cr0.UintN = AsmReadCr0 (); + if (Cr0.Bits.PG != 0) { + // + // Make sure that the buffer memory is executable if NX protection is enabled + // for EfiReservedMemoryType. + // + RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages)); + } + + mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages); + ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); + mReservedApLoop.Data = (VOID *)(UINTN)Address; + ASSERT (mReservedApLoop.Data != NULL); + CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize); + if (!CpuMpData->UseSevEsAPMethod) { + // + // processors without SEV-ES and paging is enabled + // + mApPageTable = CreatePageTable ( + (UINTN)Address, + EFI_PAGES_TO_SIZE (StackPages+FuncPages) + ); + } +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 179f8e585b..a4a33bf538 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -1,7 +1,7 @@ /** @file Common header file for MP Initialize Library. - Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -357,7 +357,8 @@ typedef IN UINTN StackStart ); -extern EFI_GUID mCpuInitMpLibHobGuid; +extern EFI_GUID mCpuInitMpLibHobGuid; +extern volatile UINT32 mNumberToFinish; /** Assembly code to place AP into safe loop mode. @@ -933,4 +934,52 @@ AmdSevUpdateCpuMpData ( IN CPU_MP_DATA *CpuMpData ); +/** + Prepare ApLoopCode. + + @param[in] CpuMpData Pointer to CpuMpData. +**/ +VOID +PrepareApLoopCode ( + IN CPU_MP_DATA *CpuMpData + ); + +/** + Do sync on APs. + + @param[in, out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +RelocateApLoop ( + IN OUT VOID *Buffer + ); + +/** + Allocate buffer for ApLoopCode. + + @param[in] Pages Number of pages to allocate. + @param[in, out] Address Pointer to the allocated buffer. +**/ +VOID +AllocateApLoopCodeBuffer ( + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Address + ); + +/** + Remove Nx protection for the range specific by BaseAddress and Length. + + The PEI implementation uses CpuPageTableLib to change the attribute. + The DXE implementation uses gDS to change the attribute. + + @param[in] BaseAddress BaseAddress of the range. + @param[in] Length Length of the range. +**/ +VOID +RemoveNxprotection ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ); + #endif -- cgit From 669291db5a326928b4ab048524eb0ffa7d9a619f Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 18 Dec 2023 12:21:08 +0800 Subject: UefiCpuPkg: Install gEdkiiEndOfS3ResumeGuid in S3Resume Install gEdkiiEndOfS3ResumeGuid in S3Resume to trigger callback registered by PeiMpLib. The callback is to relocate Ap to new safe memory before jump to OS waking vector in S3 boot flow. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c index 078ae2d72d..e6dfa09c71 100644 --- a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c @@ -260,6 +260,12 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListS3SmmInitDoneTable = { 0 }; +EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfS3ResumeTable = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiEndOfS3ResumeGuid, + 0 +}; + // // Global Descriptor Table (GDT) // @@ -490,6 +496,13 @@ S3ResumeBootOs ( PERF_INMODULE_BEGIN ("EndOfS3Resume"); DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n")); + + // + // Install EndOfS3Resume. + // + Status = PeiServicesInstallPpi (&mPpiListEndOfS3ResumeTable); + ASSERT_EFI_ERROR (Status); + // // Signal EndOfS3Resume to SMM. // -- cgit From cdc1a88272237149003d1d1ea301d320f7b3bdf6 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 11:49:58 +0800 Subject: UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib In this commit, change PeiMpLib to install callback of gEdkiiEndOfS3ResumeGuid to relocate AP to new safe buffer. The gEdkiiEndOfS3ResumeGuid is installed in S3Resume.c before jmping to OS waking vector. Previously, code in CpuS3.c of PiSmmCpuDxe driver will prepare the new safe buffer for AP and place AP in hlt loop state. With this code change, we can remove the Machine Instructions of mApHltLoopCode in PiSmmCpuDxe. Also we can reuse the related code in DxeMpLib for PeiMpLib. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Library/MpInitLib/MpLib.h | 3 + UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 6 +- UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 154 +++++++++++++++++++++++++- 3 files changed, 161 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index a4a33bf538..cc850c7dd5 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,8 @@ // #define DEFAULT_MAX_MICROCODE_PATCH_NUM 8 +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull + // // Data structure for microcode patch information // diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf index e31e34b6f9..e4a7485fef 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -1,7 +1,7 @@ ## @file # MP Initialize Library instance for PEI driver. # -# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -25,10 +25,12 @@ [Sources.IA32] Ia32/AmdSev.c Ia32/MpFuncs.nasm + Ia32/CreatePageTable.c [Sources.X64] X64/AmdSev.c X64/MpFuncs.nasm + X64/CreatePageTable.c [Sources.IA32, Sources.X64] AmdSev.c @@ -64,6 +66,7 @@ LocalApicLib MicrocodeLib MtrrLib + CpuPageTableLib [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES @@ -87,6 +90,7 @@ gEdkiiS3SmmInitDoneGuid gEdkiiMicrocodePatchHobGuid gGhcbApicIdsGuid ## SOMETIMES_CONSUMES + gEdkiiEndOfS3ResumeGuid [Guids.LoongArch64] gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c index 4d3acb491f..16a858d542 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c @@ -1,7 +1,7 @@ /** @file MP initialize support functions for PEI phase. - Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -9,6 +9,7 @@ #include "MpLib.h" #include #include +#include #include STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB; @@ -449,6 +450,47 @@ BuildMicrocodeCacheHob ( return; } +/** + S3 SMM Init Done notification function. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDesc Address of the notification descriptor data structure. + @param InvokePpi Address of the PPI that was invoked. + + @retval EFI_SUCCESS The function completes successfully. + +**/ +EFI_STATUS +EFIAPI +NotifyOnEndOfS3Resume ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi + ) +{ + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + mNumberToFinish = CpuMpData->CpuCount - 1; + WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); + while (mNumberToFinish > 0) { + CpuPause (); + } + + DEBUG ((DEBUG_INFO, "%a() done!\n", __func__)); + + return EFI_SUCCESS; +} + +// +// Global function +// +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfS3ResumeNotifyDesc = { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEdkiiEndOfS3ResumeGuid, + NotifyOnEndOfS3Resume +}; + /** Initialize global data for MP support. @@ -463,12 +505,16 @@ InitMpGlobalData ( BuildMicrocodeCacheHob (CpuMpData); SaveCpuMpData (CpuMpData); + PrepareApLoopCode (CpuMpData); /// /// Install Notify /// Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc); ASSERT_EFI_ERROR (Status); + + Status = PeiServicesNotifyPpi (&mEndOfS3ResumeNotifyDesc); + ASSERT_EFI_ERROR (Status); } /** @@ -815,3 +861,109 @@ PlatformShadowMicrocode ( return EFI_SUCCESS; } + +/** + Allocate buffer for ApLoopCode. + + @param[in] Pages Number of pages to allocate. + @param[in, out] Address Pointer to the allocated buffer. +**/ +VOID +AllocateApLoopCodeBuffer ( + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_STATUS Status; + + Status = PeiServicesAllocatePages (EfiACPIMemoryNVS, Pages, Address); + if (EFI_ERROR (Status)) { + *Address = 0; + } +} + +/** + Remove Nx protection for the range specific by BaseAddress and Length. + + The PEI implementation uses CpuPageTableLib to change the attribute. + The DXE implementation uses gDS to change the attribute. + + @param[in] BaseAddress BaseAddress of the range. + @param[in] Length Length of the range. +**/ +VOID +RemoveNxprotection ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ) +{ + EFI_STATUS Status; + UINTN PageTable; + EFI_PHYSICAL_ADDRESS Buffer; + UINTN BufferSize; + IA32_MAP_ATTRIBUTE MapAttribute; + IA32_MAP_ATTRIBUTE MapMask; + PAGING_MODE PagingMode; + IA32_CR4 Cr4; + BOOLEAN Page5LevelSupport; + UINT32 RegEax; + BOOLEAN Page1GSupport; + CPUID_EXTENDED_CPU_SIG_EDX RegEdx; + + if (sizeof (UINTN) == sizeof (UINT64)) { + // + // Check Page5Level Support or not. + // + Cr4.UintN = AsmReadCr4 (); + Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE); + + // + // Check Page1G Support or not. + // + Page1GSupport = FALSE; + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32); + if (RegEdx.Bits.Page1GB != 0) { + Page1GSupport = TRUE; + } + } + + // + // Decide Paging Mode according Page5LevelSupport & Page1GSupport. + // + if (Page5LevelSupport) { + PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level; + } else { + PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level; + } + } else { + PagingMode = PagingPae; + } + + MapAttribute.Uint64 = 0; + MapMask.Uint64 = 0; + MapMask.Bits.Nx = 1; + PageTable = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64; + BufferSize = 0; + + // + // Get required buffer size for changing the pagetable. + // + Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Allocate required Buffer. + // + Status = PeiServicesAllocatePages ( + EfiBootServicesData, + EFI_SIZE_TO_PAGES (BufferSize), + &Buffer + ); + ASSERT_EFI_ERROR (Status); + Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL); + } + + ASSERT_EFI_ERROR (Status); + AsmWriteCr3 (PageTable); +} -- cgit From 525578bdd5ddbf13346c6e5c3a5d04f2efc5a50e Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 14:53:26 +0800 Subject: UefiCpuPkg:Remove code to handle APIC setting and Interrupt Remove ProgramVirtualWireMode()/DisableLvtInterrupts() since APs won't be waken by INIT-SIPI-SIPI in CpuS3.c any more. The two functions has been executed in MpInitLibInitialize() in PeiMplib. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 0bc4a3572d..89223e1726 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -105,11 +105,6 @@ InitializeCpuBeforeRebase ( IN BOOLEAN IsBsp ) { - ProgramVirtualWireMode (); - if (!IsBsp) { - DisableLvtInterrupts (); - } - // // Count down the number with lock mechanism. // -- cgit From 341ee5c31b724f9c505731ddc3d254d875836d63 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 15:10:00 +0800 Subject: UefiCpuPkg:Remove code to wakeup AP and relocate ap After the code to load mtrr setting, set register table, handle APIC setting and Interrupt after INIT-SIPI-SIPI is moved, the InitializeCpuProcedure() only contains following code logic: 1.Bsp runs ExecuteFirstSmiInit(). 2.Bsp transfers AP to safe hlt-loop During S3 boot, since APs will be relocated to new safe buffer by the callback of gEdkiiEndOfS3ResumeGuid in PeiMpLib, Bsp doesn't need to transfer AP to safe hlt-loop any more. SmmRestoreCpu() in CpuS3 only needs to runs the ExecuteFirstSmiInit() on BSP. So remove code to wakeup AP by INIT-SIPI-SIPI and remove code to relocate ap to safe hlt-loop. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 292 +------------------------- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm | 153 -------------- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c | 29 +-- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 5 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm | 189 ----------------- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 30 +-- 6 files changed, 12 insertions(+), 686 deletions(-) delete mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm delete mode 100644 UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 89223e1726..4f69326fdf 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -8,30 +8,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuDxeSmm.h" #include -#include - -#pragma pack(1) -typedef struct { - UINTN Lock; - VOID *StackStart; - UINTN StackSize; - VOID *ApFunction; - IA32_DESCRIPTOR GdtrProfile; - IA32_DESCRIPTOR IdtrProfile; - UINT32 BufferStart; - UINT32 Cr3; - UINTN InitializeFloatingPointUnitsAddress; -} MP_CPU_EXCHANGE_INFO; -#pragma pack() - -typedef struct { - UINT8 *RendezvousFunnelAddress; - UINTN PModeEntryOffset; - UINTN FlatJumpOffset; - UINTN Size; - UINTN LModeEntryOffset; - UINTN LongJumpOffset; -} MP_ASSEMBLY_ADDRESS_MAP; // // Flags used when program the register. @@ -44,31 +20,11 @@ typedef struct { // package level semaphore. } PROGRAM_CPU_REGISTER_FLAGS; -// -// Signal that SMM BASE relocation is complete. -// -volatile BOOLEAN mInitApsAfterSmmBaseReloc; - -/** - Get starting address and size of the rendezvous entry for APs. - Information for fixing a jump instruction in the code is also returned. - - @param AddressMap Output buffer for address map information. -**/ -VOID * -EFIAPI -AsmGetAddressMap ( - MP_ASSEMBLY_ADDRESS_MAP *AddressMap - ); - #define LEGACY_REGION_SIZE (2 * 0x1000) #define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE) -PROGRAM_CPU_REGISTER_FLAGS mCpuFlags; -ACPI_CPU_DATA mAcpiCpuData; -volatile UINT32 mNumberToFinish; -MP_CPU_EXCHANGE_INFO *mExchangeInfo; -BOOLEAN mRestoreSmmConfigurationInS3 = FALSE; +ACPI_CPU_DATA mAcpiCpuData; +BOOLEAN mRestoreSmmConfigurationInS3 = FALSE; // // S3 boot flag @@ -82,191 +38,6 @@ SMM_S3_RESUME_STATE *mSmmS3ResumeState = NULL; BOOLEAN mAcpiS3Enable = TRUE; -UINT8 *mApHltLoopCode = NULL; -UINT8 mApHltLoopCodeTemplate[] = { - 0x8B, 0x44, 0x24, 0x04, // mov eax, dword ptr [esp+4] - 0xF0, 0xFF, 0x08, // lock dec dword ptr [eax] - 0xFA, // cli - 0xF4, // hlt - 0xEB, 0xFC // jmp $-2 -}; - -/** - The function is invoked before SMBASE relocation in S3 path to restores CPU status. - - The function is invoked before SMBASE relocation in S3 path. It does first time microcode load - and restores MTRRs for both BSP and APs. - - @param IsBsp The CPU this function executes on is BSP or not. - -**/ -VOID -InitializeCpuBeforeRebase ( - IN BOOLEAN IsBsp - ) -{ - // - // Count down the number with lock mechanism. - // - InterlockedDecrement (&mNumberToFinish); - - if (IsBsp) { - // - // Bsp wait here till all AP finish the initialization before rebase - // - while (mNumberToFinish > 0) { - CpuPause (); - } - } -} - -/** - The function is invoked after SMBASE relocation in S3 path to restores CPU status. - - The function is invoked after SMBASE relocation in S3 path. It restores configuration according to - data saved by normal boot path for both BSP and APs. - - @param IsBsp The CPU this function executes on is BSP or not. - -**/ -VOID -InitializeCpuAfterRebase ( - IN BOOLEAN IsBsp - ) -{ - UINTN TopOfStack; - UINT8 Stack[128]; - - if (mSmmS3ResumeState->MpService2Ppi == 0) { - if (IsBsp) { - while (mNumberToFinish > 0) { - CpuPause (); - } - } else { - // - // Place AP into the safe code, count down the number with lock mechanism in the safe code. - // - TopOfStack = (UINTN)Stack + sizeof (Stack); - TopOfStack &= ~(UINTN)(CPU_STACK_ALIGNMENT - 1); - CopyMem ((VOID *)(UINTN)mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate)); - TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish); - } - } -} - -/** - Cpu initialization procedure. - - @param[in,out] Buffer The pointer to private data buffer. - -**/ -VOID -EFIAPI -InitializeCpuProcedure ( - IN OUT VOID *Buffer - ) -{ - BOOLEAN IsBsp; - - IsBsp = (BOOLEAN)(mBspApicId == GetApicId ()); - - // - // Skip initialization if mAcpiCpuData is not valid - // - if (mAcpiCpuData.NumberOfCpus > 0) { - // - // First time microcode load and restore MTRRs - // - InitializeCpuBeforeRebase (IsBsp); - } - - if (IsBsp) { - // - // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init. - // - ExecuteFirstSmiInit (); - } - - // - // Skip initialization if mAcpiCpuData is not valid - // - if (mAcpiCpuData.NumberOfCpus > 0) { - if (IsBsp) { - // - // mNumberToFinish should be set before AP executes InitializeCpuAfterRebase() - // - mNumberToFinish = (UINT32)(mNumberOfCpus - 1); - // - // Signal that SMM base relocation is complete and to continue initialization for all APs. - // - mInitApsAfterSmmBaseReloc = TRUE; - } else { - // - // AP Wait for BSP to signal SMM Base relocation done. - // - while (!mInitApsAfterSmmBaseReloc) { - CpuPause (); - } - } - - // - // Restore MSRs for BSP and all APs - // - InitializeCpuAfterRebase (IsBsp); - } -} - -/** - Prepares startup vector for APs. - - This function prepares startup vector for APs. - - @param WorkingBuffer The address of the work buffer. -**/ -VOID -PrepareApStartupVector ( - EFI_PHYSICAL_ADDRESS WorkingBuffer - ) -{ - EFI_PHYSICAL_ADDRESS StartupVector; - MP_ASSEMBLY_ADDRESS_MAP AddressMap; - - // - // Get the address map of startup code for AP, - // including code size, and offset of long jump instructions to redirect. - // - ZeroMem (&AddressMap, sizeof (AddressMap)); - AsmGetAddressMap (&AddressMap); - - StartupVector = WorkingBuffer; - - // - // Copy AP startup code to startup vector, and then redirect the long jump - // instructions for mode switching. - // - CopyMem ((VOID *)(UINTN)StartupVector, AddressMap.RendezvousFunnelAddress, AddressMap.Size); - *(UINT32 *)(UINTN)(StartupVector + AddressMap.FlatJumpOffset + 3) = (UINT32)(StartupVector + AddressMap.PModeEntryOffset); - if (AddressMap.LongJumpOffset != 0) { - *(UINT32 *)(UINTN)(StartupVector + AddressMap.LongJumpOffset + 2) = (UINT32)(StartupVector + AddressMap.LModeEntryOffset); - } - - // - // Get the start address of exchange data between BSP and AP. - // - mExchangeInfo = (MP_CPU_EXCHANGE_INFO *)(UINTN)(StartupVector + AddressMap.Size); - ZeroMem ((VOID *)mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO)); - - CopyMem ((VOID *)(UINTN)&mExchangeInfo->GdtrProfile, (VOID *)(UINTN)mAcpiCpuData.GdtrProfile, sizeof (IA32_DESCRIPTOR)); - CopyMem ((VOID *)(UINTN)&mExchangeInfo->IdtrProfile, (VOID *)(UINTN)mAcpiCpuData.IdtrProfile, sizeof (IA32_DESCRIPTOR)); - - mExchangeInfo->StackStart = (VOID *)(UINTN)mAcpiCpuData.StackAddress; - mExchangeInfo->StackSize = mAcpiCpuData.StackSize; - mExchangeInfo->BufferStart = (UINT32)StartupVector; - mExchangeInfo->Cr3 = (UINT32)(AsmReadCr3 ()); - mExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits; - mExchangeInfo->ApFunction = (VOID *)(UINTN)InitializeCpuProcedure; -} - /** Restore SMM Configuration in S3 boot path. @@ -315,12 +86,11 @@ SmmRestoreCpu ( VOID ) { - SMM_S3_RESUME_STATE *SmmS3ResumeState; - IA32_DESCRIPTOR Ia32Idtr; - IA32_DESCRIPTOR X64Idtr; - IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER]; - EFI_STATUS Status; - EDKII_PEI_MP_SERVICES2_PPI *Mp2ServicePpi; + SMM_S3_RESUME_STATE *SmmS3ResumeState; + IA32_DESCRIPTOR Ia32Idtr; + IA32_DESCRIPTOR X64Idtr; + IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER]; + EFI_STATUS Status; DEBUG ((DEBUG_INFO, "SmmRestoreCpu()\n")); @@ -369,38 +139,10 @@ SmmRestoreCpu ( } } - mBspApicId = GetApicId (); // - // Skip AP initialization if mAcpiCpuData is not valid + // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init. // - if (mAcpiCpuData.NumberOfCpus > 0) { - if (FeaturePcdGet (PcdCpuHotPlugSupport)) { - ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus); - } else { - ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus); - } - - mNumberToFinish = (UINT32)mNumberOfCpus; - - // - // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots. - // - mInitApsAfterSmmBaseReloc = FALSE; - - if (mSmmS3ResumeState->MpService2Ppi != 0) { - Mp2ServicePpi = (EDKII_PEI_MP_SERVICES2_PPI *)(UINTN)mSmmS3ResumeState->MpService2Ppi; - Mp2ServicePpi->StartupAllCPUs (Mp2ServicePpi, InitializeCpuProcedure, 0, NULL); - } else { - PrepareApStartupVector (mAcpiCpuData.StartupVector); - // - // Send INIT IPI - SIPI to all APs - // - SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector); - InitializeCpuProcedure (NULL); - } - } else { - InitializeCpuProcedure (NULL); - } + ExecuteFirstSmiInit (); // // Set a flag to restore SMM configuration in S3 path. @@ -471,8 +213,6 @@ InitSmmS3ResumeState ( VOID *GuidHob; EFI_SMRAM_DESCRIPTOR *SmramDescriptor; SMM_S3_RESUME_STATE *SmmS3ResumeState; - EFI_PHYSICAL_ADDRESS Address; - EFI_STATUS Status; if (!mAcpiS3Enable) { return; @@ -524,20 +264,6 @@ InitSmmS3ResumeState ( // InitSmmS3Cr3 (); } - - // - // Allocate safe memory in ACPI NVS for AP to execute hlt loop in - // protected mode on S3 path - // - Address = BASE_4GB - 1; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiACPIMemoryNVS, - EFI_SIZE_TO_PAGES (sizeof (mApHltLoopCodeTemplate)), - &Address - ); - ASSERT_EFI_ERROR (Status); - mApHltLoopCode = (UINT8 *)(UINTN)Address; } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm deleted file mode 100644 index dbd1418c0d..0000000000 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm +++ /dev/null @@ -1,153 +0,0 @@ -;------------------------------------------------------------------------------ ; -; Copyright (c) 2016, Intel Corporation. All rights reserved.
-; SPDX-License-Identifier: BSD-2-Clause-Patent -; -; Module Name: -; -; MpFuncs.nasm -; -; Abstract: -; -; This is the assembly code for Multi-processor S3 support -; -;------------------------------------------------------------------------------- - -SECTION .text - -extern ASM_PFX(InitializeFloatingPointUnits) - -%define VacantFlag 0x0 -%define NotVacantFlag 0xff - -%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart -%define StackStart LockLocation + 0x4 -%define StackSize LockLocation + 0x8 -%define RendezvousProc LockLocation + 0xC -%define GdtrProfile LockLocation + 0x10 -%define IdtrProfile LockLocation + 0x16 -%define BufferStart LockLocation + 0x1C - -;------------------------------------------------------------------------------------- -;RendezvousFunnelProc procedure follows. All APs execute their procedure. This -;procedure serializes all the AP processors through an Init sequence. It must be -;noted that APs arrive here very raw...ie: real mode, no stack. -;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC -;IS IN MACHINE CODE. -;------------------------------------------------------------------------------------- -;RendezvousFunnelProc (&WakeUpBuffer,MemAddress); - -BITS 16 -global ASM_PFX(RendezvousFunnelProc) -ASM_PFX(RendezvousFunnelProc): -RendezvousFunnelProcStart: - -; At this point CS = 0x(vv00) and ip= 0x0. - - mov ax, cs - mov ds, ax - mov es, ax - mov ss, ax - xor ax, ax - mov fs, ax - mov gs, ax - -flat32Start: - - mov si, BufferStart - mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer - - mov si, GdtrProfile -o32 lgdt [cs:si] - - mov si, IdtrProfile -o32 lidt [cs:si] - - xor ax, ax - mov ds, ax - - mov eax, cr0 ; Get control register 0 - or eax, 0x000000001 ; Set PE bit (bit #0) - mov cr0, eax - -FLAT32_JUMP: - -a32 jmp dword 0x20:0x0 - -BITS 32 -PMODE_ENTRY: ; protected mode entry point - - mov ax, 0x8 -o16 mov ds, ax -o16 mov es, ax -o16 mov fs, ax -o16 mov gs, ax -o16 mov ss, ax ; Flat mode setup. - - mov esi, edx - - mov edi, esi - add edi, LockLocation - mov al, NotVacantFlag -TestLock: - xchg byte [edi], al - cmp al, NotVacantFlag - jz TestLock - -ProgramStack: - - mov edi, esi - add edi, StackSize - mov eax, dword [edi] - mov edi, esi - add edi, StackStart - add eax, dword [edi] - mov esp, eax - mov dword [edi], eax - -Releaselock: - - mov al, VacantFlag - mov edi, esi - add edi, LockLocation - xchg byte [edi], al - - ; - ; Call assembly function to initialize FPU. - ; - mov ebx, ASM_PFX(InitializeFloatingPointUnits) - call ebx - ; - ; Call C Function - ; - mov edi, esi - add edi, RendezvousProc - mov eax, dword [edi] - - test eax, eax - jz GoToSleep - call eax ; Call C function - -GoToSleep: - cli - hlt - jmp $-2 - -RendezvousFunnelProcEnd: -;------------------------------------------------------------------------------------- -; AsmGetAddressMap (&AddressMap); -;------------------------------------------------------------------------------------- -global ASM_PFX(AsmGetAddressMap) -ASM_PFX(AsmGetAddressMap): - - pushad - mov ebp,esp - - mov ebx, dword [ebp+0x24] - mov dword [ebx], RendezvousFunnelProcStart - mov dword [ebx+0x4], PMODE_ENTRY - RendezvousFunnelProcStart - mov dword [ebx+0x8], FLAT32_JUMP - RendezvousFunnelProcStart - mov dword [ebx+0xc], RendezvousFunnelProcEnd - RendezvousFunnelProcStart - - popad - ret - diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c index 636dc8d92f..0c1cc51ada 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c @@ -1,7 +1,7 @@ /** @file SMM CPU misc functions for Ia32 arch specific. -Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -141,33 +141,6 @@ InitGdt ( return GdtTssTables; } -/** - Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. - - @param[in] ApHltLoopCode The address of the safe hlt-loop function. - @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. - @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. - -**/ -VOID -TransferApToSafeState ( - IN UINTN ApHltLoopCode, - IN UINTN TopOfStack, - IN UINTN NumberToFinishAddress - ) -{ - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)ApHltLoopCode, - (VOID *)NumberToFinishAddress, - NULL, - (VOID *)TopOfStack - ); - // - // It should never reach here - // - ASSERT (FALSE); -} - /** Initialize the shadow stack related data structure. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 3354f94a64..f0598b0364 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -4,7 +4,7 @@ # This SMM driver performs SMM initialization, deploy SMM Entry Vector, # provides CPU specific services in SMM. # -# Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2017, AMD Incorporated. All rights reserved.
# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
# @@ -53,7 +53,6 @@ Ia32/SmmProfileArch.h Ia32/SmiEntry.nasm Ia32/SmiException.nasm - Ia32/MpFuncs.nasm Ia32/Cet.nasm [Sources.X64] @@ -63,7 +62,6 @@ X64/SmmProfileArch.h X64/SmiEntry.nasm X64/SmiException.nasm - X64/MpFuncs.nasm X64/Cet.nasm [Packages] @@ -136,7 +134,6 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm deleted file mode 100644 index a12538f72b..0000000000 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm +++ /dev/null @@ -1,189 +0,0 @@ -;------------------------------------------------------------------------------ ; -; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
-; SPDX-License-Identifier: BSD-2-Clause-Patent -; -; Module Name: -; -; MpFuncs.nasm -; -; Abstract: -; -; This is the assembly code for Multi-processor S3 support -; -;------------------------------------------------------------------------------- - -%define VacantFlag 0x0 -%define NotVacantFlag 0xff - -%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart -%define StackStartAddressLocation LockLocation + 0x8 -%define StackSizeLocation LockLocation + 0x10 -%define CProcedureLocation LockLocation + 0x18 -%define GdtrLocation LockLocation + 0x20 -%define IdtrLocation LockLocation + 0x2A -%define BufferStartLocation LockLocation + 0x34 -%define Cr3OffsetLocation LockLocation + 0x38 -%define InitializeFloatingPointUnitsAddress LockLocation + 0x3C - -;------------------------------------------------------------------------------------- -;RendezvousFunnelProc procedure follows. All APs execute their procedure. This -;procedure serializes all the AP processors through an Init sequence. It must be -;noted that APs arrive here very raw...ie: real mode, no stack. -;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC -;IS IN MACHINE CODE. -;------------------------------------------------------------------------------------- -;RendezvousFunnelProc (&WakeUpBuffer,MemAddress); - -;text SEGMENT -DEFAULT REL -SECTION .text - -BITS 16 -global ASM_PFX(RendezvousFunnelProc) -ASM_PFX(RendezvousFunnelProc): -RendezvousFunnelProcStart: - -; At this point CS = 0x(vv00) and ip= 0x0. - - mov ax, cs - mov ds, ax - mov es, ax - mov ss, ax - xor ax, ax - mov fs, ax - mov gs, ax - -flat32Start: - - mov si, BufferStartLocation - mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer - - mov si, Cr3OffsetLocation - mov ecx,dword [si] ; ECX is keeping the value of CR3 - - mov si, GdtrLocation -o32 lgdt [cs:si] - - mov si, IdtrLocation -o32 lidt [cs:si] - - xor ax, ax - mov ds, ax - - mov eax, cr0 ; Get control register 0 - or eax, 0x000000001 ; Set PE bit (bit #0) - mov cr0, eax - -FLAT32_JUMP: - -a32 jmp dword 0x20:0x0 - -BITS 32 -PMODE_ENTRY: ; protected mode entry point - - mov ax, 0x18 -o16 mov ds, ax -o16 mov es, ax -o16 mov fs, ax -o16 mov gs, ax -o16 mov ss, ax ; Flat mode setup. - - mov eax, cr4 - bts eax, 5 - mov cr4, eax - - mov cr3, ecx - - mov esi, edx ; Save wakeup buffer address - - mov ecx, 0xc0000080 ; EFER MSR number. - rdmsr ; Read EFER. - bts eax, 8 ; Set LME=1. - wrmsr ; Write EFER. - - mov eax, cr0 ; Read CR0. - bts eax, 31 ; Set PG=1. - mov cr0, eax ; Write CR0. - -LONG_JUMP: - -a16 jmp dword 0x38:0x0 - -BITS 64 -LongModeStart: - - mov ax, 0x30 -o16 mov ds, ax -o16 mov es, ax -o16 mov ss, ax - - mov edi, esi - add edi, LockLocation - mov al, NotVacantFlag -TestLock: - xchg byte [edi], al - cmp al, NotVacantFlag - jz TestLock - -ProgramStack: - - mov edi, esi - add edi, StackSizeLocation - mov rax, qword [edi] - mov edi, esi - add edi, StackStartAddressLocation - add rax, qword [edi] - mov rsp, rax - mov qword [edi], rax - -Releaselock: - - mov al, VacantFlag - mov edi, esi - add edi, LockLocation - xchg byte [edi], al - - ; - ; Call assembly function to initialize FPU. - ; - mov rax, qword [esi + InitializeFloatingPointUnitsAddress] - sub rsp, 0x20 - call rax - add rsp, 0x20 - - ; - ; Call C Function - ; - mov edi, esi - add edi, CProcedureLocation - mov rax, qword [edi] - - test rax, rax - jz GoToSleep - - sub rsp, 0x20 - call rax - add rsp, 0x20 - -GoToSleep: - cli - hlt - jmp $-2 - -RendezvousFunnelProcEnd: - -;------------------------------------------------------------------------------------- -; AsmGetAddressMap (&AddressMap); -;------------------------------------------------------------------------------------- -; comments here for definition of address map -global ASM_PFX(AsmGetAddressMap) -ASM_PFX(AsmGetAddressMap): - lea rax, [RendezvousFunnelProcStart] - mov qword [rcx], rax - mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart - mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart - mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart - mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart - mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart - ret - diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c index c4f21e2155..ca706ee32c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c @@ -1,7 +1,7 @@ /** @file SMM CPU misc functions for x64 arch specific. -Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -132,34 +132,6 @@ GetProtectedModeCS ( return Index * 8; } -/** - Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. - - @param[in] ApHltLoopCode The address of the safe hlt-loop function. - @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. - @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. - -**/ -VOID -TransferApToSafeState ( - IN UINTN ApHltLoopCode, - IN UINTN TopOfStack, - IN UINTN NumberToFinishAddress - ) -{ - AsmDisablePaging64 ( - GetProtectedModeCS (), - (UINT32)ApHltLoopCode, - (UINT32)NumberToFinishAddress, - 0, - (UINT32)TopOfStack - ); - // - // It should never reach here - // - ASSERT (FALSE); -} - /** Initialize the shadow stack related data structure. -- cgit From d390b163f806e3c369ce7b51007916252c5fb5de Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 6 May 2024 13:39:16 +0800 Subject: UefiCpuPkg: Remove unneeded MpService2Ppi assignment Remove the unneeded assignment of MpService2Ppi field in SmmS3ResumeState. Previously, when the execution combination of PEI and DXE are the same, the pointer of mpservice ppi will be passed to CpuS3.c in smm cpu driver to wakeup all APs, instead of init-sipi-sipi. Currently, CpuS3.c doesn't need to wakeup Aps anymore. So remove the duplicated mpservice locate and assignment to MpService2Ppi field in SmmS3ResumeState. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c index e6dfa09c71..3e64a115bf 100644 --- a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c @@ -1152,7 +1152,6 @@ S3RestoreConfig2 ( SmmS3ResumeState->ReturnContext1 = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context; SmmS3ResumeState->ReturnContext2 = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable; SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status); - SmmS3ResumeState->MpService2Ppi = 0; DEBUG ((DEBUG_INFO, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature)); DEBUG ((DEBUG_INFO, "SMM S3 Stack Base = %x\n", SmmS3ResumeState->SmmS3StackBase)); @@ -1181,19 +1180,6 @@ S3RestoreConfig2 ( if (((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) && (sizeof (UINTN) == sizeof (UINT32))) || ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) && (sizeof (UINTN) == sizeof (UINT64)))) { - // - // Get MP Services2 Ppi to pass it to Smm S3. - // - Status = PeiServicesLocatePpi ( - &gEdkiiPeiMpServices2PpiGuid, - 0, - NULL, - (VOID **)&MpService2Ppi - ); - ASSERT_EFI_ERROR (Status); - SmmS3ResumeState->MpService2Ppi = (EFI_PHYSICAL_ADDRESS)(UINTN)MpService2Ppi; - DEBUG ((DEBUG_INFO, "SMM S3 MpService2Ppi Point = %lx\n", SmmS3ResumeState->MpService2Ppi)); - SwitchStack ( (SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->SmmS3ResumeEntryPoint, (VOID *)AcpiS3Context, -- cgit From e3b3e907e178da7ced228d21f99af843d7fb9291 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 23 Apr 2024 11:33:39 +0800 Subject: MdeModulePkg:Remove MpService2Ppi field in SMM_S3_RESUME_STATE This MpService2Ppi field in SMM_S3_RESUME_STATE is used to wakeup AP to do the CPU initialization during smm s3 boot when the execution mode of PEI and DXE are the same. Currently, in CpuS3.c of smm cpu driver, BSP doesn't need to wakeup AP anymore. The initialization for AP will be done in S3Resume.c before transfer to CpuS3.c of smm cpu driver. So we can remove the MpService2Ppi field in SMM_S3_RESUME_STATE. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Jian J Wang Reviewed-by: Liming Gao --- MdeModulePkg/Include/Guid/AcpiS3Context.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MdeModulePkg/Include/Guid/AcpiS3Context.h b/MdeModulePkg/Include/Guid/AcpiS3Context.h index 72d173c4fd..6c7237727e 100644 --- a/MdeModulePkg/Include/Guid/AcpiS3Context.h +++ b/MdeModulePkg/Include/Guid/AcpiS3Context.h @@ -1,7 +1,7 @@ /** @file Definitions for data structures used in S3 resume. -Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -30,7 +30,6 @@ typedef struct { EFI_PHYSICAL_ADDRESS ReturnContext1; EFI_PHYSICAL_ADDRESS ReturnContext2; EFI_PHYSICAL_ADDRESS ReturnStackPointer; - EFI_PHYSICAL_ADDRESS MpService2Ppi; EFI_PHYSICAL_ADDRESS Smst; } SMM_S3_RESUME_STATE; -- cgit From 077760fec40c2e5fcae274cc609d97aee12e5d56 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 10 May 2024 15:15:27 +0800 Subject: UefiCpuPkg: Remove GetAcpiCpuData() in CpuS3.c Remove GetAcpiCpuData() in CpuS3.c. The mAcpiCpuData is not needed in S3 boot anymore. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 243 +---------------------------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 8 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 26 +-- 3 files changed, 5 insertions(+), 272 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 4f69326fdf..c37a2d4d1b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -9,22 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuDxeSmm.h" #include -// -// Flags used when program the register. -// -typedef struct { - volatile UINTN MemoryMappedLock; // Spinlock used to program mmio - volatile UINT32 *CoreSemaphoreCount; // Semaphore container used to program - // core level semaphore. - volatile UINT32 *PackageSemaphoreCount; // Semaphore container used to program - // package level semaphore. -} PROGRAM_CPU_REGISTER_FLAGS; - -#define LEGACY_REGION_SIZE (2 * 0x1000) -#define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE) - -ACPI_CPU_DATA mAcpiCpuData; -BOOLEAN mRestoreSmmConfigurationInS3 = FALSE; +BOOLEAN mRestoreSmmConfigurationInS3 = FALSE; // // S3 boot flag @@ -266,232 +251,6 @@ InitSmmS3ResumeState ( } } -/** - Copy register table from non-SMRAM into SMRAM. - - @param[in] DestinationRegisterTableList Points to destination register table. - @param[in] SourceRegisterTableList Points to source register table. - @param[in] NumberOfCpus Number of CPUs. - -**/ -VOID -CopyRegisterTable ( - IN CPU_REGISTER_TABLE *DestinationRegisterTableList, - IN CPU_REGISTER_TABLE *SourceRegisterTableList, - IN UINT32 NumberOfCpus - ) -{ - UINTN Index; - CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; - - CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); - for (Index = 0; Index < NumberOfCpus; Index++) { - if (DestinationRegisterTableList[Index].TableLength != 0) { - DestinationRegisterTableList[Index].AllocatedSize = DestinationRegisterTableList[Index].TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY); - RegisterTableEntry = AllocateCopyPool ( - DestinationRegisterTableList[Index].AllocatedSize, - (VOID *)(UINTN)SourceRegisterTableList[Index].RegisterTableEntry - ); - ASSERT (RegisterTableEntry != NULL); - DestinationRegisterTableList[Index].RegisterTableEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTableEntry; - } - } -} - -/** - Check whether the register table is empty or not. - - @param[in] RegisterTable Point to the register table. - @param[in] NumberOfCpus Number of CPUs. - - @retval TRUE The register table is empty. - @retval FALSE The register table is not empty. -**/ -BOOLEAN -IsRegisterTableEmpty ( - IN CPU_REGISTER_TABLE *RegisterTable, - IN UINT32 NumberOfCpus - ) -{ - UINTN Index; - - if (RegisterTable != NULL) { - for (Index = 0; Index < NumberOfCpus; Index++) { - if (RegisterTable[Index].TableLength != 0) { - return FALSE; - } - } - } - - return TRUE; -} - -/** - Copy the data used to initialize processor register into SMRAM. - - @param[in,out] CpuFeatureInitDataDst Pointer to the destination CPU_FEATURE_INIT_DATA structure. - @param[in] CpuFeatureInitDataSrc Pointer to the source CPU_FEATURE_INIT_DATA structure. - -**/ -VOID -CopyCpuFeatureInitDatatoSmram ( - IN OUT CPU_FEATURE_INIT_DATA *CpuFeatureInitDataDst, - IN CPU_FEATURE_INIT_DATA *CpuFeatureInitDataSrc - ) -{ - CPU_STATUS_INFORMATION *CpuStatus; - - if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus)) { - CpuFeatureInitDataDst->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); - ASSERT (CpuFeatureInitDataDst->PreSmmInitRegisterTable != 0); - - CopyRegisterTable ( - (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataDst->PreSmmInitRegisterTable, - (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->PreSmmInitRegisterTable, - mAcpiCpuData.NumberOfCpus - ); - } - - if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->RegisterTable, mAcpiCpuData.NumberOfCpus)) { - CpuFeatureInitDataDst->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); - ASSERT (CpuFeatureInitDataDst->RegisterTable != 0); - - CopyRegisterTable ( - (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataDst->RegisterTable, - (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->RegisterTable, - mAcpiCpuData.NumberOfCpus - ); - } - - CpuStatus = &CpuFeatureInitDataDst->CpuStatus; - CopyMem (CpuStatus, &CpuFeatureInitDataSrc->CpuStatus, sizeof (CPU_STATUS_INFORMATION)); - - if (CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerPackage != 0) { - CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool ( - sizeof (UINT32) * CpuStatus->PackageCount, - (UINT32 *)(UINTN)CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerPackage - ); - ASSERT (CpuStatus->ThreadCountPerPackage != 0); - } - - if (CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerCore != 0) { - CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool ( - sizeof (UINT8) * (CpuStatus->PackageCount * CpuStatus->MaxCoreCount), - (UINT32 *)(UINTN)CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerCore - ); - ASSERT (CpuStatus->ThreadCountPerCore != 0); - } - - if (CpuFeatureInitDataSrc->ApLocation != 0) { - CpuFeatureInitDataDst->ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool ( - mAcpiCpuData.NumberOfCpus * sizeof (EFI_CPU_PHYSICAL_LOCATION), - (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)CpuFeatureInitDataSrc->ApLocation - ); - ASSERT (CpuFeatureInitDataDst->ApLocation != 0); - } -} - -/** - Get ACPI CPU data. - -**/ -VOID -GetAcpiCpuData ( - VOID - ) -{ - ACPI_CPU_DATA *AcpiCpuData; - IA32_DESCRIPTOR *Gdtr; - IA32_DESCRIPTOR *Idtr; - VOID *GdtForAp; - VOID *IdtForAp; - VOID *MachineCheckHandlerForAp; - CPU_STATUS_INFORMATION *CpuStatus; - - if (!mAcpiS3Enable) { - return; - } - - // - // Prevent use of mAcpiCpuData by initialize NumberOfCpus to 0 - // - mAcpiCpuData.NumberOfCpus = 0; - - // - // If PcdCpuS3DataAddress was never set, then do not copy CPU S3 Data into SMRAM - // - AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress); - if (AcpiCpuData == 0) { - return; - } - - // - // For a native platform, copy the CPU S3 data into SMRAM for use on CPU S3 Resume. - // - CopyMem (&mAcpiCpuData, AcpiCpuData, sizeof (mAcpiCpuData)); - - mAcpiCpuData.MtrrTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (MTRR_SETTINGS)); - ASSERT (mAcpiCpuData.MtrrTable != 0); - - CopyMem ((VOID *)(UINTN)mAcpiCpuData.MtrrTable, (VOID *)(UINTN)AcpiCpuData->MtrrTable, sizeof (MTRR_SETTINGS)); - - mAcpiCpuData.GdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR)); - ASSERT (mAcpiCpuData.GdtrProfile != 0); - - CopyMem ((VOID *)(UINTN)mAcpiCpuData.GdtrProfile, (VOID *)(UINTN)AcpiCpuData->GdtrProfile, sizeof (IA32_DESCRIPTOR)); - - mAcpiCpuData.IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR)); - ASSERT (mAcpiCpuData.IdtrProfile != 0); - - CopyMem ((VOID *)(UINTN)mAcpiCpuData.IdtrProfile, (VOID *)(UINTN)AcpiCpuData->IdtrProfile, sizeof (IA32_DESCRIPTOR)); - - // - // Copy AP's GDT, IDT and Machine Check handler into SMRAM. - // - Gdtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.GdtrProfile; - Idtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.IdtrProfile; - - GdtForAp = AllocatePool ((Gdtr->Limit + 1) + (Idtr->Limit + 1) + mAcpiCpuData.ApMachineCheckHandlerSize); - ASSERT (GdtForAp != NULL); - IdtForAp = (VOID *)((UINTN)GdtForAp + (Gdtr->Limit + 1)); - MachineCheckHandlerForAp = (VOID *)((UINTN)IdtForAp + (Idtr->Limit + 1)); - - CopyMem (GdtForAp, (VOID *)Gdtr->Base, Gdtr->Limit + 1); - CopyMem (IdtForAp, (VOID *)Idtr->Base, Idtr->Limit + 1); - CopyMem (MachineCheckHandlerForAp, (VOID *)(UINTN)mAcpiCpuData.ApMachineCheckHandlerBase, mAcpiCpuData.ApMachineCheckHandlerSize); - - Gdtr->Base = (UINTN)GdtForAp; - Idtr->Base = (UINTN)IdtForAp; - mAcpiCpuData.ApMachineCheckHandlerBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MachineCheckHandlerForAp; - - ZeroMem (&mAcpiCpuData.CpuFeatureInitData, sizeof (CPU_FEATURE_INIT_DATA)); - - if (!PcdGetBool (PcdCpuFeaturesInitOnS3Resume)) { - // - // If the CPU features will not be initialized by CpuFeaturesPei module during - // next ACPI S3 resume, copy the CPU features initialization data into SMRAM, - // which will be consumed in SmmRestoreCpu during next S3 resume. - // - CopyCpuFeatureInitDatatoSmram (&mAcpiCpuData.CpuFeatureInitData, &AcpiCpuData->CpuFeatureInitData); - - CpuStatus = &mAcpiCpuData.CpuFeatureInitData.CpuStatus; - - mCpuFlags.CoreSemaphoreCount = AllocateZeroPool ( - sizeof (UINT32) * CpuStatus->PackageCount * - CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount - ); - ASSERT (mCpuFlags.CoreSemaphoreCount != NULL); - - mCpuFlags.PackageSemaphoreCount = AllocateZeroPool ( - sizeof (UINT32) * CpuStatus->PackageCount * - CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount - ); - ASSERT (mCpuFlags.PackageSemaphoreCount != NULL); - - InitializeSpinLock ((SPIN_LOCK *)&mCpuFlags.MemoryMappedLock); - } -} - /** Get ACPI S3 enable flag. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index e400bee8d5..20a1a9cdbc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -1,7 +1,7 @@ /** @file Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
@@ -435,8 +435,8 @@ ExecuteFirstSmiInit ( /** SMM Ready To Lock event notification handler. - The CPU S3 data is copied to SMRAM for security and mSmmReadyToLock is set to - perform additional lock actions that must be performed from SMM on the next SMI. + mSmmReadyToLock is set to perform additional lock actions that must be + performed from SMM on the next SMI. @param[in] Protocol Points to the protocol's unique identifier. @param[in] Interface Points to the interface instance. @@ -452,8 +452,6 @@ SmmReadyToLockEventNotify ( IN EFI_HANDLE Handle ) { - GetAcpiCpuData (); - // // Cache a copy of UEFI memory map before we start profiling feature. // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index f42910ddf1..315a33d578 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -1,7 +1,7 @@ /** @file Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
@@ -1048,15 +1048,6 @@ InitSmmS3ResumeState ( IN UINT32 Cr3 ); -/** - Get ACPI CPU data. - -**/ -VOID -GetAcpiCpuData ( - VOID - ); - /** Restore SMM Configuration in S3 boot path. @@ -1075,21 +1066,6 @@ GetAcpiS3EnableFlag ( VOID ); -/** - Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. - - @param[in] ApHltLoopCode The address of the safe hlt-loop function. - @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. - @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. - -**/ -VOID -TransferApToSafeState ( - IN UINTN ApHltLoopCode, - IN UINTN TopOfStack, - IN UINTN NumberToFinishAddress - ); - /** Set ShadowStack memory. -- cgit From 839bd179735284592ba8f0879d2cbf07e0cb585a Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 7 May 2024 17:00:56 +0800 Subject: UefiCpuPkg:fix issue when splitting paging entry This patch is to fix issue when splitting leaf paging entry in CpuPageTableLib code. In previous code, before we assign the new child paging structure address to the content of splitted paging entry, PageTableLibSetPnle() is called to make sure the bit7 is set to 0, which indicate the previous leaf entry is changed to non-leaf entry now. There is a gap between we change the bit7 and we assign the new child paging structure address to the content of the splitted paging entry. If the address of code execution or data access happens to be in the range covered by the splitted paging entry, this gap may cause issue. In this patch, we prepare the new paging entry content value in a local variable and assign the value to the splitted paging entry at once. The volatile keyword is used to ensure that no optimization will occur in compilation. Signed-off-by: Dun Tan Reviewed-by: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Reviewed-by: Jiaxin Wu Cc: Zhou Jianfeng --- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c index b10a3008e4..bdc411338f 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -342,6 +342,7 @@ PageTableLibMapInLevel ( UINT64 PhysicalAddrInAttr; IA32_PAGING_ENTRY OriginalParentPagingEntry; IA32_PAGING_ENTRY OriginalCurrentPagingEntry; + IA32_PAGING_ENTRY TempPagingEntry; ASSERT (Level != 0); ASSERT ((Attribute != NULL) && (Mask != NULL)); @@ -359,6 +360,8 @@ PageTableLibMapInLevel ( OriginalParentPagingEntry.Uint64 = ParentPagingEntry->Uint64; OneOfPagingEntry.Uint64 = 0; + TempPagingEntry.Uint64 = 0; + // // RegionLength: 256T (1 << 48) 512G (1 << 39), 1G (1 << 30), 2M (1 << 21) or 4K (1 << 12). // @@ -441,8 +444,10 @@ PageTableLibMapInLevel ( // Non-leaf entry doesn't have PAT bit. So use ~IA32_PE_BASE_ADDRESS_MASK_40 is to make sure PAT bit // (bit12) in original big-leaf entry is not assigned to PageTableBaseAddress field of non-leaf entry. // - PageTableLibSetPnle (&ParentPagingEntry->Pnle, &NopAttribute, &AllOneMask); - ParentPagingEntry->Uint64 = ((UINTN)(VOID *)PagingEntry) | (ParentPagingEntry->Uint64 & (~IA32_PE_BASE_ADDRESS_MASK_40)); + TempPagingEntry.Uint64 = ParentPagingEntry->Uint64; + PageTableLibSetPnle (&TempPagingEntry.Pnle, &NopAttribute, &AllOneMask); + TempPagingEntry.Uint64 = ((UINTN)(VOID *)PagingEntry) | (TempPagingEntry.Uint64 & (~IA32_PE_BASE_ADDRESS_MASK_40)); + *(volatile UINT64 *)&(ParentPagingEntry->Uint64) = TempPagingEntry.Uint64; } } else { // -- cgit From de4cc40b8c1d9044df82e077e72ef6e192ea12e2 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 3 Jun 2024 10:00:40 +0200 Subject: MdeModulePkg/HiiDatabaseDxe: Avoid struct assignment Struct assignments are not permitted in EDK2, as they may be converted by the compiler into calls to the 'memcpy' intrinsic, which is not guaranteed to be available in EDK2. So replace the assignment with a call to CopyMem (), and -while at it- replace the loop with a single CopyMem () call, as the loop operates on items that are contiguous in memory. Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Universal/HiiDatabaseDxe/Image.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c index b5b9625969..ab8f056914 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c @@ -1288,7 +1288,6 @@ HiiDrawImage ( UINTN BufferLen; UINT16 Width; UINT16 Height; - UINTN Xpos; UINTN Ypos; UINTN OffsetY1; UINTN OffsetY2; @@ -1390,9 +1389,11 @@ HiiDrawImage ( for (Ypos = 0; Ypos < Height; Ypos++) { OffsetY1 = Image->Width * Ypos; OffsetY2 = Width * Ypos; - for (Xpos = 0; Xpos < Width; Xpos++) { - BltBuffer[OffsetY2 + Xpos] = Image->Bitmap[OffsetY1 + Xpos]; - } + CopyMem ( + &BltBuffer[OffsetY2], + &Image->Bitmap[OffsetY1], + Width * sizeof (*BltBuffer) + ); } } -- cgit From cac1ea6c2a6eac1772556e718154a00fcb093b88 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Mon, 6 May 2024 11:13:41 +0800 Subject: OvmfPkg: Add no hardcode version of FdtNorFlashQemuLib This library is copied from ArmVirtPkg, in the Arm version, the value of PcdFlashNvStorageVariableBase, PcdFlashNvStorageFtwWorkingBase and PcdFlashNvStorageFtwSpareBase are hardcoded in INC file. This version will calculate them from FDT resource and using the set PCD to store when the NorFlashInitialise is called. By default, the first available flash(not used for storage UEFI code) as NV variable storage medium. In this way, UEFI can better handle the change of flash base address, which is suitable for different cpu architecture board implementation. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770 Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Sami Mujawar Cc: Gerd Hoffmann Cc: Jiewen Yao Signed-off-by: Chao Li Co-authored-by: Xianglai Li Tested-by: Gerd Hoffmann Acked-by: Gerd Hoffmann --- .../FdtNorFlashQemuLib/FdtNorFlashQemuLib.c | 165 +++++++++++++++++++++ .../FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf | 46 ++++++ 2 files changed, 211 insertions(+) create mode 100644 OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c create mode 100644 OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf diff --git a/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c new file mode 100644 index 0000000000..e5c7d4cdfa --- /dev/null +++ b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c @@ -0,0 +1,165 @@ +/** @file + + Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +#include +#include + +#define QEMU_NOR_BLOCK_SIZE SIZE_256KB +#define MAX_FLASH_BANKS 4 + +STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS]; + +EFI_STATUS +VirtNorFlashPlatformInitialization ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +VirtNorFlashPlatformGetDevices ( + OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions, + OUT UINT32 *Count + ) +{ + FDT_CLIENT_PROTOCOL *FdtClient; + INT32 Node; + EFI_STATUS Status; + EFI_STATUS FindNodeStatus; + CONST UINT32 *Reg; + UINT32 PropSize; + UINT32 Num; + UINT64 Base; + UINT64 Size; + BOOLEAN Found; + + Status = gBS->LocateProtocol ( + &gFdtClientProtocolGuid, + NULL, + (VOID **)&FdtClient + ); + ASSERT_EFI_ERROR (Status); + + Num = 0; + Found = FALSE; + for (FindNodeStatus = FdtClient->FindCompatibleNode ( + FdtClient, + "cfi-flash", + &Node + ); + !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS; + FindNodeStatus = FdtClient->FindNextCompatibleNode ( + FdtClient, + "cfi-flash", + Node, + &Node + )) + { + Status = FdtClient->GetNodeProperty ( + FdtClient, + Node, + "reg", + (CONST VOID **)&Reg, + &PropSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: GetNodeProperty () failed (Status == %r)\n", + __func__, + Status + )); + continue; + } + + ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0); + + while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) { + Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0])); + Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2])); + Reg += 4; + + PropSize -= 4 * sizeof (UINT32); + + // + // Disregard any flash devices that overlap with the primary FV. + // The firmware is not updatable from inside the guest anyway. + // + if ((PcdGet32 (PcdOvmfFdBaseAddress) + PcdGet32 (PcdOvmfFirmwareFdSize) > Base) && + ((Base + Size) > PcdGet32 (PcdOvmfFdBaseAddress))) + { + continue; + } + + mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base; + mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base; + mNorFlashDevices[Num].Size = (UINTN)Size; + mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE; + Num++; + if (!Found) { + // + // By default, the second available flash is stored as a non-volatile variable. + // + Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base); + ASSERT_EFI_ERROR (Status); + + // + // The Base is the value of PcdFlashNvStorageVariableBase, + // PcdFlashNvStorageFtwWorkingBase can be got by + // PcdFlashNvStorageVariableBase + PcdFlashNvStorageVariableSize + // + Base += PcdGet32 (PcdFlashNvStorageVariableSize); + Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, Base); + ASSERT_EFI_ERROR (Status); + + // + // Now, the Base is the value of PcdFlashNvStorageFtwWorkingBase, + // PcdFlashNvStorageFtwSpareBase can be got by + // PcdFlashNvStorageFtwWorkingBase + PcdFlashNvStorageFtwWorkingSize. + // + Base += PcdGet32 (PcdFlashNvStorageFtwWorkingSize); + Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base); + ASSERT_EFI_ERROR (Status); + Found = TRUE; + } + } + + // + // UEFI takes ownership of the NOR flash, and exposes its functionality + // through the UEFI Runtime Services GetVariable, SetVariable, etc. This + // means we need to disable it in the device tree to prevent the OS from + // attaching its device driver as well. + // Note that this also hides other flash banks, but the only other flash + // bank we expect to encounter is the one that carries the UEFI executable + // code, which is not intended to be guest updatable, and is usually backed + // in a readonly manner by QEMU anyway. + // + Status = FdtClient->SetNodeProperty ( + FdtClient, + Node, + "status", + "disabled", + sizeof ("disabled") + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n")); + } + } + + *NorFlashDescriptions = mNorFlashDevices; + *Count = Num; + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf new file mode 100644 index 0000000000..14ddb4c11e --- /dev/null +++ b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf @@ -0,0 +1,46 @@ +## @file +# +# Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = NorFlashQemuLib + FILE_GUID = E225C90F-6CB9-8AF3-095B-2668FC633A57 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NorFlashQemuLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION + +[Sources] + FdtNorFlashQemuLib.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UefiBootServicesTableLib + +[Protocols] + gFdtClientProtocolGuid ## CONSUMES + +[Depex] + gFdtClientProtocolGuid + +[Pcd] +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase -- cgit From 7772e339bdbbaad81e84086eec0f8577e54e0f28 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 17 May 2024 11:13:36 +0800 Subject: ArmVirtPkg: Enable the non-hardcode version FdtNorFlashQemuLib Enable the non-hardcode version of FdtNorFlashQemuLib in ArmVirtQemu.dsc and ArmVirtQemuKernel.dsc, and it can work rightly after enabling it. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770 Build-tested (with "ArmVirtQemu.dsc" and "ArmVirtQemuKernel.dsc"). Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Sami Mujawar Cc: Gerd Hoffmann Cc: Jiewen Yao Signed-off-by: Chao Li Co-authored-by: Xianglai Li Tested-by: Gerd Hoffmann Acked-by: Gerd Hoffmann --- ArmVirtPkg/ArmVirtQemu.dsc | 21 +++++++++++++++++++-- ArmVirtPkg/ArmVirtQemuKernel.dsc | 20 ++++++++++++++++++-- ArmVirtPkg/VarStore.fdf.inc | 5 +---- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 64aa4e96e5..565b5c494f 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -66,7 +66,7 @@ QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf - VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf + VirtNorFlashPlatformLib|OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf @@ -152,6 +152,9 @@ gArmTokenSpaceGuid.PcdVFPEnabled|1 !endif + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x00000000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|$(FD_SIZE) + gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000 gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 @@ -231,6 +234,10 @@ # System Memory Size -- 128 MB initially, actual size will be fetched from DT gArmTokenSpaceGuid.PcdSystemMemorySize|0x8000000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000 + [PcdsFixedAtBuild.AARCH64] # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point, # if the entry point version is >= 3.0. AARCH64 OSes cannot assume the @@ -243,6 +250,13 @@ [PcdsDynamicDefault.common] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0 + ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI # enumeration to complete before installing ACPI tables. gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE @@ -404,7 +418,10 @@ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf !endif MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf { + + NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf + } MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf { diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index 2cf96accbd..a8c3336eb8 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -65,7 +65,7 @@ ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf - VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf + VirtNorFlashPlatformLib|OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf @@ -120,6 +120,8 @@ gArmTokenSpaceGuid.PcdVFPEnabled|1 !endif + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x00000000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|$(FD_SIZE) gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 @@ -181,6 +183,10 @@ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3 gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000 + [PcdsPatchableInModule.common] # we need to provide a resolution for this PCD that supports PcdSet64() # being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c, @@ -208,6 +214,13 @@ [PcdsDynamicDefault.common] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0 + ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI # enumeration to complete before installing ACPI tables. gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE @@ -313,7 +326,10 @@ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf !endif MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf { + + NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf + } MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf { diff --git a/ArmVirtPkg/VarStore.fdf.inc b/ArmVirtPkg/VarStore.fdf.inc index b4afaf12b6..1f035a132e 100644 --- a/ArmVirtPkg/VarStore.fdf.inc +++ b/ArmVirtPkg/VarStore.fdf.inc @@ -10,7 +10,7 @@ ## [FD.QEMU_VARS] -BaseAddress = 0x04000000 +BaseAddress = 0x00000000 Size = 0xc0000 ErasePolarity = 1 BlockSize = 0x40000 @@ -18,7 +18,6 @@ NumBlocks = 3 0x00000000|0x00040000 -gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize #NV_VARIABLE_STORE DATA = { ## This is the EFI_FIRMWARE_VOLUME_HEADER @@ -57,7 +56,6 @@ DATA = { 0x00040000|0x00040000 -gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize #NV_FTW_WORKING DATA = { # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid = @@ -71,5 +69,4 @@ DATA = { } 0x00080000|0x00040000 -gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize #NV_FTW_SPARE -- cgit From e2e09d8512898709a3d076fdd36c8abee2734027 Mon Sep 17 00:00:00 2001 From: Aaron <105021049+apop5@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:40:41 -0700 Subject: MdePkg: Add Ipmi Net Sensor Thresholds command defines. Adding definitions for Ipmi Net Sensor Get/Set Thresholds commands and structures as found in Ipmi specification v2.0 Signed-off-by: Aaron Pop --- .../IndustryStandard/IpmiNetFnSensorEvent.h | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/IpmiNetFnSensorEvent.h b/MdePkg/Include/IndustryStandard/IpmiNetFnSensorEvent.h index b92958454f..93f625a32b 100644 --- a/MdePkg/Include/IndustryStandard/IpmiNetFnSensorEvent.h +++ b/MdePkg/Include/IndustryStandard/IpmiNetFnSensorEvent.h @@ -10,6 +10,7 @@ and Appendix H, Sub-function Assignments. Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -42,5 +43,50 @@ typedef struct { UINT8 OEMEvData3; } IPMI_PLATFORM_EVENT_MESSAGE_DATA_REQUEST; +// +// Definitions for Set Sensor Thresholds command +// +#define IPMI_SENSOR_SET_SENSOR_THRESHOLDS 0x26 + +typedef union { + struct _SENSOR_BITS { + UINT8 LowerNonCriticalThreshold : 1; + UINT8 LowerCriticalThreshold : 1; + UINT8 LowerNonRecoverableThreshold : 1; + UINT8 UpperNonCriticalThreshold : 1; + UINT8 UpperCriticalThreshold : 1; + UINT8 UpperNonRecoverableThreshold : 1; + UINT8 Reserved : 2; + } Bits; + UINT8 Uint8; +} SENSOR_BITS; + +typedef struct _IPMI_SENSOR_SET_SENSOR_THRESHOLD_REQUEST_DATA { + UINT8 SensorNumber; + SENSOR_BITS SetBitEnable; + UINT8 LowerNonCriticalThreshold; + UINT8 LowerCriticalThreshold; + UINT8 LowerNonRecoverableThreshold; + UINT8 UpperNonCriticalThreshold; + UINT8 UpperCriticalThreshold; + UINT8 UpperNonRecoverableThreshold; +} IPMI_SENSOR_SET_SENSOR_THRESHOLD_REQUEST_DATA; + +// +// Definitions for Get Sensor Thresholds command +// +#define IPMI_SENSOR_GET_SENSOR_THRESHOLDS 0x27 + +typedef struct _IPMI_SENSOR_GET_SENSOR_THRESHOLD_RESPONSE_DATA { + UINT8 CompletionCode; + SENSOR_BITS GetBitEnable; + UINT8 LowerNonCriticalThreshold; + UINT8 LowerCriticalThreshold; + UINT8 LowerNonRecoverableThreshold; + UINT8 UpperNonCriticalThreshold; + UINT8 UpperCriticalThreshold; + UINT8 UpperNonRecoverableThreshold; +} IPMI_SENSOR_GET_SENSOR_THRESHOLD_RESPONSE_DATA; + #pragma pack() #endif -- cgit From 10cd8b45ce36152996bcb1520ba36107a8cdc63f Mon Sep 17 00:00:00 2001 From: Neo Hsueh Date: Wed, 1 May 2024 14:13:39 -0500 Subject: MdePkg: Remove non-ASCII characters from header file REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4775 Signed-off-by: Neo Hsueh Reviewed-by: Liming Gao Cc: Jiangang He --- MdePkg/Include/Register/Amd/Cpuid.h | 4 ++-- MdePkg/Include/Register/Intel/ArchitecturalMsr.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MdePkg/Include/Register/Amd/Cpuid.h b/MdePkg/Include/Register/Amd/Cpuid.h index add43c40aa..51fa9f235c 100644 --- a/MdePkg/Include/Register/Amd/Cpuid.h +++ b/MdePkg/Include/Register/Amd/Cpuid.h @@ -46,9 +46,9 @@ CPUID Signature Information CPUID Extended Topology Enumeration @note - Reference: AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions, + Reference: AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions, Revision 3.35 Appendix E, - E.4.24 Function 8000_0026—Extended CPU Topology: + E.4.24 Function 8000_0026-Extended CPU Topology: CPUID Fn8000_0026 reports extended topology information for logical processors, including asymmetric and heterogenous topology descriptions. Individual logical processors may report different values in systems with asynchronous and heterogeneous topologies. diff --git a/MdePkg/Include/Register/Intel/ArchitecturalMsr.h b/MdePkg/Include/Register/Intel/ArchitecturalMsr.h index 756e7c86ec..4715c59dc4 100644 --- a/MdePkg/Include/Register/Intel/ArchitecturalMsr.h +++ b/MdePkg/Include/Register/Intel/ArchitecturalMsr.h @@ -5733,9 +5733,9 @@ typedef union { /// [Bit 7:4] TME Policy/Encryption Algorithm: Only algorithms enumerated in /// IA32_TME_CAPABILITY are allowed. /// For example: - /// 0000 – AES-XTS-128. - /// 0001 – AES-XTS-128 with integrity. - /// 0010 – AES-XTS-256. + /// 0000 - AES-XTS-128. + /// 0001 - AES-XTS-128 with integrity. + /// 0010 - AES-XTS-256. /// Other values are invalid. /// UINT32 TmePolicy : 4; @@ -5756,7 +5756,7 @@ typedef union { /// Similar to enumeration, this is an encoded value. /// Writing a value greater than MK_TME_MAX_KEYID_BITS will result in #GP. /// Writing a non-zero value to this field will #GP if bit 1 of EAX (Hardware - /// Encryption Enable) is not also set to ‘1, as encryption hardware must be + /// Encryption Enable) is not also set to 1, as encryption hardware must be /// enabled to use MKTME. /// Example: To support 255 keys, this field would be set to a value of 8. /// -- cgit From 10ab1c67c489942b787b784a48d46623b442cfd1 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Tue, 4 Jun 2024 15:36:45 +0800 Subject: ArmVirtPkg: Remove the NorFlashQemuLib The FdtNorFlashQemuLib has been enabled, remove ArmVirtPkg version. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770 Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Sami Mujawar Cc: Gerd Hoffmann Signed-off-by: Chao Li --- .../Library/NorFlashQemuLib/NorFlashQemuLib.c | 136 --------------------- .../Library/NorFlashQemuLib/NorFlashQemuLib.inf | 42 ------- 2 files changed, 178 deletions(-) delete mode 100644 ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c delete mode 100644 ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf diff --git a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c b/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c deleted file mode 100644 index d0fa7e5046..0000000000 --- a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c +++ /dev/null @@ -1,136 +0,0 @@ -/** @file - - Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - - **/ - -#include -#include -#include -#include - -#include - -#define QEMU_NOR_BLOCK_SIZE SIZE_256KB - -#define MAX_FLASH_BANKS 4 - -EFI_STATUS -VirtNorFlashPlatformInitialization ( - VOID - ) -{ - return EFI_SUCCESS; -} - -STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS]; - -EFI_STATUS -VirtNorFlashPlatformGetDevices ( - OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions, - OUT UINT32 *Count - ) -{ - FDT_CLIENT_PROTOCOL *FdtClient; - INT32 Node; - EFI_STATUS Status; - EFI_STATUS FindNodeStatus; - CONST UINT32 *Reg; - UINT32 PropSize; - UINT32 Num; - UINT64 Base; - UINT64 Size; - - Status = gBS->LocateProtocol ( - &gFdtClientProtocolGuid, - NULL, - (VOID **)&FdtClient - ); - ASSERT_EFI_ERROR (Status); - - Num = 0; - for (FindNodeStatus = FdtClient->FindCompatibleNode ( - FdtClient, - "cfi-flash", - &Node - ); - !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS; - FindNodeStatus = FdtClient->FindNextCompatibleNode ( - FdtClient, - "cfi-flash", - Node, - &Node - )) - { - Status = FdtClient->GetNodeProperty ( - FdtClient, - Node, - "reg", - (CONST VOID **)&Reg, - &PropSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: GetNodeProperty () failed (Status == %r)\n", - __func__, - Status - )); - continue; - } - - ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0); - - while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) { - Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0])); - Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2])); - Reg += 4; - - PropSize -= 4 * sizeof (UINT32); - - // - // Disregard any flash devices that overlap with the primary FV. - // The firmware is not updatable from inside the guest anyway. - // - if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) && - ((Base + Size) > PcdGet64 (PcdFvBaseAddress))) - { - continue; - } - - mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base; - mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base; - mNorFlashDevices[Num].Size = (UINTN)Size; - mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE; - Num++; - } - - // - // UEFI takes ownership of the NOR flash, and exposes its functionality - // through the UEFI Runtime Services GetVariable, SetVariable, etc. This - // means we need to disable it in the device tree to prevent the OS from - // attaching its device driver as well. - // Note that this also hides other flash banks, but the only other flash - // bank we expect to encounter is the one that carries the UEFI executable - // code, which is not intended to be guest updatable, and is usually backed - // in a readonly manner by QEMU anyway. - // - Status = FdtClient->SetNodeProperty ( - FdtClient, - Node, - "status", - "disabled", - sizeof ("disabled") - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n")); - } - } - - *NorFlashDescriptions = mNorFlashDevices; - *Count = Num; - - return EFI_SUCCESS; -} diff --git a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf b/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf deleted file mode 100644 index a6b5865be9..0000000000 --- a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf +++ /dev/null @@ -1,42 +0,0 @@ -#/** @file -# -# Component description file for NorFlashQemuLib module -# -# Copyright (c) 2014, Linaro Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = NorFlashQemuLib - FILE_GUID = 339B7829-4C5F-4EFC-B2DD-5050E530DECE - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = VirtNorFlashPlatformLib - -[Sources.common] - NorFlashQemuLib.c - -[Packages] - MdePkg/MdePkg.dec - ArmPkg/ArmPkg.dec - ArmVirtPkg/ArmVirtPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - OvmfPkg/OvmfPkg.dec - -[LibraryClasses] - BaseLib - DebugLib - UefiBootServicesTableLib - -[Protocols] - gFdtClientProtocolGuid ## CONSUMES - -[Depex] - gFdtClientProtocolGuid - -[Pcd] - gArmTokenSpaceGuid.PcdFvBaseAddress - gArmTokenSpaceGuid.PcdFvSize -- cgit From b45aff0dc9cb87f316eb17a11e5d4438175d9cca Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 8 May 2024 13:14:26 +0200 Subject: OvmfPkg: add morlock support Add dsc + fdf include files to add the MorLock drivers to the build. Add the include files to OVMF build configurations. Signed-off-by: Gerd Hoffmann --- OvmfPkg/Include/Dsc/MorLock.dsc.inc | 10 ++++++++++ OvmfPkg/Include/Fdf/MorLock.fdf.inc | 10 ++++++++++ OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32.fdf | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.fdf | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/OvmfPkgX64.fdf | 1 + 8 files changed, 26 insertions(+) create mode 100644 OvmfPkg/Include/Dsc/MorLock.dsc.inc create mode 100644 OvmfPkg/Include/Fdf/MorLock.fdf.inc diff --git a/OvmfPkg/Include/Dsc/MorLock.dsc.inc b/OvmfPkg/Include/Dsc/MorLock.dsc.inc new file mode 100644 index 0000000000..a8c5fb24b8 --- /dev/null +++ b/OvmfPkg/Include/Dsc/MorLock.dsc.inc @@ -0,0 +1,10 @@ +## +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# MorLock support +## + + SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf +!if $(SMM_REQUIRE) == TRUE + SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf +!endif diff --git a/OvmfPkg/Include/Fdf/MorLock.fdf.inc b/OvmfPkg/Include/Fdf/MorLock.fdf.inc new file mode 100644 index 0000000000..20b7d6619a --- /dev/null +++ b/OvmfPkg/Include/Fdf/MorLock.fdf.inc @@ -0,0 +1,10 @@ +## +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# MorLock support +## + +INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf +!if $(SMM_REQUIRE) == TRUE +INF SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf +!endif diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 2ca005d768..8ed950bb1c 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -881,6 +881,7 @@ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +!include OvmfPkg/Include/Dsc/MorLock.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 0d4abb50a8..2d9cffb3f3 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -359,6 +359,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf !include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +!include OvmfPkg/Include/Fdf/MorLock.fdf.inc !if $(LOAD_X64_ON_IA32_ENABLE) == TRUE INF OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index a39070a626..371a53232d 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -895,6 +895,7 @@ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +!include OvmfPkg/Include/Dsc/MorLock.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 23a825a012..0de247bb12 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -366,6 +366,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf !include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +!include OvmfPkg/Include/Fdf/MorLock.fdf.inc ################################################################################ diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 1b90aa8f57..b5e433e94f 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -963,6 +963,7 @@ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +!include OvmfPkg/Include/Dsc/MorLock.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 4dcd6a033c..4398d3f3f4 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -406,6 +406,7 @@ INF OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf !include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +!include OvmfPkg/Include/Fdf/MorLock.fdf.inc ################################################################################ -- cgit From 65b0d08786888284cd1bb705c58f53a65ae443b0 Mon Sep 17 00:00:00 2001 From: Jeff Brasen Date: Mon, 3 Jun 2024 08:36:17 -0700 Subject: MdeModulePkg/HiiDatabaseDxe: Remove assert for VarStoreId = 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is legal for the VarStoreId of a question to be 0 per the UEFI spec: "Specifies the identifier of a previously declared variable store to use when storing the question’s value. A value of zero indicates no associated variable store." Instead of hitting an assert just skip this question as there is no value to return. Signed-off-by: Jeff Brasen --- MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c index 6e791783a6..426dead981 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c @@ -2101,8 +2101,9 @@ ExtractConfigRequest ( // // Header->VarStoreId == 0 means no storage for this question. // - ASSERT (Header->VarStoreId != 0); - DEBUG ((DEBUG_INFO, "Varstore Id: 0x%x\n", Header->VarStoreId)); + if (Header->VarStoreId == 0) { + continue; + } Storage = FindStorageFromVarId (FormPackage, Header->VarStoreId); ASSERT (Storage != NULL); -- cgit From 603ad2d6ae7c0b46815123a59a2b8c8169711c0e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 1 Mar 2024 11:23:58 +0100 Subject: OvmfPkg/PlatformInitLib: add support for GuestPhysBits Add support for GuestPhysBits (cpuid 0x80000008, eax, bits 23:16). GuestPhysBits is a field which can be set by the hypervisor to inform the guest about the /usable/ physical address space bits. This can be smaller than the PhysBits of the CPU, for example because of nested paging limitations. OVMF will read GuestPhysBits, log the value, in case it is set use it as upper limit. Signed-off-by: Gerd Hoffmann --- OvmfPkg/Library/PlatformInitLib/MemDetect.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index e64c0ee324..f531b982bc 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -633,6 +633,7 @@ PlatformAddressWidthFromCpuid ( { UINT32 RegEax, RegEbx, RegEcx, RegEdx, Max; UINT8 PhysBits; + UINT8 GuestPhysBits; CHAR8 Signature[13]; IA32_CR4 Cr4; BOOLEAN Valid = FALSE; @@ -655,13 +656,17 @@ PlatformAddressWidthFromCpuid ( if (Max >= 0x80000008) { AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); - PhysBits = (UINT8)RegEax; + PhysBits = (UINT8)RegEax; + GuestPhysBits = (UINT8)(RegEax >> 16); } else { - PhysBits = 36; + PhysBits = 36; + GuestPhysBits = 0; } if (!QemuQuirk) { Valid = TRUE; + } else if (GuestPhysBits) { + Valid = TRUE; } else if (PhysBits >= 41) { Valid = TRUE; } else if (AsciiStrCmp (Signature, "GenuineIntel") == 0) { @@ -678,15 +683,21 @@ PlatformAddressWidthFromCpuid ( DEBUG (( DEBUG_INFO, - "%a: Signature: '%a', PhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n", + "%a: Signature: '%a', PhysBits: %d, GuestPhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n", __func__, Signature, PhysBits, + GuestPhysBits, QemuQuirk ? "On" : "Off", Cr4.Bits.LA57 ? "On" : "Off", Valid ? "Yes" : "No" )); + if (GuestPhysBits && (PhysBits > GuestPhysBits)) { + DEBUG ((DEBUG_INFO, "%a: limit PhysBits to %d (GuestPhysBits)\n", __func__, GuestPhysBits)); + PhysBits = GuestPhysBits; + } + if (Valid) { /* * Due to the sign extension we can use only the lower half of the -- cgit From 90cb1ec33225a070e9fea1d94c72ff590bd38731 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 1 Mar 2024 11:28:34 +0100 Subject: OvmfPkg/PlatformInitLib: allow PhysBits larger than 48 If GuestPhysBits reports more than 48 phys-bits can be used allow to go beyond that limit. Signed-off-by: Gerd Hoffmann --- OvmfPkg/Library/PlatformInitLib/MemDetect.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index f531b982bc..2b6404cc51 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -706,7 +706,7 @@ PlatformAddressWidthFromCpuid ( * and a 56 bit wide address space with 5 paging levels. */ if (Cr4.Bits.LA57) { - if (PhysBits > 48) { + if ((PhysBits > 48) && !GuestPhysBits) { /* * Some Intel CPUs support 5-level paging, have more than 48 * phys-bits but support only 4-level EPT, which effectively @@ -716,11 +716,11 @@ PlatformAddressWidthFromCpuid ( * problem: They can handle guest phys-bits larger than 48 * only in case the host runs in 5-level paging mode. * - * Until we have some way to communicate that kind of - * limitations from hypervisor to guest, limit phys-bits - * to 48 unconditionally. + * GuestPhysBits is used to communicate that kind of + * limitations from hypervisor to guest. If GuestPhysBits is + * not set play safe and limit phys-bits to 48. */ - DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 48 (5-level paging)\n", __func__)); + DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 48 (5-level paging, no GuestPhysBits)\n", __func__)); PhysBits = 48; } } else { -- cgit From 71606314f80500ff0849f66553fad0da11bf4beb Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Tue, 4 Jun 2024 14:52:18 +0800 Subject: CryptoPkg: Fix wrong logic in X509GetTBSCert REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4509 Both return 0x80 value and Asn1Tag != V_ASN1_SEQUENCE are wrong return. Signed-off-by: Wenxing Hou --- CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c index 7ebec9dbad..021cc328f8 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c @@ -839,7 +839,7 @@ X509GetTBSCert ( Length = 0; Inf = ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize); - if (((Inf & 0x80) == 0x80) && (Asn1Tag != V_ASN1_SEQUENCE)) { + if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) { return FALSE; } @@ -849,7 +849,7 @@ X509GetTBSCert ( // // Verify the parsed TBSCertificate is one correct SEQUENCE data. // - if (((Inf & 0x80) == 0x80) && (Asn1Tag != V_ASN1_SEQUENCE)) { + if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) { return FALSE; } -- cgit From f9c2f2fa0fd92f94d6c20292f37d5302762cad66 Mon Sep 17 00:00:00 2001 From: Michael D Kinney Date: Thu, 6 Jun 2024 15:29:21 -0700 Subject: BaseTools/Scripts: Fix PatchCheck commit range Fix logic error that changes the commit range checked depending on the verbosity level set. Signed-off-by: Michael D Kinney --- BaseTools/Scripts/PatchCheck.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/BaseTools/Scripts/PatchCheck.py b/BaseTools/Scripts/PatchCheck.py index 762a1a89f9..d797ac80c1 100755 --- a/BaseTools/Scripts/PatchCheck.py +++ b/BaseTools/Scripts/PatchCheck.py @@ -684,8 +684,6 @@ class CheckGitCommits: def __init__(self, rev_spec, max_count): dec_files = self.read_dec_files_from_git() commits = self.read_commit_list_from_git(rev_spec, max_count) - if len(commits) == 1 and Verbose.level > Verbose.ONELINE: - commits = [ rev_spec ] self.ok = True blank_line = False for commit in commits: -- cgit From 80b59ff8320d1bd134bf689fe9c0ddf4e0473b88 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Mon, 4 Mar 2024 15:32:58 +0100 Subject: MdeModulePkg: Warn if out of flash space when writing variables Emit a DEBUG_WARN message if there is not enough flash space left to write/update a variable. This condition is currently not logged appropriately in all cases, given that full variable store can easily render the system unbootable. This new message helps identifying this condition. Signed-off-by: Oliver Steffen Reviewed-by: Laszlo Ersek Reviewed-by: Gerd Hoffmann --- MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index d394d237a5..1c7659031d 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -2364,6 +2364,8 @@ Done: ); ASSERT_EFI_ERROR (Status); } + } else if (Status == EFI_OUT_OF_RESOURCES) { + DEBUG ((DEBUG_WARN, "UpdateVariable failed: Out of flash space\n")); } return Status; -- cgit From 665b223d57369d8b28dcdc81352428adfe435ff4 Mon Sep 17 00:00:00 2001 From: HoraceX Lien Date: Mon, 27 May 2024 13:27:15 +0800 Subject: ShellPkg/Pci.c: Update supported link speed to PCIe Gen6 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4779 Refer to PCI express base specification Reversion 6.2, table 7-23 Link Capabilities Register. Supported Link Speeds Vector bit 5: speed 64 GT/s. Add the support to shell command 'pci'. Signed-off-by: HoraceX Lien Cc: Zhichao Gao Reviewed-by: Zhichao Gao --- ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c index 7b11f49d0d..93622733a5 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c @@ -4809,6 +4809,9 @@ ExplainPcieLinkCap ( case 5: MaxLinkSpeed = L"32.0 GT/s"; break; + case 6: + MaxLinkSpeed = L"64.0 GT/s"; + break; default: MaxLinkSpeed = L"Reserved"; break; @@ -5015,6 +5018,9 @@ ExplainPcieLinkStatus ( case 5: CurLinkSpeed = L"32.0 GT/s"; break; + case 6: + CurLinkSpeed = L"64.0 GT/s"; + break; default: CurLinkSpeed = L"Reserved"; break; -- cgit From 8c826be35c736f4b718c8f927853aa957a1973d8 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Wed, 29 May 2024 23:51:33 -0600 Subject: MdeModulePkg: In RemoveTableFromRsdt don't read from unallocated memory Instead of copying from unallocated memory in RemoveTableFromRsdt, do a CopyMem followed by ZeroMem. Signed-off-by: Rebecca Cran --- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c index 5f8d20a7e9..45c0ae6c80 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c @@ -1279,16 +1279,16 @@ RemoveTableFromRsdt ( { // // Found entry, so copy all following entries and shrink table - // We actually copy all + 1 to copy the initialized value of memory over - // the last entry. // if (Rsdt != NULL) { - CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32)); + CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index - 1) * sizeof (UINT32)); + ZeroMem ((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ((*NumberOfTableEntries - 1) * sizeof (UINT32)), sizeof (UINT32)); Rsdt->Length = Rsdt->Length - sizeof (UINT32); } if (Xsdt != NULL) { - CopyMem (CurrentXsdtEntry, ((UINT64 *)CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64)); + CopyMem (CurrentXsdtEntry, ((UINT64 *)CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index - 1) * sizeof (UINT64)); + ZeroMem ((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ((*NumberOfTableEntries - 1) * sizeof (UINT64)), sizeof (UINT64)); Xsdt->Length = Xsdt->Length - sizeof (UINT64); } -- cgit From df8c61e4c071d1c6ab04e3ebeeb07cf97fc893e0 Mon Sep 17 00:00:00 2001 From: Sebastian Witt Date: Tue, 4 Jun 2024 13:10:13 +0200 Subject: CryptoPkg: Fix BaseCryptLib CrtWrapper strcpy strcpy fails when strSource is closer than 4096 bytes after strDest. This is caused by an overlap check in AsciiStrCpyS: // // 5. Copying shall not take place between objects that overlap. // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); Since DestMax is MAX_STRING_SIZE (0x1000) and with a Source that is in this area behind Destination, AsciiStrCpyS will fail and strcpy will do nothing. When called by CRYPTO_strdup in openssl this leads to uninitialzed memory that gets accessed instead of the copied string. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2817 Signed-off-by: Sebastian Witt --- CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c index 37cdecc9bd..880ed140fd 100644 --- a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c @@ -271,7 +271,7 @@ strcpy ( const char *strSource ) { - AsciiStrCpyS (strDest, MAX_STRING_SIZE, strSource); + AsciiStrCpyS (strDest, AsciiStrnSizeS (strSource, MAX_STRING_SIZE), strSource); return strDest; } -- cgit From 948f23417010309a5557d46195eae258f6105025 Mon Sep 17 00:00:00 2001 From: Sebastian Witt Date: Tue, 4 Jun 2024 13:38:26 +0200 Subject: CryptoPkg: Fix BaseCryptLib CrtWrapper strncpy and strcat Following https://bugzilla.tianocore.org/show_bug.cgi?id=2817 this bug could also apply to strncpy and strcat. For strncpy use count+1 if smaller than MAX_STRING_SIZE. This still restricts the destination size to MAX_STRING_SIZE as before but allows a strncpy when the source is close after destination without triggering the InternalSafeStringNoAsciiStrOverlap check in AsciiStrnCpyS. For strcat use the destination string length + the size of the source string including the terminator as destination size if smaller than MAX_STRING_SIZE. Also move both functions to CrtWrapper.c as they do not return the correct return value. AsciiStrnCpyS and AsciiStrCatS return RETURN_VALUE instead of a char * to the destination buffer. Signed-off-by: Sebastian Witt --- .../Library/BaseCryptLib/SysCall/CrtWrapper.c | 41 +++++++++++++++++++++- CryptoPkg/Library/Include/CrtLibSupport.h | 37 ++++++++++++------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c index 880ed140fd..b114cc069a 100644 --- a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c @@ -271,7 +271,46 @@ strcpy ( const char *strSource ) { - AsciiStrCpyS (strDest, AsciiStrnSizeS (strSource, MAX_STRING_SIZE), strSource); + AsciiStrCpyS (strDest, AsciiStrnSizeS (strSource, MAX_STRING_SIZE - 1), strSource); + return strDest; +} + +char * +strncpy ( + char *strDest, + const char *strSource, + size_t count + ) +{ + UINTN DestMax = MAX_STRING_SIZE; + + if (count < MAX_STRING_SIZE) { + DestMax = count + 1; + } else { + count = MAX_STRING_SIZE-1; + } + + AsciiStrnCpyS (strDest, DestMax, strSource, (UINTN)count); + + return strDest; +} + +char * +strcat ( + char *strDest, + const char *strSource + ) +{ + UINTN DestMax; + + DestMax = AsciiStrnLenS (strDest, MAX_STRING_SIZE) + AsciiStrnSizeS (strSource, MAX_STRING_SIZE); + + if (DestMax > MAX_STRING_SIZE) { + DestMax = MAX_STRING_SIZE; + } + + AsciiStrCatS (strDest, DestMax, strSource); + return strDest; } diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h b/CryptoPkg/Library/Include/CrtLibSupport.h index f36fe08f0c..afc00956ab 100644 --- a/CryptoPkg/Library/Include/CrtLibSupport.h +++ b/CryptoPkg/Library/Include/CrtLibSupport.h @@ -403,22 +403,33 @@ strcpy ( const char *strSource ); +char * +strncpy ( + char *strDest, + const char *strSource, + size_t count + ); + +char * +strcat ( + char *strDest, + const char *strSource + ); + // // Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions // -#define memcpy(dest, source, count) CopyMem(dest,source,(UINTN)(count)) -#define memset(dest, ch, count) SetMem(dest,(UINTN)(count),(UINT8)(ch)) -#define memchr(buf, ch, count) ScanMem8(buf,(UINTN)(count),(UINT8)ch) -#define memcmp(buf1, buf2, count) (int)(CompareMem(buf1,buf2,(UINTN)(count))) -#define memmove(dest, source, count) CopyMem(dest,source,(UINTN)(count)) -#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE)) -#define strncpy(strDest, strSource, count) AsciiStrnCpyS(strDest,MAX_STRING_SIZE,strSource,(UINTN)count) -#define strcat(strDest, strSource) AsciiStrCatS(strDest,MAX_STRING_SIZE,strSource) -#define strncmp(string1, string2, count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count))) -#define strcasecmp(str1, str2) (int)AsciiStriCmp(str1,str2) -#define strstr(s1, s2) AsciiStrStr(s1,s2) -#define sprintf(buf, ...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__) -#define localtime(timer) NULL +#define memcpy(dest, source, count) CopyMem(dest,source,(UINTN)(count)) +#define memset(dest, ch, count) SetMem(dest,(UINTN)(count),(UINT8)(ch)) +#define memchr(buf, ch, count) ScanMem8(buf,(UINTN)(count),(UINT8)ch) +#define memcmp(buf1, buf2, count) (int)(CompareMem(buf1,buf2,(UINTN)(count))) +#define memmove(dest, source, count) CopyMem(dest,source,(UINTN)(count)) +#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE)) +#define strncmp(string1, string2, count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count))) +#define strcasecmp(str1, str2) (int)AsciiStriCmp(str1,str2) +#define strstr(s1, s2) AsciiStrStr(s1,s2) +#define sprintf(buf, ...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__) +#define localtime(timer) NULL #define assert(expression) #define offsetof(type, member) OFFSET_OF(type,member) #define atoi(nptr) AsciiStrDecimalToUintn(nptr) -- cgit From c36414b131dfd0a1ca51f10f87a18955bc110ff2 Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Wed, 29 May 2024 09:46:25 +0700 Subject: MdeModulePkg/DxeCapsuleLibFmp: Fix crash if no ESRT is found The ESRT table is not required in UEFI firmware. In such cases, the table may not be present in the UEFI Configuration Table. The mEsrtTable is to check if the IsNestedFmpCapsule() function is invoked at runtime to determine whether to use gEsrtManagementProtocolGuid or the ESRT table from the Configuration Table. Unfortunately, the check does not cover situations where the ESRT is not present, potentially resulting in a kernel crash. This patch is intended to fix this issue. Signed-off-by: Nhi Pham --- MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c | 13 +++++++++++++ MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c index 2433c76a8c..36efd64c4c 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c @@ -11,6 +11,7 @@ performs basic validation. Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -48,6 +49,8 @@ EFI_EVENT mDxeCapsuleLibEndOfDxeEvent = NULL; EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL *mFmpProgress = NULL; +extern BOOLEAN mDxeCapsuleLibReadyToBootEvent; + /** Initialize capsule related variables. **/ @@ -1402,6 +1405,16 @@ IsNestedFmpCapsule ( } } } else { + if (mDxeCapsuleLibReadyToBootEvent) { + // + // The ESRT table (mEsrtTable) in the Configuration Table would be located + // at the ReadyToBoot event if it exists. Hence, it should return here to + // avoid a crash due to calling gBS->LocateProtocol () at runtime in case + // there is no ERST table installed. + // + return FALSE; + } + // // Check ESRT protocol // diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c index 44f30c16c2..efff714d01 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c @@ -2,6 +2,7 @@ Capsule library runtime support. Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -23,6 +24,7 @@ extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable; EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL; EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL; +BOOLEAN mDxeCapsuleLibReadyToBootEvent = FALSE; /** Convert EsrtTable physical address to virtual address. @@ -93,6 +95,8 @@ DxeCapsuleLibReadyToBootEventNotify ( // mEsrtTable->FwResourceCountMax = mEsrtTable->FwResourceCount; } + + mDxeCapsuleLibReadyToBootEvent = TRUE; } /** -- cgit From ab069d580111ccc64d6b0c9697b7c5fd6e1507ce Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 12 Feb 2024 22:04:28 +0100 Subject: OvmfPkg/QemuVideoDxe: purge VbeShim The guest os which depends on vbeshim for video support is -- according to the comments -- Windows 2008 R2. Which went EOL in January 2020, more than four years ago. Time to retire VbeShim. RIP. Signed-off-by: Gerd Hoffmann Acked-by: Ard Biesheuvel Reviewed-by: Laszlo Ersek --- OvmfPkg/QemuVideoDxe/Driver.c | 9 - OvmfPkg/QemuVideoDxe/Qemu.h | 6 - OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 4 - OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 -------------- OvmfPkg/QemuVideoDxe/VbeShim.c | 328 ---------------- OvmfPkg/QemuVideoDxe/VbeShim.h | 701 ---------------------------------- OvmfPkg/QemuVideoDxe/VbeShim.sh | 82 ---- 7 files changed, 1411 deletions(-) delete mode 100644 OvmfPkg/QemuVideoDxe/VbeShim.asm delete mode 100644 OvmfPkg/QemuVideoDxe/VbeShim.c delete mode 100644 OvmfPkg/QemuVideoDxe/VbeShim.h delete mode 100755 OvmfPkg/QemuVideoDxe/VbeShim.sh diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c index c28171d137..6feca83802 100644 --- a/OvmfPkg/QemuVideoDxe/Driver.c +++ b/OvmfPkg/QemuVideoDxe/Driver.c @@ -466,15 +466,6 @@ QemuVideoControllerDriverStart ( goto UninstallGop; } - #if defined MDE_CPU_IA32 || defined MDE_CPU_X64 - if ((Private->Variant == QEMU_VIDEO_BOCHS_MMIO) || - (Private->Variant == QEMU_VIDEO_BOCHS)) - { - InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase); - } - - #endif - gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; diff --git a/OvmfPkg/QemuVideoDxe/Qemu.h b/OvmfPkg/QemuVideoDxe/Qemu.h index 57341a0bbf..bd6198dd50 100644 --- a/OvmfPkg/QemuVideoDxe/Qemu.h +++ b/OvmfPkg/QemuVideoDxe/Qemu.h @@ -495,10 +495,4 @@ QemuVideoBochsModeSetup ( BOOLEAN IsQxl ); -VOID -InstallVbeShim ( - IN CONST CHAR16 *CardName, - IN EFI_PHYSICAL_ADDRESS FrameBufferBase - ); - #endif diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf index 43a6e07faa..6b7baa8525 100644 --- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf @@ -33,10 +33,6 @@ Initialize.c Qemu.h -[Sources.Ia32, Sources.X64] - VbeShim.c - VbeShim.h - [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.asm b/OvmfPkg/QemuVideoDxe/VbeShim.asm deleted file mode 100644 index 1d284b2641..0000000000 --- a/OvmfPkg/QemuVideoDxe/VbeShim.asm +++ /dev/null @@ -1,281 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy, -; default VGA driver to switch to 1024x768x32, on the stdvga and QXL video -; cards of QEMU. -; -; Copyright (C) 2014, Red Hat, Inc. -; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-; -; SPDX-License-Identifier: BSD-2-Clause-Patent -; -;------------------------------------------------------------------------------ - -; enable this macro for debug messages -;%define DEBUG - -%macro DebugLog 1 -%ifdef DEBUG - push si - mov si, %1 - call PrintStringSi - pop si -%endif -%endmacro - - -BITS 16 -ORG 0 - -VbeInfo: -TIMES 256 nop - -VbeModeInfo: -TIMES 256 nop - - -Handler: - cmp ax, 0x4f00 - je GetInfo - cmp ax, 0x4f01 - je GetModeInfo - cmp ax, 0x4f02 - je SetMode - cmp ax, 0x4f03 - je GetMode - cmp ax, 0x4f10 - je GetPmCapabilities - cmp ax, 0x4f15 - je ReadEdid - cmp ah, 0x00 - je SetModeLegacy - DebugLog StrUnknownFunction -Hang: - jmp Hang - - -GetInfo: - push es - push di - push ds - push si - push cx - - DebugLog StrEnterGetInfo - - ; target (es:di) set on input - push cs - pop ds - mov si, VbeInfo - ; source (ds:si) set now - - mov cx, 256 - cld - rep movsb - - pop cx - pop si - pop ds - pop di - pop es - jmp Success - - -GetModeInfo: - push es - push di - push ds - push si - push cx - - DebugLog StrEnterGetModeInfo - - and cx, ~0x4000 ; clear potentially set LFB bit in mode number - cmp cx, 0x00f1 - je KnownMode1 - DebugLog StrUnknownMode - jmp Hang -KnownMode1: - ; target (es:di) set on input - push cs - pop ds - mov si, VbeModeInfo - ; source (ds:si) set now - - mov cx, 256 - cld - rep movsb - - pop cx - pop si - pop ds - pop di - pop es - jmp Success - - -%define ATT_ADDRESS_REGISTER 0x03c0 -%define VBE_DISPI_IOPORT_INDEX 0x01ce -%define VBE_DISPI_IOPORT_DATA 0x01d0 - -%define VBE_DISPI_INDEX_XRES 0x1 -%define VBE_DISPI_INDEX_YRES 0x2 -%define VBE_DISPI_INDEX_BPP 0x3 -%define VBE_DISPI_INDEX_ENABLE 0x4 -%define VBE_DISPI_INDEX_BANK 0x5 -%define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 -%define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 -%define VBE_DISPI_INDEX_X_OFFSET 0x8 -%define VBE_DISPI_INDEX_Y_OFFSET 0x9 - -%define VBE_DISPI_ENABLED 0x01 -%define VBE_DISPI_LFB_ENABLED 0x40 - -%macro BochsWrite 2 - push dx - push ax - - mov dx, VBE_DISPI_IOPORT_INDEX - mov ax, %1 - out dx, ax - - mov dx, VBE_DISPI_IOPORT_DATA - mov ax, %2 - out dx, ax - - pop ax - pop dx -%endmacro - -SetMode: - push dx - push ax - - DebugLog StrEnterSetMode - - cmp bx, 0x40f1 - je KnownMode2 - DebugLog StrUnknownMode - jmp Hang -KnownMode2: - - ; unblank - mov dx, ATT_ADDRESS_REGISTER - mov al, 0x20 - out dx, al - - BochsWrite VBE_DISPI_INDEX_ENABLE, 0 - BochsWrite VBE_DISPI_INDEX_BANK, 0 - BochsWrite VBE_DISPI_INDEX_X_OFFSET, 0 - BochsWrite VBE_DISPI_INDEX_Y_OFFSET, 0 - BochsWrite VBE_DISPI_INDEX_BPP, 32 - BochsWrite VBE_DISPI_INDEX_XRES, 1024 - BochsWrite VBE_DISPI_INDEX_VIRT_WIDTH, 1024 - BochsWrite VBE_DISPI_INDEX_YRES, 768 - BochsWrite VBE_DISPI_INDEX_VIRT_HEIGHT, 768 - BochsWrite VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED - - pop ax - pop dx - jmp Success - - -GetMode: - DebugLog StrEnterGetMode - mov bx, 0x40f1 - jmp Success - - -GetPmCapabilities: - DebugLog StrGetPmCapabilities - jmp Unsupported - - -ReadEdid: - DebugLog StrReadEdid - jmp Unsupported - - -SetModeLegacy: - DebugLog StrEnterSetModeLegacy - - cmp al, 0x03 - je KnownMode3 - cmp al, 0x12 - je KnownMode4 - DebugLog StrUnknownMode - jmp Hang -KnownMode3: - mov al, 0x30 - jmp SetModeLegacyDone -KnownMode4: - mov al, 0x20 -SetModeLegacyDone: - DebugLog StrExitSuccess - iret - - -Success: - DebugLog StrExitSuccess - mov ax, 0x004f - iret - - -Unsupported: - DebugLog StrExitUnsupported - mov ax, 0x014f - iret - - -%ifdef DEBUG -PrintStringSi: - pusha - push ds ; save original - push cs - pop ds - mov dx, 0x0402 -PrintStringSiLoop: - lodsb - cmp al, 0 - je PrintStringSiDone - out dx, al - jmp PrintStringSiLoop -PrintStringSiDone: - pop ds ; restore original - popa - ret - - -StrExitSuccess: - db 'Exit', 0x0a, 0 - -StrExitUnsupported: - db 'Unsupported', 0x0a, 0 - -StrUnknownFunction: - db 'Unknown Function', 0x0a, 0 - -StrEnterGetInfo: - db 'GetInfo', 0x0a, 0 - -StrEnterGetModeInfo: - db 'GetModeInfo', 0x0a, 0 - -StrEnterGetMode: - db 'GetMode', 0x0a, 0 - -StrEnterSetMode: - db 'SetMode', 0x0a, 0 - -StrEnterSetModeLegacy: - db 'SetModeLegacy', 0x0a, 0 - -StrUnknownMode: - db 'Unknown Mode', 0x0a, 0 - -StrGetPmCapabilities: - db 'GetPmCapabilities', 0x0a, 0 - -StrReadEdid: - db 'ReadEdid', 0x0a, 0 -%endif diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.c b/OvmfPkg/QemuVideoDxe/VbeShim.c deleted file mode 100644 index 8f151b96f9..0000000000 --- a/OvmfPkg/QemuVideoDxe/VbeShim.c +++ /dev/null @@ -1,328 +0,0 @@ -/** @file - Install a fake VGABIOS service handler (real mode Int10h) for the buggy - Windows 2008 R2 SP1 UEFI guest. - - The handler is never meant to be directly executed by a VCPU; it's there for - the internal real mode emulator of Windows 2008 R2 SP1. - - The code is based on Ralf Brown's Interrupt List: - - - - Copyright (C) 2014, Red Hat, Inc. - Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include -#include -#include -#include - -#include "Qemu.h" -#include "VbeShim.h" - -#pragma pack (1) -typedef struct { - UINT16 Offset; - UINT16 Segment; -} IVT_ENTRY; -#pragma pack () - -// -// This string is displayed by Windows 2008 R2 SP1 in the Screen Resolution, -// Advanced Settings dialog. It should be short. -// -STATIC CONST CHAR8 mProductRevision[] = "OVMF Int10h (fake)"; - -/** - Install the VBE Info and VBE Mode Info structures, and the VBE service - handler routine in the C segment. Point the real-mode Int10h interrupt vector - to the handler. The only advertised mode is 1024x768x32. - - @param[in] CardName Name of the video card to be exposed in the - Product Name field of the VBE Info structure. The - parameter must originate from a - QEMU_VIDEO_CARD.Name field. - @param[in] FrameBufferBase Guest-physical base address of the video card's - frame buffer. -**/ -VOID -InstallVbeShim ( - IN CONST CHAR16 *CardName, - IN EFI_PHYSICAL_ADDRESS FrameBufferBase - ) -{ - EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF; - UINTN Segment0Pages; - IVT_ENTRY *Int0x10; - EFI_STATUS Segment0AllocationStatus; - UINT16 HostBridgeDevId; - UINTN Pam1Address; - UINT8 Pam1; - UINTN SegmentCPages; - VBE_INFO *VbeInfoFull; - VBE_INFO_BASE *VbeInfo; - UINT8 *Ptr; - UINTN Printed; - VBE_MODE_INFO *VbeModeInfo; - - if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) { - DEBUG (( - DEBUG_WARN, - "%a: page 0 protected, not installing VBE shim\n", - __func__ - )); - DEBUG (( - DEBUG_WARN, - "%a: page 0 protection prevents Windows 7 from booting anyway\n", - __func__ - )); - return; - } - - Segment0 = 0x00000; - SegmentC = 0xC0000; - SegmentF = 0xF0000; - - // - // Attempt to cover the real mode IVT with an allocation. This is a UEFI - // driver, hence the arch protocols have been installed previously. Among - // those, the CPU arch protocol has configured the IDT, so we can overwrite - // the IVT used in real mode. - // - // The allocation request may fail, eg. if LegacyBiosDxe has already run. - // - Segment0Pages = 1; - Int0x10 = (IVT_ENTRY *)(UINTN)(Segment0 + 0x10 * sizeof (IVT_ENTRY)); - Segment0AllocationStatus = gBS->AllocatePages ( - AllocateAddress, - EfiBootServicesCode, - Segment0Pages, - &Segment0 - ); - - if (EFI_ERROR (Segment0AllocationStatus)) { - EFI_PHYSICAL_ADDRESS Handler; - - // - // Check if a video BIOS handler has been installed previously -- we - // shouldn't override a real video BIOS with our shim, nor our own shim if - // it's already present. - // - Handler = (Int0x10->Segment << 4) + Int0x10->Offset; - if ((Handler >= SegmentC) && (Handler < SegmentF)) { - DEBUG (( - DEBUG_INFO, - "%a: Video BIOS handler found at %04x:%04x\n", - __func__, - Int0x10->Segment, - Int0x10->Offset - )); - return; - } - - // - // Otherwise we'll overwrite the Int10h vector, even though we may not own - // the page at zero. - // - DEBUG (( - DEBUG_INFO, - "%a: failed to allocate page at zero: %r\n", - __func__, - Segment0AllocationStatus - )); - } else { - // - // We managed to allocate the page at zero. SVN r14218 guarantees that it - // is NUL-filled. - // - ASSERT (Int0x10->Segment == 0x0000); - ASSERT (Int0x10->Offset == 0x0000); - } - - // - // Put the shim in place first. - // - // Start by determining the address of the PAM1 register. - // - HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId); - switch (HostBridgeDevId) { - case INTEL_82441_DEVICE_ID: - Pam1Address = PMC_REGISTER_PIIX4 (PIIX4_PAM1); - break; - case INTEL_Q35_MCH_DEVICE_ID: - Pam1Address = DRAMC_REGISTER_Q35 (MCH_PAM1); - break; - case MICROVM_PSEUDO_DEVICE_ID: - return; - default: - DEBUG (( - DEBUG_ERROR, - "%a: unknown host bridge device ID: 0x%04x\n", - __func__, - HostBridgeDevId - )); - ASSERT (FALSE); - - if (!EFI_ERROR (Segment0AllocationStatus)) { - gBS->FreePages (Segment0, Segment0Pages); - } - - return; - } - - // - // low nibble covers 0xC0000 to 0xC3FFF - // high nibble covers 0xC4000 to 0xC7FFF - // bit1 in each nibble is Write Enable - // bit0 in each nibble is Read Enable - // - Pam1 = PciRead8 (Pam1Address); - PciWrite8 (Pam1Address, Pam1 | (BIT1 | BIT0)); - - // - // We never added memory space during PEI or DXE for the C segment, so we - // don't need to (and can't) allocate from there. Also, guest operating - // systems will see a hole in the UEFI memory map there. - // - SegmentCPages = 4; - - ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages)); - CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim); - - // - // Fill in the VBE INFO structure. - // - VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC; - VbeInfo = &VbeInfoFull->Base; - Ptr = VbeInfoFull->Buffer; - - CopyMem (VbeInfo->Signature, "VESA", 4); - VbeInfo->VesaVersion = 0x0300; - - VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; - CopyMem (Ptr, "QEMU", 5); - Ptr += 5; - - VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode - - VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; - *(UINT16 *)Ptr = 0x00f1; // mode number - Ptr += 2; - *(UINT16 *)Ptr = 0xFFFF; // mode list terminator - Ptr += 2; - - VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536); - VbeInfo->OemSoftwareVersion = 0x0000; - - VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; - CopyMem (Ptr, "OVMF", 5); - Ptr += 5; - - VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; - Printed = AsciiSPrint ( - (CHAR8 *)Ptr, - sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), - "%s", - CardName - ); - Ptr += Printed + 1; - - VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; - CopyMem (Ptr, mProductRevision, sizeof mProductRevision); - Ptr += sizeof mProductRevision; - - ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer); - ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer)); - - // - // Fil in the VBE MODE INFO structure. - // - VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1); - - // - // bit0: mode supported by present hardware configuration - // bit1: optional information available (must be =1 for VBE v1.2+) - // bit3: set if color, clear if monochrome - // bit4: set if graphics mode, clear if text mode - // bit5: mode is not VGA-compatible - // bit7: linear framebuffer mode supported - // - VbeModeInfo->ModeAttr = BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0; - - // - // bit0: exists - // bit1: bit1: readable - // bit2: writeable - // - VbeModeInfo->WindowAAttr = BIT2 | BIT1 | BIT0; - - VbeModeInfo->WindowBAttr = 0x00; - VbeModeInfo->WindowGranularityKB = 0x0040; - VbeModeInfo->WindowSizeKB = 0x0040; - VbeModeInfo->WindowAStartSegment = 0xA000; - VbeModeInfo->WindowBStartSegment = 0x0000; - VbeModeInfo->WindowPositioningAddress = 0x0000; - VbeModeInfo->BytesPerScanLine = 1024 * 4; - - VbeModeInfo->Width = 1024; - VbeModeInfo->Height = 768; - VbeModeInfo->CharCellWidth = 8; - VbeModeInfo->CharCellHeight = 16; - VbeModeInfo->NumPlanes = 1; - VbeModeInfo->BitsPerPixel = 32; - VbeModeInfo->NumBanks = 1; - VbeModeInfo->MemoryModel = 6; // direct color - VbeModeInfo->BankSizeKB = 0; - VbeModeInfo->NumImagePagesLessOne = 0; - VbeModeInfo->Vbe3 = 0x01; - - VbeModeInfo->RedMaskSize = 8; - VbeModeInfo->RedMaskPos = 16; - VbeModeInfo->GreenMaskSize = 8; - VbeModeInfo->GreenMaskPos = 8; - VbeModeInfo->BlueMaskSize = 8; - VbeModeInfo->BlueMaskPos = 0; - VbeModeInfo->ReservedMaskSize = 8; - VbeModeInfo->ReservedMaskPos = 24; - - // - // bit1: Bytes in reserved field may be used by application - // - VbeModeInfo->DirectColorModeInfo = BIT1; - - VbeModeInfo->LfbAddress = (UINT32)FrameBufferBase; - VbeModeInfo->OffScreenAddress = 0; - VbeModeInfo->OffScreenSizeKB = 0; - - VbeModeInfo->BytesPerScanLineLinear = 1024 * 4; - VbeModeInfo->NumImagesLessOneBanked = 0; - VbeModeInfo->NumImagesLessOneLinear = 0; - VbeModeInfo->RedMaskSizeLinear = 8; - VbeModeInfo->RedMaskPosLinear = 16; - VbeModeInfo->GreenMaskSizeLinear = 8; - VbeModeInfo->GreenMaskPosLinear = 8; - VbeModeInfo->BlueMaskSizeLinear = 8; - VbeModeInfo->BlueMaskPosLinear = 0; - VbeModeInfo->ReservedMaskSizeLinear = 8; - VbeModeInfo->ReservedMaskPosLinear = 24; - VbeModeInfo->MaxPixelClockHz = 0; - - ZeroMem (VbeModeInfo->Reserved, sizeof VbeModeInfo->Reserved); - - // - // Clear Write Enable (bit1), keep Read Enable (bit0) set - // - PciWrite8 (Pam1Address, (Pam1 & ~BIT1) | BIT0); - - // - // Second, point the Int10h vector at the shim. - // - Int0x10->Segment = (UINT16)((UINT32)SegmentC >> 4); - Int0x10->Offset = (UINT16)((UINTN)(VbeModeInfo + 1) - SegmentC); - - DEBUG ((DEBUG_INFO, "%a: VBE shim installed\n", __func__)); -} diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.h b/OvmfPkg/QemuVideoDxe/VbeShim.h deleted file mode 100644 index cc9b6e14cd..0000000000 --- a/OvmfPkg/QemuVideoDxe/VbeShim.h +++ /dev/null @@ -1,701 +0,0 @@ -// -// THIS FILE WAS GENERATED BY "VbeShim.sh". DO NOT EDIT. -// -#ifndef _VBE_SHIM_H_ -#define _VBE_SHIM_H_ -STATIC CONST UINT8 mVbeShim[] = { - /* 00000000 nop */ 0x90, - /* 00000001 nop */ 0x90, - /* 00000002 nop */ 0x90, - /* 00000003 nop */ 0x90, - /* 00000004 nop */ 0x90, - /* 00000005 nop */ 0x90, - /* 00000006 nop */ 0x90, - /* 00000007 nop */ 0x90, - /* 00000008 nop */ 0x90, - /* 00000009 nop */ 0x90, - /* 0000000A nop */ 0x90, - /* 0000000B nop */ 0x90, - /* 0000000C nop */ 0x90, - /* 0000000D nop */ 0x90, - /* 0000000E nop */ 0x90, - /* 0000000F nop */ 0x90, - /* 00000010 nop */ 0x90, - /* 00000011 nop */ 0x90, - /* 00000012 nop */ 0x90, - /* 00000013 nop */ 0x90, - /* 00000014 nop */ 0x90, - /* 00000015 nop */ 0x90, - /* 00000016 nop */ 0x90, - /* 00000017 nop */ 0x90, - /* 00000018 nop */ 0x90, - /* 00000019 nop */ 0x90, - /* 0000001A nop */ 0x90, - /* 0000001B nop */ 0x90, - /* 0000001C nop */ 0x90, - /* 0000001D nop */ 0x90, - /* 0000001E nop */ 0x90, - /* 0000001F nop */ 0x90, - /* 00000020 nop */ 0x90, - /* 00000021 nop */ 0x90, - /* 00000022 nop */ 0x90, - /* 00000023 nop */ 0x90, - /* 00000024 nop */ 0x90, - /* 00000025 nop */ 0x90, - /* 00000026 nop */ 0x90, - /* 00000027 nop */ 0x90, - /* 00000028 nop */ 0x90, - /* 00000029 nop */ 0x90, - /* 0000002A nop */ 0x90, - /* 0000002B nop */ 0x90, - /* 0000002C nop */ 0x90, - /* 0000002D nop */ 0x90, - /* 0000002E nop */ 0x90, - /* 0000002F nop */ 0x90, - /* 00000030 nop */ 0x90, - /* 00000031 nop */ 0x90, - /* 00000032 nop */ 0x90, - /* 00000033 nop */ 0x90, - /* 00000034 nop */ 0x90, - /* 00000035 nop */ 0x90, - /* 00000036 nop */ 0x90, - /* 00000037 nop */ 0x90, - /* 00000038 nop */ 0x90, - /* 00000039 nop */ 0x90, - /* 0000003A nop */ 0x90, - /* 0000003B nop */ 0x90, - /* 0000003C nop */ 0x90, - /* 0000003D nop */ 0x90, - /* 0000003E nop */ 0x90, - /* 0000003F nop */ 0x90, - /* 00000040 nop */ 0x90, - /* 00000041 nop */ 0x90, - /* 00000042 nop */ 0x90, - /* 00000043 nop */ 0x90, - /* 00000044 nop */ 0x90, - /* 00000045 nop */ 0x90, - /* 00000046 nop */ 0x90, - /* 00000047 nop */ 0x90, - /* 00000048 nop */ 0x90, - /* 00000049 nop */ 0x90, - /* 0000004A nop */ 0x90, - /* 0000004B nop */ 0x90, - /* 0000004C nop */ 0x90, - /* 0000004D nop */ 0x90, - /* 0000004E nop */ 0x90, - /* 0000004F nop */ 0x90, - /* 00000050 nop */ 0x90, - /* 00000051 nop */ 0x90, - /* 00000052 nop */ 0x90, - /* 00000053 nop */ 0x90, - /* 00000054 nop */ 0x90, - /* 00000055 nop */ 0x90, - /* 00000056 nop */ 0x90, - /* 00000057 nop */ 0x90, - /* 00000058 nop */ 0x90, - /* 00000059 nop */ 0x90, - /* 0000005A nop */ 0x90, - /* 0000005B nop */ 0x90, - /* 0000005C nop */ 0x90, - /* 0000005D nop */ 0x90, - /* 0000005E nop */ 0x90, - /* 0000005F nop */ 0x90, - /* 00000060 nop */ 0x90, - /* 00000061 nop */ 0x90, - /* 00000062 nop */ 0x90, - /* 00000063 nop */ 0x90, - /* 00000064 nop */ 0x90, - /* 00000065 nop */ 0x90, - /* 00000066 nop */ 0x90, - /* 00000067 nop */ 0x90, - /* 00000068 nop */ 0x90, - /* 00000069 nop */ 0x90, - /* 0000006A nop */ 0x90, - /* 0000006B nop */ 0x90, - /* 0000006C nop */ 0x90, - /* 0000006D nop */ 0x90, - /* 0000006E nop */ 0x90, - /* 0000006F nop */ 0x90, - /* 00000070 nop */ 0x90, - /* 00000071 nop */ 0x90, - /* 00000072 nop */ 0x90, - /* 00000073 nop */ 0x90, - /* 00000074 nop */ 0x90, - /* 00000075 nop */ 0x90, - /* 00000076 nop */ 0x90, - /* 00000077 nop */ 0x90, - /* 00000078 nop */ 0x90, - /* 00000079 nop */ 0x90, - /* 0000007A nop */ 0x90, - /* 0000007B nop */ 0x90, - /* 0000007C nop */ 0x90, - /* 0000007D nop */ 0x90, - /* 0000007E nop */ 0x90, - /* 0000007F nop */ 0x90, - /* 00000080 nop */ 0x90, - /* 00000081 nop */ 0x90, - /* 00000082 nop */ 0x90, - /* 00000083 nop */ 0x90, - /* 00000084 nop */ 0x90, - /* 00000085 nop */ 0x90, - /* 00000086 nop */ 0x90, - /* 00000087 nop */ 0x90, - /* 00000088 nop */ 0x90, - /* 00000089 nop */ 0x90, - /* 0000008A nop */ 0x90, - /* 0000008B nop */ 0x90, - /* 0000008C nop */ 0x90, - /* 0000008D nop */ 0x90, - /* 0000008E nop */ 0x90, - /* 0000008F nop */ 0x90, - /* 00000090 nop */ 0x90, - /* 00000091 nop */ 0x90, - /* 00000092 nop */ 0x90, - /* 00000093 nop */ 0x90, - /* 00000094 nop */ 0x90, - /* 00000095 nop */ 0x90, - /* 00000096 nop */ 0x90, - /* 00000097 nop */ 0x90, - /* 00000098 nop */ 0x90, - /* 00000099 nop */ 0x90, - /* 0000009A nop */ 0x90, - /* 0000009B nop */ 0x90, - /* 0000009C nop */ 0x90, - /* 0000009D nop */ 0x90, - /* 0000009E nop */ 0x90, - /* 0000009F nop */ 0x90, - /* 000000A0 nop */ 0x90, - /* 000000A1 nop */ 0x90, - /* 000000A2 nop */ 0x90, - /* 000000A3 nop */ 0x90, - /* 000000A4 nop */ 0x90, - /* 000000A5 nop */ 0x90, - /* 000000A6 nop */ 0x90, - /* 000000A7 nop */ 0x90, - /* 000000A8 nop */ 0x90, - /* 000000A9 nop */ 0x90, - /* 000000AA nop */ 0x90, - /* 000000AB nop */ 0x90, - /* 000000AC nop */ 0x90, - /* 000000AD nop */ 0x90, - /* 000000AE nop */ 0x90, - /* 000000AF nop */ 0x90, - /* 000000B0 nop */ 0x90, - /* 000000B1 nop */ 0x90, - /* 000000B2 nop */ 0x90, - /* 000000B3 nop */ 0x90, - /* 000000B4 nop */ 0x90, - /* 000000B5 nop */ 0x90, - /* 000000B6 nop */ 0x90, - /* 000000B7 nop */ 0x90, - /* 000000B8 nop */ 0x90, - /* 000000B9 nop */ 0x90, - /* 000000BA nop */ 0x90, - /* 000000BB nop */ 0x90, - /* 000000BC nop */ 0x90, - /* 000000BD nop */ 0x90, - /* 000000BE nop */ 0x90, - /* 000000BF nop */ 0x90, - /* 000000C0 nop */ 0x90, - /* 000000C1 nop */ 0x90, - /* 000000C2 nop */ 0x90, - /* 000000C3 nop */ 0x90, - /* 000000C4 nop */ 0x90, - /* 000000C5 nop */ 0x90, - /* 000000C6 nop */ 0x90, - /* 000000C7 nop */ 0x90, - /* 000000C8 nop */ 0x90, - /* 000000C9 nop */ 0x90, - /* 000000CA nop */ 0x90, - /* 000000CB nop */ 0x90, - /* 000000CC nop */ 0x90, - /* 000000CD nop */ 0x90, - /* 000000CE nop */ 0x90, - /* 000000CF nop */ 0x90, - /* 000000D0 nop */ 0x90, - /* 000000D1 nop */ 0x90, - /* 000000D2 nop */ 0x90, - /* 000000D3 nop */ 0x90, - /* 000000D4 nop */ 0x90, - /* 000000D5 nop */ 0x90, - /* 000000D6 nop */ 0x90, - /* 000000D7 nop */ 0x90, - /* 000000D8 nop */ 0x90, - /* 000000D9 nop */ 0x90, - /* 000000DA nop */ 0x90, - /* 000000DB nop */ 0x90, - /* 000000DC nop */ 0x90, - /* 000000DD nop */ 0x90, - /* 000000DE nop */ 0x90, - /* 000000DF nop */ 0x90, - /* 000000E0 nop */ 0x90, - /* 000000E1 nop */ 0x90, - /* 000000E2 nop */ 0x90, - /* 000000E3 nop */ 0x90, - /* 000000E4 nop */ 0x90, - /* 000000E5 nop */ 0x90, - /* 000000E6 nop */ 0x90, - /* 000000E7 nop */ 0x90, - /* 000000E8 nop */ 0x90, - /* 000000E9 nop */ 0x90, - /* 000000EA nop */ 0x90, - /* 000000EB nop */ 0x90, - /* 000000EC nop */ 0x90, - /* 000000ED nop */ 0x90, - /* 000000EE nop */ 0x90, - /* 000000EF nop */ 0x90, - /* 000000F0 nop */ 0x90, - /* 000000F1 nop */ 0x90, - /* 000000F2 nop */ 0x90, - /* 000000F3 nop */ 0x90, - /* 000000F4 nop */ 0x90, - /* 000000F5 nop */ 0x90, - /* 000000F6 nop */ 0x90, - /* 000000F7 nop */ 0x90, - /* 000000F8 nop */ 0x90, - /* 000000F9 nop */ 0x90, - /* 000000FA nop */ 0x90, - /* 000000FB nop */ 0x90, - /* 000000FC nop */ 0x90, - /* 000000FD nop */ 0x90, - /* 000000FE nop */ 0x90, - /* 000000FF nop */ 0x90, - /* 00000100 nop */ 0x90, - /* 00000101 nop */ 0x90, - /* 00000102 nop */ 0x90, - /* 00000103 nop */ 0x90, - /* 00000104 nop */ 0x90, - /* 00000105 nop */ 0x90, - /* 00000106 nop */ 0x90, - /* 00000107 nop */ 0x90, - /* 00000108 nop */ 0x90, - /* 00000109 nop */ 0x90, - /* 0000010A nop */ 0x90, - /* 0000010B nop */ 0x90, - /* 0000010C nop */ 0x90, - /* 0000010D nop */ 0x90, - /* 0000010E nop */ 0x90, - /* 0000010F nop */ 0x90, - /* 00000110 nop */ 0x90, - /* 00000111 nop */ 0x90, - /* 00000112 nop */ 0x90, - /* 00000113 nop */ 0x90, - /* 00000114 nop */ 0x90, - /* 00000115 nop */ 0x90, - /* 00000116 nop */ 0x90, - /* 00000117 nop */ 0x90, - /* 00000118 nop */ 0x90, - /* 00000119 nop */ 0x90, - /* 0000011A nop */ 0x90, - /* 0000011B nop */ 0x90, - /* 0000011C nop */ 0x90, - /* 0000011D nop */ 0x90, - /* 0000011E nop */ 0x90, - /* 0000011F nop */ 0x90, - /* 00000120 nop */ 0x90, - /* 00000121 nop */ 0x90, - /* 00000122 nop */ 0x90, - /* 00000123 nop */ 0x90, - /* 00000124 nop */ 0x90, - /* 00000125 nop */ 0x90, - /* 00000126 nop */ 0x90, - /* 00000127 nop */ 0x90, - /* 00000128 nop */ 0x90, - /* 00000129 nop */ 0x90, - /* 0000012A nop */ 0x90, - /* 0000012B nop */ 0x90, - /* 0000012C nop */ 0x90, - /* 0000012D nop */ 0x90, - /* 0000012E nop */ 0x90, - /* 0000012F nop */ 0x90, - /* 00000130 nop */ 0x90, - /* 00000131 nop */ 0x90, - /* 00000132 nop */ 0x90, - /* 00000133 nop */ 0x90, - /* 00000134 nop */ 0x90, - /* 00000135 nop */ 0x90, - /* 00000136 nop */ 0x90, - /* 00000137 nop */ 0x90, - /* 00000138 nop */ 0x90, - /* 00000139 nop */ 0x90, - /* 0000013A nop */ 0x90, - /* 0000013B nop */ 0x90, - /* 0000013C nop */ 0x90, - /* 0000013D nop */ 0x90, - /* 0000013E nop */ 0x90, - /* 0000013F nop */ 0x90, - /* 00000140 nop */ 0x90, - /* 00000141 nop */ 0x90, - /* 00000142 nop */ 0x90, - /* 00000143 nop */ 0x90, - /* 00000144 nop */ 0x90, - /* 00000145 nop */ 0x90, - /* 00000146 nop */ 0x90, - /* 00000147 nop */ 0x90, - /* 00000148 nop */ 0x90, - /* 00000149 nop */ 0x90, - /* 0000014A nop */ 0x90, - /* 0000014B nop */ 0x90, - /* 0000014C nop */ 0x90, - /* 0000014D nop */ 0x90, - /* 0000014E nop */ 0x90, - /* 0000014F nop */ 0x90, - /* 00000150 nop */ 0x90, - /* 00000151 nop */ 0x90, - /* 00000152 nop */ 0x90, - /* 00000153 nop */ 0x90, - /* 00000154 nop */ 0x90, - /* 00000155 nop */ 0x90, - /* 00000156 nop */ 0x90, - /* 00000157 nop */ 0x90, - /* 00000158 nop */ 0x90, - /* 00000159 nop */ 0x90, - /* 0000015A nop */ 0x90, - /* 0000015B nop */ 0x90, - /* 0000015C nop */ 0x90, - /* 0000015D nop */ 0x90, - /* 0000015E nop */ 0x90, - /* 0000015F nop */ 0x90, - /* 00000160 nop */ 0x90, - /* 00000161 nop */ 0x90, - /* 00000162 nop */ 0x90, - /* 00000163 nop */ 0x90, - /* 00000164 nop */ 0x90, - /* 00000165 nop */ 0x90, - /* 00000166 nop */ 0x90, - /* 00000167 nop */ 0x90, - /* 00000168 nop */ 0x90, - /* 00000169 nop */ 0x90, - /* 0000016A nop */ 0x90, - /* 0000016B nop */ 0x90, - /* 0000016C nop */ 0x90, - /* 0000016D nop */ 0x90, - /* 0000016E nop */ 0x90, - /* 0000016F nop */ 0x90, - /* 00000170 nop */ 0x90, - /* 00000171 nop */ 0x90, - /* 00000172 nop */ 0x90, - /* 00000173 nop */ 0x90, - /* 00000174 nop */ 0x90, - /* 00000175 nop */ 0x90, - /* 00000176 nop */ 0x90, - /* 00000177 nop */ 0x90, - /* 00000178 nop */ 0x90, - /* 00000179 nop */ 0x90, - /* 0000017A nop */ 0x90, - /* 0000017B nop */ 0x90, - /* 0000017C nop */ 0x90, - /* 0000017D nop */ 0x90, - /* 0000017E nop */ 0x90, - /* 0000017F nop */ 0x90, - /* 00000180 nop */ 0x90, - /* 00000181 nop */ 0x90, - /* 00000182 nop */ 0x90, - /* 00000183 nop */ 0x90, - /* 00000184 nop */ 0x90, - /* 00000185 nop */ 0x90, - /* 00000186 nop */ 0x90, - /* 00000187 nop */ 0x90, - /* 00000188 nop */ 0x90, - /* 00000189 nop */ 0x90, - /* 0000018A nop */ 0x90, - /* 0000018B nop */ 0x90, - /* 0000018C nop */ 0x90, - /* 0000018D nop */ 0x90, - /* 0000018E nop */ 0x90, - /* 0000018F nop */ 0x90, - /* 00000190 nop */ 0x90, - /* 00000191 nop */ 0x90, - /* 00000192 nop */ 0x90, - /* 00000193 nop */ 0x90, - /* 00000194 nop */ 0x90, - /* 00000195 nop */ 0x90, - /* 00000196 nop */ 0x90, - /* 00000197 nop */ 0x90, - /* 00000198 nop */ 0x90, - /* 00000199 nop */ 0x90, - /* 0000019A nop */ 0x90, - /* 0000019B nop */ 0x90, - /* 0000019C nop */ 0x90, - /* 0000019D nop */ 0x90, - /* 0000019E nop */ 0x90, - /* 0000019F nop */ 0x90, - /* 000001A0 nop */ 0x90, - /* 000001A1 nop */ 0x90, - /* 000001A2 nop */ 0x90, - /* 000001A3 nop */ 0x90, - /* 000001A4 nop */ 0x90, - /* 000001A5 nop */ 0x90, - /* 000001A6 nop */ 0x90, - /* 000001A7 nop */ 0x90, - /* 000001A8 nop */ 0x90, - /* 000001A9 nop */ 0x90, - /* 000001AA nop */ 0x90, - /* 000001AB nop */ 0x90, - /* 000001AC nop */ 0x90, - /* 000001AD nop */ 0x90, - /* 000001AE nop */ 0x90, - /* 000001AF nop */ 0x90, - /* 000001B0 nop */ 0x90, - /* 000001B1 nop */ 0x90, - /* 000001B2 nop */ 0x90, - /* 000001B3 nop */ 0x90, - /* 000001B4 nop */ 0x90, - /* 000001B5 nop */ 0x90, - /* 000001B6 nop */ 0x90, - /* 000001B7 nop */ 0x90, - /* 000001B8 nop */ 0x90, - /* 000001B9 nop */ 0x90, - /* 000001BA nop */ 0x90, - /* 000001BB nop */ 0x90, - /* 000001BC nop */ 0x90, - /* 000001BD nop */ 0x90, - /* 000001BE nop */ 0x90, - /* 000001BF nop */ 0x90, - /* 000001C0 nop */ 0x90, - /* 000001C1 nop */ 0x90, - /* 000001C2 nop */ 0x90, - /* 000001C3 nop */ 0x90, - /* 000001C4 nop */ 0x90, - /* 000001C5 nop */ 0x90, - /* 000001C6 nop */ 0x90, - /* 000001C7 nop */ 0x90, - /* 000001C8 nop */ 0x90, - /* 000001C9 nop */ 0x90, - /* 000001CA nop */ 0x90, - /* 000001CB nop */ 0x90, - /* 000001CC nop */ 0x90, - /* 000001CD nop */ 0x90, - /* 000001CE nop */ 0x90, - /* 000001CF nop */ 0x90, - /* 000001D0 nop */ 0x90, - /* 000001D1 nop */ 0x90, - /* 000001D2 nop */ 0x90, - /* 000001D3 nop */ 0x90, - /* 000001D4 nop */ 0x90, - /* 000001D5 nop */ 0x90, - /* 000001D6 nop */ 0x90, - /* 000001D7 nop */ 0x90, - /* 000001D8 nop */ 0x90, - /* 000001D9 nop */ 0x90, - /* 000001DA nop */ 0x90, - /* 000001DB nop */ 0x90, - /* 000001DC nop */ 0x90, - /* 000001DD nop */ 0x90, - /* 000001DE nop */ 0x90, - /* 000001DF nop */ 0x90, - /* 000001E0 nop */ 0x90, - /* 000001E1 nop */ 0x90, - /* 000001E2 nop */ 0x90, - /* 000001E3 nop */ 0x90, - /* 000001E4 nop */ 0x90, - /* 000001E5 nop */ 0x90, - /* 000001E6 nop */ 0x90, - /* 000001E7 nop */ 0x90, - /* 000001E8 nop */ 0x90, - /* 000001E9 nop */ 0x90, - /* 000001EA nop */ 0x90, - /* 000001EB nop */ 0x90, - /* 000001EC nop */ 0x90, - /* 000001ED nop */ 0x90, - /* 000001EE nop */ 0x90, - /* 000001EF nop */ 0x90, - /* 000001F0 nop */ 0x90, - /* 000001F1 nop */ 0x90, - /* 000001F2 nop */ 0x90, - /* 000001F3 nop */ 0x90, - /* 000001F4 nop */ 0x90, - /* 000001F5 nop */ 0x90, - /* 000001F6 nop */ 0x90, - /* 000001F7 nop */ 0x90, - /* 000001F8 nop */ 0x90, - /* 000001F9 nop */ 0x90, - /* 000001FA nop */ 0x90, - /* 000001FB nop */ 0x90, - /* 000001FC nop */ 0x90, - /* 000001FD nop */ 0x90, - /* 000001FE nop */ 0x90, - /* 000001FF nop */ 0x90, - /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F, - /* 00000203 jz 0x22d */ 0x74, 0x28, - /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F, - /* 00000208 jz 0x245 */ 0x74, 0x3B, - /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F, - /* 0000020D jz 0x269 */ 0x74, 0x5A, - /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F, - /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01, - /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F, - /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01, - /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F, - /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01, - /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00, - /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01, - /* 0000022B jmp short 0x22b */ 0xEB, 0xFE, - /* 0000022D push es */ 0x06, - /* 0000022E push di */ 0x57, - /* 0000022F push ds */ 0x1E, - /* 00000230 push si */ 0x56, - /* 00000231 push cx */ 0x51, - /* 00000232 push cs */ 0x0E, - /* 00000233 pop ds */ 0x1F, - /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00, - /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01, - /* 0000023A cld */ 0xFC, - /* 0000023B rep movsb */ 0xF3, 0xA4, - /* 0000023D pop cx */ 0x59, - /* 0000023E pop si */ 0x5E, - /* 0000023F pop ds */ 0x1F, - /* 00000240 pop di */ 0x5F, - /* 00000241 pop es */ 0x07, - /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01, - /* 00000245 push es */ 0x06, - /* 00000246 push di */ 0x57, - /* 00000247 push ds */ 0x1E, - /* 00000248 push si */ 0x56, - /* 00000249 push cx */ 0x51, - /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, - /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, - /* 00000252 jz 0x256 */ 0x74, 0x02, - /* 00000254 jmp short 0x22b */ 0xEB, 0xD5, - /* 00000256 push cs */ 0x0E, - /* 00000257 pop ds */ 0x1F, - /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01, - /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01, - /* 0000025E cld */ 0xFC, - /* 0000025F rep movsb */ 0xF3, 0xA4, - /* 00000261 pop cx */ 0x59, - /* 00000262 pop si */ 0x5E, - /* 00000263 pop ds */ 0x1F, - /* 00000264 pop di */ 0x5F, - /* 00000265 pop es */ 0x07, - /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00, - /* 00000269 push dx */ 0x52, - /* 0000026A push ax */ 0x50, - /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, - /* 0000026F jz 0x273 */ 0x74, 0x02, - /* 00000271 jmp short 0x22b */ 0xEB, 0xB8, - /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, - /* 00000276 mov al,0x20 */ 0xB0, 0x20, - /* 00000278 out dx,al */ 0xEE, - /* 00000279 push dx */ 0x52, - /* 0000027A push ax */ 0x50, - /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00, - /* 00000281 out dx,ax */ 0xEF, - /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00, - /* 00000288 out dx,ax */ 0xEF, - /* 00000289 pop ax */ 0x58, - /* 0000028A pop dx */ 0x5A, - /* 0000028B push dx */ 0x52, - /* 0000028C push ax */ 0x50, - /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00, - /* 00000293 out dx,ax */ 0xEF, - /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00, - /* 0000029A out dx,ax */ 0xEF, - /* 0000029B pop ax */ 0x58, - /* 0000029C pop dx */ 0x5A, - /* 0000029D push dx */ 0x52, - /* 0000029E push ax */ 0x50, - /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00, - /* 000002A5 out dx,ax */ 0xEF, - /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00, - /* 000002AC out dx,ax */ 0xEF, - /* 000002AD pop ax */ 0x58, - /* 000002AE pop dx */ 0x5A, - /* 000002AF push dx */ 0x52, - /* 000002B0 push ax */ 0x50, - /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00, - /* 000002B7 out dx,ax */ 0xEF, - /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00, - /* 000002BE out dx,ax */ 0xEF, - /* 000002BF pop ax */ 0x58, - /* 000002C0 pop dx */ 0x5A, - /* 000002C1 push dx */ 0x52, - /* 000002C2 push ax */ 0x50, - /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00, - /* 000002C9 out dx,ax */ 0xEF, - /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00, - /* 000002D0 out dx,ax */ 0xEF, - /* 000002D1 pop ax */ 0x58, - /* 000002D2 pop dx */ 0x5A, - /* 000002D3 push dx */ 0x52, - /* 000002D4 push ax */ 0x50, - /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00, - /* 000002DB out dx,ax */ 0xEF, - /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04, - /* 000002E2 out dx,ax */ 0xEF, - /* 000002E3 pop ax */ 0x58, - /* 000002E4 pop dx */ 0x5A, - /* 000002E5 push dx */ 0x52, - /* 000002E6 push ax */ 0x50, - /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00, - /* 000002ED out dx,ax */ 0xEF, - /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04, - /* 000002F4 out dx,ax */ 0xEF, - /* 000002F5 pop ax */ 0x58, - /* 000002F6 pop dx */ 0x5A, - /* 000002F7 push dx */ 0x52, - /* 000002F8 push ax */ 0x50, - /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00, - /* 000002FF out dx,ax */ 0xEF, - /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03, - /* 00000306 out dx,ax */ 0xEF, - /* 00000307 pop ax */ 0x58, - /* 00000308 pop dx */ 0x5A, - /* 00000309 push dx */ 0x52, - /* 0000030A push ax */ 0x50, - /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00, - /* 00000311 out dx,ax */ 0xEF, - /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03, - /* 00000318 out dx,ax */ 0xEF, - /* 00000319 pop ax */ 0x58, - /* 0000031A pop dx */ 0x5A, - /* 0000031B push dx */ 0x52, - /* 0000031C push ax */ 0x50, - /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, - /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00, - /* 00000323 out dx,ax */ 0xEF, - /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, - /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00, - /* 0000032A out dx,ax */ 0xEF, - /* 0000032B pop ax */ 0x58, - /* 0000032C pop dx */ 0x5A, - /* 0000032D pop ax */ 0x58, - /* 0000032E pop dx */ 0x5A, - /* 0000032F jmp short 0x34c */ 0xEB, 0x1B, - /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, - /* 00000334 jmp short 0x34c */ 0xEB, 0x16, - /* 00000336 jmp short 0x350 */ 0xEB, 0x18, - /* 00000338 jmp short 0x350 */ 0xEB, 0x16, - /* 0000033A cmp al,0x3 */ 0x3C, 0x03, - /* 0000033C jz 0x345 */ 0x74, 0x07, - /* 0000033E cmp al,0x12 */ 0x3C, 0x12, - /* 00000340 jz 0x349 */ 0x74, 0x07, - /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE, - /* 00000345 mov al,0x30 */ 0xB0, 0x30, - /* 00000347 jmp short 0x34b */ 0xEB, 0x02, - /* 00000349 mov al,0x20 */ 0xB0, 0x20, - /* 0000034B iretw */ 0xCF, - /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00, - /* 0000034F iretw */ 0xCF, - /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01, - /* 00000353 iretw */ 0xCF, -}; -#endif diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.sh b/OvmfPkg/QemuVideoDxe/VbeShim.sh deleted file mode 100755 index 7a0095a813..0000000000 --- a/OvmfPkg/QemuVideoDxe/VbeShim.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh -### -# @file -# Shell script to assemble and dump the fake Int10h handler from NASM source to -# a C array. -# -# Copyright (C) 2014, Red Hat, Inc. -# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -### - -set -e -u - -STEM=$(dirname -- "$0")/$(basename -- "$0" .sh) - -# -# Install exit handler -- remove temporary files. -# -exit_handler() -{ - rm -f -- "$STEM".bin "$STEM".disasm "$STEM".offsets "$STEM".insns \ - "$STEM".bytes -} -trap exit_handler EXIT - -# -# Assemble the source file. -# (nasm doesn't recognize the "--" end-of-options delimiter; -# .) -# -nasm -o "$STEM".bin "$STEM".asm - -# -# Disassemble it, in order to get a binary dump associated with the source. -# (ndisasm doesn't recognize the "--" end-of-options delimiter; -# .) -# -ndisasm "$STEM".bin >"$STEM".disasm - -# -# Create three files, each with one column of the disassembly. -# -# The first column contains the offsets, and it starts the comment. -# -cut -c 1-8 -- "$STEM".disasm \ -| sed -e 's,^, /* ,' >"$STEM".offsets - -# -# The second column contains the assembly-language instructions, and it closes -# the comment. We first pad it to 30 characters. -# -cut -c 29- -- "$STEM".disasm \ -| sed -e 's,$, ,' \ - -e 's,^\(.\{30\}\).*$,\1 */,' >"$STEM".insns - -# -# The third column contains the bytes corresponding to the instruction, -# represented as C integer constants. First strip trailing whitespace from the -# middle column of the input disassembly, then process pairs of nibbles. -# -cut -c 11-28 -- "$STEM".disasm \ -| sed -e 's, \+$,,' -e 's/\(..\)/ 0x\1,/g' >"$STEM".bytes - -# -# Write the output file, recombining the columns. The output should have CRLF -# line endings. -# -{ - printf '//\n' - printf '// THIS FILE WAS GENERATED BY "%s". DO NOT EDIT.\n' \ - "$(basename -- "$0")" - printf '//\n' - printf '#ifndef _VBE_SHIM_H_\n' - printf '#define _VBE_SHIM_H_\n' - printf 'STATIC CONST UINT8 mVbeShim[] = {\n' - paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes - printf '};\n' - printf '#endif\n' -} \ -| unix2dos >"$STEM".h -- cgit From 5bea69123349ef3c02e5d8a49ceaae971975ba90 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 7 Jun 2024 10:02:25 +0200 Subject: ArmVirtPkg/PrePi: Enable VFP before calling into C code When building ArmVirtQemuKernel with CLANGDWARF (which does not require a GCC workaround where -mgeneral-regs-only is needed to ensure -mstrict-align works as expected), the C code invoked from the PrePi startup code may contain instructions that access the FP/SIMD register file. This means that the FP/SIMD must be enabled before making such calls, and this is currently not the case. So fix that, by moving the call to ArmEnableVFP() early into the asm startup code. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/PrePi/AArch64/ArchPrePi.c | 5 ---- ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 41 +++++++++++++++++------------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c b/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c index 9cab88ca08..a02c2ad560 100644 --- a/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c +++ b/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c @@ -15,11 +15,6 @@ ArchInitialize ( VOID ) { - // Enable Floating Point - if (FixedPcdGet32 (PcdVFPEnabled)) { - ArmEnableVFP (); - } - if (ArmReadCurrentEL () == AARCH64_EL2) { // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2 ArmWriteHcr (ARM_HCR_TGE); diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S index 01623b6b35..fc06c28daa 100644 --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -9,6 +9,23 @@ #include ASM_FUNC(_ModuleEntryPoint) + // + // If we are booting from RAM using the Linux kernel boot protocol, x0 will + // point to the DTB image in memory. Otherwise, use the default value defined + // by the platform. + // + cbnz x0, 0f + ldr x0, PcdGet64 (PcdDeviceTreeInitialBaseAddress) + +0:mov x28, x0 // preserve DTB pointer + mov x27, x1 // preserve base of image pointer + +#if (FixedPcdGet32 (PcdVFPEnabled)) + // Enable Floating Point. This needs to be done before entering C code, which + // may use FP/SIMD registers. + bl ArmEnableVFP +#endif + bl ASM_PFX(DiscoverDramFromDt) // Get ID of this CPU in Multicore system @@ -95,28 +112,18 @@ _NeverReturn: // VOID // DiscoverDramFromDt ( -// VOID *DeviceTreeBaseAddress, // passed by loader in x0 -// VOID *ImageBase // passed by FDF trampoline in x1 +// VOID *DeviceTreeBaseAddress, // passed by loader in x0, preserved in x28 +// VOID *ImageBase // passed by FDF trampoline in x1, preserved in x27 // ); ASM_PFX(DiscoverDramFromDt): - // - // If we are booting from RAM using the Linux kernel boot protocol, x0 will - // point to the DTB image in memory. Otherwise, use the default value defined - // by the platform. - // - cbnz x0, 0f - ldr x0, PcdGet64 (PcdDeviceTreeInitialBaseAddress) - -0:mov x29, x30 // preserve LR - mov x28, x0 // preserve DTB pointer - mov x27, x1 // preserve base of image pointer + mov x29, x30 // preserve LR // - // The base of the runtime image has been preserved in x1. Check whether + // The base of the runtime image has been preserved in x27. Check whether // the expected magic number can be found in the header. // ldr w8, .LArm64LinuxMagic - ldr w9, [x1, #0x38] + ldr w9, [x27, #0x38] cmp w8, w9 bne .Lout @@ -132,8 +139,8 @@ ASM_PFX(DiscoverDramFromDt): ldr x6, [x8] ldr x7, [x9] sub x7, x7, x6 - add x7, x7, x1 - str x1, [x8] + add x7, x7, x27 + str x27, [x8] str x7, [x9] // -- cgit From 059676e4faef29ebe50549ed9cd80b6f68a0d556 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 7 Jun 2024 18:39:43 +0200 Subject: ArmVirtPkg/ArmVirtQemu: Implement ArmMonitorLib for QEMU specifically Whether SMCCC calls use HVC or SMC generally depends on the exception level that the firmware executes at, but also on whether or not EL2 is implemented. This is almost always known at build time, which is why the default ArmMonitorLib used to model this as a feature PCD. However, on QEMU, things are not that simple. However, SMCCC specifies that the conduit is the same as the one used for PSCI calls (which has been retrofitted into SMCCC when it was defined). Given that QEMU provides this information via the device tree, let's use it to select the conduit, using a special ArmMonitorLib implementation. This also removes the need to set the associated PCD at runtime, given that its updated value will no longer be used. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirtQemu.dsc | 2 + ArmVirtPkg/ArmVirtQemuKernel.dsc | 2 + .../ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.c | 95 ++++++++++++++++++++++ .../ArmVirtQemuMonitorLib.inf | 39 +++++++++ ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 12 --- 5 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.c create mode 100644 ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 565b5c494f..fa4f0ca853 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -92,6 +92,8 @@ TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf !endif + ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf + [LibraryClasses.AARCH64] ArmPlatformLib|ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index a8c3336eb8..a1bafbaba1 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -82,6 +82,8 @@ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf + ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf + [LibraryClasses.common.DXE_DRIVER] AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf diff --git a/ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.c b/ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.c new file mode 100644 index 0000000000..1c8b18d5e5 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.c @@ -0,0 +1,95 @@ +/** @file + Arm Monitor Library that chooses the conduit based on the PSCI node in the + device tree provided by QEMU + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ Copyright (c) 2024, Google LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +STATIC UINT32 mArmSmcccMethod; + +/** Library constructor. + + Assign the global variable mArmSmcccMethod based on the PSCI node in the + device tree. +**/ +RETURN_STATUS +EFIAPI +ArmVirtQemuMonitorLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + FDT_CLIENT_PROTOCOL *FdtClient; + CONST VOID *Prop; + + Status = gBS->LocateProtocol ( + &gFdtClientProtocolGuid, + NULL, + (VOID **)&FdtClient + ); + ASSERT_EFI_ERROR (Status); + + Status = FdtClient->FindCompatibleNodeProperty ( + FdtClient, + "arm,psci-0.2", + "method", + &Prop, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (AsciiStrnCmp (Prop, "hvc", 3) == 0) { + mArmSmcccMethod = 1; + } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) { + mArmSmcccMethod = 2; + } else { + DEBUG (( + DEBUG_ERROR, + "%a: Unknown SMCCC method \"%a\"\n", + __func__, + Prop + )); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** Monitor call. + + An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued + depending on the default conduit. + + @param [in,out] Args Arguments for the HVC/SMC. +**/ +VOID +EFIAPI +ArmMonitorCall ( + IN OUT ARM_MONITOR_ARGS *Args + ) +{ + if (mArmSmcccMethod == 1) { + ArmCallHvc ((ARM_HVC_ARGS *)Args); + } else if (mArmSmcccMethod == 2) { + ArmCallSmc ((ARM_SMC_ARGS *)Args); + } else { + ASSERT ((mArmSmcccMethod == 1) || (mArmSmcccMethod == 2)); + } +} diff --git a/ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf b/ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf new file mode 100644 index 0000000000..e43ba215c2 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtQemuMonitorLib/ArmVirtQemuMonitorLib.inf @@ -0,0 +1,39 @@ +## @file +# Arm Monitor Library that chooses the conduit based on the PSCI node in the +# device tree provided by QEMU +# +# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2024, Google LLC. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ArmVirtQemuMonitorLib + FILE_GUID = 09f50ee5-2aa2-42b9-a2a0-090faeefed2b + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmMonitorLib|DXE_DRIVER DXE_RUNTIME_DRIVER + CONSTRUCTOR = ArmVirtQemuMonitorLibConstructor + +[Sources] + ArmVirtQemuMonitorLib.c + +[Packages] + ArmPkg/ArmPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmHvcLib + ArmSmcLib + BaseLib + DebugLib + UefiBootServicesTableLib + +[Protocols] + gFdtClientProtocolGuid ## CONSUMES + +[Depex] + gFdtClientProtocolGuid diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c index b8e9208301..3c80f05984 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c @@ -226,17 +226,5 @@ PlatformPeim ( BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize)); - #ifdef MDE_CPU_AARCH64 - // - // Set the SMCCC conduit to SMC if executing at EL2, which is typically the - // exception level that services HVCs rather than the one that invokes them. - // - if (ArmReadCurrentEL () == AARCH64_EL2) { - Status = PcdSetBoolS (PcdMonitorConduitHvc, FALSE); - ASSERT_EFI_ERROR (Status); - } - - #endif - return EFI_SUCCESS; } -- cgit From 7bcd49edd0a1daa23f8e910d0082abb0f9f2119d Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 7 Jun 2024 10:15:18 +0200 Subject: ArmVirtPkg: Revert "Use dynamic PCD to set the SMCCC conduit" This reverts commit c98f7f75508912c086158892fc56b0c3b85abcf1, which is no longer needed: the SMCCC conduit will be converted back to being hardcoded, as PrePi based ArmVirtPkg build cannot support dynamic PCDs, and falling back to patchable PCDs does not work either. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirtCloudHv.dsc | 3 --- ArmVirtPkg/ArmVirtQemu.dsc | 4 ---- ArmVirtPkg/ArmVirtQemuKernel.dsc | 2 -- ArmVirtPkg/ArmVirtXen.dsc | 2 -- ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 2 -- ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 1 - 6 files changed, 14 deletions(-) diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc index d5055a0341..5cb2a609b1 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.dsc +++ b/ArmVirtPkg/ArmVirtCloudHv.dsc @@ -201,9 +201,6 @@ [PcdsDynamicHii] gUefiOvmfPkgTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gOvmfVariableGuid|0x0|FALSE|NV,BS -[PcdsPatchableInModule.common] - gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE - ################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index fa4f0ca853..95c5fcc296 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -309,10 +309,6 @@ gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01 gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01 - # whether to use HVC or SMC to issue monitor calls - this typically depends - # on the exception level at which the UEFI system firmware executes - gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE - # # TPM2 support # diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index a1bafbaba1..7d41f280cb 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -211,8 +211,6 @@ gArmTokenSpaceGuid.PcdFdBaseAddress|0x0 gArmTokenSpaceGuid.PcdFvBaseAddress|0x0 - gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE - [PcdsDynamicDefault.common] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3 diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 1505709a29..3689106857 100644 --- a/ArmVirtPkg/ArmVirtXen.dsc +++ b/ArmVirtPkg/ArmVirtXen.dsc @@ -120,8 +120,6 @@ gArmTokenSpaceGuid.PcdFdBaseAddress|0x0 gArmTokenSpaceGuid.PcdFvBaseAddress|0x0 - gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE - [PcdsDynamicDefault.common] gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|0x0 diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c index 3c80f05984..7ab4aa2d6b 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c @@ -18,8 +18,6 @@ #include #include -#include - #include #include diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf index a38b89c103..e9a34b6e2e 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf @@ -45,7 +45,6 @@ [Pcd] gArmTokenSpaceGuid.PcdFvBaseAddress - gArmTokenSpaceGuid.PcdMonitorConduitHvc gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOMETIMES_PRODUCES gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress -- cgit From 2c19297e6cf004379415ec1dd7f8655befe2e536 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 7 Jun 2024 10:18:39 +0200 Subject: ArmVirtPkg/ArmVirtQemu: Revert "Permit the use of dynamic PCDs in PEI" This reverts commit 865229bcc8939c7a69d525f2b0627ef1532d5bc6, and restores the old state where dynamic PCDs are only used when TPM support is configured. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirtQemu.dsc | 6 +++++- ArmVirtPkg/ArmVirtQemu.fdf | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 95c5fcc296..d90c60b28a 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -334,7 +334,11 @@ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 [LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] +!if $(TPM2_ENABLE) == TRUE PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf +!else + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf +!endif ################################################################################ # @@ -351,11 +355,11 @@ ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf ArmPkg/Drivers/CpuPei/CpuPei.inf +!if $(TPM2_ENABLE) == TRUE MdeModulePkg/Universal/PCD/Pei/Pcd.inf { PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf } -!if $(TPM2_ENABLE) == TRUE MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf { ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf index 6073a31970..764f652afd 100644 --- a/ArmVirtPkg/ArmVirtQemu.fdf +++ b/ArmVirtPkg/ArmVirtQemu.fdf @@ -111,8 +111,8 @@ READ_LOCK_STATUS = TRUE INF ArmPkg/Drivers/CpuPei/CpuPei.inf INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf - INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf !if $(TPM2_ENABLE) == TRUE + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf -- cgit From 3dcc7b73df2b1c38c3c1a31724d577f4085f3ab1 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 7 Jun 2024 10:23:14 +0200 Subject: ArmPkg: Revert "Allow SMC/HVC monitor conduit to be specified at runtime" This reverts commit 32460bb5b17b5caec29037a4e9462ca149a190e6, which is no longer needed as ArmVirtQemu now has its own special implementation for ArmMonitorLib. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Ard Biesheuvel --- ArmPkg/ArmPkg.dec | 10 +++++----- ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c | 2 +- ArmVirtPkg/ArmVirt.dsc.inc | 2 ++ ArmVirtPkg/ArmVirtKvmTool.dsc | 2 -- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index ac030e295b..7fe2b9bca4 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -139,6 +139,11 @@ # Define if the GICv3 controller should use the GICv2 legacy gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042 + ## Define the conduit to use for monitor calls. + # Default PcdMonitorConduitHvc = FALSE, conduit = SMC + # If PcdMonitorConduitHvc = TRUE, conduit = HVC + gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047 + # Whether to remap all unused memory NX before installing the CPU arch # protocol driver. This is needed on platforms that map all DRAM with RWX # attributes initially, and can be disabled otherwise. @@ -312,11 +317,6 @@ gArmTokenSpaceGuid.PcdSystemBiosRelease|0xFFFF|UINT16|0x30000058 gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059 - ## Define the conduit to use for monitor calls. - # Default PcdMonitorConduitHvc = FALSE, conduit = SMC - # If PcdMonitorConduitHvc = TRUE, conduit = HVC - gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047 - [PcdsFixedAtBuild.common, PcdsDynamic.common] # # ARM Architectural Timer diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c index ec5b0b6619..617e88f367 100644 --- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c +++ b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c @@ -26,7 +26,7 @@ ArmMonitorCall ( IN OUT ARM_MONITOR_ARGS *Args ) { - if (PcdGetBool (PcdMonitorConduitHvc)) { + if (FeaturePcdGet (PcdMonitorConduitHvc)) { ArmCallHvc ((ARM_HVC_ARGS *)Args); } else { ArmCallSmc ((ARM_SMC_ARGS *)Args); diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 7044790a1e..038931562c 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -289,6 +289,8 @@ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE + gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE + [PcdsFeatureFlag.AARCH64] # # Activate AcpiSdtProtocol diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index ae0dd1497f..da6737d9d7 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -165,8 +165,6 @@ # gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16 - gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE - [PcdsPatchableInModule.common] # # This will be overridden in the code -- cgit From 6d15276ceddd2bf05995ee2efa86316fca1cd73a Mon Sep 17 00:00:00 2001 From: Sebastian Witt Date: Mon, 3 Jun 2024 17:43:22 +0200 Subject: UefiPayloadPkg: Fix LoadDxeCore for payload size > 16MB Fix calculation of first section in FileFindSection for FILE2 headers in UefiPayloadEntry module. Signed-off-by: Sebastian Witt Reviewed-by: Guo Dong Cc: Sean Rhodes Cc: James Lu Reviewed-by: Gua Guo --- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index 898d610951..3e13496147 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -211,14 +211,15 @@ FileFindSection ( if (IS_FFS_FILE2 (FileHeader)) { FileSize = FFS_FILE2_SIZE (FileHeader); + Section = (EFI_COMMON_SECTION_HEADER *)(((EFI_FFS_FILE_HEADER2 *)FileHeader) + 1); } else { FileSize = FFS_FILE_SIZE (FileHeader); + Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1); } FileSize -= sizeof (EFI_FFS_FILE_HEADER); - Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1); - Index = 0; + Index = 0; while (Index < FileSize) { if (Section->Type == SectionType) { if (IS_SECTION2 (Section)) { -- cgit From 0982da4f50279bfb2be479f97821b86feb87c336 Mon Sep 17 00:00:00 2001 From: Dhaval Date: Tue, 11 Jun 2024 08:24:18 +0530 Subject: UefiPayloadPkg: Enable UPL FIT build config from cmdline Provide commandline configuration to select proper platform file. Cc: Gua Guo Cc: Guo Dong Cc: James Lu Cc: Sean Rhodes Signed-off-by: Dhaval Sharma --- UefiPayloadPkg/UniversalPayloadBuild.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/UniversalPayloadBuild.py b/UefiPayloadPkg/UniversalPayloadBuild.py index 0423e6da17..59c78a21b4 100644 --- a/UefiPayloadPkg/UniversalPayloadBuild.py +++ b/UefiPayloadPkg/UniversalPayloadBuild.py @@ -112,6 +112,8 @@ def RunCommand(cmd): raise Exception("ERROR: when run command: %s"%cmd) def BuildUniversalPayload(Args): + DscPath = os.path.normpath(Args.DscPath) + print("Building FIT for DSC file %s"%DscPath) BuildTarget = Args.Target ToolChain = Args.ToolChain Quiet = "--quiet" if Args.Quiet else "" @@ -140,7 +142,6 @@ def BuildUniversalPayload(Args): EntryOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, PayloadEntryToolChain), os.path.normpath("{}/UefiPayloadPkg/UefiPayloadEntry/{}/DEBUG/{}.dll".format (Args.Arch, UpldEntryFile, UpldEntryFile))) EntryModuleInf = os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/{}.inf".format (UpldEntryFile)) - DscPath = os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc") DxeFvOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/DXEFV.Fv")) BdsFvOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/BDSFV.Fv")) NetworkFvOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) @@ -321,6 +322,7 @@ def main(): parser.add_argument("-af", "--AddFv", type=ValidateAddFv, action='append', help='Add or replace specific FV into payload, Ex: uefi_fv=XXX.fv') parser.add_argument("-f", "--Fit", action='store_true', help='Build UniversalPayload file as UniversalPayload.fit', default=False) parser.add_argument('-l', "--LoadAddress", type=int, help='Specify payload load address', default =0x000800000) + parser.add_argument('-c', '--DscPath', type=str, default="UefiPayloadPkg/UefiPayloadPkg.dsc", help='Path to the DSC file') args = parser.parse_args() -- cgit From d3b32dca06b987d7214637f3952c2ce1ce69f308 Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Tue, 11 Jun 2024 15:00:41 +0800 Subject: MdePkg/BaseLib: Let CpuDeadLoop() be breakable in debugger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting from certain version of Visual Studio C compiler (I don’t have the exact version. I am using VS2019), CpuDeadLoop is optimized quite well by compiler. The compiler does not generate instructions that jump out of the loop when the "Index" is non-zero. It becomes harder/impossible for developers to break out of the dead-loop in debugger. The new version of CpuDeadLoop() compares a volatile global to a volatile local. This forces 2 reads and a comparison on every loop iteration. The local variable can be set to 1 to exit the loop without modifying the global variable. Using VS2019 with max opt enabled, The dead-loop can be exit by setting Index to 1 in a debugger. Signed-off-by: Michael D Kinney --- MdePkg/Library/BaseLib/CpuDeadLoop.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MdePkg/Library/BaseLib/CpuDeadLoop.c b/MdePkg/Library/BaseLib/CpuDeadLoop.c index b3b7548fa5..01e7b4def7 100644 --- a/MdePkg/Library/BaseLib/CpuDeadLoop.c +++ b/MdePkg/Library/BaseLib/CpuDeadLoop.c @@ -1,7 +1,7 @@ /** @file Base Library CPU Functions for all architectures. - Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -9,6 +9,8 @@ #include #include +static volatile UINTN mDeadLoopComparator = 0; + /** Executes an infinite loop. @@ -26,7 +28,7 @@ CpuDeadLoop ( { volatile UINTN Index; - for (Index = 0; Index == 0;) { + for (Index = mDeadLoopComparator; Index == mDeadLoopComparator;) { CpuPause (); } } -- cgit From c3a8ca7b54a9fd17acdf16c6282a92cc989fa92a Mon Sep 17 00:00:00 2001 From: Pedro Falcato Date: Tue, 22 Nov 2022 22:31:03 +0000 Subject: MdePkg/BaseRngLib: Add a smoketest for RDRAND and check CPUID RDRAND has notoriously been broken many times over its lifespan. Add a smoketest to RDRAND, in order to better sniff out potential security concerns. Also add a proper CPUID test in order to support older CPUs which may not have it; it was previously being tested but then promptly ignored. Testing algorithm inspired by linux's arch/x86/kernel/cpu/rdrand.c :x86_init_rdrand() per commit 049f9ae9.. Many thanks to Jason Donenfeld for relicensing his linux RDRAND detection code to MIT and the public domain. >On Tue, Nov 22, 2022 at 2:21 PM Jason A. Donenfeld wrote: <..> > I (re)wrote that function in Linux. I hereby relicense it as MIT, and > also place it into public domain. Do with it what you will now. > > Jason BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4163 Signed-off-by: Pedro Falcato Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Jason A. Donenfeld --- MdePkg/Library/BaseRngLib/Rand/RdRand.c | 99 ++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 8 deletions(-) diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c index 9bd68352f9..06d2a6f12d 100644 --- a/MdePkg/Library/BaseRngLib/Rand/RdRand.c +++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c @@ -3,6 +3,7 @@ to provide high-quality random numbers. Copyright (c) 2023, Arm Limited. All rights reserved.
+Copyright (c) 2022, Pedro Falcato. All rights reserved.
Copyright (c) 2021, NUVIA Inc. All rights reserved.
Copyright (c) 2015, Intel Corporation. All rights reserved.
@@ -24,6 +25,88 @@ SPDX-License-Identifier: BSD-2-Clause-Patent STATIC BOOLEAN mRdRandSupported; +// +// Intel SDM says 10 tries is good enough for reliable RDRAND usage. +// +#define RDRAND_RETRIES 10 + +#define RDRAND_TEST_SAMPLES 8 + +#define RDRAND_MIN_CHANGE 5 + +// +// Add a define for native-word RDRAND, just for the test. +// +#ifdef MDE_CPU_X64 +#define ASM_RDRAND AsmRdRand64 +#else +#define ASM_RDRAND AsmRdRand32 +#endif + +/** + Tests RDRAND for broken implementations. + + @retval TRUE RDRAND is reliable (and hopefully safe). + @retval FALSE RDRAND is unreliable and should be disabled, despite CPUID. + +**/ +STATIC +BOOLEAN +TestRdRand ( + VOID + ) +{ + // + // Test for notoriously broken rdrand implementations that always return the same + // value, like the Zen 3 uarch (all-1s) or other several AMD families on suspend/resume (also all-1s). + // Note that this should be expanded to extensively test for other sorts of possible errata. + // + + // + // Our algorithm samples rdrand $RDRAND_TEST_SAMPLES times and expects + // a different result $RDRAND_MIN_CHANGE times for reliable RDRAND usage. + // + UINTN Prev; + UINT8 Idx; + UINT8 TestIteration; + UINT32 Changed; + + Changed = 0; + + for (TestIteration = 0; TestIteration < RDRAND_TEST_SAMPLES; TestIteration++) { + UINTN Sample; + // + // Note: We use a retry loop for rdrand. Normal users get this in BaseRng.c + // Any failure to get a random number will assume RDRAND does not work. + // + for (Idx = 0; Idx < RDRAND_RETRIES; Idx++) { + if (ASM_RDRAND (&Sample)) { + break; + } + } + + if (Idx == RDRAND_RETRIES) { + DEBUG ((DEBUG_ERROR, "BaseRngLib/x86: CPU BUG: Failed to get an RDRAND random number - disabling\n")); + return FALSE; + } + + if (TestIteration != 0) { + Changed += Sample != Prev; + } + + Prev = Sample; + } + + if (Changed < RDRAND_MIN_CHANGE) { + DEBUG ((DEBUG_ERROR, "BaseRngLib/x86: CPU BUG: RDRAND not reliable - disabling\n")); + return FALSE; + } + + return TRUE; +} + +#undef ASM_RDRAND + /** The constructor function checks whether or not RDRAND instruction is supported by the host hardware. @@ -48,10 +131,13 @@ BaseRngLibConstructor ( // CPUID. A value of 1 indicates that processor support RDRAND instruction. // AsmCpuid (1, 0, 0, &RegEcx, 0); - ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK); mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK); + if (mRdRandSupported) { + mRdRandSupported = TestRdRand (); + } + return EFI_SUCCESS; } @@ -70,6 +156,7 @@ ArchGetRandomNumber16 ( OUT UINT16 *Rand ) { + ASSERT (mRdRandSupported); return AsmRdRand16 (Rand); } @@ -88,6 +175,7 @@ ArchGetRandomNumber32 ( OUT UINT32 *Rand ) { + ASSERT (mRdRandSupported); return AsmRdRand32 (Rand); } @@ -106,6 +194,7 @@ ArchGetRandomNumber64 ( OUT UINT64 *Rand ) { + ASSERT (mRdRandSupported); return AsmRdRand64 (Rand); } @@ -122,13 +211,7 @@ ArchIsRngSupported ( VOID ) { - /* - Existing software depends on this always returning TRUE, so for - now hard-code it. - - return mRdRandSupported; - */ - return TRUE; + return mRdRandSupported; } /** -- cgit From a61bc0accb8a76edba4f073fdc7bafc908df045d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 31 May 2024 09:49:13 +0200 Subject: SecurityPkg/RngDxe: add rng test Check whenever RngLib actually returns random numbers, only return a non-zero number of Algorithms if that is the case. This has the effect that RndDxe loads and installs EFI_RNG_PROTOCOL only in case it can actually deliver random numbers. Signed-off-by: Gerd Hoffmann --- SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c index 5723ed6957..8b0742bab6 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c @@ -23,6 +23,7 @@ #include #include +#include #include "RngDxeInternals.h" @@ -43,7 +44,12 @@ GetAvailableAlgorithms ( VOID ) { - mAvailableAlgoArrayCount = RNG_ALGORITHM_COUNT; + UINT64 RngTest; + + if (GetRandomNumber64 (&RngTest)) { + mAvailableAlgoArrayCount = RNG_ALGORITHM_COUNT; + } + return EFI_SUCCESS; } -- cgit From 712797cf19acd292bf203522a79e40e7e13d268b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 24 May 2024 12:51:17 +0200 Subject: OvmfPkg: wire up RngDxe Add OvmfRng include snippets with the random number generator configuration for OVMF. Include RngDxe, build with BaseRngLib, so the rdrand instruction is used (if available). Also move VirtioRng to the include snippets. Use the new include snippets for OVMF builds. Signed-off-by: Gerd Hoffmann --- OvmfPkg/AmdSev/AmdSevX64.dsc | 2 +- OvmfPkg/AmdSev/AmdSevX64.fdf | 2 +- OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc | 9 +++++++++ OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc | 6 ++++++ OvmfPkg/IntelTdx/IntelTdxX64.dsc | 2 +- OvmfPkg/IntelTdx/IntelTdxX64.fdf | 2 +- OvmfPkg/Microvm/MicrovmX64.dsc | 2 +- OvmfPkg/Microvm/MicrovmX64.fdf | 2 +- OvmfPkg/OvmfPkgIa32.dsc | 2 +- OvmfPkg/OvmfPkgIa32.fdf | 2 +- OvmfPkg/OvmfPkgIa32X64.dsc | 2 +- OvmfPkg/OvmfPkgIa32X64.fdf | 2 +- OvmfPkg/OvmfPkgX64.dsc | 2 +- OvmfPkg/OvmfPkgX64.fdf | 2 +- 14 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc create mode 100644 OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index 8eb6f4f24f..40553c0019 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -649,7 +649,6 @@ OvmfPkg/Virtio10Dxe/Virtio10.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf OvmfPkg/VirtioScsiDxe/VirtioScsi.inf - OvmfPkg/VirtioRngDxe/VirtioRng.inf !if $(PVSCSI_ENABLE) == TRUE OvmfPkg/PvScsiDxe/PvScsiDxe.inf !endif @@ -733,6 +732,7 @@ OvmfPkg/AmdSev/Grub/Grub.inf !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +!include OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc OvmfPkg/PlatformDxe/Platform.inf OvmfPkg/AmdSevDxe/AmdSevDxe.inf { diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf index 595945181c..70e6434b09 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.fdf +++ b/OvmfPkg/AmdSev/AmdSevX64.fdf @@ -228,7 +228,6 @@ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf INF OvmfPkg/Virtio10Dxe/Virtio10.inf INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf -INF OvmfPkg/VirtioRngDxe/VirtioRng.inf !if $(PVSCSI_ENABLE) == TRUE INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf !endif @@ -321,6 +320,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf !include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc ################################################################################ diff --git a/OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc b/OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc new file mode 100644 index 0000000000..68839a0caa --- /dev/null +++ b/OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc @@ -0,0 +1,9 @@ +## +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf { + + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf + } + OvmfPkg/VirtioRngDxe/VirtioRng.inf diff --git a/OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc b/OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc new file mode 100644 index 0000000000..99cb4a32b1 --- /dev/null +++ b/OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc @@ -0,0 +1,6 @@ +## +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf +INF OvmfPkg/VirtioRngDxe/VirtioRng.inf diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 0931ce061a..fc1332598e 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -635,7 +635,6 @@ OvmfPkg/Virtio10Dxe/Virtio10.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf OvmfPkg/VirtioScsiDxe/VirtioScsi.inf - OvmfPkg/VirtioRngDxe/VirtioRng.inf !if $(PVSCSI_ENABLE) == TRUE OvmfPkg/PvScsiDxe/PvScsiDxe.inf !endif @@ -718,6 +717,7 @@ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +!include OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.fdf b/OvmfPkg/IntelTdx/IntelTdxX64.fdf index ce5d542048..88d0f75ae2 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.fdf +++ b/OvmfPkg/IntelTdx/IntelTdxX64.fdf @@ -285,7 +285,6 @@ READ_LOCK_STATUS = TRUE # INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf -INF OvmfPkg/VirtioRngDxe/VirtioRng.inf !if $(PVSCSI_ENABLE) == TRUE INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf !endif @@ -326,6 +325,7 @@ INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf INF OvmfPkg/PlatformDxe/Platform.inf !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc ################################################################################ diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc index 69de4dd3f1..3b2312ddbc 100644 --- a/OvmfPkg/Microvm/MicrovmX64.dsc +++ b/OvmfPkg/Microvm/MicrovmX64.dsc @@ -760,7 +760,6 @@ OvmfPkg/Virtio10Dxe/Virtio10.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf OvmfPkg/VirtioScsiDxe/VirtioScsi.inf - OvmfPkg/VirtioRngDxe/VirtioRng.inf OvmfPkg/VirtioSerialDxe/VirtioSerial.inf MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf @@ -846,6 +845,7 @@ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +!include OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/Microvm/MicrovmX64.fdf b/OvmfPkg/Microvm/MicrovmX64.fdf index 055e659a35..c8268d7e8c 100644 --- a/OvmfPkg/Microvm/MicrovmX64.fdf +++ b/OvmfPkg/Microvm/MicrovmX64.fdf @@ -207,7 +207,6 @@ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf INF OvmfPkg/Virtio10Dxe/Virtio10.inf INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf -INF OvmfPkg/VirtioRngDxe/VirtioRng.inf INF OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(SECURE_BOOT_ENABLE) == TRUE @@ -299,6 +298,7 @@ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc ################################################################################ diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 8ed950bb1c..998ecde303 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -784,7 +784,6 @@ OvmfPkg/Virtio10Dxe/Virtio10.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf OvmfPkg/VirtioScsiDxe/VirtioScsi.inf - OvmfPkg/VirtioRngDxe/VirtioRng.inf OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(PVSCSI_ENABLE) == TRUE OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -882,6 +881,7 @@ !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc !include OvmfPkg/Include/Dsc/MorLock.dsc.inc +!include OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 2d9cffb3f3..2eaf4882ed 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -232,7 +232,6 @@ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf INF OvmfPkg/Virtio10Dxe/Virtio10.inf INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf -INF OvmfPkg/VirtioRngDxe/VirtioRng.inf INF OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(PVSCSI_ENABLE) == TRUE INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -360,6 +359,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc !include OvmfPkg/Include/Fdf/MorLock.fdf.inc +!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc !if $(LOAD_X64_ON_IA32_ENABLE) == TRUE INF OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 371a53232d..603f93c5e7 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -798,7 +798,6 @@ OvmfPkg/Virtio10Dxe/Virtio10.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf OvmfPkg/VirtioScsiDxe/VirtioScsi.inf - OvmfPkg/VirtioRngDxe/VirtioRng.inf OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(PVSCSI_ENABLE) == TRUE OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -896,6 +895,7 @@ !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc !include OvmfPkg/Include/Dsc/MorLock.dsc.inc +!include OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 0de247bb12..7711d88e2c 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -233,7 +233,6 @@ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf INF OvmfPkg/Virtio10Dxe/Virtio10.inf INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf -INF OvmfPkg/VirtioRngDxe/VirtioRng.inf INF OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(PVSCSI_ENABLE) == TRUE INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -367,6 +366,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc !include OvmfPkg/Include/Fdf/MorLock.fdf.inc +!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc ################################################################################ diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index b5e433e94f..1482728a31 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -866,7 +866,6 @@ OvmfPkg/Virtio10Dxe/Virtio10.inf OvmfPkg/VirtioBlkDxe/VirtioBlk.inf OvmfPkg/VirtioScsiDxe/VirtioScsi.inf - OvmfPkg/VirtioRngDxe/VirtioRng.inf OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(PVSCSI_ENABLE) == TRUE OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -964,6 +963,7 @@ !include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc !include OvmfPkg/Include/Dsc/MorLock.dsc.inc +!include OvmfPkg/Include/Dsc/OvmfRngComponents.dsc.inc !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 4398d3f3f4..b64970582e 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -264,7 +264,6 @@ INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf INF OvmfPkg/Virtio10Dxe/Virtio10.inf INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf -INF OvmfPkg/VirtioRngDxe/VirtioRng.inf INF OvmfPkg/VirtioSerialDxe/VirtioSerial.inf !if $(PVSCSI_ENABLE) == TRUE INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -407,6 +406,7 @@ INF OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf !include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc !include OvmfPkg/Include/Fdf/MorLock.fdf.inc +!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc ################################################################################ -- cgit From af2bbe1b79251f46efaca2ed36860105272dd14f Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 31 May 2024 14:35:27 +0800 Subject: UefiCpuPkg: Add PcdCpuSmmApSyncTimeout2 PCD Provide the capability for platform to specifies the 2nd timeout value in microseconds for the BSP/AP in SMM to wait for one another to enter SMM. The added interface can enhance the flexibility of timeout configuration. In some cases, certain processors may not be able to enter SMI, and prolonged waiting could lead to kernel soft/hard lockup. We have now defined two timeouts. The first timeout can be set to a smaller value to reduce the waiting period. Processors that are unable to enter SMI will be woken up through SMIIPL to enter SMI, followed by a second waiting period. The second timeout can be set to a larger value to prevent delays in processors entering SMI case due to the long instruction execution. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/UefiCpuPkg.dec | 4 ++++ UefiCpuPkg/UefiCpuPkg.uni | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 73bae90ddb..3e91d6c195 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -370,6 +370,10 @@ # @Prompt AP synchronization timeout value in SMM. gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000000|UINT64|0x32132104 + ## Specifies the 2nd timeout value in microseconds for the BSP/AP in SMM to wait for one another to enter SMM. + # @Prompt The 2nd BSP/AP synchronization timeout value in SMM. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2|1000000|UINT64|0x32132115 + ## Indicates the CPU synchronization method used when processing an SMI. # 0x00 - Traditional CPU synchronization method.
# 0x01 - Relaxed CPU synchronization method.
diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni index d17bcfd10c..0637b8309b 100644 --- a/UefiCpuPkg/UefiCpuPkg.uni +++ b/UefiCpuPkg/UefiCpuPkg.uni @@ -3,7 +3,7 @@ // // This Package provides UEFI compatible CPU modules and libraries. // -// Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.
+// Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.
// // SPDX-License-Identifier: BSD-2-Clause-Patent // @@ -132,6 +132,10 @@ #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_HELP #language en-US "Specifies timeout value in microseconds for the BSP in SMM to wait for all APs to come into SMM." +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout2_PROMPT #language en-US "The 2nd BSP/AP synchronization timeout value in SMM" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout2_HELP #language en-US "Specifies the 2nd timeout value in microseconds for the BSP/AP in SMM to wait for one another to enter SMM." + #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmCodeAccessCheckEnable_PROMPT #language en-US "SMM Code Access Check" #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmCodeAccessCheckEnable_HELP #language en-US "Enable SMM Code Access Check? If enabled, the SMM handler cannot execute the code outside SMM regions. This PCD is suggested to TRUE in production image.

\n" -- cgit From cb3134612d11102fe066c94c8fa7edb20d62c1a8 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 31 May 2024 14:37:43 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Consume PcdCpuSmmApSyncTimeout2 This patch is to consume the PcdCpuSmmApSyncTimeout2 to enhance the flexibility of timeout configuration. In some cases, certain processors may not be able to enter SMI, and prolonged waiting could lead to kernel soft/hard lockup. We have now defined two timeouts. The first timeout can be set to a smaller value to reduce the waiting period. Processors that are unable to enter SMI will be woken up through SMIIPL to enter SMI, followed by a second waiting period. The second timeout can be set to a larger value to prevent delays in processors entering SMI case due to the long instruction execution. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 10 +++++----- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 11 ++++++++--- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c | 19 ++++++++++++++----- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 10baf3ceb9..570e99177f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -1,7 +1,7 @@ /** @file SMM MP service implementation -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -268,7 +268,7 @@ SmmWaitForApArrival ( // Sync with APs 1st timeout // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal); + !IsSyncTimerTimeout (Timer, mTimeoutTicker) && !(LmceEn && LmceSignal); ) { mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); @@ -309,7 +309,7 @@ SmmWaitForApArrival ( // Sync with APs 2nd timeout. // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer); + !IsSyncTimerTimeout (Timer, mTimeoutTicker2); ) { mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); @@ -736,7 +736,7 @@ APHandler ( // Timeout BSP // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && + !IsSyncTimerTimeout (Timer, mTimeoutTicker) && !(*mSmmMpSyncData->InsideSmm); ) { @@ -764,7 +764,7 @@ APHandler ( // Now clock BSP for the 2nd time // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && + !IsSyncTimerTimeout (Timer, mTimeoutTicker2) && !(*mSmmMpSyncData->InsideSmm); ) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 315a33d578..8409891b1d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -471,6 +471,9 @@ extern BOOLEAN mSmmDebugAgentSupport; // extern UINT64 mAddressEncMask; +extern UINT64 mTimeoutTicker; +extern UINT64 mTimeoutTicker2; + /** Create 4G PageTable in SMRAM. @@ -533,15 +536,17 @@ StartSyncTimer ( ); /** - Check if the SMM AP Sync timer is timeout. + Check if the SMM AP Sync Timer is timeout specified by Timeout. - @param Timer The start timer from the begin. + @param Timer The start timer from the begin. + @param Timeout The timeout ticker to wait. **/ BOOLEAN EFIAPI IsSyncTimerTimeout ( - IN UINT64 Timer + IN UINT64 Timer, + IN UINT64 Timeout ); /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index f0598b0364..3c4518da7b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -134,6 +134,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c index 0c070c5736..8d29ba7326 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -1,7 +1,7 @@ /** @file SMM Timer feature support -Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -9,6 +9,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuDxeSmm.h" UINT64 mTimeoutTicker = 0; + +UINT64 mTimeoutTicker2 = 0; + // // Number of counts in a roll-over cycle of the performance counter. // @@ -36,6 +39,10 @@ InitializeSmmTimer ( MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)), 1000 * 1000 ); + mTimeoutTicker2 = DivU64x32 ( + MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout2)), + 1000 * 1000 + ); if (End < Start) { mCountDown = TRUE; mCycle = Start - End; @@ -59,15 +66,17 @@ StartSyncTimer ( } /** - Check if the SMM AP Sync timer is timeout. + Check if the SMM AP Sync Timer is timeout specified by Timeout. - @param Timer The start timer from the begin. + @param Timer The start timer from the begin. + @param Timeout The timeout ticker to wait. **/ BOOLEAN EFIAPI IsSyncTimerTimeout ( - IN UINT64 Timer + IN UINT64 Timer, + IN UINT64 Timeout ) { UINT64 CurrentTimer; @@ -105,5 +114,5 @@ IsSyncTimerTimeout ( } } - return (BOOLEAN)(Delta >= mTimeoutTicker); + return (BOOLEAN)(Delta >= Timeout); } -- cgit From 870c1ae253f56703d1e92144940831ebcbcca04c Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 31 May 2024 14:43:37 +0800 Subject: UefiCpuPkg: Refine the PCD usage comment PcdCpuSmmApSyncTimeout is not only used by BSP to wait AP, but also for AP to wait BSP (APHandler). This patch is only to refine the PCD comment. No function impact. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/UefiCpuPkg.dec | 4 ++-- UefiCpuPkg/UefiCpuPkg.uni | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 3e91d6c195..c026cf535b 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -366,8 +366,8 @@ # @Prompt The specified AP target C-state for Mwait. gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0|UINT8|0x00000007 - ## Specifies timeout value in microseconds for the BSP in SMM to wait for all APs to come into SMM. - # @Prompt AP synchronization timeout value in SMM. + ## Specifies the 1st timeout value in microseconds for the BSP/AP in SMM to wait for one another to enter SMM. + # @Prompt The 1st BSP/AP synchronization timeout value in SMM. gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000000|UINT64|0x32132104 ## Specifies the 2nd timeout value in microseconds for the BSP/AP in SMM to wait for one another to enter SMM. diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni index 0637b8309b..25a7176194 100644 --- a/UefiCpuPkg/UefiCpuPkg.uni +++ b/UefiCpuPkg/UefiCpuPkg.uni @@ -128,9 +128,9 @@ #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmShadowStackSize_HELP #language en-US "Specifies shadow stack size in bytes for each processor in SMM." -#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_PROMPT #language en-US "AP synchronization timeout value in SMM" +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_PROMPT #language en-US "The 1st BSP/AP synchronization timeout value in SMM." -#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_HELP #language en-US "Specifies timeout value in microseconds for the BSP in SMM to wait for all APs to come into SMM." +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_HELP #language en-US "Specifies the 1st timeout value in microseconds for the BSP/AP in SMM to wait for one another to enter SMM." #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout2_PROMPT #language en-US "The 2nd BSP/AP synchronization timeout value in SMM" -- cgit From ce91687a1b2d4e03b01abb474b4665629776f588 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Tue, 11 Jun 2024 20:31:12 +0800 Subject: OvmfPkg: Override PcdCpuSmmApSyncTimeout2 to 10ms PcdCpuSmmApSyncTimeout2 PCD was added in previous patch (52d0a208), this patch is to override PcdCpuSmmApSyncTimeout2 to 10ms (same as PcdCpuSmmApSyncTimeout) so as to align with original behavior. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Ray Ni Signed-off-by: Jiaxin Wu --- OvmfPkg/CloudHv/CloudHvX64.dsc | 3 ++- OvmfPkg/OvmfPkgIa32.dsc | 3 ++- OvmfPkg/OvmfPkgIa32X64.dsc | 3 ++- OvmfPkg/OvmfPkgX64.dsc | 3 ++- OvmfPkg/SmmControl2Dxe/SmiFeatures.c | 2 ++ OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf | 6 ++++-- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc index 4996885301..0ad495545c 100644 --- a/OvmfPkg/CloudHv/CloudHvX64.dsc +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc @@ -1,7 +1,7 @@ ## @file # EFI/Framework Open Virtual Machine Firmware (OVMF) platform # -# Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# Copyright (c) Microsoft Corporation. # @@ -625,6 +625,7 @@ !if $(SMM_REQUIRE) == TRUE gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2|100000 !endif gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00 diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 998ecde303..bd6e8abbcb 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -1,7 +1,7 @@ ## @file # EFI/Framework Open Virtual Machine Firmware (OVMF) platform # -# Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# Copyright (c) Microsoft Corporation. # @@ -651,6 +651,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2|100000 !endif gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00 diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 603f93c5e7..f28049a36a 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -1,7 +1,7 @@ ## @file # EFI/Framework Open Virtual Machine Firmware (OVMF) platform # -# Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# Copyright (c) Microsoft Corporation. # Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved.
@@ -663,6 +663,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2|100000 !endif gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00 diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 1482728a31..f131328932 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -1,7 +1,7 @@ ## @file # EFI/Framework Open Virtual Machine Firmware (OVMF) platform # -# Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# Copyright (c) Microsoft Corporation. # @@ -683,6 +683,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2|100000 !endif gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00 diff --git a/OvmfPkg/SmmControl2Dxe/SmiFeatures.c b/OvmfPkg/SmmControl2Dxe/SmiFeatures.c index 4bd24bf119..b5a9590d23 100644 --- a/OvmfPkg/SmmControl2Dxe/SmiFeatures.c +++ b/OvmfPkg/SmmControl2Dxe/SmiFeatures.c @@ -3,6 +3,7 @@ accordingly. Copyright (C) 2016-2017, Red Hat, Inc. + Copyright (c) 2024, Intel Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -187,6 +188,7 @@ NegotiateSmiFeatures ( // the original QEMU behavior (i.e., unicast SMI) used to differ. // if (RETURN_ERROR (PcdSet64S (PcdCpuSmmApSyncTimeout, 1000000)) || + RETURN_ERROR (PcdSet64S (PcdCpuSmmApSyncTimeout2, 1000000)) || RETURN_ERROR (PcdSet8S (PcdCpuSmmSyncMode, 0x00))) { DEBUG (( diff --git a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf index 4cad56516f..d20198cab7 100644 --- a/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf +++ b/OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf @@ -12,6 +12,7 @@ # configuring it. # # Copyright (C) 2013, 2015, Red Hat, Inc. +# Copyright (c) 2024, Intel Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -61,8 +62,9 @@ gEfiSmmControl2ProtocolGuid ## PRODUCES [Pcd] - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## SOMETIMES_PRODUCES - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## SOMETIMES_PRODUCES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## SOMETIMES_PRODUCES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## SOMETIMES_PRODUCES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## SOMETIMES_PRODUCES gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable [FeaturePcd] -- cgit From 94961b8817eec6f8d0434555ac50a7aa51c22201 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 14 Jun 2024 11:45:49 +0200 Subject: CryptoPkg/Test: call ProcessLibraryConstructorList Needed to properly initialize BaseRngLib. Signed-off-by: Gerd Hoffmann --- CryptoPkg/Test/UnitTest/Library/BaseCryptLib/UnitTestMain.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/UnitTestMain.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/UnitTestMain.c index d0c1c7a4f7..48d463b8ad 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/UnitTestMain.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/UnitTestMain.c @@ -8,6 +8,12 @@ **/ #include "TestBaseCryptLib.h" +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + /** Initialize the unit test framework, suite, and unit tests for the sample unit tests and run the unit tests. @@ -76,5 +82,6 @@ main ( char *argv[] ) { + ProcessLibraryConstructorList (); return UefiTestMain (); } -- cgit From 5e776299a2604b336a947e68593012ab2cc16eb4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 14 Jun 2024 11:45:53 +0200 Subject: MdePkg/X86UnitTestHost: set rdrand cpuid bit Set the rdrand feature bit when faking cpuid for host test cases. Needed to make the CryptoPkg test cases work. Signed-off-by: Gerd Hoffmann --- MdePkg/Library/BaseLib/X86UnitTestHost.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MdePkg/Library/BaseLib/X86UnitTestHost.c b/MdePkg/Library/BaseLib/X86UnitTestHost.c index 8ba4f54a38..7f7276f7f4 100644 --- a/MdePkg/Library/BaseLib/X86UnitTestHost.c +++ b/MdePkg/Library/BaseLib/X86UnitTestHost.c @@ -66,6 +66,15 @@ UnitTestHostBaseLibAsmCpuid ( OUT UINT32 *Edx OPTIONAL ) { + UINT32 RetEcx; + + RetEcx = 0; + switch (Index) { + case 1: + RetEcx |= BIT30; /* RdRand */ + break; + } + if (Eax != NULL) { *Eax = 0; } @@ -75,7 +84,7 @@ UnitTestHostBaseLibAsmCpuid ( } if (Ecx != NULL) { - *Ecx = 0; + *Ecx = RetEcx; } if (Edx != NULL) { -- cgit From f2b9d5417dccf763bcbb68cd0effed0e25890aab Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Tue, 21 Nov 2023 16:42:28 +0000 Subject: ArmPkg,MdePkg: move ArmLib.h to MdePkg Related to https://bugzilla.tianocore.org/show_bug.cgi?id=4121, but not resolving it. (Nearly?) all of ArmPkg describes industry standard behaviour, and hence according to general rules, ought to live in MdePkg. Addressing this will however be a substantial task. Take a first step by moving the ArmLib interface definition to MdePkg, as discussed in https://edk2.groups.io/g/devel/topic/patch_v5_2_6/102725178 Continuous-integration-options: PatchCheck.ignore-multi-package Cc: Pierre Gondois Cc: Jiewen Yao Cc: Ard Biesheuvel Cc: Liming Gao Cc: Michael D Kinney Cc: Sami Mujawar Cc: Zhiguang Liu Signed-off-by: Pierre Gondois --- ArmPkg/ArmPkg.dec | 4 - ArmPkg/Include/Library/ArmLib.h | 829 ---------------------------------------- Maintainers.txt | 6 + MdePkg/Include/Library/ArmLib.h | 829 ++++++++++++++++++++++++++++++++++++++++ MdePkg/MdePkg.dec | 5 + 5 files changed, 840 insertions(+), 833 deletions(-) delete mode 100644 ArmPkg/Include/Library/ArmLib.h create mode 100644 MdePkg/Include/Library/ArmLib.h diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 7fe2b9bca4..4ce59f3e1f 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -50,10 +50,6 @@ # ArmHvcLib|Include/Library/ArmHvcLib.h - ## @libraryclass Provides an interface to Arm registers. - # - ArmLib|Include/Library/ArmLib.h - ## @libraryclass Provides a Mmu interface. # ArmMmuLib|Include/Library/ArmMmuLib.h diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h deleted file mode 100644 index 6aa8a48f07..0000000000 --- a/ArmPkg/Include/Library/ArmLib.h +++ /dev/null @@ -1,829 +0,0 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.
- Copyright (c) 2020 - 2021, NUVIA Inc. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef ARM_LIB_H_ -#define ARM_LIB_H_ - -#include - -#ifdef MDE_CPU_ARM - #include -#elif defined (MDE_CPU_AARCH64) - #include -#else - #error "Unknown chipset." -#endif - -#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | \ - EFI_MEMORY_WT | EFI_MEMORY_WB | \ - EFI_MEMORY_UCE) - -typedef enum { - ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED = 0, - ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, - - // On some platforms, memory mapped flash region is designed as not supporting - // shareable attribute, so WRITE_BACK_NONSHAREABLE is added for such special - // need. - // Do NOT use below two attributes if you are not sure. - ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE, - - // Special region types for memory that must be mapped with read-only or - // non-execute permissions from the very start, e.g., to support the use - // of the WXN virtual memory control. - ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO, - ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP, - - ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH, - ARM_MEMORY_REGION_ATTRIBUTE_DEVICE, -} ARM_MEMORY_REGION_ATTRIBUTES; - -typedef struct { - EFI_PHYSICAL_ADDRESS PhysicalBase; - EFI_VIRTUAL_ADDRESS VirtualBase; - UINT64 Length; - ARM_MEMORY_REGION_ATTRIBUTES Attributes; -} ARM_MEMORY_REGION_DESCRIPTOR; - -typedef VOID (*CACHE_OPERATION)( - VOID - ); -typedef VOID (*LINE_OPERATION)( - UINTN - ); - -// -// ARM Processor Mode -// -typedef enum { - ARM_PROCESSOR_MODE_USER = 0x10, - ARM_PROCESSOR_MODE_FIQ = 0x11, - ARM_PROCESSOR_MODE_IRQ = 0x12, - ARM_PROCESSOR_MODE_SUPERVISOR = 0x13, - ARM_PROCESSOR_MODE_ABORT = 0x17, - ARM_PROCESSOR_MODE_HYP = 0x1A, - ARM_PROCESSOR_MODE_UNDEFINED = 0x1B, - ARM_PROCESSOR_MODE_SYSTEM = 0x1F, - ARM_PROCESSOR_MODE_MASK = 0x1F -} ARM_PROCESSOR_MODE; - -// -// ARM Cpu IDs -// -#define ARM_CPU_IMPLEMENTER_MASK (0xFFU << 24) -#define ARM_CPU_IMPLEMENTER_ARMLTD (0x41U << 24) -#define ARM_CPU_IMPLEMENTER_DEC (0x44U << 24) -#define ARM_CPU_IMPLEMENTER_MOT (0x4DU << 24) -#define ARM_CPU_IMPLEMENTER_QUALCOMM (0x51U << 24) -#define ARM_CPU_IMPLEMENTER_MARVELL (0x56U << 24) - -#define ARM_CPU_PRIMARY_PART_MASK (0xFFF << 4) -#define ARM_CPU_PRIMARY_PART_CORTEXA5 (0xC05 << 4) -#define ARM_CPU_PRIMARY_PART_CORTEXA7 (0xC07 << 4) -#define ARM_CPU_PRIMARY_PART_CORTEXA8 (0xC08 << 4) -#define ARM_CPU_PRIMARY_PART_CORTEXA9 (0xC09 << 4) -#define ARM_CPU_PRIMARY_PART_CORTEXA15 (0xC0F << 4) - -// -// ARM MP Core IDs -// -#define ARM_CORE_AFF0 0xFF -#define ARM_CORE_AFF1 (0xFF << 8) -#define ARM_CORE_AFF2 (0xFF << 16) -#define ARM_CORE_AFF3 (0xFFULL << 32) - -#define ARM_CORE_MASK ARM_CORE_AFF0 -#define ARM_CLUSTER_MASK ARM_CORE_AFF1 -#define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK) -#define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8) -#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId)) -#define GET_MPIDR_AFF0(MpId) ((MpId) & ARM_CORE_AFF0) -#define GET_MPIDR_AFF1(MpId) (((MpId) & ARM_CORE_AFF1) >> 8) -#define GET_MPIDR_AFF2(MpId) (((MpId) & ARM_CORE_AFF2) >> 16) -#define GET_MPIDR_AFF3(MpId) (((MpId) & ARM_CORE_AFF3) >> 32) -#define GET_MPIDR_AFFINITY_BITS(MpId) ((MpId) & 0xFF00FFFFFF) -#define PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK) -#define MPIDR_MT_BIT BIT24 - -/** Reads the CCSIDR register for the specified cache. - - @param CSSELR The CSSELR cache selection register value. - - @return The contents of the CCSIDR_EL1 register for the specified cache, when in AARCH64 mode. - Returns the contents of the CCSIDR register in AARCH32 mode. -**/ -UINTN -ReadCCSIDR ( - IN UINT32 CSSELR - ); - -/** Reads the CCSIDR2 for the specified cache. - - @param CSSELR The CSSELR cache selection register value - - @return The contents of the CCSIDR2 register for the specified cache. -**/ -UINT32 -ReadCCSIDR2 ( - IN UINT32 CSSELR - ); - -/** Reads the Cache Level ID (CLIDR) register. - - @return The contents of the CLIDR_EL1 register. -**/ -UINT32 -ReadCLIDR ( - VOID - ); - -UINTN -EFIAPI -ArmDataCacheLineLength ( - VOID - ); - -UINTN -EFIAPI -ArmInstructionCacheLineLength ( - VOID - ); - -UINTN -EFIAPI -ArmCacheWritebackGranule ( - VOID - ); - -UINTN -EFIAPI -ArmIsArchTimerImplemented ( - VOID - ); - -UINTN -EFIAPI -ArmCacheInfo ( - VOID - ); - -BOOLEAN -EFIAPI -ArmIsMpCore ( - VOID - ); - -VOID -EFIAPI -ArmInvalidateDataCache ( - VOID - ); - -VOID -EFIAPI -ArmCleanInvalidateDataCache ( - VOID - ); - -VOID -EFIAPI -ArmCleanDataCache ( - VOID - ); - -VOID -EFIAPI -ArmInvalidateInstructionCache ( - VOID - ); - -VOID -EFIAPI -ArmInvalidateDataCacheEntryByMVA ( - IN UINTN Address - ); - -VOID -EFIAPI -ArmCleanDataCacheEntryToPoUByMVA ( - IN UINTN Address - ); - -VOID -EFIAPI -ArmInvalidateInstructionCacheEntryToPoUByMVA ( - IN UINTN Address - ); - -VOID -EFIAPI -ArmCleanDataCacheEntryByMVA ( - IN UINTN Address - ); - -VOID -EFIAPI -ArmCleanInvalidateDataCacheEntryByMVA ( - IN UINTN Address - ); - -VOID -EFIAPI -ArmEnableDataCache ( - VOID - ); - -VOID -EFIAPI -ArmDisableDataCache ( - VOID - ); - -VOID -EFIAPI -ArmEnableInstructionCache ( - VOID - ); - -VOID -EFIAPI -ArmDisableInstructionCache ( - VOID - ); - -VOID -EFIAPI -ArmEnableMmu ( - VOID - ); - -VOID -EFIAPI -ArmDisableMmu ( - VOID - ); - -VOID -EFIAPI -ArmEnableCachesAndMmu ( - VOID - ); - -VOID -EFIAPI -ArmDisableCachesAndMmu ( - VOID - ); - -VOID -EFIAPI -ArmEnableInterrupts ( - VOID - ); - -UINTN -EFIAPI -ArmDisableInterrupts ( - VOID - ); - -BOOLEAN -EFIAPI -ArmGetInterruptState ( - VOID - ); - -VOID -EFIAPI -ArmEnableAsynchronousAbort ( - VOID - ); - -UINTN -EFIAPI -ArmDisableAsynchronousAbort ( - VOID - ); - -VOID -EFIAPI -ArmEnableIrq ( - VOID - ); - -UINTN -EFIAPI -ArmDisableIrq ( - VOID - ); - -VOID -EFIAPI -ArmEnableFiq ( - VOID - ); - -UINTN -EFIAPI -ArmDisableFiq ( - VOID - ); - -BOOLEAN -EFIAPI -ArmGetFiqState ( - VOID - ); - -/** - * Invalidate Data and Instruction TLBs - */ -VOID -EFIAPI -ArmInvalidateTlb ( - VOID - ); - -VOID -EFIAPI -ArmUpdateTranslationTableEntry ( - IN VOID *TranslationTableEntry, - IN VOID *Mva - ); - -VOID -EFIAPI -ArmSetDomainAccessControl ( - IN UINT32 Domain - ); - -VOID -EFIAPI -ArmSetTTBR0 ( - IN VOID *TranslationTableBase - ); - -VOID -EFIAPI -ArmSetTTBCR ( - IN UINT32 Bits - ); - -VOID * -EFIAPI -ArmGetTTBR0BaseAddress ( - VOID - ); - -BOOLEAN -EFIAPI -ArmMmuEnabled ( - VOID - ); - -VOID -EFIAPI -ArmEnableBranchPrediction ( - VOID - ); - -VOID -EFIAPI -ArmDisableBranchPrediction ( - VOID - ); - -VOID -EFIAPI -ArmSetLowVectors ( - VOID - ); - -VOID -EFIAPI -ArmSetHighVectors ( - VOID - ); - -VOID -EFIAPI -ArmDataMemoryBarrier ( - VOID - ); - -VOID -EFIAPI -ArmDataSynchronizationBarrier ( - VOID - ); - -VOID -EFIAPI -ArmInstructionSynchronizationBarrier ( - VOID - ); - -VOID -EFIAPI -ArmWriteVBar ( - IN UINTN VectorBase - ); - -UINTN -EFIAPI -ArmReadVBar ( - VOID - ); - -VOID -EFIAPI -ArmWriteAuxCr ( - IN UINT32 Bit - ); - -UINT32 -EFIAPI -ArmReadAuxCr ( - VOID - ); - -VOID -EFIAPI -ArmSetAuxCrBit ( - IN UINT32 Bits - ); - -VOID -EFIAPI -ArmUnsetAuxCrBit ( - IN UINT32 Bits - ); - -VOID -EFIAPI -ArmCallSEV ( - VOID - ); - -VOID -EFIAPI -ArmCallWFE ( - VOID - ); - -VOID -EFIAPI -ArmCallWFI ( - - VOID - ); - -UINTN -EFIAPI -ArmReadMpidr ( - VOID - ); - -UINTN -EFIAPI -ArmReadMidr ( - VOID - ); - -UINT32 -EFIAPI -ArmReadCpacr ( - VOID - ); - -VOID -EFIAPI -ArmWriteCpacr ( - IN UINT32 Access - ); - -VOID -EFIAPI -ArmEnableVFP ( - VOID - ); - -/** - Get the Secure Configuration Register value - - @return Value read from the Secure Configuration Register - -**/ -UINT32 -EFIAPI -ArmReadScr ( - VOID - ); - -/** - Set the Secure Configuration Register - - @param Value Value to write to the Secure Configuration Register - -**/ -VOID -EFIAPI -ArmWriteScr ( - IN UINT32 Value - ); - -UINT32 -EFIAPI -ArmReadMVBar ( - VOID - ); - -VOID -EFIAPI -ArmWriteMVBar ( - IN UINT32 VectorMonitorBase - ); - -UINT32 -EFIAPI -ArmReadSctlr ( - VOID - ); - -VOID -EFIAPI -ArmWriteSctlr ( - IN UINT32 Value - ); - -UINTN -EFIAPI -ArmReadHVBar ( - VOID - ); - -VOID -EFIAPI -ArmWriteHVBar ( - IN UINTN HypModeVectorBase - ); - -// -// Helper functions for accessing CPU ACTLR -// - -UINTN -EFIAPI -ArmReadCpuActlr ( - VOID - ); - -VOID -EFIAPI -ArmWriteCpuActlr ( - IN UINTN Val - ); - -VOID -EFIAPI -ArmSetCpuActlrBit ( - IN UINTN Bits - ); - -VOID -EFIAPI -ArmUnsetCpuActlrBit ( - IN UINTN Bits - ); - -// -// Accessors for the architected generic timer registers -// - -#define ARM_ARCH_TIMER_ENABLE (1 << 0) -#define ARM_ARCH_TIMER_IMASK (1 << 1) -#define ARM_ARCH_TIMER_ISTATUS (1 << 2) - -UINTN -EFIAPI -ArmReadCntFrq ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntFrq ( - UINTN FreqInHz - ); - -UINT64 -EFIAPI -ArmReadCntPct ( - VOID - ); - -UINTN -EFIAPI -ArmReadCntkCtl ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntkCtl ( - UINTN Val - ); - -UINTN -EFIAPI -ArmReadCntpTval ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntpTval ( - UINTN Val - ); - -UINTN -EFIAPI -ArmReadCntpCtl ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntpCtl ( - UINTN Val - ); - -UINTN -EFIAPI -ArmReadCntvTval ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntvTval ( - UINTN Val - ); - -UINTN -EFIAPI -ArmReadCntvCtl ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntvCtl ( - UINTN Val - ); - -UINT64 -EFIAPI -ArmReadCntvCt ( - VOID - ); - -UINT64 -EFIAPI -ArmReadCntpCval ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntpCval ( - UINT64 Val - ); - -UINT64 -EFIAPI -ArmReadCntvCval ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntvCval ( - UINT64 Val - ); - -UINT64 -EFIAPI -ArmReadCntvOff ( - VOID - ); - -VOID -EFIAPI -ArmWriteCntvOff ( - UINT64 Val - ); - -UINTN -EFIAPI -ArmGetPhysicalAddressBits ( - VOID - ); - -/// -/// ID Register Helper functions -/// - -/** - Check whether the CPU supports the GIC system register interface (any version) - - @return Whether GIC System Register Interface is supported - -**/ -BOOLEAN -EFIAPI -ArmHasGicSystemRegisters ( - VOID - ); - -/** Checks if CCIDX is implemented. - - @retval TRUE CCIDX is implemented. - @retval FALSE CCIDX is not implemented. -**/ -BOOLEAN -EFIAPI -ArmHasCcidx ( - VOID - ); - -#ifdef MDE_CPU_AARCH64 -/// -/// AArch64-only ID Register Helper functions -/// - -/** - Checks whether the CPU implements the Virtualization Host Extensions. - - @retval TRUE FEAT_VHE is implemented. - @retval FALSE FEAT_VHE is not mplemented. -**/ -BOOLEAN -EFIAPI -ArmHasVhe ( - VOID - ); - -/** - Checks whether the CPU implements the Trace Buffer Extension. - - @retval TRUE FEAT_TRBE is implemented. - @retval FALSE FEAT_TRBE is not mplemented. -**/ -BOOLEAN -EFIAPI -ArmHasTrbe ( - VOID - ); - -/** - Checks whether the CPU implements the Embedded Trace Extension. - - @retval TRUE FEAT_ETE is implemented. - @retval FALSE FEAT_ETE is not mplemented. -**/ -BOOLEAN -EFIAPI -ArmHasEte ( - VOID - ); - -#endif // MDE_CPU_AARCH64 - -#ifdef MDE_CPU_ARM -/// -/// AArch32-only ID Register Helper functions -/// - -/** - Check whether the CPU supports the Security extensions - - @return Whether the Security extensions are implemented - -**/ -BOOLEAN -EFIAPI -ArmHasSecurityExtensions ( - VOID - ); - -#endif // MDE_CPU_ARM - -#endif // ARM_LIB_H_ diff --git a/Maintainers.txt b/Maintainers.txt index 274554a2c5..6f91c218b4 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -461,6 +461,12 @@ F: MdePkg/Include/IndustryStandard/SpiNorFlashJedecSfdp.h M: Abner Chang [changab] R: Brit Chesley [BritChesley] +MdePkg: ARM/AARCH64 standard interfaces +F: MdePkg/Include/Library/ArmLib.h +M: Leif Lindholm [leiflindholm] +M: Ard Biesheuvel [ardbiesheuvel] +R: Sami Mujawar [samimujawar] + NetworkPkg F: NetworkPkg/ W: https://github.com/tianocore/tianocore.github.io/wiki/NetworkPkg diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h new file mode 100644 index 0000000000..6aa8a48f07 --- /dev/null +++ b/MdePkg/Include/Library/ArmLib.h @@ -0,0 +1,829 @@ +/** @file + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.
+ Copyright (c) 2020 - 2021, NUVIA Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef ARM_LIB_H_ +#define ARM_LIB_H_ + +#include + +#ifdef MDE_CPU_ARM + #include +#elif defined (MDE_CPU_AARCH64) + #include +#else + #error "Unknown chipset." +#endif + +#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | \ + EFI_MEMORY_WT | EFI_MEMORY_WB | \ + EFI_MEMORY_UCE) + +typedef enum { + ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED = 0, + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, + + // On some platforms, memory mapped flash region is designed as not supporting + // shareable attribute, so WRITE_BACK_NONSHAREABLE is added for such special + // need. + // Do NOT use below two attributes if you are not sure. + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE, + + // Special region types for memory that must be mapped with read-only or + // non-execute permissions from the very start, e.g., to support the use + // of the WXN virtual memory control. + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_RO, + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP, + + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH, + ARM_MEMORY_REGION_ATTRIBUTE_DEVICE, +} ARM_MEMORY_REGION_ATTRIBUTES; + +typedef struct { + EFI_PHYSICAL_ADDRESS PhysicalBase; + EFI_VIRTUAL_ADDRESS VirtualBase; + UINT64 Length; + ARM_MEMORY_REGION_ATTRIBUTES Attributes; +} ARM_MEMORY_REGION_DESCRIPTOR; + +typedef VOID (*CACHE_OPERATION)( + VOID + ); +typedef VOID (*LINE_OPERATION)( + UINTN + ); + +// +// ARM Processor Mode +// +typedef enum { + ARM_PROCESSOR_MODE_USER = 0x10, + ARM_PROCESSOR_MODE_FIQ = 0x11, + ARM_PROCESSOR_MODE_IRQ = 0x12, + ARM_PROCESSOR_MODE_SUPERVISOR = 0x13, + ARM_PROCESSOR_MODE_ABORT = 0x17, + ARM_PROCESSOR_MODE_HYP = 0x1A, + ARM_PROCESSOR_MODE_UNDEFINED = 0x1B, + ARM_PROCESSOR_MODE_SYSTEM = 0x1F, + ARM_PROCESSOR_MODE_MASK = 0x1F +} ARM_PROCESSOR_MODE; + +// +// ARM Cpu IDs +// +#define ARM_CPU_IMPLEMENTER_MASK (0xFFU << 24) +#define ARM_CPU_IMPLEMENTER_ARMLTD (0x41U << 24) +#define ARM_CPU_IMPLEMENTER_DEC (0x44U << 24) +#define ARM_CPU_IMPLEMENTER_MOT (0x4DU << 24) +#define ARM_CPU_IMPLEMENTER_QUALCOMM (0x51U << 24) +#define ARM_CPU_IMPLEMENTER_MARVELL (0x56U << 24) + +#define ARM_CPU_PRIMARY_PART_MASK (0xFFF << 4) +#define ARM_CPU_PRIMARY_PART_CORTEXA5 (0xC05 << 4) +#define ARM_CPU_PRIMARY_PART_CORTEXA7 (0xC07 << 4) +#define ARM_CPU_PRIMARY_PART_CORTEXA8 (0xC08 << 4) +#define ARM_CPU_PRIMARY_PART_CORTEXA9 (0xC09 << 4) +#define ARM_CPU_PRIMARY_PART_CORTEXA15 (0xC0F << 4) + +// +// ARM MP Core IDs +// +#define ARM_CORE_AFF0 0xFF +#define ARM_CORE_AFF1 (0xFF << 8) +#define ARM_CORE_AFF2 (0xFF << 16) +#define ARM_CORE_AFF3 (0xFFULL << 32) + +#define ARM_CORE_MASK ARM_CORE_AFF0 +#define ARM_CLUSTER_MASK ARM_CORE_AFF1 +#define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK) +#define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8) +#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId)) +#define GET_MPIDR_AFF0(MpId) ((MpId) & ARM_CORE_AFF0) +#define GET_MPIDR_AFF1(MpId) (((MpId) & ARM_CORE_AFF1) >> 8) +#define GET_MPIDR_AFF2(MpId) (((MpId) & ARM_CORE_AFF2) >> 16) +#define GET_MPIDR_AFF3(MpId) (((MpId) & ARM_CORE_AFF3) >> 32) +#define GET_MPIDR_AFFINITY_BITS(MpId) ((MpId) & 0xFF00FFFFFF) +#define PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK) +#define MPIDR_MT_BIT BIT24 + +/** Reads the CCSIDR register for the specified cache. + + @param CSSELR The CSSELR cache selection register value. + + @return The contents of the CCSIDR_EL1 register for the specified cache, when in AARCH64 mode. + Returns the contents of the CCSIDR register in AARCH32 mode. +**/ +UINTN +ReadCCSIDR ( + IN UINT32 CSSELR + ); + +/** Reads the CCSIDR2 for the specified cache. + + @param CSSELR The CSSELR cache selection register value + + @return The contents of the CCSIDR2 register for the specified cache. +**/ +UINT32 +ReadCCSIDR2 ( + IN UINT32 CSSELR + ); + +/** Reads the Cache Level ID (CLIDR) register. + + @return The contents of the CLIDR_EL1 register. +**/ +UINT32 +ReadCLIDR ( + VOID + ); + +UINTN +EFIAPI +ArmDataCacheLineLength ( + VOID + ); + +UINTN +EFIAPI +ArmInstructionCacheLineLength ( + VOID + ); + +UINTN +EFIAPI +ArmCacheWritebackGranule ( + VOID + ); + +UINTN +EFIAPI +ArmIsArchTimerImplemented ( + VOID + ); + +UINTN +EFIAPI +ArmCacheInfo ( + VOID + ); + +BOOLEAN +EFIAPI +ArmIsMpCore ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateDataCache ( + VOID + ); + +VOID +EFIAPI +ArmCleanInvalidateDataCache ( + VOID + ); + +VOID +EFIAPI +ArmCleanDataCache ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateInstructionCache ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateDataCacheEntryByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmCleanDataCacheEntryToPoUByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmInvalidateInstructionCacheEntryToPoUByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmCleanDataCacheEntryByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmCleanInvalidateDataCacheEntryByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmEnableDataCache ( + VOID + ); + +VOID +EFIAPI +ArmDisableDataCache ( + VOID + ); + +VOID +EFIAPI +ArmEnableInstructionCache ( + VOID + ); + +VOID +EFIAPI +ArmDisableInstructionCache ( + VOID + ); + +VOID +EFIAPI +ArmEnableMmu ( + VOID + ); + +VOID +EFIAPI +ArmDisableMmu ( + VOID + ); + +VOID +EFIAPI +ArmEnableCachesAndMmu ( + VOID + ); + +VOID +EFIAPI +ArmDisableCachesAndMmu ( + VOID + ); + +VOID +EFIAPI +ArmEnableInterrupts ( + VOID + ); + +UINTN +EFIAPI +ArmDisableInterrupts ( + VOID + ); + +BOOLEAN +EFIAPI +ArmGetInterruptState ( + VOID + ); + +VOID +EFIAPI +ArmEnableAsynchronousAbort ( + VOID + ); + +UINTN +EFIAPI +ArmDisableAsynchronousAbort ( + VOID + ); + +VOID +EFIAPI +ArmEnableIrq ( + VOID + ); + +UINTN +EFIAPI +ArmDisableIrq ( + VOID + ); + +VOID +EFIAPI +ArmEnableFiq ( + VOID + ); + +UINTN +EFIAPI +ArmDisableFiq ( + VOID + ); + +BOOLEAN +EFIAPI +ArmGetFiqState ( + VOID + ); + +/** + * Invalidate Data and Instruction TLBs + */ +VOID +EFIAPI +ArmInvalidateTlb ( + VOID + ); + +VOID +EFIAPI +ArmUpdateTranslationTableEntry ( + IN VOID *TranslationTableEntry, + IN VOID *Mva + ); + +VOID +EFIAPI +ArmSetDomainAccessControl ( + IN UINT32 Domain + ); + +VOID +EFIAPI +ArmSetTTBR0 ( + IN VOID *TranslationTableBase + ); + +VOID +EFIAPI +ArmSetTTBCR ( + IN UINT32 Bits + ); + +VOID * +EFIAPI +ArmGetTTBR0BaseAddress ( + VOID + ); + +BOOLEAN +EFIAPI +ArmMmuEnabled ( + VOID + ); + +VOID +EFIAPI +ArmEnableBranchPrediction ( + VOID + ); + +VOID +EFIAPI +ArmDisableBranchPrediction ( + VOID + ); + +VOID +EFIAPI +ArmSetLowVectors ( + VOID + ); + +VOID +EFIAPI +ArmSetHighVectors ( + VOID + ); + +VOID +EFIAPI +ArmDataMemoryBarrier ( + VOID + ); + +VOID +EFIAPI +ArmDataSynchronizationBarrier ( + VOID + ); + +VOID +EFIAPI +ArmInstructionSynchronizationBarrier ( + VOID + ); + +VOID +EFIAPI +ArmWriteVBar ( + IN UINTN VectorBase + ); + +UINTN +EFIAPI +ArmReadVBar ( + VOID + ); + +VOID +EFIAPI +ArmWriteAuxCr ( + IN UINT32 Bit + ); + +UINT32 +EFIAPI +ArmReadAuxCr ( + VOID + ); + +VOID +EFIAPI +ArmSetAuxCrBit ( + IN UINT32 Bits + ); + +VOID +EFIAPI +ArmUnsetAuxCrBit ( + IN UINT32 Bits + ); + +VOID +EFIAPI +ArmCallSEV ( + VOID + ); + +VOID +EFIAPI +ArmCallWFE ( + VOID + ); + +VOID +EFIAPI +ArmCallWFI ( + + VOID + ); + +UINTN +EFIAPI +ArmReadMpidr ( + VOID + ); + +UINTN +EFIAPI +ArmReadMidr ( + VOID + ); + +UINT32 +EFIAPI +ArmReadCpacr ( + VOID + ); + +VOID +EFIAPI +ArmWriteCpacr ( + IN UINT32 Access + ); + +VOID +EFIAPI +ArmEnableVFP ( + VOID + ); + +/** + Get the Secure Configuration Register value + + @return Value read from the Secure Configuration Register + +**/ +UINT32 +EFIAPI +ArmReadScr ( + VOID + ); + +/** + Set the Secure Configuration Register + + @param Value Value to write to the Secure Configuration Register + +**/ +VOID +EFIAPI +ArmWriteScr ( + IN UINT32 Value + ); + +UINT32 +EFIAPI +ArmReadMVBar ( + VOID + ); + +VOID +EFIAPI +ArmWriteMVBar ( + IN UINT32 VectorMonitorBase + ); + +UINT32 +EFIAPI +ArmReadSctlr ( + VOID + ); + +VOID +EFIAPI +ArmWriteSctlr ( + IN UINT32 Value + ); + +UINTN +EFIAPI +ArmReadHVBar ( + VOID + ); + +VOID +EFIAPI +ArmWriteHVBar ( + IN UINTN HypModeVectorBase + ); + +// +// Helper functions for accessing CPU ACTLR +// + +UINTN +EFIAPI +ArmReadCpuActlr ( + VOID + ); + +VOID +EFIAPI +ArmWriteCpuActlr ( + IN UINTN Val + ); + +VOID +EFIAPI +ArmSetCpuActlrBit ( + IN UINTN Bits + ); + +VOID +EFIAPI +ArmUnsetCpuActlrBit ( + IN UINTN Bits + ); + +// +// Accessors for the architected generic timer registers +// + +#define ARM_ARCH_TIMER_ENABLE (1 << 0) +#define ARM_ARCH_TIMER_IMASK (1 << 1) +#define ARM_ARCH_TIMER_ISTATUS (1 << 2) + +UINTN +EFIAPI +ArmReadCntFrq ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntFrq ( + UINTN FreqInHz + ); + +UINT64 +EFIAPI +ArmReadCntPct ( + VOID + ); + +UINTN +EFIAPI +ArmReadCntkCtl ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntkCtl ( + UINTN Val + ); + +UINTN +EFIAPI +ArmReadCntpTval ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntpTval ( + UINTN Val + ); + +UINTN +EFIAPI +ArmReadCntpCtl ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntpCtl ( + UINTN Val + ); + +UINTN +EFIAPI +ArmReadCntvTval ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntvTval ( + UINTN Val + ); + +UINTN +EFIAPI +ArmReadCntvCtl ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntvCtl ( + UINTN Val + ); + +UINT64 +EFIAPI +ArmReadCntvCt ( + VOID + ); + +UINT64 +EFIAPI +ArmReadCntpCval ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntpCval ( + UINT64 Val + ); + +UINT64 +EFIAPI +ArmReadCntvCval ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntvCval ( + UINT64 Val + ); + +UINT64 +EFIAPI +ArmReadCntvOff ( + VOID + ); + +VOID +EFIAPI +ArmWriteCntvOff ( + UINT64 Val + ); + +UINTN +EFIAPI +ArmGetPhysicalAddressBits ( + VOID + ); + +/// +/// ID Register Helper functions +/// + +/** + Check whether the CPU supports the GIC system register interface (any version) + + @return Whether GIC System Register Interface is supported + +**/ +BOOLEAN +EFIAPI +ArmHasGicSystemRegisters ( + VOID + ); + +/** Checks if CCIDX is implemented. + + @retval TRUE CCIDX is implemented. + @retval FALSE CCIDX is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasCcidx ( + VOID + ); + +#ifdef MDE_CPU_AARCH64 +/// +/// AArch64-only ID Register Helper functions +/// + +/** + Checks whether the CPU implements the Virtualization Host Extensions. + + @retval TRUE FEAT_VHE is implemented. + @retval FALSE FEAT_VHE is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasVhe ( + VOID + ); + +/** + Checks whether the CPU implements the Trace Buffer Extension. + + @retval TRUE FEAT_TRBE is implemented. + @retval FALSE FEAT_TRBE is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasTrbe ( + VOID + ); + +/** + Checks whether the CPU implements the Embedded Trace Extension. + + @retval TRUE FEAT_ETE is implemented. + @retval FALSE FEAT_ETE is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasEte ( + VOID + ); + +#endif // MDE_CPU_AARCH64 + +#ifdef MDE_CPU_ARM +/// +/// AArch32-only ID Register Helper functions +/// + +/** + Check whether the CPU supports the Security extensions + + @return Whether the Security extensions are implemented + +**/ +BOOLEAN +EFIAPI +ArmHasSecurityExtensions ( + VOID + ); + +#endif // MDE_CPU_ARM + +#endif // ARM_LIB_H_ diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index bf94549cbf..94170ff9a4 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -339,6 +339,11 @@ ## @libraryclass Provides function to make ecalls to SBI BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h +[LibraryClasses.ARM, LibraryClasses.AARCH64] + ## @libraryclass Provides an interface to Arm registers. + # + ArmLib|Include/Library/ArmLib.h + [Guids] # # GUID defined in UEFI2.1/UEFI2.0/EFI1.1 -- cgit From c68fb69dfefa7a76ebad33674a49632c4f8c6926 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 11 Mar 2024 16:04:41 +0100 Subject: ArmPkg,MdePkg: Move ArmPkg/Chipset/ArmV7[|Mmu].h to MdePkg Following the discussion at [1] and as the ArmLib relies on them, move ArmPkg/Chipset/ArmV7[|Mmu].h files to the MdePkg. Update the path to correctly include the moved files. [1] https://edk2.groups.io/g/devel/message/111566 Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Pierre Gondois Acked-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- ArmPkg/Include/Chipset/AArch64.h | 252 --------------------- ArmPkg/Include/Chipset/AArch64Mmu.h | 195 ---------------- .../ArmExceptionLib/AArch64/AArch64Exception.c | 2 +- .../ArmExceptionLib/AArch64/ExceptionSupport.S | 2 +- ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c | 2 +- ArmPkg/Library/ArmLib/AArch64/AArch64Support.S | 2 +- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 2 +- ArmPlatformPkg/PrePeiCore/AArch64/Exception.S | 2 +- ArmPlatformPkg/PrePeiCore/AArch64/Helper.S | 2 +- ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c | 2 +- ArmVirtPkg/PrePi/AArch64/ArchPrePi.c | 2 +- MdePkg/Include/AArch64/AArch64.h | 252 +++++++++++++++++++++ MdePkg/Include/AArch64/AArch64Mmu.h | 195 ++++++++++++++++ MdePkg/Include/Library/ArmLib.h | 2 +- 14 files changed, 457 insertions(+), 457 deletions(-) delete mode 100644 ArmPkg/Include/Chipset/AArch64.h delete mode 100644 ArmPkg/Include/Chipset/AArch64Mmu.h create mode 100644 MdePkg/Include/AArch64/AArch64.h create mode 100644 MdePkg/Include/AArch64/AArch64Mmu.h diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h deleted file mode 100644 index 5390bf0a27..0000000000 --- a/ArmPkg/Include/Chipset/AArch64.h +++ /dev/null @@ -1,252 +0,0 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef AARCH64_H_ -#define AARCH64_H_ - -#include - -// ARM Interrupt ID in Exception Table -#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_AARCH64_IRQ - -// CPACR - Coprocessor Access Control Register definitions -#define CPACR_TTA_EN (1UL << 28) -#define CPACR_FPEN_EL1 (1UL << 20) -#define CPACR_FPEN_FULL (3UL << 20) -#define CPACR_CP_FULL_ACCESS 0x300000 - -// Coprocessor Trap Register (CPTR) -#define AARCH64_CPTR_TFP (1 << 10) - -// ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions -#define AARCH64_MMFR1_VH (0xF << 8) - -// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions -#define AARCH64_PFR0_FP (0xF << 16) -#define AARCH64_PFR0_GIC (0xF << 24) - -// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions -#define AARCH64_DFR0_TRACEVER (0xFULL << 4) -#define AARCH64_DFR0_TRBE (0xFULL << 44) - -// SCR - Secure Configuration Register definitions -#define SCR_NS (1 << 0) -#define SCR_IRQ (1 << 1) -#define SCR_FIQ (1 << 2) -#define SCR_EA (1 << 3) -#define SCR_FW (1 << 4) -#define SCR_AW (1 << 5) - -// MIDR - Main ID Register definitions -#define ARM_CPU_TYPE_SHIFT 4 -#define ARM_CPU_TYPE_MASK 0xFFF -#define ARM_CPU_TYPE_AEMV8 0xD0F -#define ARM_CPU_TYPE_A53 0xD03 -#define ARM_CPU_TYPE_A57 0xD07 -#define ARM_CPU_TYPE_A72 0xD08 -#define ARM_CPU_TYPE_A15 0xC0F -#define ARM_CPU_TYPE_A9 0xC09 -#define ARM_CPU_TYPE_A7 0xC07 -#define ARM_CPU_TYPE_A5 0xC05 - -#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) ) -#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF)) - -// Hypervisor Configuration Register -#define ARM_HCR_FMO BIT3 -#define ARM_HCR_IMO BIT4 -#define ARM_HCR_AMO BIT5 -#define ARM_HCR_TSC BIT19 -#define ARM_HCR_TGE BIT27 - -// Exception Syndrome Register -#define AARCH64_ESR_EC(Ecr) ((0x3F << 26) & (Ecr)) -#define AARCH64_ESR_ISS(Ecr) ((0x1FFFFFF) & (Ecr)) - -#define AARCH64_ESR_EC_SMC32 (0x13 << 26) -#define AARCH64_ESR_EC_SMC64 (0x17 << 26) - -// AArch64 Exception Level -#define AARCH64_EL3 0xC -#define AARCH64_EL2 0x8 -#define AARCH64_EL1 0x4 - -// Saved Program Status Register definitions -#define SPSR_A BIT8 -#define SPSR_I BIT7 -#define SPSR_F BIT6 - -#define SPSR_AARCH32 BIT4 - -#define SPSR_AARCH32_MODE_USER 0x0 -#define SPSR_AARCH32_MODE_FIQ 0x1 -#define SPSR_AARCH32_MODE_IRQ 0x2 -#define SPSR_AARCH32_MODE_SVC 0x3 -#define SPSR_AARCH32_MODE_ABORT 0x7 -#define SPSR_AARCH32_MODE_UNDEF 0xB -#define SPSR_AARCH32_MODE_SYS 0xF - -// Counter-timer Hypervisor Control register definitions -#define CNTHCTL_EL2_EL1PCTEN BIT0 -#define CNTHCTL_EL2_EL1PCEN BIT1 - -#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 11)-1) - -// Vector table offset definitions -#define ARM_VECTOR_CUR_SP0_SYNC 0x000 -#define ARM_VECTOR_CUR_SP0_IRQ 0x080 -#define ARM_VECTOR_CUR_SP0_FIQ 0x100 -#define ARM_VECTOR_CUR_SP0_SERR 0x180 - -#define ARM_VECTOR_CUR_SPX_SYNC 0x200 -#define ARM_VECTOR_CUR_SPX_IRQ 0x280 -#define ARM_VECTOR_CUR_SPX_FIQ 0x300 -#define ARM_VECTOR_CUR_SPX_SERR 0x380 - -#define ARM_VECTOR_LOW_A64_SYNC 0x400 -#define ARM_VECTOR_LOW_A64_IRQ 0x480 -#define ARM_VECTOR_LOW_A64_FIQ 0x500 -#define ARM_VECTOR_LOW_A64_SERR 0x580 - -#define ARM_VECTOR_LOW_A32_SYNC 0x600 -#define ARM_VECTOR_LOW_A32_IRQ 0x680 -#define ARM_VECTOR_LOW_A32_FIQ 0x700 -#define ARM_VECTOR_LOW_A32_SERR 0x780 - -// The ID_AA64ISAR2_EL1 register is not recognized by older -// assemblers, we need to define it here. -#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2 - -// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we -// build for ARMv8.0, we need to define the register here. -#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 - -#define VECTOR_BASE(tbl) \ - .section .text.##tbl##,"ax"; \ - .align 11; \ - .org 0x0; \ - GCC_ASM_EXPORT(tbl); \ - ASM_PFX(tbl): \ - -#define VECTOR_ENTRY(tbl, off) \ - .org off - -#define VECTOR_END(tbl) \ - .org 0x800; \ - .previous - -VOID -EFIAPI -ArmEnableSWPInstruction ( - VOID - ); - -UINTN -EFIAPI -ArmReadCbar ( - VOID - ); - -UINTN -EFIAPI -ArmReadTpidrurw ( - VOID - ); - -VOID -EFIAPI -ArmWriteTpidrurw ( - UINTN Value - ); - -UINTN -EFIAPI -ArmGetTCR ( - VOID - ); - -VOID -EFIAPI -ArmSetTCR ( - UINTN Value - ); - -UINTN -EFIAPI -ArmGetMAIR ( - VOID - ); - -VOID -EFIAPI -ArmSetMAIR ( - UINTN Value - ); - -VOID -EFIAPI -ArmDisableAlignmentCheck ( - VOID - ); - -VOID -EFIAPI -ArmEnableAlignmentCheck ( - VOID - ); - -VOID -EFIAPI -ArmDisableStackAlignmentCheck ( - VOID - ); - -VOID -EFIAPI -ArmEnableStackAlignmentCheck ( - VOID - ); - -VOID -EFIAPI -ArmDisableAllExceptions ( - VOID - ); - -VOID -ArmWriteHcr ( - IN UINTN Hcr - ); - -UINTN -ArmReadHcr ( - VOID - ); - -UINTN -ArmReadCurrentEL ( - VOID - ); - -UINTN -ArmWriteCptr ( - IN UINT64 Cptr - ); - -UINT32 -ArmReadCntHctl ( - VOID - ); - -VOID -ArmWriteCntHctl ( - IN UINT32 CntHctl - ); - -#endif // AARCH64_H_ diff --git a/ArmPkg/Include/Chipset/AArch64Mmu.h b/ArmPkg/Include/Chipset/AArch64Mmu.h deleted file mode 100644 index 2ea2cc0a87..0000000000 --- a/ArmPkg/Include/Chipset/AArch64Mmu.h +++ /dev/null @@ -1,195 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2021, Arm Limited. All rights reserved.
-* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#ifndef AARCH64_MMU_H_ -#define AARCH64_MMU_H_ - -// -// Memory Attribute Indirection register Definitions -// -#define MAIR_ATTR_DEVICE_MEMORY 0x0ULL -#define MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE 0x44ULL -#define MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH 0xBBULL -#define MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK 0xFFULL - -#define MAIR_ATTR(n, value) ((value) << (((n) >> 2)*8)) - -// -// Long-descriptor Translation Table format -// - -// Return the smallest offset from the table level. -// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0 -#define TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel) (12 + ((3 - (TableLevel)) * 9)) - -#define TT_BLOCK_ENTRY_SIZE_AT_LEVEL(Level) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(Level)) - -// Get the associated entry in the given Translation Table -#define TT_GET_ENTRY_FOR_ADDRESS(TranslationTable, Level, Address) \ - ((UINTN)(TranslationTable) + ((((UINTN)(Address) >> TT_ADDRESS_OFFSET_AT_LEVEL(Level)) & (BIT9-1)) * sizeof(UINT64))) - -// Return the smallest address granularity from the table level. -// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0 -#define TT_ADDRESS_AT_LEVEL(TableLevel) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel)) - -#define TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount) \ - ((UINT64*)((EFI_PHYSICAL_ADDRESS)(TranslationTable) + (((EntryCount) - 1) * sizeof(UINT64)))) - -// There are 512 entries per table when 4K Granularity -#define TT_ENTRY_COUNT 512 -#define TT_ALIGNMENT_BLOCK_ENTRY BIT12 -#define TT_ALIGNMENT_DESCRIPTION_TABLE BIT12 - -#define TT_ADDRESS_MASK_BLOCK_ENTRY (0xFFFFFFFFFULL << 12) -#define TT_ADDRESS_MASK_DESCRIPTION_TABLE (0xFFFFFFFFFULL << 12) - -#define TT_TYPE_MASK 0x3 -#define TT_TYPE_TABLE_ENTRY 0x3 -#define TT_TYPE_BLOCK_ENTRY 0x1 -#define TT_TYPE_BLOCK_ENTRY_LEVEL3 0x3 - -#define TT_ATTR_INDX_MASK (0x7 << 2) -#define TT_ATTR_INDX_DEVICE_MEMORY (0x0 << 2) -#define TT_ATTR_INDX_MEMORY_NON_CACHEABLE (0x1 << 2) -#define TT_ATTR_INDX_MEMORY_WRITE_THROUGH (0x2 << 2) -#define TT_ATTR_INDX_MEMORY_WRITE_BACK (0x3 << 2) - -#define TT_AP_MASK (0x3UL << 6) -#define TT_AP_NO_RW (0x0UL << 6) -#define TT_AP_RW_RW (0x1UL << 6) -#define TT_AP_NO_RO (0x2UL << 6) -#define TT_AP_RO_RO (0x3UL << 6) - -#define TT_NS BIT5 -#define TT_AF BIT10 - -#define TT_SH_NON_SHAREABLE (0x0 << 8) -#define TT_SH_OUTER_SHAREABLE (0x2 << 8) -#define TT_SH_INNER_SHAREABLE (0x3 << 8) -#define TT_SH_MASK (0x3 << 8) - -#define TT_PXN_MASK BIT53 -#define TT_UXN_MASK BIT54 // EL1&0 -#define TT_XN_MASK BIT54 // EL2 / EL3 - -#define TT_ATTRIBUTES_MASK ((0xFFFULL << 52) | (0x3FFULL << 2)) - -#define TT_TABLE_PXN BIT59 -#define TT_TABLE_UXN BIT60 // EL1&0 -#define TT_TABLE_XN BIT60 // EL2 / EL3 -#define TT_TABLE_NS BIT63 - -#define TT_TABLE_AP_MASK (BIT62 | BIT61) -#define TT_TABLE_AP_NO_PERMISSION (0x0ULL << 61) -#define TT_TABLE_AP_EL0_NO_ACCESS (0x1ULL << 61) -#define TT_TABLE_AP_NO_WRITE_ACCESS (0x2ULL << 61) - -// -// Translation Control Register -// -#define TCR_T0SZ_MASK 0x3FUL - -#define TCR_PS_4GB (0UL << 16) -#define TCR_PS_64GB (1UL << 16) -#define TCR_PS_1TB (2UL << 16) -#define TCR_PS_4TB (3UL << 16) -#define TCR_PS_16TB (4UL << 16) -#define TCR_PS_256TB (5UL << 16) - -#define TCR_TG0_4KB (0UL << 14) -#define TCR_TG1_4KB (2UL << 30) - -#define TCR_IPS_4GB (0ULL << 32) -#define TCR_IPS_64GB (1ULL << 32) -#define TCR_IPS_1TB (2ULL << 32) -#define TCR_IPS_4TB (3ULL << 32) -#define TCR_IPS_16TB (4ULL << 32) -#define TCR_IPS_256TB (5ULL << 32) - -#define TCR_EPD1 (1UL << 23) - -#define TTBR_ASID_FIELD (48) -#define TTBR_ASID_MASK (0xFF << TTBR_ASID_FIELD) -#define TTBR_BADDR_MASK (0xFFFFFFFFFFFF ) // The width of this field depends on the values in TxSZ. Addr occupies bottom 48bits - -#define TCR_EL1_T0SZ_FIELD (0) -#define TCR_EL1_EPD0_FIELD (7) -#define TCR_EL1_IRGN0_FIELD (8) -#define TCR_EL1_ORGN0_FIELD (10) -#define TCR_EL1_SH0_FIELD (12) -#define TCR_EL1_TG0_FIELD (14) -#define TCR_EL1_T1SZ_FIELD (16) -#define TCR_EL1_A1_FIELD (22) -#define TCR_EL1_EPD1_FIELD (23) -#define TCR_EL1_IRGN1_FIELD (24) -#define TCR_EL1_ORGN1_FIELD (26) -#define TCR_EL1_SH1_FIELD (28) -#define TCR_EL1_TG1_FIELD (30) -#define TCR_EL1_IPS_FIELD (32) -#define TCR_EL1_AS_FIELD (36) -#define TCR_EL1_TBI0_FIELD (37) -#define TCR_EL1_TBI1_FIELD (38) -#define TCR_EL1_T0SZ_MASK (0x1FUL << TCR_EL1_T0SZ_FIELD) -#define TCR_EL1_EPD0_MASK (0x01UL << TCR_EL1_EPD0_FIELD) -#define TCR_EL1_IRGN0_MASK (0x03UL << TCR_EL1_IRGN0_FIELD) -#define TCR_EL1_ORGN0_MASK (0x03UL << TCR_EL1_ORGN0_FIELD) -#define TCR_EL1_SH0_MASK (0x03UL << TCR_EL1_SH0_FIELD) -#define TCR_EL1_TG0_MASK (0x01UL << TCR_EL1_TG0_FIELD) -#define TCR_EL1_T1SZ_MASK (0x1FUL << TCR_EL1_T1SZ_FIELD) -#define TCR_EL1_A1_MASK (0x01UL << TCR_EL1_A1_FIELD) -#define TCR_EL1_EPD1_MASK (0x01UL << TCR_EL1_EPD1_FIELD) -#define TCR_EL1_IRGN1_MASK (0x03UL << TCR_EL1_IRGN1_FIELD) -#define TCR_EL1_ORGN1_MASK (0x03UL << TCR_EL1_ORGN1_FIELD) -#define TCR_EL1_SH1_MASK (0x03UL << TCR_EL1_SH1_FIELD) -#define TCR_EL1_TG1_MASK (0x01UL << TCR_EL1_TG1_FIELD) -#define TCR_EL1_IPS_MASK (0x07UL << TCR_EL1_IPS_FIELD) -#define TCR_EL1_AS_MASK (0x01UL << TCR_EL1_AS_FIELD) -#define TCR_EL1_TBI0_MASK (0x01UL << TCR_EL1_TBI0_FIELD) -#define TCR_EL1_TBI1_MASK (0x01UL << TCR_EL1_TBI1_FIELD) - -#define TCR_EL23_T0SZ_FIELD (0) -#define TCR_EL23_IRGN0_FIELD (8) -#define TCR_EL23_ORGN0_FIELD (10) -#define TCR_EL23_SH0_FIELD (12) -#define TCR_EL23_TG0_FIELD (14) -#define TCR_EL23_PS_FIELD (16) -#define TCR_EL23_T0SZ_MASK (0x1FUL << TCR_EL23_T0SZ_FIELD) -#define TCR_EL23_IRGN0_MASK (0x03UL << TCR_EL23_IRGN0_FIELD) -#define TCR_EL23_ORGN0_MASK (0x03UL << TCR_EL23_ORGN0_FIELD) -#define TCR_EL23_SH0_MASK (0x03UL << TCR_EL23_SH0_FIELD) -#define TCR_EL23_TG0_MASK (0x01UL << TCR_EL23_TG0_FIELD) -#define TCR_EL23_PS_MASK (0x07UL << TCR_EL23_PS_FIELD) - -#define TCR_RGN_OUTER_NON_CACHEABLE (0x0UL << 10) -#define TCR_RGN_OUTER_WRITE_BACK_ALLOC (0x1UL << 10) -#define TCR_RGN_OUTER_WRITE_THROUGH (0x2UL << 10) -#define TCR_RGN_OUTER_WRITE_BACK_NO_ALLOC (0x3UL << 10) - -#define TCR_RGN_INNER_NON_CACHEABLE (0x0UL << 8) -#define TCR_RGN_INNER_WRITE_BACK_ALLOC (0x1UL << 8) -#define TCR_RGN_INNER_WRITE_THROUGH (0x2UL << 8) -#define TCR_RGN_INNER_WRITE_BACK_NO_ALLOC (0x3UL << 8) - -#define TCR_SH_NON_SHAREABLE (0x0UL << 12) -#define TCR_SH_OUTER_SHAREABLE (0x2UL << 12) -#define TCR_SH_INNER_SHAREABLE (0x3UL << 12) - -#define TCR_PASZ_32BITS_4GB (0x0UL) -#define TCR_PASZ_36BITS_64GB (0x1UL) -#define TCR_PASZ_40BITS_1TB (0x2UL) -#define TCR_PASZ_42BITS_4TB (0x3UL) -#define TCR_PASZ_44BITS_16TB (0x4UL) -#define TCR_PASZ_48BITS_256TB (0x5UL) - -// The value written to the T*SZ fields are defined as 2^(64-T*SZ). So a 39Bit -// Virtual address range for 512GB of virtual space sets T*SZ to 25 -#define INPUT_ADDRESS_SIZE_TO_TXSZ(a) (64 - a) - -// Uses LPAE Page Table format - -#endif // AARCH64_MMU_H_ diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/AArch64Exception.c b/ArmPkg/Library/ArmExceptionLib/AArch64/AArch64Exception.c index ef6a132b8d..b0c2e39cd9 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/AArch64Exception.c +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/AArch64Exception.c @@ -10,7 +10,7 @@ #include -#include +#include #include #include // for MAX_AARCH64_EXCEPTION diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index cd9437b6aa..f5cbc2e97c 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -7,7 +7,7 @@ // //------------------------------------------------------------------------------ -#include +#include #include #include #include // for exception type definitions diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c index 8728546587..6739f5c37d 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include "AArch64Lib.h" #include "ArmLibPrivate.h" diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index a7111e5188..177d10e66d 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -9,7 +9,7 @@ # #------------------------------------------------------------------------------ -#include +#include #include .set CTRL_M_BIT, (1 << 0) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 9d9c623581..6a1f3f9477 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S index ffb643a56d..d0d6bc44f7 100644 --- a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S +++ b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S @@ -5,7 +5,7 @@ # # -#include +#include #include #include #include diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S index 2a604b719b..9b81b96a49 100644 --- a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S +++ b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S @@ -6,7 +6,7 @@ #======================================================================================= #include -#include +#include // Setup EL1 while in EL1 ASM_FUNC(SetupExceptionLevel1) diff --git a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c index 296b029e08..27a85049fa 100644 --- a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c +++ b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c @@ -8,7 +8,7 @@ #include "PrePi.h" -#include +#include VOID ArchInitialize ( diff --git a/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c b/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c index a02c2ad560..a7f53132c7 100644 --- a/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c +++ b/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c @@ -8,7 +8,7 @@ #include "PrePi.h" -#include +#include VOID ArchInitialize ( diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h new file mode 100644 index 0000000000..a77c3a95f1 --- /dev/null +++ b/MdePkg/Include/AArch64/AArch64.h @@ -0,0 +1,252 @@ +/** @file + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef AARCH64_H_ +#define AARCH64_H_ + +#include + +// ARM Interrupt ID in Exception Table +#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_AARCH64_IRQ + +// CPACR - Coprocessor Access Control Register definitions +#define CPACR_TTA_EN (1UL << 28) +#define CPACR_FPEN_EL1 (1UL << 20) +#define CPACR_FPEN_FULL (3UL << 20) +#define CPACR_CP_FULL_ACCESS 0x300000 + +// Coprocessor Trap Register (CPTR) +#define AARCH64_CPTR_TFP (1 << 10) + +// ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions +#define AARCH64_MMFR1_VH (0xF << 8) + +// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions +#define AARCH64_PFR0_FP (0xF << 16) +#define AARCH64_PFR0_GIC (0xF << 24) + +// ID_AA64DFR0 - AArch64 Debug Feature Register 0 definitions +#define AARCH64_DFR0_TRACEVER (0xFULL << 4) +#define AARCH64_DFR0_TRBE (0xFULL << 44) + +// SCR - Secure Configuration Register definitions +#define SCR_NS (1 << 0) +#define SCR_IRQ (1 << 1) +#define SCR_FIQ (1 << 2) +#define SCR_EA (1 << 3) +#define SCR_FW (1 << 4) +#define SCR_AW (1 << 5) + +// MIDR - Main ID Register definitions +#define ARM_CPU_TYPE_SHIFT 4 +#define ARM_CPU_TYPE_MASK 0xFFF +#define ARM_CPU_TYPE_AEMV8 0xD0F +#define ARM_CPU_TYPE_A53 0xD03 +#define ARM_CPU_TYPE_A57 0xD07 +#define ARM_CPU_TYPE_A72 0xD08 +#define ARM_CPU_TYPE_A15 0xC0F +#define ARM_CPU_TYPE_A9 0xC09 +#define ARM_CPU_TYPE_A7 0xC07 +#define ARM_CPU_TYPE_A5 0xC05 + +#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) ) +#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF)) + +// Hypervisor Configuration Register +#define ARM_HCR_FMO BIT3 +#define ARM_HCR_IMO BIT4 +#define ARM_HCR_AMO BIT5 +#define ARM_HCR_TSC BIT19 +#define ARM_HCR_TGE BIT27 + +// Exception Syndrome Register +#define AARCH64_ESR_EC(Ecr) ((0x3F << 26) & (Ecr)) +#define AARCH64_ESR_ISS(Ecr) ((0x1FFFFFF) & (Ecr)) + +#define AARCH64_ESR_EC_SMC32 (0x13 << 26) +#define AARCH64_ESR_EC_SMC64 (0x17 << 26) + +// AArch64 Exception Level +#define AARCH64_EL3 0xC +#define AARCH64_EL2 0x8 +#define AARCH64_EL1 0x4 + +// Saved Program Status Register definitions +#define SPSR_A BIT8 +#define SPSR_I BIT7 +#define SPSR_F BIT6 + +#define SPSR_AARCH32 BIT4 + +#define SPSR_AARCH32_MODE_USER 0x0 +#define SPSR_AARCH32_MODE_FIQ 0x1 +#define SPSR_AARCH32_MODE_IRQ 0x2 +#define SPSR_AARCH32_MODE_SVC 0x3 +#define SPSR_AARCH32_MODE_ABORT 0x7 +#define SPSR_AARCH32_MODE_UNDEF 0xB +#define SPSR_AARCH32_MODE_SYS 0xF + +// Counter-timer Hypervisor Control register definitions +#define CNTHCTL_EL2_EL1PCTEN BIT0 +#define CNTHCTL_EL2_EL1PCEN BIT1 + +#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 11)-1) + +// Vector table offset definitions +#define ARM_VECTOR_CUR_SP0_SYNC 0x000 +#define ARM_VECTOR_CUR_SP0_IRQ 0x080 +#define ARM_VECTOR_CUR_SP0_FIQ 0x100 +#define ARM_VECTOR_CUR_SP0_SERR 0x180 + +#define ARM_VECTOR_CUR_SPX_SYNC 0x200 +#define ARM_VECTOR_CUR_SPX_IRQ 0x280 +#define ARM_VECTOR_CUR_SPX_FIQ 0x300 +#define ARM_VECTOR_CUR_SPX_SERR 0x380 + +#define ARM_VECTOR_LOW_A64_SYNC 0x400 +#define ARM_VECTOR_LOW_A64_IRQ 0x480 +#define ARM_VECTOR_LOW_A64_FIQ 0x500 +#define ARM_VECTOR_LOW_A64_SERR 0x580 + +#define ARM_VECTOR_LOW_A32_SYNC 0x600 +#define ARM_VECTOR_LOW_A32_IRQ 0x680 +#define ARM_VECTOR_LOW_A32_FIQ 0x700 +#define ARM_VECTOR_LOW_A32_SERR 0x780 + +// The ID_AA64ISAR2_EL1 register is not recognized by older +// assemblers, we need to define it here. +#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2 + +// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we +// build for ARMv8.0, we need to define the register here. +#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 + +#define VECTOR_BASE(tbl) \ + .section .text.##tbl##,"ax"; \ + .align 11; \ + .org 0x0; \ + GCC_ASM_EXPORT(tbl); \ + ASM_PFX(tbl): \ + +#define VECTOR_ENTRY(tbl, off) \ + .org off + +#define VECTOR_END(tbl) \ + .org 0x800; \ + .previous + +VOID +EFIAPI +ArmEnableSWPInstruction ( + VOID + ); + +UINTN +EFIAPI +ArmReadCbar ( + VOID + ); + +UINTN +EFIAPI +ArmReadTpidrurw ( + VOID + ); + +VOID +EFIAPI +ArmWriteTpidrurw ( + UINTN Value + ); + +UINTN +EFIAPI +ArmGetTCR ( + VOID + ); + +VOID +EFIAPI +ArmSetTCR ( + UINTN Value + ); + +UINTN +EFIAPI +ArmGetMAIR ( + VOID + ); + +VOID +EFIAPI +ArmSetMAIR ( + UINTN Value + ); + +VOID +EFIAPI +ArmDisableAlignmentCheck ( + VOID + ); + +VOID +EFIAPI +ArmEnableAlignmentCheck ( + VOID + ); + +VOID +EFIAPI +ArmDisableStackAlignmentCheck ( + VOID + ); + +VOID +EFIAPI +ArmEnableStackAlignmentCheck ( + VOID + ); + +VOID +EFIAPI +ArmDisableAllExceptions ( + VOID + ); + +VOID +ArmWriteHcr ( + IN UINTN Hcr + ); + +UINTN +ArmReadHcr ( + VOID + ); + +UINTN +ArmReadCurrentEL ( + VOID + ); + +UINTN +ArmWriteCptr ( + IN UINT64 Cptr + ); + +UINT32 +ArmReadCntHctl ( + VOID + ); + +VOID +ArmWriteCntHctl ( + IN UINT32 CntHctl + ); + +#endif // AARCH64_H_ diff --git a/MdePkg/Include/AArch64/AArch64Mmu.h b/MdePkg/Include/AArch64/AArch64Mmu.h new file mode 100644 index 0000000000..2ea2cc0a87 --- /dev/null +++ b/MdePkg/Include/AArch64/AArch64Mmu.h @@ -0,0 +1,195 @@ +/** @file +* +* Copyright (c) 2011-2021, Arm Limited. All rights reserved.
+* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#ifndef AARCH64_MMU_H_ +#define AARCH64_MMU_H_ + +// +// Memory Attribute Indirection register Definitions +// +#define MAIR_ATTR_DEVICE_MEMORY 0x0ULL +#define MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE 0x44ULL +#define MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH 0xBBULL +#define MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK 0xFFULL + +#define MAIR_ATTR(n, value) ((value) << (((n) >> 2)*8)) + +// +// Long-descriptor Translation Table format +// + +// Return the smallest offset from the table level. +// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0 +#define TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel) (12 + ((3 - (TableLevel)) * 9)) + +#define TT_BLOCK_ENTRY_SIZE_AT_LEVEL(Level) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(Level)) + +// Get the associated entry in the given Translation Table +#define TT_GET_ENTRY_FOR_ADDRESS(TranslationTable, Level, Address) \ + ((UINTN)(TranslationTable) + ((((UINTN)(Address) >> TT_ADDRESS_OFFSET_AT_LEVEL(Level)) & (BIT9-1)) * sizeof(UINT64))) + +// Return the smallest address granularity from the table level. +// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0 +#define TT_ADDRESS_AT_LEVEL(TableLevel) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel)) + +#define TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount) \ + ((UINT64*)((EFI_PHYSICAL_ADDRESS)(TranslationTable) + (((EntryCount) - 1) * sizeof(UINT64)))) + +// There are 512 entries per table when 4K Granularity +#define TT_ENTRY_COUNT 512 +#define TT_ALIGNMENT_BLOCK_ENTRY BIT12 +#define TT_ALIGNMENT_DESCRIPTION_TABLE BIT12 + +#define TT_ADDRESS_MASK_BLOCK_ENTRY (0xFFFFFFFFFULL << 12) +#define TT_ADDRESS_MASK_DESCRIPTION_TABLE (0xFFFFFFFFFULL << 12) + +#define TT_TYPE_MASK 0x3 +#define TT_TYPE_TABLE_ENTRY 0x3 +#define TT_TYPE_BLOCK_ENTRY 0x1 +#define TT_TYPE_BLOCK_ENTRY_LEVEL3 0x3 + +#define TT_ATTR_INDX_MASK (0x7 << 2) +#define TT_ATTR_INDX_DEVICE_MEMORY (0x0 << 2) +#define TT_ATTR_INDX_MEMORY_NON_CACHEABLE (0x1 << 2) +#define TT_ATTR_INDX_MEMORY_WRITE_THROUGH (0x2 << 2) +#define TT_ATTR_INDX_MEMORY_WRITE_BACK (0x3 << 2) + +#define TT_AP_MASK (0x3UL << 6) +#define TT_AP_NO_RW (0x0UL << 6) +#define TT_AP_RW_RW (0x1UL << 6) +#define TT_AP_NO_RO (0x2UL << 6) +#define TT_AP_RO_RO (0x3UL << 6) + +#define TT_NS BIT5 +#define TT_AF BIT10 + +#define TT_SH_NON_SHAREABLE (0x0 << 8) +#define TT_SH_OUTER_SHAREABLE (0x2 << 8) +#define TT_SH_INNER_SHAREABLE (0x3 << 8) +#define TT_SH_MASK (0x3 << 8) + +#define TT_PXN_MASK BIT53 +#define TT_UXN_MASK BIT54 // EL1&0 +#define TT_XN_MASK BIT54 // EL2 / EL3 + +#define TT_ATTRIBUTES_MASK ((0xFFFULL << 52) | (0x3FFULL << 2)) + +#define TT_TABLE_PXN BIT59 +#define TT_TABLE_UXN BIT60 // EL1&0 +#define TT_TABLE_XN BIT60 // EL2 / EL3 +#define TT_TABLE_NS BIT63 + +#define TT_TABLE_AP_MASK (BIT62 | BIT61) +#define TT_TABLE_AP_NO_PERMISSION (0x0ULL << 61) +#define TT_TABLE_AP_EL0_NO_ACCESS (0x1ULL << 61) +#define TT_TABLE_AP_NO_WRITE_ACCESS (0x2ULL << 61) + +// +// Translation Control Register +// +#define TCR_T0SZ_MASK 0x3FUL + +#define TCR_PS_4GB (0UL << 16) +#define TCR_PS_64GB (1UL << 16) +#define TCR_PS_1TB (2UL << 16) +#define TCR_PS_4TB (3UL << 16) +#define TCR_PS_16TB (4UL << 16) +#define TCR_PS_256TB (5UL << 16) + +#define TCR_TG0_4KB (0UL << 14) +#define TCR_TG1_4KB (2UL << 30) + +#define TCR_IPS_4GB (0ULL << 32) +#define TCR_IPS_64GB (1ULL << 32) +#define TCR_IPS_1TB (2ULL << 32) +#define TCR_IPS_4TB (3ULL << 32) +#define TCR_IPS_16TB (4ULL << 32) +#define TCR_IPS_256TB (5ULL << 32) + +#define TCR_EPD1 (1UL << 23) + +#define TTBR_ASID_FIELD (48) +#define TTBR_ASID_MASK (0xFF << TTBR_ASID_FIELD) +#define TTBR_BADDR_MASK (0xFFFFFFFFFFFF ) // The width of this field depends on the values in TxSZ. Addr occupies bottom 48bits + +#define TCR_EL1_T0SZ_FIELD (0) +#define TCR_EL1_EPD0_FIELD (7) +#define TCR_EL1_IRGN0_FIELD (8) +#define TCR_EL1_ORGN0_FIELD (10) +#define TCR_EL1_SH0_FIELD (12) +#define TCR_EL1_TG0_FIELD (14) +#define TCR_EL1_T1SZ_FIELD (16) +#define TCR_EL1_A1_FIELD (22) +#define TCR_EL1_EPD1_FIELD (23) +#define TCR_EL1_IRGN1_FIELD (24) +#define TCR_EL1_ORGN1_FIELD (26) +#define TCR_EL1_SH1_FIELD (28) +#define TCR_EL1_TG1_FIELD (30) +#define TCR_EL1_IPS_FIELD (32) +#define TCR_EL1_AS_FIELD (36) +#define TCR_EL1_TBI0_FIELD (37) +#define TCR_EL1_TBI1_FIELD (38) +#define TCR_EL1_T0SZ_MASK (0x1FUL << TCR_EL1_T0SZ_FIELD) +#define TCR_EL1_EPD0_MASK (0x01UL << TCR_EL1_EPD0_FIELD) +#define TCR_EL1_IRGN0_MASK (0x03UL << TCR_EL1_IRGN0_FIELD) +#define TCR_EL1_ORGN0_MASK (0x03UL << TCR_EL1_ORGN0_FIELD) +#define TCR_EL1_SH0_MASK (0x03UL << TCR_EL1_SH0_FIELD) +#define TCR_EL1_TG0_MASK (0x01UL << TCR_EL1_TG0_FIELD) +#define TCR_EL1_T1SZ_MASK (0x1FUL << TCR_EL1_T1SZ_FIELD) +#define TCR_EL1_A1_MASK (0x01UL << TCR_EL1_A1_FIELD) +#define TCR_EL1_EPD1_MASK (0x01UL << TCR_EL1_EPD1_FIELD) +#define TCR_EL1_IRGN1_MASK (0x03UL << TCR_EL1_IRGN1_FIELD) +#define TCR_EL1_ORGN1_MASK (0x03UL << TCR_EL1_ORGN1_FIELD) +#define TCR_EL1_SH1_MASK (0x03UL << TCR_EL1_SH1_FIELD) +#define TCR_EL1_TG1_MASK (0x01UL << TCR_EL1_TG1_FIELD) +#define TCR_EL1_IPS_MASK (0x07UL << TCR_EL1_IPS_FIELD) +#define TCR_EL1_AS_MASK (0x01UL << TCR_EL1_AS_FIELD) +#define TCR_EL1_TBI0_MASK (0x01UL << TCR_EL1_TBI0_FIELD) +#define TCR_EL1_TBI1_MASK (0x01UL << TCR_EL1_TBI1_FIELD) + +#define TCR_EL23_T0SZ_FIELD (0) +#define TCR_EL23_IRGN0_FIELD (8) +#define TCR_EL23_ORGN0_FIELD (10) +#define TCR_EL23_SH0_FIELD (12) +#define TCR_EL23_TG0_FIELD (14) +#define TCR_EL23_PS_FIELD (16) +#define TCR_EL23_T0SZ_MASK (0x1FUL << TCR_EL23_T0SZ_FIELD) +#define TCR_EL23_IRGN0_MASK (0x03UL << TCR_EL23_IRGN0_FIELD) +#define TCR_EL23_ORGN0_MASK (0x03UL << TCR_EL23_ORGN0_FIELD) +#define TCR_EL23_SH0_MASK (0x03UL << TCR_EL23_SH0_FIELD) +#define TCR_EL23_TG0_MASK (0x01UL << TCR_EL23_TG0_FIELD) +#define TCR_EL23_PS_MASK (0x07UL << TCR_EL23_PS_FIELD) + +#define TCR_RGN_OUTER_NON_CACHEABLE (0x0UL << 10) +#define TCR_RGN_OUTER_WRITE_BACK_ALLOC (0x1UL << 10) +#define TCR_RGN_OUTER_WRITE_THROUGH (0x2UL << 10) +#define TCR_RGN_OUTER_WRITE_BACK_NO_ALLOC (0x3UL << 10) + +#define TCR_RGN_INNER_NON_CACHEABLE (0x0UL << 8) +#define TCR_RGN_INNER_WRITE_BACK_ALLOC (0x1UL << 8) +#define TCR_RGN_INNER_WRITE_THROUGH (0x2UL << 8) +#define TCR_RGN_INNER_WRITE_BACK_NO_ALLOC (0x3UL << 8) + +#define TCR_SH_NON_SHAREABLE (0x0UL << 12) +#define TCR_SH_OUTER_SHAREABLE (0x2UL << 12) +#define TCR_SH_INNER_SHAREABLE (0x3UL << 12) + +#define TCR_PASZ_32BITS_4GB (0x0UL) +#define TCR_PASZ_36BITS_64GB (0x1UL) +#define TCR_PASZ_40BITS_1TB (0x2UL) +#define TCR_PASZ_42BITS_4TB (0x3UL) +#define TCR_PASZ_44BITS_16TB (0x4UL) +#define TCR_PASZ_48BITS_256TB (0x5UL) + +// The value written to the T*SZ fields are defined as 2^(64-T*SZ). So a 39Bit +// Virtual address range for 512GB of virtual space sets T*SZ to 25 +#define INPUT_ADDRESS_SIZE_TO_TXSZ(a) (64 - a) + +// Uses LPAE Page Table format + +#endif // AARCH64_MMU_H_ diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index 6aa8a48f07..852264dba2 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -16,7 +16,7 @@ #ifdef MDE_CPU_ARM #include #elif defined (MDE_CPU_AARCH64) - #include + #include #else #error "Unknown chipset." #endif -- cgit From cf323e2839ce260fde43487baae205527dee1b2f Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 11 Mar 2024 16:05:46 +0100 Subject: ArmPkg,MdePkg: Move ArmPkg/Chipset/Aarch64[|Mmu].h to MdePkg Following the discussion at [1] and as the ArmLib relies on them, move ArmPkg/Chipset/Aarch64[|Mmu].h files to the MdePkg. Update the path to correctly include the moved files. [1] https://edk2.groups.io/g/devel/message/111566 Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Pierre Gondois Acked-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- ArmPkg/Include/Chipset/ArmV7.h | 122 ------------ ArmPkg/Include/Chipset/ArmV7Mmu.h | 216 ---------------------- ArmPkg/Library/ArmExceptionLib/Arm/ArmException.c | 2 +- ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c | 2 +- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c | 2 +- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 2 +- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c | 2 +- ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S | 2 +- MdePkg/Include/Arm/AArch32.h | 122 ++++++++++++ MdePkg/Include/Arm/AArch32Mmu.h | 216 ++++++++++++++++++++++ MdePkg/Include/Library/ArmLib.h | 2 +- 11 files changed, 345 insertions(+), 345 deletions(-) delete mode 100644 ArmPkg/Include/Chipset/ArmV7.h delete mode 100644 ArmPkg/Include/Chipset/ArmV7Mmu.h create mode 100644 MdePkg/Include/Arm/AArch32.h create mode 100644 MdePkg/Include/Arm/AArch32Mmu.h diff --git a/ArmPkg/Include/Chipset/ArmV7.h b/ArmPkg/Include/Chipset/ArmV7.h deleted file mode 100644 index 94620c087d..0000000000 --- a/ArmPkg/Include/Chipset/ArmV7.h +++ /dev/null @@ -1,122 +0,0 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2011-2021, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef ARM_V7_H_ -#define ARM_V7_H_ - -#include - -// ARM Interrupt ID in Exception Table -#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_ARM_IRQ - -// ID_PFR1 - ARM Processor Feature Register 1 definitions -#define ARM_PFR1_SEC (0xFUL << 4) -#define ARM_PFR1_TIMER (0xFUL << 16) -#define ARM_PFR1_GIC (0xFUL << 28) - -// Domain Access Control Register -#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a))) -#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a))) -#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a))) -#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a))) -#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a))) - -// CPSR - Coprocessor Status Register definitions -#define CPSR_MODE_USER 0x10 -#define CPSR_MODE_FIQ 0x11 -#define CPSR_MODE_IRQ 0x12 -#define CPSR_MODE_SVC 0x13 -#define CPSR_MODE_ABORT 0x17 -#define CPSR_MODE_HYP 0x1A -#define CPSR_MODE_UNDEFINED 0x1B -#define CPSR_MODE_SYSTEM 0x1F -#define CPSR_MODE_MASK 0x1F -#define CPSR_ASYNC_ABORT (1 << 8) -#define CPSR_IRQ (1 << 7) -#define CPSR_FIQ (1 << 6) - -// CPACR - Coprocessor Access Control Register definitions -#define CPACR_CP_DENIED(cp) 0x00 -#define CPACR_CP_PRIV(cp) ((0x1 << ((cp) << 1)) & 0x0FFFFFFF) -#define CPACR_CP_FULL(cp) ((0x3 << ((cp) << 1)) & 0x0FFFFFFF) -#define CPACR_ASEDIS (1 << 31) -#define CPACR_D32DIS (1 << 30) -#define CPACR_CP_FULL_ACCESS 0x0FFFFFFF - -// NSACR - Non-Secure Access Control Register definitions -#define NSACR_CP(cp) ((1 << (cp)) & 0x3FFF) -#define NSACR_NSD32DIS (1 << 14) -#define NSACR_NSASEDIS (1 << 15) -#define NSACR_PLE (1 << 16) -#define NSACR_TL (1 << 17) -#define NSACR_NS_SMP (1 << 18) -#define NSACR_RFR (1 << 19) - -// SCR - Secure Configuration Register definitions -#define SCR_NS (1 << 0) -#define SCR_IRQ (1 << 1) -#define SCR_FIQ (1 << 2) -#define SCR_EA (1 << 3) -#define SCR_FW (1 << 4) -#define SCR_AW (1 << 5) - -// MIDR - Main ID Register definitions -#define ARM_CPU_TYPE_SHIFT 4 -#define ARM_CPU_TYPE_MASK 0xFFF -#define ARM_CPU_TYPE_AEMV8 0xD0F -#define ARM_CPU_TYPE_A53 0xD03 -#define ARM_CPU_TYPE_A57 0xD07 -#define ARM_CPU_TYPE_A15 0xC0F -#define ARM_CPU_TYPE_A12 0xC0D -#define ARM_CPU_TYPE_A9 0xC09 -#define ARM_CPU_TYPE_A7 0xC07 -#define ARM_CPU_TYPE_A5 0xC05 - -#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) ) -#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF)) - -#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 5)-1) - -VOID -EFIAPI -ArmEnableSWPInstruction ( - VOID - ); - -UINTN -EFIAPI -ArmReadCbar ( - VOID - ); - -UINTN -EFIAPI -ArmReadTpidrurw ( - VOID - ); - -VOID -EFIAPI -ArmWriteTpidrurw ( - UINTN Value - ); - -UINT32 -EFIAPI -ArmReadNsacr ( - VOID - ); - -VOID -EFIAPI -ArmWriteNsacr ( - IN UINT32 Nsacr - ); - -#endif // ARM_V7_H_ diff --git a/ArmPkg/Include/Chipset/ArmV7Mmu.h b/ArmPkg/Include/Chipset/ArmV7Mmu.h deleted file mode 100644 index 89b81e33d0..0000000000 --- a/ArmPkg/Include/Chipset/ArmV7Mmu.h +++ /dev/null @@ -1,216 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2013, ARM Limited. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#ifndef ARMV7_MMU_H_ -#define ARMV7_MMU_H_ - -#define TTBR_NOT_OUTER_SHAREABLE BIT5 -#define TTBR_RGN_OUTER_NON_CACHEABLE 0 -#define TTBR_RGN_OUTER_WRITE_BACK_ALLOC BIT3 -#define TTBR_RGN_OUTER_WRITE_THROUGH BIT4 -#define TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC (BIT3|BIT4) -#define TTBR_SHAREABLE BIT1 -#define TTBR_NON_SHAREABLE 0 -#define TTBR_INNER_CACHEABLE BIT0 -#define TTBR_INNER_NON_CACHEABLE 0 -#define TTBR_RGN_INNER_NON_CACHEABLE 0 -#define TTBR_RGN_INNER_WRITE_BACK_ALLOC BIT6 -#define TTBR_RGN_INNER_WRITE_THROUGH BIT0 -#define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC (BIT0|BIT6) - -#define TTBR_WRITE_THROUGH ( TTBR_RGN_OUTER_WRITE_THROUGH | TTBR_INNER_CACHEABLE | TTBR_SHAREABLE) -#define TTBR_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_INNER_CACHEABLE | TTBR_SHAREABLE) -#define TTBR_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_INNER_NON_CACHEABLE ) -#define TTBR_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_INNER_CACHEABLE | TTBR_SHAREABLE) - -#define TTBR_MP_WRITE_THROUGH ( TTBR_RGN_OUTER_WRITE_THROUGH | TTBR_RGN_INNER_WRITE_THROUGH | TTBR_SHAREABLE) -#define TTBR_MP_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC | TTBR_SHAREABLE) -#define TTBR_MP_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE ) -#define TTBR_MP_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC | TTBR_SHAREABLE) - -#define TRANSLATION_TABLE_SECTION_COUNT 4096 -#define TRANSLATION_TABLE_SECTION_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT) -#define TRANSLATION_TABLE_SECTION_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT) -#define TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK (TRANSLATION_TABLE_SECTION_ALIGNMENT - 1) - -#define TRANSLATION_TABLE_PAGE_COUNT 256 -#define TRANSLATION_TABLE_PAGE_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT) -#define TRANSLATION_TABLE_PAGE_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT) -#define TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK (TRANSLATION_TABLE_PAGE_ALIGNMENT - 1) - -#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20)) - -// Translation table descriptor types -#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (3UL << 0)) -#define TT_DESCRIPTOR_SECTION_TYPE_FAULT (0UL << 0) -#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE (1UL << 0) -#define TT_DESCRIPTOR_SECTION_TYPE_SECTION ((0UL << 18) | (2UL << 0)) -#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0)) -#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE) - -// Translation table descriptor types -#define TT_DESCRIPTOR_PAGE_TYPE_MASK (1UL << 1) -#define TT_DESCRIPTOR_PAGE_TYPE_FAULT (0UL << 1) -#define TT_DESCRIPTOR_PAGE_TYPE_PAGE (1UL << 1) - -// Section descriptor definitions -#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000) - -#define TT_DESCRIPTOR_SECTION_NS_MASK (1UL << 19) -#define TT_DESCRIPTOR_SECTION_NS (1UL << 19) - -#define TT_DESCRIPTOR_SECTION_NG_MASK (1UL << 17) -#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17) -#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17) - -#define TT_DESCRIPTOR_PAGE_NG_MASK (1UL << 11) -#define TT_DESCRIPTOR_PAGE_NG_GLOBAL (0UL << 11) -#define TT_DESCRIPTOR_PAGE_NG_LOCAL (1UL << 11) - -#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16) -#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16) -#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16) - -#define TT_DESCRIPTOR_PAGE_S_MASK (1UL << 10) -#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED (0UL << 10) -#define TT_DESCRIPTOR_PAGE_S_SHARED (1UL << 10) - -#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (1UL << 11)) -#define TT_DESCRIPTOR_SECTION_AP_NO_RW ((0UL << 15) | (0UL << 11)) -#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (1UL << 11)) -#define TT_DESCRIPTOR_SECTION_AP_NO_RO ((1UL << 15) | (0UL << 11)) -#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (1UL << 11)) - -#define TT_DESCRIPTOR_SECTION_AF (1UL << 10) - -#define TT_DESCRIPTOR_PAGE_AP_MASK ((1UL << 9) | (1UL << 5)) -#define TT_DESCRIPTOR_PAGE_AP_NO_RW ((0UL << 9) | (0UL << 5)) -#define TT_DESCRIPTOR_PAGE_AP_RW_RW ((0UL << 9) | (1UL << 5)) -#define TT_DESCRIPTOR_PAGE_AP_NO_RO ((1UL << 9) | (0UL << 5)) -#define TT_DESCRIPTOR_PAGE_AP_RO_RO ((1UL << 9) | (1UL << 5)) - -#define TT_DESCRIPTOR_PAGE_AF (1UL << 4) - -#define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4) -#define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0) - -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK (1UL << 3) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2)) - -#define TT_DESCRIPTOR_PAGE_SIZE (0x00001000) - -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK ((3UL << 6) | (1UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHEABLE_MASK (1UL << 3) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 6) | (0UL << 3) | (0UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 6) | (0UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 6) | (1UL << 3) | (0UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 6) | (1UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 6) | (0UL << 3) | (0UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 6) | (1UL << 3) | (1UL << 2)) -#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 6) | (0UL << 3) | (0UL << 2)) - -#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AF(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AF) >> 6) & TT_DESCRIPTOR_PAGE_AF) -#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc) ((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2))) - -#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_SECTION_S(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_S_MASK) << 6) & TT_DESCRIPTOR_SECTION_S_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AF(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AF) << 6) & TT_DESCRIPTOR_SECTION_AF) -#define TT_DESCRIPTOR_CONVERT_TO_SECTION_XN(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_XN_MASK) << 4) & TT_DESCRIPTOR_SECTION_XN_MASK) -#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc) ((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2))) - -#define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \ - TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \ - TT_DESCRIPTOR_SECTION_AF | \ - TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) - -#define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \ - TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_XN_MASK | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) - -#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5) -#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5) - -#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000) -#define TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK (0xFFFFFC00) -#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK) -#define TT_DESCRIPTOR_SECTION_BASE_SHIFT 20 - -#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK (0xFFFFF000) -#define TT_DESCRIPTOR_PAGE_INDEX_MASK (0x000FF000) -#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) -#define TT_DESCRIPTOR_PAGE_BASE_SHIFT 12 - -#define TT_DESCRIPTOR_SECTION_DEFAULT (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \ - TT_DESCRIPTOR_SECTION_NG_GLOBAL | \ - TT_DESCRIPTOR_SECTION_S_SHARED | \ - TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ - TT_DESCRIPTOR_SECTION_AP_RW_RW | \ - TT_DESCRIPTOR_SECTION_AF) - -#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_DEFAULT | \ - TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC) - -#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_SECTION_DEFAULT | \ - TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC) - -#define TT_DESCRIPTOR_SECTION_DEVICE (TT_DESCRIPTOR_SECTION_DEFAULT | \ - TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE) - -#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_SECTION_DEFAULT | \ - TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE) - -#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC) -#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC) -#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_XN_MASK | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE) -#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE) - -// First Level Descriptors -typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR; - -// Second Level Descriptors -typedef UINT32 ARM_PAGE_TABLE_ENTRY; - -UINT32 -ConvertSectionAttributesToPageAttributes ( - IN UINT32 SectionAttributes - ); - -#endif // ARMV7_MMU_H_ diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ArmException.c b/ArmPkg/Library/ArmExceptionLib/Arm/ArmException.c index fc411b845d..7652b97b43 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ArmException.c +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ArmException.c @@ -11,7 +11,7 @@ #include -#include +#include #include diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c index 521d5be0de..6acc4d3e7c 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include "ArmV7Lib.h" #include "ArmLibPrivate.h" diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c index 52dbfd7140..bf3a874822 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c @@ -11,7 +11,7 @@ #include -#include +#include UINT32 ConvertSectionAttributesToPageAttributes ( diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c index 28e4cd9f1a..60dc6c987c 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c @@ -8,7 +8,7 @@ **/ #include -#include +#include #include #include #include diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c index 548ee13038..5e751cddd7 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c @@ -17,7 +17,7 @@ #include #include -#include +#include #define __EFI_MEMORY_RWX 0 // no restrictions diff --git a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S index 6709dad0b9..60e530e4f1 100644 --- a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S @@ -7,7 +7,7 @@ #include -#include +#include ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions diff --git a/MdePkg/Include/Arm/AArch32.h b/MdePkg/Include/Arm/AArch32.h new file mode 100644 index 0000000000..e7e6e4dcd0 --- /dev/null +++ b/MdePkg/Include/Arm/AArch32.h @@ -0,0 +1,122 @@ +/** @file + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2011-2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef ARM_V7_H_ +#define ARM_V7_H_ + +#include + +// ARM Interrupt ID in Exception Table +#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_ARM_IRQ + +// ID_PFR1 - ARM Processor Feature Register 1 definitions +#define ARM_PFR1_SEC (0xFUL << 4) +#define ARM_PFR1_TIMER (0xFUL << 16) +#define ARM_PFR1_GIC (0xFUL << 28) + +// Domain Access Control Register +#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a))) + +// CPSR - Coprocessor Status Register definitions +#define CPSR_MODE_USER 0x10 +#define CPSR_MODE_FIQ 0x11 +#define CPSR_MODE_IRQ 0x12 +#define CPSR_MODE_SVC 0x13 +#define CPSR_MODE_ABORT 0x17 +#define CPSR_MODE_HYP 0x1A +#define CPSR_MODE_UNDEFINED 0x1B +#define CPSR_MODE_SYSTEM 0x1F +#define CPSR_MODE_MASK 0x1F +#define CPSR_ASYNC_ABORT (1 << 8) +#define CPSR_IRQ (1 << 7) +#define CPSR_FIQ (1 << 6) + +// CPACR - Coprocessor Access Control Register definitions +#define CPACR_CP_DENIED(cp) 0x00 +#define CPACR_CP_PRIV(cp) ((0x1 << ((cp) << 1)) & 0x0FFFFFFF) +#define CPACR_CP_FULL(cp) ((0x3 << ((cp) << 1)) & 0x0FFFFFFF) +#define CPACR_ASEDIS (1 << 31) +#define CPACR_D32DIS (1 << 30) +#define CPACR_CP_FULL_ACCESS 0x0FFFFFFF + +// NSACR - Non-Secure Access Control Register definitions +#define NSACR_CP(cp) ((1 << (cp)) & 0x3FFF) +#define NSACR_NSD32DIS (1 << 14) +#define NSACR_NSASEDIS (1 << 15) +#define NSACR_PLE (1 << 16) +#define NSACR_TL (1 << 17) +#define NSACR_NS_SMP (1 << 18) +#define NSACR_RFR (1 << 19) + +// SCR - Secure Configuration Register definitions +#define SCR_NS (1 << 0) +#define SCR_IRQ (1 << 1) +#define SCR_FIQ (1 << 2) +#define SCR_EA (1 << 3) +#define SCR_FW (1 << 4) +#define SCR_AW (1 << 5) + +// MIDR - Main ID Register definitions +#define ARM_CPU_TYPE_SHIFT 4 +#define ARM_CPU_TYPE_MASK 0xFFF +#define ARM_CPU_TYPE_AEMV8 0xD0F +#define ARM_CPU_TYPE_A53 0xD03 +#define ARM_CPU_TYPE_A57 0xD07 +#define ARM_CPU_TYPE_A15 0xC0F +#define ARM_CPU_TYPE_A12 0xC0D +#define ARM_CPU_TYPE_A9 0xC09 +#define ARM_CPU_TYPE_A7 0xC07 +#define ARM_CPU_TYPE_A5 0xC05 + +#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) ) +#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF)) + +#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 5)-1) + +VOID +EFIAPI +ArmEnableSWPInstruction ( + VOID + ); + +UINTN +EFIAPI +ArmReadCbar ( + VOID + ); + +UINTN +EFIAPI +ArmReadTpidrurw ( + VOID + ); + +VOID +EFIAPI +ArmWriteTpidrurw ( + UINTN Value + ); + +UINT32 +EFIAPI +ArmReadNsacr ( + VOID + ); + +VOID +EFIAPI +ArmWriteNsacr ( + IN UINT32 Nsacr + ); + +#endif // ARM_V7_H_ diff --git a/MdePkg/Include/Arm/AArch32Mmu.h b/MdePkg/Include/Arm/AArch32Mmu.h new file mode 100644 index 0000000000..89b81e33d0 --- /dev/null +++ b/MdePkg/Include/Arm/AArch32Mmu.h @@ -0,0 +1,216 @@ +/** @file +* +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#ifndef ARMV7_MMU_H_ +#define ARMV7_MMU_H_ + +#define TTBR_NOT_OUTER_SHAREABLE BIT5 +#define TTBR_RGN_OUTER_NON_CACHEABLE 0 +#define TTBR_RGN_OUTER_WRITE_BACK_ALLOC BIT3 +#define TTBR_RGN_OUTER_WRITE_THROUGH BIT4 +#define TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC (BIT3|BIT4) +#define TTBR_SHAREABLE BIT1 +#define TTBR_NON_SHAREABLE 0 +#define TTBR_INNER_CACHEABLE BIT0 +#define TTBR_INNER_NON_CACHEABLE 0 +#define TTBR_RGN_INNER_NON_CACHEABLE 0 +#define TTBR_RGN_INNER_WRITE_BACK_ALLOC BIT6 +#define TTBR_RGN_INNER_WRITE_THROUGH BIT0 +#define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC (BIT0|BIT6) + +#define TTBR_WRITE_THROUGH ( TTBR_RGN_OUTER_WRITE_THROUGH | TTBR_INNER_CACHEABLE | TTBR_SHAREABLE) +#define TTBR_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_INNER_CACHEABLE | TTBR_SHAREABLE) +#define TTBR_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_INNER_NON_CACHEABLE ) +#define TTBR_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_INNER_CACHEABLE | TTBR_SHAREABLE) + +#define TTBR_MP_WRITE_THROUGH ( TTBR_RGN_OUTER_WRITE_THROUGH | TTBR_RGN_INNER_WRITE_THROUGH | TTBR_SHAREABLE) +#define TTBR_MP_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC | TTBR_SHAREABLE) +#define TTBR_MP_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE ) +#define TTBR_MP_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC | TTBR_SHAREABLE) + +#define TRANSLATION_TABLE_SECTION_COUNT 4096 +#define TRANSLATION_TABLE_SECTION_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT) +#define TRANSLATION_TABLE_SECTION_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT) +#define TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK (TRANSLATION_TABLE_SECTION_ALIGNMENT - 1) + +#define TRANSLATION_TABLE_PAGE_COUNT 256 +#define TRANSLATION_TABLE_PAGE_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT) +#define TRANSLATION_TABLE_PAGE_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT) +#define TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK (TRANSLATION_TABLE_PAGE_ALIGNMENT - 1) + +#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20)) + +// Translation table descriptor types +#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (3UL << 0)) +#define TT_DESCRIPTOR_SECTION_TYPE_FAULT (0UL << 0) +#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE (1UL << 0) +#define TT_DESCRIPTOR_SECTION_TYPE_SECTION ((0UL << 18) | (2UL << 0)) +#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0)) +#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE) + +// Translation table descriptor types +#define TT_DESCRIPTOR_PAGE_TYPE_MASK (1UL << 1) +#define TT_DESCRIPTOR_PAGE_TYPE_FAULT (0UL << 1) +#define TT_DESCRIPTOR_PAGE_TYPE_PAGE (1UL << 1) + +// Section descriptor definitions +#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000) + +#define TT_DESCRIPTOR_SECTION_NS_MASK (1UL << 19) +#define TT_DESCRIPTOR_SECTION_NS (1UL << 19) + +#define TT_DESCRIPTOR_SECTION_NG_MASK (1UL << 17) +#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17) +#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17) + +#define TT_DESCRIPTOR_PAGE_NG_MASK (1UL << 11) +#define TT_DESCRIPTOR_PAGE_NG_GLOBAL (0UL << 11) +#define TT_DESCRIPTOR_PAGE_NG_LOCAL (1UL << 11) + +#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16) +#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16) +#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16) + +#define TT_DESCRIPTOR_PAGE_S_MASK (1UL << 10) +#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED (0UL << 10) +#define TT_DESCRIPTOR_PAGE_S_SHARED (1UL << 10) + +#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (1UL << 11)) +#define TT_DESCRIPTOR_SECTION_AP_NO_RW ((0UL << 15) | (0UL << 11)) +#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (1UL << 11)) +#define TT_DESCRIPTOR_SECTION_AP_NO_RO ((1UL << 15) | (0UL << 11)) +#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (1UL << 11)) + +#define TT_DESCRIPTOR_SECTION_AF (1UL << 10) + +#define TT_DESCRIPTOR_PAGE_AP_MASK ((1UL << 9) | (1UL << 5)) +#define TT_DESCRIPTOR_PAGE_AP_NO_RW ((0UL << 9) | (0UL << 5)) +#define TT_DESCRIPTOR_PAGE_AP_RW_RW ((0UL << 9) | (1UL << 5)) +#define TT_DESCRIPTOR_PAGE_AP_NO_RO ((1UL << 9) | (0UL << 5)) +#define TT_DESCRIPTOR_PAGE_AP_RO_RO ((1UL << 9) | (1UL << 5)) + +#define TT_DESCRIPTOR_PAGE_AF (1UL << 4) + +#define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4) +#define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0) + +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK (1UL << 3) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2)) + +#define TT_DESCRIPTOR_PAGE_SIZE (0x00001000) + +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK ((3UL << 6) | (1UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHEABLE_MASK (1UL << 3) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 6) | (0UL << 3) | (0UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 6) | (0UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 6) | (1UL << 3) | (0UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 6) | (1UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 6) | (0UL << 3) | (0UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 6) | (1UL << 3) | (1UL << 2)) +#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 6) | (0UL << 3) | (0UL << 2)) + +#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AF(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AF) >> 6) & TT_DESCRIPTOR_PAGE_AF) +#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc) ((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2))) + +#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_SECTION_S(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_S_MASK) << 6) & TT_DESCRIPTOR_SECTION_S_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AF(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AF) << 6) & TT_DESCRIPTOR_SECTION_AF) +#define TT_DESCRIPTOR_CONVERT_TO_SECTION_XN(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_XN_MASK) << 4) & TT_DESCRIPTOR_SECTION_XN_MASK) +#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc) ((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2))) + +#define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \ + TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \ + TT_DESCRIPTOR_SECTION_AF | \ + TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) + +#define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \ + TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_XN_MASK | \ + TT_DESCRIPTOR_PAGE_AF | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) + +#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5) +#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5) + +#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000) +#define TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK (0xFFFFFC00) +#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK) +#define TT_DESCRIPTOR_SECTION_BASE_SHIFT 20 + +#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK (0xFFFFF000) +#define TT_DESCRIPTOR_PAGE_INDEX_MASK (0x000FF000) +#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) +#define TT_DESCRIPTOR_PAGE_BASE_SHIFT 12 + +#define TT_DESCRIPTOR_SECTION_DEFAULT (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \ + TT_DESCRIPTOR_SECTION_NG_GLOBAL | \ + TT_DESCRIPTOR_SECTION_S_SHARED | \ + TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ + TT_DESCRIPTOR_SECTION_AP_RW_RW | \ + TT_DESCRIPTOR_SECTION_AF) + +#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_DEFAULT | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC) + +#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_SECTION_DEFAULT | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC) + +#define TT_DESCRIPTOR_SECTION_DEVICE (TT_DESCRIPTOR_SECTION_DEFAULT | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE) + +#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_SECTION_DEFAULT | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE) + +#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ + TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ + TT_DESCRIPTOR_PAGE_S_SHARED | \ + TT_DESCRIPTOR_PAGE_AP_RW_RW | \ + TT_DESCRIPTOR_PAGE_AF | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC) +#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ + TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ + TT_DESCRIPTOR_PAGE_S_SHARED | \ + TT_DESCRIPTOR_PAGE_AP_RW_RW | \ + TT_DESCRIPTOR_PAGE_AF | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC) +#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ + TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ + TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ + TT_DESCRIPTOR_PAGE_AP_RW_RW | \ + TT_DESCRIPTOR_PAGE_AF | \ + TT_DESCRIPTOR_PAGE_XN_MASK | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE) +#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ + TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ + TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ + TT_DESCRIPTOR_PAGE_AP_RW_RW | \ + TT_DESCRIPTOR_PAGE_AF | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE) + +// First Level Descriptors +typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR; + +// Second Level Descriptors +typedef UINT32 ARM_PAGE_TABLE_ENTRY; + +UINT32 +ConvertSectionAttributesToPageAttributes ( + IN UINT32 SectionAttributes + ); + +#endif // ARMV7_MMU_H_ diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index 852264dba2..71c2076652 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -14,7 +14,7 @@ #include #ifdef MDE_CPU_ARM - #include + #include #elif defined (MDE_CPU_AARCH64) #include #else -- cgit From a84876ba283176eb683dc84274bc6c66faffc7a0 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 10 Jun 2024 14:32:50 +0100 Subject: OvmfPkg/Xen: Fix use of networking Since commit 4c4ceb2ceb80 ("NetworkPkg: SECURITY PATCH CVE-2023-45237"), networking modules depend on gEfiRngProtocolGuid but nothing in OvmfXen provides it. This is visible in the logs as several modules present but not loading: Driver A2F436EA-A127-4EF8-957C-8048606FF670 was discovered but not loaded!! Driver E4F61863-FE2C-4B56-A8F4-08519BC439DF was discovered but not loaded!! Driver 025BBFC7-E6A9-4B8B-82AD-6815A1AEAF4A was discovered but not loaded!! Driver 529D3F93-E8E9-4E73-B1E1-BDF6A9D50113 was discovered but not loaded!! Driver 94734718-0BBC-47FB-96A5-EE7A5AE6A2AD was discovered but not loaded!! Include SecurityPkg/RandomNumberGenerator/RngDxe to fix this. Signed-off-by: Ross Lagerwall --- OvmfPkg/OvmfXen.dsc | 2 ++ OvmfPkg/OvmfXen.fdf | 2 ++ 2 files changed, 4 insertions(+) diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index 7fc340d1c1..c6fc3031ca 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -642,6 +642,8 @@ OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf + SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf + # # ISA Support # diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf index 41368f37e2..84564b3552 100644 --- a/OvmfPkg/OvmfXen.fdf +++ b/OvmfPkg/OvmfXen.fdf @@ -314,6 +314,8 @@ INF ShellPkg/Application/Shell/Shell.inf INF MdeModulePkg/Logo/LogoDxe.inf +INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf + # # Hash2 Protocol producer # -- cgit From d8095b36abc521970dd930449a8ae8ddc431314c Mon Sep 17 00:00:00 2001 From: Jeff Brasen Date: Tue, 30 Jan 2024 15:05:08 -0800 Subject: ArmPkg/CompilerIntrinsicsLib: provide __ashlti3 The compiler will use this function if it is left shifting a 128 bit value. Seen when updating OpenSSL. Signed-off-by: Jeff Brasen --- .../CompilerIntrinsicsLib/AArch64/ashlti3.S | 33 ++++++++++++++++++++++ .../CompilerIntrinsicsLib.inf | 1 + 2 files changed, 34 insertions(+) create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S new file mode 100644 index 0000000000..79a7b3514c --- /dev/null +++ b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S @@ -0,0 +1,33 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +#include + +ASM_FUNC(__ashlti3) + # return if shift is 0 + cbz x2, 1f + + mov x3, #64 + sub x3, x3, x2 + cmp x3, #0 + b.le 2f + + # shift is <= 64 bits + lsr x3, x0, x3 + lsl x1, x1, x2 + orr x1, x1, x3 + lsl x0, x0, x2 +1: + ret + +2: + # shift is > 64 + neg w3, w3 + lsl x1, x0, x3 + mov x0, #0 + ret diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf index 7e22e6f67b..054e681307 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf +++ b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf @@ -66,6 +66,7 @@ [Sources.AARCH64] AArch64/Atomics.S | GCC + AArch64/ashlti3.S | GCC [Packages] MdePkg/MdePkg.dec -- cgit From aa99d36be9ad68d8d0a99896332a9b5da10cf343 Mon Sep 17 00:00:00 2001 From: Jeff Brasen Date: Wed, 7 Feb 2024 23:42:09 -0800 Subject: BaseTools/BuildReport: Improve compile_commands generation This produces output that matches CodeChecker log command - Set directory to build output path - Set build destination to the object created instead of the path - Add recursive macro support - Add lookup in module.Macros dictionary - Add leading include flag to include list - Add source file to compile commands Signed-off-by: Jeff Brasen --- BaseTools/Source/Python/build/BuildReport.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 26dfe53fff..497bbbd646 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -2416,20 +2416,27 @@ class BuildReport(object): # Generate compile command for each c file # compile_command["file"] = source.Path - compile_command["directory"] = source.Dir + compile_command["directory"] = module.BuildDir build_command = module.BuildRules[source.Ext].CommandList[0] + destination = os.path.join (module.OutputDir, os.path.join (source.SubDir, source.BaseName + ".obj")) build_command_variables = re.findall(r"\$\((.*?)\)", build_command) - for var in build_command_variables: + while build_command_variables: + var = build_command_variables.pop() var_tokens = var.split("_") var_main = var_tokens[0] - if len(var_tokens) == 1: + if var == "INC": + var_value = inc_flag + f" {inc_flag}".join(module.IncludePathList) + elif var in module.Macros: + var_value = module.Macros[var] + elif len(var_tokens) == 1: var_value = module.BuildOption[var_main]["PATH"] else: var_value = module.BuildOption[var_main][var_tokens[1]] build_command = build_command.replace(f"$({var})", var_value) - include_files = f" {inc_flag}".join(module.IncludePathList) - build_command = build_command.replace("${src}", include_files) - build_command = build_command.replace("${dst}", module.OutputDir) + build_command = build_command.replace("${src}", source.Path) + build_command = build_command.replace("${dst}", destination) + build_command = build_command.replace("$@", destination) + build_command_variables.extend (re.findall(r"\$\((.*?)\)", var_value)) # Remove un defined macros compile_command["command"] = re.sub(r"\$\(.*?\)", "", build_command) -- cgit From a7dbd2ac7b359644b4961b027d711893132cdb00 Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Fri, 14 Jun 2024 10:52:59 +0800 Subject: CryptoPkg: Fix strncpy for BaseCryptLibMbedTls REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2817 Because the change for strncpy, add the strncpy implementation. Signed-off-by: Wenxing Hou --- .../SysCall/DummyOpensslSupport.c | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c index d3786f0e2a..3b5f430378 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SysCall/DummyOpensslSupport.c @@ -258,9 +258,28 @@ strcpy ( const char *strSource ) { - // AsciiStrCpyS (strDest, MAX_STRING_SIZE, strSource); - // return strDest; - return NULL; + AsciiStrCpyS (strDest, AsciiStrnSizeS (strSource, MAX_STRING_SIZE - 1), strSource); + return strDest; +} + +char * +strncpy ( + char *strDest, + const char *strSource, + size_t count + ) +{ + UINTN DestMax = MAX_STRING_SIZE; + + if (count < MAX_STRING_SIZE) { + DestMax = count + 1; + } else { + count = MAX_STRING_SIZE-1; + } + + AsciiStrnCpyS (strDest, DestMax, strSource, (UINTN)count); + + return strDest; } // -- cgit From 587100a95d7bfddc60bc5699ae0cca45914f1d81 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Tue, 23 Apr 2024 13:33:46 +0800 Subject: UefiCpuPkg/SmmCpuSyncLib: Add MM_STANDALONE tag. Declares in the .inf file that the current component is an MM_STANDALONE Signed-off-by: Yuanhao Xie Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Jiaxin Wu Reviewed-by: Jiaxin Wu Reviewed-by: Ray Ni --- UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf index 6b0d49c30a..2199b7948d 100644 --- a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf +++ b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf @@ -3,7 +3,7 @@ # # This is SMM CPU Synchronization lib used for SMM CPU sync operations. # -# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2023 - 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -13,7 +13,7 @@ BASE_NAME = SmmCpuSyncLib FILE_GUID = 1ca1bc1a-16a4-46ef-956a-ca500fd3381f MODULE_TYPE = DXE_SMM_DRIVER - LIBRARY_CLASS = SmmCpuSyncLib|DXE_SMM_DRIVER + LIBRARY_CLASS = SmmCpuSyncLib|DXE_SMM_DRIVER MM_STANDALONE [Sources] SmmCpuSyncLib.c -- cgit From 9fc61309bf56aa7863e36b8f418a49ca6d8364d0 Mon Sep 17 00:00:00 2001 From: Jeff Brasen Date: Wed, 14 Dec 2022 23:07:06 -0700 Subject: ArmPkg/ProcessorSubClassDxe: Limit values to 0xFF The CoreCount, EnabledCore and ThreadCount counts should be set to 0xFF if value is greater than 255 per the SMBIOS specification. Signed-off-by: Jeff Brasen --- ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c index 9050588500..4f2d421337 100644 --- a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c +++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c @@ -709,11 +709,11 @@ AddSmbiosProcessorTypeTable ( Type4Record->L1CacheHandle = L1CacheHandle; Type4Record->L2CacheHandle = L2CacheHandle; Type4Record->L3CacheHandle = L3CacheHandle; - Type4Record->CoreCount = MiscProcessorData.CoreCount; + Type4Record->CoreCount = MIN (MiscProcessorData.CoreCount, MAX_UINT8); Type4Record->CoreCount2 = MiscProcessorData.CoreCount; - Type4Record->EnabledCoreCount = MiscProcessorData.CoresEnabled; + Type4Record->EnabledCoreCount = MIN (MiscProcessorData.CoresEnabled, MAX_UINT8); Type4Record->EnabledCoreCount2 = MiscProcessorData.CoresEnabled; - Type4Record->ThreadCount = MiscProcessorData.ThreadCount; + Type4Record->ThreadCount = MIN (MiscProcessorData.ThreadCount, MAX_UINT8); Type4Record->ThreadCount2 = MiscProcessorData.ThreadCount; Type4Record->CurrentSpeed = GetCpuFrequency (ProcessorIndex); -- cgit From 025a95b7edfbb6ca11356ab87a300db443bd105b Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 10 Apr 2024 11:27:51 +0800 Subject: MdeModulePkg:Add new gEdkiiVariableRuntimeCacheInfoHobGuid This commit defines VARIABLE_RUNTIME_CACHE_INFO HOB. The HOB is used to store the address and size of the buffer that will be used for variable runtime service when the PcdEnableVariableRuntimeCache is TRUE. In following patches, when PcdEnableVariableRuntimeCache is TRUE, VariablePei module will install a callback of gEfiPeiMemoryDiscoveredPpiGuid to allocate needed buffer for different type cache, unblock the buffer and build HOB. Then VariableSmmRuntimeDxe driver will consume the gEdkiiVariableRuntimeCacheInfoHobGuid to initialize the variable runtime cache related content. Signed-off-by: Dun Tan --- .../Include/Guid/VariableRuntimeCacheInfo.h | 61 ++++++++++++++++++++++ MdeModulePkg/MdeModulePkg.dec | 3 ++ 2 files changed, 64 insertions(+) create mode 100644 MdeModulePkg/Include/Guid/VariableRuntimeCacheInfo.h diff --git a/MdeModulePkg/Include/Guid/VariableRuntimeCacheInfo.h b/MdeModulePkg/Include/Guid/VariableRuntimeCacheInfo.h new file mode 100644 index 0000000000..2f807b8371 --- /dev/null +++ b/MdeModulePkg/Include/Guid/VariableRuntimeCacheInfo.h @@ -0,0 +1,61 @@ +/** @file + This Variable Runtime Cache Info HOB is used to store the address + and the size of the buffer that will be used for variable runtime + service when the PcdEnableVariableRuntimeCache is TRUE. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef VARIABLE_RUNTIME_CACHE_INFO_H_ +#define VARIABLE_RUNTIME_CACHE_INFO_H_ + +#define VARIABLE_RUNTIME_CACHE_INFO_HOB_REVISION 1 + +#define VARIABLE_RUNTIME_CACHE_INFO_GUID \ + { \ + 0x0f472f7d, 0x6713, 0x4915, {0x96, 0x14, 0x5d, 0xda, 0x28, 0x40, 0x10, 0x56} \ + } + +typedef struct { + /// + /// TRUE indicates GetVariable () or GetNextVariable () is being called. + /// When the value is FALSE, the given update (and any other pending updates) + /// can be flushed to the runtime cache. + /// + BOOLEAN ReadLock; + /// + /// TRUE indicates there is pending update for the given variable store needed + /// to be flushed to the runtime cache. + /// + BOOLEAN PendingUpdate; + /// + /// TRUE indicates all HOB variables have been flushed in flash. + /// + BOOLEAN HobFlushComplete; +} CACHE_INFO_FLAG; + +typedef struct { + EFI_PHYSICAL_ADDRESS CacheInfoFlagBuffer; + /// + /// Base address of the runtime Hob variable cache Buffer. + /// + EFI_PHYSICAL_ADDRESS RuntimeHobCacheBuffer; + UINT64 RuntimeHobCachePages; + /// + /// Base address of the non-volatile variable runtime cache Buffer. + /// + EFI_PHYSICAL_ADDRESS RuntimeNvCacheBuffer; + UINT64 RuntimeNvCachePages; + /// + /// Base address of the volatile variable runtime cache Buffer. + /// + EFI_PHYSICAL_ADDRESS RuntimeVolatileCacheBuffer; + UINT64 RuntimeVolatileCachePages; +} VARIABLE_RUNTIME_CACHE_INFO; + +extern EFI_GUID gEdkiiVariableRuntimeCacheInfoHobGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 02f330a453..fdd1d48c47 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -468,6 +468,9 @@ ## This GUID will be used to save MTRR_SETTINGS at EndOfDxe by LockBox and restore at S3 boot PEI phase for s3 usage. gEdkiiS3MtrrSettingGuid = { 0xd77baa84, 0xb332, 0x4463, { 0x9f, 0x1d, 0xce, 0x81, 0x00, 0xfe, 0x7f, 0x35 }} + ## Include/Guid/VariableRuntimeCacheInfo.h + gEdkiiVariableRuntimeCacheInfoHobGuid = { 0x0f472f7d, 0x6713, 0x4915, { 0x96, 0x14, 0x5d, 0xda, 0x28, 0x40, 0x10, 0x56 }} + [Ppis] ## Include/Ppi/FirmwareVolumeShadowPpi.h gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } } -- cgit From d8f513de3e3ef228af7e6facf0ad3e35c3224032 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 24 Apr 2024 17:41:42 +0800 Subject: MdeModulePkg:Create gEdkiiVariableRuntimeCacheInfoHobGuid Install the callback of gEfiPeiMemoryDiscoveredPpiGuid to create gEdkiiVariableRuntimeCacheInfoHobGuid in VariablePei module. When PcdEnableVariableRuntimeCache is TRUE, the callback will be installed to allocate the needed buffer for different type variable runtime cache, unblock the buffer and build this HOB. Then the runtime cache buffer address and size will be saved in the HOB content. Signed-off-by: Dun Tan --- MdeModulePkg/Universal/Variable/Pei/Variable.c | 301 ++++++++++++++++++++- MdeModulePkg/Universal/Variable/Pei/Variable.h | 3 + .../Universal/Variable/Pei/VariablePei.inf | 8 +- 3 files changed, 310 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.c b/MdeModulePkg/Universal/Variable/Pei/Variable.c index 26a4c73b45..26f95c6d95 100644 --- a/MdeModulePkg/Universal/Variable/Pei/Variable.c +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.c @@ -2,7 +2,7 @@ Implement ReadOnly Variable Services required by PEIM and install PEI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space. -Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -24,6 +24,31 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = { &mVariablePpi }; +/** + Build gEdkiiVariableRuntimeCacheInfoHobGuid. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. + @retval others Failed to build VariableRuntimeCacheInfo Hob. + +**/ +EFI_STATUS +EFIAPI +BuildVariableRuntimeCacheInfoHob ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mPostMemNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + BuildVariableRuntimeCacheInfoHob +}; + /** Provide the functionality of the variable services. @@ -41,6 +66,10 @@ PeimInitializeVariableServices ( IN CONST EFI_PEI_SERVICES **PeiServices ) { + if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) { + PeiServicesNotifyPpi (&mPostMemNotifyList); + } + return PeiServicesInstallPpi (&mPpiListVariable); } @@ -1250,3 +1279,273 @@ PeiGetNextVariableName ( } } } + +/** + Calculate the auth variable storage size converted from normal variable storage. + + @param[in] StoreInfo Pointer to the store info + @param[in] NormalHobVarStorage Pointer to the normal variable storage header + + @retval the auth variable storage size +**/ +UINTN +CalculateAuthVarStorageSize ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN VARIABLE_STORE_HEADER *NormalHobVarStorage + ) +{ + VARIABLE_HEADER *StartPtr; + VARIABLE_HEADER *EndPtr; + UINTN AuthVarStroageSize; + + AuthVarStroageSize = sizeof (VARIABLE_STORE_HEADER); + + // + // Calculate Auth Variable Storage Size + // + StartPtr = GetStartPointer (NormalHobVarStorage); + EndPtr = GetEndPointer (NormalHobVarStorage); + while (StartPtr < EndPtr) { + if (StartPtr->State == VAR_ADDED) { + AuthVarStroageSize = HEADER_ALIGN (AuthVarStroageSize); + AuthVarStroageSize += sizeof (AUTHENTICATED_VARIABLE_HEADER); + AuthVarStroageSize += StartPtr->NameSize + GET_PAD_SIZE (StartPtr->NameSize); + AuthVarStroageSize += StartPtr->DataSize + GET_PAD_SIZE (StartPtr->DataSize); + } + + StartPtr = GetNextVariablePtr (StoreInfo, StartPtr, StartPtr); + } + + return AuthVarStroageSize; +} + +/** + Calculate Hob variable cache size. + + @param[in] NvAuthFlag If the NV variable store is Auth. + + @retval Maximum of Nv variable cache size. + +**/ +UINTN +CalculateHobVariableCacheSize ( + IN BOOLEAN NvAuthFlag + ) +{ + VARIABLE_STORE_INFO StoreInfo; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + VariableStoreHeader = NULL; + GetHobVariableStore (&StoreInfo, &VariableStoreHeader); + + if (VariableStoreHeader == NULL) { + return 0; + } + + if (NvAuthFlag == StoreInfo.AuthFlag) { + return VariableStoreHeader->Size; + } else { + // + // Normal NV variable store + Auth HOB variable store is not supported + // + ASSERT (NvAuthFlag && (!StoreInfo.AuthFlag)); + + // + // Need to calculate auth variable storage size converted from normal variable storage + // + return CalculateAuthVarStorageSize (&StoreInfo, VariableStoreHeader); + } +} + +/** + Calculate Nv variable cache size. + + @param[out] NvAuthFlag If the NV variable store is Auth. + + @retval Maximum of Nv variable cache size. + +**/ +UINTN +CalculateNvVariableCacheSize ( + OUT BOOLEAN *NvAuthFlag + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + EFI_PHYSICAL_ADDRESS NvStorageBase; + UINT32 NvStorageSize; + UINT64 NvStorageSize64; + FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; + + if (PcdGetBool (PcdEmuVariableNvModeEnable)) { + return PcdGet32 (PcdVariableStoreSize); + } + + Status = GetVariableFlashNvStorageInfo (&NvStorageBase, &NvStorageSize64); + ASSERT_EFI_ERROR (Status); + + Status = SafeUint64ToUint32 (NvStorageSize64, &NvStorageSize); + ASSERT_EFI_ERROR (Status); + ASSERT (NvStorageBase != 0); + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)NvStorageBase; + + // + // Check the FTW last write data hob. + // + GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); + if (GuidHob != NULL) { + FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *)GET_GUID_HOB_DATA (GuidHob); + if (FtwLastWriteData->TargetAddress == NvStorageBase) { + // + // Let FvHeader point to spare block. + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FtwLastWriteData->SpareAddress; + } + } + + VariableStoreHeader = (VARIABLE_STORE_HEADER *)((UINT8 *)FvHeader + FvHeader->HeaderLength); + *NvAuthFlag = (BOOLEAN)(CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)); + + return NvStorageSize - FvHeader->HeaderLength; +} + +/** + Build gEdkiiVariableRuntimeCacheInfoHobGuid. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. + @retval others Failed to build VariableRuntimeCacheInfo Hob. + +**/ +EFI_STATUS +EFIAPI +BuildVariableRuntimeCacheInfoHob ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + VARIABLE_RUNTIME_CACHE_INFO TempHobBuffer; + VARIABLE_RUNTIME_CACHE_INFO *VariableRuntimeCacheInfo; + EFI_STATUS Status; + VOID *Buffer; + UINTN BufferSize; + BOOLEAN NvAuthFlag; + UINTN Pages; + + ZeroMem (&TempHobBuffer, sizeof (VARIABLE_RUNTIME_CACHE_INFO)); + + // + // AllocateRuntimePages for CACHE_INFO_FLAG and unblock it. + // + Pages = EFI_SIZE_TO_PAGES (sizeof (CACHE_INFO_FLAG)); + Buffer = AllocateRuntimePages (Pages); + ASSERT (Buffer != NULL); + Status = MmUnblockMemoryRequest ( + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, + Pages + ); + if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { + return Status; + } + + TempHobBuffer.CacheInfoFlagBuffer = (UINTN)Buffer; + DEBUG (( + DEBUG_INFO, + "PeiVariable: CACHE_INFO_FLAG Buffer is: 0x%lx, number of pages is: 0x%x\n", + TempHobBuffer.CacheInfoFlagBuffer, + Pages + )); + + // + // AllocateRuntimePages for VolatileCache and unblock it. + // + BufferSize = PcdGet32 (PcdVariableStoreSize); + if (BufferSize > 0) { + Pages = EFI_SIZE_TO_PAGES (BufferSize); + Buffer = AllocateRuntimePages (Pages); + ASSERT (Buffer != NULL); + Status = MmUnblockMemoryRequest ( + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, + Pages + ); + if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { + return Status; + } + + TempHobBuffer.RuntimeVolatileCacheBuffer = (UINTN)Buffer; + TempHobBuffer.RuntimeVolatileCachePages = Pages; + } + + DEBUG (( + DEBUG_INFO, + "PeiVariable: Volatile cache Buffer is: 0x%lx, number of pages is: 0x%lx\n", + TempHobBuffer.RuntimeVolatileCacheBuffer, + TempHobBuffer.RuntimeVolatileCachePages + )); + + // + // AllocateRuntimePages for NVCache and unblock it. + // + BufferSize = CalculateNvVariableCacheSize (&NvAuthFlag); + if (BufferSize > 0) { + Pages = EFI_SIZE_TO_PAGES (BufferSize); + Buffer = AllocateRuntimePages (Pages); + ASSERT (Buffer != NULL); + Status = MmUnblockMemoryRequest ( + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, + Pages + ); + if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { + return Status; + } + + TempHobBuffer.RuntimeNvCacheBuffer = (UINTN)Buffer; + TempHobBuffer.RuntimeNvCachePages = Pages; + } + + DEBUG (( + DEBUG_INFO, + "PeiVariable: NV cache Buffer is: 0x%lx, number of pages is: 0x%lx\n", + TempHobBuffer.RuntimeNvCacheBuffer, + TempHobBuffer.RuntimeNvCachePages + )); + + // + // AllocateRuntimePages for HobCache and unblock it. + // + BufferSize = CalculateHobVariableCacheSize (NvAuthFlag); + if (BufferSize > 0) { + Pages = EFI_SIZE_TO_PAGES (BufferSize); + Buffer = AllocateRuntimePages (Pages); + ASSERT (Buffer != NULL); + Status = MmUnblockMemoryRequest ( + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, + Pages + ); + if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { + return Status; + } + + TempHobBuffer.RuntimeHobCacheBuffer = (UINTN)Buffer; + TempHobBuffer.RuntimeHobCachePages = Pages; + } + + DEBUG (( + DEBUG_INFO, + "PeiVariable: HOB cache Buffer is: 0x%lx, number of pages is: 0x%lx\n", + TempHobBuffer.RuntimeHobCacheBuffer, + TempHobBuffer.RuntimeHobCachePages + )); + + VariableRuntimeCacheInfo = BuildGuidHob (&gEdkiiVariableRuntimeCacheInfoHobGuid, sizeof (VARIABLE_RUNTIME_CACHE_INFO)); + ASSERT (VariableRuntimeCacheInfo != NULL); + CopyMem (VariableRuntimeCacheInfo, &TempHobBuffer, sizeof (VARIABLE_RUNTIME_CACHE_INFO)); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.h b/MdeModulePkg/Universal/Variable/Pei/Variable.h index 51effbf799..aa0d79f166 100644 --- a/MdeModulePkg/Universal/Variable/Pei/Variable.h +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.h @@ -22,11 +22,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include +#include #include #include #include #include +#include typedef enum { VariableStoreTypeHob, diff --git a/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf b/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf index 7264a24bdf..f2dc7c042c 100644 --- a/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf +++ b/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf @@ -3,7 +3,7 @@ # # This module implements ReadOnly Variable Services required by PEIM and installs PEI ReadOnly Varaiable2 PPI. # -# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -41,6 +41,8 @@ PeiServicesLib SafeIntLib VariableFlashInfoLib + MmUnblockMemoryLib + MemoryAllocationLib [Guids] ## CONSUMES ## GUID # Variable store header @@ -56,12 +58,16 @@ ## SOMETIMES_CONSUMES ## HOB ## CONSUMES ## GUID # Dependence gEdkiiFaultTolerantWriteGuid + gEdkiiVariableRuntimeCacheInfoHobGuid [Ppis] gEfiPeiReadOnlyVariable2PpiGuid ## PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache ## CONSUMES [Depex] gEdkiiFaultTolerantWriteGuid -- cgit From 645d9f6f8d221802dc9cdf22b05139b593817507 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 14 May 2024 12:13:15 +0800 Subject: MdeModulePkg:Remove unnecessary global variables Remove the two unnecessary global variables and replace them by two local variables: mVariableRuntimeNvCacheBufferSize mVariableRuntimeVolatileCacheBufferSize Signed-off-by: Dun Tan --- .../Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 6930875e9f..8b42ae7d72 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -13,7 +13,7 @@ InitCommunicateBuffer() is really function to check the variable data size. -Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -55,8 +55,6 @@ VARIABLE_STORE_HEADER *mVariableRuntimeNvCacheBuffer = NULL; VARIABLE_STORE_HEADER *mVariableRuntimeVolatileCacheBuffer = NULL; UINTN mVariableBufferSize; UINTN mVariableRuntimeHobCacheBufferSize; -UINTN mVariableRuntimeNvCacheBufferSize; -UINTN mVariableRuntimeVolatileCacheBufferSize; UINTN mVariableBufferPayloadSize; BOOLEAN mVariableRuntimeCachePendingUpdate; BOOLEAN mVariableRuntimeCacheReadLock; @@ -1691,6 +1689,8 @@ SmmVariableReady ( ) { EFI_STATUS Status; + UINTN RuntimeNvCacheSize; + UINTN RuntimeVolatileCacheSize; Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable); if (EFI_ERROR (Status)) { @@ -1721,16 +1721,16 @@ SmmVariableReady ( // Status = GetRuntimeCacheInfo ( &mVariableRuntimeHobCacheBufferSize, - &mVariableRuntimeNvCacheBufferSize, - &mVariableRuntimeVolatileCacheBufferSize, + &RuntimeNvCacheSize, + &RuntimeVolatileCacheSize, &mVariableAuthFormat ); if (!EFI_ERROR (Status)) { Status = InitVariableCache (&mVariableRuntimeHobCacheBuffer, &mVariableRuntimeHobCacheBufferSize); if (!EFI_ERROR (Status)) { - Status = InitVariableCache (&mVariableRuntimeNvCacheBuffer, &mVariableRuntimeNvCacheBufferSize); + Status = InitVariableCache (&mVariableRuntimeNvCacheBuffer, &RuntimeNvCacheSize); if (!EFI_ERROR (Status)) { - Status = InitVariableCache (&mVariableRuntimeVolatileCacheBuffer, &mVariableRuntimeVolatileCacheBufferSize); + Status = InitVariableCache (&mVariableRuntimeVolatileCacheBuffer, &RuntimeVolatileCacheSize); if (!EFI_ERROR (Status)) { Status = SendRuntimeVariableCacheContextToSmm (); if (!EFI_ERROR (Status)) { -- cgit From c1c2e474a23ab134f93266815a1b4c147b0e9b48 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 27 May 2024 17:37:41 +0800 Subject: MdeModulePkg:Remove unneed FreePages for RuntimeHobCacheBuffer Remove unneed FreePages() for RuntimeHobCacheBuffer which is allocated in PEI phase. So the global variable mVariableRuntimeHobCacheBufferSize also can be removed. Signed-off-by: Dun Tan --- .../Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 8b42ae7d72..68082497d2 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -54,7 +54,6 @@ VARIABLE_STORE_HEADER *mVariableRuntimeHobCacheBuffer = NULL; VARIABLE_STORE_HEADER *mVariableRuntimeNvCacheBuffer = NULL; VARIABLE_STORE_HEADER *mVariableRuntimeVolatileCacheBuffer = NULL; UINTN mVariableBufferSize; -UINTN mVariableRuntimeHobCacheBufferSize; UINTN mVariableBufferPayloadSize; BOOLEAN mVariableRuntimeCachePendingUpdate; BOOLEAN mVariableRuntimeCacheReadLock; @@ -578,10 +577,6 @@ CheckForRuntimeCacheSync ( // The HOB variable data may have finished being flushed in the runtime cache sync update // if (mHobFlushComplete && (mVariableRuntimeHobCacheBuffer != NULL)) { - if (!EfiAtRuntime ()) { - FreePages (mVariableRuntimeHobCacheBuffer, EFI_SIZE_TO_PAGES (mVariableRuntimeHobCacheBufferSize)); - } - mVariableRuntimeHobCacheBuffer = NULL; } } @@ -1691,6 +1686,7 @@ SmmVariableReady ( EFI_STATUS Status; UINTN RuntimeNvCacheSize; UINTN RuntimeVolatileCacheSize; + UINTN RuntimeHobCacheBufferSize; Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable); if (EFI_ERROR (Status)) { @@ -1720,13 +1716,13 @@ SmmVariableReady ( // Allocate runtime variable cache memory buffers. // Status = GetRuntimeCacheInfo ( - &mVariableRuntimeHobCacheBufferSize, + &RuntimeHobCacheBufferSize, &RuntimeNvCacheSize, &RuntimeVolatileCacheSize, &mVariableAuthFormat ); if (!EFI_ERROR (Status)) { - Status = InitVariableCache (&mVariableRuntimeHobCacheBuffer, &mVariableRuntimeHobCacheBufferSize); + Status = InitVariableCache (&mVariableRuntimeHobCacheBuffer, &RuntimeHobCacheBufferSize); if (!EFI_ERROR (Status)) { Status = InitVariableCache (&mVariableRuntimeNvCacheBuffer, &RuntimeNvCacheSize); if (!EFI_ERROR (Status)) { -- cgit From 689f415a494b859453c5ebec7aa8c94d310a0b25 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 17 May 2024 14:39:45 +0800 Subject: MdeModulePkg:Consume gEdkiiVariableRuntimeCacheInfoHobGuid Consume gEdkiiVariableRuntimeCacheInfoHobGuid in VariableSmmRuntimeDxe driver to initialize the following variable cache related buffer: *mVariableRuntimeHobCacheBuffer *mVariableRuntimeNvCacheBuffer *mVariableRuntimeVolatileCacheBuffer *mVariableRuntimeCachePendingUpdate *mVariableRuntimeCacheReadLock *mHobFlushComplete The code to to allocate and unblock the buffer for different type cache in VariableSmmRuntimeDxe is also removed in this commit. Signed-off-by: Dun Tan --- .../Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 124 +++++++++------------ .../Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf | 5 +- 2 files changed, 55 insertions(+), 74 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 68082497d2..aedcae6383 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -35,10 +35,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include +#include #include "PrivilegePolymorphic.h" #include "VariableParsing.h" @@ -55,10 +56,10 @@ VARIABLE_STORE_HEADER *mVariableRuntimeNvCacheBuffer = NULL; VARIABLE_STORE_HEADER *mVariableRuntimeVolatileCacheBuffer = NULL; UINTN mVariableBufferSize; UINTN mVariableBufferPayloadSize; -BOOLEAN mVariableRuntimeCachePendingUpdate; -BOOLEAN mVariableRuntimeCacheReadLock; +BOOLEAN *mVariableRuntimeCachePendingUpdate; +BOOLEAN *mVariableRuntimeCacheReadLock; BOOLEAN mVariableAuthFormat; -BOOLEAN mHobFlushComplete; +BOOLEAN *mHobFlushComplete; EFI_LOCK mVariableServicesLock; EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; EDKII_VAR_CHECK_PROTOCOL mVarCheck; @@ -179,27 +180,6 @@ InitVariableCache ( *TotalVariableCacheSize = ALIGN_VALUE (*TotalVariableCacheSize, sizeof (UINT32)); - // - // Allocate NV Storage Cache and initialize it to all 1's (like an erased FV) - // - *VariableCacheBuffer = (VARIABLE_STORE_HEADER *)AllocateRuntimePages ( - EFI_SIZE_TO_PAGES (*TotalVariableCacheSize) - ); - if (*VariableCacheBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Request to unblock the newly allocated cache region to be accessible from inside MM - // - Status = MmUnblockMemoryRequest ( - (EFI_PHYSICAL_ADDRESS)(UINTN)*VariableCacheBuffer, - EFI_SIZE_TO_PAGES (*TotalVariableCacheSize) - ); - if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { - return Status; - } - VariableCacheStorePtr = *VariableCacheBuffer; SetMem32 ((VOID *)VariableCacheStorePtr, *TotalVariableCacheSize, (UINT32)0xFFFFFFFF); @@ -567,16 +547,16 @@ CheckForRuntimeCacheSync ( VOID ) { - if (mVariableRuntimeCachePendingUpdate) { + if (*mVariableRuntimeCachePendingUpdate) { SyncRuntimeCache (); } - ASSERT (!mVariableRuntimeCachePendingUpdate); + ASSERT (!(*mVariableRuntimeCachePendingUpdate)); // // The HOB variable data may have finished being flushed in the runtime cache sync update // - if (mHobFlushComplete && (mVariableRuntimeHobCacheBuffer != NULL)) { + if ((*mHobFlushComplete) && (mVariableRuntimeHobCacheBuffer != NULL)) { mVariableRuntimeHobCacheBuffer = NULL; } } @@ -628,12 +608,12 @@ FindVariableInRuntimeCache ( // a GetVariable () or GetNextVariable () call from being issued until a prior call has returned. The runtime // cache read lock should always be free when entering this function. // - ASSERT (!mVariableRuntimeCacheReadLock); + ASSERT (!(*mVariableRuntimeCacheReadLock)); - mVariableRuntimeCacheReadLock = TRUE; + *mVariableRuntimeCacheReadLock = TRUE; CheckForRuntimeCacheSync (); - if (!mVariableRuntimeCachePendingUpdate) { + if (!(*mVariableRuntimeCachePendingUpdate)) { // // 0: Volatile, 1: HOB, 2: Non-Volatile. // The index and attributes mapping must be kept in this order as FindVariable @@ -693,7 +673,7 @@ Done: } } - mVariableRuntimeCacheReadLock = FALSE; + *mVariableRuntimeCacheReadLock = FALSE; return Status; } @@ -916,12 +896,12 @@ GetNextVariableNameInRuntimeCache ( // a GetVariable () or GetNextVariable () call from being issued until a prior call has returned. The runtime // cache read lock should always be free when entering this function. // - ASSERT (!mVariableRuntimeCacheReadLock); + ASSERT (!(*mVariableRuntimeCacheReadLock)); CheckForRuntimeCacheSync (); - mVariableRuntimeCacheReadLock = TRUE; - if (!mVariableRuntimeCachePendingUpdate) { + *mVariableRuntimeCacheReadLock = TRUE; + if (!(*mVariableRuntimeCachePendingUpdate)) { // // 0: Volatile, 1: HOB, 2: Non-Volatile. // The index and attributes mapping must be kept in this order as FindVariable @@ -953,7 +933,7 @@ GetNextVariableNameInRuntimeCache ( } } - mVariableRuntimeCacheReadLock = FALSE; + *mVariableRuntimeCacheReadLock = FALSE; return Status; } @@ -1411,6 +1391,9 @@ VariableAddressChangeEvent ( EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeHobCacheBuffer); EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeNvCacheBuffer); EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeVolatileCacheBuffer); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeCachePendingUpdate); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeCacheReadLock); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mHobFlushComplete); } /** @@ -1617,37 +1600,9 @@ SendRuntimeVariableCacheContextToSmm ( SmmRuntimeVarCacheContext->RuntimeHobCache = mVariableRuntimeHobCacheBuffer; SmmRuntimeVarCacheContext->RuntimeVolatileCache = mVariableRuntimeVolatileCacheBuffer; SmmRuntimeVarCacheContext->RuntimeNvCache = mVariableRuntimeNvCacheBuffer; - SmmRuntimeVarCacheContext->PendingUpdate = &mVariableRuntimeCachePendingUpdate; - SmmRuntimeVarCacheContext->ReadLock = &mVariableRuntimeCacheReadLock; - SmmRuntimeVarCacheContext->HobFlushComplete = &mHobFlushComplete; - - // - // Request to unblock this region to be accessible from inside MM environment - // These fields "should" be all on the same page, but just to be on the safe side... - // - Status = MmUnblockMemoryRequest ( - (EFI_PHYSICAL_ADDRESS)ALIGN_VALUE ((UINTN)SmmRuntimeVarCacheContext->PendingUpdate - EFI_PAGE_SIZE + 1, EFI_PAGE_SIZE), - EFI_SIZE_TO_PAGES (sizeof (mVariableRuntimeCachePendingUpdate)) - ); - if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { - goto Done; - } - - Status = MmUnblockMemoryRequest ( - (EFI_PHYSICAL_ADDRESS)ALIGN_VALUE ((UINTN)SmmRuntimeVarCacheContext->ReadLock - EFI_PAGE_SIZE + 1, EFI_PAGE_SIZE), - EFI_SIZE_TO_PAGES (sizeof (mVariableRuntimeCacheReadLock)) - ); - if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { - goto Done; - } - - Status = MmUnblockMemoryRequest ( - (EFI_PHYSICAL_ADDRESS)ALIGN_VALUE ((UINTN)SmmRuntimeVarCacheContext->HobFlushComplete - EFI_PAGE_SIZE + 1, EFI_PAGE_SIZE), - EFI_SIZE_TO_PAGES (sizeof (mHobFlushComplete)) - ); - if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { - goto Done; - } + SmmRuntimeVarCacheContext->PendingUpdate = mVariableRuntimeCachePendingUpdate; + SmmRuntimeVarCacheContext->ReadLock = mVariableRuntimeCacheReadLock; + SmmRuntimeVarCacheContext->HobFlushComplete = mHobFlushComplete; // // Send data to SMM. @@ -1683,10 +1638,15 @@ SmmVariableReady ( IN VOID *Context ) { - EFI_STATUS Status; - UINTN RuntimeNvCacheSize; - UINTN RuntimeVolatileCacheSize; - UINTN RuntimeHobCacheBufferSize; + EFI_STATUS Status; + UINTN RuntimeNvCacheSize; + UINTN RuntimeVolatileCacheSize; + UINTN RuntimeHobCacheBufferSize; + UINTN AllocatedHobCacheSize; + UINTN AllocatedNvCacheSize; + UINTN AllocatedVolatileCacheSize; + EFI_HOB_GUID_TYPE *GuidHob; + VARIABLE_RUNTIME_CACHE_INFO *VariableRuntimeCacheInfo; Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable); if (EFI_ERROR (Status)) { @@ -1713,7 +1673,7 @@ SmmVariableReady ( if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) { DEBUG ((DEBUG_INFO, "Variable driver runtime cache is enabled.\n")); // - // Allocate runtime variable cache memory buffers. + // Get needed runtime cache buffer size and check if auth variables are to be used from SMM // Status = GetRuntimeCacheInfo ( &RuntimeHobCacheBufferSize, @@ -1722,6 +1682,26 @@ SmmVariableReady ( &mVariableAuthFormat ); if (!EFI_ERROR (Status)) { + GuidHob = GetFirstGuidHob (&gEdkiiVariableRuntimeCacheInfoHobGuid); + ASSERT (GuidHob != NULL); + VariableRuntimeCacheInfo = GET_GUID_HOB_DATA (GuidHob); + AllocatedHobCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeHobCachePages); + AllocatedNvCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeNvCachePages); + AllocatedVolatileCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCachePages); + + ASSERT ( + (AllocatedHobCacheSize >= RuntimeHobCacheBufferSize) && + (AllocatedNvCacheSize >= RuntimeNvCacheSize) && + (AllocatedVolatileCacheSize >= RuntimeVolatileCacheSize) + ); + + mVariableRuntimeHobCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeHobCacheBuffer; + mVariableRuntimeNvCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeNvCacheBuffer; + mVariableRuntimeVolatileCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCacheBuffer; + mVariableRuntimeCachePendingUpdate = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->PendingUpdate; + mVariableRuntimeCacheReadLock = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->ReadLock; + mHobFlushComplete = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->HobFlushComplete; + Status = InitVariableCache (&mVariableRuntimeHobCacheBuffer, &RuntimeHobCacheBufferSize); if (!EFI_ERROR (Status)) { Status = InitVariableCache (&mVariableRuntimeNvCacheBuffer, &RuntimeNvCacheSize); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf index e1085653fe..2d16f28674 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf @@ -13,7 +13,7 @@ # may not be modified without authorization. If platform fails to protect these resources, # the authentication service provided in this driver will be broken, and the behavior is undefined. # -# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -60,7 +60,7 @@ TpmMeasurementLib SafeIntLib PcdLib - MmUnblockMemoryLib + HobLib [Protocols] gEfiVariableWriteArchProtocolGuid ## PRODUCES @@ -113,6 +113,7 @@ gVarCheckPolicyLibMmiHandlerGuid gEfiEndOfDxeEventGroupGuid gEfiDeviceSignatureDatabaseGuid + gEdkiiVariableRuntimeCacheInfoHobGuid [Depex] gEfiMmCommunication2ProtocolGuid -- cgit From 92974e3d189156f46c8f78390eec33d3e0e0c26e Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 13 Jun 2024 17:28:10 +0800 Subject: MdeModulePkg:Remove the usage of PcdEnableVariableRuntimeCache Remove the usage of PcdEnableVariableRuntimeCache. We can use the existence of gEdkiiVariableRuntimeCacheInfoHobGuid to indicate if variable runtime cache is enabled or not. Signed-off-by: Dun Tan --- .../Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 13 +++++++------ .../Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf | 1 - 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index aedcae6383..9bbf484645 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -63,6 +63,7 @@ BOOLEAN *mHobFlushComplete; EFI_LOCK mVariableServicesLock; EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; EDKII_VAR_CHECK_PROTOCOL mVarCheck; +BOOLEAN mIsRuntimeCacheEnabled = FALSE; /** The logic to initialize the VariablePolicy engine is in its own file. @@ -840,7 +841,7 @@ RuntimeServiceGetVariable ( } AcquireLockOnlyAtBootTime (&mVariableServicesLock); - if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) { + if (mIsRuntimeCacheEnabled) { Status = FindVariableInRuntimeCache (VariableName, VendorGuid, Attributes, DataSize, Data); } else { Status = FindVariableInSmm (VariableName, VendorGuid, Attributes, DataSize, Data); @@ -1106,7 +1107,7 @@ RuntimeServiceGetNextVariableName ( } AcquireLockOnlyAtBootTime (&mVariableServicesLock); - if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) { + if (mIsRuntimeCacheEnabled) { Status = GetNextVariableNameInRuntimeCache (VariableNameSize, VariableName, VendorGuid); } else { Status = GetNextVariableNameInSmm (VariableNameSize, VariableName, VendorGuid); @@ -1358,7 +1359,7 @@ OnReadyToBoot ( // // Install the system configuration table for variable info data captured // - if (FeaturePcdGet (PcdEnableVariableRuntimeCache) && FeaturePcdGet (PcdVariableCollectStatistics)) { + if (mIsRuntimeCacheEnabled && FeaturePcdGet (PcdVariableCollectStatistics)) { if (mVariableAuthFormat) { gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, mVariableInfo); } else { @@ -1670,7 +1671,9 @@ SmmVariableReady ( // mVariableBufferPhysical = mVariableBuffer; - if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) { + GuidHob = GetFirstGuidHob (&gEdkiiVariableRuntimeCacheInfoHobGuid); + if (GuidHob != NULL) { + mIsRuntimeCacheEnabled = TRUE; DEBUG ((DEBUG_INFO, "Variable driver runtime cache is enabled.\n")); // // Get needed runtime cache buffer size and check if auth variables are to be used from SMM @@ -1682,8 +1685,6 @@ SmmVariableReady ( &mVariableAuthFormat ); if (!EFI_ERROR (Status)) { - GuidHob = GetFirstGuidHob (&gEdkiiVariableRuntimeCacheInfoHobGuid); - ASSERT (GuidHob != NULL); VariableRuntimeCacheInfo = GET_GUID_HOB_DATA (GuidHob); AllocatedHobCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeHobCachePages); AllocatedNvCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeNvCachePages); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf index 2d16f28674..d984a3637d 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf @@ -75,7 +75,6 @@ gEdkiiVariablePolicyProtocolGuid ## PRODUCES [FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES [Pcd] -- cgit From 081df0ec203346e8fb711478c95d222f70a522eb Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 17 May 2024 14:47:42 +0800 Subject: MdeModulePkg: Refine InitVariableCache() Refine the code logic in InitVariableCache(). In this commit, three times calling of InitVariableCache() for different type cache are merged into one calling. This commit is to make the code looks cleaner and doesn't change any code functionality. Signed-off-by: Dun Tan --- .../Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 194 ++++++++++----------- 1 file changed, 94 insertions(+), 100 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 9bbf484645..36e65f12d2 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -144,54 +144,6 @@ AtRuntime ( return EfiAtRuntime (); } -/** - Initialize the variable cache buffer as an empty variable store. - - @param[out] VariableCacheBuffer A pointer to pointer of a cache variable store. - @param[in,out] TotalVariableCacheSize On input, the minimum size needed for the UEFI variable store cache - buffer that is allocated. On output, the actual size of the buffer allocated. - If TotalVariableCacheSize is zero, a buffer will not be allocated and the - function will return with EFI_SUCCESS. - - @retval EFI_SUCCESS The variable cache was allocated and initialized successfully. - @retval EFI_INVALID_PARAMETER A given pointer is NULL or an invalid variable store size was specified. - @retval EFI_OUT_OF_RESOURCES Insufficient resources are available to allocate the variable store cache buffer. - -**/ -EFI_STATUS -InitVariableCache ( - OUT VARIABLE_STORE_HEADER **VariableCacheBuffer, - IN OUT UINTN *TotalVariableCacheSize - ) -{ - VARIABLE_STORE_HEADER *VariableCacheStorePtr; - EFI_STATUS Status; - - if (TotalVariableCacheSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (*TotalVariableCacheSize == 0) { - return EFI_SUCCESS; - } - - if ((VariableCacheBuffer == NULL) || (*TotalVariableCacheSize < sizeof (VARIABLE_STORE_HEADER))) { - return EFI_INVALID_PARAMETER; - } - - *TotalVariableCacheSize = ALIGN_VALUE (*TotalVariableCacheSize, sizeof (UINT32)); - - VariableCacheStorePtr = *VariableCacheBuffer; - SetMem32 ((VOID *)VariableCacheStorePtr, *TotalVariableCacheSize, (UINT32)0xFFFFFFFF); - - ZeroMem ((VOID *)VariableCacheStorePtr, sizeof (VARIABLE_STORE_HEADER)); - VariableCacheStorePtr->Size = (UINT32)*TotalVariableCacheSize; - VariableCacheStorePtr->Format = VARIABLE_STORE_FORMATTED; - VariableCacheStorePtr->State = VARIABLE_STORE_HEALTHY; - - return EFI_SUCCESS; -} - /** Initialize the communicate buffer using DataSize and Function. @@ -1553,6 +1505,89 @@ Done: return Status; } +/** + Initialize the variable cache buffer as an empty variable store. + + @param[in] VariableCacheBuffer A pointer to pointer of a cache variable store. + @param[in] TotalVariableCacheSize The size needed for the UEFI variable store cache buffer that is allocated. + +**/ +VOID +InitVariableStoreHeader ( + IN VARIABLE_STORE_HEADER *VariableCacheBuffer, + IN UINTN TotalVariableCacheSize + ) +{ + if (TotalVariableCacheSize > 0) { + ASSERT ((VariableCacheBuffer != NULL) && (TotalVariableCacheSize >= sizeof (VARIABLE_STORE_HEADER))); + + SetMem32 ((VOID *)VariableCacheBuffer, TotalVariableCacheSize, (UINT32)0xFFFFFFFF); + ZeroMem ((VOID *)VariableCacheBuffer, sizeof (VARIABLE_STORE_HEADER)); + VariableCacheBuffer->Size = (UINT32)TotalVariableCacheSize; + VariableCacheBuffer->Format = VARIABLE_STORE_FORMATTED; + VariableCacheBuffer->State = VARIABLE_STORE_HEALTHY; + } +} + +/** + Initialize the runtime variable cache related content. + + @param[in] RuntimeCacheInfoGuidHob Pointer to the gEdkiiVariableRuntimeCacheInfoHobGuid HOB. + + @retval EFI_SUCCESS Initialize the runtime variable cache related content successfully. + @retval Others Could not initialize the runtime variable cache related content successfully. + +**/ +EFI_STATUS +InitVariableCache ( + IN EFI_HOB_GUID_TYPE *RuntimeCacheInfoGuidHob + ) +{ + EFI_STATUS Status; + UINTN ExpectedHobCacheSize; + UINTN ExpectedNvCacheSize; + UINTN ExpectedVolatileCacheSize; + UINTN AllocatedHobCacheSize; + UINTN AllocatedNvCacheSize; + UINTN AllocatedVolatileCacheSize; + VARIABLE_RUNTIME_CACHE_INFO *VariableRuntimeCacheInfo; + + // + // Get needed runtime cache buffer size and check if auth variables are to be used from SMM + // + Status = GetRuntimeCacheInfo ( + &ExpectedHobCacheSize, + &ExpectedNvCacheSize, + &ExpectedVolatileCacheSize, + &mVariableAuthFormat + ); + if (!EFI_ERROR (Status)) { + VariableRuntimeCacheInfo = GET_GUID_HOB_DATA (RuntimeCacheInfoGuidHob); + AllocatedHobCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeHobCachePages); + AllocatedNvCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeNvCachePages); + AllocatedVolatileCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCachePages); + + ASSERT ( + (AllocatedHobCacheSize >= ExpectedHobCacheSize) && + (AllocatedNvCacheSize >= ExpectedNvCacheSize) && + (AllocatedVolatileCacheSize >= ExpectedVolatileCacheSize) + ); + + mVariableRuntimeHobCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeHobCacheBuffer; + mVariableRuntimeNvCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeNvCacheBuffer; + mVariableRuntimeVolatileCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCacheBuffer; + mVariableRuntimeCachePendingUpdate = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->PendingUpdate; + mVariableRuntimeCacheReadLock = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->ReadLock; + mHobFlushComplete = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->HobFlushComplete; + + InitVariableStoreHeader (mVariableRuntimeHobCacheBuffer, AllocatedHobCacheSize); + InitVariableStoreHeader (mVariableRuntimeNvCacheBuffer, AllocatedNvCacheSize); + InitVariableStoreHeader (mVariableRuntimeVolatileCacheBuffer, AllocatedVolatileCacheSize); + } + + return Status; +} + /** Sends the runtime variable cache context information to SMM. @@ -1639,15 +1674,8 @@ SmmVariableReady ( IN VOID *Context ) { - EFI_STATUS Status; - UINTN RuntimeNvCacheSize; - UINTN RuntimeVolatileCacheSize; - UINTN RuntimeHobCacheBufferSize; - UINTN AllocatedHobCacheSize; - UINTN AllocatedNvCacheSize; - UINTN AllocatedVolatileCacheSize; - EFI_HOB_GUID_TYPE *GuidHob; - VARIABLE_RUNTIME_CACHE_INFO *VariableRuntimeCacheInfo; + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable); if (EFI_ERROR (Status)) { @@ -1675,53 +1703,19 @@ SmmVariableReady ( if (GuidHob != NULL) { mIsRuntimeCacheEnabled = TRUE; DEBUG ((DEBUG_INFO, "Variable driver runtime cache is enabled.\n")); - // - // Get needed runtime cache buffer size and check if auth variables are to be used from SMM - // - Status = GetRuntimeCacheInfo ( - &RuntimeHobCacheBufferSize, - &RuntimeNvCacheSize, - &RuntimeVolatileCacheSize, - &mVariableAuthFormat - ); - if (!EFI_ERROR (Status)) { - VariableRuntimeCacheInfo = GET_GUID_HOB_DATA (GuidHob); - AllocatedHobCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeHobCachePages); - AllocatedNvCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeNvCachePages); - AllocatedVolatileCacheSize = EFI_PAGES_TO_SIZE ((UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCachePages); - - ASSERT ( - (AllocatedHobCacheSize >= RuntimeHobCacheBufferSize) && - (AllocatedNvCacheSize >= RuntimeNvCacheSize) && - (AllocatedVolatileCacheSize >= RuntimeVolatileCacheSize) - ); - - mVariableRuntimeHobCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeHobCacheBuffer; - mVariableRuntimeNvCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeNvCacheBuffer; - mVariableRuntimeVolatileCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCacheBuffer; - mVariableRuntimeCachePendingUpdate = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->PendingUpdate; - mVariableRuntimeCacheReadLock = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->ReadLock; - mHobFlushComplete = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->HobFlushComplete; - Status = InitVariableCache (&mVariableRuntimeHobCacheBuffer, &RuntimeHobCacheBufferSize); + Status = InitVariableCache (GuidHob); + if (!EFI_ERROR (Status)) { + Status = SendRuntimeVariableCacheContextToSmm (); if (!EFI_ERROR (Status)) { - Status = InitVariableCache (&mVariableRuntimeNvCacheBuffer, &RuntimeNvCacheSize); - if (!EFI_ERROR (Status)) { - Status = InitVariableCache (&mVariableRuntimeVolatileCacheBuffer, &RuntimeVolatileCacheSize); - if (!EFI_ERROR (Status)) { - Status = SendRuntimeVariableCacheContextToSmm (); - if (!EFI_ERROR (Status)) { - SyncRuntimeCache (); - } - } - } + SyncRuntimeCache (); } + } - if (EFI_ERROR (Status)) { - mVariableRuntimeHobCacheBuffer = NULL; - mVariableRuntimeNvCacheBuffer = NULL; - mVariableRuntimeVolatileCacheBuffer = NULL; - } + if (EFI_ERROR (Status)) { + mVariableRuntimeHobCacheBuffer = NULL; + mVariableRuntimeNvCacheBuffer = NULL; + mVariableRuntimeVolatileCacheBuffer = NULL; } ASSERT_EFI_ERROR (Status); -- cgit From 128513afcdfa77e94c9637e643898e61c8218e34 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 17 May 2024 12:08:06 +0800 Subject: MdeModulePkg:Add global variable mVariableRtCacheInfo Add global variable mVariableRtCacheInfo to save the content in gEdkiiVariableRuntimeCacheInfoHobGuid. With this new global variable, 7 global variables can be removed. Signed-off-by: Dun Tan --- .../Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 109 ++++++++++----------- 1 file changed, 51 insertions(+), 58 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 36e65f12d2..5a0306164c 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -44,25 +44,20 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PrivilegePolymorphic.h" #include "VariableParsing.h" -EFI_HANDLE mHandle = NULL; -EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL; -EFI_EVENT mVirtualAddressChangeEvent = NULL; -EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication2 = NULL; -UINT8 *mVariableBuffer = NULL; -UINT8 *mVariableBufferPhysical = NULL; -VARIABLE_INFO_ENTRY *mVariableInfo = NULL; -VARIABLE_STORE_HEADER *mVariableRuntimeHobCacheBuffer = NULL; -VARIABLE_STORE_HEADER *mVariableRuntimeNvCacheBuffer = NULL; -VARIABLE_STORE_HEADER *mVariableRuntimeVolatileCacheBuffer = NULL; +EFI_HANDLE mHandle = NULL; +EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL; +EFI_EVENT mVirtualAddressChangeEvent = NULL; +EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication2 = NULL; +UINT8 *mVariableBuffer = NULL; +UINT8 *mVariableBufferPhysical = NULL; +VARIABLE_INFO_ENTRY *mVariableInfo = NULL; UINTN mVariableBufferSize; UINTN mVariableBufferPayloadSize; -BOOLEAN *mVariableRuntimeCachePendingUpdate; -BOOLEAN *mVariableRuntimeCacheReadLock; BOOLEAN mVariableAuthFormat; -BOOLEAN *mHobFlushComplete; EFI_LOCK mVariableServicesLock; EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; EDKII_VAR_CHECK_PROTOCOL mVarCheck; +VARIABLE_RUNTIME_CACHE_INFO mVariableRtCacheInfo; BOOLEAN mIsRuntimeCacheEnabled = FALSE; /** @@ -500,17 +495,21 @@ CheckForRuntimeCacheSync ( VOID ) { - if (*mVariableRuntimeCachePendingUpdate) { + CACHE_INFO_FLAG *CacheInfoFlag; + + CacheInfoFlag = (CACHE_INFO_FLAG *)(UINTN)mVariableRtCacheInfo.CacheInfoFlagBuffer; + + if (CacheInfoFlag->PendingUpdate) { SyncRuntimeCache (); } - ASSERT (!(*mVariableRuntimeCachePendingUpdate)); + ASSERT (!(CacheInfoFlag->PendingUpdate)); // // The HOB variable data may have finished being flushed in the runtime cache sync update // - if ((*mHobFlushComplete) && (mVariableRuntimeHobCacheBuffer != NULL)) { - mVariableRuntimeHobCacheBuffer = NULL; + if ((CacheInfoFlag->HobFlushComplete) && (mVariableRtCacheInfo.RuntimeHobCacheBuffer != 0)) { + mVariableRtCacheInfo.RuntimeHobCacheBuffer = 0; } } @@ -546,8 +545,10 @@ FindVariableInRuntimeCache ( VARIABLE_POINTER_TRACK RtPtrTrack; VARIABLE_STORE_TYPE StoreType; VARIABLE_STORE_HEADER *VariableStoreList[VariableStoreTypeMax]; + CACHE_INFO_FLAG *CacheInfoFlag; - Status = EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + CacheInfoFlag = (CACHE_INFO_FLAG *)(UINTN)mVariableRtCacheInfo.CacheInfoFlagBuffer; if ((VariableName == NULL) || (VendorGuid == NULL) || (DataSize == NULL)) { return EFI_INVALID_PARAMETER; @@ -561,20 +562,20 @@ FindVariableInRuntimeCache ( // a GetVariable () or GetNextVariable () call from being issued until a prior call has returned. The runtime // cache read lock should always be free when entering this function. // - ASSERT (!(*mVariableRuntimeCacheReadLock)); + ASSERT (!(CacheInfoFlag->ReadLock)); - *mVariableRuntimeCacheReadLock = TRUE; + CacheInfoFlag->ReadLock = TRUE; CheckForRuntimeCacheSync (); - if (!(*mVariableRuntimeCachePendingUpdate)) { + if (!(CacheInfoFlag->PendingUpdate)) { // // 0: Volatile, 1: HOB, 2: Non-Volatile. // The index and attributes mapping must be kept in this order as FindVariable // makes use of this mapping to implement search algorithm. // - VariableStoreList[VariableStoreTypeVolatile] = mVariableRuntimeVolatileCacheBuffer; - VariableStoreList[VariableStoreTypeHob] = mVariableRuntimeHobCacheBuffer; - VariableStoreList[VariableStoreTypeNv] = mVariableRuntimeNvCacheBuffer; + VariableStoreList[VariableStoreTypeVolatile] = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeVolatileCacheBuffer; + VariableStoreList[VariableStoreTypeHob] = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeHobCacheBuffer; + VariableStoreList[VariableStoreTypeNv] = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeNvCacheBuffer; for (StoreType = (VARIABLE_STORE_TYPE)0; StoreType < VariableStoreTypeMax; StoreType++) { if (VariableStoreList[StoreType] == NULL) { @@ -626,7 +627,7 @@ Done: } } - *mVariableRuntimeCacheReadLock = FALSE; + CacheInfoFlag->ReadLock = FALSE; return Status; } @@ -840,8 +841,10 @@ GetNextVariableNameInRuntimeCache ( UINTN VarNameSize; VARIABLE_HEADER *VariablePtr; VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax]; + CACHE_INFO_FLAG *CacheInfoFlag; - Status = EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + CacheInfoFlag = (CACHE_INFO_FLAG *)(UINTN)mVariableRtCacheInfo.CacheInfoFlagBuffer; // // The UEFI specification restricts Runtime Services callers from invoking the same or certain other Runtime Service @@ -849,20 +852,20 @@ GetNextVariableNameInRuntimeCache ( // a GetVariable () or GetNextVariable () call from being issued until a prior call has returned. The runtime // cache read lock should always be free when entering this function. // - ASSERT (!(*mVariableRuntimeCacheReadLock)); + ASSERT (!(CacheInfoFlag->ReadLock)); CheckForRuntimeCacheSync (); - *mVariableRuntimeCacheReadLock = TRUE; - if (!(*mVariableRuntimeCachePendingUpdate)) { + CacheInfoFlag->ReadLock = TRUE; + if (!(CacheInfoFlag->PendingUpdate)) { // // 0: Volatile, 1: HOB, 2: Non-Volatile. // The index and attributes mapping must be kept in this order as FindVariable // makes use of this mapping to implement search algorithm. // - VariableStoreHeader[VariableStoreTypeVolatile] = mVariableRuntimeVolatileCacheBuffer; - VariableStoreHeader[VariableStoreTypeHob] = mVariableRuntimeHobCacheBuffer; - VariableStoreHeader[VariableStoreTypeNv] = mVariableRuntimeNvCacheBuffer; + VariableStoreHeader[VariableStoreTypeVolatile] = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeVolatileCacheBuffer; + VariableStoreHeader[VariableStoreTypeHob] = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeHobCacheBuffer; + VariableStoreHeader[VariableStoreTypeNv] = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeNvCacheBuffer; Status = VariableServiceGetNextVariableInternal ( VariableName, @@ -886,7 +889,7 @@ GetNextVariableNameInRuntimeCache ( } } - *mVariableRuntimeCacheReadLock = FALSE; + CacheInfoFlag->ReadLock = FALSE; return Status; } @@ -1341,12 +1344,10 @@ VariableAddressChangeEvent ( { EfiConvertPointer (0x0, (VOID **)&mVariableBuffer); EfiConvertPointer (0x0, (VOID **)&mMmCommunication2); - EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeHobCacheBuffer); - EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeNvCacheBuffer); - EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeVolatileCacheBuffer); - EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeCachePendingUpdate); - EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRuntimeCacheReadLock); - EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mHobFlushComplete); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.CacheInfoFlagBuffer); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.RuntimeHobCacheBuffer); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.RuntimeNvCacheBuffer); + EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.RuntimeVolatileCacheBuffer); } /** @@ -1573,16 +1574,10 @@ InitVariableCache ( (AllocatedVolatileCacheSize >= ExpectedVolatileCacheSize) ); - mVariableRuntimeHobCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeHobCacheBuffer; - mVariableRuntimeNvCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeNvCacheBuffer; - mVariableRuntimeVolatileCacheBuffer = (VARIABLE_STORE_HEADER *)(UINTN)VariableRuntimeCacheInfo->RuntimeVolatileCacheBuffer; - mVariableRuntimeCachePendingUpdate = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->PendingUpdate; - mVariableRuntimeCacheReadLock = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->ReadLock; - mHobFlushComplete = &((CACHE_INFO_FLAG *)(UINTN)VariableRuntimeCacheInfo->CacheInfoFlagBuffer)->HobFlushComplete; - - InitVariableStoreHeader (mVariableRuntimeHobCacheBuffer, AllocatedHobCacheSize); - InitVariableStoreHeader (mVariableRuntimeNvCacheBuffer, AllocatedNvCacheSize); - InitVariableStoreHeader (mVariableRuntimeVolatileCacheBuffer, AllocatedVolatileCacheSize); + CopyMem (&mVariableRtCacheInfo, VariableRuntimeCacheInfo, sizeof (VARIABLE_RUNTIME_CACHE_INFO)); + InitVariableStoreHeader ((VOID *)(UINTN)mVariableRtCacheInfo.RuntimeHobCacheBuffer, AllocatedHobCacheSize); + InitVariableStoreHeader ((VOID *)(UINTN)mVariableRtCacheInfo.RuntimeNvCacheBuffer, AllocatedNvCacheSize); + InitVariableStoreHeader ((VOID *)(UINTN)mVariableRtCacheInfo.RuntimeVolatileCacheBuffer, AllocatedVolatileCacheSize); } return Status; @@ -1633,12 +1628,12 @@ SendRuntimeVariableCacheContextToSmm ( SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_INIT_RUNTIME_VARIABLE_CACHE_CONTEXT; SmmRuntimeVarCacheContext = (SMM_VARIABLE_COMMUNICATE_RUNTIME_VARIABLE_CACHE_CONTEXT *)SmmVariableFunctionHeader->Data; - SmmRuntimeVarCacheContext->RuntimeHobCache = mVariableRuntimeHobCacheBuffer; - SmmRuntimeVarCacheContext->RuntimeVolatileCache = mVariableRuntimeVolatileCacheBuffer; - SmmRuntimeVarCacheContext->RuntimeNvCache = mVariableRuntimeNvCacheBuffer; - SmmRuntimeVarCacheContext->PendingUpdate = mVariableRuntimeCachePendingUpdate; - SmmRuntimeVarCacheContext->ReadLock = mVariableRuntimeCacheReadLock; - SmmRuntimeVarCacheContext->HobFlushComplete = mHobFlushComplete; + SmmRuntimeVarCacheContext->RuntimeHobCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeHobCacheBuffer; + SmmRuntimeVarCacheContext->RuntimeVolatileCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeVolatileCacheBuffer; + SmmRuntimeVarCacheContext->RuntimeNvCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableRtCacheInfo.RuntimeNvCacheBuffer; + SmmRuntimeVarCacheContext->PendingUpdate = &((CACHE_INFO_FLAG *)(UINTN)mVariableRtCacheInfo.CacheInfoFlagBuffer)->PendingUpdate; + SmmRuntimeVarCacheContext->ReadLock = &((CACHE_INFO_FLAG *)(UINTN)mVariableRtCacheInfo.CacheInfoFlagBuffer)->ReadLock; + SmmRuntimeVarCacheContext->HobFlushComplete = &((CACHE_INFO_FLAG *)(UINTN)mVariableRtCacheInfo.CacheInfoFlagBuffer)->HobFlushComplete; // // Send data to SMM. @@ -1713,9 +1708,7 @@ SmmVariableReady ( } if (EFI_ERROR (Status)) { - mVariableRuntimeHobCacheBuffer = NULL; - mVariableRuntimeNvCacheBuffer = NULL; - mVariableRuntimeVolatileCacheBuffer = NULL; + ZeroMem (&mVariableRtCacheInfo, sizeof (VARIABLE_RUNTIME_CACHE_INFO)); } ASSERT_EFI_ERROR (Status); -- cgit From 6eaeef2c9b9a2cc1933e7a0e0c6dbbc8a6195588 Mon Sep 17 00:00:00 2001 From: Paul Grimes Date: Tue, 11 Jun 2024 09:56:42 -0700 Subject: MdePkg/Include: Add AMD SEV-SNP header file Add SevSnpMsr.h as part of a refactor of MSR definitions and SEV-SNP related defines, which aims to remove family-specific references (filename) as these defines are common to all modern EPYC Processors. Signed-off-by: Paul Grimes --- MdePkg/Include/Register/Amd/SevSnpMsr.h | 153 ++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 MdePkg/Include/Register/Amd/SevSnpMsr.h diff --git a/MdePkg/Include/Register/Amd/SevSnpMsr.h b/MdePkg/Include/Register/Amd/SevSnpMsr.h new file mode 100644 index 0000000000..1b8fbc1978 --- /dev/null +++ b/MdePkg/Include/Register/Amd/SevSnpMsr.h @@ -0,0 +1,153 @@ +/** @file + MSR Definitions. + + Provides defines for Machine Specific Registers(MSR) indexes. Data structures + are provided for MSRs that contain one or more bit fields. If the MSR value + returned is a single 32-bit or 64-bit value, then a data structure is not + provided for that MSR. + + Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + AMD64 Architecture Programming Manual volume 2, March 2024 + +**/ + +#ifndef SEV_SNP_MSR_H_ +#define SEV_SNP_MSR_H_ + +/** + Secure Encrypted Virtualization - Encrypted State (SEV-ES) GHCB register + +**/ +#define MSR_SEV_ES_GHCB 0xc0010130 + +/** + MSR information returned for #MSR_SEV_ES_GHCB +**/ +typedef union { + struct { + UINT32 Function : 12; + UINT32 Reserved1 : 20; + UINT32 Reserved2 : 32; + } GhcbInfo; + + struct { + UINT8 Reserved[3]; + UINT8 SevEncryptionBitPos; + UINT16 SevEsProtocolMin; + UINT16 SevEsProtocolMax; + } GhcbProtocol; + + struct { + UINT32 Function : 12; + UINT32 ReasonCodeSet : 4; + UINT32 ReasonCode : 8; + UINT32 Reserved1 : 8; + UINT32 Reserved2 : 32; + } GhcbTerminate; + + struct { + UINT64 Function : 12; + UINT64 Features : 52; + } GhcbHypervisorFeatures; + + struct { + UINT64 Function : 12; + UINT64 GuestFrameNumber : 52; + } GhcbGpaRegister; + + struct { + UINT64 Function : 12; + UINT64 GuestFrameNumber : 40; + UINT64 Operation : 4; + UINT64 Reserved : 8; + } SnpPageStateChangeRequest; + + struct { + UINT32 Function : 12; + UINT32 Reserved : 20; + UINT32 ErrorCode; + } SnpPageStateChangeResponse; + + struct { + UINT64 Function : 12; + UINT64 Reserved1 : 20; + UINT64 Vmpl : 8; + UINT64 Reserved2 : 56; + } SnpVmplRequest; + + struct { + UINT32 Function : 12; + UINT32 Reserved : 20; + UINT32 ErrorCode; + } SnpVmplResponse; + + VOID *Ghcb; + + UINT64 GhcbPhysicalAddress; + + UINT64 Uint64; +} MSR_SEV_ES_GHCB_REGISTER; + +#define GHCB_INFO_SEV_INFO 1 +#define GHCB_INFO_SEV_INFO_GET 2 +#define GHCB_INFO_CPUID_REQUEST 4 +#define GHCB_INFO_CPUID_RESPONSE 5 +#define GHCB_INFO_GHCB_GPA_REGISTER_REQUEST 18 +#define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE 19 +#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_REQUEST 20 +#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_RESPONSE 21 +#define GHCB_INFO_SNP_VMPL_REQUEST 22 +#define GHCB_INFO_SNP_VMPL_RESPONSE 23 +#define GHCB_HYPERVISOR_FEATURES_REQUEST 128 +#define GHCB_HYPERVISOR_FEATURES_RESPONSE 129 +#define GHCB_INFO_TERMINATE_REQUEST 256 + +#define GHCB_TERMINATE_GHCB 0 +#define GHCB_TERMINATE_GHCB_GENERAL 0 +#define GHCB_TERMINATE_GHCB_PROTOCOL 1 + +/** + Secure Encrypted Virtualization (SEV) status register + +**/ +#define MSR_SEV_STATUS 0xc0010131 + +/** + MSR information returned for #MSR_SEV_STATUS +**/ +typedef union { + /// + /// Individual bit fields + /// + struct { + /// + /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled + /// + UINT32 SevBit : 1; + + /// + /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled + /// + UINT32 SevEsBit : 1; + + /// + /// [Bit 2] Secure Nested Paging (SevSnp) is enabled + /// + UINT32 SevSnpBit : 1; + + UINT32 Reserved2 : 29; + } Bits; + /// + /// All bit fields as a 32-bit value + /// + UINT32 Uint32; + /// + /// All bit fields as a 64-bit value + /// + UINT64 Uint64; +} MSR_SEV_STATUS_REGISTER; + +#endif -- cgit From d40c71ef3f44e44684c1b478356b9654d351fd6b Mon Sep 17 00:00:00 2001 From: Paul Grimes Date: Tue, 4 Jun 2024 09:12:20 -0700 Subject: MdePkg/Include: Update reference to SEV-SNP header file Update reference to SevSnpMsr.h as part of a refactor of MSR definitions and SEV-SNP related defines. Remove family-specific references (filename) as these defines are common to all modern EPYC Processors. Signed-off-by: Paul Grimes --- MdePkg/Include/Register/Amd/Msr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/Register/Amd/Msr.h b/MdePkg/Include/Register/Amd/Msr.h index 04a3cbeb43..8f771a78bf 100644 --- a/MdePkg/Include/Register/Amd/Msr.h +++ b/MdePkg/Include/Register/Amd/Msr.h @@ -18,7 +18,7 @@ #define __AMD_MSR_H__ #include -#include +#include #include #endif -- cgit From 55c3ecde32edf88eee2ff51ef1c1fe372ad423f7 Mon Sep 17 00:00:00 2001 From: Paul Grimes Date: Tue, 4 Jun 2024 09:13:38 -0700 Subject: UefiCpuPkg/MpInitLib: Update references to SEV-SNP header file Update reference to SevSnpMsr.h as part of a refactor of MSR definitions and SEV-SNP related defines. Remove family-specific references (filename) as these defines are common to all modern EPYC Processors. Signed-off-by: Paul Grimes --- UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 3 ++- UefiCpuPkg/Library/MpInitLib/MpLib.c | 2 +- UefiCpuPkg/Library/MpInitLib/MpLib.h | 2 +- UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index f9c5c92c22..a8d884f607 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -2,6 +2,7 @@ MP initialize support functions for DXE phase. Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
+ Copyright (c) 2024, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -13,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index f97298887f..8fbcebdc03 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -10,7 +10,7 @@ #include "MpLib.h" #include -#include +#include #include EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index cc850c7dd5..88b31fecca 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c index bbdc47b5a3..a75e1e2018 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c +++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c @@ -11,7 +11,7 @@ #include "MpLib.h" #include #include -#include +#include #include #define _IS_ALIGNED(x, y) (ALIGN_POINTER((x), (y)) == (x)) -- cgit From 17424fae4f6f2478d7b67ff304e8f0f517d4d9c5 Mon Sep 17 00:00:00 2001 From: Paul Grimes Date: Tue, 4 Jun 2024 09:17:27 -0700 Subject: MdePkg/Include: Remove deprecated AMD SEV-SNP header file Delete Fam17Msr.h as part of a refactor of MSR definitions and SEV-SNP related defines, which aims to remove family-specific references (filename) as these defines are common to all modern EPYC Processors. Signed-off-by: Paul Grimes --- MdePkg/Include/Register/Amd/Fam17Msr.h | 153 --------------------------------- 1 file changed, 153 deletions(-) delete mode 100644 MdePkg/Include/Register/Amd/Fam17Msr.h diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h deleted file mode 100644 index f2d5ccb39d..0000000000 --- a/MdePkg/Include/Register/Amd/Fam17Msr.h +++ /dev/null @@ -1,153 +0,0 @@ -/** @file - MSR Definitions. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Specification Reference: - AMD64 Architecture Programming Manual volume 2, March 2017, Sections 15.34 - -**/ - -#ifndef __FAM17_MSR_H__ -#define __FAM17_MSR_H__ - -/** - Secure Encrypted Virtualization - Encrypted State (SEV-ES) GHCB register - -**/ -#define MSR_SEV_ES_GHCB 0xc0010130 - -/** - MSR information returned for #MSR_SEV_ES_GHCB -**/ -typedef union { - struct { - UINT32 Function : 12; - UINT32 Reserved1 : 20; - UINT32 Reserved2 : 32; - } GhcbInfo; - - struct { - UINT8 Reserved[3]; - UINT8 SevEncryptionBitPos; - UINT16 SevEsProtocolMin; - UINT16 SevEsProtocolMax; - } GhcbProtocol; - - struct { - UINT32 Function : 12; - UINT32 ReasonCodeSet : 4; - UINT32 ReasonCode : 8; - UINT32 Reserved1 : 8; - UINT32 Reserved2 : 32; - } GhcbTerminate; - - struct { - UINT64 Function : 12; - UINT64 Features : 52; - } GhcbHypervisorFeatures; - - struct { - UINT64 Function : 12; - UINT64 GuestFrameNumber : 52; - } GhcbGpaRegister; - - struct { - UINT64 Function : 12; - UINT64 GuestFrameNumber : 40; - UINT64 Operation : 4; - UINT64 Reserved : 8; - } SnpPageStateChangeRequest; - - struct { - UINT32 Function : 12; - UINT32 Reserved : 20; - UINT32 ErrorCode; - } SnpPageStateChangeResponse; - - struct { - UINT64 Function : 12; - UINT64 Reserved1 : 20; - UINT64 Vmpl : 8; - UINT64 Reserved2 : 56; - } SnpVmplRequest; - - struct { - UINT32 Function : 12; - UINT32 Reserved : 20; - UINT32 ErrorCode; - } SnpVmplResponse; - - VOID *Ghcb; - - UINT64 GhcbPhysicalAddress; - - UINT64 Uint64; -} MSR_SEV_ES_GHCB_REGISTER; - -#define GHCB_INFO_SEV_INFO 1 -#define GHCB_INFO_SEV_INFO_GET 2 -#define GHCB_INFO_CPUID_REQUEST 4 -#define GHCB_INFO_CPUID_RESPONSE 5 -#define GHCB_INFO_GHCB_GPA_REGISTER_REQUEST 18 -#define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE 19 -#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_REQUEST 20 -#define GHCB_INFO_SNP_PAGE_STATE_CHANGE_RESPONSE 21 -#define GHCB_INFO_SNP_VMPL_REQUEST 22 -#define GHCB_INFO_SNP_VMPL_RESPONSE 23 -#define GHCB_HYPERVISOR_FEATURES_REQUEST 128 -#define GHCB_HYPERVISOR_FEATURES_RESPONSE 129 -#define GHCB_INFO_TERMINATE_REQUEST 256 - -#define GHCB_TERMINATE_GHCB 0 -#define GHCB_TERMINATE_GHCB_GENERAL 0 -#define GHCB_TERMINATE_GHCB_PROTOCOL 1 - -/** - Secure Encrypted Virtualization (SEV) status register - -**/ -#define MSR_SEV_STATUS 0xc0010131 - -/** - MSR information returned for #MSR_SEV_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled - /// - UINT32 SevBit : 1; - - /// - /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled - /// - UINT32 SevEsBit : 1; - - /// - /// [Bit 2] Secure Nested Paging (SevSnp) is enabled - /// - UINT32 SevSnpBit : 1; - - UINT32 Reserved2 : 29; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SEV_STATUS_REGISTER; - -#endif -- cgit From a9def1ed9da3a091d78983cb9233241b345f344c Mon Sep 17 00:00:00 2001 From: Paul Grimes Date: Tue, 11 Jun 2024 09:59:23 -0700 Subject: MdePkg/Include: Update Msr.h header guard define Update the Msr.h eader guard to comply with latest edk2 coding guidelines. This change is part of a refactor of MSR definitions and SEV-SNP related defines, which aims to remove family-specific references (filename) as these defines are common to all modern EPYC Processors. Signed-off-by: Paul Grimes --- MdePkg/Include/Register/Amd/Msr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/Register/Amd/Msr.h b/MdePkg/Include/Register/Amd/Msr.h index 8f771a78bf..5f84aa6372 100644 --- a/MdePkg/Include/Register/Amd/Msr.h +++ b/MdePkg/Include/Register/Amd/Msr.h @@ -14,8 +14,8 @@ **/ -#ifndef __AMD_MSR_H__ -#define __AMD_MSR_H__ +#ifndef AMD_MSR_H_ +#define AMD_MSR_H_ #include #include -- cgit From 537a81ae81622d65052184b281e8b2754d0b5313 Mon Sep 17 00:00:00 2001 From: Paul Grimes Date: Tue, 11 Jun 2024 10:00:06 -0700 Subject: MdePkg/Include: Update AMD specification references Update AMD sepcification references (code comments) as part of a refactor of MSR definitions and SEV-SNP related defines, which aims to remove family-specific references (filename) as these defines are common to all modern EPYC Processors. Signed-off-by: Paul Grimes --- MdePkg/Include/Register/Amd/Cpuid.h | 2 +- MdePkg/Include/Register/Amd/Msr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/Register/Amd/Cpuid.h b/MdePkg/Include/Register/Amd/Cpuid.h index 51fa9f235c..fdcbc475d5 100644 --- a/MdePkg/Include/Register/Amd/Cpuid.h +++ b/MdePkg/Include/Register/Amd/Cpuid.h @@ -11,7 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent @par Specification Reference: - AMD64 Architecture Programming Manual volume 2, March 2017, Sections 15.34 + AMD64 Architecture Programming Manual volume 2, March 2024 **/ diff --git a/MdePkg/Include/Register/Amd/Msr.h b/MdePkg/Include/Register/Amd/Msr.h index 5f84aa6372..352b1f8f1c 100644 --- a/MdePkg/Include/Register/Amd/Msr.h +++ b/MdePkg/Include/Register/Amd/Msr.h @@ -10,7 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent @par Specification Reference: - AMD64 Architecture Programming Manual volume 2, March 2017, Sections 15.34 + AMD64 Architecture Programming Manual volume 2, March 2024 **/ -- cgit From 176b9d41f8f71c7572dab615a8d5259dd2cbc02a Mon Sep 17 00:00:00 2001 From: Zhihao Li Date: Fri, 8 Mar 2024 18:05:23 +0800 Subject: MdeModulePkg/Core/Pei: Install MigrateTempRamPpi REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4716 Migrate FSP-T/M binary from temporary RAM to permanent RAM before NEM tear down. Tcg module will use permanent address of FSP-T/M for measurement. In MdeModulePkg, PeiCore installs mMigrateTempRamPpi if PcdMigrateTemporaryRamFirmwareVolumes is True before NEM tear down and after permanent memory ready. Cc: Chasel Chiu Cc: Nate DeSimone Cc: Duggapu Chinni B Cc: Chen Gang C Cc: Liming Gao Signed-off-by: Zhihao Li --- MdeModulePkg/Core/Pei/PeiMain.h | 3 ++- MdeModulePkg/Core/Pei/PeiMain.inf | 3 ++- MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 10 +++++++++- MdeModulePkg/Include/Guid/MigratedFvInfo.h | 4 ++-- MdeModulePkg/Include/Ppi/MigrateTempRam.h | 23 +++++++++++++++++++++++ MdeModulePkg/MdeModulePkg.dec | 3 +++ 6 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 MdeModulePkg/Include/Ppi/MigrateTempRam.h diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index 46b6c23014..8df0c2d561 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -1,7 +1,7 @@ /** @file Definition of Pei Core Structures and Services -Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include #include diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index 893bdc0527..4e545ddab2 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -6,7 +6,7 @@ # 2) Dispatch PEIM from discovered FV. # 3) Handoff control to DxeIpl to load DXE core and enter DXE phase. # -# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -101,6 +101,7 @@ gEfiPeiReset2PpiGuid ## SOMETIMES_CONSUMES gEfiSecHobDataPpiGuid ## SOMETIMES_CONSUMES gEfiPeiCoreFvLocationPpiGuid ## SOMETIMES_CONSUMES + gEdkiiPeiMigrateTempRamPpiGuid ## PRODUCES [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize ## CONSUMES diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index bf1719d794..0e3d9a8438 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -1,7 +1,7 @@ /** @file Pei Core Main Entry Point -Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -13,6 +13,11 @@ EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = { &gEfiPeiMemoryDiscoveredPpiGuid, NULL }; +EFI_PEI_PPI_DESCRIPTOR mMigrateTempRamPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiPeiMigrateTempRamPpiGuid, + NULL +}; /// /// Pei service instance @@ -449,6 +454,9 @@ PeiCore ( // EvacuateTempRam (&PrivateData, SecCoreData); + Status = PeiServicesInstallPpi (&mMigrateTempRamPpi); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:\n")); DumpPpiList (&PrivateData); } diff --git a/MdeModulePkg/Include/Guid/MigratedFvInfo.h b/MdeModulePkg/Include/Guid/MigratedFvInfo.h index 1c8b0dfefc..255e278235 100644 --- a/MdeModulePkg/Include/Guid/MigratedFvInfo.h +++ b/MdeModulePkg/Include/Guid/MigratedFvInfo.h @@ -1,7 +1,7 @@ /** @file Migrated FV information -Copyright (c) 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2020 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -50,7 +50,7 @@ typedef struct { typedef struct { UINT32 FvOrgBase; // original FV address - UINT32 FvNewBase; // new FV address + UINT32 FvNewBase; // new FV address, 0 means rebased data is not copied UINT32 FvDataBase; // original FV data, 0 means raw data is not copied UINT32 FvLength; // Fv Length } EDKII_MIGRATED_FV_INFO; diff --git a/MdeModulePkg/Include/Ppi/MigrateTempRam.h b/MdeModulePkg/Include/Ppi/MigrateTempRam.h new file mode 100644 index 0000000000..9bbb55d5cf --- /dev/null +++ b/MdeModulePkg/Include/Ppi/MigrateTempRam.h @@ -0,0 +1,23 @@ +/** @file + This file declares Migrate Temporary Memory PPI. + + This PPI is published by the PEI Foundation when temporary RAM needs to evacuate. + Its purpose is to be used as a signal for other PEIMs who can register for a + notification on its installation. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PEI_MIGRATE_TEMP_RAM_PPI_H_ +#define PEI_MIGRATE_TEMP_RAM_PPI_H_ + +#define EFI_PEI_MIGRATE_TEMP_RAM_PPI_GUID \ + { \ + 0xc79dc53b, 0xafcd, 0x4a6a, {0xad, 0x94, 0xa7, 0x6a, 0x3f, 0xa9, 0xe9, 0xc2 } \ + } + +extern EFI_GUID gEdkiiPeiMigrateTempRamPpiGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index fdd1d48c47..6148025085 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -557,6 +557,9 @@ ## Include/Ppi/MemoryAttribute.h gEdkiiMemoryAttributePpiGuid = { 0x1be840de, 0x2d92, 0x41ec, { 0xb6, 0xd3, 0x19, 0x64, 0x13, 0x50, 0x51, 0xfb } } + ## Include/Ppi/MigrateTempRam.h + gEdkiiPeiMigrateTempRamPpiGuid = { 0xc79dc53b, 0xafcd, 0x4a6a, { 0xad, 0x94, 0xa7, 0x6a, 0x3f, 0xa9, 0xe9, 0xc2 } } + [Protocols] ## Load File protocol provides capability to load and unload EFI image into memory and execute it. # Include/Protocol/LoadPe32Image.h -- cgit From b0c5781671f322472836ff25ee11242f59aa9945 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 16 Jun 2024 19:04:31 -0600 Subject: .devcontainer: bump Fedora version to 39 Fedora 35 is EOL. Use Fedora 39 instead: don't use 40 for now since it comes with gcc 14 which still has some problems building edk2. Fix the git command to disable the safe directory checks. Signed-off-by: Rebecca Cran --- .devcontainer/devcontainer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 592bb8cf66..ef51e1695a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { - "image": "ghcr.io/tianocore/containers/fedora-35-dev:latest", - "postCreateCommand": "git config --global --add safe.directory * && pip install --upgrade -r pip-requirements.txt", + "image": "ghcr.io/tianocore/containers/fedora-39-dev:latest", + "postCreateCommand": "git config --global --add safe.directory '*' && pip install --upgrade -r pip-requirements.txt", "customizations": { "vscode": { "extensions": [ -- cgit From e3e27f22d248742f3e25598a75de5ab99ef3335c Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:01:42 +0800 Subject: OvmfPkg/LoongArchVirt: Add stable timer driver Add a CPU timer driver named StableTimerDxe, which proviedes EFI_TIMER_ARCH_PROTOCOL for LoongArch. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Baoqi Zhang --- .../LoongArchVirt/Drivers/StableTimerDxe/Timer.c | 397 +++++++++++++++++++++ .../Drivers/StableTimerDxe/TimerDxe.inf | 40 +++ 2 files changed, 437 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/Timer.c create mode 100644 OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/TimerDxe.inf diff --git a/OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/Timer.c b/OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/Timer.c new file mode 100644 index 0000000000..8a57508554 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/Timer.c @@ -0,0 +1,397 @@ +/** @file + Timer Architectural Protocol as defined in the DXE CIS + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_TIMER_TICK_DURATION 100000 // 10ms = 100000 100 ns units + +// +// The current period of the timer interrupt +// +STATIC UINT64 mTimerPeriod = 0; +STATIC UINT64 mTimerTicks = 0; + +// +// The handle onto which the Timer Architectural Protocol will be installed +// +STATIC EFI_HANDLE mTimerHandle = NULL; +STATIC EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL; + +// +// Pointer to the CPU Architectural Protocol instance +// +STATIC EFI_CPU_ARCH_PROTOCOL *mCpu; + +// +// The notification function to call on every timer interrupt. +// A bug in the compiler prevents us from initializing this here. +// +STATIC EFI_TIMER_NOTIFY mTimerNotifyFunction; + +/** + Sets the counter value for timer. + + @param Count The 16-bit counter value to program into stable timer. + + @retval VOID +**/ +STATIC +VOID +SetPitCount ( + IN UINT64 Count + ) +{ + if (Count <= 4) { + return; + } + + Count &= LOONGARCH_CSR_TMCFG_TIMEVAL; + Count |= LOONGARCH_CSR_TMCFG_EN | LOONGARCH_CSR_TMCFG_PERIOD; + CsrWrite (LOONGARCH_CSR_TMCFG, Count); +} + +/** + Timer Interrupt Handler. + + @param InterruptType The type of interrupt that occurred + @param SystemContext A pointer to the system context when the interrupt occurred + + @retval VOID +**/ +STATIC +VOID +EFIAPI +TimerInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EFI_TPL OriginalTPL; + + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // + // Clear interrupt. + // + CsrWrite (LOONGARCH_CSR_TINTCLR, 0x1); + + if (mTimerNotifyFunction != NULL) { + // + // @bug : This does not handle missed timer interrupts + // + mTimerNotifyFunction (mTimerPeriod); + } + + gBS->RestoreTPL (OriginalTPL); +} + +/** + This function registers the handler NotifyFunction so it is called every time + the timer interrupt fires. It also passes the amount of time since the last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS is + returned. If the CPU does not support registering a timer interrupt handler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR + is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + + @retval EFI_SUCCESS The timer handler was registered. + @retval EFI_UNSUPPORTED The platform does not support timer interrupts. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + @retval EFI_DEVICE_ERROR The timer handler could not be registered. +**/ +STATIC +EFI_STATUS +EFIAPI +TimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +{ + // + // Check for invalid parameters + // + if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) { + return EFI_ALREADY_STARTED; + } + + mTimerNotifyFunction = NotifyFunction; + + return EFI_SUCCESS; +} + +/** + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. +**/ +STATIC +EFI_STATUS +EFIAPI +TimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +{ + UINT64 TimerCount; + + if (TimerPeriod == 0) { + // + // Disable timer interrupt for a TimerPeriod of 0 + // + mCpu->DisableInterrupt (mCpu); + } else { + TimerCount = TimerPeriod * GetPerformanceCounterProperties (NULL, NULL) / 10000000ULL; + + if (TimerCount >= BIT48) { + TimerCount = 0; + } + + // + // Program the stable timer with the new count value + // + mTimerTicks = TimerCount; + SetPitCount (TimerCount); + + // + // Enable timer interrupt + // + mCpu->EnableInterrupt (mCpu); + } + + // + // Save the new timer period + // + mTimerPeriod = TimerPeriod; + + return EFI_SUCCESS; +} + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. +**/ +STATIC +EFI_STATUS +EFIAPI +TimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +{ + if (TimerPeriod == NULL) { + return EFI_INVALID_PARAMETER; + } + + *TimerPeriod = mTimerPeriod; + + return EFI_SUCCESS; +} + +/** + Disable the timer + DXE Core will disable the timer after all the event handlers have run. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +STATIC +VOID +EFIAPI +ExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + /* + * Disable timer interrupt when exiting boot service + */ + CsrWrite (LOONGARCH_CSR_TMCFG, 0x0); +} + +/** + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler () + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts. +**/ +STATIC +EFI_STATUS +EFIAPI +TimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +// +// The Timer Architectural Protocol that this driver produces +// +STATIC EFI_TIMER_ARCH_PROTOCOL mTimer = { + TimerDriverRegisterHandler, + TimerDriverSetTimerPeriod, + TimerDriverGetTimerPeriod, + TimerDriverGenerateSoftInterrupt +}; + +/** + Initialize the Timer Architectural Protocol driver + + @param ImageHandle ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Timer Architectural Protocol created + @retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver. + @retval EFI_DEVICE_ERROR A device error occurred attempting to initialize the driver. +**/ +EFI_STATUS +EFIAPI +StableTimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT32 TimerVector; + + // + // Initialize the pointer to our notify function. + // + mTimerNotifyFunction = NULL; + + // + // Make sure the Timer Architectural Protocol is not already installed in the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); + + // + // Find the CPU architectural protocol. + // + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu); + ASSERT_EFI_ERROR (Status); + + // + // Force the timer to be disabled + // + Status = TimerDriverSetTimerPeriod (&mTimer, 0); + ASSERT_EFI_ERROR (Status); + + // + // Calculate const frequence + // + DEBUG (( + DEBUG_INFO, + "===========Stable timer freq %d Hz=============\n", + GetPerformanceCounterProperties (NULL, NULL) + )); + + // + // Install interrupt handler for Stable Timer #0 (ISA IRQ0) + // + TimerVector = EXCEPT_LOONGARCH_INT_TIMER; + Status = mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInterruptHandler); + ASSERT_EFI_ERROR (Status); + + // + // Enable TI local timer interrupt + // + EnableLocalInterrupts (1 << EXCEPT_LOONGARCH_INT_TIMER); + + // + // Force the timer to be enabled at its default period + // + Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); + ASSERT_EFI_ERROR (Status); + + // + // Install the Timer Architectural Protocol onto a new handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mTimerHandle, + &gEfiTimerArchProtocolGuid, + &mTimer, + NULL + ); + + ASSERT_EFI_ERROR (Status); + + // Register for an ExitBootServicesEvent + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + ExitBootServicesEvent, + NULL, + &EfiExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/TimerDxe.inf b/OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/TimerDxe.inf new file mode 100644 index 0000000000..52aab83e86 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/TimerDxe.inf @@ -0,0 +1,40 @@ +## @file +# Stable timer driver that provides Timer Arch protocol. +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION = 1.29 + BASE_NAME = Timer + MODULE_UNI_FILE = Timer.uni + FILE_GUID = AEBE2648-47A9-40FA-83FD-06AA88443BB2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = StableTimerDriverInitialize + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + Timer.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + TimerLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiCpuArchProtocolGuid ## CONSUMES + gEfiTimerArchProtocolGuid ## PRODUCES + +[depex] + gEfiCpuArchProtocolGuid -- cgit From ace279c036fc15a0317a94dade9ee17f685ec592 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:02:59 +0800 Subject: OvmfPkg/LoongArchVirt: Add CpuMmuInit library Added a new library for LoongArch, it use for initialization the CPU MMU, it consumed the CpuMmuLib. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Chao Li Co-authored-by: Baoqi Zhang Co-authored-by: Dongyan Qian Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- OvmfPkg/Include/Library/CpuMmuInitLib.h | 26 +++ .../Library/CpuMmuInitLib/CpuMmuInit.c | 200 +++++++++++++++++++++ .../Library/CpuMmuInitLib/CpuMmuInitLib.inf | 35 ++++ .../Library/CpuMmuInitLib/CpuMmuInitLib.uni | 14 ++ OvmfPkg/OvmfPkg.dec | 4 + 5 files changed, 279 insertions(+) create mode 100644 OvmfPkg/Include/Library/CpuMmuInitLib.h create mode 100644 OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c create mode 100644 OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.uni diff --git a/OvmfPkg/Include/Library/CpuMmuInitLib.h b/OvmfPkg/Include/Library/CpuMmuInitLib.h new file mode 100644 index 0000000000..44b5664998 --- /dev/null +++ b/OvmfPkg/Include/Library/CpuMmuInitLib.h @@ -0,0 +1,26 @@ +/** @file + CPU Memory Map Unit Initialization library header. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +/** + Create a page table and initialize the memory management unit(MMU). + + @param[in] MemoryTable A pointer to a memory ragion table. + + @retval EFI_SUCCESS Configure MMU successfully. + EFI_INVALID_PARAMETER MemoryTable is NULL. + EFI_UNSUPPORTED MemoryRegionMap failed or out of memory space or size not aligned + or MaxLivel out of bound. +**/ +EFI_STATUS +EFIAPI +ConfigureMemoryManagementUnit ( + IN EFI_MEMORY_DESCRIPTOR *MemoryTable + ); diff --git a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c new file mode 100644 index 0000000000..be2d98cc9a --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c @@ -0,0 +1,200 @@ +/** @file + CPU Memory Map Unit Initialization library instance. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +// +// Because the page size in edk2 is 4KB, the lowest level +// page table is align to 12 bits, and the page table width +// of other levels is set to 9 bits by default, which will +// be 3 or 4 or 5 level page tables, and continuous. +// +// Correspondence between max virtual memory address width +// and page table level: +// 39 bit >= VA > 31 bit, 3 level page tables +// 48 bit >= VA > 40 bit, 4 level page tables +// 57 bit >= VA > 49 bit, 5 level page tables +// +#define DEFAULT_BIT_WIDTH_PER_LEVEL (EFI_PAGE_SHIFT - 3) + +/** + Decided page walker width, level. + + @param[in, out] PageWalkCfg Page walker value instance. + @param[in] BitWidt The bit width what you want, 0 is means use the default bit width. + + @retval PageTableLevelNum The max page table level. +**/ +STATIC +UINT8 +DecidePageWalkConfiguration ( + IN OUT UINT64 *PageWalkCfg OPTIONAL, + IN UINT8 BitWidth + ) +{ + CPUCFG_REG1_INFO_DATA CpucfgReg1Data; + UINT8 CpuVirtMemAddressWidth; + UINT8 PageTableLevelNum; + UINT8 CurrentPageTableLevel; + UINT32 Pwcl0Value; + UINT32 Pwcl1Value; + + // + // If BitWidth is 0, use the default bit width. + // + if (BitWidth == 0) { + BitWidth = DEFAULT_BIT_WIDTH_PER_LEVEL; + } + + // + // Get the the CPU virtual memory address width. + // + AsmCpucfg (CPUCFG_REG1_INFO, &CpucfgReg1Data.Uint32); + + CpuVirtMemAddressWidth = (UINT8)(CpucfgReg1Data.Bits.VALEN + 1); + + // + // Statisitics the maximum page table level + // + PageTableLevelNum = 0x0; + if (((CpuVirtMemAddressWidth - EFI_PAGE_SHIFT) % BitWidth) > 0) { + PageTableLevelNum++; + } + + PageTableLevelNum += (CpuVirtMemAddressWidth - EFI_PAGE_SHIFT) / BitWidth; + + // + // Set page table level + // + Pwcl0Value = 0x0; + Pwcl1Value = 0x0; + for (CurrentPageTableLevel = 0x0; CurrentPageTableLevel < PageTableLevelNum; CurrentPageTableLevel++) { + if (CurrentPageTableLevel < 0x3) { + // Less then or equal to level 3 + Pwcl0Value |= ((BitWidth * CurrentPageTableLevel + EFI_PAGE_SHIFT) << 10 * CurrentPageTableLevel) | + BitWidth << (10 * CurrentPageTableLevel + 5); + } else { + // Lager then level 3 + Pwcl1Value |= ((BitWidth * CurrentPageTableLevel + EFI_PAGE_SHIFT) << 12 * (CurrentPageTableLevel - 3)) | + BitWidth << (12 * (CurrentPageTableLevel - 3) + 6); + } + + DEBUG (( + DEBUG_INFO, + "%a %d Level %d DIR shift %d.\n", + __func__, + __LINE__, + (CurrentPageTableLevel + 1), + (BitWidth * CurrentPageTableLevel + EFI_PAGE_SHIFT) + )); + } + + *PageWalkCfg = ((UINT64)Pwcl1Value << 32) | Pwcl0Value; + + return PageTableLevelNum; +} + +/** + Create a page table and initialize the memory management unit(MMU). + + @param[in] MemoryTable A pointer to a memory ragion table. + + @retval EFI_SUCCESS Configure MMU successfully. + EFI_INVALID_PARAMETER MemoryTable is NULL. + EFI_UNSUPPORTED MemoryRegionMap failed or out of memory space or size not aligned + or MaxLivel out of bound. +**/ +EFI_STATUS +EFIAPI +ConfigureMemoryManagementUnit ( + IN EFI_MEMORY_DESCRIPTOR *MemoryTable + ) +{ + EFI_STATUS Status; + UINTN PageTable; + UINT64 PageWalkCfg; + UINT8 MaxLevel; + + if (MemoryTable == NULL) { + ASSERT (MemoryTable != NULL); + return EFI_INVALID_PARAMETER; + } + + // + // Automatically obtain the current appropriate page walker configuration. + // + MaxLevel = DecidePageWalkConfiguration (&PageWalkCfg, 0); + + if ((MaxLevel < 0) || (MaxLevel > 5)) { + return EFI_UNSUPPORTED; + } + + PageTable = 0; + while (MemoryTable->NumberOfPages != 0) { + DEBUG (( + DEBUG_INFO, + "%a %d VirtualBase %p VirtualEnd %p Attributes %p .\n", + __func__, + __LINE__, + MemoryTable->VirtualStart, + (EFI_PAGES_TO_SIZE (MemoryTable->NumberOfPages) + MemoryTable->VirtualStart), + MemoryTable->Attribute + )); + + Status = MemoryRegionMap ( + &PageTable, + PageWalkCfg, + MemoryTable->VirtualStart, + EFI_PAGES_TO_SIZE (MemoryTable->NumberOfPages), + MemoryTable->Attribute, + 0x0 + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + MemoryTable++; + } + + // + // Configure page walker. + // + CsrWrite (LOONGARCH_CSR_PWCTL0, (UINT32)PageWalkCfg); + if ((PageWalkCfg >> 32) != 0x0) { + CsrWrite (LOONGARCH_CSR_PWCTL1, (UINT32)(PageWalkCfg >> 32)); + } + + // + // Set page size + // + CsrXChg (LOONGARCH_CSR_TLBIDX, (DEFAULT_PAGE_SIZE << CSR_TLBIDX_SIZE), CSR_TLBIDX_SIZE_MASK); + CsrWrite (LOONGARCH_CSR_STLBPGSIZE, DEFAULT_PAGE_SIZE); + CsrXChg (LOONGARCH_CSR_TLBREHI, (DEFAULT_PAGE_SIZE << CSR_TLBREHI_PS_SHIFT), CSR_TLBREHI_PS); + + // + // Enable MMU + // + CsrWrite (LOONGARCH_CSR_PGDL, PageTable); + + // + // Enable Paging + // + CsrXChg (LOONGARCH_CSR_CRMD, BIT4, BIT4|BIT3); + + DEBUG ((DEBUG_INFO, "%a %d Enable MMU Start PageBassAddress %p.\n", __func__, __LINE__, PageTable)); + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf new file mode 100644 index 0000000000..64bd3ce3e6 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf @@ -0,0 +1,35 @@ +## @file +# CPU Memory Map Unit Initialization library instance. +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = CpuMmuInitLib + MODULE_UNI_FILE = CpuMmuInitLib.uni + FILE_GUID = F67EB983-AC2A-7550-AB69-3BC51A1C895B + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CpuMmuInitLib + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + CpuMmuInit.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + CacheMaintenanceLib + CpuMmuLib + DebugLib diff --git a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.uni b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.uni new file mode 100644 index 0000000000..907f024302 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.uni @@ -0,0 +1,14 @@ +// /** @file +// CPU Memory Map Unit Initialization library instance. +// +// CPU Memory Map Unit Initialization library instance. +// +// Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "CPU Memory Manager Unit library instance for PEI modules." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Memory Manager Unit library instance for PEI modules." diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 51be9a5959..ad7c196c5b 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -148,6 +148,10 @@ # HardwareInfoLib|Include/Library/HardwareInfoLib.h + ## @libraryclass CPU MMU Initialization library. + # + CpuMmuInitLib|Include/Library/CpuMmuInitLib.h + [Guids] gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}} gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}} -- cgit From 05f74f1ca7de7962f9b6656c50a960528668f792 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:05:54 +0800 Subject: OvmfPkg/LoongArchVirt: Add serial port hook library Add a serial port hook library in LoongArchVirt named Fdt16550SerialProtHookLib, this library is referenced from ArmVirtPkg. LoongArch QEMU virtual machine uses register of LOONGARCH_CSR_KS1 to transfer serial port base addres from the PEI phase to the DXE phase. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Reviewed-by: Bibo Mao Acked-by: Gerd Hoffmann --- .../EarlyFdt16550SerialPortHookLib.c | 52 ++++++++++++++++++++++ .../EarlyFdt16550SerialPortHookLib.inf | 35 +++++++++++++++ .../Fdt16550SerialPortHookLib.c | 38 ++++++++++++++++ .../Fdt16550SerialPortHookLib.inf | 33 ++++++++++++++ .../Fdt16550SerialPortHookLib.uni | 14 ++++++ 5 files changed, 172 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.c create mode 100644 OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c create mode 100644 OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.uni diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.c b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.c new file mode 100644 index 0000000000..9f1fcc970a --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.c @@ -0,0 +1,52 @@ +/** @file + PEI Phase Early Platform Hook Library instance for 16550 Uart. + + Copyright (c) 2020 - 2023, Arm Ltd. All rights reserved.
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +/** Platform hook to retrieve the 16550 UART base address from the platform + Device tree and store it in the reigster LOONGARCH_CSR_KS1. + + @retval RETURN_SUCCESS Success. + @retval RETURN_INVALID_PARAMETER A parameter was invalid. + @retval RETURN_NOT_FOUND Serial port information not found. + +**/ +RETURN_STATUS +EFIAPI +PlatformHookSerialPortInitialize ( + VOID + ) +{ + RETURN_STATUS Status; + VOID *DeviceTreeBase; + UINT64 SerialConsoleAddress; + + if (PcdGet64 (PcdSerialRegisterBase) != 0) { + return RETURN_SUCCESS; + } + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); + if (DeviceTreeBase == NULL) { + return RETURN_NOT_FOUND; + } + + Status = FdtSerialGetConsolePort (DeviceTreeBase, &SerialConsoleAddress); + if (RETURN_ERROR (Status)) { + return Status; + } + + CsrWrite (LOONGARCH_CSR_KS1, (UINTN)SerialConsoleAddress); + + return RETURN_SUCCESS; +} diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf new file mode 100644 index 0000000000..084cd18ce1 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf @@ -0,0 +1,35 @@ +## @file +# PEI Phase Early Platform Hook Library instance for 16550 Uart. +# +# Copyright (c) 2020, ARM Ltd. All rights reserved.
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = EarlyFdt16550SerialPortHookLib + MODULE_UNI_FILE = Fdt16550SerialPortHookLib.uni + FILE_GUID = 6A5FEBCB-C676-A7C1-A96C-B79D4860EEC5 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformHookLib|SEC PEI_CORE PEIM + +[Sources] + EarlyFdt16550SerialPortHookLib.c + +[LibraryClasses] + BaseLib + PcdLib + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c new file mode 100644 index 0000000000..baaa7ae7a9 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c @@ -0,0 +1,38 @@ +/** @file + Platform Hook Library instance for 16550 Uart. + + Copyright (c) 2020, ARM Ltd. All rights reserved.
+ Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** Platform hook to retrieve the 16550 UART base address from register + LOONGARCH_CSR_KS1 that caches the UART base address from early boot + stage and store it in PcdSerialRegisterBase. + + @retval RETURN_SUCCESS Success. + @retval RETURN_NOT_FOUND Serial Port information not found. + +**/ +RETURN_STATUS +EFIAPI +PlatformHookSerialPortInitialize ( + VOID + ) +{ + UINT64 *UartBase; + + if (PcdGet64 (PcdSerialRegisterBase) != 0) { + return RETURN_SUCCESS; + } + + *UartBase = CsrRead (LOONGARCH_CSR_KS1); + + return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)*UartBase); +} diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf new file mode 100644 index 0000000000..b5fc03a284 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf @@ -0,0 +1,33 @@ +## @file +# Platform Hook Library instance for 16550 Uart. +# +# Copyright (c) 2020, ARM Ltd. All rights reserved.
+# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = Fdt16550SerialPortHookLib + MODULE_UNI_FILE = Fdt16550SerialPortHookLib.uni + FILE_GUID = 808335DB-220E-A353-887C-9AA1B7D433A1 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformHookLib|DXE_CORE DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION + CONSTRUCTOR = PlatformHookSerialPortInitialize + +[Sources] + Fdt16550SerialPortHookLib.c + +[LibraryClasses] + BaseLib + PcdLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.uni b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.uni new file mode 100644 index 0000000000..92eb2ed0b4 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.uni @@ -0,0 +1,14 @@ +// /** @file +// Platform Hook Library instance for 16550 Uart. +// +// +// Copyright (c) 2020, ARM Ltd. All rights reserved.
+// Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Platform Hook Library instance for 16550 Uart." + +#string STR_MODULE_DESCRIPTION #language en-US "Platform Hook Library instance for 16550 Uart." -- cgit From ab4b1f113dada005a1a88f07039c0cccc9ce840c Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:07:04 +0800 Subject: OvmfPkg/LoongArchVirt: Add the early serial port output library Add a early serial port output library into LoongArchVirt that named EarlyFdtSerialPortLib16550, this library is referenced from MdeModulePkg. This library is used in the PEI phase. Since the serial port address can not be saved in memory of the LoongArch QEMU virtual machine in the PEI phase, the serial prot base address will be obtained from the FDT before each output. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Xianglai Li --- .../EarlyFdtSerialPortLib16550.c | 819 +++++++++++++++++++++ .../EarlyFdtSerialPortLib16550.inf | 47 ++ 2 files changed, 866 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.c create mode 100644 OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf diff --git a/OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.c b/OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.c new file mode 100644 index 0000000000..9e6e3d6a00 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.c @@ -0,0 +1,819 @@ +/** @file + 16550 UART Serial Port library functions + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +// +// PCI Defintions. +// +#define PCI_BRIDGE_32_BIT_IO_SPACE 0x01 + +// +// 16550 UART register offsets and bitfields +// +#define R_UART_RXBUF 0 // LCR_DLAB = 0 +#define R_UART_TXBUF 0 // LCR_DLAB = 0 +#define R_UART_BAUD_LOW 0 // LCR_DLAB = 1 +#define R_UART_BAUD_HIGH 1 // LCR_DLAB = 1 +#define R_UART_IER 1 // LCR_DLAB = 0 +#define R_UART_FCR 2 +#define B_UART_FCR_FIFOE BIT0 +#define B_UART_FCR_FIFO64 BIT5 +#define R_UART_LCR 3 +#define B_UART_LCR_DLAB BIT7 +#define R_UART_MCR 4 +#define B_UART_MCR_DTRC BIT0 +#define B_UART_MCR_RTS BIT1 +#define R_UART_LSR 5 +#define B_UART_LSR_RXRDY BIT0 +#define B_UART_LSR_TXRDY BIT5 +#define B_UART_LSR_TEMT BIT6 +#define R_UART_MSR 6 +#define B_UART_MSR_CTS BIT4 +#define B_UART_MSR_DSR BIT5 +#define B_UART_MSR_RI BIT6 +#define B_UART_MSR_DCD BIT7 + +/** + Read an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is read from + MMIO space. If PcdSerialUseMmio is FALSE, then the value is read from I/O space. The + parameter Offset is added to the base address of the 16550 registers that is specified + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the MMIO space access + width and defaults to 8 bit access, and supports 8 or 32 bit access. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to read. + + @return The value read from the 16550 register. +**/ +STATIC +UINT8 +SerialPortReadRegister ( + UINTN Base, + UINTN Offset + ) +{ + if (PcdGetBool (PcdSerialUseMmio)) { + if (PcdGet8 (PcdSerialRegisterAccessWidth) == 32) { + return (UINT8)MmioRead32 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } + + return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } else { + return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } +} + +/** + Write an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is written to + MMIO space. If PcdSerialUseMmio is FALSE, then the value is written to I/O space. The + parameter Offset is added to the base address of the 16550 registers that is specified + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the MMIO space access + width and defaults to 8 bit access, and supports 8 or 32 bit access. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to write. + @param Value The value to write to the 16550 register specified by Offset. + + @return The value written to the 16550 register. +**/ +STATIC +UINT8 +SerialPortWriteRegister ( + UINTN Base, + UINTN Offset, + UINT8 Value + ) +{ + if (PcdGetBool (PcdSerialUseMmio)) { + if (PcdGet8 (PcdSerialRegisterAccessWidth) == 32) { + return (UINT8)MmioWrite32 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), (UINT8)Value); + } + + return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); + } else { + return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); + } +} + +/** + Retrieve the I/O or MMIO base address register for the PCI UART device. + + This function assumes Root Bus Numer is Zero, and enables I/O and MMIO in PCI UART + Device if they are not already enabled. + + @return The base address register of the UART device. +**/ +STATIC +UINTN +GetSerialRegisterBase ( + VOID + ) +{ + VOID *Base; + RETURN_STATUS Status; + UINT64 SerialConsoleAddress; + + Base = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); + Status = FdtSerialGetConsolePort (Base, &SerialConsoleAddress); + if (RETURN_ERROR (Status)) { + return (UINTN)0; + } + + return SerialConsoleAddress; +} + +/** + Return whether the hardware flow control signal allows writing. + + @param SerialRegisterBase The base address register of UART device. + + @retval TRUE The serial port is writable. + @retval FALSE The serial port is not writable. +**/ +STATIC +BOOLEAN +SerialPortWritable ( + UINTN SerialRegisterBase + ) +{ + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + if (PcdGetBool (PcdSerialDetectCable)) { + // + // Wait for both DSR and CTS to be set + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // === === ======================================== ======== + // 0 0 No cable connected. Wait + // 0 1 No cable connected. Wait + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clear to send. Transmit + // + return (BOOLEAN)((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS)); + } else { + // + // Wait for both DSR and CTS to be set OR for DSR to be clear. + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // === === ======================================== ======== + // 0 0 No cable connected. Transmit + // 0 1 No cable connected. Transmit + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clar to send. Transmit + // + return (BOOLEAN)((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR)); + } + } + + return TRUE; +} + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + UINTN SerialRegisterBase; + UINT32 Divisor; + UINT32 CurrentDivisor; + BOOLEAN Initialized; + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) * 16); + if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) * 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) { + Divisor++; + } + + // + // Get the base address of the serial port in either I/O or MMIO space + // + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return RETURN_DEVICE_ERROR; + } + + // + // See if the serial port is already initialized + // + Initialized = TRUE; + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) { + Initialized = FALSE; + } + + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB)); + CurrentDivisor = SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH) << 8; + CurrentDivisor |= (UINT32)SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB)); + if (CurrentDivisor != Divisor) { + Initialized = FALSE; + } + + if (Initialized) { + return RETURN_SUCCESS; + } + + // + // Wait for the serial port to be ready. + // Verify that both the transmit FIFO and the shift register are empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(Divisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Divisor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from PcdSerialLineControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F)); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); + + // + // Set FIFO Polled Mode by clearing IER after setting FCR + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00); + + // + // Put Modem Control Register(MCR) into its reset state of 0x00. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00); + + return RETURN_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + + If Buffer is NULL, then ASSERT(). + + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the write operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINTN Index; + UINTN FifoSize; + + if (Buffer == NULL) { + return 0; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return 0; + } + + if (NumberOfBytes == 0) { + // + // Flush the hardware + // + + // + // Wait for both the transmit FIFO and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + } + + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)) { + } + + return 0; + } + + // + // Compute the maximum size of the Tx FIFO + // + FifoSize = 1; + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) { + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) { + FifoSize = 16; + } else { + FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize); + } + } + + Result = NumberOfBytes; + while (NumberOfBytes != 0) { + // + // Wait for the serial port to be ready, to make sure both the transmit FIFO + // and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + } + + // + // Fill then entire Tx FIFO + // + for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) { + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)) { + } + + // + // Write byte to the transmit buffer. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer); + } + } + + return Result; +} + +/** + Reads data from a serial device into a buffer. + + @param Buffer Pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes Number of bytes to read from the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes read from the serial device. + If this value is less than NumberOfBytes, then the read operation failed. +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINT8 Mcr; + + if (NULL == Buffer) { + return 0; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return 0; + } + + Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS); + + for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) { + // + // Wait for the serial port to have some data. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) == 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr | B_UART_MCR_RTS)); + } + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + } + + // + // Read byte from the receive buffer. + // + *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF); + } + + return Result; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls aserial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + UINTN SerialRegisterBase; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return FALSE; + } + + // + // Read the serial port status + // + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) != 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS)); + } + + return TRUE; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS)); + } + + return FALSE; +} + +/** + Sets the control bits on a serial device. + + @param Control Sets the bits of Control that are settable. + + @retval RETURN_SUCCESS The new control bits were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Mcr; + + // + // First determine the parameter is invalid. + // + if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY | + EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) + { + return RETURN_UNSUPPORTED; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return RETURN_UNSUPPORTED; + } + + // + // Read the Modem Control Register. + // + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS)); + + if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) { + Mcr |= B_UART_MCR_DTRC; + } + + if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) { + Mcr |= B_UART_MCR_RTS; + } + + // + // Write the Modem Control Register. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + + return RETURN_SUCCESS; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control signals from the serial device. + + @retval RETURN_SUCCESS The control bits were read from the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Msr; + UINT8 Mcr; + UINT8 Lsr; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return RETURN_UNSUPPORTED; + } + + *Control = 0; + + // + // Read the Modem Status Register. + // + Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR); + + if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) { + *Control |= EFI_SERIAL_CLEAR_TO_SEND; + } + + if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) { + *Control |= EFI_SERIAL_DATA_SET_READY; + } + + if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) { + *Control |= EFI_SERIAL_RING_INDICATE; + } + + if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) { + *Control |= EFI_SERIAL_CARRIER_DETECT; + } + + // + // Read the Modem Control Register. + // + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + + if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) { + *Control |= EFI_SERIAL_DATA_TERMINAL_READY; + } + + if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) { + *Control |= EFI_SERIAL_REQUEST_TO_SEND; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + + // + // Read the Line Status Register. + // + Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR); + + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + + if ((Lsr & B_UART_LSR_RXRDY) == 0) { + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + On output, the value actually set. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + On output, the value actually set. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + On output, the value actually set. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + On output, the value actually set. + + @retval RETURN_SUCCESS The new attributes were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. +**/ +RETURN_STATUS +EFIAPI +SerialPortSetAttributes ( + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT UINT32 *Timeout, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + UINTN SerialRegisterBase; + UINT32 SerialBaudRate; + UINTN Divisor; + UINT8 Lcr; + UINT8 LcrData; + UINT8 LcrParity; + UINT8 LcrStop; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return RETURN_UNSUPPORTED; + } + + // + // Check for default settings and fill in actual values. + // + if (*BaudRate == 0) { + *BaudRate = PcdGet32 (PcdSerialBaudRate); + } + + SerialBaudRate = (UINT32)*BaudRate; + + if (*DataBits == 0) { + LcrData = (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3); + *DataBits = LcrData + 5; + } else { + if ((*DataBits < 5) || (*DataBits > 8)) { + return RETURN_INVALID_PARAMETER; + } + + // + // Map 5..8 to 0..3 + // + LcrData = (UINT8)(*DataBits - (UINT8)5); + } + + if (*Parity == DefaultParity) { + LcrParity = (UINT8)((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); + switch (LcrParity) { + case 0: + *Parity = NoParity; + break; + + case 3: + *Parity = EvenParity; + break; + + case 1: + *Parity = OddParity; + break; + + case 7: + *Parity = SpaceParity; + break; + + case 5: + *Parity = MarkParity; + break; + + default: + break; + } + } else { + switch (*Parity) { + case NoParity: + LcrParity = 0; + break; + + case EvenParity: + LcrParity = 3; + break; + + case OddParity: + LcrParity = 1; + break; + + case SpaceParity: + LcrParity = 7; + break; + + case MarkParity: + LcrParity = 5; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + if (*StopBits == DefaultStopBits) { + LcrStop = (UINT8)((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); + switch (LcrStop) { + case 0: + *StopBits = OneStopBit; + break; + + case 1: + if (*DataBits == 5) { + *StopBits = OneFiveStopBits; + } else { + *StopBits = TwoStopBits; + } + + break; + + default: + break; + } + } else { + switch (*StopBits) { + case OneStopBit: + LcrStop = 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + LcrStop = 1; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16); + if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >= SerialBaudRate * 8) { + Divisor++; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(Divisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Divisor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from line control value + // + Lcr = (UINT8)((LcrParity << 3) | (LcrStop << 2) | LcrData); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(Lcr & 0x3F)); + + return RETURN_SUCCESS; +} diff --git a/OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf b/OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf new file mode 100644 index 0000000000..76a6bd051b --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf @@ -0,0 +1,47 @@ +## @file +# SerialPortLib instance for 16550 UART. +# +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = EarlySerialPortLib16550 + FILE_GUID = f4fb883d-8138-4f29-bb0c-c574e9312c74 + MODULE_TYPE = BASE + VERSION_STRING = 1.1 + LIBRARY_CLASS = SerialPortLib + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + FdtSerialPortAddressLib + IoLib + PcdLib + SerialPortLib + +[Sources] + EarlyFdtSerialPortLib16550.c + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterAccessWidth ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress ## CONSUMES -- cgit From 74433f66b1a44bbac8662c39654ca80ddcff1cee Mon Sep 17 00:00:00 2001 From: Chao Li Date: Tue, 11 Jun 2024 16:49:58 +0800 Subject: OvmfPkg: Add a new GUID called gRtcRegisterBaseAddressHobGuid Added a new GUID use for store the RTC register base address if the platform can not uses the dynamic PCD in PEI stage. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Chao Li --- OvmfPkg/OvmfPkg.dec | 1 + 1 file changed, 1 insertion(+) diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index ad7c196c5b..e1ef8420ce 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -172,6 +172,7 @@ gEfiNonCcFvGuid = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}} gOvmfVariableGuid = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}} gQemuFirmwareResourceHobGuid = {0x3cc47b04, 0x0d3e, 0xaa64, {0x06, 0xa6, 0x4b, 0xdc, 0x9a, 0x2c, 0x61, 0x19}} + gRtcRegisterBaseAddressHobGuid = {0x40435d97, 0xeb37, 0x4a4b, {0x7f, 0xad, 0xb7, 0xed, 0x72, 0xa1, 0x43, 0xc5}} [Ppis] # PPI whose presence in the PPI database signals that the TPM base address -- cgit From 79835e08f5ef3da5a3daad7e815f69c0df8d0214 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:08:01 +0800 Subject: OvmfPkg/LoongArchVirt: Add real time clock library This library is provides real time clock for LoongArch virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Baoqi Zhang Co-authored-by: Xianglai Li --- .../Library/LsRealTimeClockLib/LsRealTimeClock.h | 40 +++ .../LsRealTimeClockLib/LsRealTimeClockLib.c | 325 +++++++++++++++++++++ .../LsRealTimeClockLib/LsRealTimeClockLib.inf | 44 +++ 3 files changed, 409 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h new file mode 100644 index 0000000000..5ad0b14642 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h @@ -0,0 +1,40 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef LS_REAL_TIME_CLOCK_H_ +#define LS_REAL_TIME_CLOCK_H_ + +#define TOY_WRITE0_REG 0x24 +#define TOY_WRITE1_REG 0x28 +#define TOY_READ0_REG 0x2c +#define TOY_READ1_REG 0x30 +#define RTC_CTRL_REG 0x40 + +/* TOY Enable bits */ +#define RTC_ENABLE_BIT (1UL << 13) +#define TOY_ENABLE_BIT (1UL << 11) +#define OSC_ENABLE_BIT (1UL << 8) + +/* + * shift bits and filed mask + */ +#define TOY_MON_MASK 0x3f +#define TOY_DAY_MASK 0x1f +#define TOY_HOUR_MASK 0x1f +#define TOY_MIN_MASK 0x3f +#define TOY_SEC_MASK 0x3f +#define TOY_MSEC_MASK 0xf + +#define TOY_MON_SHIFT 26 +#define TOY_DAY_SHIFT 21 +#define TOY_HOUR_SHIFT 16 +#define TOY_MIN_SHIFT 10 +#define TOY_SEC_SHIFT 4 + +#endif // LS_REAL_TIME_CLOCK_H_ diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c new file mode 100644 index 0000000000..0925ab1166 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c @@ -0,0 +1,325 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "LsRealTimeClock.h" + +STATIC BOOLEAN mInitialized = FALSE; +STATIC EFI_EVENT mRtcVirtualAddrChangeEvent; +STATIC UINTN mRtcBase; + +/* + Enable Real-time clock. + + @param VOID + + @retval VOID + */ +STATIC +VOID +InitRtc ( + VOID + ) +{ + UINTN Val; + EFI_HOB_GUID_TYPE *GuidHob = NULL; + VOID *DataInHob = NULL; + + if (!mInitialized) { + /* Enable rtc */ + GuidHob = GetFirstGuidHob (&gRtcRegisterBaseAddressHobGuid); + if (GuidHob) { + DataInHob = GET_GUID_HOB_DATA (GuidHob); + mRtcBase = (UINT64)(*(UINTN *)DataInHob); + Val = MmioRead32 (mRtcBase + RTC_CTRL_REG); + Val |= TOY_ENABLE_BIT | OSC_ENABLE_BIT; + MmioWrite32 (mRtcBase + RTC_CTRL_REG, Val); + mInitialized = TRUE; + } else { + DebugPrint (EFI_D_INFO, "RTC register address not found!\n"); + ASSERT (FALSE); + } + } +} + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param Time A pointer to storage to receive a snapshot of the current time. + @param Capabilities An optional pointer to a buffer to receive the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + @retval EFI_SECURITY_VIOLATION The time could not be retrieved due to an authentication failure. +**/ +EFI_STATUS +EFIAPI +LibGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities + ) +{ + UINT32 Val; + + // Ensure Time is a valid pointer + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + Val = MmioRead32 (mRtcBase + TOY_READ1_REG); + Time->Year = Val + 1900; + + Val = MmioRead32 (mRtcBase + TOY_READ0_REG); + Time->Month = (Val >> TOY_MON_SHIFT) & TOY_MON_MASK; + Time->Day = (Val >> TOY_DAY_SHIFT) & TOY_DAY_MASK; + Time->Hour = (Val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; + Time->Minute = (Val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; + Time->Second = (Val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; + Time->Nanosecond = 0; + return EFI_SUCCESS; +} + +/** + Sets the current local time and date information. + + @param Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. +**/ +EFI_STATUS +EFIAPI +LibSetTime ( + IN EFI_TIME *Time + ) +{ + UINT32 Val; + + // Initialize the hardware if not already done + + Val = 0; + Val |= (Time->Second << TOY_SEC_SHIFT); + Val |= (Time->Minute << TOY_MIN_SHIFT); + Val |= (Time->Hour << TOY_HOUR_SHIFT); + Val |= (Time->Day << TOY_DAY_SHIFT); + Val |= (Time->Month << TOY_MON_SHIFT); + MmioWrite32 (mRtcBase + TOY_WRITE0_REG, Val); + + Val = Time->Year - 1900; + MmioWrite32 (mRtcBase + TOY_WRITE1_REG, Val); + return EFI_SUCCESS; +} + +/** + Returns the current wakeup alarm clock setting. + + @param Enabled Indicates if the alarm is currently enabled or disabled. + @param Pending Indicates if the alarm signal is pending and requires acknowledgement. + @param Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Any parameter is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. +**/ +EFI_STATUS +EFIAPI +LibGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +/** + Sets the system wakeup alarm clock time. + + @param Enabled Enable or disable the wakeup alarm. + @param Time If Enable is TRUE, the time to set the wakeup alarm for. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. +**/ +EFI_STATUS +EFIAPI +LibSetWakeupTime ( + IN BOOLEAN Enabled, + OUT EFI_TIME *Time + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +STATIC +VOID +EFIAPI +VirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Only needed if you are going to support the OS calling RTC functions in virtual mode. + // You will need to call EfiConvertPointer (). To convert any stored physical addresses + // to virtual address. After the OS transitions to calling in virtual mode, all future + // runtime calls will be made in virtual mode. + // + EfiConvertPointer (0x0, (VOID **)&mRtcBase); + return; +} + +/** Add the RTC controller address range to the memory map. + + @param [in] ImageHandle The handle to the image. + @param [in] RtcPageBase Base address of the RTC controller. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Flash device not found. +**/ +STATIC +EFI_STATUS +MapRtcResources ( + IN EFI_HANDLE ImageHandle, + IN EFI_PHYSICAL_ADDRESS RtcPageBase + ) +{ + EFI_STATUS Status; + + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + RtcPageBase, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to add memory space. Status = %r\n", + Status + )); + return Status; + } + + Status = gDS->AllocateMemorySpace ( + EfiGcdAllocateAddress, + EfiGcdMemoryTypeMemoryMappedIo, + 0, + EFI_PAGE_SIZE, + &RtcPageBase, + ImageHandle, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to allocate memory space. Status = %r\n", + Status + )); + gDS->RemoveMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + return Status; + } + + Status = gDS->SetMemorySpaceAttributes ( + RtcPageBase, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to set memory attributes. Status = %r\n", + Status + )); + + gDS->FreeMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + + gDS->RemoveMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + } + + return Status; +} + +/** + This is the declaration of an EFI image entry point. This can be the entry point to an application + written to this specification, an EFI boot service driver, or an EFI runtime driver. + + @param ImageHandle Handle that identifies the loaded image. + @param SystemTable System Table for this image. + + @retval EFI_SUCCESS The operation completed successfully. +**/ +EFI_STATUS +EFIAPI +LibRtcInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + InitRtc (); + Status = MapRtcResources (ImageHandle, (mRtcBase & ~EFI_PAGE_MASK)); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to map memory for loongson 7A RTC. Status = %r\n", + Status + )); + return Status; + } + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + VirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mRtcVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf new file mode 100644 index 0000000000..a5bb80655e --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf @@ -0,0 +1,44 @@ +## @file +# LoongArch64 CPU Real Time Clock DXE Phase Library. +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = LsRealTimeClockLib + FILE_GUID = 9793a3da-1869-4fdf-88b1-c6484341f50b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RealTimeClockLib + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + LsRealTimeClockLib.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + DebugLib + DxeServicesTableLib + HobLib + IoLib + PcdLib + UefiBootServicesTableLib + UefiRuntimeLib + +[Guids] + gEfiEventVirtualAddressChangeGuid + gRtcRegisterBaseAddressHobGuid + +[Depex] + TRUE -- cgit From c63d90085beeaa5ea6202ed67e27d561a9cd19aa Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:08:46 +0800 Subject: OvmfPkg/LoongArchVirt: Add reset system library This library provides interface related to restart and shudown the LoongArch64 virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- .../ResetSystemAcpiLib/BaseResetSystemAcpiGed.c | 151 ++++++++++++ .../BaseResetSystemAcpiGedLib.inf | 35 +++ .../ResetSystemAcpiLib/DxeResetSystemAcpiGed.c | 262 +++++++++++++++++++++ .../DxeResetSystemAcpiGedLib.inf | 41 ++++ .../ResetSystemAcpiLib/ResetSystemAcpiGed.c | 125 ++++++++++ .../ResetSystemAcpiLib/ResetSystemAcpiGed.h | 23 ++ 6 files changed, 637 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c create mode 100644 OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c new file mode 100644 index 0000000000..a88ed2ace4 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c @@ -0,0 +1,151 @@ +/** @file + Base ResetSystem library implementation. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include "ResetSystemAcpiGed.h" + +/** + Get configuration item data by the firmware configuration file name. + + @param[in] Name - Name of file to look up. + + @return VOID* The Pointer of Value of Firmware Configuration item read. +**/ +STATIC +VOID * +GetFwCfgData ( + CONST CHAR8 *Name + ) +{ + FIRMWARE_CONFIG_ITEM FwCfgItem; + EFI_STATUS Status; + UINTN FwCfgSize; + VOID *Data; + + Status = QemuFwCfgFindFile (Name, &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d read %s error Status %d \n", __func__, __LINE__, Name, Status)); + return NULL; + } + + Data = AllocatePool (FwCfgSize); + if (Data == NULL) { + return NULL; + } + + QemuFwCfgSelectItem (FwCfgItem); + QemuFwCfgReadBytes (FwCfgSize, Data); + + return Data; +} + +/** + Find the power manager related info from ACPI table + + @retval EFI_SUCCESS Successfully find out all the required information. + @retval EFI_NOT_FOUND Failed to find the required info. +**/ +STATIC +EFI_STATUS +GetPowerManagerByParseAcpiInfo ( + VOID + ) +{ + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt = NULL; + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp = NULL; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt = NULL; + EFI_ACPI_DESCRIPTION_HEADER *Rsdt = NULL; + VOID *AcpiTables = NULL; + UINT32 *Entry32 = NULL; + UINTN Entry32Num; + UINT32 *Signature = NULL; + UINTN Idx; + + Rsdp = GetFwCfgData ("etc/acpi/rsdp"); + if (Rsdp == NULL) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/rsdp error \n", __func__, __LINE__)); + return EFI_NOT_FOUND; + } + + AcpiTables = GetFwCfgData ("etc/acpi/tables"); + if (AcpiTables == NULL) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/tables error \n", __func__, __LINE__)); + FreePool (Rsdp); + return EFI_NOT_FOUND; + } + + Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables + Rsdp->RsdtAddress); + Entry32 = (UINT32 *)(Rsdt + 1); + Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2; + for (Idx = 0; Idx < Entry32Num; Idx++) { + Signature = (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables); + if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { + Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n")); + goto Done; + } + } + + Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables + Rsdp->XsdtAddress); + Entry32 = (UINT32 *)(Xsdt + 1); + Entry32Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2; + for (Idx = 0; Idx < Entry32Num; Idx++) { + Signature = (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables); + if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { + Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n")); + goto Done; + } + } + + FreePool (Rsdp); + FreePool (AcpiTables); + DEBUG ((DEBUG_ERROR, " Fadt Not Found\n")); + return EFI_NOT_FOUND; + +Done: + mPowerManager.ResetRegAddr = Fadt->ResetReg.Address; + mPowerManager.ResetValue = Fadt->ResetValue; + mPowerManager.SleepControlRegAddr = Fadt->SleepControlReg.Address; + mPowerManager.SleepStatusRegAddr = Fadt->SleepStatusReg.Address; + + FreePool (Rsdp); + FreePool (AcpiTables); + + return EFI_SUCCESS; +} + +/** + The constructor function to initialize mPowerManager. + + @retval EFI_SUCCESS Initialize mPowerManager success. + @retval EFI_NOT_FOUND Failed to initialize mPowerManager. +**/ +EFI_STATUS +EFI_API +ResetSystemLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = GetPowerManagerByParseAcpiInfo (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__)); + } + + ASSERT (mPowerManager.SleepControlRegAddr); + ASSERT (mPowerManager.SleepStatusRegAddr); + ASSERT (mPowerManager.ResetRegAddr); + + return Status; +} diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf new file mode 100644 index 0000000000..f63915d872 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf @@ -0,0 +1,35 @@ +## @file +# Base library instance for ResetSystem library class for LoongArch +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ResetSystemLib + FILE_GUID = BA521997-9016-32B5-65DF-EA5F560A3837 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib|SEC PEI_CORE PEIM DXE_CORE + CONSTRUCTOR = ResetSystemLibConstructor + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + BaseResetSystemAcpiGed.c + ResetSystemAcpiGed.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + DebugLib + MemoryAllocationLib + QemuFwCfgLib diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c new file mode 100644 index 0000000000..4aea6de668 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGed.c @@ -0,0 +1,262 @@ +/** @file + Dxe ResetSystem library implementation. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include // EfiConvertPointer() +#include "ResetSystemAcpiGed.h" + +/** + Modifies the attributes to Runtime type for a page size memory region. + + @param BaseAddress Specified start address + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + @retval EFI_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + @retval EFI_ACCESS_DEFINED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is + not available yet. +**/ +STATIC +EFI_STATUS +SetMemoryAttributesRunTime ( + UINTN Address + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + + Address &= ~EFI_PAGE_MASK; + + Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: GetMemorySpaceDescriptor failed\n", __func__)); + return Status; + } + + if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) { + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Address, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: AddMemorySpace failed\n", __func__)); + return Status; + } + + Status = gDS->SetMemorySpaceAttributes ( + Address, + EFI_PAGE_SIZE, + EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __func__, __LINE__)); + return Status; + } + } else if (!(Descriptor.Attributes & EFI_MEMORY_RUNTIME)) { + Status = gDS->SetMemorySpaceAttributes ( + Address, + EFI_PAGE_SIZE, + Descriptor.Attributes | EFI_MEMORY_RUNTIME + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __func__, __LINE__)); + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + Find the power manager related info from ACPI table + + @retval RETURN_SUCCESS Successfully find out all the required information. + @retval RETURN_NOT_FOUND Failed to find the required info. +**/ +STATIC +EFI_STATUS +GetPowerManagerByParseAcpiInfo ( + VOID + ) +{ + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt = NULL; + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp = NULL; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt = NULL; + EFI_ACPI_DESCRIPTION_HEADER *Rsdt = NULL; + UINT32 *Entry32 = NULL; + UINTN Entry32Num; + UINT32 *Signature = NULL; + UINTN Idx; + EFI_STATUS Status; + + Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp); + if (EFI_ERROR (Status)) { + Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp); + } + + if (EFI_ERROR (Status) || (Rsdp == NULL)) { + DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n")); + return RETURN_NOT_FOUND; + } + + Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress; + Entry32 = (UINT32 *)(UINTN)(Rsdt + 1); + Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2; + for (Idx = 0; Idx < Entry32Num; Idx++) { + Signature = (UINT32 *)(UINTN)Entry32[Idx]; + if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { + Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n")); + goto Done; + } + } + + Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Rsdp->XsdtAddress; + Entry32 = (UINT32 *)(Xsdt + 1); + Entry32Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2; + for (Idx = 0; Idx < Entry32Num; Idx++) { + Signature = (UINT32 *)(UINTN)Entry32[Idx]; + if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { + Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature; + DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n")); + goto Done; + } + } + + DEBUG ((DEBUG_ERROR, " Fadt Not Found\n")); + return RETURN_NOT_FOUND; + +Done: + mPowerManager.ResetRegAddr = Fadt->ResetReg.Address; + mPowerManager.ResetValue = Fadt->ResetValue; + mPowerManager.SleepControlRegAddr = Fadt->SleepControlReg.Address; + mPowerManager.SleepStatusRegAddr = Fadt->SleepStatusReg.Address; + return RETURN_SUCCESS; +} + +/** + This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE + event. It converts a pointer to a new virtual address. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context +**/ +STATIC +VOID +ResetSystemLibAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EfiConvertPointer (0, (VOID **)&mPowerManager.SleepControlRegAddr); + EfiConvertPointer (0, (VOID **)&mPowerManager.SleepStatusRegAddr); + EfiConvertPointer (0, (VOID **)&mPowerManager.ResetRegAddr); +} + +/** + Notification function of ACPI Table change. + + This is a notification function registered on ACPI Table change event. + It saves the Century address stored in ACPI FADT table. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context. +**/ +STATIC +VOID +AcpiNotificationEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status = GetPowerManagerByParseAcpiInfo (); + if (EFI_ERROR (Status)) { + return; + } + + DEBUG ((DEBUG_INFO, "%a: sleepControl %llx\n", __func__, mPowerManager.SleepControlRegAddr)); + ASSERT (mPowerManager.SleepControlRegAddr); + Status = SetMemoryAttributesRunTime (mPowerManager.SleepControlRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__)); + return; + } + + DEBUG ((DEBUG_INFO, "%a: sleepStatus %llx\n", __func__, mPowerManager.SleepStatusRegAddr)); + ASSERT (mPowerManager.SleepStatusRegAddr); + Status = SetMemoryAttributesRunTime (mPowerManager.SleepStatusRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__)); + return; + } + + DEBUG ((DEBUG_INFO, "%a: ResetReg %llx\n", __func__, mPowerManager.ResetRegAddr)); + ASSERT (mPowerManager.ResetRegAddr); + Status = SetMemoryAttributesRunTime (mPowerManager.ResetRegAddr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__)); + } + + return; +} + +/** + The constructor function to Register ACPI Table change event and Address Change Event. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. +**/ +EFI_STATUS +EFIAPI +ResetSystemLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + EFI_EVENT ResetSystemVirtualNotifyEvent; + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiNotificationEvent, + NULL, + &gEfiAcpiTableGuid, + &Event + ); + + // + // Register SetVirtualAddressMap () notify function + // + Status = gBS->CreateEvent ( + EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, + TPL_NOTIFY, + ResetSystemLibAddressChangeEvent, + NULL, + &ResetSystemVirtualNotifyEvent + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf new file mode 100644 index 0000000000..9815e2f6e7 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf @@ -0,0 +1,41 @@ +## @file +# DXE library instance for ResetSystem library class for LoongArch. +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ResetSystemLib + FILE_GUID = F05197D5-5827-AA61-FB2D-BC69259F17A9 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION + CONSTRUCTOR = ResetSystemLibConstructor + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + DxeResetSystemAcpiGed.c + ResetSystemAcpiGed.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + DebugLib + DxeServicesTableLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeLib + +[Guids] + gEfiAcpi10TableGuid ## PRODUCES ## SystemTable + gEfiAcpiTableGuid ## PRODUCES ## SystemTable diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c new file mode 100644 index 0000000000..105382da35 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.c @@ -0,0 +1,125 @@ +/** @file + ResetSystem library implementation. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include // CpuDeadLoop() +#include +#include +#include // ResetCold() +#include "ResetSystemAcpiGed.h" + +POWER_MANAGER mPowerManager; + +/** + Calling this function causes a system-wide reset. This sets + all circuitry within the system to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + System reset should not return, if it returns, it means the system does + not support cold reset. +**/ +STATIC VOID +AcpiGedReset ( + VOID + ) +{ + MmioWrite8 ( + (UINTN)mPowerManager.ResetRegAddr, + mPowerManager.ResetValue + ); + + CpuDeadLoop (); +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI S5 states. + + * */ +STATIC VOID +AcpiGedShutdown ( + VOID + ) +{ + MmioWrite8 ( + (UINTN)mPowerManager.SleepControlRegAddr, + (1 << 5) /* enable bit */ | + (5 << 2) /* typ == S5 */ + ); + + CpuDeadLoop (); +} + +/** + This function causes a system-wide reset (cold reset), in which + all circuitry within the system returns to its initial state. This type of + reset is asynchronous to system operation and operates without regard to + cycle boundaries. + + If this function returns, it means that the system does not support cold + reset. +**/ +VOID EFIAPI +ResetCold ( + VOID + ) +{ + AcpiGedReset (); +} + +/** + This function causes a system-wide initialization (warm reset), in which all + processors are set to their initial state. Pending cycles are not corrupted. + + If this function returns, it means that the system does not support warm + reset. +**/ +VOID EFIAPI +ResetWarm ( + VOID + ) +{ + AcpiGedReset (); +} + +/** + This function causes a systemwide reset. The exact type of the reset is + defined by the EFI_GUID that follows the Null-terminated Unicode string passed + into ResetData. If the platform does not recognize the EFI_GUID in ResetData + the platform must pick a supported reset type to perform.The platform may + optionally log the parameters from any non-normal reset that occurs. + + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData The data buffer starts with a Null-terminated string, + followed by the EFI_GUID. +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + AcpiGedReset (); +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + If this function returns, it means that the system does not support shut down + reset. +**/ +VOID EFIAPI +ResetShutdown ( + VOID + ) +{ + AcpiGedShutdown (); +} diff --git a/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h new file mode 100644 index 0000000000..06e2572db0 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/ResetSystemAcpiGed.h @@ -0,0 +1,23 @@ +/** @file + ResetSystem lib head file. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef RESET_SYSTEM_ACPI_GED_H_ +#define RESET_SYSTEM_ACPI_GED_H_ + +#include + +typedef struct { + UINT64 SleepControlRegAddr; + UINT64 SleepStatusRegAddr; + UINT64 ResetRegAddr; + UINT8 ResetValue; +} POWER_MANAGER; + +extern POWER_MANAGER mPowerManager; +#endif // RESET_SYSTEM_ACPI_GED_H_ -- cgit From 9912434785e4cffabd9989ab7fb4c65aa8b08d1d Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:09:42 +0800 Subject: OvmfPkg/LoongArchVirt: Support SEC phase Add SEC code for LoongArch virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S | 184 +++++++++ OvmfPkg/LoongArchVirt/Sec/SecMain.c | 512 ++++++++++++++++++++++++++ OvmfPkg/LoongArchVirt/Sec/SecMain.inf | 54 +++ 3 files changed, 750 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S create mode 100644 OvmfPkg/LoongArchVirt/Sec/SecMain.c create mode 100644 OvmfPkg/LoongArchVirt/Sec/SecMain.inf diff --git a/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S new file mode 100644 index 0000000000..dd74c6b296 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S @@ -0,0 +1,184 @@ +#------------------------------------------------------------------------------ +# +# Start for Loongson LoongArch processor +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - CSR - CPU Status Register +# - EBASE - Exception Base Address +#------------------------------------------------------------------------------ +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include +#include +#include + +#define BOOTCORE_ID 0 +// +// For coding convenience, define the maximum valid +// LoongArch exception. +// Since UEFI V2.11, it will be present in DebugSupport.h. +// +#define MAX_LOONGARCH_EXCEPTION 64 + +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + /* Disable global interrupt */ + bl DisableInterrupts + + /* Disable all local interrupt */ + li.w $a0, 0x1FFF + bl DisableLocalInterrupts + + /* Read physical cpu number id */ + bl GetApicId + li.d $t0, BOOTCORE_ID //0 + bne $a0, $t0, SlaveMain + + /* Set BSP stack */ + li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) # stack base + move $sp, $t0 + addi.d $sp, $sp, -0x8 + + /* Load the exception vector base address */ + li.d $s0, FixedPcdGet64(PcdLoongArchExceptionVectorBaseAddress) + + /* Construct SEC and PEI step exception environment */ + la.pcrel $a1, ExceptionEntryStart + la.pcrel $t0, ExceptionEntryEnd + sub.d $a2, $t0, $a1 + li.w $t0, (MAX_LOONGARCH_EXCEPTION + MAX_LOONGARCH_INTERRUPT) * 512 + bgeu $a2, $t0, DeadLoop + move $a0, $s0 + bl CopyMem + + /* Configure BSP reset ebase */ + move $a0, $s0 + bl SetExceptionBaseAddress + +CallEntry: + /* Call C function make sure parameter true */ + li.d $a0, FixedPcdGet64(PcdOvmfFdBaseAddress) # FW base + addi.d $a1, $sp, 0x8 + bl SecCoreStartupWithStack +# End of _ModuleEntryPoint + +ASM_PFX(ClearMailBox): + /* Clear mailbox */ + li.d $t1, LOONGARCH_IOCSR_MBUF3 + iocsrwr.d $zero, $t1 + li.d $t1, LOONGARCH_IOCSR_MBUF2 + iocsrwr.d $zero, $t1 + li.d $t1, LOONGARCH_IOCSR_MBUF1 + iocsrwr.d $zero, $t1 + li.d $t1, LOONGARCH_IOCSR_MBUF0 + iocsrwr.d $zero, $t1 + jirl $zero, $ra, 0 +# End of ClearMailBox + +ASM_PFX(EnableIPI): + /* Enable IPI interrupt */ + li.w $t1, BIT12 + csrxchg $t1, $t1, LOONGARCH_CSR_ECFG + + li.w $t2, 0xFFFFFFFFU + li.d $t1, LOONGARCH_IOCSR_IPI_EN + iocsrwr.w $t2, $t1 + jirl $zero, $ra, 0 +# End of EeableIPI + +#/** +# Get APIC ID for every CPU. +# +# @param NULL +# @return APICID +# +# UINTN +# EFI_API +# GetApicId ( +# VOID +# ) +#**/ +ASM_PFX(GetApicId): + csrrd $a0, LOONGARCH_CSR_CPUNUM + andi $a0, $a0, 0x3ff + jirl $zero, $ra, 0 +# End of GetApicId + +ASM_PFX(ApInitStack): + li.d $t1, SIZE_1KB + csrrd $t0, LOONGARCH_CSR_TMID + mul.d $t1, $t0, $t1 + li.d $t2, FixedPcdGet32(PcdCpuMaxLogicalProcessorNumber) + bgeu $t0, $t2, DeadLoop + li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) - SIZE_64KB + sub.d $sp, $t0, $t1 + addi.d $sp, $sp, -0x8 + jirl $zero, $ra, 0 +# End of ApInitStack + +ASM_PFX(SlaveMain): + /* Set AP exception handle in flash */ + la.pcrel $a0, ApException + bl SetExceptionBaseAddress + + /* Clean up local mail box and open INT */ + bl ClearMailBox + bl EnableIPI + bl EnableInterrupts + +WaitForWake: + /* Wait for wakeup */ + bl CpuSleep + b WaitForWake +# End of SlaveMain + +.align 12 +ASM_PFX(ApException): + csrrd $t0, LOONGARCH_CSR_ESTAT + srli.d $t0, $t0, 12 + andi $t0, $t0, 0x1 + beqz $t0, DeadLoop + + li.d $t0, LOONGARCH_IOCSR_IPI_STATUS + iocsrrd.w $t1, $t0 + li.d $t0, LOONGARCH_IOCSR_IPI_CLEAR + iocsrwr.w $t1, $t0 + + /* Read mail buf and jump to specified entry */ + li.d $t1, LOONGARCH_IOCSR_MBUF0 + iocsrrd.d $t0, $t1 + beqz $t0, OutOfException + csrwr $t0, LOONGARCH_CSR_ERA + li.d $t0, LOONGARCH_IOCSR_MBUF3 + iocsrrd.d $a1, $t0 + bl ClearMailBox + beqz $a1, NoParameterCall + + // + // If the parameters are not NULL, then calling happened in FW ENV. + // Set the EBASE to be the same as BSP. + // + li.d $a0, FixedPcdGet64(PcdLoongArchExceptionVectorBaseAddress) + bl SetExceptionBaseAddress + + bl ApInitStack + bl GetApicId + b OutOfException +NoParameterCall: + li.w $t0, BIT2 // IE + csrxchg $zero, $t0, LOONGARCH_CSR_PRMD // Clean PIE + +OutOfException: + ertn +# End of ApException + +ASM_PFX(DeadLoop): + b DeadLoop +# End of DeadLoop +.end diff --git a/OvmfPkg/LoongArchVirt/Sec/SecMain.c b/OvmfPkg/LoongArchVirt/Sec/SecMain.c new file mode 100644 index 0000000000..6f541b1b89 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Sec/SecMain.c @@ -0,0 +1,512 @@ +/** @file + Main SEC phase code. Transitions to PEI. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + temporary memory to permanent memory and do stack switching. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Temporary Memory Base address. + @param[in] PermanentMemoryBase Permanent Memory Base address. + @param[in] CopySize The size of memory that needs to be migrated. + + @retval EFI_SUCCESS Migration successful. +**/ +STATIC +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { + TemporaryRamMigration +}; + +STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamSupportPpiGuid, + &mTemporaryRamSupportPpi + }, +}; + +/** + Locates a section within a series of sections + with the specified section type. + + The Instance parameter indicates which instance of the section + type to return. (0 is first instance, 1 is second...) + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[in] Instance The section instance number + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +STATIC +EFI_STATUS +FindFfsSectionInstance ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + IN UINTN Instance, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfSections; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + // + // Loop through the FFS file sections within the PEI Core FFS file + // + EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections; + EndOfSections = EndOfSection + SizeOfSections; + for ( ; ; ) { + if (EndOfSection == EndOfSections) { + break; + } + + CurrentAddress = (EndOfSection + 3) & ~(3ULL); + if (CurrentAddress >= EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress; + + Size = SECTION_SIZE (Section); + if (Size < sizeof (*Section)) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfSection = CurrentAddress + Size; + if (EndOfSection > EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the requested section type + // + if (Section->Type == SectionType) { + if (Instance == 0) { + *FoundSection = Section; + return EFI_SUCCESS; + } else { + Instance--; + } + } + } + + return EFI_NOT_FOUND; +} + +/** + Locates a section within a series of sections + with the specified section type. + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +STATIC +EFI_STATUS +FindFfsSectionInSections ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + return FindFfsSectionInstance ( + Sections, + SizeOfSections, + SectionType, + 0, + FoundSection + ); +} + +/** + Locates a FFS file with the specified file type and a section + within that file with the specified section type. + + @param[in] Fv The firmware volume to search + @param[in] FileType The file type to locate + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +STATIC +EFI_STATUS +FindFfsFileAndSection ( + IN EFI_FIRMWARE_VOLUME_HEADER *Fv, + IN EFI_FV_FILETYPE FileType, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + + if (Fv->Signature != EFI_FVH_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv)); + return EFI_VOLUME_CORRUPTED; + } + + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv; + EndOfFirmwareVolume = CurrentAddress + Fv->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) { + CurrentAddress = (EndOfFile + 7) & ~(7ULL); + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress; + Size = *(UINT32 *)File->Size & 0xffffff; + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfFile = CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the request file type + // + if (File->Type != FileType) { + continue; + } + + Status = FindFfsSectionInSections ( + (VOID *)(File + 1), + (UINTN)EndOfFile - (UINTN)(File + 1), + SectionType, + FoundSection + ); + if (!EFI_ERROR (Status) || + (Status == EFI_VOLUME_CORRUPTED)) + { + return Status; + } + } +} + +/** + Locates the PEI Core entry point address + + @param[in] Fv The firmware volume to search + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted +**/ +STATIC +EFI_STATUS +FindPeiCoreImageBaseInFv ( + IN EFI_FIRMWARE_VOLUME_HEADER *Fv, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + EFI_STATUS Status; + EFI_COMMON_SECTION_HEADER *Section; + + Status = FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_PE32, + &Section + ); + if (EFI_ERROR (Status)) { + Status = FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_TE, + &Section + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n")); + return Status; + } + } + + *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1); + return EFI_SUCCESS; +} + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug information. It will report them if + remote debug is enabled. +**/ +STATIC +VOID +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase = 0; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + Status = FindPeiCoreImageBaseInFv (*BootFirmwareVolumePtr, &PeiCoreImageBase); + ASSERT (Status == EFI_SUCCESS); + + ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint = 0; + } + + return; +} + +/** + Find the peicore entry point and jump to the entry point to execute. + + @param[in] Context The first input parameter of InitializeDebugAgent(). +**/ +STATIC +VOID +EFIAPI +SecStartupPhase2 ( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_FIRMWARE_VOLUME_HEADER *BootFv; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context; + + // + // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug + // is enabled. + // + BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase; + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint); + SecCoreData->BootFirmwareVolumeBase = BootFv; + SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength; + + DEBUG ((DEBUG_INFO, "Find Pei EntryPoint=%p\n", PeiCoreEntryPoint)); + + // + // Transfer the control to the PEI core + // + DEBUG ((DEBUG_INFO, "SecStartupPhase2 %p\n", PeiCoreEntryPoint)); + + (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable); + + // + // If we get here then the PEI Core returned, which is not recoverable. + // + ASSERT (FALSE); + CpuDeadLoop (); +} + +/** + Entry point to the C language phase of SEC. initialize some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] BootFv The pointer to the PEI FV in memory. + @param[in] TopOfCurrentStack Top of Current Stack. +**/ +VOID +EFIAPI +SecCoreStartupWithStack ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, + IN VOID *TopOfCurrentStack + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + EFI_FIRMWARE_VOLUME_HEADER *BootPeiFv = (EFI_FIRMWARE_VOLUME_HEADER *)BootFv; + + DEBUG ((DEBUG_INFO, "Entering C environment\n")); + + ProcessLibraryConstructorList (); + + DEBUG (( + DEBUG_INFO, + "SecCoreStartupWithStack (0x%lx, 0x%lx)\n", + (UINTN)BootFv, + (UINTN)TopOfCurrentStack + )); + DEBUG (( + DEBUG_INFO, + "(0x%lx, 0x%lx)\n", + (UINTN)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase)), + (UINTN)(FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) + )); + + // |-------------| <-- TopOfCurrentStack + // | BSP Stack | 32k + // |-------------| + // | BSP Heap | 32k + // |-------------| <-- SecCoreData.TemporaryRamBase + // | Ap Stack | 384k + // |-------------| + // | Exception | 64k + // |-------------| <-- PcdOvmfSecPeiTempRamBase + + ASSERT ( + (UINTN)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) + + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) == + (UINTN)TopOfCurrentStack + ); + + // + // Initialize SEC hand-off state + // + SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); + + SecCoreData.TemporaryRamSize = (UINTN)SIZE_64KB; + SecCoreData.TemporaryRamBase = (VOID *)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SecCoreData.TemporaryRamSize); + + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize; + SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.BootFirmwareVolumeBase = BootPeiFv; + SecCoreData.BootFirmwareVolumeSize = (UINTN)BootPeiFv->FvLength; + + DEBUG (( + DEBUG_INFO, + "&SecCoreData.BootFirmwareVolumeBase=%lx SecCoreData.BootFirmwareVolumeBase=%lx\n", + (UINT64)&(SecCoreData.BootFirmwareVolumeBase), + (UINT64)(SecCoreData.BootFirmwareVolumeBase) + )); + DEBUG (( + DEBUG_INFO, + "&SecCoreData.BootFirmwareVolumeSize=%lx SecCoreData.BootFirmwareVolumeSize=%lx\n", + (UINT64)&(SecCoreData.BootFirmwareVolumeSize), + (UINT64)(SecCoreData.BootFirmwareVolumeSize) + )); + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL); + SecStartupPhase2 (&SecCoreData); +} + +/** + temporary memory to permanent memory and do stack switching. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Temporary Memory Base address. + @param[in] PermanentMemoryBase Permanent Memory Base address. + @param[in] CopySize The size of memory that needs to be migrated. + + @retval EFI_SUCCESS Migration successful. +**/ +STATIC +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + VOID *OldHeap; + VOID *NewHeap; + VOID *OldStack; + VOID *NewStack; + BASE_LIBRARY_JUMP_BUFFER JumpBuffer; + + DEBUG (( + DEBUG_INFO, + "TemporaryRamMigration (0x%Lx, 0x%Lx, 0x%Lx)\n", + TemporaryMemoryBase, + PermanentMemoryBase, + (UINT64)CopySize + )); + + OldHeap = (VOID *)(UINTN)TemporaryMemoryBase; + NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1)); + + OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1)); + NewStack = (VOID *)(UINTN)PermanentMemoryBase; + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize >> 1); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, CopySize >> 1); + + // Use SetJump ()/LongJump () to switch to a new stack. + // + if (SetJump (&JumpBuffer) == 0) { + JumpBuffer.SP = JumpBuffer.SP - (UINTN)OldStack + (UINTN)NewStack; + LongJump (&JumpBuffer, (UINTN)-1); + } + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/LoongArchVirt/Sec/SecMain.inf b/OvmfPkg/LoongArchVirt/Sec/SecMain.inf new file mode 100644 index 0000000000..afa0ff8fd1 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Sec/SecMain.inf @@ -0,0 +1,54 @@ +## @file +# SEC Driver +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = SecMain + FILE_GUID = 57d02d4f-5a5d-4bfa-b7d6-ba0a4d2c72ce + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + LoongArch64/Start.S + SecMain.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + CpuExceptionHandlerLib + DebugAgentLib + DebugLib + IoLib + PcdLib + PeCoffLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PeiServicesLib + +[Ppis] + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED + +[FixedPcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + gUefiCpuPkgTokenSpaceGuid.PcdLoongArchExceptionVectorBaseAddress + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber + + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress -- cgit From e5e2cf48a99295d58b7d01877c7f380c6fee50ae Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 14 Jun 2024 17:10:15 +0800 Subject: OvmfPkg/LoongArchVirt: Support PEI phase Platfrom PEI module for LoongArch platfrom initialization. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- OvmfPkg/LoongArchVirt/PlatformPei/Fv.c | 36 +++ OvmfPkg/LoongArchVirt/PlatformPei/MemDetect.c | 237 ++++++++++++++ OvmfPkg/LoongArchVirt/PlatformPei/Platform.c | 364 ++++++++++++++++++++++ OvmfPkg/LoongArchVirt/PlatformPei/Platform.h | 85 +++++ OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf | 67 ++++ 5 files changed, 789 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/PlatformPei/Fv.c create mode 100644 OvmfPkg/LoongArchVirt/PlatformPei/MemDetect.c create mode 100644 OvmfPkg/LoongArchVirt/PlatformPei/Platform.c create mode 100644 OvmfPkg/LoongArchVirt/PlatformPei/Platform.h create mode 100644 OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf diff --git a/OvmfPkg/LoongArchVirt/PlatformPei/Fv.c b/OvmfPkg/LoongArchVirt/PlatformPei/Fv.c new file mode 100644 index 0000000000..360ad9cad8 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/PlatformPei/Fv.c @@ -0,0 +1,36 @@ +/** @file + Build FV related hobs for platform. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +/** + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI + and DXE know about them. + + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. +**/ +EFI_STATUS +PeiFvInitialization ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "Platform PEI Firmware Volume Initialization\n")); + + // + // Create a memory allocation HOB for the PEI FV. + // + BuildMemoryAllocationHob ( + FixedPcdGet64 (PcdOvmfSecPeiTempRamBase), + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize), + EfiBootServicesData + ); + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/LoongArchVirt/PlatformPei/MemDetect.c b/OvmfPkg/LoongArchVirt/PlatformPei/MemDetect.c new file mode 100644 index 0000000000..b2f7c7edad --- /dev/null +++ b/OvmfPkg/LoongArchVirt/PlatformPei/MemDetect.c @@ -0,0 +1,237 @@ +/** @file + Memory Detection for Virtual Machines. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Platform.h" + +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS (128) +#define LOONGARCH_FW_RAM_TOP BASE_256MB + +/** + Publish PEI core memory + + @return EFI_SUCCESS The PEIM initialized successfully. +**/ +EFI_STATUS +PublishPeiMemory ( + VOID + ) +{ + EFI_STATUS Status; + UINT64 Base; + UINT64 Size; + UINT64 RamTop; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + UINTN Processed; + MEMMAP_ENTRY MemoryMapEntry; + + // + // Determine the range of memory to use during PEI + // + Base = FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize); + RamTop = 0; + + Status = QemuFwCfgFindFile ("etc/memmap", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + return Status; + } + + if (FwCfgSize % sizeof MemoryMapEntry != 0) { + return EFI_PROTOCOL_ERROR; + } + + QemuFwCfgSelectItem (FwCfgItem); + for (Processed = 0; Processed < FwCfgSize; Processed += sizeof MemoryMapEntry) { + QemuFwCfgReadBytes (sizeof MemoryMapEntry, &MemoryMapEntry); + if (MemoryMapEntry.Type != EfiAcpiAddressRangeMemory) { + continue; + } + + // + // Find memory map entry where PEI temp stack is located + // + if ((MemoryMapEntry.BaseAddr <= Base) && + (Base < (MemoryMapEntry.BaseAddr + MemoryMapEntry.Length))) + { + RamTop = MemoryMapEntry.BaseAddr + MemoryMapEntry.Length; + break; + } + } + + if (RamTop == 0) { + DEBUG ((DEBUG_ERROR, "ERROR: No memory map entry contains temp stack \n")); + ASSERT (FALSE); + } + + Size = RamTop - Base; + + // + // Publish this memory to the PEI Core + // + Status = PublishSystemMemory (Base, Size); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "Publish Memory Initialize done.\n")); + return Status; +} + +/** + Peform Memory Detection + Publish system RAM and reserve memory regions +**/ +VOID +InitializeRamRegions ( + VOID + ) +{ + EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + MEMMAP_ENTRY MemoryMapEntry; + MEMMAP_ENTRY *StartEntry; + MEMMAP_ENTRY *pEntry; + UINTN Processed; + + Status = QemuFwCfgFindFile ("etc/memmap", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/memmap error Status %d \n", __func__, __LINE__, Status)); + return; + } + + if (FwCfgSize % sizeof MemoryMapEntry != 0) { + DEBUG ((DEBUG_ERROR, "no MemoryMapEntry FwCfgSize:%d\n", FwCfgSize)); + return; + } + + QemuFwCfgSelectItem (FwCfgItem); + StartEntry = AllocatePages (EFI_SIZE_TO_PAGES (FwCfgSize)); + QemuFwCfgReadBytes (FwCfgSize, StartEntry); + for (Processed = 0; Processed < (FwCfgSize / sizeof MemoryMapEntry); Processed++) { + pEntry = StartEntry + Processed; + if (pEntry->Length == 0) { + continue; + } + + DEBUG ((DEBUG_INFO, "MemmapEntry Base %p length %p type %d\n", pEntry->BaseAddr, pEntry->Length, pEntry->Type)); + if (pEntry->Type != EfiAcpiAddressRangeMemory) { + continue; + } + + AddMemoryRangeHob (pEntry->BaseAddr, pEntry->BaseAddr + pEntry->Length); + } + + // + // When 0 address protection is enabled, + // 0-4k memory needs to be preallocated to prevent UEFI applications from allocating use, + // such as grub + // + if (PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) { + BuildMemoryAllocationHob ( + 0, + EFI_PAGE_SIZE, + EfiBootServicesData + ); + } +} + +/** + Gets the Virtual Memory Map of corresponding platforms. + + This Virtual Memory Map is used by initialize the MMU on corresponding + platforms. + + @param[out] MemoryTable Array of EFI_MEMORY_DESCRIPTOR + describing a Physical-to-Virtual Memory + mapping. This array must be ended by a + zero-filled entry. The allocated memory + will not be freed. +**/ +VOID +EFIAPI +GetMemoryMapPolicy ( + OUT EFI_MEMORY_DESCRIPTOR **MemoryTable + ) +{ + EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + MEMMAP_ENTRY MemoryMapEntry; + MEMMAP_ENTRY *StartEntry; + MEMMAP_ENTRY *pEntry; + UINTN Processed; + EFI_MEMORY_DESCRIPTOR *VirtualMemoryTable; + UINTN Index = 0; + + ASSERT (MemoryTable != NULL); + + VirtualMemoryTable = AllocatePool ( + sizeof (EFI_MEMORY_DESCRIPTOR) * + MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS + ); + + // + // Add the 0x10000000-0x20000000. In the virtual machine, this area use for CPU UART, flash, PIC etc. + // + VirtualMemoryTable[Index].PhysicalStart = BASE_256MB; + VirtualMemoryTable[Index].VirtualStart = VirtualMemoryTable[Index].PhysicalStart; + VirtualMemoryTable[Index].NumberOfPages = EFI_SIZE_TO_PAGES (SIZE_256MB); + VirtualMemoryTable[Index].Attribute = EFI_MEMORY_UC; + ++Index; + + Status = QemuFwCfgFindFile ("etc/memmap", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a %d read etc/memmap error Status %d \n", __func__, __LINE__, Status)); + ZeroMem (&VirtualMemoryTable[Index], sizeof (EFI_MEMORY_DESCRIPTOR)); + *MemoryTable = VirtualMemoryTable; + return; + } + + if (FwCfgSize % sizeof MemoryMapEntry != 0) { + DEBUG ((DEBUG_ERROR, "no MemoryMapEntry FwCfgSize:%d\n", FwCfgSize)); + } + + QemuFwCfgSelectItem (FwCfgItem); + StartEntry = AllocatePages (EFI_SIZE_TO_PAGES (FwCfgSize)); + QemuFwCfgReadBytes (FwCfgSize, StartEntry); + for (Processed = 0; Processed < (FwCfgSize / sizeof MemoryMapEntry); Processed++) { + pEntry = StartEntry + Processed; + if (pEntry->Length == 0) { + continue; + } + + DEBUG ((DEBUG_INFO, "MemmapEntry Base %p length %p type %d\n", pEntry->BaseAddr, pEntry->Length, pEntry->Type)); + VirtualMemoryTable[Index].PhysicalStart = pEntry->BaseAddr; + VirtualMemoryTable[Index].VirtualStart = VirtualMemoryTable[Index].PhysicalStart; + VirtualMemoryTable[Index].NumberOfPages = EFI_SIZE_TO_PAGES (pEntry->Length); + VirtualMemoryTable[Index].Attribute = EFI_MEMORY_WB; + ++Index; + } + + FreePages (StartEntry, EFI_SIZE_TO_PAGES (FwCfgSize)); + // End of Table + ZeroMem (&VirtualMemoryTable[Index], sizeof (EFI_MEMORY_DESCRIPTOR)); + *MemoryTable = VirtualMemoryTable; +} diff --git a/OvmfPkg/LoongArchVirt/PlatformPei/Platform.c b/OvmfPkg/LoongArchVirt/PlatformPei/Platform.c new file mode 100644 index 0000000000..cfc0cec41d --- /dev/null +++ b/OvmfPkg/LoongArchVirt/PlatformPei/Platform.c @@ -0,0 +1,364 @@ +/** @file + Platform PEI driver + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Mem - Memory +**/ + +// +// The package level header files this module uses +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" + +STATIC EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { + { EfiReservedMemoryType, 0x004 }, + { EfiRuntimeServicesData, 0x024 }, + { EfiRuntimeServicesCode, 0x030 }, + { EfiBootServicesCode, 0x180 }, + { EfiBootServicesData, 0xF00 }, + { EfiMaxMemoryType, 0x000 } +}; + +// +// Module globals +// +CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMasterBootModePpiGuid, + NULL +}; + +STATIC EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION; + +/** + Create system type memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +STATIC +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +/** + Create memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); +} + +STATIC +VOID +SaveRtcRegisterAddressHob ( + UINT64 RtcRegisterBase + ) +{ + UINT64 Data64; + + // + // Build location of RTC register base address buffer in HOB + // + Data64 = (UINT64)(UINTN)RtcRegisterBase; + + BuildGuidDataHob ( + &gRtcRegisterBaseAddressHobGuid, + (VOID *)&Data64, + sizeof (UINT64) + ); +} + +/** + Create memory type information hand off block. + + @param VOID + + @return VOID +**/ +STATIC +VOID +MemMapInitialization ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "==%a==\n", __func__)); + // + // Create Memory Type Information HOB + // + BuildGuidDataHob ( + &gEfiMemoryTypeInformationGuid, + mDefaultMemoryTypeInformation, + sizeof (mDefaultMemoryTypeInformation) + ); +} + +/** Get the Rtc base address from the DT. + + This function fetches the node referenced in the "loongson,ls7a-rtc" + property of the "reg" node and returns the base address of + the RTC. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [out] RtcBaseAddress If success, contains the base address + of the Rtc. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND RTC info not found in DT. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GetRtcAddress ( + IN CONST VOID *Fdt, + OUT UINT64 *RtcBaseAddress + ) +{ + INT32 Node; + INT32 Prev; + CONST CHAR8 *Type; + INT32 Len; + CONST UINT64 *RegProp; + EFI_STATUS Status; + + if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_NOT_FOUND; + for (Prev = 0; ; Prev = Node) { + Node = fdt_next_node (Fdt, Prev, NULL); + if (Node < 0) { + break; + } + + // + // Check for memory node + // + Type = fdt_getprop (Fdt, Node, "compatible", &Len); + if ((Type) && (AsciiStrnCmp (Type, "loongson,ls7a-rtc", Len) == 0)) { + // + // Get the 'reg' property of this node. For now, we will assume + // two 8 byte quantities for base and size, respectively. + // + RegProp = fdt_getprop (Fdt, Node, "reg", &Len); + if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) { + *RtcBaseAddress = SwapBytes64 (RegProp[0]); + Status = RETURN_SUCCESS; + DEBUG ((DEBUG_INFO, "%a Len %d RtcBase %llx\n", __func__, Len, *RtcBaseAddress)); + break; + } else { + DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT rtc node\n", __func__)); + break; + } + } + } + + return Status; +} + +/** + Misc Initialization. + + @param VOID + + @return VOID +**/ +STATIC +VOID +MiscInitialization ( + VOID + ) +{ + CPUCFG_REG1_INFO_DATA CpucfgReg1Data; + UINT8 CpuPhysMemAddressWidth; + + DEBUG ((DEBUG_INFO, "==%a==\n", __func__)); + + // + // Get the the CPU physical memory address width. + // + AsmCpucfg (CPUCFG_REG1_INFO, &CpucfgReg1Data.Uint32); + + CpuPhysMemAddressWidth = (UINT8)(CpucfgReg1Data.Bits.PALEN + 1); + + // + // Creat CPU HOBs. + // + BuildCpuHob (CpuPhysMemAddressWidth, FixedPcdGet8 (PcdPrePiCpuIoSize)); +} + +/** + add fdt hand off block. + + @param VOID + + @return VOID +**/ +STATIC +VOID +AddFdtHob ( + VOID + ) +{ + VOID *Base; + VOID *NewBase; + UINTN FdtSize; + UINTN FdtPages; + UINT64 *FdtHobData; + UINT64 RtcBaseAddress; + RETURN_STATUS Status; + + Base = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); + ASSERT (Base != NULL); + + Status = GetRtcAddress (Base, &RtcBaseAddress); + if (RETURN_ERROR (Status)) { + return; + } + + SaveRtcRegisterAddressHob (RtcBaseAddress); + + FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding); + FdtPages = EFI_SIZE_TO_PAGES (FdtSize); + NewBase = AllocatePages (FdtPages); + ASSERT (NewBase != NULL); + fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages)); + + FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData); + ASSERT (FdtHobData != NULL); + *FdtHobData = (UINTN)NewBase; +} + +/** + Fetch the size of system memory from QEMU. + + @param VOID + + @return VOID +**/ +STATIC +VOID +ReportSystemMemorySize ( + VOID + ) +{ + UINT64 RamSize; + + QemuFwCfgSelectItem (QemuFwCfgItemRamSize); + RamSize = QemuFwCfgRead64 (); + DEBUG (( + DEBUG_INFO, + "%a: QEMU reports %dM system memory\n", + __func__, + RamSize/1024/1024 + )); +} + +/** + Perform Platform PEI initialization. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @return EFI_SUCCESS The PEIM initialized successfully. +**/ +EFI_STATUS +EFIAPI +InitializePlatform ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_MEMORY_DESCRIPTOR *MemoryTable; + + DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n")); + + Status = PeiServicesSetBootMode (mBootMode); + ASSERT_EFI_ERROR (Status); + + Status = PeiServicesInstallPpi (&mPpiListBootMode); + ASSERT_EFI_ERROR (Status); + + ReportSystemMemorySize (); + + PublishPeiMemory (); + + PeiFvInitialization (); + InitializeRamRegions (); + MemMapInitialization (); + + Status = PlatformHookSerialPortInitialize (); + ASSERT_EFI_ERROR (Status); + + MiscInitialization (); + + AddFdtHob (); + + // + // Initialization MMU + // + GetMemoryMapPolicy (&MemoryTable); + Status = ConfigureMemoryManagementUnit (MemoryTable); + ASSERT_EFI_ERROR (Status); + + MpInitLibInitialize (); + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/LoongArchVirt/PlatformPei/Platform.h b/OvmfPkg/LoongArchVirt/PlatformPei/Platform.h new file mode 100644 index 0000000000..62456a5725 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/PlatformPei/Platform.h @@ -0,0 +1,85 @@ +/** @file + Platform PEI module include file. + + Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PLATFORM_H_ +#define PLATFORM_H_ + +#include + +typedef struct { + UINT64 BaseAddr; + UINT64 Length; + UINT32 Type; + UINT32 Reserved; +} MEMMAP_ENTRY; + +/** + Create memory range hand off block. + + @param MemoryBase memory base address. + @param MemoryLimit memory length. + + @return VOID +**/ +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ); + +/** + Publish PEI core memory + + @return EFI_SUCCESS The PEIM initialized successfully. +**/ +EFI_STATUS +PublishPeiMemory ( + VOID + ); + +/** + Publish system RAM and reserve memory regions + + @return VOID +**/ +VOID +InitializeRamRegions ( + VOID + ); + +/** + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI + and DXE know about them. + + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. +**/ +EFI_STATUS +PeiFvInitialization ( + VOID + ); + +/** + Gets the Virtual Memory Map of corresponding platforms. + + This Virtual Memory Map is used by initialize the MMU on corresponding + platforms. + + @param[out] MemoryTable Array of EFI_MEMORY_DESCRIPTOR + describing a Physical-to-Virtual Memory + mapping. This array must be ended by a + zero-filled entry. The allocated memory + will not be freed. +**/ +VOID +EFIAPI +GetMemoryMapPolicy ( + OUT EFI_MEMORY_DESCRIPTOR **MemoryTable + ); + +#endif // PLATFORM_H_ diff --git a/OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf b/OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf new file mode 100644 index 0000000000..c4f5affb15 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf @@ -0,0 +1,67 @@ +## @file +# Platform PEI driver +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = PlatformPei + FILE_GUID = 4c0e81e5-e8e3-4eef-b24b-19b686e9ab53 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = InitializePlatform + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources] + Fv.c + MemDetect.c + Platform.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[Ppis] + gEfiPeiMasterBootModePpiGuid + +[Guids] + gEfiMemoryTypeInformationGuid + gFdtHobGuid + gRtcRegisterBaseAddressHobGuid + +[LibraryClasses] + BaseMemoryLib + CpuMmuInitLib + DebugLib + HobLib + MemoryAllocationLib + MpInitLib + PcdLib + PeimEntryPoint + PeiServicesLib + PlatformHookLib + PeiResourcePublicationLib + QemuFwCfgLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeAllocationPadding + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask + +[FixedPcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + +[Depex] + TRUE -- cgit From d6dcf621df22d4433b2b61d57e3f9f66b52a390a Mon Sep 17 00:00:00 2001 From: Chao Li Date: Tue, 11 Jun 2024 18:14:31 +0800 Subject: OvmfPkg/LoongArchVirt: Add build file Add infrastructure files to build edk2 for LoongArch QEMU virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Co-authored-by: Xianglai Li Co-authored-by: Bibo Mao --- OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc | 34 ++ OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc | 684 ++++++++++++++++++++++++++++ OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf | 313 +++++++++++++ OvmfPkg/LoongArchVirt/VarStore.fdf.inc | 67 +++ 4 files changed, 1098 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc create mode 100644 OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc create mode 100644 OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf create mode 100644 OvmfPkg/LoongArchVirt/VarStore.fdf.inc diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc b/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc new file mode 100644 index 0000000000..22373bec6a --- /dev/null +++ b/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc @@ -0,0 +1,34 @@ +## @file +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +DEFINE BLOCK_SIZE = 0x1000 + +############################################################################ +# FW total +DEFINE FW_BASE_ADDRESS = 0x1c000000 +DEFINE FW_BLOCKS = 0x400 +DEFINE FW_SIZE = 0x400000 + +############################################################################ +#Flash code layout +#Set Sec size in flash +DEFINE SECFV_SIZE = 0x00010000 + +#Set Pei size in flash +DEFINE PEIFV_SIZE = 0x00040000 + +#Set Dxe size in flash +DEFINE DXEFV_SIZE = 0x00350000 + +#Set FVMAIN size +DEFINE FVMAIN_SIZE = $(SECFV_SIZE) + $(PEIFV_SIZE) +$(DXEFV_SIZE) + +#Set Memory layout +DEFINE SEC_PEI_TEMP_RAM_BASE = 0x10000 +DEFINE SEC_PEI_TEMP_RAM_SIZE = 0x80000 +DEFINE DEVICE_TREE_RAM_BASE = 0x100000 diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc new file mode 100644 index 0000000000..90be933cdc --- /dev/null +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc @@ -0,0 +1,684 @@ +## @file +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +############################################################################### +[Defines] + PLATFORM_NAME = LoongArchVirtQemu + PLATFORMPKG_NAME = LoongArchVirtQemu + PLATFORM_GUID = 7926ea52-b0dc-4ee8-ac63-341eebd84ed4 + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 1.29 + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES = LOONGARCH64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf + TTY_TERMINAL = FALSE + +!include LoongArchVirt.fdf.inc + + # + # Defines for default states. These can be changed on the command line. + # -D FLAG=VALUE + DEFINE TTY_TERMINAL = FALSE + DEFINE SECURE_BOOT_ENABLE = FALSE + DEFINE TPM2_ENABLE = FALSE + DEFINE TPM2_CONFIG_ENABLE = FALSE + + # + # Network definition + # + DEFINE NETWORK_IP6_ENABLE = FALSE + DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE + DEFINE NETWORK_SNP_ENABLE = FALSE + DEFINE NETWORK_TLS_ENABLE = FALSE + DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE + DEFINE NETWORK_ISCSI_ENABLE = FALSE + +!include NetworkPkg/NetworkDefines.dsc.inc +############################################################################ +# +# Defines for default states. These can be changed on the command line. +# -D FLAG=VALUE +############################################################################ +[BuildOptions] + GCC:RELEASE_*_*_CC_FLAGS = -DSPEEDUP + + # + # Disable deprecated APIs. + # + GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES + +!include NetworkPkg/NetworkBuildOptions.dsc.inc + +[BuildOptions.LOONGARCH64.EDKII.SEC] + *_*_*_CC_FLAGS = + +# +# Default page size is 16K for loongarch qemu tcg +# code section separated with data section with 16K page alignment, else data +# write operation in the same page with code section will cause qemu TB flush. +# +[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION] + GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x4000 + +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] + GCC:*_*_LOONGARCH64_DLINK_FLAGS = -z common-page-size=0x10000 + +################################################################################ +# +# SKU Identification section - list of all SKU IDs supported by this Platform. +# +################################################################################ +[SkuIds] + 0|DEFAULT + +################################################################################ +# +# Library Class section - list of all Library Classes needed by this Platform. +# +################################################################################ + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses.common] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + TimerLib | UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf + PrintLib | MdePkg/Library/BasePrintLib/BasePrintLib.inf + BaseMemoryLib | MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + + # Networking Requirements +!include NetworkPkg/NetworkLibs.dsc.inc +!if $(NETWORK_TLS_ENABLE) == TRUE + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf +!endif + + # For stack protector support + NULL | MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + + BaseLib | MdePkg/Library/BaseLib/BaseLib.inf + SafeIntLib | MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + TimeBaseLib | EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf + BmpSupportLib | MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + SynchronizationLib | MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + CpuLib | MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + PerformanceLib | MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + PeCoffLib | MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + CacheMaintenanceLib | MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + UefiDecompressLib | MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + UefiHiiServicesLib | MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib | MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + CapsuleLib | MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + DxeServicesLib | MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib | MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PciLib | MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf + PciExpressLib | OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf + PciCapLib | OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf + PciCapPciSegmentLib | OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf + PciCapPciIoLib | OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf + DxeHardwareInfoLib | OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf + IoLib | MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + FdtSerialPortAddressLib | OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf + PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf + SerialPortLib | MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf + ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf + + UefiLib | MdePkg/Library/UefiLib/UefiLib.inf + UefiBootServicesTableLib | MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib | MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiDriverEntryPoint | MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint | MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + DevicePathLib | MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf + FileHandleLib | MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SecurityManagementLib | MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + UefiUsbLib | MdePkg/Library/UefiUsbLib/UefiUsbLib.inf + SerializeVariablesLib | OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf + CustomizedDisplayLib | MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + DebugPrintErrorLevelLib | MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + TpmMeasurementLib | MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + AuthVariableLib | MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf + VarCheckLib | MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib | MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + VariablePolicyHelperLib | MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + SortLib | MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + FdtLib | EmbeddedPkg/Library/FdtLib/FdtLib.inf + PciSegmentLib | MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf + PciHostBridgeLib | OvmfPkg/Fdt/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf + PciHostBridgeUtilityLib | OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf + FileExplorerLib | MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + ImagePropertiesRecordLib | MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf + +!if $(HTTP_BOOT_ENABLE) == TRUE + HttpLib | MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf +!endif + UefiBootManagerLib | MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + OrderedCollectionLib | MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + ReportStatusCodeLib | MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffExtraActionLib | MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + DebugAgentLib | MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + + TpmPlatformHierarchyLib | SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLibNull/PeiDxeTpmPlatformHierarchyLib.inf + PlatformBmPrintScLib | OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf + PlatformBootManagerLib | OvmfPkg/Library/PlatformBootManagerLibLight/PlatformBootManagerLib.inf + BootLogoLib | MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf + QemuBootOrderLib | OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf + QemuFwCfgSimpleParserLib | OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf + QemuLoadImageLib | OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf + + # + # Virtio Support + # + VirtioLib | OvmfPkg/Library/VirtioLib/VirtioLib.inf + FrameBufferBltLib | MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf + DebugLib | MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + PeiServicesLib | MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + VariableFlashInfoLib | MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf + VirtNorFlashPlatformLib | OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf + +[LibraryClasses.common.SEC] + PcdLib | MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + ReportStatusCodeLib | MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PeiServicesTablePointerLib | MdePkg/Library/PeiServicesTablePointerLibKs0/PeiServicesTablePointerLibKs0.inf + PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf + SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf + CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf + +[LibraryClasses.common.PEI_CORE] + PcdLib | MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib | MdePkg/Library/PeiServicesTablePointerLibKs0/PeiServicesTablePointerLibKs0.inf + MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PeiCoreEntryPoint | MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf + ReportStatusCodeLib | MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + OemHookStatusCodeLib | MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioPeiLib.inf + PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf + SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf + +[LibraryClasses.common.PEIM] + HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib | MdePkg/Library/PeiServicesTablePointerLibKs0/PeiServicesTablePointerLibKs0.inf + MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PeimEntryPoint | MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + ReportStatusCodeLib | MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + OemHookStatusCodeLib | MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeiResourcePublicationLib | MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf + ExtractGuidedSectionLib | MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + PcdLib | MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioPeiLib.inf + CpuMmuLib | UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.inf + CpuMmuInitLib | OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf + MpInitLib | UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf + PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf + SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf + +[LibraryClasses.common.DXE_CORE] + HobLib | MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + MemoryAllocationLib | MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | MdePkg/Library/DxeHobLib/DxeHobLib.inf + DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf + UefiRuntimeLib | MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + ExtractGuidedSectionLib | MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + RealTimeClockLib | OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf + VariablePolicyLib | MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf + EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf + ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf +!if $(TARGET) != RELEASE + DebugLib | MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf +!endif + +[LibraryClasses.common.UEFI_DRIVER] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | MdePkg/Library/DxeHobLib/DxeHobLib.inf + DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + UefiScsiLib | MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + ExtractGuidedSectionLib | MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + +[LibraryClasses.common.DXE_DRIVER] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + UefiScsiLib | MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf + ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf + AcpiPlatformLib | OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf + MpInitLib | UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf + HobLib | MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform. +# +################################################################################ +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport | FALSE +# gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial | TRUE +# gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory | TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress | TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport | TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport | FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport | FALSE + gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation | TRUE + gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation | TRUE +[PcdsFixedAtBuild] +## BaseLib ## + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength | 1000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength | 1000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength | 1000000 + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout | 10000000 + + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress | $(FW_BASE_ADDRESS) + + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize | 1 + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange | FALSE + gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler | 0x10 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize | 0x2000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize | 0x8000 + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress | 0x0 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask | 0x07 + + # Use MMIO for accessing Serial port registers. + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio | TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo | {0xFF} + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate | 115200 + + # DEBUG_INIT 0x00000001 // Initialization + # DEBUG_WARN 0x00000002 // Warnings + # DEBUG_LOAD 0x00000004 // Load events + # DEBUG_FS 0x00000008 // EFI File system + # DEBUG_POOL 0x00000010 // Alloc & Free (pool) + # DEBUG_PAGE 0x00000020 // Alloc & Free (page) + # DEBUG_INFO 0x00000040 // Informational debug messages + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers + # DEBUG_VARIABLE 0x00000100 // Variable + # DEBUG_BM 0x00000400 // Boot Manager + # DEBUG_BLKIO 0x00001000 // BlkIo Driver + # DEBUG_NET 0x00004000 // Network Io Driver + # DEBUG_UNDI 0x00010000 // UNDI Driver + # DEBUG_LOADFILE 0x00020000 // LoadFile + # DEBUG_EVENT 0x00080000 // Event messages + # DEBUG_GCD 0x00100000 // Global Coherency Database changes + # DEBUG_CACHE 0x00200000 // Memory range cachability changes + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may + # DEBUG_ERROR 0x80000000 // Error + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0x8000004F + + # DEBUG_ASSERT_ENABLED 0x01 + # DEBUG_PRINT_ENABLED 0x02 + # DEBUG_CODE_ENABLED 0x04 + # CLEAR_MEMORY_ENABLED 0x08 + # ASSERT_BREAKPOINT_ENABLED 0x10 + # ASSERT_DEADLOOP_ENABLED 0x20 +!if $(TARGET) == RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x21 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x2f +!endif + +####################################################################################### + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase | $(SEC_PEI_TEMP_RAM_BASE) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize | $(SEC_PEI_TEMP_RAM_SIZE) + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress | $(DEVICE_TREE_RAM_BASE) + + gUefiCpuPkgTokenSpaceGuid.PcdLoongArchExceptionVectorBaseAddress | gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + + # + # minimal memory for uefi bios should be 512M + # 0x00000000 - 0x10000000 + # 0x90000000 - 0xA0000000 + # + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions | 0x06 + + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile | { 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + + # + # Network Pcds + # +!include NetworkPkg/NetworkPcds.dsc.inc + + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask | 1 + +################################################################################ +# +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ +[PcdsDynamicDefault] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved | 0 + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration | FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution | 800 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution | 600 + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut | 3 + + # Set video resolution for text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution | 640 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution | 480 + + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion | 0x0300 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev | 0x0 + + ## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI + # enumeration to complete before installing ACPI tables. + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration |TRUE + gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation |0x0 + # set PcdPciExpressBaseAddress to MAX_UINT64, which signifies that this + # PCD and PcdPciDisableBusEnumeration above have not been assigned yet + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress |0xFFFFFFFFFFFFFFFF + + # + # IPv4 and IPv6 PXE Boot support. + # + gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport | 0x01 + gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport | 0x01 + + # + # SMBIOS entry point version + # + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0300 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 + gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|TRUE + +[PcdsDynamicHii] + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|3 + +[PcdsPatchableInModule.common] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0 + +[Components] + + # + # SEC Phase modules + # + OvmfPkg/LoongArchVirt/Sec/SecMain.inf + + # + # PEI Phase modules + # + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { + + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + } + + OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } + + # + # DXE Phase modules + # + MdeModulePkg/Core/Dxe/DxeMain.inf { + + NULL | MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + DevicePathLib | MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + } + + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + UefiCpuPkg/CpuDxe/CpuDxe.inf { + + CpuMmuLib | UefiCpuPkg/Library/CpuMmuLib/CpuMmuLib.inf + } + MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf + OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/TimerDxe.inf + MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf + MdeModulePkg/Universal/Metronome/Metronome.inf + EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf + + # + # Variable + # + OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf { + + NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf + } + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + } + + # + # Platform Driver + # + OvmfPkg/VirtioBlkDxe/VirtioBlk.inf + OvmfPkg/VirtioScsiDxe/VirtioScsi.inf + OvmfPkg/VirtioRngDxe/VirtioRng.inf + + # + # FAT filesystem + GPT/MBR partitioning + UDF filesystem + virtio-fs + # + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf + + # + #BDS + # + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf { + + DevicePathLib | MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + PcdLib | MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + MdeModulePkg/Logo/LogoDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf + NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf + NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf + } + + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf { + + NULL|OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierLibNull.inf + } + + # + # Network Support + # +#!include NetworkPkg/NetworkComponents.dsc.inc + +# NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf { +# +# NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf +# } + +!if $(NETWORK_TLS_ENABLE) == TRUE + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { + + NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf + } +!endif + OvmfPkg/VirtioNetDxe/VirtioNet.inf + + # + # IDE/SCSI + # + MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + + # + # NVME Driver + # + MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + + # + # SMBIOS Support + # + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf { + + NULL | OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf + } + OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + + # + # PCI + # + UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf + } + EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf + } + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf + } + OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf + OvmfPkg/Virtio10Dxe/Virtio10.inf + + # + # Console + # + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/PrintDxe/PrintDxe.inf + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf { + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + + # + # Video + # + OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf + OvmfPkg/VirtioGpuDxe/VirtioGpu.inf + OvmfPkg/PlatformDxe/Platform.inf + + # + # Usb Support + # + MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf + MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + + # + # ACPI Support + # + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf { + + NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf + } + + # + #app + # + ShellPkg/Application/Shell/Shell.inf { + + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 + } diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf new file mode 100644 index 0000000000..ca28e6e888 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf @@ -0,0 +1,313 @@ +## @file +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##################################################################################################### +[Defines] +!include LoongArchVirt.fdf.inc + +##################################################################################################### +[FD.QEMU_EFI] +BaseAddress = $(FW_BASE_ADDRESS)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress +Size = $(FW_SIZE)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize +ErasePolarity = 1 +BlockSize = $(BLOCK_SIZE) +NumBlocks = $(FW_BLOCKS) + +0x0|$(FVMAIN_SIZE) +FV = FVMAIN_COMPACT + +!include VarStore.fdf.inc + +##################################################################################################### +[FV.DXEFV] +FvNameGuid = 5d19a5b3-130f-459b-a292-9270a9e6bc62 +BlockSize = $(BLOCK_SIZE) +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE + +APRIORI DXE { + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +} + +# +# DXE Phase modules +# +INF MdeModulePkg/Core/Dxe/DxeMain.inf + +INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf +INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF UefiCpuPkg/CpuDxe/CpuDxe.inf +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +INF OvmfPkg/LoongArchVirt/Drivers/StableTimerDxe/TimerDxe.inf +INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf +INF MdeModulePkg/Universal/Metronome/Metronome.inf +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf +INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf +INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + +# +# Variable +# +INF OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +# +# PCI +# +INF UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf +INF EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf +INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf +INF OvmfPkg/Virtio10Dxe/Virtio10.inf + +# +# Platform Driver +# +INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf +INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf +INF OvmfPkg/VirtioRngDxe/VirtioRng.inf +INF OvmfPkg/VirtioNetDxe/VirtioNet.inf + +# +# Console +# +INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf +INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf +INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + +# +#Video +# +INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf +INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf +INF OvmfPkg/PlatformDxe/Platform.inf + +# +# SATA/SCSI +# +INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + +# +# NVME +# +INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + +# +# Usb Support +# +INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf +INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf +INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf +INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf +INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + +# +#BDS +# +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf +INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +INF MdeModulePkg/Logo/LogoDxe.inf +INF MdeModulePkg/Application/UiApp/UiApp.inf +INF OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf + +# +#Smbios +# +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf +INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + +# +#Acpi +# +INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf +INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf +INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf + +# +# Network modules +#!include NetworkPkg/Network.fdf.inc + +# +# File system +# +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf +INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf + +# +#Boot OS +# +INF ShellPkg/Application/Shell/Shell.inf + +##################################################################################################### +[FV.FVMAIN_COMPACT] +FvNameGuid = af8c3fe8-9ce8-4548-884a-e3f4dd91f040 +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +# +# +# PEI Phase priori modules +# +APRIORI PEI { + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +} + +# +# SEC Phase modules +# +INF OvmfPkg/LoongArchVirt/Sec/SecMain.inf + +# +# PEI Phase modules +# +INF MdeModulePkg/Core/Pei/PeiMain.inf +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +INF OvmfPkg/LoongArchVirt/PlatformPei/PlatformPei.inf +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + +# +# DXE Phase modules +# +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { + SECTION FV_IMAGE = DXEFV + } + } + +##################################################################################################### +[Rule.Common.SEC] + FILE SEC = $(NAMED_GUID) { + TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.PEI_CORE] + FILE PEI_CORE = $(NAMED_GUID) { + TE TE Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.PEIM] + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.DXE_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +##################################################################################################### +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.UEFI_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +##################################################################################################### +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +##################################################################################################### +[Rule.Common.UEFI_APPLICATION.BINARY] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +##################################################################################################### +[Rule.Common.USER_DEFINED.ACPITABLE] + FILE FREEFORM = $(NAMED_GUID) { + RAW ACPI |.acpi + RAW ASL |.aml + } diff --git a/OvmfPkg/LoongArchVirt/VarStore.fdf.inc b/OvmfPkg/LoongArchVirt/VarStore.fdf.inc new file mode 100644 index 0000000000..1e0ae468e5 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/VarStore.fdf.inc @@ -0,0 +1,67 @@ +## @file +# +# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[FD.QEMU_VARS] +BaseAddress = 0x0 +Size = 0x1000000 +ErasePolarity = 1 +BlockSize = 0x40000 +NumBlocks = 64 + +0x00000000|0x00040000 +#NV_VARIABLE_STORE +DATA = { + ## This is the EFI_FIRMWARE_VOLUME_HEADER + # ZeroVector [] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # FileSystemGuid: gEfiSystemNvDataFvGuid = + # { 0xFFF12B8D, 0x7696, 0x4C8B, + # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # FvLength: 0xC0000 + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, + # Signature "_FVH" # Attributes + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, + # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision + 0x48, 0x00, 0x28, 0x09, 0x00, 0x00, 0x00, 0x02, + # Blockmap[0]: 0x3 Blocks * 0x40000 Bytes / Block + 0x3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + # Blockmap[1]: End + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ## This is the VARIABLE_STORE_HEADER + # It is compatible with SECURE_BOOT_ENABLE == FALSE as well. + # Signature: gEfiAuthenticatedVariableGuid = + # { 0xaaf32c78, 0x947b, 0x439a, + # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }} + 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43, + 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92, + # Size: 0x40000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - + # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3ffb8 + # This can speed up the Variable Dispatch a bit. + 0xB8, 0xFF, 0x03, 0x00, + # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x00040000|0x00040000 +#NV_FTW_WORKING +DATA = { + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid = + # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }} + 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49, + 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95, + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved + 0x5b, 0xe7, 0xc6, 0x86, 0xFE, 0xFF, 0xFF, 0xFF, + # WriteQueueSize: UINT64 + 0xE0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x00080000|0x00040000 +#NV_FTW_SPARE -- cgit From c2d6efaef952d2513e7066020235f8bd1baefecc Mon Sep 17 00:00:00 2001 From: Chao Li Date: Sat, 4 Nov 2023 14:19:43 +0800 Subject: OvmfPkg/LoongArchVirt: Add self introduction file Add self introduction file for LoongArch virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Dongyan Qian Signed-off-by: Chao Li Reviewed-by: Bibo Mao --- OvmfPkg/LoongArchVirt/Readme.md | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Readme.md diff --git a/OvmfPkg/LoongArchVirt/Readme.md b/OvmfPkg/LoongArchVirt/Readme.md new file mode 100644 index 0000000000..5e409d5070 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Readme.md @@ -0,0 +1,69 @@ +# LoongArch QEMU virt platform + +## Overview + + LoongArch QEMU virt is a generic platform that does not require any actual hardware. + The minimum required QEMU version is [8.1](https://gitlab.com/qemu-project/qemu/-/tags), the minimum required GCC version is [GCC13](https://gcc.gnu.org/gcc-13/), the minimum required Binutils version is [2.40](https://ftp.gnu.org/gnu/binutils/). + +## Prepare (X86 Linux Environment) + +### Fedora39 and higher +Install LoongArch64 cross compiler, LoongArch system QEMU. + + yum install gcc-loongarch64-linux-gnu + yum install qemu-system-loongarch64 + +### Others X86 OS ENV +#### Configure cross-tools + +**Download:** + + wget https://github.com/loongson/build-tools/releases/download/2023.08.08/x86_64-cross-tools-loongarch64-binutils_2.41-gcc_13.2.0.tar.xz + +**Configure the cross-tools environment:** + + mkdir /opt/loongarch64_cross-toolchain/ + tar -vxf x86_64-cross-tools-loongarch64-binutils_2.41-gcc_13.2.0.tar.xz -C /opt/loongarch64_cross-toolchain/ + export PATH=/opt/loongarch64_cross-toolchain/cross-tools/bin:$PATH + +Note: Please obtain [the latest cross-compilation](https://github.com/loongson/build-tools) toolchains. + +#### Build QEMU + + git clone https://gitlab.com/qemu-project/qemu.git + +Note: Please refer to QEMU compilation rules, located in qemu/doc/system/loongarch/virt.rst. + + +## Build LoongArch QEMU virtual machine firmware +#### Get edk2 resouces + + git clone --recurse-submodule https://github.com/tianocore/edk2.git + +#### Building LoongArch QEMU virt FW with GCC + + export WORKSPACE=`pwd` + export GCC5_LOONGARCH64_PREFIX=loongarch64-unknown-linux-gnu- + export PACKAGES_PATH=$WORKSPACE/edk2 + export EDK_TOOLS_PATH=$WORKSPACE/edk2/BaseTools + source edk2/edksetup.sh --reconfig + make -C edk2/BaseTools + source edk2/edksetup.sh BaseTools + build -b RELEASE -t GCC5 -a LOONGARCH64 -p OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc + +## Test LoongArch QEMU virtual machine firmware + qemu-system-loongarch64 \ + -m 4G \ + -M virt \ + -smp 2 \ + -cpu la464 \ + -bios Build/LoongArchVirtQemu/RELEASE_GCC5/FV/QEMU_EFI.fd \ + -serial stdio + +## Test LoongArch QEMU virtual machine OS + +* Download ArchLinux QCOW [images](https://mirrors.pku.edu.cn/loongarch/archlinux/images) for LoongArch. + +* [Running LoongArch ArchLinux on virtual machine](https://mirrors.pku.edu.cn/loongarch/archlinux/images/README.html). + +* Download openEuler 22.03 LTS QCOW [images](https://mirrors.nju.edu.cn/openeuler/openEuler-22.03-LTS/virtual_machine_img/loongarch64/openEuler-22.03-LTS-LoongArch-loongarch64.qcow2.xz) for LoongArch. -- cgit From 7a1739d896cb9b7665fac0a12e7021993e960bdb Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 6 Jun 2024 17:08:25 +0800 Subject: OvmfPkg/PlatformCI: Add CI coverage for LoongArchVirtQemu Add support for building LoongArchVirtQemu platform in CI BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Chao Li --- OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml | 9 +++++++++ OvmfPkg/PlatformCI/QemuBuild.py | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml index 5809152d26..6762c2cc3a 100644 --- a/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml +++ b/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml @@ -186,6 +186,15 @@ jobs: Run.Flags: "QEMU_SKIP=TRUE" Run: $(should_run) + QEMU_LOONGARCH64_DEBUG: + Build.File: "$(package)/PlatformCI/QemuBuild.py" + Build.Arch: "LOONGARCH64" + Build.Flags: "" + Build.Target: "DEBUG" + # this build is for LOONGARCH qemu virt not qemu-kvm + Run.Flags: "QEMU_SKIP=TRUE" + Run: $(should_run) + workspace: clean: all diff --git a/OvmfPkg/PlatformCI/QemuBuild.py b/OvmfPkg/PlatformCI/QemuBuild.py index c737d98d51..e80e0cbbd8 100644 --- a/OvmfPkg/PlatformCI/QemuBuild.py +++ b/OvmfPkg/PlatformCI/QemuBuild.py @@ -19,7 +19,7 @@ class CommonPlatform(): for the different parts of stuart ''' PackagesSupported = ("OvmfPkg",) - ArchSupported = ("RISCV64",) + ArchSupported = ("RISCV64","LOONGARCH64") TargetsSupported = ("DEBUG", "RELEASE", "NOOPT") Scopes = ('ovmf', 'edk2-build') WorkspaceRoot = os.path.realpath(os.path.join( @@ -31,7 +31,11 @@ class CommonPlatform(): ArchCsv: csv string containing all architectures to build ''' - return "RiscVVirt/RiscVVirtQemu.dsc" + if "RISCV64" in ArchCsv.upper().split(","): + dsc = "RiscVVirt/RiscVVirtQemu.dsc" + if "LOONGARCH64" in ArchCsv.upper().split(","): + dsc = "LoongArchVirt/LoongArchVirtQemu.dsc" + return dsc import PlatformBuildLib PlatformBuildLib.CommonPlatform = CommonPlatform -- cgit From bfda27ddc89502190c79f74fc20cb81458d58449 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 6 Jun 2024 10:48:09 +0800 Subject: Maintainers.txt: Update maintainers and reviewers for OvmfPkg/LoongArchVirt Update Maintainers.txt to add Chao Li and Bibo Mao as LoongArchVirt Qemu virt-machine platform maintainers, add Xianglai Li as the reviewer. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Michael D Kinney Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Bibo Mao Cc: Xianglai Li Signed-off-by: Chao Li --- Maintainers.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Maintainers.txt b/Maintainers.txt index 6f91c218b4..d22929b85b 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -580,6 +580,12 @@ F: OvmfPkg/RiscVVirt M: Sunil V L [vlsunil] R: Andrei Warkentin [andreiw] +OvmfPkg: LOONGARCH Qemu Virt Platform +F: OvmfPkg/LoongArchVirt +M: Chao Li [kilaterlee] +M: Bibo Mao [bibo-mao] +R: Xianglai Li [lixianglai] + PcAtChipsetPkg F: PcAtChipsetPkg/ W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg -- cgit From ffce430d2b65d508a1604dc986ba16db3583943d Mon Sep 17 00:00:00 2001 From: Corvin Köhne Date: Mon, 16 Aug 2021 15:54:38 +0200 Subject: OvmfPkg/BhyvePkg: honor FwCfg when setting the bootorder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bhyve has added support for the bootorder FwCfg file some time ago [1][2]. This FwCfg file is currently ignored by the OVMF and has no effect. Copy the relevant code from Qemu to Bhyve to make it usable. [1] https://github.com/freebsd/freebsd-src/commit/6632a0a4e3ab68b0e31b612e8aeca14de3fc8159 [2] https://github.com/freebsd/freebsd-src/commit/480bef9481f0c44b19ac4b2adb09f6c3191acd41 Signed-off-by: Corvin Köhne --- OvmfPkg/Bhyve/BhyveX64.dsc | 1 + .../Library/PlatformBootManagerLibBhyve/BdsPlatform.c | 17 +++++++++++------ .../PlatformBootManagerLibBhyve.inf | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc index 78050959f8..0689d6442f 100644 --- a/OvmfPkg/Bhyve/BhyveX64.dsc +++ b/OvmfPkg/Bhyve/BhyveX64.dsc @@ -358,6 +358,7 @@ !endif PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf + QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c index ac9c02cb1c..4489eaae0b 100644 --- a/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c @@ -1433,7 +1433,8 @@ PlatformBdsConnectSequence ( VOID ) { - UINTN Index; + UINTN Index; + RETURN_STATUS Status; DEBUG ((DEBUG_INFO, "PlatformBdsConnectSequence\n")); @@ -1452,11 +1453,14 @@ PlatformBdsConnectSequence ( Index++; } - // - // Just use the simple policy to connect all devices - // - DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n")); - EfiBootManagerConnectAll (); + Status = ConnectDevicesFromQemu (); + if (RETURN_ERROR (Status)) { + // + // Just use the simple policy to connect all devices + // + DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n")); + EfiBootManagerConnectAll (); + } } /** @@ -1581,6 +1585,7 @@ PlatformBootManagerAfterConsole ( ); RemoveStaleFvFileOptions (); + SetBootOrderFromQemu (); PlatformBmPrintScRegisterHandler (); } diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf b/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf index c1fb5119ef..abfe4f97e4 100644 --- a/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf +++ b/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf @@ -46,6 +46,7 @@ BootLogoLib DevicePathLib PciLib + QemuBootOrderLib NvVarsFileLib ReportStatusCodeLib UefiLib -- cgit From c1d1910be6e04a8b1a73090cf2881fb698947a6e Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 17 Jun 2024 17:07:41 +0200 Subject: OvmfPkg/QemuVideoDxe: add feature PCD to remap framebuffer W/C Some platforms (such as SBSA-QEMU on recent builds of the emulator) only tolerate misaligned accesses to normal memory, and raise alignment faults on such accesses to device memory, which is the default for PCIe MMIO BARs. When emulating a PCIe graphics controller, the framebuffer is typically exposed via a MMIO BAR, while the disposition of the region is closer to memory (no side effects on reads or writes, except for the changing picture on the screen; direct random access to any pixel in the image). In order to permit the use of such controllers on platforms that only tolerate these types of accesses for normal memory, it is necessary to remap the memory. Use the DXE services to set the desired capabilities and attributes. Hide this behavior under a feature PCD so only platforms that really need it can enable it. (OVMF on x86 has no need for this) Signed-off-by: Ard Biesheuvel --- OvmfPkg/OvmfPkg.dec | 5 +++++ OvmfPkg/QemuVideoDxe/Gop.c | 19 +++++++++++++++++++ OvmfPkg/QemuVideoDxe/Qemu.h | 2 +- OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 4 ++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index e1ef8420ce..c1c8198061 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -449,3 +449,8 @@ ## This feature flag indicates the firmware build supports secure boot. gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootSupported|FALSE|BOOLEAN|0x6d + + ## Whether QemuVideoDxe should perform a EFI_MEMORY_WC remap of the PCI + # framebuffer. This might be required on platforms that do not tolerate + # misaligned accesses otherwise. + gUefiOvmfPkgTokenSpaceGuid.PcdRemapFrameBufferWriteCombine|FALSE|BOOLEAN|0x75 diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index b11eed7558..a29c025afd 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -9,6 +9,8 @@ #include "Qemu.h" +#include + STATIC VOID QemuVideoCompleteModeInfo ( @@ -54,6 +56,7 @@ QemuVideoCompleteModeData ( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc; QEMU_VIDEO_MODE_DATA *ModeData; + EFI_STATUS Status; ModeData = &Private->ModeData[Mode->Mode]; Info = Mode->Info; @@ -79,6 +82,22 @@ QemuVideoCompleteModeData ( (UINT64)Mode->FrameBufferSize )); + if (FeaturePcdGet (PcdRemapFrameBufferWriteCombine)) { + Status = gDS->SetMemorySpaceCapabilities ( + FrameBufDesc->AddrRangeMin, + FrameBufDesc->AddrLen, + EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_XP + ); + ASSERT_EFI_ERROR (Status); + + Status = gDS->SetMemorySpaceAttributes ( + FrameBufDesc->AddrRangeMin, + FrameBufDesc->AddrLen, + EFI_MEMORY_WC | EFI_MEMORY_XP + ); + ASSERT_EFI_ERROR (Status); + } + FreePool (FrameBufDesc); return EFI_SUCCESS; } diff --git a/OvmfPkg/QemuVideoDxe/Qemu.h b/OvmfPkg/QemuVideoDxe/Qemu.h index bd6198dd50..3a190ae0b1 100644 --- a/OvmfPkg/QemuVideoDxe/Qemu.h +++ b/OvmfPkg/QemuVideoDxe/Qemu.h @@ -13,7 +13,7 @@ #ifndef _QEMU_H_ #define _QEMU_H_ -#include +#include #include #include #include diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf index 6b7baa8525..4f11365423 100644 --- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf @@ -40,6 +40,7 @@ [LibraryClasses] BaseMemoryLib + DxeServicesTableLib FrameBufferBltLib DebugLib DevicePathLib @@ -57,6 +58,9 @@ gEfiDevicePathProtocolGuid # PROTOCOL BY_START gEfiPciIoProtocolGuid # PROTOCOL TO_START +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdRemapFrameBufferWriteCombine + [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource -- cgit From 26a30abdd0f7fe5a9d2421cba6efe9397185ad98 Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Tue, 18 Jun 2024 16:41:53 +0700 Subject: MdeModulePkg/DxeCapsuleLibFmp: Fix compilation error The commit "MdeModulePkg/DxeCapsuleLibFmp: Fix crash if no ESRT is found" leads to a compilation error in MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf. The issue occurs because the variable mDxeCapsuleLibReadyToBootEvent which is declared as extern does not exist, while it is defined in DxeCapsuleRuntime.c, a file not included in DxeCapsuleLib.inf. This patch is to fix this by moving the variable defintion to DxeCapsuleLib.c and declare it as extern in DxeCapsuleRuntime.c. Reported-by: Gua Guo Signed-off-by: Nhi Pham --- MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c | 2 +- MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c index 36efd64c4c..8befbae1de 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c @@ -49,7 +49,7 @@ EFI_EVENT mDxeCapsuleLibEndOfDxeEvent = NULL; EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL *mFmpProgress = NULL; -extern BOOLEAN mDxeCapsuleLibReadyToBootEvent; +BOOLEAN mDxeCapsuleLibReadyToBootEvent = FALSE; /** Initialize capsule related variables. diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c index efff714d01..855b7a60fc 100644 --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c @@ -24,7 +24,7 @@ extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable; EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL; EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL; -BOOLEAN mDxeCapsuleLibReadyToBootEvent = FALSE; +extern BOOLEAN mDxeCapsuleLibReadyToBootEvent; /** Convert EsrtTable physical address to virtual address. -- cgit From 4d4f56992460c039d0cfe48c394c2e07aecf1d22 Mon Sep 17 00:00:00 2001 From: Dhaval Date: Tue, 18 Jun 2024 21:19:05 +0530 Subject: MdeModulePkg: Avoid efi memory allocation for SP memory HBM/CXL memory systems are treated as special purpose memories. In many cases it is desirable not to use special purpose memory for regular edk2 usages as these memories (HBm/CXL) are either meant for special purposes or are less reliable to be used. Until such memory systems evolve and we have better clarity from UEFI spec, avoid using them for edk2 boot memory purposes. Cc: Liming Gao Cc: Michael Kinney Cc: Oliver Smith-Denny Signed-off-by: Dhaval Sharma Co-authored-by: Tim Wawrzynczak --- MdeModulePkg/Core/Dxe/Mem/Page.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 5a51d9df1a..e4daa741b9 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -1183,6 +1183,13 @@ CoreFindFreePagesI ( continue; } + // + // Don't allocate out of Special-Purpose memory. + // + if ((Entry->Attribute & EFI_MEMORY_SP) != 0) { + continue; + } + DescStart = Entry->Start; DescEnd = Entry->End; -- cgit From e76be772aae59d3d58a92ac441e524a1a5c8952b Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 19 Jun 2024 17:17:38 +0200 Subject: ArmPkg/ArmLib ArmMmuLib: Drop support for EL3/MON execution Drop logic from the ARM architectural support libraries that can only execute in EL3 on AArch64 or Monitor mode on 32-bit ARM. While early 32-bit ports (and even some early 64-bit code) included some monitor logic in EDK2, UEFI per the spec runs in non-secure execution contexts only, and secure monitor and other secure world duties are usually delegated to TF-A (Trusted Firmware for the A profile). Since there are no longer users of this code in EDK2 or the edk2-platforms tree, let's remove it from the core support libraries. Signed-off-by: Ard Biesheuvel --- ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S | 9 +- ArmPkg/Include/AsmMacroIoLibV8.h | 11 --- .../ArmExceptionLib/AArch64/ExceptionSupport.S | 13 +-- ArmPkg/Library/ArmLib/AArch64/AArch64Support.S | 95 +++++----------------- ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S | 50 ++---------- ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S | 17 ---- .../ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S | 4 +- 7 files changed, 36 insertions(+), 163 deletions(-) diff --git a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S index 20f83aa85f..7316502d23 100644 --- a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S +++ b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S @@ -17,7 +17,6 @@ // #define ICC_SRE_EL1 S3_0_C12_C12_5 #define ICC_SRE_EL2 S3_4_C12_C9_5 -#define ICC_SRE_EL3 S3_6_C12_C12_5 #define ICC_IGRPEN1_EL1 S3_0_C12_C12_7 #define ICC_EOIR1_EL1 S3_0_C12_C12_1 #define ICC_IAR1_EL1 S3_0_C12_C12_0 @@ -32,12 +31,10 @@ // VOID // ); ASM_FUNC(ArmGicV3GetControlSystemRegisterEnable) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, ICC_SRE_EL1 b 4f 2: mrs x0, ICC_SRE_EL2 - b 4f -3: mrs x0, ICC_SRE_EL3 4: ret //VOID @@ -46,12 +43,10 @@ ASM_FUNC(ArmGicV3GetControlSystemRegisterEnable) // IN UINT32 ControlSystemRegisterEnable // ); ASM_FUNC(ArmGicV3SetControlSystemRegisterEnable) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr ICC_SRE_EL1, x0 b 4f 2: msr ICC_SRE_EL2, x0 - b 4f -3: msr ICC_SRE_EL3, x0 4: isb ret diff --git a/ArmPkg/Include/AsmMacroIoLibV8.h b/ArmPkg/Include/AsmMacroIoLibV8.h index 81164ea9c9..a5c8635840 100644 --- a/ArmPkg/Include/AsmMacroIoLibV8.h +++ b/ArmPkg/Include/AsmMacroIoLibV8.h @@ -23,17 +23,6 @@ cbnz SAFE_XREG, 1f ;\ b . ;// We should never get here -// CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1 -// This only selects between EL1 and EL2 and EL3, else we die. -// Provide the Macro with a safe temp xreg to use. -#define EL1_OR_EL2_OR_EL3(SAFE_XREG) \ - mrs SAFE_XREG, CurrentEL ;\ - cmp SAFE_XREG, #0x8 ;\ - b.gt 3f ;\ - b.eq 2f ;\ - cbnz SAFE_XREG, 1f ;\ - b . ;// We should never get here - #define _ASM_FUNC(Name, Section) \ .global Name ; \ .section #Section, "ax" ; \ diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index f5cbc2e97c..de9d3316de 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -260,7 +260,7 @@ ASM_PFX(ExceptionHandlersEnd): ASM_PFX(CommonExceptionEntry): - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:mrs x2, elr_el1 // Exception Link Register mrs x3, spsr_el1 // Saved Processor Status Register 32bit mrs x5, esr_el1 // EL1 Exception syndrome register 32bit @@ -271,12 +271,6 @@ ASM_PFX(CommonExceptionEntry): mrs x3, spsr_el2 // Saved Processor Status Register 32bit mrs x5, esr_el2 // EL2 Exception syndrome register 32bit mrs x6, far_el2 // EL2 Fault Address Register - b 4f - -3:mrs x2, elr_el3 // Exception Link Register - mrs x3, spsr_el3 // Saved Processor Status Register 32bit - mrs x5, esr_el3 // EL3 Exception syndrome register 32bit - mrs x6, far_el3 // EL3 Fault Address Register 4:mrs x4, fpsr // Floating point Status Register 32bit @@ -365,15 +359,12 @@ ASM_PFX(CommonExceptionEntry): msr daifset, #3 isb - EL1_OR_EL2_OR_EL3(x28) + EL1_OR_EL2(x28) 1:msr elr_el1, x29 // Exception Link Register msr spsr_el1, x30 // Saved Processor Status Register 32bit b 4f 2:msr elr_el2, x29 // Exception Link Register msr spsr_el2, x30 // Saved Processor Status Register 32bit - b 4f -3:msr elr_el3, x29 // Exception Link Register - msr spsr_el3, x30 // Saved Processor Status Register 32bit 4: // pop remaining GP regs and return from exception. diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 177d10e66d..1ec868ee12 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -67,14 +67,12 @@ ASM_FUNC(ArmInvalidateInstructionCache) ASM_FUNC(ArmEnableMmu) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Read System control register EL1 b 4f 2: mrs x0, sctlr_el2 // Read System control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Read System control register EL3 4: orr x0, x0, #CTRL_M_BIT // Set MMU enable bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: tlbi vmalle1 dsb nsh isb @@ -84,139 +82,107 @@ ASM_FUNC(ArmEnableMmu) dsb nsh isb msr sctlr_el2, x0 // Write back - b 4f -3: tlbi alle3 - dsb nsh - isb - msr sctlr_el3, x0 // Write back 4: isb ret ASM_FUNC(ArmDisableMmu) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Read System Control Register EL1 b 4f 2: mrs x0, sctlr_el2 // Read System Control Register EL2 - b 4f -3: mrs x0, sctlr_el3 // Read System Control Register EL3 4: and x0, x0, #~CTRL_M_BIT // Clear MMU enable bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back tlbi vmalle1 b 4f 2: msr sctlr_el2, x0 // Write back tlbi alle2 - b 4f -3: msr sctlr_el3, x0 // Write back - tlbi alle3 4: dsb sy isb ret ASM_FUNC(ArmDisableCachesAndMmu) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: mov x1, #~(CTRL_M_BIT | CTRL_C_BIT | CTRL_I_BIT) // Disable MMU, D & I caches and x0, x0, x1 - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret ASM_FUNC(ArmMmuEnabled) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: and x0, x0, #CTRL_M_BIT ret ASM_FUNC(ArmEnableDataCache) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: orr x0, x0, #CTRL_C_BIT // Set C bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret ASM_FUNC(ArmDisableDataCache) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: and x0, x0, #~CTRL_C_BIT // Clear C bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret ASM_FUNC(ArmEnableInstructionCache) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: orr x0, x0, #CTRL_I_BIT // Set I bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret ASM_FUNC(ArmDisableInstructionCache) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: and x0, x0, #~CTRL_I_BIT // Clear I bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret @@ -238,19 +204,15 @@ ASM_FUNC(ArmEnableAlignmentCheck) ASM_FUNC(ArmDisableAlignmentCheck) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: and x0, x0, #~CTRL_A_BIT // Clear A (alignment check) bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret @@ -271,19 +233,15 @@ ASM_FUNC(ArmEnableStackAlignmentCheck) ASM_FUNC(ArmDisableStackAlignmentCheck) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, sctlr_el1 // Get control register EL1 b 4f 2: mrs x0, sctlr_el2 // Get control register EL2 - b 4f -3: mrs x0, sctlr_el3 // Get control register EL3 4: bic x0, x0, #CTRL_SA_BIT // Clear SA (stack alignment check) bit - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr sctlr_el1, x0 // Write back control register b 4f 2: msr sctlr_el2, x0 // Write back control register - b 4f -3: msr sctlr_el3, x0 // Write back control register 4: dsb sy isb ret @@ -374,24 +332,19 @@ ASM_FUNC(ArmInstructionSynchronizationBarrier) ASM_FUNC(ArmWriteVBar) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: msr vbar_el1, x0 // Set the Address of the EL1 Vector Table in the VBAR register b 4f 2: msr vbar_el2, x0 // Set the Address of the EL2 Vector Table in the VBAR register - b 4f -3: msr vbar_el3, x0 // Set the Address of the EL3 Vector Table in the VBAR register 4: isb ret ASM_FUNC(ArmReadVBar) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1: mrs x0, vbar_el1 // Set the Address of the EL1 Vector Table in the VBAR register ret 2: mrs x0, vbar_el2 // Set the Address of the EL2 Vector Table in the VBAR register ret -3: mrs x0, vbar_el3 // Set the Address of the EL3 Vector Table in the VBAR register - ret - ASM_FUNC(ArmEnableVFP) // Check whether floating-point is implemented in the processor. @@ -409,15 +362,11 @@ ASM_FUNC(ArmEnableVFP) orr x0, x0, #CPACR_VFP_BITS // Disable FVP traps to EL1 msr cpacr_el1, x0 // Write back EL1 Coprocessor Access Control Register (CPACR) mov x1, #AARCH64_CPTR_TFP // TFP Bit for trapping VFP Exceptions - EL1_OR_EL2_OR_EL3(x2) + EL1_OR_EL2(x2) 1:ret // Not configurable in EL1 2:mrs x0, cptr_el2 // Disable VFP traps to EL2 bic x0, x0, x1 msr cptr_el2, x0 - ret -3:mrs x0, cptr_el3 // Disable VFP traps to EL3 - bic x0, x0, x1 - msr cptr_el3, x0 4:ret diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S index ba0ec5682b..ec34200d4d 100644 --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S @@ -54,12 +54,10 @@ ASM_FUNC(ArmReadAuxCr) ret ASM_FUNC(ArmSetTTBR0) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:msr ttbr0_el1, x0 // Translation Table Base Reg 0 (TTBR0) b 4f 2:msr ttbr0_el2, x0 // Translation Table Base Reg 0 (TTBR0) - b 4f -3:msr ttbr0_el3, x0 // Translation Table Base Reg 0 (TTBR0) 4:isb ret @@ -73,42 +71,34 @@ ASM_FUNC(ArmGetTTBR0BaseAddress) ret ASM_FUNC(ArmGetTCR) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:mrs x0, tcr_el1 b 4f 2:mrs x0, tcr_el2 - b 4f -3:mrs x0, tcr_el3 4:isb ret ASM_FUNC(ArmSetTCR) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:msr tcr_el1, x0 b 4f 2:msr tcr_el2, x0 - b 4f -3:msr tcr_el3, x0 4:isb ret ASM_FUNC(ArmGetMAIR) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:mrs x0, mair_el1 b 4f 2:mrs x0, mair_el2 - b 4f -3:mrs x0, mair_el3 4:isb ret ASM_FUNC(ArmSetMAIR) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:msr mair_el1, x0 b 4f 2:msr mair_el2, x0 - b 4f -3:msr mair_el3, x0 4:isb ret @@ -122,15 +112,12 @@ ASM_FUNC(ArmSetMAIR) ASM_FUNC(ArmUpdateTranslationTableEntry) dsb nshst lsr x1, x1, #12 - EL1_OR_EL2_OR_EL3(x2) + EL1_OR_EL2(x2) 1: tlbi vaae1, x1 // TLB Invalidate VA , EL1 mrs x2, sctlr_el1 b 4f 2: tlbi vae2, x1 // TLB Invalidate VA , EL2 mrs x2, sctlr_el2 - b 4f -3: tlbi vae3, x1 // TLB Invalidate VA , EL3 - mrs x2, sctlr_el3 4: tbnz x2, SCTLR_ELx_M_BIT_POS, 5f dc ivac, x0 // invalidate in Dcache if MMU is still off 5: dsb nsh @@ -138,29 +125,14 @@ ASM_FUNC(ArmUpdateTranslationTableEntry) ret ASM_FUNC(ArmInvalidateTlb) - EL1_OR_EL2_OR_EL3(x0) + EL1_OR_EL2(x0) 1: tlbi vmalle1 b 4f 2: tlbi alle2 - b 4f -3: tlbi alle3 4: dsb sy isb ret -ASM_FUNC(ArmWriteCptr) - msr cptr_el3, x0 // EL3 Coprocessor Trap Reg (CPTR) - ret - -ASM_FUNC(ArmWriteScr) - msr scr_el3, x0 // Secure configuration register EL3 - isb - ret - -ASM_FUNC(ArmWriteMVBar) - msr vbar_el3, x0 // Exception Vector Base address for Monitor on EL3 - ret - ASM_FUNC(ArmCallWFE) wfe ret @@ -180,22 +152,18 @@ ASM_FUNC(ArmWriteCpuActlr) ret ASM_FUNC(ArmReadSctlr) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:mrs x0, sctlr_el1 ret 2:mrs x0, sctlr_el2 ret -3:mrs x0, sctlr_el3 -4:ret ASM_FUNC(ArmWriteSctlr) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:msr sctlr_el1, x0 ret 2:msr sctlr_el2, x0 ret -3:msr sctlr_el3, x0 -4:ret ASM_FUNC(ArmGetPhysicalAddressBits) mrs x0, id_aa64mmfr0_el1 diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S index 0856740e32..7e032dd07c 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S @@ -108,15 +108,6 @@ ASM_FUNC(ArmInvalidateTlb) isb bx lr -ASM_FUNC(ArmReadScr) - mrc p15, 0, r0, c1, c1, 0 - bx lr - -ASM_FUNC(ArmWriteScr) - mcr p15, 0, r0, c1, c1, 0 - isb - bx lr - ASM_FUNC(ArmReadHVBar) mrc p15, 4, r0, c12, c0, 0 bx lr @@ -125,14 +116,6 @@ ASM_FUNC(ArmWriteHVBar) mcr p15, 4, r0, c12, c0, 0 bx lr -ASM_FUNC(ArmReadMVBar) - mrc p15, 0, r0, c12, c0, 1 - bx lr - -ASM_FUNC(ArmWriteMVBar) - mcr p15, 0, r0, c12, c0, 1 - bx lr - ASM_FUNC(ArmCallWFE) wfe bx lr diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S index 1f0d805792..0332cf7ce1 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S @@ -86,12 +86,10 @@ ASM_FUNC_ALIGN(ArmReplaceLiveTranslationEntry, 0x200) msr daifset, #0xf isb - EL1_OR_EL2_OR_EL3(x5) + EL1_OR_EL2(x5) 1:__replace_entry 1 b 4f 2:__replace_entry 2 - b 4f -3:__replace_entry 3 4:msr daif, x4 ret -- cgit From 95e220e95d6237e21f7c0b83fca02d56b9327c4a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 19 Jun 2024 17:22:33 +0200 Subject: MdePkg/ArmLib: Drop obsolete library declarations Drop obsolete library declarations that are no longer (and should not be) implemented in EDK2 or UEFI, given that they are specific to the secure world. Signed-off-by: Ard Biesheuvel --- MdePkg/Include/AArch64/AArch64.h | 5 ----- MdePkg/Include/Library/ArmLib.h | 36 ------------------------------------ 2 files changed, 41 deletions(-) diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index a77c3a95f1..c1a24c1e30 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -234,11 +234,6 @@ ArmReadCurrentEL ( VOID ); -UINTN -ArmWriteCptr ( - IN UINT64 Cptr - ); - UINT32 ArmReadCntHctl ( VOID diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index 71c2076652..6a1503a7e5 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -515,42 +515,6 @@ ArmEnableVFP ( VOID ); -/** - Get the Secure Configuration Register value - - @return Value read from the Secure Configuration Register - -**/ -UINT32 -EFIAPI -ArmReadScr ( - VOID - ); - -/** - Set the Secure Configuration Register - - @param Value Value to write to the Secure Configuration Register - -**/ -VOID -EFIAPI -ArmWriteScr ( - IN UINT32 Value - ); - -UINT32 -EFIAPI -ArmReadMVBar ( - VOID - ); - -VOID -EFIAPI -ArmWriteMVBar ( - IN UINT32 VectorMonitorBase - ); - UINT32 EFIAPI ArmReadSctlr ( -- cgit From 57a890fd03356350a1b7a2a0064c8118f44e9958 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 16 Jun 2024 02:55:33 -0600 Subject: MdePkg: Check if compiler has __has_builtin before trying to use it When building AArch64 code, cpp gets run with the `-undef` flag which on Fedora 40 with gcc version 14.1.1 20240607 (Red Hat 14.1.1-5) causes __has_builtin to be undefined. When running the check for __builtin_unreachable in Base.h it causes an error "missing binary operator before token "("". Check that we have __has_builtin before trying to use it. Signed-off-by: Rebecca Cran --- MdePkg/Include/Base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index e02970a052..7caebbeb1f 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -59,7 +59,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent /// up to the compiler to remove any code past that point. /// #define UNREACHABLE() __builtin_unreachable () - #elif defined (__has_feature) + #elif defined (__has_builtin) && defined (__has_feature) #if __has_builtin (__builtin_unreachable) /// /// Signal compilers and analyzers that this call is not reachable. It is -- cgit From d512bd31293c7f2aeef9b60fb6f112d0e90adff3 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Tue, 18 Jun 2024 19:59:56 +0800 Subject: UefiCpuPkg: Correct the count of different type of Cache. This patch fixes an error in calculating cache sizes for cores from different Dies. The original code incorrectly cleared cache sizes for different core types during intermediate calculation steps, leading to mistakes in counting duplicate entries. This patch adds a check for cache size to distinguish between different cache types. Cc: Gerd Hoffmann Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Tom Lendacky Signed-off-by: xieyuanh --- UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c index c7973735e1..df07a10a2a 100644 --- a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c @@ -348,7 +348,8 @@ CpuCacheInfoCollectCpuCacheInfoData ( if ((LocalCacheInfo[CacheInfoIndex].Package == ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package) && (LocalCacheInfo[CacheInfoIndex].CoreType == ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType) && (LocalCacheInfo[CacheInfoIndex].CacheLevel == CacheData[Index].CacheLevel) && - (LocalCacheInfo[CacheInfoIndex].CacheType == CacheData[Index].CacheType)) + (LocalCacheInfo[CacheInfoIndex].CacheType == CacheData[Index].CacheType) && + (LocalCacheInfo[CacheInfoIndex].CacheSizeinKB == CacheData[Index].CacheSizeinKB)) { LocalCacheInfo[CacheInfoIndex].CacheCount++; break; -- cgit From be38c01da2dd949e0a6f8bceeb88d2e19c8c65f7 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Fri, 28 Jul 2023 16:34:34 +0300 Subject: OvmfPkg: refine TdTcg2Dxe This patch removes unused references to ResetNotification code. ACPI table generation refined by removing excessive CopyMem() call. Signed-off-by: Mike Maslenkin --- OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c | 5 +---- OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c index 5241f60891..0a23bff5a1 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c +++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -2355,7 +2354,6 @@ InstallAcpiTable ( UINTN TableKey; EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; - UINT64 OemTableId; Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable); if (EFI_ERROR (Status)) { @@ -2366,8 +2364,7 @@ InstallAcpiTable ( mTdxEventlogAcpiTemplate.Laml = (UINT64)PcdGet32 (PcdCcEventlogAcpiTableLaml); mTdxEventlogAcpiTemplate.Lasa = PcdGet64 (PcdCcEventlogAcpiTableLasa); CopyMem (mTdxEventlogAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTdxEventlogAcpiTemplate.Header.OemId)); - OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); - CopyMem (&mTdxEventlogAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); + mTdxEventlogAcpiTemplate.Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); mTdxEventlogAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTdxEventlogAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTdxEventlogAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf index 6861a1452d..0f86c12fdd 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf +++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf @@ -73,7 +73,6 @@ gEfiCcMeasurementProtocolGuid ## PRODUCES gEfiMpServiceProtocolGuid ## SOMETIMES_CONSUMES gEfiVariableWriteArchProtocolGuid ## NOTIFY - gEfiResetNotificationProtocolGuid ## CONSUMES gEfiAcpiTableProtocolGuid ## NOTIFY [Pcd] -- cgit From 56059941ec8c2f4d8fb126227b1154f8a869ac2b Mon Sep 17 00:00:00 2001 From: Tobin Feldman-Fitzthum Date: Fri, 19 Apr 2024 14:35:54 -0400 Subject: AmdSev: Rework Blob Verifier The Blob Verifier checks boot artifacts against a hash table injected by the hypervisor and measured by hardware. Update the Blob Verifier to enter a dead loop if the artifacts do not match. The verifier still returns ACCESS_DENIED in some cases, but this is considered non-fatal. These non-fatal cases occur when the artifact cannot be verified because the hashes table makes no claims about the artifiact (e.g. if the hashes table is not present or if there is no entry for the blob in question). Since the hash table is reflected in the launch measurement, it is okay to continue the boot in these cases. If the hash table does contain expected hash values, the boot cannot continue if the provided blobs do not match. In these cases we enter a dead loop to make sure no guest can boot with a TCB that does not reflect the launch measurement. Signed-off-by: Tobin Feldman-Fitzthum --- .../BlobVerifierSevHashes.c | 35 +++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c index 2e58794c3c..37c38e9e98 100644 --- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c +++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c @@ -77,13 +77,17 @@ FindBlobEntryGuid ( /** Verify blob from an external source. + If a non-secure configuration is detected this function will enter a + dead loop to prevent a boot. + @param[in] BlobName The name of the blob @param[in] Buf The data of the blob @param[in] BufSize The size of the blob in bytes - @retval EFI_SUCCESS The blob was verified successfully. - @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore - should be considered non-secure. + @retval EFI_SUCCESS The blob was verified successfully or was not + found in the hash table. + @retval EFI_ACCESS_DENIED Kernel hashes not supported, but the boot + can continue safely. **/ EFI_STATUS EFIAPI @@ -99,7 +103,7 @@ VerifyBlob ( if ((mHashesTable == NULL) || (mHashesTableSize == 0)) { DEBUG (( - DEBUG_ERROR, + DEBUG_WARN, "%a: Verifier called but no hashes table discoverd in MEMFD\n", __func__ )); @@ -114,7 +118,8 @@ VerifyBlob ( __func__, BlobName )); - return EFI_ACCESS_DENIED; + + CpuDeadLoop (); } // @@ -136,10 +141,20 @@ VerifyBlob ( DEBUG ((DEBUG_INFO, "%a: Found GUID %g in table\n", __func__, Guid)); + if (BufSize == 0) { + DEBUG (( + DEBUG_ERROR, + "%a: Blob Specified in Hash Table was not Provided", + __func__ + )); + + CpuDeadLoop (); + } + EntrySize = Entry->Len - sizeof Entry->Guid - sizeof Entry->Len; if (EntrySize != SHA256_DIGEST_SIZE) { DEBUG (( - DEBUG_ERROR, + DEBUG_WARN, "%a: Hash has the wrong size %d != %d\n", __func__, EntrySize, @@ -170,18 +185,24 @@ VerifyBlob ( __func__, BlobName )); + + CpuDeadLoop (); } return Status; } + // + // If the GUID is not in the hash table, execution can still continue. + // This blob will not be measured, but at least one blob must be. + // DEBUG (( DEBUG_ERROR, "%a: Hash GUID %g not found in table\n", __func__, Guid )); - return EFI_ACCESS_DENIED; + return EFI_SUCCESS; } /** -- cgit From 10b4bb8d6d0c515ed9663691aea3684be8f7b0fc Mon Sep 17 00:00:00 2001 From: Tobin Feldman-Fitzthum Date: Mon, 29 Apr 2024 20:07:19 +0000 Subject: AmdSev: Halt on failed blob allocation A malicious host may be able to undermine the fw_cfg interface such that loading a blob fails. In this case rather than continuing to the next boot option, the blob verifier should halt. For non-confidential guests, the error should be non-fatal. Signed-off-by: Tobin Feldman-Fitzthum --- .../BlobVerifierLibSevHashes/BlobVerifierSevHashes.c | 17 ++++++++++++++++- OvmfPkg/Include/Library/BlobVerifierLib.h | 11 +++++++---- OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c | 13 ++++++++----- OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 9 ++++----- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c index 37c38e9e98..bc2d5daadc 100644 --- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c +++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c @@ -83,6 +83,7 @@ FindBlobEntryGuid ( @param[in] BlobName The name of the blob @param[in] Buf The data of the blob @param[in] BufSize The size of the blob in bytes + @param[in] FetchStatus The status of the previous blob fetch @retval EFI_SUCCESS The blob was verified successfully or was not found in the hash table. @@ -94,13 +95,27 @@ EFIAPI VerifyBlob ( IN CONST CHAR16 *BlobName, IN CONST VOID *Buf, - IN UINT32 BufSize + IN UINT32 BufSize, + IN EFI_STATUS FetchStatus ) { CONST GUID *Guid; INT32 Remaining; HASH_TABLE *Entry; + // Enter a dead loop if the fetching of this blob + // failed. This prevents a malicious host from + // circumventing the following checks. + if (EFI_ERROR (FetchStatus)) { + DEBUG (( + DEBUG_ERROR, + "%a: Fetching blob failed.\n", + __func__ + )); + + CpuDeadLoop (); + } + if ((mHashesTable == NULL) || (mHashesTableSize == 0)) { DEBUG (( DEBUG_WARN, diff --git a/OvmfPkg/Include/Library/BlobVerifierLib.h b/OvmfPkg/Include/Library/BlobVerifierLib.h index 7e1af27574..09af1b77de 100644 --- a/OvmfPkg/Include/Library/BlobVerifierLib.h +++ b/OvmfPkg/Include/Library/BlobVerifierLib.h @@ -22,17 +22,20 @@ @param[in] BlobName The name of the blob @param[in] Buf The data of the blob @param[in] BufSize The size of the blob in bytes + @param[in] FetchStatus The status of fetching this blob - @retval EFI_SUCCESS The blob was verified successfully. - @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore - should be considered non-secure. + @retval EFI_SUCCESS The blob was verified successfully or was not + found in the hash table. + @retval EFI_ACCESS_DENIED Kernel hashes not supported but the boot can + continue safely. **/ EFI_STATUS EFIAPI VerifyBlob ( IN CONST CHAR16 *BlobName, IN CONST VOID *Buf, - IN UINT32 BufSize + IN UINT32 BufSize, + IN EFI_STATUS FetchStatus ); #endif diff --git a/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c b/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c index e817c3cc95..db5320571c 100644 --- a/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c +++ b/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c @@ -16,18 +16,21 @@ @param[in] BlobName The name of the blob @param[in] Buf The data of the blob @param[in] BufSize The size of the blob in bytes + @param[in] FetchStatus The status of the fetch of this blob - @retval EFI_SUCCESS The blob was verified successfully. - @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore - should be considered non-secure. + @retval EFI_SUCCESS The blob was verified successfully or was not + found in the hash table. + @retval EFI_ACCESS_DENIED Kernel hashes not supported but the boot can + continue safely. **/ EFI_STATUS EFIAPI VerifyBlob ( IN CONST CHAR16 *BlobName, IN CONST VOID *Buf, - IN UINT32 BufSize + IN UINT32 BufSize, + IN EFI_STATUS FetchStatus ) { - return EFI_SUCCESS; + return FetchStatus; } diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c index 3c12085f6c..cf58c97cd2 100644 --- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c @@ -1042,6 +1042,7 @@ QemuKernelLoaderFsDxeEntrypoint ( KERNEL_BLOB *CurrentBlob; KERNEL_BLOB *KernelBlob; EFI_STATUS Status; + EFI_STATUS FetchStatus; EFI_HANDLE FileSystemHandle; EFI_HANDLE InitrdLoadFile2Handle; @@ -1060,15 +1061,13 @@ QemuKernelLoaderFsDxeEntrypoint ( // for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) { CurrentBlob = &mKernelBlob[BlobType]; - Status = FetchBlob (CurrentBlob); - if (EFI_ERROR (Status)) { - goto FreeBlobs; - } + FetchStatus = FetchBlob (CurrentBlob); Status = VerifyBlob ( CurrentBlob->Name, CurrentBlob->Data, - CurrentBlob->Size + CurrentBlob->Size, + FetchStatus ); if (EFI_ERROR (Status)) { goto FreeBlobs; -- cgit From 84d8eb08e15e455826ef66a4b1f1f61758cb9aba Mon Sep 17 00:00:00 2001 From: Sebastian Witt Date: Tue, 4 Jun 2024 14:34:39 +0200 Subject: CryptoPkg: Add SNI extension to TLS ClientHello Webservers hosting multiple websites require the TLS SNI (Server Name Indication) in the ClientHello to know which certificate to return. The current TLS code does not include the server name in the ClientHello handshake, which leads to failed HTTPS boots when the server does not return the correct certificate. This sets the host name for SNI in TlsSetVerifyHost which receives the host name also for verification against the certificates. Signed-off-by: Sebastian Witt --- CryptoPkg/Library/TlsLib/TlsConfig.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c b/CryptoPkg/Library/TlsLib/TlsConfig.c index 29d24abdca..afbc583daf 100644 --- a/CryptoPkg/Library/TlsLib/TlsConfig.c +++ b/CryptoPkg/Library/TlsLib/TlsConfig.c @@ -500,6 +500,24 @@ TlsSetVerifyHost ( return EFI_INVALID_PARAMETER; } + DEBUG (( + DEBUG_VERBOSE, + "%a:%a: SNI hostname: %a\n", + gEfiCallerBaseName, + __func__, + HostName + )); + + if (!SSL_set_tlsext_host_name (TlsConn->Ssl, HostName)) { + DEBUG (( + DEBUG_ERROR, + "%a:%a: Could not set hostname %a for SNI\n", + gEfiCallerBaseName, + __func__, + HostName + )); + } + SSL_set_hostflags (TlsConn->Ssl, Flags); VerifyParam = SSL_get0_param (TlsConn->Ssl); -- cgit From dc93ff8a5561a3085eeda9d4ac00d40545eb43cd Mon Sep 17 00:00:00 2001 From: Sebastian Witt Date: Thu, 6 Jun 2024 16:26:28 +0200 Subject: CryptoPkg: Extend TLS handshake debug output The error codes during TLS handshake errors are sometimes not enough to understand the root cause of the problem. Extending the debug output by the function and optional data helps in some cases. Signed-off-by: Sebastian Witt --- CryptoPkg/Library/TlsLib/TlsProcess.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CryptoPkg/Library/TlsLib/TlsProcess.c b/CryptoPkg/Library/TlsLib/TlsProcess.c index 1b712cd452..17aeff1c37 100644 --- a/CryptoPkg/Library/TlsLib/TlsProcess.c +++ b/CryptoPkg/Library/TlsLib/TlsProcess.c @@ -133,19 +133,23 @@ TlsDoHandshake ( DEBUG_CODE_BEGIN (); while (TRUE) { unsigned long ErrorCode; + const char *Func; + const char *Data; - ErrorCode = ERR_get_error (); + ErrorCode = ERR_get_error_all (NULL, NULL, &Func, &Data, NULL); if (ErrorCode == 0) { break; } DEBUG (( DEBUG_ERROR, - "%a ERROR 0x%x=L%x:R%x\n", + "%a ERROR 0x%x=L%x:R%x %a(): %a\n", __func__, ErrorCode, ERR_GET_LIB (ErrorCode), - ERR_GET_REASON (ErrorCode) + ERR_GET_REASON (ErrorCode), + Func, + Data )); } -- cgit From 5db0091418c8ed6a62178469e8ffb3dacaab13ee Mon Sep 17 00:00:00 2001 From: Dongyan Qian Date: Tue, 25 Jun 2024 10:35:14 +0800 Subject: UefiCpuPkg/ExceptionHandler: Fix a context error in LoongArch64 On the LoongArch platform: the a0 register can be used as both a function parameter and a return value. Due to parameter EFI_SYSTEM_CONTEXT being overwritten by an invalid context address, when calling GetExceptionType, incorrect parameter address causes memory access exception. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4796 Cc: Chao Li Signed-off-by: Dongyan Qian --- .../CpuExceptionHandlerLib/LoongArch/LoongArch64/ExceptionHandlerAsm.S | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ExceptionHandlerAsm.S index 7c692e01c1..1c685f9567 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ExceptionHandlerAsm.S +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ExceptionHandlerAsm.S @@ -34,6 +34,7 @@ PopContext: // bl DisableInterrupts + move $a0, $s0 // Restore a0 parameter through s0(EFI_SYSTEM_CONTEXT) bl GetExceptionType // Get current exception type, and stored in register a0 // Check whether the FPE is changed during interrupt handler, if ture restore it. -- cgit From 2fbaaa96d11ad61a9133df1728e3fe965d1457a5 Mon Sep 17 00:00:00 2001 From: Dongyan Qian Date: Tue, 25 Jun 2024 11:09:01 +0800 Subject: MdePkg/BaseLib: Fix an instruction write width error in LoongArch64 Cpucfg fetch is a 32-bit register, and AsmCpucfg's function declaration is a 32-bit address storage operation in BaseLib.h, So, fix it by replacing stptr.d with stptr.w instrcution. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4797 Cc: Chao Li Signed-off-by: Dongyan Qian Co-authored-by: Chao Li --- MdePkg/Library/BaseLib/LoongArch64/Cpucfg.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Library/BaseLib/LoongArch64/Cpucfg.S b/MdePkg/Library/BaseLib/LoongArch64/Cpucfg.S index 8b3f842f9e..0240213705 100644 --- a/MdePkg/Library/BaseLib/LoongArch64/Cpucfg.S +++ b/MdePkg/Library/BaseLib/LoongArch64/Cpucfg.S @@ -20,7 +20,7 @@ ASM_GLOBAL ASM_PFX(AsmCpucfg) ASM_PFX(AsmCpucfg): cpucfg $t0, $a0 - stptr.d $t0, $a1, 0 + stptr.w $t0, $a1, 0 jirl $zero, $ra, 0 .end -- cgit From a715d456de47187cbaad1747a398499180cac710 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Wed, 19 Jun 2024 15:41:33 +0100 Subject: ArmPkg: drop manual ARM programming of generic timer frequency There is a bit of legacy code in ArmArchTimerLib that attempts to program the generic timer based on a Pcd. This was only ever done for (32-bit) ARM in case the cpu lacked the Security Extensions (because if they were there, Secure firmware would be expected to have configured this before switching to Non-secure state). We don't support operation without Secure firmware anymore, but also the code has been incorrectly invoked only on platforms that *do* implement the Security Extensions since December 2020 and commit 0dd0d42ab5b6 ("ArmPkg: use helper to check for Security extensions in ArmArchTimerLib") As a result, edk2 has been overriding any programming done by Secure Firmware on ARM platforms. Which is wrong. Drop this programming in preparation for deleting the Pcd completely. Signed-off-by: Leif Lindholm --- ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c index d663a76a9b..00700395ef 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c @@ -45,19 +45,6 @@ TimerConstructor ( // Ref manual, lower bound of the frequency is in the range of 1-10MHz. // ASSERT (TICKS_PER_MICRO_SEC); - - #ifdef MDE_CPU_ARM - // - // Only set the frequency for ARMv7. We expect the secure firmware to - // have already done it. - // If the security extension is not implemented, set Timer Frequency - // here. - // - if (ArmHasSecurityExtensions ()) { - ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz)); - } - - #endif } // -- cgit From 7ee89453b5a20199e96d08eb80db8dbaf06280e8 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Wed, 19 Jun 2024 18:35:34 +0100 Subject: ArmVirtPkg: drop use of PcdArmArchTimerFreqInHz PcdArmArchTimerFreqInHz lets platforms override the architectural timer frequency, but this really isn't supported in hardware by anything lower than EL3. Setting it to 0 skips the override - but that is also the default. So drop the explicit setting in ArmVirtPkg platforms in preparation for deleting the Pcd completely. Signed-off-by: Leif Lindholm --- ArmVirtPkg/ArmVirtKvmTool.dsc | 5 ----- ArmVirtPkg/ArmVirtQemu.dsc | 5 ----- ArmVirtPkg/ArmVirtQemuKernel.dsc | 5 ----- ArmVirtPkg/ArmVirtXen.dsc | 5 ----- 4 files changed, 20 deletions(-) diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index da6737d9d7..8688236084 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -147,11 +147,6 @@ # 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4 - # - # ARM Virtual Architectural Timer -- fetch frequency from KVM - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0 - # Use MMIO for accessing Serial port registers. gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0xFF} diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index d90c60b28a..6a0e99bc64 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -190,11 +190,6 @@ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|1 !endif - # - # ARM Virtual Architectural Timer -- fetch frequency from QEMU (TCG) or KVM - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0 - # # Network Pcds # diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index 7d41f280cb..4e8ed6c968 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -156,11 +156,6 @@ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|1 !endif - # - # ARM Virtual Architectural Timer -- fetch frequency from QEMU (TCG) or KVM - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0 - # # Network Pcds # diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 3689106857..6c1190dce3 100644 --- a/ArmVirtPkg/ArmVirtXen.dsc +++ b/ArmVirtPkg/ArmVirtXen.dsc @@ -86,11 +86,6 @@ # Size of the region used by UEFI in permanent memory (Reserved 64MB) gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000 - # - # ARM Virtual Architectural Timer - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0 - gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } -- cgit From 0333faf50e49d3b3ea2c624b4d403b405b3107a1 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Wed, 19 Jun 2024 18:29:30 +0100 Subject: ArmPkg: delete PcdArmArchTimerFreqInHz PcdArmArchTimerFreqInHz lets platforms override the architectural timer frequency, but this really isn't supported in hardware by anything lower than EL3. And we no longer support running edk2 at EL3. So drop this Pcd and update ArmArchTimerLib to unconditionally use ArmGenericTimerGetTimerFreq () instead. Signed-off-by: Leif Lindholm --- ArmPkg/ArmPkg.dec | 5 ----- ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c | 20 ++------------------ ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf | 1 - 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 4ce59f3e1f..c0861140e8 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -314,11 +314,6 @@ gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059 [PcdsFixedAtBuild.common, PcdsDynamic.common] - # - # ARM Architectural Timer - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0|UINT32|0x00000034 - # ARM Architectural Timer Interrupt(GIC PPI) numbers gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035 gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036 diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c index 00700395ef..ccb4f6474b 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c @@ -15,7 +15,7 @@ #include #include -#define TICKS_PER_MICRO_SEC (PcdGet32 (PcdArmArchTimerFreqInHz)/1000000U) +#define TICKS_PER_MICRO_SEC (ArmGenericTimerGetTimerFreq ()/1000000U) // Select appropriate multiply function for platform architecture. #ifdef MDE_CPU_ARM @@ -34,19 +34,6 @@ TimerConstructor ( // Check if the ARM Generic Timer Extension is implemented. // if (ArmIsArchTimerImplemented ()) { - // - // Check if Architectural Timer frequency is pre-determined by the platform - // (ie. nonzero). - // - if (PcdGet32 (PcdArmArchTimerFreqInHz) != 0) { - // - // Check if ticks/uS is not 0. The Architectural timer runs at constant - // frequency, irrespective of CPU frequency. According to Generic Timer - // Ref manual, lower bound of the frequency is in the range of 1-10MHz. - // - ASSERT (TICKS_PER_MICRO_SEC); - } - // // Architectural Timer Frequency must be set in Secure privileged // mode (if secure extension is supported). @@ -76,10 +63,7 @@ GetPlatformTimerFreq ( { UINTN TimerFreq; - TimerFreq = PcdGet32 (PcdArmArchTimerFreqInHz); - if (TimerFreq == 0) { - TimerFreq = ArmGenericTimerGetTimerFreq (); - } + TimerFreq = ArmGenericTimerGetTimerFreq (); return TimerFreq; } diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf index 6f576ceab9..273b1e9555 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf @@ -29,4 +29,3 @@ ArmGenericTimerCounterLib [Pcd] - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz -- cgit From e21bfae345f9eee1c3f585013ca50ad6ab4f86a1 Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Thu, 20 Jun 2024 09:33:10 +0800 Subject: ReadMe.rst: Add mbedtls submodule license This patch add mbedtls submodule license. Cc: Andrew Fish Cc: Leif Lindholm Cc: Michael D Kinney Cc: Liming Gao Signed-off-by: Wenxing Hou --- ReadMe.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/ReadMe.rst b/ReadMe.rst index cfd522fdbd..3fbabe1a1b 100644 --- a/ReadMe.rst +++ b/ReadMe.rst @@ -91,6 +91,7 @@ that are covered by additional licenses. - `ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 `__ - `BaseTools/Source/C/BrotliCompress/brotli `__ - `CryptoPkg/Library/OpensslLib/openssl `__ +- `CryptoPkg/Library/MbedTlsLib/mbedtls `__ - `MdeModulePkg/Library/BrotliCustomDecompressLib/brotli `__ - `MdeModulePkg/Universal/RegularExpressionDxe/oniguruma `__ - `UnitTestFrameworkPkg/Library/CmockaLib/cmocka `__ -- cgit From ce4c76e46d52e24551f4986bded4c9b764502200 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 23 Jan 2024 15:33:51 +0100 Subject: OvmfPkg/Sec: Setup MTRR early in the boot process. Specifically before running lzma uncompress of the main firmware volume. This is needed to make sure caching is enabled, otherwise the uncompress can be extremely slow. Adapt the ASSERTs and MTRR setup in PlatformInitLib to the changes. Background: Depending on virtual machine configuration kvm may uses EPT memory types to apply guest MTRR settings. In case MTRRs are disabled kvm will use the uncachable memory type for all mappings. The vmx_get_mt_mask() function in the linux kernel handles this and can be found here: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/kvm/vmx/vmx.c?h=v6.7.1#n7580 In most VM configurations kvm uses MTRR_TYPE_WRBACK unconditionally. In case the VM has a mdev device assigned that is not the case though. Before commit e8aa4c6546ad ("UefiCpuPkg/ResetVector: Cache Disable should not be set by default in CR0") kvm also ended up using MTRR_TYPE_WRBACK due to KVM_X86_QUIRK_CD_NW_CLEARED. After that commit kvm evaluates guest mtrr settings, which why setting up MTRRs early is important now. Signed-off-by: Gerd Hoffmann --- OvmfPkg/Bhyve/PlatformPei/MemDetect.c | 10 ++++----- OvmfPkg/IntelTdx/Sec/SecMain.c | 32 +++++++++++++++++++++++++++++ OvmfPkg/Library/PlatformInitLib/MemDetect.c | 10 ++++----- OvmfPkg/Sec/SecMain.c | 32 +++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/OvmfPkg/Bhyve/PlatformPei/MemDetect.c b/OvmfPkg/Bhyve/PlatformPei/MemDetect.c index 29cbb9e3dc..351862942d 100644 --- a/OvmfPkg/Bhyve/PlatformPei/MemDetect.c +++ b/OvmfPkg/Bhyve/PlatformPei/MemDetect.c @@ -511,18 +511,18 @@ QemuInitializeRam ( MtrrGetAllMtrrs (&MtrrSettings); // - // MTRRs disabled, fixed MTRRs disabled, default type is uncached + // See SecMtrrSetup(), default type should be write back // - ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0); + ASSERT ((MtrrSettings.MtrrDefType & BIT11) != 0); ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0); - ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0); + ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == MTRR_CACHE_WRITE_BACK); // // flip default type to writeback // - SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06); + SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, MTRR_CACHE_WRITE_BACK); ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables); - MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6; + MtrrSettings.MtrrDefType |= BIT10; MtrrSetAllMtrrs (&MtrrSettings); // diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c index 4e750755bf..6eeae09e3b 100644 --- a/OvmfPkg/IntelTdx/Sec/SecMain.c +++ b/OvmfPkg/IntelTdx/Sec/SecMain.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #define SEC_IDT_ENTRY_COUNT 34 @@ -47,6 +49,31 @@ IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = { } }; +// +// Enable MTRR early, set default type to write back. +// Needed to make sure caching is enabled, +// without this lzma decompress can be very slow. +// +STATIC +VOID +SecMtrrSetup ( + VOID + ) +{ + CPUID_VERSION_INFO_EDX Edx; + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32); + if (!Edx.Bits.MTRR) { + return; + } + + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + DefType.Bits.Type = 6; /* write back */ + DefType.Bits.E = 1; /* enable */ + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); +} + VOID EFIAPI SecCoreStartupWithStack ( @@ -203,6 +230,11 @@ SecCoreStartupWithStack ( InitializeApicTimer (0, MAX_UINT32, TRUE, 5); DisableApicTimerInterrupt (); + // + // Initialize MTRR + // + SecMtrrSetup (); + PeilessStartup (&SecCoreData); ASSERT (FALSE); diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index 2b6404cc51..bd6c79e4e4 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -1175,18 +1175,18 @@ PlatformQemuInitializeRam ( MtrrGetAllMtrrs (&MtrrSettings); // - // MTRRs disabled, fixed MTRRs disabled, default type is uncached + // See SecMtrrSetup(), default type should be write back // - ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0); + ASSERT ((MtrrSettings.MtrrDefType & BIT11) != 0); ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0); - ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0); + ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == MTRR_CACHE_WRITE_BACK); // // flip default type to writeback // - SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06); + SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, MTRR_CACHE_WRITE_BACK); ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables); - MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6; + MtrrSettings.MtrrDefType |= BIT10; MtrrSetAllMtrrs (&MtrrSettings); // diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index 60dfa61842..b0bb7b295d 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "AmdSev.h" #define SEC_IDT_ENTRY_COUNT 34 @@ -743,6 +745,31 @@ FindAndReportEntryPoints ( return; } +// +// Enable MTRR early, set default type to write back. +// Needed to make sure caching is enabled, +// without this lzma decompress can be very slow. +// +STATIC +VOID +SecMtrrSetup ( + VOID + ) +{ + CPUID_VERSION_INFO_EDX Edx; + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32); + if (!Edx.Bits.MTRR) { + return; + } + + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + DefType.Bits.Type = 6; /* write back */ + DefType.Bits.E = 1; /* enable */ + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); +} + VOID EFIAPI SecCoreStartupWithStack ( @@ -942,6 +969,11 @@ SecCoreStartupWithStack ( InitializeApicTimer (0, MAX_UINT32, TRUE, 5); DisableApicTimerInterrupt (); + // + // Initialize MTRR + // + SecMtrrSetup (); + // // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. // -- cgit From 5bef25dca4119ae9bd537480d703575ad166723a Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 25 Jan 2024 08:36:57 +0100 Subject: MdePkg/ArchitecturalMsr.h: add #defines for MTRR cache types Signed-off-by: Gerd Hoffmann --- MdePkg/Include/Register/Intel/ArchitecturalMsr.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MdePkg/Include/Register/Intel/ArchitecturalMsr.h b/MdePkg/Include/Register/Intel/ArchitecturalMsr.h index 4715c59dc4..faabf0c433 100644 --- a/MdePkg/Include/Register/Intel/ArchitecturalMsr.h +++ b/MdePkg/Include/Register/Intel/ArchitecturalMsr.h @@ -2103,6 +2103,13 @@ typedef union { #define MSR_IA32_MTRR_PHYSBASE9 0x00000212 /// @} +#define MSR_IA32_MTRR_CACHE_UNCACHEABLE 0 +#define MSR_IA32_MTRR_CACHE_WRITE_COMBINING 1 +#define MSR_IA32_MTRR_CACHE_WRITE_THROUGH 4 +#define MSR_IA32_MTRR_CACHE_WRITE_PROTECTED 5 +#define MSR_IA32_MTRR_CACHE_WRITE_BACK 6 +#define MSR_IA32_MTRR_CACHE_INVALID_TYPE 7 + /** MSR information returned for MSR indexes #MSR_IA32_MTRR_PHYSBASE0 to #MSR_IA32_MTRR_PHYSBASE9 -- cgit From 71e6cc8dad2de85512de2fdd6439ae2ebada295d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 25 Jan 2024 08:38:00 +0100 Subject: UefiCpuPkg/MtrrLib.h: use cache type #defines from ArchitecturalMsr.h Signed-off-by: Gerd Hoffmann --- UefiCpuPkg/Include/Library/MtrrLib.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/UefiCpuPkg/Include/Library/MtrrLib.h b/UefiCpuPkg/Include/Library/MtrrLib.h index 86cc1aab3b..9d715d50df 100644 --- a/UefiCpuPkg/Include/Library/MtrrLib.h +++ b/UefiCpuPkg/Include/Library/MtrrLib.h @@ -9,6 +9,8 @@ #ifndef _MTRR_LIB_H_ #define _MTRR_LIB_H_ +#include + // // According to IA32 SDM, MTRRs number and MSR offset are always consistent // for IA32 processor family @@ -82,20 +84,20 @@ typedef struct _MTRR_SETTINGS_ { // Memory cache types // typedef enum { - CacheUncacheable = 0, - CacheWriteCombining = 1, - CacheWriteThrough = 4, - CacheWriteProtected = 5, - CacheWriteBack = 6, - CacheInvalid = 7 + CacheUncacheable = MSR_IA32_MTRR_CACHE_UNCACHEABLE, + CacheWriteCombining = MSR_IA32_MTRR_CACHE_WRITE_COMBINING, + CacheWriteThrough = MSR_IA32_MTRR_CACHE_WRITE_THROUGH, + CacheWriteProtected = MSR_IA32_MTRR_CACHE_WRITE_PROTECTED, + CacheWriteBack = MSR_IA32_MTRR_CACHE_WRITE_BACK, + CacheInvalid = MSR_IA32_MTRR_CACHE_INVALID_TYPE, } MTRR_MEMORY_CACHE_TYPE; -#define MTRR_CACHE_UNCACHEABLE 0 -#define MTRR_CACHE_WRITE_COMBINING 1 -#define MTRR_CACHE_WRITE_THROUGH 4 -#define MTRR_CACHE_WRITE_PROTECTED 5 -#define MTRR_CACHE_WRITE_BACK 6 -#define MTRR_CACHE_INVALID_TYPE 7 +#define MTRR_CACHE_UNCACHEABLE MSR_IA32_MTRR_CACHE_UNCACHEABLE +#define MTRR_CACHE_WRITE_COMBINING MSR_IA32_MTRR_CACHE_WRITE_COMBINING +#define MTRR_CACHE_WRITE_THROUGH MSR_IA32_MTRR_CACHE_WRITE_THROUGH +#define MTRR_CACHE_WRITE_PROTECTED MSR_IA32_MTRR_CACHE_WRITE_PROTECTED +#define MTRR_CACHE_WRITE_BACK MSR_IA32_MTRR_CACHE_WRITE_BACK +#define MTRR_CACHE_INVALID_TYPE MSR_IA32_MTRR_CACHE_INVALID_TYPE typedef struct { UINT64 BaseAddress; -- cgit From 78bccfec9ce5082499db035270e7998d5330d75c Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 25 Jan 2024 08:39:18 +0100 Subject: OvmfPkg/Sec: use cache type #defines from ArchitecturalMsr.h Signed-off-by: Gerd Hoffmann --- OvmfPkg/IntelTdx/Sec/SecMain.c | 2 +- OvmfPkg/Sec/SecMain.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c index 6eeae09e3b..95a31af029 100644 --- a/OvmfPkg/IntelTdx/Sec/SecMain.c +++ b/OvmfPkg/IntelTdx/Sec/SecMain.c @@ -69,7 +69,7 @@ SecMtrrSetup ( } DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); - DefType.Bits.Type = 6; /* write back */ + DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK; DefType.Bits.E = 1; /* enable */ AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); } diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index b0bb7b295d..c1c08a947a 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -765,7 +765,7 @@ SecMtrrSetup ( } DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); - DefType.Bits.Type = 6; /* write back */ + DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK; DefType.Bits.E = 1; /* enable */ AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); } -- cgit From dc002d4f2d76bdd826359a3dd608d9bc621fcb47 Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Thu, 20 Jun 2024 10:44:10 +0800 Subject: CryptoPkg: Fix wrong comment for CryptoPkg Fix the wrong comment. Cc: Jiewen Yao Cc: Yi Li Signed-off-by: Wenxing Hou --- CryptoPkg/Include/Library/BaseCryptLib.h | 18 +++++++++--------- CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 18 +++++++++--------- .../Library/BaseCryptLibMbedTls/InternalCryptLib.h | 4 ++-- .../BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c | 1 - CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c | 18 +++++++++--------- .../Library/BaseCryptLibMbedTls/Pk/CryptX509Null.c | 18 +++++++++--------- CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRand.c | 2 +- .../Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c | 2 +- 8 files changed, 40 insertions(+), 41 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index ac5841f1d9..95e4142f52 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2843,7 +2843,7 @@ X509GetKeyUsage ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize Size of the X509 certificate in bytes. @param[out] Usage Key Usage bytes. - @param[in, out] UsageSize Key Usage buffer sizs in bytes. + @param[in, out] UsageSize Key Usage buffer size in bytes. @retval TRUE The Usage bytes retrieve successfully. @retval FALSE If Cert is NULL. @@ -2870,12 +2870,12 @@ X509GetExtendedKeyUsage ( @param[in] RootCertLength Trusted Root Certificate buffer length @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. - @retval TRUE All cerificates was issued by the first certificate in X509Certchain. + @retval TRUE All certificates was issued by the first certificate in X509Certchain. @retval FALSE Invalid certificate or the certificate was not issued by the given trusted CA. **/ @@ -2893,9 +2893,9 @@ X509VerifyCertChain ( @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. @param[in] CertIndex Index of certificate. If index is -1 indecate the @@ -2943,7 +2943,7 @@ Asn1GetTag ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize size of the X509 certificate in bytes. @param[out] BasicConstraints basic constraints bytes. - @param[in, out] BasicConstraintsSize basic constraints buffer sizs in bytes. + @param[in, out] BasicConstraintsSize basic constraints buffer size in bytes. @retval TRUE The basic constraints retrieve successfully. @retval FALSE If cert is NULL. diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c index 021cc328f8..349d37b045 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c @@ -1391,7 +1391,7 @@ Cleanup: @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize Size of the X509 certificate in bytes. @param[out] Usage Key Usage bytes. - @param[in, out] UsageSize Key Usage buffer sizs in bytes. + @param[in, out] UsageSize Key Usage buffer size in bytes. @retval TRUE The Usage bytes retrieve successfully. @retval FALSE If Cert is NULL. @@ -1692,12 +1692,12 @@ _Exit: @param[in] RootCertLength Trusted Root Certificate buffer length @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. - @retval TRUE All cerificates was issued by the first certificate in X509Certchain. + @retval TRUE All certificates was issued by the first certificate in X509Certchain. @retval FALSE Invalid certificate or the certificate was not issued by the given trusted CA. **/ @@ -1775,9 +1775,9 @@ X509VerifyCertChain ( @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. @param[in] CertIndex Index of certificate. @@ -1922,7 +1922,7 @@ Asn1GetTag ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize size of the X509 certificate in bytes. @param[out] BasicConstraints basic constraints bytes. - @param[in, out] BasicConstraintsSize basic constraints buffer sizs in bytes. + @param[in, out] BasicConstraintsSize basic constraints buffer size in bytes. @retval TRUE The basic constraints retrieve successfully. @retval FALSE If cert is NULL. diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h index c9f19dd0cd..d3fa5ffc89 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h @@ -17,7 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include // -// We should alwasy add mbedtls/config.h here +// We should always add mbedtls/config.h here // to ensure the config override takes effect. // #include @@ -25,7 +25,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent /** The MbedTLS function f_rng, which MbedtlsRand implements. - @param[in] RngState Not used, just for compatibility with mbedlts. + @param[in] RngState Not used, just for compatibility with mbedtls. @param[out] Output Pointer to buffer to receive random value. @param[in] Len Size of random bytes to generate. diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c index 47a8230cf6..55110062c4 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c @@ -288,7 +288,6 @@ IsEkuInCertificate ( } Status = EFI_NOT_FOUND; - /*find the spdm hardware identity OID*/ for (Index = 0; Index <= Len - EkuLen; Index++) { if (!CompareMem (Buffer + Index, EKU, EkuLen)) { // check sub EKU diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c index 84b67c8f0a..f0727135ad 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c @@ -744,12 +744,12 @@ X509VerifyCert ( @param[in] RootCertLength Trusted Root Certificate buffer length @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. - @retval TRUE All cerificates was issued by the first certificate in X509Certchain. + @retval TRUE All certificates was issued by the first certificate in X509Certchain. @retval FALSE Invalid certificate or the certificate was not issued by the given trusted CA. **/ @@ -816,9 +816,9 @@ X509VerifyCertChain ( @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. @param[in] CertIndex Index of certificate. @@ -1592,7 +1592,7 @@ X509GetKeyUsage ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize Size of the X509 certificate in bytes. @param[out] Usage Key Usage bytes. - @param[in, out] UsageSize Key Usage buffer sizs in bytes. + @param[in, out] UsageSize Key Usage buffer size in bytes. @retval TRUE The Usage bytes retrieve successfully. @retval FALSE If Cert is NULL. @@ -1841,7 +1841,7 @@ X509CompareDateTime ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize size of the X509 certificate in bytes. @param[out] BasicConstraints basic constraints bytes. - @param[in, out] BasicConstraintsSize basic constraints buffer sizs in bytes. + @param[in, out] BasicConstraintsSize basic constraints buffer size in bytes. @retval TRUE The basic constraints retrieve successfully. @retval FALSE If cert is NULL. diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509Null.c index 96356f87fd..b927a6a755 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509Null.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509Null.c @@ -489,7 +489,7 @@ X509GetExtensionData ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize Size of the X509 certificate in bytes. @param[out] Usage Key Usage bytes. - @param[in, out] UsageSize Key Usage buffer sizs in bytes. + @param[in, out] UsageSize Key Usage buffer size in bytes. @retval TRUE The Usage bytes retrieve successfully. @retval FALSE If Cert is NULL. @@ -641,12 +641,12 @@ X509GetKeyUsage ( @param[in] RootCertLength Trusted Root Certificate buffer length @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. - @retval TRUE All cerificates was issued by the first certificate in X509Certchain. + @retval TRUE All certificates was issued by the first certificate in X509Certchain. @retval FALSE Invalid certificate or the certificate was not issued by the given trusted CA. **/ @@ -668,9 +668,9 @@ X509VerifyCertChain ( @param[in] CertChain One or more ASN.1 DER-encoded X.509 certificates where the first certificate is signed by the Root - Certificate or is the Root Cerificate itself. and - subsequent cerificate is signed by the preceding - cerificate. + Certificate or is the Root Certificate itself. and + subsequent certificate is signed by the preceding + certificate. @param[in] CertChainLength Total length of the certificate chain, in bytes. @param[in] CertIndex Index of certificate. @@ -725,7 +725,7 @@ Asn1GetTag ( @param[in] Cert Pointer to the DER-encoded X509 certificate. @param[in] CertSize size of the X509 certificate in bytes. @param[out] BasicConstraints basic constraints bytes. - @param[in, out] BasicConstraintsSize basic constraints buffer sizs in bytes. + @param[in, out] BasicConstraintsSize basic constraints buffer size in bytes. @retval TRUE The basic constraints retrieve successfully. @retval FALSE If cert is NULL. diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRand.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRand.c index e01aabc0de..94367327ca 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRand.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRand.c @@ -92,7 +92,7 @@ RandomBytes ( /** The MbedTLS function f_rng, which MbedtlsRand implements. - @param[in] RngState Not used, just for compatibility with mbedlts. + @param[in] RngState Not used, just for compatibility with mbedtls. @param[out] Output Pointer to buffer to receive random value. @param[in] Len Size of random bytes to generate. diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c index e01aabc0de..94367327ca 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Rand/CryptRandTsc.c @@ -92,7 +92,7 @@ RandomBytes ( /** The MbedTLS function f_rng, which MbedtlsRand implements. - @param[in] RngState Not used, just for compatibility with mbedlts. + @param[in] RngState Not used, just for compatibility with mbedtls. @param[out] Output Pointer to buffer to receive random value. @param[in] Len Size of random bytes to generate. -- cgit From 89377ece8f1c7243d25fd84488dcd03e37b9e661 Mon Sep 17 00:00:00 2001 From: Nhi Pham Date: Mon, 24 Jun 2024 12:22:52 +0700 Subject: MdeModulePkg/ImagePropertiesRecordLib: Reduce debug level The presense of PdbPointer (PDB file name) is not an error. Hence, the debug message should be categorized as VERBOSE or INFO. However, the DEBUG_VERBOSE is more appropriate since the PDB file name is already output by the PeCoffLoaderRelocateImageExtraAction() function with the inline "add-symbol-file" when a platform uses the library instance DebugPeCoffExtraActionLib. Signed-off-by: Nhi Pham --- .../Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c index 3ac043f980..08e3311d15 100644 --- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c @@ -1052,7 +1052,7 @@ CreateImagePropertiesRecord ( PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase); if (PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, " Image - %a\n", PdbPointer)); + DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); } // Check PE/COFF image -- cgit From ae09721a65ab3294439f6fa233adaf3b897f702f Mon Sep 17 00:00:00 2001 From: Gaurav Pandya Date: Wed, 20 Sep 2023 20:37:49 +0800 Subject: MdeModulePkg/DisplayEngineDxe: Support "^" and "V" key on pop-up form BZ #4790 Support "^" and "V" key stokes on the pop-up form. Align the implementation with key support on the regular HII form. Signed-off-by: Gaurav Pandya --- .../Universal/DisplayEngineDxe/InputHandler.c | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c index f70feeb55f..b6dc23476a 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c @@ -2,6 +2,7 @@ Implementation for handling user input from the User Interfaces. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -1568,6 +1569,47 @@ TheKey: break; + case '^': + if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { + // + // Highlight reaches the top of the popup window, scroll one menu item. + // + TopOptionIndex--; + ShowDownArrow = TRUE; + } + + if (TopOptionIndex == 0) { + ShowUpArrow = FALSE; + } + + if (HighlightOptionIndex > 0) { + HighlightOptionIndex--; + } + + break; + + case 'V': + case 'v': + if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && + (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) + { + // + // Highlight reaches the bottom of the popup window, scroll one menu item. + // + TopOptionIndex++; + ShowUpArrow = TRUE; + } + + if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { + ShowDownArrow = FALSE; + } + + if (HighlightOptionIndex < (PopUpMenuLines - 1)) { + HighlightOptionIndex++; + } + + break; + case CHAR_NULL: switch (Key.ScanCode) { case SCAN_UP: -- cgit From 6862b9d538d96363635677198899e1669e591259 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Jun 2024 09:07:56 +0200 Subject: NetworkPkg/DxeNetLib: adjust PseudoRandom error logging There is a list of allowed rng algorithms, if /one/ of them is not supported this is not a problem, only /all/ of them failing is an error condition. Downgrade the message for a single unsupported algorithm from ERROR to VERBOSE. Add an error message in case we finish the loop without finding a supported algorithm. Signed-off-by: Gerd Hoffmann --- NetworkPkg/Library/DxeNetLib/DxeNetLib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c index 01c13c08d2..4dfbe91a55 100644 --- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c @@ -951,7 +951,7 @@ PseudoRandom ( // // Secure Algorithm was not supported on this platform // - DEBUG ((DEBUG_ERROR, "Failed to generate random data using secure algorithm %d: %r\n", AlgorithmIndex, Status)); + DEBUG ((DEBUG_VERBOSE, "Failed to generate random data using secure algorithm %d: %r\n", AlgorithmIndex, Status)); // // Try the next secure algorithm @@ -971,6 +971,7 @@ PseudoRandom ( // If we get here, we failed to generate random data using any secure algorithm // Platform owner should ensure that at least one secure algorithm is supported // + DEBUG ((DEBUG_ERROR, "Failed to generate random data, no supported secure algorithm found\n")); ASSERT_EFI_ERROR (Status); return Status; } -- cgit From a5f147b2a31c093cc83a3f10cdda529c6b59799b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:12:31 +0000 Subject: pip: bump edk2-pytool-extensions from 0.27.5 to 0.27.6 Bumps [edk2-pytool-extensions](https://github.com/tianocore/edk2-pytool-extensions) from 0.27.5 to 0.27.6. - [Release notes](https://github.com/tianocore/edk2-pytool-extensions/releases) - [Commits](https://github.com/tianocore/edk2-pytool-extensions/compare/v0.27.5...v0.27.6) --- updated-dependencies: - dependency-name: edk2-pytool-extensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pip-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index 92d46e865f..7cee905ba4 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -13,7 +13,7 @@ ## edk2-pytool-library==0.21.5 -edk2-pytool-extensions==0.27.5 +edk2-pytool-extensions==0.27.6 edk2-basetools==0.1.51 antlr4-python3-runtime==4.7.1 lcov-cobertura==2.0.2 -- cgit From ed46e507e6d220b09e73fed936f50bd875024dab Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 20 Jun 2024 17:23:19 +0800 Subject: UefiCpuPkg/Library: Add MM_STANDALONE type for MmSaveStateLib Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf b/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf index b7fd4078f5..71d8e5e6d1 100644 --- a/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf +++ b/UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf @@ -16,7 +16,7 @@ FILE_GUID = 37E8137B-9F74-4250-8951-7A970A3C39C0 MODULE_TYPE = DXE_SMM_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = MmSaveStateLib + LIBRARY_CLASS = MmSaveStateLib|DXE_SMM_DRIVER MM_STANDALONE [Sources] MmSaveState.h -- cgit From dc3ed379dfb62ed720e46f10b6c6d0ebda6bde5f Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 20 Jun 2024 17:24:13 +0800 Subject: UefiCpuPkg/Library: Add MM_STANDALONE type for SmmCpuPlatformHookLib Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Dun Tan Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Yuanhao Xie --- .../Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf index fab6b30b7a..50eb74638b 100644 --- a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf +++ b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf @@ -18,7 +18,7 @@ FILE_GUID = D6494E1B-E06F-4ab5-B64D-48B25AA9EB33 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = SmmCpuPlatformHookLib + LIBRARY_CLASS = SmmCpuPlatformHookLib|DXE_SMM_DRIVER MM_STANDALONE # # The following information is for reference only and not required by the build tools. -- cgit From 3b2025969e6e8a2f6542996182cd4132868641c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:49:08 +0000 Subject: pip: bump edk2-pytool-library from 0.21.5 to 0.21.8 Bumps [edk2-pytool-library](https://github.com/tianocore/edk2-pytool-library) from 0.21.5 to 0.21.8. - [Release notes](https://github.com/tianocore/edk2-pytool-library/releases) - [Commits](https://github.com/tianocore/edk2-pytool-library/compare/v0.21.5...v0.21.8) --- updated-dependencies: - dependency-name: edk2-pytool-library dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pip-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index 7cee905ba4..e07b9cac52 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -12,7 +12,7 @@ # https://www.python.org/dev/peps/pep-0440/#version-specifiers ## -edk2-pytool-library==0.21.5 +edk2-pytool-library==0.21.8 edk2-pytool-extensions==0.27.6 edk2-basetools==0.1.51 antlr4-python3-runtime==4.7.1 -- cgit From 8c09d862bfb034e00b6b3bc37fe37243c866dd3a Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Wed, 26 Jun 2024 14:04:28 -0700 Subject: BaseTools: BinToPcd: Remove xdrlib dependency The xdrlib dependency was removed in commit 5cadb8ce2148979b6c464f6da5a8cd97425c5165 but the actual import of the module was not removed. This commit removes the import of xdrlib and sorts the imports. Signed-off-by: Joey Vagedes --- BaseTools/Scripts/BinToPcd.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/BaseTools/Scripts/BinToPcd.py b/BaseTools/Scripts/BinToPcd.py index 460c08b7f7..be726cc6d8 100644 --- a/BaseTools/Scripts/BinToPcd.py +++ b/BaseTools/Scripts/BinToPcd.py @@ -10,13 +10,12 @@ BinToPcd ''' from __future__ import print_function -import sys import argparse -import re -import xdrlib import io -import struct import math +import re +import struct +import sys # # Globals for help information -- cgit From 469d09d6b25f4ac83dd4ed511db45795aa09d45b Mon Sep 17 00:00:00 2001 From: Jeshua Smith Date: Fri, 3 May 2024 14:25:37 -0700 Subject: DynamicTablesPkg: AmlLib CONST cleanup Several input strings to AmlLib APIs are treated as CONST but were missing the CONST keyword, requiring their callers to create unnecessary r/w copies of r/o input strings. This change properly marks these input strings as CONST. Signed-off-by: Jeshua Smith Reviewed-by: Jeff Brasen --- DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h | 12 ++++++------ DynamicTablesPkg/Library/Common/AmlLib/Api/AmlApi.c | 2 +- DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c | 10 +++++----- .../Library/Common/AmlLib/NameSpace/AmlNameSpace.c | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h index 4427ab68fa..7c130736b4 100644 --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h @@ -339,7 +339,7 @@ EFI_STATUS EFIAPI AmlFindNode ( IN AML_NODE_HANDLE ReferenceNode, - IN CHAR8 *AslPath, + IN CONST CHAR8 *AslPath, OUT AML_NODE_HANDLE *OutNode ); @@ -374,7 +374,7 @@ EFI_STATUS EFIAPI AmlDeviceOpUpdateName ( IN AML_OBJECT_NODE_HANDLE DeviceOpNode, - IN CHAR8 *NewNameString + IN CONST CHAR8 *NewNameString ); /** Update an integer value defined by a NameOp object node. @@ -1090,7 +1090,7 @@ EFI_STATUS EFIAPI AmlCodeGenNameString ( IN CONST CHAR8 *NameString, - IN CHAR8 *String, + IN CONST CHAR8 *String, IN AML_NODE_HANDLE ParentNode OPTIONAL, OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL ); @@ -1613,7 +1613,7 @@ AmlAddLpiState ( IN UINT64 Integer OPTIONAL, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *ResidencyCounterRegister OPTIONAL, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *UsageCounterRegister OPTIONAL, - IN CHAR8 *StateName OPTIONAL, + IN CONST CHAR8 *StateName OPTIONAL, IN AML_OBJECT_NODE_HANDLE LpiNode ); @@ -1668,7 +1668,7 @@ AmlAddDeviceDataDescriptorPackage ( EFI_STATUS EFIAPI AmlAddNameIntegerPackage ( - IN CHAR8 *Name, + IN CONST CHAR8 *Name, IN UINT64 Value, IN AML_OBJECT_NODE_HANDLE PackageNode ); @@ -1739,7 +1739,7 @@ AmlCreateCpcNode ( EFI_STATUS EFIAPI AmlAddNameStringToNamedPackage ( - IN CHAR8 *NameString, + IN CONST CHAR8 *NameString, IN AML_OBJECT_NODE_HANDLE NamedNode ); diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Api/AmlApi.c b/DynamicTablesPkg/Library/Common/AmlLib/Api/AmlApi.c index 9f162abe2d..41643d5eee 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/Api/AmlApi.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/Api/AmlApi.c @@ -40,7 +40,7 @@ EFI_STATUS EFIAPI AmlDeviceOpUpdateName ( IN AML_OBJECT_NODE_HANDLE DeviceOpNode, - IN CHAR8 *NewNameString + IN CONST CHAR8 *NewNameString ) { EFI_STATUS Status; diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c index 89fa4e06f8..f433a461b2 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c @@ -139,7 +139,7 @@ STATIC EFI_STATUS EFIAPI AmlCodeGenString ( - IN CHAR8 *String, + IN CONST CHAR8 *String, OUT AML_OBJECT_NODE **NewObjectNode ) { @@ -664,7 +664,7 @@ EFI_STATUS EFIAPI AmlCodeGenNameString ( IN CONST CHAR8 *NameString, - IN CHAR8 *String, + IN CONST CHAR8 *String, IN AML_NODE_HEADER *ParentNode OPTIONAL, OUT AML_OBJECT_NODE **NewObjectNode OPTIONAL ) @@ -2615,7 +2615,7 @@ AmlAddLpiState ( IN UINT64 Integer OPTIONAL, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *ResidencyCounterRegister OPTIONAL, IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE *UsageCounterRegister OPTIONAL, - IN CHAR8 *StateName OPTIONAL, + IN CONST CHAR8 *StateName OPTIONAL, IN AML_OBJECT_NODE_HANDLE LpiNode ) { @@ -3204,7 +3204,7 @@ error_handler: EFI_STATUS EFIAPI AmlAddNameIntegerPackage ( - IN CHAR8 *Name, + IN CONST CHAR8 *Name, IN UINT64 Value, IN AML_OBJECT_NODE_HANDLE PackageNode ) @@ -3800,7 +3800,7 @@ error_handler: EFI_STATUS EFIAPI AmlAddNameStringToNamedPackage ( - IN CHAR8 *NameString, + IN CONST CHAR8 *NameString, IN AML_OBJECT_NODE_HANDLE NamedNode ) { diff --git a/DynamicTablesPkg/Library/Common/AmlLib/NameSpace/AmlNameSpace.c b/DynamicTablesPkg/Library/Common/AmlLib/NameSpace/AmlNameSpace.c index 9104b781d9..e871afef7f 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/NameSpace/AmlNameSpace.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/NameSpace/AmlNameSpace.c @@ -1234,7 +1234,7 @@ EFI_STATUS EFIAPI AmlBuildAbsoluteAmlPath ( IN AML_NODE_HEADER *ReferenceNode, - IN CHAR8 *AslPath, + IN CONST CHAR8 *AslPath, IN OUT AML_STREAM *RawAmlAbsSearchPathBStream ) { @@ -1373,7 +1373,7 @@ EFI_STATUS EFIAPI AmlFindNode ( IN AML_NODE_HEADER *ReferenceNode, - IN CHAR8 *AslPath, + IN CONST CHAR8 *AslPath, OUT AML_NODE_HEADER **OutNode ) { -- cgit From 8bf27965dbb94ecccc453c60de3270acf238ea3d Mon Sep 17 00:00:00 2001 From: Jeshua Smith Date: Wed, 26 Jun 2024 14:22:24 -0700 Subject: DynamicTablesPkg: AmlLib remove unnecessary cast Now that CONST input strings to the AmlLib APIs are properly marked as CONST we don't need to cast them to non-CONST before passing them. Signed-off-by: Jeshua Smith --- .../Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c | 2 +- .../Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c index b990686d40..6118df0549 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c @@ -372,7 +372,7 @@ FixupCmn600Info ( } // Update the CMN600 Device's name. - Status = AmlDeviceOpUpdateName (DeviceNode, (CHAR8 *)Name); + Status = AmlDeviceOpUpdateName (DeviceNode, Name); if (EFI_ERROR (Status)) { goto error_handler; } diff --git a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c index b1a628e419..f2594de2e9 100644 --- a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c +++ b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c @@ -381,7 +381,7 @@ FixupName ( } // Update the Device's name. - return AmlDeviceOpUpdateName (DeviceNode, (CHAR8 *)Name); + return AmlDeviceOpUpdateName (DeviceNode, Name); } /** Fixup the Serial Port Information in the AML tree. -- cgit From 5ab96f5437e03ddc0288771fdfd9e916cd755aac Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 23 May 2024 17:24:55 +0800 Subject: SecurityPkg: Add a new gEdkiiTpmInstanceHobGuid This new Guid HOB contains a TPM instance Guid which is the same as PcdTpmInstanceGuid. The HOB is used for StandaloneMm driver which needs to consume the dynamic PcdTpmInstanceGuid. Signed-off-by: Dun Tan --- SecurityPkg/SecurityPkg.dec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec index a91e3ea028..2c2153c19e 100644 --- a/SecurityPkg/SecurityPkg.dec +++ b/SecurityPkg/SecurityPkg.dec @@ -230,6 +230,10 @@ ## GUID used to generate Spdm Uid gEfiDeviceSecuritySpdmUidGuid = {0xe37b5665, 0x5ef9, 0x4e7e, {0xb4, 0x91, 0xd6, 0x78, 0xab, 0xff, 0xfb, 0xcb }} + ## GUID used to tag the HOB indicating the TPM instance. + ## The GUIDed HOB contains the same value as PcdGetPtr (PcdTpmInstanceGuid). + gEdkiiTpmInstanceHobGuid = { 0x4551b023, 0xba46, 0x4584, { 0x81, 0xcd, 0x4d, 0xe8, 0x61, 0xa7, 0x28, 0xbe } } + [Ppis] ## The PPI GUID for that TPM physical presence should be locked. # Include/Ppi/LockPhysicalPresence.h -- cgit From f9950cceecc12d40298b0287f193c6e6ddb9a14b Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 23 May 2024 17:30:45 +0800 Subject: SecurityPkg:Add new HOB for PhysicalPresenceInterfaceVersion Add a new gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid. This new Guid HOB contains a a string of the Version of Physical Presence interface which is the same as PcdTcgPhysicalPresenceInterfaceVer. The HOB is used for StandaloneMm driver which needs to consume the dynamic PcdTcgPhysicalPresenceInterfaceVer. Signed-off-by: Dun Tan --- SecurityPkg/SecurityPkg.dec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec index 2c2153c19e..65f3587c48 100644 --- a/SecurityPkg/SecurityPkg.dec +++ b/SecurityPkg/SecurityPkg.dec @@ -234,6 +234,10 @@ ## The GUIDed HOB contains the same value as PcdGetPtr (PcdTpmInstanceGuid). gEdkiiTpmInstanceHobGuid = { 0x4551b023, 0xba46, 0x4584, { 0x81, 0xcd, 0x4d, 0xe8, 0x61, 0xa7, 0x28, 0xbe } } + ## GUID used to tag the HOB indicating the Version of Physical Presence interface. + ## The GUIDed HOB contains the same value as PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer). + gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid = { 0x3979411a, 0x4e6d, 0x47e4, { 0x94, 0x4b, 0x0e, 0xcc, 0x6c, 0xf6, 0xc0, 0xcd } } + [Ppis] ## The PPI GUID for that TPM physical presence should be locked. # Include/Ppi/LockPhysicalPresence.h -- cgit From cb38d27f1dbbd787d3606f6314b5f33a5cb86646 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 24 May 2024 15:00:30 +0800 Subject: SecurityPkg/Tcg2ConfigPei: Build two new HOBs Build following two new HOBs: gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid gEdkiiTpmInstanceHobGuid The two HOBs will be used by Tcg2StandaloneMm driver to avoid using the related dynamic PCDs. Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf | 6 +++++- SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf index f2aa3234ad..b0c9c44e29 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf @@ -4,7 +4,7 @@ # This module initializes TPM device type based on variable and detection. # NOTE: This module is only for reference only, each platform should have its own setup page. # -# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -46,6 +46,7 @@ TimerLib Tpm12CommandLib Tpm12DeviceLib + HobLib [Guids] ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION" @@ -53,6 +54,8 @@ gTcg2ConfigFormSetGuid gEfiTpmDeviceSelectedGuid ## PRODUCES ## GUID # Used as a PPI GUID gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_CONSUMES ## GUID # TPM device identifier + gEdkiiTpmInstanceHobGuid + gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid [Ppis] gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES @@ -62,6 +65,7 @@ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PRODUCES gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy ## PRODUCES gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer [Depex] gEfiPeiMasterBootModePpiGuid AND diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c index 21a01f07e1..9840deb210 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c @@ -1,7 +1,7 @@ /** @file The module entry point for Tcg2 configuration module. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -73,6 +74,7 @@ Tcg2ConfigPeimEntryPoint ( TCG2_CONFIGURATION Tcg2Configuration; UINTN Index; UINT8 TpmDevice; + VOID *Hob; Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi); ASSERT_EFI_ERROR (Status); @@ -133,6 +135,26 @@ Tcg2ConfigPeimEntryPoint ( } } + // + // Build Hob for PcdTpmInstanceGuid + // + Hob = BuildGuidDataHob ( + &gEdkiiTpmInstanceHobGuid, + PcdGetPtr (PcdTpmInstanceGuid), + sizeof (EFI_GUID) + ); + ASSERT (Hob != NULL); + + // + // Build Hob for PcdTcgPhysicalPresenceInterfaceVer + // + Hob = BuildGuidDataHob ( + &gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid, + PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), + AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer)) + ); + ASSERT (Hob != NULL); + // // Selection done // -- cgit From 97ede07beb5eb09b1e3fe09c9ce0137a7425dc1e Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 24 May 2024 17:03:02 +0800 Subject: SecurityPkg/Tcg2StandaloneMm:Consume gEdkiiTpmInstanceHobGuid Consume gEdkiiTpmInstanceHobGuid in Tcg2StandaloneMm driver. It's to avoid using dynamic PcdTpmInstanceGuid in StandaloneMm driver. Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c | 4 ++-- SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h | 13 +++++++++++- SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c | 30 +++++++++++++++++++++++++++- SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf | 7 +++---- SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c | 16 ++++++++++++++- 5 files changed, 61 insertions(+), 9 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c index c47c582cc8..c2cef764e0 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c @@ -9,7 +9,7 @@ PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -285,7 +285,7 @@ InitializeTcgCommon ( EFI_HANDLE McSwHandle; EFI_HANDLE NotifyHandle; - if (!CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)) { + if (!IsTpm20Dtpm ()) { DEBUG ((DEBUG_ERROR, "No TPM2 DTPM instance required!\n")); return EFI_UNSUPPORTED; } diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h index 84b65eb089..3672db939b 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h @@ -1,7 +1,7 @@ /** @file The header file for Tcg2 SMM driver. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -84,4 +84,15 @@ InitializeTcgCommon ( VOID ); +/** + This function checks if the required DTPM instance is TPM 2.0. + + @retval TRUE The required DTPM instance is equal to gEfiTpmDeviceInstanceTpm20DtpmGuid. + @retval FALSE The required DTPM instance is not equal to gEfiTpmDeviceInstanceTpm20DtpmGuid. +**/ +BOOLEAN +IsTpm20Dtpm ( + VOID + ); + #endif // __TCG_SMM_H__ diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c index 77fa3691f4..9320053224 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c @@ -9,7 +9,7 @@ PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -17,6 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "Tcg2Smm.h" #include +#include /** Notify the system that the SMM variable driver is ready. @@ -47,6 +48,33 @@ IsBufferOutsideMmValid ( return MmIsBufferOutsideMmValid (Buffer, Length); } +/** + This function checks if the required DTPM instance is TPM 2.0. + + @retval TRUE The required DTPM instance is equal to gEfiTpmDeviceInstanceTpm20DtpmGuid. + @retval FALSE The required DTPM instance is not equal to gEfiTpmDeviceInstanceTpm20DtpmGuid. +**/ +BOOLEAN +IsTpm20Dtpm ( + VOID + ) +{ + VOID *GuidHob; + + GuidHob = GetFirstGuidHob (&gEdkiiTpmInstanceHobGuid); + if (GuidHob != NULL) { + if (CompareGuid ((EFI_GUID *)GET_GUID_HOB_DATA (GuidHob), &gEfiTpmDeviceInstanceTpm20DtpmGuid)) { + return TRUE; + } + + DEBUG ((DEBUG_ERROR, "No TPM2 DTPM instance required! - %g\n", (EFI_GUID *)GET_GUID_HOB_DATA (GuidHob))); + } else { + DEBUG ((DEBUG_ERROR, "No gEdkiiTpmInstanceHobGuid!\n")); + } + + return FALSE; +} + /** The driver's entry point. diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf index 746eda3e9f..bca59a539b 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.inf @@ -20,7 +20,7 @@ # This driver will have external input - variable and ACPINvs data in SMM mode. # This external input must be validated carefully to avoid security issue. # -# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -55,6 +55,7 @@ Tcg2PhysicalPresenceLib PcdLib MemLib + HobLib [Guids] ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl" @@ -63,15 +64,13 @@ gEfiTpmDeviceInstanceTpm20DtpmGuid ## PRODUCES ## GUID # TPM device identifier gTpmNvsMmGuid ## CONSUMES + gEdkiiTpmInstanceHobGuid [Protocols] gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES gEfiSmmVariableProtocolGuid ## CONSUMES gEfiMmReadyToLockProtocolGuid ## CONSUMES -[Pcd] - gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES - [Depex] gEfiSmmSwDispatch2ProtocolGuid AND gEfiSmmVariableProtocolGuid diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c index 514171cfac..f7d595e7f3 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c @@ -9,7 +9,7 @@ PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -58,6 +58,20 @@ IsBufferOutsideMmValid ( return SmmIsBufferOutsideSmmValid (Buffer, Length); } +/** + This function checks if the required DTPM instance is TPM 2.0. + + @retval TRUE The required DTPM instance is equal to gEfiTpmDeviceInstanceTpm20DtpmGuid. + @retval FALSE The required DTPM instance is not equal to gEfiTpmDeviceInstanceTpm20DtpmGuid. +**/ +BOOLEAN +IsTpm20Dtpm ( + VOID + ) +{ + return CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid); +} + /** The driver's entry point. -- cgit From add3ca4e0060cbf134f3c8559d5569bda24a5c9b Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 24 May 2024 17:41:40 +0800 Subject: SecurityPkg:Consume gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid Consume gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid in StandaloneMmTcg2PhysicalPresenceLib. This is to avoid using the dynamic PcdTcgPhysicalPresenceInterfaceVer in StandaloneMm module. Signed-off-by: Dun Tan --- .../MmTcg2PhysicalPresenceLibCommon.c | 20 +++------------- .../MmTcg2PhysicalPresenceLibCommon.h | 25 +++++++++++++++++++- .../SmmTcg2PhysicalPresenceLib.c | 16 ++++++++++++- .../StandaloneMmTcg2PhysicalPresenceLib.c | 27 +++++++++++++++++++++- .../StandaloneMmTcg2PhysicalPresenceLib.inf | 5 ++-- 5 files changed, 71 insertions(+), 22 deletions(-) diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c index f2ab4f1250..e8f3a7a274 100644 --- a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c +++ b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c @@ -10,24 +10,12 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction() will receive untrusted input and do validation. -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include - -#include - -#include - -#include -#include -#include -#include -#include - -#define PP_INF_VERSION_1_2 "1.2" +#include "MmTcg2PhysicalPresenceLibCommon.h" EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable; BOOLEAN mIsTcg2PPVerLowerThan_1_3 = FALSE; @@ -392,9 +380,7 @@ Tcg2PhysicalPresenceLibCommonConstructor ( { EFI_STATUS Status; - if (AsciiStrnCmp (PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), sizeof (PP_INF_VERSION_1_2) - 1) >= 0) { - mIsTcg2PPVerLowerThan_1_3 = TRUE; - } + mIsTcg2PPVerLowerThan_1_3 = IsTcg2PPVerLowerThan_1_3 (); // // Locate SmmVariableProtocol. diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.h b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.h index a0182739e9..4409c4daaa 100644 --- a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.h +++ b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.h @@ -10,7 +10,7 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction() will receive untrusted input and do validation. -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -18,6 +18,18 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _MM_TCG2_PHYSICAL_PRESENCE_LIB_COMMON_H_ #define _MM_TCG2_PHYSICAL_PRESENCE_LIB_COMMON_H_ +#include + +#include + +#include +#include +#include +#include +#include + +#define PP_INF_VERSION_1_2 "1.2" + /** The constructor function locates MmVariable protocol. @@ -31,4 +43,15 @@ Tcg2PhysicalPresenceLibCommonConstructor ( VOID ); +/** + Check if Tcg2 PP version is lower than PP_INF_VERSION_1_3. + + @retval TRUE Tcg2 PP version is lower than PP_INF_VERSION_1_3. + @retval Other Tcg2 PP version is not lower than PP_INF_VERSION_1_3. +**/ +BOOLEAN +IsTcg2PPVerLowerThan_1_3 ( + VOID + ); + #endif diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c index 36d8b89dcd..da89be35bd 100644 --- a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c +++ b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c @@ -10,7 +10,7 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction() will receive untrusted input and do validation. -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -39,3 +39,17 @@ Tcg2PhysicalPresenceLibTraditionalConstructor ( { return Tcg2PhysicalPresenceLibCommonConstructor (); } + +/** + Check if Tcg2 PP version is lower than PP_INF_VERSION_1_3. + + @retval TRUE Tcg2 PP version is lower than PP_INF_VERSION_1_3. + @retval Other Tcg2 PP version is not lower than PP_INF_VERSION_1_3. +**/ +BOOLEAN +IsTcg2PPVerLowerThan_1_3 ( + VOID + ) +{ + return (BOOLEAN)(AsciiStrnCmp (PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), sizeof (PP_INF_VERSION_1_2) - 1) >= 0); +} diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.c b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.c index 5c298a8d57..d1646d0b9d 100644 --- a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.c +++ b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.c @@ -10,7 +10,7 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction() will receive untrusted input and do validation. -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -18,6 +18,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include +#include + #include "MmTcg2PhysicalPresenceLibCommon.h" /** @@ -40,3 +42,26 @@ Tcg2PhysicalPresenceLibStandaloneMmConstructor ( { return Tcg2PhysicalPresenceLibCommonConstructor (); } + +/** + Check if Tcg2 PP version is lower than PP_INF_VERSION_1_3. + + @retval TRUE Tcg2 PP version is lower than PP_INF_VERSION_1_3. + @retval Other Tcg2 PP version is not lower than PP_INF_VERSION_1_3. +**/ +BOOLEAN +IsTcg2PPVerLowerThan_1_3 ( + VOID + ) +{ + VOID *GuidHob; + + GuidHob = GetFirstGuidHob (&gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid); + ASSERT (GuidHob != NULL); + + if (AsciiStrnCmp (PP_INF_VERSION_1_2, (CHAR8 *)GET_GUID_HOB_DATA (GuidHob), sizeof (PP_INF_VERSION_1_2) - 1) >= 0) { + return TRUE; + } + + return FALSE; +} diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf index 6d11b6b9f1..0d8d111792 100644 --- a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf +++ b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf @@ -7,7 +7,7 @@ # This driver will have external input - variable. # This external input must be validated carefully to avoid security issue. # -# Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -44,18 +44,19 @@ Tcg2PpVendorLib MmServicesTableLib BaseMemoryLib + HobLib [Guids] ## SOMETIMES_PRODUCES ## Variable:L"PhysicalPresence" ## SOMETIMES_CONSUMES ## Variable:L"PhysicalPresence" ## SOMETIMES_CONSUMES ## Variable:L"PhysicalPresenceFlags" gEfiTcg2PhysicalPresenceGuid + gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid [Protocols] gEfiSmmVariableProtocolGuid ## CONSUMES [Pcd] - gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer ## CONSUMES gEfiSecurityPkgTokenSpaceGuid.PcdTcg2PhysicalPresenceFlags ## SOMETIMES_CONSUMES [Depex] -- cgit From cb6ba975ae54f8eb915136264bf040d52d7bc2b4 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 3 Jun 2024 17:42:10 +0800 Subject: SecurityPkg: Add new gEdkiiTcg2AcpiCommunicateBufferHobGuid Add a new GUID HOB gEdkiiTcg2AcpiCommunicateBufferHobGuid. This Tcg2 Acpi Communicate Buffer HOB is used to store the address of a buffer reserved for Tcg2Acpi driver. The buffer will be used to retrive information from Standalone mm environment. Signed-off-by: Dun Tan --- .../Include/Guid/Tcg2AcpiCommunicateBuffer.h | 33 ++++++++++++++++++++++ SecurityPkg/SecurityPkg.dec | 3 ++ 2 files changed, 36 insertions(+) create mode 100644 SecurityPkg/Include/Guid/Tcg2AcpiCommunicateBuffer.h diff --git a/SecurityPkg/Include/Guid/Tcg2AcpiCommunicateBuffer.h b/SecurityPkg/Include/Guid/Tcg2AcpiCommunicateBuffer.h new file mode 100644 index 0000000000..c1d8c2d6f5 --- /dev/null +++ b/SecurityPkg/Include/Guid/Tcg2AcpiCommunicateBuffer.h @@ -0,0 +1,33 @@ +/** @file + This Tcg2 Acpi Communicate Buffer HOB is used to store the address + of a buffer reserved for Tcg2Acpi driver. The buffer will be used to + retrive information from standalone mm environment. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef TCG2_ACPI_COMMUNICATE_BUFFER_H_ +#define TCG2_ACPI_COMMUNICATE_BUFFER_H_ + +#define TCG2_ACPI_COMMUNICATE_BUFFER_HOB_REVISION 1 + +#define TCG2_ACPI_COMMUNICATE_BUFFER_GUID \ + { \ + 0xcefea14f, 0x9f1a, 0x4774, {0x8d, 0x18, 0x79, 0x93, 0x8d, 0x48, 0xfe, 0x7d} \ + } + +typedef struct { + /// + /// Base address of the buffer reserved for Tcg2Acpi driver. + /// Tcg2Acpi will use it to exchange information with Tcg2StandaloneMm. + /// + EFI_PHYSICAL_ADDRESS Tcg2AcpiCommunicateBuffer; + UINT64 Pages; +} TCG2_ACPI_COMMUNICATE_BUFFER; + +extern EFI_GUID gEdkiiTcg2AcpiCommunicateBufferHobGuid; + +#endif diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec index 65f3587c48..1fa9a567da 100644 --- a/SecurityPkg/SecurityPkg.dec +++ b/SecurityPkg/SecurityPkg.dec @@ -238,6 +238,9 @@ ## The GUIDed HOB contains the same value as PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer). gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid = { 0x3979411a, 0x4e6d, 0x47e4, { 0x94, 0x4b, 0x0e, 0xcc, 0x6c, 0xf6, 0xc0, 0xcd } } + ## Include/Guid/Tcg2AcpiCommunicateBuffer.h + gEdkiiTcg2AcpiCommunicateBufferHobGuid = { 0xcefea14f, 0x9f1a, 0x4774, { 0x8d, 0x18, 0x79, 0x93, 0x8d, 0x48, 0xfe, 0x7d } } + [Ppis] ## The PPI GUID for that TPM physical presence should be locked. # Include/Ppi/LockPhysicalPresence.h -- cgit From 9a76c7945b762ed8abed3b917aa6217846ae1918 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 4 Jun 2024 09:52:52 +0800 Subject: SecurityPkg: Build gEdkiiTcg2AcpiCommunicateBufferHobGuid Install a callback of gEfiPeiMemoryDiscoveredPpiGuid to build the gEdkiiTcg2AcpiCommunicateBufferHobGuid in the Tcg2ConfigPei PEIM. The HOB contains a buffer reserved by MmUnblockMemoryLib. The buffer will be used in Tcg2Acpi driver to retrive information from standalone mm environment. Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf | 3 ++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c | 52 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf index b0c9c44e29..f7213b2780 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf @@ -47,6 +47,7 @@ Tpm12CommandLib Tpm12DeviceLib HobLib + MmUnblockMemoryLib [Guids] ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION" @@ -56,10 +57,12 @@ gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_CONSUMES ## GUID # TPM device identifier gEdkiiTpmInstanceHobGuid gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid + gEdkiiTcg2AcpiCommunicateBufferHobGuid [Ppis] gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid [Pcd] gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PRODUCES diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c index 9840deb210..ce78e32537 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include +#include #include #include @@ -17,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -51,6 +54,53 @@ DetectTpmDevice ( IN UINT8 SetupTpmDevice ); +/** + Build gEdkiiTcg2AcpiCommunicateBufferHobGuid. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. + @retval others Failed to build Tcg2AcpiCommunicateBuffer Hob. + +**/ +EFI_STATUS +EFIAPI +BuildTcg2AcpiCommunicateBufferHob ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + TCG2_ACPI_COMMUNICATE_BUFFER *Tcg2AcpiCommunicateBufferHob; + EFI_STATUS Status; + VOID *Buffer; + UINTN Pages; + + Pages = sizeof (TCG_NVS); + Buffer = AllocateRuntimePages (Pages); + ASSERT (Buffer != NULL); + + Status = MmUnblockMemoryRequest ((UINTN)Buffer, Pages); + if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { + return Status; + } + + Tcg2AcpiCommunicateBufferHob = BuildGuidHob (&gEdkiiTcg2AcpiCommunicateBufferHobGuid, sizeof (TCG2_ACPI_COMMUNICATE_BUFFER)); + ASSERT (Tcg2AcpiCommunicateBufferHob != NULL); + Tcg2AcpiCommunicateBufferHob->Tcg2AcpiCommunicateBuffer = (UINTN)Buffer; + Tcg2AcpiCommunicateBufferHob->Pages = Pages; + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mPostMemNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + BuildTcg2AcpiCommunicateBufferHob +}; + /** The entry point for Tcg2 configuration driver. @@ -155,6 +205,8 @@ Tcg2ConfigPeimEntryPoint ( ); ASSERT (Hob != NULL); + PeiServicesNotifyPpi (&mPostMemNotifyList); + // // Selection done // -- cgit From e939ecf6c19f932535d073e383d016e8bf2e8ee7 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 4 Jun 2024 10:26:49 +0800 Subject: SecurityPkg: Consume gEdkiiTcg2AcpiCommunicateBufferHobGuid Consume gEdkiiTcg2AcpiCommunicateBufferHobGuid in Tcg2Acpi driver. Tcg2Acpi will use the buffer stored in the HOB to exchange information with Tcg2StandaloneMm by the MM_COMMUNICATION_PROTOCOL. Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c | 28 +++++++++++++++------------- SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf | 5 +++-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c index 76123fc51a..5addd2f563 100644 --- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c @@ -9,7 +9,7 @@ This driver will have external input - variable and ACPINvs data in SMM mode. This external input must be validated carefully to avoid security issue. -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -38,7 +39,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include // // Physical Presence Interface Version supported by Platform @@ -116,7 +117,7 @@ TCG_NVS *mTcgNvs; @param[in] Name The name string to find in TPM table. @param[in] Size The size of the region to find. - @return The allocated address for the found region. + @return The Acpi Communicate Buffer for the found region. **/ VOID * @@ -126,9 +127,10 @@ AssignOpRegion ( UINT16 Size ) { - EFI_STATUS Status; - AML_OP_REGION_32_8 *OpRegion; - EFI_PHYSICAL_ADDRESS MemoryAddress; + AML_OP_REGION_32_8 *OpRegion; + EFI_PHYSICAL_ADDRESS MemoryAddress; + EFI_HOB_GUID_TYPE *GuidHob; + TCG2_ACPI_COMMUNICATE_BUFFER *Tcg2AcpiCommunicateBufferHob; MemoryAddress = SIZE_4GB - 1; @@ -144,16 +146,16 @@ AssignOpRegion ( (OpRegion->DWordPrefix == AML_DWORD_PREFIX) && (OpRegion->BytePrefix == AML_BYTE_PREFIX)) { - Status = gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress); - ASSERT_EFI_ERROR (Status); + GuidHob = GetFirstGuidHob (&gEdkiiTcg2AcpiCommunicateBufferHobGuid); + ASSERT (GuidHob != NULL); + Tcg2AcpiCommunicateBufferHob = GET_GUID_HOB_DATA (GuidHob); + MemoryAddress = Tcg2AcpiCommunicateBufferHob->Tcg2AcpiCommunicateBuffer; + ASSERT (MemoryAddress != 0); + ASSERT (EFI_PAGES_TO_SIZE (Tcg2AcpiCommunicateBufferHob->Pages) >= Size); + ZeroMem ((VOID *)(UINTN)MemoryAddress, Size); OpRegion->RegionOffset = (UINT32)(UINTN)MemoryAddress; OpRegion->RegionLen = (UINT8)Size; - // Request to unblock this region from MM core - Status = MmUnblockMemoryRequest (MemoryAddress, EFI_SIZE_TO_PAGES (Size)); - if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - } break; } diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf index f1c6ae5b1c..d7686251f4 100644 --- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf @@ -22,7 +22,7 @@ # This driver will have external input - variable and ACPINvs data in SMM mode. # This external input must be validated carefully to avoid security issue. # -# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -57,12 +57,13 @@ Tpm2CommandLib Tcg2PhysicalPresenceLib PcdLib - MmUnblockMemoryLib + HobLib [Guids] gEfiTpmDeviceInstanceTpm20DtpmGuid ## PRODUCES ## GUID # TPM device identifier gTpmNvsMmGuid ## CONSUMES gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES + gEdkiiTcg2AcpiCommunicateBufferHobGuid [Protocols] gEfiAcpiTableProtocolGuid ## CONSUMES -- cgit From b2216427ca7b0d31a36616e2876d362629de926d Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Tue, 2 Jul 2024 09:58:23 +0100 Subject: EmbeddedPkg/.ci.yaml: add temporary workaround ECC exception A new contributor has a name not describable by the character set developed for 1960s US teleprinters, causing the CI to object and blocking their code from being merged due to the copyright statement. While we do want to keep the code clean from characters other contributors cannot trivially reproduce, this should not extend to requiring intentionally misstating legal claims. Until we figure out the long-term fix, add an exception for the surname triggering the failure. Signed-off-by: Leif Lindholm --- EmbeddedPkg/EmbeddedPkg.ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/EmbeddedPkg/EmbeddedPkg.ci.yaml b/EmbeddedPkg/EmbeddedPkg.ci.yaml index 6d042fc721..f4956e679d 100644 --- a/EmbeddedPkg/EmbeddedPkg.ci.yaml +++ b/EmbeddedPkg/EmbeddedPkg.ci.yaml @@ -20,6 +20,7 @@ ## "", "" ## ] "ExceptionList": [ + "1008", "Bălănică" ], ## Both file path and directory path are accepted. "IgnoreFiles": [] -- cgit From ff1c4fa1680d3f9a5f2be3e0048d2de15a5846fb Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Thu, 6 Jun 2024 17:33:45 +0000 Subject: MdePkg: UefiTcgPlatform.h updates The TCG_Sp800_155_PlatformId_Event2 and 3 structures both list the platform model string twice, which is incorrect according to the TCG PC Client Platform Firmware Profile. Also add constant definitions for the locator types added in the December 2023 revision. Signed-off-by: Dionna Glaze --- MdePkg/Include/IndustryStandard/UefiTcgPlatform.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h b/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h index aaee5d6c88..1b7b2406e9 100644 --- a/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h +++ b/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h @@ -473,8 +473,6 @@ typedef struct tdTCG_Sp800_155_PlatformId_Event2 { // UINT8 PlatformModel[PlatformModelSize]; // UINT8 PlatformVersionSize; // UINT8 PlatformVersion[PlatformVersionSize]; - // UINT8 PlatformModelSize; - // UINT8 PlatformModel[PlatformModelSize]; // UINT8 FirmwareManufacturerStrSize; // UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize]; // UINT32 FirmwareManufacturerId; @@ -499,8 +497,6 @@ typedef struct tdTCG_Sp800_155_PlatformId_Event3 { // UINT8 PlatformModel[PlatformModelSize]; // UINT8 PlatformVersionSize; // UINT8 PlatformVersion[PlatformVersionSize]; - // UINT8 PlatformModelSize; - // UINT8 PlatformModel[PlatformModelSize]; // UINT8 FirmwareManufacturerStrSize; // UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize]; // UINT32 FirmwareManufacturerId; @@ -517,6 +513,18 @@ typedef struct tdTCG_Sp800_155_PlatformId_Event3 { // UINT8 PlatformCertLocator[PlatformCertLocatorLength]; } TCG_Sp800_155_PlatformId_Event3; +/** + * TCG specifies a locator type with the following values + * 0 - Raw data in the locator itself. + * 1 - URI in rtf2396 format. + * 2 - local device path in EFI_DEVICE_PATH_PROTOCOL format. + * 3 - UEFI variable (16 byte EFI_GUID, then 00-terminated UCS2 string) +**/ +#define TCG_LOCATOR_TYPE_RAW_DATA 0 +#define TCG_LOCATOR_TYPE_URI 1 +#define TCG_LOCATOR_TYPE_DEVICE_PATH 2 +#define TCG_LOCATOR_TYPE_UEFI_VARIABLE 3 + #define TCG_EfiStartupLocalityEvent_SIGNATURE "StartupLocality" // -- cgit From 6b256cef01825fd597ce31ec9343ea280c6114c9 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Tue, 4 Jun 2024 17:22:53 +0000 Subject: OvmfPkg: Create SP800155 HOBs from QemuFwCfgFile Signed firmware measurements are allowed to be passed along to in the TCG and CC event logs according to the TCG PC Client Platform Firware Profile. The event logs include events that Tcg2Dxe reads from appropriately GUIDed HOBs, so allow opt/org.tianocode/sp800155evt/%d to pass along events that the VMM sees fit to provide. One event per number, starting from 0, increasing by 1 until there are no more contiguous files. The VMM may provide reference measurements through UEFI variables that it references from the SP800-155 event3 structure given the appropriate RIM locator type, or via URL, etc. Each event read from fw_cfg, is written one-by-one to a EFI_HOB_GUID_TYPE HOB created for the event. The name they target gTcg800155PlatformIdEventHobGuid for the later Dxe driver to use to extend the event log. Signed-off-by: Dionna Glaze --- OvmfPkg/PlatformPei/Platform.c | 2 + OvmfPkg/PlatformPei/PlatformId.c | 124 ++++++++++++++++++++++++++++++++++++ OvmfPkg/PlatformPei/PlatformId.h | 26 ++++++++ OvmfPkg/PlatformPei/PlatformPei.inf | 4 +- 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 OvmfPkg/PlatformPei/PlatformId.c create mode 100644 OvmfPkg/PlatformPei/PlatformId.h diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index df35726ff6..0114529778 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -40,6 +40,7 @@ #include #include "Platform.h" +#include "PlatformId.h" EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = { { @@ -363,6 +364,7 @@ InitializePlatform ( MiscInitializationForMicrovm (PlatformInfoHob); } else { MiscInitialization (PlatformInfoHob); + PlatformIdInitialization (PeiServices); } IntelTdxInitialize (); diff --git a/OvmfPkg/PlatformPei/PlatformId.c b/OvmfPkg/PlatformPei/PlatformId.c new file mode 100644 index 0000000000..afa2f811d9 --- /dev/null +++ b/OvmfPkg/PlatformPei/PlatformId.c @@ -0,0 +1,124 @@ +/**@file + PlatformId Event HOB creation + + Copyright (c) 2024, Google LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPREFIX "sp800155evts: " + +/** + * Creates an EFI_HOB_TYPE_GUID_EXTENSION HOB for a given SP800155 event. + * Associates the string data with gTcg800155PlatformIdEventHobGuid. Any + * unused bytes or out-of-bounds event sizes are considered corrupted and + * are discarded. +**/ +STATIC +VOID +PlatformIdRegisterSp800155 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT8 *Evt, + IN UINTN EvtSize + ) +{ + EFI_STATUS Status; + VOID *Hob; + EFI_HOB_GUID_TYPE *GuidHob; + UINT8 *EvtDest; + + Status = (*PeiServices)->CreateHob ( + PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + sizeof (EFI_HOB_GUID_TYPE) + (UINT16)EvtSize, + &Hob + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, DPREFIX "GUID HOB creation failed, skipping\n")); + return; + } + + GuidHob = (EFI_HOB_GUID_TYPE *)Hob; + CopyGuid (&GuidHob->Name, &gTcg800155PlatformIdEventHobGuid); + EvtDest = (UINT8 *)GET_GUID_HOB_DATA (Hob); + CopyMem (EvtDest, Evt, EvtSize); + // Fill the remaining HOB padding bytes with 0s. + SetMem (EvtDest + EvtSize, GET_GUID_HOB_DATA_SIZE (Hob) - EvtSize, 0); +} + +/** + * Reads the given path from the fw_cfg file and registers it as an + * EFI_HOB_GUID_EXTENSION HOB with gTcg800155PlatformIdEventHobGuid. + * Returns FALSE iff the file does not exist. +**/ +BOOLEAN +PlatformIdRegisterEvent ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST CHAR8 *Path + ) +{ + EFI_STATUS Status; + UINTN NumPages; + EFI_PHYSICAL_ADDRESS Pages; + FIRMWARE_CONFIG_ITEM FdtItem; + UINTN FdtSize; + UINT8 *Evt; + + Status = QemuFwCfgFindFile (Path, &FdtItem, &FdtSize); + if (EFI_ERROR (Status)) { + return FALSE; + } + + if (FdtSize > MAX_UINT16 - sizeof (EFI_HOB_GUID_TYPE)) { + DEBUG ((DEBUG_ERROR, DPREFIX "Eventdata too large for HOB, skipping\n")); + return TRUE; + } + + NumPages = EFI_SIZE_TO_PAGES (FdtSize); + Status = (*PeiServices)->AllocatePages ( + PeiServices, + EfiBootServicesData, + NumPages, + &Pages + ); + if (EFI_ERROR (Status)) { + return TRUE; + } + + Evt = (UINT8 *)(UINTN)Pages; + QemuFwCfgSelectItem (FdtItem); + QemuFwCfgReadBytes (FdtSize, Evt); + PlatformIdRegisterSp800155 (PeiServices, Evt, FdtSize); + + Status = (*PeiServices)->FreePages (PeiServices, Pages, NumPages); + ASSERT_EFI_ERROR (Status); + return TRUE; +} + +VOID +PlatformIdInitialization ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINTN Index; + CHAR8 Path[64]; + + for (Index = 0; ; Index++) { + AsciiSPrint (Path, sizeof (Path), "opt/org.tianocode/sp800155evt/%d", Index); + if (!PlatformIdRegisterEvent (PeiServices, Path)) { + break; + } + } +} diff --git a/OvmfPkg/PlatformPei/PlatformId.h b/OvmfPkg/PlatformPei/PlatformId.h new file mode 100644 index 0000000000..c8b55288c4 --- /dev/null +++ b/OvmfPkg/PlatformPei/PlatformId.h @@ -0,0 +1,26 @@ +/** @file + PlatformId internal header for PlatformPei + + Copyright (c) 2024, Google LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PLATFORM_PEI_PLATFORMID_H__ +#define __PLATFORM_PEI_PLATFORMID_H__ + +/** + * Reads opt/org.tianocode/sp800155evt/%d from 0 to the first positive integer + * where the file does not exist and registers each file's contents in an + * EFI_HOB_GUID_TYPE with name gTcg800155PlatformIdEventHobGuid. These HOBs + * are used by a later driver to write to the event log as unmeasured events. + * These events inform the event log analyzer of firmware provenance and + * reference integrity manifests. +**/ +VOID +PlatformIdInitialization ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +#endif // __PLATFORM_PEI_PLATFORMID_H__ diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index e036018eab..0bb1a46291 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -31,6 +31,8 @@ MemTypeInfo.c Platform.c Platform.h + PlatformId.c + PlatformId.h IntelTdx.c SmmRelocation.c @@ -47,6 +49,7 @@ gFdtHobGuid gUefiOvmfPkgPlatformInfoGuid gGhcbApicIdsGuid + gTcg800155PlatformIdEventHobGuid ## SOMETIMES_PRODUCES [LibraryClasses] BaseLib @@ -148,4 +151,3 @@ [Depex] TRUE - -- cgit From 4f174696fd8fbd9cc29c9f172e8e83fe6da5b070 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Thu, 27 Jun 2024 08:43:48 -0700 Subject: .pytool: CompilerPlugin: Pass through build vars Pass build variables (those passed to build.py through -D) to the DSC parser to provide a more accurate parsing of the DSC file. Signed-off-by: Joey Vagedes --- .pytool/Plugin/CompilerPlugin/CompilerPlugin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.pytool/Plugin/CompilerPlugin/CompilerPlugin.py b/.pytool/Plugin/CompilerPlugin/CompilerPlugin.py index 3cf3888828..01101b2f4a 100644 --- a/.pytool/Plugin/CompilerPlugin/CompilerPlugin.py +++ b/.pytool/Plugin/CompilerPlugin/CompilerPlugin.py @@ -74,9 +74,10 @@ class CompilerPlugin(ICiBuildPlugin): self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin") # Parse DSC to check for SUPPORTED_ARCHITECTURES + build_target = self._env.GetValue("TARGET") + input_vars = self._env.GetAllBuildKeyValues(build_target) dp = DscParser() - dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath) - dp.SetPackagePaths(Edk2pathObj.PackagePathList) + dp.SetEdk2Path(Edk2pathObj).SetInputVars(input_vars) dp.ParseFile(AP_Path) if "SUPPORTED_ARCHITECTURES" in dp.LocalVars: SUPPORTED_ARCHITECTURES = dp.LocalVars["SUPPORTED_ARCHITECTURES"].split('|') @@ -85,7 +86,7 @@ class CompilerPlugin(ICiBuildPlugin): # Skip if there is no intersection between SUPPORTED_ARCHITECTURES and TARGET_ARCHITECTURES if len(set(SUPPORTED_ARCHITECTURES) & set(TARGET_ARCHITECTURES)) == 0: tc.SetSkipped() - tc.LogStdError("No supported architecutres to build") + tc.LogStdError("No supported architectures to build") return -1 uefiBuilder = UefiBuilder() -- cgit From ed07a2bb11b358fdece44a760fc193d56f22cfb2 Mon Sep 17 00:00:00 2001 From: Britton Chesley Date: Tue, 16 May 2023 15:40:50 -0500 Subject: MdeModulePkg/UsbBusDxe: USB issue fix when the port reset BZ #4456 Fixed a bug which led to an ASSERT due to the USB device context being maintained after a port reset, but the underlying XHCI context was uninitialized. Specifically, Xhc->UsbDevContext is freed after a reset and only re-allocates the default [0] enpoint transfer ring. In order to avoid a memory leak, device enumeration is performed after freeing the necessary buffers. This allocates the Xhc->UsbDevContext for all endpoints of the USB device. Signed-off-by: Britton Chesley --- MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c index c25f3cc2f2..2826ac130e 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c @@ -3,6 +3,7 @@ Usb Bus Driver Binding and Bus IO Protocol. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -821,6 +822,7 @@ UsbIoPortReset ( EFI_TPL OldTpl; EFI_STATUS Status; UINT8 DevAddress; + UINT8 Config; OldTpl = gBS->RaiseTPL (USB_BUS_TPL); @@ -882,8 +884,26 @@ UsbIoPortReset ( // is in CONFIGURED state. // if (Dev->ActiveConfig != NULL) { - Status = UsbSetConfig (Dev, Dev->ActiveConfig->Desc.ConfigurationValue); + UsbFreeDevDesc (Dev->DevDesc); + Status = UsbRemoveConfig (Dev); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to remove configuration - %r\n", Status)); + } + + Status = UsbGetMaxPacketSize0 (Dev); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to get max packet size - %r\n", Status)); + } + + Status = UsbBuildDescTable (Dev); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to build descriptor table - %r\n", Status)); + } + + Config = Dev->DevDesc->Configs[0]->Desc.ConfigurationValue; + + Status = UsbSetConfig (Dev, Config); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, @@ -892,6 +912,11 @@ UsbIoPortReset ( Status )); } + + Status = UsbSelectConfig (Dev, Config); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to set configuration - %r\n", Status)); + } } ON_EXIT: -- cgit From 592725d2291b9844cfd9187111e904c6383e2000 Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Tue, 25 Jun 2024 10:11:06 -0700 Subject: DscCompleteCheck: Allow git ignore syntax Allows ignore lines in the CI YAML file to use git ignore syntax. This is especially useful for ignore files recursively in directories like those that may exist in an external dependency folder. Co-authored-by: Michael Kubacki Signed-off-by: Joey Vagedes --- .../Plugin/DscCompleteCheck/DscCompleteCheck.py | 53 ++++++++++++++++------ .pytool/Plugin/DscCompleteCheck/Readme.md | 3 +- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py b/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py index 351137c5e4..14f99330f6 100644 --- a/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py +++ b/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py @@ -6,9 +6,12 @@ import logging import os from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin +from edk2toollib.uefi.edk2.path_utilities import Edk2Path from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser from edk2toolext.environment.var_dict import VarDict +from edk2toollib.gitignore_parser import parse_gitignore_lines +from pathlib import Path class DscCompleteCheck(ICiBuildPlugin): @@ -71,38 +74,39 @@ class DscCompleteCheck(ICiBuildPlugin): # Get INF Files INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path) - INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath( - x) for x in INFFiles] # make edk2relative path so can compare with DSC # remove ignores - + ignored_paths = [] if "IgnoreInf" in pkgconfig: - for a in pkgconfig["IgnoreInf"]: - a = a.replace(os.sep, "/") + ignore_filter = parse_gitignore_lines( + pkgconfig["IgnoreInf"], + "DSC Complete Check Config", + os.path.dirname(abs_pkg_path)) + + # INFFiles must be a list of absolute paths + ignored_paths = list(filter(ignore_filter, INFFiles)) + for a in ignored_paths: try: tc.LogStdOut("Ignoring INF {0}".format(a)) INFFiles.remove(a) - except: + except Exception: tc.LogStdError( "DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a)) logging.info( "DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a)) + # make edk2relative path so can compare with DSC + INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles] + # DSC Parser - dp = DscParser() - dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath) - dp.SetPackagePaths(Edk2pathObj.PackagePathList) + dp = DscParser().SetEdk2Path(Edk2pathObj) dp.SetInputVars(environment.GetAllBuildKeyValues()) dp.ParseFile(wsr_dsc_path) # Check if INF in component section for INF in INFFiles: - if not any(INF.strip() in x for x in dp.ThreeMods) and \ - not any(INF.strip() in x for x in dp.SixMods) and \ - not any(INF.strip() in x for x in dp.OtherMods): - - infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath) - infp.SetPackagePaths(Edk2pathObj.PackagePathList) + if not DscCompleteCheck._module_in_dsc(INF, dp, Edk2pathObj): + infp = InfParser().SetEdk2Path(Edk2pathObj) infp.ParseFile(INF) if("MODULE_TYPE" not in infp.Dict): tc.LogStdOut( @@ -131,3 +135,22 @@ class DscCompleteCheck(ICiBuildPlugin): else: tc.SetSuccess() return overall_status + + @staticmethod + def _module_in_dsc(inf: str, dsc: DscParser, Edk2pathObj: Edk2Path) -> bool: + + """Checks if the given module (inf) is in the given dsc. + Args: + inf (str): The inf file to check for + dsc (DscParser): The parsed dsc file. + Edk2pathObj (Edk2Path): The path object capturing the workspace and package paths. + Returns: + bool: if the module is in the dsc. + """ + for module_type in (dsc.ThreeMods, dsc.SixMods, dsc.OtherMods): + for module in module_type: + if Path(module).is_absolute(): + module = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(module) + if inf in module: + return True + return False diff --git a/.pytool/Plugin/DscCompleteCheck/Readme.md b/.pytool/Plugin/DscCompleteCheck/Readme.md index 8aaa4f76ee..9f7291b747 100644 --- a/.pytool/Plugin/DscCompleteCheck/Readme.md +++ b/.pytool/Plugin/DscCompleteCheck/Readme.md @@ -29,4 +29,5 @@ Path to DSC to consider platform dsc ### IgnoreInf -Ignore error if Inf file is not listed in DSC file +A list of paths in git ignore syntax to ignore in the check. These can include directory and file paths. The path is +relative to the directory that contains the package. -- cgit From 6b9307192bf590b3136e690a07196d4255051fdc Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Tue, 12 Mar 2024 14:18:14 -0700 Subject: BaseTools: InfBuildData: Fix Private value retrieval Update retrieval of private guids, protocols, or ppis from a package's declaration file to use the original path of the module's INF file rather than the current path. When building the same module multiple times in the same INF (by override the define's FILE_GUID), a temporary instance of the module is generated outside the package, causing the retrieval of private values to fail as the check to access private values is done by verifying the module to build, is inside the package. Signed-off-by: Joey Vagedes Cc: Rebecca Cran Cc: Liming Gao Cc: Bob Feng Cc: Yuwei Chen --- BaseTools/Source/Python/Workspace/InfBuildData.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py index e4ff1c6686..6339e494ca 100644 --- a/BaseTools/Source/Python/Workspace/InfBuildData.py +++ b/BaseTools/Source/Python/Workspace/InfBuildData.py @@ -592,7 +592,7 @@ class InfBuildData(ModuleBuildClassObject): RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform] for Record in RecordList: CName = Record[0] - Value = _ProtocolValue(CName, self.Packages, self.MetaFile.Path) + Value = _ProtocolValue(CName, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: PackageList = "\n\t".join(str(P) for P in self.Packages) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, @@ -616,7 +616,7 @@ class InfBuildData(ModuleBuildClassObject): RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform] for Record in RecordList: CName = Record[0] - Value = _PpiValue(CName, self.Packages, self.MetaFile.Path) + Value = _PpiValue(CName, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: PackageList = "\n\t".join(str(P) for P in self.Packages) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, @@ -640,7 +640,7 @@ class InfBuildData(ModuleBuildClassObject): RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform] for Record in RecordList: CName = Record[0] - Value = GuidValue(CName, self.Packages, self.MetaFile.Path) + Value = GuidValue(CName, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: PackageList = "\n\t".join(str(P) for P in self.Packages) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, @@ -655,7 +655,7 @@ class InfBuildData(ModuleBuildClassObject): for TokenSpaceGuid, _, _, _, _, _, LineNo in RecordList: # get the guid value if TokenSpaceGuid not in RetVal: - Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path) + Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: PackageList = "\n\t".join(str(P) for P in self.Packages) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, @@ -818,11 +818,11 @@ class InfBuildData(ModuleBuildClassObject): Value = Token else: # get the GUID value now - Value = _ProtocolValue(Token, self.Packages, self.MetaFile.Path) + Value = _ProtocolValue(Token, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: - Value = _PpiValue(Token, self.Packages, self.MetaFile.Path) + Value = _PpiValue(Token, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: - Value = GuidValue(Token, self.Packages, self.MetaFile.Path) + Value = GuidValue(Token, self.Packages, self.MetaFile.OriginalPath.Path) if Value is None: PackageList = "\n\t".join(str(P) for P in self.Packages) -- cgit From 4f73eef8383f423be0fef1d1e66cd897a5367cd3 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Fri, 16 Feb 2024 15:49:27 +0300 Subject: MdeModulePkg/NvmExpressDxe: fix format used for Eui64 conversion Eui64 is a 64 bit value, so the "L" or "l" is required for format specifier, otherwise only lower 32 bit will be converted. Signed-off-by: Mike Maslenkin Reviewed-by: Laszlo Ersek --- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c index dea14f1a44..dfa3653d6a 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c @@ -300,7 +300,7 @@ EnumerateNvmeDevNamespace ( Sn[20] = 0; CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn)); Mn[40] = 0; - UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%x", Sn, Mn, NamespaceData->Eui64); + UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%lx", Sn, Mn, NamespaceData->Eui64); AddUnicodeString2 ( "eng", -- cgit From 4e36bed8128f67fc73f41acb1beaffd77ef76e90 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Fri, 16 Feb 2024 17:17:53 +0300 Subject: MdeModulePkg/NvmExpressDxe: use format "0x%lx" for UINT64 values. Signed-off-by: Mike Maslenkin Reviewed-by: Laszlo Ersek --- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c index dfa3653d6a..069da12a9b 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c @@ -288,9 +288,9 @@ EnumerateNvmeDevNamespace ( // Dump NvmExpress Identify Namespace Data // DEBUG ((DEBUG_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId)); - DEBUG ((DEBUG_INFO, " NSZE : 0x%x\n", NamespaceData->Nsze)); - DEBUG ((DEBUG_INFO, " NCAP : 0x%x\n", NamespaceData->Ncap)); - DEBUG ((DEBUG_INFO, " NUSE : 0x%x\n", NamespaceData->Nuse)); + DEBUG ((DEBUG_INFO, " NSZE : 0x%lx\n", NamespaceData->Nsze)); + DEBUG ((DEBUG_INFO, " NCAP : 0x%lx\n", NamespaceData->Ncap)); + DEBUG ((DEBUG_INFO, " NUSE : 0x%lx\n", NamespaceData->Nuse)); DEBUG ((DEBUG_INFO, " LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads))); // -- cgit From cdffb638c85da87f6b9d61194513a24cd6a73c6a Mon Sep 17 00:00:00 2001 From: Tobin Feldman-Fitzthum Date: Wed, 26 Jun 2024 18:42:45 +0000 Subject: AmdSev: enable kernel hashes without initrd If kernel hashes are enabled but no initrd is provided, QEMU will still create an entry in the hash table, but it will be the hash of an empty buffer. Remove the explicit check for the length of the blob. This logic will be handled by the later hash comparison, which will still fail when the blob is not present but is expected, but will pass when the blob is not present and the hash table contains a hash of an empty buffer. Signed-off-by: Tobin Feldman-Fitzthum --- .../AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c index bc2d5daadc..7bc9f89007 100644 --- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c +++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c @@ -156,16 +156,6 @@ VerifyBlob ( DEBUG ((DEBUG_INFO, "%a: Found GUID %g in table\n", __func__, Guid)); - if (BufSize == 0) { - DEBUG (( - DEBUG_ERROR, - "%a: Blob Specified in Hash Table was not Provided", - __func__ - )); - - CpuDeadLoop (); - } - EntrySize = Entry->Len - sizeof Entry->Guid - sizeof Entry->Len; if (EntrySize != SHA256_DIGEST_SIZE) { DEBUG (( -- cgit From 8430c69dc1d92085c3ef22370bfbb4d41ef2e94c Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 2 Jul 2024 15:05:05 -0400 Subject: MdePkg/Nvme.h: Add missing NVMe capability descriptions Most of the definitions in this file are currently well documented. This adds documentation for a few missing fields in the NVMe Controller Capabilities structure. Signed-off-by: Michael Kubacki --- MdePkg/Include/IndustryStandard/Nvme.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/Nvme.h b/MdePkg/Include/IndustryStandard/Nvme.h index c190d678e1..2a94e21203 100644 --- a/MdePkg/Include/IndustryStandard/Nvme.h +++ b/MdePkg/Include/IndustryStandard/Nvme.h @@ -54,16 +54,16 @@ typedef struct { UINT8 Cqr : 1; // Contiguous Queues Required UINT8 Ams : 2; // Arbitration Mechanism Supported UINT8 Rsvd1 : 5; - UINT8 To; // Timeout - UINT16 Dstrd : 4; + UINT8 To; // Timeout + UINT16 Dstrd : 4; // Doorbell Stride UINT16 Nssrs : 1; // NVM Subsystem Reset Supported NSSRS UINT16 Css : 8; // Command Sets Supported - Bit 37 UINT16 Bps : 1; // Boot Partition Support - Bit 45 in NVMe1.4 UINT16 Rsvd3 : 2; - UINT8 Mpsmin : 4; - UINT8 Mpsmax : 4; - UINT8 Pmrs : 1; - UINT8 Cmbs : 1; + UINT8 Mpsmin : 4; // Memory Page Size Minimum + UINT8 Mpsmax : 4; // Memory Page Size Maximum + UINT8 Pmrs : 1; // Persistent Memory Region Supported + UINT8 Cmbs : 1; // Controller Memory Buffer Supported UINT8 Rsvd4 : 6; } NVME_CAP; -- cgit From 6852f6984bdab86a1662e89e1ef0f3abc39559b6 Mon Sep 17 00:00:00 2001 From: Chun-Yi Lee Date: Fri, 12 Apr 2024 15:07:33 +0800 Subject: EmbeddedPkg/VirtualRealTimeClockLib: Support SOURCE_DATE_EPOCH RISC-V ovmf used VirtualRealTimeClockLib but the default epoch is a compilation time. It causes that the RISC-V ovmf binary image is NOT reproducible. This patch added the support of SOURCE_DATE_EPOCH by printenv command. If SOURCE_DATE_EPOCH be found then we use it as BUILD_EPOCH. Otherwise we run date command for setting BUILD_EPOCH. For distributions want a reproducible RISC-V ovmf image, they should export SOURCE_DATE_EPOCH environment variable before building ovmf. References: https://reproducible-builds.org/docs/source-date-epoch/ Cc: Pete Batard Cc: Ard Biesheuvel Signed-off-by: "Lee, Chun-Yi" --- EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf index 5d0f867eb6..285e880daa 100644 --- a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf +++ b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf @@ -34,4 +34,4 @@ # Current usage of this library expects GCC in a UNIX-like shell environment with the date command [BuildOptions] - GCC:*_*_*_CC_FLAGS = -DBUILD_EPOCH=`date +%s` + GCC:*_*_*_CC_FLAGS = -DBUILD_EPOCH=`printenv SOURCE_DATE_EPOCH || date +%s` -- cgit From bc3a1ec2a2838f596678ddd247d10332c6790dab Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 22 Nov 2022 13:18:41 +1100 Subject: MdePkg/Register/Amd: Define all bits from MSR_SEV_STATUS_REGISTER For now we need DebugSwap but others are likely to be needed too. Cc: Liming Gao Cc: Michael D Kinney Cc: Zhiguang Liu Reviewed-by: Tom Lendacky Signed-off-by: Alexey Kardashevskiy Changes: v5: * "rb" from Tom v4: * added more from April/2024 APM --- MdePkg/Include/Register/Amd/SevSnpMsr.h | 95 +++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/MdePkg/Include/Register/Amd/SevSnpMsr.h b/MdePkg/Include/Register/Amd/SevSnpMsr.h index 1b8fbc1978..5187f965a6 100644 --- a/MdePkg/Include/Register/Amd/SevSnpMsr.h +++ b/MdePkg/Include/Register/Amd/SevSnpMsr.h @@ -126,19 +126,106 @@ typedef union { /// /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled /// - UINT32 SevBit : 1; + UINT32 SevBit : 1; /// /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled /// - UINT32 SevEsBit : 1; + UINT32 SevEsBit : 1; /// /// [Bit 2] Secure Nested Paging (SevSnp) is enabled /// - UINT32 SevSnpBit : 1; + UINT32 SevSnpBit : 1; - UINT32 Reserved2 : 29; + /// + /// [Bit 3] Virtual TOM feature is enabled in SEV_FEATURES[1] + /// + UINT32 vTOM : 1; + + /// + /// [Bit 4] ReflectVC feature is enabled in SEV_FEATURES[2] + /// + UINT32 ReflectVC : 1; + + /// + /// [Bit 5] Restricted Injection feature is enabled in SEV_FEATURES[3] + /// + UINT32 RestrictedInjection : 1; + + /// + /// [Bit 6] Alternate Injection feature is enabled in SEV_FEATURES[4] + /// + UINT32 AlternateInjection : 1; + + /// + /// [Bit 7] Debug Virtualization feature is enabled in SEV_FEATURES[5] + /// + UINT32 DebugVirtualization : 1; + + /// + /// [Bit 8] PreventHostIBS feature is enabled in SEV_FEATURES[6] + /// + UINT32 PreventHostIBS : 1; + + /// + /// [Bit 9] BTB isolation feature is enabled in SEV_FEATURES[7] + /// + UINT32 SNPBTBIsolation : 1; + + /// + /// [Bit 10] VMPL SSS feature is enabled in SEV_FEATURES[8] + /// + UINT32 VmplSSS : 1; + + /// + /// [Bit 11] Secure TSC feature is enabled in SEV_FEATURES[9] + /// + UINT32 SecureTsc : 1; + + /// + /// [Bit 12] VMGEXIT Parameter feature is enabled in SEV_FEATURES[10] + /// + UINT32 VmgexitParameter : 1; + + /// + /// [Bit 13] PMC Virtualization feature is enabled in SEV_FEATURES[11] + /// + UINT32 PmcVirtualization : 1; + + /// + /// [Bit 14] IBS Virtualization feature is enabled in SEV_FEATURES[12] + /// + UINT32 IbsVirtualization : 1; + + /// + /// [Bit 15] + /// + UINT32 Reserved1 : 1; + + /// + /// [Bit 16] VMSA Register Protection feature is enabled in SEV_FEATURES[14] + /// + UINT32 VmsaRegProt : 1; + + /// + /// [Bit 17] SMT Protection feature is enabled in SEV_FEATURES[15] + /// + UINT32 SmtProtection : 1; + /// + /// + /// [Bit 18] Secure AVIC feature is enabled in SEV_FEATURES[16] + /// + UINT32 SecureAVIC : 1; + + UINT32 Reserved2 : 4; + + /// + /// [Bit 23] IBPB on Entry feature is enabled in SEV_FEATURES[21] + /// + UINT32 IbpbOnEntry : 1; + + UINT32 Reserved3 : 8; } Bits; /// /// All bit fields as a 32-bit value -- cgit From 3f28aa2fb07f57afa58d4030d6dc60f5d01d5888 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 22 Nov 2022 16:12:55 +1100 Subject: MdePkg: Add AMD SEV features to PcdConfidentialComputingGuestAttr PcdConfidentialComputingGuestAttr so far only contained an SEV mode bit but there are more other features which do not translate to levels such as DebugVirtualization or SecureTsc. Add the feature mask and the DebugVirtualization feature bit to the PCD. Cc: Liming Gao Cc: Michael D Kinney Cc: Zhiguang Liu Reviewed-by: Tom Lendacky Signed-off-by: Alexey Kardashevskiy --- Changes: v4: * s/CCAttrFeatureAmdSevDebugSwap/CCAttrFeatureAmdSevEsDebugVirtualization/ v2: * expanded features mask * added type mask --- MdePkg/Include/ConfidentialComputingGuestAttr.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/ConfidentialComputingGuestAttr.h b/MdePkg/Include/ConfidentialComputingGuestAttr.h index 44e6df8002..f62158f77e 100644 --- a/MdePkg/Include/ConfidentialComputingGuestAttr.h +++ b/MdePkg/Include/ConfidentialComputingGuestAttr.h @@ -29,9 +29,20 @@ typedef enum { /* The guest is running with Intel TDX memory encryption enabled. */ CCAttrIntelTdx = 0x200, + + CCAttrTypeMask = 0x000000000000ffff, + + /* Features */ + + /* The AMD SEV-ES DebugVirtualization feature is enabled in SEV_STATUS */ + CCAttrFeatureAmdSevEsDebugVirtualization = 0x0000000000010000, + + CCAttrFeatureMask = 0xffffffffffff0000, } CONFIDENTIAL_COMPUTING_GUEST_ATTR; -#define CC_GUEST_IS_TDX(x) ((x) == CCAttrIntelTdx) -#define CC_GUEST_IS_SEV(x) ((x) == CCAttrAmdSev || (x) == CCAttrAmdSevEs || (x) == CCAttrAmdSevSnp) +#define _CC_GUEST_IS_TDX(x) ((x) == CCAttrIntelTdx) +#define CC_GUEST_IS_TDX(x) _CC_GUEST_IS_TDX((x) & CCAttrTypeMask) +#define _CC_GUEST_IS_SEV(x) ((x) == CCAttrAmdSev || (x) == CCAttrAmdSevEs || (x) == CCAttrAmdSevSnp) +#define CC_GUEST_IS_SEV(x) _CC_GUEST_IS_SEV((x) & CCAttrTypeMask) #endif -- cgit From 9f06feb5d2fa43e184690034e70e6d427cf6913d Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 30 Nov 2022 19:41:12 +1100 Subject: OvmfPkg: Add AMD SEV-ES DebugVirtualization feature support The SEV-ES DebugVirtualization feature enables type B swapping of debug registers on #VMEXIT and makes #DB and DR7 intercepts unnecessary and unwanted. When DebugVirtualization is enabled, this stops booting if interaction from the HV. Add new API to PEI, SEC, DXE. This does not change the existing behaviour yet. Cc: Ard Biesheuvel Cc: Erdem Aktas Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Michael Roth Cc: Min Xu Reviewed-by: Tom Lendacky Signed-off-by: Alexey Kardashevskiy --- Changes: v5: * "rb" from Tom v4: * s/DebugSwap/DebugVirtualization/ --- OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++++++++ .../DxeMemEncryptSevLibInternal.c | 27 +++++++++++++++++++--- .../PeiMemEncryptSevLibInternal.c | 15 ++++++++++++ .../SecMemEncryptSevLibInternal.c | 15 ++++++++++++ OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 8 +++++++ 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h index 4fa9c0d700..c5653539d8 100644 --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h @@ -166,6 +166,18 @@ MemEncryptSevGetEncryptionMask ( VOID ); +/** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ); + /** Returns the encryption state of the specified virtual address range. diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c index 4aba0075b9..9947d663de 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c @@ -40,19 +40,25 @@ AmdMemEncryptionAttrCheck ( IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr ) { + UINT64 CurrentLevel; + + CurrentLevel = CurrentAttr & CCAttrTypeMask; + switch (Attr) { case CCAttrAmdSev: // // SEV is automatically enabled if SEV-ES or SEV-SNP is active. // - return CurrentAttr >= CCAttrAmdSev; + return CurrentLevel >= CCAttrAmdSev; case CCAttrAmdSevEs: // // SEV-ES is automatically enabled if SEV-SNP is active. // - return CurrentAttr >= CCAttrAmdSevEs; + return CurrentLevel >= CCAttrAmdSevEs; case CCAttrAmdSevSnp: - return CurrentAttr == CCAttrAmdSevSnp; + return CurrentLevel == CCAttrAmdSevSnp; + case CCAttrFeatureAmdSevEsDebugVirtualization: + return !!(CurrentAttr & CCAttrFeatureAmdSevEsDebugVirtualization); default: return FALSE; } @@ -159,3 +165,18 @@ MemEncryptSevGetEncryptionMask ( return mSevEncryptionMask; } + +/** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ) +{ + return ConfidentialComputingGuestHas (CCAttrFeatureAmdSevEsDebugVirtualization); +} diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c index 41d1246a5b..7d823ad639 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c @@ -141,3 +141,18 @@ MemEncryptSevGetEncryptionMask ( return SevEsWorkArea->EncryptionMask; } + +/** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ) +{ + return FALSE; +} diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c index 27148c7e33..33a326ac15 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c @@ -142,6 +142,21 @@ MemEncryptSevGetEncryptionMask ( return SevEsWorkArea->EncryptionMask; } +/** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ) +{ + return FALSE; +} + /** Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM Save State Map. diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c index da8f1e5db9..2031fa9e22 100644 --- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c +++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c @@ -1609,6 +1609,10 @@ Dr7WriteExit ( UINT64 *Register; UINT64 Status; + if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) { + return UnsupportedExit (Ghcb, Regs, InstructionData); + } + Ext = &InstructionData->Ext; SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1); @@ -1659,6 +1663,10 @@ Dr7ReadExit ( SEV_ES_PER_CPU_DATA *SevEsData; UINT64 *Register; + if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) { + return UnsupportedExit (Ghcb, Regs, InstructionData); + } + Ext = &InstructionData->Ext; SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1); -- cgit From 63a7152471111306184e4ac20a1ca705e6b75b6b Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 30 Nov 2022 19:40:48 +1100 Subject: UefiCpuPkg: Add AMD SEV-ES features support CONFIDENTIAL_COMPUTING_GUEST_ATTR is not a simple SEV level anymore and includes a feature mask since the previous commit. Fix AmdMemEncryptionAttrCheck to check the level and feature correctly and add DebugVirtualization support. Since the actual feature flag is not set yet, this should cause no behavioural change. Cc: Gerd Hoffmann Cc: Jiaxin Wu Cc: Rahul Kumar Cc: Ray Ni Reviewed-by: Tom Lendacky Signed-off-by: Alexey Kardashevskiy --- Changes: v5: * "rb" from Tom --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 8fbcebdc03..1951922912 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -3196,19 +3196,25 @@ AmdMemEncryptionAttrCheck ( IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr ) { + UINT64 CurrentLevel; + + CurrentLevel = CurrentAttr & CCAttrTypeMask; + switch (Attr) { case CCAttrAmdSev: // // SEV is automatically enabled if SEV-ES or SEV-SNP is active. // - return CurrentAttr >= CCAttrAmdSev; + return CurrentLevel >= CCAttrAmdSev; case CCAttrAmdSevEs: // // SEV-ES is automatically enabled if SEV-SNP is active. // - return CurrentAttr >= CCAttrAmdSevEs; + return CurrentLevel >= CCAttrAmdSevEs; case CCAttrAmdSevSnp: - return CurrentAttr == CCAttrAmdSevSnp; + return CurrentLevel == CCAttrAmdSevSnp; + case CCAttrFeatureAmdSevEsDebugVirtualization: + return !!(CurrentAttr & CCAttrFeatureAmdSevEsDebugVirtualization); default: return FALSE; } -- cgit From 28099661893327296e18b8f98a1e7c3e757c7d49 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 28 May 2024 14:48:40 +1000 Subject: OvmfPkg: Enable AMD SEV-ES DebugVirtualization Write the feature bit into PcdConfidentialComputingGuestAttr and enable DebugVirtualization in PEI, SEC, DXE. Cc: Ard Biesheuvel Cc: Erdem Aktas Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Michael Roth Cc: Min Xu Reviewed-by: Tom Lendacky Signed-off-by: Alexey Kardashevskiy --- Changes: v5: * "rb" from Tom v4: * s/DebugSwap/DebugVirtualization/g --- .../BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c | 6 +++++- .../BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c | 6 +++++- OvmfPkg/PlatformPei/AmdSev.c | 13 ++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c index 7d823ad639..f381b9255b 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c @@ -154,5 +154,9 @@ MemEncryptSevEsDebugVirtualizationIsEnabled ( VOID ) { - return FALSE; + MSR_SEV_STATUS_REGISTER Msr; + + Msr.Uint32 = InternalMemEncryptSevStatus (); + + return Msr.Bits.DebugVirtualization ? TRUE : FALSE; } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c index 33a326ac15..946bed2ada 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c @@ -154,7 +154,11 @@ MemEncryptSevEsDebugVirtualizationIsEnabled ( VOID ) { - return FALSE; + MSR_SEV_STATUS_REGISTER Msr; + + Msr.Uint32 = InternalMemEncryptSevStatus (); + + return Msr.Bits.DebugVirtualization ? TRUE : FALSE; } /** diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c index 88ca14507f..8562787035 100644 --- a/OvmfPkg/PlatformPei/AmdSev.c +++ b/OvmfPkg/PlatformPei/AmdSev.c @@ -434,6 +434,7 @@ AmdSevInitialize ( ) { UINT64 EncryptionMask; + UINT64 CCGuestAttr; RETURN_STATUS PcdStatus; // @@ -517,13 +518,19 @@ AmdSevInitialize ( // technology is active. // if (MemEncryptSevSnpIsEnabled ()) { - PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevSnp); + CCGuestAttr = CCAttrAmdSevSnp; } else if (MemEncryptSevEsIsEnabled ()) { - PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevEs); + CCGuestAttr = CCAttrAmdSevEs; } else { - PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSev); + CCGuestAttr = CCAttrAmdSev; } + if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) { + CCGuestAttr |= CCAttrFeatureAmdSevEsDebugVirtualization; + } + + PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCGuestAttr); + ASSERT_RETURN_ERROR (PcdStatus); } -- cgit From ed9a64af1be2724362b50cf96281de7117ad7bff Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 4 Jul 2024 15:15:15 +0800 Subject: SecurityPkg/Tcg2Config: avoid potential build error Cast pointer type to VOID* to avoid potential build error. If the two PCD are FixAtBuild, PcdGetPtr will return a const type pointer. Since the second parameter of BuildGuidDataHob is VOID*, build error may happen with following log: C4090: 'function': different 'const' qualifiers Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c index ce78e32537..73121b0a26 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c @@ -190,7 +190,7 @@ Tcg2ConfigPeimEntryPoint ( // Hob = BuildGuidDataHob ( &gEdkiiTpmInstanceHobGuid, - PcdGetPtr (PcdTpmInstanceGuid), + (VOID *)PcdGetPtr (PcdTpmInstanceGuid), sizeof (EFI_GUID) ); ASSERT (Hob != NULL); @@ -200,7 +200,7 @@ Tcg2ConfigPeimEntryPoint ( // Hob = BuildGuidDataHob ( &gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid, - PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), + (VOID *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer)) ); ASSERT (Hob != NULL); -- cgit From 9389b9a208cc5c7d9b055ea06d92cc4903f705ee Mon Sep 17 00:00:00 2001 From: Xiaoyao Li Date: Wed, 26 Jun 2024 05:06:05 -0400 Subject: MdePkg/Tdx.h: Fix the order of NumVcpus and MaxVcpus For TDCALL leaf TDG.VP.INFO, the bit 31:0 in R8 returns NUM_VCPUS and bit 63:32 in R8 returns MAX_VCPUS. Current struct TDCALL_INFO_RETURN_DATA defines them in wrong order. Signed-off-by: Xiaoyao Li Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Laszlo Ersek --- MdePkg/Include/IndustryStandard/Tdx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/IndustryStandard/Tdx.h b/MdePkg/Include/IndustryStandard/Tdx.h index 2662761883..17f1e8f414 100644 --- a/MdePkg/Include/IndustryStandard/Tdx.h +++ b/MdePkg/Include/IndustryStandard/Tdx.h @@ -113,8 +113,8 @@ typedef struct { typedef struct { UINT64 Gpaw; UINT64 Attributes; - UINT32 MaxVcpus; UINT32 NumVcpus; + UINT32 MaxVcpus; UINT64 Resv[3]; } TDCALL_INFO_RETURN_DATA; -- cgit From bef0d333dc4fccdfc75e4be31e067b467a9a4093 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 3 Jul 2024 16:16:57 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Fix system hang when SmmProfile enable MMIO ranges within the mProtectionMemRange array may exceed 4G and should be configured as 'Present & NX'. However, the initial attribute for these MMIO addresses in the page table is 'non-present'. Other attributes should not be set or updated for a non-present range if the present bit mask is zero, as this could result in an error during the InitPaging for the page table update process. This patch is to resolve the error to make sure MMIO page table can be configured correctly. Signed-off-by: Jiaxin Wu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 40 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 8142d3ceac..692aad2d15 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1,7 +1,7 @@ /** @file Enable SMM profile. -Copyright (c) 2012 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -594,6 +594,7 @@ InitPaging ( UINT64 Limit; UINT64 PreviousAddress; UINT64 MemoryAttrMask; + BOOLEAN IsSet; BOOLEAN WriteProtect; BOOLEAN CetEnabled; @@ -616,19 +617,38 @@ InitPaging ( DEBUG ((DEBUG_INFO, "Patch page table start ...\n")); if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { for (Index = 0; Index < mProtectionMemRangeCount; Index++) { - MemoryAttrMask = 0; - if (mProtectionMemRange[Index].Nx == TRUE) { + Base = mProtectionMemRange[Index].Range.Base; + Length = mProtectionMemRange[Index].Range.Top - Base; + + MemoryAttrMask = EFI_MEMORY_RP; + if (!mProtectionMemRange[Index].Present) { + // + // Config the EFI_MEMORY_RP attribute to make it non-present. + // + IsSet = TRUE; + } else { + // + // Clear the EFI_MEMORY_RP attribute to make it present. + // + IsSet = FALSE; + + // + // Config the range as writable and executable when mapping a range as present. + // + MemoryAttrMask |= EFI_MEMORY_RO; MemoryAttrMask |= EFI_MEMORY_XP; } - if (mProtectionMemRange[Index].Present == FALSE) { - MemoryAttrMask = EFI_MEMORY_RP; - } + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, IsSet, NULL); + ASSERT_RETURN_ERROR (Status); - Base = mProtectionMemRange[Index].Range.Base; - Length = mProtectionMemRange[Index].Range.Top - Base; - if (MemoryAttrMask != 0) { - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL); + if (mProtectionMemRange[Index].Present && mProtectionMemRange[Index].Nx) { + // + // Since EFI_MEMORY_XP has already been cleared above, only handle the case to disable execution. + // Config the EFI_MEMORY_XP attribute to disable execution. + // + MemoryAttrMask = EFI_MEMORY_XP; + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL); ASSERT_RETURN_ERROR (Status); } -- cgit From 051c7bb434f9f6b908aac2a0b00368192aa616ec Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 2 Jul 2024 11:43:24 -0400 Subject: StandaloneMmPkg: Fix section data length returned larger than actual data This change fixes an issue where the returned section data length is always 4 bytes larger than the actual section length. This could cause an issue where the caller accesses the final 4 bytes which would be invalid. Co-authored-by: Kun Qin Signed-off-by: Michael Kubacki --- StandaloneMmPkg/Include/Library/FvLib.h | 2 +- StandaloneMmPkg/Library/FvLib/FvLib.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/StandaloneMmPkg/Include/Library/FvLib.h b/StandaloneMmPkg/Include/Library/FvLib.h index 1eb9ea7e04..3b603e473d 100644 --- a/StandaloneMmPkg/Include/Library/FvLib.h +++ b/StandaloneMmPkg/Include/Library/FvLib.h @@ -87,7 +87,7 @@ FindFfsSectionInSections ( @param FfsFileHeader Pointer to the current file to search. @param SectionData Pointer to the Section matching SectionType in FfsFileHeader. NULL if section not found - @param SectionDataSize The size of SectionData + @param SectionDataSize The size of SectionData, excluding the section header. @retval EFI_NOT_FOUND No files matching the search criteria were found @retval EFI_SUCCESS diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.c b/StandaloneMmPkg/Library/FvLib/FvLib.c index 89504b9ee9..e0f344af38 100644 --- a/StandaloneMmPkg/Library/FvLib/FvLib.c +++ b/StandaloneMmPkg/Library/FvLib/FvLib.c @@ -338,11 +338,11 @@ FfsFindSection ( Given the input file pointer, search for the next matching section in the FFS volume. - @param SearchType Filter to find only sections of this type. - @param FfsFileHeader Pointer to the current file to search. - @param SectionData Pointer to the Section matching SectionType in FfsFileHeader. - NULL if section not found - @param SectionDataSize The size of SectionData + @param[in] SectionType Filter to find only sections of this type. + @param[in] FfsFileHeader Pointer to the current file to search. + @param[in,out] SectionData Pointer to the Section matching SectionType in FfsFileHeader. + NULL if section not found + @param[in,out] SectionDataSize The size of SectionData, excluding the section header. @retval EFI_NOT_FOUND No files matching the search criteria were found @retval EFI_SUCCESS @@ -380,10 +380,10 @@ FfsFindSectionData ( if (Section->Type == SectionType) { if (IS_SECTION2 (Section)) { *SectionData = (VOID *)((EFI_COMMON_SECTION_HEADER2 *)Section + 1); - *SectionDataSize = SECTION2_SIZE (Section); + *SectionDataSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2); } else { *SectionData = (VOID *)(Section + 1); - *SectionDataSize = SECTION_SIZE (Section); + *SectionDataSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER); } return EFI_SUCCESS; -- cgit From a1d94d9e6e109aa7e63f29b015e28c76910a0d7d Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 5 Jul 2024 13:41:06 +0800 Subject: MdePkg/StandaloneMmServicesTableLib: Support MM_CORE_STANDALONE Support the module type for MM_CORE_STANDALONE Signed-off-by: Jiaxin Wu --- .../StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf b/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf index 40f14aee62..5225d64d97 100644 --- a/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf +++ b/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf @@ -16,7 +16,7 @@ FILE_GUID = eaa4684f-fb4e-41f3-9967-307d5b409182 MODULE_TYPE = MM_STANDALONE VERSION_STRING = 1.0 - LIBRARY_CLASS = MmServicesTableLib|MM_STANDALONE + LIBRARY_CLASS = MmServicesTableLib|MM_STANDALONE MM_CORE_STANDALONE PI_SPECIFICATION_VERSION = 0x00010032 CONSTRUCTOR = StandaloneMmServicesTableLibConstructor -- cgit From 22d0babd3315dc24027321819cf0efc487dc9d18 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 5 Jul 2024 13:41:46 +0800 Subject: MdeModulePkg/StandaloneMmReportStatusCodeLib: Support MM_CORE_STANDALONE Support the module type for MM_CORE_STANDALONE Signed-off-by: Jiaxin Wu --- .../Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf b/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf index 866e09249a..08437176e7 100644 --- a/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf +++ b/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf @@ -18,7 +18,7 @@ MODULE_TYPE = MM_STANDALONE VERSION_STRING = 1.0 PI_SPECIFICATION_VERSION = 0x00010032 - LIBRARY_CLASS = ReportStatusCodeLib|MM_STANDALONE + LIBRARY_CLASS = ReportStatusCodeLib|MM_STANDALONE MM_CORE_STANDALONE # # The following information is for reference only and not required by the build tools. -- cgit From a3359ffb25ce70ee90822f6886136bf0d200406e Mon Sep 17 00:00:00 2001 From: Xianglai Li Date: Thu, 27 Jun 2024 18:57:37 +0800 Subject: OvmfPkg/LoongArchVirt: Optimize the use of serial port libraries Because the complex dependency between SerialPortLib and PciExpressLib leads to multiple references to the lib library in the loongarch dsc file, optimizing SerialPortLib now simplifies multiple references to lib in the dsc file. Cc: Ard Biesheuvel Cc: Bibo Mao Cc: Chao Li Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Xianglai Li Signed-off-by: Xianglai Li --- OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc index 90be933cdc..70f6c75b0f 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc @@ -130,7 +130,7 @@ IoLib | MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf FdtSerialPortAddressLib | OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf - SerialPortLib | MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf @@ -196,7 +196,6 @@ MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf PeiServicesTablePointerLib | MdePkg/Library/PeiServicesTablePointerLibKs0/PeiServicesTablePointerLibKs0.inf PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf - SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf [LibraryClasses.common.PEI_CORE] @@ -210,7 +209,6 @@ PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioPeiLib.inf PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf - SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf [LibraryClasses.common.PEIM] HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -229,14 +227,12 @@ CpuMmuInitLib | OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf MpInitLib | UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf - SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf [LibraryClasses.common.DXE_CORE] HobLib | MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf MemoryAllocationLib | MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf - PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -254,7 +250,6 @@ QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf - PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf !if $(TARGET) != RELEASE DebugLib | MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf !endif @@ -281,7 +276,6 @@ QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf AcpiPlatformLib | OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf MpInitLib | UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -291,7 +285,6 @@ MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf ################################################################################ # @@ -601,18 +594,15 @@ UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf { NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf } EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf } MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf { NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf } OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf OvmfPkg/Virtio10Dxe/Virtio10.inf -- cgit From 4efcd654ecd94b91bd45da79583f114a0fa12a87 Mon Sep 17 00:00:00 2001 From: Yanbo Huang Date: Fri, 5 Jul 2024 17:54:19 +0800 Subject: Revert "UefiCpuPkg/PiSmmCpuDxeSmm: Consume PcdCpuSmmApSyncTimeout2" This reverts commit cb3134612d11102fe066c94c8fa7edb20d62c1a8. Intel server platform sync this commit will hit conflict since our code base is old. We don't want to cherry-pick the dependent patches to avoid potential issue. We need to revert this commit first and then fix the conflict and reapply the change. Sorry for the incovenience. Signed-off-by: Yanbo Huang --- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 10 +++++----- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 11 +++-------- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 - UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c | 19 +++++-------------- 4 files changed, 13 insertions(+), 28 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 570e99177f..10baf3ceb9 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -1,7 +1,7 @@ /** @file SMM MP service implementation -Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -268,7 +268,7 @@ SmmWaitForApArrival ( // Sync with APs 1st timeout // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer, mTimeoutTicker) && !(LmceEn && LmceSignal); + !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal); ) { mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); @@ -309,7 +309,7 @@ SmmWaitForApArrival ( // Sync with APs 2nd timeout. // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer, mTimeoutTicker2); + !IsSyncTimerTimeout (Timer); ) { mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); @@ -736,7 +736,7 @@ APHandler ( // Timeout BSP // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer, mTimeoutTicker) && + !IsSyncTimerTimeout (Timer) && !(*mSmmMpSyncData->InsideSmm); ) { @@ -764,7 +764,7 @@ APHandler ( // Now clock BSP for the 2nd time // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer, mTimeoutTicker2) && + !IsSyncTimerTimeout (Timer) && !(*mSmmMpSyncData->InsideSmm); ) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 8409891b1d..315a33d578 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -471,9 +471,6 @@ extern BOOLEAN mSmmDebugAgentSupport; // extern UINT64 mAddressEncMask; -extern UINT64 mTimeoutTicker; -extern UINT64 mTimeoutTicker2; - /** Create 4G PageTable in SMRAM. @@ -536,17 +533,15 @@ StartSyncTimer ( ); /** - Check if the SMM AP Sync Timer is timeout specified by Timeout. + Check if the SMM AP Sync timer is timeout. - @param Timer The start timer from the begin. - @param Timeout The timeout ticker to wait. + @param Timer The start timer from the begin. **/ BOOLEAN EFIAPI IsSyncTimerTimeout ( - IN UINT64 Timer, - IN UINT64 Timeout + IN UINT64 Timer ); /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 3c4518da7b..f0598b0364 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -134,7 +134,6 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c index 8d29ba7326..0c070c5736 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -1,7 +1,7 @@ /** @file SMM Timer feature support -Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -9,9 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuDxeSmm.h" UINT64 mTimeoutTicker = 0; - -UINT64 mTimeoutTicker2 = 0; - // // Number of counts in a roll-over cycle of the performance counter. // @@ -39,10 +36,6 @@ InitializeSmmTimer ( MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)), 1000 * 1000 ); - mTimeoutTicker2 = DivU64x32 ( - MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout2)), - 1000 * 1000 - ); if (End < Start) { mCountDown = TRUE; mCycle = Start - End; @@ -66,17 +59,15 @@ StartSyncTimer ( } /** - Check if the SMM AP Sync Timer is timeout specified by Timeout. + Check if the SMM AP Sync timer is timeout. - @param Timer The start timer from the begin. - @param Timeout The timeout ticker to wait. + @param Timer The start timer from the begin. **/ BOOLEAN EFIAPI IsSyncTimerTimeout ( - IN UINT64 Timer, - IN UINT64 Timeout + IN UINT64 Timer ) { UINT64 CurrentTimer; @@ -114,5 +105,5 @@ IsSyncTimerTimeout ( } } - return (BOOLEAN)(Delta >= Timeout); + return (BOOLEAN)(Delta >= mTimeoutTicker); } -- cgit From f8bf46be599a957d9374b513f730243725637127 Mon Sep 17 00:00:00 2001 From: Yanbo Huang Date: Fri, 5 Jul 2024 18:17:57 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Consume PcdCpuSmmApSyncTimeout2 This patch is to consume the PcdCpuSmmApSyncTimeout2 to enhance the flexibility of timeout configuration. In some cases, certain processors may not be able to enter SMI, and prolonged waiting could lead to kernel soft/hard lockup. We have now defined two timeouts. The first timeout can be set to a smaller value to reduce the waiting period. Processors that are unable to enter SMI will be woken up through SMIIPL to enter SMI, followed by a second waiting period. The second timeout can be set to a larger value to prevent delays in processors entering SMI case due to the long instruction execution. This patch adjust the location of PcdCpuSmmApSyncTimeout2 to avoid conflict. Signed-off-by: Yanbo Huang Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c | 10 +++++----- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 11 ++++++++--- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c | 19 ++++++++++++++----- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 10baf3ceb9..570e99177f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -1,7 +1,7 @@ /** @file SMM MP service implementation -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -268,7 +268,7 @@ SmmWaitForApArrival ( // Sync with APs 1st timeout // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal); + !IsSyncTimerTimeout (Timer, mTimeoutTicker) && !(LmceEn && LmceSignal); ) { mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); @@ -309,7 +309,7 @@ SmmWaitForApArrival ( // Sync with APs 2nd timeout. // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer); + !IsSyncTimerTimeout (Timer, mTimeoutTicker2); ) { mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); @@ -736,7 +736,7 @@ APHandler ( // Timeout BSP // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && + !IsSyncTimerTimeout (Timer, mTimeoutTicker) && !(*mSmmMpSyncData->InsideSmm); ) { @@ -764,7 +764,7 @@ APHandler ( // Now clock BSP for the 2nd time // for (Timer = StartSyncTimer (); - !IsSyncTimerTimeout (Timer) && + !IsSyncTimerTimeout (Timer, mTimeoutTicker2) && !(*mSmmMpSyncData->InsideSmm); ) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 315a33d578..8409891b1d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -471,6 +471,9 @@ extern BOOLEAN mSmmDebugAgentSupport; // extern UINT64 mAddressEncMask; +extern UINT64 mTimeoutTicker; +extern UINT64 mTimeoutTicker2; + /** Create 4G PageTable in SMRAM. @@ -533,15 +536,17 @@ StartSyncTimer ( ); /** - Check if the SMM AP Sync timer is timeout. + Check if the SMM AP Sync Timer is timeout specified by Timeout. - @param Timer The start timer from the begin. + @param Timer The start timer from the begin. + @param Timeout The timeout ticker to wait. **/ BOOLEAN EFIAPI IsSyncTimerTimeout ( - IN UINT64 Timer + IN UINT64 Timer, + IN UINT64 Timeout ); /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index f0598b0364..c64d37e498 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -130,6 +130,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdSmmApPerfLogEnable ## CONSUMES [Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c index 0c070c5736..8d29ba7326 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -1,7 +1,7 @@ /** @file SMM Timer feature support -Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -9,6 +9,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PiSmmCpuDxeSmm.h" UINT64 mTimeoutTicker = 0; + +UINT64 mTimeoutTicker2 = 0; + // // Number of counts in a roll-over cycle of the performance counter. // @@ -36,6 +39,10 @@ InitializeSmmTimer ( MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)), 1000 * 1000 ); + mTimeoutTicker2 = DivU64x32 ( + MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout2)), + 1000 * 1000 + ); if (End < Start) { mCountDown = TRUE; mCycle = Start - End; @@ -59,15 +66,17 @@ StartSyncTimer ( } /** - Check if the SMM AP Sync timer is timeout. + Check if the SMM AP Sync Timer is timeout specified by Timeout. - @param Timer The start timer from the begin. + @param Timer The start timer from the begin. + @param Timeout The timeout ticker to wait. **/ BOOLEAN EFIAPI IsSyncTimerTimeout ( - IN UINT64 Timer + IN UINT64 Timer, + IN UINT64 Timeout ) { UINT64 CurrentTimer; @@ -105,5 +114,5 @@ IsSyncTimerTimeout ( } } - return (BOOLEAN)(Delta >= mTimeoutTicker); + return (BOOLEAN)(Delta >= Timeout); } -- cgit From 5a4a7172bce4a6aed0090363c10d806c9c6ec41f Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:26:41 +0300 Subject: BaseTools/FmpCapsuleHeader.py: Explain error when throwing exceptions This gives a caller a chance to report a meaningful error to the user. Signed-off-by: Sergii Dmytruk --- .../Python/Common/Uefi/Capsule/FmpCapsuleHeader.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py index 8abb449c6f..6a112d5f89 100644 --- a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py +++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py @@ -92,7 +92,7 @@ class FmpCapsuleImageHeaderClass (object): def Decode (self, Buffer): if len (Buffer) < self._StructSize: - raise ValueError + raise ValueError ('Buffer is too small for decoding') (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance, ImageCapsuleSupport) = \ struct.unpack ( self._StructFormat, @@ -100,11 +100,11 @@ class FmpCapsuleImageHeaderClass (object): ) if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION: - raise ValueError + raise ValueError ('Incorrect capsule image header version') if UpdateImageIndex < 1: - raise ValueError + raise ValueError ('Update image index is less than 1') if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]): - raise ValueError + raise ValueError ('Non-vendor and vendor parts do not add up') self.Version = Version self.UpdateImageTypeId = uuid.UUID (bytes_le = UpdateImageTypeId) @@ -120,7 +120,7 @@ class FmpCapsuleImageHeaderClass (object): def DumpInfo (self): if not self._Valid: - raise ValueError + raise ValueError ('Can not dump an invalid header') print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version = self.Version)) print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper())) print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex)) @@ -180,7 +180,7 @@ class FmpCapsuleHeaderClass (object): def GetEmbeddedDriver (self, Index): if Index > len (self._EmbeddedDriverList): - raise ValueError + raise ValueError ('Invalid embedded driver index') return self._EmbeddedDriverList[Index] def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1, CapsuleSupport = 0): @@ -188,7 +188,7 @@ class FmpCapsuleHeaderClass (object): def GetFmpCapsuleImageHeader (self, Index): if Index >= len (self._FmpCapsuleImageHeaderList): - raise ValueError + raise ValueError ('Invalid capsule image index') return self._FmpCapsuleImageHeaderList[Index] def Encode (self): @@ -234,14 +234,14 @@ class FmpCapsuleHeaderClass (object): def Decode (self, Buffer): if len (Buffer) < self._StructSize: - raise ValueError + raise ValueError ('Buffer is too small for decoding') (Version, EmbeddedDriverCount, PayloadItemCount) = \ struct.unpack ( self._StructFormat, Buffer[0:self._StructSize] ) if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION: - raise ValueError + raise ValueError ('Incorrect capsule header version') self.Version = Version self.EmbeddedDriverCount = EmbeddedDriverCount @@ -258,7 +258,7 @@ class FmpCapsuleHeaderClass (object): for Index in range (0, EmbeddedDriverCount + PayloadItemCount): ItemOffset = struct.unpack (self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0] if ItemOffset >= len (Buffer): - raise ValueError + raise ValueError ('Item offset is outside of buffer') self._ItemOffsetList.append (ItemOffset) Offset = Offset + self._ItemOffsetSize Result = Buffer[Offset:] @@ -297,7 +297,7 @@ class FmpCapsuleHeaderClass (object): def DumpInfo (self): if not self._Valid: - raise ValueError + raise ValueError ('Can not dump an invalid header') print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version = self.Version)) print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount)) for EmbeddedDriver in self._EmbeddedDriverList: -- cgit From 8e7bd66dc11300cedc520c841e1cc8303f6b4169 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:31:39 +0300 Subject: BaseTools/GenerateCapsule.py: Fix --decode operation Commit b68d566439683d0ebe60d52c85ff0e90331db740 added support for input subject name with signtool and broke --decode operation by using incorrect identifier in one place (could be an incomplete rename during review). It's `args.SignToolSubjectName`, not `args.SignSubjectName`. Signed-off-by: Sergii Dmytruk --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index 35435946c6..9a395d0072 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -690,7 +690,7 @@ if __name__ == '__main__': args.HardwareInstance, args.UpdateImageIndex, args.SignToolPfxFile, - args.SignSubjectName, + args.SignToolSubjectName, args.OpenSslSignerPrivateCertFile, args.OpenSslOtherPublicCertFile, args.OpenSslTrustedPublicCertFile, -- cgit From 3be79ece37085f1037103e665e5df67b3a22b630 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:38:03 +0300 Subject: BaseTools/GenerateCapsule.py: Disallow UpdateImageIndex == 0 on --encode This field seems to be one-based according UEFI specification, default value is 1 and --decode of GenerateCapsule.py errors upon seeing UpdateImageIndex less than 1. So align --encode behaviour to enforce a value within the 1..255 range. Signed-off-by: Sergii Dmytruk --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index 9a395d0072..de1dbbab5f 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -513,11 +513,11 @@ if __name__ == '__main__': raise argparse.ArgumentTypeError ('JSON field MonotonicCount must be an integer in range 0x0..0xffffffffffffffff') else: raise argparse.ArgumentTypeError ('--monotonic-count must be an integer in range 0x0..0xffffffffffffffff') - if self.UpdateImageIndex >0xFF: + if self.UpdateImageIndex < 0x1 or self.UpdateImageIndex > 0xFF: if args.JsonFile: - raise argparse.ArgumentTypeError ('JSON field UpdateImageIndex must be an integer in range 0x0..0xff') + raise argparse.ArgumentTypeError ('JSON field UpdateImageIndex must be an integer in range 0x1..0xff') else: - raise argparse.ArgumentTypeError ('--update-image-index must be an integer in range 0x0..0xff') + raise argparse.ArgumentTypeError ('--update-image-index must be an integer in range 0x1..0xff') if self.UseSignTool: if self.SignToolPfxFile is not None: -- cgit From 822ff966c6dcc8bf5dc9b87d0b4e4ac2f7102e8b Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:42:16 +0300 Subject: BaseTools/GenerateCapsule.py: Better error message on --decode failure Print error text from the exception. Signed-off-by: Sergii Dmytruk --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index de1dbbab5f..4d4e526432 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -873,8 +873,8 @@ if __name__ == '__main__': print ('GenerateCapsule: error: can not write embedded driver file {File}'.format (File = EmbeddedDriverPath)) sys.exit (1) - except: - print ('GenerateCapsule: error: can not decode capsule') + except Exception as Msg: + print ('GenerateCapsule: error: can not decode capsule: ' + str(Msg)) sys.exit (1) GenerateOutputJson(PayloadJsonDescriptorList) PayloadIndex = 0 -- cgit From 47c107817532609ec5b9a142308408510c0a9e39 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:43:13 +0300 Subject: BaseTools/GenerateCapsule.py: Require --output for --decode --decode unconditionally uses args.OutputFile.name as a prefix for output files that it creates and fails in a non-pretty way without --output option. This doesn't address creation/truncation of the file specified via --output, but at least you're able to decode a capsule. Signed-off-by: Sergii Dmytruk --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index 4d4e526432..87fa998274 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -519,6 +519,10 @@ if __name__ == '__main__': else: raise argparse.ArgumentTypeError ('--update-image-index must be an integer in range 0x1..0xff') + if args.Decode: + if args.OutputFile is None: + raise argparse.ArgumentTypeError ('--decode requires --output') + if self.UseSignTool: if self.SignToolPfxFile is not None: self.SignToolPfxFile.close() -- cgit From eeddb86aaaadcf5e716741db54af08531e25ff62 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:46:44 +0300 Subject: BaseTools/GenerateCapsule.py: Fix inconsistent error formatting Just add a space between colon and a more detailed error message in two places. Signed-off-by: Sergii Dmytruk --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index 87fa998274..d694130bc4 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -580,7 +580,7 @@ if __name__ == '__main__': try: SinglePayloadDescriptor.Validate (args) except Exception as Msg: - print ('GenerateCapsule: error:' + str(Msg)) + print ('GenerateCapsule: error: ' + str(Msg)) sys.exit (1) for SinglePayloadDescriptor in PayloadDescriptorList: ImageCapsuleSupport = 0x0000000000000000 @@ -708,7 +708,7 @@ if __name__ == '__main__': try: SinglePayloadDescriptor.Validate (args) except Exception as Msg: - print ('GenerateCapsule: error:' + str(Msg)) + print ('GenerateCapsule: error: ' + str(Msg)) sys.exit (1) try: Result = UefiCapsuleHeader.Decode (Buffer) -- cgit From 26bc42f1e34cdf43057a75b8edcc0bd86c091214 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Sat, 22 Jun 2024 20:47:56 +0300 Subject: BaseTools/GenerateCapsule.py: Fix checking for DepExp presence struct.unpack() returns a tuple even for a single-element pack, resulting in signature verification being evaluated to false even when the signature is there. This fixes --decode and --dump-info actions incorrectly reporting issues with parsing capsule dependencies when there are none. Signed-off-by: Sergii Dmytruk --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index d694130bc4..a773cfb2b3 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -831,7 +831,7 @@ if __name__ == '__main__': print ('--------') print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION') - PayloadSignature = struct.unpack (' Date: Fri, 31 May 2024 13:02:39 +0800 Subject: MdeModulePkg/FaultTolerantWriteSmm: Update buffer valid check func name In the MdeModulePkg/FaultTolerantWriteSmm, the Primary Buffer (CommBuffer) check function has been updated to match the buffer validation behavior: For SMM, the SMM Handlers is to validate the buffer outside MMRAM. For MM, the MM Handlers do not need to validate the buffer if it is the CommBuffer passed from MmCore through the MmiHandler() parameter. Return TRUE directly in this case. There is no function impact. Signed-off-by: Jiaxin Wu Cc: Liming Gao Cc: Ray Ni Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- .../Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c | 6 +++--- .../FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h | 13 +++++-------- .../FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c | 13 +++++-------- .../FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c | 6 +++--- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c index 8c2d209fa0..676f46ded2 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c @@ -43,7 +43,7 @@ Caution: This module requires additional review when modified. This driver need to make sure the CommBuffer is not in the SMRAM range. -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -332,8 +332,8 @@ SmmFaultTolerantWriteHandler ( CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE; - if (!FtwSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { - DEBUG ((DEBUG_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n")); + if (!FtwSmmIsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) { + DEBUG ((DEBUG_ERROR, "SmmFtwHandler: SMM Primary(communication buffer) is not valid!\n")); return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h index f717432e15..73799d3256 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h @@ -2,7 +2,7 @@ The common header file for SMM FTW module and SMM FTW DXE Module. -Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -85,19 +85,16 @@ MmFaultTolerantWriteInitialize ( ); /** - This function checks if the buffer is valid per processor architecture and - does not overlap with SMRAM. + This function checks if the Primary Buffer is valid. @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. - @retval TRUE This buffer is valid per processor architecture and does not - overlap with SMRAM. - @retval FALSE This buffer is not valid per processor architecture or overlaps - with SMRAM. + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. **/ BOOLEAN -FtwSmmIsBufferOutsideSmmValid ( +FtwSmmIsPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ); diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c index 52922a0c53..af837f03d5 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c @@ -2,7 +2,7 @@ Parts of the SMM/MM implementation that are specific to standalone MM -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -14,19 +14,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "FaultTolerantWriteSmmCommon.h" /** - This function checks if the buffer is valid per processor architecture and - does not overlap with SMRAM. + This function checks if the Primary Buffer is valid. @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. - @retval TRUE This buffer is valid per processor architecture and does not - overlap with SMRAM. - @retval FALSE This buffer is not valid per processor architecture or overlaps - with SMRAM. + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. **/ BOOLEAN -FtwSmmIsBufferOutsideSmmValid ( +FtwSmmIsPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c index a7241e651a..d0a218490b 100644 --- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c +++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c @@ -2,7 +2,7 @@ Parts of the SMM/MM implementation that are specific to traditional MM -Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "FaultTolerantWriteSmmCommon.h" /** - This function checks if the buffer is valid per processor architecture and + This function checks if the Primary Buffer is valid per processor architecture and does not overlap with SMRAM. @param Buffer The buffer start address to be checked. @@ -26,7 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent with SMRAM. **/ BOOLEAN -FtwSmmIsBufferOutsideSmmValid ( +FtwSmmIsPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) -- cgit From c0021d31f847f9005cdc1386f8675375d455e8f2 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 5 Jul 2024 11:06:25 +0800 Subject: MdeModulePkg/VarCheckPolicyLib: Update buffer valid check func name In the MdeModulePkg/VarCheckPolicyLib, the Primary Buffer (CommBuffer) check function has been updated to match the buffer validation behavior. For SMM, the SMM Handlers is to validate the buffer outside MMRAM. For MM, the MM Handlers do not need to validate the buffer if it is the CommBuffer passed from MmCore through the MmiHandler() parameter. Return TRUE directly in this case. Existing code is incorrect for the MM check. This will be fixed in the following patch. There is no function impact. Signed-off-by: Jiaxin Wu Cc: Liming Gao Cc: Ray Ni Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c | 9 ++++++--- MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h | 9 +++++---- .../Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c | 9 +++++---- .../Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c | 5 +++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c index 1448af8555..3539206afc 100644 --- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c @@ -2,6 +2,7 @@ This is a NULL library instance that leverages the VarCheck interface and the business logic behind the VariablePolicy code to make its decisions. +Copyright (c) 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -105,13 +106,15 @@ VarCheckPolicyLibMmiHandler ( return EFI_INVALID_PARAMETER; } - // Make sure that the buffer does not overlap SMM. + // + // Make sure that the buffer is valid. // This should be covered by the SmiManage infrastructure, but just to be safe... + // InternalCommBufferSize = *CommBufferSize; if ((InternalCommBufferSize > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE) || - !VarCheckPolicyIsBufferOutsideValid ((UINTN)CommBuffer, (UINT64)InternalCommBufferSize)) + !VarCheckPolicyIsPrimaryBufferValid ((UINTN)CommBuffer, (UINT64)InternalCommBufferSize)) { - DEBUG ((DEBUG_ERROR, "%a - Invalid CommBuffer supplied! 0x%016lX[0x%016lX]\n", __func__, CommBuffer, InternalCommBufferSize)); + DEBUG ((DEBUG_ERROR, "%a - Invalid Primary Buffer (CommBuffer) supplied! 0x%016lX[0x%016lX]\n", __func__, CommBuffer, InternalCommBufferSize)); return EFI_INVALID_PARAMETER; } diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h index 2226c8a19f..5f89f1e285 100644 --- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h @@ -2,6 +2,7 @@ This internal header file defines the common interface of constructor for VarCheckPolicyLib. +Copyright (c) 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -24,17 +25,17 @@ VarCheckPolicyLibCommonConstructor ( ); /** - This function is wrapper function to validate the buffer. + This function is wrapper function to validate the Primary Buffer (CommBuffer). @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. - @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM/MMRAM. - @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM/MMRAM. + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. **/ BOOLEAN EFIAPI -VarCheckPolicyIsBufferOutsideValid ( +VarCheckPolicyIsPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ); diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c index 784a2422aa..f93ad7e7c0 100644 --- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c @@ -1,6 +1,7 @@ /** @file -- VarCheckPolicyLibStandaloneMm.c This is an instance of a VarCheck lib constructor for Standalone MM. +Copyright (c) 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -31,17 +32,17 @@ VarCheckPolicyLibStandaloneConstructor ( } /** - This function is wrapper function to validate the buffer. + This function is wrapper function to validate the Primary Buffer (CommBuffer). @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. - @retval TRUE This buffer is valid per processor architectureand not overlap with MMRAM. - @retval FALSE This buffer is not valid per processor architecture or overlap with MMRAM. + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. **/ BOOLEAN EFIAPI -VarCheckPolicyIsBufferOutsideValid ( +VarCheckPolicyIsPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c index 07bead2724..36dccefdd9 100644 --- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c @@ -1,6 +1,7 @@ /** @file -- VarCheckPolicyLibTraditional.c This is an instance of a VarCheck lib constructor for traditional SMM. +Copyright (c) 2024, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -31,7 +32,7 @@ VarCheckPolicyLibTraditionalConstructor ( } /** - This function is wrapper function to validate the buffer. + This function is wrapper function to validate the Primary Buffer (CommBuffer). @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. @@ -41,7 +42,7 @@ VarCheckPolicyLibTraditionalConstructor ( **/ BOOLEAN EFIAPI -VarCheckPolicyIsBufferOutsideValid ( +VarCheckPolicyIsPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) -- cgit From acfdb6771cdf5db13f8a829b4e1c9f9b45178151 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 5 Jul 2024 11:14:16 +0800 Subject: MdeModulePkg/VarCheckPolicyLib: Fix buffer valid check for MM For MM, the MM Handlers do not need to validate the buffer if it is the CommBuffer passed from MmCore through the MmiHandler() parameter. Return TRUE directly in this case. Fix buffer valid check for MM in this patch. Signed-off-by: Jiaxin Wu Cc: Liming Gao Cc: Ray Ni Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c index f93ad7e7c0..4bfaf1e261 100644 --- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c @@ -47,5 +47,5 @@ VarCheckPolicyIsPrimaryBufferValid ( IN UINT64 Length ) { - return MmIsBufferOutsideMmValid (Buffer, Length); + return TRUE; } -- cgit From 8befdb144193f0fe10c39ab0c21e138c59018b05 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 31 May 2024 12:11:53 +0800 Subject: MdeModulePkg/VariableSmm: Add func for Primary Buffer valid check Add a new function (VariableSmmIsPrimaryBufferValid) to check Primary Buffer valid or not. original function (VariableSmmIsBufferOutsideSmmValid) is used to check the buffer outside MMRAM. Signed-off-by: Jiaxin Wu Cc: Liming Gao Cc: Ray Ni Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- .../Variable/RuntimeDxe/PrivilegePolymorphic.h | 17 ++++++++++++++++- .../Universal/Variable/RuntimeDxe/VariableSmm.c | 6 +++--- .../Variable/RuntimeDxe/VariableStandaloneMm.c | 20 +++++++++++++++++++- .../Variable/RuntimeDxe/VariableTraditionalMm.c | 20 +++++++++++++++++++- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h index 065c75a642..23e950aaed 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h @@ -7,7 +7,7 @@ vs. non-privileged driver code. Copyright (c) 2017, Red Hat, Inc.
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -122,6 +122,21 @@ MmVariableServiceInitialize ( VOID ); +/** + This function checks if the communication buffer is valid. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. +**/ +BOOLEAN +VariableSmmIsPrimaryBufferValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ); + /** This function checks if the buffer is valid per processor architecture and does not overlap with SMRAM. diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c index 5253c328dc..189880c817 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c @@ -14,7 +14,7 @@ VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), SmmVariableGetStatistics() should also do validation based on its own knowledge. -Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -497,8 +497,8 @@ SmmVariableHandler ( return EFI_SUCCESS; } - if (!VariableSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { - DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n")); + if (!VariableSmmIsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) { + DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM Primary Buffer (CommBuffer) is not valid!\n")); return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c index 943993eb67..1e1e933405 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c @@ -2,7 +2,7 @@ Parts of the SMM/MM implementation that are specific to standalone MM -Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,6 +10,24 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "Variable.h" +/** + This function checks if the Primary Buffer (CommBuffer) is valid. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. +**/ +BOOLEAN +VariableSmmIsPrimaryBufferValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ) +{ + return TRUE; +} + /** This function checks if the buffer is valid per processor architecture and does not overlap with SMRAM. diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c index 0369c3cd01..35f6f4b04f 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c @@ -2,7 +2,7 @@ Parts of the SMM/MM implementation that are specific to traditional MM -Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -12,6 +12,24 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include "Variable.h" +/** + This function checks if the Primary Buffer (CommBuffer) is valid. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. +**/ +BOOLEAN +VariableSmmIsPrimaryBufferValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ) +{ + return SmmIsBufferOutsideSmmValid (Buffer, Length); +} + /** This function checks if the buffer is valid per processor architecture and does not overlap with SMRAM. -- cgit From 0986faad973c8d2e98cb8733f9c58d0210f458f4 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 31 May 2024 12:27:54 +0800 Subject: MdeModulePkg/VariableSmm: Fix NonPrimary Buffer check issue VariableSmmIsBufferOutsideSmmValid function is to check the buffer is outside SMM or not. This patch fix the issue that always return true for MM. Meanwhile, this patch renames VariableSmmIsBufferOutsideSmmValid to VariableSmmIsNonPrimaryBufferValid. Signed-off-by: Jiaxin Wu Cc: Liming Gao Cc: Ray Ni Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- .../Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h | 4 ++-- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c | 12 ++++++------ .../Universal/Variable/RuntimeDxe/VariableStandaloneMm.c | 6 +++--- .../Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | 3 ++- .../Universal/Variable/RuntimeDxe/VariableTraditionalMm.c | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h index 23e950aaed..e7bd4c9706 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h @@ -123,7 +123,7 @@ MmVariableServiceInitialize ( ); /** - This function checks if the communication buffer is valid. + This function checks if the Primary Buffer (CommBuffer) is valid. @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. @@ -150,7 +150,7 @@ VariableSmmIsPrimaryBufferValid ( with SMRAM. **/ BOOLEAN -VariableSmmIsBufferOutsideSmmValid ( +VariableSmmIsNonPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c index 189880c817..12b76a9746 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c @@ -864,7 +864,7 @@ SmmVariableHandler ( // Verify runtime buffers do not overlap with SMRAM ranges. // if ((RuntimeVariableCacheContext->RuntimeHobCache != NULL) && - !VariableSmmIsBufferOutsideSmmValid ( + !VariableSmmIsNonPrimaryBufferValid ( (UINTN)RuntimeVariableCacheContext->RuntimeHobCache, (UINTN)RuntimeVariableCacheContext->RuntimeHobCache->Size )) @@ -874,7 +874,7 @@ SmmVariableHandler ( goto EXIT; } - if (!VariableSmmIsBufferOutsideSmmValid ( + if (!VariableSmmIsNonPrimaryBufferValid ( (UINTN)RuntimeVariableCacheContext->RuntimeVolatileCache, (UINTN)RuntimeVariableCacheContext->RuntimeVolatileCache->Size )) @@ -884,7 +884,7 @@ SmmVariableHandler ( goto EXIT; } - if (!VariableSmmIsBufferOutsideSmmValid ( + if (!VariableSmmIsNonPrimaryBufferValid ( (UINTN)RuntimeVariableCacheContext->RuntimeNvCache, (UINTN)RuntimeVariableCacheContext->RuntimeNvCache->Size )) @@ -894,7 +894,7 @@ SmmVariableHandler ( goto EXIT; } - if (!VariableSmmIsBufferOutsideSmmValid ( + if (!VariableSmmIsNonPrimaryBufferValid ( (UINTN)RuntimeVariableCacheContext->PendingUpdate, sizeof (*(RuntimeVariableCacheContext->PendingUpdate)) )) @@ -904,7 +904,7 @@ SmmVariableHandler ( goto EXIT; } - if (!VariableSmmIsBufferOutsideSmmValid ( + if (!VariableSmmIsNonPrimaryBufferValid ( (UINTN)RuntimeVariableCacheContext->ReadLock, sizeof (*(RuntimeVariableCacheContext->ReadLock)) )) @@ -914,7 +914,7 @@ SmmVariableHandler ( goto EXIT; } - if (!VariableSmmIsBufferOutsideSmmValid ( + if (!VariableSmmIsNonPrimaryBufferValid ( (UINTN)RuntimeVariableCacheContext->HobFlushComplete, sizeof (*(RuntimeVariableCacheContext->HobFlushComplete)) )) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c index 1e1e933405..1b9cf6dfd9 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c @@ -7,7 +7,7 @@ Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ - +#include #include "Variable.h" /** @@ -41,12 +41,12 @@ VariableSmmIsPrimaryBufferValid ( with SMRAM. **/ BOOLEAN -VariableSmmIsBufferOutsideSmmValid ( +VariableSmmIsNonPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) { - return TRUE; + return MmIsBufferOutsideMmValid (Buffer, Length); } /** diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index f09bed40cf..c4185718aa 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -18,7 +18,7 @@ # may not be modified without authorization. If platform fails to protect these resources, # the authentication service provided in this driver will be broken, and the behavior is undefined. # -# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2018, Linaro, Ltd. All rights reserved.
# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -71,6 +71,7 @@ BaseMemoryLib DebugLib HobLib + MemLib MemoryAllocationLib MmServicesTableLib SafeIntLib diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c index 35f6f4b04f..7247f7574d 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c @@ -43,7 +43,7 @@ VariableSmmIsPrimaryBufferValid ( with SMRAM. **/ BOOLEAN -VariableSmmIsBufferOutsideSmmValid ( +VariableSmmIsNonPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) -- cgit From d5fad2176cb14283922e07ff1758118d16b17383 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 27 May 2024 13:25:15 +0800 Subject: SecurityPkg/Tcg: Correct buffer valid check func For SMM, the SMM Handlers is to validate the buffer outside MMRAM including the Primary & NonPrimary buffer. For MM, the MM Handlers do not need to validate the Primary buffer if it is passed from MmCore through the MmiHandler() parameter. Return TRUE directly in this case. But need to validate NonPrimary buffer that outside MMRAM. Signed-off-by: Jiaxin Wu Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Yuanhao Xie --- SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c | 18 ++++++++++++++--- SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h | 27 ++++++++++++++++++++++---- SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c | 30 +++++++++++++++++++++++++---- SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c | 26 +++++++++++++++++++++++-- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c index c2cef764e0..0c2799b42a 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c @@ -73,16 +73,28 @@ TpmNvsCommunciate ( return EFI_ACCESS_DENIED; } - if (!IsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) { + CommParams = (TPM_NVS_MM_COMM_BUFFER *)CommBuffer; + + // + // The Primary Buffer validation + // + if (!Tcg2IsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) { DEBUG ((DEBUG_ERROR, "[%a] - MM Communication buffer in invalid location!\n", __func__)); return EFI_ACCESS_DENIED; } + // + // The NonPrimary Buffer validation + // + if (!Tcg2IsNonPrimaryBufferValid (CommParams->TargetAddress, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (TCG_NVS))))) { + DEBUG ((DEBUG_ERROR, "[%a] - MM NonPrimary buffer pointed from Communication buffer in invalid location!\n", __func__)); + return EFI_ACCESS_DENIED; + } + // // Farm out the job to individual functions based on what was requested. // - CommParams = (TPM_NVS_MM_COMM_BUFFER *)CommBuffer; - Status = EFI_SUCCESS; + Status = EFI_SUCCESS; switch (CommParams->Function) { case TpmNvsMmExchangeInfo: DEBUG ((DEBUG_VERBOSE, "[%a] - Function requested: MM_EXCHANGE_NVS_INFO\n", __func__)); diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h index 3672db939b..0be4984f87 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h @@ -55,16 +55,35 @@ Tcg2NotifyMmReady ( ); /** - This function is an abstraction layer for implementation specific Mm buffer validation routine. + This function is for the Primary Buffer validation routine. + The Primary Buffer is the communication buffer requested from + Communicate protocol/PPI. @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. - @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM. - @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM. + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. **/ BOOLEAN -IsBufferOutsideMmValid ( +Tcg2IsPrimaryBufferValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ); + +/** + This function is for the NonPrimary Buffer validation routine. + The NonPrimary Buffer is the buffer which might be pointed from the + communication buffer. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. +**/ +BOOLEAN +Tcg2IsNonPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ); diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c index 9320053224..0f23662ff8 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c @@ -31,16 +31,38 @@ Tcg2NotifyMmReady ( } /** - This function is an abstraction layer for implementation specific Mm buffer validation routine. + This function is for the Primary Buffer validation routine. + The Primary Buffer is the communication buffer requested from + Communicate protocol/PPI. @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. - @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM. - @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM. + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. **/ BOOLEAN -IsBufferOutsideMmValid ( +Tcg2IsPrimaryBufferValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ) +{ + return TRUE; +} + +/** + This function is for the Secondary Buffer validation routine. + The Secondary Buffer is the buffer which is pointed from the + communication buffer. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. +**/ +BOOLEAN +Tcg2IsNonPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c index f7d595e7f3..fd8a51bfd0 100644 --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c @@ -41,7 +41,9 @@ Tcg2NotifyMmReady ( } /** - This function is an abstraction layer for implementation specific Mm buffer validation routine. + This function is for the Primary Buffer validation routine. + The Primary Buffer is the communication buffer requested from + Communicate protocol/PPI. @param Buffer The buffer start address to be checked. @param Length The buffer length to be checked. @@ -50,7 +52,27 @@ Tcg2NotifyMmReady ( @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM. **/ BOOLEAN -IsBufferOutsideMmValid ( +Tcg2IsPrimaryBufferValid ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ) +{ + return SmmIsBufferOutsideSmmValid (Buffer, Length); +} + +/** + This function is for the NonPrimary Buffer validation routine. + The NonPrimary Buffer is the buffer which is pointed from the + communication buffer. + + @param Buffer The buffer start address to be checked. + @param Length The buffer length to be checked. + + @retval TRUE This buffer is valid. + @retval FALSE This buffer is not valid. +**/ +BOOLEAN +Tcg2IsNonPrimaryBufferValid ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length ) -- cgit From 19bcc73213ba1cb280b6e455dea7e153217d579c Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 21 May 2024 10:45:17 +0800 Subject: MdeModulePkg: Add HobPrintLib header file Interface PrintHobList() is added to dump all HOBs info in the HobList. Caller could specify a custom HOB print handler to replace the default print handler when calling the interface. Cc: Ray Ni Cc: Liming Gao Signed-off-by: Wei6 Xu --- MdeModulePkg/Include/Library/HobPrintLib.h | 46 ++++++++++++++++++++++++++++++ MdeModulePkg/MdeModulePkg.dec | 4 +++ 2 files changed, 50 insertions(+) create mode 100644 MdeModulePkg/Include/Library/HobPrintLib.h diff --git a/MdeModulePkg/Include/Library/HobPrintLib.h b/MdeModulePkg/Include/Library/HobPrintLib.h new file mode 100644 index 0000000000..40bb035b91 --- /dev/null +++ b/MdeModulePkg/Include/Library/HobPrintLib.h @@ -0,0 +1,46 @@ +/** @file + The library to print all the HOBs. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HOB_PRINT_LIB_H_ +#define HOB_PRINT_LIB_H_ + +/** + HOB Print Handler to print HOB information. + + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + + @retval EFI_SUCCESS If it completed successfully. + @retval EFI_UNSUPPORTED If the HOB type is not supported. + +**/ +typedef +EFI_STATUS +(*HOB_PRINT_HANDLER)( + IN VOID *Hob, + IN UINT16 HobLength + ); + +/** + Print all HOBs info from the HOB list. + If the input PrintHandler is not NULL, the PrintHandler will be processed first. + If PrintHandler returns EFI_SUCCESS, default HOB info print logic in PrintHobList + will be skipped. + + @param[in] HobStart A pointer to the HOB list. + @param[in] PrintHandler A custom handler to print HOB info. + +**/ +VOID +EFIAPI +PrintHobList ( + IN CONST VOID *HobStart, + IN HOB_PRINT_HANDLER PrintHandler OPTIONAL + ); + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 6148025085..e6e0139fdc 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -174,6 +174,10 @@ # SpiHcPlatformLib|Include/Library/SpiHcPlatformLib.h + ## @libraryclass Provides services to prints all HOB information. + # + HobPrintLib|Include/Library/HobPrintLib.h + [Guids] ## MdeModule package token space guid # Include/Guid/MdeModulePkgTokenSpace.h -- cgit From d5b03d5fba30deb77e3ba0c21f6b0ceb412a9c26 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Mon, 27 May 2024 14:35:47 +0800 Subject: MdeModulePkg: Add HobPrintLib instance The HobPrintLib prints all HOB info from the HOB list. The code is abstracted from UefiPayloadPkg/UefiPayloadEntry/PrintHob.c. Cc: Guo Dong Cc: Sean Rhodes Cc: James Lu Cc: Gua Guo Cc: Ray Ni Signed-off-by: Wei6 Xu --- MdeModulePkg/Library/HobPrintLib/HobPrintLib.c | 469 +++++++++++++++++++++++ MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf | 34 ++ MdeModulePkg/MdeModulePkg.dsc | 1 + 3 files changed, 504 insertions(+) create mode 100644 MdeModulePkg/Library/HobPrintLib/HobPrintLib.c create mode 100644 MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf diff --git a/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c new file mode 100644 index 0000000000..d2fa92ee6a --- /dev/null +++ b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c @@ -0,0 +1,469 @@ +/** @file + Prints all the HOBs. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ROW_LIMITER 16 + +typedef struct { + UINT16 Type; + CHAR8 *Name; + HOB_PRINT_HANDLER PrintHandler; +} HOB_PRINT_HANDLER_TABLE; + +CHAR8 *mMemoryTypeStr[] = { + "EfiReservedMemoryType", + "EfiLoaderCode", + "EfiLoaderData", + "EfiBootServicesCode", + "EfiBootServicesData", + "EfiRuntimeServicesCode", + "EfiRuntimeServicesData", + "EfiConventionalMemory", + "EfiUnusableMemory", + "EfiACPIReclaimMemory", + "EfiACPIMemoryNVS", + "EfiMemoryMappedIO", + "EfiMemoryMappedIOPortSpace", + "EfiPalCode", + "EfiPersistentMemory", + "EfiMaxMemoryType" +}; + +CHAR8 *mResource_Type_List[] = { + "EFI_RESOURCE_SYSTEM_MEMORY ", // 0x00000000 + "EFI_RESOURCE_MEMORY_MAPPED_IO ", // 0x00000001 + "EFI_RESOURCE_IO ", // 0x00000002 + "EFI_RESOURCE_FIRMWARE_DEVICE ", // 0x00000003 + "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT ", // 0x00000004 + "EFI_RESOURCE_MEMORY_RESERVED ", // 0x00000005 + "EFI_RESOURCE_IO_RESERVED ", // 0x00000006 + "EFI_RESOURCE_MAX_MEMORY_TYPE " // 0x00000007 +}; + +/** + Print the Hex value of a given range. + + @param[in] ErrorLevel Error Level to print the Hex value. + @param[in] DataStart A pointer to the start of data to be printed. + @param[in] DataSize The length of the data to be printed. + + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintHex ( + IN UINT32 ErrorLevel, + IN UINT8 *DataStart, + IN UINT16 DataSize + ) +{ + UINTN Index1; + UINTN Index2; + UINT8 *StartAddr; + + StartAddr = DataStart; + for (Index1 = 0; Index1 * ROW_LIMITER < DataSize; Index1++) { + DEBUG ((ErrorLevel, " 0x%04p:", (DataStart - StartAddr))); + for (Index2 = 0; (Index2 < ROW_LIMITER) && (Index1 * ROW_LIMITER + Index2 < DataSize); Index2++) { + DEBUG ((ErrorLevel, " %02x", *DataStart)); + DataStart++; + } + + DEBUG ((ErrorLevel, "\n")); + } + + return EFI_SUCCESS; +} + +/** + Print the Hex value of the Invalid HOB. + + @param[in] HobStart A pointer to the Invalid HOB. + @param[in] HobLength The length in bytes of the Invalid HOB. + + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintInvalidHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + DEBUG ((DEBUG_ERROR, " Invalid HOB. Full hex dump in below:\n")); + PrintHex (DEBUG_ERROR, HobStart, HobLength); + return RETURN_INVALID_PARAMETER; +} + +/** + Print the information in HandOffHob. + + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_HANDOFF. + @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_HANDOFF. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintHandOffHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + if (HobLength < sizeof (*Hob.HandoffInformationTable)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " BootMode = 0x%x\n", Hob.HandoffInformationTable->BootMode)); + DEBUG ((DEBUG_INFO, " EfiMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryTop)); + DEBUG ((DEBUG_INFO, " EfiMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryBottom)); + DEBUG ((DEBUG_INFO, " EfiFreeMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop)); + DEBUG ((DEBUG_INFO, " EfiFreeMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryBottom)); + DEBUG ((DEBUG_INFO, " EfiEndOfHobList = 0x%lx\n", Hob.HandoffInformationTable->EfiEndOfHobList)); + return EFI_SUCCESS; +} + +/** + Print the information in Memory Allocation Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION. + @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintMemoryAllocationHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + + if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocStackGuid)) { + if (HobLength < sizeof (*Hob.MemoryAllocationStack)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_STACK\n")); + } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocBspStoreGuid)) { + if (HobLength < sizeof (*Hob.MemoryAllocationBspStore)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_BSP_STORE\n")); + } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocModuleGuid)) { + if (HobLength < sizeof (*Hob.MemoryAllocationModule)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_MODULE\n")); + DEBUG ((DEBUG_INFO, " ModuleName = %g\n", &Hob.MemoryAllocationModule->ModuleName)); + DEBUG ((DEBUG_INFO, " EntryPoint = 0x%lx\n", Hob.MemoryAllocationModule->EntryPoint)); + } else { + if (HobLength < sizeof (*Hob.MemoryAllocation)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_TYPE_MEMORY_ALLOCATION\n")); + } + + DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.MemoryAllocationStack->AllocDescriptor.Name)); + DEBUG ((DEBUG_INFO, " MemoryBaseAddress = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress)); + DEBUG ((DEBUG_INFO, " MemoryLength = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength)); + DEBUG ((DEBUG_INFO, " MemoryType = %a \n", mMemoryTypeStr[Hob.MemoryAllocationStack->AllocDescriptor.MemoryType])); + return EFI_SUCCESS; +} + +/** + Print the information in Resource Discriptor Hob. + @param[in] HobStart A pointer to HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. + @param[in] HobLength The Length in bytes of HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintResourceDiscriptorHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.ResourceDescriptor)); + + DEBUG ((DEBUG_INFO, " ResourceType = %a\n", mResource_Type_List[Hob.ResourceDescriptor->ResourceType])); + if (!IsZeroGuid (&Hob.ResourceDescriptor->Owner)) { + DEBUG ((DEBUG_INFO, " Owner = %g\n", &Hob.ResourceDescriptor->Owner)); + } + + DEBUG ((DEBUG_INFO, " ResourceAttribute = 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); + DEBUG ((DEBUG_INFO, " PhysicalStart = 0x%lx\n", Hob.ResourceDescriptor->PhysicalStart)); + DEBUG ((DEBUG_INFO, " ResourceLength = 0x%lx\n", Hob.ResourceDescriptor->ResourceLength)); + return EFI_SUCCESS; +} + +/** + Print the Guid Hob using related print handle function. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintGuidHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT16 DataLength; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Guid)); + + DataLength = GET_GUID_HOB_DATA_SIZE (Hob.Raw); + + DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.Guid->Name)); + DEBUG ((DEBUG_INFO, " DataLength = 0x%x\n", DataLength)); + PrintHex (DEBUG_VERBOSE, GET_GUID_HOB_DATA (Hob.Raw), DataLength); + return EFI_SUCCESS; +} + +/** + Print the information in FV Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintFvHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume->Length)); + return EFI_SUCCESS; +} + +/** + Print the information in Cpu Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_CPU. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_CPU. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintCpuHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Cpu)); + + DEBUG ((DEBUG_INFO, " SizeOfMemorySpace = 0x%lx\n", Hob.Cpu->SizeOfMemorySpace)); + DEBUG ((DEBUG_INFO, " SizeOfIoSpace = 0x%lx\n", Hob.Cpu->SizeOfIoSpace)); + return EFI_SUCCESS; +} + +/** + Print the information in MemoryPoolHob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_POOL. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_MEMORY_POOL. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintMemoryPoolHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT16 AllocationSize; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Pool)); + + AllocationSize = HobLength - sizeof (EFI_HOB_GENERIC_HEADER); + DEBUG ((DEBUG_INFO, " AllocationSize = 0x%lx\n", AllocationSize)); + + PrintHex (DEBUG_VERBOSE, Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER), AllocationSize); + + return EFI_SUCCESS; +} + +/** + Print the information in Fv2Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV2. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV2. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintFv2Hob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume2)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume2->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume2->Length)); + DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume2->FvName)); + DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume2->FileName)); + return EFI_SUCCESS; +} + +/** + Print the information in Capsule Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintCapsuleHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Capsule)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.Capsule->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.Capsule->Length)); + return EFI_SUCCESS; +} + +/** + Print the information in Fv3 Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV3. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV3. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintFv3Hob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume3)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume3->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume3->Length)); + DEBUG ((DEBUG_INFO, " AuthenticationStatus = 0x%x\n", Hob.FirmwareVolume3->AuthenticationStatus)); + DEBUG ((DEBUG_INFO, " ExtractedFv = %a\n", (Hob.FirmwareVolume3->ExtractedFv ? "True" : "False"))); + DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume3->FvName)); + DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume3->FileName)); + return EFI_SUCCESS; +} + +// +// Mapping table from Hob type to Hob print function. +// +HOB_PRINT_HANDLER_TABLE mHobHandles[] = { + { EFI_HOB_TYPE_HANDOFF, "EFI_HOB_TYPE_HANDOFF", PrintHandOffHob }, + { EFI_HOB_TYPE_MEMORY_ALLOCATION, "EFI_HOB_TYPE_MEMORY_ALLOCATION", PrintMemoryAllocationHob }, + { EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR", PrintResourceDiscriptorHob }, + { EFI_HOB_TYPE_GUID_EXTENSION, "EFI_HOB_TYPE_GUID_EXTENSION", PrintGuidHob }, + { EFI_HOB_TYPE_FV, "EFI_HOB_TYPE_FV", PrintFvHob }, + { EFI_HOB_TYPE_CPU, "EFI_HOB_TYPE_CPU", PrintCpuHob }, + { EFI_HOB_TYPE_MEMORY_POOL, "EFI_HOB_TYPE_MEMORY_POOL", PrintMemoryPoolHob }, + { EFI_HOB_TYPE_FV2, "EFI_HOB_TYPE_FV2", PrintFv2Hob }, + { EFI_HOB_TYPE_UEFI_CAPSULE, "EFI_HOB_TYPE_UEFI_CAPSULE", PrintCapsuleHob }, + { EFI_HOB_TYPE_FV3, "EFI_HOB_TYPE_FV3", PrintFv3Hob } +}; + +/** + Print all HOBs info from the HOB list. + + @param[in] HobStart A pointer to the HOB list. + @param[in] PrintHandler A custom handler to print HOB info. + +**/ +VOID +EFIAPI +PrintHobList ( + IN CONST VOID *HobStart, + IN HOB_PRINT_HANDLER PrintHandler + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + UINTN Count; + UINTN Index; + + ASSERT (HobStart != NULL); + + Hob.Raw = (UINT8 *)HobStart; + DEBUG ((DEBUG_INFO, "Print all Hob information from Hob 0x%p\n", Hob.Raw)); + + Status = EFI_SUCCESS; + Count = 0; + // + // Parse the HOB list to see which type it is, and print the information. + // + while (!END_OF_HOB_LIST (Hob)) { + // + // Print HOB generic information + // + for (Index = 0; Index < ARRAY_SIZE (mHobHandles); Index++) { + if (Hob.Header->HobType == mHobHandles[Index].Type) { + DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %a, Offset = 0x%p, Length = 0x%x\n", Count, mHobHandles[Index].Name, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength)); + break; + } + } + + if (Index == ARRAY_SIZE (mHobHandles)) { + DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %d, Offset = 0x%p, Length = 0x%x\n", Count, Hob.Header->HobType, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength)); + } + + // + // Process custom HOB print handler first + // + if (PrintHandler != NULL) { + Status = PrintHandler (Hob.Raw, Hob.Header->HobLength); + } + + // + // Process internal HOB print handler + // + if ((PrintHandler == NULL) || EFI_ERROR (Status)) { + if (Index < ARRAY_SIZE (mHobHandles)) { + mHobHandles[Index].PrintHandler (Hob.Raw, Hob.Header->HobLength); + } else { + DEBUG ((DEBUG_INFO, " Unkown Hob type, full hex dump in below:\n")); + PrintHex (DEBUG_INFO, Hob.Raw, Hob.Header->HobLength); + } + } + + Count++; + Hob.Raw = GET_NEXT_HOB (Hob); + } + + DEBUG ((DEBUG_INFO, "There are totally %d Hobs, the End Hob address is %p\n", Count, Hob.Raw)); +} diff --git a/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf new file mode 100644 index 0000000000..a88cabf67d --- /dev/null +++ b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf @@ -0,0 +1,34 @@ +## @file +# Library class that prints all HOBs. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = HobPrintLib + FILE_GUID = 6b6f69c4-4272-4e8f-9c7f-747e7eed3ba8 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = HobPrintLib + +[Sources] + HobPrintLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + HobLib + +[Guids] + gEfiHobMemoryAllocBspStoreGuid + gEfiHobMemoryAllocStackGuid + gEfiMemoryTypeInformationGuid diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index a1c8e2f905..fe7ab972ad 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -353,6 +353,7 @@ MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf + MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf -- cgit From e94cbfc84579304a7f4bfc99cf90ec8fba733ff1 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Mon, 27 May 2024 14:39:19 +0800 Subject: UefiPayloadPkg/UefiPayloadEntry: Use HobPrintLib to dump HOBs Leverage generic HOB print code in MdeModulePkg/Library/HobPrintLib. Print UefiPayload specified GUID HOB info as custom HOB print handler when calling the PrintHobList() interface. Cc: Guo Dong Cc: Sean Rhodes Cc: James Lu Cc: Gua Guo Cc: Ray Ni Signed-off-by: Wei6 Xu --- .../UefiPayloadEntry/FitUniversalPayloadEntry.inf | 1 + UefiPayloadPkg/UefiPayloadEntry/PrintHob.c | 343 +-------------------- .../UefiPayloadEntry/UniversalPayloadEntry.inf | 1 + UefiPayloadPkg/UefiPayloadPkg.dsc | 1 + 4 files changed, 20 insertions(+), 326 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf index b87a0989ee..04d0a795dc 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf @@ -54,6 +54,7 @@ PeCoffLib CpuLib FdtLib + HobPrintLib [Guids] gEfiMemoryTypeInformationGuid diff --git a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c index b63e93c07e..8c5d944759 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c +++ b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c @@ -10,51 +10,7 @@ #include #include #include - -#define ROW_LIMITER 16 - -typedef -EFI_STATUS -(*HOB_PRINT_HANDLER) ( - IN VOID *Hob, - IN UINT16 HobLength - ); - -typedef struct { - UINT16 Type; - CHAR8 *Name; - HOB_PRINT_HANDLER PrintHandler; -} HOB_PRINT_HANDLER_TABLE; - -CHAR8 *mMemoryTypeStr[] = { - "EfiReservedMemoryType", - "EfiLoaderCode", - "EfiLoaderData", - "EfiBootServicesCode", - "EfiBootServicesData", - "EfiRuntimeServicesCode", - "EfiRuntimeServicesData", - "EfiConventionalMemory", - "EfiUnusableMemory", - "EfiACPIReclaimMemory", - "EfiACPIMemoryNVS", - "EfiMemoryMappedIO", - "EfiMemoryMappedIOPortSpace", - "EfiPalCode", - "EfiPersistentMemory", - "EfiMaxMemoryType" -}; - -CHAR8 *mResource_Type_List[] = { - "EFI_RESOURCE_SYSTEM_MEMORY ", // 0x00000000 - "EFI_RESOURCE_MEMORY_MAPPED_IO ", // 0x00000001 - "EFI_RESOURCE_IO ", // 0x00000002 - "EFI_RESOURCE_FIRMWARE_DEVICE ", // 0x00000003 - "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT ", // 0x00000004 - "EFI_RESOURCE_MEMORY_RESERVED ", // 0x00000005 - "EFI_RESOURCE_IO_RESERVED ", // 0x00000006 - "EFI_RESOURCE_MAX_MEMORY_TYPE " // 0x00000007 -}; +#include typedef EFI_STATUS @@ -69,133 +25,6 @@ typedef struct { CHAR8 *GuidName; } GUID_HOB_PRINT_HANDLE; -typedef struct { - EFI_GUID *Guid; - CHAR8 *Type; -} PRINT_MEMORY_ALLOCCATION_HOB; - -/** - Print the Hex value of a given range. - @param[in] DataStart A pointer to the start of data to be printed. - @param[in] DataSize The length of the data to be printed. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintHex ( - IN UINT8 *DataStart, - IN UINT16 DataSize - ) -{ - UINTN Index1; - UINTN Index2; - UINT8 *StartAddr; - - StartAddr = DataStart; - for (Index1 = 0; Index1 * ROW_LIMITER < DataSize; Index1++) { - DEBUG ((DEBUG_VERBOSE, " 0x%04p:", (DataStart - StartAddr))); - for (Index2 = 0; (Index2 < ROW_LIMITER) && (Index1 * ROW_LIMITER + Index2 < DataSize); Index2++) { - DEBUG ((DEBUG_VERBOSE, " %02x", *DataStart)); - DataStart++; - } - - DEBUG ((DEBUG_VERBOSE, "\n")); - } - - return EFI_SUCCESS; -} - -/** - Print the information in HandOffHob. - - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_HANDOFF. - @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_HANDOFF. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintHandOffHob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.HandoffInformationTable)); - DEBUG ((DEBUG_INFO, " BootMode = 0x%x\n", Hob.HandoffInformationTable->BootMode)); - DEBUG ((DEBUG_INFO, " EfiMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryTop)); - DEBUG ((DEBUG_INFO, " EfiMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryBottom)); - DEBUG ((DEBUG_INFO, " EfiFreeMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop)); - DEBUG ((DEBUG_INFO, " EfiFreeMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryBottom)); - DEBUG ((DEBUG_INFO, " EfiEndOfHobList = 0x%lx\n", Hob.HandoffInformationTable->EfiEndOfHobList)); - return EFI_SUCCESS; -} - -/** - Print the information in Memory Allocation Hob. - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION. - @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintMemoryAllocationHob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = (UINT8 *)HobStart; - - if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocStackGuid)) { - ASSERT (HobLength >= sizeof (*Hob.MemoryAllocationStack)); - DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_STACK\n")); - } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocBspStoreGuid)) { - ASSERT (HobLength >= sizeof (*Hob.MemoryAllocationBspStore)); - DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_BSP_STORE\n")); - } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocModuleGuid)) { - ASSERT (HobLength >= sizeof (*Hob.MemoryAllocationModule)); - DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_MODULE\n")); - DEBUG ((DEBUG_INFO, " Module Name = %g\n", Hob.MemoryAllocationModule->ModuleName)); - DEBUG ((DEBUG_INFO, " Physical Address = 0x%lx\n", Hob.MemoryAllocationModule->EntryPoint)); - } else { - ASSERT (HobLength >= sizeof (*Hob.MemoryAllocation)); - DEBUG ((DEBUG_INFO, " Type = EFI_HOB_TYPE_MEMORY_ALLOCATION\n")); - } - - DEBUG ((DEBUG_INFO, " MemoryBaseAddress = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress)); - DEBUG ((DEBUG_INFO, " MemoryLength = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength)); - DEBUG ((DEBUG_INFO, " MemoryType = %a \n", mMemoryTypeStr[Hob.MemoryAllocationStack->AllocDescriptor.MemoryType])); - return EFI_SUCCESS; -} - -/** - Print the information in Resource Discriptor Hob. - @param[in] HobStart A pointer to HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. - @param[in] HobLength The Length in bytes of HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintResourceDiscriptorHob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.ResourceDescriptor)); - - DEBUG ((DEBUG_INFO, " ResourceType = %a\n", mResource_Type_List[Hob.ResourceDescriptor->ResourceType])); - if (!IsZeroGuid (&Hob.ResourceDescriptor->Owner)) { - DEBUG ((DEBUG_INFO, " Owner = %g\n", Hob.ResourceDescriptor->Owner)); - } - - DEBUG ((DEBUG_INFO, " ResourceAttribute = 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); - DEBUG ((DEBUG_INFO, " PhysicalStart = 0x%lx\n", Hob.ResourceDescriptor->PhysicalStart)); - DEBUG ((DEBUG_INFO, " ResourceLength = 0x%lx\n", Hob.ResourceDescriptor->ResourceLength)); - return EFI_SUCCESS; -} - /** Print the information in Acpi Guid Hob. @@ -456,9 +285,10 @@ GUID_HOB_PRINT_HANDLE GuidHobPrintHandleTable[] = { @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. @retval EFI_SUCCESS If it completed successfully. + @retval EFI_UNSUPPORTED If the HOB GUID is not supported. **/ EFI_STATUS -PrintGuidHob ( +InternalPrintGuidHob ( IN VOID *HobStart, IN UINT16 HobLength ) @@ -478,53 +308,7 @@ PrintGuidHob ( } } - DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.Guid->Name)); - PrintHex (GET_GUID_HOB_DATA (Hob.Raw), GET_GUID_HOB_DATA_SIZE (Hob.Raw)); - return EFI_SUCCESS; -} - -/** - Print the information in FV Hob. - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV. - @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintFvHob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume)); - - DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume->BaseAddress)); - DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume->Length)); - return EFI_SUCCESS; -} - -/** - Print the information in Cpu Hob. - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_CPU. - @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_CPU. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintCpuHob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.Cpu)); - - DEBUG ((DEBUG_INFO, " SizeOfMemorySpace = 0x%lx\n", Hob.Cpu->SizeOfMemorySpace)); - DEBUG ((DEBUG_INFO, " SizeOfIoSpace = 0x%lx\n", Hob.Cpu->SizeOfIoSpace)); - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } /** @@ -534,7 +318,7 @@ PrintCpuHob ( @retval EFI_SUCCESS If it completed successfully. **/ EFI_STATUS -PrintMemoryPoolHob ( +InternalPrintMemoryPoolHob ( IN VOID *HobStart, IN UINT16 HobLength ) @@ -543,37 +327,16 @@ PrintMemoryPoolHob ( } /** - Print the information in Fv2Hob. - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV2. - @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV2. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintFv2Hob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; + HOB Print Handler to print Guid Hob. - Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume2)); - - DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume2->BaseAddress)); - DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume2->Length)); - DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume2->FvName)); - DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume2->FileName)); - return EFI_SUCCESS; -} + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. -/** - Print the information in Capsule Hob. - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE. - @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE. @retval EFI_SUCCESS If it completed successfully. + @retval EFI_UNSUPPORTED If the HOB type is not supported. **/ EFI_STATUS -PrintCapsuleHob ( +InternalPrintHobs ( IN VOID *HobStart, IN UINT16 HobLength ) @@ -581,96 +344,24 @@ PrintCapsuleHob ( EFI_PEI_HOB_POINTERS Hob; Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.Capsule)); - - DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.Capsule->BaseAddress)); - DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.Capsule->Length)); - return EFI_SUCCESS; -} -/** - Print the information in Fv3 Hob. - @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV3. - @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV3. - @retval EFI_SUCCESS If it completed successfully. -**/ -EFI_STATUS -PrintFv3Hob ( - IN VOID *HobStart, - IN UINT16 HobLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; + if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) { + return InternalPrintGuidHob (Hob.Raw, HobLength); + } else if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_POOL) { + return InternalPrintMemoryPoolHob (Hob.Raw, HobLength); + } - Hob.Raw = (UINT8 *)HobStart; - ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume3)); - - DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume3->BaseAddress)); - DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume3->Length)); - DEBUG ((DEBUG_INFO, " AuthenticationStatus = 0x%x\n", Hob.FirmwareVolume3->AuthenticationStatus)); - DEBUG ((DEBUG_INFO, " ExtractedFv = %a\n", (Hob.FirmwareVolume3->ExtractedFv ? "True" : "False"))); - DEBUG ((DEBUG_INFO, " FVName = %g\n", &Hob.FirmwareVolume3->FvName)); - DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume3->FileName)); - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } -// -// Mappint table from Hob type to Hob print function. -// -HOB_PRINT_HANDLER_TABLE mHobHandles[] = { - { EFI_HOB_TYPE_HANDOFF, "EFI_HOB_TYPE_HANDOFF", PrintHandOffHob }, - { EFI_HOB_TYPE_MEMORY_ALLOCATION, "EFI_HOB_TYPE_MEMORY_ALLOCATION", PrintMemoryAllocationHob }, - { EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR", PrintResourceDiscriptorHob }, - { EFI_HOB_TYPE_GUID_EXTENSION, "EFI_HOB_TYPE_GUID_EXTENSION", PrintGuidHob }, - { EFI_HOB_TYPE_FV, "EFI_HOB_TYPE_FV", PrintFvHob }, - { EFI_HOB_TYPE_CPU, "EFI_HOB_TYPE_CPU", PrintCpuHob }, - { EFI_HOB_TYPE_MEMORY_POOL, "EFI_HOB_TYPE_MEMORY_POOL", PrintMemoryPoolHob }, - { EFI_HOB_TYPE_FV2, "EFI_HOB_TYPE_FV2", PrintFv2Hob }, - { EFI_HOB_TYPE_UEFI_CAPSULE, "EFI_HOB_TYPE_UEFI_CAPSULE", PrintCapsuleHob }, - { EFI_HOB_TYPE_FV3, "EFI_HOB_TYPE_FV3", PrintFv3Hob } -}; - /** Print all HOBs info from the HOB list. @param[in] HobStart A pointer to the HOB list - @return The pointer to the HOB list. **/ VOID PrintHob ( IN CONST VOID *HobStart ) { - EFI_PEI_HOB_POINTERS Hob; - UINTN Count; - UINTN Index; - - ASSERT (HobStart != NULL); - - Hob.Raw = (UINT8 *)HobStart; - DEBUG ((DEBUG_INFO, "Print all Hob information from Hob 0x%p\n", Hob.Raw)); - - Count = 0; - // - // Parse the HOB list to see which type it is, and print the information. - // - while (!END_OF_HOB_LIST (Hob)) { - for (Index = 0; Index < ARRAY_SIZE (mHobHandles); Index++) { - if (Hob.Header->HobType == mHobHandles[Index].Type) { - DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %a, Offset = 0x%p, Length = 0x%x\n", Count, mHobHandles[Index].Name, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength)); - mHobHandles[Index].PrintHandler (Hob.Raw, Hob.Header->HobLength); - break; - } - } - - if (Index == ARRAY_SIZE (mHobHandles)) { - DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %d, Offset = 0x%p, Length = 0x%x\n", Count, Hob.Header->HobType, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength)); - DEBUG ((DEBUG_INFO, " Unkown Hob type\n")); - PrintHex (Hob.Raw, Hob.Header->HobLength); - } - - Count++; - Hob.Raw = GET_NEXT_HOB (Hob); - } - - DEBUG ((DEBUG_INFO, "There are totally %d Hobs, the End Hob address is %p\n", Count, Hob.Raw)); + PrintHobList (HobStart, InternalPrintHobs); } diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index a62da5c705..c3571e3c28 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -53,6 +53,7 @@ HobLib PeCoffLib CpuLib + HobPrintLib [Guids] gEfiMemoryTypeInformationGuid diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 2860a659f6..ca419a950b 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -317,6 +317,7 @@ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf SmmRelocationLib|UefiCpuPkg/Library/SmmRelocationLib/SmmRelocationLib.inf + HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf [LibraryClasses.common] !if $(BOOTSPLASH_IMAGE) -- cgit From 049e12c03d27f0a6bf57f4f1835cab5e205661a7 Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Tue, 21 May 2024 11:46:20 +0800 Subject: StandaloneMmPkg/Core: Dump all HOB info in entrypoint Print HOB information at top of StandaloneMmMain(). Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Ray Ni Cc: Jiaxin Wu Signed-off-by: Wei6 Xu --- StandaloneMmPkg/Core/StandaloneMmCore.c | 4 ++++ StandaloneMmPkg/Core/StandaloneMmCore.h | 2 +- StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 + StandaloneMmPkg/StandaloneMmPkg.dsc | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 1074f309d7..81db9a9538 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -512,6 +512,10 @@ StandaloneMmMain ( DEBUG ((DEBUG_INFO, "MmMain - 0x%x\n", HobStart)); + DEBUG_CODE ( + PrintHobList (HobStart, NULL); + ); + // // Determine if the caller has passed a reference to a MM_CORE_PRIVATE_DATA // structure in the Hoblist. This choice will govern how boot information is diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index cfb417d7cc..a8fda6dcc2 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -40,7 +40,7 @@ #include #include #include - +#include #include #include diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 02ecd68f37..8cc9638db5 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -52,6 +52,7 @@ PeCoffLib ReportStatusCodeLib StandaloneMmCoreEntryPoint + HobPrintLib [Protocols] gEfiDxeMmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 8012f93b7d..f548bf87d4 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -59,6 +59,7 @@ StandaloneMmCoreEntryPoint|StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf + HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf [LibraryClasses.AARCH64, LibraryClasses.ARM] ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf -- cgit From 95a6892aacfef6c7862058fcdc495f6b35df9367 Mon Sep 17 00:00:00 2001 From: Matthew Carlson Date: Wed, 19 Jun 2024 21:31:38 -0700 Subject: BaseTools: Add VS2022 support. Adding tools_def for VS2022. Update WindowsVsToolChain to support VS2022. Update set_vsPrefix_envs and toolsetup and edksetup to support VS2022. Signed-off-by: Aaron Pop --- BaseTools/Conf/tools_def.template | 165 ++++++++++++++++++++- .../WindowsVsToolChain/WindowsVsToolChain.py | 158 +++++++++++++++++++- BaseTools/set_vsprefix_envs.bat | 62 ++++++++ BaseTools/toolsetup.bat | 12 +- edksetup.bat | 2 + 5 files changed, 392 insertions(+), 7 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index c34ecfd557..0dea1899fb 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -20,8 +20,9 @@ # - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC # - Add GCC and GCCNOLTO # - Deprecate GCC48, GCC49 and GCC5. +# 3.01 - Add toolchain for VS2022 # -#!VERSION=3.00 +#!VERSION=3.01 IDENTIFIER = Default TOOL_CHAIN_CONF @@ -50,6 +51,13 @@ DEFINE VS2019_BIN_X64 = DEF(VS2019_BIN)\HostDEF(VS_HOST)\x64 DEFINE VS2019_BIN_ARM = DEF(VS2019_BIN)\HostDEF(VS_HOST)\arm DEFINE VS2019_BIN_AARCH64 = DEF(VS2019_BIN)\HostDEF(VS_HOST)\arm64 +DEFINE VS2022_BIN = ENV(VS2022_PREFIX)bin +DEFINE VS2022_BIN_HOST = DEF(VS2022_BIN)\HostDEF(VS_HOST)\DEF(VS_HOST) +DEFINE VS2022_BIN_IA32 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\x86 +DEFINE VS2022_BIN_X64 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\x64 +DEFINE VS2022_BIN_ARM = DEF(VS2022_BIN)\HostDEF(VS_HOST)\arm +DEFINE VS2022_BIN_AARCH64 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\arm64 + # # Resource compiler # @@ -62,7 +70,7 @@ DEFINE WINSDKx86_BIN = ENV(WINSDKx86_PREFIX) DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x86\ DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x64 -# Microsoft Visual Studio 2017/2019 Professional Edition +# Microsoft Visual Studio 2017/2019/2022 Professional Edition DEFINE WINSDK10_BIN = ENV(WINSDK10_PREFIX)DEF(VS_HOST) # These defines are needed for certain Microsoft Visual Studio tools that @@ -158,9 +166,11 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc # Required to build platforms or ACPI tables: # Intel(r) ACPI Compiler (iasl.exe) from # https://acpica.org/downloads -# Note: -# Building of XIP firmware images for ARM/ARM64 is not currently supported (only applications). -# /FILEALIGN:4096 and other changes are needed for ARM firmware builds. +# VS2022 -win32,win64- Requires: +# Microsoft Visual Studio 2022 version 17.0 or later +# Optional: +# Required to build EBC drivers: +# Intel(r) Compiler for Efi Byte Code (Intel(r) EBC Compiler) # GCCNOLTO -Linux,Windows- Requires: # GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi # Optional: @@ -723,6 +733,151 @@ NOOPT_VS2019_AARCH64_ASM_FLAGS = /nologo RELEASE_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /MERGE:.rdata=.data NOOPT_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG +#################################################################################### +# VS2022 - Microsoft Visual Studio 2022 with Intel ASL +# ASL - Intel ACPI Source Language Compiler (iasl.exe) +#################################################################################### +# VS2022 - Microsoft Visual Studio 2022 with Intel ASL +*_VS2022_*_*_FAMILY = MSFT +*_VS2022_*_*_DLL = DEF(VS2022_BIN_HOST) + +*_VS2022_*_MAKE_PATH = DEF(VS2022_BIN_HOST)\nmake.exe +*_VS2022_*_MAKE_FLAG = /nologo +*_VS2022_*_RC_PATH = DEF(RC_PATH) + +*_VS2022_*_MAKE_FLAGS = /nologo +*_VS2022_*_SLINK_FLAGS = /NOLOGO /LTCG +*_VS2022_*_APP_FLAGS = /nologo /E /TC +*_VS2022_*_PP_FLAGS = /nologo /E /TC /FIAutoGen.h +*_VS2022_*_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FI$(MODULE_NAME)StrDefs.h +# *_VS2022_*_DLINK2_FLAGS = /WHOLEARCHIVE # MU_CHANGE +*_VS2022_*_ASM16_PATH = DEF(VS2022_BIN_IA32)\ml.exe +*_VS2022_*_DEPS_FLAGS = DEF(MSFT_DEPS_FLAGS) +################## +# ASL definitions +################## +*_VS2022_*_ASL_PATH = DEF(WIN_IASL_BIN) +*_VS2022_*_ASL_FLAGS = DEF(DEFAULT_WIN_ASL_FLAGS) +*_VS2022_*_ASL_OUTFLAGS = DEF(DEFAULT_WIN_ASL_OUTFLAGS) +*_VS2022_*_ASLCC_FLAGS = DEF(MSFT_ASLCC_FLAGS) +*_VS2022_*_ASLPP_FLAGS = DEF(MSFT_ASLPP_FLAGS) +*_VS2022_*_ASLDLINK_FLAGS = DEF(MSFT_ASLDLINK_FLAGS) + +################## +# IA32 definitions +################## +*_VS2022_IA32_CC_PATH = DEF(VS2022_BIN_IA32)\cl.exe +*_VS2022_IA32_VFRPP_PATH = DEF(VS2022_BIN_IA32)\cl.exe +*_VS2022_IA32_ASLCC_PATH = DEF(VS2022_BIN_IA32)\cl.exe +*_VS2022_IA32_ASLPP_PATH = DEF(VS2022_BIN_IA32)\cl.exe +*_VS2022_IA32_SLINK_PATH = DEF(VS2022_BIN_IA32)\lib.exe +*_VS2022_IA32_DLINK_PATH = DEF(VS2022_BIN_IA32)\link.exe +*_VS2022_IA32_ASLDLINK_PATH= DEF(VS2022_BIN_IA32)\link.exe +*_VS2022_IA32_APP_PATH = DEF(VS2022_BIN_IA32)\cl.exe +*_VS2022_IA32_PP_PATH = DEF(VS2022_BIN_IA32)\cl.exe +*_VS2022_IA32_ASM_PATH = DEF(VS2022_BIN_IA32)\ml.exe + + *_VS2022_IA32_MAKE_FLAGS = /nologo + DEBUG_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw +RELEASE_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw +NOOPT_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od + + DEBUG_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi +RELEASE_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd +NOOPT_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi + + DEBUG_VS2022_IA32_NASM_FLAGS = -Ox -f win32 -g +RELEASE_VS2022_IA32_NASM_FLAGS = -Ox -f win32 +NOOPT_VS2022_IA32_NASM_FLAGS = -O0 -f win32 -g + + DEBUG_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG +RELEASE_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data +NOOPT_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + +################## +# X64 definitions +################## +*_VS2022_X64_CC_PATH = DEF(VS2022_BIN_X64)\cl.exe +*_VS2022_X64_PP_PATH = DEF(VS2022_BIN_X64)\cl.exe +*_VS2022_X64_APP_PATH = DEF(VS2022_BIN_X64)\cl.exe +*_VS2022_X64_VFRPP_PATH = DEF(VS2022_BIN_X64)\cl.exe +*_VS2022_X64_ASLCC_PATH = DEF(VS2022_BIN_X64)\cl.exe +*_VS2022_X64_ASLPP_PATH = DEF(VS2022_BIN_X64)\cl.exe +*_VS2022_X64_ASM_PATH = DEF(VS2022_BIN_X64)\ml64.exe +*_VS2022_X64_SLINK_PATH = DEF(VS2022_BIN_X64)\lib.exe +*_VS2022_X64_DLINK_PATH = DEF(VS2022_BIN_X64)\link.exe +*_VS2022_X64_ASLDLINK_PATH = DEF(VS2022_BIN_X64)\link.exe + + DEBUG_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw +RELEASE_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw +NOOPT_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od + + DEBUG_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi +RELEASE_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd +NOOPT_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi + + DEBUG_VS2022_X64_NASM_FLAGS = -Ox -f win64 -g +RELEASE_VS2022_X64_NASM_FLAGS = -Ox -f win64 +NOOPT_VS2022_X64_NASM_FLAGS = -O0 -f win64 -g + + DEBUG_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL +RELEASE_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data /ALIGN:4096 /DLL +NOOPT_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL + +################# +# ARM definitions +################# +*_VS2022_ARM_CC_PATH = DEF(VS2022_BIN_ARM)\cl.exe +*_VS2022_ARM_VFRPP_PATH = DEF(VS2022_BIN_ARM)\cl.exe +*_VS2022_ARM_SLINK_PATH = DEF(VS2022_BIN_ARM)\lib.exe +*_VS2022_ARM_DLINK_PATH = DEF(VS2022_BIN_ARM)\link.exe +*_VS2022_ARM_APP_PATH = DEF(VS2022_BIN_ARM)\cl.exe +*_VS2022_ARM_PP_PATH = DEF(VS2022_BIN_ARM)\cl.exe +*_VS2022_ARM_ASM_PATH = DEF(VS2022_BIN_ARM)\armasm.exe +*_VS2022_ARM_ASLCC_PATH = DEF(VS2022_BIN_ARM)\cl.exe +*_VS2022_ARM_ASLPP_PATH = DEF(VS2022_BIN_ARM)\cl.exe +*_VS2022_ARM_ASLDLINK_PATH = DEF(VS2022_BIN_ARM)\link.exe + + *_VS2022_ARM_MAKE_FLAGS = /nologo + DEBUG_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- +RELEASE_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- +NOOPT_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- + + DEBUG_VS2022_ARM_ASM_FLAGS = /nologo /g +RELEASE_VS2022_ARM_ASM_FLAGS = /nologo +NOOPT_VS2022_ARM_ASM_FLAGS = /nologo + + DEBUG_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG +RELEASE_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data +NOOPT_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + +##################### +# AARCH64 definitions +##################### +*_VS2022_AARCH64_CC_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe +*_VS2022_AARCH64_VFRPP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe +*_VS2022_AARCH64_SLINK_PATH = DEF(VS2022_BIN_AARCH64)\lib.exe +*_VS2022_AARCH64_DLINK_PATH = DEF(VS2022_BIN_AARCH64)\link.exe +*_VS2022_AARCH64_APP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe +*_VS2022_AARCH64_PP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe +*_VS2022_AARCH64_ASM_PATH = DEF(VS2022_BIN_AARCH64)\armasm64.exe +*_VS2022_AARCH64_ASLCC_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe +*_VS2022_AARCH64_ASLPP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe +*_VS2022_AARCH64_ASLDLINK_PATH = DEF(VS2022_BIN_AARCH64)\link.exe + + *_VS2022_AARCH64_MAKE_FLAGS = /nologo + DEBUG_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi- +RELEASE_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi- +NOOPT_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi- + + DEBUG_VS2022_AARCH64_ASM_FLAGS = /nologo /g +RELEASE_VS2022_AARCH64_ASM_FLAGS = /nologo +NOOPT_VS2022_AARCH64_ASM_FLAGS = /nologo + + DEBUG_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG +RELEASE_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /MERGE:.rdata=.data +NOOPT_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG + #################################################################################### # GCC Common #################################################################################### diff --git a/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py b/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py index 615b5ed6d1..04e59f10f1 100644 --- a/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py +++ b/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py @@ -1,5 +1,8 @@ # @file WindowsVsToolChain.py -# Plugin to configures paths for the VS2017 and VS2019 tool chain +# Plugin to configure the environment for the VS2017, VS2019, and VS2022 toolchains +# +# This plugin also runs for CLANGPDB toolchain on Windows as that toolchain +# leverages nmake from VS and needs to the SDK paths for unit tests ## # This plugin works in conjuncture with the tools_def # @@ -173,6 +176,159 @@ class WindowsVsToolChain(IUefiBuildPlugin): self.Logger.error("Path for VS2019 toolchain is invalid") return -2 + # + # VS2022 - VS2022 allows a user to install many copies/versions of the tools. + # If a specific version is required then the user must set both env variables: + # VS170INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc + # VS170TOOLVER: version number for the VC compiler tools + # VS2022_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above) + # VS2022_HOST: set the host architecture to use for host tools, and host libs, etc + elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2022": + + # check to see if host is configured + # HostType for VS2022 should be (defined in tools_def): + # x86 == 32bit Intel + # x64 == 64bit Intel + # arm == 32bit Arm + # arm64 == 64bit Arm + # + HostType = shell_environment.GetEnvironment().get_shell_var("VS2022_HOST") + if HostType is not None: + HostType = HostType.lower() + self.Logger.info( + f"HOST TYPE defined by environment. Host Type is {HostType}") + else: + HostInfo = GetHostInfo() + if HostInfo.arch == "x86": + if HostInfo.bit == "32": + HostType = "x86" + elif HostInfo.bit == "64": + HostType = "x64" + else: + raise NotImplementedError() + + # VS2022_HOST options are not exactly the same as QueryVcVariables. This translates. + VC_HOST_ARCH_TRANSLATOR = { + "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"} + + # check to see if full path already configured + if shell_environment.GetEnvironment().get_shell_var("VS2022_PREFIX") is not None: + self.Logger.debug("VS2022_PREFIX is already set.") + + else: + install_path = self._get_vs_install_path( + "VS2022".lower(), "VS170INSTALLPATH") + vc_ver = self._get_vc_version(install_path, "VS170TOOLVER") + + if install_path is None or vc_ver is None: + self.Logger.error( + "Failed to configure environment for VS2022") + return -1 + + version_aggregator.GetVersionAggregator().ReportVersion( + "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO) + version_aggregator.GetVersionAggregator().ReportVersion( + "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL) + + # make VS2022_PREFIX to align with tools_def.txt + prefix = os.path.join(install_path, "VC", + "Tools", "MSVC", vc_ver) + prefix = prefix + os.path.sep + shell_environment.GetEnvironment().set_shell_var("VS2022_PREFIX", prefix) + shell_environment.GetEnvironment().set_shell_var("VS2022_HOST", HostType) + + shell_env = shell_environment.GetEnvironment() + # Use the tools lib to determine the correct values for the vars that interest us. + vs_vars = locate_tools.QueryVcVariables( + interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType], vs_version="VS2022") + for (k, v) in vs_vars.items(): + shell_env.set_shell_var(k, v) + + # now confirm it exists + if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2022_PREFIX")): + self.Logger.error("Path for VS2022 toolchain is invalid") + return -2 + + # + # CLANGPDB on Windows uses nmake from + # the VS compiler toolchain. Find a version and set + # as the CLANG_HOST_BIN path if not already set. + # + # Also get the platform header files, SDK, etc based on the + # host type. This is used for unit test compilation. + # If CLANG_VS_HOST is not set then find the host type based on Host Info. + ## + elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "CLANGPDB": + HostInfo = GetHostInfo() + + # check to see if host is configured + # HostType for VS tools should be (defined in tools_def): + # x86 == 32bit Intel + # x64 == 64bit Intel + # arm == 32bit Arm + # arm64 == 64bit Arm + # + HostType = shell_environment.GetEnvironment().get_shell_var("CLANG_VS_HOST") + if HostType is not None: + HostType = HostType.lower() + self.Logger.info( + f"CLANG_VS_HOST defined by environment. Value is {HostType}") + else: + #figure it out based on host info + if HostInfo.arch == "x86": + if HostInfo.bit == "32": + HostType = "x86" + elif HostInfo.bit == "64": + HostType = "x64" + else: + # anything other than x86 or x64 is not supported + raise NotImplementedError() + + # CLANG_VS_HOST options are not exactly the same as QueryVcVariables. This translates. + VC_HOST_ARCH_TRANSLATOR = { + "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"} + + # now get the environment variables for the platform + shell_env = shell_environment.GetEnvironment() + # Use the tools lib to determine the correct values for the vars that interest us. + vs_vars = locate_tools.QueryVcVariables( + interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType]) + for (k, v) in vs_vars.items(): + shell_env.set_shell_var(k, v) + + ## + # If environment already has CLANG_HOST_BIN set then user has already + # set the path to the VS tools like nmake.exe + ## + if shell_environment.GetEnvironment().get_shell_var("CLANG_HOST_BIN") is not None: + self.Logger.debug("CLANG_HOST_BIN is already set.") + + else: + install_path = self._get_vs_install_path(None, None) + vc_ver = self._get_vc_version(install_path, None) + + if install_path is None or vc_ver is None: + self.Logger.error("Failed to configure environment for VS") + return -1 + + version_aggregator.GetVersionAggregator().ReportVersion( + "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO) + version_aggregator.GetVersionAggregator().ReportVersion( + "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL) + + # make path align with tools_def.txt + prefix = os.path.join(install_path, "VC", "Tools", "MSVC", vc_ver) + clang_host_bin_prefix = os.path.join(prefix, "bin", "Host%s" % HostType, HostType) + + # now confirm it exists + if not os.path.exists(clang_host_bin_prefix): + self.Logger.error("Path for VS toolchain is invalid") + return -2 + + # The environment is using nmake (not make) so add "n" to the end of the path. + # The rest of the command is derived from definitions in tools.def. + shell_environment.GetEnvironment().set_shell_var("CLANG_HOST_BIN", os.path.join(clang_host_bin_prefix, "n")) + return 0 def _get_vs_install_path(self, vs_version, varname): diff --git a/BaseTools/set_vsprefix_envs.bat b/BaseTools/set_vsprefix_envs.bat index 0b9a0c75b9..39e4e004b5 100644 --- a/BaseTools/set_vsprefix_envs.bat +++ b/BaseTools/set_vsprefix_envs.bat @@ -18,6 +18,7 @@ set SCRIPT_ERROR=1 goto :EOF :main +if /I "%1"=="VS2022" goto SetVS2022 if /I "%1"=="VS2019" goto SetVS2019 if /I "%1"=="VS2017" goto SetVS2017 if /I "%1"=="VS2015" goto SetVS2015 @@ -166,6 +167,67 @@ if not defined WINSDK_PATH_FOR_RC_EXE ( if /I "%1"=="VS2019" goto SetWinDDK +:SetVS2022 +if not defined VS170COMNTOOLS ( + @REM clear two envs so that vcvars32.bat can run successfully. + set VSINSTALLDIR= + set VCToolsVersion= + if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" ( + if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" ( + call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools -version 17,18 > vswhereInfo + for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do ( + if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat" + ) + del vswhereInfo + ) else ( + call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version 17,18 > vswhereInfo + for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do ( + if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat" + ) + del vswhereInfo + ) + ) else if exist "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" ( + if exist "%ProgramFiles%\Microsoft Visual Studio\2022\BuildTools" ( + call "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools -version 17,18 > vswhereInfo + for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do ( + if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat" + ) + del vswhereInfo + ) else ( + call "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -version 17,18 > vswhereInfo + for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do ( + if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat" + ) + del vswhereInfo + ) + ) else ( + if /I "%1"=="VS2022" goto ToolNotInstall + goto SetWinDDK + ) +) + +if defined VCToolsInstallDir ( + if not defined VS2022_PREFIX ( + set "VS2022_PREFIX=%VCToolsInstallDir%" + ) + if not defined WINSDK10_PREFIX ( + if defined WindowsSdkVerBinPath ( + set "WINSDK10_PREFIX=%WindowsSdkVerBinPath%" + ) else if exist "%ProgramFiles(x86)%\Windows Kits\10\bin" ( + set "WINSDK10_PREFIX=%ProgramFiles(x86)%\Windows Kits\10\bin\" + ) else if exist "%ProgramFiles%\Windows Kits\10\bin" ( + set "WINSDK10_PREFIX=%ProgramFiles%\Windows Kits\10\bin\" + ) + ) +) +if not defined WINSDK_PATH_FOR_RC_EXE ( + if defined WINSDK10_PREFIX ( + set "WINSDK_PATH_FOR_RC_EXE=%WINSDK10_PREFIX%x86" + ) +) + +if /I "%1"=="VS2022" goto SetWinDDK + :SetWinDDK if not defined WINDDK3790_PREFIX ( set WINDDK3790_PREFIX=C:\WINDDK\3790.1830\bin\ diff --git a/BaseTools/toolsetup.bat b/BaseTools/toolsetup.bat index 22bd0faeb9..5b1070f1e4 100755 --- a/BaseTools/toolsetup.bat +++ b/BaseTools/toolsetup.bat @@ -44,6 +44,12 @@ if /I "%1"=="/?" goto Usage set FORCE_REBUILD=TRUE goto loop ) + if /I "%1"=="VS2022" ( + shift + set VS2022=TRUE + set VSTool=VS2022 + goto loop + ) if /I "%1"=="VS2019" ( shift set VS2019=TRUE @@ -172,7 +178,9 @@ IF NOT exist "%EDK_TOOLS_PATH%\set_vsprefix_envs.bat" ( @echo. goto end ) -if defined VS2019 ( +if defined VS2022 ( + call %EDK_TOOLS_PATH%\set_vsprefix_envs.bat VS2022 +) else if defined VS2019 ( call %EDK_TOOLS_PATH%\set_vsprefix_envs.bat VS2019 ) else if defined VS2017 ( call %EDK_TOOLS_PATH%\set_vsprefix_envs.bat VS2017 @@ -437,12 +445,14 @@ if %ERRORLEVEL% EQU 0 ( @echo VS2015 Set the env for VS2015 build. @echo VS2017 Set the env for VS2017 build. @echo VS2019 Set the env for VS2019 build. + @echo VS2022 Set the env for VS2022 build. @echo. :end set REBUILD= set FORCE_REBUILD= set RECONFIG= +set VS2022= set VS2019= set VS2017= set VS2015= diff --git a/edksetup.bat b/edksetup.bat index 71ceefb327..0695388850 100755 --- a/edksetup.bat +++ b/edksetup.bat @@ -146,6 +146,7 @@ if defined CYGWIN_HOME ( :cygwin_done if /I "%1"=="Rebuild" shift if /I "%1"=="ForceRebuild" shift +if /I "%1"=="VS2022" shift if /I "%1"=="VS2019" shift if /I "%1"=="VS2017" shift if /I "%1"=="VS2015" shift @@ -161,6 +162,7 @@ if "%1"=="" goto end @echo VS2015 Set the env for VS2015 build. @echo VS2017 Set the env for VS2017 build. @echo VS2019 Set the env for VS2019 build. + @echo VS2022 Set the env for VS2022 build. @echo. @echo Note that target.template, tools_def.template and build_rules.template @echo will only be copied to target.txt, tools_def.txt and build_rule.txt -- cgit From 426b69830efff788f2c17a4b920a84d6e08739c8 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Tue, 9 Jul 2024 13:17:25 +0100 Subject: BaseTools: change non-ASCII characters in LinuxGcc5ToolChain.py Commit ea56fa3d4706 ("BaseTools: Enable RISC-V architecture for RISC-V EDK2 CI") introduced a UTF-8 NBSP (0xc2a0) inside a comment block otherwise copied identically from pre-existing architectures. This was clearly unintentional and confuses things when looking for which files contain UTF-8 encodings, so change it to good old 0x20. Signed-off-by: Leif Lindholm --- BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py b/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py index dab7a87997..57866a5159 100644 --- a/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py +++ b/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py @@ -99,7 +99,7 @@ class LinuxGcc5ToolChain(IUefiBuildPlugin): return 0 def _check_riscv64(self): - # now check for install dir.  If set then set the Prefix + # now check for install dir. If set then set the Prefix install_path = shell_environment.GetEnvironment( ).get_shell_var("GCC5_RISCV64_INSTALL") if install_path is None: -- cgit From 7aaee521a1966e71a51b71b73f5e3bbddb6faa31 Mon Sep 17 00:00:00 2001 From: Thamballi Sreelalitha Date: Thu, 4 Jul 2024 14:16:03 +0530 Subject: FmpDevicePkg: Correct broken Depex in FmpDxe Commit 2f6f3329add3 ("FmpDevicePkg/FmpDxe: Use new Variable Lock interface"), moved to using gEdkiiVariablePolicyProtocolGuid instead of gEdkiiVariableLockProtocolGuid however the Depex was not updated to reflect the change. Correct the dependency. Signed-off-by: Vishal Oliyil Kunnil --- FmpDevicePkg/FmpDxe/FmpDxe.inf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 FmpDevicePkg/FmpDxe/FmpDxe.inf diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf old mode 100644 new mode 100755 index 1c296388b0..d7a02733de --- a/FmpDevicePkg/FmpDxe/FmpDxe.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf @@ -5,6 +5,7 @@ # # Copyright (c) 2016, Microsoft Corporation. All rights reserved.
# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -78,7 +79,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ## SOMETIMES_PRODUCES [Depex] - gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid + gEfiVariableWriteArchProtocolGuid AND gEdkiiVariablePolicyProtocolGuid [UserExtensions.TianoCore."ExtraFiles"] FmpDxeExtra.uni -- cgit From f91211049c1522f7db2ae8f7a509ac270868d0e9 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Thu, 12 Jul 2018 23:44:35 +0000 Subject: MdeModulePkg: Remove PeiAllocatePool() Assert Removes an assert if PeiAllocatePool() fails to allocate memory to defer error handling to the caller so the error can be handled gracefully or asserted at that location which is more specific to the call that led to the allocation. Signed-off-by: Michael Kubacki --- MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c index 52f37c960e..59613e5131 100644 --- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c +++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c @@ -862,8 +862,6 @@ PeiAllocatePool ( (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size), (VOID **)&Hob ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { *Buffer = NULL; } else { -- cgit From 749065300a42d86e55074f461feed23533a77ab3 Mon Sep 17 00:00:00 2001 From: Sam Kaynor Date: Wed, 10 Jan 2024 12:33:01 -0600 Subject: ShellPkg: UefiShellDebug1CommandsLib: Dumping RT Properties in Dmem.c REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4352 Implemented the dumping of the UEFI RT Properties Table using Dmem.c Added new entry to the help command for the -verbose option Cc: Ray Ni Cc: Zhichao Gao Signed-off-by: Sam Kaynor Tested-by: Stuart Yoder Reviewed-by: Stuart Yoder Reviewed-by: Zhichao Gao --- ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c | 66 +++++++++++++++++++++- .../UefiShellDebug1CommandsLib.uni | 23 +++++++- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c index a609971f34..d4030798f3 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c @@ -84,9 +84,65 @@ DisplayMmioMemory ( return (ShellStatus); } +/** + Display the RtPropertiesTable entries + + @param[in] Address The pointer to the RtPropertiesTable. +**/ +SHELL_STATUS +DisplayRtProperties ( + IN UINT64 Address + ) +{ + EFI_RT_PROPERTIES_TABLE *RtPropertiesTable; + UINT32 RtServices; + SHELL_STATUS ShellStatus; + EFI_STATUS Status; + + ShellStatus = SHELL_SUCCESS; + + if (Address != 0) { + EfiGetSystemConfigurationTable (&gEfiRtPropertiesTableGuid, (VOID **)&RtPropertiesTable); + + RtServices = (UINT32)RtPropertiesTable->RuntimeServicesSupported; + Status = ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DMEM_RT_PROPERTIES), + gShellDebug1HiiHandle, + EFI_RT_PROPERTIES_TABLE_VERSION, + (RtServices & EFI_RT_SUPPORTED_GET_TIME) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_SET_TIME) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_GET_WAKEUP_TIME) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_SET_WAKEUP_TIME) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_GET_VARIABLE) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_SET_VARIABLE) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_CONVERT_POINTER) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_GET_NEXT_HIGH_MONOTONIC_COUNT) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_RESET_SYSTEM) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_UPDATE_CAPSULE) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES) ? 1 : 0, + (RtServices & EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO) ? 1 : 0 + ); + + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_ABORTED; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_GET_FAIL), gShellDebug1HiiHandle, L"RtPropertiesTable"); + } + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_NOT_FOUND), gShellDebug1HiiHandle, L"RtPropertiesTable"); + } + + return (ShellStatus); +} + STATIC CONST SHELL_PARAM_ITEM ParamList[] = { - { L"-mmio", TypeFlag }, - { NULL, TypeMax } + { L"-mmio", TypeFlag }, + { L"-verbose", TypeFlag }, + { NULL, TypeMax } }; /** @@ -308,6 +364,12 @@ ShellCommandRunDmem ( ConformanceProfileTableAddress ); } + + if (ShellCommandLineGetFlag (Package, L"-verbose")) { + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = DisplayRtProperties (RtPropertiesTableAddress); + } + } } else { ShellStatus = DisplayMmioMemory (Address, (UINTN)Size); } diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni index 4041f0cd48..a2241614f1 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni @@ -126,8 +126,26 @@ "Memory Range Capsule %016LX\r\n" "Hii Database Export Buffer %016LX\r\n" "Conformance Profile Table %016LX\r\n" - - +#string STR_DMEM_RT_PROPERTIES #language en-US "\r\nRT Properties Table\r\n" + "----------------------------------------\r\n" + "Version 0x%01LX\r\n" + "Runtime Services Supported:\r\n" + " GET_TIME %d\r\n" + " GET_WAKEUP_TIME %d\r\n" + " SET_TIME %d\r\n" + " SET_WAKEUP_TIME %d\r\n" + " GET_VARIABLE %d\r\n" + " GET_NEXT_VARIABLE_NAME %d\r\n" + " SET_VARIABLE %d\r\n" + " SET_VIRTUAL_ADDRESS_MAP %d\r\n" + " CONVERT_POINTERS %d\r\n" + " GET_NEXT_HIGH_MONOTONIC_COUNT %d\r\n" + " RESET_SYSTEM %d\r\n" + " UPDATE_CAPSULE %d\r\n" + " QUERY_CAPSULE_CAPABILITIES %d\r\n" + " QUERY_VARIABLE_INFO %d\r\n" +#string STR_DMEM_ERR_NOT_FOUND #language en-US "\r\n%H%s%N: Table address not found.\r\n" +#string STR_DMEM_ERR_GET_FAIL #language en-US "\r\n%H%s%N: Unable to get table information.\r\n" #string STR_LOAD_PCI_ROM_RES #language en-US "Image '%B%s%N' load result: %r\r\n" #string STR_LOADPCIROM_CORRUPT #language en-US "%H%s%N: File '%B%s%N' Image %d is corrupt.\r\n" @@ -589,6 +607,7 @@ " \r\n" " -b - Displays one screen at a time.\r\n" " -MMIO - Forces address cycles to the PCI bus.\r\n" +" -verbose - Displays contents of certain EFI System Tables.\r\n" " address - Specifies a starting address in hexadecimal format.\r\n" " size - Specifies the number of bytes to display in hexadecimal format.\r\n" ".SH DESCRIPTION\r\n" -- cgit From f46b5b06c69dcd0a7997b416789617e5d33ae18a Mon Sep 17 00:00:00 2001 From: Sam Kaynor Date: Wed, 10 Jan 2024 12:48:17 -0600 Subject: ShellPkg: UefiShellDebug1CommandsLib: Image Execution Table in Dmem.c REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4352 Implemented dumping of the Image Execution Table using Dmem.c Cc: Ray Ni Cc: Zhichao Gao Signed-off-by: Sam Kaynor Tested-by: Stuart Yoder Reviewed-by: Stuart Yoder Reviewed-by: Zhichao Gao --- ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c | 136 +++++++++++++++++++++ .../UefiShellDebug1CommandsLib.uni | 3 + 2 files changed, 139 insertions(+) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c index d4030798f3..80c779a0b3 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c @@ -139,6 +139,138 @@ DisplayRtProperties ( return (ShellStatus); } +/** + Retrieve the ImageExecutionTable Entry ImageName from ImagePath + + @param[in] FileName The full path of the image. + @param[out] BaseName The name of the image. +**/ +EFI_STATUS +GetBaseName ( + IN CHAR16 *FileName, + OUT CHAR16 **BaseName + ) +{ + UINTN StrLen; + CHAR16 *StrTail; + + StrLen = StrSize (FileName); + + for (StrTail = FileName + StrLen - 1; StrTail != FileName && *StrTail != L'\\'; StrTail--) { + } + + if (StrTail == FileName) { + return EFI_NOT_FOUND; + } + + *BaseName = StrTail+1; + + return EFI_SUCCESS; +} + +/** + Retrieve the ImageExecutionTable entries. +**/ +EFI_STATUS +GetImageExecutionInfo ( + ) +{ + EFI_STATUS Status; + EFI_IMAGE_EXECUTION_INFO_TABLE *ExecInfoTablePtr; + EFI_IMAGE_EXECUTION_INFO *InfoPtr; + CHAR8 *ptr; + CHAR16 *ImagePath; + CHAR16 *ImageName; + UINTN Image; + UINTN *NumberOfImages; + CHAR16 *ActionType; + + EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **)&ExecInfoTablePtr); + + NumberOfImages = &ExecInfoTablePtr->NumberOfImages; + + ptr = (CHAR8 *)ExecInfoTablePtr + 1; + + for (Image = 0; Image < *NumberOfImages; Image++, ptr += InfoPtr->InfoSize) { + InfoPtr = (EFI_IMAGE_EXECUTION_INFO *)ptr; + ImagePath = (CHAR16 *)(InfoPtr + 1); + + GetBaseName (ImagePath, &ImageName); + + switch (InfoPtr->Action) { + case EFI_IMAGE_EXECUTION_AUTHENTICATION: + ActionType = L"AUTHENTICATION"; + break; + case EFI_IMAGE_EXECUTION_AUTH_UNTESTED: + ActionType = L"AUTH_UNTESTED"; + break; + case EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED: + ActionType = L"AUTH_SIG_FAILED"; + break; + case EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED: + ActionType = L"AUTH_SIG_PASSED"; + break; + case EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND: + ActionType = L"AUTH_SIG_NOT_FOUND"; + break; + case EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND: + ActionType = L"AUTH_SIG_FOUND"; + break; + case EFI_IMAGE_EXECUTION_POLICY_FAILED: + ActionType = L"POLICY_FAILED"; + break; + case EFI_IMAGE_EXECUTION_INITIALIZED: + ActionType = L"INITIALIZED"; + break; + default: + ActionType = L"invalid action"; + } + + Status = ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DMEM_IMG_EXE_ENTRY), + gShellDebug1HiiHandle, + ImageName, + ActionType + ); + } + + return Status; +} + +/** + Display the ImageExecutionTable entries + + @param[in] Address The pointer to the ImageExecutionTable. +**/ +SHELL_STATUS +DisplayImageExecutionEntries ( + IN UINT64 Address + ) +{ + SHELL_STATUS ShellStatus; + EFI_STATUS Status; + + ShellStatus = SHELL_SUCCESS; + + if (Address != 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_IMG_EXE_TABLE), gShellDebug1HiiHandle); + Status = GetImageExecutionInfo (); + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_ABORTED; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_GET_FAIL), gShellDebug1HiiHandle, L"ImageExecutionTable"); + } + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_NOT_FOUND), gShellDebug1HiiHandle, L"ImageExecutionTable"); + } + + return (ShellStatus); +} + + + STATIC CONST SHELL_PARAM_ITEM ParamList[] = { { L"-mmio", TypeFlag }, { L"-verbose", TypeFlag }, @@ -369,6 +501,10 @@ ShellCommandRunDmem ( if (ShellStatus == SHELL_SUCCESS) { ShellStatus = DisplayRtProperties (RtPropertiesTableAddress); } + + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = DisplayImageExecutionEntries (ImageExecutionTableAddress); + } } } else { ShellStatus = DisplayMmioMemory (Address, (UINTN)Size); diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni index a2241614f1..3b730164dd 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni @@ -144,6 +144,9 @@ " UPDATE_CAPSULE %d\r\n" " QUERY_CAPSULE_CAPABILITIES %d\r\n" " QUERY_VARIABLE_INFO %d\r\n" +#string STR_DMEM_IMG_EXE_TABLE #language en-US "\r\nImage Execution Table\r\n" + "----------------------------------------\r\n" +#string STR_DMEM_IMG_EXE_ENTRY #language en-US "%20s: %s\r\n" #string STR_DMEM_ERR_NOT_FOUND #language en-US "\r\n%H%s%N: Table address not found.\r\n" #string STR_DMEM_ERR_GET_FAIL #language en-US "\r\n%H%s%N: Unable to get table information.\r\n" -- cgit From 3ad878fde5ba29041c4718d06fb8af1d87eb8af3 Mon Sep 17 00:00:00 2001 From: Sam Kaynor Date: Fri, 26 Apr 2024 11:16:04 -0500 Subject: MdePkg: Adding support for EFI_CONFORMANCE_PROFILE_TABLE REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4352 Adding support for EFI_CONFORMANCE_PROFILE_TABLE by adding an associated header file and relevant GUIDs to MdePkg.dec as defined in the UEFI 2.10 spec. This table is needed to address changes being made within ShellPkg. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Sam Kaynor --- MdePkg/Include/Guid/ConformanceProfiles.h | 57 +++++++++++++++++++++++++++++++ MdePkg/MdePkg.dec | 4 +++ 2 files changed, 61 insertions(+) create mode 100644 MdePkg/Include/Guid/ConformanceProfiles.h diff --git a/MdePkg/Include/Guid/ConformanceProfiles.h b/MdePkg/Include/Guid/ConformanceProfiles.h new file mode 100644 index 0000000000..5505011231 --- /dev/null +++ b/MdePkg/Include/Guid/ConformanceProfiles.h @@ -0,0 +1,57 @@ +/** @file + GUIDs used for UEFI Conformance Profiles Table in the UEFI 2.10 specification. + + Copyright (c) 2024, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef CONFORMANCE_PROFILES_TABLE_GUID_H_ +#define CONFORMANCE_PROFILES_TABLE_GUID_H_ + +// +// This table allows the platform to advertise its UEFI specification conformance +// in the form of pre-defined profiles. Each profile is identified by a GUID, with +// known profiles listed in the section below. +// The absence of this table shall indicate that the platform implementation is +// conformant with the UEFI specification requirements, as defined in Section 2.6. +// This is equivalent to publishing this configuration table with the +// EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID conformance profile. +// +#define EFI_CONFORMANCE_PROFILES_TABLE_GUID \ + { \ + 0x36122546, 0xf7e7, 0x4c8f, { 0xbd, 0x9b, 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b } \ + } + +#pragma pack(1) + +typedef struct { + /// + /// Version of the table must be 0x1 + /// + UINT16 Version; + /// + /// The number of profiles GUIDs present in ConformanceProfiles + /// + UINT16 NumberOfProfiles; + /// + /// An array of conformance profile GUIDs that are supported by this system. + /// EFI_GUID ConformanceProfiles[]; + /// +} EFI_CONFORMANCE_PROFILES_TABLE; + +#pragma pack() + +#define EFI_CONFORMANCE_PROFILES_TABLE_VERSION 0x1 + +// +// GUID defined in spec. +// +#define EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID \ + { 0x523c91af, 0xa195, 0x4382, \ + { 0x81, 0x8d, 0x29, 0x5f, 0xe4, 0x00, 0x64, 0x65 }} + +extern EFI_GUID gEfiConfProfilesTableGuid; +extern EFI_GUID gEfiConfProfilesUefiSpecGuid; + +#endif diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 94170ff9a4..3a9a0fec24 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -751,6 +751,10 @@ ## Include/Guid/DeviceAuthentication.h gEfiDeviceSignatureDatabaseGuid = { 0xb9c2b4f4, 0xbf5f, 0x462d, {0x8a, 0xdf, 0xc5, 0xc7, 0xa, 0xc3, 0x5d, 0xad }} + ## Include/Guid/ConformanceProfiles.h + gEfiConfProfilesTableGuid = { 0x36122546, 0xf7e7, 0x4c8f, { 0xbd, 0x9b, 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b }} + gEfiConfProfilesUefiSpecGuid = { 0x523c91af, 0xa195, 0x4382, { 0x81, 0x8d, 0x29, 0x5f, 0xe4, 0x00, 0x64, 0x65 }} + # # GUID defined in PI1.0 # -- cgit From 960b6e8309bd304e2baae0a6e5ca5c0a0f7b0e2e Mon Sep 17 00:00:00 2001 From: Sam Kaynor Date: Tue, 30 Apr 2024 12:54:10 -0500 Subject: MdePkg: Adding EBBR EFI_CONFORMANCE_PROFILE_TABLE GUIDs REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4352 Adding additional GUIDs for the EFI_CONFORMANCE_PROFILE_TABLE that are defined in the Embedded Base Boot Requirments (EBBR) Specification. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Sam Kaynor --- MdePkg/Include/Guid/ConformanceProfiles.h | 12 +++++++++++- MdePkg/MdePkg.dec | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Guid/ConformanceProfiles.h b/MdePkg/Include/Guid/ConformanceProfiles.h index 5505011231..bf89ab61dd 100644 --- a/MdePkg/Include/Guid/ConformanceProfiles.h +++ b/MdePkg/Include/Guid/ConformanceProfiles.h @@ -45,12 +45,22 @@ typedef struct { #define EFI_CONFORMANCE_PROFILES_TABLE_VERSION 0x1 // -// GUID defined in spec. +// GUID defined in UEFI 2.10 // #define EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID \ { 0x523c91af, 0xa195, 0x4382, \ { 0x81, 0x8d, 0x29, 0x5f, 0xe4, 0x00, 0x64, 0x65 }} +// +// GUID defined in EBBR +// +#define EFI_CONFORMANCE_PROFILE_EBBR_2_1_GUID \ + { 0xcce33c35, 0x74ac, 0x4087, \ + { 0xbc, 0xe7, 0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27 }} +#define EFI_CONFORMANCE_PROFILE_EBBR_2_2_GUID \ + { 0x9073eed4, 0xe50d, 0x11ee, \ + { 0xb8, 0xb0, 0x8b, 0x68, 0xda, 0x62, 0xfc, 0x80 }} + extern EFI_GUID gEfiConfProfilesTableGuid; extern EFI_GUID gEfiConfProfilesUefiSpecGuid; diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 3a9a0fec24..5dbe5a9f72 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -755,6 +755,12 @@ gEfiConfProfilesTableGuid = { 0x36122546, 0xf7e7, 0x4c8f, { 0xbd, 0x9b, 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b }} gEfiConfProfilesUefiSpecGuid = { 0x523c91af, 0xa195, 0x4382, { 0x81, 0x8d, 0x29, 0x5f, 0xe4, 0x00, 0x64, 0x65 }} + # GUIDs defined in EBBR + # + ## Include/Guid/ConformanceProfiles.h + gEfiConfProfilesEbbrSpec21Guid = { 0xcce33c35, 0x74ac, 0x4087, { 0xbc, 0xe7, 0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27 }} + gEfiConfProfilesEbbrSpec22Guid = { 0x9073eed4, 0xe50d, 0x11ee, { 0xb8, 0xb0, 0x8b, 0x68, 0xda, 0x62, 0xfc, 0x80 }} + # # GUID defined in PI1.0 # -- cgit From 497766f70975b9c1f88df42228c79095198f2b4e Mon Sep 17 00:00:00 2001 From: Sam Kaynor Date: Wed, 10 Jan 2024 13:03:19 -0600 Subject: ShellPkg: UefiShellDebug1CommandsLib: Conformance Profiles in Dmem.c REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4352 Implemented dumping of the UEFI Conformance Profiles Table using Dmem.c Uses header file for GUIDs added in previous patches Cc: Ray Ni Cc: Zhichao Gao Signed-off-by: Sam Kaynor Tested-by: Stuart Yoder Reviewed-by: Stuart Yoder --- ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c | 80 ++++++++++++++++++++++ .../UefiShellDebug1CommandsLib.inf | 4 ++ .../UefiShellDebug1CommandsLib.uni | 5 ++ 3 files changed, 89 insertions(+) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c index 80c779a0b3..046cfd5270 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c @@ -19,6 +19,7 @@ #include #include #include +#include /** Make a printable character. @@ -269,7 +270,77 @@ DisplayImageExecutionEntries ( return (ShellStatus); } +/** + Display the ConformanceProfileTable entries + + @param[in] Address The pointer to the ConformanceProfileTable. +**/ +SHELL_STATUS +DisplayConformanceProfiles ( + IN UINT64 Address + ) +{ + SHELL_STATUS ShellStatus; + EFI_STATUS Status; + EFI_GUID *EntryGuid; + CHAR16 *GuidName; + UINTN Profile; + EFI_CONFORMANCE_PROFILES_TABLE *ConfProfTable; + ShellStatus = SHELL_SUCCESS; + + if (Address != 0) { + EfiGetSystemConfigurationTable (&gEfiConfProfilesTableGuid, (VOID **)&ConfProfTable); + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_CONF_PRO_TABLE), gShellDebug1HiiHandle); + + EntryGuid = (EFI_GUID *)(ConfProfTable + 1); + + for (Profile = 0; Profile < ConfProfTable->NumberOfProfiles; Profile++, EntryGuid++) { + GuidName = L"Unknown_Profile"; + + if (CompareGuid (EntryGuid, &gEfiConfProfilesUefiSpecGuid)) { + GuidName = L"EFI_CONFORMANCE_PROFILE_UEFI_SPEC_GUID"; + } + + if (CompareGuid (EntryGuid, &gEfiConfProfilesEbbrSpec21Guid)) { + GuidName = L"EBBR_2.1"; + } + + if (CompareGuid (EntryGuid, &gEfiConfProfilesEbbrSpec22Guid)) { + GuidName = L"EBBR_2.2"; + } + + Status = ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DMEM_CONF_PRO_ROW), + gShellDebug1HiiHandle, + GuidName, + EntryGuid + ); + } + + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_ABORTED; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_GET_FAIL), gShellDebug1HiiHandle, L"ComformanceProfilesTable"); + } + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_CONF_PRO_TABLE), gShellDebug1HiiHandle); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DMEM_CONF_PRO_ROW), + gShellDebug1HiiHandle, + L"EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID", + &gEfiConfProfilesUefiSpecGuid + ); + } + + return (ShellStatus); +} STATIC CONST SHELL_PARAM_ITEM ParamList[] = { { L"-mmio", TypeFlag }, @@ -461,6 +532,11 @@ ShellCommandRunDmem ( HiiDatabaseExportBufferAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable; continue; } + + if (CompareGuid (&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiConfProfilesTableGuid)) { + ConformanceProfileTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable; + continue; + } } ShellPrintHiiEx ( @@ -505,6 +581,10 @@ ShellCommandRunDmem ( if (ShellStatus == SHELL_SUCCESS) { ShellStatus = DisplayImageExecutionEntries (ImageExecutionTableAddress); } + + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = DisplayConformanceProfiles (ConformanceProfileTableAddress); + } } } else { ShellStatus = DisplayMmioMemory (Address, (UINTN)Size); diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf index 3741dac5d9..140e9dc644 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf @@ -139,3 +139,7 @@ gEfiJsonConfigDataTableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiJsonCapsuleDataTableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiJsonCapsuleResultTableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiConfProfilesTableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiConfProfilesUefiSpecGuid ## SOMETIMES_CONSUMES ## GUID + gEfiConfProfilesEbbrSpec21Guid ## SOMETIMES_CONSUMES ## GUID + gEfiConfProfilesEbbrSpec22Guid ## SOMETIMES_CONSUMES ## GUID diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni index 3b730164dd..6ef923e4fd 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni @@ -147,6 +147,11 @@ #string STR_DMEM_IMG_EXE_TABLE #language en-US "\r\nImage Execution Table\r\n" "----------------------------------------\r\n" #string STR_DMEM_IMG_EXE_ENTRY #language en-US "%20s: %s\r\n" +#string STR_DMEM_CONF_PRO_TABLE #language en-US "\r\nConformance Profile Table\r\n" + "----------------------------------------\r\n" + "Version 0x1\r\n" + "Profile GUIDs:\r\n" +#string STR_DMEM_CONF_PRO_ROW #language en-US " %s %g\r\n" #string STR_DMEM_ERR_NOT_FOUND #language en-US "\r\n%H%s%N: Table address not found.\r\n" #string STR_DMEM_ERR_GET_FAIL #language en-US "\r\n%H%s%N: Unable to get table information.\r\n" -- cgit From 3abe627f29add4d05a404e9170b81cf72d9c404b Mon Sep 17 00:00:00 2001 From: Nickle Wang Date: Wed, 10 Jul 2024 16:14:47 +0800 Subject: RedfishPkg/RedfishPlatformConfigDxe: remove false alarm Change the debug message level to DEBUG_INFO for protocol notification functions. The protocol notification function is invoked at least one time. So, the failure of locating protocol is expected because protocol may not be installed when Redfish platform config driver is launched. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Igor Kulchytskyy Cc: Rebecca Cran --- RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c index 46d01fca60..26bec8435f 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c @@ -2483,7 +2483,7 @@ HiiStringProtocolInstalled ( (VOID **)&mRedfishPlatformConfigPrivate->HiiString ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: locate EFI_HII_STRING_PROTOCOL failure: %r\n", __func__, Status)); + DEBUG ((DEBUG_INFO, "%a: locate EFI_HII_STRING_PROTOCOL failure: %r\n", __func__, Status)); return; } @@ -2518,7 +2518,7 @@ HiiDatabaseProtocolInstalled ( (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __func__, Status)); + DEBUG ((DEBUG_INFO, "%a: locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __func__, Status)); return; } @@ -2581,7 +2581,7 @@ RegexProtocolInstalled ( (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __func__, Status)); + DEBUG ((DEBUG_INFO, "%a: locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __func__, Status)); return; } -- cgit From 6c061c4715325494b8b25453158166f9032e0335 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 9 Jul 2024 19:10:26 -0400 Subject: BaseTools/Ecc: Allow `static` as a modifier Currently, `STATIC` is allowed as a function modifier but `static` results in the below ECC errors: ``` *Error code: 5001 *Return type of a function should exist and in the first line *file: D:\src\edk2\Build\.pytool\Plugin\EccCheck\MdePkg\Library\UefiDebugLibDebugPortProtocol\DebugLibConstructor.c *Line number: 37 *[UefiDebugLibDebugPortProtocolExitBootServicesCallback] Return Type should appear at the start of line EFI coding style error *Error code: 5002 *Any optional functional modifiers should exist and next to the return type *file: D:\src\edk2\Build\.pytool\Plugin\EccCheck\MdePkg\Library\UefiDebugLibDebugPortProtocol\DebugLibConstructor.c *Line number: 37 ``` This is because `GetDataTypeFromModifier()` will return both `static` and the return type (e.g. `VOID`) whereas for a modifier in the list (e.g. `STATIC`) it will return only the return type allowing logic in Ecc/c.py to process the modifier and return type with current logic. Signed-off-by: Michael Kubacki --- BaseTools/Source/Python/Ecc/config.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini index 5529d0f2db..6edf897ffd 100644 --- a/BaseTools/Source/Python/Ecc/config.ini +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -35,7 +35,7 @@ AutoCorrect = 1 # # List customized Modifer here, split with ',' # -ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI, STATIC +ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI, STATIC, static # # General Checking -- cgit From 0f45be16336035e69bb30761f8cd20ba3b0a3f39 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Tue, 9 Jul 2024 16:01:42 +0100 Subject: .github: Update pull_request_template.md Slightly reword the template to be more specific and use active language. Signed-off-by: Leif Lindholm --- .github/pull_request_template.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 70e8c56496..3ecabed46b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,13 +9,13 @@ <_Delete lines in \<\> tags before creating the PR._> - [ ] Breaking change? - - **Breaking change** - Will this cause a break in build or boot behavior? - - Examples: Add a new library class or move a module to a different repo. + - **Breaking change** - Does this PR cause a break in build or boot behavior? + - Examples: Does it add a new library class or move a module to a different repo. - [ ] Impacts security? - - **Security** - Does the change have a direct security impact? + - **Security** - Does this PR have a direct security impact? - Examples: Crypto algorithm change or buffer overflow fix. - [ ] Includes tests? - - **Tests** - Does the change include any explicit test code? + - **Tests** - Does this PR include any explicit test code? - Examples: Unit tests or integration tests. ## How This Was Tested -- cgit From 071d2cfab8347e396c8b2709bfb588a18c497bbd Mon Sep 17 00:00:00 2001 From: Ceping Sun Date: Tue, 2 Jul 2024 01:50:10 +0800 Subject: OvmfPkg/Sec: Skip setup MTRR early in TD-Guest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the commit ce4c76e (“OvmfPkg/Sec: Setup MTRR early in the boot process.”), we find an unexpected #VE is triggered in TD-Guest. The background of importing the above commit is that: Before running lzma uncompress of the main firmware volume, if not correctly set MTRR, that would make the uncompress be extremely slow. Detailed discussion info can refer to below links: https://edk2.groups.io/g/devel/message/114202 https://edk2.groups.io/g/devel/message/114977 Refer to [intel-tdx-module-1.5-base-spec] Section 11.3 and section11.6.1, CR0.CD is enforced to 0 in TD-Guest. And refer to section 18.2.1.4, TDX module MTRR emulation enforces WB in VMM. Currently the initial MTRR are: - Td-Guest : MTRR disabled, Type is WB. - Non-Td-Guest : MTRR disabled, Type is UC. In DXE phase, OVMF/TDVF would check the MTRR Type for MMIO (in CpuSetMemoryAttributes -> MtrrGetMemoryAttribute -> MtrrGetMemoryAttributeworker: https://github.com/tianocore/edk2/blob/master/UefiCpuPkg/Library/MtrrLib/MtrrLib.c#L929 ). If MTRR is disabled, it always returns UC. Otherwise, it returns the actual value. If it checks that the type is not UC then the MTRR is programmed. It is required to disable cache by setting CR0.CD to 1. That will trigger an unexpected #VE in TD-Guest. Based on above analysis we propose to skip "Setup MTRR early" in TD-Guest because of: - TD-Guest doesn’t have the issue that lzma uncompress extremely slow. - This patch will trigger an unexpected #VE in TD-Guest. intel-tdx-module-1.5-base-spec: https://cdrdv2.intel.com/v1/dl/getContent/733575 Cc: Erdem Aktas Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Cc: Elena Reshetova Signed-off-by: Ceping Sun --- OvmfPkg/IntelTdx/Sec/SecMain.c | 12 ++++++++++++ OvmfPkg/Sec/SecMain.c | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c index 95a31af029..7f2d28af95 100644 --- a/OvmfPkg/IntelTdx/Sec/SecMain.c +++ b/OvmfPkg/IntelTdx/Sec/SecMain.c @@ -68,6 +68,18 @@ SecMtrrSetup ( return; } + if (CcProbe () == CcGuestTypeIntelTdx) { + // + // According to TDX Spec, the default MTRR type is enforced to WB + // and CR0.CD is enforced to 0. + // The TD guest has to disable MTRR otherwise it tries to + // program MTRRs to disable caching. CR0.CD=1 results in the + // unexpected #VE. + // + DEBUG ((DEBUG_INFO, "%a: Skip TD-Guest\n", __func__)); + return; + } + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK; DefType.Bits.E = 1; /* enable */ diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index c1c08a947a..d13a948509 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -764,6 +764,21 @@ SecMtrrSetup ( return; } + #if defined (TDX_GUEST_SUPPORTED) + if (CcProbe () == CcGuestTypeIntelTdx) { + // + // According to TDX Spec, the default MTRR type is enforced to WB + // and CR0.CD is enforced to 0. + // The TD guest has to disable MTRR otherwise it tries to + // program MTRRs to disable caching. CR0.CD=1 results in the + // unexpected #VE. + // + DEBUG ((DEBUG_INFO, "%a: Skip TD-Guest\n", __func__)); + return; + } + + #endif + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK; DefType.Bits.E = 1; /* enable */ -- cgit From 5c86b0b57c153bde28f925de80cc011dd4ff1f9d Mon Sep 17 00:00:00 2001 From: Saloni Kasbekar Date: Wed, 10 Jul 2024 14:44:50 -0700 Subject: NetworkPkg/HttpDxe: Track HttpInstance URL buffer length. In EfiHttpRequest(), length of target URLs was always compared to fixed-size value, even after allocating a larger URL buffer. Added UrlLen to HTTP_PROTOCOL to store the size and reallocate if the size changes. Signed-off-by: Saloni Kasbekar --- NetworkPkg/HttpDxe/HttpImpl.c | 12 ++++++++---- NetworkPkg/HttpDxe/HttpProto.c | 6 ++++-- NetworkPkg/HttpDxe/HttpProto.h | 3 ++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c index 6606c29342..9500f565d0 100644 --- a/NetworkPkg/HttpDxe/HttpImpl.c +++ b/NetworkPkg/HttpDxe/HttpImpl.c @@ -1,7 +1,7 @@ /** @file Implementation of EFI_HTTP_PROTOCOL protocol interfaces. - Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
@@ -341,14 +341,18 @@ EfiHttpRequest ( // Url = HttpInstance->Url; UrlLen = StrLen (Request->Url) + 1; - if (UrlLen > HTTP_URL_BUFFER_LEN) { + if (UrlLen > HttpInstance->UrlLen) { Url = AllocateZeroPool (UrlLen); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } - FreePool (HttpInstance->Url); - HttpInstance->Url = Url; + if (HttpInstance->Url != NULL) { + FreePool (HttpInstance->Url); + } + + HttpInstance->Url = Url; + HttpInstance->UrlLen = UrlLen; } UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen); diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c index 9c3b497dce..75eb068010 100644 --- a/NetworkPkg/HttpDxe/HttpProto.c +++ b/NetworkPkg/HttpDxe/HttpProto.c @@ -1,7 +1,7 @@ /** @file Miscellaneous routines for HttpDxe driver. -Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -738,6 +738,7 @@ HttpInitProtocol ( goto ON_ERROR; } + HttpInstance->UrlLen = HTTP_URL_BUFFER_LEN; return EFI_SUCCESS; ON_ERROR: @@ -847,7 +848,8 @@ HttpCleanProtocol ( if (HttpInstance->Url != NULL) { FreePool (HttpInstance->Url); - HttpInstance->Url = NULL; + HttpInstance->Url = NULL; + HttpInstance->UrlLen = 0; } NetMapClean (&HttpInstance->TxTokens); diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h index 7e77b389a7..e49d2a229a 100644 --- a/NetworkPkg/HttpDxe/HttpProto.h +++ b/NetworkPkg/HttpDxe/HttpProto.h @@ -1,7 +1,7 @@ /** @file The header files of miscellaneous routines for HttpDxe driver. -Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -165,6 +165,7 @@ typedef struct _HTTP_PROTOCOL { NET_MAP RxTokens; CHAR8 *Url; + UINTN UrlLen; // // Https Support -- cgit From f122c6f639cd3babedc0dd9b38b279d94b087c7a Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 2 Jul 2024 19:20:38 -0400 Subject: MdeModulePkg/RuntimeResetSystemLib: Make global static Makes the `mInternalRT` global static in this library instance to avoid conflicting with other code such as a global variable with the same name in MdePkg/Library/UefiRuntimeLib. Signed-off-by: Michael Kubacki --- MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c b/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c index 59b5c2b9d8..8e9f63246e 100644 --- a/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c +++ b/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c @@ -12,8 +12,8 @@ #include #include -EFI_EVENT mRuntimeResetSystemLibVirtualAddressChangeEvent; -EFI_RUNTIME_SERVICES *mInternalRT; +EFI_EVENT mRuntimeResetSystemLibVirtualAddressChangeEvent; +static EFI_RUNTIME_SERVICES *mInternalRT; /** This function causes a system-wide reset (cold reset), in which -- cgit From 72d6e247b781cca65aac71c97c5094650b003a9d Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Thu, 11 Jul 2024 20:55:30 -0400 Subject: MdePkg/StmApi.h: Add SMM_REV_ID definition for STM header The `SMM_REV_ID` is defined in the STM specification: https://www.intel.com/content/www/us/en/content-details/671521/smi-transfer-monitor-stm-developer-or-user-guide.html?wapkw=stm, section 10.1.1. This adds it into the `StmApi.h` for potential STM usage. Signed-off-by: Michael Kubacki --- MdePkg/Include/Register/Intel/StmApi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdePkg/Include/Register/Intel/StmApi.h b/MdePkg/Include/Register/Intel/StmApi.h index 9d42bcde76..6c1cdf988f 100644 --- a/MdePkg/Include/Register/Intel/StmApi.h +++ b/MdePkg/Include/Register/Intel/StmApi.h @@ -18,6 +18,8 @@ #pragma pack (1) +#define STM_SMM_REV_ID 0x80010100 + /** STM Header Structures **/ -- cgit From 2e7230f1ba65e0ec9e6a3e191cca3a8b04e22ca8 Mon Sep 17 00:00:00 2001 From: Awiral Shrivastava Date: Fri, 5 Jul 2024 12:34:34 +0530 Subject: IntelFsp2WrapperPkg: FSP measurement based on PcdFspMeasurementConfig REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4725 ACM provides register to report TPM measurement status. If ACM has already measured FSP component, BIOS shoule be able to skip measurement. PcdFspMeasurementConfig should be DynamicEx to skip measurement. Signed-off-by: Awiral Shrivastava --- IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec | 34 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec index 922ccc063f..6865ffaf13 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec @@ -90,23 +90,6 @@ # @Prompt Skip FSP API from FSP wrapper. gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi|0x00000000|UINT32|0x40000009 - ## This PCD decides how FSP is measured - # 1) The BootGuard ACM may already measured the FSP component, such as FSPT/FSPM. - # We need a flag (PCD) to indicate if there is need to do such FSP measurement or NOT. - # 2) The FSP binary includes FSP code and FSP UPD region. The UPD region is considered - # as configuration block, and it may be updated by OEM by design. - # This flag (PCD) is to indicate if we need isolate the UPD region from the FSP code region. - # BIT0: Need measure FSP. (for FSP1.x) - reserved in FSP2. - # BIT1: Need measure FSPT. (for FSP 2.x) - # BIT2: Need measure FSPM. (for FSP 2.x) - # BIT3: Need measure FSPS. (for FSP 2.x) - # BIT4~30: reserved. - # BIT31: Need isolate UPD region measurement. - #0: measure FSP[T|M|S] as one binary in one record (PCR0). - #1: measure FSP UPD region in one record (PCR1), the FSP code without UPD in another record (PCR0). - # - gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000|UINT32|0x4000000B - [PcdsFixedAtBuild, PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx] ## This PCD decides how Wrapper code utilizes FSP # 0: DISPATCH mode (FSP Wrapper will load PeiCore from FSP without calling FSP API) @@ -137,3 +120,20 @@ # Non-0 means PcdFspsUpdDataAddress will be ignored, otherwise PcdFspsUpdDataAddress will be used. # gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress64|0x00000000|UINT64|0x50000003 + + ## This PCD decides how FSP is measured + # 1) The BootGuard ACM may already measured the FSP component, such as FSPT/FSPM. + # We need a flag (PCD) to indicate if there is need to do such FSP measurement or NOT. + # 2) The FSP binary includes FSP code and FSP UPD region. The UPD region is considered + # as configuration block, and it may be updated by OEM by design. + # This flag (PCD) is to indicate if we need isolate the UPD region from the FSP code region. + # BIT0: Need measure FSP. (for FSP1.x) - reserved in FSP2. + # BIT1: Need measure FSPT. (for FSP 2.x) + # BIT2: Need measure FSPM. (for FSP 2.x) + # BIT3: Need measure FSPS. (for FSP 2.x) + # BIT4~30: reserved. + # BIT31: Need isolate UPD region measurement. + #0: measure FSP[T|M|S] as one binary in one record (PCR0). + #1: measure FSP UPD region in one record (PCR1), the FSP code without UPD in another record (PCR0). + # + gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000|UINT32|0x50000004 -- cgit From 2b6d0eb43439891e641750cd5054b1bc3fb40e72 Mon Sep 17 00:00:00 2001 From: Min M Xu Date: Wed, 10 Jul 2024 21:05:53 -0400 Subject: OvmfPkg/OvmfPkgX64: Set default value of CC_MEASUREMENT_ENABLE to TRUE CC_MEASUREMENT_ENABLE is designed to control the loading of TdTcg2Dxe driver which is for EFI_CC_MEASUREMENT_PROTOCOL. TdTcg2Dxe is TD-Guest specific driver. From the security perspective a TD-Guest shall always load the TdTcg2Dxe driver so that EFI_CC_MEASUREMENT_PROTOCOL is installed and booting events are measured and extended to RTMRs. TdTcg2Dxe will check if it is running in a TD-Guest. If not then it returns right now and no EFI_CC_MEASUREMENT_PROTOCOL is installed. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Erdem Aktas Cc: Tom Lendacky Cc: Michael Roth Signed-off-by: Min Xu --- OvmfPkg/IntelTdx/README.md | 4 ++-- OvmfPkg/OvmfPkgX64.dsc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/IntelTdx/README.md b/OvmfPkg/IntelTdx/README.md index c168167c12..6e13c1748e 100644 --- a/OvmfPkg/IntelTdx/README.md +++ b/OvmfPkg/IntelTdx/README.md @@ -61,8 +61,8 @@ Build cd /path/to/edk2 source edksetup.sh -## without CC_MEASUREMENT enabled -build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -b RELEASE +## CC_MEASUREMENT disabled +build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -D CC_MEASUREMENT_ENABLE=FALSE -b RELEASE ## CC_MEASUREMENT enabled build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -D CC_MEASUREMENT_ENABLE=TRUE -b RELEASE diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index f131328932..efb0eedb04 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -32,7 +32,7 @@ DEFINE SECURE_BOOT_ENABLE = FALSE DEFINE SMM_REQUIRE = FALSE DEFINE SOURCE_DEBUG_ENABLE = FALSE - DEFINE CC_MEASUREMENT_ENABLE = FALSE + DEFINE CC_MEASUREMENT_ENABLE = TRUE !include OvmfPkg/Include/Dsc/OvmfTpmDefines.dsc.inc -- cgit From b92e16d5c30d3a525721720691035cf149a48f74 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Wed, 10 Jul 2024 10:49:47 +0800 Subject: BaseTools: Remove fno-plt from LoongArch CC flags Static relocation types have been handled in GenFw if using the PIC, and the CC flags not enable `fno-pic` by default. The option `fno-plt` is not necessary, as is not created by defualt in edk2(static linking) regardless of wether `fplt` is used or not, so remove this option from the LoongArch common CC flags. Cc: Rebecca Cran Cc: Liming Gao Cc: Bob Feng Cc: Yuwei Chen Signed-off-by: Chao Li --- BaseTools/Conf/tools_def.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 0dea1899fb..c459d83d68 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -896,7 +896,7 @@ NOOPT_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink="$(DEBUG_DIR)/$(MODULE_ DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -mthumb -fno-pic -fno-pie -DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -fno-plt -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections +DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections DEFINE GCC_ARM_CC_XIPFLAGS = -mno-unaligned-access DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only -- cgit From 5dc6f19b384abe761429d3192ab76c213b57b211 Mon Sep 17 00:00:00 2001 From: Chao Li Date: Thu, 11 Jul 2024 09:25:03 +0800 Subject: OvmfPkg: Fix the wild pointer in Fdt16550SerialProtHookLib There was a wild pointer in Fdt16550SerialProtHookLib which pointed to an unknown space, which was very wrong and has been fixed. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Chao Li --- .../Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c index baaa7ae7a9..8a73b8f9b3 100644 --- a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c +++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c @@ -26,13 +26,13 @@ PlatformHookSerialPortInitialize ( VOID ) { - UINT64 *UartBase; + UINT64 UartBase; if (PcdGet64 (PcdSerialRegisterBase) != 0) { return RETURN_SUCCESS; } - *UartBase = CsrRead (LOONGARCH_CSR_KS1); + UartBase = CsrRead (LOONGARCH_CSR_KS1); - return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)*UartBase); + return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)UartBase); } -- cgit From 807ab61359061003c154174799b1e184cb089b46 Mon Sep 17 00:00:00 2001 From: KasimX Liu Date: Thu, 11 Jul 2024 20:46:27 +0800 Subject: UefiPayloadPkg:Modify the PCD PcieResizableBar to dynamic PCD REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4808 Synchronize the use of the PCD PcieResizableBar attribute state Signed-off-by: KasimX Liu --- UefiPayloadPkg/UefiPayloadPkg.dsc | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index ca419a950b..e94a7db886 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -575,6 +575,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarSupport|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1 gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000 gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode|1 -- cgit From d4dbe5e101dcb86974f8dce3505b38343b83b432 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 3 Jul 2024 19:32:22 -0400 Subject: SecurityPkg/Tcg2Acpi: Revise debug print This debug print may attempt to print a string without a null terminator that can lead to a machine check. The value printed is substituted with a source buffer to still allow debug. Signed-off-by: Michael Kubacki --- SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c index 5addd2f563..b3c99a97e0 100644 --- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c @@ -641,7 +641,7 @@ UpdateHID ( CopyMem (DataPtr, Hid, TPM_HID_ACPI_SIZE); } - DEBUG ((DEBUG_INFO, "TPM2 ACPI _HID is patched to %a\n", DataPtr)); + DEBUG ((DEBUG_INFO, "TPM2 ACPI _HID is patched to %a\n", Hid)); return Status; } -- cgit From b54bc983c6102a59c9e0472dd0406ac9ccbaa0bf Mon Sep 17 00:00:00 2001 From: Dhaval Date: Thu, 20 Jun 2024 17:42:41 +0530 Subject: MdePkg/Library: Add RISCV64 support to BaseRngLib The ratified RISC-V crypto scalar extensions provide entropy bits via the seed CSR, as exposed by the Zkr extension. The Zkr extension is ratified and provides 16 bits of entropy seed when reading the SEED CSR. Guarded by a RISCV64 Feature PCD, 64-bit random numbers can be accumulated from the `seed` CSR. This driver is based on the driver in the Linux kernel. Cc: Liming Gao Cc: Michael D Kinney Cc: Zhiguang Liu Signed-off-by: Dhaval Sharma Co-authored-by: Tim Wawrzynczak --- MdePkg/Include/Register/RiscV64/RiscVEncoding.h | 10 + MdePkg/Library/BaseRngLib/BaseRngLib.inf | 8 + MdePkg/Library/BaseRngLib/Riscv/Rng.c | 277 ++++++++++++++++++++++++ MdePkg/Library/BaseRngLib/Riscv/Seed.S | 19 ++ MdePkg/MdePkg.dec | 2 + 5 files changed, 316 insertions(+) create mode 100644 MdePkg/Library/BaseRngLib/Riscv/Rng.c create mode 100644 MdePkg/Library/BaseRngLib/Riscv/Seed.S diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h index 8ccdea2f4f..a656d443a5 100644 --- a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h +++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h @@ -120,4 +120,14 @@ #define CAUSE_VIRTUAL_INST_FAULT 0x16 #define CAUSE_STORE_GUEST_PAGE_FAULT 0x17 +/* Sstc extension */ +#define CSR_SEED 0x15 + +#define SEED_OPST_MASK 0xc0000000 +#define SEED_OPST_BIST 0x00000000 +#define SEED_OPST_WAIT 0x40000000 +#define SEED_OPST_ES16 0x80000000 +#define SEED_OPST_DEAD 0xc0000000 +#define SEED_ENTROPY_MASK 0xffff + #endif diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf b/MdePkg/Library/BaseRngLib/BaseRngLib.inf index 49503b139b..a1614a900f 100644 --- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf +++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -50,6 +50,10 @@ [Guids.Ia32, Guids.X64] gEfiRngAlgorithmSp80090Ctr256Guid +[Sources.RISCV64] + Riscv/Rng.c + Riscv/Seed.S | GCC + [Packages] MdePkg/MdePkg.dec @@ -59,3 +63,7 @@ [LibraryClasses] BaseLib DebugLib + +[Pcd.RISCV64] + # Does the CPU support the Zkr extension (for the `Seed` CSR) + gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES diff --git a/MdePkg/Library/BaseRngLib/Riscv/Rng.c b/MdePkg/Library/BaseRngLib/Riscv/Rng.c new file mode 100644 index 0000000000..305ab60b4d --- /dev/null +++ b/MdePkg/Library/BaseRngLib/Riscv/Rng.c @@ -0,0 +1,277 @@ +/** @file + Random number generator service that uses the SEED instruction + to provide pseudorandom numbers. + + Copyright (c) 2024, Rivos, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + +#include +#include +#include +#include +#include + +#include "BaseRngLibInternals.h" +#define RISCV_CPU_FEATURE_ZKR_BITMASK 0x8 + +#define SEED_RETRY_LOOPS 100 + +// 64-bit Mersenne Twister implementation +// A widely used pseudo random number generator. It performs bit shifts etc to +// achieve the random number. It's output is determined by SEED value generated +// by RISC-V SEED CSR" + +#define STATE_SIZE 312 +#define MIDDLE 156 +#define INIT_SHIFT 62 +#define TWIST_MASK 0xb5026f5aa96619e9ULL +#define INIT_FACT 6364136223846793005ULL +#define SHIFT1 29 +#define MASK1 0x5555555555555555ULL +#define SHIFT2 17 +#define MASK2 0x71d67fffeda60000ULL +#define SHIFT3 37 +#define MASK3 0xfff7eee000000000ULL +#define SHIFT4 43 + +#define LOWER_MASK 0x7fffffff +#define UPPER_MASK (~(UINT64)LOWER_MASK) + +static UINT64 mState[STATE_SIZE]; +static UINTN mIndex = STATE_SIZE + 1; + +/** + Initialize mState to defualt state. + + @param[in] S Input seed value + **/ +STATIC +VOID +SeedRng ( + IN UINT64 S + ) +{ + UINTN I; + + mIndex = STATE_SIZE; + mState[0] = S; + + for (I = 1; I < STATE_SIZE; I++) { + mState[I] = (INIT_FACT * (mState[I - 1] ^ (mState[I - 1] >> INIT_SHIFT))) + I; + } +} + +/** + Initializes mState with entropy values. The initialization is based on the + Seed value populated in mState[0] which then influences all the other values + in the mState array. Later values are retrieved from the same array instead + of calling trng instruction every time. + + **/ +STATIC +VOID +TwistRng ( + VOID + ) +{ + UINTN I; + UINT64 X; + + for (I = 0; I < STATE_SIZE; I++) { + X = (mState[I] & UPPER_MASK) | (mState[(I + 1) % STATE_SIZE] & LOWER_MASK); + X = (X >> 1) ^ (X & 1 ? TWIST_MASK : 0); + mState[I] = mState[(I + MIDDLE) % STATE_SIZE] ^ X; + } + + mIndex = 0; +} + +// Defined in Seed.S +extern UINT64 +ReadSeed ( + VOID + ); + +/** + Gets seed value by executing trng instruction (CSR 0x15) amd returns + the see to the caller 64bit value. + + @param[out] Out Buffer pointer to store the 64-bit random value. + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + **/ +STATIC +BOOLEAN +Get64BitSeed ( + OUT UINT64 *Out + ) +{ + UINT64 Seed; + UINTN Retry; + UINTN ValidSeeds; + UINTN NeededSeeds; + UINT16 *Entropy; + + Retry = SEED_RETRY_LOOPS; + Entropy = (UINT16 *)Out; + NeededSeeds = sizeof (UINT64) / sizeof (UINT16); + ValidSeeds = 0; + + if (!ArchIsRngSupported ()) { + DEBUG ((DEBUG_ERROR, "Get64BitSeed: HW not supported!\n")); + return FALSE; + } + + do { + Seed = ReadSeed (); + + switch (Seed & SEED_OPST_MASK) { + case SEED_OPST_ES16: + Entropy[ValidSeeds++] = Seed & SEED_ENTROPY_MASK; + if (ValidSeeds == NeededSeeds) { + return TRUE; + } + + break; + + case SEED_OPST_DEAD: + DEBUG ((DEBUG_ERROR, "Get64BitSeed: Unrecoverable error!\n")); + return FALSE; + + case SEED_OPST_BIST: // fallthrough + case SEED_OPST_WAIT: // fallthrough + default: + continue; + } + } while (--Retry); + + return FALSE; +} + +/** + Constructor library which initializes Seeds and mStatus array. + + @retval EFI_SUCCESS Intialization was successful. + @retval EFI_UNSUPPORTED Feature not supported. + + **/ +EFI_STATUS +EFIAPI +BaseRngLibConstructor ( + VOID + ) +{ + UINT64 Seed; + + if (Get64BitSeed (&Seed)) { + SeedRng (Seed); + return EFI_SUCCESS; + } else { + return EFI_UNSUPPORTED; + } +} + +/** + Generates a 16-bit random number. + + @param[out] Rand Buffer pointer to store the 16-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + + **/ +BOOLEAN +EFIAPI +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ) +{ + UINT64 Rand64; + + if (ArchGetRandomNumber64 (&Rand64)) { + *Rand = Rand64 & MAX_UINT16; + return TRUE; + } + + return FALSE; +} + +/** + Generates a 32-bit random number. + + @param[out] Rand Buffer pointer to store the 32-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + + **/ +BOOLEAN +EFIAPI +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ) +{ + UINT64 Rand64; + + if (ArchGetRandomNumber64 (&Rand64)) { + *Rand = Rand64 & MAX_UINT32; + return TRUE; + } + + return FALSE; +} + +/** + Generates a 64-bit random number. + + @param[out] Rand Buffer pointer to store the 64-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + + **/ +BOOLEAN +EFIAPI +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ) +{ + UINT64 Y; + + // Never initialized. + if (mIndex > STATE_SIZE) { + return FALSE; + } + + // Mersenne Twister + if (mIndex == STATE_SIZE) { + TwistRng (); + } + + Y = mState[mIndex]; + Y ^= (Y >> SHIFT1) & MASK1; + Y ^= (Y << SHIFT2) & MASK2; + Y ^= (Y << SHIFT3) & MASK3; + Y ^= Y >> SHIFT4; + + mIndex++; + + *Rand = Y; + return TRUE; +} + +/** + Checks whether SEED is supported. + + @retval TRUE SEED is supported. + **/ +BOOLEAN +EFIAPI +ArchIsRngSupported ( + VOID + ) +{ + return ((PcdGet64 (PcdRiscVFeatureOverride) & RISCV_CPU_FEATURE_ZKR_BITMASK) != 0); +} diff --git a/MdePkg/Library/BaseRngLib/Riscv/Seed.S b/MdePkg/Library/BaseRngLib/Riscv/Seed.S new file mode 100644 index 0000000000..0028923395 --- /dev/null +++ b/MdePkg/Library/BaseRngLib/Riscv/Seed.S @@ -0,0 +1,19 @@ +//------------------------------------------------------------------------------ +// +// RISC-V cache operation. +// +// Copyright (c) 2024, Rivos Inc. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//------------------------------------------------------------------------------ + +#include + +.text + .p2align 4 + +ASM_FUNC (ReadSeed) +#The SEED CSR must only be accessed with read-write instructions +csrrw a0, CSR_SEED, x0 +ret diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 5dbe5a9f72..f8c30d3e76 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2430,6 +2430,8 @@ # previous stage has feature enabled and user wants to disable it. # BIT 2 = Page-Based Memory Types (Pbmt). This bit is relevant only if # previous stage has feature enabled and user wants to disable it. + # BIT 3 = Zkr extension.This bit is relevant only if + # previous stage has feature enabled and user wants to disable it. # gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFFF|UINT64|0x69 -- cgit From 91226e1eecacac832e5091d6a1867dc52666ee85 Mon Sep 17 00:00:00 2001 From: Dhaval Date: Thu, 20 Jun 2024 17:47:18 +0530 Subject: OvmfPkg/RiscVVirt: Configure zkr PCD for Virt Keep ZKR feature disabled by default until HW supports it. Feature is implemented in RISC-V BaseRngLib. Cc: Andrei Warkentin Cc: Ard Biesheuvel Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Sunil V L Signed-off-by: Dhaval Sharma Co-authored-by: Tim Wawrzynczak --- OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index b8338d2eb5..30e51790ac 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -203,7 +203,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE [PcdsFixedAtBuild.common] - gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFF8 + gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFF0 gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000 gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000 gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0 -- cgit From 8bb9145ad1a5db068f63e3e19b4a532226351b2b Mon Sep 17 00:00:00 2001 From: Chao Li Date: Fri, 12 Jul 2024 16:11:43 +0800 Subject: OvmfPkg: Add network support for LoongArch QEMU platform Open the network option to enable networking on the LoongArch QEMU platform. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Chao Li --- OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc | 10 +++++----- OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc index 70f6c75b0f..d1efc48d35 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc @@ -552,12 +552,12 @@ # # Network Support # -#!include NetworkPkg/NetworkComponents.dsc.inc +!include NetworkPkg/NetworkComponents.dsc.inc -# NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf { -# -# NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf -# } + NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf { + + NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf + } !if $(NETWORK_TLS_ENABLE) == TRUE NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf index ca28e6e888..ac197ade80 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf @@ -159,7 +159,7 @@ INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf # # Network modules -#!include NetworkPkg/Network.fdf.inc +!include NetworkPkg/Network.fdf.inc # # File system -- cgit From 8ade6d7bd1d8bb0b67ff254526078bd17689f363 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Wed, 3 Jul 2024 13:58:35 +0100 Subject: BaseTools: fix consistent Ecc misspelling of ASCII Ecc concistently referred to ASCII/Ascii as ACSII/Acsii, which bugged me to no end when trying to figure out how those tests worked. Fix all instances. Signed-off-by: Leif Lindholm --- BaseTools/Source/Python/Ecc/Check.py | 12 ++++++------ BaseTools/Source/Python/Ecc/Configuration.py | 6 +++--- BaseTools/Source/Python/Ecc/EccToolError.py | 4 ++-- BaseTools/Source/Python/Ecc/config.ini | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py index 33060db5f2..9ca2fa5cec 100644 --- a/BaseTools/Source/Python/Ecc/Check.py +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -181,7 +181,7 @@ class Check(object): # General Checking def GeneralCheck(self): - self.GeneralCheckNonAcsii() + self.GeneralCheckNonAscii() self.UniCheck() self.GeneralCheckNoTab() self.GeneralCheckLineEnding() @@ -238,10 +238,10 @@ class Check(object): OtherMsg = "File %s has trailing white spaces at line %s" % (Record[1], IndexOfLine) EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0]) - # Check whether file has non ACSII char - def GeneralCheckNonAcsii(self): - if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking Non-ACSII char in file ...") + # Check whether file has non ASCII char + def GeneralCheckNonAscii(self): + if EccGlobalData.gConfig.GeneralCheckNonAscii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Non-ASCII char in file ...") SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')""" RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) for Record in RecordSet: @@ -255,7 +255,7 @@ class Check(object): IndexOfChar += 1 if ord(Char) > 126: OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar) - EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ACSII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0]) + EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ASCII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0]) # C Function Layout Checking def FunctionLayoutCheck(self): diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py index 9d9feaca5e..ec49e0d0aa 100644 --- a/BaseTools/Source/Python/Ecc/Configuration.py +++ b/BaseTools/Source/Python/Ecc/Configuration.py @@ -59,7 +59,7 @@ _ConfigFileToInternalTranslation = { "GeneralCheckNoProgma":"GeneralCheckNoProgma", "GeneralCheckNoTab":"GeneralCheckNoTab", "GeneralCheckNo_Asm":"GeneralCheckNo_Asm", - "GeneralCheckNonAcsii":"GeneralCheckNonAcsii", + "GeneralCheckNonAscii":"GeneralCheckNonAscii", "GeneralCheckTabWidth":"GeneralCheckTabWidth", "GeneralCheckTrailingWhiteSpaceLine":"GeneralCheckTrailingWhiteSpaceLine", "GeneralCheckUni":"GeneralCheckUni", @@ -179,8 +179,8 @@ class Configuration(object): self.GeneralCheckCarriageReturn = 1 # Check whether the file exists self.GeneralCheckFileExistence = 1 - # Check whether file has non ACSII char - self.GeneralCheckNonAcsii = 1 + # Check whether file has non ASCII char + self.GeneralCheckNonAscii = 1 # Check whether UNI file is valid self.GeneralCheckUni = 1 # Check Only use CRLF (Carriage Return Line Feed) line endings. diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py index 2ff36c8329..b7874bac26 100644 --- a/BaseTools/Source/Python/Ecc/EccToolError.py +++ b/BaseTools/Source/Python/Ecc/EccToolError.py @@ -14,7 +14,7 @@ ERROR_GENERAL_CHECK_NO_ASM = 1004 ERROR_GENERAL_CHECK_NO_PROGMA = 1005 ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006 ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007 -ERROR_GENERAL_CHECK_NON_ACSII = 1008 +ERROR_GENERAL_CHECK_NON_ASCII = 1008 ERROR_GENERAL_CHECK_UNI = 1009 ERROR_GENERAL_CHECK_UNI_HELP_INFO = 1010 ERROR_GENERAL_CHECK_INVALID_LINE_ENDING = 1011 @@ -113,7 +113,7 @@ gEccErrorMessage = { ERROR_GENERAL_CHECK_NO_PROGMA : """There should be no use of "#progma" in source file except "#pragma pack(#)\"""", ERROR_GENERAL_CHECK_CARRIAGE_RETURN : "There should be a carriage return at the end of the file", ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found", - ERROR_GENERAL_CHECK_NON_ACSII : "File has invalid Non-ACSII char", + ERROR_GENERAL_CHECK_NON_ASCII : "File has invalid Non-ASCII char", ERROR_GENERAL_CHECK_UNI : "File is not a valid UTF-16 UNI file", ERROR_GENERAL_CHECK_UNI_HELP_INFO : "UNI file that is associated by INF or DEC file need define the prompt and help information.", ERROR_GENERAL_CHECK_INVALID_LINE_ENDING : "Only CRLF (Carriage Return Line Feed) is allowed to line ending.", diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini index 6edf897ffd..7ed3de7747 100644 --- a/BaseTools/Source/Python/Ecc/config.ini +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -62,8 +62,8 @@ GeneralCheckNoProgma = 1 GeneralCheckCarriageReturn = 1 # Check whether the file exists GeneralCheckFileExistence = 1 -# Check whether file has non ACSII char -GeneralCheckNonAcsii = 1 +# Check whether file has non ASCII char +GeneralCheckNonAscii = 1 # Check whether UNI file is valid GeneralCheckUni = 1 # Check Only use CRLF (Carriage Return Line Feed) line endings. -- cgit From 5366def8d01d141163a727aeaef61318180deb98 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Wed, 10 Jul 2024 20:34:00 +0100 Subject: BaseTools: drop GeneralCheckNonAscii() from ECC The GeneralCheckNonAscii() function is a sledgehammer rejecting any file containing any character outside of the 7-bit ASCII encoding space, as well as the DEL character (which seems unrelated). This conflicts with basic stuff like correctly spelling certain proper nouns in comments (like copyright statements), or string literals (for example in multi-language driver binding ComponentNames). So rip it out, to be replaced by more fine-grained checks to be added as identified and needed. Signed-off-by: Leif Lindholm --- BaseTools/Source/Python/Ecc/Check.py | 20 -------------------- BaseTools/Source/Python/Ecc/Configuration.py | 3 --- BaseTools/Source/Python/Ecc/EccToolError.py | 2 -- BaseTools/Source/Python/Ecc/config.ini | 2 -- 4 files changed, 27 deletions(-) diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py index 9ca2fa5cec..4561961141 100644 --- a/BaseTools/Source/Python/Ecc/Check.py +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -181,7 +181,6 @@ class Check(object): # General Checking def GeneralCheck(self): - self.GeneralCheckNonAscii() self.UniCheck() self.GeneralCheckNoTab() self.GeneralCheckLineEnding() @@ -238,25 +237,6 @@ class Check(object): OtherMsg = "File %s has trailing white spaces at line %s" % (Record[1], IndexOfLine) EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0]) - # Check whether file has non ASCII char - def GeneralCheckNonAscii(self): - if EccGlobalData.gConfig.GeneralCheckNonAscii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': - EdkLogger.quiet("Checking Non-ASCII char in file ...") - SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')""" - RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) - for Record in RecordSet: - if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList: - op = open(Record[1]).readlines() - IndexOfLine = 0 - for Line in op: - IndexOfLine += 1 - IndexOfChar = 0 - for Char in Line: - IndexOfChar += 1 - if ord(Char) > 126: - OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar) - EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ASCII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0]) - # C Function Layout Checking def FunctionLayoutCheck(self): self.FunctionLayoutCheckReturnType() diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py index ec49e0d0aa..d4aab1d131 100644 --- a/BaseTools/Source/Python/Ecc/Configuration.py +++ b/BaseTools/Source/Python/Ecc/Configuration.py @@ -59,7 +59,6 @@ _ConfigFileToInternalTranslation = { "GeneralCheckNoProgma":"GeneralCheckNoProgma", "GeneralCheckNoTab":"GeneralCheckNoTab", "GeneralCheckNo_Asm":"GeneralCheckNo_Asm", - "GeneralCheckNonAscii":"GeneralCheckNonAscii", "GeneralCheckTabWidth":"GeneralCheckTabWidth", "GeneralCheckTrailingWhiteSpaceLine":"GeneralCheckTrailingWhiteSpaceLine", "GeneralCheckUni":"GeneralCheckUni", @@ -179,8 +178,6 @@ class Configuration(object): self.GeneralCheckCarriageReturn = 1 # Check whether the file exists self.GeneralCheckFileExistence = 1 - # Check whether file has non ASCII char - self.GeneralCheckNonAscii = 1 # Check whether UNI file is valid self.GeneralCheckUni = 1 # Check Only use CRLF (Carriage Return Line Feed) line endings. diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py index b7874bac26..734a2b8b86 100644 --- a/BaseTools/Source/Python/Ecc/EccToolError.py +++ b/BaseTools/Source/Python/Ecc/EccToolError.py @@ -14,7 +14,6 @@ ERROR_GENERAL_CHECK_NO_ASM = 1004 ERROR_GENERAL_CHECK_NO_PROGMA = 1005 ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006 ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007 -ERROR_GENERAL_CHECK_NON_ASCII = 1008 ERROR_GENERAL_CHECK_UNI = 1009 ERROR_GENERAL_CHECK_UNI_HELP_INFO = 1010 ERROR_GENERAL_CHECK_INVALID_LINE_ENDING = 1011 @@ -113,7 +112,6 @@ gEccErrorMessage = { ERROR_GENERAL_CHECK_NO_PROGMA : """There should be no use of "#progma" in source file except "#pragma pack(#)\"""", ERROR_GENERAL_CHECK_CARRIAGE_RETURN : "There should be a carriage return at the end of the file", ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found", - ERROR_GENERAL_CHECK_NON_ASCII : "File has invalid Non-ASCII char", ERROR_GENERAL_CHECK_UNI : "File is not a valid UTF-16 UNI file", ERROR_GENERAL_CHECK_UNI_HELP_INFO : "UNI file that is associated by INF or DEC file need define the prompt and help information.", ERROR_GENERAL_CHECK_INVALID_LINE_ENDING : "Only CRLF (Carriage Return Line Feed) is allowed to line ending.", diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini index 7ed3de7747..ba4346e25b 100644 --- a/BaseTools/Source/Python/Ecc/config.ini +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -62,8 +62,6 @@ GeneralCheckNoProgma = 1 GeneralCheckCarriageReturn = 1 # Check whether the file exists GeneralCheckFileExistence = 1 -# Check whether file has non ASCII char -GeneralCheckNonAscii = 1 # Check whether UNI file is valid GeneralCheckUni = 1 # Check Only use CRLF (Carriage Return Line Feed) line endings. -- cgit From 8e6ba0dcae40bfd4c191b2cd47e08f38186513d1 Mon Sep 17 00:00:00 2001 From: v-bhavanisu <144935558+v-bhavanisu@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:45:58 -0700 Subject: BaseTools/HostBasedUnitTestRunner: Promote Unittest error to CI fail. Some unit tests would fail to execute or execute and not produce any output logs. In these cases, the only output would be in the CI Log as `UnitTest Execution Error`. A UnitTest Execution Error should be considered the same as a unit tests test failing. Signed-off-by: Aaron Pop --- BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py index 2e5c462cd2..31d13b2ee7 100644 --- a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py +++ b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py @@ -110,6 +110,7 @@ class HostBasedUnitTestRunner(IUefiBuildPlugin): if ret != 0: logging.error("UnitTest Execution Error: " + os.path.basename(test)) + failure_count += 1 else: logging.info("UnitTest Completed: " + os.path.basename(test)) -- cgit From 1bb9f47739ae7993191a36bea76c5a2157fdd10f Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 12 Jul 2024 19:29:22 -0400 Subject: BaseTools/CodeQL: Removed unused static function query This query seems to produce a rate of false positives with some common patterns in edk2 like passing function pointers for callback. Due to the usage of `STATIC` instead of `static` particularly for functions, this query was rarely used in the past. It is removed here to prevent future false positives. Signed-off-by: Michael Kubacki --- BaseTools/Plugin/CodeQL/CodeQlQueries.qls | 2 -- 1 file changed, 2 deletions(-) diff --git a/BaseTools/Plugin/CodeQL/CodeQlQueries.qls b/BaseTools/Plugin/CodeQL/CodeQlQueries.qls index 1a50983221..34fa6b3665 100644 --- a/BaseTools/Plugin/CodeQL/CodeQlQueries.qls +++ b/BaseTools/Plugin/CodeQL/CodeQlQueries.qls @@ -69,8 +69,6 @@ id: cpp/missing-header-guard - include: id: cpp/unused-local-variable -- include: - id: cpp/unused-static-function - include: id: cpp/unused-static-variable -- cgit From f9c373c8388f819166e57365197bc423d56209a6 Mon Sep 17 00:00:00 2001 From: Mario Bălănică Date: Sun, 30 Jun 2024 15:59:32 +0300 Subject: EmbeddedPkg: Add option to disable EFI Memory Attribute Protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a driver that allows users to disable the EFI Memory Attribute protocol through an HII setup option, in order to work around a broken version of rhboot's shim used in some distros (e.g. CentOS Stream 9) which incorrectly invokes the protocol and results in a Synchronous Exception. Default is enabled, which can also be overridden at build time by changing `gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault`. It is only applicable to ARM64 and there isn't any other technical reason for disabling this security feature. See: - https://github.com/microsoft/mu_silicon_arm_tiano/issues/124 - https://edk2.groups.io/g/devel/topic/99631663 - https://github.com/tianocore/edk2/pull/5840 Signed-off-by: Mario Bălănică --- .../MemoryAttributeManagerDxe.c | 197 +++++++++++++++++++++ .../MemoryAttributeManagerDxe.h | 22 +++ .../MemoryAttributeManagerDxe.inf | 62 +++++++ .../MemoryAttributeManagerDxeHii.uni | 17 ++ .../MemoryAttributeManagerDxeHii.vfr | 35 ++++ EmbeddedPkg/EmbeddedPkg.dec | 8 + EmbeddedPkg/EmbeddedPkg.dsc | 2 + .../Include/Guid/MemoryAttributeManagerFormSet.h | 17 ++ 8 files changed, 360 insertions(+) create mode 100644 EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c create mode 100644 EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h create mode 100644 EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf create mode 100644 EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni create mode 100644 EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr create mode 100644 EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c new file mode 100644 index 0000000000..7a0156ddbf --- /dev/null +++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c @@ -0,0 +1,197 @@ +/** @file + + Copyright (c) 2023-2024, Mario Bălănică + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#include "MemoryAttributeManagerDxe.h" + +extern UINT8 MemoryAttributeManagerDxeHiiBin[]; +extern UINT8 MemoryAttributeManagerDxeStrings[]; + +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +STATIC HII_VENDOR_DEVICE_PATH mVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +/** + Installs HII page for user configuration. + + @retval EFI_SUCCESS The operation completed successfully. + +**/ +STATIC +EFI_STATUS +EFIAPI +InstallHiiPages ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + EFI_HANDLE DriverHandle; + + DriverHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mVendorDevicePath, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiHandle = HiiAddPackages ( + &gMemoryAttributeManagerFormSetGuid, + DriverHandle, + MemoryAttributeManagerDxeStrings, + MemoryAttributeManagerDxeHiiBin, + NULL + ); + + if (HiiHandle == NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + &mVendorDevicePath, + NULL + ); + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + This function uninstalls the EFI_MEMORY_ATTRIBUTE_PROTOCOL + from CpuDxe's handle. +**/ +STATIC +VOID +UninstallEfiMemoryAttributeProtocol ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + UINTN Size; + VOID *MemoryAttributeProtocol; + + Size = sizeof (Handle); + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiMemoryAttributeProtocolGuid, + NULL, + &Size, + &Handle + ); + if (EFI_ERROR (Status)) { + ASSERT (Status == EFI_NOT_FOUND); + return; + } + + Status = gBS->HandleProtocol ( + Handle, + &gEfiMemoryAttributeProtocolGuid, + &MemoryAttributeProtocol + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + + Status = gBS->UninstallProtocolInterface ( + Handle, + &gEfiMemoryAttributeProtocolGuid, + MemoryAttributeProtocol + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return; + } + + DEBUG (( + DEBUG_INFO, + "EFI Memory Attribute Protocol disabled due to user/platform preference!\n" + )); +} + +/** + The entry point for MemoryAttributeManagerDxe driver. + + @param[in] ImageHandle The image handle of the driver. + @param[in] SystemTable The system table. + + @retval EFI_SUCCESS The operation completed successfully. + +**/ +EFI_STATUS +EFIAPI +MemoryAttributeManagerInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN Size; + MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA Config; + + Config.Enabled = PROTOCOL_ENABLED_DEFAULT; + + Size = sizeof (MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA); + Status = gRT->GetVariable ( + MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME, + &gMemoryAttributeManagerFormSetGuid, + NULL, + &Size, + &Config + ); + if (EFI_ERROR (Status)) { + Status = gRT->SetVariable ( + MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME, + &gMemoryAttributeManagerFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + Size, + &Config + ); + ASSERT_EFI_ERROR (Status); + } + + if (!Config.Enabled) { + UninstallEfiMemoryAttributeProtocol (); + } + + return InstallHiiPages (); +} diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h new file mode 100644 index 0000000000..a027f3e4b6 --- /dev/null +++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h @@ -0,0 +1,22 @@ +/** @file + + Copyright (c) 2023-2024, Mario Bălănică + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MEMORY_ATTRIBUTE_MANAGER_DXE_H_ +#define MEMORY_ATTRIBUTE_MANAGER_DXE_H_ + +#include + +#define PROTOCOL_ENABLED_DEFAULT FixedPcdGetBool(PcdMemoryAttributeEnabledDefault) + +#define MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME L"MemoryAttributeManagerData" + +typedef struct { + BOOLEAN Enabled; +} MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA; + +#endif // __MEMORY_ATTRIBUTE_MANAGER_DXE_H__ diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf new file mode 100644 index 0000000000..b55639cd71 --- /dev/null +++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf @@ -0,0 +1,62 @@ +## @file +# EFI Memory Attribute Protocol state manager +# +# This driver allows users to disable the EFI Memory Attribute protocol +# through an HII setup option, in order to work around a broken version +# of rhboot's shim used in some distros (e.g. CentOS Stream 9) which +# incorrectly invokes the protocol and results in a Synchronous Exception. +# +# It is only applicable to ARM64 and there isn't any other technical +# reason for disabling this security feature. +# +# See: +# - https://github.com/microsoft/mu_silicon_arm_tiano/issues/124 +# - https://edk2.groups.io/g/devel/topic/99631663 +# - https://github.com/tianocore/edk2/pull/5840 +# +# Copyright (c) 2023-2024, Mario Bălănică +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = MemoryAttributeManagerDxe + FILE_GUID = 5319346b-66ad-433a-9a91-f7fc286bc9a1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MemoryAttributeManagerInitialize + +[Sources] + MemoryAttributeManagerDxe.c + MemoryAttributeManagerDxe.h + MemoryAttributeManagerDxeHii.uni + MemoryAttributeManagerDxeHii.vfr + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + DevicePathLib + HiiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + +[Guids] + gMemoryAttributeManagerFormSetGuid + +[Protocols] + gEfiMemoryAttributeProtocolGuid + +[Pcd] + gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault + +[Depex] + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid AND + gEfiMemoryAttributeProtocolGuid diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni new file mode 100644 index 0000000000..8537824b1f --- /dev/null +++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni @@ -0,0 +1,17 @@ +/** @file + + Copyright (c) 2023-2024, Mario Bălănică + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#langdef en-US "English" + +#string STR_NULL_STRING #language en-US "" + +#string STR_FORM_SET_TITLE #language en-US "EFI Memory Attribute Protocol" +#string STR_FORM_SET_TITLE_HELP #language en-US "Configure the state of the EFI Memory Attribute Protocol.\n\n" + "Some old OS loader versions (e.g. as found in CentOS Stream 9) do not properly support the protocol and may cause a Synchronous Exception. This security feature can be disabled to work around the issue; otherwise it should be kept enabled." + +#string STR_ENABLE_PROTOCOL_PROMPT #language en-US "Enable Protocol" diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr new file mode 100644 index 0000000000..a303426e3c --- /dev/null +++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr @@ -0,0 +1,35 @@ +/** @file + + Copyright (c) 2023-2024, Mario Bălănică + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include "MemoryAttributeManagerDxe.h" + +formset + guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID, + title = STRING_TOKEN(STR_FORM_SET_TITLE), + help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP), + classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID, + + efivarstore MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA, + attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + name = MemoryAttributeManagerData, + guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID; + + form formid = 1, + title = STRING_TOKEN(STR_FORM_SET_TITLE); + + checkbox varid = MemoryAttributeManagerData.Enabled, + prompt = STRING_TOKEN(STR_ENABLE_PROTOCOL_PROMPT), + help = STRING_TOKEN(STR_NULL_STRING), + flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED, + default = PROTOCOL_ENABLED_DEFAULT, + endcheckbox; + endform; +endformset; diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index 5dfbbc2933..3497fa1df7 100644 --- a/EmbeddedPkg/EmbeddedPkg.dec +++ b/EmbeddedPkg/EmbeddedPkg.dec @@ -73,6 +73,9 @@ ## Include/Guid/NvVarStoreFormatted.h gEdkiiNvVarStoreFormattedGuid = { 0xd1a86e3f, 0x0707, 0x4c35, { 0x83, 0xcd, 0xdc, 0x2c, 0x29, 0xc8, 0x91, 0xa3 } } + # Include/Guid/MemoryAttributeManagerFormSet.h + gMemoryAttributeManagerFormSetGuid = { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } } + [Protocols.common] gHardwareInterruptProtocolGuid = { 0x2890B3EA, 0x053D, 0x1643, { 0xAD, 0x0C, 0xD6, 0x48, 0x08, 0xDA, 0x3F, 0xF1 } } gHardwareInterrupt2ProtocolGuid = { 0x32898322, 0x2da1, 0x474a, { 0xba, 0xaa, 0xf3, 0xf7, 0xcf, 0x56, 0x94, 0x70 } } @@ -192,3 +195,8 @@ # Expected Overflow Android Kernel Command Line Characters # gEmbeddedTokenSpaceGuid.PcdAndroidKernelCommandLineOverflow|0|UINT32|0x000005C + + # + # EFI Memory Attribute Protocol default enable state + # + gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault|TRUE|BOOLEAN|0x00000060 diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index e9062cacbb..ef66aea29d 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -239,6 +239,8 @@ EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf + EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf + EmbeddedPkg/Drivers/NonCoherentIoMmuDxe/NonCoherentIoMmuDxe.inf { DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf diff --git a/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h b/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h new file mode 100644 index 0000000000..2efdf03216 --- /dev/null +++ b/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h @@ -0,0 +1,17 @@ +/** @file + + Copyright (c) 2023-2024, Mario Bălănică + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MEMORY_ATTRIBUTE_MANAGER_FORMSET_H_ +#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_H_ + +#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID \ + { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } } + +extern EFI_GUID gMemoryAttributeManagerFormSetGuid; + +#endif // __MEMORY_ATTRIBUTE_MANAGER_FORMSET_H__ -- cgit From 690f13fcb4a7b74b30091c7067a18bb7971982d8 Mon Sep 17 00:00:00 2001 From: "levi.yun" Date: Mon, 8 Jul 2024 17:08:48 +0100 Subject: ArmPlatformPkg/Driver/PL061Gpio: Error checking for pin on release build ASSERT_EFI_ERROR would be removed in release build. This means it would trigger wrong behavior when invalid pin number given to Get(), Set() and GetMode(). Adding error check routine for invalid pin number and before check the pin number, check first other argument given to each function. Signed-off-by: Levi Yun --- ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c index d87ab3d3de..fc062204c0 100644 --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c @@ -177,13 +177,16 @@ Get ( EFI_STATUS Status; UINTN Index, Offset, RegisterBase; - Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); - ASSERT_EFI_ERROR (Status); - if (Value == NULL) { return EFI_INVALID_PARAMETER; } + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + if (PL061GetPins (RegisterBase, GPIO_PIN_MASK (Offset)) != 0) { *Value = 1; } else { @@ -223,7 +226,10 @@ Set ( UINTN Index, Offset, RegisterBase; Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); - ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } switch (Mode) { case GPIO_MODE_INPUT: @@ -285,14 +291,17 @@ GetMode ( EFI_STATUS Status; UINTN Index, Offset, RegisterBase; - Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); - ASSERT_EFI_ERROR (Status); - // Check for errors if (Mode == NULL) { return EFI_INVALID_PARAMETER; } + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + // Check if it is input or output if (MmioRead8 (RegisterBase + PL061_GPIO_DIR_REG) & GPIO_PIN_MASK (Offset)) { // Pin set to output -- cgit From 55b043732d20305c769c6243e0a9a6e1f5ae879d Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 2 Jul 2024 12:10:55 -0400 Subject: MdePkg/UefiDebugLibDebugPortProtocol: ExitBootServicesCallback() static REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3083 Since this is a library, make the function ExitBootServicesCallback() STATIC to prevent the likelihood that it collides with other symbols. Signed-off-by: Michael Kubacki --- MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c index 298d17c6a0..7ddecd0b62 100644 --- a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c +++ b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c @@ -34,9 +34,10 @@ EFI_BOOT_SERVICES *mDebugBS; @param Context Pointer to the notification function's context. **/ +static VOID EFIAPI -ExitBootServicesCallback ( +UefiDebugLibDebugPortProtocolExitBootServicesCallback ( EFI_EVENT Event, VOID *Context ) @@ -67,7 +68,7 @@ DxeDebugLibConstructor ( mDebugBS->CreateEvent ( EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, - ExitBootServicesCallback, + UefiDebugLibDebugPortProtocolExitBootServicesCallback, NULL, &mExitBootServicesEvent ); -- cgit From 6b4dd3625b24fbb9ac5d6d931dd11ff50e288a79 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 2 Jul 2024 16:50:23 -0400 Subject: MdeModulePkg/SmiHandlerProfileInfo: Declare correct XML encoding The code prints wide strings, so the content should be "utf-16" rather than "utf-8". Signed-off-by: Michael Kubacki --- MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c index 69baf1c51d..68c2e35791 100644 --- a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c +++ b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c @@ -667,7 +667,7 @@ SmiHandlerProfileInfoEntrypoint ( // // Dump all image // - Print (L"\n"); + Print (L"\n"); Print (L"\n"); Print (L"\n"); Print (L" \n"); -- cgit From 43b7a856fad2e25b1b5bddeb6cb08881a29caf4d Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 16 Jul 2024 14:38:59 -0600 Subject: RedfishPkg: Reduce DEBUG_ERROR to DEBUG_MANAGEABILITY in various places The Redfish drivers log messages as errors in various places when they don't find an appropriate network interface - even when one has already been found. Reduce those log messages to DEBUG_MANAGEABILITY to avoid spamming the console in Release builds. Signed-off-by: Rebecca Cran --- RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c | 2 +- RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c index 5e03132695..d6498b508e 100644 --- a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c @@ -412,7 +412,7 @@ AcquireRedfishServiceOnNetworkInterfaceCallback ( EFI_ERROR (ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances->Status)) { gBS->CloseEvent (ThisRedfishDiscoveredToken->Event); - DEBUG ((DEBUG_ERROR, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken)); + DEBUG ((DEBUG_MANAGEABILITY, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken)); FreePool (ThisRedfishDiscoveredToken); } diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c index f56ef0ec17..6870a2cae0 100644 --- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c +++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c @@ -570,9 +570,9 @@ DiscoverRedfishHostInterface ( } if (MacCompareStatus != 0) { - DEBUG ((DEBUG_ERROR, "%a: MAC address is not matched.\n", __func__)); + DEBUG ((DEBUG_MANAGEABILITY, "%a: MAC address is not matched.\n", __func__)); DEBUG (( - DEBUG_ERROR, + DEBUG_MANAGEABILITY, " NetworkInterface: %02x %02x %02x %02x %02x %02x.\n", Instance->NetworkInterface->MacAddress.Addr[0], Instance->NetworkInterface->MacAddress.Addr[1], @@ -582,7 +582,7 @@ DiscoverRedfishHostInterface ( Instance->NetworkInterface->MacAddress.Addr[5] )); DEBUG (( - DEBUG_ERROR, + DEBUG_MANAGEABILITY, " Redfish Host interface: %02x %02x %02x %02x %02x %02x.\n", DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[0], DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[1], @@ -1559,7 +1559,7 @@ RedfishServiceAcquireService ( FreePool ((VOID *)Instance); } - DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1)); + DEBUG ((DEBUG_MANAGEABILITY, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1)); } else { if (NewInstance) { InsertTailList (&mRedfishDiscoverList, &Instance->Entry); -- cgit From b3441e01003ab91df816263df98f9675b2cd2aa1 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Mon, 15 Jul 2024 22:29:40 +0800 Subject: MdeModulePkg/Core/DxeIplPeim: Enhance Code in DxeIplFindDxeCore Function REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4653 In DxeIplFindDxeCore function, there exists different behavior between Debug and Release built BIOS. This change is used to unify both of the code flow and fix the potential overflow of "Instance" variable. In this change, [1] Move the ASSERT_EFI_ERROR (Status) in failure to find DxeCore in any firmware volume condition. [2] Break the while-loop when not found required DxeCore. This would make the Instance variable not overflow in while-loop. [3] Add the CpuDeadLoop () in the end of the function and do not return since DxeCore is mandatory for the following booting to hand-off the PEI phase to DXE phase. [4] In case of the CpuDeadLoop () is de-assert by debugger, return the NULL pointer. Signed-off-by: Jason1 Lin --- MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c index 2c19f1a507..933b245036 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -3,7 +3,7 @@ Responsibility of this module is to load the DXE Core from a Firmware Volume. Copyright (c) 2016 HP Development Company, L.P. -Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -487,10 +487,10 @@ DxeIplFindDxeCore ( // if (EFI_ERROR (Status)) { REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT)); + ASSERT_EFI_ERROR (Status); + break; } - ASSERT_EFI_ERROR (Status); - // // Find the DxeCore file type from the beginning in this firmware volume. // @@ -509,6 +509,13 @@ DxeIplFindDxeCore ( // Instance++; } + + // + // DxeCore cannot find in any firmware volume. + // + CpuDeadLoop (); + + return NULL; } /** -- cgit From e32d24ef8c8211e76c020fa7a395328cd176190c Mon Sep 17 00:00:00 2001 From: Dongyan Qian Date: Tue, 16 Jul 2024 23:21:25 +0800 Subject: MdePkg: Define SMBIOS Protocol header according IndustryStandard As the SMBIOS table types belong to the SMBIOS standard, they were moved from the SMBIOS IndustryStandard into the SMBIOS Protocol header with the EFI_-prefix. Filling in definitions facilitates consistent use of header files: EFI_SMBIOS_TYPE_TPM_DEVICE EFI_SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION EFI_SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION EFI_SMBIOS_TYPE_STRING_PROPERTY_INFORMATION Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Chao Li Signed-off-by: Dongyan Qian --- MdePkg/Include/Protocol/Smbios.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdePkg/Include/Protocol/Smbios.h b/MdePkg/Include/Protocol/Smbios.h index f9346aac72..e6977b4100 100644 --- a/MdePkg/Include/Protocol/Smbios.h +++ b/MdePkg/Include/Protocol/Smbios.h @@ -69,6 +69,10 @@ #define EFI_SMBIOS_TYPE_ADDITIONAL_INFORMATION SMBIOS_TYPE_ADDITIONAL_INFORMATION #define EFI_SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION #define EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE +#define EFI_SMBIOS_TYPE_TPM_DEVICE SMBIOS_TYPE_TPM_DEVICE +#define EFI_SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION +#define EFI_SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION +#define EFI_SMBIOS_TYPE_STRING_PROPERTY_INFORMATION SMBIOS_TYPE_STRING_PROPERTY_INFORMATION #define EFI_SMBIOS_TYPE_INACTIVE SMBIOS_TYPE_INACTIVE #define EFI_SMBIOS_TYPE_END_OF_TABLE SMBIOS_TYPE_END_OF_TABLE #define EFI_SMBIOS_OEM_BEGIN SMBIOS_OEM_BEGIN -- cgit From dd58d1227c102ad4a799002f16b3a8c796d7d7cc Mon Sep 17 00:00:00 2001 From: Shenbagadevi R Date: Thu, 2 May 2024 13:06:00 +0530 Subject: MdePkg: Added support for Smbios 3.7.0 Spec REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4563 As per Smbios 3.7.0 spec, added CXL 3.0 support in Type 9, also added PMIC & RCD manufacturer ID and Revision information in Type17. Cc: Sainadh N Cc: Sundaresan S Cc: Srinivasan M Cc: Ramesh R Signed-off-by: Shenbagadevi R Reviewed-by: Gaoliming --- MdePkg/Include/IndustryStandard/SmBios.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h index 020733b777..c07cfcb814 100644 --- a/MdePkg/Include/IndustryStandard/SmBios.h +++ b/MdePkg/Include/IndustryStandard/SmBios.h @@ -1524,7 +1524,7 @@ typedef struct { UINT8 AsyncSurpriseRemoval : 1; UINT8 FlexbusSlotCxl10Capable : 1; UINT8 FlexbusSlotCxl20Capable : 1; - UINT8 Reserved : 1; ///< Set to 0. + UINT8 FlexbusSlotCxl30Capable : 1; /// SMBIOS spec 3.7.0 updated CXL 3.0 support } MISC_SLOT_CHARACTERISTICS2; /// @@ -2027,6 +2027,13 @@ typedef struct { // UINT32 ExtendedSpeed; UINT32 ExtendedConfiguredMemorySpeed; + // + // Add for smbios 3.7.0 + // + UINT16 Pmic0ManufacturerID; + UINT16 Pmic0RevisionNumber; + UINT16 RcdManufacturerID; + UINT16 RcdRevisionNumber; } SMBIOS_TABLE_TYPE17; /// -- cgit From c2d6e2e18a262b21c94684e8ff179614cd7c1b17 Mon Sep 17 00:00:00 2001 From: "levi.yun" Date: Thu, 2 May 2024 09:26:52 +0100 Subject: MdePkg/IndustryStandard: Add SET_ERROR_TYPE_WITH_ADDRESS define SET_ERROR_TYPE_WITH_ADDRESS Error Injection Actions was added from ACPI 5.1 specification. Update Error Injection Action with the ACPI spec. Cc: Zhiguang Liu Cc: Dandan Bi Cc: Liming Gao Cc: Zhichao Gao Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: levi.yun --- MdePkg/Include/IndustryStandard/Acpi51.h | 1 + MdePkg/Include/IndustryStandard/Acpi60.h | 1 + MdePkg/Include/IndustryStandard/Acpi61.h | 1 + MdePkg/Include/IndustryStandard/Acpi62.h | 1 + MdePkg/Include/IndustryStandard/Acpi63.h | 1 + MdePkg/Include/IndustryStandard/Acpi64.h | 1 + MdePkg/Include/IndustryStandard/Acpi65.h | 1 + 7 files changed, 7 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/Acpi51.h b/MdePkg/Include/IndustryStandard/Acpi51.h index 4241b8f198..cdf95386d2 100644 --- a/MdePkg/Include/IndustryStandard/Acpi51.h +++ b/MdePkg/Include/IndustryStandard/Acpi51.h @@ -1760,6 +1760,7 @@ typedef struct { #define EFI_ACPI_5_1_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_5_1_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_5_1_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_5_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_5_1_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi60.h b/MdePkg/Include/IndustryStandard/Acpi60.h index 3757d3f827..d545de1ba2 100644 --- a/MdePkg/Include/IndustryStandard/Acpi60.h +++ b/MdePkg/Include/IndustryStandard/Acpi60.h @@ -1947,6 +1947,7 @@ typedef struct { #define EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_0_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi61.h b/MdePkg/Include/IndustryStandard/Acpi61.h index c3facc6e37..94d7241013 100644 --- a/MdePkg/Include/IndustryStandard/Acpi61.h +++ b/MdePkg/Include/IndustryStandard/Acpi61.h @@ -1979,6 +1979,7 @@ typedef struct { #define EFI_ACPI_6_1_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_1_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_1_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_6_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_1_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi62.h b/MdePkg/Include/IndustryStandard/Acpi62.h index 4dd3e21c23..732e4d16c5 100644 --- a/MdePkg/Include/IndustryStandard/Acpi62.h +++ b/MdePkg/Include/IndustryStandard/Acpi62.h @@ -2292,6 +2292,7 @@ typedef struct { #define EFI_ACPI_6_2_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_2_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_2_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_6_2_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_2_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi63.h b/MdePkg/Include/IndustryStandard/Acpi63.h index 7582dccf64..0cf984a840 100644 --- a/MdePkg/Include/IndustryStandard/Acpi63.h +++ b/MdePkg/Include/IndustryStandard/Acpi63.h @@ -2252,6 +2252,7 @@ typedef struct { #define EFI_ACPI_6_3_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_3_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_3_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_6_3_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_3_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi64.h b/MdePkg/Include/IndustryStandard/Acpi64.h index faf069a045..fd7b718ce4 100644 --- a/MdePkg/Include/IndustryStandard/Acpi64.h +++ b/MdePkg/Include/IndustryStandard/Acpi64.h @@ -2335,6 +2335,7 @@ typedef struct { #define EFI_ACPI_6_4_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_4_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_4_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_6_4_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_4_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index b9616a3e29..6721c42e47 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -2432,6 +2432,7 @@ typedef struct { #define EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS 0x07 +#define EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_5_EINJ_TRIGGER_ERROR 0xFF /// -- cgit From 5b429acec7d049f249479b5e75e075aa74ec5a79 Mon Sep 17 00:00:00 2001 From: "levi.yun" Date: Thu, 2 May 2024 09:32:26 +0100 Subject: MdePkg/IndustryStandard: Add GET_EXECUTE_OPERATION_TIMINGS define GET_EXECUTE_OPERATION_TIMINGS Error Injection Actions was added from ACPI 6.1 specification. Update Error Injection Action with the ACPI spec. Cc: Zhiguang Liu Cc: Dandan Bi Cc: Liming Gao Cc: Zhichao Gao Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: levi.yun --- MdePkg/Include/IndustryStandard/Acpi61.h | 1 + MdePkg/Include/IndustryStandard/Acpi62.h | 1 + MdePkg/Include/IndustryStandard/Acpi63.h | 1 + MdePkg/Include/IndustryStandard/Acpi64.h | 1 + MdePkg/Include/IndustryStandard/Acpi65.h | 1 + 5 files changed, 5 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/Acpi61.h b/MdePkg/Include/IndustryStandard/Acpi61.h index 94d7241013..5100d8b3b4 100644 --- a/MdePkg/Include/IndustryStandard/Acpi61.h +++ b/MdePkg/Include/IndustryStandard/Acpi61.h @@ -1980,6 +1980,7 @@ typedef struct { #define EFI_ACPI_6_1_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_1_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 +#define EFI_ACPI_6_1_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_1_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi62.h b/MdePkg/Include/IndustryStandard/Acpi62.h index 732e4d16c5..711b88b758 100644 --- a/MdePkg/Include/IndustryStandard/Acpi62.h +++ b/MdePkg/Include/IndustryStandard/Acpi62.h @@ -2293,6 +2293,7 @@ typedef struct { #define EFI_ACPI_6_2_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_2_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_2_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 +#define EFI_ACPI_6_2_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_2_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi63.h b/MdePkg/Include/IndustryStandard/Acpi63.h index 0cf984a840..68798da725 100644 --- a/MdePkg/Include/IndustryStandard/Acpi63.h +++ b/MdePkg/Include/IndustryStandard/Acpi63.h @@ -2253,6 +2253,7 @@ typedef struct { #define EFI_ACPI_6_3_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_3_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_3_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 +#define EFI_ACPI_6_3_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_3_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi64.h b/MdePkg/Include/IndustryStandard/Acpi64.h index fd7b718ce4..bbe6a3c9eb 100644 --- a/MdePkg/Include/IndustryStandard/Acpi64.h +++ b/MdePkg/Include/IndustryStandard/Acpi64.h @@ -2336,6 +2336,7 @@ typedef struct { #define EFI_ACPI_6_4_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_4_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_4_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 +#define EFI_ACPI_6_4_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_4_EINJ_TRIGGER_ERROR 0xFF /// diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 6721c42e47..264869e862 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -2433,6 +2433,7 @@ typedef struct { #define EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 +#define EFI_ACPI_6_4_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_5_EINJ_TRIGGER_ERROR 0xFF /// -- cgit From 873f35625daff05364d4f8abe93c3df86087978d Mon Sep 17 00:00:00 2001 From: "levi.yun" Date: Tue, 30 Apr 2024 14:49:49 +0100 Subject: MdePkg/IndustryStandard: Update EINJ information according to ACPI 6.5 ACPI 6.5 specification updates EINJ revision to 0x02 and adds new Error Injection Actions - EINJV2_SET_ERROR_TYPE - EINJV2_GET_ERROR_TYPE This patches updates EINJ information based on ACPI 6.5 specification. Also, add missing Error Injection Actions too. Cc: Zhiguang Liu Cc: Dandan Bi Cc: Liming Gao Cc: Zhichao Gao Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: levi.yun --- MdePkg/Include/IndustryStandard/Acpi65.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 264869e862..387af78cfe 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -2419,7 +2419,7 @@ typedef struct { /// /// EINJ Version (as defined in ACPI 6.5 spec.) /// -#define EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION 0x01 +#define EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION 0x02 /// /// EINJ Error Injection Actions @@ -2433,7 +2433,9 @@ typedef struct { #define EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 -#define EFI_ACPI_6_4_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 +#define EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 +#define EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE 0x10 +#define EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE 0x11 #define EFI_ACPI_6_5_EINJ_TRIGGER_ERROR 0xFF /// -- cgit From 23d3fc056d37039ffe1bd4461492a1e226c779e5 Mon Sep 17 00:00:00 2001 From: "levi.yun" Date: Tue, 30 Apr 2024 14:53:18 +0100 Subject: ShellPkg/Acpiview: Add EINJ Parser Add a new parser for the Error Injection Table (EINJ). The EINJ table provides machinism through which OSPM can inject hardware errors to the platform without requiring platform specific OSPM software. Cc: Zhiguang Liu Cc: Dandan Bi Cc: Liming Gao Cc: Zhichao Gao Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: levi.yun --- .../UefiShellAcpiViewCommandLib/AcpiParser.h | 21 ++ .../Parsers/Einj/EinjParser.c | 358 +++++++++++++++++++++ .../UefiShellAcpiViewCommandLib.c | 1 + .../UefiShellAcpiViewCommandLib.inf | 1 + 4 files changed, 381 insertions(+) create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 6468fe5d8c..b41f110f6a 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -616,6 +616,27 @@ ParseAcpiDsdt ( IN UINT8 AcpiTableRevision ); +/** + This function parses the EINJ table. + When trace is enabled this function parses the EINJ table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiEinj ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + /** This function parses the ACPI ERST table. When trace is enabled this function parses the ERST table and diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c new file mode 100644 index 0000000000..de867fb34a --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c @@ -0,0 +1,358 @@ +/** @file + EINJ table parser + + Copyright (c) 2024, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - ACPI 6.5, Table 18.3.2 ACPI Error Source +**/ + +#include +#include + +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" + +STATIC ACPI_DESCRIPTION_HEADER_INFO mAcpiHdrInfo; +STATIC UINT32 *mEinjInjectionHdrSize; +STATIC UINT32 *mEinjInjectionEntryCnt; + +STATIC CONST CHAR16 *InstNameTable[] = { + L"READ_REGISTER", + L"READ_REGISTER_VALUE", + L"WRITE_REGISTER", + L"WRITE_REGISTER_VALUE", + L"NOOP", +}; + +/** + This function validates the flags field in the EINJ injection header. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInjectionFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 Flags; + + Flags = *(UINT8 *)Ptr; + + if (Flags != 0) { + IncrementErrorCount (); + Print (L"\nERROR: Injection Flags must be zero..."); + } +} + +/** + An ACPI_PARSER array describing the ACPI EINJ Table. +**/ +STATIC CONST ACPI_PARSER EinjParser[] = { + PARSE_ACPI_HEADER (&mAcpiHdrInfo), + { L"Injection Header Size", 4, 36, L"%d", NULL, (VOID **)&mEinjInjectionHdrSize, + NULL, NULL }, + { L"Injection Flags", 1, 40, L"0x%x", NULL, NULL, ValidateInjectionFlags,NULL }, + { L"Reserved", 3, 41, NULL, NULL, NULL, NULL, NULL }, + { L"Injection Entry Count", 4, 44, L"%d", NULL, (VOID **)&mEinjInjectionEntryCnt, + NULL, NULL }, + /// Injection Action Table. + /// ... +}; + +/** + This function validates the injection action field in + the EINJ injection instruction entry. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInjectionAction ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 InjectionAction; + UINT8 MaxInjectionAction; + + InjectionAction = *(UINT8 *)Ptr; + + /** + * EFI_ACPI_6_5_EINJ_TRIGGER_ERROR is only used Trigger Action Table + * not used in Injection Action Table in EINJ. + * Cf ACPI 6.5 Table 18.24 - Error Injection Table + * Cf ACPI 6.5 Table 18.36 - Trigger Error Action + */ + if (*mAcpiHdrInfo.Revision < EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION) { + MaxInjectionAction = EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS; + } else { + MaxInjectionAction = EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE; + } + + if ((InjectionAction < EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION) || + (InjectionAction > MaxInjectionAction)) + { + IncrementErrorCount (); + Print (L"\nERROR: Invalid Injection Action(0x%x)...", InjectionAction); + } +} + +/** + This function validates the instruction field in + the EINJ injection instruction entry. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInstruction ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 Inst; + + Inst = *Ptr; + + if (*mAcpiHdrInfo.Revision <= EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION) { + if (Inst > EFI_ACPI_6_5_EINJ_NOOP) { + IncrementErrorCount (); + Print (L"\nERROR: Invalid Instruction(0x%x)...", Inst); + } + } +} + +/** + This function validates the register region field in + the EINJ injection instruction entry. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateRegisterRegion ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *RegisterRegion; + + RegisterRegion = (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *)Ptr; + + if ((RegisterRegion->AddressSpaceId != EFI_ACPI_6_5_SYSTEM_MEMORY) && + (RegisterRegion->AddressSpaceId != EFI_ACPI_6_5_SYSTEM_IO)) + { + IncrementErrorCount (); + Print (L"\nERROR: Register Region Must be SYSTEM_MEMORY or SYSTEM_IO..."); + } +} + +/** + Dumps the injection action fields in injection instruction entry. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpInjectionInstAction ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + UINT8 InjectionAction; + CONST CHAR16 *ActionName; + + InjectionAction = *Ptr; + + switch (InjectionAction) { + case EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION: + ActionName = L"BEGIN_INJECTION_OPERATION"; + break; + case EFI_ACPI_6_5_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE: + ActionName = L"GET_TRIGGER_ERROR_ACTION_TABLE"; + break; + case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE: + ActionName = L"SET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_GET_ERROR_TYPE: + ActionName = L"GET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_END_OPERATION: + ActionName = L"END_OPERATION"; + break; + case EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION: + ActionName = L"EXECUTE_OPERATION"; + break; + case EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS: + ActionName = L"CHECK_BUSY_STATUS"; + break; + case EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS: + ActionName = L"GET_COMMAND_STATUS"; + break; + case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS: + ActionName = L"SET_ERROR_TYPE_WITH_ADDRESS"; + break; + case EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS: + ActionName = L"GET_EXECUTE_OPERATION_TIMINGS"; + break; + case EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE: + ActionName = L"EINJV2_SET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE: + ActionName = L"EINJV2_GET_ERROR_TYPE"; + break; + case EFI_ACPI_6_5_EINJ_TRIGGER_ERROR: + ActionName = L"TRIGGER_ERROR"; + break; + default: + IncrementErrorCount (); + ActionName = L"UNKNOWN"; + } + + Print (L"%s(0x%x)", ActionName, InjectionAction); +} + +/** + Dumps the instruction fields in injection instruction entry. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpInstruction ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + UINT8 Inst; + CONST CHAR16 *InstName; + + Inst = *Ptr; + + if (Inst < ARRAY_SIZE (InstNameTable)) { + InstName = InstNameTable[Inst]; + } else { + IncrementErrorCount (); + InstName = L"UNKNOWN"; + } + + Print (L"%s(0x%x)", InstName, Inst); +} + +/** + An ACPI_PARSER array describing the EINJ Injection instruction entry. +**/ +STATIC CONST ACPI_PARSER EinjInjectionInstEntryParser[] = { + { L"Injection Action", 1, 0, NULL, DumpInjectionInstAction, NULL, + ValidateInjectionAction, NULL }, + { L"Instruction", 1, 1, NULL, DumpInstruction, NULL, + ValidateInstruction, NULL }, + { L"Flags", 1, 2, L"0x%x", NULL, NULL,NULL, NULL }, + { L"Reserved", 1, 3, NULL, NULL, NULL,NULL, NULL }, + { L"Register Region", 12, 4, NULL, DumpGas, NULL, + ValidateRegisterRegion, NULL }, + { L"Value", 8, 16, L"0x%x", NULL, NULL,NULL, NULL }, + { L"Mask", 8, 24, L"0x%x", NULL, NULL,NULL, NULL }, +}; + +/** + This function parses the EINJ table. + When trace is enabled this function parses the EINJ table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiEinj ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8 *InjInstEntryPtr; + UINT32 InjInstEntrySize; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "EINJ", + Ptr, + AcpiTableLength, + PARSER_PARAMS (EinjParser) + ); + + // Validate Error Source Descriptors Count. + if ((mEinjInjectionHdrSize == NULL) || (*mEinjInjectionHdrSize != Offset)) { + IncrementErrorCount (); + Print (L"ERROR: Invalid Injection Header...\n"); + return; + } + + if ((mEinjInjectionEntryCnt == NULL) || (*mEinjInjectionEntryCnt == 0)) { + IncrementErrorCount (); + Print (L"ERROR: Injection Instruction Entry should be presented...\n"); + return; + } + + InjInstEntrySize = sizeof (EFI_ACPI_6_5_EINJ_INJECTION_INSTRUCTION_ENTRY); + + if ((*mEinjInjectionEntryCnt * InjInstEntrySize) != (AcpiTableLength - Offset)) { + IncrementErrorCount (); + Print ( + L"ERROR: Incorrect count for Injection Instruction Entry.\n" \ + L" Injection Entry Count= %d.\n" \ + L" Present Count= %d.\n", + *mEinjInjectionEntryCnt, + (AcpiTableLength - Offset) / InjInstEntrySize + ); + } + + while (Offset < AcpiTableLength) { + InjInstEntryPtr = Ptr + Offset; + + // Get Injection Instruction Entry. + ParseAcpi ( + TRUE, + 2, + "Injection Instruction Entry", + InjInstEntryPtr, + AcpiTableLength - Offset, + PARSER_PARAMS (EinjInjectionInstEntryParser) + ); + + Offset += InjInstEntrySize; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c index 0bdf068fe0..4a90372d81 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -54,6 +54,7 @@ ACPI_TABLE_PARSER ParserList[] = { { EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2 }, { EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiDsdt }, + { EFI_ACPI_6_5_ERROR_INJECTION_TABLE_SIGNATURE, ParseAcpiEinj }, { EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE, ParseAcpiErst }, { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs }, { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt }, diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index e62366116c..9c2e2b703d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -33,6 +33,7 @@ Parsers/Bgrt/BgrtParser.c Parsers/Dbg2/Dbg2Parser.c Parsers/Dsdt/DsdtParser.c + Parsers/Einj/EinjParser.c Parsers/Erst/ErstParser.c Parsers/Facs/FacsParser.c Parsers/Fadt/FadtParser.c -- cgit From 11c50d6ca10a1410c2db187078fa7139e29e3042 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Fri, 5 Jul 2024 22:01:00 +0800 Subject: MdeModulePkg/UfsBlockIoPei: Wait fDeviceInit Be Cleared by Devices REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4655 [Feature Description] - UFS device would clear fDeviceInit flag once the device initialization is completed. - This change is polling to check the flag is cleared or not with specific timeout (UFS_INIT_COMPLETION_TIMEOUT - 600ms). - This behavior is the same as UfsPassThruDxe module. [Notes] - This change included as a partial of below SHA1-ID - 95ad8f7f6a6c84ef46a96a8ba852afed805d1ca3 - c5740f360636479fb91681093b1dee1cc366075c Signed-off-by: Jason1 Lin --- MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c | 60 ++++++++++++++++++++-- MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h | 24 ++++++++- MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c | 28 +++++++++- 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c index b8651ff998..4dbd033d41 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -1016,6 +1016,58 @@ UfsEndOfPei ( return EFI_SUCCESS; } +/** + Finishes device initialization by setting fDeviceInit flag and waiting until device responds by + clearing it. + + @param[in] Private Pointer to the UFS_PEIM_HC_PRIVATE_DATA. + + @retval EFI_SUCCESS The operation succeeds. + @retval Others The operation fails. + +**/ +EFI_STATUS +UfsFinishDeviceInitialization ( + IN UFS_PEIM_HC_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + UINT8 DeviceInitStatus; + UINT32 Timeout; + + DeviceInitStatus = 0xFF; + + // + // The host enables the device initialization completion by setting fDeviceInit flag. + // + Status = UfsSetFlag (Private, UfsFlagDevInit); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // There are cards that can take upto 600ms to clear fDeviceInit flag. + // + Timeout = UFS_INIT_COMPLETION_TIMEOUT; + do { + Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus); + if (EFI_ERROR (Status)) { + return Status; + } + + MicroSecondDelay (1); + Timeout--; + } while (DeviceInitStatus != 0 && Timeout != 0); + + if (Timeout == 0) { + DEBUG ((DEBUG_ERROR, "%a: DeviceInitStatus = %x EFI_TIMEOUT \n", __func__, DeviceInitStatus)); + return EFI_TIMEOUT; + } else { + DEBUG ((DEBUG_INFO, "%a: Timeout left = %x EFI_SUCCESS \n", __func__, Timeout)); + return EFI_SUCCESS; + } +} + /** The user code starts with this function. @@ -1116,11 +1168,11 @@ InitializeUfsBlockIoPeim ( } // - // The host enables the device initialization completion by setting fDeviceInit flag. + // Check the UFS device is initialized completed. // - Status = UfsSetFlag (Private, UfsFlagDevInit); + Status = UfsFinishDeviceInitialization (Private); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ufs Set fDeviceInit Flag Error, Status = %r\n", Status)); + DEBUG ((DEBUG_ERROR, "Device failed to finish initialization, Status = %r\n", Status)); Controller++; continue; } diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h index ed4776f548..489b6c34ec 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -31,7 +31,8 @@ #define UFS_PEIM_HC_SIG SIGNATURE_32 ('U', 'F', 'S', 'H') -#define UFS_PEIM_MAX_LUNS 8 +#define UFS_PEIM_MAX_LUNS 8 +#define UFS_INIT_COMPLETION_TIMEOUT 600000 typedef struct { UINT8 Lun[UFS_PEIM_MAX_LUNS]; @@ -226,6 +227,25 @@ UfsSetFlag ( IN UINT8 FlagId ); +/** + Read specified flag from a UFS device. + + @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure. + @param[in] FlagId The ID of flag to be read. + @param[out] Value The flag's value. + + @retval EFI_SUCCESS The flag was read successfully. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag. + @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag. + +**/ +EFI_STATUS +UfsReadFlag ( + IN UFS_PEIM_HC_PRIVATE_DATA *Private, + IN UINT8 FlagId, + OUT UINT8 *Value + ); + /** Read or write specified device descriptor of a UFS device. diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c index d19a7fed6e..360b642611 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -1065,6 +1065,32 @@ UfsSetFlag ( return Status; } +/** + Read specified flag from a UFS device. + + @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure. + @param[in] FlagId The ID of flag to be read. + @param[out] Value The flag's value. + + @retval EFI_SUCCESS The flag was read successfully. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag. + @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag. + +**/ +EFI_STATUS +UfsReadFlag ( + IN UFS_PEIM_HC_PRIVATE_DATA *Private, + IN UINT8 FlagId, + OUT UINT8 *Value + ) +{ + EFI_STATUS Status; + + Status = UfsRwFlags (Private, TRUE, FlagId, Value); + + return Status; +} + /** Sends NOP IN cmd to a UFS device for initialization process request. For more details, please refer to UFS 2.0 spec Figure 13.3. -- cgit From 0adc868b362873eb7c749f3ac6c38f9e293af10d Mon Sep 17 00:00:00 2001 From: Dongyan Qian Date: Tue, 16 Jul 2024 23:29:22 +0800 Subject: MdePkg/BaseLib: Optimize LOONGARCH64 csr usage REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4812 When the Select is out of support, use method break exception instead of method return -1, avoid unknown errors caused by untimely detection. Cc: Chao Li Signed-off-by: Dongyan Qian --- MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S | 9 +++------ MdePkg/Library/BaseLib/LoongArch64/Csr.c | 7 ++++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S index 3a879411f5..eb82724503 100644 --- a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S +++ b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S @@ -100,8 +100,7 @@ DirMapCsrRd: jirl $zero, $t0, 0 ReadSelNumErr: - addi.d $a0, $zero, -1 - jirl $zero, $ra, 0 + break 0 BasicCsrRead: CsrSel = LOONGARCH_CSR_CRMD @@ -230,8 +229,7 @@ DirMapCsrWr: jirl $zero, $t0, 0 WriteSelNumErr: - addi.d $a0, $zero, -1 - jirl $zero, $ra, 0 + break 0 BasicCsrWrite: CsrSel = LOONGARCH_CSR_CRMD @@ -368,8 +366,7 @@ DirMapCsrXchg: jirl $zero, $t0, 0 XchgSelNumErr: - addi.d $a0, $zero, -1 - jirl $zero, $ra, 0 + break 0 BasicCsrXchange: CsrSel = LOONGARCH_CSR_CRMD diff --git a/MdePkg/Library/BaseLib/LoongArch64/Csr.c b/MdePkg/Library/BaseLib/LoongArch64/Csr.c index f2ec80b38d..5a40bfede5 100644 --- a/MdePkg/Library/BaseLib/LoongArch64/Csr.c +++ b/MdePkg/Library/BaseLib/LoongArch64/Csr.c @@ -29,7 +29,8 @@ AsmCsrXChg ( @param[in] Select CSR read instruction select values. - @return The return value of csrrd instruction, return -1 means Select is out of support. + @return The return value of csrrd instruction, + if a break exception is triggered, the Select is out of support. **/ UINTN EFIAPI @@ -47,7 +48,7 @@ CsrRead ( @param[in, out] Value The csrwr will write the value. @return The return value of csrwr instruction, that is, store the old value of - the register, return -1 means Select is out of support. + the register, if a break exception is triggered, the Select is out of support. **/ UINTN EFIAPI @@ -67,7 +68,7 @@ CsrWrite ( @param[in] Mask The csrxchg mask value. @return The return value of csrxchg instruction, that is, store the old value of - the register, return -1 means Select is out of support. + the register, if a break exception is triggered, the Select is out of support. **/ UINTN EFIAPI -- cgit From cee9d1b16bdcd7fe8bad6b39fe18af0a15941ca4 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Tue, 16 Jul 2024 15:50:01 -0700 Subject: MdeModulePkg: DxeCore: Fix Use-After-Free guard causing page fault REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2411 With Use-After-Free heap guard feature enabled, the DxeCore would blindly attempt to "level-up" when the `GuardAllFreedPages` inspect a non-max level table entry from the last loop. This could cause the next round of inspection to dereference a potentially null pointer and as such causing a page fault. This change adds a null pointer check to prevent such case from happening. Cc: Liming Gao Signed-off-by: Kun Qin --- MdeModulePkg/Core/Dxe/Mem/HeapGuard.c | 51 +++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index 0c0ca61872..4071053036 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -1406,34 +1406,39 @@ GuardAllFreedPages ( TableEntry = ((UINT64 *)(UINTN)(Tables[Level]))[Indices[Level]]; Address = Addresses[Level]; - if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) { - Level += 1; - Tables[Level] = TableEntry; - Addresses[Level] = Address; - Indices[Level] = 0; - - continue; + if (TableEntry == 0) { + GuardPageNumber = 0; + GuardPage = (UINT64)-1; } else { - BitIndex = 1; - while (BitIndex != 0) { - if ((TableEntry & BitIndex) != 0) { - if (GuardPage == (UINT64)-1) { - GuardPage = Address; + if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) { + Level += 1; + Tables[Level] = TableEntry; + Addresses[Level] = Address; + Indices[Level] = 0; + + continue; + } else { + BitIndex = 1; + while (BitIndex != 0) { + if ((TableEntry & BitIndex) != 0) { + if (GuardPage == (UINT64)-1) { + GuardPage = Address; + } + + ++GuardPageNumber; + } else if (GuardPageNumber > 0) { + GuardFreedPages (GuardPage, GuardPageNumber); + GuardPageNumber = 0; + GuardPage = (UINT64)-1; } - ++GuardPageNumber; - } else if (GuardPageNumber > 0) { - GuardFreedPages (GuardPage, GuardPageNumber); - GuardPageNumber = 0; - GuardPage = (UINT64)-1; - } + if (TableEntry == 0) { + break; + } - if (TableEntry == 0) { - break; + Address += EFI_PAGES_TO_SIZE (1); + BitIndex = LShiftU64 (BitIndex, 1); } - - Address += EFI_PAGES_TO_SIZE (1); - BitIndex = LShiftU64 (BitIndex, 1); } } } -- cgit From 62bf2aefc7d58288bb9e32c0c7fe2052c33101e9 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 28 Jun 2024 15:27:14 -0400 Subject: .pytool/Plugin: Improve plugin log messages Improves the CI output with more actionable messages and downgrades some errors/warnings. Signed-off-by: Michael Kubacki --- .pytool/Plugin/DependencyCheck/DependencyCheck.py | 4 ++-- .pytool/Plugin/SpellCheck/SpellCheck.py | 3 ++- .pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py | 16 +++++++--------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.pytool/Plugin/DependencyCheck/DependencyCheck.py b/.pytool/Plugin/DependencyCheck/DependencyCheck.py index 07c5682d95..30b0c0254f 100644 --- a/.pytool/Plugin/DependencyCheck/DependencyCheck.py +++ b/.pytool/Plugin/DependencyCheck/DependencyCheck.py @@ -108,8 +108,8 @@ class DependencyCheck(ICiBuildPlugin): if mod_specific_key in pkgconfig and p in pkgconfig[mod_specific_key]: continue - logging.error("Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}".format(file, p)) - tc.LogStdError("Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}".format(file, p)) + logging.error(f"Dependency Check: {file} depends on pkg {p} but pkg is not listed in AcceptableDependencies") + tc.LogStdError(f"Dependency Check: {file} depends on pkg {p} but pkg is not listed in AcceptableDependencies") overall_status += 1 # If XML object exists, add results diff --git a/.pytool/Plugin/SpellCheck/SpellCheck.py b/.pytool/Plugin/SpellCheck/SpellCheck.py index 8347fa9900..d5408479e7 100644 --- a/.pytool/Plugin/SpellCheck/SpellCheck.py +++ b/.pytool/Plugin/SpellCheck/SpellCheck.py @@ -186,13 +186,14 @@ class SpellCheck(ICiBuildPlugin): # Helper - Log the syntax needed to add these words to dictionary if len(EasyFix) > 0: EasyFix = sorted(set(a.lower() for a in EasyFix)) + logging.error(f'SpellCheck found {len(EasyFix)} failing words. See CI log for details.') tc.LogStdOut("\n Easy fix:") OneString = "If these are not errors add this to your ci.yaml file.\n" OneString += '"SpellCheck": {\n "ExtendWords": [' for a in EasyFix: tc.LogStdOut(f'\n"{a}",') OneString += f'\n "{a}",' - logging.info(OneString.rstrip(",") + '\n ]\n}') + logging.critical(OneString.rstrip(",") + '\n ]\n}') # add result to test case overall_status = len(Errors) diff --git a/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py b/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py index 73dc03c0dc..2bdc3e2925 100644 --- a/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py +++ b/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py @@ -563,26 +563,26 @@ class UncrustifyCheck(ICiBuildPlugin): self._formatted_file_error_count = len(formatted_files) if self._formatted_file_error_count > 0: - logging.error( + logging.warning(f'Uncrustify found {self._formatted_file_error_count} files with formatting errors') + self._tc.LogStdError(f"Uncrustify found {self._formatted_file_error_count} files with formatting errors:\n") + logging.critical( "Visit the following instructions to learn " "how to find the detailed formatting errors in Azure " "DevOps CI: " "https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting#how-to-find-uncrustify-formatting-errors-in-continuous-integration-ci") - self._tc.LogStdError("Files with formatting errors:\n") if self._output_file_diffs: logging.info("Calculating file diffs. This might take a while...") for formatted_file in formatted_files: - pre_formatted_file = formatted_file[:- - len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)] - logging.error(pre_formatted_file) + pre_formatted_file = formatted_file[:-len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)] + + self._tc.LogStdError(f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n") + logging.info(f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}") if (self._output_file_diffs or self._file_template_contents is not None or self._func_template_contents is not None): - self._tc.LogStdError( - f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n") with open(formatted_file) as ff: formatted_file_text = ff.read() @@ -603,8 +603,6 @@ class UncrustifyCheck(ICiBuildPlugin): self._tc.LogStdError(line) self._tc.LogStdError('\n') - else: - self._tc.LogStdError(pre_formatted_file) def _remove_tree(self, dir_path: str, ignore_errors: bool = False) -> None: """ -- cgit From 489e4a60ea88326a07a7cee8086227c3df2bf93d Mon Sep 17 00:00:00 2001 From: Bret Barkelew Date: Fri, 19 Jan 2018 12:30:14 -0800 Subject: MdeModulePkg/SmiHandlerProfileInfo: Include profile SMI in profile Includes the profiler SMI in the profile itself for completeness. Co-authored-by: Michael Kubacki Signed-off-by: Michael Kubacki --- MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c index 27da2898dd..e48532c0fb 100644 --- a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c +++ b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c @@ -2,6 +2,7 @@ SMI handler profile support. Copyright (c) 2017, Intel Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -47,6 +48,14 @@ RegisterSmiHandlerProfileHandler ( VOID ); +/** + Build SMI handler profile database. +**/ +VOID +BuildSmiHandlerProfileDatabase ( + VOID + ); + /** Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded into system memory with the PE/COFF Loader Library functions. @@ -495,6 +504,8 @@ SmmReadyToLockInSmiHandlerProfile ( IN EFI_HANDLE Handle ) { + RegisterSmiHandlerProfileHandler (); + // // Dump all image // @@ -528,7 +539,7 @@ SmmReadyToLockInSmiHandlerProfile ( DEBUG ((DEBUG_INFO, "\n")); - RegisterSmiHandlerProfileHandler (); + BuildSmiHandlerProfileDatabase (); if (mImageStruct != NULL) { FreePool (mImageStruct); @@ -860,7 +871,7 @@ GetSmiHandlerProfileDatabaseData ( } /** - build SMI handler profile database. + Build SMI handler profile database. **/ VOID BuildSmiHandlerProfileDatabase ( @@ -1074,8 +1085,6 @@ RegisterSmiHandlerProfileHandler ( &DispatchHandle ); ASSERT_EFI_ERROR (Status); - - BuildSmiHandlerProfileDatabase (); } /** -- cgit From 734aaff8625760fb5d38024168a5f8696b14fd10 Mon Sep 17 00:00:00 2001 From: Bret Barkelew Date: Wed, 21 Apr 2021 13:24:31 -0700 Subject: ArmPlatformPkg: Update LcdHwNullLib to prevent init Library previously returned EFI_SUCCESS which causes the platform to continue initializing LCD HW. Should return EFI_NOT_FOUND. Resolves TCBZ3351. Signed-off-by: Oliver Smith-Denny --- ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c b/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c index ca48871993..8044730512 100644 --- a/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c +++ b/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c @@ -23,7 +23,7 @@ LcdIdentify ( VOID ) { - return EFI_SUCCESS; + return EFI_NOT_FOUND; } /** -- cgit From 469f29fe7647c6dc8975a3c03ea7e181270d44d3 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 19 Jul 2024 19:29:33 -0400 Subject: MdeModulePkg/VariablePolicyLib: Use wildcard character constant Makes the `#` character used for comparison against wildcard characters in `CHAR16` strings to be prefixed with `L` so the character is treated as a wide character constant. Signed-off-by: Michael Kubacki --- MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c index 768662829d..053b48d90e 100644 --- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c @@ -178,7 +178,7 @@ IsValidVariablePolicyStructure ( WildcardCount = 0; while (*CheckChar != CHAR_NULL) { // Make sure there aren't excessive wildcards. - if (*CheckChar == '#') { + if (*CheckChar == L'#') { WildcardCount++; if (WildcardCount > MATCH_PRIORITY_MIN) { return FALSE; @@ -263,7 +263,7 @@ EvaluatePolicyMatch ( // Keep going until the end of both strings. while (PolicyName[Index] != CHAR_NULL || VariableName[Index] != CHAR_NULL) { // If we don't have a match... - if ((PolicyName[Index] != VariableName[Index]) || (PolicyName[Index] == '#')) { + if ((PolicyName[Index] != VariableName[Index]) || (PolicyName[Index] == L'#')) { // If this is a numerical wildcard, we can consider // it a match if we alter the priority. if ((PolicyName[Index] == L'#') && -- cgit From 8984fba2f22a2cd44e1189403e3553f447b82852 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Wed, 3 Jul 2024 14:39:16 -0700 Subject: EmbeddedPkg: Mark DMA Memory Allocations XP By Default When allocating memory for a non-coherent DMA device, the current core code removes the XP attribute, allowing code to execute from that region. This is a security vulnerability and unneeded. This change updates to mark the region as XP when allocating memory for the non-coherent DMA device. Signed-off-by: Oliver Smith-Denny --- EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c index e193352fbe..0a21d72290 100644 --- a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c +++ b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c @@ -553,11 +553,11 @@ DmaAllocateAlignedBuffer ( InsertHeadList (&UncachedAllocationList, &Alloc->Link); - // Remap the region with the new attributes + // Remap the region with the new attributes and mark it non-executable Status = gDS->SetMemorySpaceAttributes ( (PHYSICAL_ADDRESS)(UINTN)Allocation, EFI_PAGES_TO_SIZE (Pages), - MemType + MemType | EFI_MEMORY_XP ); if (EFI_ERROR (Status)) { goto FreeAlloc; -- cgit From c5582e435c2ed7faa5bee46b5c7a5d04b8edfeaa Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 28 Jul 2023 13:19:41 -0400 Subject: ArmVirtPkg: QemuVirtMemInfoPeiLib: Allow Dynamic PcdSystemMemorySize Platforms today may use this PCD as a dynamic PCD as that is an allowed type in its PCD declaration. From `ArmPkg.dec`: [PcdsFixedAtBuild.common, PcdsDynamic.common, PcdsPatchableInModule.common] gArmTokenSpaceGuid.PcdSystemMemorySize|0|UINT64|0x0000002A This library causes a build error if it used as a dynamic PCD since it places the PCD in a `[FixedPcd]` section in the INF. Other libraries do set the PCD and depend on the dynamic PCD behavior. Since this library accesses the PCD with `PcdGet64 ()` which is compatible with FixedAtBuild PCDs, this change moves the PCD out an explicit `[FixedPcd]` section to resolve the following build error: ``` INFO - : error 3000: Building modules from source INFs, following PCD use Dynamic and FixedAtBuild access method. It must be corrected to use only one access method. INFO - gArmTokenSpaceGuid.PcdSystemMemorySize ``` Signed-off-by: Oliver Smith-Denny --- ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf index 76c3c5d3c8..da957cfaff 100644 --- a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf +++ b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf @@ -38,11 +38,13 @@ [Guids] gArmVirtSystemMemorySizeGuid +[Pcd] + gArmTokenSpaceGuid.PcdSystemMemorySize + [FixedPcd] gArmTokenSpaceGuid.PcdFdBaseAddress gArmTokenSpaceGuid.PcdFvBaseAddress gArmTokenSpaceGuid.PcdSystemMemoryBase - gArmTokenSpaceGuid.PcdSystemMemorySize gArmTokenSpaceGuid.PcdFdSize gArmTokenSpaceGuid.PcdFvSize gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress -- cgit From 37287bf9add9edbfbc0dac9a66f8f2a3112e3ce8 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 19 Jul 2024 12:33:49 -0700 Subject: ArmPkg: CpuDxe: Add Memory Attribute Protocol Logging The memory attribute protocol is primarily used by bootloaders and there are many released bootloaders who use the protocol incorrectly. It is challenging to debug these situations because the bootloaders are generally black boxes and we silently fail on the FW side. This patch adds logging to some common memory attribute protocol failures in CpuDxe. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Drivers/CpuDxe/MemoryAttribute.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c index 16cc4ef474..c77feb848c 100644 --- a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c +++ b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c @@ -82,6 +82,13 @@ GetMemoryAttributes ( EFI_STATUS Status; if ((Length == 0) || (Attributes == NULL)) { + DEBUG (( + DEBUG_ERROR, + "%a: BaseAddress 0x%llx Length 0x%llx is zero or Attributes is NULL\n", + __func__, + BaseAddress, + Length + )); return EFI_INVALID_PARAMETER; } @@ -195,6 +202,13 @@ SetMemoryAttributes ( if ((Length == 0) || ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0)) { + DEBUG (( + DEBUG_ERROR, + "%a: BaseAddress 0x%llx Length is zero or Attributes (0x%llx) is invalid\n", + __func__, + BaseAddress, + Attributes + )); return EFI_INVALID_PARAMETER; } @@ -256,6 +270,13 @@ ClearMemoryAttributes ( if ((Length == 0) || ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0)) { + DEBUG (( + DEBUG_ERROR, + "%a: BaseAddress 0x%llx Length is zero or Attributes (0x%llx) is invalid\n", + __func__, + BaseAddress, + Attributes + )); return EFI_INVALID_PARAMETER; } -- cgit From 74833ca459577307da02c3d74a9e65fb3d3161c2 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 19 Jul 2024 12:37:36 -0700 Subject: ArmPkg: ArmMmuLib: Add ARM32 Memory Attribute Update Failure Logging This adds logging in failure cases of SetMemoryAttributes. This is useful generally as if an attribute update fails, code will typically break, but is added in particular to make debugging incorrect bootloader usage of the Memory Attribute Protocol. This patch updates the ARM32 SetMemoryAttributes. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c index 5e751cddd7..b8b8a7016d 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c @@ -377,6 +377,13 @@ SetMemoryAttributes ( BOOLEAN FlushTlbs; if (BaseAddress > (UINT64)MAX_ADDRESS) { + DEBUG (( + DEBUG_ERROR, + "%a BaseAddress: 0x%llx is greater than MAX_ADDRESS: 0x%llx, fail to apply attributes!\n", + __func__, + BaseAddress, + (UINT64)MAX_ADDRESS + )); return EFI_UNSUPPORTED; } @@ -437,6 +444,14 @@ SetMemoryAttributes ( } if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a failed to update attributes with status %r for BaseAddress 0x%llx of length 0x%llx\n", + __func__, + Status, + BaseAddress, + ChunkLength + )); break; } -- cgit From e10de1cb0345e54c0b4d83f5979a76111d10d6c7 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 19 Jul 2024 12:40:18 -0700 Subject: ArmPkg: ArmMmuLib: Add AARCH64 Memory Attribute Update Failure Log This adds logging in failure cases of SetMemoryAttributes. This is useful generally as if an attribute update fails, code will typically break, but is added in particular to make debugging incorrect bootloader usage of the Memory Attribute Protocol. This patch updates the AARCH64 UpdateRegionMapping. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 6a1f3f9477..b83373d4b5 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -382,6 +382,13 @@ UpdateRegionMapping ( UINTN T0SZ; if (((RegionStart | RegionLength) & EFI_PAGE_MASK) != 0) { + DEBUG (( + DEBUG_ERROR, + "%a RegionStart: 0x%llx or RegionLength: 0x%llx are not page aligned!\n", + __func__, + RegionStart, + RegionLength + )); return EFI_INVALID_PARAMETER; } -- cgit From 1b8ca81133f1860a08d6e5477ab8d2fdf4b23b1e Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 19 Jul 2024 15:50:48 -0700 Subject: ArmVirtPkg: KvmtoolRtcFdtClientLib: Set MMIO Memory NX When setting memory attributes on its MMIO region, KvmtoolRtcFdtClientLib will clear EFI_MEMORY_XP from the region if a platform has it set. This MMIO region is not intended to be executed from, so fix this by explicitly setting EFI_MEMORY_XP on this region in the lib. Signed-off-by: Oliver Smith-Denny --- ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c b/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c index e8d3576a71..2afb56ccf8 100644 --- a/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c +++ b/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c @@ -44,7 +44,7 @@ KvmtoolRtcMapMemory ( EfiGcdMemoryTypeMemoryMappedIo, RtcPageBase, EFI_PAGE_SIZE, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP ); if (EFI_ERROR (Status)) { DEBUG (( @@ -80,7 +80,7 @@ KvmtoolRtcMapMemory ( Status = gDS->SetMemorySpaceAttributes ( RtcPageBase, EFI_PAGE_SIZE, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP ); if (EFI_ERROR (Status)) { DEBUG (( -- cgit From c5ab17430b2579dd79e3cbd497b8b9deccd34abc Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 19 Jul 2024 15:52:21 -0700 Subject: ArmPlatformPkg: PL031RealTimeClockLib: Set MMIO Memory XP PL031RealTimeClockLib will clear EFI_MEMORY_XP if a platform has set it for MMIO memory when it does not include that bit in its SetMemoryAttributes call. This region is not intended to be executed from and as such the lib should explicitly set EFI_MEMORY_XP to this region. Signed-off-by: Oliver Smith-Denny --- ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c index 6ab3e99483..fb353cf2df 100644 --- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c +++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c @@ -331,13 +331,13 @@ LibRtcInitialize ( EfiGcdMemoryTypeMemoryMappedIo, mPL031RtcBase, SIZE_4KB, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP ); if (EFI_ERROR (Status)) { return Status; } - Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); + Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP); if (EFI_ERROR (Status)) { return Status; } -- cgit From 46eb0ca29bf6bd84381af8506e0d9b1755f767d9 Mon Sep 17 00:00:00 2001 From: Shenbagadevi R Date: Thu, 2 May 2024 15:39:19 +0530 Subject: ShellPkg: Changes to print Type17 in Smbiosview Add changes to print PMIC and RCD details of Smbios Type17 in Shell smbiosview command. Cc: Gaoliming Cc: Sainadh N Cc: Sundaresan S Cc: Srinivasan M Cc: Ramesh R Cc: Karthika R Signed-off-by: Shenbagadevi R Reviewed-by: Giri Mudusuru --- ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c index 35369f0183..e5a742950d 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c @@ -903,6 +903,13 @@ SmbiosPrintStructure ( ShellPrintEx (-1, -1, L"Extended Configured Memory Speed: 0x%x\n", Struct->Type17->ExtendedConfiguredMemorySpeed); } + if (AE_SMBIOS_VERSION (0x3, 0x7) && (Struct->Hdr->Length > 0x5C)) { + ShellPrintEx (-1, -1, L"PMIC0 Manufacturer ID: 0x%x\n", Struct->Type17->Pmic0ManufacturerID); + ShellPrintEx (-1, -1, L"PMIC0 Revision Number: 0x%x\n", Struct->Type17->Pmic0RevisionNumber); + ShellPrintEx (-1, -1, L"RCD Manufacturer ID: 0x%x\n", Struct->Type17->RcdManufacturerID); + ShellPrintEx (-1, -1, L"RCD Revision Number: 0x%x\n", Struct->Type17->RcdRevisionNumber); + } + break; // -- cgit From 32e7f9aa6cdfe406034e2ce3f8714a968dae3a7c Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 22 Jul 2024 16:02:59 +0800 Subject: UefiCpuPkg: Revert "UefiCpuPkg/PiSmmCpuDxeSmm:Map SMRAM in 4K..." This reverts commit ae59b8ba4166384cbfa32a921aac289bcff2aef9. The commit ae59b8ba41 was added to modify the GenSmmPageTable() to map SMRAM in 4K page granularity. It was to urgently fix a smm hang issue by avoiding page split in paging structures that covers SMRAM range when SMI happens. But finally the smm hang issue was root caused and fixed by commit 839bd17973. Meanwhile a smm page table creation related issue was introduced by commit ae59b8ba41: In the function GenSmmPageTable(), the paging level for the range outside SMRAM is depend on the Input parameter PagingMode. However, the paging level for SMRAM range is depend on m5LevelPagingNeeded. If the two paging levels are different, then the smm page table is created incorrectly. So let's revert the commit "UefiCpuPkg/PiSmmCpuDxeSmm:Map SMRAM in 4K page granularity" Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 114 +++++---------------- 1 file changed, 24 insertions(+), 90 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index b8c356bfe8..6e0c251397 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -1647,115 +1647,49 @@ EdkiiSmmClearMemoryAttributes ( } /** - Create page table based on input PagingMode, LinearAddress and Length. + Create page table based on input PagingMode and PhysicalAddressBits in smm. + + @param[in] PagingMode The paging mode. + @param[in] PhysicalAddressBits The bits of physical address to map. - @param[in, out] PageTable The pointer to the page table. - @param[in] PagingMode The paging mode. - @param[in] LinearAddress The start of the linear address range. - @param[in] Length The length of the linear address range. + @retval PageTable Address **/ -VOID -GenPageTable ( - IN OUT UINTN *PageTable, - IN PAGING_MODE PagingMode, - IN UINT64 LinearAddress, - IN UINT64 Length +UINTN +GenSmmPageTable ( + IN PAGING_MODE PagingMode, + IN UINT8 PhysicalAddressBits ) { - RETURN_STATUS Status; UINTN PageTableBufferSize; + UINTN PageTable; VOID *PageTableBuffer; IA32_MAP_ATTRIBUTE MapAttribute; IA32_MAP_ATTRIBUTE MapMask; + RETURN_STATUS Status; + UINTN GuardPage; + UINTN Index; + UINT64 Length; + Length = LShiftU64 (1, PhysicalAddressBits); + PageTable = 0; + PageTableBufferSize = 0; MapMask.Uint64 = MAX_UINT64; - MapAttribute.Uint64 = mAddressEncMask|LinearAddress; + MapAttribute.Uint64 = mAddressEncMask; MapAttribute.Bits.Present = 1; MapAttribute.Bits.ReadWrite = 1; MapAttribute.Bits.UserSupervisor = 1; MapAttribute.Bits.Accessed = 1; MapAttribute.Bits.Dirty = 1; - PageTableBufferSize = 0; - - Status = PageTableMap ( - PageTable, - PagingMode, - NULL, - &PageTableBufferSize, - LinearAddress, - Length, - &MapAttribute, - &MapMask, - NULL - ); - if (Status == RETURN_BUFFER_TOO_SMALL) { - DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize)); - PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize)); - ASSERT (PageTableBuffer != NULL); - Status = PageTableMap ( - PageTable, - PagingMode, - PageTableBuffer, - &PageTableBufferSize, - LinearAddress, - Length, - &MapAttribute, - &MapMask, - NULL - ); - } + Status = PageTableMap (&PageTable, PagingMode, NULL, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL); + ASSERT (Status == RETURN_BUFFER_TOO_SMALL); + DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize)); + PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize)); + ASSERT (PageTableBuffer != NULL); + Status = PageTableMap (&PageTable, PagingMode, PageTableBuffer, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL); ASSERT (Status == RETURN_SUCCESS); ASSERT (PageTableBufferSize == 0); -} - -/** - Create page table based on input PagingMode and PhysicalAddressBits in smm. - - @param[in] PagingMode The paging mode. - @param[in] PhysicalAddressBits The bits of physical address to map. - - @retval PageTable Address - -**/ -UINTN -GenSmmPageTable ( - IN PAGING_MODE PagingMode, - IN UINT8 PhysicalAddressBits - ) -{ - UINTN PageTable; - RETURN_STATUS Status; - UINTN GuardPage; - UINTN Index; - UINT64 Length; - PAGING_MODE SmramPagingMode; - - PageTable = 0; - Length = LShiftU64 (1, PhysicalAddressBits); - ASSERT (Length > mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize); - - if (sizeof (UINTN) == sizeof (UINT64)) { - SmramPagingMode = m5LevelPagingNeeded ? Paging5Level4KB : Paging4Level4KB; - } else { - SmramPagingMode = PagingPae4KB; - } - - ASSERT (mCpuHotPlugData.SmrrBase % SIZE_4KB == 0); - ASSERT (mCpuHotPlugData.SmrrSize % SIZE_4KB == 0); - GenPageTable (&PageTable, PagingMode, 0, mCpuHotPlugData.SmrrBase); - - // - // Map smram range in 4K page granularity to avoid subsequent page split when smm ready to lock. - // If BSP are splitting the 1G/2M paging entries to 512 2M/4K paging entries, and all APs are - // still running in SMI at the same time, which might access the affected linear-address range - // between the time of modification and the time of invalidation access. That will be a potential - // problem leading exception happen. - // - GenPageTable (&PageTable, SmramPagingMode, mCpuHotPlugData.SmrrBase, mCpuHotPlugData.SmrrSize); - - GenPageTable (&PageTable, PagingMode, mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize, Length - mCpuHotPlugData.SmrrBase - mCpuHotPlugData.SmrrSize); if (FeaturePcdGet (PcdCpuSmmStackGuard)) { // -- cgit From f96298d75cebfe2a7707157ed644eb86bf6d46ca Mon Sep 17 00:00:00 2001 From: "levi.yun" Date: Wed, 5 Jun 2024 13:03:47 +0100 Subject: ShellPkg/Acpiview: Add HEST Parser Add a new pareser for the Hardware Error Source Table (HEST). The HEST table is used to describe a system's hardware error sources to OSPM. Cc: Zhichao Gao Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: levi.yun --- .../UefiShellAcpiViewCommandLib/AcpiParser.h | 21 + .../Parsers/Hest/HestParser.c | 958 +++++++++++++++++++++ .../UefiShellAcpiViewCommandLib.c | 1 + .../UefiShellAcpiViewCommandLib.inf | 3 +- 4 files changed, 982 insertions(+), 1 deletion(-) create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index b41f110f6a..b449ded0d1 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -725,6 +725,27 @@ ParseAcpiGtdt ( IN UINT8 AcpiTableRevision ); +/** + This function parses the ACPI HEST table. + When trace is enabled this function parses the HEST table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiHest ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + /** This function parses the ACPI HMAT table. When trace is enabled this function parses the HMAT table and diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c new file mode 100644 index 0000000000..963163448f --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c @@ -0,0 +1,958 @@ +/** @file + HEST table parser + + Copyright (c) 2024, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - ACPI 6.5, Table 18.3.2 ACPI Error Source +**/ + +#include +#include + +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" + +STATIC ACPI_DESCRIPTION_HEADER_INFO mAcpiHdrInfo; +STATIC UINT32 *mHestErrorSourceCount; +STATIC UINT16 *mHestErrorSourceType; +STATIC UINT8 *mHestIA32HardwareBankCount; + +/** + An String array for Error Notification Structure's type. + Cf ACPI 6.5 Table 18.14: Hardware Error Notification Structure +**/ +STATIC CONST CHAR16 *HestErrorNotificationStructureTypeStr[] = { + L"Polled", + L"External Interrupt", + L"Local Interrupt", + L"SCI", + L"NMI", + L"CMCI", + L"MCE", + L"GPIO-Signal", + L"ARMv8 SEA", + L"ARMv8 SEI", + L"External Interrupt - GSIV", + L"Software Delegated Exception", +}; + +/** + An ACPI_PARSER array describing the ACPI HEST Table. +**/ +STATIC CONST ACPI_PARSER HestParser[] = { + PARSE_ACPI_HEADER (&mAcpiHdrInfo), + { L"Error Source Count", 4, 36, L"%d", NULL, + (VOID **)&mHestErrorSourceCount,NULL, NULL }, + // Error Source Descriptor 1 + // Error Source Descriptor Type + // Error Source Descriptor Data + // ... + // Error Source Descriptor 2 + // Error Source Descriptor Type + // Error Source Descriptor Data + // ... + // .... + // Error Source Descriptor n + // Error Source Descriptor Type + // Error Source Descriptor Data + // ... +}; + +/** + An ACPI_PARSER array describing the HEST error source descriptor type. +**/ +STATIC CONST ACPI_PARSER HestErrorSourceTypeParser[] = { + { L"Type", 2, 0, L"%d", NULL, (VOID **)&mHestErrorSourceType, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the HEST error source flags information. +**/ +STATIC CONST ACPI_PARSER HestErrorSourceFlags[] = { + { L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Global", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"GHES Assist", 1, 2, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 5, 3, NULL, NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing IA-32 Architecture Machine Check Bank Structure + Cf ACPI 6.5 Table 18.4: IA-32 Architecture Machine Check Error Bank Structure +**/ +STATIC CONST ACPI_PARSER HestErrorIA32ArchMachineCheckBankStructureParser[] = { + { L"Bank Number", 1, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Clear Status On Initialization", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Status Data Format", 1, 2, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 3, NULL, NULL, NULL, NULL, NULL }, + { L"Control Register MSR Address", 4, 4, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Control Init Data", 8, 8, L"0x%llx", NULL, NULL, NULL, NULL }, + { L"Status Register MSR Address", 4, 16, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Address Register MSR Address", 4, 20, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Misc Register MSR Address", 4, 24, L"0x%lx", NULL, NULL, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the Hardware Error Notification Structure's + Configuration Write Enable Field (CWE) + Cf ACPI 6.5 Table 18.14: Hardware Error Notification Structure +**/ +STATIC CONST ACPI_PARSER HestErrorNotificationCweParser[] = { + { L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Poll Interval", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Switch To Polling Threshold Value", 1, 2, L"%d", NULL, NULL, NULL, NULL }, + { L"Switch To Polling Threshold Window", 1, 3, L"%d", NULL, NULL, NULL, NULL }, + { L"Error Threshold Value", 1, 4, L"%d", NULL, NULL, NULL, NULL }, + { L"Error Threshold Window", 1, 5, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 10, 6, L"0x%x", NULL, NULL, NULL, NULL }, +}; + +/** + This function validates the Type field of Hardware Error Notification Structure + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateErrorNotificationType ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 Type; + + Type = *(UINT8 *)Ptr; + + if (Type > + EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION) + { + IncrementErrorCount (); + Print ( + L"\nERROR: Notification Structure Type must be <= 0x%x.", + EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION + ); + } +} + +/** + Dumps flags fields of error source descriptor. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpSourceFlags ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%x\n", *Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 1, + PARSER_PARAMS (HestErrorSourceFlags) + ); +} + +/** + Dumps type fields of Error Notification Structure + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpErrorNotificationType ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *Ptr); + return; + } + + if (*Ptr <= EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION) { + Print (L"%s(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]); + } else { + Print (L"UNKNOWN(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]); + } +} + +/** + Dumps Configuration Write Enable fields of Hardware Error Notification Structure. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpErrorNotificationCwe ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%x\n", *Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 1, + PARSER_PARAMS (HestErrorNotificationCweParser) + ); +} + +/** + An ACPI_PARSER array describing the Hardware Error Notification Structure + Cf ACPI 6.5 Table 18.14: Hardware Error Notification Structure +**/ +STATIC CONST ACPI_PARSER HestErrorNotificationParser[] = { + { L"Type", 1, 0, NULL, DumpErrorNotificationType, NULL, ValidateErrorNotificationType, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Configuration Write Enable", 2, 2, NULL, DumpErrorNotificationCwe, NULL, NULL, NULL }, + { L"Pull Interval", 4, 4, L"%d ms", NULL, NULL, NULL, NULL }, + { L"Vector", 4, 8, L"%d", NULL, NULL, NULL, NULL }, + { L"Switch To Polling Threshold Value", 4, 12, L"%d", NULL, NULL, NULL, NULL }, + { L"Switch To Polling Threshold Window", 4, 16, L"%d ms", NULL, NULL, NULL, NULL }, + { L"Error Threshold Value", 4, 20, L"%d", NULL, NULL, NULL, NULL }, + { L"Error Threshold Window", 4, 24, L"%d ms", NULL, NULL, NULL, NULL }, +}; + +/** + This function validates reserved bits of + pci related Error source structure's bus field. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidatePciBusReservedBits ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*Ptr != 0x00) { + IncrementErrorCount (); + Print (L"\nERROR: bits[31:24] should must be zero..."); + } +} + +/** + An ACPI_PARSER array describing the PCI related Error Source Bus field. +**/ +STATIC CONST ACPI_PARSER HestErrorSourcePciCommonBusParser[] = { + { L"Bus", 8, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Segment Number", 16, 8, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 8, 24, L"0x%x", NULL, NULL, ValidatePciBusReservedBits, NULL }, +}; + +/** + This function validates the flags field of IA32 related + error source descriptor structure. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateIA32ErrorSourceFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 SourceFlags; + + SourceFlags = *(UINT8 *)Ptr; + + if ((SourceFlags & + ~(EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST | + EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GHES_ASSIST)) != 0) + { + IncrementErrorCount (); + Print (L"\nERROR: Invalid IA32 source flags field value..."); + } + + if (((SourceFlags & EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST) != 0) && + ((SourceFlags & EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GHES_ASSIST) != 0)) + { + IncrementErrorCount (); + Print (L"\nERROR: GHES_ASSIST should be reserved if FIRMWARE_FIRST is set..."); + } +} + +/** + This function validates the flags field of PCI related + error source descriptor structure. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidatePciErrorSourceFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 SourceFlags; + + SourceFlags = *(UINT8 *)Ptr; + + if ((SourceFlags & + ~(EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST | + EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GLOBAL)) != 0) + { + IncrementErrorCount (); + Print (L"\nERROR: Invalid PCI source flags field value..."); + } +} + +/** + This function validates the flags field of Ghes related + error source descriptor structure. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateGhesSourceFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 SourceFlags; + + SourceFlags = *(UINT8 *)Ptr; + + if (SourceFlags != 0) { + IncrementErrorCount (); + Print (L"\nERROR: Ghes'source flags should be reserved..."); + } +} + +/** + This function validates the enabled field of error source descriptor + structure. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateEnabledField ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*(UINT8 *)Ptr > 1) { + IncrementErrorCount (); + Print (L"\nERROR: Invalid Enabled field value must be either 0 or 1."); + } +} + +/** + This function validates the number of records to preallocated and + max sections per record fields of error source descriptor + structure. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateRecordCount ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 RecordCount; + BOOLEAN CheckRecordCount; + + RecordCount = *Ptr; + CheckRecordCount = ((BOOLEAN)(UINTN)Context); + + if ((CheckRecordCount) && (RecordCount == 0)) { + IncrementErrorCount (); + Print (L"\nERROR: Record count must be >= 1..."); + } +} + +/** + Dumps the notification structure fields. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpNotificationStructure ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + UINT32 Offset; + UINT32 Size; + + Size = sizeof (EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE); + Print (L"\n"); + Offset = ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + Size, + PARSER_PARAMS (HestErrorNotificationParser) + ); + if (Offset != Size) { + IncrementErrorCount (); + Print (L"ERROR: Failed to parse Hardware Error Notification Structure!\n"); + } +} + +/** + Dumps bus field in the PCI related Error Source Structure. + from HestTable. + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpPciBus ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%x\n", *Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 1, + PARSER_PARAMS (HestErrorSourcePciCommonBusParser) + ); +} + +/** + Dumps the IA32 Arch Machine Check Error Bank structure fields. + + @param [in] HestTable Start pointer to Hest table. + @param [in] AcpiTableLength Length of HestTable. + @param [in,out] Offset Offset to machine check bank structure + from HestTable. + + @retval EFI_SUCCESS Success + @retval EFI_INVALID_PARAMETER Invalid Hest Table +**/ +STATIC +EFI_STATUS +EFIAPI +DumpIA32ArchMachineCheckErrorBankStructure ( + IN UINT8 *HestTable, + UINT32 AcpiTableLength, + UINT32 *Offset + ) +{ + UINT8 Idx; + UINT8 *IA32BankStructPtr; + UINT32 TotalBankStructSize; + + TotalBankStructSize = *mHestIA32HardwareBankCount * + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE); + + if ((*Offset + TotalBankStructSize) > AcpiTableLength) { + IncrementErrorCount (); + Print ( + L"ERROR: Not enough data for " + "IA-32 Architecture Machine Check Exception Error source.\n" + ); + return EFI_INVALID_PARAMETER; + } + + for (Idx = 0; Idx < *mHestIA32HardwareBankCount; Idx++) { + IA32BankStructPtr = HestTable + *Offset; + ParseAcpi ( + TRUE, + 4, + "IA-32 Architecture Machine Check Bank Structure", + IA32BankStructPtr, + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE), + PARSER_PARAMS (HestErrorIA32ArchMachineCheckBankStructureParser) + ); + *Offset += + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE); + } + + *mHestIA32HardwareBankCount = 0; + + return EFI_SUCCESS; +} + +/** + Helper macro to populate the header fields of error source descriptor in the + ACPI_PARSER array. +**/ +#define PARSE_HEST_ERROR_SOURCE_COMMON_HEADER(FlagsValidateFunc, CheckRecordCount) \ + { L"Type", 2, 0, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Source Id", 2, 2, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Reserved", 2, 4, NULL, NULL, NULL, NULL, NULL }, \ + { L"Flags", 1, 6, NULL, DumpSourceFlags, NULL, \ + FlagsValidateFunc, NULL }, \ + { L"Enabled", 1, 7, L"%d", NULL, NULL, ValidateEnabledField, NULL }, \ + { L"Number of Records to Pre-allocate", 4, 8, L"%d", NULL, NULL, \ + ValidateRecordCount, (VOID *) ((UINTN) CheckRecordCount) }, \ + { L"Max Sections Per Record", 4, 12, L"%d", NULL, NULL, \ + ValidateRecordCount, (VOID *) ((UINTN) CheckRecordCount) } + +/** + Helper macro to populate the header fields of PCI related + error source descriptor in the ACPI_PARSER array. +**/ +#define PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER() \ + PARSE_HEST_ERROR_SOURCE_COMMON_HEADER(ValidatePciErrorSourceFlags, TRUE), \ + { L"Bus", 4, 16, NULL, DumpPciBus, NULL, NULL, NULL }, \ + { L"Device", 2, 20, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Function", 2, 22, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Device Control", 2, 24, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Reserved", 2, 26, NULL, NULL, NULL, NULL, NULL }, \ + { L"Uncorrectable Error Mask", 4, 28, L"0x%lx", NULL, NULL, NULL, NULL }, \ + { L"Uncorrectable Error Severity", 4, 32, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Correctable Error Mask", 4, 36, L"0x%lx", NULL, NULL, NULL, NULL }, \ + { L"Advanced Error Capabilities and Control", 4, 40, L"%d", NULL, NULL, \ + NULL, NULL } + +/** + Helper macro to populate the header fields of GHES related + error source descriptor in the ACPI_PARSER array. +**/ +#define PARSE_HEST_GHES_ERROR_SOURCE() \ + { L"Type", 2, 0, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Source Id", 2, 2, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Related Source Id", 2, 4, L"0x%x", NULL, NULL, NULL, NULL }, \ + { L"Flags", 1, 6, L"0x%x", NULL, NULL, ValidateGhesSourceFlags, NULL }, \ + { L"Enabled", 1, 7, L"%d", NULL, NULL, ValidateEnabledField, NULL }, \ + { L"Number of Records to Pre-allocate", 4, 8, L"%d", NULL, NULL, \ + ValidateRecordCount, (VOID *) ((UINTN) TRUE) }, \ + { L"Max Sections Per Record", 4, 12, L"%d", NULL, NULL, \ + ValidateRecordCount, (VOID *) ((UINTN) TRUE) }, \ + { L"Max Raw Data Length", 4, 16, L"%d", NULL, NULL, NULL, NULL }, \ + { L"Error Status Address", 12, 20, NULL, DumpGas, NULL, NULL, NULL }, \ + { L"Notification Structure", 28, 32, NULL, DumpNotificationStructure, \ + NULL, NULL, NULL }, \ + { L"Error Status Block Length", 4, 60, L"%d", NULL, NULL, NULL, NULL } + +/** + An ACPI_PARSER array describing the IA-32 Architecture Machine Check Exception + error source descriptor. + Cf ACPI 6.5 Table 18.3: IA-32 Architecture Machine Check Exception Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchMachineCheckExceptionParser[] = { + PARSE_HEST_ERROR_SOURCE_COMMON_HEADER (ValidateIA32ErrorSourceFlags, FALSE), + { L"Global Capability Init Data", + 8, 16, L"0x%llx", NULL, NULL, NULL, NULL }, + { L"Global Control Init Data", + 8, 24, L"0x%llx", NULL, NULL, NULL, NULL }, + { L"Number of Hardware Banks", + 1, 32, L"%d", NULL, (VOID **)&mHestIA32HardwareBankCount, NULL, NULL }, + { L"Reserved", + 7, 33, NULL, NULL, NULL, NULL, NULL }, + /// HestErrorIA32ArchMachineCheckBankStructureParser + /// ... +}; + +/** + An ACPI_PARSER array describing the IA-32 Architecture Machine Check Exception + error source descriptor. + Cf ACPI 6.5 Table 18.5: IA-32 Architecture Machine Check Exception Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchCorrectedMachineCheckParser[] = { + PARSE_HEST_ERROR_SOURCE_COMMON_HEADER (ValidateIA32ErrorSourceFlags, TRUE), + { L"Notification Structure", + 28, 16, NULL, DumpNotificationStructure, NULL, NULL, NULL }, + { L"Number of Hardware Banks", + 1, 44, L"%d", NULL, (VOID **)&mHestIA32HardwareBankCount, NULL, NULL }, + { L"Reserved", + 3, 45, NULL, NULL, NULL, NULL, NULL }, + /// HestErrorIA32ArchMachineCheckBankStructureParser + /// ... +}; + +/** + An ACPI_PARSER array describing the IA-32 Non-Maskable Interrupt + error source descriptor. + Cf ACPI 6.5 Table 18.6: IA-32 Architecture NMI Error Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchNonMaskableInterruptParser[] = { + { L"Type", 2, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Source Id", 2, 2, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 4, NULL, NULL, NULL, NULL, NULL }, + { L"Number of Records to Pre-allocate", 4, 8, L"%d", NULL, NULL, + ValidateRecordCount, (VOID *)((UINTN)TRUE) }, + { L"Max Sections Per Record", 4, 12, L"%d", NULL, NULL, + ValidateRecordCount, (VOID *)((UINTN)TRUE) }, + { L"Max Raw Data Length", 4, 16, L"%d", NULL, NULL, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the HEST PCIe Root Port AER + error source descriptor. + Cf ACPI 6.5 Table 18.7: PCI Express Root Port AER Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourcePciExpressRootPortAerParser[] = { + PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER (), + { L"Root Error Command", + 4, 44,L"%d", NULL, NULL, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the HEST PCIe Device AER + error source descriptor. + Cf ACPI 6.5 Table 18.8: PCI Express Device AER Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourcePciExpressDeviceAerParser[] = { + PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER (), +}; + +/** + An ACPI_PARSER array describing the HEST PCIe/PCI-X Bridge AER + error source descriptor. + Cf ACPI 6.5 Table 18.9: PCI Express/PCI-X Bridge AER Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourcePciExpressBridgeAerParser[] = { + PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER (), + { L"Secondary Uncorrectable Error Mask", + 4, 44, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Secondary Uncorrectable Error Severity", + 4, 48, L"%d", NULL, NULL, NULL, NULL }, + { L"Secondary Advanced Error Capabilities and Control", + 4, 52, L"%d", NULL, NULL, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the HEST GHES error source descriptor. + Cf ACPI 6.5 Table 18.10: Generic Hardware Error Source Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourceGhesParser[] = { + PARSE_HEST_GHES_ERROR_SOURCE (), +}; + +/** + An ACPI_PARSER array describing the HEST GHESv2 error source descriptor. + Cf ACPI 6.5 Table 18.11: Generic Hardware Error Source version 2 Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourceGhesv2Parser[] = { + PARSE_HEST_GHES_ERROR_SOURCE (), + { L"Read Ack Register", 12, 64, NULL, DumpGas, NULL, NULL, NULL }, + { L"Read Ack Preserve", 8, 76, L"%llx", NULL, NULL, NULL, NULL }, + { L"Read Ack Write", 8, 84, L"%llx", NULL, NULL, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the IA-32 Architecture Deferred Machine Check + error source descriptor. + Cf ACPI 6.5 Table 18.15: IA-32 Architecture Deferred Machine Check Structure +**/ +STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchDeferredMachineCheckParser[] = { + PARSE_HEST_ERROR_SOURCE_COMMON_HEADER (ValidateIA32ErrorSourceFlags, TRUE), + { L"Notification Structure", 28, 16, NULL, DumpNotificationStructure, + NULL, NULL, NULL }, + { L"Number of Hardware Banks", 1, 44, L"%d", NULL, + (VOID **)&mHestIA32HardwareBankCount, NULL, NULL }, + { L"Reserved", 3, 45, NULL, NULL, NULL,NULL, NULL }, + /// HestErrorIA32ArchMachineCheckBankStructureParser + /// ... +}; + +/** + This function parses the ACPI HEST table. + When trace is enabled this function parses the HEST table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiHest ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + EFI_STATUS Status; + UINT32 Offset; + UINT8 *ErrorSourcePtr; + UINT32 ParsedErrorSourceCount; + UINT32 CurErrorSourceType; + + if (Trace != TRUE) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "HEST", + Ptr, + AcpiTableLength, + PARSER_PARAMS (HestParser) + ); + + // Validate Error Source Descriptors Count. + if (mHestErrorSourceCount == NULL) { + IncrementErrorCount (); + Print (L"ERROR: Invalid Hardware Error Source Table Header...\n"); + return; + } + + ParsedErrorSourceCount = 0; + CurErrorSourceType = EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION; + + while ((Offset < AcpiTableLength) && (ParsedErrorSourceCount < *mHestErrorSourceCount)) { + ErrorSourcePtr = Ptr + Offset; + + // Get Type of Error Source Descriptor. + ParseAcpi ( + FALSE, + 0, + NULL, + ErrorSourcePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (HestErrorSourceTypeParser) + ); + + // Validate Error Source Descriptors Type. + if (mHestErrorSourceType == NULL) { + IncrementErrorCount (); + Print (L"ERROR: Invalid Error Source Structure...\n"); + return; + } + + if (CurErrorSourceType > *mHestErrorSourceType) { + IncrementErrorCount (); + Print (L"ERROR: Error Source Structure must be sorted in Type with ascending order...\n"); + return; + } + + switch (*mHestErrorSourceType) { + case EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION: + ParseAcpi ( + TRUE, + 2, + "IA-32 Architecture Machine Check Exception", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE), + PARSER_PARAMS (HestErrorSourceIA32ArchMachineCheckExceptionParser) + ); + + Offset += + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE); + + Status = DumpIA32ArchMachineCheckErrorBankStructure ( + Ptr, + AcpiTableLength, + &Offset + ); + if (EFI_ERROR (Status)) { + return; + } + + break; + case EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK: + ParseAcpi ( + TRUE, + 2, + "IA-32 Architecture Corrected Machine Check", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE), + PARSER_PARAMS (HestErrorSourceIA32ArchCorrectedMachineCheckParser) + ); + + Offset += + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE); + + Status = DumpIA32ArchMachineCheckErrorBankStructure ( + Ptr, + AcpiTableLength, + &Offset + ); + if (EFI_ERROR (Status)) { + return; + } + + break; + case EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR: + ParseAcpi ( + TRUE, + 2, + "IA-32 Architecture Non-Maskable Interrupt", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE), + PARSER_PARAMS (HestErrorSourceIA32ArchNonMaskableInterruptParser) + ); + + Offset += + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE); + break; + case EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER: + ParseAcpi ( + TRUE, + 2, + "PCI Express RootPort AER Structure", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE), + PARSER_PARAMS (HestErrorSourcePciExpressRootPortAerParser) + ); + + Offset += sizeof (EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE); + break; + case EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER: + ParseAcpi ( + TRUE, + 2, + "PCI Express Device AER Structure", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER_STRUCTURE), + PARSER_PARAMS (HestErrorSourcePciExpressDeviceAerParser) + ); + + Offset += sizeof (EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER_STRUCTURE); + break; + case EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER: + ParseAcpi ( + TRUE, + 2, + "PCI Express Bridge AER Structure", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER_STRUCTURE), + PARSER_PARAMS (HestErrorSourcePciExpressBridgeAerParser) + ); + + Offset += sizeof (EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER_STRUCTURE); + break; + case EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR: + ParseAcpi ( + TRUE, + 2, + "Generic Hardware Error Source Structure", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE), + PARSER_PARAMS (HestErrorSourceGhesParser) + ); + + Offset += sizeof (EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE); + break; + case EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_VERSION_2: + ParseAcpi ( + TRUE, + 2, + "Generic Hardware Error Source V2 Structure", + ErrorSourcePtr, + sizeof ( + EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE + ), + PARSER_PARAMS (HestErrorSourceGhesv2Parser) + ); + + Offset += + sizeof ( + EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE + ); + break; + case EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK: + ParseAcpi ( + TRUE, + 2, + "IA-32 Architecture Deferred Machine Check", + ErrorSourcePtr, + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE), + PARSER_PARAMS (HestErrorSourceIA32ArchDeferredMachineCheckParser) + ); + + Offset += + sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE), + + Status = DumpIA32ArchMachineCheckErrorBankStructure ( + Ptr, + AcpiTableLength, + &Offset + ); + if (EFI_ERROR (Status)) { + return; + } + + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Error Source Descriptor Type(%d).\n", *mHestErrorSourceType); + return; + } // switch + + ParsedErrorSourceCount++; + } // while + + if (ParsedErrorSourceCount < *mHestErrorSourceCount) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Error Source Count... Real:%d, ErrorSourceCount:%d\n", + ParsedErrorSourceCount, + *mHestErrorSourceCount + ); + return; + } + + if (Offset < AcpiTableLength) { + IncrementErrorCount (); + Print (L"ERROR: Invalid Error Source Count, There's more data...\n"); + return; + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c index 4a90372d81..81c58da45e 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -59,6 +59,7 @@ ACPI_TABLE_PARSER ParserList[] = { { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs }, { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt }, { EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt }, + { EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiHest }, { EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, ParseAcpiHmat }, { EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE, ParseAcpiHpet }, { EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort }, diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index 9c2e2b703d..87998b210d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -2,7 +2,7 @@ # Provides Shell 'acpiview' command functions # # Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. -# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -38,6 +38,7 @@ Parsers/Facs/FacsParser.c Parsers/Fadt/FadtParser.c Parsers/Gtdt/GtdtParser.c + Parsers/Hest/HestParser.c Parsers/Hmat/HmatParser.c Parsers/Hpet/HpetParser.c Parsers/Iort/IortParser.c -- cgit From 990bc4e562772521d771f3d0fe3e3d107ba3752f Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 22 Jul 2024 15:45:48 -0700 Subject: BaseTools: Move GccLto Files to BaseTools This moves the GccLto files from ArmPkg to BaseTools as they are files that are only used in the build. This removes an artificial dependency on ArmPkg from BaseTools and keeps build related files in BaseTools. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Library/GccLto/liblto-aarch64.a | Bin 1128 -> 0 bytes ArmPkg/Library/GccLto/liblto-aarch64.s | 21 ------------- ArmPkg/Library/GccLto/liblto-arm.a | Bin 2096 -> 0 bytes ArmPkg/Library/GccLto/liblto-arm.s | 55 --------------------------------- BaseTools/Bin/GccLto/liblto-aarch64.a | Bin 0 -> 1128 bytes BaseTools/Bin/GccLto/liblto-aarch64.s | 21 +++++++++++++ BaseTools/Bin/GccLto/liblto-arm.a | Bin 0 -> 2096 bytes BaseTools/Bin/GccLto/liblto-arm.s | 55 +++++++++++++++++++++++++++++++++ BaseTools/Conf/tools_def.template | 24 +++++++------- 9 files changed, 88 insertions(+), 88 deletions(-) delete mode 100644 ArmPkg/Library/GccLto/liblto-aarch64.a delete mode 100644 ArmPkg/Library/GccLto/liblto-aarch64.s delete mode 100644 ArmPkg/Library/GccLto/liblto-arm.a delete mode 100644 ArmPkg/Library/GccLto/liblto-arm.s create mode 100644 BaseTools/Bin/GccLto/liblto-aarch64.a create mode 100644 BaseTools/Bin/GccLto/liblto-aarch64.s create mode 100644 BaseTools/Bin/GccLto/liblto-arm.a create mode 100644 BaseTools/Bin/GccLto/liblto-arm.s diff --git a/ArmPkg/Library/GccLto/liblto-aarch64.a b/ArmPkg/Library/GccLto/liblto-aarch64.a deleted file mode 100644 index 6ca3932f1c..0000000000 Binary files a/ArmPkg/Library/GccLto/liblto-aarch64.a and /dev/null differ diff --git a/ArmPkg/Library/GccLto/liblto-aarch64.s b/ArmPkg/Library/GccLto/liblto-aarch64.s deleted file mode 100644 index 02a55ef445..0000000000 --- a/ArmPkg/Library/GccLto/liblto-aarch64.s +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (c) 2016, Linaro Ltd. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// - -// -// GCC in LTO mode interoperates poorly with non-standard libraries that -// provide implementations of compiler intrinsics such as memcpy/memset -// or the stack protector entry points. -// -// By referencing these functions from a non-LTO object that can be passed -// to the linker via the -plugin-opt=-pass-through=-lxxx options, the -// intrinsics are included in the link in a way that allows them to be -// pruned again if no other references to them exist. -// - - .long memcpy - . - .long memset - . - .long __stack_chk_fail - . - .long __stack_chk_guard - . diff --git a/ArmPkg/Library/GccLto/liblto-arm.a b/ArmPkg/Library/GccLto/liblto-arm.a deleted file mode 100644 index d811c09573..0000000000 Binary files a/ArmPkg/Library/GccLto/liblto-arm.a and /dev/null differ diff --git a/ArmPkg/Library/GccLto/liblto-arm.s b/ArmPkg/Library/GccLto/liblto-arm.s deleted file mode 100644 index f19fb45551..0000000000 --- a/ArmPkg/Library/GccLto/liblto-arm.s +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (c) 2016, Linaro Ltd. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// - -// -// GCC in LTO mode interoperates poorly with non-standard libraries that -// provide implementations of compiler intrinsics such as memcpy/memset -// or the stack protector entry points. -// -// By referencing these functions from a non-LTO object that can be passed -// to the linker via the -plugin-opt=-pass-through=-lxxx options, the -// intrinsics are included in the link in a way that allows them to be -// pruned again if no other references to them exist. -// - - .long memcpy - . - .long memset - . - .long __stack_chk_fail - . - .long __stack_chk_guard - . - .long __ashrdi3 - . - .long __ashldi3 - . - .long __aeabi_idiv - . - .long __aeabi_idivmod - . - .long __aeabi_uidiv - . - .long __aeabi_uidivmod - . - .long __divdi3 - . - .long __divsi3 - . - .long __lshrdi3 - . - .long __aeabi_memcpy - . - .long __aeabi_memset - . - .long memmove - . - .long __modsi3 - . - .long __moddi3 - . - .long __muldi3 - . - .long __aeabi_lmul - . - .long __ARM_ll_mullu - . - .long __udivsi3 - . - .long __umodsi3 - . - .long __udivdi3 - . - .long __umoddi3 - . - .long __udivmoddi4 - . - .long __clzsi2 - . - .long __ctzsi2 - . - .long __ucmpdi2 - . - .long __switch8 - . - .long __switchu8 - . - .long __switch16 - . - .long __switch32 - . - .long __aeabi_ulcmp - . - .long __aeabi_uldivmod - . - .long __aeabi_ldivmod - . - .long __aeabi_llsr - . - .long __aeabi_llsl - . diff --git a/BaseTools/Bin/GccLto/liblto-aarch64.a b/BaseTools/Bin/GccLto/liblto-aarch64.a new file mode 100644 index 0000000000..6ca3932f1c Binary files /dev/null and b/BaseTools/Bin/GccLto/liblto-aarch64.a differ diff --git a/BaseTools/Bin/GccLto/liblto-aarch64.s b/BaseTools/Bin/GccLto/liblto-aarch64.s new file mode 100644 index 0000000000..02a55ef445 --- /dev/null +++ b/BaseTools/Bin/GccLto/liblto-aarch64.s @@ -0,0 +1,21 @@ +// +// Copyright (c) 2016, Linaro Ltd. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// + +// +// GCC in LTO mode interoperates poorly with non-standard libraries that +// provide implementations of compiler intrinsics such as memcpy/memset +// or the stack protector entry points. +// +// By referencing these functions from a non-LTO object that can be passed +// to the linker via the -plugin-opt=-pass-through=-lxxx options, the +// intrinsics are included in the link in a way that allows them to be +// pruned again if no other references to them exist. +// + + .long memcpy - . + .long memset - . + .long __stack_chk_fail - . + .long __stack_chk_guard - . diff --git a/BaseTools/Bin/GccLto/liblto-arm.a b/BaseTools/Bin/GccLto/liblto-arm.a new file mode 100644 index 0000000000..d811c09573 Binary files /dev/null and b/BaseTools/Bin/GccLto/liblto-arm.a differ diff --git a/BaseTools/Bin/GccLto/liblto-arm.s b/BaseTools/Bin/GccLto/liblto-arm.s new file mode 100644 index 0000000000..f19fb45551 --- /dev/null +++ b/BaseTools/Bin/GccLto/liblto-arm.s @@ -0,0 +1,55 @@ +// +// Copyright (c) 2016, Linaro Ltd. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// + +// +// GCC in LTO mode interoperates poorly with non-standard libraries that +// provide implementations of compiler intrinsics such as memcpy/memset +// or the stack protector entry points. +// +// By referencing these functions from a non-LTO object that can be passed +// to the linker via the -plugin-opt=-pass-through=-lxxx options, the +// intrinsics are included in the link in a way that allows them to be +// pruned again if no other references to them exist. +// + + .long memcpy - . + .long memset - . + .long __stack_chk_fail - . + .long __stack_chk_guard - . + .long __ashrdi3 - . + .long __ashldi3 - . + .long __aeabi_idiv - . + .long __aeabi_idivmod - . + .long __aeabi_uidiv - . + .long __aeabi_uidivmod - . + .long __divdi3 - . + .long __divsi3 - . + .long __lshrdi3 - . + .long __aeabi_memcpy - . + .long __aeabi_memset - . + .long memmove - . + .long __modsi3 - . + .long __moddi3 - . + .long __muldi3 - . + .long __aeabi_lmul - . + .long __ARM_ll_mullu - . + .long __udivsi3 - . + .long __umodsi3 - . + .long __udivdi3 - . + .long __umoddi3 - . + .long __udivmoddi4 - . + .long __clzsi2 - . + .long __ctzsi2 - . + .long __ucmpdi2 - . + .long __switch8 - . + .long __switchu8 - . + .long __switch16 - . + .long __switch32 - . + .long __aeabi_ulcmp - . + .long __aeabi_uldivmod - . + .long __aeabi_ldivmod - . + .long __aeabi_llsr - . + .long __aeabi_llsl - . diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index c459d83d68..8a2047e403 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -1562,10 +1562,10 @@ RELEASE_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC5_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) DEBUG_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm + DEBUG_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm RELEASE_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm +RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm NOOPT_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 NOOPT_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0 @@ -1596,11 +1596,11 @@ RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKS *_GCC5_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) DEBUG_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch + DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch DEBUG_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 RELEASE_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch +RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 NOOPT_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 @@ -1779,10 +1779,10 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm + DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm RELEASE_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm +RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm NOOPT_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 NOOPT_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0 @@ -1813,11 +1813,11 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP *_GCC_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch + DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch DEBUG_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch +RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch RELEASE_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 @@ -2127,11 +2127,11 @@ DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLI *_CLANGDWARF_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS) DEBUG_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1 - DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax + DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax NOOPT_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -O0 NOOPT_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3 -RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax +RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax ################## # CLANGDWARF AARCH64 definitions @@ -2173,11 +2173,11 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ *_CLANGDWARF_AARCH64_CC_XIPFLAGS = -mstrict-align DEBUG_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1 - DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax + DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax NOOPT_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -O0 NOOPT_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3 -RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax +RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax ################## # CLANGDWARF RISCV64 definitions -- cgit From da591416ee8fddb1b691d157e3c61bdc7a994b79 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 22 Jul 2024 15:50:50 -0700 Subject: BaseTools: Move GnuNoteBti.bin to BaseTools This patch moves GnuNoteBti.bin from ArmPkg to BaseTools as it is used during the build by GCC. This removes an unnecessary dependency on ArmPkg from BaseTools and keeps build related files in BaseTools. Signed-off-by: Oliver Smith-Denny --- ArmPkg/Library/GnuNoteBti.bin | Bin 32 -> 0 bytes BaseTools/Bin/GnuNoteBti.bin | Bin 0 -> 32 bytes BaseTools/Conf/tools_def.template | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 ArmPkg/Library/GnuNoteBti.bin create mode 100644 BaseTools/Bin/GnuNoteBti.bin diff --git a/ArmPkg/Library/GnuNoteBti.bin b/ArmPkg/Library/GnuNoteBti.bin deleted file mode 100644 index 339567b4e8..0000000000 Binary files a/ArmPkg/Library/GnuNoteBti.bin and /dev/null differ diff --git a/BaseTools/Bin/GnuNoteBti.bin b/BaseTools/Bin/GnuNoteBti.bin new file mode 100644 index 0000000000..339567b4e8 Binary files /dev/null and b/BaseTools/Bin/GnuNoteBti.bin differ diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 8a2047e403..994cae2588 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -926,7 +926,7 @@ DEFINE GCC_IA32_RC_FLAGS = -I binary -O elf32-i386 -B i386 DEFINE GCC_X64_RC_FLAGS = -I binary -O elf64-x86-64 -B i386 --rename-section .data=.hii DEFINE GCC_ARM_RC_FLAGS = -I binary -O elf32-littlearm -B arm --rename-section .data=.hii DEFINE GCC_AARCH64_RC_FLAGS = -I binary -O elf64-littleaarch64 -B aarch64 --rename-section .data=.hii -DEFINE GCC_AARCH64_RC_BTI_FLAGS = --add-section .note.gnu.property=$(WORKSPACE)/ArmPkg/Library/GnuNoteBti.bin --set-section-flags .note.gnu.property=alloc,readonly +DEFINE GCC_AARCH64_RC_BTI_FLAGS = --add-section .note.gnu.property=$(WORKSPACE)/BaseTools/Bin/GnuNoteBti.bin --set-section-flags .note.gnu.property=alloc,readonly DEFINE GCC_RISCV64_RC_FLAGS = -I binary -O elf64-littleriscv -B riscv --rename-section .data=.hii DEFINE GCC_LOONGARCH64_RC_FLAGS = -I binary -O elf64-loongarch -B loongarch64 --rename-section .data=.hii -- cgit From f5901ff2a472a5418ee6ff790c3b86cf9c3f54f1 Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Thu, 18 Jul 2024 10:19:04 -0700 Subject: ArmPkg: Remove Deprecated ArmPsciResetSystemLib ArmPsciResetSystemLib has been deprecated since commit b2c55e732888fd721f5235a820b1d1c45209992d in 2017. The lib itself has not been meaningfully updated in 10 years. This commit removes the library to complete the deprecation process and remove confusion over which library to use for resetting an ARM platform. Signed-off-by: Oliver Smith-Denny --- ArmPkg/ArmPkg.dsc | 1 - .../ArmPsciResetSystemLib/ArmPsciResetSystemLib.c | 90 ---------------------- .../ArmPsciResetSystemLib.inf | 32 -------- 3 files changed, 123 deletions(-) delete mode 100644 ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c delete mode 100644 ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 6dd91e6941..f4ffc71d71 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -116,7 +116,6 @@ ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf ArmPkg/Library/SemihostLib/SemihostLib.inf - ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf ArmPkg/Library/ArmExceptionLib/ArmRelocateExceptionLib.inf diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c deleted file mode 100644 index 02b0c27e4d..0000000000 --- a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c +++ /dev/null @@ -1,90 +0,0 @@ -/** @file - Support ResetSystem Runtime call using PSCI calls - - Note: A similar library is implemented in - ArmVirtPkg/Library/ArmVirtualizationPsciResetSystemLib - So similar issues might exist in this implementation too. - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
- Copyright (c) 2014, Linaro Ltd. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include - -#include - -/** - Resets the entire platform. - - @param ResetType The type of reset to perform. - @param ResetStatus The status code for the reset. - @param DataSize The size, in bytes, of WatchdogData. - @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - Unicode string, optionally followed by additional binary data. - -**/ -EFI_STATUS -EFIAPI -LibResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN CHAR16 *ResetData OPTIONAL - ) -{ - ARM_SMC_ARGS ArmSmcArgs; - - switch (ResetType) { - case EfiResetPlatformSpecific: - // Map the platform specific reset as reboot - case EfiResetWarm: - // Map a warm reset into a cold reset - case EfiResetCold: - // Send a PSCI 0.2 SYSTEM_RESET command - ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET; - break; - case EfiResetShutdown: - // Send a PSCI 0.2 SYSTEM_OFF command - ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF; - break; - default: - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - - ArmCallSmc (&ArmSmcArgs); - - // We should never be here - DEBUG ((DEBUG_ERROR, "%a: PSCI Reset failed\n", __func__)); - CpuDeadLoop (); - return EFI_UNSUPPORTED; -} - -/** - Initialize any infrastructure required for LibResetSystem () to function. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -LibInitializeResetSystem ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EFI_SUCCESS; -} diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf deleted file mode 100644 index 3d05de4fd4..0000000000 --- a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf +++ /dev/null @@ -1,32 +0,0 @@ -#/** @file -# Reset System lib using PSCI hypervisor or secure monitor calls -# -# Copyright (c) 2008, Apple Inc. All rights reserved.
-# Copyright (c) 2014, Linaro Ltd. All rights reserved.
-# Copyright (c) 2014, ARM Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = ArmPsciResetSystemLib - FILE_GUID = A8F59B69-A105-41C7-8F5A-2C60DD7FD7AA - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = EfiResetSystemLib - -[Sources] - ArmPsciResetSystemLib.c - -[Packages] - ArmPkg/ArmPkg.dec - MdePkg/MdePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - -[LibraryClasses] - DebugLib - BaseLib - ArmSmcLib -- cgit From 76f441c57c6653d689fbe936ba494ebfdbc7cb4f Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 28 May 2024 09:52:06 +0800 Subject: UefiCpuPkg: Also exchange CPU_AP_DATA in SortApicId() CPU_AP_DATA contains AP's information such as CpuHealthy and VolatileRegisters. Exchange the whole CPU_AP_DATA buffer instead some fields to make code more simple. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 1951922912..78eeaa6de2 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -377,10 +377,9 @@ SortApicId ( UINTN Index3; UINT32 ApicId; CPU_INFO_IN_HOB CpuInfo; + CPU_AP_DATA CpuApData; UINT32 ApCount; CPU_INFO_IN_HOB *CpuInfoInHob; - volatile UINT32 *StartupApSignal; - VOID *SevEsSaveArea; ApCount = CpuMpData->CpuCount - 1; CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; @@ -407,18 +406,13 @@ SortApicId ( ); CopyMem (&CpuInfoInHob[Index1], &CpuInfo, sizeof (CPU_INFO_IN_HOB)); - // - // Also exchange the StartupApSignal and SevEsSaveArea. - // - StartupApSignal = CpuMpData->CpuData[Index3].StartupApSignal; - CpuMpData->CpuData[Index3].StartupApSignal = - CpuMpData->CpuData[Index1].StartupApSignal; - CpuMpData->CpuData[Index1].StartupApSignal = StartupApSignal; - - SevEsSaveArea = CpuMpData->CpuData[Index3].SevEsSaveArea; - CpuMpData->CpuData[Index3].SevEsSaveArea = - CpuMpData->CpuData[Index1].SevEsSaveArea; - CpuMpData->CpuData[Index1].SevEsSaveArea = SevEsSaveArea; + CopyMem (&CpuApData, &CpuMpData->CpuData[Index3], sizeof (CPU_AP_DATA)); + CopyMem ( + &CpuMpData->CpuData[Index3], + &CpuMpData->CpuData[Index1], + sizeof (CPU_AP_DATA) + ); + CopyMem (&CpuMpData->CpuData[Index1], &CpuApData, sizeof (CPU_AP_DATA)); } } -- cgit From 7033f359a99121fd2c3fefe03d9f0c64e8bfaa10 Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 28 May 2024 11:22:10 +0800 Subject: UefiCpuPkg: Preserve Local APIC Timer Settings During BSP Switch This update ensures the consistency of Local APIC timer settings across all processors when a BSP switch occurs. The Local APIC timer is utilized in two distinct scenarios: 1. As a delay mechanism within the timer library. 2. To generate periodic timer interrupts during the DXE phase. For scenario 1, APs can simply inherit the initial settings from the BSP. Even the local APIC timer setting is changed by BSP later, AP can still use the old setting. Therefore, the code to save the Local APIC timer can be moved to MpInitLibInitialize(). For scenario 2, because normal AP doesn't enable timer interrupt, we only need to care SwitchBsp case. It is crucial that the periodic timer interrupts remain operational after BSP is switched. To achieve this, the Local APIC timer settings on old BSP are now preserved and synced to new BSP. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 78eeaa6de2..69c53c6228 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -1258,7 +1258,6 @@ WakeUpAP ( AllocateResetVectorBelow1Mb (CpuMpData); AllocateSevEsAPMemory (CpuMpData); FillExchangeInfoData (CpuMpData); - SaveLocalApicTimerSetting (CpuMpData); } if (CpuMpData->ApLoopMode == ApInMwaitLoop) { @@ -2236,6 +2235,7 @@ MpInitLibInitialize ( // Enable the local APIC for Virtual Wire Mode. // ProgramVirtualWireMode (); + SaveLocalApicTimerSetting (CpuMpData); if (FirstMpHandOff == NULL) { if (MaxLogicalProcessorNumber > 1) { @@ -2611,6 +2611,11 @@ SwitchBSPWorker ( ApicBaseMsr.Bits.BSP = 0; AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + // + // Save BSP's local APIC timer setting. + // + SaveLocalApicTimerSetting (CpuMpData); + // // Need to wakeUp AP (future BSP). // -- cgit From 7fc08c68cd64ccf30e4d46d1a60fcdd61b31f1ec Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 28 May 2024 11:22:10 +0800 Subject: UefiCpuPkg: Sync the init timer count instead of current timer count BSP should save and sync to AP the init timer count instead of current timer count. Also, BSP can check the init timer count to know if the local apic timer is enabled. Only sync the setting when it is enabled. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 51 ++++++++++++++++++++---------------- UefiCpuPkg/Library/MpInitLib/MpLib.h | 2 +- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 69c53c6228..5cbcef70e8 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -167,16 +167,19 @@ SaveLocalApicTimerSetting ( IN CPU_MP_DATA *CpuMpData ) { - // - // Record the current local APIC timer setting of BSP - // - GetApicTimerState ( - &CpuMpData->DivideValue, - &CpuMpData->PeriodicMode, - &CpuMpData->Vector - ); - CpuMpData->CurrentTimerCount = GetApicTimerCurrentCount (); - CpuMpData->TimerInterruptState = GetApicTimerInterruptState (); + CpuMpData->InitTimerCount = GetApicTimerInitCount (); + if (CpuMpData->InitTimerCount != 0) { + // + // Record the current local APIC timer setting of BSP + // + GetApicTimerState ( + &CpuMpData->DivideValue, + &CpuMpData->PeriodicMode, + &CpuMpData->Vector + ); + + CpuMpData->TimerInterruptState = GetApicTimerInterruptState (); + } } /** @@ -189,19 +192,21 @@ SyncLocalApicTimerSetting ( IN CPU_MP_DATA *CpuMpData ) { - // - // Sync local APIC timer setting from BSP to AP - // - InitializeApicTimer ( - CpuMpData->DivideValue, - CpuMpData->CurrentTimerCount, - CpuMpData->PeriodicMode, - CpuMpData->Vector - ); - // - // Disable AP's local APIC timer interrupt - // - DisableApicTimerInterrupt (); + if (CpuMpData->InitTimerCount != 0) { + // + // Sync local APIC timer setting from BSP to AP + // + InitializeApicTimer ( + CpuMpData->DivideValue, + CpuMpData->InitTimerCount, + CpuMpData->PeriodicMode, + CpuMpData->Vector + ); + // + // Disable AP's local APIC timer interrupt + // + DisableApicTimerInterrupt (); + } } /** diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 88b31fecca..8742fa175b 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -289,7 +289,7 @@ struct _CPU_MP_DATA { CPU_AP_DATA *CpuData; volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo; - UINT32 CurrentTimerCount; + UINT32 InitTimerCount; UINTN DivideValue; UINT8 Vector; BOOLEAN PeriodicMode; -- cgit From 4a0c77be6834818dd2b73f9f85869ba46854d677 Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Thu, 30 May 2024 14:16:25 +0800 Subject: UefiCpuPkg: Let AP always save/restore volatile registers When enable stack guard, APs needs separate GDTs. In current code, APs will lose their separate GDTs when AP get disabled and later re-enabled. This is because when re-enabling AP, AP restores volatile registers from BSP. This patch updates the AP management to ensure that each AP saves and restores its own set of volatile registers to solve this issue. Key changes include: - APs now maintain their own volatile register space, eliminating dependency on the BSP's register state. - Special handling is implemented for the first AP wake-up during the PEI and DXE phases, where the volatile registers are synchronized from the BSP. - When switching BSP, remove manual handling the global variable CpuMpData->CpuData[Index].VolatileRegisters. The manually handling in previous code is because, old BSP may not save volatile registers after the AP procedure and new BSP's VolatileRegisters buffer may be used by other APs. Now, since AP always save/restore volatile registers from their own buffer, no need to do the special handling. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 71 +++++++++++++----------------------- 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 5cbcef70e8..4a23fd1a92 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -119,10 +119,6 @@ FutureBSPProc ( SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters); AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo); RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE); - // - // Update VolatileRegisters saved in CpuMpData->CpuData - // - CopyMem (&DataInHob->CpuData[DataInHob->BspNumber].VolatileRegisters, &DataInHob->APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS)); } /** @@ -769,11 +765,11 @@ ApWakeupFunction ( BistData = (UINT32)ApStackData->Bist; // - // CpuMpData->CpuData[BspNumber].VolatileRegisters is initialized based on BSP environment, + // CpuMpData->CpuData[ProcessorNumber].VolatileRegisters is initialized based on BSP environment, // to initialize AP in InitConfig path. - // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a different IDT shared by all APs. + // NOTE: IDTR.BASE stored in CpuMpData->CpuData[ProcessorNumber].VolatileRegisters points to a different IDT shared by all APs. // - RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, FALSE); InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; } else { @@ -800,31 +796,7 @@ ApWakeupFunction ( 0 ); - if (CpuMpData->InitFlag == ApInitReconfig) { - // - // ApInitReconfig happens when: - // 1. AP is re-enabled after it's disabled, in either PEI or DXE phase. - // 2. AP is initialized in DXE phase. - // In either case, use the volatile registers value derived from BSP. - // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a - // different IDT shared by all APs. - // - RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); - } else { - if (CpuMpData->ApLoopMode == ApInHltLoop) { - // - // Restore AP's volatile registers saved before AP is halted - // - RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); - } else { - // - // The CPU driver might not flush TLB for APs on spot after updating - // page attributes. AP in mwait loop mode needs to take care of it when - // woken up. - // - CpuFlushTlb (); - } - } + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) { Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction; @@ -875,12 +847,7 @@ ApWakeupFunction ( } } - if (CpuMpData->ApLoopMode == ApInHltLoop) { - // - // Save AP volatile registers - // - SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters); - } + SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters); // // AP finished executing C code @@ -935,7 +902,7 @@ DxeApEntryPoint ( AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64); } - RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, FALSE); InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount); PlaceAPInMwaitLoopOrRunLoop ( CpuMpData->ApLoopMode, @@ -2198,7 +2165,25 @@ MpInitLibInitialize ( // Don't pass BSP's TR to APs to avoid AP init failure. // VolatileRegisters.Tr = 0; - CopyMem (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters)); + // + // Set DR as 0 since DR is set only for BSP. + // + VolatileRegisters.Dr0 = 0; + VolatileRegisters.Dr1 = 0; + VolatileRegisters.Dr2 = 0; + VolatileRegisters.Dr3 = 0; + VolatileRegisters.Dr6 = 0; + VolatileRegisters.Dr7 = 0; + + // + // Copy volatile registers since either APs are the first time to bring up, + // or BSP is in DXE phase but APs are still running in PEI context. + // In both cases, APs need use volatile registers from BSP + // + for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) { + CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters)); + } + // // Set BSP basic information // @@ -2633,12 +2618,6 @@ SwitchBSPWorker ( AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo); RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE); // - // Update VolatileRegisters saved in CpuMpData->CpuData - // Don't pass BSP's TR to APs to avoid AP init failure. - // - CopyMem (&CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters, &CpuMpData->BSPInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS)); - CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters.Tr = 0; - // // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP // ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); -- cgit From 9f06e5c7021c02afac4698adbb49d482cb606e3e Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 23 Jul 2024 09:46:01 +0800 Subject: UefiCpuPkg: Remove ApInitReconfig status ApInitReconfig status is used to indicate that when AP wakes up, AP need to restore volatile registers from BSP and use InitSipiSipi. Since we handle the volatile registers well, we can use WakeUpByInitSipiSipi flag to replace ApInitReconfig. Avoid using ApInitReconfig can simplify code. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 25 ++++++++++--------------- UefiCpuPkg/Library/MpInitLib/MpLib.h | 5 ++--- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 4a23fd1a92..8b2bacb65e 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -1224,7 +1224,7 @@ WakeUpAP ( ResetVectorRequired = FALSE; if (CpuMpData->WakeUpByInitSipiSipi || - (CpuMpData->InitFlag != ApInitDone)) + (CpuMpData->InitFlag == ApInitConfig)) { ResetVectorRequired = TRUE; AllocateResetVectorBelow1Mb (CpuMpData); @@ -1258,7 +1258,7 @@ WakeUpAP ( CpuData->ApFunction = (UINTN)Procedure; CpuData->ApFunctionArgument = (UINTN)ProcedureArgument; SetApState (CpuData, CpuStateReady); - if (CpuMpData->InitFlag != ApInitConfig) { + if (CpuMpData->InitFlag == ApInitDone) { *(UINT32 *)CpuData->StartupApSignal = WAKEUP_AP_SIGNAL; } } @@ -1376,7 +1376,7 @@ WakeUpAP ( // // Wakeup specified AP // - ASSERT (CpuMpData->InitFlag != ApInitConfig); + ASSERT (CpuMpData->InitFlag == ApInitDone); *(UINT32 *)CpuData->StartupApSignal = WAKEUP_AP_SIGNAL; if (ResetVectorRequired) { CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; @@ -1648,14 +1648,12 @@ ResetProcessorToIdleState ( CpuMpData = GetCpuMpData (); - CpuMpData->InitFlag = ApInitReconfig; + CpuMpData->WakeUpByInitSipiSipi = TRUE; WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL, TRUE); while (CpuMpData->FinishedCount < 1) { CpuPause (); } - CpuMpData->InitFlag = ApInitDone; - SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle); } @@ -2315,6 +2313,12 @@ MpInitLibInitialize ( // InitMpGlobalData (CpuMpData); return EFI_SUCCESS; + } else { + // + // PEI and DXE are in different Execution Mode + // Use Init Sipi Sipi for the first AP wake up in DXE phase. + // + CpuMpData->WakeUpByInitSipiSipi = TRUE; } } @@ -2343,15 +2347,6 @@ MpInitLibInitialize ( // Wakeup APs to do some AP initialize sync (Microcode & MTRR) // if (CpuMpData->CpuCount > 1) { - if (FirstMpHandOff != NULL) { - // - // Only needs to use this flag for DXE phase to update the wake up - // buffer. Wakeup buffer allocated in PEI phase is no longer valid - // in DXE. - // - CpuMpData->InitFlag = ApInitReconfig; - } - WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE); // // Wait for all APs finished initialization diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 8742fa175b..e92991d5dc 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -120,9 +120,8 @@ typedef enum { // AP initialization state during APs wakeup // typedef enum { - ApInitConfig = 1, - ApInitReconfig = 2, - ApInitDone = 3 + ApInitConfig = 1, + ApInitDone = 2 } AP_INIT_STATE; // -- cgit From 3912aa3d32dbd8a684d78d23bb938b3dc920d300 Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 23 Jul 2024 09:49:03 +0800 Subject: UefiCpuPkg: Combine the code to set ApInitDone In previoud commit, we remove the ApInitReconfig status. Now there are only two status ApInitConfig and ApInitDone. Only the very first waking up AP needs to set ApInitConfig status. Therefore, if this is not the first wake up, set ApInitDone status Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 8b2bacb65e..7eee646312 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -2237,6 +2237,7 @@ MpInitLibInitialize ( // APs have been wakeup before, just get the CPU Information // from HOB // + CpuMpData->InitFlag = ApInitDone; if (CpuMpData->UseSevEsAPMethod) { AmdSevUpdateCpuMpData (CpuMpData); } @@ -2280,7 +2281,6 @@ MpInitLibInitialize ( ASSERT (CpuMpData->ApLoopMode != ApInHltLoop); CpuMpData->FinishedCount = 0; - CpuMpData->InitFlag = ApInitDone; CpuMpData->EnableExecuteDisableForSwitchContext = IsBspExecuteDisableEnabled (); SaveCpuMpData (CpuMpData); // @@ -2355,10 +2355,6 @@ MpInitLibInitialize ( CpuPause (); } - if (FirstMpHandOff != NULL) { - CpuMpData->InitFlag = ApInitDone; - } - for (Index = 0; Index < CpuMpData->CpuCount; Index++) { SetApState (&CpuMpData->CpuData[Index], CpuStateIdle); } -- cgit From 6fe3137fe529c9d8ae146041af6681077914ffa8 Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Mon, 1 Jul 2024 15:56:29 +0800 Subject: UefiCpuPkg: Change RestoreVolatileRegisters second parameter Analysis of the current usage patterns revealed that this parameter should consistently set to TRUE. Specifically, the parameter was found to be False in the following scenarios: 1. During the initial volatile register setup for the first AP wake-up in both the PEI and DXE phases. In these instances, the volatile registers are pre-initialized in MpInitLibInitialize(), and manually setting them to zero does not require altering the DR state. 2. When switching the BSP, the new BSP does not synchronize the DR. This behavior is now adjusted to ensure the DR state is synchronized, aligning with a more logical and expected behavior when transitioning BSP roles. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 7eee646312..c3b1620b14 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -118,7 +118,7 @@ FutureBSPProc ( // SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters); AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo); - RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE); + RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, TRUE); } /** @@ -769,7 +769,7 @@ ApWakeupFunction ( // to initialize AP in InitConfig path. // NOTE: IDTR.BASE stored in CpuMpData->CpuData[ProcessorNumber].VolatileRegisters points to a different IDT shared by all APs. // - RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, FALSE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; } else { @@ -902,7 +902,7 @@ DxeApEntryPoint ( AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64); } - RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, FALSE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount); PlaceAPInMwaitLoopOrRunLoop ( CpuMpData->ApLoopMode, @@ -2607,7 +2607,7 @@ SwitchBSPWorker ( // SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters); AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo); - RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE); + RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, TRUE); // // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP // -- cgit From 9bc7a361200215fc5065dfaa6d90d4eb50fec00c Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Mon, 3 Jun 2024 13:31:19 +0800 Subject: UefiCpuPkg: Removing redundant parameter in RestoreVolatileRegisters Given that the second parameter can be universally set to TRUE across all use cases, its removal simplifies the function interface and the associated code paths. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 45 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index c3b1620b14..4088e76f45 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -41,8 +41,7 @@ SaveVolatileRegisters ( **/ VOID RestoreVolatileRegisters ( - IN CPU_VOLATILE_REGISTERS *VolatileRegisters, - IN BOOLEAN IsRestoreDr + IN CPU_VOLATILE_REGISTERS *VolatileRegisters ); /** @@ -118,7 +117,7 @@ FutureBSPProc ( // SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters); AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo); - RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, TRUE); + RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters); } /** @@ -244,13 +243,11 @@ SaveVolatileRegisters ( Restore the volatile registers following INIT IPI. @param[in] VolatileRegisters Pointer to volatile resisters - @param[in] IsRestoreDr TRUE: Restore DRx if supported - FALSE: Do not restore DRx + **/ VOID RestoreVolatileRegisters ( - IN CPU_VOLATILE_REGISTERS *VolatileRegisters, - IN BOOLEAN IsRestoreDr + IN CPU_VOLATILE_REGISTERS *VolatileRegisters ) { CPUID_VERSION_INFO_EDX VersionInfoEdx; @@ -260,20 +257,18 @@ RestoreVolatileRegisters ( AsmWriteCr4 (VolatileRegisters->Cr4); AsmWriteCr0 (VolatileRegisters->Cr0); - if (IsRestoreDr) { - AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); - if (VersionInfoEdx.Bits.DE != 0) { - // - // If processor supports Debugging Extensions feature - // by CPUID.[EAX=01H]:EDX.BIT2 - // - AsmWriteDr0 (VolatileRegisters->Dr0); - AsmWriteDr1 (VolatileRegisters->Dr1); - AsmWriteDr2 (VolatileRegisters->Dr2); - AsmWriteDr3 (VolatileRegisters->Dr3); - AsmWriteDr6 (VolatileRegisters->Dr6); - AsmWriteDr7 (VolatileRegisters->Dr7); - } + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); + if (VersionInfoEdx.Bits.DE != 0) { + // + // If processor supports Debugging Extensions feature + // by CPUID.[EAX=01H]:EDX.BIT2 + // + AsmWriteDr0 (VolatileRegisters->Dr0); + AsmWriteDr1 (VolatileRegisters->Dr1); + AsmWriteDr2 (VolatileRegisters->Dr2); + AsmWriteDr3 (VolatileRegisters->Dr3); + AsmWriteDr6 (VolatileRegisters->Dr6); + AsmWriteDr7 (VolatileRegisters->Dr7); } AsmWriteGdtr (&VolatileRegisters->Gdtr); @@ -769,7 +764,7 @@ ApWakeupFunction ( // to initialize AP in InitConfig path. // NOTE: IDTR.BASE stored in CpuMpData->CpuData[ProcessorNumber].VolatileRegisters points to a different IDT shared by all APs. // - RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters); InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; } else { @@ -796,7 +791,7 @@ ApWakeupFunction ( 0 ); - RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters); if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) { Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction; @@ -902,7 +897,7 @@ DxeApEntryPoint ( AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64); } - RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE); + RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters); InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount); PlaceAPInMwaitLoopOrRunLoop ( CpuMpData->ApLoopMode, @@ -2607,7 +2602,7 @@ SwitchBSPWorker ( // SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters); AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo); - RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, TRUE); + RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters); // // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP // -- cgit From d4ae23b1e6c5fe95205818fcae9d5561c20588d3 Mon Sep 17 00:00:00 2001 From: Dongyan Qian Date: Mon, 22 Jul 2024 10:57:36 +0800 Subject: ShellPkg: Support parser of MADT for LoongArch64 Parse CORE_PIC, LIO_PIC, HT_PIC, EIO_PIC, MSI_PIC, BIO_PIC and LPC_PIC tables in ACPI SPEC 6.5. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4306 Cc: Zhichao Gao Cc: Chao Li Signed-off-by: Dongyan Qian Co-authored-by: Jinwei Wang Reviewed-by: Liming Gao Reviewed-by: Chao Li --- .../Parsers/Madt/MadtParser.c | 178 +++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c index 3a4f246347..42f45d5a94 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c @@ -3,6 +3,7 @@ Copyright (c) 2016 - 2023, ARM Limited. All rights reserved. Copyright (c) 2022, AMD Incorporated. All rights reserved. + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -325,6 +326,92 @@ STATIC CONST ACPI_PARSER LocalX2ApicNmi[] = { { L"Reserved", 3, 9, L"0x%x%x%x", Dump3Chars, NULL, NULL, NULL } }; +/** + An ACPI_PARSER array describing the Core Pragrammable Interrupt Controller (CORE PIC) Structure. +**/ +STATIC CONST ACPI_PARSER CorePic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"ACPI Processor ID", 4, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Physical Processor ID", 4, 7, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Flags", 4, 11, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Leagcy I/O Programmable Interrupt Controller (LIO PIC) Structure. +**/ +STATIC CONST ACPI_PARSER LegacyIoPic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Cascade Vector", 2, 13, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Cascade vector mapping", 8, 15, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the HyperTransport Programmable Interrupt Controller (HT PIC) Structure. +**/ +STATIC CONST ACPI_PARSER HyperTransportPic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Cascade Vector", 8, 13, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Extend I/0 Programmable Interrupt Controller (EIO PIC) Structure. +**/ +STATIC CONST ACPI_PARSER ExtendIoPic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Cascade Vector", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Node", 1, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Node Map", 8, 5, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the MSI Programmable Interrupt Controller (MSI PIC) Structure. +**/ +STATIC CONST ACPI_PARSER MsiPic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Message Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Start", 4, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Count", 4, 15, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Bridge I/O Programmable Interrupt Controller (BIO PIC) Structure. +**/ +STATIC CONST ACPI_PARSER BridgeIoPic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Hardware ID", 2, 13, L"0x%x", NULL, NULL, NULL, NULL }, + { L"GSI base", 2, 15, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the LPC Programmable Interrupt Controller (LPC PIC) Structure. +**/ +STATIC CONST ACPI_PARSER LpcPic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Cascade vector", 2, 13, L"0x%x", NULL, NULL, NULL, NULL } +}; + /** An ACPI_PARSER array describing the ACPI MADT Table. **/ @@ -572,6 +659,97 @@ ParseAcpiMadt ( break; } + case EFI_ACPI_6_5_CORE_PIC: + { + ParseAcpi ( + TRUE, + 2, + "CORE PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (CorePic) + ); + break; + } + + case EFI_ACPI_6_5_LIO_PIC: + { + ParseAcpi ( + TRUE, + 2, + "LIO PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (LegacyIoPic) + ); + break; + } + + case EFI_ACPI_6_5_HT_PIC: + { + ParseAcpi ( + TRUE, + 2, + "HT PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (HyperTransportPic) + ); + break; + } + + case EFI_ACPI_6_5_EIO_PIC: + { + ParseAcpi ( + TRUE, + 2, + "EIO PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (ExtendIoPic) + ); + break; + } + + case EFI_ACPI_6_5_MSI_PIC: + { + ParseAcpi ( + TRUE, + 2, + "MSI PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (MsiPic) + ); + break; + } + + case EFI_ACPI_6_5_BIO_PIC: + { + ParseAcpi ( + TRUE, + 2, + "BIO PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (BridgeIoPic) + ); + break; + } + + case EFI_ACPI_6_5_LPC_PIC: + { + ParseAcpi ( + TRUE, + 2, + "LPC PIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (LpcPic) + ); + break; + } + default: { IncrementErrorCount (); -- cgit From a9c8c47d5347c74f5e7e7cb859912a276c6e9fb8 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 24 Jul 2024 12:02:39 +0200 Subject: ArmPkg: Disable AuditOnly mode for uncrustify Fix up a handful of uncrustify infractions and drop the AuditOnly override for uncrustify so we get the same uncrustify CI coverage as other packages. Signed-off-by: Ard Biesheuvel --- ArmPkg/ArmPkg.ci.yaml | 5 ----- ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c | 2 +- .../DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c | 10 ++++++---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/ArmPkg/ArmPkg.ci.yaml b/ArmPkg/ArmPkg.ci.yaml index d312481611..24db742505 100644 --- a/ArmPkg/ArmPkg.ci.yaml +++ b/ArmPkg/ArmPkg.ci.yaml @@ -239,10 +239,5 @@ ], "AdditionalIncludePaths": [] # Additional paths to spell check # (wildcards supported) - }, - - # options defined in .pytool/Plugin/UncrustifyCheck - "UncrustifyCheck": { - "AuditOnly": True } } diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c index 617e88f367..741f5c6157 100644 --- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c +++ b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c @@ -26,7 +26,7 @@ ArmMonitorCall ( IN OUT ARM_MONITOR_ARGS *Args ) { - if (FeaturePcdGet (PcdMonitorConduitHvc)) { + if (FeaturePcdGet (PcdMonitorConduitHvc)) { ArmCallHvc ((ARM_HVC_ARGS *)Args); } else { ArmCallSmc ((ARM_SMC_ARGS *)Args); diff --git a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c index 992c14d7ef..9ae83d9a98 100644 --- a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c +++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c @@ -32,7 +32,7 @@ PeCoffLoaderRelocateImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { -#ifdef __GNUC__ + #ifdef __GNUC__ if (ImageContext->PdbPointer) { DEBUG (( DEBUG_LOAD | DEBUG_INFO, @@ -42,7 +42,8 @@ PeCoffLoaderRelocateImageExtraAction ( )); return; } -#endif + + #endif DEBUG (( DEBUG_LOAD | DEBUG_INFO, @@ -68,7 +69,7 @@ PeCoffLoaderUnloadImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { -#ifdef __GNUC__ + #ifdef __GNUC__ if (ImageContext->PdbPointer) { DEBUG (( DEBUG_LOAD | DEBUG_INFO, @@ -78,7 +79,8 @@ PeCoffLoaderUnloadImageExtraAction ( )); return; } -#endif + + #endif DEBUG (( DEBUG_LOAD | DEBUG_INFO, -- cgit From a7abb77c599f4243d7dbab552ec74ed4d0d0d152 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sun, 21 Jul 2024 19:05:23 +0200 Subject: ArmPkg: Introduce ResetSystemLib implementation based on ArmMonitorLib The ARM SMCCC specification stipulates that the conduit for ARM monitor calls can be determined by taking the conduit for PSCI calls. The converse is also true, and so we can implement ResetSystemLib for PSCI using ArmMonitorLib to choose between SMC and HVC instructions. Signed-off-by: Ard Biesheuvel --- ArmPkg/ArmPkg.dsc | 1 + .../ArmPsciResetSystemLib/ArmPsciResetSystemLib.c | 176 +++++++++++++++++++++ .../ArmPsciResetSystemLib.inf | 32 ++++ 3 files changed, 209 insertions(+) create mode 100644 ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c create mode 100644 ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index f4ffc71d71..09037c59b5 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -109,6 +109,7 @@ [Components.common] ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf + ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c new file mode 100644 index 0000000000..4134c8bfda --- /dev/null +++ b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c @@ -0,0 +1,176 @@ +/** @file + Support ResetSystem Runtime call using PSCI calls + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2014, Linaro Ltd. All rights reserved.
+ Copyright (c) 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2024, Google Llc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include + +/** + Library constructor. This function does nothing, but this library may depend + on other libraries that do have a non-trivial constructor, which the + BaseToools fail to account for if a library has no constructor at all. + **/ +RETURN_STATUS +EFIAPI +ArmPsciResetSystemLibConstructor ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + This function causes a system-wide reset (cold reset), in which + all circuitry within the system returns to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + If this function returns, it means that the system does not support cold reset. +**/ +VOID +EFIAPI +ResetCold ( + VOID + ) +{ + ARM_MONITOR_ARGS Args; + + // Send a PSCI 0.2 SYSTEM_RESET command + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET; + + ArmMonitorCall (&Args); +} + +/** + This function causes a system-wide initialization (warm reset), in which all processors + are set to their initial state. Pending cycles are not corrupted. + + If this function returns, it means that the system does not support warm reset. +**/ +VOID +EFIAPI +ResetWarm ( + VOID + ) +{ + ARM_MONITOR_ARGS Args; + + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64; + + // Is SYSTEM_RESET2 supported? + ArmMonitorCall (&Args); + if (Args.Arg0 == ARM_SMC_PSCI_RET_SUCCESS) { + // Send PSCI SYSTEM_RESET2 command + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64; + + ArmMonitorCall (&Args); + } else { + // Map a warm reset into a cold reset + DEBUG (( + DEBUG_INFO, + "Warm reboot not supported by platform, issuing cold reboot\n" + )); + ResetCold (); + } +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + If this function returns, it means that the system does not support shutdown reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + ARM_MONITOR_ARGS Args; + + // Send a PSCI 0.2 SYSTEM_RESET command + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF; + + ArmMonitorCall (&Args); +} + +/** + This function causes a systemwide reset. The exact type of the reset is + defined by the EFI_GUID that follows the Null-terminated Unicode string passed + into ResetData. If the platform does not recognize the EFI_GUID in ResetData + the platform must pick a supported reset type to perform.The platform may + optionally log the parameters from any non-normal reset that occurs. + + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData The data buffer starts with a Null-terminated string, + followed by the EFI_GUID. +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + // Map the platform specific reset as reboot + ResetCold (); +} + +/** + The ResetSystem function resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown + the data buffer starts with a Null-terminated string, optionally + followed by additional binary data. The string is a description + that the caller may use to further indicate the reason for the + system reset. +**/ +VOID +EFIAPI +ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + switch (ResetType) { + case EfiResetWarm: + ResetWarm (); + break; + + case EfiResetCold: + ResetCold (); + break; + + case EfiResetShutdown: + ResetShutdown (); + return; + + case EfiResetPlatformSpecific: + ResetPlatformSpecific (DataSize, ResetData); + return; + + default: + return; + } +} diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf new file mode 100644 index 0000000000..c98f60df78 --- /dev/null +++ b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf @@ -0,0 +1,32 @@ +## @file +# Reset System lib using PSCI hypervisor or secure monitor calls +# +# Copyright (c) 2008, Apple Inc. All rights reserved.
+# Copyright (c) 2014, Linaro Ltd. All rights reserved.
+# Copyright (c) 2024, Google Llc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ArmPsciResetSystemLib + FILE_GUID = 31db596f-cc80-47fd-849f-e6be5e9f7560 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib + CONSTRUCTOR = ArmPsciResetSystemLibConstructor + +[Sources] + ArmPsciResetSystemLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmMonitorLib + BaseLib + DebugLib -- cgit From a96d2a8f2dd3eb7e32b383821fe30cfd7cdb2248 Mon Sep 17 00:00:00 2001 From: Taylor Beebe <31827475+TaylorBeebe@users.noreply.github.com> Date: Tue, 8 Nov 2022 11:56:07 -0800 Subject: PrmPkg: Don't Set Access Attributes of Runtime MMIO Ranges Passing in access attributes to SetMemorySpaceAttributes() will cause the existing attributes to be overwritten. The MMIO region should have the appropriate attributes applied during memory protection initialization and the attributes of the memory space descriptor are inaccurate. Don't pass in any CPU arch attributes so SetMemorySpaceAttributes() doesn't subsequently call gCpu->SetMemoryAttributes(). Signed-off-by: Oliver Smith-Denny --- PrmPkg/PrmConfigDxe/PrmConfigDxe.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c index 550ee64b4c..7a3913ee09 100644 --- a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c +++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c @@ -152,10 +152,15 @@ SetRuntimeMemoryRangeAttributes ( continue; } + // The memory space descriptor access attributes are not accurate. Don't pass + // in access attributes so SetMemorySpaceAttributes() doesn't update them. + // EFI_MEMORY_RUNTIME is not a CPU arch attribute, so calling + // SetMemorySpaceAttributes() with only it set will not clear existing page table + // attributes for this region, such as EFI_MEMORY_XP Status = gDS->SetMemorySpaceAttributes ( RuntimeMmioRanges->Range[Index].PhysicalBaseAddress, (UINT64)RuntimeMmioRanges->Range[Index].Length, - Descriptor.Attributes | EFI_MEMORY_RUNTIME + EFI_MEMORY_RUNTIME ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { -- cgit From 3f0c4cee940d550cf7543eef188b3b068df8b818 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 22 Jul 2024 17:14:55 -0400 Subject: BaseTools/GetMaintainer.py: Add GitHub username argument Adds a new `-g` parameter so that output will also include the GitHub username. This change uses a simple regular expression as opposed to directly returning the original line from the file to make the extraction of GitHub usernames more robust to other changes on the line in the maintainers text file. Signed-off-by: Michael Kubacki --- BaseTools/Scripts/GetMaintainer.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/BaseTools/Scripts/GetMaintainer.py b/BaseTools/Scripts/GetMaintainer.py index 8097ba4e7b..986550c4a9 100644 --- a/BaseTools/Scripts/GetMaintainer.py +++ b/BaseTools/Scripts/GetMaintainer.py @@ -179,6 +179,10 @@ if __name__ == '__main__': PARSER.add_argument('-l', '--lookup', help='Find section matches for path LOOKUP', required=False) + PARSER.add_argument('-g', '--github', + action='store_true', + help='Include GitHub usernames in output', + required=False) ARGS = PARSER.parse_args() REPO = SetupGit.locate_repo() @@ -203,5 +207,8 @@ if __name__ == '__main__': for address in ADDRESSES: if '<' in address and '>' in address: - address = address.split('>', 1)[0] + '>' - print(' %s' % address) + address, github_id = address.split('>', 1) + address = address + '>' + github_id = github_id.strip() if ARGS.github else '' + + print(' %s %s' % (address, github_id)) -- cgit From 89a06a245bd27c6a83fa2b2ed80cfe186dab0029 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 22 Jul 2024 17:15:52 -0400 Subject: .github: Add GitHub helper python script Adds a script that provides GitHub API helpers for workflows and other GitHub automation in the repository. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 .github/scripts/GitHub.py diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py new file mode 100644 index 0000000000..cd6bea5205 --- /dev/null +++ b/.github/scripts/GitHub.py @@ -0,0 +1,187 @@ +## @file +# GitHub API helper functions. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import logging +import re +import requests + +from collections import OrderedDict +from edk2toollib.utility_functions import RunCmd, RunPythonScript +from io import StringIO +from typing import List + +"""GitHub API helper functions.""" + + +def leave_pr_comment( + token: str, owner: str, repo: str, pr_number: str, comment_body: str +): + """Leaves a comment on a PR. + + Args: + token (str): The GitHub token to use for authentication. + owner (str): The GitHub owner (organization) name. + repo (str): The GitHub repository name (e.g. 'edk2'). + pr_number (str): The pull request number. + comment_body (str): The comment text. Markdown is supported. + """ + url = f"https://api.github.com/repos/{owner}/{repo}/issues/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github.v3+json", + } + data = {"body": comment_body} + response = requests.post(url, json=data, headers=headers) + response.raise_for_status() + + +def get_reviewers_for_current_branch( + workspace_path: str, maintainer_file_path: str, target_branch: str = "master" +) -> List[str]: + """Get the reviewers for the current branch. + + Args: + workspace_path (str): The workspace path. + maintainer_file_path (str): The maintainer file path. + target_branch (str, optional): The name of the target branch that the + current HEAD will merge to. Defaults to "master". + + Returns: + List[str]: A list of GitHub usernames. + """ + + commit_stream_buffer = StringIO() + cmd_ret = RunCmd( + "git", + f"log --format=format:%H {target_branch}..HEAD", + workingdir=workspace_path, + outstream=commit_stream_buffer, + logging_level=logging.INFO, + ) + if cmd_ret != 0: + print( + f"::error title=Commit Lookup Error!::Error getting branch commits: [{cmd_ret}]: {commit_stream_buffer.getvalue()}" + ) + return [] + + raw_reviewers = [] + for commit_sha in commit_stream_buffer.getvalue().splitlines(): + reviewer_stream_buffer = StringIO() + cmd_ret = RunPythonScript( + maintainer_file_path, + f"-g {commit_sha}", + workingdir=workspace_path, + outstream=reviewer_stream_buffer, + logging_level=logging.INFO, + ) + if cmd_ret != 0: + print( + f"::error title=Reviewer Lookup Error!::Error calling GetMaintainer.py: [{cmd_ret}]: {reviewer_stream_buffer.getvalue()}" + ) + return [] + + commit_reviewers = reviewer_stream_buffer.getvalue() + + pattern = r"\[(.*?)\]" + matches = re.findall(pattern, commit_reviewers) + if not matches: + return [] + + print( + f"::debug title=Commit {commit_sha[:7]} Reviewer(s)::{', '.join(matches)}" + ) + + raw_reviewers.extend(matches) + + reviewers = list(OrderedDict.fromkeys([r.strip() for r in raw_reviewers])) + + print(f"::debug title=Total Reviewer Set::{', '.join(reviewers)}") + + return reviewers + + +def download_gh_file(github_url: str, local_path: str, token=None): + """Downloads a file from GitHub. + + Args: + github_url (str): The GitHub raw file URL. + local_path (str): A local path to write the file contents to. + token (_type_, optional): A GitHub authentication token. + Only needed for a private repo. Defaults to None. + """ + headers = {} + if token: + headers["Authorization"] = f"Bearer {token}" + + try: + response = requests.get(github_url, headers=headers) + response.raise_for_status() + except requests.exceptions.HTTPError: + print( + f"::error title=HTTP Error!::Error downloading {github_url}: {response.reason}" + ) + return + + with open(local_path, "w", encoding="utf-8") as file: + file.write(response.text) + + +def add_reviewers_to_pr( + token: str, owner: str, repo: str, pr_number: str, user_names: List[str] +): + """Adds the set of GitHub usernames as reviewers to the PR. + + Args: + token (str): The GitHub token to use for authentication. + owner (str): The GitHub owner (organization) name. + repo (str): The GitHub repository name (e.g. 'edk2'). + pr_number (str): The pull request number. + user_names (List[str]): List of GitHub usernames to add as reviewers. + """ + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github.v3+json", + } + pr_author_url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" + url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/requested_reviewers" + + response = requests.get(pr_author_url, headers=headers) + if response.status_code != 200: + print(f"::error title=HTTP Error!::Error getting PR author: {response.reason}") + return + pr_author = response.json().get("user").get("login").strip() + while pr_author in user_names: + user_names.remove(pr_author) + data = {"reviewers": user_names} + response = requests.post(url, json=data, headers=headers) + try: + response.raise_for_status() + except requests.exceptions.HTTPError: + if ( + response.status_code == 422 + and "Reviews may only be requested from collaborators" + in response.json().get("message") + ): + print( + f"::error title=User is not a Collaborator!::{response.json().get('message')}" + ) + leave_pr_comment( + token, + owner, + repo, + pr_number, + f"⚠ **WARNING: Cannot add reviewers**: A user specified as a " + f"reviewer for this PR is not a collaborator " + f"of the edk2 repository. Please add them as a collaborator to the " + f"repository and re-request the review.\n\n" + f"Users requested:\n{', '.join(user_names)}", + ) + elif response.status_code == 422: + print( + "::error title=Invalid Request!::The request is invalid. " + "Verify the API request string." + ) -- cgit From 6271b617b4e653029246152871cde93f3926e144 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 22 Jul 2024 17:42:43 -0400 Subject: .github/workflows/request-reviews.yml: Add workflow Adds a new GitHub workflow to automatically add reviewers to pull requests when they are opened, reopened, synchronized, and if a draft pull request is marked as ready for review. The workflow will not run on draft pull requests. The workflow is meant to be simple to understand and modify, relying on existing logic in GetMaintainer.py to determine the relevant reviewers and using simple Python GitHub REST API wrappers with the default GitHub token for authentication. Future changes may optimize the workflow. Signed-off-by: Michael Kubacki --- .github/workflows/request-reviews.yml | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/workflows/request-reviews.yml diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml new file mode 100644 index 0000000000..4f43d56122 --- /dev/null +++ b/.github/workflows/request-reviews.yml @@ -0,0 +1,73 @@ + +# This workflow automatically adds the appropriate reviewers to a pull request. +# +# The workflow directly reuses logic in the BaseTools/Scripts/GetMaintainer.py script +# to determine the appropriate reviewers, so it matches what a user would see running +# the script locally. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent + +name: Add Pull Request Reviewers + +on: + pull_request: + branches: + - master + types: [opened, ready_for_review, reopened, synchronize] + +env: + GET_MAINTAINER_REL_PATH: "BaseTools/Scripts/GetMaintainer.py" + +jobs: + auto-request-review: + name: Add Pull Request Reviewers + # Do not run on draft PRs and only run on PRs in the tianocore organization + if: ${{ github.event.pull_request.draft == false && github.repository_owner == 'tianocore' }} + runs-on: ubuntu-latest + + permissions: + contents: read + issues: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install PIP Modules + run: pip install edk2-pytool-library edk2-pytool-extensions requests + + - name: Add Reviewers to Pull Request + shell: python + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG_NAME: ${{ github.repository_owner }} + PR_NUMBER: ${{ github.event.number}} + REPO_NAME: ${{ github.event.pull_request.base.repo.name }} + TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} + WORKSPACE_PATH: ${{ github.workspace }} + run: | + import os + import sys + sys.path.append(os.path.join(os.environ['WORKSPACE_PATH'], ".github")) + from scripts import GitHub + + WORKSPACE_PATH = os.environ['WORKSPACE_PATH'] + GET_MAINTAINER_LOCAL_PATH = os.path.join(WORKSPACE_PATH, os.environ['GET_MAINTAINER_REL_PATH']) + + reviewers = GitHub.get_reviewers_for_current_branch(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, f"origin/{os.environ['TARGET_BRANCH']}") + if not reviewers: + print("::notice title=No Reviewers Found!::No reviewers found for this PR.") + sys.exit(1) + + print(f"::notice title=Reviewer List::Reviewers found for PR {os.environ['PR_NUMBER']}:\n{', '.join(reviewers)}") + + GitHub.add_reviewers_to_pr(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], os.environ['PR_NUMBER'], reviewers) -- cgit From 556640bceac32c86a843d09a1dd0688e44883781 Mon Sep 17 00:00:00 2001 From: Dongyan Qian Date: Tue, 25 Jun 2024 13:51:44 +0800 Subject: UefiCpuPkg/MpInitLib: Reduce compiler dependencies for LoongArch Structure assignment may depend on the compiler to expand to memcpy. For this, we may need to add -mno-memcpy to the compilation flag. Here, we reduce dependencies and use CopyMem for data conversion without memcpy. Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Jiaxin Wu Cc: Chao Li Signed-off-by: Dongyan Qian Co-authored-by: Chao Li --- UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c index c18671e95f..54c23ecf10 100644 --- a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c @@ -130,8 +130,8 @@ SortApicId ( } else { for ( ; Index2 <= ApCount; Index2++) { if (CpuInfoInHob[Index2].ApicId == INVALID_APIC_ID) { - CopyMem (&CpuInfoInHob[Index2], &CpuInfoInHob[Index1], sizeof (CPU_INFO_IN_HOB)); - CpuMpData->CpuData[Index2] = CpuMpData->CpuData[Index1]; + CopyMem (CpuInfoInHob + Index2, CpuInfoInHob + Index1, sizeof (CPU_INFO_IN_HOB)); + CopyMem (CpuMpData->CpuData + Index2, CpuMpData->CpuData + Index1, sizeof (CPU_AP_DATA)); CpuInfoInHob[Index1].ApicId = INVALID_APIC_ID; break; } -- cgit From 8665187b017b0e4e4febf2241b433e6371f6e7e1 Mon Sep 17 00:00:00 2001 From: HoraceX Lien Date: Wed, 17 Jul 2024 11:24:47 +0800 Subject: ShellPkg: Correct smbiosview strings for SMBIOS Type0 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4813 Some strings not match SMBIOS specification definition, include uppercase and lowercase, wrong characters, extra words,...etc Signed-off-by: HoraceX Lien Cc: Liming Gao Reviewed-by: Liming Gao --- .../SmbiosView/PrintInfo.c | 4 +- .../SmbiosView/SmbiosViewStrings.uni | 56 +++++++++++----------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c index e5a742950d..5c4413cbe3 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c @@ -1489,7 +1489,7 @@ DisplayBiosCharacteristics ( } if (BIT (Chara, 5) != 0) { - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MSA_SUPPORTED), gShellDebug1HiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MCA_SUPPORTED), gShellDebug1HiiHandle); } if (BIT (Chara, 6) != 0) { @@ -1600,7 +1600,7 @@ DisplayBiosCharacteristics ( // Just print the Reserved // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_32_47), gShellDebug1HiiHandle); - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_48_64), gShellDebug1HiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_48_63), gShellDebug1HiiHandle); } /** diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni index 971e0d09bd..d55af31884 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni @@ -119,52 +119,52 @@ #string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR #language en-US "BIOS Characteristics: \r\n" #string STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT #language en-US "Reserved bit\r\n" #string STR_SMBIOSVIEW_PRINTINFO_UNKNOWN_BIT #language en-US "Unknown bit\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_NOT_SUPPORTED #language en-US "BIOS Characteristics Not Supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_NOT_SUPPORTED #language en-US "BIOS Characteristics are not supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_ISA_SUPPORTED #language en-US "ISA is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_MSA_SUPPORTED #language en-US "MSA is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_MCA_SUPPORTED #language en-US "MCA is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_EISA_SUPPORTED #language en-US "EISA is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_PCI_SUPPORTED #language en-US "PCI is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_PC_CARD_SUPPORTED #language en-US "PC Card(PCMCIA) is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_PC_CARD_SUPPORTED #language en-US "PC card (PCMCIA) is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_PLUG_PLAY_SUPPORTED #language en-US "Plug and play is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_APM_SUPPORTED #language en-US "APM is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BIOS_UPGRADEABLE #language en-US "BIOS is Upgradeable(FLASH)\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BIOS_UPGRADEABLE #language en-US "BIOS is upgradeable (Flash)\r\n" #string STR_SMBIOSVIEW_PRINTINFO_BIOS_SHADOWING #language en-US "BIOS shadowing is allowed\r\n" #string STR_SMBIOSVIEW_PRINTINFO_VESA_SUPPORTED #language en-US "VL-VESA is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_ECSD_SUPPORT #language en-US "ESCD support is available\r\n" #string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_CD_SUPPORTED #language en-US "Boot from CD is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_SELECTED_BOOT_SUPPORTED #language en-US "Selectable Boot is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BIOS_ROM_SOCKETED #language en-US "BIOS ROM is socketed\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_PC_CARD #language en-US "Boot From PC Card(PCMCIA)is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_EDD_ENHANCED_DRIVER #language en-US "EDD (Enhanced Disk Driver) Specification is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_NEC #language en-US "Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5\",1k Bytes/Sector, 360 RPM) is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_TOSHIBA #language en-US "Int 13h - Japanese Floppy for Toshiba 1.2mn (3.5\", 360 RPM) is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_FLOPPY_SERVICES_SUPPORTED #language en-US "Int 13h - 5.25\"/360KB Floppy Services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_ONE_POINT_TWO_MB #language en-US "Int 13h - 5.25\"/1.2MB Floppy services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_720_KB #language en-US "Int 13h - 3.5\"/720KB Floppy services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_TWO_POINT_EIGHT_EIGHT_MB #language en-US "Int 13h - 3.5\"/2.88MB Floppy services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_PRINT_SCREEN_SUPPORT #language en-US "Int 5h, Print screen Services is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_SERV_SUPPORT #language en-US "Int 9h, 8042 Keyboard services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_SERIAL_SERVICES_SUPPORT #language en-US "Int 14h, Serial Services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_PRINTER_SERVICES_SUPPORT #language en-US "Int 17h, Printer services are supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_MONO_VIDEO_SUPPORT #language en-US "Int 10h, CGA/Mono Video services are supported2\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BIOS_ROM_SOCKETED #language en-US "BIOS ROM is socketed (e.g., PLCC or SOP socket)\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_PC_CARD #language en-US "Boot from PC card (PCMCIA) is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_EDD_ENHANCED_DRIVER #language en-US "EDD specification is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_NEC #language en-US "Int 13h - Japanese floppy for NEC 9800 1.2MB (3.5\", 1K bytes/sector, 360 RPM) is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_TOSHIBA #language en-US "Int 13h - Japanese floppy for Toshiba 1.2MB (3.5\", 360 RPM) is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_FLOPPY_SERVICES_SUPPORTED #language en-US "Int 13h - 5.25\"/360KB floppy services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_ONE_POINT_TWO_MB #language en-US "Int 13h - 5.25\"/1.2MB floppy services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_720_KB #language en-US "Int 13h - 3.5\"/720KB floppy services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_TWO_POINT_EIGHT_EIGHT_MB #language en-US "Int 13h - 3.5\"/2.88MB floppy services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_PRINT_SCREEN_SUPPORT #language en-US "Int 5h, print screen Services is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_SERV_SUPPORT #language en-US "Int 9h, 8042 keyboard services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_SERIAL_SERVICES_SUPPORT #language en-US "Int 14h, serial services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_PRINTER_SERVICES_SUPPORT #language en-US "Int 17h, printer services are supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_MONO_VIDEO_SUPPORT #language en-US "Int 10h, CGA/Mono Video Services are supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_NEC_PC_98 #language en-US "NEC PC-98\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BITS_32_47 #language en-US " Bits 32:47 are reserved for BIOS Vendor\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BITS_48_64 #language en-US " Bits 48:64 are reserved for System Vendor\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BITS_32_47 #language en-US " Bits 32:47 are reserved for BIOS vendor\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BITS_48_63 #language en-US " Bits 48:63 are reserved for system vendor\r\n" #string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION #language en-US "BIOS Characteristics Extension Byte1:\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_ACPI_SUPPORTED #language en-US "ACPI supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_ACPI_SUPPORTED #language en-US "ACPI is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_USB_LEGACY_SUPPORTED #language en-US "USB Legacy is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_AGP_SUPPORTED #language en-US "AGP is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_I2O_BOOT_SUPPORTED #language en-US "I2O boot is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_LS_120_BOOT_SUPPORTED #language en-US "LS-120 boot is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_ATAPI_ZIP_DRIVE #language en-US "ATAPI ZIP Drive boot is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_LS_120_BOOT_SUPPORTED #language en-US "LS-120 SuperDisk boot is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_ATAPI_ZIP_DRIVE #language en-US "ATAPI ZIP drive boot is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_1394_BOOT_SUPPORTED #language en-US "1394 boot is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_SMART_BATTERY_SUPPORTED #language en-US "Smart battery supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_SMART_BATTERY_SUPPORTED #language en-US "Smart battery is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION_2 #language en-US "BIOS Characteristics Extension Byte2:\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_BIOS_BOOT_SPEC_SUPP #language en-US "BIOS Boot Specification supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_FUNCTION_KEY_INIT #language en-US "Function key-initiated Network Service boot supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_ENABLE_TAR_CONT_DIST #language en-US "Enable Targeted Content Distribution\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_BIOS_BOOT_SPEC_SUPP #language en-US "BIOS Boot Specification is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_FUNCTION_KEY_INIT #language en-US "Function key-initiated network service boot is supported\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_ENABLE_TAR_CONT_DIST #language en-US "Enable targeted content distribution\r\n" #string STR_SMBIOSVIEW_PRINTINFO_UEFI_SPEC_SUPPORT #language en-US "UEFI Specification is supported\r\n" -#string STR_SMBIOSVIEW_PRINTINFO_VIRTUAL_MACHINE #language en-US "The SMBIOS table describes a virtual machine\r\n" +#string STR_SMBIOSVIEW_PRINTINFO_VIRTUAL_MACHINE #language en-US "SMBIOS table describes a virtual machine\r\n" #string STR_SMBIOSVIEW_PRINTINFO_MCFG_SUPPORTED #language en-US "Manufacturing mode is supported\r\n" #string STR_SMBIOSVIEW_PRINTINFO_MCFG_ENABLED #language en-US "Manufacturing mode is enabled\r\n" #string STR_SMBIOSVIEW_PRINTINFO_BITS_RSVD_FOR_FUTURE #language en-US " Bits %d:7 are reserved for future assignment\r\n" -- cgit From 43130ae4034cdcf0fa0ff928105fbe3e52d9f628 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 24 Jul 2024 23:04:35 +0200 Subject: ArmPkg: Convert PcdMonitorConduitHvc to FixedAtBuild Feature PCDs and fixed-at-build PCDs are identical in concept, but the latter are accessible from assembler, whereas the former are not. So convert the SMCCC conduit selection PCD to fixed-at-build so we can make use of this in a subsequent patch. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Ard Biesheuvel --- ArmPkg/ArmPkg.dec | 10 +++++----- ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c | 2 +- ArmVirtPkg/ArmVirt.dsc.inc | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index c0861140e8..49cbffa5fc 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -135,11 +135,6 @@ # Define if the GICv3 controller should use the GICv2 legacy gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042 - ## Define the conduit to use for monitor calls. - # Default PcdMonitorConduitHvc = FALSE, conduit = SMC - # If PcdMonitorConduitHvc = TRUE, conduit = HVC - gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047 - # Whether to remap all unused memory NX before installing the CPU arch # protocol driver. This is needed on platforms that map all DRAM with RWX # attributes initially, and can be disabled otherwise. @@ -229,6 +224,11 @@ # gArmTokenSpaceGuid.PcdUefiShellDefaultBootEnable|FALSE|BOOLEAN|0x0000052 + ## Define the conduit to use for monitor calls. + # Default PcdMonitorConduitHvc = FALSE, conduit = SMC + # If PcdMonitorConduitHvc = TRUE, conduit = HVC + gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047 + [PcdsFixedAtBuild.common, PcdsPatchableInModule.common] gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c index 741f5c6157..72f71296e5 100644 --- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c +++ b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c @@ -26,7 +26,7 @@ ArmMonitorCall ( IN OUT ARM_MONITOR_ARGS *Args ) { - if (FeaturePcdGet (PcdMonitorConduitHvc)) { + if (FixedPcdGetBool (PcdMonitorConduitHvc)) { ArmCallHvc ((ARM_HVC_ARGS *)Args); } else { ArmCallSmc ((ARM_SMC_ARGS *)Args); diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 038931562c..eb0bca24ea 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -289,8 +289,6 @@ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE - gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE - [PcdsFeatureFlag.AARCH64] # # Activate AcpiSdtProtocol @@ -298,6 +296,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE [PcdsFixedAtBuild.common] + gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE + !ifdef $(FIRMWARE_VER) gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)" !endif -- cgit From b1bce5e5649840159d54eb8bffa4fa3d4fae8ee6 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 24 Jul 2024 23:33:08 +0200 Subject: ArmPkg/ArmMonitorLib: Implement SMCCC protocol correctly and directly The SMCCC protocol stipulates the following: - on AARCH64, 18 arguments can be passed, and 18 values can be returned, via registers X0-x17; - on ARM, 8 arguments can be passed, and 8 values can be returned. This makes ArmSmcLib and ArmHvcLib as implemented currently unsuitable for use with SMCCC services in general, although for PSCI in particular, they work fine. The dependency on both ArmSmcLib and ArmHvcLib is also impractical because it requires every platform that consumes ArmMonitorLib to provide resolutions for each, even though most platforms will only ever need one of these (and the choice is made at compile time) So let's drop these dependencies, and re-implement the asm helpers from scratch. Note that the only difference is the actual instruction used -HVC vs SMC- and so all other code can be shared. Signed-off-by: Ard Biesheuvel --- ArmPkg/Include/Library/ArmMonitorLib.h | 12 ++++ .../Library/ArmMonitorLib/AArch64/ArmMonitorLib.S | 79 ++++++++++++++++++++++ ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S | 49 ++++++++++++++ ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c | 34 ---------- ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf | 11 ++- 5 files changed, 145 insertions(+), 40 deletions(-) create mode 100644 ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S create mode 100644 ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S delete mode 100644 ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c diff --git a/ArmPkg/Include/Library/ArmMonitorLib.h b/ArmPkg/Include/Library/ArmMonitorLib.h index d6e13b61d6..1192ee2888 100644 --- a/ArmPkg/Include/Library/ArmMonitorLib.h +++ b/ArmPkg/Include/Library/ArmMonitorLib.h @@ -23,6 +23,18 @@ typedef struct { UINTN Arg5; UINTN Arg6; UINTN Arg7; + #ifdef MDE_CPU_AARCH64 + UINTN Arg8; + UINTN Arg9; + UINTN Arg10; + UINTN Arg11; + UINTN Arg12; + UINTN Arg13; + UINTN Arg14; + UINTN Arg15; + UINTN Arg16; + UINTN Arg17; + #endif } ARM_MONITOR_ARGS; /** Monitor call. diff --git a/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S b/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S new file mode 100644 index 0000000000..a99adf00ad --- /dev/null +++ b/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S @@ -0,0 +1,79 @@ +// +// Copyright (c) 2024, Google Llc. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include + +/** Monitor call. + + An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued + depending on the default conduit. PcdMonitorConduitHvc determines the type + of the call: if true, do an HVC. + + @param [in,out] Args Arguments for the HVC/SMC. +**/ +ASM_FUNC(ArmMonitorCall) + // Create a stack frame + stp x29, x30, [sp, #-16]! + mov x29, sp + + // Preserve X0 for later use + mov x30, x0 + + // Load the SMCCC arguments values into the appropriate registers + ldp x0, x1, [x30, #0] + ldp x2, x3, [x30, #16] + ldp x4, x5, [x30, #32] + ldp x6, x7, [x30, #48] + ldp x8, x9, [x30, #64] + ldp x10, x11, [x30, #80] + ldp x12, x13, [x30, #96] + ldp x14, x15, [x30, #112] + ldp x16, x17, [x30, #128] + +#if !defined(_PCD_VALUE_PcdMonitorConduitHvc) +#error +#elif _PCD_VALUE_PcdMonitorConduitHvc == 0 + smc #0 +#elif _PCD_VALUE_PcdMonitorConduitHvc == 1 + hvc #0 +#else +#error +#endif + + // A SMCCC SMC64/HVC64 call can return up to 18 values. + stp x0, x1, [x30, #0] + stp x2, x3, [x30, #16] + stp x4, x5, [x30, #32] + stp x6, x7, [x30, #48] + stp x8, x9, [x30, #64] + stp x10, x11, [x30, #80] + stp x12, x13, [x30, #96] + stp x14, x15, [x30, #112] + stp x16, x17, [x30, #128] + + // Clear return values from registers + mov x0, xzr + mov x1, xzr + mov x2, xzr + mov x3, xzr + mov x4, xzr + mov x5, xzr + mov x6, xzr + mov x7, xzr + mov x8, xzr + mov x9, xzr + mov x10, xzr + mov x11, xzr + mov x12, xzr + mov x13, xzr + mov x14, xzr + mov x15, xzr + mov x16, xzr + mov x17, xzr + + ldp x29, x30, [sp], #16 + ret diff --git a/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S b/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S new file mode 100644 index 0000000000..9029059cf4 --- /dev/null +++ b/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S @@ -0,0 +1,49 @@ +// +// Copyright (c) 2024, Google Llc. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include + +/** Monitor call. + + An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued + depending on the default conduit. PcdMonitorConduitHvc determines the type + of the call: if true, do an HVC. + + @param [in,out] Args Arguments for the HVC/SMC. +**/ +ASM_FUNC(ArmMonitorCall) + push {r4-r7} + + // Preserve R0 for later use + mov ip, r0 + + // Load the SMCCC arguments values into the appropriate registers + ldm r0, {r0-r7} + +#if !defined(_PCD_VALUE_PcdMonitorConduitHvc) +#error +#elif _PCD_VALUE_PcdMonitorConduitHvc == 0 + .arch_extension sec + smc #0 +#elif _PCD_VALUE_PcdMonitorConduitHvc == 1 + .arch_extension virt + hvc #0 +#else +#error +#endif + + // A SMCCC SMC32/HVC32 call can return up to 8 values. + stm ip, {r0-r7} + + // Clear return values from registers + mov r0, #0 + mov r1, #0 + mov r2, #0 + mov r3, #0 + + pop {r4-r7} + bx lr diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c deleted file mode 100644 index 72f71296e5..0000000000 --- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c +++ /dev/null @@ -1,34 +0,0 @@ -/** @file - Arm Monitor Library. - - Copyright (c) 2022, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include - -/** Monitor call. - - An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued - depending on the default conduit. PcdMonitorConduitHvc determines the type - of the call: if true, do an HVC. - - @param [in,out] Args Arguments for the HVC/SMC. -**/ -VOID -EFIAPI -ArmMonitorCall ( - IN OUT ARM_MONITOR_ARGS *Args - ) -{ - if (FixedPcdGetBool (PcdMonitorConduitHvc)) { - ArmCallHvc ((ARM_HVC_ARGS *)Args); - } else { - ArmCallSmc ((ARM_SMC_ARGS *)Args); - } -} diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf index f504cb80f1..06fbab28b6 100644 --- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf +++ b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf @@ -14,16 +14,15 @@ VERSION_STRING = 1.0 LIBRARY_CLASS = ArmMonitorLib -[Sources] - ArmMonitorLib.c +[Sources.ARM] + Arm/ArmMonitorLib.S + +[Sources.AARCH64] + AArch64/ArmMonitorLib.S [Packages] ArmPkg/ArmPkg.dec MdePkg/MdePkg.dec -[LibraryClasses] - ArmHvcLib - ArmSmcLib - [Pcd] gArmTokenSpaceGuid.PcdMonitorConduitHvc -- cgit From 41426040daab53efc31265560050be6fdd96e879 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 18 Jul 2024 16:32:08 -0700 Subject: BaseTools: Move MEMORY_TYPE_* Defines to EFI_MEMORY_TYPE Enum Per TCBZ2372, clang on Linux emits a warning if an enum-typed variable is compared with a constant outside of the range of the enum. Such comparisons are performed in multiple locations in DXE core on variables of type EFI_MEMORY_TYPE. This patch moves the OEM and OS reserved types into the EFI_MEMORY_TYPE enum itself to resolve this issue and improve readability. This commit does this for the BaseTools copy of this enum. Signed-off-by: Oliver Smith-Denny --- BaseTools/Source/C/Include/Common/UefiMultiPhase.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/BaseTools/Source/C/Include/Common/UefiMultiPhase.h b/BaseTools/Source/C/Include/Common/UefiMultiPhase.h index b889508b85..5b5af8b43c 100644 --- a/BaseTools/Source/C/Include/Common/UefiMultiPhase.h +++ b/BaseTools/Source/C/Include/Common/UefiMultiPhase.h @@ -14,6 +14,15 @@ // // Enumeration of memory types introduced in UEFI. +// +---------------------------------------------------+ +// | 0..(EfiMaxMemoryType - 1) - Normal memory type | +// +---------------------------------------------------+ +// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | +// +---------------------------------------------------+ +// | 0x70000000..0x7FFFFFFF - OEM reserved | +// +---------------------------------------------------+ +// | 0x80000000..0xFFFFFFFF - OS reserved | +// +---------------------------------------------------+ // typedef enum { EfiReservedMemoryType, @@ -31,7 +40,11 @@ typedef enum { EfiMemoryMappedIOPortSpace, EfiPalCode, EfiPersistentMemory, - EfiMaxMemoryType + EfiMaxMemoryType, + MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000, + MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF, + MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000, + MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF } EFI_MEMORY_TYPE; -- cgit From c82ca2bb4441b92bea768d710f10a4e260e32e07 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Sun, 30 Jun 2024 08:40:55 -0700 Subject: MdePkg: Move MEMORY_TYPE_* Defines to EFI_MEMORY_TYPE Enum Per TCBZ2372, clang on Linux emits a warning if an enum-typed variable is compared with a constant outside of the range of the enum. Such comparisons are performed in multiple locations in DXE core on variables of type EFI_MEMORY_TYPE. This patch moves the OEM and OS reserved types into the EFI_MEMORY_TYPE enum itself to resolve this issue and improve readability. This commit does this for the MdePkg copy of this enum. Signed-off-by: Oliver Smith-Denny --- MdePkg/Include/Uefi/UefiMultiPhase.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Uefi/UefiMultiPhase.h b/MdePkg/Include/Uefi/UefiMultiPhase.h index 7884913371..1f1f3f45e5 100644 --- a/MdePkg/Include/Uefi/UefiMultiPhase.h +++ b/MdePkg/Include/Uefi/UefiMultiPhase.h @@ -108,7 +108,22 @@ typedef enum { /// by a corresponding call to the underlying isolation architecture. /// EfiUnacceptedMemoryType, - EfiMaxMemoryType + EfiMaxMemoryType, + // + // +---------------------------------------------------+ + // | 0..(EfiMaxMemoryType - 1) - Normal memory type | + // +---------------------------------------------------+ + // | EfiMaxMemoryType..0x6FFFFFFF - Invalid | + // +---------------------------------------------------+ + // | 0x70000000..0x7FFFFFFF - OEM reserved | + // +---------------------------------------------------+ + // | 0x80000000..0xFFFFFFFF - OS reserved | + // +---------------------------------------------------+ + // + MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000, + MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF, + MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000, + MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF } EFI_MEMORY_TYPE; /// -- cgit From ffc09b51cb7cc47bc80730d6c9e14563140dd052 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Sun, 30 Jun 2024 08:42:08 -0700 Subject: MdeModulePkg: Remove EFI_MEMORY_* Defines Now that all of the EFI_MEMORY_* defines live in the EFI_MEMORY_TYPE enum, remove the old defines. Signed-off-by: Oliver Smith-Denny --- MdeModulePkg/Core/Dxe/Mem/Imem.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h index 2f0bf2bf63..84027d628b 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h +++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h @@ -9,22 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _IMEM_H_ #define _IMEM_H_ -// -// +---------------------------------------------------+ -// | 0..(EfiMaxMemoryType - 1) - Normal memory type | -// +---------------------------------------------------+ -// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | -// +---------------------------------------------------+ -// | 0x70000000..0x7FFFFFFF - OEM reserved | -// +---------------------------------------------------+ -// | 0x80000000..0xFFFFFFFF - OS reserved | -// +---------------------------------------------------+ -// -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 -#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF - // // MEMORY_MAP_ENTRY // -- cgit From 68300746421eed4df291e4d075c1fd566d1d5169 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 22 Jul 2024 11:49:07 -0400 Subject: ShellPkg: Add missing apps ShellPkg.dsc is missing a few applications in the package. They are added to the DSC in this change to include the ShellPkg build. Signed-off-by: Michael Kubacki --- ShellPkg/ShellPkg.dsc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc index 557b0ec0f3..720288e2f5 100644 --- a/ShellPkg/ShellPkg.dsc +++ b/ShellPkg/ShellPkg.dsc @@ -139,6 +139,11 @@ NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf } + ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf + ShellPkg/Application/ShellCTestApp/ShellCTestApp.inf + ShellPkg/Application/ShellExecTestApp/SA.inf + ShellPkg/Application/ShellSortTestApp/ShellSortTestApp.inf + ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf { gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE @@ -159,7 +164,6 @@ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE } ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.inf - ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf [BuildOptions] *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -- cgit From 6589843cc619b3a5e2d2c0e5b12451b11a3f2288 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Thu, 25 Jul 2024 15:46:17 -0400 Subject: BaseTools/codeql: Update to CodeQL 2.18.1 Updates to the latest CodeQL version to resolve query dependencies. Signed-off-by: Michael Kubacki --- BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml | 6 +++--- BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml | 6 +++--- BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml index dbc9c2ba02..842c144f0b 100644 --- a/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml +++ b/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml @@ -16,9 +16,9 @@ "scope": "codeql-ext-dep", "type": "web", "name": "codeql_cli", - "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.17.3/codeql.zip", - "version": "2.17.3", - "sha256": "e5ac1d87ab38e405c9af5db234a338b10dffabc98a648903f1664dd2a566dfd5", + "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.18.1/codeql.zip", + "version": "2.18.1", + "sha256": "815f71c1a46e76f9dafdec26c2a4bab7ea4019a3773e91e39253e2d21cf792a2", "compression_type": "zip", "internal_path": "/codeql/", "flags": ["set_shell_var", ], diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml index 536322f2b3..1972cde74b 100644 --- a/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml +++ b/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml @@ -14,9 +14,9 @@ "scope": "codeql-linux-ext-dep", "type": "web", "name": "codeql_linux_cli", - "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.17.3/codeql-linux64.zip", - "version": "2.17.3", - "sha256": "9fba000c4b821534d354bc16821aa066fdb1304446226ea449870e64a8ad3c7a", + "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.18.1/codeql-linux64.zip", + "version": "2.18.1", + "sha256": "1547f4a3b509474404daf2e4b821f71cd93462ec45322d9124c2b04e3d52c771", "compression_type": "zip", "internal_path": "/codeql/", "flags": ["set_shell_var", ], diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml index 93a81ffd50..28ad30e790 100644 --- a/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml +++ b/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml @@ -14,9 +14,9 @@ "scope": "codeql-windows-ext-dep", "type": "web", "name": "codeql_windows_cli", - "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.17.3/codeql-win64.zip", - "version": "2.17.3", - "sha256": "4c6fbf2ea2eaf0f47bf0347eacf54c6b9d6bdf7acb6b63e17f9e6f2dd83b34e7", + "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.18.1/codeql-win64.zip", + "version": "2.18.1", + "sha256": "eb69c9ce40142904965ca3f2491c989f12747d74358385e2e94c427b4324201c", "compression_type": "zip", "internal_path": "/codeql/", "flags": ["set_shell_var", ], -- cgit From 03ad59e631aaab0143c5b1c1d64f27f5da1eb8c4 Mon Sep 17 00:00:00 2001 From: George Liao Date: Mon, 17 Jun 2024 16:48:21 +0800 Subject: MdeModulePkg: Consume SOC related ACPI table from ACPI Silicon HOB REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4787 If ACPI Silicon Hob has been found from entry of AcpiTableDxe driver, that means SOC related ACPI tables been pass to the DXE phase by HOB. Each SOC related ACPI tables will be install. Signed-off-by: George Liao --- MdeModulePkg/MdeModulePkg.dec | 3 + .../Universal/Acpi/AcpiTableDxe/AcpiTable.h | 6 ++ .../Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf | 1 + .../Acpi/AcpiTableDxe/AcpiTableProtocol.c | 119 +++++++++++++++++++++ 4 files changed, 129 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index e6e0139fdc..6ed4c5bf1c 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -475,6 +475,9 @@ ## Include/Guid/VariableRuntimeCacheInfo.h gEdkiiVariableRuntimeCacheInfoHobGuid = { 0x0f472f7d, 0x6713, 0x4915, { 0x96, 0x14, 0x5d, 0xda, 0x28, 0x40, 0x10, 0x56 }} + ## HOB GUID to get ACPI table after FSP is done. The ACPI table that related SOC will be pass by this HOB. + gAcpiTableHobGuid = { 0xf9886b57, 0x8a35, 0x455e, { 0xbb, 0xb1, 0x14, 0x65, 0x5e, 0x7b, 0xe7, 0xec }} + [Ppis] ## Include/Ppi/FirmwareVolumeShadowPpi.h gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } } diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h index 9cfef3d718..3caa20d9eb 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h @@ -126,6 +126,12 @@ typedef struct { EFI_ACPI_TABLE_SIGNATURE \ ) +// +// ACPI HOB produced by silicon initialization code will provide the RSDP structure. +// +typedef struct { + EFI_PHYSICAL_ADDRESS Rsdp; +} ACPI_SILICON_HOB; // // Protocol Constructor functions // diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf index be498a56cf..8d147a3a0d 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf @@ -57,6 +57,7 @@ gEfiAcpi10TableGuid ## PRODUCES ## SystemTable gEfiAcpiTableGuid ## PRODUCES ## SystemTable gUniversalPayloadAcpiTableGuid ## SOMETIMES_CONSUMES ## HOB + gAcpiTableHobGuid ## SOMETIMES_CONSUMES ## HOB [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol ## CONSUMES diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c index 45c0ae6c80..f2a7be5778 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c @@ -1947,6 +1947,107 @@ InstallAcpiTableFromHob ( return Status; } +/** + This function is updating the instance with RSDP and RSDT, these are steps in the constructor that will be skipped if this HOB is available. + + @param AcpiTableInstance Protocol instance private data. + @param GuidHob GUID HOB header. + + @return EFI_SUCCESS The function completed successfully. + @return EFI_NOT_FOUND The function doesn't find the Rsdp from AcpiSiliconHob. + @return EFI_ABORTED The function could not complete successfully. + +**/ +EFI_STATUS +InstallAcpiTableFromAcpiSiliconHob ( + EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, + EFI_HOB_GUID_TYPE *GuidHob + ) +{ + ACPI_SILICON_HOB *AcpiSiliconHob; + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *SiAcpiHobRsdp; + EFI_ACPI_DESCRIPTION_HEADER *SiCommonAcpiTable; + EFI_STATUS Status; + UINT8 *TempBuffer; + UINTN NumOfTblEntries; + + DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob\n")); + // + // Initial variable. + // + SiAcpiHobRsdp = NULL; + SiCommonAcpiTable = NULL; + AcpiSiliconHob = GET_GUID_HOB_DATA (GuidHob); + Status = EFI_SUCCESS; + // + // Got RSDP table from ACPI Silicon Hob. + // + SiAcpiHobRsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)(AcpiSiliconHob->Rsdp); + if (SiAcpiHobRsdp == NULL) { + DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to locate RSDP Acpi table!!\n")); + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%lx\n", SiAcpiHobRsdp)); + AcpiTableInstance->Rsdp3 = SiAcpiHobRsdp; + + if (SiAcpiHobRsdp->RsdtAddress != 0x00000000) { + // + // Initial RSDT. + // + TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->RsdtAddress); + SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer; + AcpiTableInstance->Rsdt3 = SiCommonAcpiTable; + + if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) { + DEBUG ((DEBUG_ERROR, "RSDT length is incorrect\n")); + return EFI_ABORTED; + } + + // + // Calcaue 32bit Acpi table number. + // + NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32); + AcpiTableInstance->NumberOfTableEntries1 = NumOfTblEntries; + DEBUG ((DEBUG_INFO, "32bit NumOfTblEntries : 0x%x\n", NumOfTblEntries)); + // + // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES + // + if (AcpiTableInstance->NumberOfTableEntries1 >= EFI_ACPI_MAX_NUM_TABLES) { + mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries1 + EFI_ACPI_MAX_NUM_TABLES; + DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables)); + } + } else { + // + // Initial XSDT. + // + TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress); + SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer; + AcpiTableInstance->Xsdt = SiCommonAcpiTable; + + if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) { + DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n")); + return EFI_ABORTED; + } + + // + // Calcaue 64bit Acpi table number. + // + NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64); + AcpiTableInstance->NumberOfTableEntries3 = NumOfTblEntries; + DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries)); + // + // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES + // + if (AcpiTableInstance->NumberOfTableEntries3 >= EFI_ACPI_MAX_NUM_TABLES) { + mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries3 + EFI_ACPI_MAX_NUM_TABLES; + DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables)); + } + } + + return Status; +} + /** Constructor for the ACPI table protocol. Initializes instance data. @@ -1969,6 +2070,7 @@ AcpiTableAcpiTableConstructor ( UINT8 *Pointer; EFI_PHYSICAL_ADDRESS PageAddress; EFI_MEMORY_TYPE AcpiAllocateMemoryType; + EFI_HOB_GUID_TYPE *GuidHob; // // Check for invalid input parameters @@ -1995,6 +2097,23 @@ AcpiTableAcpiTableConstructor ( SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance); } + // + // Check Silicon ACPI Hob. + // + GuidHob = GetFirstGuidHob (&gAcpiTableHobGuid); + if (GuidHob != NULL) { + Status = InstallAcpiTableFromAcpiSiliconHob (AcpiTableInstance, GuidHob); + if (Status == EFI_SUCCESS) { + DEBUG ((DEBUG_INFO, "Installed ACPI Table from AcpiSiliconHob.\n")); + return EFI_SUCCESS; + } else { + DEBUG ((DEBUG_ERROR, "Fail to Installed ACPI Table from AcpiSiliconHob!!\n")); + ASSERT (Status != EFI_SUCCESS); + } + } else { + DEBUG ((DEBUG_INFO, "Fail to locate AcpiSiliconHob!!\n")); + } + // // Create RSDP table // -- cgit From d7e36ccbbde76ab39dd8bb21c3712767c2f2c98f Mon Sep 17 00:00:00 2001 From: Sean Brogan Date: Wed, 24 May 2017 18:52:24 -0700 Subject: MdeModulePkg: Add NVMe Long Delay Time Events Fire an event if a long delay occurs when starting an NVMe device. This can be used by platforms to draw pictures on the screen or take other actions to notify a user or move boot forward. Signed-off-by: Oliver Smith-Denny --- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h | 2 ++ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf | 5 +++++ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c | 10 ++++++++-- MdeModulePkg/Include/Guid/NVMeEventGroup.h | 16 ++++++++++++++++ MdeModulePkg/MdeModulePkg.dec | 7 +++++++ 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 MdeModulePkg/Include/Guid/NVMeEventGroup.h diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h index 4c26b2e1b4..2b9ab8a08e 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h @@ -41,6 +41,8 @@ #include #include +#include + typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA; typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA; diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf index dc1990c327..1a29c0b907 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf @@ -41,8 +41,13 @@ NvmExpressHci.h NvmExpressPassthru.c +[Guids] + gNVMeEnableStartEventGroupGuid + gNVMeEnableCompleteEventGroupGuid + [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec [LibraryClasses] BaseMemoryLib diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c index b90c48731c..e1b0ee6051 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c @@ -8,6 +8,7 @@ **/ #include "NvmExpress.h" +#include #define NVME_SHUTDOWN_PROCESS_TIMEOUT 45 @@ -399,6 +400,8 @@ NvmeEnableController ( UINT32 Index; UINT8 Timeout; + EfiEventGroupSignal (&gNVMeEnableStartEventGroupGuid); + // // Enable the controller. // CC.AMS, CC.MPS and CC.CSS are all set to 0. @@ -410,7 +413,7 @@ NvmeEnableController ( Status = WriteNvmeControllerConfiguration (Private, &Cc); if (EFI_ERROR (Status)) { - return Status; + goto Cleanup; } // @@ -432,7 +435,7 @@ NvmeEnableController ( Status = ReadNvmeControllerStatus (Private, &Csts); if (EFI_ERROR (Status)) { - return Status; + goto Cleanup; } if (Csts.Rdy) { @@ -449,6 +452,9 @@ NvmeEnableController ( } DEBUG ((DEBUG_INFO, "NVMe controller is enabled with status [%r].\n", Status)); + +Cleanup: + EfiEventGroupSignal (&gNVMeEnableCompleteEventGroupGuid); return Status; } diff --git a/MdeModulePkg/Include/Guid/NVMeEventGroup.h b/MdeModulePkg/Include/Guid/NVMeEventGroup.h new file mode 100644 index 0000000000..bd59b0cb8f --- /dev/null +++ b/MdeModulePkg/Include/Guid/NVMeEventGroup.h @@ -0,0 +1,16 @@ +/** @file + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef NVME_EVENT_GROUP_GUID_ +#define NVME_EVENT_GROUP_GUID_ + +// gNVMeEnableStartEventGroupGuid is used to signal the start of enabling the NVMe controller +extern EFI_GUID gNVMeEnableStartEventGroupGuid; +// gNVMeEnableCompleteEventGroupGuid is used to signal that the NVMe controller enable has finished +extern EFI_GUID gNVMeEnableCompleteEventGroupGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 6ed4c5bf1c..3b484db913 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -413,6 +413,13 @@ ## Include/Guid/EndofS3Resume.h gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } } + # + # Guids for NVMe Timeout Events + # {4754469d-6528-4dfc-84aa-8c8a03a2158b} + gNVMeEnableStartEventGroupGuid = { 0x4754469d, 0x6528, 0x4dfc, { 0x84, 0xaa, 0x8c, 0x8a, 0x03, 0xa2, 0x15, 0x8b } } + # {da383315-906b-486f-80db-847f268451e4} + gNVMeEnableCompleteEventGroupGuid = { 0xda383315, 0x906b, 0x486f, { 0x80, 0xdb, 0x84, 0x7f, 0x26, 0x84, 0x51, 0xe4 } } + ## Used (similar to Variable Services) to communicate policies to the enforcement engine. # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB} gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }} -- cgit From 7868d509dd33af30f57de76d8fd67117cf23c8a7 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Thu, 25 Jul 2024 21:26:02 -0400 Subject: .azurepipelines: Disable the PR gate code coverage job REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4819 Code Coverage was added to PR pipelines in 89c5d90 and is currently running on every pull request. It is run in a separate job that is queued after all builds from the build matrix have completed. This means it extends the entire pipeline run by placing it at the beginning of the build queue right when it should be finished. In turn, pipeline runs that should finish in 30 minutes are taking over 3 hours. This has a substantial impact on the developer efficiency of the entire community. This patch disables code coverage until a more sustainable solution can be swapped in. Users can still get code coverage locally. Signed-off-by: Michael Kubacki --- .azurepipelines/templates/pr-gate-build-job.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azurepipelines/templates/pr-gate-build-job.yml b/.azurepipelines/templates/pr-gate-build-job.yml index 689e2f0987..3cad858ea2 100644 --- a/.azurepipelines/templates/pr-gate-build-job.yml +++ b/.azurepipelines/templates/pr-gate-build-job.yml @@ -90,6 +90,9 @@ jobs: extra_install_step: ${{ parameters.extra_install_step }} - job: Build_${{ parameters.tool_chain_tag }}_TARGET_CODE_COVERAGE + # Disable this job from running in PR gatees. It causes the entire pipeline run to wait while the job is requeued + # causing runs take several hours. + condition: false dependsOn: Build_${{ parameters.tool_chain_tag }} workspace: clean: all -- cgit From 0343e7523387df6204c3219211d798683d3fd200 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Thu, 25 Jul 2024 07:43:09 -0400 Subject: .github/request-reviews.yml: Switch to pull_request_target This change simply moves the trigger to `pull_request_target`. The rest of this message contains verbose details related to that. `pull_request_target` is used instead of `pull_request` since the default GitHub token cannot pick up write permissions with the `pull_request` type on PRs from public forks. Write permission is needed to add reviewrs. This was previously tested on an edk2 fork where PRs were not from other public forks into the fork being used for testing but directly on the fork itself. Because `pull_request_target` runs the pull request in the context of the base branch (not the PR branch) some logic needs slightly modified. The main change is that the GitHub context will no longer give the PR branch HEAD as the PR commit SHA (i.e. `github.event.pull_request.head.sha`). The SHA will be the base branch (`master`) SHA as that is what is checked out for the workflow run. SO, the actual PR SHA is now fetched separately. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 82 +++++++++++++++++++++++++++-------- .github/workflows/request-reviews.yml | 27 +++++++++++- 2 files changed, 90 insertions(+), 19 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index cd6bea5205..95865dea41 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -39,37 +39,47 @@ def leave_pr_comment( response.raise_for_status() -def get_reviewers_for_current_branch( - workspace_path: str, maintainer_file_path: str, target_branch: str = "master" +def get_reviewers_for_range( + workspace_path: str, + maintainer_file_path: str, + range_start: str = "master", + range_end: str = "HEAD", ) -> List[str]: """Get the reviewers for the current branch. + To get the reviewers for a single commit, set `range_start` and + `range_end` to the commit SHA. + Args: workspace_path (str): The workspace path. maintainer_file_path (str): The maintainer file path. - target_branch (str, optional): The name of the target branch that the - current HEAD will merge to. Defaults to "master". + range_start (str, optional): The range start ref. Defaults to "master". + range_end (str, optional): The range end ref. Defaults to "HEAD". Returns: List[str]: A list of GitHub usernames. """ - commit_stream_buffer = StringIO() - cmd_ret = RunCmd( - "git", - f"log --format=format:%H {target_branch}..HEAD", - workingdir=workspace_path, - outstream=commit_stream_buffer, - logging_level=logging.INFO, - ) - if cmd_ret != 0: - print( - f"::error title=Commit Lookup Error!::Error getting branch commits: [{cmd_ret}]: {commit_stream_buffer.getvalue()}" + if range_start == range_end: + commits = [range_start] + else: + commit_stream_buffer = StringIO() + cmd_ret = RunCmd( + "git", + f"log --format=format:%H {range_start}..{range_end}", + workingdir=workspace_path, + outstream=commit_stream_buffer, + logging_level=logging.INFO, ) - return [] + if cmd_ret != 0: + print( + f"::error title=Commit Lookup Error!::Error getting branch commits: [{cmd_ret}]: {commit_stream_buffer.getvalue()}" + ) + return [] + commits = commit_stream_buffer.getvalue().splitlines() raw_reviewers = [] - for commit_sha in commit_stream_buffer.getvalue().splitlines(): + for commit_sha in commits: reviewer_stream_buffer = StringIO() cmd_ret = RunPythonScript( maintainer_file_path, @@ -104,6 +114,44 @@ def get_reviewers_for_current_branch( return reviewers +def get_pr_sha(token: str, owner: str, repo: str, pr_number: str) -> str: + """Returns the commit SHA of given PR branch. + + This returns the SHA of the merge commit that GitHub creates from a + PR branch. This commit contains all of the files in the PR branch in + a single commit. + + Args: + token (str): The GitHub token to use for authentication. + owner (str): The GitHub owner (organization) name. + repo (str): The GitHub repository name (e.g. 'edk2'). + pr_number (str): The pull request number. + + Returns: + str: The commit SHA of the PR branch. An empty string is returned + if the request fails. + """ + url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github.v3+json", + } + response = requests.get(url, headers=headers) + try: + response.raise_for_status() + except requests.exceptions.HTTPError: + print( + f"::error title=HTTP Error!::Error getting PR Commit Info: {response.reason}" + ) + return "" + + commit_sha = response.json()["merge_commit_sha"] + + print(f"::debug title=PR {pr_number} Commit SHA::{commit_sha}") + + return commit_sha + + def download_gh_file(github_url: str, local_path: str, token=None): """Downloads a file from GitHub. diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index 4f43d56122..3311e1165d 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -11,7 +11,7 @@ name: Add Pull Request Reviewers on: - pull_request: + pull_request_target: branches: - master types: [opened, ready_for_review, reopened, synchronize] @@ -55,15 +55,38 @@ jobs: TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} WORKSPACE_PATH: ${{ github.workspace }} run: | + import logging import os import sys sys.path.append(os.path.join(os.environ['WORKSPACE_PATH'], ".github")) + from edk2toollib.utility_functions import RunCmd + from io import StringIO from scripts import GitHub WORKSPACE_PATH = os.environ['WORKSPACE_PATH'] GET_MAINTAINER_LOCAL_PATH = os.path.join(WORKSPACE_PATH, os.environ['GET_MAINTAINER_REL_PATH']) - reviewers = GitHub.get_reviewers_for_current_branch(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, f"origin/{os.environ['TARGET_BRANCH']}") + pr_commit_sha = GitHub.get_pr_sha(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], os.environ['PR_NUMBER']) + if not pr_commit_sha: + sys.exit(1) + + print(f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}") + + out_stream_buffer = StringIO() + cmd_ret = RunCmd( + "git", + f"fetch origin {pr_commit_sha}", + workingdir=WORKSPACE_PATH, + outstream=out_stream_buffer, + logging_level=logging.INFO, + ) + if cmd_ret != 0: + print( + f"::error title=Commit Fetch Error!::Error fetching PR commit: [{cmd_ret}]: {out_stream_buffer.getvalue()}" + ) + sys.exit(1) + + reviewers = GitHub.get_reviewers_for_range(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha) if not reviewers: print("::notice title=No Reviewers Found!::No reviewers found for this PR.") sys.exit(1) -- cgit From 418b8176b8d7d99f4303d92f87130f1b09989b7a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 25 Jul 2024 10:27:34 +0200 Subject: ArmPkg: Retire ArmSmcPsciResetSystemLib This library is no longer used, and has been superseded by ArmPsciResetSystemLib based on ArmMonitorLib. So delete it. Signed-off-by: Ard Biesheuvel --- ArmPkg/ArmPkg.dsc | 1 - .../ArmSmcPsciResetSystemLib.c | 150 --------------------- .../ArmSmcPsciResetSystemLib.inf | 29 ---- 3 files changed, 180 deletions(-) delete mode 100644 ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c delete mode 100644 ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 09037c59b5..910e8589c4 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -150,7 +150,6 @@ ArmPkg/Library/ArmLib/ArmBaseLib.inf ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf - ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf ArmPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf diff --git a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c b/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c deleted file mode 100644 index dc7b9fd019..0000000000 --- a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c +++ /dev/null @@ -1,150 +0,0 @@ -/** @file - ResetSystemLib implementation using PSCI calls - - Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.
- Copyright (c) 2019, Intel Corporation. All rights reserved.
- Copyright (c) 2022, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include - -#include - -/** - This function causes a system-wide reset (cold reset), in which - all circuitry within the system returns to its initial state. This type of reset - is asynchronous to system operation and operates without regard to - cycle boundaries. - - If this function returns, it means that the system does not support cold reset. -**/ -VOID -EFIAPI -ResetCold ( - VOID - ) -{ - // Send a PSCI 0.2 SYSTEM_RESET command - ArmCallSmc0 (ARM_SMC_ID_PSCI_SYSTEM_RESET, NULL, NULL, NULL); -} - -/** - This function causes a system-wide initialization (warm reset), in which all processors - are set to their initial state. Pending cycles are not corrupted. - - If this function returns, it means that the system does not support warm reset. -**/ -VOID -EFIAPI -ResetWarm ( - VOID - ) -{ - UINTN Arg1; - UINTN Ret; - - Arg1 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64; - - // Is SYSTEM_RESET2 supported? - Ret = ArmCallSmc0 (ARM_SMC_ID_PSCI_FEATURES, &Arg1, NULL, NULL); - if (Ret == ARM_SMC_PSCI_RET_SUCCESS) { - // Send PSCI SYSTEM_RESET2 command - ArmCallSmc0 (Arg1, NULL, NULL, NULL); - } else { - // Map a warm reset into a cold reset - DEBUG (( - DEBUG_INFO, - "Warm reboot not supported by platform, issuing cold reboot\n" - )); - ResetCold (); - } -} - -/** - This function causes the system to enter a power state equivalent - to the ACPI G2/S5 or G3 states. - - If this function returns, it means that the system does not support shutdown reset. -**/ -VOID -EFIAPI -ResetShutdown ( - VOID - ) -{ - // Send a PSCI 0.2 SYSTEM_OFF command - ArmCallSmc0 (ARM_SMC_ID_PSCI_SYSTEM_OFF, NULL, NULL, NULL); -} - -/** - This function causes a systemwide reset. The exact type of the reset is - defined by the EFI_GUID that follows the Null-terminated Unicode string passed - into ResetData. If the platform does not recognize the EFI_GUID in ResetData - the platform must pick a supported reset type to perform.The platform may - optionally log the parameters from any non-normal reset that occurs. - - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData The data buffer starts with a Null-terminated string, - followed by the EFI_GUID. -**/ -VOID -EFIAPI -ResetPlatformSpecific ( - IN UINTN DataSize, - IN VOID *ResetData - ) -{ - // Map the platform specific reset as reboot - ResetCold (); -} - -/** - The ResetSystem function resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown - the data buffer starts with a Null-terminated string, optionally - followed by additional binary data. The string is a description - that the caller may use to further indicate the reason for the - system reset. -**/ -VOID -EFIAPI -ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - switch (ResetType) { - case EfiResetWarm: - ResetWarm (); - break; - - case EfiResetCold: - ResetCold (); - break; - - case EfiResetShutdown: - ResetShutdown (); - return; - - case EfiResetPlatformSpecific: - ResetPlatformSpecific (DataSize, ResetData); - return; - - default: - return; - } -} diff --git a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf b/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf deleted file mode 100644 index c17b28cfac..0000000000 --- a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf +++ /dev/null @@ -1,29 +0,0 @@ -#/** @file -# ResetSystemLib implementation using PSCI calls -# -# Copyright (c) 2017, Linaro Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 0x00010019 - BASE_NAME = ArmSmcPsciResetSystemLib - FILE_GUID = 18B12C83-7718-4D83-ADA4-87F2FE698DD4 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = ResetSystemLib - -[Sources] - ArmSmcPsciResetSystemLib.c - -[Packages] - ArmPkg/ArmPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - ArmSmcLib - BaseLib - DebugLib -- cgit From 358b19e6bf7ddbc42ee4765e23f260fa01448082 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sun, 21 Jul 2024 19:01:21 +0200 Subject: ArmVirtPkg: Move to generic ArmPsciResetSystemLib Switch to the new, generic ArmPsciResetSystemLib implementation that obtains the conduit using ArmMonitorLib, of which a version already exists that determines the conduit by looking up the PSCI DT node. This permits the removal of the ArmVirtPkg specific implementation of ResetSystemLib, which essentially does the exact same thing, but in a single library. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirt.dsc.inc | 2 +- .../ArmVirtPsciResetSystemLib.c | 224 --------------------- .../ArmVirtPsciResetSystemLib.inf | 42 ---- 3 files changed, 1 insertion(+), 267 deletions(-) delete mode 100644 ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c delete mode 100644 ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index eb0bca24ea..3462adf9b6 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -114,7 +114,7 @@ PlatformPeiLib|ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf MemoryInitPeiLib|ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf - ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf + ResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf # ARM PL031 RTC Driver RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c b/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c deleted file mode 100644 index 1f27b7648d..0000000000 --- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c +++ /dev/null @@ -1,224 +0,0 @@ -/** @file - Support ResetSystem Runtime call using PSCI calls - - Note: A similar library is implemented in - ArmPkg/Library/ArmPsciResetSystemLib. Similar issues might - exist in this implementation too. - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2013, ARM Ltd. All rights reserved.
- Copyright (c) 2014, Linaro Ltd. All rights reserved.
- Copyright (c) 2019, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -STATIC UINT32 mArmPsciMethod; - -RETURN_STATUS -EFIAPI -ArmPsciResetSystemLibConstructor ( - VOID - ) -{ - EFI_STATUS Status; - FDT_CLIENT_PROTOCOL *FdtClient; - CONST VOID *Prop; - - Status = gBS->LocateProtocol ( - &gFdtClientProtocolGuid, - NULL, - (VOID **)&FdtClient - ); - ASSERT_EFI_ERROR (Status); - - Status = FdtClient->FindCompatibleNodeProperty ( - FdtClient, - "arm,psci-0.2", - "method", - &Prop, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - if (AsciiStrnCmp (Prop, "hvc", 3) == 0) { - mArmPsciMethod = 1; - } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) { - mArmPsciMethod = 2; - } else { - DEBUG (( - DEBUG_ERROR, - "%a: Unknown PSCI method \"%a\"\n", - __func__, - Prop - )); - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -/** - This function causes a system-wide reset (cold reset), in which - all circuitry within the system returns to its initial state. This type of reset - is asynchronous to system operation and operates without regard to - cycle boundaries. - - If this function returns, it means that the system does not support cold reset. -**/ -VOID -EFIAPI -ResetCold ( - VOID - ) -{ - ARM_SMC_ARGS ArmSmcArgs; - ARM_HVC_ARGS ArmHvcArgs; - - // Send a PSCI 0.2 SYSTEM_RESET command - ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET; - ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET; - - switch (mArmPsciMethod) { - case 1: - ArmCallHvc (&ArmHvcArgs); - break; - - case 2: - ArmCallSmc (&ArmSmcArgs); - break; - - default: - DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __func__)); - } -} - -/** - This function causes a system-wide initialization (warm reset), in which all processors - are set to their initial state. Pending cycles are not corrupted. - - If this function returns, it means that the system does not support warm reset. -**/ -VOID -EFIAPI -ResetWarm ( - VOID - ) -{ - // Map a warm reset into a cold reset - ResetCold (); -} - -/** - This function causes the system to enter a power state equivalent - to the ACPI G2/S5 or G3 states. - - If this function returns, it means that the system does not support shutdown reset. -**/ -VOID -EFIAPI -ResetShutdown ( - VOID - ) -{ - ARM_SMC_ARGS ArmSmcArgs; - ARM_HVC_ARGS ArmHvcArgs; - - // Send a PSCI 0.2 SYSTEM_OFF command - ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF; - ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF; - - switch (mArmPsciMethod) { - case 1: - ArmCallHvc (&ArmHvcArgs); - break; - - case 2: - ArmCallSmc (&ArmSmcArgs); - break; - - default: - DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __func__)); - } -} - -/** - This function causes a systemwide reset. The exact type of the reset is - defined by the EFI_GUID that follows the Null-terminated Unicode string passed - into ResetData. If the platform does not recognize the EFI_GUID in ResetData - the platform must pick a supported reset type to perform.The platform may - optionally log the parameters from any non-normal reset that occurs. - - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData The data buffer starts with a Null-terminated string, - followed by the EFI_GUID. -**/ -VOID -EFIAPI -ResetPlatformSpecific ( - IN UINTN DataSize, - IN VOID *ResetData - ) -{ - // Map the platform specific reset as reboot - ResetCold (); -} - -/** - The ResetSystem function resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown - the data buffer starts with a Null-terminated string, optionally - followed by additional binary data. The string is a description - that the caller may use to further indicate the reason for the - system reset. -**/ -VOID -EFIAPI -ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - switch (ResetType) { - case EfiResetWarm: - ResetWarm (); - break; - - case EfiResetCold: - ResetCold (); - break; - - case EfiResetShutdown: - ResetShutdown (); - return; - - case EfiResetPlatformSpecific: - ResetPlatformSpecific (DataSize, ResetData); - return; - - default: - return; - } -} diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf b/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf deleted file mode 100644 index 4fde5e443f..0000000000 --- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf +++ /dev/null @@ -1,42 +0,0 @@ -#/** @file -# Reset System lib using PSCI hypervisor or secure monitor calls -# -# Copyright (c) 2008, Apple Inc. All rights reserved.
-# Copyright (c) 2014, Linaro Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = ArmVirtPsciResetSystemLib - FILE_GUID = c81d76ed-66fa-44a3-ac4a-f163120187a9 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER - CONSTRUCTOR = ArmPsciResetSystemLibConstructor - -[Sources] - ArmVirtPsciResetSystemLib.c - -[Packages] - ArmPkg/ArmPkg.dec - ArmVirtPkg/ArmVirtPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - ArmSmcLib - ArmHvcLib - BaseLib - DebugLib - UefiBootServicesTableLib - -[Protocols] - gFdtClientProtocolGuid ## CONSUMES - -[Depex] - gFdtClientProtocolGuid -- cgit From 08c60b40da2a850bfa760832d040710cfde39760 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 22 Jul 2024 12:45:50 +0200 Subject: ArmVirtPkg: Implement DT-based ArmMonitorLib for the PEI phase The TPM2 related PEIMs depend on ResetSystemLib too, and so in order to be able to switch to the generic ArmPkg implementation which relies on ArmMonitorLib, the latter library class requires a PEIM-compatible implementation too. Signed-off-by: Ard Biesheuvel --- .../ArmVirtQemuMonitorPeiLib.c | 128 +++++++++++++++++++++ .../ArmVirtQemuMonitorPeiLib.inf | 35 ++++++ 2 files changed, 163 insertions(+) create mode 100644 ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c create mode 100644 ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf diff --git a/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c new file mode 100644 index 0000000000..aa8d5d6082 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c @@ -0,0 +1,128 @@ +/** @file + Arm Monitor Library that chooses the conduit based on the PSCI node in the + device tree provided by QEMU. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ Copyright (c) 2024, Google LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include + +typedef enum { + SmcccConduitUnknown, + SmcccConduitSmc, + SmcccConduitHvc, +} SMCCC_CONDUIT; + +/** + Discover the SMCCC conduit by parsing the PSCI device tree node. + + @return the discovered SMCCC conduit +**/ +STATIC +SMCCC_CONDUIT +DiscoverSmcccConduit ( + VOID + ) +{ + VOID *DeviceTreeBase; + INT32 Node, Prev; + INT32 Len; + CONST FDT_PROPERTY *Compatible; + CONST CHAR8 *CompatibleItem; + CONST FDT_PROPERTY *Prop; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); + ASSERT (FdtCheckHeader (DeviceTreeBase) == 0); + + // + // Enumerate all FDT nodes looking for the PSCI node and capture the conduit + // + for (Prev = 0; ; Prev = Node) { + Node = FdtNextNode (DeviceTreeBase, Prev, NULL); + if (Node < 0) { + break; + } + + Compatible = FdtGetProperty (DeviceTreeBase, Node, "compatible", &Len); + if (Compatible == NULL) { + continue; + } + + // + // Iterate over the NULL-separated items in the compatible string + // + for (CompatibleItem = Compatible->Data; CompatibleItem < Compatible->Data + Len; + CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) + { + if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) { + continue; + } + + Prop = FdtGetProperty (DeviceTreeBase, Node, "method", NULL); + if (Prop == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Missing PSCI method property\n", + __func__ + )); + + return SmcccConduitUnknown; + } + + if (AsciiStrnCmp (Prop->Data, "hvc", 3) == 0) { + return SmcccConduitHvc; + } else if (AsciiStrnCmp (Prop->Data, "smc", 3) == 0) { + return SmcccConduitSmc; + } else { + DEBUG (( + DEBUG_ERROR, + "%a: Unknown PSCI method \"%a\"\n", + __func__, + Prop + )); + + return SmcccConduitUnknown; + } + } + } + + return SmcccConduitUnknown; +} + +/** Monitor call. + + An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued + depending on the default conduit. + + @param [in,out] Args Arguments for the HVC/SMC. +**/ +VOID +EFIAPI +ArmMonitorCall ( + IN OUT ARM_MONITOR_ARGS *Args + ) +{ + switch (DiscoverSmcccConduit ()) { + case SmcccConduitHvc: + ArmCallHvc ((ARM_HVC_ARGS *)Args); + break; + + case SmcccConduitSmc: + ArmCallSmc ((ARM_SMC_ARGS *)Args); + break; + + default: + ASSERT (FALSE); + } +} diff --git a/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf new file mode 100644 index 0000000000..cd850f342d --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf @@ -0,0 +1,35 @@ +## @file +# Arm Monitor Library that chooses the conduit based on the PSCI node in the +# device tree provided by QEMU. +# +# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2024, Google LLC. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ArmVirtQemuMonitorPeiLib + FILE_GUID = c610e0dc-dd7a-47c8-8fea-26c4710709ff + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmMonitorLib|PEIM + +[Sources] + ArmVirtQemuMonitorPeiLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + ArmHvcLib + ArmSmcLib + BaseLib + DebugLib + FdtLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress -- cgit From 52eb643d0785a19c7f1c107d390c7bb52a79789e Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 22 Jul 2024 12:49:19 +0200 Subject: ArmVirtPkg/ArmVirtQemu: Switch to generic ResetSystemLib Retire the special ResetSystemLib implementation for the PEI phase on virtual platforms, which has been superseded by the generic version combined with a PEI-compatible implementation of ArmMonitorLib. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirtQemu.dsc | 8 +- .../ArmVirtPsciResetSystemPeiLib.c | 240 --------------------- .../ArmVirtPsciResetSystemPeiLib.inf | 40 ---- 3 files changed, 3 insertions(+), 285 deletions(-) delete mode 100644 ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c delete mode 100644 ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 6a0e99bc64..942a602706 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -104,8 +104,9 @@ ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf !if $(TPM2_ENABLE) == TRUE + ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf - ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf + FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf !endif @@ -355,10 +356,7 @@ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf } - MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf { - - ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf - } + MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c deleted file mode 100644 index dffc1fb979..0000000000 --- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c +++ /dev/null @@ -1,240 +0,0 @@ -/** @file - Reset System lib using PSCI hypervisor or secure monitor calls - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2013, ARM Ltd. All rights reserved.
- Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.
- Copyright (c) 2019, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef enum { - PsciMethodUnknown, - PsciMethodSmc, - PsciMethodHvc, -} PSCI_METHOD; - -STATIC -PSCI_METHOD -DiscoverPsciMethod ( - VOID - ) -{ - VOID *DeviceTreeBase; - INT32 Node, Prev; - INT32 Len; - CONST CHAR8 *Compatible; - CONST CHAR8 *CompatibleItem; - CONST VOID *Prop; - - DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); - ASSERT (fdt_check_header (DeviceTreeBase) == 0); - - // - // Enumerate all FDT nodes looking for the PSCI node and capture the method - // - for (Prev = 0; ; Prev = Node) { - Node = fdt_next_node (DeviceTreeBase, Prev, NULL); - if (Node < 0) { - break; - } - - Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len); - if (Compatible == NULL) { - continue; - } - - // - // Iterate over the NULL-separated items in the compatible string - // - for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len; - CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) - { - if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) { - continue; - } - - Prop = fdt_getprop (DeviceTreeBase, Node, "method", NULL); - if (!Prop) { - DEBUG (( - DEBUG_ERROR, - "%a: Missing PSCI method property\n", - __func__ - )); - return PsciMethodUnknown; - } - - if (AsciiStrnCmp (Prop, "hvc", 3) == 0) { - return PsciMethodHvc; - } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) { - return PsciMethodSmc; - } else { - DEBUG (( - DEBUG_ERROR, - "%a: Unknown PSCI method \"%a\"\n", - __func__, - Prop - )); - return PsciMethodUnknown; - } - } - } - - return PsciMethodUnknown; -} - -STATIC -VOID -PerformPsciAction ( - IN UINTN Arg0 - ) -{ - ARM_SMC_ARGS ArmSmcArgs; - ARM_HVC_ARGS ArmHvcArgs; - - ArmSmcArgs.Arg0 = Arg0; - ArmHvcArgs.Arg0 = Arg0; - - switch (DiscoverPsciMethod ()) { - case PsciMethodHvc: - ArmCallHvc (&ArmHvcArgs); - break; - - case PsciMethodSmc: - ArmCallSmc (&ArmSmcArgs); - break; - - default: - DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __func__)); - ASSERT (FALSE); - } -} - -/** - This function causes a system-wide reset (cold reset), in which - all circuitry within the system returns to its initial state. This type of reset - is asynchronous to system operation and operates without regard to - cycle boundaries. - - If this function returns, it means that the system does not support cold reset. -**/ -VOID -EFIAPI -ResetCold ( - VOID - ) -{ - // Send a PSCI 0.2 SYSTEM_RESET command - PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_RESET); -} - -/** - This function causes a system-wide initialization (warm reset), in which all processors - are set to their initial state. Pending cycles are not corrupted. - - If this function returns, it means that the system does not support warm reset. -**/ -VOID -EFIAPI -ResetWarm ( - VOID - ) -{ - // Map a warm reset into a cold reset - ResetCold (); -} - -/** - This function causes the system to enter a power state equivalent - to the ACPI G2/S5 or G3 states. - - If this function returns, it means that the system does not support shutdown reset. -**/ -VOID -EFIAPI -ResetShutdown ( - VOID - ) -{ - // Send a PSCI 0.2 SYSTEM_OFF command - PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_OFF); -} - -/** - This function causes a systemwide reset. The exact type of the reset is - defined by the EFI_GUID that follows the Null-terminated Unicode string passed - into ResetData. If the platform does not recognize the EFI_GUID in ResetData - the platform must pick a supported reset type to perform.The platform may - optionally log the parameters from any non-normal reset that occurs. - - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData The data buffer starts with a Null-terminated string, - followed by the EFI_GUID. -**/ -VOID -EFIAPI -ResetPlatformSpecific ( - IN UINTN DataSize, - IN VOID *ResetData - ) -{ - // Map the platform specific reset as reboot - ResetCold (); -} - -/** - The ResetSystem function resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown - the data buffer starts with a Null-terminated string, optionally - followed by additional binary data. The string is a description - that the caller may use to further indicate the reason for the - system reset. -**/ -VOID -EFIAPI -ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - switch (ResetType) { - case EfiResetWarm: - ResetWarm (); - break; - - case EfiResetCold: - ResetCold (); - break; - - case EfiResetShutdown: - ResetShutdown (); - return; - - case EfiResetPlatformSpecific: - ResetPlatformSpecific (DataSize, ResetData); - return; - - default: - return; - } -} diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf deleted file mode 100644 index 79217d296d..0000000000 --- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf +++ /dev/null @@ -1,40 +0,0 @@ -#/** @file -# Reset System lib using PSCI hypervisor or secure monitor calls -# -# Copyright (c) 2008, Apple Inc. All rights reserved.
-# Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# -#**/ - -[Defines] - INF_VERSION = 1.27 - BASE_NAME = ArmVirtPsciResetSystemPeiLib - FILE_GUID = 551cfb98-c185-41a3-86bf-8cdb7e2a530c - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = ResetSystemLib|PEIM - -[Sources] - ArmVirtPsciResetSystemPeiLib.c - -[Packages] - ArmPkg/ArmPkg.dec - ArmVirtPkg/ArmVirtPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - OvmfPkg/OvmfPkg.dec - -[LibraryClasses] - ArmSmcLib - ArmHvcLib - BaseLib - DebugLib - FdtLib - HobLib - -[Pcd] - gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress -- cgit From b7f963d570ec5e27bc04d546372c6fc47e4f3b17 Mon Sep 17 00:00:00 2001 From: Bret Barkelew Date: Tue, 6 Nov 2018 18:34:49 +0000 Subject: FmpDevicePkg: Assert on PcdFmpDeviceImageTypeIdGuid Size Mismatch This patch adds an assert to FmpDxe.c to catch a platform misconfiguration of PcdFmpDeviceImageTypeIdGuid. Signed-off-by: Oliver Smith-Denny --- FmpDevicePkg/FmpDxe/FmpDxe.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 1e7ec4a09e..b04998ba04 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -181,7 +181,12 @@ GetImageTypeIdGuid ( if (ImageTypeIdGuidSize == sizeof (EFI_GUID)) { FmpDeviceLibGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceImageTypeIdGuid); } else { - DEBUG ((DEBUG_WARN, "FmpDxe(%s): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid\n", mImageIdName)); + DEBUG (( + DEBUG_ERROR, + "FmpDxe(%s): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid. FmpDxe error: misconfiguration\n", + mImageIdName + )); + ASSERT (FALSE); FmpDeviceLibGuid = &gEfiCallerIdGuid; } } -- cgit From ecb1d67775a6dcaa9a0deb4869ca60e250987e91 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sun, 28 Jul 2024 18:50:09 +0200 Subject: BaseTools/tools_def CLANGDWARF: Always use -Oz in RELEASE mode GCC5 and CLANGDWARF for IA32/X64 use -Os or -Oz as the optimization level, which agressively optimizes for the smallest possible object code. On AARCH64, RISCV64 and ARM, we use -O3 instead, which results in considerable image bloat, to the point where the Raspberry Pi 4 build in edk2-platforms does not even build with -D SECURE_BOOT_ENABLE. So let's align CLANGDWARF across all architectures, and use -Oz throughout. Note that O3 is still used for the linker, which build in LTO mode and therefore performs some code generation as well. This is deliberate: LLD does not support the Os/Oz optimization levels at all, and using Oz for the compile pass is sufficient to reduce the code size substantially. Signed-off-by: Ard Biesheuvel --- BaseTools/Conf/tools_def.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 994cae2588..13cf0f91b6 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -2130,7 +2130,7 @@ DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLI DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax NOOPT_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -O0 NOOPT_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax -RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3 +RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax ################## @@ -2176,7 +2176,7 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax NOOPT_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -O0 NOOPT_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax -RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3 +RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax ################## @@ -2228,7 +2228,7 @@ DEFINE CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF DEBUG_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -Wl,--no-pie,--no-relax NOOPT_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -O0 NOOPT_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax -RELEASE_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3 +RELEASE_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz RELEASE_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -Wl,--no-pie,--no-relax # -- cgit From 51edd4830d822e70b96a8548d0d89383e12bc4c0 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 26 Jul 2024 15:32:13 +0800 Subject: UefiCpuPkg: fix issue when SMM profile is enabled This commit is to fix smm code assert issue when SMM Profile is enabled. When SMM Profile is enabled, the function InitProtectedMemRange() retrives MMIO ranges from GCD and store the MMIO ranges in the mProtectionMemRange. When ReadyToLock, the function InitPaging() modifies the page table based on the mProtectionMemRange. If the MMIO ranges in mProtectionMemRange is not 4k aligned, code will assert when modifying page table. In this commit, we skip the MMIO ranges that BaseAddress and Length are not 4k aligned when creating mProtectionMemRange. This will only cause each access to the skipped MMIO range to be logged. In current failure case on QEMU and QSP SimicsOpenBoard, the skipped MMIO range is [0xFED00000, 0xFED00400] for HPET. Considering that the probability of HPET MMIO range being accessed is very small in SMM, the solution in this commit is acceptable and simple. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 36 ++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 692aad2d15..5c0f9b4a3f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -438,8 +438,23 @@ InitProtectedMemRange ( &MemorySpaceMap ); for (Index = 0; Index < NumberOfDescriptors; Index++) { - if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { - NumberOfAddedDescriptors++; + if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) { + if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) && + (MemorySpaceMap[Index].Length % SIZE_4KB == 0)) + { + NumberOfAddedDescriptors++; + } else { + // + // Skip the MMIO range that BaseAddress and Length are not 4k aligned since + // the minimum granularity of the page table is 4k + // + DEBUG (( + DEBUG_WARN, + "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n", + MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length + )); + } } } @@ -486,15 +501,16 @@ InitProtectedMemRange ( // Create MMIO ranges which are set to present and execution-disable. // for (Index = 0; Index < NumberOfDescriptors; Index++) { - if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { - continue; + if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && + ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) && + (MemorySpaceMap[Index].Length % SIZE_4KB == 0)) + { + mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress; + mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length; + mProtectionMemRange[NumberOfProtectRange].Present = TRUE; + mProtectionMemRange[NumberOfProtectRange].Nx = TRUE; + NumberOfProtectRange++; } - - mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress; - mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length; - mProtectionMemRange[NumberOfProtectRange].Present = TRUE; - mProtectionMemRange[NumberOfProtectRange].Nx = TRUE; - NumberOfProtectRange++; } // -- cgit From 43e2395c1b130540820957305451340e1fff81e4 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Mon, 29 Jul 2024 09:32:19 +0800 Subject: MdeModulePkg: fix issue caused by uninitialized variable This patch is to fix issue caused by uninitialized local variable in Pei/Variable.c. In the fucntion CalculateHobVariableCacheSize(), the local variable VARIABLE_STORE_INFO StoreInfo is used without initialization. When the uninitialized variable is passed to CalculateAuthVarStorageSize() and GetNextVariablePtr(), the field StoreInfo->FtwLastWriteData might be a uninitialized non-zero value. Then the code execution will access the invalid address StoreInfo->FtwLastWriteData->TargetAddress. This might cause issue. So in this commit, the local variable VARIABLE_STORE_INFO StoreInfo is initialized by a ZeroMem() before use. Signed-off-by: Dun Tan --- MdeModulePkg/Universal/Variable/Pei/Variable.c | 1 + 1 file changed, 1 insertion(+) diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.c b/MdeModulePkg/Universal/Variable/Pei/Variable.c index 26f95c6d95..9f3d43486c 100644 --- a/MdeModulePkg/Universal/Variable/Pei/Variable.c +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.c @@ -1336,6 +1336,7 @@ CalculateHobVariableCacheSize ( VARIABLE_STORE_HEADER *VariableStoreHeader; VariableStoreHeader = NULL; + ZeroMem (&StoreInfo, sizeof (VARIABLE_STORE_INFO)); GetHobVariableStore (&StoreInfo, &VariableStoreHeader); if (VariableStoreHeader == NULL) { -- cgit From 0dacb43505df060f1005edab6c2a6bcf69c18acb Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 14 Feb 2024 10:06:54 +0000 Subject: DynamicTablesPkg: Introduce an Arch Common Namespace Introduce an Arch Common Namespace so that the common architectural objects can be defined under this namespace in the Configuration manager. Also rearrange the namespace IDs so that the Arch Common Namespace has a value of 0x1, the Arm Namespace ID has a value of 0x2, and the Custom/OEM namespace ID has a value of 0xF. Also introduce a helper macro to create configuration manager objects in the Arch Common Namespace. The Arch Common Namespace shall contain objects like Serial Port, PCI Bus information etc. It must not contain Architecture specific components e.g. GICC which is Arm architecture specific component and therefore must be defined in the Arm Namespace. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Reviewed-by: Sunil V L --- .../Include/ConfigurationManagerObject.h | 26 ++++-- DynamicTablesPkg/Readme.md | 97 ++++++++++++++++++++++ 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h index 74ad25d5d9..4255c82b42 100644 --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2017 - 2022, ARM Limited. All rights reserved. + Copyright (c) 2017 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -29,8 +29,9 @@ _______________________________________________________________________________ Bits: [31:28] - Name Space ID 0000 - Standard - 0001 - ARM - 1000 - Custom/OEM + 0001 - Arch Common + 0010 - ARM + 1111 - Custom/OEM All other values are reserved. Bits: [27:16] - Reserved. @@ -105,10 +106,11 @@ typedef UINT32 CM_OBJECT_ID; for the Configuration Manager Objects. */ typedef enum ObjectNameSpaceID { - EObjNameSpaceStandard, ///< Standard Objects Namespace - EObjNameSpaceArm, ///< ARM Objects Namespace - EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace - EObjNameSpaceMax + EObjNameSpaceStandard, ///< Standard Objects Namespace + EObjNameSpaceArchCommon, ///< Arch Common Objects Namespace + EObjNameSpaceArm, ///< ARM Objects Namespace + EObjNameSpaceOem = 0xF, ///< OEM Objects Namespace + EObjNameSpaceMax, } EOBJECT_NAMESPACE_ID; /** A descriptor for Configuration Manager Objects. @@ -182,6 +184,16 @@ typedef struct CmObjDescriptor { #define CREATE_CM_ARM_OBJECT_ID(ObjectId) \ (CREATE_CM_OBJECT_ID (EObjNameSpaceArm, ObjectId)) +/** This macro returns a Configuration Manager Object ID + in the Arch Common Object Namespace. + + @param [in] ObjectId The Object ID. + + @retval Returns an Arch Common Configuration Manager Object ID. +**/ +#define CREATE_CM_ARCH_COMMON_OBJECT_ID(ObjectId) \ + (CREATE_CM_OBJECT_ID (EObjNameSpaceArchCommon, ObjectId)) + /** This macro returns a Configuration Manager Object ID in the OEM Object Namespace. diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index c1cdc5e173..1ae423af75 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -402,3 +402,100 @@ Refer to the following presentation from *UEFI Plugfest Seattle 2018*: [Dynamic Tables Framework: A Step Towards Automatic Generation of Advanced Configuration and Power Interface (ACPI) & System Management BIOS (SMBIOS) Tables](http://www.uefi.org/sites/default/files/resources/Arm_Dynamic%20Tables%20Framework%20A%20Step%20Towards%20Automatic%20Generation%20of%20Advanced%20Configuration%20and%20Power%20Interface%20%28ACPI%29%20%26%20System%20Management%20BIOS%20%28SMBIOS%29%20Tables%20_0.pdf) +## Configuration Manager Objects + +The CM_OBJECT_ID type is used to identify the Configuration Manager + objects. + +## Description of Configuration Manager Object ID + +| 31 - 28 | 27 - 8 | 7 - 0 | +| :-------------: | :----: | :---------: | +| `Name Space ID` | 0 | `Object ID` | +------------------------------------------ + +### Name Space ID: Bits [31:28] + +| ID | Description | Comments | +| ---: | :-------------------------- | :--- | +| 0000b | Standard | | +| 0001b | Arch Common | | +| 0010b | ARM | | +| 1111b | Custom/OEM | | +| `*` | All other values are reserved. | | + +### Bits: [27:8] - Reserved, must be zero. + +### Bits: [7:0] - Object ID + +#### Object ID's in the Standard Namespace: + +| ID | Description | Comments | +| ---: | :-------------------------- | :--- | +| 0 | Configuration Manager Revision | | +| 1 | ACPI Table List | | +| 2 | SMBIOS Table List | | + +#### Object ID's in the ARM Namespace: + +| ID | Description | Comments | +| ---: | :-------------------------- | :--- | +| 0 | Reserved | | +| 1 | Boot Architecture Info | | +| 2 | CPU Info | | +| 3 | Power Management Profile Info | | +| 4 | GICC Info | | +| 5 | GICD Info | | +| 6 | GIC MSI Frame Info | | +| 7 | GIC Redistributor Info | | +| 8 | GIC ITS Info | | +| 9 | Serial Console Port Info | | +| 10 | Serial Debug Port Info | | +| 11 | Generic Timer Info | | +| 12 | Platform GT Block Info | | +| 13 | Generic Timer Block Frame Info | | +| 14 | Platform Generic Watchdog | | +| 15 | PCI Configuration Space Info | | +| 16 | Hypervisor Vendor Id | | +| 17 | Fixed feature flags for FADT | | +| 18 | ITS Group | | +| 19 | Named Component | | +| 20 | Root Complex | | +| 21 | SMMUv1 or SMMUv2 | | +| 22 | SMMUv3 | | +| 23 | PMCG | | +| 24 | GIC ITS Identifier Array | | +| 25 | ID Mapping Array | | +| 26 | SMMU Interrupt Array | | +| 27 | Processor Hierarchy Info | | +| 28 | Cache Info | | +| 29 | Reserved29 | | +| 30 | CM Object Reference | | +| 31 | Memory Affinity Info | | +| 32 | Device Handle Acpi | | +| 33 | Device Handle PCI | | +| 34 | Generic Initiator Affinity Info | | +| 35 | Serial Port Info | | +| 36 | CMN 600 Info | | +| 37 | Low Power Idle State Info | | +| 38 | PCI Address Map Info | | +| 39 | PCI Interrupt Map Info | | +| 40 | Reserved Memory Range Node | | +| 41 | Memory Range Descriptor | | +| 42 | Continuous Performance Control Info | | +| 43 | Pcc Subspace Type 0 Info | | +| 44 | Pcc Subspace Type 1 Info | | +| 45 | Pcc Subspace Type 2 Info | | +| 46 | Pcc Subspace Type 3 Info | | +| 47 | Pcc Subspace Type 4 Info | | +| 48 | Pcc Subspace Type 5 Info | | +| 49 | Embedded Trace Extension/Module Info | | +| 50 | P-State Dependency (PSD) Info | | +| `*` | All other values are reserved. | | + +#### Object ID's in the Arch Common Namespace: + +| ID | Description | Comments | +| ---: | :-------------------------- | :--- | +| 0 | Reserved | | +| `*` | All other values are reserved. | | -- cgit From 6fb4e7b4adbf819e2d42e9abc4b127c96ed857c7 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Thu, 21 Mar 2024 15:12:17 +0100 Subject: DynamicTablesPkg/SsdtCpuTopology: Update function's parameter description The parameters of CreateAmlProcessorContainer() were not updated in: commit 5fb3f5723a1e ("DynamicTablesPkg: Allow for specified CPU names") This causes the EccCheck CI test to fail. Fix this. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index 40ed10eae6..e3cbe18a49 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -980,7 +980,8 @@ CreateAmlCpuFromProcHierarchy ( container node to. @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO object used to create the node. - @param [in] ProcContainerIndex Index used to generate the node name. + @param [in] ProcContainerName Name of the processor container. + @param [in] ProcContainerUid Uid of the processor container. @param [out] ProcContainerNodePtr If success, contains the created processor container node. -- cgit From 991b70c0dab71b9f2129deacf493c2e253470fb9 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 7 Mar 2024 14:38:01 +0000 Subject: DynamicTablesPkg: Replace ProcNodeIdInfo with EArmObjReserved29 The CM_ARM_PROC_NODE_ID_INFO was dropped by the patch at "b2bbe3df5470 DynamicTablesPkg: Remove PPTT ID structure from ACPI 6.4 generator" and the EArmObjProcNodeIdInfo was made EArmObjReserved29. Since ProcNodeIdInfo is no longer used drop the CM object parser code from EArmObjProcNodeIdInfo and specify a null entry for EArmObjReserved29. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 2 +- .../TableHelperLib/ConfigurationManagerObjectParser.c | 15 +-------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 345acab53f..9a6ab2a274 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -172,7 +172,7 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 26 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 27 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 28 - Cache Info - TokenFixerNotImplemented, ///< 29 - Processor Node ID Info + TokenFixerNotImplemented, ///< 29 - Reserved NULL, ///< 30 - CM Object Reference NULL, ///< 31 - Memory Affinity Info NULL, ///< 32 - Device Handle Acpi diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 69b6eba23c..f96b05b1c0 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -350,18 +350,6 @@ STATIC CONST CM_OBJ_PARSER CmArmCacheInfoParser[] = { { "CacheId", 4, "0x%x", NULL }, }; -/** A parser for EArmObjProcNodeIdInfo. -*/ -STATIC CONST CM_OBJ_PARSER CmArmProcNodeIdInfoParser[] = { - { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, - { "VendorId", 4, "0x%p", NULL }, - { "Level1Id", 8, "0x%x", NULL }, - { "Level2Id", 8, "0x%x", NULL }, - { "MajorRev", 2, "0x%x", NULL }, - { "MinorRev", 2, "0x%x", NULL }, - { "SpinRev", 2, "0x%x", NULL } -}; - /** A parser for EArmObjCmRef. */ STATIC CONST CM_OBJ_PARSER CmArmObjRefParser[] = { @@ -735,8 +723,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { ARRAY_SIZE (CmArmProcHierarchyInfoParser) }, { "EArmObjCacheInfo", CmArmCacheInfoParser, ARRAY_SIZE (CmArmCacheInfoParser) }, - { "EArmObjProcNodeIdInfo", CmArmProcNodeIdInfoParser, - ARRAY_SIZE (CmArmProcNodeIdInfoParser) }, + { "EArmObjReserved29", NULL, 0 }, { "EArmObjCmRef", CmArmObjRefParser, ARRAY_SIZE (CmArmObjRefParser) }, { "EArmObjMemoryAffinityInfo", CmArmMemoryAffinityInfoParser, ARRAY_SIZE (CmArmMemoryAffinityInfoParser) }, -- cgit From cb3c2362cd1830067d620d1c8c5bb5e04de32cbc Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 7 Mar 2024 14:05:40 +0000 Subject: DynamicTablesPkg: Introduce ObjectId to validate CmObject Parser Array Add ObjectId to CM_OBJ_PARSER_ARRAY so that the code can validate the entries in the Cm object parser array. Also introduce helper macros to populate the Cm Object Parser Arrays. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../ConfigurationManagerObjectParser.c | 165 ++++++++------------- .../ConfigurationManagerObjectParser.h | 15 ++ 2 files changed, 75 insertions(+), 105 deletions(-) diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index f96b05b1c0..68d6c57acf 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -670,103 +670,58 @@ STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = { /** A parser for Arm namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { - { "EArmObjReserved", NULL, 0 }, - { "EArmObjBootArchInfo", CmArmBootArchInfoParser, - ARRAY_SIZE (CmArmBootArchInfoParser) }, - { "EArmObjCpuInfo", NULL, 0 }, - { "EArmObjPowerManagementProfileInfo", CmArmPowerManagementProfileInfoParser, - ARRAY_SIZE (CmArmPowerManagementProfileInfoParser) }, - { "EArmObjGicCInfo", CmArmGicCInfoParser, ARRAY_SIZE (CmArmGicCInfoParser) }, - { "EArmObjGicDInfo", CmArmGicDInfoParser, ARRAY_SIZE (CmArmGicDInfoParser) }, - { "EArmObjGicMsiFrameInfo", CmArmGicMsiFrameInfoParser, - ARRAY_SIZE (CmArmGicMsiFrameInfoParser) }, - { "EArmObjGicRedistributorInfo", CmArmGicRedistInfoParser, - ARRAY_SIZE (CmArmGicRedistInfoParser) }, - { "EArmObjGicItsInfo", CmArmGicItsInfoParser, - ARRAY_SIZE (CmArmGicItsInfoParser) }, - { "EArmObjSerialConsolePortInfo", CmArmSerialPortInfoParser, - ARRAY_SIZE (CmArmSerialPortInfoParser) }, - { "EArmObjSerialDebugPortInfo", CmArmSerialPortInfoParser, - ARRAY_SIZE (CmArmSerialPortInfoParser) }, - { "EArmObjGenericTimerInfo", CmArmGenericTimerInfoParser, - ARRAY_SIZE (CmArmGenericTimerInfoParser) }, - { "EArmObjPlatformGTBlockInfo", CmArmGTBlockInfoParser, - ARRAY_SIZE (CmArmGTBlockInfoParser) }, - { "EArmObjGTBlockTimerFrameInfo", CmArmGTBlockTimerFrameInfoParser, - ARRAY_SIZE (CmArmGTBlockTimerFrameInfoParser) }, - { "EArmObjPlatformGenericWatchdogInfo", CmArmGenericWatchdogInfoParser, - ARRAY_SIZE (CmArmGenericWatchdogInfoParser) }, - { "EArmObjPciConfigSpaceInfo", CmArmPciConfigSpaceInfoParser, - ARRAY_SIZE (CmArmPciConfigSpaceInfoParser) }, - { "EArmObjHypervisorVendorIdentity", CmArmHypervisorVendorIdParser, - ARRAY_SIZE (CmArmHypervisorVendorIdParser) }, - { "EArmObjFixedFeatureFlags", CmArmFixedFeatureFlagsParser, - ARRAY_SIZE (CmArmFixedFeatureFlagsParser) }, - { "EArmObjItsGroup", CmArmItsGroupNodeParser, - ARRAY_SIZE (CmArmItsGroupNodeParser) }, - { "EArmObjNamedComponent", CmArmNamedComponentNodeParser, - ARRAY_SIZE (CmArmNamedComponentNodeParser) }, - { "EArmObjRootComplex", CmArmRootComplexNodeParser, - ARRAY_SIZE (CmArmRootComplexNodeParser) }, - { "EArmObjSmmuV1SmmuV2", CmArmSmmuV1SmmuV2NodeParser, - ARRAY_SIZE (CmArmSmmuV1SmmuV2NodeParser) }, - { "EArmObjSmmuV3", CmArmSmmuV3NodeParser, - ARRAY_SIZE (CmArmSmmuV3NodeParser) }, - { "EArmObjPmcg", CmArmPmcgNodeParser, ARRAY_SIZE (CmArmPmcgNodeParser) }, - { "EArmObjGicItsIdentifierArray", CmArmGicItsIdentifierParser, - ARRAY_SIZE (CmArmGicItsIdentifierParser) }, - { "EArmObjIdMappingArray", CmArmIdMappingParser, - ARRAY_SIZE (CmArmIdMappingParser) }, - { "EArmObjSmmuInterruptArray", CmArmGenericInterruptParser, - ARRAY_SIZE (CmArmGenericInterruptParser) }, - { "EArmObjProcHierarchyInfo", CmArmProcHierarchyInfoParser, - ARRAY_SIZE (CmArmProcHierarchyInfoParser) }, - { "EArmObjCacheInfo", CmArmCacheInfoParser, - ARRAY_SIZE (CmArmCacheInfoParser) }, - { "EArmObjReserved29", NULL, 0 }, - { "EArmObjCmRef", CmArmObjRefParser, ARRAY_SIZE (CmArmObjRefParser) }, - { "EArmObjMemoryAffinityInfo", CmArmMemoryAffinityInfoParser, - ARRAY_SIZE (CmArmMemoryAffinityInfoParser) }, - { "EArmObjDeviceHandleAcpi", CmArmDeviceHandleAcpiParser, - ARRAY_SIZE (CmArmDeviceHandleAcpiParser) }, - { "EArmObjDeviceHandlePci", CmArmDeviceHandlePciParser, - ARRAY_SIZE (CmArmDeviceHandlePciParser) }, - { "EArmObjGenericInitiatorAffinityInfo", - CmArmGenericInitiatorAffinityInfoParser, - ARRAY_SIZE (CmArmGenericInitiatorAffinityInfoParser) }, - { "EArmObjSerialPortInfo", CmArmSerialPortInfoParser, - ARRAY_SIZE (CmArmSerialPortInfoParser) }, - { "EArmObjCmn600Info", CmArmCmn600InfoParser, - ARRAY_SIZE (CmArmCmn600InfoParser) }, - { "EArmObjLpiInfo", CmArmLpiInfoParser, - ARRAY_SIZE (CmArmLpiInfoParser) }, - { "EArmObjPciAddressMapInfo", CmArmPciAddressMapInfoParser, - ARRAY_SIZE (CmArmPciAddressMapInfoParser) }, - { "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser, - ARRAY_SIZE (CmPciInterruptMapInfoParser) }, - { "EArmObjRmr", CmArmRmrInfoParser, - ARRAY_SIZE (CmArmRmrInfoParser) }, - { "EArmObjMemoryRangeDescriptor", CmArmMemoryRangeDescriptorInfoParser, - ARRAY_SIZE (CmArmMemoryRangeDescriptorInfoParser) }, - { "EArmObjCpcInfo", CmArmCpcInfoParser, - ARRAY_SIZE (CmArmCpcInfoParser) }, - { "EArmObjPccSubspaceType0Info", CmArmPccSubspaceType0InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, - { "EArmObjPccSubspaceType1Info", CmArmPccSubspaceType1InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType1InfoParser) }, - { "EArmObjPccSubspaceType2Info", CmArmPccSubspaceType2InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType2InfoParser) }, - { "EArmObjPccSubspaceType3Info", CmArmPccSubspaceType34InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType34InfoParser) }, - { "EArmObjPccSubspaceType4Info", CmArmPccSubspaceType34InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType34InfoParser) }, - { "EArmObjPccSubspaceType5Info", CmArmPccSubspaceType5InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType5InfoParser) }, - { "EArmObjEtInfo", CmArmEtInfo, - ARRAY_SIZE (CmArmEtInfo) }, - { "EArmObjPsdInfo", CmArmPsdInfoParser, - ARRAY_SIZE (CmArmPsdInfoParser) }, - { "EArmObjMax", NULL, 0 }, + CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved), + CM_PARSER_ADD_OBJECT (EArmObjBootArchInfo, CmArmBootArchInfoParser), + CM_PARSER_ADD_OBJECT_RESERVED (EArmObjCpuInfo), + CM_PARSER_ADD_OBJECT (EArmObjPowerManagementProfileInfo, CmArmPowerManagementProfileInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicCInfo, CmArmGicCInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicDInfo, CmArmGicDInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicMsiFrameInfo, CmArmGicMsiFrameInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicRedistributorInfo, CmArmGicRedistInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicItsInfo, CmArmGicItsInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjSerialConsolePortInfo, CmArmSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjSerialDebugPortInfo, CmArmSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGenericTimerInfo, CmArmGenericTimerInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPlatformGTBlockInfo, CmArmGTBlockInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo, CmArmGenericWatchdogInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPciConfigSpaceInfo, CmArmPciConfigSpaceInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjHypervisorVendorIdentity, CmArmHypervisorVendorIdParser), + CM_PARSER_ADD_OBJECT (EArmObjFixedFeatureFlags, CmArmFixedFeatureFlagsParser), + CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjRootComplex, CmArmRootComplexNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuV1SmmuV2, CmArmSmmuV1SmmuV2NodeParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuV3, CmArmSmmuV3NodeParser), + CM_PARSER_ADD_OBJECT (EArmObjPmcg, CmArmPmcgNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser), + CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArmGenericInterruptParser), + CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), + CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved29), + CM_PARSER_ADD_OBJECT (EArmObjCmRef, CmArmObjRefParser), + CM_PARSER_ADD_OBJECT (EArmObjMemoryAffinityInfo, CmArmMemoryAffinityInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjDeviceHandleAcpi, CmArmDeviceHandleAcpiParser), + CM_PARSER_ADD_OBJECT (EArmObjDeviceHandlePci, CmArmDeviceHandlePciParser), + CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjSerialPortInfo, CmArmSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPciAddressMapInfo, CmArmPciAddressMapInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPciInterruptMapInfo, CmPciInterruptMapInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjCpcInfo, CmArmCpcInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType0Info, CmArmPccSubspaceType0InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType1Info, CmArmPccSubspaceType1InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType4Info, CmArmPccSubspaceType34InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType5Info, CmArmPccSubspaceType5InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo), + CM_PARSER_ADD_OBJECT (EArmObjPsdInfo, CmArmPsdInfoParser), + CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax) }; /** A parser for EStdObjCfgMgrInfo. @@ -798,13 +753,10 @@ STATIC CONST CM_OBJ_PARSER StdObjSmbiosTableInfoParser[] = { /** A parser for Standard namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY StdNamespaceObjectParser[] = { - { "EStdObjCfgMgrInfo", StdObjCfgMgrInfoParser, - ARRAY_SIZE (StdObjCfgMgrInfoParser) }, - { "EStdObjAcpiTableList", StdObjAcpiTableInfoParser, - ARRAY_SIZE (StdObjAcpiTableInfoParser) }, - { "EStdObjSmbiosTableList", StdObjSmbiosTableInfoParser, - ARRAY_SIZE (StdObjSmbiosTableInfoParser) }, - { "EStdObjMax", NULL, 0} + CM_PARSER_ADD_OBJECT (EStdObjCfgMgrInfo, StdObjCfgMgrInfoParser), + CM_PARSER_ADD_OBJECT (EStdObjAcpiTableList, StdObjAcpiTableInfoParser), + CM_PARSER_ADD_OBJECT (EStdObjSmbiosTableList, StdObjSmbiosTableInfoParser), + CM_PARSER_ADD_OBJECT_RESERVED (EStdObjMax) }; /** Print string data. @@ -975,7 +927,7 @@ PrintCmObjDesc ( *RemainingSize -= Parser[Index].Length; if (*RemainingSize < 0) { DEBUG (( - DEBUG_INFO, + DEBUG_ERROR, "\nERROR: %a: Buffer overrun\n", Parser[Index].NameStr )); @@ -1118,6 +1070,9 @@ ParseCmObjDesc ( ObjIndex + 1, ObjectCount )); + + ASSERT (ObjId == ParserArray->ObjectId); + if (ParserArray->Parser == NULL) { DEBUG ((DEBUG_ERROR, "Parser not implemented\n")); RemainingSize = 0; diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h index 3204f53143..d996d05a55 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h @@ -11,6 +11,18 @@ #define OUTPUT_FIELD_COLUMN_WIDTH 32 +/** A helper macro for populating the Reserved objects + like EArmObjReserved, EArmObjMax, etc. in the CM_OBJ_PARSER_ARRAY. +**/ +#define CM_PARSER_ADD_OBJECT_RESERVED(ObjectId) \ + {ObjectId, #ObjectId, NULL, 0} + +/** A helper macro for populating the Cm Arm objects + in the CM_OBJ_PARSER_ARRAY. +**/ +#define CM_PARSER_ADD_OBJECT(ObjectId, Parser) \ + {ObjectId, #ObjectId, Parser, ARRAY_SIZE(Parser) } + /** Function prototype to format a field print. @param [in] Format Format string for tracing the data as specified by @@ -58,6 +70,9 @@ struct CmObjParser { with their object names. */ typedef struct CmObjParserArray { + /// Object ID + CONST UINTN ObjectId; + /// Object name CONST CHAR8 *ObjectName; -- cgit From 15ce6edd041e93ad0132eefe95b7f5f68d101539 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 6 Mar 2024 09:04:09 +0000 Subject: DynamicTablesPkg: Introduce an Arch Common Namespace header file Introduce a new header file for defining the Arch Common Namespace objects. Also include it in the Configuration Manager Object header file so that the required definitions are propagated. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- DynamicTablesPkg/DynamicTablesPkg.ci.yaml | 1 + .../Include/ArchCommonNameSpaceObjects.h | 27 ++++++++++++++++++++++ .../Include/ConfigurationManagerObject.h | 1 + 3 files changed, 29 insertions(+) create mode 100644 DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml index 42829f393e..07768ed648 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml +++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml @@ -104,6 +104,7 @@ "CCIDX", "CCSIDR", "countof", + "EArch", "edynamic", "EOBJECT", "invoc", diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h new file mode 100644 index 0000000000..e4205d6ba6 --- /dev/null +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -0,0 +1,27 @@ +/** @file + + Copyright (c) 2024, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object + - Std or STD - Standard +**/ + +#ifndef ARCH_COMMON_NAMESPACE_OBJECTS_H_ +#define ARCH_COMMON_NAMESPACE_OBJECTS_H_ + +#include +#include + +/** The EARCH_COMMON_OBJECT_ID enum describes the Object IDs + in the Arch Common Namespace +*/ +typedef enum ArchCommonObjectID { + EArchCommonObjReserved, ///< 0 - Reserved + EArchCommonObjMax +} EARCH_COMMON_OBJECT_ID; + +#endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h index 4255c82b42..04b365f3d0 100644 --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h @@ -12,6 +12,7 @@ #ifndef CONFIGURATION_MANAGER_OBJECT_H_ #define CONFIGURATION_MANAGER_OBJECT_H_ +#include #include #include -- cgit From af337d1291ed44947b397dd3efc79795605b6c6c Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 7 Mar 2024 14:11:31 +0000 Subject: DynamicTablesPkg: Add support for ArchCommon objects in CmObjParser Update the Cm Object Parser to support parsing of Arch Common namespace objects. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../ConfigurationManagerObjectParser.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 68d6c57acf..6f5dbdfd2d 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -667,6 +667,13 @@ STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = { { "NumProc", 4, "0x%x", NULL }, }; +/** A parser for Arch Common namespace objects. +*/ +STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { + CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjReserved), + CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) +}; + /** A parser for Arm namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { @@ -1050,6 +1057,21 @@ ParseCmObjDesc ( ParserArray = &ArmNamespaceObjectParser[ObjId]; break; + + case EObjNameSpaceArchCommon: + if (ObjId >= EArchCommonObjMax) { + ASSERT (0); + return; + } + + if (ObjId >= ARRAY_SIZE (ArchCommonNamespaceObjectParser)) { + DEBUG ((DEBUG_ERROR, "ObjId 0x%x is missing from the ArchCommonNamespaceObjectParser array\n", ObjId)); + ASSERT (0); + return; + } + + ParserArray = &ArchCommonNamespaceObjectParser[ObjId]; + break; default: // Not supported DEBUG ((DEBUG_ERROR, "NameSpaceId 0x%x, ObjId 0x%x is not supported by the parser\n", NameSpaceId, ObjId)); -- cgit From 3c2d524ceb5e6832d04a4898f902d1f57f9289ee Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Sat, 9 Mar 2024 23:03:06 +0000 Subject: DynamicTablesPkg: TokenFixer: Return Non Arm NS objs as unsupported Update the Token Fixer to return objects other than Arm Namespace objects as unsupported. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 9a6ab2a274..bbbb81ea31 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -209,14 +209,17 @@ FixupCmObjectSelfToken ( CM_OBJECT_TOKEN_FIXER TokenFixerFunc; CM_OBJECT_ID ArmNamespaceObjId; - // Only support Arm objects for now. - if ((CmObjDesc == NULL) || - (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm)) - { + if (CmObjDesc == NULL) { ASSERT (0); return EFI_INVALID_PARAMETER; } + // Only support Arm objects for now. + if (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm) { + ASSERT (0); + return EFI_UNSUPPORTED; + } + ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId); if (ArmNamespaceObjId >= EArmObjMax) { ASSERT (0); -- cgit From 9c040c003a4b8645bbf45f149d1ddb43cc3e9b11 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 6 Mar 2024 16:45:47 +0000 Subject: DynamicTablesPkg: Update DynamicPlatRepo for Arch Common namespace Update DynamicPlatRepo to reflect the introduction of the Arch Common namespace. Also, update the TokenFixer map to reflect the current state of the ArmNamespace Objects and add a note in the documentation header for the EARM_OBJECT_ID enum, that the Token fixer map needs updating whenever the ArmObjectId space is updated. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 6 + .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 11 + .../Common/DynamicPlatRepoLib/DynamicPlatRepo.c | 265 ++++++++++++++++----- .../DynamicPlatRepoLib/DynamicPlatRepoInternal.h | 11 +- 4 files changed, 229 insertions(+), 64 deletions(-) diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 4a419a8fcd..853d722b8c 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -20,6 +20,12 @@ /** The EARM_OBJECT_ID enum describes the Object IDs in the ARM Namespace + + Note: Whenever an entry in this enum is updated, + the following data structures must also be + updated: + - CM_OBJECT_TOKEN_FIXER TokenFixer[] in + Library\Common\DynamicPlatRepoLib\CmObjectTokenFixer.c */ typedef enum ArmObjectID { EArmObjReserved, ///< 0 - Reserved diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index bbbb81ea31..df9452efe5 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -183,6 +183,17 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 37 - Lpi Info NULL, ///< 38 - Pci Address Map Info NULL, ///< 39 - Pci Interrupt Map Info + NULL, ///< 40 - Reserved Memory Range Node + NULL, ///< 41 - Memory Range Descriptor + NULL, ///< 42 - Continuous Performance Control Info + NULL, ///< 43 - Pcc Subspace Type 0 Info + NULL, ///< 44 - Pcc Subspace Type 2 Info + NULL, ///< 45 - Pcc Subspace Type 2 Info + NULL, ///< 46 - Pcc Subspace Type 3 Info + NULL, ///< 47 - Pcc Subspace Type 4 Info + NULL, ///< 48 - Pcc Subspace Type 5 Info + NULL, ///< 49 - Embedded Trace Extension/Module Info + NULL ///< 50 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c index bdeb5c78ae..e4fa123370 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c @@ -127,10 +127,12 @@ DynPlatRepoAddObject ( OUT CM_OBJECT_TOKEN *Token OPTIONAL ) { - EFI_STATUS Status; - CM_OBJ_NODE *ObjNode; - CM_OBJECT_ID ArmNamespaceObjId; - CM_OBJECT_TOKEN NewToken; + EFI_STATUS Status; + CM_OBJ_NODE *ObjNode; + CM_OBJECT_ID ObjId; + CM_OBJECT_TOKEN NewToken; + LIST_ENTRY *ObjList; + EOBJECT_NAMESPACE_ID NamespaceId; // The dynamic repository must be able to receive objects. if ((This == NULL) || @@ -142,15 +144,33 @@ DynPlatRepoAddObject ( } // Check the CmObjDesc: - // - only Arm objects are supported for now. + // - only Arm objects and Arch Common objects are supported for now. // - only EArmObjCmRef objects can be added as arrays. - ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId); - if ((CmObjDesc->Size == 0) || - (CmObjDesc->Count == 0) || - (ArmNamespaceObjId >= EArmObjMax) || - ((CmObjDesc->Count > 1) && (ArmNamespaceObjId != EArmObjCmRef)) || - (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm)) - { + if ((CmObjDesc->Size == 0) || (CmObjDesc->Count == 0)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId); + NamespaceId = GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId); + + if (EObjNameSpaceArm == NamespaceId) { + if ((ObjId >= EArmObjMax) || + ((CmObjDesc->Count > 1) && (ObjId != EArmObjCmRef))) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ObjList = &This->ArmCmObjList[ObjId]; + } else if (EObjNameSpaceArchCommon == NamespaceId) { + if (ObjId >= EArchCommonObjMax) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ObjList = &This->ArchCommonCmObjList[ObjId]; + } else { ASSERT (0); return EFI_INVALID_PARAMETER; } @@ -166,15 +186,17 @@ DynPlatRepoAddObject ( } // Fixup self-token if necessary. - Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken); - if (EFI_ERROR (Status)) { - FreeCmObjNode (ObjNode); - ASSERT (0); - return Status; + if (EObjNameSpaceArm == NamespaceId) { + Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken); + if (EFI_ERROR (Status)) { + FreeCmObjNode (ObjNode); + ASSERT (0); + return Status; + } } // Add to link list. - InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link); + InsertTailList (ObjList, &ObjNode->Link); This->ObjectCount += 1; if (Token != NULL) { @@ -184,11 +206,14 @@ DynPlatRepoAddObject ( return EFI_SUCCESS; } -/** Group lists of CmObjNode from the ArmNameSpace to one array. +/** Group lists of CmObjNode from the Arm Namespace or ArchCommon namespace + to one array. @param [in] This This dynamic platform repository. - @param [in] ArmObjIndex Index in EARM_OBJECT_ID - (must be < EArmObjMax). + @param [in] NamespaceId The namespace ID which can be EObjNameSpaceArm or + EObjNameSpaceArchCommon. + @param [in] ObjIndex Index in EARM_OBJECT_ID (must be < EArmObjMax) or + EARCH_COMMON_OBJECT_ID (must be = EArmObjMax)) - { + if (This == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if (NamespaceId == EObjNameSpaceArm) { + if (ObjIndex >= EArmObjMax) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ListHead = &This->ArmCmObjList[ObjIndex]; + ObjArray = &This->ArmCmObjArray[ObjIndex]; + } else if (NamespaceId == EObjNameSpaceArchCommon) { + if (ObjIndex >= EArchCommonObjMax) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ListHead = &This->ArchCommonCmObjList[ObjIndex]; + ObjArray = &This->ArchCommonCmObjArray[ObjIndex]; + } else { ASSERT (0); return EFI_INVALID_PARAMETER; } - Count = 0; - Size = 0; - CmObjId = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex); - ListHead = &This->ArmCmObjList[ArmObjIndex]; - Link = GetFirstNode (ListHead); + Count = 0; + Size = 0; + CmObjId = CREATE_CM_OBJECT_ID (NamespaceId, ObjIndex); + Link = GetFirstNode (ListHead); // Compute the total count and size of the CmObj in the list. while (Link != ListHead) { @@ -235,7 +280,10 @@ GroupCmObjNodes ( return EFI_INVALID_PARAMETER; } - if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)) { + if ((CmObjDesc->Count != 1) && + ((NamespaceId != EObjNameSpaceArm) || + (ObjIndex != EArmObjCmRef))) + { // We expect each descriptor to contain an individual object. // EArmObjCmRef objects are counted as groups, so +1 as well. ASSERT (0); @@ -286,7 +334,7 @@ GroupCmObjNodes ( Link = GetNextNode (ListHead, Link); } // while - CmObjDesc = &This->ArmCmObjArray[ArmObjIndex]; + CmObjDesc = ObjArray; CmObjDesc->ObjectId = CmObjId; CmObjDesc->Size = (UINT32)Size; CmObjDesc->Count = (UINT32)Count; @@ -317,7 +365,7 @@ DynamicPlatRepoFinalise ( ) { EFI_STATUS Status; - UINTN ArmObjIndex; + UINTN ObjIndex; if ((This == NULL) || (This->RepoState != DynRepoTransient)) @@ -340,18 +388,29 @@ DynamicPlatRepoFinalise ( // - Convert the list of nodes to an array // (the array is wrapped in a CmObjDesc). // - Add the Token/CmObj binding to the token mapper. - for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) { - Status = GroupCmObjNodes (This, (UINT32)ArmObjIndex); + for (ObjIndex = 0; ObjIndex < EArmObjMax; ObjIndex++) { + Status = GroupCmObjNodes (This, EObjNameSpaceArm, (UINT32)ObjIndex); if (EFI_ERROR (Status)) { ASSERT (0); - // Free the TokenMapper. - // Ignore the returned Status since we already failed. - TokenMapperShutdown (&This->TokenMapper); - return Status; + goto error_handler; + } + } // for + + for (ObjIndex = 0; ObjIndex < EArchCommonObjMax; ObjIndex++) { + Status = GroupCmObjNodes (This, EObjNameSpaceArchCommon, (UINT32)ObjIndex); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto error_handler; } } // for return EFI_SUCCESS; + +error_handler: + // Free the TokenMapper. + // Ignore the returned Status since we already failed. + TokenMapperShutdown (&This->TokenMapper); + return Status; } /** Get a CmObj from the dynamic repository. @@ -376,9 +435,10 @@ DynamicPlatRepoGetObject ( IN OUT CM_OBJ_DESCRIPTOR *CmObjDesc ) { - EFI_STATUS Status; - CM_OBJ_DESCRIPTOR *Desc; - CM_OBJECT_ID ArmNamespaceObjId; + EFI_STATUS Status; + CM_OBJ_DESCRIPTOR *Desc; + CM_OBJECT_ID ObjId; + EOBJECT_NAMESPACE_ID NamespaceId; if ((This == NULL) || (CmObjDesc == NULL) || @@ -388,8 +448,28 @@ DynamicPlatRepoGetObject ( return EFI_INVALID_PARAMETER; } - ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId); - if (ArmNamespaceObjId >= EArmObjMax) { + NamespaceId = GET_CM_NAMESPACE_ID (CmObjectId); + ObjId = GET_CM_OBJECT_ID (CmObjectId); + + if (NamespaceId == EObjNameSpaceArm) { + if ((ObjId >= EArmObjMax) || + ((ObjId == EArmObjCmRef) && + (Token == CM_NULL_TOKEN))) + { + // EArmObjCmRef object must be requested using a valid token. + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Desc = &This->ArmCmObjArray[ObjId]; + } else if (NamespaceId == EObjNameSpaceArchCommon) { + if (ObjId >= EArchCommonObjMax) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Desc = &This->ArchCommonCmObjArray[ObjId]; + } else { ASSERT (0); return EFI_INVALID_PARAMETER; } @@ -406,14 +486,6 @@ DynamicPlatRepoGetObject ( return Status; } - if (ArmNamespaceObjId == EArmObjCmRef) { - // EArmObjCmRef object must be requested using a valid token. - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Desc = &This->ArmCmObjArray[ArmNamespaceObjId]; - // Nothing here. if (Desc->Count == 0) { return EFI_NOT_FOUND; @@ -462,6 +534,10 @@ DynamicPlatRepoInit ( InitializeListHead (&Repo->ArmCmObjList[Index]); } + for (Index = 0; Index < EArchCommonObjMax; Index++) { + InitializeListHead (&Repo->ArchCommonCmObjList[Index]); + } + Repo->ObjectCount = 0; Repo->RepoState = DynRepoTransient; @@ -470,31 +546,27 @@ DynamicPlatRepoInit ( return EFI_SUCCESS; } -/** Shutdown the dynamic platform repository. +/** Free Arm Namespace objects. - Free all the memory allocated for the dynamic platform repository. + Free all the memory allocated for the Arm namespace objects in the + dynamic platform repository. @param [in] DynPlatRepo The dynamic platform repository. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_SUCCESS Success. **/ -EFI_STATUS +STATIC +VOID EFIAPI -DynamicPlatRepoShutdown ( +DynamicPlatRepoFreeArmObjects ( IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo ) { - EFI_STATUS Status; UINT32 Index; LIST_ENTRY *ListHead; CM_OBJ_DESCRIPTOR *CmObjDesc; VOID *Data; - if (DynPlatRepo == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } + ASSERT (DynPlatRepo != NULL); // Free the list of objects. for (Index = 0; Index < EArmObjMax; Index++) { @@ -513,6 +585,73 @@ DynamicPlatRepoShutdown ( FreePool (Data); } } // for +} + +/** Free Arch Common Namespace objects. + + Free all the memory allocated for the Arch Common namespace objects in the + dynamic platform repository. + + @param [in] DynPlatRepo The dynamic platform repository. + +**/ +STATIC +VOID +EFIAPI +DynamicPlatRepoFreeArchCommonObjects ( + IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo + ) +{ + UINT32 Index; + LIST_ENTRY *ListHead; + CM_OBJ_DESCRIPTOR *CmObjDesc; + VOID *Data; + + ASSERT (DynPlatRepo != NULL); + + // Free the list of objects. + for (Index = 0; Index < EArchCommonObjMax; Index++) { + // Free all the nodes with this object Id. + ListHead = &DynPlatRepo->ArchCommonCmObjList[Index]; + while (!IsListEmpty (ListHead)) { + FreeCmObjNode ((CM_OBJ_NODE *)GetFirstNode (ListHead)); + } // while + } // for + + // Free the arrays. + CmObjDesc = DynPlatRepo->ArchCommonCmObjArray; + for (Index = 0; Index < EArchCommonObjMax; Index++) { + Data = CmObjDesc[Index].Data; + if (Data != NULL) { + FreePool (Data); + } + } // for +} + +/** Shutdown the dynamic platform repository. + + Free all the memory allocated for the dynamic platform repository. + + @param [in] DynPlatRepo The dynamic platform repository. + + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +EFIAPI +DynamicPlatRepoShutdown ( + IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo + ) +{ + EFI_STATUS Status; + + if (DynPlatRepo == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + DynamicPlatRepoFreeArmObjects (DynPlatRepo); + DynamicPlatRepoFreeArchCommonObjects (DynPlatRepo); // Free the TokenMapper Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper); diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h index eaee5d4ce9..0c842bc2d5 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h @@ -67,7 +67,16 @@ typedef struct DynamicPlatformRepositoryInfo { /// This array is populated when the Repo is finalized. CM_OBJ_DESCRIPTOR ArmCmObjArray[EArmObjMax]; - /// A token mapper for the objects in the ArmNamespaceObjectArray + /// Link lists of CmObj from the ArchCommon Namespace + /// that are added in the Transient state. + LIST_ENTRY ArchCommonCmObjList[EArchCommonObjMax]; + + /// Structure Members used in Finalized state. + /// An array of CmObj Descriptors from the ArchCommon Namespace + /// This array is populated when the Repo is finalized. + CM_OBJ_DESCRIPTOR ArchCommonCmObjArray[EArchCommonObjMax]; + + /// A token mapper for the objects in the CmObjArray /// The Token mapper is populated when the Repo is finalized in /// a call to DynamicPlatRepoFinalise (). TOKEN_MAPPER TokenMapper; -- cgit From fc8a16871c27270067b97a7275ec56f74041c76d Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 8 Mar 2024 16:31:21 +0000 Subject: DynamicTablesPkg: Update documentation for CM_OBJECT_ID Remove the partial listing of the Arm Namespace object IDs from and add a reference to the enum EARM_OBJECT_ID that is used to describe the object in the ARM Namespace. Also document that the Arch Common namespace objects will be described using the enum EARCH_COMMON_OBJECT_ID. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ConfigurationManagerObject.h | 35 +++------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h index 04b365f3d0..dd730ca677 100644 --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h @@ -51,38 +51,11 @@ Object ID's in the Standard Namespace: 1 - ACPI Table List 2 - SMBIOS Table List +Object ID's in the Arch Common Namespace: + See EARCH_COMMON_OBJECT_ID. + Object ID's in the ARM Namespace: - 0 - Reserved - 1 - Boot Architecture Info - 2 - CPU Info - 3 - Power Management Profile Info - 4 - GICC Info - 5 - GICD Info - 6 - GIC MSI Frame Info - 7 - GIC Redistributor Info - 8 - GIC ITS Info - 9 - Serial Console Port Info - 10 - Serial Debug Port Info - 11 - Generic Timer Info - 12 - Platform GT Block Info - 13 - Generic Timer Block Frame Info - 14 - Platform Generic Watchdog - 15 - PCI Configuration Space Info - 16 - Hypervisor Vendor Id - 17 - Fixed feature flags for FADT - 18 - ITS Group - 19 - Named Component - 20 - Root Complex - 21 - SMMUv1 or SMMUv2 - 22 - SMMUv3 - 23 - PMCG - 24 - GIC ITS Identifier Array - 25 - ID Mapping Array - 26 - SMMU Interrupt Array - 27 - Processor Hierarchy Info - 28 - Cache Info - 29 - Processor Hierarchy Node ID Info - 30 - CM Object Reference + See EARM_OBJECT_ID. */ typedef UINT32 CM_OBJECT_ID; -- cgit From b0b0812a6e085945bb01d31eaefd7d4b2c24c243 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Tue, 5 Mar 2024 14:23:38 +0000 Subject: DynamicTablesPkg: Drop Cpu Info object ID from Arm Namespace The Arm Namespace Object ID for CPU info was not used. Therefore, drop the EArmObjCpuInfo object ID. Also remove - the partial listing of the Arm Namespace object IDs from ConfigurationManagerObject.h and add a reference to the location where they are defined. - the parsing code in Configuration Manager ObjectParser. - update the Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 97 +++++++++++----------- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 93 ++++++++++----------- .../ConfigurationManagerObjectParser.c | 1 - DynamicTablesPkg/Readme.md | 97 +++++++++++----------- 4 files changed, 142 insertions(+), 146 deletions(-) diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 853d722b8c..2eeff594fc 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -30,55 +30,54 @@ typedef enum ArmObjectID { EArmObjReserved, ///< 0 - Reserved EArmObjBootArchInfo, ///< 1 - Boot Architecture Info - EArmObjCpuInfo, ///< 2 - CPU Info - EArmObjPowerManagementProfileInfo, ///< 3 - Power Management Profile Info - EArmObjGicCInfo, ///< 4 - GIC CPU Interface Info - EArmObjGicDInfo, ///< 5 - GIC Distributor Info - EArmObjGicMsiFrameInfo, ///< 6 - GIC MSI Frame Info - EArmObjGicRedistributorInfo, ///< 7 - GIC Redistributor Info - EArmObjGicItsInfo, ///< 8 - GIC ITS Info - EArmObjSerialConsolePortInfo, ///< 9 - Serial Console Port Info - EArmObjSerialDebugPortInfo, ///< 10 - Serial Debug Port Info - EArmObjGenericTimerInfo, ///< 11 - Generic Timer Info - EArmObjPlatformGTBlockInfo, ///< 12 - Platform GT Block Info - EArmObjGTBlockTimerFrameInfo, ///< 13 - Generic Timer Block Frame Info - EArmObjPlatformGenericWatchdogInfo, ///< 14 - Platform Generic Watchdog - EArmObjPciConfigSpaceInfo, ///< 15 - PCI Configuration Space Info - EArmObjHypervisorVendorIdentity, ///< 16 - Hypervisor Vendor Id - EArmObjFixedFeatureFlags, ///< 17 - Fixed feature flags for FADT - EArmObjItsGroup, ///< 18 - ITS Group - EArmObjNamedComponent, ///< 19 - Named Component - EArmObjRootComplex, ///< 20 - Root Complex - EArmObjSmmuV1SmmuV2, ///< 21 - SMMUv1 or SMMUv2 - EArmObjSmmuV3, ///< 22 - SMMUv3 - EArmObjPmcg, ///< 23 - PMCG - EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array - EArmObjIdMappingArray, ///< 25 - ID Mapping Array - EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 27 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 28 - Cache Info - EArmObjReserved29, ///< 29 - Reserved - EArmObjCmRef, ///< 30 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 31 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 32 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 33 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity - EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info - EArmObjCmn600Info, ///< 36 - CMN-600 Info - EArmObjLpiInfo, ///< 37 - Lpi Info - EArmObjPciAddressMapInfo, ///< 38 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info - EArmObjRmr, ///< 40 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor - EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 43 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 44 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 45 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 46 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 47 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 48 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 49 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 50 - P-State Dependency (PSD) Info + EArmObjPowerManagementProfileInfo, ///< 2 - Power Management Profile Info + EArmObjGicCInfo, ///< 3 - GIC CPU Interface Info + EArmObjGicDInfo, ///< 4 - GIC Distributor Info + EArmObjGicMsiFrameInfo, ///< 5 - GIC MSI Frame Info + EArmObjGicRedistributorInfo, ///< 6 - GIC Redistributor Info + EArmObjGicItsInfo, ///< 7 - GIC ITS Info + EArmObjSerialConsolePortInfo, ///< 8 - Serial Console Port Info + EArmObjSerialDebugPortInfo, ///< 9 - Serial Debug Port Info + EArmObjGenericTimerInfo, ///< 10 - Generic Timer Info + EArmObjPlatformGTBlockInfo, ///< 11 - Platform GT Block Info + EArmObjGTBlockTimerFrameInfo, ///< 12 - Generic Timer Block Frame Info + EArmObjPlatformGenericWatchdogInfo, ///< 13 - Platform Generic Watchdog + EArmObjPciConfigSpaceInfo, ///< 14 - PCI Configuration Space Info + EArmObjHypervisorVendorIdentity, ///< 15 - Hypervisor Vendor Id + EArmObjFixedFeatureFlags, ///< 16 - Fixed feature flags for FADT + EArmObjItsGroup, ///< 17 - ITS Group + EArmObjNamedComponent, ///< 18 - Named Component + EArmObjRootComplex, ///< 19 - Root Complex + EArmObjSmmuV1SmmuV2, ///< 20 - SMMUv1 or SMMUv2 + EArmObjSmmuV3, ///< 21 - SMMUv3 + EArmObjPmcg, ///< 22 - PMCG + EArmObjGicItsIdentifierArray, ///< 23 - GIC ITS Identifier Array + EArmObjIdMappingArray, ///< 24 - ID Mapping Array + EArmObjSmmuInterruptArray, ///< 25 - SMMU Interrupt Array + EArmObjProcHierarchyInfo, ///< 26 - Processor Hierarchy Info + EArmObjCacheInfo, ///< 27 - Cache Info + EArmObjReserved29, ///< 28 - Reserved + EArmObjCmRef, ///< 29 - CM Object Reference + EArmObjMemoryAffinityInfo, ///< 30 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 31 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 32 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 33 - Generic Initiator Affinity + EArmObjSerialPortInfo, ///< 34 - Generic Serial Port Info + EArmObjCmn600Info, ///< 35 - CMN-600 Info + EArmObjLpiInfo, ///< 36 - Lpi Info + EArmObjPciAddressMapInfo, ///< 37 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 38 - Pci Interrupt Map Info + EArmObjRmr, ///< 39 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 40 - Memory Range Descriptor + EArmObjCpcInfo, ///< 41 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 42 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 43 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 44 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 45 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 46 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 47 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 48 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 49 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index df9452efe5..07e26a4f4e 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -145,55 +145,54 @@ CONST CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 0 - Reserved NULL, ///< 1 - Boot Architecture Info - NULL, ///< 2 - CPU Info - NULL, ///< 3 - Power Management Profile Info - NULL, ///< 4 - GIC CPU Interface Info - NULL, ///< 5 - GIC Distributor Info - NULL, ///< 6 - GIC MSI Frame Info - NULL, ///< 7 - GIC Redistributor Info - NULL, ///< 8 - GIC ITS Info - NULL, ///< 9 - Serial Console Port Info - NULL, ///< 10 - Serial Debug Port Info - NULL, ///< 11 - Generic Timer Info - NULL, ///< 12 - Platform GT Block Info - NULL, ///< 13 - Generic Timer Block Frame Info - NULL, ///< 14 - Platform Generic Watchdog - NULL, ///< 15 - PCI Configuration Space Info - NULL, ///< 16 - Hypervisor Vendor Id - NULL, ///< 17 - Fixed feature flags for FADT - TokenFixerItsGroup, ///< 18 - ITS Group - TokenFixerNamedComponentNode, ///< 19 - Named Component - TokenFixerRootComplexNode, ///< 20 - Root Complex - TokenFixerNotImplemented, ///< 21 - SMMUv1 or SMMUv2 - TokenFixerSmmuV3Node, ///< 22 - SMMUv3 - TokenFixerNotImplemented, ///< 23 - PMCG - NULL, ///< 24 - GIC ITS Identifier Array - NULL, ///< 25 - ID Mapping Array - NULL, ///< 26 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 27 - Processor Hierarchy Info - TokenFixerNotImplemented, ///< 28 - Cache Info + NULL, ///< 2 - Power Management Profile Info + NULL, ///< 3 - GIC CPU Interface Info + NULL, ///< 4 - GIC Distributor Info + NULL, ///< 5 - GIC MSI Frame Info + NULL, ///< 6 - GIC Redistributor Info + NULL, ///< 7 - GIC ITS Info + NULL, ///< 8 - Serial Console Port Info + NULL, ///< 9 - Serial Debug Port Info + NULL, ///< 10 - Generic Timer Info + NULL, ///< 11 - Platform GT Block Info + NULL, ///< 12 - Generic Timer Block Frame Info + NULL, ///< 13 - Platform Generic Watchdog + NULL, ///< 14 - PCI Configuration Space Info + NULL, ///< 15 - Hypervisor Vendor Id + NULL, ///< 16 - Fixed feature flags for FADT + TokenFixerItsGroup, ///< 17 - ITS Group + TokenFixerNamedComponentNode, ///< 18 - Named Component + TokenFixerRootComplexNode, ///< 19 - Root Complex + TokenFixerNotImplemented, ///< 20 - SMMUv1 or SMMUv2 + TokenFixerSmmuV3Node, ///< 21 - SMMUv3 + TokenFixerNotImplemented, ///< 22 - PMCG + NULL, ///< 23 - GIC ITS Identifier Array + NULL, ///< 24 - ID Mapping Array + NULL, ///< 25 - SMMU Interrupt Array + TokenFixerNotImplemented, ///< 26 - Processor Hierarchy Info + TokenFixerNotImplemented, ///< 27 - Cache Info TokenFixerNotImplemented, ///< 29 - Reserved - NULL, ///< 30 - CM Object Reference - NULL, ///< 31 - Memory Affinity Info - NULL, ///< 32 - Device Handle Acpi - NULL, ///< 33 - Device Handle Pci - NULL, ///< 34 - Generic Initiator Affinity - NULL, ///< 35 - Generic Serial Port Info - NULL, ///< 36 - CMN-600 Info - NULL, ///< 37 - Lpi Info - NULL, ///< 38 - Pci Address Map Info - NULL, ///< 39 - Pci Interrupt Map Info - NULL, ///< 40 - Reserved Memory Range Node - NULL, ///< 41 - Memory Range Descriptor - NULL, ///< 42 - Continuous Performance Control Info - NULL, ///< 43 - Pcc Subspace Type 0 Info + NULL, ///< 29 - CM Object Reference + NULL, ///< 30 - Memory Affinity Info + NULL, ///< 31 - Device Handle Acpi + NULL, ///< 32 - Device Handle Pci + NULL, ///< 33 - Generic Initiator Affinity + NULL, ///< 34 - Generic Serial Port Info + NULL, ///< 35 - CMN-600 Info + NULL, ///< 36 - Lpi Info + NULL, ///< 37 - Pci Address Map Info + NULL, ///< 38 - Pci Interrupt Map Info + NULL, ///< 39 - Reserved Memory Range Node + NULL, ///< 40 - Memory Range Descriptor + NULL, ///< 41 - Continuous Performance Control Info + NULL, ///< 42 - Pcc Subspace Type 0 Info + NULL, ///< 43 - Pcc Subspace Type 2 Info NULL, ///< 44 - Pcc Subspace Type 2 Info - NULL, ///< 45 - Pcc Subspace Type 2 Info - NULL, ///< 46 - Pcc Subspace Type 3 Info - NULL, ///< 47 - Pcc Subspace Type 4 Info - NULL, ///< 48 - Pcc Subspace Type 5 Info - NULL, ///< 49 - Embedded Trace Extension/Module Info - NULL ///< 50 - P-State Dependency (PSD) Info + NULL, ///< 45 - Pcc Subspace Type 3 Info + NULL, ///< 46 - Pcc Subspace Type 4 Info + NULL, ///< 47 - Pcc Subspace Type 5 Info + NULL, ///< 48 - Embedded Trace Extension/Module Info + NULL ///< 49 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 6f5dbdfd2d..af5884832c 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -679,7 +679,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved), CM_PARSER_ADD_OBJECT (EArmObjBootArchInfo, CmArmBootArchInfoParser), - CM_PARSER_ADD_OBJECT_RESERVED (EArmObjCpuInfo), CM_PARSER_ADD_OBJECT (EArmObjPowerManagementProfileInfo, CmArmPowerManagementProfileInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicCInfo, CmArmGicCInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicDInfo, CmArmGicDInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 1ae423af75..80759f9534 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -442,55 +442,54 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | ---: | :-------------------------- | :--- | | 0 | Reserved | | | 1 | Boot Architecture Info | | -| 2 | CPU Info | | -| 3 | Power Management Profile Info | | -| 4 | GICC Info | | -| 5 | GICD Info | | -| 6 | GIC MSI Frame Info | | -| 7 | GIC Redistributor Info | | -| 8 | GIC ITS Info | | -| 9 | Serial Console Port Info | | -| 10 | Serial Debug Port Info | | -| 11 | Generic Timer Info | | -| 12 | Platform GT Block Info | | -| 13 | Generic Timer Block Frame Info | | -| 14 | Platform Generic Watchdog | | -| 15 | PCI Configuration Space Info | | -| 16 | Hypervisor Vendor Id | | -| 17 | Fixed feature flags for FADT | | -| 18 | ITS Group | | -| 19 | Named Component | | -| 20 | Root Complex | | -| 21 | SMMUv1 or SMMUv2 | | -| 22 | SMMUv3 | | -| 23 | PMCG | | -| 24 | GIC ITS Identifier Array | | -| 25 | ID Mapping Array | | -| 26 | SMMU Interrupt Array | | -| 27 | Processor Hierarchy Info | | -| 28 | Cache Info | | -| 29 | Reserved29 | | -| 30 | CM Object Reference | | -| 31 | Memory Affinity Info | | -| 32 | Device Handle Acpi | | -| 33 | Device Handle PCI | | -| 34 | Generic Initiator Affinity Info | | -| 35 | Serial Port Info | | -| 36 | CMN 600 Info | | -| 37 | Low Power Idle State Info | | -| 38 | PCI Address Map Info | | -| 39 | PCI Interrupt Map Info | | -| 40 | Reserved Memory Range Node | | -| 41 | Memory Range Descriptor | | -| 42 | Continuous Performance Control Info | | -| 43 | Pcc Subspace Type 0 Info | | -| 44 | Pcc Subspace Type 1 Info | | -| 45 | Pcc Subspace Type 2 Info | | -| 46 | Pcc Subspace Type 3 Info | | -| 47 | Pcc Subspace Type 4 Info | | -| 48 | Pcc Subspace Type 5 Info | | -| 49 | Embedded Trace Extension/Module Info | | -| 50 | P-State Dependency (PSD) Info | | +| 2 | Power Management Profile Info | Move to Arch Common NS | +| 3 | GICC Info | | +| 4 | GICD Info | | +| 5 | GIC MSI Frame Info | | +| 6 | GIC Redistributor Info | | +| 7 | GIC ITS Info | | +| 8 | Serial Console Port Info | Move to Arch Common NS | +| 9 | Serial Debug Port Info | Move to Arch Common NS | +| 10 | Generic Timer Info | | +| 11 | Platform GT Block Info | | +| 12 | Generic Timer Block Frame Info | | +| 13 | Platform Generic Watchdog | | +| 14 | PCI Configuration Space Info | Move to Arch Common NS | +| 15 | Hypervisor Vendor Id | Move to Arch Common NS | +| 16 | Fixed feature flags for FADT | Move to Arch Common NS | +| 17 | ITS Group | | +| 18 | Named Component | | +| 19 | Root Complex | | +| 20 | SMMUv1 or SMMUv2 | | +| 21 | SMMUv3 | | +| 22 | PMCG | | +| 23 | GIC ITS Identifier Array | | +| 24 | ID Mapping Array | | +| 25 | SMMU Interrupt Array | | +| 26 | Processor Hierarchy Info | Move to Arch Common NS | +| 27 | Cache Info | Move to Arch Common NS | +| 28 | Reserved29 | Unused to be dropped.| +| 29 | CM Object Reference | Move to Arch Common NS | +| 30 | Memory Affinity Info | Move to Arch Common NS | +| 31 | Device Handle Acpi | Move to Arch Common NS | +| 32 | Device Handle PCI | Move to Arch Common NS | +| 33 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 34 | Serial Port Info | Move to Arch Common NS | +| 35 | CMN 600 Info | | +| 36 | Low Power Idle State Info | Move to Arch Common NS | +| 37 | PCI Address Map Info | Move to Arch Common NS | +| 38 | PCI Interrupt Map Info | Move to Arch Common NS | +| 39 | Reserved Memory Range Node | | +| 40 | Memory Range Descriptor | | +| 41 | Continuous Performance Control Info | Move to Arch Common NS | +| 42 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 43 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 44 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 45 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 46 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 47 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 48 | Embedded Trace Extension/Module Info | | +| 49 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: -- cgit From 58c36ce09f677a2e14681d3baf19753e86c6c103 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Tue, 5 Mar 2024 14:31:49 +0000 Subject: DynamicTablesPkg: Drop Reserved29 object ID from Arm Namespace The Arm Namespace Object ID Reserved29 was a reserved ID that was never used. Therefore, drop the EArmObjReserved29 object ID also update the Dynamic Plat Repo TokenFixer map and the Configuration Manager Object Parser. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 43 +++++++++++----------- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 41 ++++++++++----------- .../ConfigurationManagerObjectParser.c | 1 - DynamicTablesPkg/Readme.md | 43 +++++++++++----------- 4 files changed, 62 insertions(+), 66 deletions(-) diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 2eeff594fc..f7e1a0933f 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -56,28 +56,27 @@ typedef enum ArmObjectID { EArmObjSmmuInterruptArray, ///< 25 - SMMU Interrupt Array EArmObjProcHierarchyInfo, ///< 26 - Processor Hierarchy Info EArmObjCacheInfo, ///< 27 - Cache Info - EArmObjReserved29, ///< 28 - Reserved - EArmObjCmRef, ///< 29 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 30 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 31 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 32 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 33 - Generic Initiator Affinity - EArmObjSerialPortInfo, ///< 34 - Generic Serial Port Info - EArmObjCmn600Info, ///< 35 - CMN-600 Info - EArmObjLpiInfo, ///< 36 - Lpi Info - EArmObjPciAddressMapInfo, ///< 37 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 38 - Pci Interrupt Map Info - EArmObjRmr, ///< 39 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 40 - Memory Range Descriptor - EArmObjCpcInfo, ///< 41 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 42 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 43 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 44 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 45 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 46 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 47 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 48 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 49 - P-State Dependency (PSD) Info + EArmObjCmRef, ///< 28 - CM Object Reference + EArmObjMemoryAffinityInfo, ///< 29 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 30 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 31 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 32 - Generic Initiator Affinity + EArmObjSerialPortInfo, ///< 33 - Generic Serial Port Info + EArmObjCmn600Info, ///< 34 - CMN-600 Info + EArmObjLpiInfo, ///< 35 - Lpi Info + EArmObjPciAddressMapInfo, ///< 36 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 37 - Pci Interrupt Map Info + EArmObjRmr, ///< 38 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 39 - Memory Range Descriptor + EArmObjCpcInfo, ///< 40 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 41 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 42 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 43 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 44 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 45 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 46 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 47 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 48 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 07e26a4f4e..833fa2d6a2 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -171,28 +171,27 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 25 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 26 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 27 - Cache Info - TokenFixerNotImplemented, ///< 29 - Reserved - NULL, ///< 29 - CM Object Reference - NULL, ///< 30 - Memory Affinity Info - NULL, ///< 31 - Device Handle Acpi - NULL, ///< 32 - Device Handle Pci - NULL, ///< 33 - Generic Initiator Affinity - NULL, ///< 34 - Generic Serial Port Info - NULL, ///< 35 - CMN-600 Info - NULL, ///< 36 - Lpi Info - NULL, ///< 37 - Pci Address Map Info - NULL, ///< 38 - Pci Interrupt Map Info - NULL, ///< 39 - Reserved Memory Range Node - NULL, ///< 40 - Memory Range Descriptor - NULL, ///< 41 - Continuous Performance Control Info - NULL, ///< 42 - Pcc Subspace Type 0 Info + NULL, ///< 28 - CM Object Reference + NULL, ///< 29 - Memory Affinity Info + NULL, ///< 30 - Device Handle Acpi + NULL, ///< 31 - Device Handle Pci + NULL, ///< 32 - Generic Initiator Affinity + NULL, ///< 33 - Generic Serial Port Info + NULL, ///< 34 - CMN-600 Info + NULL, ///< 35 - Lpi Info + NULL, ///< 36 - Pci Address Map Info + NULL, ///< 37 - Pci Interrupt Map Info + NULL, ///< 38 - Reserved Memory Range Node + NULL, ///< 39 - Memory Range Descriptor + NULL, ///< 40 - Continuous Performance Control Info + NULL, ///< 41 - Pcc Subspace Type 0 Info + NULL, ///< 42 - Pcc Subspace Type 2 Info NULL, ///< 43 - Pcc Subspace Type 2 Info - NULL, ///< 44 - Pcc Subspace Type 2 Info - NULL, ///< 45 - Pcc Subspace Type 3 Info - NULL, ///< 46 - Pcc Subspace Type 4 Info - NULL, ///< 47 - Pcc Subspace Type 5 Info - NULL, ///< 48 - Embedded Trace Extension/Module Info - NULL ///< 49 - P-State Dependency (PSD) Info + NULL, ///< 44 - Pcc Subspace Type 3 Info + NULL, ///< 45 - Pcc Subspace Type 4 Info + NULL, ///< 46 - Pcc Subspace Type 5 Info + NULL, ///< 47 - Embedded Trace Extension/Module Info + NULL ///< 48 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index af5884832c..6896463b28 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -705,7 +705,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArmGenericInterruptParser), CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), - CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved29), CM_PARSER_ADD_OBJECT (EArmObjCmRef, CmArmObjRefParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryAffinityInfo, CmArmMemoryAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandleAcpi, CmArmDeviceHandleAcpiParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 80759f9534..8d30bf560b 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -468,28 +468,27 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 25 | SMMU Interrupt Array | | | 26 | Processor Hierarchy Info | Move to Arch Common NS | | 27 | Cache Info | Move to Arch Common NS | -| 28 | Reserved29 | Unused to be dropped.| -| 29 | CM Object Reference | Move to Arch Common NS | -| 30 | Memory Affinity Info | Move to Arch Common NS | -| 31 | Device Handle Acpi | Move to Arch Common NS | -| 32 | Device Handle PCI | Move to Arch Common NS | -| 33 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 34 | Serial Port Info | Move to Arch Common NS | -| 35 | CMN 600 Info | | -| 36 | Low Power Idle State Info | Move to Arch Common NS | -| 37 | PCI Address Map Info | Move to Arch Common NS | -| 38 | PCI Interrupt Map Info | Move to Arch Common NS | -| 39 | Reserved Memory Range Node | | -| 40 | Memory Range Descriptor | | -| 41 | Continuous Performance Control Info | Move to Arch Common NS | -| 42 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 43 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 44 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 45 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 46 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 47 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 48 | Embedded Trace Extension/Module Info | | -| 49 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 28 | CM Object Reference | Move to Arch Common NS | +| 29 | Memory Affinity Info | Move to Arch Common NS | +| 30 | Device Handle Acpi | Move to Arch Common NS | +| 31 | Device Handle PCI | Move to Arch Common NS | +| 32 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 33 | Serial Port Info | Move to Arch Common NS | +| 34 | CMN 600 Info | | +| 35 | Low Power Idle State Info | Move to Arch Common NS | +| 36 | PCI Address Map Info | Move to Arch Common NS | +| 37 | PCI Interrupt Map Info | Move to Arch Common NS | +| 38 | Reserved Memory Range Node | | +| 39 | Memory Range Descriptor | | +| 40 | Continuous Performance Control Info | Move to Arch Common NS | +| 41 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 42 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 43 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 44 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 45 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 46 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 47 | Embedded Trace Extension/Module Info | | +| 48 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: -- cgit From 6dad45b7dd1eeeee633d5628d2dfe8b83ac04413 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Thu, 7 Mar 2024 13:31:39 +0000 Subject: ArmVirtPkg: Kvmtool: Update ConfigMgr to support ArchCommon Update the Configuration Manager for Kvmtool guest firmware to handle ArchComm namespace objects. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c index 68b9d2bf05..4a76583f96 100644 --- a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c +++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c @@ -722,6 +722,73 @@ GetStandardNameSpaceObject ( return Status; } +/** + Return an ArchCommon namespace object. + + @param [in] This Pointer to the Configuration Manager Protocol. + @param [in] CmObjectId The Configuration Manager Object ID. + @param [in] Token An optional token identifying the object. If + unused this must be CM_NULL_TOKEN. + @param [in, out] CmObject Pointer to the Configuration Manager Object + descriptor describing the requested Object. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not found. +**/ +EFI_STATUS +EFIAPI +GetArchCommonNameSpaceObject ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject + ) +{ + EFI_STATUS Status; + EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; + + if ((This == NULL) || (CmObject == NULL)) { + ASSERT (This != NULL); + ASSERT (CmObject != NULL); + return EFI_INVALID_PARAMETER; + } + + Status = EFI_NOT_FOUND; + PlatformRepo = This->PlatRepoInfo; + + // + // First check among the static objects. + // + switch (GET_CM_OBJECT_ID (CmObjectId)) { + default: + // + // No match found among the static objects. + // Check the dynamic objects. + // + Status = DynamicPlatRepoGetObject ( + PlatformRepo->DynamicPlatformRepo, + CmObjectId, + Token, + CmObject + ); + break; + } // switch + + if (Status == EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "INFO: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n", + CmObjectId, + Status + )); + } else { + ASSERT_EFI_ERROR (Status); + } + + return Status; +} + /** Return an ARM namespace object. @@ -929,6 +996,9 @@ ArmKvmtoolPlatformGetObject ( case EObjNameSpaceStandard: Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject); break; + case EObjNameSpaceArchCommon: + Status = GetArchCommonNameSpaceObject (This, CmObjectId, Token, CmObject); + break; case EObjNameSpaceArm: Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject); break; -- cgit From 4362ddea7f068e27b6f2a763018da3ed60178f2a Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Tue, 5 Mar 2024 16:34:46 +0000 Subject: DynamicTablesPkg: Move Power Mgmt Profile Info Object Move PowerManagementProfileInfo Object from Arm Namespace to the Arch Common namespace. The following updates are also done to reflect the changes introduced by the move: - Update the FADT Generator to migrate to use the Power Management Profile Info object CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO and EArchCommonObjPowerManagementProfileInfo. - Update the Configuration manager object parser to parse Arch Common namespace objects and update the parsing of the Power Management Profile information object from Arm namespace to the Arch Common namespace. - Update the Dynamic Plat Repo TokenFixer map Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 18 ++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 105 +++++++++------------ .../Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c | 14 +-- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 91 +++++++++--------- .../ConfigurationManagerObjectParser.c | 6 +- DynamicTablesPkg/Readme.md | 94 +++++++++--------- 6 files changed, 166 insertions(+), 162 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index e4205d6ba6..bbf3cd1e2e 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -21,7 +21,25 @@ */ typedef enum ArchCommonObjectID { EArchCommonObjReserved, ///< 0 - Reserved + EArchCommonObjPowerManagementProfileInfo, ///< 1 - Power Management Profile Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; +#pragma pack(1) + +/** A structure that describes the + Power Management Profile Information for the Platform. + + ID: EArchCommonObjPowerManagementProfileInfo +*/ +typedef struct CmArchCommonPowerManagementProfileInfo { + /** This is the Preferred_PM_Profile field of the FADT Table + described in the ACPI Specification + */ + UINT8 PowerManagementProfile; +} CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO; + + +#pragma pack() + #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index f7e1a0933f..3d9a151846 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -30,53 +30,52 @@ typedef enum ArmObjectID { EArmObjReserved, ///< 0 - Reserved EArmObjBootArchInfo, ///< 1 - Boot Architecture Info - EArmObjPowerManagementProfileInfo, ///< 2 - Power Management Profile Info - EArmObjGicCInfo, ///< 3 - GIC CPU Interface Info - EArmObjGicDInfo, ///< 4 - GIC Distributor Info - EArmObjGicMsiFrameInfo, ///< 5 - GIC MSI Frame Info - EArmObjGicRedistributorInfo, ///< 6 - GIC Redistributor Info - EArmObjGicItsInfo, ///< 7 - GIC ITS Info - EArmObjSerialConsolePortInfo, ///< 8 - Serial Console Port Info - EArmObjSerialDebugPortInfo, ///< 9 - Serial Debug Port Info - EArmObjGenericTimerInfo, ///< 10 - Generic Timer Info - EArmObjPlatformGTBlockInfo, ///< 11 - Platform GT Block Info - EArmObjGTBlockTimerFrameInfo, ///< 12 - Generic Timer Block Frame Info - EArmObjPlatformGenericWatchdogInfo, ///< 13 - Platform Generic Watchdog - EArmObjPciConfigSpaceInfo, ///< 14 - PCI Configuration Space Info - EArmObjHypervisorVendorIdentity, ///< 15 - Hypervisor Vendor Id - EArmObjFixedFeatureFlags, ///< 16 - Fixed feature flags for FADT - EArmObjItsGroup, ///< 17 - ITS Group - EArmObjNamedComponent, ///< 18 - Named Component - EArmObjRootComplex, ///< 19 - Root Complex - EArmObjSmmuV1SmmuV2, ///< 20 - SMMUv1 or SMMUv2 - EArmObjSmmuV3, ///< 21 - SMMUv3 - EArmObjPmcg, ///< 22 - PMCG - EArmObjGicItsIdentifierArray, ///< 23 - GIC ITS Identifier Array - EArmObjIdMappingArray, ///< 24 - ID Mapping Array - EArmObjSmmuInterruptArray, ///< 25 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 26 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 27 - Cache Info - EArmObjCmRef, ///< 28 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 29 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 30 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 31 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 32 - Generic Initiator Affinity - EArmObjSerialPortInfo, ///< 33 - Generic Serial Port Info - EArmObjCmn600Info, ///< 34 - CMN-600 Info - EArmObjLpiInfo, ///< 35 - Lpi Info - EArmObjPciAddressMapInfo, ///< 36 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 37 - Pci Interrupt Map Info - EArmObjRmr, ///< 38 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 39 - Memory Range Descriptor - EArmObjCpcInfo, ///< 40 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 41 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 42 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 43 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 44 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 45 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 46 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 47 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 48 - P-State Dependency (PSD) Info + EArmObjGicCInfo, ///< 2 - GIC CPU Interface Info + EArmObjGicDInfo, ///< 3 - GIC Distributor Info + EArmObjGicMsiFrameInfo, ///< 4 - GIC MSI Frame Info + EArmObjGicRedistributorInfo, ///< 5 - GIC Redistributor Info + EArmObjGicItsInfo, ///< 6 - GIC ITS Info + EArmObjSerialConsolePortInfo, ///< 7 - Serial Console Port Info + EArmObjSerialDebugPortInfo, ///< 8 - Serial Debug Port Info + EArmObjGenericTimerInfo, ///< 9 - Generic Timer Info + EArmObjPlatformGTBlockInfo, ///< 10 - Platform GT Block Info + EArmObjGTBlockTimerFrameInfo, ///< 11 - Generic Timer Block Frame Info + EArmObjPlatformGenericWatchdogInfo, ///< 12 - Platform Generic Watchdog + EArmObjPciConfigSpaceInfo, ///< 13 - PCI Configuration Space Info + EArmObjHypervisorVendorIdentity, ///< 14 - Hypervisor Vendor Id + EArmObjFixedFeatureFlags, ///< 15 - Fixed feature flags for FADT + EArmObjItsGroup, ///< 16 - ITS Group + EArmObjNamedComponent, ///< 17 - Named Component + EArmObjRootComplex, ///< 18 - Root Complex + EArmObjSmmuV1SmmuV2, ///< 19 - SMMUv1 or SMMUv2 + EArmObjSmmuV3, ///< 20 - SMMUv3 + EArmObjPmcg, ///< 21 - PMCG + EArmObjGicItsIdentifierArray, ///< 22 - GIC ITS Identifier Array + EArmObjIdMappingArray, ///< 23 - ID Mapping Array + EArmObjSmmuInterruptArray, ///< 24 - SMMU Interrupt Array + EArmObjProcHierarchyInfo, ///< 25 - Processor Hierarchy Info + EArmObjCacheInfo, ///< 26 - Cache Info + EArmObjCmRef, ///< 27 - CM Object Reference + EArmObjMemoryAffinityInfo, ///< 28 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 29 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 30 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 31 - Generic Initiator Affinity + EArmObjSerialPortInfo, ///< 32 - Generic Serial Port Info + EArmObjCmn600Info, ///< 33 - CMN-600 Info + EArmObjLpiInfo, ///< 34 - Lpi Info + EArmObjPciAddressMapInfo, ///< 35 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 36 - Pci Interrupt Map Info + EArmObjRmr, ///< 37 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 38 - Memory Range Descriptor + EArmObjCpcInfo, ///< 39 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 40 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 41 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 42 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 43 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 44 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 45 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 46 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 47 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -92,18 +91,6 @@ typedef struct CmArmBootArchInfo { UINT16 BootArchFlags; } CM_ARM_BOOT_ARCH_INFO; -/** A structure that describes the - Power Management Profile Information for the Platform. - - ID: EArmObjPowerManagementProfileInfo -*/ -typedef struct CmArmPowerManagementProfileInfo { - /** This is the Preferred_PM_Profile field of the FADT Table - described in the ACPI Specification - */ - UINT8 PowerManagementProfile; -} CM_ARM_POWER_MANAGEMENT_PROFILE_INFO; - /** A structure that describes the GIC CPU Interface for the Platform. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c index 57aaaf85e6..ea8c821d11 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c @@ -25,7 +25,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjPowerManagementProfileInfo + - EArchCommonObjPowerManagementProfileInfo - EArmObjBootArchInfo - EArmObjHypervisorVendorIdentity (OPTIONAL) */ @@ -202,9 +202,9 @@ EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = { Management Profile Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPowerManagementProfileInfo, - CM_ARM_POWER_MANAGEMENT_PROFILE_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPowerManagementProfileInfo, + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO ); /** This macro expands to a function that retrieves the Boot @@ -253,13 +253,13 @@ FadtAddPmProfileInfo ( IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol ) { - EFI_STATUS Status; - CM_ARM_POWER_MANAGEMENT_PROFILE_INFO *PmProfile; + EFI_STATUS Status; + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO *PmProfile; ASSERT (CfgMgrProtocol != NULL); // Get the Power Management Profile from the Platform Configuration Manager - Status = GetEArmObjPowerManagementProfileInfo ( + Status = GetEArchCommonObjPowerManagementProfileInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &PmProfile, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 833fa2d6a2..ef2a8dcfdd 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -145,53 +145,52 @@ CONST CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 0 - Reserved NULL, ///< 1 - Boot Architecture Info - NULL, ///< 2 - Power Management Profile Info - NULL, ///< 3 - GIC CPU Interface Info - NULL, ///< 4 - GIC Distributor Info - NULL, ///< 5 - GIC MSI Frame Info - NULL, ///< 6 - GIC Redistributor Info - NULL, ///< 7 - GIC ITS Info - NULL, ///< 8 - Serial Console Port Info - NULL, ///< 9 - Serial Debug Port Info - NULL, ///< 10 - Generic Timer Info - NULL, ///< 11 - Platform GT Block Info - NULL, ///< 12 - Generic Timer Block Frame Info - NULL, ///< 13 - Platform Generic Watchdog - NULL, ///< 14 - PCI Configuration Space Info - NULL, ///< 15 - Hypervisor Vendor Id - NULL, ///< 16 - Fixed feature flags for FADT - TokenFixerItsGroup, ///< 17 - ITS Group - TokenFixerNamedComponentNode, ///< 18 - Named Component - TokenFixerRootComplexNode, ///< 19 - Root Complex - TokenFixerNotImplemented, ///< 20 - SMMUv1 or SMMUv2 - TokenFixerSmmuV3Node, ///< 21 - SMMUv3 - TokenFixerNotImplemented, ///< 22 - PMCG - NULL, ///< 23 - GIC ITS Identifier Array - NULL, ///< 24 - ID Mapping Array - NULL, ///< 25 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 26 - Processor Hierarchy Info - TokenFixerNotImplemented, ///< 27 - Cache Info - NULL, ///< 28 - CM Object Reference - NULL, ///< 29 - Memory Affinity Info - NULL, ///< 30 - Device Handle Acpi - NULL, ///< 31 - Device Handle Pci - NULL, ///< 32 - Generic Initiator Affinity - NULL, ///< 33 - Generic Serial Port Info - NULL, ///< 34 - CMN-600 Info - NULL, ///< 35 - Lpi Info - NULL, ///< 36 - Pci Address Map Info - NULL, ///< 37 - Pci Interrupt Map Info - NULL, ///< 38 - Reserved Memory Range Node - NULL, ///< 39 - Memory Range Descriptor - NULL, ///< 40 - Continuous Performance Control Info - NULL, ///< 41 - Pcc Subspace Type 0 Info + NULL, ///< 2 - GIC CPU Interface Info + NULL, ///< 3 - GIC Distributor Info + NULL, ///< 4 - GIC MSI Frame Info + NULL, ///< 5 - GIC Redistributor Info + NULL, ///< 6 - GIC ITS Info + NULL, ///< 7 - Serial Console Port Info + NULL, ///< 8 - Serial Debug Port Info + NULL, ///< 9 - Generic Timer Info + NULL, ///< 10 - Platform GT Block Info + NULL, ///< 11 - Generic Timer Block Frame Info + NULL, ///< 12 - Platform Generic Watchdog + NULL, ///< 13 - PCI Configuration Space Info + NULL, ///< 14 - Hypervisor Vendor Id + NULL, ///< 15 - Fixed feature flags for FADT + TokenFixerItsGroup, ///< 16 - ITS Group + TokenFixerNamedComponentNode, ///< 17 - Named Component + TokenFixerRootComplexNode, ///< 18 - Root Complex + TokenFixerNotImplemented, ///< 19 - SMMUv1 or SMMUv2 + TokenFixerSmmuV3Node, ///< 20 - SMMUv3 + TokenFixerNotImplemented, ///< 21 - PMCG + NULL, ///< 22 - GIC ITS Identifier Array + NULL, ///< 23 - ID Mapping Array + NULL, ///< 24 - SMMU Interrupt Array + TokenFixerNotImplemented, ///< 25 - Processor Hierarchy Info + TokenFixerNotImplemented, ///< 26 - Cache Info + NULL, ///< 27 - CM Object Reference + NULL, ///< 28 - Memory Affinity Info + NULL, ///< 29 - Device Handle Acpi + NULL, ///< 30 - Device Handle Pci + NULL, ///< 31 - Generic Initiator Affinity + NULL, ///< 32 - Generic Serial Port Info + NULL, ///< 33 - CMN-600 Info + NULL, ///< 34 - Lpi Info + NULL, ///< 35 - Pci Address Map Info + NULL, ///< 36 - Pci Interrupt Map Info + NULL, ///< 37 - Reserved Memory Range Node + NULL, ///< 38 - Memory Range Descriptor + NULL, ///< 39 - Continuous Performance Control Info + NULL, ///< 40 - Pcc Subspace Type 0 Info + NULL, ///< 41 - Pcc Subspace Type 2 Info NULL, ///< 42 - Pcc Subspace Type 2 Info - NULL, ///< 43 - Pcc Subspace Type 2 Info - NULL, ///< 44 - Pcc Subspace Type 3 Info - NULL, ///< 45 - Pcc Subspace Type 4 Info - NULL, ///< 46 - Pcc Subspace Type 5 Info - NULL, ///< 47 - Embedded Trace Extension/Module Info - NULL ///< 48 - P-State Dependency (PSD) Info + NULL, ///< 43 - Pcc Subspace Type 3 Info + NULL, ///< 44 - Pcc Subspace Type 4 Info + NULL, ///< 45 - Pcc Subspace Type 5 Info + NULL, ///< 46 - Embedded Trace Extension/Module Info + NULL ///< 47 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 6896463b28..0d3e53312b 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -57,9 +57,9 @@ STATIC CONST CM_OBJ_PARSER CmArmBootArchInfoParser[] = { { "BootArchFlags", 2, "0x%x", NULL } }; -/** A parser for EArmObjPowerManagementProfileInfo. +/** A parser for EArchCommonObjPowerManagementProfileInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmPowerManagementProfileInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPowerManagementProfileInfoParser[] = { { "PowerManagementProfile", 1, "0x%x", NULL } }; @@ -671,6 +671,7 @@ STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = { */ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjReserved), + CM_PARSER_ADD_OBJECT (EArchCommonObjPowerManagementProfileInfo,CmArchCommonPowerManagementProfileInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -679,7 +680,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved), CM_PARSER_ADD_OBJECT (EArmObjBootArchInfo, CmArmBootArchInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPowerManagementProfileInfo, CmArmPowerManagementProfileInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicCInfo, CmArmGicCInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicDInfo, CmArmGicDInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicMsiFrameInfo, CmArmGicMsiFrameInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 8d30bf560b..3295bb2993 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -442,53 +442,52 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | ---: | :-------------------------- | :--- | | 0 | Reserved | | | 1 | Boot Architecture Info | | -| 2 | Power Management Profile Info | Move to Arch Common NS | -| 3 | GICC Info | | -| 4 | GICD Info | | -| 5 | GIC MSI Frame Info | | -| 6 | GIC Redistributor Info | | -| 7 | GIC ITS Info | | -| 8 | Serial Console Port Info | Move to Arch Common NS | -| 9 | Serial Debug Port Info | Move to Arch Common NS | -| 10 | Generic Timer Info | | -| 11 | Platform GT Block Info | | -| 12 | Generic Timer Block Frame Info | | -| 13 | Platform Generic Watchdog | | -| 14 | PCI Configuration Space Info | Move to Arch Common NS | -| 15 | Hypervisor Vendor Id | Move to Arch Common NS | -| 16 | Fixed feature flags for FADT | Move to Arch Common NS | -| 17 | ITS Group | | -| 18 | Named Component | | -| 19 | Root Complex | | -| 20 | SMMUv1 or SMMUv2 | | -| 21 | SMMUv3 | | -| 22 | PMCG | | -| 23 | GIC ITS Identifier Array | | -| 24 | ID Mapping Array | | -| 25 | SMMU Interrupt Array | | -| 26 | Processor Hierarchy Info | Move to Arch Common NS | -| 27 | Cache Info | Move to Arch Common NS | -| 28 | CM Object Reference | Move to Arch Common NS | -| 29 | Memory Affinity Info | Move to Arch Common NS | -| 30 | Device Handle Acpi | Move to Arch Common NS | -| 31 | Device Handle PCI | Move to Arch Common NS | -| 32 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 33 | Serial Port Info | Move to Arch Common NS | -| 34 | CMN 600 Info | | -| 35 | Low Power Idle State Info | Move to Arch Common NS | -| 36 | PCI Address Map Info | Move to Arch Common NS | -| 37 | PCI Interrupt Map Info | Move to Arch Common NS | -| 38 | Reserved Memory Range Node | | -| 39 | Memory Range Descriptor | | -| 40 | Continuous Performance Control Info | Move to Arch Common NS | -| 41 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 42 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 43 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 44 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 45 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 46 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 47 | Embedded Trace Extension/Module Info | | -| 48 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 2 | GICC Info | | +| 3 | GICD Info | | +| 4 | GIC MSI Frame Info | | +| 5 | GIC Redistributor Info | | +| 6 | GIC ITS Info | | +| 7 | Serial Console Port Info | Move to Arch Common NS | +| 8 | Serial Debug Port Info | Move to Arch Common NS | +| 9 | Generic Timer Info | | +| 10 | Platform GT Block Info | | +| 11 | Generic Timer Block Frame Info | | +| 12 | Platform Generic Watchdog | | +| 13 | PCI Configuration Space Info | Move to Arch Common NS | +| 14 | Hypervisor Vendor Id | Move to Arch Common NS | +| 15 | Fixed feature flags for FADT | Move to Arch Common NS | +| 16 | ITS Group | | +| 17 | Named Component | | +| 18 | Root Complex | | +| 19 | SMMUv1 or SMMUv2 | | +| 20 | SMMUv3 | | +| 21 | PMCG | | +| 22 | GIC ITS Identifier Array | | +| 23 | ID Mapping Array | | +| 24 | SMMU Interrupt Array | | +| 25 | Processor Hierarchy Info | Move to Arch Common NS | +| 26 | Cache Info | Move to Arch Common NS | +| 27 | CM Object Reference | Move to Arch Common NS | +| 28 | Memory Affinity Info | Move to Arch Common NS | +| 29 | Device Handle Acpi | Move to Arch Common NS | +| 30 | Device Handle PCI | Move to Arch Common NS | +| 31 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 32 | Serial Port Info | Move to Arch Common NS | +| 33 | CMN 600 Info | | +| 34 | Low Power Idle State Info | Move to Arch Common NS | +| 35 | PCI Address Map Info | Move to Arch Common NS | +| 36 | PCI Interrupt Map Info | Move to Arch Common NS | +| 37 | Reserved Memory Range Node | | +| 38 | Memory Range Descriptor | | +| 39 | Continuous Performance Control Info | Move to Arch Common NS | +| 40 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 41 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 42 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 43 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 44 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 45 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 46 | Embedded Trace Extension/Module Info | | +| 47 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | ID | Description | Comments | | ---: | :-------------------------- | :--- | | 0 | Reserved | | +| 1 | Power Management Profile Info | | | `*` | All other values are reserved. | | -- cgit From 1775c9d51c34de85f76874e34a04afa496dcafd6 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Tue, 16 Apr 2024 14:46:50 +0530 Subject: ArmVirtPkg: Kvmtool: Update Power Mgmt Profile info in Cfg Manager The PowerManagementProfileInfo Object has been moved from the Arm Namespace to the Arch Common namespace. Therefore, update the Kvmtool Guest firmware configuration manager to reflect this change. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Reviewed-by: Sunil V L --- ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c | 20 ++++++++++---------- ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c index 4a76583f96..7240544406 100644 --- a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c +++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c @@ -761,6 +761,16 @@ GetArchCommonNameSpaceObject ( // First check among the static objects. // switch (GET_CM_OBJECT_ID (CmObjectId)) { + case EArchCommonObjPowerManagementProfileInfo: + Status = HandleCmObject ( + CmObjectId, + &PlatformRepo->PmProfileInfo, + sizeof (PlatformRepo->PmProfileInfo), + 1, + CmObject + ); + break; + default: // // No match found among the static objects. @@ -828,16 +838,6 @@ GetArmNameSpaceObject ( // First check among the static objects. // switch (GET_CM_OBJECT_ID (CmObjectId)) { - case EArmObjPowerManagementProfileInfo: - Status = HandleCmObject ( - CmObjectId, - &PlatformRepo->PmProfileInfo, - sizeof (PlatformRepo->PmProfileInfo), - 1, - CmObject - ); - break; - case EArmObjItsGroup: Status = HandleCmObject ( CmObjectId, diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h index 3373948bc4..4fb12db73b 100644 --- a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h +++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h @@ -73,53 +73,53 @@ typedef struct PlatformRepositoryInfo { /// /// Configuration Manager Information. /// - CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo; + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo; /// /// List of ACPI tables /// - CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT]; + CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT]; /// /// Power management profile information /// - CM_ARM_POWER_MANAGEMENT_PROFILE_INFO PmProfileInfo; + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO PmProfileInfo; /// /// ITS Group node /// - CM_ARM_ITS_GROUP_NODE ItsGroupInfo; + CM_ARM_ITS_GROUP_NODE ItsGroupInfo; /// /// ITS Identifier array /// - CM_ARM_ITS_IDENTIFIER ItsIdentifierArray[1]; + CM_ARM_ITS_IDENTIFIER ItsIdentifierArray[1]; /// /// PCI Root complex node /// - CM_ARM_ROOT_COMPLEX_NODE RootComplexInfo; + CM_ARM_ROOT_COMPLEX_NODE RootComplexInfo; /// /// Array of DeviceID mapping /// - CM_ARM_ID_MAPPING DeviceIdMapping[1]; + CM_ARM_ID_MAPPING DeviceIdMapping[1]; /// /// Dynamic platform repository. /// CmObj created by parsing the Kvmtool device tree are stored here. /// - DYNAMIC_PLATFORM_REPOSITORY_INFO *DynamicPlatformRepo; + DYNAMIC_PLATFORM_REPOSITORY_INFO *DynamicPlatformRepo; /// /// Base address of the FDT. /// - VOID *FdtBase; + VOID *FdtBase; /// /// A handle to the FDT HwInfoParser. /// - HW_INFO_PARSER_HANDLE FdtParserHandle; + HW_INFO_PARSER_HANDLE FdtParserHandle; } EDKII_PLATFORM_REPOSITORY_INFO; #endif // CONFIGURATION_MANAGER_H_ -- cgit From e5d8bd476c1e8dfaa95f2b0c1cdda144e3b985d8 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 6 Mar 2024 10:08:09 +0000 Subject: DynamicTablesPkg: Move Serial Port Info Objects to Arch Common Move Serial port info objects like the generic serial port info, Serial console port info and Serial debug port info from Arm Namespace to the Arch Common namespace. i.e. EArmObjSerialPortInfo -> EArchCommonObjSerialPortInfo EArmObjConsolePortInfo -> EArchCommonObjConsolePortInfo EArmObjSerialDebugPortInfo -> EArchCommonObjSerialDebugPortInfo CM_ARM_SERIAL_PORT_INFO -> CM_ARCH_COMMON_SERIAL_PORT_INFO Correspondingly also update the following modules to reflect the changes introduced by the move: - DBG2 Generator - SPCR Generator - SSDT Serial Port Fixup Lib - SSDT Serial Port Generator - FdtHwInfoParserLib/ArmSerialPortParser - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 35 +++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 112 +++++++-------------- .../Include/Library/SsdtSerialPortFixupLib.h | 16 +-- .../Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c | 20 ++-- .../Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c | 18 ++-- .../SsdtSerialPortGenerator.c | 24 ++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 79 +++++++-------- .../SsdtSerialPortFixupLib.c | 46 ++++----- .../ConfigurationManagerObjectParser.c | 12 +-- .../Serial/ArmSerialPortParser.c | 79 ++++++++------- .../Serial/ArmSerialPortParser.h | 8 +- DynamicTablesPkg/Readme.md | 82 +++++++-------- 12 files changed, 264 insertions(+), 267 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index bbf3cd1e2e..4eabb4d38b 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -22,6 +22,9 @@ typedef enum ArchCommonObjectID { EArchCommonObjReserved, ///< 0 - Reserved EArchCommonObjPowerManagementProfileInfo, ///< 1 - Power Management Profile Info + EArchCommonObjSerialPortInfo, ///< 2 - Generic Serial Port Info + EArchCommonObjConsolePortInfo, ///< 3 - Serial Console Port Info + EArchCommonObjSerialDebugPortInfo, ///< 4 - Serial Debug Port Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -39,6 +42,38 @@ typedef struct CmArchCommonPowerManagementProfileInfo { UINT8 PowerManagementProfile; } CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO; +/** A structure that describes the + Serial Port information for the Platform. + + ID: EArchCommonObjConsolePortInfo or + EArchCommonObjSerialDebugPortInfo or + EArchCommonObjSerialPortInfo +*/ +typedef struct EArchCommonSerialPortInfo { + /// The physical base address for the serial port + UINT64 BaseAddress; + + /** The serial port interrupt. + 0 indicates that the serial port does not + have an interrupt wired. + */ + UINT32 Interrupt; + + /// The serial port baud rate + UINT64 BaudRate; + + /// The serial port clock + UINT32 Clock; + + /// Serial Port subtype + UINT16 PortSubtype; + + /// The Base address length + UINT64 BaseAddressLength; + + /// The access size + UINT8 AccessSize; +} CM_ARCH_COMMON_SERIAL_PORT_INFO; #pragma pack() diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 3d9a151846..4878eb60e3 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -35,47 +35,44 @@ typedef enum ArmObjectID { EArmObjGicMsiFrameInfo, ///< 4 - GIC MSI Frame Info EArmObjGicRedistributorInfo, ///< 5 - GIC Redistributor Info EArmObjGicItsInfo, ///< 6 - GIC ITS Info - EArmObjSerialConsolePortInfo, ///< 7 - Serial Console Port Info - EArmObjSerialDebugPortInfo, ///< 8 - Serial Debug Port Info - EArmObjGenericTimerInfo, ///< 9 - Generic Timer Info - EArmObjPlatformGTBlockInfo, ///< 10 - Platform GT Block Info - EArmObjGTBlockTimerFrameInfo, ///< 11 - Generic Timer Block Frame Info - EArmObjPlatformGenericWatchdogInfo, ///< 12 - Platform Generic Watchdog - EArmObjPciConfigSpaceInfo, ///< 13 - PCI Configuration Space Info - EArmObjHypervisorVendorIdentity, ///< 14 - Hypervisor Vendor Id - EArmObjFixedFeatureFlags, ///< 15 - Fixed feature flags for FADT - EArmObjItsGroup, ///< 16 - ITS Group - EArmObjNamedComponent, ///< 17 - Named Component - EArmObjRootComplex, ///< 18 - Root Complex - EArmObjSmmuV1SmmuV2, ///< 19 - SMMUv1 or SMMUv2 - EArmObjSmmuV3, ///< 20 - SMMUv3 - EArmObjPmcg, ///< 21 - PMCG - EArmObjGicItsIdentifierArray, ///< 22 - GIC ITS Identifier Array - EArmObjIdMappingArray, ///< 23 - ID Mapping Array - EArmObjSmmuInterruptArray, ///< 24 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 25 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 26 - Cache Info - EArmObjCmRef, ///< 27 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 28 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 29 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 30 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 31 - Generic Initiator Affinity - EArmObjSerialPortInfo, ///< 32 - Generic Serial Port Info - EArmObjCmn600Info, ///< 33 - CMN-600 Info - EArmObjLpiInfo, ///< 34 - Lpi Info - EArmObjPciAddressMapInfo, ///< 35 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 36 - Pci Interrupt Map Info - EArmObjRmr, ///< 37 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 38 - Memory Range Descriptor - EArmObjCpcInfo, ///< 39 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 40 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 41 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 42 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 43 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 44 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 45 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 46 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 47 - P-State Dependency (PSD) Info + EArmObjGenericTimerInfo, ///< 7 - Generic Timer Info + EArmObjPlatformGTBlockInfo, ///< 8 - Platform GT Block Info + EArmObjGTBlockTimerFrameInfo, ///< 9 - Generic Timer Block Frame Info + EArmObjPlatformGenericWatchdogInfo, ///< 10 - Platform Generic Watchdog + EArmObjPciConfigSpaceInfo, ///< 11 - PCI Configuration Space Info + EArmObjHypervisorVendorIdentity, ///< 12 - Hypervisor Vendor Id + EArmObjFixedFeatureFlags, ///< 13 - Fixed feature flags for FADT + EArmObjItsGroup, ///< 14 - ITS Group + EArmObjNamedComponent, ///< 15 - Named Component + EArmObjRootComplex, ///< 16 - Root Complex + EArmObjSmmuV1SmmuV2, ///< 17 - SMMUv1 or SMMUv2 + EArmObjSmmuV3, ///< 18 - SMMUv3 + EArmObjPmcg, ///< 19 - PMCG + EArmObjGicItsIdentifierArray, ///< 20 - GIC ITS Identifier Array + EArmObjIdMappingArray, ///< 21 - ID Mapping Array + EArmObjSmmuInterruptArray, ///< 22 - SMMU Interrupt Array + EArmObjProcHierarchyInfo, ///< 23 - Processor Hierarchy Info + EArmObjCacheInfo, ///< 24 - Cache Info + EArmObjCmRef, ///< 25 - CM Object Reference + EArmObjMemoryAffinityInfo, ///< 26 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 27 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 28 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 29 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 30 - CMN-600 Info + EArmObjLpiInfo, ///< 31 - Lpi Info + EArmObjPciAddressMapInfo, ///< 32 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 33 - Pci Interrupt Map Info + EArmObjRmr, ///< 34 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 35 - Memory Range Descriptor + EArmObjCpcInfo, ///< 36 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 37 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 38 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 39 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 40 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 41 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 42 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 43 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 44 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -297,39 +294,6 @@ typedef struct CmArmGicItsInfo { UINT32 ProximityDomain; } CM_ARM_GIC_ITS_INFO; -/** A structure that describes the - Serial Port information for the Platform. - - ID: EArmObjSerialConsolePortInfo or - EArmObjSerialDebugPortInfo or - EArmObjSerialPortInfo -*/ -typedef struct CmArmSerialPortInfo { - /// The physical base address for the serial port - UINT64 BaseAddress; - - /** The serial port interrupt. - 0 indicates that the serial port does not - have an interrupt wired. - */ - UINT32 Interrupt; - - /// The serial port baud rate - UINT64 BaudRate; - - /// The serial port clock - UINT32 Clock; - - /// Serial Port subtype - UINT16 PortSubtype; - - /// The Base address length - UINT64 BaseAddressLength; - - /// The access size - UINT8 AccessSize; -} CM_ARM_SERIAL_PORT_INFO; - /** A structure that describes the Generic Timer information for the Platform. diff --git a/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h b/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h index 4835f314c4..ac7b39f552 100644 --- a/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h +++ b/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h @@ -29,11 +29,11 @@ EFI_STATUS EFIAPI BuildSsdtSerialPortTable ( - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo, - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo, - IN CONST CHAR8 *Name, - IN CONST UINT64 Uid, - OUT EFI_ACPI_DESCRIPTION_HEADER **Table + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo, + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN CONST CHAR8 *Name, + IN CONST UINT64 Uid, + OUT EFI_ACPI_DESCRIPTION_HEADER **Table ); /** Free an SSDT table previously created by @@ -52,7 +52,7 @@ FreeSsdtSerialPortTable ( /** Validate the Serial Port Information. - @param [in] SerialPortInfoTable Table of CM_ARM_SERIAL_PORT_INFO. + @param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO. @param [in] SerialPortCount Count of SerialPort in the table. @retval EFI_SUCCESS Success. @@ -61,8 +61,8 @@ FreeSsdtSerialPortTable ( EFI_STATUS EFIAPI ValidateSerialPortInfo ( - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfoTable, - IN UINT32 SerialPortCount + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable, + IN UINT32 SerialPortCount ); #endif // SSDT_SERIAL_PORT_LIB_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c index f6dfb3d94c..fbf2ba3733 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c @@ -33,7 +33,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjSerialDebugPortInfo + - EArchCommonObjSerialDebugPortInfo */ #pragma pack(1) @@ -181,9 +181,9 @@ DBG2_TABLE AcpiDbg2 = { debug port information from the Configuration Manager */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjSerialDebugPortInfo, - CM_ARM_SERIAL_PORT_INFO + EObjNameSpaceArchCommon, + EArchCommonObjSerialDebugPortInfo, + CM_ARCH_COMMON_SERIAL_PORT_INFO ); /** Initialize the PL011/SBSA UART with the parameters obtained from @@ -198,7 +198,7 @@ GET_OBJECT_LIST ( STATIC EFI_STATUS SetupDebugUart ( - IN CONST CM_ARM_SERIAL_PORT_INFO *CONST SerialPortInfo + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *CONST SerialPortInfo ) { EFI_STATUS Status; @@ -329,10 +329,10 @@ BuildDbg2TableEx ( OUT UINTN *CONST TableCount ) { - EFI_STATUS Status; - CM_ARM_SERIAL_PORT_INFO *SerialPortInfo; - UINT32 SerialPortCount; - EFI_ACPI_DESCRIPTION_HEADER **TableList; + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 SerialPortCount; + EFI_ACPI_DESCRIPTION_HEADER **TableList; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -358,7 +358,7 @@ BuildDbg2TableEx ( *Table = NULL; - Status = GetEArmObjSerialDebugPortInfo ( + Status = GetEArchCommonObjSerialDebugPortInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &SerialPortInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c index 59cbacbfbb..6f027f3bf9 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c @@ -33,7 +33,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjSerialConsolePortInfo + - EArchCommonObjConsolePortInfo NOTE: This implementation ignores the possibility that the Serial settings may be modified from the UEFI Shell. A more complex handler would be needed @@ -98,9 +98,9 @@ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE AcpiSpcr = { Port Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjSerialConsolePortInfo, - CM_ARM_SERIAL_PORT_INFO + EObjNameSpaceArchCommon, + EArchCommonObjConsolePortInfo, + CM_ARCH_COMMON_SERIAL_PORT_INFO ) /** Free any resources allocated for constructing the tables. @@ -200,10 +200,10 @@ BuildSpcrTableEx ( OUT UINTN *CONST TableCount ) { - EFI_STATUS Status; - CM_ARM_SERIAL_PORT_INFO *SerialPortInfo; - UINT32 SerialPortCount; - EFI_ACPI_DESCRIPTION_HEADER **TableList; + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 SerialPortCount; + EFI_ACPI_DESCRIPTION_HEADER **TableList; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -229,7 +229,7 @@ BuildSpcrTableEx ( *Table = NULL; - Status = GetEArmObjSerialConsolePortInfo ( + Status = GetEArchCommonObjConsolePortInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &SerialPortInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c index b850320eed..671ba05740 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c @@ -29,16 +29,16 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjSerialPortInfo + - EArchCommonObjSerialPortInfo */ /** This macro expands to a function that retrieves the Serial-port information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjSerialPortInfo, - CM_ARM_SERIAL_PORT_INFO + EObjNameSpaceArchCommon, + EArchCommonObjSerialPortInfo, + CM_ARCH_COMMON_SERIAL_PORT_INFO ); /** Starting value for the UID to represent the serial ports. @@ -167,13 +167,13 @@ BuildSsdtSerialPortTableEx ( OUT UINTN *CONST TableCount ) { - EFI_STATUS Status; - CM_ARM_SERIAL_PORT_INFO *SerialPortInfo; - UINT32 SerialPortCount; - UINTN Index; - CHAR8 NewName[AML_NAME_SEG_SIZE + 1]; - UINT64 Uid; - EFI_ACPI_DESCRIPTION_HEADER **TableList; + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 SerialPortCount; + UINTN Index; + CHAR8 NewName[AML_NAME_SEG_SIZE + 1]; + UINT64 Uid; + EFI_ACPI_DESCRIPTION_HEADER **TableList; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -185,7 +185,7 @@ BuildSsdtSerialPortTableEx ( *Table = NULL; - Status = GetEArmObjSerialPortInfo ( + Status = GetEArchCommonObjSerialPortInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &SerialPortInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index ef2a8dcfdd..412bf41647 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -150,47 +150,44 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 4 - GIC MSI Frame Info NULL, ///< 5 - GIC Redistributor Info NULL, ///< 6 - GIC ITS Info - NULL, ///< 7 - Serial Console Port Info - NULL, ///< 8 - Serial Debug Port Info - NULL, ///< 9 - Generic Timer Info - NULL, ///< 10 - Platform GT Block Info - NULL, ///< 11 - Generic Timer Block Frame Info - NULL, ///< 12 - Platform Generic Watchdog - NULL, ///< 13 - PCI Configuration Space Info - NULL, ///< 14 - Hypervisor Vendor Id - NULL, ///< 15 - Fixed feature flags for FADT - TokenFixerItsGroup, ///< 16 - ITS Group - TokenFixerNamedComponentNode, ///< 17 - Named Component - TokenFixerRootComplexNode, ///< 18 - Root Complex - TokenFixerNotImplemented, ///< 19 - SMMUv1 or SMMUv2 - TokenFixerSmmuV3Node, ///< 20 - SMMUv3 - TokenFixerNotImplemented, ///< 21 - PMCG - NULL, ///< 22 - GIC ITS Identifier Array - NULL, ///< 23 - ID Mapping Array - NULL, ///< 24 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 25 - Processor Hierarchy Info - TokenFixerNotImplemented, ///< 26 - Cache Info - NULL, ///< 27 - CM Object Reference - NULL, ///< 28 - Memory Affinity Info - NULL, ///< 29 - Device Handle Acpi - NULL, ///< 30 - Device Handle Pci - NULL, ///< 31 - Generic Initiator Affinity - NULL, ///< 32 - Generic Serial Port Info - NULL, ///< 33 - CMN-600 Info - NULL, ///< 34 - Lpi Info - NULL, ///< 35 - Pci Address Map Info - NULL, ///< 36 - Pci Interrupt Map Info - NULL, ///< 37 - Reserved Memory Range Node - NULL, ///< 38 - Memory Range Descriptor - NULL, ///< 39 - Continuous Performance Control Info - NULL, ///< 40 - Pcc Subspace Type 0 Info - NULL, ///< 41 - Pcc Subspace Type 2 Info - NULL, ///< 42 - Pcc Subspace Type 2 Info - NULL, ///< 43 - Pcc Subspace Type 3 Info - NULL, ///< 44 - Pcc Subspace Type 4 Info - NULL, ///< 45 - Pcc Subspace Type 5 Info - NULL, ///< 46 - Embedded Trace Extension/Module Info - NULL ///< 47 - P-State Dependency (PSD) Info + NULL, ///< 7 - Generic Timer Info + NULL, ///< 8 - Platform GT Block Info + NULL, ///< 9 - Generic Timer Block Frame Info + NULL, ///< 10 - Platform Generic Watchdog + NULL, ///< 11 - PCI Configuration Space Info + NULL, ///< 12 - Hypervisor Vendor Id + NULL, ///< 13 - Fixed feature flags for FADT + TokenFixerItsGroup, ///< 14 - ITS Group + TokenFixerNamedComponentNode, ///< 15 - Named Component + TokenFixerRootComplexNode, ///< 16 - Root Complex + TokenFixerNotImplemented, ///< 17 - SMMUv1 or SMMUv2 + TokenFixerSmmuV3Node, ///< 18 - SMMUv3 + TokenFixerNotImplemented, ///< 19 - PMCG + NULL, ///< 20 - GIC ITS Identifier Array + NULL, ///< 21 - ID Mapping Array + NULL, ///< 22 - SMMU Interrupt Array + TokenFixerNotImplemented, ///< 23 - Processor Hierarchy Info + TokenFixerNotImplemented, ///< 24 - Cache Info + NULL, ///< 25 - Memory Affinity Info + NULL, ///< 26 - Memory Affinity Info + NULL, ///< 27 - Device Handle Acpi + NULL, ///< 28 - Device Handle Pci + NULL, ///< 29 - Generic Initiator Affinity + NULL, ///< 30 - CMN-600 Info + NULL, ///< 31 - Lpi Info + NULL, ///< 32 - Pci Address Map Info + NULL, ///< 33 - Pci Interrupt Map Info + NULL, ///< 34 - Reserved Memory Range Node + NULL, ///< 35 - Memory Range Descriptor + NULL, ///< 36 - Continuous Performance Control Info + NULL, ///< 37 - Pcc Subspace Type 0 Info + NULL, ///< 38 - Pcc Subspace Type 2 Info + NULL, ///< 39 - Pcc Subspace Type 2 Info + NULL, ///< 40 - Pcc Subspace Type 3 Info + NULL, ///< 41 - Pcc Subspace Type 4 Info + NULL, ///< 42 - Pcc Subspace Type 5 Info + NULL, ///< 43 - Embedded Trace Extension/Module Info + NULL ///< 44 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c index f2594de2e9..e8eef4048d 100644 --- a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c +++ b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c @@ -46,7 +46,7 @@ extern CHAR8 ssdtserialporttemplate_aml_code[]; /** Validate the Serial Port Information. - @param [in] SerialPortInfoTable Table of CM_ARM_SERIAL_PORT_INFO. + @param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO. @param [in] SerialPortCount Count of SerialPort in the table. @retval EFI_SUCCESS Success. @@ -55,12 +55,12 @@ extern CHAR8 ssdtserialporttemplate_aml_code[]; EFI_STATUS EFIAPI ValidateSerialPortInfo ( - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfoTable, - IN UINT32 SerialPortCount + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable, + IN UINT32 SerialPortCount ) { - UINT32 Index; - CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 Index; + CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; if ((SerialPortInfoTable == NULL) || (SerialPortCount == 0)) @@ -163,9 +163,9 @@ STATIC EFI_STATUS EFIAPI FixupIds ( - IN AML_ROOT_NODE_HANDLE RootNodeHandle, - IN CONST UINT64 Uid, - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo + IN AML_ROOT_NODE_HANDLE RootNodeHandle, + IN CONST UINT64 Uid, + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo ) { EFI_STATUS Status; @@ -290,8 +290,8 @@ STATIC EFI_STATUS EFIAPI FixupCrs ( - IN AML_ROOT_NODE_HANDLE RootNodeHandle, - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo + IN AML_ROOT_NODE_HANDLE RootNodeHandle, + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo ) { EFI_STATUS Status; @@ -366,9 +366,9 @@ STATIC EFI_STATUS EFIAPI FixupName ( - IN AML_ROOT_NODE_HANDLE RootNodeHandle, - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo, - IN CONST CHAR8 *Name + IN AML_ROOT_NODE_HANDLE RootNodeHandle, + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN CONST CHAR8 *Name ) { EFI_STATUS Status; @@ -410,11 +410,11 @@ STATIC EFI_STATUS EFIAPI FixupSerialPortInfo ( - IN AML_ROOT_NODE_HANDLE RootNodeHandle, - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo, - IN CONST CHAR8 *Name, - IN CONST UINT64 Uid, - OUT EFI_ACPI_DESCRIPTION_HEADER **Table + IN AML_ROOT_NODE_HANDLE RootNodeHandle, + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN CONST CHAR8 *Name, + IN CONST UINT64 Uid, + OUT EFI_ACPI_DESCRIPTION_HEADER **Table ) { EFI_STATUS Status; @@ -480,11 +480,11 @@ FreeSsdtSerialPortTable ( EFI_STATUS EFIAPI BuildSsdtSerialPortTable ( - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo, - IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo, - IN CONST CHAR8 *Name, - IN CONST UINT64 Uid, - OUT EFI_ACPI_DESCRIPTION_HEADER **Table + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo, + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN CONST CHAR8 *Name, + IN CONST UINT64 Uid, + OUT EFI_ACPI_DESCRIPTION_HEADER **Table ) { EFI_STATUS Status; diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 0d3e53312b..334d2a0265 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -122,10 +122,10 @@ STATIC CONST CM_OBJ_PARSER CmArmGicItsInfoParser[] = { { "ProximityDomain", 4, "0x%x", NULL } }; -/** A parser for EArmObjSerialConsolePortInfo, - EArmObjSerialDebugPortInfo and EArmObjSerialPortInfo. +/** A parser for EArchCommonObjConsolePortInfo, + EArchCommonObjSerialDebugPortInfo and EArchCommonObjSerialPortInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmSerialPortInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonSerialPortInfoParser[] = { { "BaseAddress", 8, "0x%llx", NULL }, { "Interrupt", 4, "0x%x", NULL }, { "BaudRate", 8, "0x%llx", NULL }, @@ -672,6 +672,9 @@ STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = { STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjReserved), CM_PARSER_ADD_OBJECT (EArchCommonObjPowerManagementProfileInfo,CmArchCommonPowerManagementProfileInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjSerialPortInfo, CmArchCommonSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjConsolePortInfo, CmArchCommonSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -685,8 +688,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGicMsiFrameInfo, CmArmGicMsiFrameInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicRedistributorInfo, CmArmGicRedistInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGicItsInfo, CmArmGicItsInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjSerialConsolePortInfo, CmArmSerialPortInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjSerialDebugPortInfo, CmArmSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGenericTimerInfo, CmArmGenericTimerInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPlatformGTBlockInfo, CmArmGTBlockInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), @@ -710,7 +711,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjDeviceHandleAcpi, CmArmDeviceHandleAcpiParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandlePci, CmArmDeviceHandlePciParser), CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjSerialPortInfo, CmArmSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPciAddressMapInfo, CmArmPciAddressMapInfoParser), diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c index 732b482eeb..f17ad2e842 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c @@ -71,7 +71,7 @@ CONST COMPATIBILITY_INFO SerialSbsaCompatibleInfo = { @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). @param [in] SerialPortNode Offset of a serial-port node. - @param [in] SerialPortInfo The CM_ARM_SERIAL_PORT_INFO to populate. + @param [in] SerialPortInfo The CM_ARCH_COMMON_SERIAL_PORT_INFO to populate. @retval EFI_SUCCESS The function completed successfully. @retval EFI_ABORTED An error occurred. @@ -82,9 +82,9 @@ STATIC EFI_STATUS EFIAPI SerialPortNodeParser ( - IN CONST VOID *Fdt, - IN INT32 SerialPortNode, - IN CM_ARM_SERIAL_PORT_INFO *SerialPortInfo + IN CONST VOID *Fdt, + IN INT32 SerialPortNode, + IN CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo ) { EFI_STATUS Status; @@ -313,7 +313,7 @@ GetSerialConsoleNode ( return EFI_SUCCESS; } -/** CM_ARM_SERIAL_PORT_INFO dispatcher function (for a generic serial-port). +/** CM_ARCH_COMMON_SERIAL_PORT_INFO dispatcher function (for a generic serial-port). @param [in] FdtParserHandle A handle to the parser instance. @param [in] GenericSerialInfo Pointer to a serial port info list. @@ -331,9 +331,9 @@ EFI_STATUS EFIAPI ArmSerialPortInfoDispatch ( IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN CM_ARM_SERIAL_PORT_INFO *GenericSerialInfo, + IN CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo, IN INT32 NodeCount, - IN EARM_OBJECT_ID SerialObjectId + IN EARCH_COMMON_OBJECT_ID SerialObjectId ) { EFI_STATUS Status; @@ -344,9 +344,9 @@ ArmSerialPortInfoDispatch ( return EFI_INVALID_PARAMETER; } - if ((SerialObjectId != EArmObjSerialPortInfo) && - (SerialObjectId != EArmObjSerialDebugPortInfo) && - (SerialObjectId != EArmObjSerialConsolePortInfo)) + if ((SerialObjectId != EArchCommonObjSerialPortInfo) && + (SerialObjectId != EArchCommonObjSerialDebugPortInfo) && + (SerialObjectId != EArchCommonObjConsolePortInfo)) { ASSERT (0); return EFI_INVALID_PARAMETER; @@ -354,10 +354,10 @@ ArmSerialPortInfoDispatch ( // Dispatch the Generic Serial ports Status = CreateCmObjDesc ( - CREATE_CM_ARM_OBJECT_ID (SerialObjectId), + CREATE_CM_ARCH_COMMON_OBJECT_ID (SerialObjectId), NodeCount, GenericSerialInfo, - sizeof (CM_ARM_SERIAL_PORT_INFO) * NodeCount, + sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) * NodeCount, &NewCmObjDesc ); if (EFI_ERROR (Status)) { @@ -372,19 +372,19 @@ ArmSerialPortInfoDispatch ( return Status; } -/** CM_ARM_SERIAL_PORT_INFO parser function (for debug/console serial-port). +/** CM_ARCH_COMMON_SERIAL_PORT_INFO parser function (for debug/console serial-port). This parser expects FdtBranch to be the debug serial-port node. At most one CmObj is created. The following structure is populated: - typedef struct CmArmSerialPortInfo { + typedef struct EArchCommonSerialPortInfo { UINT64 BaseAddress; // {Populated} UINT32 Interrupt; // {Populated} UINT64 BaudRate; // {default} UINT32 Clock; // {Populated} UINT16 PortSubtype; // {Populated} UINT64 BaseAddressLength // {Populated} - } CM_ARM_SERIAL_PORT_INFO; + } CM_ARCH_COMMON_SERIAL_PORT_INFO; A parser parses a Device Tree to populate a specific CmObj type. None, one or many CmObj can be created by the parser. @@ -396,7 +396,8 @@ ArmSerialPortInfoDispatch ( @param [in] FdtParserHandle A handle to the parser instance. @param [in] FdtBranch When searching for DT node name, restrict the search to this Device Tree branch. - @param [in] SerialObjectId ArmNamespace Object ID for the serial port. + @param [in] SerialObjectId ArchCommon Namespace Object ID for the serial + port. @retval EFI_SUCCESS The function completed successfully. @retval EFI_ABORTED An error occurred. @@ -410,14 +411,14 @@ EFIAPI ArmSerialPortInfoParser ( IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, IN INT32 FdtBranch, - IN EARM_OBJECT_ID SerialObjectId + IN EARCH_COMMON_OBJECT_ID SerialObjectId ) { - EFI_STATUS Status; - CM_ARM_SERIAL_PORT_INFO SerialInfo; + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO SerialInfo; - if ((SerialObjectId != EArmObjSerialDebugPortInfo) && - (SerialObjectId != EArmObjSerialConsolePortInfo)) + if ((SerialObjectId != EArchCommonObjSerialDebugPortInfo) && + (SerialObjectId != EArchCommonObjConsolePortInfo)) { ASSERT (0); return EFI_INVALID_PARAMETER; @@ -447,11 +448,11 @@ ArmSerialPortInfoParser ( /** SerialPort dispatcher. - This disptacher populates the CM_ARM_SERIAL_PORT_INFO structure for + This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for the following CM_OBJ_ID: - - EArmObjSerialConsolePortInfo - - EArmObjSerialDebugPortInfo - - EArmObjSerialPortInfo + - EArchCommonObjConsolePortInfo + - EArchCommonObjSerialDebugPortInfo + - EArchCommonObjSerialPortInfo A parser parses a Device Tree to populate a specific CmObj type. None, one or many CmObj can be created by the parser. @@ -477,16 +478,16 @@ SerialPortDispatcher ( IN INT32 FdtBranch ) { - EFI_STATUS Status; - INT32 SerialConsoleNode; - INT32 SerialDebugNode; - INT32 SerialNode; - UINT32 Index; - UINT32 SerialNodeCount; - UINT32 SerialNodesRemaining; - CM_ARM_SERIAL_PORT_INFO *GenericSerialInfo; - UINT32 GenericSerialIndex; - VOID *Fdt; + EFI_STATUS Status; + INT32 SerialConsoleNode; + INT32 SerialDebugNode; + INT32 SerialNode; + UINT32 Index; + UINT32 SerialNodeCount; + UINT32 SerialNodesRemaining; + CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo; + UINT32 GenericSerialIndex; + VOID *Fdt; if (FdtParserHandle == NULL) { ASSERT (0); @@ -531,7 +532,7 @@ SerialPortDispatcher ( Status = ArmSerialPortInfoParser ( FdtParserHandle, SerialConsoleNode, - EArmObjSerialConsolePortInfo + EArchCommonObjConsolePortInfo ); if (EFI_ERROR (Status)) { ASSERT (0); @@ -550,7 +551,7 @@ SerialPortDispatcher ( SerialNodesRemaining--; GenericSerialInfo = AllocateZeroPool ( SerialNodesRemaining * - sizeof (CM_ARM_SERIAL_PORT_INFO) + sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) ); if (GenericSerialInfo == NULL) { ASSERT (0); @@ -589,7 +590,7 @@ SerialPortDispatcher ( Status = ArmSerialPortInfoParser ( FdtParserHandle, SerialDebugNode, - EArmObjSerialDebugPortInfo + EArchCommonObjSerialDebugPortInfo ); if (EFI_ERROR (Status)) { ASSERT (0); @@ -620,7 +621,7 @@ SerialPortDispatcher ( FdtParserHandle, GenericSerialInfo, GenericSerialIndex, - EArmObjSerialPortInfo + EArchCommonObjSerialPortInfo ); } diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h index de08e57e6c..037c409d45 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h @@ -14,11 +14,11 @@ /** SerialPort dispatcher. - This disptacher populates the CM_ARM_SERIAL_PORT_INFO structure for + This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for the following CM_OBJ_ID: - - EArmObjSerialConsolePortInfo - - EArmObjSerialDebugPortInfo - - EArmObjSerialPortInfo + - EArchCommonObjConsolePortInfo + - EArchCommonObjSerialDebugPortInfo + - EArchCommonObjSerialPortInfo A parser parses a Device Tree to populate a specific CmObj type. None, one or many CmObj can be created by the parser. diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 3295bb2993..90f03f00e7 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -447,47 +447,44 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 4 | GIC MSI Frame Info | | | 5 | GIC Redistributor Info | | | 6 | GIC ITS Info | | -| 7 | Serial Console Port Info | Move to Arch Common NS | -| 8 | Serial Debug Port Info | Move to Arch Common NS | -| 9 | Generic Timer Info | | -| 10 | Platform GT Block Info | | -| 11 | Generic Timer Block Frame Info | | -| 12 | Platform Generic Watchdog | | -| 13 | PCI Configuration Space Info | Move to Arch Common NS | -| 14 | Hypervisor Vendor Id | Move to Arch Common NS | -| 15 | Fixed feature flags for FADT | Move to Arch Common NS | -| 16 | ITS Group | | -| 17 | Named Component | | -| 18 | Root Complex | | -| 19 | SMMUv1 or SMMUv2 | | -| 20 | SMMUv3 | | -| 21 | PMCG | | -| 22 | GIC ITS Identifier Array | | -| 23 | ID Mapping Array | | -| 24 | SMMU Interrupt Array | | -| 25 | Processor Hierarchy Info | Move to Arch Common NS | -| 26 | Cache Info | Move to Arch Common NS | -| 27 | CM Object Reference | Move to Arch Common NS | -| 28 | Memory Affinity Info | Move to Arch Common NS | -| 29 | Device Handle Acpi | Move to Arch Common NS | -| 30 | Device Handle PCI | Move to Arch Common NS | -| 31 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 32 | Serial Port Info | Move to Arch Common NS | -| 33 | CMN 600 Info | | -| 34 | Low Power Idle State Info | Move to Arch Common NS | -| 35 | PCI Address Map Info | Move to Arch Common NS | -| 36 | PCI Interrupt Map Info | Move to Arch Common NS | -| 37 | Reserved Memory Range Node | | -| 38 | Memory Range Descriptor | | -| 39 | Continuous Performance Control Info | Move to Arch Common NS | -| 40 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 41 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 42 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 43 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 44 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 45 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 46 | Embedded Trace Extension/Module Info | | -| 47 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 7 | Generic Timer Info | | +| 8 | Platform GT Block Info | | +| 9 | Generic Timer Block Frame Info | | +| 10 | Platform Generic Watchdog | | +| 11 | PCI Configuration Space Info | Move to Arch Common NS | +| 12 | Hypervisor Vendor Id | Move to Arch Common NS | +| 13 | Fixed feature flags for FADT | Move to Arch Common NS | +| 14 | ITS Group | | +| 15 | Named Component | | +| 16 | Root Complex | | +| 17 | SMMUv1 or SMMUv2 | | +| 18 | SMMUv3 | | +| 19 | PMCG | | +| 20 | GIC ITS Identifier Array | | +| 21 | ID Mapping Array | | +| 22 | SMMU Interrupt Array | | +| 23 | Processor Hierarchy Info | Move to Arch Common NS | +| 24 | Cache Info | Move to Arch Common NS | +| 25 | CM Object Reference | Move to Arch Common NS | +| 26 | Memory Affinity Info | Move to Arch Common NS | +| 27 | Device Handle Acpi | Move to Arch Common NS | +| 28 | Device Handle PCI | Move to Arch Common NS | +| 29 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 30 | CMN 600 Info | | +| 31 | Low Power Idle State Info | Move to Arch Common NS | +| 32 | PCI Address Map Info | Move to Arch Common NS | +| 33 | PCI Interrupt Map Info | Move to Arch Common NS | +| 34 | Reserved Memory Range Node | | +| 35 | Memory Range Descriptor | | +| 36 | Continuous Performance Control Info | Move to Arch Common NS | +| 37 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 38 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 39 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 40 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 41 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 42 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 43 | Embedded Trace Extension/Module Info | | +| 44 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +493,7 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | ---: | :-------------------------- | :--- | | 0 | Reserved | | | 1 | Power Management Profile Info | | +| 2 | Serial Port Info | | +| 3 | Serial Console Port Info | | +| 4 | Serial Debug Port Info | | | `*` | All other values are reserved. | | -- cgit From 87a53216e7ddce449c76f80d52db6a60fa3d1079 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 6 Mar 2024 10:49:04 +0000 Subject: DynamicTablesPkg: Move Hypervisor Vendor Id to Arch Common Move Hypervisor Vendor Id info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - FADT Generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 11 ++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 75 +++++++++------------- .../Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c | 16 ++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 61 +++++++++--------- .../ConfigurationManagerObjectParser.c | 6 +- DynamicTablesPkg/Readme.md | 66 +++++++++---------- 6 files changed, 117 insertions(+), 118 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 4eabb4d38b..401a24b6a5 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -25,6 +25,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjSerialPortInfo, ///< 2 - Generic Serial Port Info EArchCommonObjConsolePortInfo, ///< 3 - Serial Console Port Info EArchCommonObjSerialDebugPortInfo, ///< 4 - Serial Debug Port Info + EArchCommonObjHypervisorVendorIdentity, ///< 5 - Hypervisor Vendor Id EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -75,6 +76,16 @@ typedef struct EArchCommonSerialPortInfo { UINT8 AccessSize; } CM_ARCH_COMMON_SERIAL_PORT_INFO; +/** A structure that describes the + Hypervisor Vendor ID information for the Platform. + + ID: EArchCommonObjHypervisorVendorIdentity +*/ +typedef struct CmArchCommonHypervisorVendorIdentity { + /// The hypervisor Vendor ID + UINT64 HypervisorVendorId; +} CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 4878eb60e3..48e65a3cc0 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -40,39 +40,38 @@ typedef enum ArmObjectID { EArmObjGTBlockTimerFrameInfo, ///< 9 - Generic Timer Block Frame Info EArmObjPlatformGenericWatchdogInfo, ///< 10 - Platform Generic Watchdog EArmObjPciConfigSpaceInfo, ///< 11 - PCI Configuration Space Info - EArmObjHypervisorVendorIdentity, ///< 12 - Hypervisor Vendor Id - EArmObjFixedFeatureFlags, ///< 13 - Fixed feature flags for FADT - EArmObjItsGroup, ///< 14 - ITS Group - EArmObjNamedComponent, ///< 15 - Named Component - EArmObjRootComplex, ///< 16 - Root Complex - EArmObjSmmuV1SmmuV2, ///< 17 - SMMUv1 or SMMUv2 - EArmObjSmmuV3, ///< 18 - SMMUv3 - EArmObjPmcg, ///< 19 - PMCG - EArmObjGicItsIdentifierArray, ///< 20 - GIC ITS Identifier Array - EArmObjIdMappingArray, ///< 21 - ID Mapping Array - EArmObjSmmuInterruptArray, ///< 22 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 23 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 24 - Cache Info - EArmObjCmRef, ///< 25 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 26 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 27 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 28 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 29 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 30 - CMN-600 Info - EArmObjLpiInfo, ///< 31 - Lpi Info - EArmObjPciAddressMapInfo, ///< 32 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 33 - Pci Interrupt Map Info - EArmObjRmr, ///< 34 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 35 - Memory Range Descriptor - EArmObjCpcInfo, ///< 36 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 37 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 38 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 39 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 40 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 41 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 42 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 43 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 44 - P-State Dependency (PSD) Info + EArmObjFixedFeatureFlags, ///< 12 - Fixed feature flags for FADT + EArmObjItsGroup, ///< 13 - ITS Group + EArmObjNamedComponent, ///< 14 - Named Component + EArmObjRootComplex, ///< 15 - Root Complex + EArmObjSmmuV1SmmuV2, ///< 16 - SMMUv1 or SMMUv2 + EArmObjSmmuV3, ///< 17 - SMMUv3 + EArmObjPmcg, ///< 18 - PMCG + EArmObjGicItsIdentifierArray, ///< 19 - GIC ITS Identifier Array + EArmObjIdMappingArray, ///< 20 - ID Mapping Array + EArmObjSmmuInterruptArray, ///< 21 - SMMU Interrupt Array + EArmObjProcHierarchyInfo, ///< 22 - Processor Hierarchy Info + EArmObjCacheInfo, ///< 23 - Cache Info + EArmObjCmRef, ///< 24 - CM Object Reference + EArmObjMemoryAffinityInfo, ///< 25 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 26 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 27 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 28 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 29 - CMN-600 Info + EArmObjLpiInfo, ///< 30 - Lpi Info + EArmObjPciAddressMapInfo, ///< 31 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 32 - Pci Interrupt Map Info + EArmObjRmr, ///< 33 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 34 - Memory Range Descriptor + EArmObjCpcInfo, ///< 35 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 36 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 37 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 38 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 39 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 40 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 41 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 42 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 43 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -438,16 +437,6 @@ typedef struct CmArmPciConfigSpaceInfo { CM_OBJECT_TOKEN InterruptMapToken; } CM_ARM_PCI_CONFIG_SPACE_INFO; -/** A structure that describes the - Hypervisor Vendor ID information for the Platform. - - ID: EArmObjHypervisorVendorIdentity -*/ -typedef struct CmArmHypervisorVendorId { - /// The hypervisor Vendor ID - UINT64 HypervisorVendorId; -} CM_ARM_HYPERVISOR_VENDOR_ID; - /** A structure that describes the Fixed feature flags for the Platform. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c index ea8c821d11..868a974fed 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c @@ -27,7 +27,7 @@ Requirements: this Generator: - EArchCommonObjPowerManagementProfileInfo - EArmObjBootArchInfo - - EArmObjHypervisorVendorIdentity (OPTIONAL) + - EArchCommonObjHypervisorVendorIdentity (OPTIONAL) */ /** This macro defines the FADT flag options for ARM Platforms. @@ -220,9 +220,9 @@ GET_OBJECT_LIST ( Vendor ID from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjHypervisorVendorIdentity, - CM_ARM_HYPERVISOR_VENDOR_ID + EObjNameSpaceArchCommon, + EArchCommonObjHypervisorVendorIdentity, + CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID ); /** This macro expands to a function that retrieves the Fixed @@ -358,13 +358,13 @@ FadtAddHypervisorVendorId ( IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol ) { - EFI_STATUS Status; - CM_ARM_HYPERVISOR_VENDOR_ID *HypervisorVendorInfo; + EFI_STATUS Status; + CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID *HypervisorVendorInfo; ASSERT (CfgMgrProtocol != NULL); // Get the Hypervisor Vendor ID from the Platform Configuration Manager - Status = GetEArmObjHypervisorVendorIdentity ( + Status = GetEArchCommonObjHypervisorVendorIdentity ( CfgMgrProtocol, CM_NULL_TOKEN, &HypervisorVendorInfo, @@ -391,7 +391,7 @@ FadtAddHypervisorVendorId ( DEBUG (( DEBUG_INFO, - "FADT: EArmObjHypervisorVendorIdentity = 0x%lx\n", + "FADT: EArchCommonObjHypervisorVendorIdentity = 0x%lx\n", HypervisorVendorInfo->HypervisorVendorId )); diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 412bf41647..34ba9f2673 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -155,39 +155,38 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 9 - Generic Timer Block Frame Info NULL, ///< 10 - Platform Generic Watchdog NULL, ///< 11 - PCI Configuration Space Info - NULL, ///< 12 - Hypervisor Vendor Id - NULL, ///< 13 - Fixed feature flags for FADT - TokenFixerItsGroup, ///< 14 - ITS Group - TokenFixerNamedComponentNode, ///< 15 - Named Component - TokenFixerRootComplexNode, ///< 16 - Root Complex - TokenFixerNotImplemented, ///< 17 - SMMUv1 or SMMUv2 - TokenFixerSmmuV3Node, ///< 18 - SMMUv3 - TokenFixerNotImplemented, ///< 19 - PMCG - NULL, ///< 20 - GIC ITS Identifier Array - NULL, ///< 21 - ID Mapping Array - NULL, ///< 22 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 23 - Processor Hierarchy Info - TokenFixerNotImplemented, ///< 24 - Cache Info + NULL, ///< 12 - Fixed feature flags for FADT + TokenFixerItsGroup, ///< 13 - ITS Group + TokenFixerNamedComponentNode, ///< 14 - Named Component + TokenFixerRootComplexNode, ///< 15 - Root Complex + TokenFixerNotImplemented, ///< 16 - SMMUv1 or SMMUv2 + TokenFixerSmmuV3Node, ///< 17 - SMMUv3 + TokenFixerNotImplemented, ///< 18 - PMCG + NULL, ///< 19 - GIC ITS Identifier Array + NULL, ///< 20 - ID Mapping Array + NULL, ///< 21 - SMMU Interrupt Array + TokenFixerNotImplemented, ///< 22 - Processor Hierarchy Info + TokenFixerNotImplemented, ///< 23 - Cache Info + NULL, ///< 24 - Memory Affinity Info NULL, ///< 25 - Memory Affinity Info - NULL, ///< 26 - Memory Affinity Info - NULL, ///< 27 - Device Handle Acpi - NULL, ///< 28 - Device Handle Pci - NULL, ///< 29 - Generic Initiator Affinity - NULL, ///< 30 - CMN-600 Info - NULL, ///< 31 - Lpi Info - NULL, ///< 32 - Pci Address Map Info - NULL, ///< 33 - Pci Interrupt Map Info - NULL, ///< 34 - Reserved Memory Range Node - NULL, ///< 35 - Memory Range Descriptor - NULL, ///< 36 - Continuous Performance Control Info - NULL, ///< 37 - Pcc Subspace Type 0 Info + NULL, ///< 26 - Device Handle Acpi + NULL, ///< 27 - Device Handle Pci + NULL, ///< 28 - Generic Initiator Affinity + NULL, ///< 29 - CMN-600 Info + NULL, ///< 30 - Lpi Info + NULL, ///< 31 - Pci Address Map Info + NULL, ///< 32 - Pci Interrupt Map Info + NULL, ///< 33 - Reserved Memory Range Node + NULL, ///< 34 - Memory Range Descriptor + NULL, ///< 35 - Continuous Performance Control Info + NULL, ///< 36 - Pcc Subspace Type 0 Info + NULL, ///< 37 - Pcc Subspace Type 2 Info NULL, ///< 38 - Pcc Subspace Type 2 Info - NULL, ///< 39 - Pcc Subspace Type 2 Info - NULL, ///< 40 - Pcc Subspace Type 3 Info - NULL, ///< 41 - Pcc Subspace Type 4 Info - NULL, ///< 42 - Pcc Subspace Type 5 Info - NULL, ///< 43 - Embedded Trace Extension/Module Info - NULL ///< 44 - P-State Dependency (PSD) Info + NULL, ///< 39 - Pcc Subspace Type 3 Info + NULL, ///< 40 - Pcc Subspace Type 4 Info + NULL, ///< 41 - Pcc Subspace Type 5 Info + NULL, ///< 42 - Embedded Trace Extension/Module Info + NULL ///< 43 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 334d2a0265..1b3532f940 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -193,9 +193,9 @@ STATIC CONST CM_OBJ_PARSER CmArmPciConfigSpaceInfoParser[] = { { "InterruptMapToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, }; -/** A parser for EArmObjHypervisorVendorIdentity. +/** A parser for EArchCommonObjHypervisorVendorIdentity. */ -STATIC CONST CM_OBJ_PARSER CmArmHypervisorVendorIdParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonHypervisorVendorIdentityParser[] = { { "HypervisorVendorId", 8, "0x%llx", NULL } }; @@ -675,6 +675,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjSerialPortInfo, CmArchCommonSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjConsolePortInfo, CmArchCommonSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -693,7 +694,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo, CmArmGenericWatchdogInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPciConfigSpaceInfo, CmArmPciConfigSpaceInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjHypervisorVendorIdentity, CmArmHypervisorVendorIdParser), CM_PARSER_ADD_OBJECT (EArmObjFixedFeatureFlags, CmArmFixedFeatureFlagsParser), CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser), CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 90f03f00e7..79ccd86e85 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -452,39 +452,38 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 9 | Generic Timer Block Frame Info | | | 10 | Platform Generic Watchdog | | | 11 | PCI Configuration Space Info | Move to Arch Common NS | -| 12 | Hypervisor Vendor Id | Move to Arch Common NS | -| 13 | Fixed feature flags for FADT | Move to Arch Common NS | -| 14 | ITS Group | | -| 15 | Named Component | | -| 16 | Root Complex | | -| 17 | SMMUv1 or SMMUv2 | | -| 18 | SMMUv3 | | -| 19 | PMCG | | -| 20 | GIC ITS Identifier Array | | -| 21 | ID Mapping Array | | -| 22 | SMMU Interrupt Array | | -| 23 | Processor Hierarchy Info | Move to Arch Common NS | -| 24 | Cache Info | Move to Arch Common NS | -| 25 | CM Object Reference | Move to Arch Common NS | -| 26 | Memory Affinity Info | Move to Arch Common NS | -| 27 | Device Handle Acpi | Move to Arch Common NS | -| 28 | Device Handle PCI | Move to Arch Common NS | -| 29 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 30 | CMN 600 Info | | -| 31 | Low Power Idle State Info | Move to Arch Common NS | -| 32 | PCI Address Map Info | Move to Arch Common NS | -| 33 | PCI Interrupt Map Info | Move to Arch Common NS | -| 34 | Reserved Memory Range Node | | -| 35 | Memory Range Descriptor | | -| 36 | Continuous Performance Control Info | Move to Arch Common NS | -| 37 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 38 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 39 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 40 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 41 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 42 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 43 | Embedded Trace Extension/Module Info | | -| 44 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 12 | Fixed feature flags for FADT | Move to Arch Common NS | +| 13 | ITS Group | | +| 14 | Named Component | | +| 15 | Root Complex | | +| 16 | SMMUv1 or SMMUv2 | | +| 17 | SMMUv3 | | +| 18 | PMCG | | +| 19 | GIC ITS Identifier Array | | +| 20 | ID Mapping Array | | +| 21 | SMMU Interrupt Array | | +| 22 | Processor Hierarchy Info | Move to Arch Common NS | +| 23 | Cache Info | Move to Arch Common NS | +| 24 | CM Object Reference | Move to Arch Common NS | +| 25 | Memory Affinity Info | Move to Arch Common NS | +| 26 | Device Handle Acpi | Move to Arch Common NS | +| 27 | Device Handle PCI | Move to Arch Common NS | +| 28 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 29 | CMN 600 Info | | +| 30 | Low Power Idle State Info | Move to Arch Common NS | +| 31 | PCI Address Map Info | Move to Arch Common NS | +| 32 | PCI Interrupt Map Info | Move to Arch Common NS | +| 33 | Reserved Memory Range Node | | +| 34 | Memory Range Descriptor | | +| 35 | Continuous Performance Control Info | Move to Arch Common NS | +| 36 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 37 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 38 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 39 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 40 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 41 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 42 | Embedded Trace Extension/Module Info | | +| 43 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 2 | Serial Port Info | | | 3 | Serial Console Port Info | | | 4 | Serial Debug Port Info | | +| 5 | Hypervisor Vendor Id | | | `*` | All other values are reserved. | | -- cgit From 8e9ece12343d54c261888d5ee47d56921080705d Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 6 Mar 2024 11:00:12 +0000 Subject: DynamicTablesPkg: Move FADT Fixed Features Flags to Arch Common Move FADT Fixed Features Flags object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - FADT Generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 11 ++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 73 +++++++++------------- .../Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c | 14 ++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 59 +++++++++-------- .../ConfigurationManagerObjectParser.c | 6 +- DynamicTablesPkg/Readme.md | 64 +++++++++---------- 6 files changed, 113 insertions(+), 114 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 401a24b6a5..1030488f45 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -26,6 +26,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjConsolePortInfo, ///< 3 - Serial Console Port Info EArchCommonObjSerialDebugPortInfo, ///< 4 - Serial Debug Port Info EArchCommonObjHypervisorVendorIdentity, ///< 5 - Hypervisor Vendor Id + EArchCommonObjFixedFeatureFlags, ///< 6 - Fixed feature flags for FADT EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -86,6 +87,16 @@ typedef struct CmArchCommonHypervisorVendorIdentity { UINT64 HypervisorVendorId; } CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID; +/** A structure that describes the + Fixed feature flags for the Platform. + + ID: EArchCommonObjFixedFeatureFlags +*/ +typedef struct CmArchCommonFixedFeatureFlags { + /// The Fixed feature flags + UINT32 Flags; +} CM_ARCH_COMMON_FIXED_FEATURE_FLAGS; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 48e65a3cc0..66709c41fd 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -40,38 +40,37 @@ typedef enum ArmObjectID { EArmObjGTBlockTimerFrameInfo, ///< 9 - Generic Timer Block Frame Info EArmObjPlatformGenericWatchdogInfo, ///< 10 - Platform Generic Watchdog EArmObjPciConfigSpaceInfo, ///< 11 - PCI Configuration Space Info - EArmObjFixedFeatureFlags, ///< 12 - Fixed feature flags for FADT - EArmObjItsGroup, ///< 13 - ITS Group - EArmObjNamedComponent, ///< 14 - Named Component - EArmObjRootComplex, ///< 15 - Root Complex - EArmObjSmmuV1SmmuV2, ///< 16 - SMMUv1 or SMMUv2 - EArmObjSmmuV3, ///< 17 - SMMUv3 - EArmObjPmcg, ///< 18 - PMCG - EArmObjGicItsIdentifierArray, ///< 19 - GIC ITS Identifier Array - EArmObjIdMappingArray, ///< 20 - ID Mapping Array - EArmObjSmmuInterruptArray, ///< 21 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 22 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 23 - Cache Info - EArmObjCmRef, ///< 24 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 25 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 26 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 27 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 28 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 29 - CMN-600 Info - EArmObjLpiInfo, ///< 30 - Lpi Info - EArmObjPciAddressMapInfo, ///< 31 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 32 - Pci Interrupt Map Info - EArmObjRmr, ///< 33 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 34 - Memory Range Descriptor - EArmObjCpcInfo, ///< 35 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 36 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 37 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 38 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 39 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 40 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 41 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 42 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 43 - P-State Dependency (PSD) Info + EArmObjItsGroup, ///< 12 - ITS Group + EArmObjNamedComponent, ///< 13 - Named Component + EArmObjRootComplex, ///< 14 - Root Complex + EArmObjSmmuV1SmmuV2, ///< 15 - SMMUv1 or SMMUv2 + EArmObjSmmuV3, ///< 16 - SMMUv3 + EArmObjPmcg, ///< 17 - PMCG + EArmObjGicItsIdentifierArray, ///< 18 - GIC ITS Identifier Array + EArmObjIdMappingArray, ///< 19 - ID Mapping Array + EArmObjSmmuInterruptArray, ///< 20 - SMMU Interrupt Array + EArmObjProcHierarchyInfo, ///< 21 - Processor Hierarchy Info + EArmObjCacheInfo, ///< 22 - Cache Info + EArmObjCmRef, ///< 23 - CM Object Reference + EArmObjMemoryAffinityInfo, ///< 24 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 25 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 26 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 27 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 28 - CMN-600 Info + EArmObjLpiInfo, ///< 29 - Lpi Info + EArmObjPciAddressMapInfo, ///< 30 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 31 - Pci Interrupt Map Info + EArmObjRmr, ///< 32 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 33 - Memory Range Descriptor + EArmObjCpcInfo, ///< 34 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 35 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 36 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 37 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 38 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 39 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 40 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 41 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 42 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -437,16 +436,6 @@ typedef struct CmArmPciConfigSpaceInfo { CM_OBJECT_TOKEN InterruptMapToken; } CM_ARM_PCI_CONFIG_SPACE_INFO; -/** A structure that describes the - Fixed feature flags for the Platform. - - ID: EArmObjFixedFeatureFlags -*/ -typedef struct CmArmFixedFeatureFlags { - /// The Fixed feature flags - UINT32 Flags; -} CM_ARM_FIXED_FEATURE_FLAGS; - /** A structure that describes the ITS Group node for the Platform. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c index 868a974fed..470f1acfd1 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c @@ -229,9 +229,9 @@ GET_OBJECT_LIST ( feature flags for the platform from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjFixedFeatureFlags, - CM_ARM_FIXED_FEATURE_FLAGS + EObjNameSpaceArchCommon, + EArchCommonObjFixedFeatureFlags, + CM_ARCH_COMMON_FIXED_FEATURE_FLAGS ); /** Update the Power Management Profile information in the FADT Table. @@ -420,13 +420,13 @@ FadtAddFixedFeatureFlags ( IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol ) { - EFI_STATUS Status; - CM_ARM_FIXED_FEATURE_FLAGS *FixedFeatureFlags; + EFI_STATUS Status; + CM_ARCH_COMMON_FIXED_FEATURE_FLAGS *FixedFeatureFlags; ASSERT (CfgMgrProtocol != NULL); // Get the Fixed feature flags from the Platform Configuration Manager - Status = GetEArmObjFixedFeatureFlags ( + Status = GetEArchCommonObjFixedFeatureFlags ( CfgMgrProtocol, CM_NULL_TOKEN, &FixedFeatureFlags, @@ -453,7 +453,7 @@ FadtAddFixedFeatureFlags ( DEBUG (( DEBUG_INFO, - "FADT: EArmObjFixedFeatureFlags = 0x%x\n", + "FADT: EArchCommonObjFixedFeatureFlags = 0x%x\n", FixedFeatureFlags->Flags )); diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 34ba9f2673..aef818e77f 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -155,38 +155,37 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 9 - Generic Timer Block Frame Info NULL, ///< 10 - Platform Generic Watchdog NULL, ///< 11 - PCI Configuration Space Info - NULL, ///< 12 - Fixed feature flags for FADT - TokenFixerItsGroup, ///< 13 - ITS Group - TokenFixerNamedComponentNode, ///< 14 - Named Component - TokenFixerRootComplexNode, ///< 15 - Root Complex - TokenFixerNotImplemented, ///< 16 - SMMUv1 or SMMUv2 - TokenFixerSmmuV3Node, ///< 17 - SMMUv3 - TokenFixerNotImplemented, ///< 18 - PMCG - NULL, ///< 19 - GIC ITS Identifier Array - NULL, ///< 20 - ID Mapping Array - NULL, ///< 21 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 22 - Processor Hierarchy Info - TokenFixerNotImplemented, ///< 23 - Cache Info + TokenFixerItsGroup, ///< 12 - ITS Group + TokenFixerNamedComponentNode, ///< 13 - Named Component + TokenFixerRootComplexNode, ///< 14 - Root Complex + TokenFixerNotImplemented, ///< 15 - SMMUv1 or SMMUv2 + TokenFixerSmmuV3Node, ///< 16 - SMMUv3 + TokenFixerNotImplemented, ///< 17 - PMCG + NULL, ///< 18 - GIC ITS Identifier Array + NULL, ///< 19 - ID Mapping Array + NULL, ///< 20 - SMMU Interrupt Array + TokenFixerNotImplemented, ///< 21 - Processor Hierarchy Info + TokenFixerNotImplemented, ///< 22 - Cache Info + NULL, ///< 23 - CM Object Reference NULL, ///< 24 - Memory Affinity Info - NULL, ///< 25 - Memory Affinity Info - NULL, ///< 26 - Device Handle Acpi - NULL, ///< 27 - Device Handle Pci - NULL, ///< 28 - Generic Initiator Affinity - NULL, ///< 29 - CMN-600 Info - NULL, ///< 30 - Lpi Info - NULL, ///< 31 - Pci Address Map Info - NULL, ///< 32 - Pci Interrupt Map Info - NULL, ///< 33 - Reserved Memory Range Node - NULL, ///< 34 - Memory Range Descriptor - NULL, ///< 35 - Continuous Performance Control Info - NULL, ///< 36 - Pcc Subspace Type 0 Info + NULL, ///< 25 - Device Handle Acpi + NULL, ///< 26 - Device Handle Pci + NULL, ///< 27 - Generic Initiator Affinity + NULL, ///< 28 - CMN-600 Info + NULL, ///< 29 - Lpi Info + NULL, ///< 30 - Pci Address Map Info + NULL, ///< 31 - Pci Interrupt Map Info + NULL, ///< 32 - Reserved Memory Range Node + NULL, ///< 33 - Memory Range Descriptor + NULL, ///< 34 - Continuous Performance Control Info + NULL, ///< 35 - Pcc Subspace Type 0 Info + NULL, ///< 36 - Pcc Subspace Type 2 Info NULL, ///< 37 - Pcc Subspace Type 2 Info - NULL, ///< 38 - Pcc Subspace Type 2 Info - NULL, ///< 39 - Pcc Subspace Type 3 Info - NULL, ///< 40 - Pcc Subspace Type 4 Info - NULL, ///< 41 - Pcc Subspace Type 5 Info - NULL, ///< 42 - Embedded Trace Extension/Module Info - NULL ///< 43 - P-State Dependency (PSD) Info + NULL, ///< 38 - Pcc Subspace Type 3 Info + NULL, ///< 39 - Pcc Subspace Type 4 Info + NULL, ///< 40 - Pcc Subspace Type 5 Info + NULL, ///< 41 - Embedded Trace Extension/Module Info + NULL ///< 42 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 1b3532f940..3205cf87c8 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -199,9 +199,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonHypervisorVendorIdentityParser[] = { { "HypervisorVendorId", 8, "0x%llx", NULL } }; -/** A parser for EArmObjFixedFeatureFlags. +/** A parser for EArchCommonObjFixedFeatureFlags. */ -STATIC CONST CM_OBJ_PARSER CmArmFixedFeatureFlagsParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonFixedFeatureFlagsParser[] = { { "Flags", 4, "0x%x", NULL } }; @@ -676,6 +676,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjConsolePortInfo, CmArchCommonSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -694,7 +695,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo, CmArmGenericWatchdogInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPciConfigSpaceInfo, CmArmPciConfigSpaceInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjFixedFeatureFlags, CmArmFixedFeatureFlagsParser), CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser), CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser), CM_PARSER_ADD_OBJECT (EArmObjRootComplex, CmArmRootComplexNodeParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 79ccd86e85..5b9dda3e63 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -452,38 +452,37 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 9 | Generic Timer Block Frame Info | | | 10 | Platform Generic Watchdog | | | 11 | PCI Configuration Space Info | Move to Arch Common NS | -| 12 | Fixed feature flags for FADT | Move to Arch Common NS | -| 13 | ITS Group | | -| 14 | Named Component | | -| 15 | Root Complex | | -| 16 | SMMUv1 or SMMUv2 | | -| 17 | SMMUv3 | | -| 18 | PMCG | | -| 19 | GIC ITS Identifier Array | | -| 20 | ID Mapping Array | | -| 21 | SMMU Interrupt Array | | -| 22 | Processor Hierarchy Info | Move to Arch Common NS | -| 23 | Cache Info | Move to Arch Common NS | -| 24 | CM Object Reference | Move to Arch Common NS | -| 25 | Memory Affinity Info | Move to Arch Common NS | -| 26 | Device Handle Acpi | Move to Arch Common NS | -| 27 | Device Handle PCI | Move to Arch Common NS | -| 28 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 29 | CMN 600 Info | | -| 30 | Low Power Idle State Info | Move to Arch Common NS | -| 31 | PCI Address Map Info | Move to Arch Common NS | -| 32 | PCI Interrupt Map Info | Move to Arch Common NS | -| 33 | Reserved Memory Range Node | | -| 34 | Memory Range Descriptor | | -| 35 | Continuous Performance Control Info | Move to Arch Common NS | -| 36 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 37 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 38 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 39 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 40 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 41 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 42 | Embedded Trace Extension/Module Info | | -| 43 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 12 | ITS Group | | +| 13 | Named Component | | +| 14 | Root Complex | | +| 15 | SMMUv1 or SMMUv2 | | +| 16 | SMMUv3 | | +| 17 | PMCG | | +| 18 | GIC ITS Identifier Array | | +| 19 | ID Mapping Array | | +| 20 | SMMU Interrupt Array | | +| 21 | Processor Hierarchy Info | Move to Arch Common NS | +| 22 | Cache Info | Move to Arch Common NS | +| 23 | CM Object Reference | Move to Arch Common NS | +| 24 | Memory Affinity Info | Move to Arch Common NS | +| 25 | Device Handle Acpi | Move to Arch Common NS | +| 26 | Device Handle PCI | Move to Arch Common NS | +| 27 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 28 | CMN 600 Info | | +| 29 | Low Power Idle State Info | Move to Arch Common NS | +| 30 | PCI Address Map Info | Move to Arch Common NS | +| 31 | PCI Interrupt Map Info | Move to Arch Common NS | +| 32 | Reserved Memory Range Node | | +| 33 | Memory Range Descriptor | | +| 34 | Continuous Performance Control Info | Move to Arch Common NS | +| 35 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 36 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 37 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 38 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 39 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 40 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 41 | Embedded Trace Extension/Module Info | | +| 42 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 3 | Serial Console Port Info | | | 4 | Serial Debug Port Info | | | 5 | Hypervisor Vendor Id | | +| 6 | Fixed feature flags for FADT | | | `*` | All other values are reserved. | | -- cgit From 4f29b082e802e05f4dbe50734c7f2a3780d58707 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Wed, 6 Mar 2024 16:28:01 +0000 Subject: DynamicTablesPkg: Move Cm Reference object to Arch Common Move Cm Reference object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PPTT generator - SSDT CPU topology generator - SSDT PCIe generator - ConfigurationManagerObjectParser - Dynamic Plat Repo, the Token Mapper and the TokenFixer map. - FdtHwInfoParser library Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 17 ++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 61 ++++++++-------------- .../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 20 +++---- .../SsdtCpuTopologyGenerator.c | 14 ++--- .../SsdtCpuTopologyGenerator.h | 10 ++-- .../Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c | 20 +++---- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 37 +++++++------ .../Common/DynamicPlatRepoLib/DynamicPlatRepo.c | 28 +++++----- .../Common/DynamicPlatRepoLib/TokenMapper.c | 9 ++-- .../ConfigurationManagerObjectParser.c | 6 +-- .../FdtHwInfoParserLib/CmObjectDescUtility.c | 10 ++-- .../FdtHwInfoParserLib/CmObjectDescUtility.h | 6 +-- DynamicTablesPkg/Readme.md | 40 +++++++------- 13 files changed, 139 insertions(+), 139 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 1030488f45..632816da09 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -27,6 +27,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjSerialDebugPortInfo, ///< 4 - Serial Debug Port Info EArchCommonObjHypervisorVendorIdentity, ///< 5 - Hypervisor Vendor Id EArchCommonObjFixedFeatureFlags, ///< 6 - Fixed feature flags for FADT + EArchCommonObjCmRef, ///< 7 - CM Object Reference EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -97,6 +98,22 @@ typedef struct CmArchCommonFixedFeatureFlags { UINT32 Flags; } CM_ARCH_COMMON_FIXED_FEATURE_FLAGS; +/** A structure that describes a reference to another Configuration Manager + object. + + This is useful for creating an array of reference tokens. The framework + can then query the configuration manager for these arrays using the + object ID EArchCommonObjCmRef. + + This can be used is to represent one-to-many relationships between objects. + + ID: EArchCommonObjCmRef +*/ +typedef struct CmArchCommonObjRef { + /// Token of the CM object being referenced + CM_OBJECT_TOKEN ReferenceToken; +} CM_ARCH_COMMON_OBJ_REF; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 66709c41fd..cfcb2c7d27 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,26 +51,25 @@ typedef enum ArmObjectID { EArmObjSmmuInterruptArray, ///< 20 - SMMU Interrupt Array EArmObjProcHierarchyInfo, ///< 21 - Processor Hierarchy Info EArmObjCacheInfo, ///< 22 - Cache Info - EArmObjCmRef, ///< 23 - CM Object Reference - EArmObjMemoryAffinityInfo, ///< 24 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 25 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 26 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 27 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 28 - CMN-600 Info - EArmObjLpiInfo, ///< 29 - Lpi Info - EArmObjPciAddressMapInfo, ///< 30 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 31 - Pci Interrupt Map Info - EArmObjRmr, ///< 32 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 33 - Memory Range Descriptor - EArmObjCpcInfo, ///< 34 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 35 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 36 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 37 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 38 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 39 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 40 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 41 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 42 - P-State Dependency (PSD) Info + EArmObjMemoryAffinityInfo, ///< 23 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 24 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 25 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 26 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 27 - CMN-600 Info + EArmObjLpiInfo, ///< 28 - Lpi Info + EArmObjPciAddressMapInfo, ///< 29 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 30 - Pci Interrupt Map Info + EArmObjRmr, ///< 31 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 32 - Memory Range Descriptor + EArmObjCpcInfo, ///< 33 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 34 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 35 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 36 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 37 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 38 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 39 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 40 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 41 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -428,11 +427,11 @@ typedef struct CmArmPciConfigSpaceInfo { UINT8 EndBusNumber; /// Optional field: Reference Token for address mapping. - /// Token identifying a CM_ARM_OBJ_REF structure. + /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure. CM_OBJECT_TOKEN AddressMapToken; /// Optional field: Reference Token for interrupt mapping. - /// Token identifying a CM_ARM_OBJ_REF structure. + /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure. CM_OBJECT_TOKEN InterruptMapToken; } CM_ARM_PCI_CONFIG_SPACE_INFO; @@ -721,7 +720,7 @@ typedef struct CmArmProcHierarchyInfo { /// this field to CM_NULL_TOKEN. CM_OBJECT_TOKEN PrivateResourcesArrayToken; /// Optional field: Reference Token for the Lpi state of this processor. - /// Token identifying a CM_ARM_OBJ_REF structure, itself referencing + /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure, itself referencing /// CM_ARM_LPI_INFO objects. CM_OBJECT_TOKEN LpiToken; /// Set to TRUE if UID should override index for name and _UID @@ -767,22 +766,6 @@ typedef struct CmArmCacheInfo { UINT32 CacheId; } CM_ARM_CACHE_INFO; -/** A structure that describes a reference to another Configuration Manager - object. - - This is useful for creating an array of reference tokens. The framework - can then query the configuration manager for these arrays using the - object ID EArmObjCmRef. - - This can be used is to represent one-to-many relationships between objects. - - ID: EArmObjCmRef -*/ -typedef struct CmArmObjRef { - /// Token of the CM object being referenced - CM_OBJECT_TOKEN ReferenceToken; -} CM_ARM_OBJ_REF; - /** A structure that describes the Memory Affinity Structure (Type 1) in SRAT ID: EArmObjMemoryAffinityInfo diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c index 78fa63ff47..c237f7ff93 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c @@ -34,7 +34,7 @@ The following Configuration Manager Object(s) are used by this Generator: - EArmObjProcHierarchyInfo (REQUIRED) - EArmObjCacheInfo - - EArmObjCmRef + - EArchCommonObjCmRef - EArmObjGicCInfo (REQUIRED) */ @@ -63,9 +63,9 @@ GET_OBJECT_LIST ( reference information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjCmRef, - CM_ARM_OBJ_REF + EObjNameSpaceArchCommon, + EArchCommonObjCmRef, + CM_ARCH_COMMON_OBJ_REF ); /** @@ -264,7 +264,7 @@ DetectCyclesInTopology ( Protocol Interface. @param [in] PrivResArray Pointer to the array of private resources. @param [in] PrivResCount Number of private resources. - @param [in] PrivResArrayToken Reference Token for the CM_ARM_OBJ_REF + @param [in] PrivResArrayToken Reference Token for the CM_ARCH_COMMON_OBJ_REF array describing node's private resources. @retval EFI_SUCCESS Array updated successfully. @@ -281,10 +281,10 @@ AddPrivateResources ( IN CONST CM_OBJECT_TOKEN PrivResArrayToken ) { - EFI_STATUS Status; - CM_ARM_OBJ_REF *CmObjRefs; - UINT32 CmObjRefCount; - PPTT_NODE_INDEXER *PpttNodeFound; + EFI_STATUS Status; + CM_ARCH_COMMON_OBJ_REF *CmObjRefs; + UINT32 CmObjRefCount; + PPTT_NODE_INDEXER *PpttNodeFound; ASSERT ( (Generator != NULL) && @@ -308,7 +308,7 @@ AddPrivateResources ( CmObjRefCount = 0; // Get the CM Object References - Status = GetEArmObjCmRef ( + Status = GetEArchCommonObjCmRef ( CfgMgrProtocol, PrivResArrayToken, &CmObjRefs, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index e3cbe18a49..5240ff52d8 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -39,7 +39,7 @@ Requirements: this Generator: - EArmObjGicCInfo - EArmObjProcHierarchyInfo (OPTIONAL) along with - - EArmObjCmRef (OPTIONAL) + - EArchCommonObjCmRef (OPTIONAL) - EArmObjLpiInfo (OPTIONAL) - GetEArmObjEtInfo (OPTIONAL) - EArmObjPsdInfo (OPTIONAL) @@ -69,9 +69,9 @@ GET_OBJECT_LIST ( reference information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjCmRef, - CM_ARM_OBJ_REF + EObjNameSpaceArchCommon, + EArchCommonObjCmRef, + CM_ARCH_COMMON_OBJ_REF ); /** @@ -120,7 +120,7 @@ GET_OBJECT_LIST ( structure of the platform. The TokenTable allows to have a mapping: Index <-> CM_OBJECT_TOKEN (to CM_ARM_LPI_INFO structures). - There will always be less sets of Lpi states (CM_ARM_OBJ_REF) + There will always be less sets of Lpi states (CM_ARCH_COMMON_OBJ_REF) than the number of cpus/clusters (CM_ARM_PROC_HIERARCHY_INFO). @param [in] Generator The SSDT Cpu Topology generator. @@ -697,7 +697,7 @@ GenerateLpiStates ( UINT32 LastIndex; AML_OBJECT_NODE_HANDLE LpiNode; - CM_ARM_OBJ_REF *LpiRefInfo; + CM_ARCH_COMMON_OBJ_REF *LpiRefInfo; UINT32 LpiRefInfoCount; UINT32 LpiRefIndex; CM_ARM_LPI_INFO *LpiInfo; @@ -727,7 +727,7 @@ GenerateLpiStates ( } // Fetch the LPI objects referenced by the token. - Status = GetEArmObjCmRef ( + Status = GetEArchCommonObjCmRef ( CfgMgrProtocol, Generator->TokenTable.Table[Index], &LpiRefInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h index 0c7a0b0601..d6561e33da 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h @@ -69,8 +69,8 @@ /** A structure used to handle the Lpi structures referencing. - A CM_ARM_PROC_HIERARCHY_INFO structure references a CM_ARM_OBJ_REF. - This CM_ARM_OBJ_REF references CM_ARM_LPI_INFO structures. + A CM_ARM_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF. + This CM_ARCH_COMMON_OBJ_REF references CM_ARM_LPI_INFO structures. Example: (Cpu0) (Cpu1) @@ -80,7 +80,7 @@ | v (List of references to Lpi states) - CM_ARM_OBJ_REF + CM_ARCH_COMMON_OBJ_REF | +---------------------------------------- | | @@ -89,9 +89,9 @@ CM_ARM_LPI_INFO[0] CM_ARM_LPI_INFO[1] Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARM_PROC_HIERARCHY_INFO - structures reference the same CM_ARM_OBJ_REF. An entry is created in the + structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the TokenTable such as: - 0 <-> CM_ARM_OBJ_REF + 0 <-> CM_ARCH_COMMON_OBJ_REF This will lead to the creation of this pseudo-ASL code where Cpu0 and Cpu1 return the same object at \_SB.L000: diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c index 72873709aa..dc1371c3bc 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c @@ -42,7 +42,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjCmRef + - EArchCommonObjCmRef - EArmObjPciConfigSpaceInfo - EArmObjPciAddressMapInfo - EArmObjPciInterruptMapInfo @@ -52,9 +52,9 @@ Requirements: reference information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjCmRef, - CM_ARM_OBJ_REF + EObjNameSpaceArchCommon, + EArchCommonObjCmRef, + CM_ARCH_COMMON_OBJ_REF ); /** This macro expands to a function that retrieves the Pci @@ -313,7 +313,7 @@ GeneratePrt ( EFI_STATUS Status; INT32 Index; AML_OBJECT_NODE_HANDLE PrtNode; - CM_ARM_OBJ_REF *RefInfo; + CM_ARCH_COMMON_OBJ_REF *RefInfo; UINT32 RefCount; CM_ARM_PCI_INTERRUPT_MAP_INFO *IrqMapInfo; @@ -324,9 +324,9 @@ GeneratePrt ( PrtNode = NULL; - // Get the array of CM_ARM_OBJ_REF referencing the + // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the // CM_ARM_PCI_INTERRUPT_MAP_INFO objects. - Status = GetEArmObjCmRef ( + Status = GetEArchCommonObjCmRef ( CfgMgrProtocol, PciInfo->InterruptMapToken, &RefInfo, @@ -458,7 +458,7 @@ GeneratePciCrs ( EFI_STATUS Status; BOOLEAN Translation; UINT32 Index; - CM_ARM_OBJ_REF *RefInfo; + CM_ARCH_COMMON_OBJ_REF *RefInfo; UINT32 RefCount; CM_ARM_PCI_ADDRESS_MAP_INFO *AddrMapInfo; AML_OBJECT_NODE_HANDLE CrsNode; @@ -505,9 +505,9 @@ GeneratePciCrs ( return Status; } - // Get the array of CM_ARM_OBJ_REF referencing the + // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the // CM_ARM_PCI_ADDRESS_MAP_INFO objects. - Status = GetEArmObjCmRef ( + Status = GetEArchCommonObjCmRef ( CfgMgrProtocol, PciInfo->AddressMapToken, &RefInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index aef818e77f..d7ecd4dc1b 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,26 +166,25 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 21 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 22 - Cache Info - NULL, ///< 23 - CM Object Reference - NULL, ///< 24 - Memory Affinity Info - NULL, ///< 25 - Device Handle Acpi - NULL, ///< 26 - Device Handle Pci - NULL, ///< 27 - Generic Initiator Affinity - NULL, ///< 28 - CMN-600 Info - NULL, ///< 29 - Lpi Info - NULL, ///< 30 - Pci Address Map Info - NULL, ///< 31 - Pci Interrupt Map Info - NULL, ///< 32 - Reserved Memory Range Node - NULL, ///< 33 - Memory Range Descriptor - NULL, ///< 34 - Continuous Performance Control Info - NULL, ///< 35 - Pcc Subspace Type 0 Info + NULL, ///< 23 - Memory Affinity Info + NULL, ///< 24 - Device Handle Acpi + NULL, ///< 25 - Device Handle Pci + NULL, ///< 26 - Generic Initiator Affinity + NULL, ///< 27 - CMN-600 Info + NULL, ///< 28 - Lpi Info + NULL, ///< 29 - Pci Address Map Info + NULL, ///< 30 - Pci Interrupt Map Info + NULL, ///< 31 - Reserved Memory Range Node + NULL, ///< 32 - Memory Range Descriptor + NULL, ///< 33 - Continuous Performance Control Info + NULL, ///< 34 - Pcc Subspace Type 0 Info + NULL, ///< 35 - Pcc Subspace Type 2 Info NULL, ///< 36 - Pcc Subspace Type 2 Info - NULL, ///< 37 - Pcc Subspace Type 2 Info - NULL, ///< 38 - Pcc Subspace Type 3 Info - NULL, ///< 39 - Pcc Subspace Type 4 Info - NULL, ///< 40 - Pcc Subspace Type 5 Info - NULL, ///< 41 - Embedded Trace Extension/Module Info - NULL ///< 42 - P-State Dependency (PSD) Info + NULL, ///< 37 - Pcc Subspace Type 3 Info + NULL, ///< 38 - Pcc Subspace Type 4 Info + NULL, ///< 39 - Pcc Subspace Type 5 Info + NULL, ///< 40 - Embedded Trace Extension/Module Info + NULL ///< 41 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c index e4fa123370..08d11ac96a 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c @@ -145,7 +145,7 @@ DynPlatRepoAddObject ( // Check the CmObjDesc: // - only Arm objects and Arch Common objects are supported for now. - // - only EArmObjCmRef objects can be added as arrays. + // - only EArchCommonObjCmRef objects can be added as arrays. if ((CmObjDesc->Size == 0) || (CmObjDesc->Count == 0)) { ASSERT (0); return EFI_INVALID_PARAMETER; @@ -155,16 +155,16 @@ DynPlatRepoAddObject ( NamespaceId = GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId); if (EObjNameSpaceArm == NamespaceId) { - if ((ObjId >= EArmObjMax) || - ((CmObjDesc->Count > 1) && (ObjId != EArmObjCmRef))) - { + if (ObjId >= EArmObjMax) { ASSERT (0); return EFI_INVALID_PARAMETER; } ObjList = &This->ArmCmObjList[ObjId]; } else if (EObjNameSpaceArchCommon == NamespaceId) { - if (ObjId >= EArchCommonObjMax) { + if ((ObjId >= EArchCommonObjMax) || + ((CmObjDesc->Count > 1) && (ObjId != EArchCommonObjCmRef))) + { ASSERT (0); return EFI_INVALID_PARAMETER; } @@ -281,11 +281,11 @@ GroupCmObjNodes ( } if ((CmObjDesc->Count != 1) && - ((NamespaceId != EObjNameSpaceArm) || - (ObjIndex != EArmObjCmRef))) + ((NamespaceId != EObjNameSpaceArchCommon) || + (ObjIndex != EArchCommonObjCmRef))) { // We expect each descriptor to contain an individual object. - // EArmObjCmRef objects are counted as groups, so +1 as well. + // EArchCommonObjCmRef objects are counted as groups, so +1 as well. ASSERT (0); return EFI_INVALID_PARAMETER; } @@ -452,18 +452,18 @@ DynamicPlatRepoGetObject ( ObjId = GET_CM_OBJECT_ID (CmObjectId); if (NamespaceId == EObjNameSpaceArm) { - if ((ObjId >= EArmObjMax) || - ((ObjId == EArmObjCmRef) && - (Token == CM_NULL_TOKEN))) - { - // EArmObjCmRef object must be requested using a valid token. + if (ObjId >= EArmObjMax) { ASSERT (0); return EFI_INVALID_PARAMETER; } Desc = &This->ArmCmObjArray[ObjId]; } else if (NamespaceId == EObjNameSpaceArchCommon) { - if (ObjId >= EArchCommonObjMax) { + if ((ObjId >= EArchCommonObjMax) || + ((ObjId == EArchCommonObjCmRef) && + (Token == CM_NULL_TOKEN))) + { + // EArchCommonObjCmRef object must be requested using a valid token. ASSERT (0); return EFI_INVALID_PARAMETER; } diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c index 9391e935ee..2300375f03 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c @@ -66,11 +66,12 @@ TokenMapperAddObject ( // Point inside the finalized array. CmObjDesc->Data = Data; - // Only EArmObjCmRef CmObj can be added as arrays (more than 1 elements). - if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) && - (GET_CM_OBJECT_ID (ObjectId) == EArmObjCmRef)) + // Only EArchCommonObjCmRef CmObj can be added as + // arrays (more than 1 elements). + if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArchCommon) && + (GET_CM_OBJECT_ID (ObjectId) == EArchCommonObjCmRef)) { - CmObjDesc->Count = Size / sizeof (CM_ARM_OBJ_REF); + CmObjDesc->Count = Size / sizeof (CM_ARCH_COMMON_OBJ_REF); } else { CmObjDesc->Count = 1; } diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 3205cf87c8..264e01cff2 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -350,9 +350,9 @@ STATIC CONST CM_OBJ_PARSER CmArmCacheInfoParser[] = { { "CacheId", 4, "0x%x", NULL }, }; -/** A parser for EArmObjCmRef. +/** A parser for EArchCommonObjCmRef. */ -STATIC CONST CM_OBJ_PARSER CmArmObjRefParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonObjRefParser[] = { { "ReferenceToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL } }; @@ -677,6 +677,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser), CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -706,7 +707,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArmGenericInterruptParser), CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjCmRef, CmArmObjRefParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryAffinityInfo, CmArmMemoryAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandleAcpi, CmArmDeviceHandleAcpiParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandlePci, CmArmDeviceHandlePciParser), diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c index 8be1b5b8cd..120a98c2a9 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c @@ -219,11 +219,11 @@ AddMultipleCmObj ( /** Add multiple CmObj to the Configuration Manager. - Get one token referencing a EArmObjCmRef CmObj itself referencing + Get one token referencing a EArchCommonObjCmRef CmObj itself referencing the input CmObj. In the table below, RefToken is returned. Token referencing an Array of tokens Array of CmObj - array of EArmObjCmRef referencing each from the input: + array of EArchCommonObjCmRef referencing each from the input: CmObj: CmObj from the input: RefToken ---> CmObjToken[0] ---> CmObj[0] @@ -234,7 +234,7 @@ AddMultipleCmObj ( @param [in] CmObjDesc CmObjDesc containing multiple CmObj to add. @param [out] Token If success, token referencing an array - of EArmObjCmRef CmObj, themselves + of EArchCommonObjCmRef CmObj, themselves referencing the input CmObjs. @retval EFI_SUCCESS The function completed successfully. @@ -286,12 +286,12 @@ AddMultipleCmObjWithCmObjRef ( goto exit_handler; } - CmObjRef.ObjectId = CREATE_CM_ARM_OBJECT_ID (EArmObjCmRef); + CmObjRef.ObjectId = CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjCmRef); CmObjRef.Data = TokenTable; CmObjRef.Count = CmObjDesc->Count; CmObjRef.Size = TokenTableSize; - // Add the array of EArmObjCmRef CmObjs. + // Add the array of EArchCommonObjCmRef CmObjs. Status = FdtParserHandle->HwInfoAdd ( FdtParserHandle, FdtParserHandle->Context, diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h index 270e0c3528..14e135335f 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h @@ -98,11 +98,11 @@ AddMultipleCmObj ( /** Add multiple CmObj to the Configuration Manager. - Get one token referencing a EArmObjCmRef CmObj itself referencing + Get one token referencing a EArchCommonObjCmRef CmObj itself referencing the input CmObj. In the table below, RefToken is returned. Token referencing an Array of tokens Array of CmObj - array of EArmObjCmRef referencing each from the input: + array of EArchCommonObjCmRef referencing each from the input: CmObj: CmObj from the input: RefToken ---> CmObjToken[0] ---> CmObj[0] @@ -113,7 +113,7 @@ AddMultipleCmObj ( @param [in] CmObjDesc CmObjDesc containing multiple CmObj to add. @param [out] Token If success, token referencing an array - of EArmObjCmRef CmObj, themselves + of EArchCommonObjCmRef CmObj, themselves referencing the input CmObjs. @retval EFI_SUCCESS The function completed successfully. diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 5b9dda3e63..9110c75469 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,26 +463,25 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | SMMU Interrupt Array | | | 21 | Processor Hierarchy Info | Move to Arch Common NS | | 22 | Cache Info | Move to Arch Common NS | -| 23 | CM Object Reference | Move to Arch Common NS | -| 24 | Memory Affinity Info | Move to Arch Common NS | -| 25 | Device Handle Acpi | Move to Arch Common NS | -| 26 | Device Handle PCI | Move to Arch Common NS | -| 27 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 28 | CMN 600 Info | | -| 29 | Low Power Idle State Info | Move to Arch Common NS | -| 30 | PCI Address Map Info | Move to Arch Common NS | -| 31 | PCI Interrupt Map Info | Move to Arch Common NS | -| 32 | Reserved Memory Range Node | | -| 33 | Memory Range Descriptor | | -| 34 | Continuous Performance Control Info | Move to Arch Common NS | -| 35 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 36 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 37 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 38 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 39 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 40 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 41 | Embedded Trace Extension/Module Info | | -| 42 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Memory Affinity Info | Move to Arch Common NS | +| 24 | Device Handle Acpi | Move to Arch Common NS | +| 25 | Device Handle PCI | Move to Arch Common NS | +| 26 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 27 | CMN 600 Info | | +| 28 | Low Power Idle State Info | Move to Arch Common NS | +| 29 | PCI Address Map Info | Move to Arch Common NS | +| 30 | PCI Interrupt Map Info | Move to Arch Common NS | +| 31 | Reserved Memory Range Node | | +| 32 | Memory Range Descriptor | | +| 33 | Continuous Performance Control Info | Move to Arch Common NS | +| 34 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 35 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 36 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 37 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 38 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 39 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 40 | Embedded Trace Extension/Module Info | | +| 41 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 4 | Serial Debug Port Info | | | 5 | Hypervisor Vendor Id | | | 6 | Fixed feature flags for FADT | | +| 7 | CM Object Reference | | | `*` | All other values are reserved. | | -- cgit From 93bb65dcfc2e5a37d9a2950d40a55bfa22d60d66 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 8 Mar 2024 11:24:00 +0000 Subject: DynamicTablesPkg: Move Pci Config Space Info to Arm namespace Move Pci Config Space Info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - MCFG generator - SSDT PCIe generator - SSDT PCIe support library - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map - FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 28 +++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 88 ++++++++-------------- .../Include/Library/SsdtPcieSupportLib.h | 12 +-- .../Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c | 28 +++---- .../Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c | 40 +++++----- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 59 +++++++-------- .../Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c | 12 +-- .../ConfigurationManagerObjectParser.c | 6 +- .../Pci/ArmPciConfigSpaceParser.c | 20 ++--- .../Pci/ArmPciConfigSpaceParser.h | 10 +-- DynamicTablesPkg/Readme.md | 62 +++++++-------- 11 files changed, 183 insertions(+), 182 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 632816da09..7c70ba0238 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -28,6 +28,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjHypervisorVendorIdentity, ///< 5 - Hypervisor Vendor Id EArchCommonObjFixedFeatureFlags, ///< 6 - Fixed feature flags for FADT EArchCommonObjCmRef, ///< 7 - CM Object Reference + EArchCommonObjPciConfigSpaceInfo, ///< 8 - PCI Configuration Space Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -114,6 +115,33 @@ typedef struct CmArchCommonObjRef { CM_OBJECT_TOKEN ReferenceToken; } CM_ARCH_COMMON_OBJ_REF; +/** A structure that describes the + PCI Configuration Space information for the Platform. + + ID: EArchCommonObjPciConfigSpaceInfo +*/ +typedef struct CmArchCommonPciConfigSpaceInfo { + /// The physical base address for the PCI segment + UINT64 BaseAddress; + + /// The PCI segment group number + UINT16 PciSegmentGroupNumber; + + /// The start bus number + UINT8 StartBusNumber; + + /// The end bus number + UINT8 EndBusNumber; + + /// Optional field: Reference Token for address mapping. + /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure. + CM_OBJECT_TOKEN AddressMapToken; + + /// Optional field: Reference Token for interrupt mapping. + /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure. + CM_OBJECT_TOKEN InterruptMapToken; +} CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index cfcb2c7d27..a701de4bcd 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -39,37 +39,36 @@ typedef enum ArmObjectID { EArmObjPlatformGTBlockInfo, ///< 8 - Platform GT Block Info EArmObjGTBlockTimerFrameInfo, ///< 9 - Generic Timer Block Frame Info EArmObjPlatformGenericWatchdogInfo, ///< 10 - Platform Generic Watchdog - EArmObjPciConfigSpaceInfo, ///< 11 - PCI Configuration Space Info - EArmObjItsGroup, ///< 12 - ITS Group - EArmObjNamedComponent, ///< 13 - Named Component - EArmObjRootComplex, ///< 14 - Root Complex - EArmObjSmmuV1SmmuV2, ///< 15 - SMMUv1 or SMMUv2 - EArmObjSmmuV3, ///< 16 - SMMUv3 - EArmObjPmcg, ///< 17 - PMCG - EArmObjGicItsIdentifierArray, ///< 18 - GIC ITS Identifier Array - EArmObjIdMappingArray, ///< 19 - ID Mapping Array - EArmObjSmmuInterruptArray, ///< 20 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 21 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 22 - Cache Info - EArmObjMemoryAffinityInfo, ///< 23 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 24 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 25 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 26 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 27 - CMN-600 Info - EArmObjLpiInfo, ///< 28 - Lpi Info - EArmObjPciAddressMapInfo, ///< 29 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 30 - Pci Interrupt Map Info - EArmObjRmr, ///< 31 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 32 - Memory Range Descriptor - EArmObjCpcInfo, ///< 33 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 34 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 35 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 36 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 37 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 38 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 39 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 40 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 41 - P-State Dependency (PSD) Info + EArmObjItsGroup, ///< 11 - ITS Group + EArmObjNamedComponent, ///< 12 - Named Component + EArmObjRootComplex, ///< 13 - Root Complex + EArmObjSmmuV1SmmuV2, ///< 14 - SMMUv1 or SMMUv2 + EArmObjSmmuV3, ///< 15 - SMMUv3 + EArmObjPmcg, ///< 16 - PMCG + EArmObjGicItsIdentifierArray, ///< 17 - GIC ITS Identifier Array + EArmObjIdMappingArray, ///< 18 - ID Mapping Array + EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array + EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info + EArmObjCacheInfo, ///< 21 - Cache Info + EArmObjMemoryAffinityInfo, ///< 22 - Memory Affinity Info + EArmObjDeviceHandleAcpi, ///< 23 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 24 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 25 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 26 - CMN-600 Info + EArmObjLpiInfo, ///< 27 - Lpi Info + EArmObjPciAddressMapInfo, ///< 28 - Pci Address Map Info + EArmObjPciInterruptMapInfo, ///< 29 - Pci Interrupt Map Info + EArmObjRmr, ///< 30 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 31 - Memory Range Descriptor + EArmObjCpcInfo, ///< 32 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 33 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 34 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 35 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 36 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 37 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 38 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 39 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 40 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -408,33 +407,6 @@ typedef struct CmArmGenericWatchdogInfo { UINT32 Flags; } CM_ARM_GENERIC_WATCHDOG_INFO; -/** A structure that describes the - PCI Configuration Space information for the Platform. - - ID: EArmObjPciConfigSpaceInfo -*/ -typedef struct CmArmPciConfigSpaceInfo { - /// The physical base address for the PCI segment - UINT64 BaseAddress; - - /// The PCI segment group number - UINT16 PciSegmentGroupNumber; - - /// The start bus number - UINT8 StartBusNumber; - - /// The end bus number - UINT8 EndBusNumber; - - /// Optional field: Reference Token for address mapping. - /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure. - CM_OBJECT_TOKEN AddressMapToken; - - /// Optional field: Reference Token for interrupt mapping. - /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure. - CM_OBJECT_TOKEN InterruptMapToken; -} CM_ARM_PCI_CONFIG_SPACE_INFO; - /** A structure that describes the ITS Group node for the Platform. diff --git a/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h b/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h index 4171dabc33..50a335e4a4 100644 --- a/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h +++ b/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h @@ -43,8 +43,8 @@ typedef struct MappingTable { EFI_STATUS EFIAPI AddOscMethod ( - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, - IN OUT AML_OBJECT_NODE_HANDLE PciNode + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN OUT AML_OBJECT_NODE_HANDLE PciNode ); /** Generate Pci slots devices. @@ -66,10 +66,10 @@ AddOscMethod ( EFI_STATUS EFIAPI GeneratePciSlots ( - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, - IN CONST MAPPING_TABLE *MappingTable, - IN UINT32 Uid, - IN OUT AML_OBJECT_NODE_HANDLE PciNode + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST MAPPING_TABLE *MappingTable, + IN UINT32 Uid, + IN OUT AML_OBJECT_NODE_HANDLE PciNode ); #endif // SSDT_PCIE_SUPPORT_LIB_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c index 004b794a3c..722f9c17d5 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c @@ -27,7 +27,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjPciConfigSpaceInfo + - EArchCommonObjPciConfigSpaceInfo */ #pragma pack(1) @@ -51,9 +51,9 @@ typedef /** Retrieve the PCI Configuration Space Information. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPciConfigSpaceInfo, - CM_ARM_PCI_CONFIG_SPACE_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPciConfigSpaceInfo, + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO ); /** Add the PCI Enhanced Configuration Space Information to the MCFG Table. @@ -68,10 +68,10 @@ GET_OBJECT_LIST ( STATIC VOID AddPciConfigurationSpaceList ( - IN MCFG_TABLE *CONST Mcfg, - IN CONST UINT32 PciCfgSpaceOffset, - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciCfgSpaceInfoList, - IN UINT32 PciCfgSpaceCount + IN MCFG_TABLE *CONST Mcfg, + IN CONST UINT32 PciCfgSpaceOffset, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciCfgSpaceInfoList, + IN UINT32 PciCfgSpaceCount ) { MCFG_CFG_SPACE_ADDR *PciCfgSpace; @@ -126,11 +126,11 @@ BuildMcfgTable ( OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table ) { - EFI_STATUS Status; - UINT32 TableSize; - UINT32 ConfigurationSpaceCount; - CM_ARM_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfoList; - MCFG_TABLE *Mcfg; + EFI_STATUS Status; + UINT32 TableSize; + UINT32 ConfigurationSpaceCount; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfoList; + MCFG_TABLE *Mcfg; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -154,7 +154,7 @@ BuildMcfgTable ( } *Table = NULL; - Status = GetEArmObjPciConfigSpaceInfo ( + Status = GetEArchCommonObjPciConfigSpaceInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &PciConfigSpaceInfoList, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c index dc1371c3bc..2a169e0f6c 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c @@ -43,7 +43,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - EArchCommonObjCmRef - - EArmObjPciConfigSpaceInfo + - EArchCommonObjPciConfigSpaceInfo - EArmObjPciAddressMapInfo - EArmObjPciInterruptMapInfo */ @@ -61,9 +61,9 @@ GET_OBJECT_LIST ( Configuration Space Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPciConfigSpaceInfo, - CM_ARM_PCI_CONFIG_SPACE_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPciConfigSpaceInfo, + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO ); /** This macro expands to a function that retrieves the Pci @@ -208,9 +208,9 @@ STATIC EFI_STATUS EFIAPI GeneratePciDeviceInfo ( - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, - IN UINT32 Uid, - IN OUT AML_OBJECT_NODE_HANDLE PciNode + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN UINT32 Uid, + IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { EFI_STATUS Status; @@ -305,7 +305,7 @@ EFIAPI GeneratePrt ( IN ACPI_PCI_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, IN UINT32 Uid, IN OUT AML_OBJECT_NODE_HANDLE PciNode ) @@ -451,7 +451,7 @@ EFIAPI GeneratePciCrs ( IN ACPI_PCI_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { @@ -693,7 +693,7 @@ EFIAPI ReserveEcamSpace ( IN ACPI_PCI_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { @@ -760,7 +760,7 @@ EFIAPI GeneratePciDevice ( IN ACPI_PCI_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, IN UINT32 Uid, IN OUT AML_ROOT_NODE_HANDLE *RootNode ) @@ -863,7 +863,7 @@ BuildSsdtPciTable ( IN ACPI_PCI_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, IN UINT32 Uid, OUT EFI_ACPI_DESCRIPTION_HEADER **Table ) @@ -971,13 +971,13 @@ BuildSsdtPciTableEx ( OUT UINTN *CONST TableCount ) { - EFI_STATUS Status; - CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo; - UINT32 PciCount; - UINTN Index; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - ACPI_PCI_GENERATOR *Generator; - UINT32 Uid; + EFI_STATUS Status; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo; + UINT32 PciCount; + UINTN Index; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + ACPI_PCI_GENERATOR *Generator; + UINT32 Uid; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -990,7 +990,7 @@ BuildSsdtPciTableEx ( *TableCount = 0; Generator = (ACPI_PCI_GENERATOR *)This; - Status = GetEArmObjPciConfigSpaceInfo ( + Status = GetEArchCommonObjPciConfigSpaceInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &PciInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index d7ecd4dc1b..41f66ee7b6 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -154,37 +154,36 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 8 - Platform GT Block Info NULL, ///< 9 - Generic Timer Block Frame Info NULL, ///< 10 - Platform Generic Watchdog - NULL, ///< 11 - PCI Configuration Space Info - TokenFixerItsGroup, ///< 12 - ITS Group - TokenFixerNamedComponentNode, ///< 13 - Named Component - TokenFixerRootComplexNode, ///< 14 - Root Complex - TokenFixerNotImplemented, ///< 15 - SMMUv1 or SMMUv2 - TokenFixerSmmuV3Node, ///< 16 - SMMUv3 - TokenFixerNotImplemented, ///< 17 - PMCG - NULL, ///< 18 - GIC ITS Identifier Array - NULL, ///< 19 - ID Mapping Array - NULL, ///< 20 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 21 - Processor Hierarchy Info - TokenFixerNotImplemented, ///< 22 - Cache Info - NULL, ///< 23 - Memory Affinity Info - NULL, ///< 24 - Device Handle Acpi - NULL, ///< 25 - Device Handle Pci - NULL, ///< 26 - Generic Initiator Affinity - NULL, ///< 27 - CMN-600 Info - NULL, ///< 28 - Lpi Info - NULL, ///< 29 - Pci Address Map Info - NULL, ///< 30 - Pci Interrupt Map Info - NULL, ///< 31 - Reserved Memory Range Node - NULL, ///< 32 - Memory Range Descriptor - NULL, ///< 33 - Continuous Performance Control Info - NULL, ///< 34 - Pcc Subspace Type 0 Info + TokenFixerItsGroup, ///< 11 - ITS Group + TokenFixerNamedComponentNode, ///< 12 - Named Component + TokenFixerRootComplexNode, ///< 13 - Root Complex + TokenFixerNotImplemented, ///< 14 - SMMUv1 or SMMUv2 + TokenFixerSmmuV3Node, ///< 15 - SMMUv3 + TokenFixerNotImplemented, ///< 16 - PMCG + NULL, ///< 17 - GIC ITS Identifier Array + NULL, ///< 18 - ID Mapping Array + NULL, ///< 19 - SMMU Interrupt Array + TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info + TokenFixerNotImplemented, ///< 21 - Cache Info + NULL, ///< 22 - Memory Affinity Info + NULL, ///< 23 - Device Handle Acpi + NULL, ///< 24 - Device Handle Pci + NULL, ///< 25 - Generic Initiator Affinity + NULL, ///< 26 - CMN-600 Info + NULL, ///< 27 - Lpi Info + NULL, ///< 28 - Pci Address Map Info + NULL, ///< 29 - Pci Interrupt Map Info + NULL, ///< 30 - Reserved Memory Range Node + NULL, ///< 31 - Memory Range Descriptor + NULL, ///< 32 - Continuous Performance Control Info + NULL, ///< 33 - Pcc Subspace Type 0 Info + NULL, ///< 34 - Pcc Subspace Type 2 Info NULL, ///< 35 - Pcc Subspace Type 2 Info - NULL, ///< 36 - Pcc Subspace Type 2 Info - NULL, ///< 37 - Pcc Subspace Type 3 Info - NULL, ///< 38 - Pcc Subspace Type 4 Info - NULL, ///< 39 - Pcc Subspace Type 5 Info - NULL, ///< 40 - Embedded Trace Extension/Module Info - NULL ///< 41 - P-State Dependency (PSD) Info + NULL, ///< 36 - Pcc Subspace Type 3 Info + NULL, ///< 37 - Pcc Subspace Type 4 Info + NULL, ///< 38 - Pcc Subspace Type 5 Info + NULL, ///< 39 - Embedded Trace Extension/Module Info + NULL ///< 40 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c b/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c index b35fb6a7dd..3f8aae44bf 100644 --- a/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c +++ b/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c @@ -53,10 +53,10 @@ EFI_STATUS EFIAPI GeneratePciSlots ( - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, - IN CONST MAPPING_TABLE *MappingTable, - IN UINT32 Uid, - IN OUT AML_OBJECT_NODE_HANDLE PciNode + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN CONST MAPPING_TABLE *MappingTable, + IN UINT32 Uid, + IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { EFI_STATUS Status; @@ -132,8 +132,8 @@ GeneratePciSlots ( EFI_STATUS EFIAPI AddOscMethod ( - IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo, - IN OUT AML_OBJECT_NODE_HANDLE PciNode + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { EFI_STATUS Status; diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 264e01cff2..73dbb9879d 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -182,9 +182,9 @@ STATIC CONST CM_OBJ_PARSER CmArmGenericWatchdogInfoParser[] = { { "Flags", 4, "0x%x", NULL } }; -/** A parser for EArmObjPciConfigSpaceInfo. +/** A parser for EArchCommonObjPciConfigSpaceInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmPciConfigSpaceInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPciConfigSpaceInfoParser[] = { { "BaseAddress", 8, "0x%llx", NULL }, { "PciSegmentGroupNumber", 2, "0x%x", NULL }, { "StartBusNumber", 1, "0x%x", NULL }, @@ -678,6 +678,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser), CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser), CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -695,7 +696,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjPlatformGTBlockInfo, CmArmGTBlockInfoParser), CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo, CmArmGenericWatchdogInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPciConfigSpaceInfo, CmArmPciConfigSpaceInfoParser), CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser), CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser), CM_PARSER_ADD_OBJECT (EArmObjRootComplex, CmArmRootComplexNodeParser), diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c index 2ffff1ccd2..7d9fe7b1da 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c @@ -468,7 +468,7 @@ ParseIrqMap ( @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). @param [in] HostPciNode Offset of a host-pci node. - @param [in, out] PciInfo The CM_ARM_PCI_CONFIG_SPACE_INFO to populate. + @param [in, out] PciInfo The CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO to populate. @retval EFI_SUCCESS The function completed successfully. @retval EFI_ABORTED An error occurred. @@ -579,7 +579,7 @@ PciNodeParser ( /** Add the parsed Pci information to the Configuration Manager. CmObj of the following types are concerned: - - EArmObjPciConfigSpaceInfo + - EArchCommonObjPciConfigSpaceInfo - EArmObjPciAddressMapInfo - EArmObjPciInterruptMapInfo @@ -599,8 +599,8 @@ PciInfoAdd ( IN PCI_PARSER_TABLE *PciTableInfo ) { - EFI_STATUS Status; - CM_ARM_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo; + EFI_STATUS Status; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo; if ((FdtParserHandle == NULL) || (PciTableInfo == NULL)) @@ -640,9 +640,11 @@ PciInfoAdd ( // Add the configuration space CmObj to the Configuration Manager. Status = AddSingleCmObj ( FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo), + CREATE_CM_ARCH_COMMON_OBJECT_ID ( + EArchCommonObjPciConfigSpaceInfo + ), &PciTableInfo->PciConfigSpaceInfo, - sizeof (CM_ARM_PCI_CONFIG_SPACE_INFO), + sizeof (CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO), NULL ); ASSERT_EFI_ERROR (Status); @@ -682,15 +684,15 @@ FreeParserTable ( return EFI_SUCCESS; } -/** CM_ARM_PCI_CONFIG_SPACE_INFO parser function. +/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function. The following structure is populated: - typedef struct CmArmPciConfigSpaceInfo { + typedef struct CmArchCommonPciConfigSpaceInfo { UINT64 BaseAddress; // {Populated} UINT16 PciSegmentGroupNumber; // {Populated} UINT8 StartBusNumber; // {Populated} UINT8 EndBusNumber; // {Populated} - } CM_ARM_PCI_CONFIG_SPACE_INFO; + } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; typedef struct CmArmPciAddressMapInfo { UINT8 SpaceCode; // {Populated} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h index 6e0027abea..4e269508a6 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h @@ -83,24 +83,24 @@ typedef enum PciMappingTable { */ typedef struct PciParserTable { /// PCI Configuration Space Info - CM_ARM_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo; /// Store the address mapping and interrupt mapping as CmObjDesc /// before adding them to the Configuration Manager. - CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax]; + CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax]; } PCI_PARSER_TABLE; #pragma pack() -/** CM_ARM_PCI_CONFIG_SPACE_INFO parser function. +/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function. The following structure is populated: - typedef struct CmArmPciConfigSpaceInfo { + typedef struct CmArchCommonPciConfigSpaceInfo { UINT64 BaseAddress; // {Populated} UINT16 PciSegmentGroupNumber; // {Populated} UINT8 StartBusNumber; // {Populated} UINT8 EndBusNumber; // {Populated} - } CM_ARM_PCI_CONFIG_SPACE_INFO; + } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; typedef struct CmArmPciAddressMapInfo { UINT8 SpaceCode; // {Populated} diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 9110c75469..e0544fe40b 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -451,37 +451,36 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 8 | Platform GT Block Info | | | 9 | Generic Timer Block Frame Info | | | 10 | Platform Generic Watchdog | | -| 11 | PCI Configuration Space Info | Move to Arch Common NS | -| 12 | ITS Group | | -| 13 | Named Component | | -| 14 | Root Complex | | -| 15 | SMMUv1 or SMMUv2 | | -| 16 | SMMUv3 | | -| 17 | PMCG | | -| 18 | GIC ITS Identifier Array | | -| 19 | ID Mapping Array | | -| 20 | SMMU Interrupt Array | | -| 21 | Processor Hierarchy Info | Move to Arch Common NS | -| 22 | Cache Info | Move to Arch Common NS | -| 23 | Memory Affinity Info | Move to Arch Common NS | -| 24 | Device Handle Acpi | Move to Arch Common NS | -| 25 | Device Handle PCI | Move to Arch Common NS | -| 26 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 27 | CMN 600 Info | | -| 28 | Low Power Idle State Info | Move to Arch Common NS | -| 29 | PCI Address Map Info | Move to Arch Common NS | -| 30 | PCI Interrupt Map Info | Move to Arch Common NS | -| 31 | Reserved Memory Range Node | | -| 32 | Memory Range Descriptor | | -| 33 | Continuous Performance Control Info | Move to Arch Common NS | -| 34 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 35 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 36 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 37 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 38 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 39 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 40 | Embedded Trace Extension/Module Info | | -| 41 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 11 | ITS Group | | +| 12 | Named Component | | +| 13 | Root Complex | | +| 14 | SMMUv1 or SMMUv2 | | +| 15 | SMMUv3 | | +| 16 | PMCG | | +| 17 | GIC ITS Identifier Array | | +| 18 | ID Mapping Array | | +| 19 | SMMU Interrupt Array | | +| 20 | Processor Hierarchy Info | Move to Arch Common NS | +| 21 | Cache Info | Move to Arch Common NS | +| 22 | Memory Affinity Info | Move to Arch Common NS | +| 23 | Device Handle Acpi | Move to Arch Common NS | +| 24 | Device Handle PCI | Move to Arch Common NS | +| 25 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 26 | CMN 600 Info | | +| 27 | Low Power Idle State Info | Move to Arch Common NS | +| 28 | PCI Address Map Info | Move to Arch Common NS | +| 29 | PCI Interrupt Map Info | Move to Arch Common NS | +| 30 | Reserved Memory Range Node | | +| 31 | Memory Range Descriptor | | +| 32 | Continuous Performance Control Info | Move to Arch Common NS | +| 33 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 34 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 35 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 36 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 37 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 38 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 39 | Embedded Trace Extension/Module Info | | +| 40 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 5 | Hypervisor Vendor Id | | | 6 | Fixed feature flags for FADT | | | 7 | CM Object Reference | | +| 8 | PCI Configuration Space Info | | | `*` | All other values are reserved. | | -- cgit From ae1ba787188b13b69ae4d5d8aaa3249d6a735279 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Tue, 16 Apr 2024 18:13:03 +0530 Subject: ArmVirtPkg: Kvmtool: Update Pci Config Space Info in Cfg Manager The Pci Config Space Info object was moved from the Arm Namespace to the Arch Common namespace. Therefore, update the Kvmtool guest firmware configuration manager to reflect this change. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Reviewed-by: Sunil V L --- ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c index 7240544406..96fbea3335 100644 --- a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c +++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c @@ -662,7 +662,9 @@ GetStandardNameSpaceObject ( // Status = DynamicPlatRepoGetObject ( PlatformRepo->DynamicPlatformRepo, - CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo), + CREATE_CM_ARCH_COMMON_OBJECT_ID ( + EArchCommonObjPciConfigSpaceInfo + ), CM_NULL_TOKEN, &CmObjDesc ); -- cgit From 83b01dc5ccea79ff28eb53fea971eebfb436ecb6 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 8 Mar 2024 11:48:29 +0000 Subject: DynamicTablesPkg: Move Pci Address Map Info to Arch Common Move Pci Address Map Info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SSDT PCIe generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map - FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 28 ++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 52 +++++----------------- .../Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c | 30 ++++++------- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 23 +++++----- .../ConfigurationManagerObjectParser.c | 6 +-- .../Pci/ArmPciConfigSpaceParser.c | 18 ++++---- .../Pci/ArmPciConfigSpaceParser.h | 4 +- DynamicTablesPkg/Readme.md | 26 +++++------ 8 files changed, 93 insertions(+), 94 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 7c70ba0238..bbc5d7dc55 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -29,6 +29,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjFixedFeatureFlags, ///< 6 - Fixed feature flags for FADT EArchCommonObjCmRef, ///< 7 - CM Object Reference EArchCommonObjPciConfigSpaceInfo, ///< 8 - PCI Configuration Space Info + EArchCommonObjPciAddressMapInfo, ///< 9 - Pci Address Map Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -142,6 +143,33 @@ typedef struct CmArchCommonPciConfigSpaceInfo { CM_OBJECT_TOKEN InterruptMapToken; } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; +/** A structure that describes a PCI Address Map. + + The memory-ranges used by the PCI bus are described by this object. + + ID: EArchCommonObjPciAddressMapInfo +*/ +typedef struct CmArchCommonPciAddressMapInfo { + /** Pci address space code + + Available values are: + - 0: Configuration Space + - 1: I/O Space + - 2: 32-bit-address Memory Space + - 3: 64-bit-address Memory Space + */ + UINT8 SpaceCode; + + /// PCI address + UINT64 PciAddress; + + /// Cpu address + UINT64 CpuAddress; + + /// Address size + UINT64 AddressSize; +} CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index a701de4bcd..5b318bbb10 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -56,19 +56,18 @@ typedef enum ArmObjectID { EArmObjGenericInitiatorAffinityInfo, ///< 25 - Generic Initiator Affinity EArmObjCmn600Info, ///< 26 - CMN-600 Info EArmObjLpiInfo, ///< 27 - Lpi Info - EArmObjPciAddressMapInfo, ///< 28 - Pci Address Map Info - EArmObjPciInterruptMapInfo, ///< 29 - Pci Interrupt Map Info - EArmObjRmr, ///< 30 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 31 - Memory Range Descriptor - EArmObjCpcInfo, ///< 32 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 33 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 34 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 35 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 36 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 37 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 38 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 39 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 40 - P-State Dependency (PSD) Info + EArmObjPciInterruptMapInfo, ///< 28 - Pci Interrupt Map Info + EArmObjRmr, ///< 29 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 30 - Memory Range Descriptor + EArmObjCpcInfo, ///< 31 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 32 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 33 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 34 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 35 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 36 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 37 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 38 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 39 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -901,33 +900,6 @@ typedef struct CmArmLpiInfo { CHAR8 StateName[16]; } CM_ARM_LPI_INFO; -/** A structure that describes a PCI Address Map. - - The memory-ranges used by the PCI bus are described by this object. - - ID: EArmObjPciAddressMapInfo -*/ -typedef struct CmArmPciAddressMapInfo { - /** Pci address space code - - Available values are: - - 0: Configuration Space - - 1: I/O Space - - 2: 32-bit-address Memory Space - - 3: 64-bit-address Memory Space - */ - UINT8 SpaceCode; - - /// PCI address - UINT64 PciAddress; - - /// Cpu address - UINT64 CpuAddress; - - /// Address size - UINT64 AddressSize; -} CM_ARM_PCI_ADDRESS_MAP_INFO; - /** A structure that describes a PCI Interrupt Map. The legacy PCI interrupts used by PCI devices are described by this object. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c index 2a169e0f6c..e86f1cb529 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c @@ -44,7 +44,7 @@ Requirements: this Generator: - EArchCommonObjCmRef - EArchCommonObjPciConfigSpaceInfo - - EArmObjPciAddressMapInfo + - EArchCommonObjPciAddressMapInfo - EArmObjPciInterruptMapInfo */ @@ -70,9 +70,9 @@ GET_OBJECT_LIST ( Address Mapping Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPciAddressMapInfo, - CM_ARM_PCI_ADDRESS_MAP_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPciAddressMapInfo, + CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO ); /** This macro expands to a function that retrieves the Pci @@ -455,14 +455,14 @@ GeneratePciCrs ( IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { - EFI_STATUS Status; - BOOLEAN Translation; - UINT32 Index; - CM_ARCH_COMMON_OBJ_REF *RefInfo; - UINT32 RefCount; - CM_ARM_PCI_ADDRESS_MAP_INFO *AddrMapInfo; - AML_OBJECT_NODE_HANDLE CrsNode; - BOOLEAN IsPosDecode; + EFI_STATUS Status; + BOOLEAN Translation; + UINT32 Index; + CM_ARCH_COMMON_OBJ_REF *RefInfo; + UINT32 RefCount; + CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *AddrMapInfo; + AML_OBJECT_NODE_HANDLE CrsNode; + BOOLEAN IsPosDecode; ASSERT (Generator != NULL); ASSERT (CfgMgrProtocol != NULL); @@ -506,7 +506,7 @@ GeneratePciCrs ( } // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the - // CM_ARM_PCI_ADDRESS_MAP_INFO objects. + // CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO objects. Status = GetEArchCommonObjCmRef ( CfgMgrProtocol, PciInfo->AddressMapToken, @@ -519,8 +519,8 @@ GeneratePciCrs ( } for (Index = 0; Index < RefCount; Index++) { - // Get CM_ARM_PCI_ADDRESS_MAP_INFO structures one by one. - Status = GetEArmObjPciAddressMapInfo ( + // Get CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO structures one by one. + Status = GetEArchCommonObjPciAddressMapInfo ( CfgMgrProtocol, RefInfo[Index].ReferenceToken, &AddrMapInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 41f66ee7b6..0e12b0f8b1 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -171,19 +171,18 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 25 - Generic Initiator Affinity NULL, ///< 26 - CMN-600 Info NULL, ///< 27 - Lpi Info - NULL, ///< 28 - Pci Address Map Info - NULL, ///< 29 - Pci Interrupt Map Info - NULL, ///< 30 - Reserved Memory Range Node - NULL, ///< 31 - Memory Range Descriptor - NULL, ///< 32 - Continuous Performance Control Info - NULL, ///< 33 - Pcc Subspace Type 0 Info + NULL, ///< 28 - Pci Interrupt Map Info + NULL, ///< 29 - Reserved Memory Range Node + NULL, ///< 30 - Memory Range Descriptor + NULL, ///< 31 - Continuous Performance Control Info + NULL, ///< 32 - Pcc Subspace Type 0 Info + NULL, ///< 33 - Pcc Subspace Type 2 Info NULL, ///< 34 - Pcc Subspace Type 2 Info - NULL, ///< 35 - Pcc Subspace Type 2 Info - NULL, ///< 36 - Pcc Subspace Type 3 Info - NULL, ///< 37 - Pcc Subspace Type 4 Info - NULL, ///< 38 - Pcc Subspace Type 5 Info - NULL, ///< 39 - Embedded Trace Extension/Module Info - NULL ///< 40 - P-State Dependency (PSD) Info + NULL, ///< 35 - Pcc Subspace Type 3 Info + NULL, ///< 36 - Pcc Subspace Type 4 Info + NULL, ///< 37 - Pcc Subspace Type 5 Info + NULL, ///< 38 - Embedded Trace Extension/Module Info + NULL ///< 39 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 73dbb9879d..2d0e628766 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -440,9 +440,9 @@ STATIC CONST CM_OBJ_PARSER CmArmLpiInfoParser[] = { { "StateName", 16, NULL, PrintString }, }; -/** A parser for EArmObjPciAddressMapInfo. +/** A parser for EArchCommonObjPciAddressMapInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmPciAddressMapInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPciAddressMapInfoParser[] = { { "SpaceCode", 1, "%d", NULL }, { "PciAddress", 8, "0x%llx", NULL }, { "CpuAddress", 8, "0x%llx", NULL }, @@ -679,6 +679,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser), CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -713,7 +714,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPciAddressMapInfo, CmArmPciAddressMapInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPciInterruptMapInfo, CmPciInterruptMapInfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c index 7d9fe7b1da..aef0f27a15 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c @@ -188,8 +188,8 @@ ParseAddressMap ( UINT32 Count; UINT32 PciAddressAttr; - CM_ARM_PCI_ADDRESS_MAP_INFO *PciAddressMapInfo; - UINT32 BufferSize; + CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *PciAddressMapInfo; + UINT32 BufferSize; // The mapping is done on AddressMapSize bytes. AddressMapSize = (PCI_ADDRESS_CELLS + AddressCells + PCI_SIZE_CELLS) * @@ -208,7 +208,7 @@ ParseAddressMap ( Count = DataSize / AddressMapSize; // Allocate a buffer to store each address mapping. - BufferSize = Count * sizeof (CM_ARM_PCI_ADDRESS_MAP_INFO); + BufferSize = Count * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO); PciAddressMapInfo = AllocateZeroPool (BufferSize); if (PciAddressMapInfo == NULL) { ASSERT (0); @@ -246,9 +246,9 @@ ParseAddressMap ( } // for PciInfo->Mapping[PciMappingTableAddress].ObjectId = - CREATE_CM_ARM_OBJECT_ID (EArmObjPciAddressMapInfo); + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciAddressMapInfo); PciInfo->Mapping[PciMappingTableAddress].Size = - sizeof (CM_ARM_PCI_ADDRESS_MAP_INFO) * Count; + sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO) * Count; PciInfo->Mapping[PciMappingTableAddress].Data = PciAddressMapInfo; PciInfo->Mapping[PciMappingTableAddress].Count = Count; @@ -413,7 +413,7 @@ ParseIrqMap ( // Allocate a buffer to store each interrupt mapping. IrqMapCount = DataSize / IrqMapSize; - BufferSize = IrqMapCount * sizeof (CM_ARM_PCI_ADDRESS_MAP_INFO); + BufferSize = IrqMapCount * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO); PciInterruptMapInfo = AllocateZeroPool (BufferSize); if (PciInterruptMapInfo == NULL) { ASSERT (0); @@ -580,7 +580,7 @@ PciNodeParser ( CmObj of the following types are concerned: - EArchCommonObjPciConfigSpaceInfo - - EArmObjPciAddressMapInfo + - EArchCommonObjPciAddressMapInfo - EArmObjPciInterruptMapInfo @param [in] FdtParserHandle A handle to the parser instance. @@ -694,12 +694,12 @@ FreeParserTable ( UINT8 EndBusNumber; // {Populated} } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; - typedef struct CmArmPciAddressMapInfo { + typedef struct CmArchCommonPciAddressMapInfo { UINT8 SpaceCode; // {Populated} UINT64 PciAddress; // {Populated} UINT64 CpuAddress; // {Populated} UINT64 AddressSize; // {Populated} - } CM_ARM_PCI_ADDRESS_MAP_INFO; + } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; typedef struct CmArmPciInterruptMapInfo { UINT8 PciBus; // {Populated} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h index 4e269508a6..ba7090fd7e 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h @@ -102,12 +102,12 @@ typedef struct PciParserTable { UINT8 EndBusNumber; // {Populated} } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; - typedef struct CmArmPciAddressMapInfo { + typedef struct CmArchCommonPciAddressMapInfo { UINT8 SpaceCode; // {Populated} UINT64 PciAddress; // {Populated} UINT64 CpuAddress; // {Populated} UINT64 AddressSize; // {Populated} - } CM_ARM_PCI_ADDRESS_MAP_INFO; + } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; typedef struct CmArmPciInterruptMapInfo { UINT8 PciBus; // {Populated} diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index e0544fe40b..0caae7dc45 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -468,19 +468,18 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 25 | Generic Initiator Affinity Info | Move to Arch Common NS | | 26 | CMN 600 Info | | | 27 | Low Power Idle State Info | Move to Arch Common NS | -| 28 | PCI Address Map Info | Move to Arch Common NS | -| 29 | PCI Interrupt Map Info | Move to Arch Common NS | -| 30 | Reserved Memory Range Node | | -| 31 | Memory Range Descriptor | | -| 32 | Continuous Performance Control Info | Move to Arch Common NS | -| 33 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 34 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 35 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 36 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 37 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 38 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 39 | Embedded Trace Extension/Module Info | | -| 40 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 28 | PCI Interrupt Map Info | Move to Arch Common NS | +| 29 | Reserved Memory Range Node | | +| 30 | Memory Range Descriptor | | +| 31 | Continuous Performance Control Info | Move to Arch Common NS | +| 32 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 33 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 34 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 35 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 36 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 37 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 38 | Embedded Trace Extension/Module Info | | +| 39 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 6 | Fixed feature flags for FADT | | | 7 | CM Object Reference | | | 8 | PCI Configuration Space Info | | +| 9 | PCI Address Map Info | | | `*` | All other values are reserved. | | -- cgit From 4333f5c31630c316c13a6a4539613052a45266a5 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 8 Mar 2024 12:14:54 +0000 Subject: DynamicTablesPkg: Move CM_ARM_GENERIC_INTERRUPT struct to Arch Common The CM_ARM_GENERIC_INTERRUPT struct describes a standard interrupt and is generic. Therefore move it to the Arch Common namespace header file and rename it as CM_ARCH_COMMON_GENERIC_INTERRUPT. Correspondingly also update the following modules to reflect the changes introduced by the move: - SSDT CMN600 generator - ConfigurationManagerObjectParser - FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 15 ++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 55 ++++++++-------------- .../Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c | 16 +++---- .../ConfigurationManagerObjectParser.c | 36 +++++++------- .../Pci/ArmPciConfigSpaceParser.c | 8 ++-- .../Pci/ArmPciConfigSpaceParser.h | 8 ++-- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index bbc5d7dc55..c5639e0508 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -170,6 +170,21 @@ typedef struct CmArchCommonPciAddressMapInfo { UINT64 AddressSize; } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; +/** A structure that describes the + Generic Interrupts. +*/ +typedef struct CmArchCommonGenericInterrupt { + /// Interrupt number + UINT32 Interrupt; + + /// Flags + /// BIT0: 0: Interrupt is Level triggered + /// 1: Interrupt is Edge triggered + /// BIT1: 0: Interrupt is Active high + /// 1: Interrupt is Active low + UINT32 Flags; +} CM_ARCH_COMMON_GENERIC_INTERRUPT; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 5b318bbb10..60ec34a7b3 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -632,21 +632,6 @@ typedef struct CmArmIdMapping { UINT32 Flags; } CM_ARM_ID_MAPPING; -/** A structure that describes the Arm - Generic Interrupts. -*/ -typedef struct CmArmGenericInterrupt { - /// Interrupt number - UINT32 Interrupt; - - /// Flags - /// BIT0: 0: Interrupt is Level triggered - /// 1: Interrupt is Edge triggered - /// BIT1: 0: Interrupt is Active high - /// 1: Interrupt is Active low - UINT32 Flags; -} CM_ARM_GENERIC_INTERRUPT; - /** A structure that describes the SMMU interrupts for the Platform. Interrupt Interrupt number. @@ -654,7 +639,7 @@ typedef struct CmArmGenericInterrupt { ID: EArmObjSmmuInterruptArray */ -typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT; +typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT; /** A structure that describes the AML Extended Interrupts. @@ -664,7 +649,7 @@ typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT; resource descriptor. See EFI_ACPI_EXTENDED_INTERRUPT_FLAG_xxx in Acpi10.h */ -typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT; +typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT; /** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT @@ -927,14 +912,14 @@ typedef struct CmArmPciInterruptMapInfo { Device-tree bindings are shifted by 1: "INTA=1, INTB=2, INTC=3, INTD=4" */ - UINT8 PciInterrupt; + UINT8 PciInterrupt; /** Interrupt controller interrupt. Cf Devicetree Specification - Release v0.3 s2.4.3 "Interrupt Nexus Properties": "parent interrupt specifier" */ - CM_ARM_GENERIC_INTERRUPT IntcInterrupt; + CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; } CM_ARM_PCI_INTERRUPT_MAP_INFO; /** A structure that describes the @@ -1085,10 +1070,10 @@ typedef struct CmArmPccSubspaceType1Info { The Subspace of Type0 contains information that can be re-used in other Subspace types. */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; /// Platform Interrupt. - CM_ARM_GENERIC_INTERRUPT PlatIrq; + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; } CM_ARM_PCC_SUBSPACE_TYPE1_INFO; /** A structure that describes a @@ -1102,13 +1087,13 @@ typedef struct CmArmPccSubspaceType2Info { The Subspace of Type0 contains information that can be re-used in other Subspace types. */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; /// Platform Interrupt. - CM_ARM_GENERIC_INTERRUPT PlatIrq; + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; /// Platform Interrupt Register. - PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; + PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; } CM_ARM_PCC_SUBSPACE_TYPE2_INFO; /** A structure that describes a @@ -1122,24 +1107,24 @@ typedef struct CmArmPccSubspaceType3Info { The Subspace of Type0 contains information that can be re-used in other Subspace types. */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; /// Platform Interrupt. - CM_ARM_GENERIC_INTERRUPT PlatIrq; + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; /// Platform Interrupt Register. - PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; + PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; /// Command Complete Check Register. /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; + PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; /// Command Complete Update Register. - PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg; + PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg; /// Error Status Register. /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; + PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; } CM_ARM_PCC_SUBSPACE_TYPE3_INFO; /** A structure that describes a @@ -1163,21 +1148,21 @@ typedef struct CmArmPccSubspaceType5Info { MaximumPeriodicAccessRate doesn't need to be populated for this structure. */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; /// Version. - UINT16 Version; + UINT16 Version; /// Platform Interrupt. - CM_ARM_GENERIC_INTERRUPT PlatIrq; + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; /// Command Complete Check Register. /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; + PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; /// Error Status Register. /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; + PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; } CM_ARM_PCC_SUBSPACE_TYPE5_INFO; /** An enum describing the Arm Embedded Trace device type. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c index 6118df0549..3585a53a9d 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c @@ -65,10 +65,10 @@ ValidateCmn600Info ( IN CONST UINT32 Cmn600Count ) { - UINT32 Index; - UINT32 DtcIndex; - CONST CM_ARM_CMN_600_INFO *Cmn600Info; - CONST CM_ARM_GENERIC_INTERRUPT *DtcInterrupt; + UINT32 Index; + UINT32 DtcIndex; + CONST CM_ARM_CMN_600_INFO *Cmn600Info; + CONST CM_ARCH_COMMON_GENERIC_INTERRUPT *DtcInterrupt; if ((Cmn600InfoList == NULL) || (Cmn600Count == 0)) @@ -231,10 +231,10 @@ FixupCmn600Info ( OUT EFI_ACPI_DESCRIPTION_HEADER **Table ) { - EFI_STATUS Status; - EFI_STATUS Status1; - UINT8 Index; - CONST CM_ARM_GENERIC_INTERRUPT *DtcInt; + EFI_STATUS Status; + EFI_STATUS Status1; + UINT8 Index; + CONST CM_ARCH_COMMON_GENERIC_INTERRUPT *DtcInt; EFI_ACPI_DESCRIPTION_HEADER *SsdtCmn600Template; AML_ROOT_NODE_HANDLE RootNodeHandle; diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 2d0e628766..1fd1edb8eb 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -317,7 +317,7 @@ STATIC CONST CM_OBJ_PARSER CmArmIdMappingParser[] = { /** A parser for EArmObjSmmuInterruptArray. */ -STATIC CONST CM_OBJ_PARSER CmArmGenericInterruptParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonGenericInterruptParser[] = { { "Interrupt", 4, "0x%x", NULL }, { "Flags", 4, "0x%x", NULL } }; @@ -452,12 +452,12 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPciAddressMapInfoParser[] = { /** A parser for EArmObjPciInterruptMapInfo. */ STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = { - { "PciBus", 1, "0x%x", NULL }, - { "PciDevice", 1, "0x%x", NULL }, - { "PciInterrupt", 1, "0x%x", NULL }, - { "IntcInterrupt", sizeof (CM_ARM_GENERIC_INTERRUPT), - NULL, NULL, CmArmGenericInterruptParser, - ARRAY_SIZE (CmArmGenericInterruptParser) }, + { "PciBus", 1, "0x%x", NULL }, + { "PciDevice", 1, "0x%x", NULL }, + { "PciInterrupt", 1, "0x%x", NULL }, + { "IntcInterrupt", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT), + NULL, NULL, CmArchCommonGenericInterruptParser, + ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, }; /** A parser for EArmObjRmr. @@ -595,9 +595,9 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArmPccSubspaceType0InfoParser, ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, - { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), - NULL, NULL, CmArmGenericInterruptParser, - ARRAY_SIZE (CmArmGenericInterruptParser) }, + { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT), + NULL, NULL, CmArchCommonGenericInterruptParser, + ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, }; /** A parser for EArmObjPccSubspaceType2Info. @@ -606,8 +606,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArmPccSubspaceType0InfoParser, ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, - { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL, - CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) }, + { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL,NULL, + CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, { "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO), NULL, NULL, CmArmMailboxRegisterInfoParser, ARRAY_SIZE (CmArmMailboxRegisterInfoParser) }, @@ -619,8 +619,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArmPccSubspaceType0InfoParser, ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, - { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL, - CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) }, + { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL,NULL, + CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, { "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO), NULL, NULL, CmArmMailboxRegisterInfoParser, ARRAY_SIZE (CmArmMailboxRegisterInfoParser) }, @@ -641,9 +641,9 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType5InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArmPccSubspaceType0InfoParser, ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, - { "Version", 2, "0x%x",NULL }, - { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL, NULL, - CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) }, + { "Version", 2, "0x%x",NULL }, + { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL, NULL, + CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, { "CmdCompleteCheckReg", sizeof (PCC_MAILBOX_REGISTER_INFO), NULL, NULL, CmArmMailboxRegisterInfoParser, ARRAY_SIZE (CmArmMailboxRegisterInfoParser) }, @@ -705,7 +705,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjPmcg, CmArmPmcgNodeParser), CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser), CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser), - CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArmGenericInterruptParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryAffinityInfo, CmArmMemoryAffinityInfoParser), diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c index aef0f27a15..b20d265a83 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c @@ -702,10 +702,10 @@ FreeParserTable ( } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; typedef struct CmArmPciInterruptMapInfo { - UINT8 PciBus; // {Populated} - UINT8 PciDevice; // {Populated} - UINT8 PciInterrupt; // {Populated} - CM_ARM_GENERIC_INTERRUPT IntcInterrupt; // {Populated} + UINT8 PciBus; // {Populated} + UINT8 PciDevice; // {Populated} + UINT8 PciInterrupt; // {Populated} + CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} } CM_ARM_PCI_INTERRUPT_MAP_INFO; A parser parses a Device Tree to populate a specific CmObj type. None, diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h index ba7090fd7e..33457cd6e9 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h @@ -110,10 +110,10 @@ typedef struct PciParserTable { } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; typedef struct CmArmPciInterruptMapInfo { - UINT8 PciBus; // {Populated} - UINT8 PciDevice; // {Populated} - UINT8 PciInterrupt; // {Populated} - CM_ARM_GENERIC_INTERRUPT IntcInterrupt; // {Populated} + UINT8 PciBus; // {Populated} + UINT8 PciDevice; // {Populated} + UINT8 PciInterrupt; // {Populated} + CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} } CM_ARM_PCI_INTERRUPT_MAP_INFO; A parser parses a Device Tree to populate a specific CmObj type. None, -- cgit From 11dcf74d4240c5627d88a627c671037b0faf1cb8 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 8 Mar 2024 12:06:59 +0000 Subject: DynamicTablesPkg: Move Pci Interrupt Map Info to Arch Common Move Pci Interrupt Map Info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SSDT PCIe library - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map - FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 38 ++++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 60 ++++------------------ .../Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c | 26 +++++----- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 21 ++++---- .../ConfigurationManagerObjectParser.c | 6 +-- .../Pci/ArmPciConfigSpaceParser.c | 14 ++--- .../Pci/ArmPciConfigSpaceParser.h | 4 +- DynamicTablesPkg/Readme.md | 24 ++++----- 8 files changed, 96 insertions(+), 97 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index c5639e0508..429505b650 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -30,6 +30,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjCmRef, ///< 7 - CM Object Reference EArchCommonObjPciConfigSpaceInfo, ///< 8 - PCI Configuration Space Info EArchCommonObjPciAddressMapInfo, ///< 9 - Pci Address Map Info + EArchCommonObjPciInterruptMapInfo, ///< 10 - Pci Interrupt Map Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -185,6 +186,43 @@ typedef struct CmArchCommonGenericInterrupt { UINT32 Flags; } CM_ARCH_COMMON_GENERIC_INTERRUPT; +/** A structure that describes a PCI Interrupt Map. + + The legacy PCI interrupts used by PCI devices are described by this object. + + Cf Devicetree Specification - Release v0.3 + s2.4.3 "Interrupt Nexus Properties" + + ID: EArchCommonObjPciInterruptMapInfo +*/ +typedef struct CmArchCommonPciInterruptMapInfo { + /// Pci Bus. + /// Value on 8 bits (max 255). + UINT8 PciBus; + + /// Pci Device. + /// Value on 5 bits (max 31). + UINT8 PciDevice; + + /** PCI interrupt + + ACPI bindings are used: + Cf. ACPI 6.4, s6.2.13 _PRT (PCI Routing Table): + "0-INTA, 1-INTB, 2-INTC, 3-INTD" + + Device-tree bindings are shifted by 1: + "INTA=1, INTB=2, INTC=3, INTD=4" + */ + UINT8 PciInterrupt; + + /** Interrupt controller interrupt. + + Cf Devicetree Specification - Release v0.3 + s2.4.3 "Interrupt Nexus Properties": "parent interrupt specifier" + */ + CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; +} CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 60ec34a7b3..5d7c84f51d 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -56,18 +56,17 @@ typedef enum ArmObjectID { EArmObjGenericInitiatorAffinityInfo, ///< 25 - Generic Initiator Affinity EArmObjCmn600Info, ///< 26 - CMN-600 Info EArmObjLpiInfo, ///< 27 - Lpi Info - EArmObjPciInterruptMapInfo, ///< 28 - Pci Interrupt Map Info - EArmObjRmr, ///< 29 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 30 - Memory Range Descriptor - EArmObjCpcInfo, ///< 31 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 32 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 33 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 34 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 35 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 36 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 37 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 38 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 39 - P-State Dependency (PSD) Info + EArmObjRmr, ///< 28 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 29 - Memory Range Descriptor + EArmObjCpcInfo, ///< 30 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 31 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 32 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 33 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 34 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 35 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 36 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 37 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 38 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -885,43 +884,6 @@ typedef struct CmArmLpiInfo { CHAR8 StateName[16]; } CM_ARM_LPI_INFO; -/** A structure that describes a PCI Interrupt Map. - - The legacy PCI interrupts used by PCI devices are described by this object. - - Cf Devicetree Specification - Release v0.3 - s2.4.3 "Interrupt Nexus Properties" - - ID: EArmObjPciInterruptMapInfo -*/ -typedef struct CmArmPciInterruptMapInfo { - /// Pci Bus. - /// Value on 8 bits (max 255). - UINT8 PciBus; - - /// Pci Device. - /// Value on 5 bits (max 31). - UINT8 PciDevice; - - /** PCI interrupt - - ACPI bindings are used: - Cf. ACPI 6.4, s6.2.13 _PRT (PCI Routing Table): - "0-INTA, 1-INTB, 2-INTC, 3-INTD" - - Device-tree bindings are shifted by 1: - "INTA=1, INTB=2, INTC=3, INTD=4" - */ - UINT8 PciInterrupt; - - /** Interrupt controller interrupt. - - Cf Devicetree Specification - Release v0.3 - s2.4.3 "Interrupt Nexus Properties": "parent interrupt specifier" - */ - CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; -} CM_ARM_PCI_INTERRUPT_MAP_INFO; - /** A structure that describes the RMR node for the Platform. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c index e86f1cb529..2b488016e5 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c @@ -45,7 +45,7 @@ Requirements: - EArchCommonObjCmRef - EArchCommonObjPciConfigSpaceInfo - EArchCommonObjPciAddressMapInfo - - EArmObjPciInterruptMapInfo + - EArchCommonObjPciInterruptMapInfo */ /** This macro expands to a function that retrieves the cross-CM-object- @@ -79,9 +79,9 @@ GET_OBJECT_LIST ( Interrupt Mapping Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPciInterruptMapInfo, - CM_ARM_PCI_INTERRUPT_MAP_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPciInterruptMapInfo, + CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO ); /** Initialize the MappingTable. @@ -310,12 +310,12 @@ GeneratePrt ( IN OUT AML_OBJECT_NODE_HANDLE PciNode ) { - EFI_STATUS Status; - INT32 Index; - AML_OBJECT_NODE_HANDLE PrtNode; - CM_ARCH_COMMON_OBJ_REF *RefInfo; - UINT32 RefCount; - CM_ARM_PCI_INTERRUPT_MAP_INFO *IrqMapInfo; + EFI_STATUS Status; + INT32 Index; + AML_OBJECT_NODE_HANDLE PrtNode; + CM_ARCH_COMMON_OBJ_REF *RefInfo; + UINT32 RefCount; + CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *IrqMapInfo; ASSERT (Generator != NULL); ASSERT (CfgMgrProtocol != NULL); @@ -325,7 +325,7 @@ GeneratePrt ( PrtNode = NULL; // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the - // CM_ARM_PCI_INTERRUPT_MAP_INFO objects. + // CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO objects. Status = GetEArchCommonObjCmRef ( CfgMgrProtocol, PciInfo->InterruptMapToken, @@ -352,8 +352,8 @@ GeneratePrt ( } for (Index = 0; Index < RefCount; Index++) { - // Get CM_ARM_PCI_INTERRUPT_MAP_INFO structures one by one. - Status = GetEArmObjPciInterruptMapInfo ( + // Get CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO structures one by one. + Status = GetEArchCommonObjPciInterruptMapInfo ( CfgMgrProtocol, RefInfo[Index].ReferenceToken, &IrqMapInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 0e12b0f8b1..4d660265cf 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -171,18 +171,17 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 25 - Generic Initiator Affinity NULL, ///< 26 - CMN-600 Info NULL, ///< 27 - Lpi Info - NULL, ///< 28 - Pci Interrupt Map Info - NULL, ///< 29 - Reserved Memory Range Node - NULL, ///< 30 - Memory Range Descriptor - NULL, ///< 31 - Continuous Performance Control Info - NULL, ///< 32 - Pcc Subspace Type 0 Info + NULL, ///< 28 - Reserved Memory Range Node + NULL, ///< 29 - Memory Range Descriptor + NULL, ///< 30 - Continuous Performance Control Info + NULL, ///< 31 - Pcc Subspace Type 0 Info + NULL, ///< 32 - Pcc Subspace Type 2 Info NULL, ///< 33 - Pcc Subspace Type 2 Info - NULL, ///< 34 - Pcc Subspace Type 2 Info - NULL, ///< 35 - Pcc Subspace Type 3 Info - NULL, ///< 36 - Pcc Subspace Type 4 Info - NULL, ///< 37 - Pcc Subspace Type 5 Info - NULL, ///< 38 - Embedded Trace Extension/Module Info - NULL ///< 39 - P-State Dependency (PSD) Info + NULL, ///< 34 - Pcc Subspace Type 3 Info + NULL, ///< 35 - Pcc Subspace Type 4 Info + NULL, ///< 36 - Pcc Subspace Type 5 Info + NULL, ///< 37 - Embedded Trace Extension/Module Info + NULL ///< 38 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 1fd1edb8eb..4ca35d65fc 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -449,9 +449,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPciAddressMapInfoParser[] = { { "AddressSize", 8, "0x%llx", NULL }, }; -/** A parser for EArmObjPciInterruptMapInfo. +/** A parser for EArchCommonObjPciInterruptMapInfo. */ -STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPciInterruptMapInfoParser[] = { { "PciBus", 1, "0x%x", NULL }, { "PciDevice", 1, "0x%x", NULL }, { "PciInterrupt", 1, "0x%x", NULL }, @@ -680,6 +680,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -714,7 +715,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPciInterruptMapInfo, CmPciInterruptMapInfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCpcInfo, CmArmCpcInfoParser), diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c index b20d265a83..b064e62c17 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c @@ -311,8 +311,8 @@ ParseIrqMap ( UINT32 PciAddressAttr; - CM_ARM_PCI_INTERRUPT_MAP_INFO *PciInterruptMapInfo; - UINT32 BufferSize; + CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *PciInterruptMapInfo; + UINT32 BufferSize; Data = fdt_getprop (Fdt, HostPciNode, "interrupt-map", &DataSize); if ((Data == NULL) || (DataSize <= 0)) { @@ -455,9 +455,9 @@ ParseIrqMap ( } // for PciInfo->Mapping[PciMappingTableInterrupt].ObjectId = - CREATE_CM_ARM_OBJECT_ID (EArmObjPciInterruptMapInfo); + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciInterruptMapInfo); PciInfo->Mapping[PciMappingTableInterrupt].Size = - sizeof (CM_ARM_PCI_INTERRUPT_MAP_INFO) * IrqMapCount; + sizeof (CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO) * IrqMapCount; PciInfo->Mapping[PciMappingTableInterrupt].Data = PciInterruptMapInfo; PciInfo->Mapping[PciMappingTableInterrupt].Count = IrqMapCount; @@ -581,7 +581,7 @@ PciNodeParser ( CmObj of the following types are concerned: - EArchCommonObjPciConfigSpaceInfo - EArchCommonObjPciAddressMapInfo - - EArmObjPciInterruptMapInfo + - EArchCommonObjPciInterruptMapInfo @param [in] FdtParserHandle A handle to the parser instance. @param [in] PciTableInfo PCI_PARSER_TABLE structure containing the @@ -701,12 +701,12 @@ FreeParserTable ( UINT64 AddressSize; // {Populated} } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; - typedef struct CmArmPciInterruptMapInfo { + typedef struct CmArchCommonPciInterruptMapInfo { UINT8 PciBus; // {Populated} UINT8 PciDevice; // {Populated} UINT8 PciInterrupt; // {Populated} CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} - } CM_ARM_PCI_INTERRUPT_MAP_INFO; + } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; A parser parses a Device Tree to populate a specific CmObj type. None, one or many CmObj can be created by the parser. diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h index 33457cd6e9..e680138385 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h @@ -109,12 +109,12 @@ typedef struct PciParserTable { UINT64 AddressSize; // {Populated} } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; - typedef struct CmArmPciInterruptMapInfo { + typedef struct CmArchCommonPciInterruptMapInfo { UINT8 PciBus; // {Populated} UINT8 PciDevice; // {Populated} UINT8 PciInterrupt; // {Populated} CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} - } CM_ARM_PCI_INTERRUPT_MAP_INFO; + } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; A parser parses a Device Tree to populate a specific CmObj type. None, one or many CmObj can be created by the parser. diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 0caae7dc45..558cf69afa 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -468,18 +468,17 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 25 | Generic Initiator Affinity Info | Move to Arch Common NS | | 26 | CMN 600 Info | | | 27 | Low Power Idle State Info | Move to Arch Common NS | -| 28 | PCI Interrupt Map Info | Move to Arch Common NS | -| 29 | Reserved Memory Range Node | | -| 30 | Memory Range Descriptor | | -| 31 | Continuous Performance Control Info | Move to Arch Common NS | -| 32 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 33 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 34 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 35 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 36 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 37 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 38 | Embedded Trace Extension/Module Info | | -| 39 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 28 | Reserved Memory Range Node | | +| 29 | Memory Range Descriptor | | +| 30 | Continuous Performance Control Info | Move to Arch Common NS | +| 31 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 32 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 33 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 34 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 35 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 36 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 37 | Embedded Trace Extension/Module Info | | +| 38 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 7 | CM Object Reference | | | 8 | PCI Configuration Space Info | | | 9 | PCI Address Map Info | | +| 10 | PCI Interrupt Map Info | | | `*` | All other values are reserved. | | -- cgit From 71b0e9decb9a8e8620e086465ca449c033438818 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 11:00:57 +0000 Subject: DynamicTablesPkg: Move Mem Affinity Info to Arch Common Move the Memory Affinity Info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SRAT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 19 ++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 51 +++++++--------------- .../Acpi/Arm/AcpiSratLibArm/SratGenerator.c | 14 +++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 31 +++++++------ .../ConfigurationManagerObjectParser.c | 6 +-- DynamicTablesPkg/Readme.md | 34 +++++++-------- 6 files changed, 77 insertions(+), 78 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 429505b650..86d751bdfa 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -31,6 +31,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjPciConfigSpaceInfo, ///< 8 - PCI Configuration Space Info EArchCommonObjPciAddressMapInfo, ///< 9 - Pci Address Map Info EArchCommonObjPciInterruptMapInfo, ///< 10 - Pci Interrupt Map Info + EArchCommonObjMemoryAffinityInfo, ///< 11 - Memory Affinity Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -223,6 +224,24 @@ typedef struct CmArchCommonPciInterruptMapInfo { CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; +/** A structure that describes the Memory Affinity Structure (Type 1) in SRAT + + ID: EArchCommonObjMemoryAffinityInfo +*/ +typedef struct CmArchCommonMemoryAffinityInfo { + /// The proximity domain to which the "range of memory" belongs. + UINT32 ProximityDomain; + + /// Base Address + UINT64 BaseAddress; + + /// Length + UINT64 Length; + + /// Flags + UINT32 Flags; +} CM_ARCH_COMMON_MEMORY_AFFINITY_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 5d7c84f51d..7905152114 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -50,23 +50,22 @@ typedef enum ArmObjectID { EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info EArmObjCacheInfo, ///< 21 - Cache Info - EArmObjMemoryAffinityInfo, ///< 22 - Memory Affinity Info - EArmObjDeviceHandleAcpi, ///< 23 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 24 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 25 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 26 - CMN-600 Info - EArmObjLpiInfo, ///< 27 - Lpi Info - EArmObjRmr, ///< 28 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 29 - Memory Range Descriptor - EArmObjCpcInfo, ///< 30 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 31 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 32 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 33 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 34 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 35 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 36 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 37 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 38 - P-State Dependency (PSD) Info + EArmObjDeviceHandleAcpi, ///< 22 - Device Handle Acpi + EArmObjDeviceHandlePci, ///< 23 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 24 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 25 - CMN-600 Info + EArmObjLpiInfo, ///< 26 - Lpi Info + EArmObjRmr, ///< 27 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 28 - Memory Range Descriptor + EArmObjCpcInfo, ///< 29 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 30 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 31 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 32 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 33 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 34 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 35 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 36 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 37 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -721,24 +720,6 @@ typedef struct CmArmCacheInfo { UINT32 CacheId; } CM_ARM_CACHE_INFO; -/** A structure that describes the Memory Affinity Structure (Type 1) in SRAT - - ID: EArmObjMemoryAffinityInfo -*/ -typedef struct CmArmMemoryAffinityInfo { - /// The proximity domain to which the "range of memory" belongs. - UINT32 ProximityDomain; - - /// Base Address - UINT64 BaseAddress; - - /// Length - UINT64 Length; - - /// Flags - UINT32 Flags; -} CM_ARM_MEMORY_AFFINITY_INFO; - /** A structure that describes the ACPI Device Handle (Type 0) in the Generic Initiator Affinity structure in SRAT diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c index 431995ed38..3ba2448f23 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c @@ -32,7 +32,7 @@ The following Configuration Manager Object(s) are used by this Generator: - EArmObjGicCInfo (REQUIRED) - EArmObjGicItsInfo (OPTIONAL) - - EArmObjMemoryAffinityInfo (OPTIONAL) + - EArchCommonObjMemoryAffinityInfo (OPTIONAL) - EArmObjGenericInitiatorAffinityInfo (OPTIONAL) - EArmObjDeviceHandleAcpi (OPTIONAL) - EArmObjDeviceHandlePci (OPTIONAL) @@ -62,9 +62,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjMemoryAffinityInfo, - CM_ARM_MEMORY_AFFINITY_INFO + EObjNameSpaceArchCommon, + EArchCommonObjMemoryAffinityInfo, + CM_ARCH_COMMON_MEMORY_AFFINITY_INFO ); /** @@ -235,7 +235,7 @@ AddMemoryAffinity ( IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, IN CONST UINT32 MemAffOffset, - IN CONST CM_ARM_MEMORY_AFFINITY_INFO *MemAffInfo, + IN CONST CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo, IN UINT32 MemAffCount ) { @@ -467,7 +467,7 @@ BuildSratTable ( CM_ARM_GICC_INFO *GicCInfo; CM_ARM_GIC_ITS_INFO *GicItsInfo; - CM_ARM_MEMORY_AFFINITY_INFO *MemAffInfo; + CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo; CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo; EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *Srat; @@ -537,7 +537,7 @@ BuildSratTable ( goto error_handler; } - Status = GetEArmObjMemoryAffinityInfo ( + Status = GetEArchCommonObjMemoryAffinityInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &MemAffInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 4d660265cf..654686a012 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -165,23 +165,22 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 19 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 21 - Cache Info - NULL, ///< 22 - Memory Affinity Info - NULL, ///< 23 - Device Handle Acpi - NULL, ///< 24 - Device Handle Pci - NULL, ///< 25 - Generic Initiator Affinity - NULL, ///< 26 - CMN-600 Info - NULL, ///< 27 - Lpi Info - NULL, ///< 28 - Reserved Memory Range Node - NULL, ///< 29 - Memory Range Descriptor - NULL, ///< 30 - Continuous Performance Control Info - NULL, ///< 31 - Pcc Subspace Type 0 Info + NULL, ///< 22 - Device Handle Acpi + NULL, ///< 23 - Device Handle Pci + NULL, ///< 24 - Generic Initiator Affinity + NULL, ///< 25 - CMN-600 Info + NULL, ///< 26 - Lpi Info + NULL, ///< 27 - Reserved Memory Range Node + NULL, ///< 28 - Memory Range Descriptor + NULL, ///< 29 - Continuous Performance Control Info + NULL, ///< 30 - Pcc Subspace Type 0 Info + NULL, ///< 31 - Pcc Subspace Type 2 Info NULL, ///< 32 - Pcc Subspace Type 2 Info - NULL, ///< 33 - Pcc Subspace Type 2 Info - NULL, ///< 34 - Pcc Subspace Type 3 Info - NULL, ///< 35 - Pcc Subspace Type 4 Info - NULL, ///< 36 - Pcc Subspace Type 5 Info - NULL, ///< 37 - Embedded Trace Extension/Module Info - NULL ///< 38 - P-State Dependency (PSD) Info + NULL, ///< 33 - Pcc Subspace Type 3 Info + NULL, ///< 34 - Pcc Subspace Type 4 Info + NULL, ///< 35 - Pcc Subspace Type 5 Info + NULL, ///< 36 - Embedded Trace Extension/Module Info + NULL ///< 37 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 4ca35d65fc..b2fe74cd4f 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -356,9 +356,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonObjRefParser[] = { { "ReferenceToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL } }; -/** A parser for EArmObjMemoryAffinityInfo. +/** A parser for EArchCommonObjMemoryAffinityInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmMemoryAffinityInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonMemoryAffinityInfoParser[] = { { "ProximityDomain", 4, "0x%x", NULL }, { "BaseAddress", 8, "0x%llx", NULL }, { "Length", 8, "0x%llx", NULL }, @@ -681,6 +681,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryAffinityInfo, CmArchCommonMemoryAffinityInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -709,7 +710,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjMemoryAffinityInfo, CmArmMemoryAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandleAcpi, CmArmDeviceHandleAcpiParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandlePci, CmArmDeviceHandlePciParser), CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 558cf69afa..55311fd4ce 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -462,23 +462,22 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 19 | SMMU Interrupt Array | | | 20 | Processor Hierarchy Info | Move to Arch Common NS | | 21 | Cache Info | Move to Arch Common NS | -| 22 | Memory Affinity Info | Move to Arch Common NS | -| 23 | Device Handle Acpi | Move to Arch Common NS | -| 24 | Device Handle PCI | Move to Arch Common NS | -| 25 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 26 | CMN 600 Info | | -| 27 | Low Power Idle State Info | Move to Arch Common NS | -| 28 | Reserved Memory Range Node | | -| 29 | Memory Range Descriptor | | -| 30 | Continuous Performance Control Info | Move to Arch Common NS | -| 31 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 32 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 33 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 34 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 35 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 36 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 37 | Embedded Trace Extension/Module Info | | -| 38 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 22 | Device Handle Acpi | Move to Arch Common NS | +| 23 | Device Handle PCI | Move to Arch Common NS | +| 24 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 25 | CMN 600 Info | | +| 26 | Low Power Idle State Info | Move to Arch Common NS | +| 27 | Reserved Memory Range Node | | +| 28 | Memory Range Descriptor | | +| 29 | Continuous Performance Control Info | Move to Arch Common NS | +| 30 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 31 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 32 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 33 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 34 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 35 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 36 | Embedded Trace Extension/Module Info | | +| 37 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 8 | PCI Configuration Space Info | | | 9 | PCI Address Map Info | | | 10 | PCI Interrupt Map Info | | +| 11 | Memory Affinity Info | | | `*` | All other values are reserved. | | -- cgit From 0ca10ddc0f94060ec8efcf14464336ba6946aafe Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 11:08:56 +0000 Subject: DynamicTablesPkg: Move ACPI device Handle object to Arch Common Move the ACPI device Handle object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SRAT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 14 +++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 44 ++++++++-------------- .../Acpi/Arm/AcpiSratLibArm/SratGenerator.c | 12 +++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 29 +++++++------- .../ConfigurationManagerObjectParser.c | 6 +-- DynamicTablesPkg/Readme.md | 32 ++++++++-------- 6 files changed, 68 insertions(+), 69 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 86d751bdfa..0b450e8f99 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -32,6 +32,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjPciAddressMapInfo, ///< 9 - Pci Address Map Info EArchCommonObjPciInterruptMapInfo, ///< 10 - Pci Interrupt Map Info EArchCommonObjMemoryAffinityInfo, ///< 11 - Memory Affinity Info + EArchCommonObjDeviceHandleAcpi, ///< 12 - Device Handle Acpi EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -242,6 +243,19 @@ typedef struct CmArchCommonMemoryAffinityInfo { UINT32 Flags; } CM_ARCH_COMMON_MEMORY_AFFINITY_INFO; +/** A structure that describes the ACPI Device Handle (Type 0) in the + Generic Initiator Affinity structure in SRAT + + ID: EArchCommonObjDeviceHandleAcpi +*/ +typedef struct CmArchCommonDeviceHandleAcpi { + /// Hardware ID + UINT64 Hid; + + /// Unique Id + UINT32 Uid; +} CM_ARCH_COMMON_DEVICE_HANDLE_ACPI; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 7905152114..64c5f26772 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -50,22 +50,21 @@ typedef enum ArmObjectID { EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info EArmObjCacheInfo, ///< 21 - Cache Info - EArmObjDeviceHandleAcpi, ///< 22 - Device Handle Acpi - EArmObjDeviceHandlePci, ///< 23 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 24 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 25 - CMN-600 Info - EArmObjLpiInfo, ///< 26 - Lpi Info - EArmObjRmr, ///< 27 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 28 - Memory Range Descriptor - EArmObjCpcInfo, ///< 29 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 30 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 31 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 32 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 33 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 34 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 35 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 36 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 37 - P-State Dependency (PSD) Info + EArmObjDeviceHandlePci, ///< 22 - Device Handle Pci + EArmObjGenericInitiatorAffinityInfo, ///< 23 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 24 - CMN-600 Info + EArmObjLpiInfo, ///< 25 - Lpi Info + EArmObjRmr, ///< 26 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 27 - Memory Range Descriptor + EArmObjCpcInfo, ///< 28 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 29 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 30 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 31 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 32 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 33 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 34 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 35 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 36 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -720,19 +719,6 @@ typedef struct CmArmCacheInfo { UINT32 CacheId; } CM_ARM_CACHE_INFO; -/** A structure that describes the ACPI Device Handle (Type 0) in the - Generic Initiator Affinity structure in SRAT - - ID: EArmObjDeviceHandleAcpi -*/ -typedef struct CmArmDeviceHandleAcpi { - /// Hardware ID - UINT64 Hid; - - /// Unique Id - UINT32 Uid; -} CM_ARM_DEVICE_HANDLE_ACPI; - /** A structure that describes the PCI Device Handle (Type 1) in the Generic Initiator Affinity structure in SRAT diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c index 3ba2448f23..c65a28cd14 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c @@ -34,7 +34,7 @@ - EArmObjGicItsInfo (OPTIONAL) - EArchCommonObjMemoryAffinityInfo (OPTIONAL) - EArmObjGenericInitiatorAffinityInfo (OPTIONAL) - - EArmObjDeviceHandleAcpi (OPTIONAL) + - EArchCommonObjDeviceHandleAcpi (OPTIONAL) - EArmObjDeviceHandlePci (OPTIONAL) */ @@ -82,9 +82,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjDeviceHandleAcpi, - CM_ARM_DEVICE_HANDLE_ACPI + EObjNameSpaceArchCommon, + EArchCommonObjDeviceHandleAcpi, + CM_ARCH_COMMON_DEVICE_HANDLE_ACPI ); /** @@ -301,7 +301,7 @@ AddGenericInitiatorAffinity ( { EFI_STATUS Status; EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *GenInitAff; - CM_ARM_DEVICE_HANDLE_ACPI *DeviceHandleAcpi; + CM_ARCH_COMMON_DEVICE_HANDLE_ACPI *DeviceHandleAcpi; CM_ARM_DEVICE_HANDLE_PCI *DeviceHandlePci; UINT32 DeviceHandleCount; @@ -331,7 +331,7 @@ AddGenericInitiatorAffinity ( } if (GenInitAffInfo->DeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) { - Status = GetEArmObjDeviceHandleAcpi ( + Status = GetEArchCommonObjDeviceHandleAcpi ( CfgMgrProtocol, GenInitAffInfo->DeviceHandleToken, &DeviceHandleAcpi, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 654686a012..43aae42381 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -165,22 +165,21 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 19 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 21 - Cache Info - NULL, ///< 22 - Device Handle Acpi - NULL, ///< 23 - Device Handle Pci - NULL, ///< 24 - Generic Initiator Affinity - NULL, ///< 25 - CMN-600 Info - NULL, ///< 26 - Lpi Info - NULL, ///< 27 - Reserved Memory Range Node - NULL, ///< 28 - Memory Range Descriptor - NULL, ///< 29 - Continuous Performance Control Info - NULL, ///< 30 - Pcc Subspace Type 0 Info + NULL, ///< 22 - Device Handle Pci + NULL, ///< 23 - Generic Initiator Affinity + NULL, ///< 24 - CMN-600 Info + NULL, ///< 25 - Lpi Info + NULL, ///< 26 - Reserved Memory Range Node + NULL, ///< 27 - Memory Range Descriptor + NULL, ///< 28 - Continuous Performance Control Info + NULL, ///< 29 - Pcc Subspace Type 0 Info + NULL, ///< 30 - Pcc Subspace Type 2 Info NULL, ///< 31 - Pcc Subspace Type 2 Info - NULL, ///< 32 - Pcc Subspace Type 2 Info - NULL, ///< 33 - Pcc Subspace Type 3 Info - NULL, ///< 34 - Pcc Subspace Type 4 Info - NULL, ///< 35 - Pcc Subspace Type 5 Info - NULL, ///< 36 - Embedded Trace Extension/Module Info - NULL ///< 37 - P-State Dependency (PSD) Info + NULL, ///< 32 - Pcc Subspace Type 3 Info + NULL, ///< 33 - Pcc Subspace Type 4 Info + NULL, ///< 34 - Pcc Subspace Type 5 Info + NULL, ///< 35 - Embedded Trace Extension/Module Info + NULL ///< 36 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index b2fe74cd4f..9326ea6393 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -365,9 +365,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonMemoryAffinityInfoParser[] = { { "Flags", 4, "0x%x", NULL } }; -/** A parser for EArmObjDeviceHandleAcpi. +/** A parser for EArchCommonObjDeviceHandleAcpi. */ -STATIC CONST CM_OBJ_PARSER CmArmDeviceHandleAcpiParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonDeviceHandleAcpiParser[] = { { "Hid", 8, "0x%llx", NULL }, { "Uid", 4, "0x%x", NULL } }; @@ -682,6 +682,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryAffinityInfo, CmArchCommonMemoryAffinityInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandleAcpi, CmArchCommonDeviceHandleAcpiParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -710,7 +711,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjDeviceHandleAcpi, CmArmDeviceHandleAcpiParser), CM_PARSER_ADD_OBJECT (EArmObjDeviceHandlePci, CmArmDeviceHandlePciParser), CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 55311fd4ce..f82c37f4af 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -462,22 +462,21 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 19 | SMMU Interrupt Array | | | 20 | Processor Hierarchy Info | Move to Arch Common NS | | 21 | Cache Info | Move to Arch Common NS | -| 22 | Device Handle Acpi | Move to Arch Common NS | -| 23 | Device Handle PCI | Move to Arch Common NS | -| 24 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 25 | CMN 600 Info | | -| 26 | Low Power Idle State Info | Move to Arch Common NS | -| 27 | Reserved Memory Range Node | | -| 28 | Memory Range Descriptor | | -| 29 | Continuous Performance Control Info | Move to Arch Common NS | -| 30 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 31 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 32 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 33 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 34 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 35 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 36 | Embedded Trace Extension/Module Info | | -| 37 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 22 | Device Handle PCI | Move to Arch Common NS | +| 23 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 24 | CMN 600 Info | | +| 25 | Low Power Idle State Info | Move to Arch Common NS | +| 26 | Reserved Memory Range Node | | +| 27 | Memory Range Descriptor | | +| 28 | Continuous Performance Control Info | Move to Arch Common NS | +| 29 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 30 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 31 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 32 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 33 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 34 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 35 | Embedded Trace Extension/Module Info | | +| 36 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 9 | PCI Address Map Info | | | 10 | PCI Interrupt Map Info | | | 11 | Memory Affinity Info | | +| 12 | Device Handle Acpi | | | `*` | All other values are reserved. | | -- cgit From 3a644f4a43f768b571e9aac0706fd03e3e738110 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 11:14:03 +0000 Subject: DynamicTablesPkg: Move PCI device Handle object to Arch Common Move the PCI device Handle object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SRAT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 20 +++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 48 +++++++--------------- .../Acpi/Arm/AcpiSratLibArm/SratGenerator.c | 14 +++---- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 27 ++++++------ .../ConfigurationManagerObjectParser.c | 6 +-- DynamicTablesPkg/Readme.md | 30 +++++++------- 6 files changed, 72 insertions(+), 73 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 0b450e8f99..230d0bc334 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -33,6 +33,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjPciInterruptMapInfo, ///< 10 - Pci Interrupt Map Info EArchCommonObjMemoryAffinityInfo, ///< 11 - Memory Affinity Info EArchCommonObjDeviceHandleAcpi, ///< 12 - Device Handle Acpi + EArchCommonObjDeviceHandlePci, ///< 13 - Device Handle Pci EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -256,6 +257,25 @@ typedef struct CmArchCommonDeviceHandleAcpi { UINT32 Uid; } CM_ARCH_COMMON_DEVICE_HANDLE_ACPI; +/** A structure that describes the PCI Device Handle (Type 1) in the + Generic Initiator Affinity structure in SRAT + + ID: EArchCommonObjDeviceHandlePci +*/ +typedef struct CmArchCommonDeviceHandlePci { + /// PCI Segment Number + UINT16 SegmentNumber; + + /// PCI Bus Number - Max 256 busses (Bits 15:8 of BDF) + UINT8 BusNumber; + + /// PCI Device Number - Max 32 devices (Bits 7:3 of BDF) + UINT8 DeviceNumber; + + /// PCI Function Number - Max 8 functions (Bits 2:0 of BDF) + UINT8 FunctionNumber; +} CM_ARCH_COMMON_DEVICE_HANDLE_PCI; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 64c5f26772..05691e6fcf 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -50,21 +50,20 @@ typedef enum ArmObjectID { EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info EArmObjCacheInfo, ///< 21 - Cache Info - EArmObjDeviceHandlePci, ///< 22 - Device Handle Pci - EArmObjGenericInitiatorAffinityInfo, ///< 23 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 24 - CMN-600 Info - EArmObjLpiInfo, ///< 25 - Lpi Info - EArmObjRmr, ///< 26 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 27 - Memory Range Descriptor - EArmObjCpcInfo, ///< 28 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 29 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 30 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 31 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 32 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 33 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 34 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 35 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 36 - P-State Dependency (PSD) Info + EArmObjGenericInitiatorAffinityInfo, ///< 22 - Generic Initiator Affinity + EArmObjCmn600Info, ///< 23 - CMN-600 Info + EArmObjLpiInfo, ///< 24 - Lpi Info + EArmObjRmr, ///< 25 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 26 - Memory Range Descriptor + EArmObjCpcInfo, ///< 27 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 28 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 29 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 30 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 31 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 32 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 33 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 34 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 35 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -719,25 +718,6 @@ typedef struct CmArmCacheInfo { UINT32 CacheId; } CM_ARM_CACHE_INFO; -/** A structure that describes the PCI Device Handle (Type 1) in the - Generic Initiator Affinity structure in SRAT - - ID: EArmObjDeviceHandlePci -*/ -typedef struct CmArmDeviceHandlePci { - /// PCI Segment Number - UINT16 SegmentNumber; - - /// PCI Bus Number - Max 256 busses (Bits 15:8 of BDF) - UINT8 BusNumber; - - /// PCI Device Number - Max 32 devices (Bits 7:3 of BDF) - UINT8 DeviceNumber; - - /// PCI Function Number - Max 8 functions (Bits 2:0 of BDF) - UINT8 FunctionNumber; -} CM_ARM_DEVICE_HANDLE_PCI; - /** A structure that describes the Generic Initiator Affinity structure in SRAT ID: EArmObjGenericInitiatorAffinityInfo diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c index c65a28cd14..66fefc80f5 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c @@ -35,7 +35,7 @@ - EArchCommonObjMemoryAffinityInfo (OPTIONAL) - EArmObjGenericInitiatorAffinityInfo (OPTIONAL) - EArchCommonObjDeviceHandleAcpi (OPTIONAL) - - EArmObjDeviceHandlePci (OPTIONAL) + - EArchCommonObjDeviceHandlePci (OPTIONAL) */ /** This macro expands to a function that retrieves the GIC @@ -92,9 +92,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjDeviceHandlePci, - CM_ARM_DEVICE_HANDLE_PCI + EObjNameSpaceArchCommon, + EArchCommonObjDeviceHandlePci, + CM_ARCH_COMMON_DEVICE_HANDLE_PCI ); /** Return the PCI Device information in BDF format @@ -110,7 +110,7 @@ GET_OBJECT_LIST ( STATIC UINT16 GetBdf ( - IN CONST CM_ARM_DEVICE_HANDLE_PCI *DeviceHandlePci + IN CONST CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci ) { UINT16 Bdf; @@ -302,7 +302,7 @@ AddGenericInitiatorAffinity ( EFI_STATUS Status; EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *GenInitAff; CM_ARCH_COMMON_DEVICE_HANDLE_ACPI *DeviceHandleAcpi; - CM_ARM_DEVICE_HANDLE_PCI *DeviceHandlePci; + CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci; UINT32 DeviceHandleCount; ASSERT (Srat != NULL); @@ -362,7 +362,7 @@ AddGenericInitiatorAffinity ( } else if (GenInitAffInfo->DeviceHandleType == EFI_ACPI_6_3_PCI_DEVICE_HANDLE) { - Status = GetEArmObjDeviceHandlePci ( + Status = GetEArchCommonObjDeviceHandlePci ( CfgMgrProtocol, GenInitAffInfo->DeviceHandleToken, &DeviceHandlePci, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 43aae42381..d5ee9317e6 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -165,21 +165,20 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 19 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 21 - Cache Info - NULL, ///< 22 - Device Handle Pci - NULL, ///< 23 - Generic Initiator Affinity - NULL, ///< 24 - CMN-600 Info - NULL, ///< 25 - Lpi Info - NULL, ///< 26 - Reserved Memory Range Node - NULL, ///< 27 - Memory Range Descriptor - NULL, ///< 28 - Continuous Performance Control Info - NULL, ///< 29 - Pcc Subspace Type 0 Info + NULL, ///< 22 - Generic Initiator Affinity + NULL, ///< 23 - CMN-600 Info + NULL, ///< 24 - Lpi Info + NULL, ///< 25 - Reserved Memory Range Node + NULL, ///< 26 - Memory Range Descriptor + NULL, ///< 27 - Continuous Performance Control Info + NULL, ///< 28 - Pcc Subspace Type 0 Info + NULL, ///< 29 - Pcc Subspace Type 2 Info NULL, ///< 30 - Pcc Subspace Type 2 Info - NULL, ///< 31 - Pcc Subspace Type 2 Info - NULL, ///< 32 - Pcc Subspace Type 3 Info - NULL, ///< 33 - Pcc Subspace Type 4 Info - NULL, ///< 34 - Pcc Subspace Type 5 Info - NULL, ///< 35 - Embedded Trace Extension/Module Info - NULL ///< 36 - P-State Dependency (PSD) Info + NULL, ///< 31 - Pcc Subspace Type 3 Info + NULL, ///< 32 - Pcc Subspace Type 4 Info + NULL, ///< 33 - Pcc Subspace Type 5 Info + NULL, ///< 34 - Embedded Trace Extension/Module Info + NULL ///< 35 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 9326ea6393..4b4965dfb0 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -372,9 +372,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonDeviceHandleAcpiParser[] = { { "Uid", 4, "0x%x", NULL } }; -/** A parser for EArmObjDeviceHandlePci. +/** A parser for EArchCommonObjDeviceHandlePci. */ -STATIC CONST CM_OBJ_PARSER CmArmDeviceHandlePciParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonDeviceHandlePciParser[] = { { "SegmentNumber", 2, "0x%x", NULL }, { "BusNumber", 1, "0x%x", NULL }, { "DeviceNumber", 1, "0x%x", NULL }, @@ -683,6 +683,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryAffinityInfo, CmArchCommonMemoryAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandleAcpi, CmArchCommonDeviceHandleAcpiParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandlePci, CmArchCommonDeviceHandlePciParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -711,7 +712,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjDeviceHandlePci, CmArmDeviceHandlePciParser), CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index f82c37f4af..9c7738983d 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -462,21 +462,20 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 19 | SMMU Interrupt Array | | | 20 | Processor Hierarchy Info | Move to Arch Common NS | | 21 | Cache Info | Move to Arch Common NS | -| 22 | Device Handle PCI | Move to Arch Common NS | -| 23 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 24 | CMN 600 Info | | -| 25 | Low Power Idle State Info | Move to Arch Common NS | -| 26 | Reserved Memory Range Node | | -| 27 | Memory Range Descriptor | | -| 28 | Continuous Performance Control Info | Move to Arch Common NS | -| 29 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 30 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 31 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 32 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 33 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 34 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 35 | Embedded Trace Extension/Module Info | | -| 36 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 22 | Generic Initiator Affinity Info | Move to Arch Common NS | +| 23 | CMN 600 Info | | +| 24 | Low Power Idle State Info | Move to Arch Common NS | +| 25 | Reserved Memory Range Node | | +| 26 | Memory Range Descriptor | | +| 27 | Continuous Performance Control Info | Move to Arch Common NS | +| 28 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 29 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 30 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 31 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 32 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 33 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 34 | Embedded Trace Extension/Module Info | | +| 35 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 10 | PCI Interrupt Map Info | | | 11 | Memory Affinity Info | | | 12 | Device Handle Acpi | | +| 13 | Device Handle PCI | | | `*` | All other values are reserved. | | -- cgit From 0b5abcb90e83044838e95ae73794ca4bfdfaa9a4 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 11:19:16 +0000 Subject: DynamicTablesPkg: Move Generic Initiator affinity info to Arch Common Move the Generic Initiator affinity info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SRAT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 19 ++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 45 +++------- .../Acpi/Arm/AcpiSratLibArm/SratGenerator.c | 20 ++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 25 +++--- .../ConfigurationManagerObjectParser.c | 100 ++++++++++----------- DynamicTablesPkg/Readme.md | 28 +++--- 6 files changed, 118 insertions(+), 119 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 230d0bc334..b70c327d46 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -34,6 +34,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjMemoryAffinityInfo, ///< 11 - Memory Affinity Info EArchCommonObjDeviceHandleAcpi, ///< 12 - Device Handle Acpi EArchCommonObjDeviceHandlePci, ///< 13 - Device Handle Pci + EArchCommonObjGenericInitiatorAffinityInfo, ///< 14 - Generic Initiator Affinity EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -276,6 +277,24 @@ typedef struct CmArchCommonDeviceHandlePci { UINT8 FunctionNumber; } CM_ARCH_COMMON_DEVICE_HANDLE_PCI; +/** A structure that describes the Generic Initiator Affinity structure in SRAT + + ID: EArchCommonObjGenericInitiatorAffinityInfo +*/ +typedef struct CmArchCommonGenericInitiatorAffinityInfo { + /// The proximity domain to which the generic initiator belongs. + UINT32 ProximityDomain; + + /// Flags + UINT32 Flags; + + /// Device Handle Type + UINT8 DeviceHandleType; + + /// Reference Token for the Device Handle + CM_OBJECT_TOKEN DeviceHandleToken; +} CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 05691e6fcf..ddf886a53d 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -50,20 +50,19 @@ typedef enum ArmObjectID { EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info EArmObjCacheInfo, ///< 21 - Cache Info - EArmObjGenericInitiatorAffinityInfo, ///< 22 - Generic Initiator Affinity - EArmObjCmn600Info, ///< 23 - CMN-600 Info - EArmObjLpiInfo, ///< 24 - Lpi Info - EArmObjRmr, ///< 25 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 26 - Memory Range Descriptor - EArmObjCpcInfo, ///< 27 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 28 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 29 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 30 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 31 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 32 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 33 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 34 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 35 - P-State Dependency (PSD) Info + EArmObjCmn600Info, ///< 22 - CMN-600 Info + EArmObjLpiInfo, ///< 23 - Lpi Info + EArmObjRmr, ///< 24 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 25 - Memory Range Descriptor + EArmObjCpcInfo, ///< 26 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 27 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 28 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 29 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 30 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 31 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 32 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 33 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 34 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -718,24 +717,6 @@ typedef struct CmArmCacheInfo { UINT32 CacheId; } CM_ARM_CACHE_INFO; -/** A structure that describes the Generic Initiator Affinity structure in SRAT - - ID: EArmObjGenericInitiatorAffinityInfo -*/ -typedef struct CmArmGenericInitiatorAffinityInfo { - /// The proximity domain to which the generic initiator belongs. - UINT32 ProximityDomain; - - /// Flags - UINT32 Flags; - - /// Device Handle Type - UINT8 DeviceHandleType; - - /// Reference Token for the Device Handle - CM_OBJECT_TOKEN DeviceHandleToken; -} CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO; - /** A structure that describes the CMN-600 hardware. ID: EArmObjCmn600Info diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c index 66fefc80f5..48c9970a71 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c @@ -33,7 +33,7 @@ - EArmObjGicCInfo (REQUIRED) - EArmObjGicItsInfo (OPTIONAL) - EArchCommonObjMemoryAffinityInfo (OPTIONAL) - - EArmObjGenericInitiatorAffinityInfo (OPTIONAL) + - EArchCommonObjGenericInitiatorAffinityInfo (OPTIONAL) - EArchCommonObjDeviceHandleAcpi (OPTIONAL) - EArchCommonObjDeviceHandlePci (OPTIONAL) */ @@ -72,9 +72,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGenericInitiatorAffinityInfo, - CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO + EObjNameSpaceArchCommon, + EArchCommonObjGenericInitiatorAffinityInfo, + CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO ); /** @@ -295,7 +295,7 @@ AddGenericInitiatorAffinity ( IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, IN CONST UINT32 GenInitAffOff, - IN CONST CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo, + IN CONST CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo, IN UINT32 GenInitAffCount ) { @@ -465,10 +465,10 @@ BuildSratTable ( UINT32 MemAffOffset; UINT32 GenInitiatorAffOffset; - CM_ARM_GICC_INFO *GicCInfo; - CM_ARM_GIC_ITS_INFO *GicItsInfo; - CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo; - CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo; + CM_ARM_GICC_INFO *GicCInfo; + CM_ARM_GIC_ITS_INFO *GicItsInfo; + CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo; + CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo; EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *Srat; @@ -552,7 +552,7 @@ BuildSratTable ( goto error_handler; } - Status = GetEArmObjGenericInitiatorAffinityInfo ( + Status = GetEArchCommonObjGenericInitiatorAffinityInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &GenInitiatorAffInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index d5ee9317e6..5f3e9f5fdc 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -165,20 +165,19 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 19 - SMMU Interrupt Array TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 21 - Cache Info - NULL, ///< 22 - Generic Initiator Affinity - NULL, ///< 23 - CMN-600 Info - NULL, ///< 24 - Lpi Info - NULL, ///< 25 - Reserved Memory Range Node - NULL, ///< 26 - Memory Range Descriptor - NULL, ///< 27 - Continuous Performance Control Info - NULL, ///< 28 - Pcc Subspace Type 0 Info + NULL, ///< 22 - CMN-600 Info + NULL, ///< 23 - Lpi Info + NULL, ///< 24 - Reserved Memory Range Node + NULL, ///< 25 - Memory Range Descriptor + NULL, ///< 26 - Continuous Performance Control Info + NULL, ///< 27 - Pcc Subspace Type 0 Info + NULL, ///< 28 - Pcc Subspace Type 2 Info NULL, ///< 29 - Pcc Subspace Type 2 Info - NULL, ///< 30 - Pcc Subspace Type 2 Info - NULL, ///< 31 - Pcc Subspace Type 3 Info - NULL, ///< 32 - Pcc Subspace Type 4 Info - NULL, ///< 33 - Pcc Subspace Type 5 Info - NULL, ///< 34 - Embedded Trace Extension/Module Info - NULL ///< 35 - P-State Dependency (PSD) Info + NULL, ///< 30 - Pcc Subspace Type 3 Info + NULL, ///< 31 - Pcc Subspace Type 4 Info + NULL, ///< 32 - Pcc Subspace Type 5 Info + NULL, ///< 33 - Embedded Trace Extension/Module Info + NULL ///< 34 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 4b4965dfb0..732454da8f 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -381,9 +381,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonDeviceHandlePciParser[] = { { "FunctionNumber", 1, "0x%x", NULL } }; -/** A parser for EArmObjGenericInitiatorAffinityInfo. +/** A parser for EArchCommonObjGenericInitiatorAffinityInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmGenericInitiatorAffinityInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonGenericInitiatorAffinityInfoParser[] = { { "ProximityDomain", 4, "0x%x", NULL }, { "Flags", 4, "0x%x", NULL }, { "DeviceHandleType", 1, "0x%x", NULL }, @@ -671,19 +671,20 @@ STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = { */ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjReserved), - CM_PARSER_ADD_OBJECT (EArchCommonObjPowerManagementProfileInfo,CmArchCommonPowerManagementProfileInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjSerialPortInfo, CmArchCommonSerialPortInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjConsolePortInfo, CmArchCommonSerialPortInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryAffinityInfo, CmArchCommonMemoryAffinityInfoParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandleAcpi, CmArchCommonDeviceHandleAcpiParser), - CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandlePci, CmArchCommonDeviceHandlePciParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPowerManagementProfileInfo, CmArchCommonPowerManagementProfileInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjSerialPortInfo, CmArchCommonSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjConsolePortInfo, CmArchCommonSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryAffinityInfo, CmArchCommonMemoryAffinityInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandleAcpi, CmArchCommonDeviceHandleAcpiParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandlePci, CmArchCommonDeviceHandlePciParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjGenericInitiatorAffinityInfo,CmArchCommonGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -691,41 +692,40 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { */ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved), - CM_PARSER_ADD_OBJECT (EArmObjBootArchInfo, CmArmBootArchInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGicCInfo, CmArmGicCInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGicDInfo, CmArmGicDInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGicMsiFrameInfo, CmArmGicMsiFrameInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGicRedistributorInfo, CmArmGicRedistInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGicItsInfo, CmArmGicItsInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGenericTimerInfo, CmArmGenericTimerInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPlatformGTBlockInfo, CmArmGTBlockInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo, CmArmGenericWatchdogInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser), - CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser), - CM_PARSER_ADD_OBJECT (EArmObjRootComplex, CmArmRootComplexNodeParser), - CM_PARSER_ADD_OBJECT (EArmObjSmmuV1SmmuV2, CmArmSmmuV1SmmuV2NodeParser), - CM_PARSER_ADD_OBJECT (EArmObjSmmuV3, CmArmSmmuV3NodeParser), - CM_PARSER_ADD_OBJECT (EArmObjPmcg, CmArmPmcgNodeParser), - CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser), - CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser), - CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), - CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjGenericInitiatorAffinityInfo,CmArmGenericInitiatorAffinityInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjCpcInfo, CmArmCpcInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType0Info, CmArmPccSubspaceType0InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType1Info, CmArmPccSubspaceType1InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType4Info, CmArmPccSubspaceType34InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType5Info, CmArmPccSubspaceType5InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo), - CM_PARSER_ADD_OBJECT (EArmObjPsdInfo, CmArmPsdInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjBootArchInfo, CmArmBootArchInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicCInfo, CmArmGicCInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicDInfo, CmArmGicDInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicMsiFrameInfo, CmArmGicMsiFrameInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicRedistributorInfo, CmArmGicRedistInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGicItsInfo, CmArmGicItsInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGenericTimerInfo, CmArmGenericTimerInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPlatformGTBlockInfo, CmArmGTBlockInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo,CmArmGenericWatchdogInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjRootComplex, CmArmRootComplexNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuV1SmmuV2, CmArmSmmuV1SmmuV2NodeParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuV3, CmArmSmmuV3NodeParser), + CM_PARSER_ADD_OBJECT (EArmObjPmcg, CmArmPmcgNodeParser), + CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser), + CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser), + CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), + CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjCpcInfo, CmArmCpcInfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType0Info, CmArmPccSubspaceType0InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType1Info, CmArmPccSubspaceType1InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType4Info, CmArmPccSubspaceType34InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType5Info, CmArmPccSubspaceType5InfoParser), + CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo), + CM_PARSER_ADD_OBJECT (EArmObjPsdInfo, CmArmPsdInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax) }; diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 9c7738983d..303f859865 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -462,20 +462,19 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 19 | SMMU Interrupt Array | | | 20 | Processor Hierarchy Info | Move to Arch Common NS | | 21 | Cache Info | Move to Arch Common NS | -| 22 | Generic Initiator Affinity Info | Move to Arch Common NS | -| 23 | CMN 600 Info | | -| 24 | Low Power Idle State Info | Move to Arch Common NS | -| 25 | Reserved Memory Range Node | | -| 26 | Memory Range Descriptor | | -| 27 | Continuous Performance Control Info | Move to Arch Common NS | -| 28 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 29 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 30 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 31 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 32 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 33 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 34 | Embedded Trace Extension/Module Info | | -| 35 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 22 | CMN 600 Info | | +| 23 | Low Power Idle State Info | Move to Arch Common NS | +| 24 | Reserved Memory Range Node | | +| 25 | Memory Range Descriptor | | +| 26 | Continuous Performance Control Info | Move to Arch Common NS | +| 27 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 28 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 29 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 30 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 31 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 32 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 33 | Embedded Trace Extension/Module Info | | +| 34 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 11 | Memory Affinity Info | | | 12 | Device Handle Acpi | | | 13 | Device Handle PCI | | +| 14 | Generic Initiator Affinity Info | | | `*` | All other values are reserved. | | -- cgit From ead3b4239174e98c54696eecc6aeb11c990f5a6b Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 12:59:07 +0000 Subject: DynamicTablesPkg: Move LPI info object to Arch Common Move the LPI info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SSDT Cpu Topology generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 64 ++++++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 88 +++------------------- .../SsdtCpuTopologyGenerator.c | 27 +++---- .../SsdtCpuTopologyGenerator.h | 6 +- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 21 +++--- .../ConfigurationManagerObjectParser.c | 6 +- DynamicTablesPkg/Readme.md | 24 +++--- 7 files changed, 118 insertions(+), 118 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index b70c327d46..681e845019 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -35,6 +35,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjDeviceHandleAcpi, ///< 12 - Device Handle Acpi EArchCommonObjDeviceHandlePci, ///< 13 - Device Handle Pci EArchCommonObjGenericInitiatorAffinityInfo, ///< 14 - Generic Initiator Affinity + EArchCommonObjLpiInfo, ///< 15 - Lpi Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -295,6 +296,69 @@ typedef struct CmArchCommonGenericInitiatorAffinityInfo { CM_OBJECT_TOKEN DeviceHandleToken; } CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO; +/** A structure that describes the Lpi information. + + The Low Power Idle states are described in DSDT/SSDT and associated + to cpus/clusters in the cpu topology. + + ID: EArchCommonObjLpiInfo +*/ +typedef struct CmArchCommonLpiInfo { + /** Minimum Residency. Time in microseconds after which a + state becomes more energy efficient than any shallower state. + */ + UINT32 MinResidency; + + /** Worst case time in microseconds from a wake interrupt + being asserted to the return to a running state + */ + UINT32 WorstCaseWakeLatency; + + /** Flags. + */ + UINT32 Flags; + + /** Architecture specific context loss flags. + */ + UINT32 ArchFlags; + + /** Residency counter frequency in cycles-per-second (Hz). + */ + UINT32 ResCntFreq; + + /** Every shallower power state in the parent is also enabled. + */ + UINT32 EnableParentState; + + /** The EntryMethod _LPI field can be described as an integer + or in a Register resource data descriptor. + + If IsInteger is TRUE, the IntegerEntryMethod field is used. + If IsInteger is FALSE, the RegisterEntryMethod field is used. + */ + BOOLEAN IsInteger; + + /** EntryMethod described as an Integer. + */ + UINT64 IntegerEntryMethod; + + /** EntryMethod described as a EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR. + */ + EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterEntryMethod; + + /** Residency counter register. + */ + EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResidencyCounterRegister; + + /** Usage counter register. + */ + EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE UsageCounterRegister; + + /** String representing the Lpi state + */ + CHAR8 StateName[16]; +} CM_ARCH_COMMON_LPI_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index ddf886a53d..e019323c1f 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,18 +51,17 @@ typedef enum ArmObjectID { EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info EArmObjCacheInfo, ///< 21 - Cache Info EArmObjCmn600Info, ///< 22 - CMN-600 Info - EArmObjLpiInfo, ///< 23 - Lpi Info - EArmObjRmr, ///< 24 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 25 - Memory Range Descriptor - EArmObjCpcInfo, ///< 26 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 27 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 28 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 29 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 30 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 31 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 32 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 33 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 34 - P-State Dependency (PSD) Info + EArmObjRmr, ///< 23 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 24 - Memory Range Descriptor + EArmObjCpcInfo, ///< 25 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 26 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 27 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 28 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 29 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 30 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 31 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 32 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 33 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -672,7 +671,7 @@ typedef struct CmArmProcHierarchyInfo { CM_OBJECT_TOKEN PrivateResourcesArrayToken; /// Optional field: Reference Token for the Lpi state of this processor. /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure, itself referencing - /// CM_ARM_LPI_INFO objects. + /// CM_ARCH_COMMON_LPI_INFO objects. CM_OBJECT_TOKEN LpiToken; /// Set to TRUE if UID should override index for name and _UID /// for processor container nodes and name of processors. @@ -749,69 +748,6 @@ typedef struct CmArmCmn600Info { CM_ARM_EXTENDED_INTERRUPT DtcInterrupt[4]; } CM_ARM_CMN_600_INFO; -/** A structure that describes the Lpi information. - - The Low Power Idle states are described in DSDT/SSDT and associated - to cpus/clusters in the cpu topology. - - ID: EArmObjLpiInfo -*/ -typedef struct CmArmLpiInfo { - /** Minimum Residency. Time in microseconds after which a - state becomes more energy efficient than any shallower state. - */ - UINT32 MinResidency; - - /** Worst case time in microseconds from a wake interrupt - being asserted to the return to a running state - */ - UINT32 WorstCaseWakeLatency; - - /** Flags. - */ - UINT32 Flags; - - /** Architecture specific context loss flags. - */ - UINT32 ArchFlags; - - /** Residency counter frequency in cycles-per-second (Hz). - */ - UINT32 ResCntFreq; - - /** Every shallower power state in the parent is also enabled. - */ - UINT32 EnableParentState; - - /** The EntryMethod _LPI field can be described as an integer - or in a Register resource data descriptor. - - If IsInteger is TRUE, the IntegerEntryMethod field is used. - If IsInteger is FALSE, the RegisterEntryMethod field is used. - */ - BOOLEAN IsInteger; - - /** EntryMethod described as an Integer. - */ - UINT64 IntegerEntryMethod; - - /** EntryMethod described as a EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR. - */ - EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterEntryMethod; - - /** Residency counter register. - */ - EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResidencyCounterRegister; - - /** Usage counter register. - */ - EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE UsageCounterRegister; - - /** String representing the Lpi state - */ - CHAR8 StateName[16]; -} CM_ARM_LPI_INFO; - /** A structure that describes the RMR node for the Platform. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index 5240ff52d8..bfc3f2eb30 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -40,7 +40,7 @@ Requirements: - EArmObjGicCInfo - EArmObjProcHierarchyInfo (OPTIONAL) along with - EArchCommonObjCmRef (OPTIONAL) - - EArmObjLpiInfo (OPTIONAL) + - EArchCommonObjLpiInfo (OPTIONAL) - GetEArmObjEtInfo (OPTIONAL) - EArmObjPsdInfo (OPTIONAL) */ @@ -79,9 +79,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjLpiInfo, - CM_ARM_LPI_INFO + EObjNameSpaceArchCommon, + EArchCommonObjLpiInfo, + CM_ARCH_COMMON_LPI_INFO ); /** @@ -118,7 +118,7 @@ GET_OBJECT_LIST ( One entry should be allocated for each CM_ARM_PROC_HIERARCHY_INFO structure of the platform. The TokenTable allows to have a mapping: - Index <-> CM_OBJECT_TOKEN (to CM_ARM_LPI_INFO structures). + Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). There will always be less sets of Lpi states (CM_ARCH_COMMON_OBJ_REF) than the number of cpus/clusters (CM_ARM_PROC_HIERARCHY_INFO). @@ -696,12 +696,12 @@ GenerateLpiStates ( UINT32 Index; UINT32 LastIndex; - AML_OBJECT_NODE_HANDLE LpiNode; - CM_ARCH_COMMON_OBJ_REF *LpiRefInfo; - UINT32 LpiRefInfoCount; - UINT32 LpiRefIndex; - CM_ARM_LPI_INFO *LpiInfo; - CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + AML_OBJECT_NODE_HANDLE LpiNode; + CM_ARCH_COMMON_OBJ_REF *LpiRefInfo; + UINT32 LpiRefInfoCount; + UINT32 LpiRefIndex; + CM_ARCH_COMMON_LPI_INFO *LpiInfo; + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; ASSERT (Generator != NULL); ASSERT (Generator->TokenTable.Table != NULL); @@ -739,8 +739,9 @@ GenerateLpiStates ( } for (LpiRefIndex = 0; LpiRefIndex < LpiRefInfoCount; LpiRefIndex++) { - // For each CM_ARM_LPI_INFO referenced by the token, add an Lpi state. - Status = GetEArmObjLpiInfo ( + // For each CM_ARCH_COMMON_LPI_INFO referenced by the token, + // add an Lpi state. + Status = GetEArchCommonObjLpiInfo ( CfgMgrProtocol, LpiRefInfo[LpiRefIndex].ReferenceToken, &LpiInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h index d6561e33da..889711789f 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h @@ -70,7 +70,7 @@ /** A structure used to handle the Lpi structures referencing. A CM_ARM_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF. - This CM_ARCH_COMMON_OBJ_REF references CM_ARM_LPI_INFO structures. + This CM_ARCH_COMMON_OBJ_REF references CM_ARCH_COMMON_LPI_INFO structures. Example: (Cpu0) (Cpu1) @@ -86,7 +86,7 @@ | | v v (A first Lpi state) (A second Lpi state) - CM_ARM_LPI_INFO[0] CM_ARM_LPI_INFO[1] + CM_ARCH_COMMON_LPI_INFO[0] CM_ARCH_COMMON_LPI_INFO[1] Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARM_PROC_HIERARCHY_INFO structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the @@ -118,7 +118,7 @@ */ typedef struct TokenTable { /// TokenTable, a table allowing to map: - /// Index <-> CM_OBJECT_TOKEN (to CM_ARM_LPI_INFO structures). + /// Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). CM_OBJECT_TOKEN *Table; /// Last used index of the TokenTable. diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 5f3e9f5fdc..de3338d108 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,18 +166,17 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 21 - Cache Info NULL, ///< 22 - CMN-600 Info - NULL, ///< 23 - Lpi Info - NULL, ///< 24 - Reserved Memory Range Node - NULL, ///< 25 - Memory Range Descriptor - NULL, ///< 26 - Continuous Performance Control Info - NULL, ///< 27 - Pcc Subspace Type 0 Info + NULL, ///< 23 - Reserved Memory Range Node + NULL, ///< 24 - Memory Range Descriptor + NULL, ///< 25 - Continuous Performance Control Info + NULL, ///< 26 - Pcc Subspace Type 0 Info + NULL, ///< 27 - Pcc Subspace Type 2 Info NULL, ///< 28 - Pcc Subspace Type 2 Info - NULL, ///< 29 - Pcc Subspace Type 2 Info - NULL, ///< 30 - Pcc Subspace Type 3 Info - NULL, ///< 31 - Pcc Subspace Type 4 Info - NULL, ///< 32 - Pcc Subspace Type 5 Info - NULL, ///< 33 - Embedded Trace Extension/Module Info - NULL ///< 34 - P-State Dependency (PSD) Info + NULL, ///< 29 - Pcc Subspace Type 3 Info + NULL, ///< 30 - Pcc Subspace Type 4 Info + NULL, ///< 31 - Pcc Subspace Type 5 Info + NULL, ///< 32 - Embedded Trace Extension/Module Info + NULL ///< 33 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 732454da8f..050cd04d09 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -417,9 +417,9 @@ STATIC CONST CM_OBJ_PARSER AcpiGenericAddressParser[] = { { "Address", 8, "0x%llx", NULL }, }; -/** A parser for EArmObjLpiInfo. +/** A parser for EArchCommonObjLpiInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmLpiInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonLpiInfoParser[] = { { "MinResidency", 4, "0x%x", NULL }, { "WorstCaseWakeLatency", 4, "0x%x", NULL }, { "Flags", 4, "0x%x", NULL }, @@ -685,6 +685,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandleAcpi, CmArchCommonDeviceHandleAcpiParser), CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandlePci, CmArchCommonDeviceHandlePciParser), CM_PARSER_ADD_OBJECT (EArchCommonObjGenericInitiatorAffinityInfo,CmArchCommonGenericInitiatorAffinityInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjLpiInfo, CmArchCommonLpiInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -714,7 +715,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjLpiInfo, CmArmLpiInfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCpcInfo, CmArmCpcInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 303f859865..055836a7e3 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,18 +463,17 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | Processor Hierarchy Info | Move to Arch Common NS | | 21 | Cache Info | Move to Arch Common NS | | 22 | CMN 600 Info | | -| 23 | Low Power Idle State Info | Move to Arch Common NS | -| 24 | Reserved Memory Range Node | | -| 25 | Memory Range Descriptor | | -| 26 | Continuous Performance Control Info | Move to Arch Common NS | -| 27 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 28 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 29 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 30 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 31 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 32 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 33 | Embedded Trace Extension/Module Info | | -| 34 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Reserved Memory Range Node | | +| 24 | Memory Range Descriptor | | +| 25 | Continuous Performance Control Info | Move to Arch Common NS | +| 26 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 27 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 28 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 29 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 30 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 31 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 32 | Embedded Trace Extension/Module Info | | +| 33 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,5 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 12 | Device Handle Acpi | | | 13 | Device Handle PCI | | | 14 | Generic Initiator Affinity Info | | +| 15 | Low Power Idle State Info | | | `*` | All other values are reserved. | | -- cgit From d7a47297cd003600c506de952bac9a9166733384 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 13:17:13 +0000 Subject: DynamicTablesPkg: Rename GicCToken field in Processor Hierarchy Info The GicCToken field in the CM_ARM_PROC_HIERARCHY_INFO structure is a reference to the associated object which has the corresponding ACPI Processor ID, e.g. for Arm systems this is a reference to the CM_ARM_GICC_INFO object. For other architecture this may be a reference to a similar object that has the ACPI Processor ID. Therefore, rename the GicCToken field to a more generic name like AcpiIdObjectToken. Correspondingly also update the following modules to reflect the changes introduced by this renaming: - PPTT generator - SSDT CPu topology generator - ConfigurationManagerObjectParser. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 10 ++-- .../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 60 +++++++++++----------- .../SsdtCpuTopologyGenerator.c | 8 +-- .../ConfigurationManagerObjectParser.c | 2 +- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index e019323c1f..da50f581fa 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -657,11 +657,11 @@ typedef struct CmArmProcHierarchyInfo { /// Token for the parent CM_ARM_PROC_HIERARCHY_INFO object in the processor /// topology. A value of CM_NULL_TOKEN means this node has no parent. CM_OBJECT_TOKEN ParentToken; - /// Token of the associated CM_ARM_GICC_INFO object which has the - /// corresponding ACPI Processor ID. A value of CM_NULL_TOKEN means this - /// node represents a group of associated processors and it does not have an - /// associated GIC CPU interface. - CM_OBJECT_TOKEN GicCToken; + /// Token of the associated object which has the corresponding ACPI Processor + /// ID, e.g. for Arm systems this is a reference to CM_ARM_GICC_INFO object. + /// A value of CM_NULL_TOKEN means this node represents a group of associated + /// processors and it does not have an associated CPU interface. + CM_OBJECT_TOKEN AcpiIdObjectToken; /// Number of resources private to this Node UINT32 NoOfPrivateResources; /// Token of the array which contains references to the resources private to diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c index c237f7ff93..f2f2a83411 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c @@ -397,12 +397,14 @@ AddPrivateResources ( @param [in] Index2 Index of Object2 to be displayed for debugging purposes. - @retval TRUE Object1 and Object2 have the same GicCToken. - @retval FALSE Object1 and Object2 have different GicCTokens. + @retval TRUE Object1 and Object2 have the same + AcpiIdObjectToken. + @retval FALSE Object1 and Object2 have different + AcpiIdObjectTokens. **/ BOOLEAN EFIAPI -IsGicCTokenEqual ( +IsAcpiIdObjectTokenEqual ( IN CONST VOID *Object1, IN CONST VOID *Object2, IN UINTN Index1, @@ -426,18 +428,18 @@ IsGicCTokenEqual ( if (IS_ACPI_PROC_ID_VALID (ProcNode1) && IS_ACPI_PROC_ID_VALID (ProcNode2) && - (ProcNode1->GicCToken != CM_NULL_TOKEN) && - (ProcNode2->GicCToken != CM_NULL_TOKEN) && - (ProcNode1->GicCToken == ProcNode2->GicCToken)) + (ProcNode1->AcpiIdObjectToken != CM_NULL_TOKEN) && + (ProcNode2->AcpiIdObjectToken != CM_NULL_TOKEN) && + (ProcNode1->AcpiIdObjectToken == ProcNode2->AcpiIdObjectToken)) { DEBUG (( DEBUG_ERROR, "ERROR: PPTT: Two Processor Hierarchy Info objects (%d and %d) map to " \ - "the same GICC Info object. ACPI Processor IDs are not unique. " \ - "GicCToken = %p.\n", + "the same ACPI ID reference object. ACPI Processor IDs are not unique. " \ + "AcpiIdObjectToken = %p.\n", Index1, Index2, - ProcNode1->GicCToken + ProcNode1->AcpiIdObjectToken )); return TRUE; } @@ -474,7 +476,7 @@ AddProcHierarchyNodes ( EFI_STATUS Status; EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *ProcStruct; UINT32 *PrivateResources; - BOOLEAN IsGicCTokenDuplicated; + BOOLEAN IsAcpiIdObjectTokenDuplicated; CM_ARM_GICC_INFO *GicCInfoList; UINT32 GicCInfoCount; @@ -500,15 +502,15 @@ AddProcHierarchyNodes ( NodeCount = Generator->ProcHierarchyNodeCount; // Check if every GICC Object is referenced by onlu one Proc Node - IsGicCTokenDuplicated = FindDuplicateValue ( - ProcNodeIterator, - NodeCount, - sizeof (PPTT_NODE_INDEXER), - IsGicCTokenEqual - ); + IsAcpiIdObjectTokenDuplicated = FindDuplicateValue ( + ProcNodeIterator, + NodeCount, + sizeof (PPTT_NODE_INDEXER), + IsAcpiIdObjectTokenEqual + ); // Duplicate GIC CPU Interface Token was found so two PPTT Processor Hierarchy // Nodes map to the same MADT GICC structure - if (IsGicCTokenDuplicated) { + if (IsAcpiIdObjectTokenDuplicated) { return EFI_INVALID_PARAMETER; } @@ -602,14 +604,14 @@ AddProcHierarchyNodes ( if (!IS_ACPI_PROC_ID_VALID (ProcInfoNode)) { // Default invalid ACPI Processor ID to 0 ProcStruct->AcpiProcessorId = 0; - } else if (ProcInfoNode->GicCToken == CM_NULL_TOKEN) { + } else if (ProcInfoNode->AcpiIdObjectToken == CM_NULL_TOKEN) { Status = EFI_INVALID_PARAMETER; DEBUG (( DEBUG_ERROR, - "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no GICC " \ - "structure token was provided. GicCToken = %p. RequestorToken = %p. " \ - "Status = %r\n", - ProcInfoNode->GicCToken, + "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no " \ + "ACPI ID Reference object token was provided. " \ + "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n", + ProcInfoNode->AcpiIdObjectToken, ProcInfoNode->Token, Status )); @@ -617,17 +619,17 @@ AddProcHierarchyNodes ( } else { Status = GetEArmObjGicCInfo ( CfgMgrProtocol, - ProcInfoNode->GicCToken, + ProcInfoNode->AcpiIdObjectToken, &GicCInfoList, &GicCInfoCount ); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, - "ERROR: PPTT: Failed to get GICC structure. ACPI Processor ID " \ - "can't be populated. GicCToken = %p. RequestorToken = %p. " \ - "Status = %r\n", - ProcInfoNode->GicCToken, + "ERROR: PPTT: Failed to get ACPI ID Reference object token. " \ + "ACPI Processor ID can't be populated. " \ + "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n", + ProcInfoNode->AcpiIdObjectToken, ProcInfoNode->Token, Status )); @@ -640,10 +642,10 @@ AddProcHierarchyNodes ( DEBUG_ERROR, "ERROR: PPTT: Failed to find a unique GICC structure. " \ "ACPI Processor ID can't be populated. " \ - "GICC Structure Count = %d. GicCToken = %p. RequestorToken = %p " \ + "GICC Structure Count = %d. AcpiIdObjectToken = %p. RequestorToken = %p " \ "Status = %r\n", GicCInfoCount, - ProcInfoNode->GicCToken, + ProcInfoNode->AcpiIdObjectToken, ProcInfoNode->Token, Status )); diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index bfc3f2eb30..16e443b3fd 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -894,11 +894,11 @@ CreateAmlCpuFromProcHierarchy ( ASSERT (CfgMgrProtocol != NULL); ASSERT (ParentNode != NULL); ASSERT (ProcHierarchyNodeInfo != NULL); - ASSERT (ProcHierarchyNodeInfo->GicCToken != CM_NULL_TOKEN); + ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN); Status = GetEArmObjGicCInfo ( CfgMgrProtocol, - ProcHierarchyNodeInfo->GicCToken, + ProcHierarchyNodeInfo->AcpiIdObjectToken, &GicCInfo, NULL ); @@ -1175,9 +1175,9 @@ CreateAmlCpuTopologyTree ( // Find the children of the CM_ARM_PROC_HIERARCHY_INFO // currently being handled (i.e. ParentToken == NodeToken). if (Generator->ProcNodeList[Index].ParentToken == NodeToken) { - // Only Cpus (leaf nodes in this tree) have a GicCToken. + // Only Cpus (leaf nodes in this tree) have a AcpiIdObjectToken. // Create a Cpu node. - if (Generator->ProcNodeList[Index].GicCToken != CM_NULL_TOKEN) { + if (Generator->ProcNodeList[Index].AcpiIdObjectToken != CM_NULL_TOKEN) { Status = CheckProcNode ( Generator->ProcNodeList[Index].Flags, TRUE, diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 050cd04d09..17388b1835 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -328,7 +328,7 @@ STATIC CONST CM_OBJ_PARSER CmArmProcHierarchyInfoParser[] = { { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, { "Flags", 4, "0x%x", NULL }, { "ParentToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, - { "GicCToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, + { "AcpiIdObjectToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, { "NoOfPrivateResources", 4, "0x%x", NULL }, { "PrivateResourcesArrayToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, { "LpiToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, -- cgit From 79dd25848ef0914627adb7ee313b7c5909ce531b Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 13:36:32 +0000 Subject: DynamicTablesPkg: Move Processor hierarchy info to Arch Common Move the Processor hierarchy info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PPTT generator - SSDT CPU topology generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 42 ++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 74 +++++----------------- .../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 38 +++++------ .../SsdtCpuTopologyGenerator.c | 67 ++++++++++---------- .../SsdtCpuTopologyGenerator.h | 18 +++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 1 - .../ConfigurationManagerObjectParser.c | 6 +- DynamicTablesPkg/Readme.md | 29 +++++---- 8 files changed, 137 insertions(+), 138 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 681e845019..872f2eebb7 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -36,6 +36,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjDeviceHandlePci, ///< 13 - Device Handle Pci EArchCommonObjGenericInitiatorAffinityInfo, ///< 14 - Generic Initiator Affinity EArchCommonObjLpiInfo, ///< 15 - Lpi Info + EArchCommonObjProcHierarchyInfo, ///< 16 - Processor Hierarchy Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -359,6 +360,47 @@ typedef struct CmArchCommonLpiInfo { CHAR8 StateName[16]; } CM_ARCH_COMMON_LPI_INFO; +/** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT + + ID: EArchCommonObjProcHierarchyInfo +*/ +typedef struct CmArchCommonProcHierarchyInfo { + /// A unique token used to identify this object + CM_OBJECT_TOKEN Token; + /// Processor structure flags (ACPI 6.3 - January 2019, PPTT, Table 5-155) + UINT32 Flags; + /// Token for the parent CM_ARCH_COMMON_PROC_HIERARCHY_INFO object in the processor + /// topology. A value of CM_NULL_TOKEN means this node has no parent. + CM_OBJECT_TOKEN ParentToken; + /// Token of the associated object which has the corresponding ACPI Processor + /// ID, e.g. for Arm systems this is a reference to CM_ARM_GICC_INFO object. + /// A value of CM_NULL_TOKEN means this node represents a group of associated + /// processors and it does not have an associated CPU interface. + CM_OBJECT_TOKEN AcpiIdObjectToken; + /// Number of resources private to this Node + UINT32 NoOfPrivateResources; + /// Token of the array which contains references to the resources private to + /// this CM_ARCH_COMMON_PROC_HIERARCHY_INFO instance. This field is ignored if + /// the NoOfPrivateResources is 0, in which case it is recommended to set + /// this field to CM_NULL_TOKEN. + CM_OBJECT_TOKEN PrivateResourcesArrayToken; + /// Optional field: Reference Token for the Lpi state of this processor. + /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure, itself referencing + /// CM_ARCH_COMMON_LPI_INFO objects. + CM_OBJECT_TOKEN LpiToken; + /// Set to TRUE if UID should override index for name and _UID + /// for processor container nodes and name of processors. + /// This should be consistently set for containers or processors to avoid + /// duplicate values + BOOLEAN OverrideNameUidEnabled; + /// If OverrideNameUidEnabled is TRUE then this value will be used for name of + /// processors and processor containers. + UINT16 OverrideName; + /// If OverrideNameUidEnabled is TRUE then this value will be used for + /// the UID of processor containers. + UINT32 OverrideUid; +} CM_ARCH_COMMON_PROC_HIERARCHY_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index da50f581fa..4e9f0096ba 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -48,20 +48,19 @@ typedef enum ArmObjectID { EArmObjGicItsIdentifierArray, ///< 17 - GIC ITS Identifier Array EArmObjIdMappingArray, ///< 18 - ID Mapping Array EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array - EArmObjProcHierarchyInfo, ///< 20 - Processor Hierarchy Info - EArmObjCacheInfo, ///< 21 - Cache Info - EArmObjCmn600Info, ///< 22 - CMN-600 Info - EArmObjRmr, ///< 23 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 24 - Memory Range Descriptor - EArmObjCpcInfo, ///< 25 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 26 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 27 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 28 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 29 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 30 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 31 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 32 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 33 - P-State Dependency (PSD) Info + EArmObjCacheInfo, ///< 20 - Cache Info + EArmObjCmn600Info, ///< 21 - CMN-600 Info + EArmObjRmr, ///< 22 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 23 - Memory Range Descriptor + EArmObjCpcInfo, ///< 24 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 25 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 26 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 27 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 28 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 29 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 30 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 31 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 32 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -645,47 +644,6 @@ typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT; */ typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT; -/** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT - - ID: EArmObjProcHierarchyInfo -*/ -typedef struct CmArmProcHierarchyInfo { - /// A unique token used to identify this object - CM_OBJECT_TOKEN Token; - /// Processor structure flags (ACPI 6.3 - January 2019, PPTT, Table 5-155) - UINT32 Flags; - /// Token for the parent CM_ARM_PROC_HIERARCHY_INFO object in the processor - /// topology. A value of CM_NULL_TOKEN means this node has no parent. - CM_OBJECT_TOKEN ParentToken; - /// Token of the associated object which has the corresponding ACPI Processor - /// ID, e.g. for Arm systems this is a reference to CM_ARM_GICC_INFO object. - /// A value of CM_NULL_TOKEN means this node represents a group of associated - /// processors and it does not have an associated CPU interface. - CM_OBJECT_TOKEN AcpiIdObjectToken; - /// Number of resources private to this Node - UINT32 NoOfPrivateResources; - /// Token of the array which contains references to the resources private to - /// this CM_ARM_PROC_HIERARCHY_INFO instance. This field is ignored if - /// the NoOfPrivateResources is 0, in which case it is recommended to set - /// this field to CM_NULL_TOKEN. - CM_OBJECT_TOKEN PrivateResourcesArrayToken; - /// Optional field: Reference Token for the Lpi state of this processor. - /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure, itself referencing - /// CM_ARCH_COMMON_LPI_INFO objects. - CM_OBJECT_TOKEN LpiToken; - /// Set to TRUE if UID should override index for name and _UID - /// for processor container nodes and name of processors. - /// This should be consistently set for containers or processors to avoid - /// duplicate values - BOOLEAN OverrideNameUidEnabled; - /// If OverrideNameUidEnabled is TRUE then this value will be used for name of - /// processors and processor containers. - UINT16 OverrideName; - /// If OverrideNameUidEnabled is TRUE then this value will be used for - /// the UID of processor containers. - UINT32 OverrideUid; -} CM_ARM_PROC_HIERARCHY_INFO; - /** A structure that describes the Cache Type Structure (Type 1) in PPTT ID: EArmObjCacheInfo @@ -694,9 +652,9 @@ typedef struct CmArmCacheInfo { /// A unique token used to identify this object CM_OBJECT_TOKEN Token; /// Reference token for the next level of cache that is private to the same - /// CM_ARM_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN means this - /// entry represents the last cache level appropriate to the processor - /// hierarchy node structures using this entry. + /// CM_ARCH_COMMON_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN + /// means this entry represents the last cache level appropriate to the + /// processor hierarchy node structures using this entry. CM_OBJECT_TOKEN NextLevelOfCacheToken; /// Size of the cache in bytes UINT32 Size; diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c index f2f2a83411..9485de7070 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c @@ -32,7 +32,7 @@ Requirements: The following Configuration Manager Object(s) are used by this Generator: - - EArmObjProcHierarchyInfo (REQUIRED) + - EArchCommonObjProcHierarchyInfo (REQUIRED) - EArmObjCacheInfo - EArchCommonObjCmRef - EArmObjGicCInfo (REQUIRED) @@ -43,9 +43,9 @@ information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjProcHierarchyInfo, - CM_ARM_PROC_HIERARCHY_INFO + EObjNameSpaceArchCommon, + EArchCommonObjProcHierarchyInfo, + CM_ARCH_COMMON_PROC_HIERARCHY_INFO ); /** @@ -90,7 +90,7 @@ GET_OBJECT_LIST ( STATIC UINT32 GetProcHierarchyNodeSize ( - IN CONST CM_ARM_PROC_HIERARCHY_INFO *Node + IN CONST CM_ARCH_COMMON_PROC_HIERARCHY_INFO *Node ) { ASSERT (Node != NULL); @@ -107,7 +107,7 @@ GetProcHierarchyNodeSize ( GET_SIZE_OF_PPTT_STRUCTS ( ProcHierarchyNodes, GetProcHierarchyNodeSize (NodesToIndex), - CM_ARM_PROC_HIERARCHY_INFO + CM_ARCH_COMMON_PROC_HIERARCHY_INFO ); /** @@ -411,10 +411,10 @@ IsAcpiIdObjectTokenEqual ( IN UINTN Index2 ) { - PPTT_NODE_INDEXER *IndexedObject1; - PPTT_NODE_INDEXER *IndexedObject2; - CM_ARM_PROC_HIERARCHY_INFO *ProcNode1; - CM_ARM_PROC_HIERARCHY_INFO *ProcNode2; + PPTT_NODE_INDEXER *IndexedObject1; + PPTT_NODE_INDEXER *IndexedObject2; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode1; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode2; ASSERT ( (Object1 != NULL) && @@ -423,8 +423,8 @@ IsAcpiIdObjectTokenEqual ( IndexedObject1 = (PPTT_NODE_INDEXER *)Object1; IndexedObject2 = (PPTT_NODE_INDEXER *)Object2; - ProcNode1 = (CM_ARM_PROC_HIERARCHY_INFO *)IndexedObject1->Object; - ProcNode2 = (CM_ARM_PROC_HIERARCHY_INFO *)IndexedObject2->Object; + ProcNode1 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject1->Object; + ProcNode2 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject2->Object; if (IS_ACPI_PROC_ID_VALID (ProcNode1) && IS_ACPI_PROC_ID_VALID (ProcNode2) && @@ -482,8 +482,8 @@ AddProcHierarchyNodes ( UINT32 GicCInfoCount; UINT32 UniqueGicCRefCount; - PPTT_NODE_INDEXER *PpttNodeFound; - CM_ARM_PROC_HIERARCHY_INFO *ProcInfoNode; + PPTT_NODE_INDEXER *PpttNodeFound; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcInfoNode; PPTT_NODE_INDEXER *ProcNodeIterator; UINT32 NodeCount; @@ -517,7 +517,7 @@ AddProcHierarchyNodes ( UniqueGicCRefCount = 0; while (NodeCount-- != 0) { - ProcInfoNode = (CM_ARM_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object; + ProcInfoNode = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object; // Check if the private resource count is within the size limit // imposed on the Processor Hierarchy node by the specification. @@ -577,7 +577,7 @@ AddProcHierarchyNodes ( // Test if the reference is to a 'leaf' node if (IS_PROC_NODE_LEAF ( - ((CM_ARM_PROC_HIERARCHY_INFO *)PpttNodeFound->Object) + ((CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)PpttNodeFound->Object) )) { Status = EFI_INVALID_PARAMETER; @@ -1074,8 +1074,8 @@ BuildPpttTable ( UINT32 ProcHierarchyNodeOffset; UINT32 CacheStructOffset; - CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; - CM_ARM_CACHE_INFO *CacheStructList; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; + CM_ARM_CACHE_INFO *CacheStructList; ACPI_PPTT_GENERATOR *Generator; @@ -1112,7 +1112,7 @@ BuildPpttTable ( // Get the processor hierarchy info and update the processor topology // structure count with Processor Hierarchy Nodes (Type 0) - Status = GetEArmObjProcHierarchyInfo ( + Status = GetEArchCommonObjProcHierarchyInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &ProcHierarchyNodeList, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index 16e443b3fd..d7caca5a3a 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -38,7 +38,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - EArmObjGicCInfo - - EArmObjProcHierarchyInfo (OPTIONAL) along with + - EArchCommonObjProcHierarchyInfo (OPTIONAL) along with - EArchCommonObjCmRef (OPTIONAL) - EArchCommonObjLpiInfo (OPTIONAL) - GetEArmObjEtInfo (OPTIONAL) @@ -59,9 +59,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjProcHierarchyInfo, - CM_ARM_PROC_HIERARCHY_INFO + EObjNameSpaceArchCommon, + EArchCommonObjProcHierarchyInfo, + CM_ARCH_COMMON_PROC_HIERARCHY_INFO ); /** @@ -116,12 +116,12 @@ GET_OBJECT_LIST ( /** Initialize the TokenTable. - One entry should be allocated for each CM_ARM_PROC_HIERARCHY_INFO + One entry should be allocated for each CM_ARCH_COMMON_PROC_HIERARCHY_INFO structure of the platform. The TokenTable allows to have a mapping: Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). There will always be less sets of Lpi states (CM_ARCH_COMMON_OBJ_REF) - than the number of cpus/clusters (CM_ARM_PROC_HIERARCHY_INFO). + than the number of cpus/clusters (CM_ARCH_COMMON_PROC_HIERARCHY_INFO). @param [in] Generator The SSDT Cpu Topology generator. @param [in] Count Number of entries to allocate in the TokenTable. @@ -585,8 +585,8 @@ CreateAmlEtNode ( } @param [in] Generator The SSDT Cpu Topology generator. - @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing - the Cpu. + @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO + describing the Cpu. @param [in] Node Node to which the _LPI method is attached. Can represent a Cpu or a Cluster. @@ -599,9 +599,9 @@ STATIC EFI_STATUS EFIAPI CreateAmlLpiMethod ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, - IN AML_OBJECT_NODE_HANDLE *Node + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, + IN AML_OBJECT_NODE_HANDLE *Node ) { EFI_STATUS Status; @@ -860,7 +860,7 @@ CreateAmlCpu ( return Status; } -/** Create a Cpu in the AML namespace from a CM_ARM_PROC_HIERARCHY_INFO +/** Create a Cpu in the AML namespace from a CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM object. @param [in] Generator The SSDT Cpu Topology generator. @@ -868,8 +868,8 @@ CreateAmlCpu ( Protocol Interface. @param [in] ParentNode Parent node to attach the Cpu node to. @param [in] CpuName Value used to generate the node name. - @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing - the Cpu. + @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO + describing the Cpu. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER Invalid parameter. @@ -883,7 +883,7 @@ CreateAmlCpuFromProcHierarchy ( IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_NODE_HANDLE ParentNode, IN UINT32 CpuName, - IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo + IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo ) { EFI_STATUS Status; @@ -914,7 +914,7 @@ CreateAmlCpuFromProcHierarchy ( } // If a set of Lpi states is associated with the - // CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them. + // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them. if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) { Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode); if (EFI_ERROR (Status)) { @@ -961,7 +961,7 @@ CreateAmlCpuFromProcHierarchy ( /** Create a Processor Container in the AML namespace. - Any CM_ARM_PROC_HIERARCHY_INFO object with the following flags is + Any CM_ARCH_COMMON_PROC_HIERARCHY_INFO object with the following flags is assumed to be a processor container: - EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL - EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID @@ -979,8 +979,8 @@ CreateAmlCpuFromProcHierarchy ( Protocol Interface. @param [in] ParentNode Parent node to attach the processor container node to. - @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO object used - to create the node. + @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO object + used to create the node. @param [in] ProcContainerName Name of the processor container. @param [in] ProcContainerUid Uid of the processor container. @param [out] ProcContainerNodePtr If success, contains the created processor @@ -997,7 +997,7 @@ CreateAmlProcessorContainer ( IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN AML_NODE_HANDLE ParentNode, - IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, + IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, IN UINT16 ProcContainerName, IN UINT32 ProcContainerUid, OUT AML_OBJECT_NODE_HANDLE *ProcContainerNodePtr @@ -1050,7 +1050,7 @@ CreateAmlProcessorContainer ( } // If a set of Lpi states are associated with the - // CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them. + // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them. if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) { Status = CreateAmlLpiMethod ( Generator, @@ -1128,8 +1128,7 @@ CheckProcNode ( @param [in] Generator The SSDT Cpu Topology generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. - @param [in] NodeToken Token of the CM_ARM_PROC_HIERARCHY_INFO - currently handled. + @param [in] NodeToken Token of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO currently handled. @param [in] ParentNode Parent node to attach the created node to. @param [in,out] ProcContainerIndex Pointer to the current processor container @@ -1172,7 +1171,7 @@ CreateAmlCpuTopologyTree ( ProcContainerName = 0; for (Index = 0; Index < Generator->ProcNodeCount; Index++) { - // Find the children of the CM_ARM_PROC_HIERARCHY_INFO + // Find the children of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO // currently being handled (i.e. ParentToken == NodeToken). if (Generator->ProcNodeList[Index].ParentToken == NodeToken) { // Only Cpus (leaf nodes in this tree) have a AcpiIdObjectToken. @@ -1281,8 +1280,8 @@ CreateAmlCpuTopologyTree ( return EFI_SUCCESS; } -/** Create the processor hierarchy AML tree from CM_ARM_PROC_HIERARCHY_INFO - CM objects. +/** Create the processor hierarchy AML tree from + CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. @param [in] Generator The SSDT Cpu Topology generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager @@ -1469,12 +1468,12 @@ BuildSsdtCpuTopologyTable ( OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table ) { - EFI_STATUS Status; - AML_ROOT_NODE_HANDLE RootNode; - AML_OBJECT_NODE_HANDLE ScopeNode; - CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; - UINT32 ProcHierarchyNodeCount; - ACPI_CPU_TOPOLOGY_GENERATOR *Generator; + EFI_STATUS Status; + AML_ROOT_NODE_HANDLE RootNode; + AML_OBJECT_NODE_HANDLE ScopeNode; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; + UINT32 ProcHierarchyNodeCount; + ACPI_CPU_TOPOLOGY_GENERATOR *Generator; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -1502,7 +1501,7 @@ BuildSsdtCpuTopologyTable ( // Get the processor hierarchy info and update the processor topology // structure count with Processor Hierarchy Nodes (Type 0) - Status = GetEArmObjProcHierarchyInfo ( + Status = GetEArchCommonObjProcHierarchyInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &ProcHierarchyNodeList, @@ -1526,7 +1525,7 @@ BuildSsdtCpuTopologyTable ( goto exit_handler; } } else { - // Generate the topology from CM_ARM_PROC_HIERARCHY_INFO objects. + // Generate the topology from CM_ARCH_COMMON_PROC_HIERARCHY_INFO objects. Generator->ProcNodeList = ProcHierarchyNodeList; Generator->ProcNodeCount = ProcHierarchyNodeCount; diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h index 889711789f..6fb44c7e58 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h @@ -69,12 +69,12 @@ /** A structure used to handle the Lpi structures referencing. - A CM_ARM_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF. + A CM_ARCH_COMMON_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF. This CM_ARCH_COMMON_OBJ_REF references CM_ARCH_COMMON_LPI_INFO structures. Example: (Cpu0) (Cpu1) - CM_ARM_PROC_HIERARCHY_INFO CM_ARM_PROC_HIERARCHY_INFO + CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM_ARCH_COMMON_PROC_HIERARCHY_INFO | | +---------------------------------------- | @@ -88,7 +88,7 @@ (A first Lpi state) (A second Lpi state) CM_ARCH_COMMON_LPI_INFO[0] CM_ARCH_COMMON_LPI_INFO[1] - Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARM_PROC_HIERARCHY_INFO + Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARCH_COMMON_PROC_HIERARCHY_INFO structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the TokenTable such as: 0 <-> CM_ARCH_COMMON_OBJ_REF @@ -130,16 +130,16 @@ typedef struct TokenTable { */ typedef struct AcpiCpuTopologyGenerator { /// ACPI Table generator header - ACPI_TABLE_GENERATOR Header; + ACPI_TABLE_GENERATOR Header; // Private fields are defined from here. /// Private object used to handle token referencing. - TOKEN_TABLE TokenTable; - /// List of CM_ARM_PROC_HIERARCHY_INFO CM objects. - CM_ARM_PROC_HIERARCHY_INFO *ProcNodeList; - /// Count of CM_ARM_PROC_HIERARCHY_INFO CM objects. - UINT32 ProcNodeCount; + TOKEN_TABLE TokenTable; + /// List of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNodeList; + /// Count of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. + UINT32 ProcNodeCount; } ACPI_CPU_TOPOLOGY_GENERATOR; #pragma pack() diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index de3338d108..fd2a321bfb 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -163,7 +163,6 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 17 - GIC ITS Identifier Array NULL, ///< 18 - ID Mapping Array NULL, ///< 19 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 20 - Processor Hierarchy Info TokenFixerNotImplemented, ///< 21 - Cache Info NULL, ///< 22 - CMN-600 Info NULL, ///< 23 - Reserved Memory Range Node diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 17388b1835..c48e29e505 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -322,9 +322,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonGenericInterruptParser[] = { { "Flags", 4, "0x%x", NULL } }; -/** A parser for EArmObjProcHierarchyInfo. +/** A parser for EArchCommonObjProcHierarchyInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmProcHierarchyInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonProcHierarchyInfoParser[] = { { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, { "Flags", 4, "0x%x", NULL }, { "ParentToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, @@ -686,6 +686,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandlePci, CmArchCommonDeviceHandlePciParser), CM_PARSER_ADD_OBJECT (EArchCommonObjGenericInitiatorAffinityInfo,CmArchCommonGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjLpiInfo, CmArchCommonLpiInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjProcHierarchyInfo, CmArchCommonProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -712,7 +713,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser), CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser), CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), - CM_PARSER_ADD_OBJECT (EArmObjProcHierarchyInfo, CmArmProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 055836a7e3..e0af0fd336 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -460,20 +460,19 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 17 | GIC ITS Identifier Array | | | 18 | ID Mapping Array | | | 19 | SMMU Interrupt Array | | -| 20 | Processor Hierarchy Info | Move to Arch Common NS | -| 21 | Cache Info | Move to Arch Common NS | -| 22 | CMN 600 Info | | -| 23 | Reserved Memory Range Node | | -| 24 | Memory Range Descriptor | | -| 25 | Continuous Performance Control Info | Move to Arch Common NS | -| 26 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 27 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 28 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 29 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 30 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 31 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 32 | Embedded Trace Extension/Module Info | | -| 33 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 20 | Cache Info | Move to Arch Common NS | +| 21 | CMN 600 Info | | +| 22 | Reserved Memory Range Node | | +| 23 | Memory Range Descriptor | | +| 24 | Continuous Performance Control Info | Move to Arch Common NS | +| 25 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 26 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 27 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 28 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 29 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 30 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 31 | Embedded Trace Extension/Module Info | | +| 32 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,4 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 13 | Device Handle PCI | | | 14 | Generic Initiator Affinity Info | | | 15 | Low Power Idle State Info | | +| 16 | Processor Hierarchy Info | | | `*` | All other values are reserved. | | + -- cgit From afa7f8a6b17996ec13e4ce9867e5ac41d17aa262 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 13:47:52 +0000 Subject: DynamicTablesPkg: Move Cache info to Arch Common Move the Cache info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PPTT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 31 ++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 55 +++++----------------- .../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 18 +++---- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 25 +++++----- .../ConfigurationManagerObjectParser.c | 6 +-- DynamicTablesPkg/Readme.md | 26 +++++----- 6 files changed, 80 insertions(+), 81 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 872f2eebb7..17cd552a3f 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -37,6 +37,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjGenericInitiatorAffinityInfo, ///< 14 - Generic Initiator Affinity EArchCommonObjLpiInfo, ///< 15 - Lpi Info EArchCommonObjProcHierarchyInfo, ///< 16 - Processor Hierarchy Info + EArchCommonObjCacheInfo, ///< 17 - Cache Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -401,6 +402,36 @@ typedef struct CmArchCommonProcHierarchyInfo { UINT32 OverrideUid; } CM_ARCH_COMMON_PROC_HIERARCHY_INFO; +/** A structure that describes the Cache Type Structure (Type 1) in PPTT + + ID: EArchCommonObjCacheInfo +*/ +typedef struct CmArchCommonCacheInfo { + /// A unique token used to identify this object + CM_OBJECT_TOKEN Token; + /// Reference token for the next level of cache that is private to the same + /// CM_ARCH_COMMON_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN + /// means this entry represents the last cache level appropriate to the + /// processor hierarchy node structures using this entry. + CM_OBJECT_TOKEN NextLevelOfCacheToken; + /// Size of the cache in bytes + UINT32 Size; + /// Number of sets in the cache + UINT32 NumberOfSets; + /// Integer number of ways. The maximum associativity supported by + /// ACPI Cache type structure is limited to MAX_UINT8. However, + /// the maximum number of ways supported by the architecture is + /// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field + /// is 32-bit wide. + UINT32 Associativity; + /// Cache attributes (ACPI 6.4 - January 2021, PPTT, Table 5.140) + UINT8 Attributes; + /// Line size in bytes + UINT16 LineSize; + /// Unique ID for the cache + UINT32 CacheId; +} CM_ARCH_COMMON_CACHE_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 4e9f0096ba..eade2afcd0 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -48,19 +48,18 @@ typedef enum ArmObjectID { EArmObjGicItsIdentifierArray, ///< 17 - GIC ITS Identifier Array EArmObjIdMappingArray, ///< 18 - ID Mapping Array EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array - EArmObjCacheInfo, ///< 20 - Cache Info - EArmObjCmn600Info, ///< 21 - CMN-600 Info - EArmObjRmr, ///< 22 - Reserved Memory Range Node - EArmObjMemoryRangeDescriptor, ///< 23 - Memory Range Descriptor - EArmObjCpcInfo, ///< 24 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 25 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 26 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 27 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 28 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 29 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 30 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 31 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 32 - P-State Dependency (PSD) Info + EArmObjCmn600Info, ///< 20 - CMN-600 Info + EArmObjRmr, ///< 21 - Reserved Memory Range Node + EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor + EArmObjCpcInfo, ///< 23 - Continuous Performance Control Info + EArmObjPccSubspaceType0Info, ///< 24 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 25 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 26 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 27 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 28 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 29 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 30 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 31 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -644,36 +643,6 @@ typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT; */ typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT; -/** A structure that describes the Cache Type Structure (Type 1) in PPTT - - ID: EArmObjCacheInfo -*/ -typedef struct CmArmCacheInfo { - /// A unique token used to identify this object - CM_OBJECT_TOKEN Token; - /// Reference token for the next level of cache that is private to the same - /// CM_ARCH_COMMON_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN - /// means this entry represents the last cache level appropriate to the - /// processor hierarchy node structures using this entry. - CM_OBJECT_TOKEN NextLevelOfCacheToken; - /// Size of the cache in bytes - UINT32 Size; - /// Number of sets in the cache - UINT32 NumberOfSets; - /// Integer number of ways. The maximum associativity supported by - /// ACPI Cache type structure is limited to MAX_UINT8. However, - /// the maximum number of ways supported by the architecture is - /// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field - /// is 32-bit wide. - UINT32 Associativity; - /// Cache attributes (ACPI 6.4 - January 2021, PPTT, Table 5.140) - UINT8 Attributes; - /// Line size in bytes - UINT16 LineSize; - /// Unique ID for the cache - UINT32 CacheId; -} CM_ARM_CACHE_INFO; - /** A structure that describes the CMN-600 hardware. ID: EArmObjCmn600Info diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c index 9485de7070..2b8088a07f 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c @@ -33,7 +33,7 @@ Requirements: The following Configuration Manager Object(s) are used by this Generator: - EArchCommonObjProcHierarchyInfo (REQUIRED) - - EArmObjCacheInfo + - EArchCommonObjCacheInfo - EArchCommonObjCmRef - EArmObjGicCInfo (REQUIRED) */ @@ -53,9 +53,9 @@ GET_OBJECT_LIST ( from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjCacheInfo, - CM_ARM_CACHE_INFO + EObjNameSpaceArchCommon, + EArchCommonObjCacheInfo, + CM_ARCH_COMMON_CACHE_INFO ); /** @@ -117,7 +117,7 @@ GET_SIZE_OF_PPTT_STRUCTS ( GET_SIZE_OF_PPTT_STRUCTS ( CacheTypeStructs, sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE), - CM_ARM_CACHE_INFO + CM_ARCH_COMMON_CACHE_INFO ); /** @@ -788,7 +788,7 @@ AddCacheTypeStructures ( EFI_STATUS Status; EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *CacheStruct; PPTT_NODE_INDEXER *PpttNodeFound; - CM_ARM_CACHE_INFO *CacheInfoNode; + CM_ARCH_COMMON_CACHE_INFO *CacheInfoNode; PPTT_NODE_INDEXER *CacheNodeIterator; UINT32 NodeCount; BOOLEAN CacheIdUnique; @@ -814,7 +814,7 @@ AddCacheTypeStructures ( } for (NodeIndex = 0; NodeIndex < NodeCount; NodeIndex++) { - CacheInfoNode = (CM_ARM_CACHE_INFO *)CacheNodeIterator->Object; + CacheInfoNode = (CM_ARCH_COMMON_CACHE_INFO *)CacheNodeIterator->Object; // Populate the node header CacheStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_CACHE; @@ -1075,7 +1075,7 @@ BuildPpttTable ( UINT32 CacheStructOffset; CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; - CM_ARM_CACHE_INFO *CacheStructList; + CM_ARCH_COMMON_CACHE_INFO *CacheStructList; ACPI_PPTT_GENERATOR *Generator; @@ -1132,7 +1132,7 @@ BuildPpttTable ( // Get the cache info and update the processor topology structure count with // Cache Type Structures (Type 1) - Status = GetEArmObjCacheInfo ( + Status = GetEArchCommonObjCacheInfo ( CfgMgrProtocol, CM_NULL_TOKEN, &CacheStructList, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index fd2a321bfb..a162d614f9 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -163,19 +163,18 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 17 - GIC ITS Identifier Array NULL, ///< 18 - ID Mapping Array NULL, ///< 19 - SMMU Interrupt Array - TokenFixerNotImplemented, ///< 21 - Cache Info - NULL, ///< 22 - CMN-600 Info - NULL, ///< 23 - Reserved Memory Range Node - NULL, ///< 24 - Memory Range Descriptor - NULL, ///< 25 - Continuous Performance Control Info - NULL, ///< 26 - Pcc Subspace Type 0 Info - NULL, ///< 27 - Pcc Subspace Type 2 Info - NULL, ///< 28 - Pcc Subspace Type 2 Info - NULL, ///< 29 - Pcc Subspace Type 3 Info - NULL, ///< 30 - Pcc Subspace Type 4 Info - NULL, ///< 31 - Pcc Subspace Type 5 Info - NULL, ///< 32 - Embedded Trace Extension/Module Info - NULL ///< 33 - P-State Dependency (PSD) Info + NULL, ///< 20 - CMN-600 Info + NULL, ///< 21 - Reserved Memory Range Node + NULL, ///< 22 - Memory Range Descriptor + NULL, ///< 23 - Continuous Performance Control Info + NULL, ///< 24 - Pcc Subspace Type 0 Info + NULL, ///< 25 - Pcc Subspace Type 2 Info + NULL, ///< 26 - Pcc Subspace Type 2 Info + NULL, ///< 27 - Pcc Subspace Type 3 Info + NULL, ///< 28 - Pcc Subspace Type 4 Info + NULL, ///< 29 - Pcc Subspace Type 5 Info + NULL, ///< 30 - Embedded Trace Extension/Module Info + NULL ///< 31 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index c48e29e505..5440f9993b 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -337,9 +337,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonProcHierarchyInfoParser[] = { { "OverrideUid", 4, "0x%x", NULL } }; -/** A parser for EArmObjCacheInfo. +/** A parser for EArchCommonObjCacheInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmCacheInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonCacheInfoParser[] = { { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, { "NextLevelOfCacheToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }, { "Size", 4, "0x%x", NULL }, @@ -687,6 +687,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjGenericInitiatorAffinityInfo,CmArchCommonGenericInitiatorAffinityInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjLpiInfo, CmArchCommonLpiInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjProcHierarchyInfo, CmArchCommonProcHierarchyInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjCacheInfo, CmArchCommonCacheInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -713,7 +714,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser), CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser), CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser), - CM_PARSER_ADD_OBJECT (EArmObjCacheInfo, CmArmCacheInfoParser), CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index e0af0fd336..7865731841 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -460,19 +460,18 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 17 | GIC ITS Identifier Array | | | 18 | ID Mapping Array | | | 19 | SMMU Interrupt Array | | -| 20 | Cache Info | Move to Arch Common NS | -| 21 | CMN 600 Info | | -| 22 | Reserved Memory Range Node | | -| 23 | Memory Range Descriptor | | -| 24 | Continuous Performance Control Info | Move to Arch Common NS | -| 25 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 26 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 27 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 28 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 29 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 30 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 31 | Embedded Trace Extension/Module Info | | -| 32 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 20 | CMN 600 Info | | +| 21 | Reserved Memory Range Node | | +| 22 | Memory Range Descriptor | | +| 23 | Continuous Performance Control Info | Move to Arch Common NS | +| 24 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 25 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 26 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 27 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 28 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 29 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 30 | Embedded Trace Extension/Module Info | | +| 31 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 14 | Generic Initiator Affinity Info | | | 15 | Low Power Idle State Info | | | 16 | Processor Hierarchy Info | | +| 17 | Cache Info | | | `*` | All other values are reserved. | | -- cgit From ff249c62e30c3629273f5c4fb77da783f9a5b9a1 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 14:00:01 +0000 Subject: DynamicTablesPkg: Move Continuous perf control info to Arch Common Move the Continuous perfformance control info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SSDT CPU topology generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 19 +++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 37 ++++--------- .../SsdtCpuTopologyGenerator.c | 12 ++--- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 15 +++--- .../ConfigurationManagerObjectParser.c | 6 +-- DynamicTablesPkg/Readme.md | 60 +++++++++++----------- 6 files changed, 74 insertions(+), 75 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 17cd552a3f..63b24de2f2 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -38,6 +38,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjLpiInfo, ///< 15 - Lpi Info EArchCommonObjProcHierarchyInfo, ///< 16 - Processor Hierarchy Info EArchCommonObjCacheInfo, ///< 17 - Cache Info + EArchCommonObjCpcInfo, ///< 18 - Continuous Performance Control Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -432,6 +433,24 @@ typedef struct CmArchCommonCacheInfo { UINT32 CacheId; } CM_ARCH_COMMON_CACHE_INFO; +/** A structure that describes the Cpc information. + + Continuous Performance Control is described in DSDT/SSDT and associated + to cpus/clusters in the cpu topology. + + Unsupported Optional registers should be encoded with NULL resource + Register {(SystemMemory, 0, 0, 0, 0)} + + For values that support Integer or Buffer, integer will be used + if buffer is NULL resource. + If resource is not NULL then Integer must be 0 + + Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control) + + ID: EArchCommonObjCpcInfo +*/ +typedef AML_CPC_INFO CM_ARCH_COMMON_CPC_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index eade2afcd0..b9d1202be3 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,15 +51,14 @@ typedef enum ArmObjectID { EArmObjCmn600Info, ///< 20 - CMN-600 Info EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor - EArmObjCpcInfo, ///< 23 - Continuous Performance Control Info - EArmObjPccSubspaceType0Info, ///< 24 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 25 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 26 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 27 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 28 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 29 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 30 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 31 - P-State Dependency (PSD) Info + EArmObjPccSubspaceType0Info, ///< 23 - Pcc Subspace Type 0 Info + EArmObjPccSubspaceType1Info, ///< 24 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 25 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 26 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 27 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 28 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 29 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 30 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -177,7 +176,7 @@ typedef struct CmArmGicCInfo { UINT32 AffinityFlags; /** Optional field: Reference Token for the Cpc info of this processor. - i.e. a token referencing a CM_ARM_CPC_INFO object. + i.e. a token referencing a CM_ARCH_COMMON_CPC_INFO object. */ CM_OBJECT_TOKEN CpcToken; @@ -715,24 +714,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes the Cpc information. - - Continuous Performance Control is described in DSDT/SSDT and associated - to cpus/clusters in the cpu topology. - - Unsupported Optional registers should be encoded with NULL resource - Register {(SystemMemory, 0, 0, 0, 0)} - - For values that support Integer or Buffer, integer will be used - if buffer is NULL resource. - If resource is not NULL then Integer must be 0 - - Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control) - - ID: EArmObjCpcInfo -*/ -typedef AML_CPC_INFO CM_ARM_CPC_INFO; - /** A structure that describes a PCC Mailbox Register. */ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index d7caca5a3a..8c9d1258b2 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -89,9 +89,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjCpcInfo, - CM_ARM_CPC_INFO + EObjNameSpaceArchCommon, + EArchCommonObjCpcInfo, + CM_ARCH_COMMON_CPC_INFO ); /** @@ -400,10 +400,10 @@ CreateAmlCpcNode ( IN AML_OBJECT_NODE_HANDLE *Node ) { - EFI_STATUS Status; - CM_ARM_CPC_INFO *CpcInfo; + EFI_STATUS Status; + CM_ARCH_COMMON_CPC_INFO *CpcInfo; - Status = GetEArmObjCpcInfo ( + Status = GetEArchCommonObjCpcInfo ( CfgMgrProtocol, GicCInfo->CpcToken, &CpcInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index a162d614f9..68db478c57 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,15 +166,14 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - CMN-600 Info NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor - NULL, ///< 23 - Continuous Performance Control Info - NULL, ///< 24 - Pcc Subspace Type 0 Info + NULL, ///< 23 - Pcc Subspace Type 0 Info + NULL, ///< 24 - Pcc Subspace Type 2 Info NULL, ///< 25 - Pcc Subspace Type 2 Info - NULL, ///< 26 - Pcc Subspace Type 2 Info - NULL, ///< 27 - Pcc Subspace Type 3 Info - NULL, ///< 28 - Pcc Subspace Type 4 Info - NULL, ///< 29 - Pcc Subspace Type 5 Info - NULL, ///< 30 - Embedded Trace Extension/Module Info - NULL ///< 31 - P-State Dependency (PSD) Info + NULL, ///< 26 - Pcc Subspace Type 3 Info + NULL, ///< 27 - Pcc Subspace Type 4 Info + NULL, ///< 28 - Pcc Subspace Type 5 Info + NULL, ///< 29 - Embedded Trace Extension/Module Info + NULL ///< 30 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 5440f9993b..54ecc66c5b 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -479,9 +479,9 @@ STATIC CONST CM_OBJ_PARSER CmArmMemoryRangeDescriptorInfoParser[] = { { "Length", 8, "0x%llx", NULL }, }; -/** A parser for EArmObjCpcInfo. +/** A parser for EArchCommonObjCpcInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonCpcInfoParser[] = { { "Revision", 4, "0x%lx", NULL }, { "HighestPerformanceBuffer", sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE), NULL, NULL, AcpiGenericAddressParser, @@ -688,6 +688,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjLpiInfo, CmArchCommonLpiInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjProcHierarchyInfo, CmArchCommonProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjCacheInfo, CmArchCommonCacheInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjCpcInfo, CmArchCommonCpcInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -717,7 +718,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjCpcInfo, CmArmCpcInfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType0Info, CmArmPccSubspaceType0InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType1Info, CmArmPccSubspaceType1InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 7865731841..8ac9d126b8 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,38 +463,38 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | CMN 600 Info | | | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | -| 23 | Continuous Performance Control Info | Move to Arch Common NS | -| 24 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 25 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 26 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 27 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 28 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 29 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 30 | Embedded Trace Extension/Module Info | | -| 31 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Pcc Subspace Type 0 Info | Move to Arch Common NS | +| 24 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 25 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 26 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 27 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 28 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 29 | Embedded Trace Extension/Module Info | | +| 30 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: -| ID | Description | Comments | -| ---: | :-------------------------- | :--- | -| 0 | Reserved | | -| 1 | Power Management Profile Info | | -| 2 | Serial Port Info | | -| 3 | Serial Console Port Info | | -| 4 | Serial Debug Port Info | | -| 5 | Hypervisor Vendor Id | | -| 6 | Fixed feature flags for FADT | | -| 7 | CM Object Reference | | -| 8 | PCI Configuration Space Info | | -| 9 | PCI Address Map Info | | -| 10 | PCI Interrupt Map Info | | -| 11 | Memory Affinity Info | | -| 12 | Device Handle Acpi | | -| 13 | Device Handle PCI | | -| 14 | Generic Initiator Affinity Info | | -| 15 | Low Power Idle State Info | | -| 16 | Processor Hierarchy Info | | -| 17 | Cache Info | | -| `*` | All other values are reserved. | | +| ID | Description | Comments | +| ---: | :-------------------------- | :--- | +| 0 | Reserved | | +| 1 | Power Management Profile Info | | +| 2 | Serial Port Info | | +| 3 | Serial Console Port Info | | +| 4 | Serial Debug Port Info | | +| 5 | Hypervisor Vendor Id | | +| 6 | Fixed feature flags for FADT | | +| 7 | CM Object Reference | | +| 8 | PCI Configuration Space Info | | +| 9 | PCI Address Map Info | | +| 10 | PCI Interrupt Map Info | | +| 11 | Memory Affinity Info | | +| 12 | Device Handle Acpi | | +| 13 | Device Handle PCI | | +| 14 | Generic Initiator Affinity Info | | +| 15 | Low Power Idle State Info | | +| 16 | Processor Hierarchy Info | | +| 17 | Cache Info | | +| 18 | Continuous Performance Control Info | | +| `*` | All other values are reserved. | | -- cgit From b0ecf17a31a2e372d4bf33185a10f60480c5cc0f Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 14:26:15 +0000 Subject: DynamicTablesPkg: Move PCC structure definitions to Arch Common Move PCC structure definitions from Arm Namespace header file to the Arch Common namespace header file. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 72 ++++++++++++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 72 ---------------------- 2 files changed, 72 insertions(+), 72 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 63b24de2f2..e21e2ca4e0 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -451,6 +451,78 @@ typedef struct CmArchCommonCacheInfo { */ typedef AML_CPC_INFO CM_ARCH_COMMON_CPC_INFO; +/** A structure that describes a + PCC Mailbox Register. +*/ +typedef struct PccMailboxRegisterInfo { + /// GAS describing the Register. + EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE Register; + + /** Mask of bits to preserve when writing. + + This mask is also used for registers. The Register is only read + and there is no write mask required. E.g.: + - Error Status mask (Cf. PCC Subspace types 3/4/5). + - Command Complete Check mask (Cf. PCC Subspace types 3/4/5). + */ + UINT64 PreserveMask; + + /// Mask of bits to set when writing. + UINT64 WriteMask; +} PCC_MAILBOX_REGISTER_INFO; + +/** A structure that describes the + PCC Subspace CHannel Timings. +*/ +typedef struct PccSubspaceChannelTimingInfo { + /// Expected latency to process a command, in microseconds. + UINT32 NominalLatency; + + /** Maximum number of periodic requests that the subspace channel can + support, reported in commands per minute. 0 indicates no limitation. + + This field is ignored for the PCC Subspace type 5 (HW Registers based). + */ + UINT32 MaxPeriodicAccessRate; + + /** Minimum amount of time that OSPM must wait after the completion + of a command before issuing the next command, in microseconds. + */ + UINT16 MinRequestTurnaroundTime; +} PCC_SUBSPACE_CHANNEL_TIMING_INFO; + +/** A structure that describes a + Generic PCC Subspace (Type 0). +*/ +typedef struct PccSubspaceGenericInfo { + /** Subspace Id. + + Cf. ACPI 6.4, s14.7 Referencing the PCC address space + Cf. s14.1.2 Platform Communications Channel Subspace Structures + The subspace ID of a PCC subspace is its index in the array of + subspace structures, starting with subspace 0. + + At most 256 subspaces are supported. + */ + UINT8 SubspaceId; + + /// Table type (or subspace). + UINT8 Type; + + /// Base address of the shared memory range. + /// This field is ignored for the PCC Subspace type 5 (HW Registers based). + UINT64 BaseAddress; + + /// Address length. + UINT64 AddressLength; + + /// Doorbell Register. + PCC_MAILBOX_REGISTER_INFO DoorbellReg; + + /// Mailbox Timings. + PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming; +} PCC_SUBSPACE_GENERIC_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index b9d1202be3..e9a2cb0fe6 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -714,78 +714,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes a - PCC Mailbox Register. -*/ -typedef struct PccMailboxRegisterInfo { - /// GAS describing the Register. - EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE Register; - - /** Mask of bits to preserve when writing. - - This mask is also used for registers. The Register is only read - and there is no write mask required. E.g.: - - Error Status mask (Cf. PCC Subspace types 3/4/5). - - Command Complete Check mask (Cf. PCC Subspace types 3/4/5). - */ - UINT64 PreserveMask; - - /// Mask of bits to set when writing. - UINT64 WriteMask; -} PCC_MAILBOX_REGISTER_INFO; - -/** A structure that describes the - PCC Subspace CHannel Timings. -*/ -typedef struct PccSubspaceChannelTimingInfo { - /// Expected latency to process a command, in microseconds. - UINT32 NominalLatency; - - /** Maximum number of periodic requests that the subspace channel can - support, reported in commands per minute. 0 indicates no limitation. - - This field is ignored for the PCC Subspace type 5 (HW Registers based). - */ - UINT32 MaxPeriodicAccessRate; - - /** Minimum amount of time that OSPM must wait after the completion - of a command before issuing the next command, in microseconds. - */ - UINT16 MinRequestTurnaroundTime; -} PCC_SUBSPACE_CHANNEL_TIMING_INFO; - -/** A structure that describes a - Generic PCC Subspace (Type 0). -*/ -typedef struct CmArmPccSubspaceGenericInfo { - /** Subspace Id. - - Cf. ACPI 6.4, s14.7 Referencing the PCC address space - Cf. s14.1.2 Platform Communications Channel Subspace Structures - The subspace ID of a PCC subspace is its index in the array of - subspace structures, starting with subspace 0. - - At most 256 subspaces are supported. - */ - UINT8 SubspaceId; - - /// Table type (or subspace). - UINT8 Type; - - /// Base address of the shared memory range. - /// This field is ignored for the PCC Subspace type 5 (HW Registers based). - UINT64 BaseAddress; - - /// Address length. - UINT64 AddressLength; - - /// Doorbell Register. - PCC_MAILBOX_REGISTER_INFO DoorbellReg; - - /// Mailbox Timings. - PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming; -} PCC_SUBSPACE_GENERIC_INFO; - /** A structure that describes a PCC Subspace of type 0 (Generic). -- cgit From db4496d30a4a48e7c3aceb742cc681b2cc50da64 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 15:11:36 +0000 Subject: DynamicTablesPkg: Move PCC Type0 info to Arch Common Move the PCC Subspace Type0 info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PCCT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 8 ++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 22 ++--- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 104 +++++++++++---------- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h | 5 +- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 13 ++- .../ConfigurationManagerObjectParser.c | 22 ++--- DynamicTablesPkg/Readme.md | 16 ++-- 7 files changed, 96 insertions(+), 94 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index e21e2ca4e0..4ce2d7b48e 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -39,6 +39,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjProcHierarchyInfo, ///< 16 - Processor Hierarchy Info EArchCommonObjCacheInfo, ///< 17 - Cache Info EArchCommonObjCpcInfo, ///< 18 - Continuous Performance Control Info + EArchCommonObjPccSubspaceType0Info, ///< 19 - Pcc Subspace Type 0 Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -523,6 +524,13 @@ typedef struct PccSubspaceGenericInfo { PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming; } PCC_SUBSPACE_GENERIC_INFO; +/** A structure that describes a + PCC Subspace of type 0 (Generic). + + ID: EArchCommonObjPccSubspaceType0Info +*/ +typedef PCC_SUBSPACE_GENERIC_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index e9a2cb0fe6..a28415c776 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,14 +51,13 @@ typedef enum ArmObjectID { EArmObjCmn600Info, ///< 20 - CMN-600 Info EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor - EArmObjPccSubspaceType0Info, ///< 23 - Pcc Subspace Type 0 Info - EArmObjPccSubspaceType1Info, ///< 24 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 25 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 26 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 27 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 28 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 29 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 30 - P-State Dependency (PSD) Info + EArmObjPccSubspaceType1Info, ///< 23 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType2Info, ///< 24 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 25 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 26 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 27 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 28 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 29 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -714,13 +713,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes a - PCC Subspace of type 0 (Generic). - - ID: EArmObjPccSubspaceType0Info -*/ -typedef PCC_SUBSPACE_GENERIC_INFO CM_ARM_PCC_SUBSPACE_TYPE0_INFO; - /** A structure that describes a PCC Subspace of type 1 (HW-Reduced). diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c index 36caf4aaea..575ab31f7f 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c @@ -29,7 +29,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjPccSubspaceType0Info + - EArchCommonObjPccSubspaceType0Info - EArmObjPccSubspaceType1Info - EArmObjPccSubspaceType2Info - EArmObjPccSubspaceType3Info @@ -41,9 +41,9 @@ Requirements: Subspace of Type 0 Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPccSubspaceType0Info, - CM_ARM_PCC_SUBSPACE_TYPE0_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType0Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO ); /** This macro expands to a function that retrieves the PCC @@ -164,11 +164,12 @@ MappingTableFree ( } } -/** Add a new entry for CmArmPccSubspace at Index. +/** Add a new entry for PccSubspace at Index. @param [in] MappingTable The mapping table structure. - @param [in] CmArmPccSubspace Pointer to a CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO. - @param [in] Index Index at which CmArmPccSubspace must be added. + @param [in] PccSubspace A pointer to + CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO. + @param [in] Index Index at which PccSubspace must be added. This is the Subspace Id. @retval EFI_SUCCESS Success. @@ -180,13 +181,13 @@ EFI_STATUS EFIAPI MappingTableAdd ( IN MAPPING_TABLE *MappingTable, - IN VOID *CmArmPccSubspace, + IN VOID *PccSubspace, IN UINT32 Index ) { if ((MappingTable == NULL) || (MappingTable->Table == NULL) || - (CmArmPccSubspace == NULL)) + (PccSubspace == NULL)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; @@ -200,14 +201,15 @@ MappingTableAdd ( } // Just map the Pcc Subspace in the Table. - MappingTable->Table[Index] = CmArmPccSubspace; + MappingTable->Table[Index] = PccSubspace; return EFI_SUCCESS; } /** Parse the CmPccArray objects and add them to the MappingTable. @param [in] MappingTable The mapping table structure. - @param [in] CmPccArray Pointer to an array of CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO. + @param [in] CmPccArray Pointer to an array of + CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO. @param [in] CmPccCount Count of objects in CmPccArray. @retval EFI_SUCCESS Success. @@ -242,7 +244,7 @@ MapPccSubspaceId ( switch (GenericPcc->Type) { case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: - CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE0_INFO); + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO); break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: @@ -304,8 +306,8 @@ STATIC EFI_STATUS EFIAPI AddSubspaceStructType0 ( - IN CM_ARM_PCC_SUBSPACE_TYPE0_INFO *PccCmObj, - IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccCmObj, + IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi ) { PCC_MAILBOX_REGISTER_INFO *Doorbell; @@ -360,11 +362,11 @@ AddSubspaceStructType1 ( IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi ) { - CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; if ((PccCmObj == NULL) || (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS) || @@ -420,12 +422,12 @@ AddSubspaceStructType2 ( IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi ) { - CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; if ((PccCmObj == NULL) || (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS) || @@ -491,15 +493,15 @@ AddSubspaceStructType34 ( IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi ) { - CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; - PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; - PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate; - PCC_MAILBOX_REGISTER_INFO *ErrorStatus; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; + PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; + PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate; + PCC_MAILBOX_REGISTER_INFO *ErrorStatus; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; if ((PccCmObj == NULL) || ((GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC) && @@ -603,13 +605,13 @@ AddSubspaceStructType5 ( IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi ) { - CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; - PCC_MAILBOX_REGISTER_INFO *ErrorStatus; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; + PCC_MAILBOX_REGISTER_INFO *ErrorStatus; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; if ((PccCmObj == NULL) || (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS) || @@ -705,7 +707,7 @@ PopulatePcctTable ( switch (((PCC_SUBSPACE_GENERIC_INFO *)CurrentPccSubspace)->Type) { case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: Status = AddSubspaceStructType0 ( - (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace, + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace, (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *)PccBuffer ); @@ -822,18 +824,18 @@ BuildPcctTable ( MAPPING_TABLE *MappingTable; UINT32 MappingTableCount; - CM_ARM_PCC_SUBSPACE_TYPE0_INFO *PccType0; - UINT32 PccType0Count; - CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccType1; - UINT32 PccType1Count; - CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccType2; - UINT32 PccType2Count; - CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccType3; - UINT32 PccType3Count; - CM_ARM_PCC_SUBSPACE_TYPE4_INFO *PccType4; - UINT32 PccType4Count; - CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccType5; - UINT32 PccType5Count; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccType0; + UINT32 PccType0Count; + CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccType1; + UINT32 PccType1Count; + CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccType2; + UINT32 PccType2Count; + CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccType3; + UINT32 PccType3Count; + CM_ARM_PCC_SUBSPACE_TYPE4_INFO *PccType4; + UINT32 PccType4Count; + CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccType5; + UINT32 PccType5Count; ASSERT (This != NULL); ASSERT (AcpiTableInfo != NULL); @@ -863,7 +865,7 @@ BuildPcctTable ( // First get all the Pcc Subpace CmObj of type X. - Status = GetEArmObjPccSubspaceType0Info ( + Status = GetEArchCommonObjPccSubspaceType0Info ( CfgMgrProtocol, CM_NULL_TOKEN, &PccType0, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h index 0631a1f5b7..e1bca78c2f 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h @@ -19,7 +19,7 @@ */ typedef struct MappingTable { /// Mapping table for Subspace Ids. - /// Subspace ID/Index <-> CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO pointer + /// Subspace ID/Index <-> CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO pointer VOID **Table; /// Number of entries in the Table. @@ -34,7 +34,8 @@ typedef struct AcpiPcctGenerator { // Private fields are defined from here. - /// Table to map: Subspace ID/Index <-> CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO pointer + /// Table to map: + /// Subspace ID/Index <-> CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO pointer MAPPING_TABLE MappingTable; } ACPI_PCCT_GENERATOR; diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 68db478c57..1691e6015b 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,14 +166,13 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - CMN-600 Info NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor - NULL, ///< 23 - Pcc Subspace Type 0 Info + NULL, ///< 23 - Pcc Subspace Type 2 Info NULL, ///< 24 - Pcc Subspace Type 2 Info - NULL, ///< 25 - Pcc Subspace Type 2 Info - NULL, ///< 26 - Pcc Subspace Type 3 Info - NULL, ///< 27 - Pcc Subspace Type 4 Info - NULL, ///< 28 - Pcc Subspace Type 5 Info - NULL, ///< 29 - Embedded Trace Extension/Module Info - NULL ///< 30 - P-State Dependency (PSD) Info + NULL, ///< 25 - Pcc Subspace Type 3 Info + NULL, ///< 26 - Pcc Subspace Type 4 Info + NULL, ///< 27 - Pcc Subspace Type 5 Info + NULL, ///< 28 - Embedded Trace Extension/Module Info + NULL ///< 29 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 54ecc66c5b..e071fa460a 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -574,9 +574,9 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceChannelTimingInfoParser[] = { { "MinRequestTurnaroundTime", 2, "0x%x", NULL }, }; -/** A parser for EArmObjPccSubspaceType0Info. +/** A parser for EArchCommonObjPccSubspaceType0Info. */ -STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType0InfoParser[] = { { "SubspaceId", 1, "0x%x", NULL }, { "Type", 1, "0x%x", NULL }, { "BaseAddress", 8, "0x%llx", NULL }, @@ -593,8 +593,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = { */ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), - NULL, NULL, CmArmPccSubspaceType0InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, + NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, + ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT), NULL, NULL, CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, @@ -604,8 +604,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = { */ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), - NULL, NULL, CmArmPccSubspaceType0InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, + NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, + ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL,NULL, CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, { "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO), @@ -617,8 +617,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = { */ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), - NULL, NULL, CmArmPccSubspaceType0InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, + NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, + ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL,NULL, CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, { "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO), @@ -639,8 +639,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = { */ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType5InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), - NULL, NULL, CmArmPccSubspaceType0InfoParser, - ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) }, + NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, + ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, { "Version", 2, "0x%x",NULL }, { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL, NULL, CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, @@ -689,6 +689,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjProcHierarchyInfo, CmArchCommonProcHierarchyInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjCacheInfo, CmArchCommonCacheInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjCpcInfo, CmArchCommonCpcInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType0Info, CmArchCommonPccSubspaceType0InfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -718,7 +719,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType0Info, CmArmPccSubspaceType0InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType1Info, CmArmPccSubspaceType1InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 8ac9d126b8..9994220359 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,14 +463,13 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | CMN 600 Info | | | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | -| 23 | Pcc Subspace Type 0 Info | Move to Arch Common NS | -| 24 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 25 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 26 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 27 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 28 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 29 | Embedded Trace Extension/Module Info | | -| 30 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Pcc Subspace Type 1 Info | Move to Arch Common NS | +| 24 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 25 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 26 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 27 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 28 | Embedded Trace Extension/Module Info | | +| 29 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 16 | Processor Hierarchy Info | | | 17 | Cache Info | | | 18 | Continuous Performance Control Info | | +| 19 | Pcc Subspace Type 0 Info | | | `*` | All other values are reserved. | | -- cgit From 870cf728ef82c398f1a4b1e2031046a699eadb6e Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 15:20:39 +0000 Subject: DynamicTablesPkg: Move PCC Type1 info to Arch Common Move the PCC Subspace Type1 info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PCCT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 18 +++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 30 +++++----------------- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 18 ++++++------- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 11 ++++---- .../ConfigurationManagerObjectParser.c | 6 ++--- DynamicTablesPkg/Readme.md | 14 +++++----- 6 files changed, 48 insertions(+), 49 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 4ce2d7b48e..583ea00891 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -40,6 +40,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjCacheInfo, ///< 17 - Cache Info EArchCommonObjCpcInfo, ///< 18 - Continuous Performance Control Info EArchCommonObjPccSubspaceType0Info, ///< 19 - Pcc Subspace Type 0 Info + EArchCommonObjPccSubspaceType1Info, ///< 20 - Pcc Subspace Type 1 Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -531,6 +532,23 @@ typedef struct PccSubspaceGenericInfo { */ typedef PCC_SUBSPACE_GENERIC_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO; +/** A structure that describes a + PCC Subspace of type 1 (HW-Reduced). + + ID: EArchCommonObjPccSubspaceType1Info +*/ +typedef struct CmArchCommonPccSubspaceType1Info { + /** Generic Pcc information. + + The Subspace of Type0 contains information that can be re-used + in other Subspace types. + */ + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + + /// Platform Interrupt. + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; +} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index a28415c776..8a62d93862 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,13 +51,12 @@ typedef enum ArmObjectID { EArmObjCmn600Info, ///< 20 - CMN-600 Info EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor - EArmObjPccSubspaceType1Info, ///< 23 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType2Info, ///< 24 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 25 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 26 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 27 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 28 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 29 - P-State Dependency (PSD) Info + EArmObjPccSubspaceType2Info, ///< 23 - Pcc Subspace Type 2 Info + EArmObjPccSubspaceType3Info, ///< 24 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 25 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 26 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 27 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 28 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -713,23 +712,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes a - PCC Subspace of type 1 (HW-Reduced). - - ID: EArmObjPccSubspaceType1Info -*/ -typedef struct CmArmPccSubspaceType1Info { - /** Generic Pcc information. - - The Subspace of Type0 contains information that can be re-used - in other Subspace types. - */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; - - /// Platform Interrupt. - CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; -} CM_ARM_PCC_SUBSPACE_TYPE1_INFO; - /** A structure that describes a PCC Subspace of type 2 (HW-Reduced). diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c index 575ab31f7f..183d8cd221 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c @@ -30,7 +30,7 @@ Requirements: The following Configuration Manager Object(s) are required by this Generator: - EArchCommonObjPccSubspaceType0Info - - EArmObjPccSubspaceType1Info + - EArchCommonObjPccSubspaceType1Info - EArmObjPccSubspaceType2Info - EArmObjPccSubspaceType3Info - EArmObjPccSubspaceType4Info @@ -50,9 +50,9 @@ GET_OBJECT_LIST ( Subspace of Type 1 Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPccSubspaceType1Info, - CM_ARM_PCC_SUBSPACE_TYPE1_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType1Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO ); /** This macro expands to a function that retrieves the PCC @@ -248,7 +248,7 @@ MapPccSubspaceId ( break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: - CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE1_INFO); + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO); break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: @@ -358,7 +358,7 @@ STATIC EFI_STATUS EFIAPI AddSubspaceStructType1 ( - IN CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccCmObj, + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi ) { @@ -716,7 +716,7 @@ PopulatePcctTable ( case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: Status = AddSubspaceStructType1 ( - (CM_ARM_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace, + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace, (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *)PccBuffer ); @@ -826,7 +826,7 @@ BuildPcctTable ( CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccType0; UINT32 PccType0Count; - CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccType1; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccType1; UINT32 PccType1Count; CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccType2; UINT32 PccType2Count; @@ -876,7 +876,7 @@ BuildPcctTable ( goto error_handler; } - Status = GetEArmObjPccSubspaceType1Info ( + Status = GetEArchCommonObjPccSubspaceType1Info ( CfgMgrProtocol, CM_NULL_TOKEN, &PccType1, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 1691e6015b..3a19870aad 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -167,12 +167,11 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor NULL, ///< 23 - Pcc Subspace Type 2 Info - NULL, ///< 24 - Pcc Subspace Type 2 Info - NULL, ///< 25 - Pcc Subspace Type 3 Info - NULL, ///< 26 - Pcc Subspace Type 4 Info - NULL, ///< 27 - Pcc Subspace Type 5 Info - NULL, ///< 28 - Embedded Trace Extension/Module Info - NULL ///< 29 - P-State Dependency (PSD) Info + NULL, ///< 24 - Pcc Subspace Type 3 Info + NULL, ///< 25 - Pcc Subspace Type 4 Info + NULL, ///< 26 - Pcc Subspace Type 5 Info + NULL, ///< 27 - Embedded Trace Extension/Module Info + NULL ///< 28 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index e071fa460a..f8e277f180 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -589,9 +589,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType0InfoParser[] = { ARRAY_SIZE (CmArmPccSubspaceChannelTimingInfoParser) }, }; -/** A parser for EArmObjPccSubspaceType1Info. +/** A parser for EArchCommonObjPccSubspaceType1Info. */ -STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType1InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, @@ -690,6 +690,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjCacheInfo, CmArchCommonCacheInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjCpcInfo, CmArchCommonCpcInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType0Info, CmArchCommonPccSubspaceType0InfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType1Info, CmArchCommonPccSubspaceType1InfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -719,7 +720,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType1Info, CmArmPccSubspaceType1InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType4Info, CmArmPccSubspaceType34InfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 9994220359..3fa3dd9af9 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,13 +463,12 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | CMN 600 Info | | | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | -| 23 | Pcc Subspace Type 1 Info | Move to Arch Common NS | -| 24 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 25 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 26 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 27 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 28 | Embedded Trace Extension/Module Info | | -| 29 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Pcc Subspace Type 2 Info | Move to Arch Common NS | +| 24 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 25 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 26 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 27 | Embedded Trace Extension/Module Info | | +| 28 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 17 | Cache Info | | | 18 | Continuous Performance Control Info | | | 19 | Pcc Subspace Type 0 Info | | +| 20 | Pcc Subspace Type 1 Info | | | `*` | All other values are reserved. | | -- cgit From 78b77d9ec4114df1177185c4f69ad89da9610599 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 15:26:56 +0000 Subject: DynamicTablesPkg: Move PCC Type2 info to Arch Common Move the PCC Subspace Type2 info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PCCT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 21 +++++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 31 ++++------------------ .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 18 ++++++------- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 11 ++++---- .../ConfigurationManagerObjectParser.c | 6 ++--- DynamicTablesPkg/Readme.md | 12 ++++----- 6 files changed, 49 insertions(+), 50 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 583ea00891..817c07f40d 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -41,6 +41,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjCpcInfo, ///< 18 - Continuous Performance Control Info EArchCommonObjPccSubspaceType0Info, ///< 19 - Pcc Subspace Type 0 Info EArchCommonObjPccSubspaceType1Info, ///< 20 - Pcc Subspace Type 1 Info + EArchCommonObjPccSubspaceType2Info, ///< 21 - Pcc Subspace Type 2 Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -549,6 +550,26 @@ typedef struct CmArchCommonPccSubspaceType1Info { CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; } CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO; +/** A structure that describes a + PCC Subspace of type 2 (HW-Reduced). + + ID: EArchCommonObjPccSubspaceType2Info +*/ +typedef struct CmArchCommonPccSubspaceType2Info { + /** Generic Pcc information. + + The Subspace of Type0 contains information that can be re-used + in other Subspace types. + */ + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + + /// Platform Interrupt. + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; + + /// Platform Interrupt Register. + PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; +} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 8a62d93862..c287a855da 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,12 +51,11 @@ typedef enum ArmObjectID { EArmObjCmn600Info, ///< 20 - CMN-600 Info EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor - EArmObjPccSubspaceType2Info, ///< 23 - Pcc Subspace Type 2 Info - EArmObjPccSubspaceType3Info, ///< 24 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 25 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 26 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 27 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 28 - P-State Dependency (PSD) Info + EArmObjPccSubspaceType3Info, ///< 23 - Pcc Subspace Type 3 Info + EArmObjPccSubspaceType4Info, ///< 24 - Pcc Subspace Type 4 Info + EArmObjPccSubspaceType5Info, ///< 25 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 26 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 27 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -712,26 +711,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes a - PCC Subspace of type 2 (HW-Reduced). - - ID: EArmObjPccSubspaceType2Info -*/ -typedef struct CmArmPccSubspaceType2Info { - /** Generic Pcc information. - - The Subspace of Type0 contains information that can be re-used - in other Subspace types. - */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; - - /// Platform Interrupt. - CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; - - /// Platform Interrupt Register. - PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; -} CM_ARM_PCC_SUBSPACE_TYPE2_INFO; - /** A structure that describes a PCC Subspace of type 3 (Extended) diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c index 183d8cd221..552aca4af4 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c @@ -31,7 +31,7 @@ Requirements: this Generator: - EArchCommonObjPccSubspaceType0Info - EArchCommonObjPccSubspaceType1Info - - EArmObjPccSubspaceType2Info + - EArchCommonObjPccSubspaceType2Info - EArmObjPccSubspaceType3Info - EArmObjPccSubspaceType4Info - EArmObjPccSubspaceType5Info @@ -59,9 +59,9 @@ GET_OBJECT_LIST ( Subspace of Type 2 Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPccSubspaceType2Info, - CM_ARM_PCC_SUBSPACE_TYPE2_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType2Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO ); /** This macro expands to a function that retrieves the PCC @@ -252,7 +252,7 @@ MapPccSubspaceId ( break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: - CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE2_INFO); + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO); break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: @@ -418,7 +418,7 @@ STATIC EFI_STATUS EFIAPI AddSubspaceStructType2 ( - IN CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccCmObj, + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi ) { @@ -725,7 +725,7 @@ PopulatePcctTable ( case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: Status = AddSubspaceStructType2 ( - (CM_ARM_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace, + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace, (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)PccBuffer ); @@ -828,7 +828,7 @@ BuildPcctTable ( UINT32 PccType0Count; CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccType1; UINT32 PccType1Count; - CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccType2; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccType2; UINT32 PccType2Count; CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccType3; UINT32 PccType3Count; @@ -887,7 +887,7 @@ BuildPcctTable ( goto error_handler; } - Status = GetEArmObjPccSubspaceType2Info ( + Status = GetEArchCommonObjPccSubspaceType2Info ( CfgMgrProtocol, CM_NULL_TOKEN, &PccType2, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 3a19870aad..b73d0ded95 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,12 +166,11 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - CMN-600 Info NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor - NULL, ///< 23 - Pcc Subspace Type 2 Info - NULL, ///< 24 - Pcc Subspace Type 3 Info - NULL, ///< 25 - Pcc Subspace Type 4 Info - NULL, ///< 26 - Pcc Subspace Type 5 Info - NULL, ///< 27 - Embedded Trace Extension/Module Info - NULL ///< 28 - P-State Dependency (PSD) Info + NULL, ///< 23 - Pcc Subspace Type 3 Info + NULL, ///< 24 - Pcc Subspace Type 4 Info + NULL, ///< 25 - Pcc Subspace Type 5 Info + NULL, ///< 26 - Embedded Trace Extension/Module Info + NULL ///< 27 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index f8e277f180..c3e18b5a95 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -600,9 +600,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType1InfoParser[] = { ARRAY_SIZE (CmArchCommonGenericInterruptParser) }, }; -/** A parser for EArmObjPccSubspaceType2Info. +/** A parser for EArchCommonObjPccSubspaceType2Info. */ -STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType2InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, @@ -691,6 +691,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjCpcInfo, CmArchCommonCpcInfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType0Info, CmArchCommonPccSubspaceType0InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType1Info, CmArchCommonPccSubspaceType1InfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType2Info, CmArchCommonPccSubspaceType2InfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -720,7 +721,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType2Info, CmArmPccSubspaceType2InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType4Info, CmArmPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType5Info, CmArmPccSubspaceType5InfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 3fa3dd9af9..59b6f8d1ea 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,12 +463,11 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | CMN 600 Info | | | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | -| 23 | Pcc Subspace Type 2 Info | Move to Arch Common NS | -| 24 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 25 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 26 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 27 | Embedded Trace Extension/Module Info | | -| 28 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Pcc Subspace Type 3 Info | Move to Arch Common NS | +| 24 | Pcc Subspace Type 4 Info | Move to Arch Common NS | +| 25 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 26 | Embedded Trace Extension/Module Info | | +| 27 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 18 | Continuous Performance Control Info | | | 19 | Pcc Subspace Type 0 Info | | | 20 | Pcc Subspace Type 1 Info | | +| 21 | Pcc Subspace Type 2 Info | | | `*` | All other values are reserved. | | -- cgit From e8119798b189edb6e40cd9d472159d1db62e6ca5 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 15:38:58 +0000 Subject: DynamicTablesPkg: Move PCC Type 3 & 4 info to Arch Common Move the PCC Subspace Type 3 & 4 info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PCCT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 40 +++++++++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 46 ++-------------------- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 34 ++++++++-------- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 8 ++-- .../ConfigurationManagerObjectParser.c | 8 ++-- DynamicTablesPkg/Readme.md | 10 ++--- 6 files changed, 72 insertions(+), 74 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 817c07f40d..d4de70af5a 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -42,6 +42,8 @@ typedef enum ArchCommonObjectID { EArchCommonObjPccSubspaceType0Info, ///< 19 - Pcc Subspace Type 0 Info EArchCommonObjPccSubspaceType1Info, ///< 20 - Pcc Subspace Type 1 Info EArchCommonObjPccSubspaceType2Info, ///< 21 - Pcc Subspace Type 2 Info + EArchCommonObjPccSubspaceType3Info, ///< 22 - Pcc Subspace Type 3 Info + EArchCommonObjPccSubspaceType4Info, ///< 23 - Pcc Subspace Type 4 Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -570,6 +572,44 @@ typedef struct CmArchCommonPccSubspaceType2Info { PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; } CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO; +/** A structure that describes a + PCC Subspace of type 3 (Extended) + + ID: EArchCommonObjPccSubspaceType3Info +*/ +typedef struct CmArchCommonPccSubspaceType3Info { + /** Generic Pcc information. + + The Subspace of Type0 contains information that can be re-used + in other Subspace types. + */ + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + + /// Platform Interrupt. + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; + + /// Platform Interrupt Register. + PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; + + /// Command Complete Check Register. + /// The WriteMask field is not used. + PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; + + /// Command Complete Update Register. + PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg; + + /// Error Status Register. + /// The WriteMask field is not used. + PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; +} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO; + +/** A structure that describes a + PCC Subspace of type 4 (Extended) + + ID: EArchCommonObjPccSubspaceType4Info +*/ +typedef CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index c287a855da..7977cef07a 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,11 +51,9 @@ typedef enum ArmObjectID { EArmObjCmn600Info, ///< 20 - CMN-600 Info EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor - EArmObjPccSubspaceType3Info, ///< 23 - Pcc Subspace Type 3 Info - EArmObjPccSubspaceType4Info, ///< 24 - Pcc Subspace Type 4 Info - EArmObjPccSubspaceType5Info, ///< 25 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 26 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 27 - P-State Dependency (PSD) Info + EArmObjPccSubspaceType5Info, ///< 23 - Pcc Subspace Type 5 Info + EArmObjEtInfo, ///< 24 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 25 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -711,44 +709,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes a - PCC Subspace of type 3 (Extended) - - ID: EArmObjPccSubspaceType3Info -*/ -typedef struct CmArmPccSubspaceType3Info { - /** Generic Pcc information. - - The Subspace of Type0 contains information that can be re-used - in other Subspace types. - */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; - - /// Platform Interrupt. - CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; - - /// Platform Interrupt Register. - PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg; - - /// Command Complete Check Register. - /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; - - /// Command Complete Update Register. - PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg; - - /// Error Status Register. - /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; -} CM_ARM_PCC_SUBSPACE_TYPE3_INFO; - -/** A structure that describes a - PCC Subspace of type 4 (Extended) - - ID: EArmObjPccSubspaceType4Info -*/ -typedef CM_ARM_PCC_SUBSPACE_TYPE3_INFO CM_ARM_PCC_SUBSPACE_TYPE4_INFO; - /** A structure that describes a PCC Subspace of type 5 (HW-Registers). diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c index 552aca4af4..0df6429b0f 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c @@ -32,8 +32,8 @@ Requirements: - EArchCommonObjPccSubspaceType0Info - EArchCommonObjPccSubspaceType1Info - EArchCommonObjPccSubspaceType2Info - - EArmObjPccSubspaceType3Info - - EArmObjPccSubspaceType4Info + - EArchCommonObjPccSubspaceType3Info + - EArchCommonObjPccSubspaceType4Info - EArmObjPccSubspaceType5Info */ @@ -68,18 +68,18 @@ GET_OBJECT_LIST ( Subspace of Type 3 Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPccSubspaceType3Info, - CM_ARM_PCC_SUBSPACE_TYPE3_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType3Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO ); /** This macro expands to a function that retrieves the PCC Subspace of Type 4 Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPccSubspaceType4Info, - CM_ARM_PCC_SUBSPACE_TYPE4_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType4Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO ); /** This macro expands to a function that retrieves the PCC @@ -256,11 +256,11 @@ MapPccSubspaceId ( break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: - CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE3_INFO); + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO); break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: - CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE4_INFO); + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO); break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: @@ -489,7 +489,7 @@ STATIC EFI_STATUS EFIAPI AddSubspaceStructType34 ( - IN CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccCmObj, + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi ) { @@ -734,7 +734,7 @@ PopulatePcctTable ( case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: Status = AddSubspaceStructType34 ( - (CM_ARM_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace, + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace, (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *)PccBuffer ); @@ -743,7 +743,7 @@ PopulatePcctTable ( case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: Status = AddSubspaceStructType34 ( - (CM_ARM_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace, + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace, (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC *)PccBuffer ); @@ -830,9 +830,9 @@ BuildPcctTable ( UINT32 PccType1Count; CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccType2; UINT32 PccType2Count; - CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccType3; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccType3; UINT32 PccType3Count; - CM_ARM_PCC_SUBSPACE_TYPE4_INFO *PccType4; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *PccType4; UINT32 PccType4Count; CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccType5; UINT32 PccType5Count; @@ -898,7 +898,7 @@ BuildPcctTable ( goto error_handler; } - Status = GetEArmObjPccSubspaceType3Info ( + Status = GetEArchCommonObjPccSubspaceType3Info ( CfgMgrProtocol, CM_NULL_TOKEN, &PccType3, @@ -909,7 +909,7 @@ BuildPcctTable ( goto error_handler; } - Status = GetEArmObjPccSubspaceType4Info ( + Status = GetEArchCommonObjPccSubspaceType4Info ( CfgMgrProtocol, CM_NULL_TOKEN, &PccType4, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index b73d0ded95..112bef7151 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,11 +166,9 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - CMN-600 Info NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor - NULL, ///< 23 - Pcc Subspace Type 3 Info - NULL, ///< 24 - Pcc Subspace Type 4 Info - NULL, ///< 25 - Pcc Subspace Type 5 Info - NULL, ///< 26 - Embedded Trace Extension/Module Info - NULL ///< 27 - P-State Dependency (PSD) Info + NULL, ///< 23 - Pcc Subspace Type 5 Info + NULL, ///< 24 - Embedded Trace Extension/Module Info + NULL ///< 25 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index c3e18b5a95..5f08f514fa 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -613,9 +613,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType2InfoParser[] = { ARRAY_SIZE (CmArmMailboxRegisterInfoParser) }, }; -/** A parser for EArmObjPccSubspaceType3Info or EArmObjPccSubspaceType4Info. +/** A parser for EArchCommonObjPccSubspaceType3Info or EArchCommonObjPccSubspaceType4Info. */ -STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType34InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, @@ -692,6 +692,8 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType0Info, CmArchCommonPccSubspaceType0InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType1Info, CmArchCommonPccSubspaceType1InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType2Info, CmArchCommonPccSubspaceType2InfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType3Info, CmArchCommonPccSubspaceType34InfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType4Info, CmArchCommonPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -721,8 +723,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType3Info, CmArmPccSubspaceType34InfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType4Info, CmArmPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType5Info, CmArmPccSubspaceType5InfoParser), CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo), CM_PARSER_ADD_OBJECT (EArmObjPsdInfo, CmArmPsdInfoParser), diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 59b6f8d1ea..1e45bcd597 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,11 +463,9 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | CMN 600 Info | | | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | -| 23 | Pcc Subspace Type 3 Info | Move to Arch Common NS | -| 24 | Pcc Subspace Type 4 Info | Move to Arch Common NS | -| 25 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 26 | Embedded Trace Extension/Module Info | | -| 27 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Pcc Subspace Type 5 Info | Move to Arch Common NS | +| 24 | Embedded Trace Extension/Module Info | | +| 25 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +494,7 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 19 | Pcc Subspace Type 0 Info | | | 20 | Pcc Subspace Type 1 Info | | | 21 | Pcc Subspace Type 2 Info | | +| 22 | Pcc Subspace Type 3 Info | | +| 23 | Pcc Subspace Type 4 Info | | | `*` | All other values are reserved. | | -- cgit From 6466a6e63eb6d808ad9244803edcd2a483f7a121 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 15:45:15 +0000 Subject: DynamicTablesPkg: Move PCC Type 5 info to Arch Common Move the PCC Subspace Type 5 info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - PCCT generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- .../Include/ArchCommonNameSpaceObjects.h | 32 +++++++++++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 36 ++-------------------- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 22 ++++++------- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h | 4 +-- .../Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 5 ++- .../ConfigurationManagerObjectParser.c | 6 ++-- DynamicTablesPkg/Readme.md | 6 ++-- 7 files changed, 55 insertions(+), 56 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index d4de70af5a..58a137e905 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -44,6 +44,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjPccSubspaceType2Info, ///< 21 - Pcc Subspace Type 2 Info EArchCommonObjPccSubspaceType3Info, ///< 22 - Pcc Subspace Type 3 Info EArchCommonObjPccSubspaceType4Info, ///< 23 - Pcc Subspace Type 4 Info + EArchCommonObjPccSubspaceType5Info, ///< 24 - Pcc Subspace Type 5 Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -610,6 +611,37 @@ typedef struct CmArchCommonPccSubspaceType3Info { */ typedef CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO; +/** A structure that describes a + PCC Subspace of type 5 (HW-Registers). + + ID: EArchCommonObjPccSubspaceType5Info +*/ +typedef struct CmArchCommonPccSubspaceType5Info { + /** Generic Pcc information. + + The Subspace of Type0 contains information that can be re-used + in other Subspace types. + + MaximumPeriodicAccessRate doesn't need to be populated for + this structure. + */ + PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; + + /// Version. + UINT16 Version; + + /// Platform Interrupt. + CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; + + /// Command Complete Check Register. + /// The WriteMask field is not used. + PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; + + /// Error Status Register. + /// The WriteMask field is not used. + PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; +} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 7977cef07a..724e614bb6 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -51,9 +51,8 @@ typedef enum ArmObjectID { EArmObjCmn600Info, ///< 20 - CMN-600 Info EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor - EArmObjPccSubspaceType5Info, ///< 23 - Pcc Subspace Type 5 Info - EArmObjEtInfo, ///< 24 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 25 - P-State Dependency (PSD) Info + EArmObjEtInfo, ///< 23 - Embedded Trace Extension/Module Info + EArmObjPsdInfo, ///< 24 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -709,37 +708,6 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; -/** A structure that describes a - PCC Subspace of type 5 (HW-Registers). - - ID: EArmObjPccSubspaceType5Info -*/ -typedef struct CmArmPccSubspaceType5Info { - /** Generic Pcc information. - - The Subspace of Type0 contains information that can be re-used - in other Subspace types. - - MaximumPeriodicAccessRate doesn't need to be populated for - this structure. - */ - PCC_SUBSPACE_GENERIC_INFO GenericPccInfo; - - /// Version. - UINT16 Version; - - /// Platform Interrupt. - CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq; - - /// Command Complete Check Register. - /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg; - - /// Error Status Register. - /// The WriteMask field is not used. - PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; -} CM_ARM_PCC_SUBSPACE_TYPE5_INFO; - /** An enum describing the Arm Embedded Trace device type. */ typedef enum ArmEtType { diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c index 0df6429b0f..205c444057 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c @@ -34,7 +34,7 @@ Requirements: - EArchCommonObjPccSubspaceType2Info - EArchCommonObjPccSubspaceType3Info - EArchCommonObjPccSubspaceType4Info - - EArmObjPccSubspaceType5Info + - EArchCommonObjPccSubspaceType5Info */ /** This macro expands to a function that retrieves the PCC @@ -86,9 +86,9 @@ GET_OBJECT_LIST ( Subspace of Type 5 Information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPccSubspaceType5Info, - CM_ARM_PCC_SUBSPACE_TYPE5_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType5Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO ); /** The Platform is capable of generating an interrupt @@ -168,7 +168,7 @@ MappingTableFree ( @param [in] MappingTable The mapping table structure. @param [in] PccSubspace A pointer to - CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO. + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO. @param [in] Index Index at which PccSubspace must be added. This is the Subspace Id. @@ -209,7 +209,7 @@ MappingTableAdd ( @param [in] MappingTable The mapping table structure. @param [in] CmPccArray Pointer to an array of - CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO. + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO. @param [in] CmPccCount Count of objects in CmPccArray. @retval EFI_SUCCESS Success. @@ -264,7 +264,7 @@ MapPccSubspaceId ( break; case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: - CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE5_INFO); + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO); break; default: @@ -601,7 +601,7 @@ STATIC EFI_STATUS EFIAPI AddSubspaceStructType5 ( - IN CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccCmObj, + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi ) { @@ -752,7 +752,7 @@ PopulatePcctTable ( case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: Status = AddSubspaceStructType5 ( - (CM_ARM_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace, + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace, (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *)PccBuffer ); @@ -834,7 +834,7 @@ BuildPcctTable ( UINT32 PccType3Count; CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *PccType4; UINT32 PccType4Count; - CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccType5; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccType5; UINT32 PccType5Count; ASSERT (This != NULL); @@ -920,7 +920,7 @@ BuildPcctTable ( goto error_handler; } - Status = GetEArmObjPccSubspaceType5Info ( + Status = GetEArchCommonObjPccSubspaceType5Info ( CfgMgrProtocol, CM_NULL_TOKEN, &PccType5, diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h index e1bca78c2f..b99bf91b41 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h @@ -19,7 +19,7 @@ */ typedef struct MappingTable { /// Mapping table for Subspace Ids. - /// Subspace ID/Index <-> CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO pointer + /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer VOID **Table; /// Number of entries in the Table. @@ -35,7 +35,7 @@ typedef struct AcpiPcctGenerator { // Private fields are defined from here. /// Table to map: - /// Subspace ID/Index <-> CM_[ARM|ARCH_COMMON]_PCC_SUBSPACE_TYPE[X]_INFO pointer + /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer MAPPING_TABLE MappingTable; } ACPI_PCCT_GENERATOR; diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 112bef7151..05fbdadf15 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,9 +166,8 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - CMN-600 Info NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor - NULL, ///< 23 - Pcc Subspace Type 5 Info - NULL, ///< 24 - Embedded Trace Extension/Module Info - NULL ///< 25 - P-State Dependency (PSD) Info + NULL, ///< 23 - Embedded Trace Extension/Module Info + NULL ///< 24 - P-State Dependency (PSD) Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 5f08f514fa..da7901a2c4 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -635,9 +635,9 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType34InfoParser[] = { ARRAY_SIZE (CmArmMailboxRegisterInfoParser) }, }; -/** A parser for EArmObjPccSubspaceType5Info. +/** A parser for EArchCommonObjPccSubspaceType5Info. */ -STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType5InfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType5InfoParser[] = { { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO), NULL, NULL, CmArchCommonPccSubspaceType0InfoParser, ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) }, @@ -694,6 +694,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType2Info, CmArchCommonPccSubspaceType2InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType3Info, CmArchCommonPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType4Info, CmArchCommonPccSubspaceType34InfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType5Info, CmArchCommonPccSubspaceType5InfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -723,7 +724,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser), CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), - CM_PARSER_ADD_OBJECT (EArmObjPccSubspaceType5Info, CmArmPccSubspaceType5InfoParser), CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo), CM_PARSER_ADD_OBJECT (EArmObjPsdInfo, CmArmPsdInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax) diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 1e45bcd597..d4c95a3c42 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -463,9 +463,8 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 20 | CMN 600 Info | | | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | -| 23 | Pcc Subspace Type 5 Info | Move to Arch Common NS | -| 24 | Embedded Trace Extension/Module Info | | -| 25 | P-State Dependency (PSD) Info | Move to Arch Common NS | +| 23 | Embedded Trace Extension/Module Info | | +| 24 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 21 | Pcc Subspace Type 2 Info | | | 22 | Pcc Subspace Type 3 Info | | | 23 | Pcc Subspace Type 4 Info | | +| 24 | Pcc Subspace Type 5 Info | | | `*` | All other values are reserved. | | -- cgit From fb6a7147f3a9438f83e749dbbd3d1387d9471840 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 11 Mar 2024 15:50:37 +0000 Subject: DynamicTablesPkg: Move PSD info to Arch Common Move the PSD info object from Arm Namespace to the Arch Common namespace. Correspondingly also update the following modules to reflect the changes introduced by the move: - SSDT CPU topology generator - ConfigurationManagerObjectParser - Dynamic Plat Repo TokenFixer map. Cc: Pierre Gondois Cc: Yeo Reum Yun Cc: AbdulLateef Attar Cc: Jeshua Smith Cc: Jeff Brasen Cc: Girish Mahadevan Cc: Leif Lindholm Cc: Meenakshi Aggarwal Signed-off-by: Sami Mujawar Signed-off-by: Pierre Gondois Reviewed-by: Sunil V L --- DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h | 10 ++++++++++ DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 12 +----------- .../AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c | 14 +++++++------- .../Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c | 3 +-- .../TableHelperLib/ConfigurationManagerObjectParser.c | 6 +++--- DynamicTablesPkg/Readme.md | 2 +- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 58a137e905..6de57dbbf2 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -45,6 +45,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjPccSubspaceType3Info, ///< 22 - Pcc Subspace Type 3 Info EArchCommonObjPccSubspaceType4Info, ///< 23 - Pcc Subspace Type 4 Info EArchCommonObjPccSubspaceType5Info, ///< 24 - Pcc Subspace Type 5 Info + EArchCommonObjPsdInfo, ///< 25 - P-State Dependency (PSD) Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -642,6 +643,15 @@ typedef struct CmArchCommonPccSubspaceType5Info { PCC_MAILBOX_REGISTER_INFO ErrorStatusReg; } CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO; +/** A structure that describes a + P-State Dependency (PSD) Info. + + Cf. ACPI 6.5, s8.4.5.5 _PSD (P-State Dependency). + + ID: EArchCommonObjPsdInfo +*/ +typedef AML_PSD_INFO CM_ARCH_COMMON_PSD_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 724e614bb6..958c3dc93c 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -52,7 +52,6 @@ typedef enum ArmObjectID { EArmObjRmr, ///< 21 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor EArmObjEtInfo, ///< 23 - Embedded Trace Extension/Module Info - EArmObjPsdInfo, ///< 24 - P-State Dependency (PSD) Info EArmObjMax } EARM_OBJECT_ID; @@ -188,7 +187,7 @@ typedef struct CmArmGicCInfo { CM_OBJECT_TOKEN EtToken; /** Optional field: Reference Token for the Psd info of this processor. - i.e. a token referencing a CM_ARM_PSD_INFO object. + i.e. a token referencing a CM_ARCH_COMMON_PSD_INFO object. */ CM_OBJECT_TOKEN PsdToken; } CM_ARM_GICC_INFO; @@ -724,15 +723,6 @@ typedef struct CmArmEtInfo { ARM_ET_TYPE EtType; } CM_ARM_ET_INFO; -/** A structure that describes a - P-State Dependency (PSD) Info. - - Cf. ACPI 6.5, s8.4.5.5 _PSD (P-State Dependency). - - ID: EArmObjPsdInfo -*/ -typedef AML_PSD_INFO CM_ARM_PSD_INFO; - #pragma pack() #endif // ARM_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c index 8c9d1258b2..2deaa4640c 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c @@ -42,7 +42,7 @@ Requirements: - EArchCommonObjCmRef (OPTIONAL) - EArchCommonObjLpiInfo (OPTIONAL) - GetEArmObjEtInfo (OPTIONAL) - - EArmObjPsdInfo (OPTIONAL) + - EArchCommonObjPsdInfo (OPTIONAL) */ /** This macro expands to a function that retrieves the GIC @@ -109,9 +109,9 @@ GET_OBJECT_LIST ( information from the Configuration Manager. */ GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjPsdInfo, - CM_ARM_PSD_INFO + EObjNameSpaceArchCommon, + EArchCommonObjPsdInfo, + CM_ARCH_COMMON_PSD_INFO ); /** Initialize the TokenTable. @@ -313,10 +313,10 @@ CreateAmlPsdNode ( IN AML_OBJECT_NODE_HANDLE *Node ) { - EFI_STATUS Status; - CM_ARM_PSD_INFO *PsdInfo; + EFI_STATUS Status; + CM_ARCH_COMMON_PSD_INFO *PsdInfo; - Status = GetEArmObjPsdInfo ( + Status = GetEArchCommonObjPsdInfo ( CfgMgrProtocol, GicCInfo->PsdToken, &PsdInfo, diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c index 05fbdadf15..5325b20743 100644 --- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c @@ -166,8 +166,7 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = { NULL, ///< 20 - CMN-600 Info NULL, ///< 21 - Reserved Memory Range Node NULL, ///< 22 - Memory Range Descriptor - NULL, ///< 23 - Embedded Trace Extension/Module Info - NULL ///< 24 - P-State Dependency (PSD) Info + NULL ///< 23 - Embedded Trace Extension/Module Info }; /** CmObj token fixer. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index da7901a2c4..e726b2c616 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -658,9 +658,9 @@ STATIC CONST CM_OBJ_PARSER CmArmEtInfo[] = { { "EtType", sizeof (ARM_ET_TYPE), "0x%x", NULL } }; -/** A parser for EArmObjPsdInfo. +/** A parser for EArchCommonObjPsdInfo. */ -STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = { +STATIC CONST CM_OBJ_PARSER CmArchCommonPsdInfoParser[] = { { "Revision", 1, "0x%x", NULL }, { "DomainId", 4, "0x%x", NULL }, { "CoordType", 4, "0x%x", NULL }, @@ -695,6 +695,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType3Info, CmArchCommonPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType4Info, CmArchCommonPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType5Info, CmArchCommonPccSubspaceType5InfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjPsdInfo, CmArchCommonPsdInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; @@ -725,7 +726,6 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser), CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser), CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo), - CM_PARSER_ADD_OBJECT (EArmObjPsdInfo, CmArmPsdInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax) }; diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index d4c95a3c42..7790b14636 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -464,7 +464,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 21 | Reserved Memory Range Node | | | 22 | Memory Range Descriptor | | | 23 | Embedded Trace Extension/Module Info | | -| 24 | P-State Dependency (PSD) Info | Move to Arch Common NS | | `*` | All other values are reserved. | | #### Object ID's in the Arch Common Namespace: @@ -496,5 +495,6 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 22 | Pcc Subspace Type 3 Info | | | 23 | Pcc Subspace Type 4 Info | | | 24 | Pcc Subspace Type 5 Info | | +| 25 | P-State Dependency (PSD) Info | | | `*` | All other values are reserved. | | -- cgit From e640c04a7bbddc56cb01767a03e508bb012fef19 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: Acpi: Move generic libraries to common folder Some of the ACPI table generators are generic enough to be re-used by other architectures. Move the following generators to a 'Common' folder: - AcpiDbg2Lib - AcpiFadtLib - AcpiMcfgLib - AcpiPcctLib - AcpiPpttLib - AcpiRawLib - AcpiSpcrLib - AcpiSratLib - SsdtSerialPortLib - SsdtCpuTopologyLib - SsdtPcieLib and update DynamicTables.dsc.inc accordingly. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- DynamicTablesPkg/DynamicTables.dsc.inc | 64 +- .../Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf | 43 - .../Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c | 587 ------- .../Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf | 36 - .../Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c | 713 -------- .../Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf | 36 - .../Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c | 369 ----- .../Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf | 30 - .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 1188 -------------- .../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h | 44 - .../Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf | 30 - .../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 1480 ----------------- .../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h | 185 --- .../Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf | 36 - .../Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c | 146 -- .../Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf | 37 - .../Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c | 482 ------ .../Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf | 29 - .../Acpi/Arm/AcpiSratLibArm/SratGenerator.c | 842 ---------- .../SsdtCpuTopologyGenerator.c | 1705 -------------------- .../SsdtCpuTopologyGenerator.h | 147 -- .../SsdtCpuTopologyLibArm.inf | 33 - .../Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c | 1247 -------------- .../Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h | 55 - .../Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf | 35 - .../SsdtSerialPortGenerator.c | 373 ----- .../SsdtSerialPortLibArm.inf | 33 - .../Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf | 43 + .../Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c | 587 +++++++ .../Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf | 36 + .../Acpi/Common/AcpiFadtLib/FadtGenerator.c | 713 ++++++++ .../Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf | 36 + .../Acpi/Common/AcpiMcfgLib/McfgGenerator.c | 369 +++++ .../Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf | 30 + .../Acpi/Common/AcpiPcctLib/PcctGenerator.c | 1188 ++++++++++++++ .../Acpi/Common/AcpiPcctLib/PcctGenerator.h | 44 + .../Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf | 30 + .../Acpi/Common/AcpiPpttLib/PpttGenerator.c | 1480 +++++++++++++++++ .../Acpi/Common/AcpiPpttLib/PpttGenerator.h | 185 +++ .../Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf | 36 + .../Library/Acpi/Common/AcpiRawLib/RawGenerator.c | 146 ++ .../Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf | 37 + .../Acpi/Common/AcpiSpcrLib/SpcrGenerator.c | 482 ++++++ .../Acpi/Common/AcpiSratLib/AcpiSratLib.inf | 29 + .../Acpi/Common/AcpiSratLib/SratGenerator.c | 842 ++++++++++ .../SsdtCpuTopologyGenerator.c | 1705 ++++++++++++++++++++ .../SsdtCpuTopologyGenerator.h | 147 ++ .../AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf | 33 + .../Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c | 1247 ++++++++++++++ .../Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h | 55 + .../Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf | 35 + .../SsdtSerialPortGenerator.c | 373 +++++ .../AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf | 33 + 53 files changed, 9979 insertions(+), 9967 deletions(-) delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c delete mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index 19ca62d6a8..fa68b63ab1 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -25,6 +25,25 @@ DynamicTablesScmiInfoLib|DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf [Components.common] + # + # Generators (Common) + # + DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf + + # AML Fixup (Common) + DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf + + # AML Codegen (Common) + DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf + # # Dynamic Tables Manager Dxe # @@ -38,51 +57,44 @@ [Components.ARM, Components.AARCH64] # - # Generators + # Generators (Arm specific) # - DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf - # AML Fixup - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf + # AML Fixup (Arm specific) DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf - # AML Codegen - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf - # # Dynamic Table Factory Dxe # DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf { - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf + # Generators + # Common + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf + # Arm specific NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf # AML Fixup - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf + # Common + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf + # Arm specific NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf # AML Codegen - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf - NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf + # Common + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf } diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf deleted file mode 100644 index f7b7c1c025..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf +++ /dev/null @@ -1,43 +0,0 @@ -## @file -# DBG2 Table Generator -# -# Copyright (c) 2017 - 2020, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010019 - BASE_NAME = AcpiDbg2LibArm - FILE_GUID = A17BA4F0-3DEB-4FE5-BD27-EC008E541B22 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiDbg2LibConstructor - DESTRUCTOR = AcpiDbg2LibDestructor - -[Sources] - Dbg2Generator.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - BaseLib - PL011UartLib - SsdtSerialPortFixupLib - -[FixedPcd] - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c deleted file mode 100644 index fbf2ba3733..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c +++ /dev/null @@ -1,587 +0,0 @@ -/** @file - DBG2 Table Generator - - Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015. - -**/ - -#include -#include -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include - -/** ARM standard DBG2 Table Generator - - Constructs the DBG2 table for PL011 or SBSA UART peripherals. - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjSerialDebugPortInfo -*/ - -#pragma pack(1) - -/** The number of debug ports represented by the Table. -*/ -#define DBG2_NUM_DEBUG_PORTS 1 - -/** The number of Generic Address Registers - presented in the debug device information. -*/ -#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS 1 - -/** The index for the debug port 0 in the Debug port information list. -*/ -#define INDEX_DBG_PORT0 0 - -/** A string representing the name of the debug port 0. -*/ -#define NAME_STR_DBG_PORT0 "COM0" - -/** A string representing the full path name of the debug port 0. -*/ -#define NAMESPACE_STR_DBG_PORT0 "\\_SB_.COM0" - -/** An UID representing the debug port 0. -*/ -#define UID_DBG_PORT0 0 - -/** The length of the namespace string. -*/ -#define DBG2_NAMESPACESTRING_FIELD_SIZE sizeof (NAMESPACE_STR_DBG_PORT0) - -/** The PL011 UART address range length. -*/ -#define PL011_UART_LENGTH 0x1000 - -/** A structure that provides the OS with the required information - for initializing a debugger connection. -*/ -typedef struct { - /// The debug device information for the platform - EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device; - - /// The base address register for the serial port - EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister; - - /// The address size - UINT32 AddressSize; - - /// The debug port name string - UINT8 NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE]; -} DBG2_DEBUG_DEVICE_INFORMATION; - -/** A structure representing the information about the debug port(s) - available on the platform. -*/ -typedef struct { - /// The DBG2 table header - EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE Description; - - /// Debug port information list - DBG2_DEBUG_DEVICE_INFORMATION Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS]; -} DBG2_TABLE; - -/** A helper macro used for initializing the debug port device - information structure. - - @param [in] SubType The DBG Port SubType. - @param [in] UartBase The UART port base address. - @param [in] UartAddrLen The UART port address range length. - @param [in] UartNameStr The UART port name string. -**/ -#define DBG2_DEBUG_PORT_DDI( \ - SubType, \ - UartBase, \ - UartAddrLen, \ - UartNameStr \ - ) {\ - { \ - /* UINT8 Revision */ \ - EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, \ - /* UINT16 Length */ \ - sizeof (DBG2_DEBUG_DEVICE_INFORMATION), \ - /* UINT8 NumberofGenericAddressRegisters */ \ - DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS, \ - /* UINT16 NameSpaceStringLength */ \ - DBG2_NAMESPACESTRING_FIELD_SIZE, \ - /* UINT16 NameSpaceStringOffset */ \ - OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), \ - /* UINT16 OemDataLength */ \ - 0, \ - /* UINT16 OemDataOffset */ \ - 0, \ - /* UINT16 Port Type */ \ - EFI_ACPI_DBG2_PORT_TYPE_SERIAL, \ - /* UINT16 Port Subtype */ \ - SubType, \ - /* UINT8 Reserved[2] */ \ - {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, \ - /* UINT16 BaseAddressRegister Offset */ \ - OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), \ - /* UINT16 AddressSize Offset */ \ - OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) \ - }, \ - /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \ - ARM_GAS32 (UartBase), \ - /* UINT32 AddressSize */ \ - UartAddrLen, \ - /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \ - UartNameStr \ - } - -/** The DBG2 Table template definition. - - Note: fields marked with "{Template}" will be set dynamically -*/ -STATIC -DBG2_TABLE AcpiDbg2 = { - { - ACPI_HEADER ( - EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, - DBG2_TABLE, - EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION - ), - OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo), - DBG2_NUM_DEBUG_PORTS - }, - { - /* - * Debug port 1 - */ - DBG2_DEBUG_PORT_DDI ( - 0, // {Template}: Serial Port Subtype - 0, // {Template}: Serial Port Base Address - PL011_UART_LENGTH, - NAMESPACE_STR_DBG_PORT0 - ) - } -}; - -#pragma pack() - -/** This macro expands to a function that retrieves the Serial - debug port information from the Configuration Manager -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjSerialDebugPortInfo, - CM_ARCH_COMMON_SERIAL_PORT_INFO - ); - -/** Initialize the PL011/SBSA UART with the parameters obtained from - the Configuration Manager. - - @param [in] SerialPortInfo Pointer to the Serial Port Information. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER The parameters for serial port initialization - are invalid. -**/ -STATIC -EFI_STATUS -SetupDebugUart ( - IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *CONST SerialPortInfo - ) -{ - EFI_STATUS Status; - UINT64 BaudRate; - UINT32 ReceiveFifoDepth; - EFI_PARITY_TYPE Parity; - UINT8 DataBits; - EFI_STOP_BITS_TYPE StopBits; - - ASSERT (SerialPortInfo != NULL); - - // Initialize the Serial Debug UART - DEBUG ((DEBUG_INFO, "Initializing Serial Debug UART...\n")); - ReceiveFifoDepth = 0; // Use the default value for FIFO depth - Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); - DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); - StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); - - BaudRate = SerialPortInfo->BaudRate; - Status = PL011UartInitializePort ( - (UINTN)SerialPortInfo->BaseAddress, - SerialPortInfo->Clock, - &BaudRate, - &ReceiveFifoDepth, - &Parity, - &DataBits, - &StopBits - ); - - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Free any resources allocated for constructing the tables. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to an array of pointers - to ACPI Table(s). - @param [in] TableCount Number of ACPI table(s). - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -FreeDbg2TableEx ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, - IN CONST UINTN TableCount - ) -{ - EFI_STATUS Status; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || - (*Table == NULL) || - (TableCount != 2)) - { - DEBUG ((DEBUG_ERROR, "ERROR: DBG2: Invalid Table Pointer\n")); - return EFI_INVALID_PARAMETER; - } - - TableList = *Table; - - if ((TableList[1] == NULL) || - (TableList[1]->Signature != - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) - { - DEBUG ((DEBUG_ERROR, "ERROR: DBG2: Invalid SSDT table pointer.\n")); - return EFI_INVALID_PARAMETER; - } - - // Only need to free the SSDT table at index 1. The DBG2 table is static. - Status = FreeSsdtSerialPortTable (TableList[1]); - ASSERT_EFI_ERROR (Status); - - // Free the table list. - FreePool (*Table); - - return Status; -} - -/** Construct the DBG2 ACPI table and its associated SSDT table. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResourcesEx function. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI table information. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [out] Table Pointer to a list of generated ACPI table(s). - @param [out] TableCount Number of generated ACPI table(s). - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for - the requested object. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Could not find information. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. - @retval EFI_UNSUPPORTED Unsupported configuration. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildDbg2TableEx ( - IN CONST ACPI_TABLE_GENERATOR *This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, - OUT UINTN *CONST TableCount - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; - UINT32 SerialPortCount; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (TableCount != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Requested table revision = %d, is not supported." - "Supported table revision: Minimum = %d, Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - return EFI_INVALID_PARAMETER; - } - - *Table = NULL; - - Status = GetEArchCommonObjSerialDebugPortInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &SerialPortInfo, - &SerialPortCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Failed to get serial port information. Status = %r\n", - Status - )); - return Status; - } - - if (SerialPortCount == 0) { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Serial port information not found. Status = %r\n", - EFI_NOT_FOUND - )); - return EFI_NOT_FOUND; - } - - // Only use the first DBG2 port information. - Status = ValidateSerialPortInfo (SerialPortInfo, 1); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Invalid serial port information. Status = %r\n", - Status - )); - return Status; - } - - // Allocate a table to store pointers to the DBG2 and SSDT tables. - TableList = (EFI_ACPI_DESCRIPTION_HEADER **) - AllocateZeroPool (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * 2); - if (TableList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Failed to allocate memory for Table List," \ - " Status = %r\n", - Status - )); - return Status; - } - - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiDbg2, - AcpiTableInfo, - sizeof (DBG2_TABLE) - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Failed to add ACPI header. Status = %r\n", - Status - )); - goto error_handler; - } - - // Update the base address - AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].BaseAddressRegister.Address = - SerialPortInfo->BaseAddress; - - // Set the access size - if (SerialPortInfo->AccessSize >= EFI_ACPI_6_3_QWORD) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Access size must be <= 3 (DWORD). Status = %r\n", - Status - )); - goto error_handler; - } else if (SerialPortInfo->AccessSize == EFI_ACPI_6_3_UNDEFINED) { - // 0 Undefined (legacy reasons) - // Default to DWORD access size as the access - // size field was introduced at a later date - // and some ConfigurationManager implementations - // may not be providing this field data - AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].BaseAddressRegister.AccessSize = - EFI_ACPI_6_3_DWORD; - } else { - AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].BaseAddressRegister.AccessSize = - SerialPortInfo->AccessSize; - } - - // Update the serial port subtype - AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].Dbg2Device.PortSubtype = - SerialPortInfo->PortSubtype; - - if ((SerialPortInfo->PortSubtype == - EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) || - (SerialPortInfo->PortSubtype == - EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) || - (SerialPortInfo->PortSubtype == - EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART)) - { - // Initialize the serial port - Status = SetupDebugUart (SerialPortInfo); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Failed to configure debug serial port. Status = %r\n", - Status - )); - goto error_handler; - } - } - - TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiDbg2; - - // Build a SSDT table describing the serial port. - Status = BuildSsdtSerialPortTable ( - AcpiTableInfo, - SerialPortInfo, - NAME_STR_DBG_PORT0, - UID_DBG_PORT0, - &TableList[1] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: DBG2: Failed to build associated SSDT table. Status = %r\n", - Status - )); - goto error_handler; - } - - *TableCount = 2; - *Table = TableList; - - return Status; - -error_handler: - if (TableList != NULL) { - FreePool (TableList); - } - - return Status; -} - -/** This macro defines the DBG2 Table Generator revision. -*/ -#define DBG2_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the DBG2 Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR Dbg2Generator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2), - // Generator Description - L"ACPI.STD.DBG2.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, - // Minimum supported ACPI Table Revision - EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - DBG2_GENERATOR_REVISION, - // Build table function. Use the extended version instead. - NULL, - // Free table function. Use the extended version instead. - NULL, - // Extended Build table function. - BuildDbg2TableEx, - // Extended free function. - FreeDbg2TableEx -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiDbg2LibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&Dbg2Generator); - DEBUG ((DEBUG_INFO, "DBG2: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiDbg2LibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&Dbg2Generator); - DEBUG ((DEBUG_INFO, "DBG2: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf deleted file mode 100644 index 8fe34013d4..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf +++ /dev/null @@ -1,36 +0,0 @@ -## @file -# FADT Table Generator -# -# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010019 - BASE_NAME = AcpiFadtLibArm - FILE_GUID = 686FE5FE-B944-485F-8B1C-7D60E0056487 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiFadtLibConstructor - DESTRUCTOR = AcpiFadtLibDestructor - -[Sources] - FadtGenerator.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - BaseLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c deleted file mode 100644 index 470f1acfd1..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c +++ /dev/null @@ -1,713 +0,0 @@ -/** @file - FADT Table Generator - - Copyright (c) 2017 - 2023, Arm Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.5 Specification, Aug 29, 2022 - -**/ - -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include - -/** ARM standard FADT Generator - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjPowerManagementProfileInfo - - EArmObjBootArchInfo - - EArchCommonObjHypervisorVendorIdentity (OPTIONAL) -*/ - -/** This macro defines the FADT flag options for ARM Platforms. -*/ -#define FADT_FLAGS (EFI_ACPI_6_5_HW_REDUCED_ACPI | \ - EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE) - -/** This macro defines the valid mask for the FADT flag option - if HW_REDUCED_ACPI flag in the table is set. - - Invalid bits are: 1, 2, 3,7, 8, 13, 14,16, 17 and - 22-31 (reserved). - - Valid bits are: - EFI_ACPI_6_5_WBINVD BIT0 - EFI_ACPI_6_5_PWR_BUTTON BIT4 - EFI_ACPI_6_5_SLP_BUTTON BIT5 - EFI_ACPI_6_5_FIX_RTC BIT6 - EFI_ACPI_6_5_DCK_CAP BIT9 - EFI_ACPI_6_5_RESET_REG_SUP BIT10 - EFI_ACPI_6_5_SEALED_CASE BIT11 - EFI_ACPI_6_5_HEADLESS BIT12 - EFI_ACPI_6_5_USE_PLATFORM_CLOCK BIT15 - EFI_ACPI_6_5_FORCE_APIC_CLUSTER_MODEL BIT18 - EFI_ACPI_6_5_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 - EFI_ACPI_6_5_HW_REDUCED_ACPI BIT20 - EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE BIT21 -*/ -#define VALID_HARDWARE_REDUCED_FLAG_MASK ( \ - EFI_ACPI_6_5_WBINVD | \ - EFI_ACPI_6_5_PWR_BUTTON | \ - EFI_ACPI_6_5_SLP_BUTTON | \ - EFI_ACPI_6_5_FIX_RTC | \ - EFI_ACPI_6_5_DCK_CAP | \ - EFI_ACPI_6_5_RESET_REG_SUP | \ - EFI_ACPI_6_5_SEALED_CASE | \ - EFI_ACPI_6_5_HEADLESS | \ - EFI_ACPI_6_5_USE_PLATFORM_CLOCK | \ - EFI_ACPI_6_5_FORCE_APIC_CLUSTER_MODEL | \ - EFI_ACPI_6_5_FORCE_APIC_PHYSICAL_DESTINATION_MODE | \ - EFI_ACPI_6_5_HW_REDUCED_ACPI | \ - EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE) - -#pragma pack(1) - -/** The AcpiFadt is a template EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE - structure used for generating the FADT Table. - Note: fields marked with "{Template}" will be updated dynamically. -*/ -STATIC -EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = { - ACPI_HEADER ( - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE, - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_REVISION - ), - // UINT32 FirmwareCtrl - 0, - // UINT32 Dsdt - 0, - // UINT8 Reserved0 - EFI_ACPI_RESERVED_BYTE, - // UINT8 PreferredPmProfile - EFI_ACPI_6_5_PM_PROFILE_UNSPECIFIED, // {Template}: Power Management Profile - // UINT16 SciInt - 0, - // UINT32 SmiCmd - 0, - // UINT8 AcpiEnable - 0, - // UINT8 AcpiDisable - 0, - // UINT8 S4BiosReq - 0, - // UINT8 PstateCnt - 0, - // UINT32 Pm1aEvtBlk - 0, - // UINT32 Pm1bEvtBlk - 0, - // UINT32 Pm1aCntBlk - 0, - // UINT32 Pm1bCntBlk - 0, - // UINT32 Pm2CntBlk - 0, - // UINT32 PmTmrBlk - 0, - // UINT32 Gpe0Blk - 0, - // UINT32 Gpe1Blk - 0, - // UINT8 Pm1EvtLen - 0, - // UINT8 Pm1CntLen - 0, - // UINT8 Pm2CntLen - 0, - // UINT8 PmTmrLen - 0, - // UINT8 Gpe0BlkLen - 0, - // UINT8 Gpe1BlkLen - 0, - // UINT8 Gpe1Base - 0, - // UINT8 CstCnt - 0, - // UINT16 PLvl2Lat - 0, - // UINT16 PLvl3Lat - 0, - // UINT16 FlushSize - 0, - // UINT16 FlushStride - 0, - // UINT8 DutyOffset - 0, - // UINT8 DutyWidth - 0, - // UINT8 DayAlrm - 0, - // UINT8 MonAlrm - 0, - // UINT8 Century - 0, - // UINT16 IaPcBootArch - 0, - // UINT8 Reserved1 - 0, - // UINT32 Flags - FADT_FLAGS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg - NULL_GAS, - // UINT8 ResetValue - 0, - // UINT16 ArmBootArch - EFI_ACPI_6_5_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags - // UINT8 MinorRevision - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, // {Template} - // UINT64 XFirmwareCtrl - 0, - // UINT64 XDsdt - 0, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe0Blk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe1Blk - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepControlReg - NULL_GAS, - // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepStatusReg - NULL_GAS, - // UINT64 HypervisorVendorIdentity - EFI_ACPI_RESERVED_QWORD // {Template}: Hypervisor Vendor ID -}; - -#pragma pack() - -/** This macro expands to a function that retrieves the Power - Management Profile Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPowerManagementProfileInfo, - CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO - ); - -/** This macro expands to a function that retrieves the Boot - Architecture Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjBootArchInfo, - CM_ARM_BOOT_ARCH_INFO - ); - -/** This macro expands to a function that retrieves the Hypervisor - Vendor ID from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjHypervisorVendorIdentity, - CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID - ); - -/** This macro expands to a function that retrieves the Fixed - feature flags for the platform from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjFixedFeatureFlags, - CM_ARCH_COMMON_FIXED_FEATURE_FLAGS - ); - -/** Update the Power Management Profile information in the FADT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -FadtAddPmProfileInfo ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO *PmProfile; - - ASSERT (CfgMgrProtocol != NULL); - - // Get the Power Management Profile from the Platform Configuration Manager - Status = GetEArchCommonObjPowerManagementProfileInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PmProfile, - NULL - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Failed to get Power Management Profile information." \ - " Status = %r\n", - Status - )); - goto error_handler; - } - - DEBUG (( - DEBUG_INFO, - "FADT: PreferredPmProfile = 0x%x\n", - PmProfile->PowerManagementProfile - )); - - AcpiFadt.PreferredPmProfile = PmProfile->PowerManagementProfile; - -error_handler: - return Status; -} - -/** Updates the Boot Architecture information in the FADT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -FadtAddBootArchInfo ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - CM_ARM_BOOT_ARCH_INFO *BootArchInfo; - - ASSERT (CfgMgrProtocol != NULL); - - // Get the Boot Architecture flags from the Platform Configuration Manager - Status = GetEArmObjBootArchInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &BootArchInfo, - NULL - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n", - Status - )); - goto error_handler; - } - - DEBUG (( - DEBUG_INFO, - "FADT BootArchFlag = 0x%x\n", - BootArchInfo->BootArchFlags - )); - - AcpiFadt.ArmBootArch = BootArchInfo->BootArchFlags; - -error_handler: - return Status; -} - -/** Update the Hypervisor Vendor ID in the FADT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -FadtAddHypervisorVendorId ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID *HypervisorVendorInfo; - - ASSERT (CfgMgrProtocol != NULL); - - // Get the Hypervisor Vendor ID from the Platform Configuration Manager - Status = GetEArchCommonObjHypervisorVendorIdentity ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &HypervisorVendorInfo, - NULL - ); - if (EFI_ERROR (Status)) { - if (Status == EFI_NOT_FOUND) { - DEBUG (( - DEBUG_INFO, - "INFO: FADT: Platform does not have a Hypervisor Vendor ID." - "Status = %r\n", - Status - )); - } else { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Failed to get Hypervisor Vendor ID. Status = %r\n", - Status - )); - } - - goto error_handler; - } - - DEBUG (( - DEBUG_INFO, - "FADT: EArchCommonObjHypervisorVendorIdentity = 0x%lx\n", - HypervisorVendorInfo->HypervisorVendorId - )); - - AcpiFadt.HypervisorVendorIdentity = HypervisorVendorInfo->HypervisorVendorId; - -error_handler: - return Status; -} - -/** Update the Fixed Feature Flags in the FADT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -FadtAddFixedFeatureFlags ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_FIXED_FEATURE_FLAGS *FixedFeatureFlags; - - ASSERT (CfgMgrProtocol != NULL); - - // Get the Fixed feature flags from the Platform Configuration Manager - Status = GetEArchCommonObjFixedFeatureFlags ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &FixedFeatureFlags, - NULL - ); - if (EFI_ERROR (Status)) { - if (Status == EFI_NOT_FOUND) { - DEBUG (( - DEBUG_INFO, - "INFO: FADT: Platform does not define additional Fixed feature flags." - "Status = %r\n", - Status - )); - } else { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Failed to get Fixed feature flags. Status = %r\n", - Status - )); - } - - goto error_handler; - } - - DEBUG (( - DEBUG_INFO, - "FADT: EArchCommonObjFixedFeatureFlags = 0x%x\n", - FixedFeatureFlags->Flags - )); - - if ((FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) != 0) { - DEBUG (( - DEBUG_WARN, - "FADT: Invalid Fixed feature flags defined by platform," - "Invalid Flags bits are = 0x%x\n", - (FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) - )); - } - - AcpiFadt.Flags |= (FixedFeatureFlags->Flags & - VALID_HARDWARE_REDUCED_FLAG_MASK); - -error_handler: - return Status; -} - -/** Construct the FADT table. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildFadtTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - EFI_STATUS Status; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Requested table revision = %d, is not supported." - "Supported table revision: Minimum = %d, Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - return EFI_INVALID_PARAMETER; - } - - *Table = NULL; - - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiFadt, - AcpiTableInfo, - sizeof (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE) - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Failed to add ACPI header. Status = %r\n", - Status - )); - goto error_handler; - } - - // Update the MinorRevision for the FADT table if it has been specified - // otherwise default to the latest FADT minor revision supported. - // Note: - // Bits 0-3 - The low order bits correspond to the minor version of the - // specification version. - // Bits 4-7 - The high order bits correspond to the version of the ACPI - // specification errata. - if (AcpiTableInfo->MinorRevision != 0) { - if (((AcpiTableInfo->MinorRevision & 0xF) >= - EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION) && - ((AcpiTableInfo->MinorRevision & 0xF) <= - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION)) - { - AcpiFadt.MinorVersion = AcpiTableInfo->MinorRevision; - } else { - DEBUG (( - DEBUG_WARN, - "WARNING: FADT: Unsupported FADT Minor Revision 0x%x specified, " \ - "defaulting to FADT Minor Revision 0x%x\n", - AcpiTableInfo->MinorRevision, - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION - )); - } - } - - // Update PmProfile Info - Status = FadtAddPmProfileInfo (CfgMgrProtocol); - if (EFI_ERROR (Status)) { - goto error_handler; - } - - // Update BootArch Info - Status = FadtAddBootArchInfo (CfgMgrProtocol); - if (EFI_ERROR (Status)) { - goto error_handler; - } - - // Add the Hypervisor Vendor Id if present - // Note if no hypervisor is present the zero bytes - // will be placed in this field. - Status = FadtAddHypervisorVendorId (CfgMgrProtocol); - if (EFI_ERROR (Status)) { - if (Status == EFI_NOT_FOUND) { - DEBUG (( - DEBUG_INFO, - "INFO: FADT: No Hypervisor Vendor ID found," \ - " assuming no Hypervisor is present in the firmware.\n" - )); - } else { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Error reading Hypervisor Vendor ID, Status = %r", - Status - )); - goto error_handler; - } - } - - Status = FadtAddFixedFeatureFlags (CfgMgrProtocol); - if (EFI_ERROR (Status)) { - if (Status == EFI_NOT_FOUND) { - DEBUG (( - DEBUG_INFO, - "INFO: FADT: No Fixed feature flags found," \ - " assuming no additional flags are defined for the platform.\n" - )); - Status = EFI_SUCCESS; - } else { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Error reading Fixed feature flags, Status = %r", - Status - )); - goto error_handler; - } - } - - *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiFadt; -error_handler: - return Status; -} - -/** This macro defines the FADT Table Generator revision. -*/ -#define FADT_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the FADT Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR FadtGenerator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt), - // Generator Description - L"ACPI.STD.FADT.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, - // Minimum supported ACPI Table Revision - EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - FADT_GENERATOR_REVISION, - // Build Table function - BuildFadtTable, - // No additional resources are allocated by the generator. - // Hence the Free Resource function is not required. - NULL, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiFadtLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&FadtGenerator); - DEBUG ((DEBUG_INFO, "FADT: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiFadtLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&FadtGenerator); - DEBUG ((DEBUG_INFO, "FADT: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf deleted file mode 100644 index 1c7f085274..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf +++ /dev/null @@ -1,36 +0,0 @@ -## @file -# MCFG Table Generator -# -# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010019 - BASE_NAME = AcpiMcfgLibArm - FILE_GUID = 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiMcfgLibConstructor - DESTRUCTOR = AcpiMcfgLibDestructor - -[Sources] - McfgGenerator.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - BaseLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c deleted file mode 100644 index 722f9c17d5..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c +++ /dev/null @@ -1,369 +0,0 @@ -/** @file - MCFG Table Generator - - Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - PCI Firmware Specification - Revision 3.2, January 26, 2015. - -**/ - -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include - -/** ARM standard MCFG Generator - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjPciConfigSpaceInfo -*/ - -#pragma pack(1) - -/** This typedef is used to shorten the name of the MCFG Table - header structure. -*/ -typedef - EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER - MCFG_TABLE; - -/** This typedef is used to shorten the name of the Enhanced - Configuration Space address structure. -*/ -typedef - EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE - MCFG_CFG_SPACE_ADDR; - -#pragma pack() - -/** Retrieve the PCI Configuration Space Information. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPciConfigSpaceInfo, - CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO - ); - -/** Add the PCI Enhanced Configuration Space Information to the MCFG Table. - - @param [in] Mcfg Pointer to MCFG Table. - @param [in] PciCfgSpaceOffset Offset for the PCI Configuration Space - Info structure in the MCFG Table. - @param [in] PciCfgSpaceInfoList Pointer to the PCI Configuration Space - Info List. - @param [in] PciCfgSpaceCount Count of PCI Configuration Space Info. -**/ -STATIC -VOID -AddPciConfigurationSpaceList ( - IN MCFG_TABLE *CONST Mcfg, - IN CONST UINT32 PciCfgSpaceOffset, - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciCfgSpaceInfoList, - IN UINT32 PciCfgSpaceCount - ) -{ - MCFG_CFG_SPACE_ADDR *PciCfgSpace; - - ASSERT (Mcfg != NULL); - ASSERT (PciCfgSpaceInfoList != NULL); - - PciCfgSpace = (MCFG_CFG_SPACE_ADDR *)((UINT8 *)Mcfg + PciCfgSpaceOffset); - - while (PciCfgSpaceCount-- != 0) { - // Add PCI Configuration Space entry - PciCfgSpace->BaseAddress = PciCfgSpaceInfoList->BaseAddress; - PciCfgSpace->PciSegmentGroupNumber = - PciCfgSpaceInfoList->PciSegmentGroupNumber; - PciCfgSpace->StartBusNumber = PciCfgSpaceInfoList->StartBusNumber; - PciCfgSpace->EndBusNumber = PciCfgSpaceInfoList->EndBusNumber; - PciCfgSpace->Reserved = EFI_ACPI_RESERVED_DWORD; - PciCfgSpace++; - PciCfgSpaceInfoList++; - } -} - -/** Construct the MCFG ACPI table. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildMcfgTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - EFI_STATUS Status; - UINT32 TableSize; - UINT32 ConfigurationSpaceCount; - CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfoList; - MCFG_TABLE *Mcfg; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: MCFG: Requested table revision = %d, is not supported." - "Supported table revision: Minimum = %d, Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - return EFI_INVALID_PARAMETER; - } - - *Table = NULL; - Status = GetEArchCommonObjPciConfigSpaceInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PciConfigSpaceInfoList, - &ConfigurationSpaceCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: MCFG: Failed to get PCI Configuration Space Information." \ - " Status = %r\n", - Status - )); - goto error_handler; - } - - if (ConfigurationSpaceCount == 0) { - DEBUG (( - DEBUG_ERROR, - "ERROR: MCFG: Configuration Space Count = %d\n", - ConfigurationSpaceCount - )); - Status = EFI_INVALID_PARAMETER; - ASSERT (ConfigurationSpaceCount != 0); - goto error_handler; - } - - DEBUG (( - DEBUG_INFO, - "MCFG: Configuration Space Count = %d\n", - ConfigurationSpaceCount - )); - - // Calculate the MCFG Table Size - TableSize = sizeof (MCFG_TABLE) + - ((sizeof (MCFG_CFG_SPACE_ADDR) * ConfigurationSpaceCount)); - - *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); - if (*Table == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: MCFG: Failed to allocate memory for MCFG Table, Size = %d," \ - " Status = %r\n", - TableSize, - Status - )); - goto error_handler; - } - - Mcfg = (MCFG_TABLE *)*Table; - DEBUG (( - DEBUG_INFO, - "MCFG: Mcfg = 0x%p TableSize = 0x%x\n", - Mcfg, - TableSize - )); - - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - &Mcfg->Header, - AcpiTableInfo, - TableSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: MCFG: Failed to add ACPI header. Status = %r\n", - Status - )); - goto error_handler; - } - - Mcfg->Reserved = EFI_ACPI_RESERVED_QWORD; - - AddPciConfigurationSpaceList ( - Mcfg, - sizeof (MCFG_TABLE), - PciConfigSpaceInfoList, - ConfigurationSpaceCount - ); - - return EFI_SUCCESS; - -error_handler: - if (*Table != NULL) { - FreePool (*Table); - *Table = NULL; - } - - return Status; -} - -/** Free any resources allocated for constructing the MCFG - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to the ACPI Table. - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -FreeMcfgTableResources ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || (*Table == NULL)) { - DEBUG ((DEBUG_ERROR, "ERROR: MCFG: Invalid Table Pointer\n")); - ASSERT ((Table != NULL) && (*Table != NULL)); - return EFI_INVALID_PARAMETER; - } - - FreePool (*Table); - *Table = NULL; - return EFI_SUCCESS; -} - -/** This macro defines the MCFG Table Generator revision. -*/ -#define MCFG_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the MCFG Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR McfgGenerator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg), - // Generator Description - L"ACPI.STD.MCFG.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, - // Minimum supported ACPI Table Revision - EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - MCFG_GENERATOR_REVISION, - // Build Table function - BuildMcfgTable, - // Free Resource function - FreeMcfgTableResources, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiMcfgLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&McfgGenerator); - DEBUG ((DEBUG_INFO, "MCFG: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiMcfgLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&McfgGenerator); - DEBUG ((DEBUG_INFO, "MCFG: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf deleted file mode 100644 index da54585c2d..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf +++ /dev/null @@ -1,30 +0,0 @@ -## @file -# Pcct Table Generator -# -# Copyright (c) 2022, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x0001001B - BASE_NAME = AcpiPcctLibArm - FILE_GUID = 38FE945C-D6ED-4CD6-8D20-FCEF3260D15A - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiPcctLibConstructor - DESTRUCTOR = AcpiPcctLibDestructor - -[Sources] - PcctGenerator.c - PcctGenerator.h - -[Packages] - DynamicTablesPkg/DynamicTablesPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c deleted file mode 100644 index 205c444057..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c +++ /dev/null @@ -1,1188 +0,0 @@ -/** @file - PCCT Table Generator - - Copyright (c) 2022, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.4 Specification - January 2021 - s14 PLATFORM COMMUNICATIONS CHANNEL (PCC) - -**/ - -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include "PcctGenerator.h" - -/** ARM standard PCCT Generator - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjPccSubspaceType0Info - - EArchCommonObjPccSubspaceType1Info - - EArchCommonObjPccSubspaceType2Info - - EArchCommonObjPccSubspaceType3Info - - EArchCommonObjPccSubspaceType4Info - - EArchCommonObjPccSubspaceType5Info -*/ - -/** This macro expands to a function that retrieves the PCC - Subspace of Type 0 Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPccSubspaceType0Info, - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO - ); - -/** This macro expands to a function that retrieves the PCC - Subspace of Type 1 Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPccSubspaceType1Info, - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO - ); - -/** This macro expands to a function that retrieves the PCC - Subspace of Type 2 Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPccSubspaceType2Info, - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO - ); - -/** This macro expands to a function that retrieves the PCC - Subspace of Type 3 Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPccSubspaceType3Info, - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO - ); - -/** This macro expands to a function that retrieves the PCC - Subspace of Type 4 Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPccSubspaceType4Info, - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO - ); - -/** This macro expands to a function that retrieves the PCC - Subspace of Type 5 Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPccSubspaceType5Info, - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO - ); - -/** The Platform is capable of generating an interrupt - to indicate completion of a command. - - Cf: s14.1.1 Platform Communications Channel Global Flags - Platform Interrupt flag - and s14.1.6 Extended PCC subspaces (types 3 and 4) - If a responder subspace is included in the PCCT, - then the global Platform Interrupt flag must be set to 1 - - Set this variable and populate the PCCT flag accordingly if either: - - One of the PCCT Subspace uses interrupts. - - A PCC Subspace of type 4 is used. -*/ -STATIC BOOLEAN mHasPlatformInterrupt; - -/** Initialize the MappingTable. - - @param [in] MappingTable The mapping table structure. - @param [in] Count Number of entries to allocate in the - MappingTable. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -MappingTableInitialize ( - IN MAPPING_TABLE *MappingTable, - IN UINT32 Count - ) -{ - VOID **Table; - - if ((MappingTable == NULL) || - (Count == 0)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Table = AllocateZeroPool (sizeof (*Table) * Count); - if (Table == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - - MappingTable->Table = Table; - MappingTable->MaxIndex = Count; - - return EFI_SUCCESS; -} - -/** Free the MappingTable. - - @param [in, out] MappingTable The mapping table structure. -**/ -STATIC -VOID -EFIAPI -MappingTableFree ( - IN OUT MAPPING_TABLE *MappingTable - ) -{ - ASSERT (MappingTable != NULL); - ASSERT (MappingTable->Table != NULL); - - if (MappingTable->Table != NULL) { - FreePool (MappingTable->Table); - } -} - -/** Add a new entry for PccSubspace at Index. - - @param [in] MappingTable The mapping table structure. - @param [in] PccSubspace A pointer to - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO. - @param [in] Index Index at which PccSubspace must be added. - This is the Subspace Id. - - @retval EFI_SUCCESS Success. - @retval EFI_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -MappingTableAdd ( - IN MAPPING_TABLE *MappingTable, - IN VOID *PccSubspace, - IN UINT32 Index - ) -{ - if ((MappingTable == NULL) || - (MappingTable->Table == NULL) || - (PccSubspace == NULL)) - { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - if ((Index >= MappingTable->MaxIndex) || - (MappingTable->Table[Index] != 0)) - { - ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL); - return EFI_BUFFER_TOO_SMALL; - } - - // Just map the Pcc Subspace in the Table. - MappingTable->Table[Index] = PccSubspace; - return EFI_SUCCESS; -} - -/** Parse the CmPccArray objects and add them to the MappingTable. - - @param [in] MappingTable The mapping table structure. - @param [in] CmPccArray Pointer to an array of - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO. - @param [in] CmPccCount Count of objects in CmPccArray. - - @retval EFI_SUCCESS Success. - @retval EFI_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -MapPccSubspaceId ( - IN MAPPING_TABLE *MappingTable, - IN VOID *CmPccArray, - IN UINT32 CmPccCount - ) -{ - EFI_STATUS Status; - UINT8 *PccBuffer; - UINT32 Index; - UINT32 CmObjSize; - PCC_SUBSPACE_GENERIC_INFO *GenericPcc; - - if (CmPccCount == 0) { - return EFI_SUCCESS; - } - - if ((CmPccArray == NULL) || (MappingTable == NULL)) { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)CmPccArray; - - switch (GenericPcc->Type) { - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: - CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: - CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: - CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: - CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: - CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: - CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO); - break; - - default: - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - PccBuffer = (UINT8 *)CmPccArray; - - // Map the Pcc channel to their Subspace Id. - for (Index = 0; Index < CmPccCount; Index++) { - GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)PccBuffer; - - Status = MappingTableAdd ( - MappingTable, - PccBuffer, - GenericPcc->SubspaceId - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - PccBuffer += CmObjSize; - } - - return EFI_SUCCESS; -} - -/** Add one PCCT Subspace structure of Type 0 (Generic). - - @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. - @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -AddSubspaceStructType0 ( - IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccCmObj, - IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi - ) -{ - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - - if ((PccCmObj == NULL) || - (PccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC) || - (PccAcpi == NULL)) - { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - Doorbell = &PccCmObj->DoorbellReg; - ChannelTiming = &PccCmObj->ChannelTiming; - - PccAcpi->Type = PccCmObj->Type; - PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC); - *(UINT32 *)&PccAcpi->Reserved[0] = EFI_ACPI_RESERVED_DWORD; - *(UINT16 *)&PccAcpi->Reserved[4] = EFI_ACPI_RESERVED_WORD; - PccAcpi->BaseAddress = PccCmObj->BaseAddress; - PccAcpi->AddressLength = PccCmObj->AddressLength; - - CopyMem ( - &PccAcpi->DoorbellRegister, - &Doorbell->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; - PccAcpi->DoorbellWrite = Doorbell->WriteMask; - - PccAcpi->NominalLatency = ChannelTiming->NominalLatency; - PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; - PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; - - return EFI_SUCCESS; -} - -/** Add one PCCT subspace structure of Type 1 (HW-Reduced). - - @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. - @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -AddSubspaceStructType1 ( - IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccCmObj, - IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi - ) -{ - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - - GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; - - if ((PccCmObj == NULL) || - (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS) || - (PccAcpi == NULL)) - { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - Doorbell = &GenericPccCmObj->DoorbellReg; - ChannelTiming = &GenericPccCmObj->ChannelTiming; - - PccAcpi->Type = GenericPccCmObj->Type; - PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); - PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; - PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; - PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; - PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; - PccAcpi->AddressLength = GenericPccCmObj->AddressLength; - - CopyMem ( - &PccAcpi->DoorbellRegister, - &Doorbell->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; - PccAcpi->DoorbellWrite = Doorbell->WriteMask; - - PccAcpi->NominalLatency = ChannelTiming->NominalLatency; - PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; - PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; - - if ((PccCmObj->PlatIrq.Interrupt != 0)) { - mHasPlatformInterrupt = TRUE; - } - - return EFI_SUCCESS; -} - -/** Add one PCCT subspace structure of Type 2 (HW-Reduced). - - @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. - @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -AddSubspaceStructType2 ( - IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccCmObj, - IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi - ) -{ - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - - GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; - - if ((PccCmObj == NULL) || - (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS) || - (PccAcpi == NULL)) - { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - Doorbell = &GenericPccCmObj->DoorbellReg; - PlatIrqAck = &PccCmObj->PlatIrqAckReg; - ChannelTiming = &GenericPccCmObj->ChannelTiming; - - PccAcpi->Type = GenericPccCmObj->Type; - PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); - PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; - PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; - PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; - PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; - PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; - PccAcpi->AddressLength = GenericPccCmObj->AddressLength; - - CopyMem ( - &PccAcpi->DoorbellRegister, - &Doorbell->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; - PccAcpi->DoorbellWrite = Doorbell->WriteMask; - - PccAcpi->NominalLatency = ChannelTiming->NominalLatency; - PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; - PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; - - CopyMem ( - &PccAcpi->PlatformInterruptAckRegister, - &PlatIrqAck->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask; - PccAcpi->PlatformInterruptAckWrite = PlatIrqAck->WriteMask; - - if ((PccCmObj->PlatIrq.Interrupt != 0)) { - mHasPlatformInterrupt = TRUE; - } - - return EFI_SUCCESS; -} - -/** Add one PCCT subspace structure of Type 3 or 4 (Extended). - - @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. - @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -AddSubspaceStructType34 ( - IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccCmObj, - IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi - ) -{ - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; - PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; - PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate; - PCC_MAILBOX_REGISTER_INFO *ErrorStatus; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - - GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; - - if ((PccCmObj == NULL) || - ((GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC) && - (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC)) || - (PccAcpi == NULL)) - { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - Doorbell = &GenericPccCmObj->DoorbellReg; - PlatIrqAck = &PccCmObj->PlatIrqAckReg; - CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg; - CmdCompleteUpdate = &PccCmObj->CmdCompleteUpdateReg; - ErrorStatus = &PccCmObj->ErrorStatusReg; - ChannelTiming = &GenericPccCmObj->ChannelTiming; - - PccAcpi->Type = GenericPccCmObj->Type; - PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); - PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; - PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; - PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; - PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; - PccAcpi->AddressLength = GenericPccCmObj->AddressLength; - - CopyMem ( - &PccAcpi->DoorbellRegister, - &Doorbell->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; - PccAcpi->DoorbellWrite = Doorbell->WriteMask; - - PccAcpi->NominalLatency = ChannelTiming->NominalLatency; - PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; - PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; - - CopyMem ( - &PccAcpi->PlatformInterruptAckRegister, - &PlatIrqAck->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask; - PccAcpi->PlatformInterruptAckSet = PlatIrqAck->WriteMask; - - PccAcpi->Reserved1[0] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[3] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[4] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[5] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[6] = EFI_ACPI_RESERVED_BYTE; - PccAcpi->Reserved1[7] = EFI_ACPI_RESERVED_BYTE; - - CopyMem ( - &PccAcpi->CommandCompleteCheckRegister, - &CmdCompleteCheck->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask; - // No Write mask. - - CopyMem ( - &PccAcpi->CommandCompleteUpdateRegister, - &CmdCompleteUpdate->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->CommandCompleteUpdatePreserve = CmdCompleteUpdate->PreserveMask; - PccAcpi->CommandCompleteUpdateSet = CmdCompleteUpdate->WriteMask; - - CopyMem ( - &PccAcpi->ErrorStatusRegister, - &ErrorStatus->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask; - // No Write mask. - - if (GenericPccCmObj->Type == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) { - mHasPlatformInterrupt = TRUE; - } else if ((PccCmObj->PlatIrq.Interrupt != 0)) { - mHasPlatformInterrupt = TRUE; - } - - return EFI_SUCCESS; -} - -/** Add one PCCT subspace structure of Type 5 (HW-Registers). - - @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. - @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -AddSubspaceStructType5 ( - IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccCmObj, - IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi - ) -{ - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; - PCC_MAILBOX_REGISTER_INFO *Doorbell; - PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; - PCC_MAILBOX_REGISTER_INFO *ErrorStatus; - PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; - - GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; - - if ((PccCmObj == NULL) || - (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS) || - (PccAcpi == NULL)) - { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - Doorbell = &GenericPccCmObj->DoorbellReg; - CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg; - ErrorStatus = &PccCmObj->ErrorStatusReg; - ChannelTiming = &GenericPccCmObj->ChannelTiming; - - PccAcpi->Type = GenericPccCmObj->Type; - PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS); - PccAcpi->Version = PccCmObj->Version; - PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; - PccAcpi->SharedMemoryRangeLength = GenericPccCmObj->AddressLength; - - CopyMem ( - &PccAcpi->DoorbellRegister, - &Doorbell->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; - PccAcpi->DoorbellWrite = Doorbell->WriteMask; - - CopyMem ( - &PccAcpi->CommandCompleteCheckRegister, - &CmdCompleteCheck->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask; - // No Write mask. - - CopyMem ( - &PccAcpi->ErrorStatusRegister, - &ErrorStatus->Register, - sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) - ); - PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask; - // No Write mask. - - PccAcpi->NominalLatency = ChannelTiming->NominalLatency; - // No MaximumPeriodicAccessRate. - PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; - - return EFI_SUCCESS; -} - -/** Populate the PCCT table using the MappingTable. - - @param [in] MappingTable The mapping table structure. - @param [in] Pcc Pointer to an array of Pcc Subpace structures. - @param [in] Size Size of the Pcc array. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -PopulatePcctTable ( - IN MAPPING_TABLE *MappingTable, - IN VOID *Pcc, - IN UINT32 Size - ) -{ - EFI_STATUS Status; - UINT8 *PccBuffer; - UINT32 CmObjSize; - UINT32 Index; - UINT32 MaxIndex; - VOID **Table; - VOID *CurrentPccSubspace; - - ASSERT (MappingTable != NULL); - ASSERT (MappingTable->Table != NULL); - - PccBuffer = Pcc; - MaxIndex = MappingTable->MaxIndex; - Table = MappingTable->Table; - - for (Index = 0; Index < MaxIndex; Index++) { - CurrentPccSubspace = Table[Index]; - if (CurrentPccSubspace == NULL) { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - switch (((PCC_SUBSPACE_GENERIC_INFO *)CurrentPccSubspace)->Type) { - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: - Status = AddSubspaceStructType0 ( - (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace, - (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *)PccBuffer - ); - - CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: - Status = AddSubspaceStructType1 ( - (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace, - (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *)PccBuffer - ); - - CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: - Status = AddSubspaceStructType2 ( - (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace, - (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)PccBuffer - ); - - CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: - Status = AddSubspaceStructType34 ( - (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace, - (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *)PccBuffer - ); - - CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: - Status = AddSubspaceStructType34 ( - (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace, - (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC *)PccBuffer - ); - - CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC); - break; - - case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: - Status = AddSubspaceStructType5 ( - (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace, - (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *)PccBuffer - ); - - CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS); - break; - - default: - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } // switch - - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - if (Size < CmObjSize) { - ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL); - return EFI_BUFFER_TOO_SMALL; - } - - PccBuffer += CmObjSize; - Size -= CmObjSize; - } // for - - return EFI_SUCCESS; -} - -/** Construct the PCCT ACPI table. - - Called by the Dynamic Table Manager, this function invokes the - Configuration Manager protocol interface to get the required hardware - information for generating the ACPI table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. - @retval EFI_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildPcctTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - EFI_STATUS Status; - ACPI_PCCT_GENERATOR *Generator; - UINT32 TableSize; - EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *Pcct; - UINT8 *Buffer; - - MAPPING_TABLE *MappingTable; - UINT32 MappingTableCount; - - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccType0; - UINT32 PccType0Count; - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccType1; - UINT32 PccType1Count; - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccType2; - UINT32 PccType2Count; - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccType3; - UINT32 PccType3Count; - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *PccType4; - UINT32 PccType4Count; - CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccType5; - UINT32 PccType5Count; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: PCCT: Requested table revision = %d, is not supported." - "Supported table revision: Minimum = %d, Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return EFI_INVALID_PARAMETER; - } - - Generator = (ACPI_PCCT_GENERATOR *)This; - MappingTable = &Generator->MappingTable; - *Table = NULL; - - // First get all the Pcc Subpace CmObj of type X. - - Status = GetEArchCommonObjPccSubspaceType0Info ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PccType0, - &PccType0Count - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = GetEArchCommonObjPccSubspaceType1Info ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PccType1, - &PccType1Count - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = GetEArchCommonObjPccSubspaceType2Info ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PccType2, - &PccType2Count - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = GetEArchCommonObjPccSubspaceType3Info ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PccType3, - &PccType3Count - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = GetEArchCommonObjPccSubspaceType4Info ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PccType4, - &PccType4Count - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = GetEArchCommonObjPccSubspaceType5Info ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PccType5, - &PccType5Count - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - // Count the number of Pcc Subspaces. - MappingTableCount = PccType0Count; - MappingTableCount += PccType1Count; - MappingTableCount += PccType2Count; - MappingTableCount += PccType3Count; - MappingTableCount += PccType4Count; - MappingTableCount += PccType5Count; - - Status = MappingTableInitialize (MappingTable, MappingTableCount); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - // Map the Subspace Ids for all types. - - Status = MapPccSubspaceId (MappingTable, PccType0, PccType0Count); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = MapPccSubspaceId (MappingTable, PccType1, PccType1Count); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = MapPccSubspaceId (MappingTable, PccType2, PccType2Count); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = MapPccSubspaceId (MappingTable, PccType3, PccType3Count); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = MapPccSubspaceId (MappingTable, PccType4, PccType4Count); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Status = MapPccSubspaceId (MappingTable, PccType5, PccType5Count); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - // Compute the size of the PCCT table. - TableSize = sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER); - TableSize += PccType0Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC); - TableSize += PccType1Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); - TableSize += PccType2Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); - TableSize += PccType3Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); - TableSize += PccType4Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC); - TableSize += PccType5Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS); - - // Allocate a Buffer for the PCCT table. - *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); - if (*Table == NULL) { - Status = EFI_OUT_OF_RESOURCES; - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Pcct = (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *)*Table; - - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - &Pcct->Header, - AcpiTableInfo, - TableSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PCCT: Failed to add ACPI header. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - Buffer = (UINT8 *)Pcct; - Buffer += sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER); - TableSize -= sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER); - - // Populate the PCCT table by following the Subspace Id mapping. - Status = PopulatePcctTable (MappingTable, Buffer, TableSize); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto error_handler; - } - - // Setup the Reserved fields once mHasPlatformInterrupt hase been populated. - Pcct->Flags = mHasPlatformInterrupt; - Pcct->Reserved = EFI_ACPI_RESERVED_QWORD; - - MappingTableFree (MappingTable); - - return Status; - -error_handler: - DEBUG (( - DEBUG_ERROR, - "ERROR: PCCT: Failed to install table. Status = %r\n", - Status - )); - - if (*Table != NULL) { - FreePool (*Table); - *Table = NULL; - } - - MappingTableFree (MappingTable); - - return Status; -} - -/** Free any resources allocated for constructing the PCCT. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to the ACPI Table. - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -FreePcctTableResources ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || (*Table == NULL)) { - DEBUG ((DEBUG_ERROR, "ERROR: PCCT: Invalid Table Pointer\n")); - ASSERT ((Table != NULL) && (*Table != NULL)); - return EFI_INVALID_PARAMETER; - } - - FreePool (*Table); - *Table = NULL; - return EFI_SUCCESS; -} - -/** This macro defines the PCCT Table Generator revision. -*/ -#define PCCT_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the PCCT Table Generator. -*/ -STATIC -ACPI_PCCT_GENERATOR PcctGenerator = { - // ACPI table generator header - { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPcct), - // Generator Description - L"ACPI.STD.PCCT.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION, - // Minimum ACPI Table Revision supported by this Generator - EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - PCCT_GENERATOR_REVISION, - // Build Table function - BuildPcctTable, - // Free Resource function - FreePcctTableResources, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL - }, - - // Private fields are defined from here. - - // Mapping Table - { - // Table - NULL, - // MaxIndex - 0, - }, -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiPcctLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&PcctGenerator.Header); - DEBUG ((DEBUG_INFO, "PCCT: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiPcctLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&PcctGenerator.Header); - DEBUG ((DEBUG_INFO, "PCCT: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h deleted file mode 100644 index b99bf91b41..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h +++ /dev/null @@ -1,44 +0,0 @@ -/** @file - PCCT Table Generator - - Copyright (c) 2022, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.4 Specification - January 2021 - s14 PLATFORM COMMUNICATIONS CHANNEL (PCC) - -**/ - -#ifndef PCCT_GENERATOR_H_ -#define PCCT_GENERATOR_H_ - -#pragma pack(1) - -/** Structure used to map a Pcc Subspace to an index. -*/ -typedef struct MappingTable { - /// Mapping table for Subspace Ids. - /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer - VOID **Table; - - /// Number of entries in the Table. - UINT32 MaxIndex; -} MAPPING_TABLE; - -/** A structure holding the Pcct generator and additional private data. -*/ -typedef struct AcpiPcctGenerator { - /// ACPI Table generator header - ACPI_TABLE_GENERATOR Header; - - // Private fields are defined from here. - - /// Table to map: - /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer - MAPPING_TABLE MappingTable; -} ACPI_PCCT_GENERATOR; - -#pragma pack() - -#endif // PCCT_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf deleted file mode 100644 index 2c7d19513d..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf +++ /dev/null @@ -1,30 +0,0 @@ -## @file -# PPTT Table Generator -# -# Copyright (c) 2019, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x0001001B - BASE_NAME = AcpiPpttLibArm - FILE_GUID = FA102D52-5A92-4F95-A097-1D53F9CF5959 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiPpttLibConstructor - DESTRUCTOR = AcpiPpttLibDestructor - -[Sources] - PpttGenerator.c - PpttGenerator.h - -[Packages] - EmbeddedPkg/EmbeddedPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c deleted file mode 100644 index 2b8088a07f..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c +++ /dev/null @@ -1,1480 +0,0 @@ -/** @file - PPTT Table Generator - - Copyright (c) 2021, ARM Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.4 Specification, January 2021 - - @par Glossary: - - Cm or CM - Configuration Manager - - Obj or OBJ - Object -**/ - -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include - -#include "PpttGenerator.h" - -/** - ARM standard PPTT Generator - - Requirements: - The following Configuration Manager Object(s) are used by this Generator: - - EArchCommonObjProcHierarchyInfo (REQUIRED) - - EArchCommonObjCacheInfo - - EArchCommonObjCmRef - - EArmObjGicCInfo (REQUIRED) -*/ - -/** - This macro expands to a function that retrieves the Processor Hierarchy - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjProcHierarchyInfo, - CM_ARCH_COMMON_PROC_HIERARCHY_INFO - ); - -/** - This macro expands to a function that retrieves the cache information - from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjCacheInfo, - CM_ARCH_COMMON_CACHE_INFO - ); - -/** - This macro expands to a function that retrieves the cross-CM-object- - reference information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjCmRef, - CM_ARCH_COMMON_OBJ_REF - ); - -/** - This macro expands to a function that retrieves the GIC CPU interface - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicCInfo, - CM_ARM_GICC_INFO - ); - -/** - Returns the size of the PPTT Processor Hierarchy Node (Type 0) given a - Processor Hierarchy Info CM object. - - @param [in] Node Pointer to Processor Hierarchy Info CM object which - represents the Processor Hierarchy Node to be generated. - - @retval Size of the Processor Hierarchy Node in bytes. -**/ -STATIC -UINT32 -GetProcHierarchyNodeSize ( - IN CONST CM_ARCH_COMMON_PROC_HIERARCHY_INFO *Node - ) -{ - ASSERT (Node != NULL); - - // + - return sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR) + - (Node->NoOfPrivateResources * sizeof (UINT32)); -} - -/** - This macro expands to a function that retrieves the amount of memory required - to store the Processor Hierarchy Nodes (Type 0) and updates the Node Indexer. -*/ -GET_SIZE_OF_PPTT_STRUCTS ( - ProcHierarchyNodes, - GetProcHierarchyNodeSize (NodesToIndex), - CM_ARCH_COMMON_PROC_HIERARCHY_INFO - ); - -/** - This macro expands to a function that retrieves the amount of memory required - to store the Cache Type Structures (Type 1) and updates the Node Indexer. -*/ -GET_SIZE_OF_PPTT_STRUCTS ( - CacheTypeStructs, - sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE), - CM_ARCH_COMMON_CACHE_INFO - ); - -/** - Search the Node Indexer and return the indexed PPTT node with the given - Token. - - @param [in] NodeIndexer Pointer to the Node Indexer array. - @param [in] NodeCount Number of elements in Node Indexer. - @param [in] SearchToken Token used for Node Indexer lookup. - @param [out] IndexedNodeFound Pointer to the Node Indexer array element - with the given Token. - - @retval EFI_SUCCESS Success. - @retval EFI_NOT_FOUND No element with a matching token was - found in the Node Indexer array. -**/ -STATIC -EFI_STATUS -GetPpttNodeReferencedByToken ( - IN PPTT_NODE_INDEXER *NodeIndexer, - IN UINT32 NodeCount, - IN CONST CM_OBJECT_TOKEN SearchToken, - OUT PPTT_NODE_INDEXER **IndexedNodeFound - ) -{ - EFI_STATUS Status; - - ASSERT (NodeIndexer != NULL); - - DEBUG (( - DEBUG_INFO, - "PPTT: Node Indexer: SearchToken = %p\n", - SearchToken - )); - - while (NodeCount-- != 0) { - DEBUG (( - DEBUG_INFO, - "PPTT: Node Indexer: NodeIndexer->Token = %p. Offset = %d\n", - NodeIndexer->Token, - NodeIndexer->Offset - )); - - if (NodeIndexer->Token == SearchToken) { - *IndexedNodeFound = NodeIndexer; - Status = EFI_SUCCESS; - DEBUG (( - DEBUG_INFO, - "PPTT: Node Indexer: Token = %p. Found, Status = %r\n", - SearchToken, - Status - )); - return Status; - } - - NodeIndexer++; - } - - Status = EFI_NOT_FOUND; - DEBUG (( - DEBUG_ERROR, - "PPTT: Node Indexer: SearchToken = %p. Status = %r\n", - SearchToken, - Status - )); - - return Status; -} - -/** - Detect cycles in the processor and cache topology graph represented in - the PPTT table. - - @param [in] Generator Pointer to the PPTT Generator. - - @retval EFI_SUCCESS There are no cyclic references in the graph. - @retval EFI_INVALID_PARAMETER Processor or cache references form a cycle. -**/ -STATIC -EFI_STATUS -DetectCyclesInTopology ( - IN CONST ACPI_PPTT_GENERATOR *CONST Generator - ) -{ - EFI_STATUS Status; - PPTT_NODE_INDEXER *Iterator; - PPTT_NODE_INDEXER *CycleDetector; - UINT32 NodesRemaining; - - ASSERT (Generator != NULL); - - Iterator = Generator->NodeIndexer; - NodesRemaining = Generator->ProcTopologyStructCount; - - while (NodesRemaining != 0) { - DEBUG (( - DEBUG_INFO, - "INFO: PPTT: Cycle detection for element with index %d\n", - Generator->ProcTopologyStructCount - NodesRemaining - )); - - CycleDetector = Iterator; - - // Walk the topology tree - while (CycleDetector->TopologyParent != NULL) { - DEBUG (( - DEBUG_INFO, - "INFO: PPTT: %p -> %p\n", - CycleDetector->Token, - CycleDetector->TopologyParent->Token - )); - - // Check if we have already visited this node - if (CycleDetector->CycleDetectionStamp == NodesRemaining) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Cycle in processor and cache topology detected for " \ - "a chain of references originating from a node with: Token = %p " \ - "Status = %r\n", - Iterator->Token, - Status - )); - return Status; - } - - // Stamp the visited node - CycleDetector->CycleDetectionStamp = NodesRemaining; - CycleDetector = CycleDetector->TopologyParent; - } // Continue topology tree walk - - Iterator++; - NodesRemaining--; - } // Next Node Indexer - - return EFI_SUCCESS; -} - -/** - Update the array of private resources for a given Processor Hierarchy Node. - - @param [in] Generator Pointer to the PPTT Generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] PrivResArray Pointer to the array of private resources. - @param [in] PrivResCount Number of private resources. - @param [in] PrivResArrayToken Reference Token for the CM_ARCH_COMMON_OBJ_REF - array describing node's private resources. - - @retval EFI_SUCCESS Array updated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND A private resource was not found. -**/ -STATIC -EFI_STATUS -AddPrivateResources ( - IN CONST ACPI_PPTT_GENERATOR *CONST Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN UINT32 *PrivResArray, - IN UINT32 PrivResCount, - IN CONST CM_OBJECT_TOKEN PrivResArrayToken - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_OBJ_REF *CmObjRefs; - UINT32 CmObjRefCount; - PPTT_NODE_INDEXER *PpttNodeFound; - - ASSERT ( - (Generator != NULL) && - (CfgMgrProtocol != NULL) && - (PrivResArray != NULL) && - (PrivResCount != 0) - ); - - // Validate input arguments - if (PrivResArrayToken == CM_NULL_TOKEN) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The number of private resources is %d while " \ - "PrivResToken = CM_NULL_TOKEN. Status = %r\n", - PrivResCount, - Status - )); - return Status; - } - - CmObjRefCount = 0; - // Get the CM Object References - Status = GetEArchCommonObjCmRef ( - CfgMgrProtocol, - PrivResArrayToken, - &CmObjRefs, - &CmObjRefCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get CM Object References. " \ - "PrivResToken = %p. Status = %r\n", - PrivResArrayToken, - Status - )); - return Status; - } - - if (CmObjRefCount != PrivResCount) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The number of CM Object References retrieved and the " \ - "number of private resources don't match. CmObjRefCount = %d. " \ - "PrivResourceCount = %d. PrivResToken = %p. Status = %r\n", - CmObjRefCount, - PrivResCount, - PrivResArrayToken, - Status - )); - return Status; - } - - while (PrivResCount-- != 0) { - if (CmObjRefs->ReferenceToken == CM_NULL_TOKEN) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: CM_NULL_TOKEN provided as reference token for a " \ - "private resource. Status = %r\n", - Status - )); - return Status; - } - - // The Node indexer has the Processor hierarchy nodes at the begining - // followed by the cache structs. Therefore we can skip the Processor - // hierarchy nodes in the node indexer search. - Status = GetPpttNodeReferencedByToken ( - Generator->CacheStructIndexedList, - (Generator->ProcTopologyStructCount - - Generator->ProcHierarchyNodeCount), - CmObjRefs->ReferenceToken, - &PpttNodeFound - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get a private resource with Token = %p from " \ - "Node Indexer. Status = %r\n", - CmObjRefs->ReferenceToken, - Status - )); - return Status; - } - - // Update the offset of the private resources in the Processor - // Hierarchy Node structure - *(PrivResArray++) = PpttNodeFound->Offset; - CmObjRefs++; - } - - return EFI_SUCCESS; -} - -/** - Function to test if two indexed Processor Hierarchy Info objects map to the - same GIC CPU Interface Info object. - - This is a callback function that can be invoked by FindDuplicateValue (). - - @param [in] Object1 Pointer to the first indexed Processor Hierarchy - Info object. - @param [in] Object2 Pointer to the second indexed Processor Hierarchy - Info object. - @param [in] Index1 Index of Object1 to be displayed for debugging - purposes. - @param [in] Index2 Index of Object2 to be displayed for debugging - purposes. - - @retval TRUE Object1 and Object2 have the same - AcpiIdObjectToken. - @retval FALSE Object1 and Object2 have different - AcpiIdObjectTokens. -**/ -BOOLEAN -EFIAPI -IsAcpiIdObjectTokenEqual ( - IN CONST VOID *Object1, - IN CONST VOID *Object2, - IN UINTN Index1, - IN UINTN Index2 - ) -{ - PPTT_NODE_INDEXER *IndexedObject1; - PPTT_NODE_INDEXER *IndexedObject2; - CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode1; - CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode2; - - ASSERT ( - (Object1 != NULL) && - (Object2 != NULL) - ); - - IndexedObject1 = (PPTT_NODE_INDEXER *)Object1; - IndexedObject2 = (PPTT_NODE_INDEXER *)Object2; - ProcNode1 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject1->Object; - ProcNode2 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject2->Object; - - if (IS_ACPI_PROC_ID_VALID (ProcNode1) && - IS_ACPI_PROC_ID_VALID (ProcNode2) && - (ProcNode1->AcpiIdObjectToken != CM_NULL_TOKEN) && - (ProcNode2->AcpiIdObjectToken != CM_NULL_TOKEN) && - (ProcNode1->AcpiIdObjectToken == ProcNode2->AcpiIdObjectToken)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Two Processor Hierarchy Info objects (%d and %d) map to " \ - "the same ACPI ID reference object. ACPI Processor IDs are not unique. " \ - "AcpiIdObjectToken = %p.\n", - Index1, - Index2, - ProcNode1->AcpiIdObjectToken - )); - return TRUE; - } - - return FALSE; -} - -/** - Update the Processor Hierarchy Node (Type 0) information. - - This function populates the Processor Hierarchy Nodes with information from - the Configuration Manager and adds this information to the PPTT table. - - @param [in] Generator Pointer to the PPTT Generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Pptt Pointer to PPTT table structure. - @param [in] NodesStartOffset Offset from the start of PPTT table to the - start of Processor Hierarchy Nodes. - - @retval EFI_SUCCESS Node updated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. -**/ -STATIC -EFI_STATUS -AddProcHierarchyNodes ( - IN CONST ACPI_PPTT_GENERATOR *CONST Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt, - IN CONST UINT32 NodesStartOffset - ) -{ - EFI_STATUS Status; - EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *ProcStruct; - UINT32 *PrivateResources; - BOOLEAN IsAcpiIdObjectTokenDuplicated; - - CM_ARM_GICC_INFO *GicCInfoList; - UINT32 GicCInfoCount; - UINT32 UniqueGicCRefCount; - - PPTT_NODE_INDEXER *PpttNodeFound; - CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcInfoNode; - - PPTT_NODE_INDEXER *ProcNodeIterator; - UINT32 NodeCount; - UINT32 Length; - - ASSERT ( - (Generator != NULL) && - (CfgMgrProtocol != NULL) && - (Pptt != NULL) - ); - - ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)Pptt + - NodesStartOffset); - - ProcNodeIterator = Generator->ProcHierarchyNodeIndexedList; - NodeCount = Generator->ProcHierarchyNodeCount; - - // Check if every GICC Object is referenced by onlu one Proc Node - IsAcpiIdObjectTokenDuplicated = FindDuplicateValue ( - ProcNodeIterator, - NodeCount, - sizeof (PPTT_NODE_INDEXER), - IsAcpiIdObjectTokenEqual - ); - // Duplicate GIC CPU Interface Token was found so two PPTT Processor Hierarchy - // Nodes map to the same MADT GICC structure - if (IsAcpiIdObjectTokenDuplicated) { - return EFI_INVALID_PARAMETER; - } - - UniqueGicCRefCount = 0; - - while (NodeCount-- != 0) { - ProcInfoNode = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object; - - // Check if the private resource count is within the size limit - // imposed on the Processor Hierarchy node by the specification. - // Note: The length field is 8 bit wide while the number of private - // resource field is 32 bit wide. - Length = GetProcHierarchyNodeSize (ProcInfoNode); - if (Length > MAX_UINT8) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Too many private resources. Count = %d. " \ - "Maximum supported Processor Node size exceeded. " \ - "Token = %p. Status = %r\n", - ProcInfoNode->NoOfPrivateResources, - ProcInfoNode->ParentToken, - Status - )); - return Status; - } - - // Populate the node header - ProcStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR; - ProcStruct->Length = (UINT8)Length; - ProcStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE; - ProcStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE; - - // Populate the flags - ProcStruct->Flags.PhysicalPackage = ProcInfoNode->Flags & BIT0; - ProcStruct->Flags.AcpiProcessorIdValid = (ProcInfoNode->Flags & BIT1) >> 1; - ProcStruct->Flags.ProcessorIsAThread = (ProcInfoNode->Flags & BIT2) >> 2; - ProcStruct->Flags.NodeIsALeaf = (ProcInfoNode->Flags & BIT3) >> 3; - ProcStruct->Flags.IdenticalImplementation = - (ProcInfoNode->Flags & BIT4) >> 4; - ProcStruct->Flags.Reserved = 0; - - // Populate the parent reference - if (ProcInfoNode->ParentToken == CM_NULL_TOKEN) { - ProcStruct->Parent = 0; - } else { - Status = GetPpttNodeReferencedByToken ( - Generator->ProcHierarchyNodeIndexedList, - Generator->ProcHierarchyNodeCount, - ProcInfoNode->ParentToken, - &PpttNodeFound - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get parent processor hierarchy node " \ - "reference. ParentToken = %p. ChildToken = %p. Status = %r\n", - ProcInfoNode->ParentToken, - ProcInfoNode->Token, - Status - )); - return Status; - } - - // Test if the reference is to a 'leaf' node - if (IS_PROC_NODE_LEAF ( - ((CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)PpttNodeFound->Object) - )) - { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Reference to a leaf Processor Hierarchy Node. " \ - "ParentToken = %p. ChildToken = %p. Status = %r\n", - ProcInfoNode->ParentToken, - ProcInfoNode->Token, - Status - )); - return Status; - } - - // Update Proc Structure with the offset of the parent node - ProcStruct->Parent = PpttNodeFound->Offset; - - // Store the reference for the parent node in the Node Indexer - // so that this can be used later for cycle detection - ProcNodeIterator->TopologyParent = PpttNodeFound; - } - - // Populate ACPI Processor ID - if (!IS_ACPI_PROC_ID_VALID (ProcInfoNode)) { - // Default invalid ACPI Processor ID to 0 - ProcStruct->AcpiProcessorId = 0; - } else if (ProcInfoNode->AcpiIdObjectToken == CM_NULL_TOKEN) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no " \ - "ACPI ID Reference object token was provided. " \ - "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n", - ProcInfoNode->AcpiIdObjectToken, - ProcInfoNode->Token, - Status - )); - return Status; - } else { - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - ProcInfoNode->AcpiIdObjectToken, - &GicCInfoList, - &GicCInfoCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get ACPI ID Reference object token. " \ - "ACPI Processor ID can't be populated. " \ - "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n", - ProcInfoNode->AcpiIdObjectToken, - ProcInfoNode->Token, - Status - )); - return Status; - } - - if (GicCInfoCount != 1) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to find a unique GICC structure. " \ - "ACPI Processor ID can't be populated. " \ - "GICC Structure Count = %d. AcpiIdObjectToken = %p. RequestorToken = %p " \ - "Status = %r\n", - GicCInfoCount, - ProcInfoNode->AcpiIdObjectToken, - ProcInfoNode->Token, - Status - )); - return Status; - } - - // Update the ACPI Processor Id - ProcStruct->AcpiProcessorId = GicCInfoList->AcpiProcessorUid; - - // Increment the reference count for the number of - // Unique GICC objects that were retrieved. - UniqueGicCRefCount++; - } - - ProcStruct->NumberOfPrivateResources = ProcInfoNode->NoOfPrivateResources; - PrivateResources = (UINT32 *)((UINT8 *)ProcStruct + - sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR)); - - if (ProcStruct->NumberOfPrivateResources != 0) { - // Populate the private resources array - Status = AddPrivateResources ( - Generator, - CfgMgrProtocol, - PrivateResources, - ProcStruct->NumberOfPrivateResources, - ProcInfoNode->PrivateResourcesArrayToken - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to populate the private resources array. " \ - "Status = %r\n", - Status - )); - return Status; - } - } - - // Next Processor Hierarchy Node - ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)ProcStruct + - ProcStruct->Length); - ProcNodeIterator++; - } // Processor Hierarchy Node - - // Knowing the total number of GICC references made and that all GICC Token - // references are unique, we can test if no GICC instances have been left out. - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicCInfoList, - &GicCInfoCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get GICC Info. Status = %r\n", - Status - )); - return Status; - } - - // MADT - PPTT cross validation - // This checks that one and only one GICC structure is referenced by a - // Processor Hierarchy Node in the PPTT. - // Since we have already checked that the GICC objects referenced by the - // Proc Nodes are unique, the UniqueGicCRefCount cannot be greater than - // the total number of GICC objects in the platform. - if (GicCInfoCount > UniqueGicCRefCount) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: %d GICC structure(s) exposed by MADT don't have " \ - "a corresponding Processor Hierarchy Node. Status = %r\n", - GicCInfoCount - UniqueGicCRefCount, - Status - )); - } - - return Status; -} - -/** - Test whether CacheId is unique among the CacheIdList. - - @param [in] CacheId Cache ID to check. - @param [in] CacheIdList List of already existing cache IDs. - @param [in] CacheIdListSize Size of CacheIdList. - - @retval TRUE CacheId does not exist in CacheIdList. - @retval FALSE CacheId already exists in CacheIdList. -**/ -STATIC -BOOLEAN -IsCacheIdUnique ( - IN CONST UINT32 CacheId, - IN CONST UINT32 *CacheIdList, - IN CONST UINT32 CacheIdListSize - ) -{ - UINT32 Index; - - for (Index = 0; Index < CacheIdListSize; Index++) { - if (CacheIdList[Index] == CacheId) { - return FALSE; - } - } - - return TRUE; -} - -/** - Update the Cache Type Structure (Type 1) information. - - This function populates the Cache Type Structures with information from - the Configuration Manager and adds this information to the PPTT table. - - @param [in] Generator Pointer to the PPTT Generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Pptt Pointer to PPTT table structure. - @param [in] NodesStartOffset Offset from the start of PPTT table to the - start of Cache Type Structures. - @param [in] Revision Revision of the PPTT table being requested. - - @retval EFI_SUCCESS Structures updated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND A required object was not found. - @retval EFI_OUT_OF_RESOURCES Out of resources. -**/ -STATIC -EFI_STATUS -AddCacheTypeStructures ( - IN CONST ACPI_PPTT_GENERATOR *CONST Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt, - IN CONST UINT32 NodesStartOffset, - IN CONST UINT32 Revision - ) -{ - EFI_STATUS Status; - EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *CacheStruct; - PPTT_NODE_INDEXER *PpttNodeFound; - CM_ARCH_COMMON_CACHE_INFO *CacheInfoNode; - PPTT_NODE_INDEXER *CacheNodeIterator; - UINT32 NodeCount; - BOOLEAN CacheIdUnique; - UINT32 NodeIndex; - UINT32 *FoundCacheIds; - - ASSERT ( - (Generator != NULL) && - (CfgMgrProtocol != NULL) && - (Pptt != NULL) - ); - - CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *)((UINT8 *)Pptt + - NodesStartOffset); - - CacheNodeIterator = Generator->CacheStructIndexedList; - NodeCount = Generator->CacheStructCount; - - FoundCacheIds = AllocateZeroPool (NodeCount * sizeof (*FoundCacheIds)); - if (FoundCacheIds == NULL) { - DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Failed to allocate resources.\n")); - return EFI_OUT_OF_RESOURCES; - } - - for (NodeIndex = 0; NodeIndex < NodeCount; NodeIndex++) { - CacheInfoNode = (CM_ARCH_COMMON_CACHE_INFO *)CacheNodeIterator->Object; - - // Populate the node header - CacheStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_CACHE; - CacheStruct->Length = sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE); - CacheStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE; - CacheStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE; - - // "On Arm-based systems, all cache properties must be provided in the - // table." (ACPI 6.4, Section 5.2.29.2) - CacheStruct->Flags.SizePropertyValid = 1; - CacheStruct->Flags.NumberOfSetsValid = 1; - CacheStruct->Flags.AssociativityValid = 1; - CacheStruct->Flags.AllocationTypeValid = 1; - CacheStruct->Flags.CacheTypeValid = 1; - CacheStruct->Flags.WritePolicyValid = 1; - CacheStruct->Flags.LineSizeValid = 1; - CacheStruct->Flags.CacheIdValid = 1; - CacheStruct->Flags.Reserved = 0; - - // Populate the reference to the next level of cache - if (CacheInfoNode->NextLevelOfCacheToken == CM_NULL_TOKEN) { - CacheStruct->NextLevelOfCache = 0; - } else { - Status = GetPpttNodeReferencedByToken ( - Generator->CacheStructIndexedList, - Generator->CacheStructCount, - CacheInfoNode->NextLevelOfCacheToken, - &PpttNodeFound - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get the reference to the Next Level of " \ - "Cache. NextLevelOfCacheToken = %p. RequestorToken = %p. " \ - "Status = %r\n", - CacheInfoNode->NextLevelOfCacheToken, - CacheInfoNode->Token, - Status - )); - goto cleanup; - } - - // Update Cache Structure with the offset for the next level of cache - CacheStruct->NextLevelOfCache = PpttNodeFound->Offset; - - // Store the next level of cache information in the Node Indexer - // so that this can be used later for cycle detection - CacheNodeIterator->TopologyParent = PpttNodeFound; - } - - CacheStruct->Size = CacheInfoNode->Size; - - // Validate and populate the 'Number of sets' field - if (CacheInfoNode->NumberOfSets > PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: When ARMv8.3-CCIDX is implemented the maximum number " \ - "of sets can be %d. NumberOfSets = %d. Status = %r\n", - PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX, - CacheInfoNode->NumberOfSets, - Status - )); - goto cleanup; - } - - if (CacheInfoNode->NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) { - DEBUG (( - DEBUG_INFO, - "INFO: PPTT: When ARMv8.3-CCIDX is not implemented the maximum " \ - "number of sets can be %d. NumberOfSets = %d\n", - PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX, - CacheInfoNode->NumberOfSets - )); - } - - CacheStruct->NumberOfSets = CacheInfoNode->NumberOfSets; - - // Validate Associativity field based on maximum associativity - // supported by ACPI Cache type structure. - if (CacheInfoNode->Associativity > MAX_UINT8) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The maximum associativity supported by ACPI " \ - "Cache type structure is %d. Associativity = %d, Status = %r\n", - MAX_UINT8, - CacheInfoNode->Associativity, - Status - )); - goto cleanup; - } - - // Validate the Associativity field based on the architecture specification - // The architecture supports much larger associativity values than the - // current ACPI specification. - // These checks will be needed in the future when the ACPI specification - // is extended. Disabling this code for now. - #if 0 - if (CacheInfoNode->Associativity > PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: When ARMv8.3-CCIDX is implemented the maximum cache " \ - "associativity can be %d. Associativity = %d. Status = %r\n", - PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX, - CacheInfoNode->Associativity, - Status - )); - goto cleanup; - } - - if (CacheInfoNode->Associativity > PPTT_ARM_CACHE_ASSOCIATIVITY_MAX) { - DEBUG (( - DEBUG_INFO, - "INFO: PPTT: When ARMv8.3-CCIDX is not implemented the maximum " \ - "cache associativity can be %d. Associativity = %d\n", - PPTT_ARM_CACHE_ASSOCIATIVITY_MAX, - CacheInfoNode->Associativity - )); - } - - #endif - - // Note a typecast is needed as the maximum associativity - // supported by ACPI Cache type structure is MAX_UINT8. - CacheStruct->Associativity = (UINT8)CacheInfoNode->Associativity; - - // Populate cache attributes - CacheStruct->Attributes.AllocationType = - CacheInfoNode->Attributes & (BIT0 | BIT1); - CacheStruct->Attributes.CacheType = - (CacheInfoNode->Attributes & (BIT2 | BIT3)) >> 2; - CacheStruct->Attributes.WritePolicy = - (CacheInfoNode->Attributes & BIT4) >> 4; - CacheStruct->Attributes.Reserved = 0; - - // Validate and populate cache line size - if ((CacheInfoNode->LineSize < PPTT_ARM_CACHE_LINE_SIZE_MIN) || - (CacheInfoNode->LineSize > PPTT_ARM_CACHE_LINE_SIZE_MAX)) - { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The cache line size must be between %d and %d bytes " \ - "on ARM Platforms. LineSize = %d. Status = %r\n", - PPTT_ARM_CACHE_LINE_SIZE_MIN, - PPTT_ARM_CACHE_LINE_SIZE_MAX, - CacheInfoNode->LineSize, - Status - )); - goto cleanup; - } - - if ((CacheInfoNode->LineSize & (CacheInfoNode->LineSize - 1)) != 0) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The cache line size is not a power of 2. " \ - "LineSize = %d. Status = %r\n", - CacheInfoNode->LineSize, - Status - )); - goto cleanup; - } - - CacheStruct->LineSize = CacheInfoNode->LineSize; - - if (Revision >= 3) { - // Validate and populate cache id - if (CacheInfoNode->CacheId == 0) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The cache id cannot be zero. Status = %r\n", - Status - )); - goto cleanup; - } - - CacheIdUnique = IsCacheIdUnique ( - CacheInfoNode->CacheId, - FoundCacheIds, - NodeIndex - ); - if (!CacheIdUnique) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: The cache id is not unique. " \ - "CacheId = %d. Status = %r\n", - CacheInfoNode->CacheId, - Status - )); - goto cleanup; - } - - // Store the cache id so we can check future cache ids for uniqueness - FoundCacheIds[NodeIndex] = CacheInfoNode->CacheId; - - CacheStruct->CacheId = CacheInfoNode->CacheId; - } - - // Next Cache Type Structure - CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *)((UINT8 *)CacheStruct + - CacheStruct->Length); - CacheNodeIterator++; - } // for Cache Type Structure - - Status = EFI_SUCCESS; - -cleanup: - FreePool (FoundCacheIds); - - return Status; -} - -/** - Construct the PPTT ACPI table. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI table generator to be used. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for - the requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildPpttTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - EFI_STATUS Status; - UINT32 TableSize; - UINT32 ProcTopologyStructCount; - UINT32 ProcHierarchyNodeCount; - UINT32 CacheStructCount; - - UINT32 ProcHierarchyNodeOffset; - UINT32 CacheStructOffset; - - CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; - CM_ARCH_COMMON_CACHE_INFO *CacheStructList; - - ACPI_PPTT_GENERATOR *Generator; - - // Pointer to the Node Indexer array - PPTT_NODE_INDEXER *NodeIndexer; - - EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt; - - ASSERT ( - (This != NULL) && - (AcpiTableInfo != NULL) && - (CfgMgrProtocol != NULL) && - (Table != NULL) && - (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && - (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) - ); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Requested table revision = %d is not supported. " - "Supported table revisions: Minimum = %d. Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - return EFI_INVALID_PARAMETER; - } - - Generator = (ACPI_PPTT_GENERATOR *)This; - *Table = NULL; - - // Get the processor hierarchy info and update the processor topology - // structure count with Processor Hierarchy Nodes (Type 0) - Status = GetEArchCommonObjProcHierarchyInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &ProcHierarchyNodeList, - &ProcHierarchyNodeCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get processor hierarchy info. Status = %r\n", - Status - )); - goto error_handler; - } - - ProcTopologyStructCount = ProcHierarchyNodeCount; - Generator->ProcHierarchyNodeCount = ProcHierarchyNodeCount; - - // Get the cache info and update the processor topology structure count with - // Cache Type Structures (Type 1) - Status = GetEArchCommonObjCacheInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &CacheStructList, - &CacheStructCount - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to get cache info. Status = %r\n", - Status - )); - goto error_handler; - } - - ProcTopologyStructCount += CacheStructCount; - Generator->CacheStructCount = CacheStructCount; - - // Allocate Node Indexer array - NodeIndexer = (PPTT_NODE_INDEXER *)AllocateZeroPool ( - sizeof (PPTT_NODE_INDEXER) * - ProcTopologyStructCount - ); - if (NodeIndexer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to allocate memory for Node Indexer. Status = %r\n ", - Status - )); - goto error_handler; - } - - DEBUG ((DEBUG_INFO, "INFO: NodeIndexer = %p\n", NodeIndexer)); - Generator->ProcTopologyStructCount = ProcTopologyStructCount; - Generator->NodeIndexer = NodeIndexer; - - // Calculate the size of the PPTT table - TableSize = sizeof (EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER); - - // Include the size of Processor Hierarchy Nodes and index them - if (Generator->ProcHierarchyNodeCount != 0) { - ProcHierarchyNodeOffset = TableSize; - Generator->ProcHierarchyNodeIndexedList = NodeIndexer; - TableSize += GetSizeofProcHierarchyNodes ( - ProcHierarchyNodeOffset, - ProcHierarchyNodeList, - Generator->ProcHierarchyNodeCount, - &NodeIndexer - ); - - DEBUG (( - DEBUG_INFO, - " ProcHierarchyNodeCount = %d\n" \ - " ProcHierarchyNodeOffset = 0x%x\n" \ - " ProcHierarchyNodeIndexedList = 0x%p\n", - Generator->ProcHierarchyNodeCount, - ProcHierarchyNodeOffset, - Generator->ProcHierarchyNodeIndexedList - )); - } - - // Include the size of Cache Type Structures and index them - if (Generator->CacheStructCount != 0) { - CacheStructOffset = TableSize; - Generator->CacheStructIndexedList = NodeIndexer; - TableSize += GetSizeofCacheTypeStructs ( - CacheStructOffset, - CacheStructList, - Generator->CacheStructCount, - &NodeIndexer - ); - DEBUG (( - DEBUG_INFO, - " CacheStructCount = %d\n" \ - " CacheStructOffset = 0x%x\n" \ - " CacheStructIndexedList = 0x%p\n", - Generator->CacheStructCount, - CacheStructOffset, - Generator->CacheStructIndexedList - )); - } - - DEBUG (( - DEBUG_INFO, - "INFO: PPTT:\n" \ - " ProcTopologyStructCount = %d\n" \ - " TableSize = %d\n", - ProcTopologyStructCount, - TableSize - )); - - // Allocate the Buffer for the PPTT table - *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); - if (*Table == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to allocate memory for PPTT Table. " \ - "Size = %d. Status = %r\n", - TableSize, - Status - )); - goto error_handler; - } - - Pptt = (EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *)*Table; - - DEBUG (( - DEBUG_INFO, - "PPTT: Pptt = 0x%p. TableSize = 0x%x\n", - Pptt, - TableSize - )); - - // Add ACPI header - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - &Pptt->Header, - AcpiTableInfo, - TableSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to add ACPI header. Status = %r\n", - Status - )); - goto error_handler; - } - - // Add Processor Hierarchy Nodes (Type 0) to the generated table - if (Generator->ProcHierarchyNodeCount != 0) { - Status = AddProcHierarchyNodes ( - Generator, - CfgMgrProtocol, - Pptt, - ProcHierarchyNodeOffset - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to add Processor Hierarchy Nodes. Status = %r\n", - Status - )); - goto error_handler; - } - } - - // Add Cache Type Structures (Type 1) to the generated table - if (Generator->CacheStructCount != 0) { - Status = AddCacheTypeStructures ( - Generator, - CfgMgrProtocol, - Pptt, - CacheStructOffset, - AcpiTableInfo->AcpiTableRevision - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Failed to add Cache Type Structures. Status = %r\n", - Status - )); - goto error_handler; - } - } - - // Validate CM object cross-references in PPTT - Status = DetectCyclesInTopology (Generator); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: PPTT: Invalid processor and cache topology. Status = %r\n", - Status - )); - goto error_handler; - } - - return Status; - -error_handler: - if (Generator->NodeIndexer != NULL) { - FreePool (Generator->NodeIndexer); - Generator->NodeIndexer = NULL; - } - - if (*Table != NULL) { - FreePool (*Table); - *Table = NULL; - } - - return Status; -} - -/** - Free any resources allocated for constructing the PPTT - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to the ACPI Table. - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -FreePpttTableResources ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - ACPI_PPTT_GENERATOR *Generator; - - ASSERT ( - (This != NULL) && - (AcpiTableInfo != NULL) && - (CfgMgrProtocol != NULL) && - (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && - (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) - ); - - Generator = (ACPI_PPTT_GENERATOR *)This; - - // Free any memory allocated by the generator - if (Generator->NodeIndexer != NULL) { - FreePool (Generator->NodeIndexer); - Generator->NodeIndexer = NULL; - } - - if ((Table == NULL) || (*Table == NULL)) { - DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Invalid Table Pointer\n")); - ASSERT ( - (Table != NULL) && - (*Table != NULL) - ); - return EFI_INVALID_PARAMETER; - } - - FreePool (*Table); - *Table = NULL; - return EFI_SUCCESS; -} - -/** The PPTT Table Generator revision. -*/ -#define PPTT_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the PPTT Table Generator. -*/ -STATIC -ACPI_PPTT_GENERATOR PpttGenerator = { - // ACPI table generator header - { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt), - // Generator Description - L"ACPI.STD.PPTT.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION, - // Minimum supported ACPI Table Revision - EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - PPTT_GENERATOR_REVISION, - // Build Table function - BuildPpttTable, - // Free Resource function - FreePpttTableResources, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL - }, - - // PPTT Generator private data - - // Processor topology node count - 0, - // Count of Processor Hierarchy Nodes - 0, - // Count of Cache Structures - 0, - // Pointer to PPTT Node Indexer - NULL -}; - -/** - Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiPpttLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&PpttGenerator.Header); - DEBUG ((DEBUG_INFO, "PPTT: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** - Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiPpttLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&PpttGenerator.Header); - DEBUG ((DEBUG_INFO, "PPTT: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h deleted file mode 100644 index 15b0a9871c..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h +++ /dev/null @@ -1,185 +0,0 @@ -/** @file - Header file for the dynamic PPTT generator - - Copyright (c) 2019, ARM Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.3 Specification, January 2019 - - ARM Architecture Reference Manual ARMv8 (D.a) - - @par Glossary: - - Cm or CM - Configuration Manager - - Obj or OBJ - Object -**/ - -#ifndef PPTT_GENERATOR_H_ -#define PPTT_GENERATOR_H_ - -#pragma pack(1) - -/// Cache parameters allowed by the architecture with -/// ARMv8.3-CCIDX (Cache extended number of sets) -/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0001 -#define PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX (1 << 24) -#define PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX (1 << 21) - -/// Cache parameters allowed by the architecture without -/// ARMv8.3-CCIDX (Cache extended number of sets) -/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0000 -#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX (1 << 15) -#define PPTT_ARM_CACHE_ASSOCIATIVITY_MAX (1 << 10) - -/// Common cache parameters -/// Derived from CCSIDR_EL1 -/// The LineSize is represented by bits 2:0 -/// (Log2(Number of bytes in cache line)) - 4 is used to represent -/// the LineSize bits. -#define PPTT_ARM_CACHE_LINE_SIZE_MAX (1 << 11) -#define PPTT_ARM_CACHE_LINE_SIZE_MIN (1 << 4) - -/// Test if the given Processor Hierarchy Info object has the 'Node is a Leaf' -/// flag set -#define IS_PROC_NODE_LEAF(Node) ((Node->Flags & BIT3) != 0) - -/// Test if the given Processor Hierarchy Info object has the 'ACPI Processor -/// ID valid' flag set -#define IS_ACPI_PROC_ID_VALID(Node) ((Node->Flags & BIT1) != 0) - -/** - The GET_SIZE_OF_PPTT_STRUCTS macro expands to a function that is used to - calculate the total memory requirement for the PPTT structures represented - by the given list of Configuration Manager Objects of the same type. This - function also indexes the input CM objects so that various other CM objects - (possibly of different type) can reference them. - - The size of memory needed for the specified type of PPTT structures is based - on the number and type of CM objects provided. The macro assumes that the - ACPI object PpttObjName has fixed size. - - The macro expands to a function which has the following prototype: - - STATIC - UINT32 - EFIAPI - GetSizeof ( - IN CONST UINT32 StartOffset, - IN CONST CmObjectType * Nodes, - IN UINT32 NodeCount, - IN OUT PPTT_NODE_INDEXER ** CONST NodeIndexer - ) - - Generated function parameters: - @param [in] StartOffset Offset from the start of PPTT to where - the PPTT structures will be placed. - @param [in] NodesToIndex Pointer to the list of CM objects to be - indexed and size-estimated. - @param [out] NodeCount Number of CM objects in NodesToIndex. - @param [in, out] NodeIndexer Pointer to the list of Node Indexer - elements to populate. - @retval Size Total memory requirement for the PPTT - structures described in NodesToIndex. - - Macro Parameters: - @param [in] PpttObjName Name for the type of PPTT structures which - size is estimated. - @param [in] PpttObjSize Expression to use to calculate the size of - of a single instance of the PPTT structure - which corresponds to the CM object being - indexed. - @param [in] CmObjectType Data type of the CM nodes in NodesToIndex. -**/ -#define GET_SIZE_OF_PPTT_STRUCTS( \ - PpttObjName, \ - PpttObjSize, \ - CmObjectType \ - ) \ -STATIC \ -UINT32 \ -GetSizeof##PpttObjName ( \ - IN CONST UINT32 StartOffset, \ - IN CONST CmObjectType * NodesToIndex, \ - IN UINT32 NodeCount, \ - IN OUT PPTT_NODE_INDEXER ** CONST NodeIndexer \ - ) \ -{ \ - UINT32 Size; \ - \ - ASSERT ( \ - (NodesToIndex != NULL) && \ - (NodeIndexer != NULL) \ - ); \ - \ - Size = 0; \ - while (NodeCount-- != 0) { \ - (*NodeIndexer)->Token = NodesToIndex->Token; \ - (*NodeIndexer)->Object = (VOID*)NodesToIndex; \ - (*NodeIndexer)->Offset = Size + StartOffset; \ - (*NodeIndexer)->CycleDetectionStamp = 0; \ - (*NodeIndexer)->TopologyParent = NULL; \ - DEBUG (( \ - DEBUG_INFO, \ - "PPTT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", \ - *NodeIndexer, \ - (*NodeIndexer)->Token, \ - (*NodeIndexer)->Object, \ - (*NodeIndexer)->Offset \ - )); \ - \ - Size += PpttObjSize; \ - (*NodeIndexer)++; \ - NodesToIndex++; \ - } \ - return Size; \ -} - -/** - A structure for indexing CM objects (nodes) used in PPTT generation. - - PPTT_NODE_INDEXER is a wrapper around CM objects which augments these objects - with additional information that enables generating PPTT structures with - correct cross-references. - - PPTT_NODE_INDEXER keeps track of each structure's offset from the base - address of the generated table. It also caches certain information and makes - PPTT cyclic reference detection possible. -*/ -typedef struct PpttNodeIndexer { - /// Unique identifier for the node - CM_OBJECT_TOKEN Token; - /// Pointer to the CM object being indexed - VOID *Object; - /// Offset from the start of the PPTT table to the PPTT structure which is - /// represented by Object - UINT32 Offset; - /// Field used to mark nodes as 'visited' when detecting cycles in processor - /// and cache topology - UINT32 CycleDetectionStamp; - /// Reference to a Node Indexer element which is the parent of this Node - /// Indexer element in the processor and cache topology - /// e.g For a hardware thread the TopologyParent would point to a CPU node - /// For a L1 cache the TopologyParent would point to a L2 cache - struct PpttNodeIndexer *TopologyParent; -} PPTT_NODE_INDEXER; - -typedef struct AcpiPpttGenerator { - /// ACPI Table generator header - ACPI_TABLE_GENERATOR Header; - /// PPTT structure count - UINT32 ProcTopologyStructCount; - /// Count of Processor Hierarchy Nodes - UINT32 ProcHierarchyNodeCount; - /// Count of Cache Structures - UINT32 CacheStructCount; - /// List of indexed CM objects for PPTT generation - PPTT_NODE_INDEXER *NodeIndexer; - /// Pointer to the start of Processor Hierarchy nodes in - /// the Node Indexer array - PPTT_NODE_INDEXER *ProcHierarchyNodeIndexedList; - /// Pointer to the start of Cache Structures in the Node Indexer array - PPTT_NODE_INDEXER *CacheStructIndexedList; -} ACPI_PPTT_GENERATOR; - -#pragma pack() - -#endif // PPTT_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf deleted file mode 100644 index f2ab1b7111..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf +++ /dev/null @@ -1,36 +0,0 @@ -## @file -# Raw Table Generator -# -# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010019 - BASE_NAME = AcpiRawLibArm - FILE_GUID = 20F31568-D687-49BA-B326-CCD9D38EDE16 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiRawLibConstructor - DESTRUCTOR = AcpiRawLibDestructor - -[Sources] - RawGenerator.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - BaseLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c deleted file mode 100644 index a8323ad4ea..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c +++ /dev/null @@ -1,146 +0,0 @@ -/** @file - MCFG Table Generator - - Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include - -/** Construct the ACPI table using the ACPI table data provided. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildRawTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableData != NULL); - - if (AcpiTableInfo->AcpiTableData == NULL) { - *Table = NULL; - return EFI_INVALID_PARAMETER; - } - - *Table = AcpiTableInfo->AcpiTableData; - - return EFI_SUCCESS; -} - -/** This macro defines the Raw Generator revision. -*/ -#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the Raw Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR RawGenerator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdRaw), - // Generator Description - L"ACPI.STD.RAW.GENERATOR", - // ACPI Table Signature - Unused - 0, - // ACPI Table Revision - Unused - 0, - // Minimum ACPI Table Revision - Unused - 0, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - RAW_GENERATOR_REVISION, - // Build Table function - BuildRawTable, - // No additional resources are allocated by the generator. - // Hence the Free Resource function is not required. - NULL, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiRawLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&RawGenerator); - DEBUG ((DEBUG_INFO, "RAW: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiRawLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&RawGenerator); - DEBUG ((DEBUG_INFO, "RAW: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf deleted file mode 100644 index e11f878ec8..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf +++ /dev/null @@ -1,37 +0,0 @@ -## @file -# SPCR Table Generator -# -# Copyright (c) 2017 - 2020, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010019 - BASE_NAME = AcpiSpcrLibArm - FILE_GUID = 55088136-7B78-4974-B1EE-F630150D0DE7 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiSpcrLibConstructor - DESTRUCTOR = AcpiSpcrLibDestructor - -[Sources] - SpcrGenerator.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - BaseLib - SsdtSerialPortFixupLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c deleted file mode 100644 index 6f027f3bf9..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c +++ /dev/null @@ -1,482 +0,0 @@ -/** @file - SPCR Table Generator - - Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - Microsoft Serial Port Console Redirection Table - Specification - Version 1.03 - August 10, 2015. - -**/ - -#include -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include - -/** ARM standard SPCR Table Generator - - Constructs the SPCR table for PL011 or SBSA UART peripherals. - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjConsolePortInfo - -NOTE: This implementation ignores the possibility that the Serial settings may - be modified from the UEFI Shell. A more complex handler would be needed - to (e.g.) recover serial port settings from the UART, or non-volatile - storage. -*/ - -#pragma pack(1) - -/** A string representing the name of the SPCR port. -*/ -#define NAME_STR_SPCR_PORT "COM1" - -/** An UID representing the SPCR port. -*/ -#define UID_SPCR_PORT 1 - -/** This macro defines the no flow control option. -*/ -#define SPCR_FLOW_CONTROL_NONE 0 - -/**A template for generating the SPCR Table. - - Note: fields marked "{Template}" will be updated dynamically. -*/ -STATIC -EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE AcpiSpcr = { - ACPI_HEADER ( - EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION - ), - 0, // {Template}: Serial Port Subtype - { - EFI_ACPI_RESERVED_BYTE, - EFI_ACPI_RESERVED_BYTE, - EFI_ACPI_RESERVED_BYTE - }, - ARM_GAS32 (0), // {Template}: Serial Port Base Address - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC, - 0, // Not used on ARM - 0, // {Template}: Serial Port Interrupt - 0, // {Template}: Serial Port Baudrate - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY, - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, - SPCR_FLOW_CONTROL_NONE, - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI, - EFI_ACPI_RESERVED_BYTE, - 0xFFFF, - 0xFFFF, - 0x00, - 0x00, - 0x00, - 0x00000000, - 0x00, - EFI_ACPI_RESERVED_DWORD -}; - -#pragma pack() - -/** This macro expands to a function that retrieves the Serial - Port Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjConsolePortInfo, - CM_ARCH_COMMON_SERIAL_PORT_INFO - ) - -/** Free any resources allocated for constructing the tables. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to an array of pointers - to ACPI Table(s). - @param [in] TableCount Number of ACPI table(s). - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -FreeSpcrTableEx ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, - IN CONST UINTN TableCount - ) -{ - EFI_STATUS Status; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || - (*Table == NULL) || - (TableCount != 2)) - { - DEBUG ((DEBUG_ERROR, "ERROR: SPCR: Invalid Table Pointer\n")); - return EFI_INVALID_PARAMETER; - } - - TableList = *Table; - - if ((TableList[1] == NULL) || - (TableList[1]->Signature != - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) - { - DEBUG ((DEBUG_ERROR, "ERROR: SPCR: Invalid SSDT table pointer.\n")); - return EFI_INVALID_PARAMETER; - } - - // Only need to free the SSDT table at index 1. The SPCR table is static. - Status = FreeSsdtSerialPortTable (TableList[1]); - ASSERT_EFI_ERROR (Status); - - // Free the table list. - FreePool (*Table); - - return Status; -} - -/** Construct the SPCR ACPI table and its associated SSDT table. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResourcesEx function. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI table information. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [out] Table Pointer to a list of generated ACPI table(s). - @param [out] TableCount Number of generated ACPI table(s). - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for - the requested object. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Could not find information. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. - @retval EFI_UNSUPPORTED Unsupported configuration. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildSpcrTableEx ( - IN CONST ACPI_TABLE_GENERATOR *This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, - OUT UINTN *CONST TableCount - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; - UINT32 SerialPortCount; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (TableCount != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Requested table revision = %d, is not supported." - "Supported table revision: Minimum = %d, Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - return EFI_INVALID_PARAMETER; - } - - *Table = NULL; - - Status = GetEArchCommonObjConsolePortInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &SerialPortInfo, - &SerialPortCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Failed to get serial port information. Status = %r\n", - Status - )); - return Status; - } - - if (SerialPortCount == 0) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Serial port information not found. Status = %r\n", - EFI_NOT_FOUND - )); - return EFI_NOT_FOUND; - } - - // Validate the SerialPort info. Only one SPCR port can be described. - // If platform provides description for multiple SPCR ports, use the - // first SPCR port information. - Status = ValidateSerialPortInfo (SerialPortInfo, 1); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Invalid serial port information. Status = %r\n", - Status - )); - return Status; - } - - // Allocate a table to store pointers to the SPCR and SSDT tables. - TableList = (EFI_ACPI_DESCRIPTION_HEADER **) - AllocateZeroPool (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * 2); - if (TableList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Failed to allocate memory for Table List," \ - " Status = %r\n", - Status - )); - return Status; - } - - // Build SPCR table. - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpcr, - AcpiTableInfo, - sizeof (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE) - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Failed to add ACPI header. Status = %r\n", - Status - )); - goto error_handler; - } - - // The SPCR InterfaceType uses the same encoding as that of the - // DBG2 table Port Subtype field. However InterfaceType is 8-bit - // while the Port Subtype field in the DBG2 table is 16-bit. - if ((SerialPortInfo->PortSubtype & 0xFF00) != 0) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Invalid Port subtype (must be < 256). Status = %r\n", - Status - )); - goto error_handler; - } - - // Update the serial port subtype - AcpiSpcr.InterfaceType = (UINT8)SerialPortInfo->PortSubtype; - - // Update the base address - AcpiSpcr.BaseAddress.Address = SerialPortInfo->BaseAddress; - - // Set the access size - if (SerialPortInfo->AccessSize >= EFI_ACPI_6_3_QWORD) { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Access size must be <= 3 (DWORD). Status = %r\n", - Status - )); - goto error_handler; - } else if (SerialPortInfo->AccessSize == EFI_ACPI_6_3_UNDEFINED) { - // 0 Undefined (legacy reasons) - // Default to DWORD access size as the access - // size field was introduced at a later date - // and some ConfigurationManager implementations - // may not be providing this field data - AcpiSpcr.BaseAddress.AccessSize = EFI_ACPI_6_3_DWORD; - } else { - AcpiSpcr.BaseAddress.AccessSize = SerialPortInfo->AccessSize; - } - - // Update the UART interrupt - AcpiSpcr.GlobalSystemInterrupt = SerialPortInfo->Interrupt; - - switch (SerialPortInfo->BaudRate) { - case 9600: - AcpiSpcr.BaudRate = - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600; - break; - case 19200: - AcpiSpcr.BaudRate = - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200; - break; - case 57600: - AcpiSpcr.BaudRate = - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600; - break; - case 115200: - AcpiSpcr.BaudRate = - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200; - break; - default: - Status = EFI_UNSUPPORTED; - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Invalid Baud Rate %ld, Status = %r\n", - SerialPortInfo->BaudRate, - Status - )); - goto error_handler; - } // switch - - TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpcr; - - // Build a SSDT table describing the serial port. - Status = BuildSsdtSerialPortTable ( - AcpiTableInfo, - SerialPortInfo, - NAME_STR_SPCR_PORT, - UID_SPCR_PORT, - &TableList[1] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SPCR: Failed to build associated SSDT table. Status = %r\n", - Status - )); - goto error_handler; - } - - *TableCount = 2; - *Table = TableList; - - return Status; - -error_handler: - if (TableList != NULL) { - FreePool (TableList); - } - - return Status; -} - -/** This macro defines the SPCR Table Generator revision. -*/ -#define SPCR_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the SPCR Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR SpcrGenerator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr), - // Generator Description - L"ACPI.STD.SPCR.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, - // Minimum supported ACPI Table Revision - EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - SPCR_GENERATOR_REVISION, - // Build table function. Use the extended version instead. - NULL, - // Free table function. Use the extended version instead. - NULL, - // Extended Build table function. - BuildSpcrTableEx, - // Extended free function. - FreeSpcrTableEx -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiSpcrLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&SpcrGenerator); - DEBUG ((DEBUG_INFO, "SPCR: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiSpcrLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&SpcrGenerator); - DEBUG ((DEBUG_INFO, "SPCR: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf deleted file mode 100644 index 5891dc4d1c..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf +++ /dev/null @@ -1,29 +0,0 @@ -## @file -# SRAT Table Generator -# -# Copyright (c) 2019, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x0001001B - BASE_NAME = AcpiSratLibArm - FILE_GUID = 2CE21E0A-A39C-4B26-BC0E-526178036ACD - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiSratLibConstructor - DESTRUCTOR = AcpiSratLibDestructor - -[Sources] - SratGenerator.c - -[Packages] - EmbeddedPkg/EmbeddedPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c deleted file mode 100644 index 48c9970a71..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c +++ /dev/null @@ -1,842 +0,0 @@ -/** @file - SRAT Table Generator - - Copyright (c) 2019 - 2020, Arm Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.3 Specification, January 2019 - - @par Glossary: - - Cm or CM - Configuration Manager - - Obj or OBJ - Object -**/ - -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include - -/** - ARM standard SRAT Generator - - Requirements: - The following Configuration Manager Object(s) are used by this Generator: - - EArmObjGicCInfo (REQUIRED) - - EArmObjGicItsInfo (OPTIONAL) - - EArchCommonObjMemoryAffinityInfo (OPTIONAL) - - EArchCommonObjGenericInitiatorAffinityInfo (OPTIONAL) - - EArchCommonObjDeviceHandleAcpi (OPTIONAL) - - EArchCommonObjDeviceHandlePci (OPTIONAL) -*/ - -/** This macro expands to a function that retrieves the GIC - CPU interface Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicCInfo, - CM_ARM_GICC_INFO - ); - -/** This macro expands to a function that retrieves the GIC - Interrupt Translation Service Information from the - Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicItsInfo, - CM_ARM_GIC_ITS_INFO - ); - -/** - This macro expands to a function that retrieves the Memory Affinity - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjMemoryAffinityInfo, - CM_ARCH_COMMON_MEMORY_AFFINITY_INFO - ); - -/** - This macro expands to a function that retrieves the Generic Initiator Affinity - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjGenericInitiatorAffinityInfo, - CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO - ); - -/** - This macro expands to a function that retrieves the ACPI Device Handle - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjDeviceHandleAcpi, - CM_ARCH_COMMON_DEVICE_HANDLE_ACPI - ); - -/** - This macro expands to a function that retrieves the PCI Device Handle - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjDeviceHandlePci, - CM_ARCH_COMMON_DEVICE_HANDLE_PCI - ); - -/** Return the PCI Device information in BDF format - - PCI Bus Number - Max 256 busses (Bits 15:8 of BDF) - PCI Device Number - Max 32 devices (Bits 7:3 of BDF) - PCI Function Number - Max 8 functions (Bits 2:0 of BDF) - - @param [in] DeviceHandlePci Pointer to the PCI Device Handle. - - @retval BDF value corresponding to the PCI Device Handle. -**/ -STATIC -UINT16 -GetBdf ( - IN CONST CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci - ) -{ - UINT16 Bdf; - - Bdf = (UINT16)DeviceHandlePci->BusNumber << 8; - Bdf |= (DeviceHandlePci->DeviceNumber & 0x1F) << 3; - Bdf |= DeviceHandlePci->FunctionNumber & 0x7; - return Bdf; -} - -/** Add the GICC Affinity Structures in the SRAT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Srat Pointer to the SRAT Table. - @param [in] GicCAffOffset Offset of the GICC Affinity - information in the SRAT Table. - @param [in] GicCInfo Pointer to the GIC CPU Information list. - @param [in] GicCCount Count of GIC CPU Interfaces. - - @retval EFI_SUCCESS Table generated successfully. -**/ -STATIC -EFI_STATUS -AddGICCAffinity ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, - IN CONST UINT32 GicCAffOffset, - IN CONST CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 GicCCount - ) -{ - EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *GicCAff; - - ASSERT (Srat != NULL); - ASSERT (GicCInfo != NULL); - - GicCAff = (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)((UINT8 *)Srat + - GicCAffOffset); - - while (GicCCount-- != 0) { - DEBUG ((DEBUG_INFO, "SRAT: GicCAff = 0x%p\n", GicCAff)); - - GicCAff->Type = EFI_ACPI_6_3_GICC_AFFINITY; - GicCAff->Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE); - GicCAff->ProximityDomain = GicCInfo->ProximityDomain; - GicCAff->AcpiProcessorUid = GicCInfo->AcpiProcessorUid; - GicCAff->Flags = GicCInfo->AffinityFlags; - GicCAff->ClockDomain = GicCInfo->ClockDomain; - - // Next - GicCAff++; - GicCInfo++; - }// while - - return EFI_SUCCESS; -} - -/** Add the GIC ITS Affinity Structures in the SRAT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Srat Pointer to the SRAT Table. - @param [in] GicItsAffOffset Offset of the GIC ITS Affinity - information in the SRAT Table. - @param [in] GicItsInfo Pointer to the GIC ITS Information list. - @param [in] GicItsCount Count of GIC ITS. - - @retval EFI_SUCCESS Table generated successfully. -**/ -STATIC -EFI_STATUS -AddGICItsAffinity ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, - IN CONST UINT32 GicItsAffOffset, - IN CONST CM_ARM_GIC_ITS_INFO *GicItsInfo, - IN UINT32 GicItsCount - ) -{ - EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff; - - ASSERT (Srat != NULL); - ASSERT (GicItsInfo != NULL); - - GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat + - GicItsAffOffset); - - while (GicItsCount-- != 0) { - DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff)); - - GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY; - GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE); - GicItsAff->ProximityDomain = GicItsInfo->ProximityDomain; - GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE; - GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE; - GicItsAff->ItsId = GicItsInfo->GicItsId; - - // Next - GicItsAff++; - GicItsInfo++; - }// while - - return EFI_SUCCESS; -} - -/** Add the Memory Affinity Structures in the SRAT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Srat Pointer to the SRAT Table. - @param [in] MemAffOffset Offset of the Memory Affinity - information in the SRAT Table. - @param [in] MemAffInfo Pointer to the Memory Affinity Information list. - @param [in] MemAffCount Count of Memory Affinity objects. - - @retval EFI_SUCCESS Table generated successfully. -**/ -STATIC -EFI_STATUS -AddMemoryAffinity ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, - IN CONST UINT32 MemAffOffset, - IN CONST CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo, - IN UINT32 MemAffCount - ) -{ - EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *MemAff; - - ASSERT (Srat != NULL); - ASSERT (MemAffInfo != NULL); - - MemAff = (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *)((UINT8 *)Srat + - MemAffOffset); - - while (MemAffCount-- != 0) { - DEBUG ((DEBUG_INFO, "SRAT: MemAff = 0x%p\n", MemAff)); - - MemAff->Type = EFI_ACPI_6_3_MEMORY_AFFINITY; - MemAff->Length = sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE); - MemAff->ProximityDomain = MemAffInfo->ProximityDomain; - MemAff->Reserved1 = EFI_ACPI_RESERVED_WORD; - MemAff->AddressBaseLow = (UINT32)(MemAffInfo->BaseAddress & MAX_UINT32); - MemAff->AddressBaseHigh = (UINT32)(MemAffInfo->BaseAddress >> 32); - MemAff->LengthLow = (UINT32)(MemAffInfo->Length & MAX_UINT32); - MemAff->LengthHigh = (UINT32)(MemAffInfo->Length >> 32); - MemAff->Reserved2 = EFI_ACPI_RESERVED_DWORD; - MemAff->Flags = MemAffInfo->Flags; - MemAff->Reserved3 = EFI_ACPI_RESERVED_QWORD; - - // Next - MemAff++; - MemAffInfo++; - }// while - - return EFI_SUCCESS; -} - -/** Add the Generic Initiator Affinity Structures in the SRAT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Srat Pointer to the SRAT Table. - @param [in] GenInitAffOff Offset of the Generic Initiator Affinity - information in the SRAT Table. - @param [in] GenInitAffInfo Pointer to the Generic Initiator Affinity - Information list. - @param [in] GenInitAffCount Count of Generic Initiator Affinity - objects. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object information is not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -AddGenericInitiatorAffinity ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, - IN CONST UINT32 GenInitAffOff, - IN CONST CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo, - IN UINT32 GenInitAffCount - ) -{ - EFI_STATUS Status; - EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *GenInitAff; - CM_ARCH_COMMON_DEVICE_HANDLE_ACPI *DeviceHandleAcpi; - CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci; - UINT32 DeviceHandleCount; - - ASSERT (Srat != NULL); - ASSERT (GenInitAffInfo != NULL); - - GenInitAff = (EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *)( - (UINT8 *)Srat + GenInitAffOff); - - while (GenInitAffCount-- != 0) { - DEBUG ((DEBUG_INFO, "SRAT: GenInitAff = 0x%p\n", GenInitAff)); - - GenInitAff->Type = EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY; - GenInitAff->Length = - sizeof (EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE); - GenInitAff->Reserved1 = EFI_ACPI_RESERVED_WORD; - GenInitAff->DeviceHandleType = GenInitAffInfo->DeviceHandleType; - GenInitAff->ProximityDomain = GenInitAffInfo->ProximityDomain; - - if (GenInitAffInfo->DeviceHandleToken == CM_NULL_TOKEN) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Invalid Device Handle Token.\n" - )); - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - if (GenInitAffInfo->DeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) { - Status = GetEArchCommonObjDeviceHandleAcpi ( - CfgMgrProtocol, - GenInitAffInfo->DeviceHandleToken, - &DeviceHandleAcpi, - &DeviceHandleCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get ACPI Device Handle Inf." - " DeviceHandleToken = %p." - " Status = %r\n", - GenInitAffInfo->DeviceHandleToken, - Status - )); - return Status; - } - - // We are expecting only one device handle. - ASSERT (DeviceHandleCount == 1); - - // Populate the ACPI device handle information. - GenInitAff->DeviceHandle.Acpi.AcpiHid = DeviceHandleAcpi->Hid; - GenInitAff->DeviceHandle.Acpi.AcpiUid = DeviceHandleAcpi->Uid; - GenInitAff->DeviceHandle.Acpi.Reserved[0] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Acpi.Reserved[1] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Acpi.Reserved[2] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Acpi.Reserved[3] = EFI_ACPI_RESERVED_BYTE; - } else if (GenInitAffInfo->DeviceHandleType == - EFI_ACPI_6_3_PCI_DEVICE_HANDLE) - { - Status = GetEArchCommonObjDeviceHandlePci ( - CfgMgrProtocol, - GenInitAffInfo->DeviceHandleToken, - &DeviceHandlePci, - &DeviceHandleCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get ACPI Device Handle Inf." - " DeviceHandleToken = %p." - " Status = %r\n", - GenInitAffInfo->DeviceHandleToken, - Status - )); - return Status; - } - - // We are expecting only one device handle - ASSERT (DeviceHandleCount == 1); - - // Populate the ACPI device handle information. - GenInitAff->DeviceHandle.Pci.PciSegment = DeviceHandlePci->SegmentNumber; - GenInitAff->DeviceHandle.Pci.PciBdfNumber = GetBdf (DeviceHandlePci); - - GenInitAff->DeviceHandle.Pci.Reserved[0] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[1] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[2] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[3] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[4] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[5] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[6] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[7] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[8] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[9] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[10] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->DeviceHandle.Pci.Reserved[11] = EFI_ACPI_RESERVED_BYTE; - } else { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Invalid Device Handle Type.\n" - )); - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - GenInitAff->Flags = GenInitAffInfo->Flags; - GenInitAff->Reserved2[0] = EFI_ACPI_RESERVED_BYTE; - GenInitAff->Reserved2[1] = EFI_ACPI_RESERVED_BYTE; - - // Next - GenInitAff++; - GenInitAffInfo++; - }// while - - return EFI_SUCCESS; -} - -/** Construct the SRAT ACPI table. - - Called by the Dynamic Table Manager, this function invokes the - Configuration Manager protocol interface to get the required hardware - information for generating the ACPI table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildSratTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - EFI_STATUS Status; - UINT32 TableSize; - UINT32 GicCCount; - UINT32 GicItsCount; - UINT32 MemAffCount; - UINT32 GenInitiatorAffCount; - - UINT32 GicCAffOffset; - UINT32 GicItsAffOffset; - UINT32 MemAffOffset; - UINT32 GenInitiatorAffOffset; - - CM_ARM_GICC_INFO *GicCInfo; - CM_ARM_GIC_ITS_INFO *GicItsInfo; - CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo; - CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo; - - EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *Srat; - - ASSERT ( - (This != NULL) && - (AcpiTableInfo != NULL) && - (CfgMgrProtocol != NULL) && - (Table != NULL) && - (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && - (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) - ); - - if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || - (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) - { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Requested table revision = %d is not supported. " - "Supported table revisions: Minimum = %d. Maximum = %d\n", - AcpiTableInfo->AcpiTableRevision, - This->MinAcpiTableRevision, - This->AcpiTableRevision - )); - return EFI_INVALID_PARAMETER; - } - - *Table = NULL; - - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicCInfo, - &GicCCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get GICC Info. Status = %r\n", - Status - )); - goto error_handler; - } - - if (GicCCount == 0) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: GIC CPU Interface information not provided.\n" - )); - ASSERT (0); - Status = EFI_INVALID_PARAMETER; - goto error_handler; - } - - Status = GetEArmObjGicItsInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicItsInfo, - &GicItsCount - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get GIC ITS Info. Status = %r\n", - Status - )); - goto error_handler; - } - - Status = GetEArchCommonObjMemoryAffinityInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &MemAffInfo, - &MemAffCount - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get Memory Affinity Info. Status = %r\n", - Status - )); - goto error_handler; - } - - Status = GetEArchCommonObjGenericInitiatorAffinityInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GenInitiatorAffInfo, - &GenInitiatorAffCount - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get Generic Initiator Affinity Info." - " Status = %r\n", - Status - )); - goto error_handler; - } - - // Calculate the size of the SRAT table - TableSize = sizeof (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER); - - GicCAffOffset = TableSize; - TableSize += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) * GicCCount); - - if (GicItsCount != 0) { - GicItsAffOffset = TableSize; - TableSize += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) * - GicItsCount); - } - - if (MemAffCount != 0) { - MemAffOffset = TableSize; - TableSize += (sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE) * - MemAffCount); - } - - if (GenInitiatorAffCount != 0) { - GenInitiatorAffOffset = TableSize; - TableSize += (sizeof (EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE) * - GenInitiatorAffCount); - } - - // Allocate the Buffer for SRAT table - *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); - if (*Table == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to allocate memory for SRAT Table, Size = %d," \ - " Status = %r\n", - TableSize, - Status - )); - goto error_handler; - } - - Srat = (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *)*Table; - - DEBUG (( - DEBUG_INFO, - "SRAT: Srat = 0x%p TableSize = 0x%x\n", - Srat, - TableSize - )); - - Status = AddAcpiHeader ( - CfgMgrProtocol, - This, - &Srat->Header, - AcpiTableInfo, - TableSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to add ACPI header. Status = %r\n", - Status - )); - goto error_handler; - } - - // Setup the Reserved fields - // Reserved1 must be set to 1 for backward compatibility - Srat->Reserved1 = 1; - Srat->Reserved2 = EFI_ACPI_RESERVED_QWORD; - - Status = AddGICCAffinity ( - CfgMgrProtocol, - Srat, - GicCAffOffset, - GicCInfo, - GicCCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to add GICC Affinity structures. Status = %r\n", - Status - )); - goto error_handler; - } - - if (GicItsCount != 0) { - Status = AddGICItsAffinity ( - CfgMgrProtocol, - Srat, - GicItsAffOffset, - GicItsInfo, - GicItsCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to add GIC ITS Affinity structures. Status = %r\n", - Status - )); - goto error_handler; - } - } - - if (MemAffCount != 0) { - Status = AddMemoryAffinity ( - CfgMgrProtocol, - Srat, - MemAffOffset, - MemAffInfo, - MemAffCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to add Memory Affinity structures. Status = %r\n", - Status - )); - goto error_handler; - } - } - - if (GenInitiatorAffCount != 0) { - Status = AddGenericInitiatorAffinity ( - CfgMgrProtocol, - Srat, - GenInitiatorAffOffset, - GenInitiatorAffInfo, - GenInitiatorAffCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to add Generic Initiator Affinity structures." - " Status = %r\n", - Status - )); - goto error_handler; - } - } - - return Status; - -error_handler: - - if (*Table != NULL) { - FreePool (*Table); - *Table = NULL; - } - - return Status; -} - -/** Free any resources allocated for constructing the SRAT. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to the ACPI Table. - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -FreeSratTableResources ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - ASSERT ( - (This != NULL) && - (AcpiTableInfo != NULL) && - (CfgMgrProtocol != NULL) && - (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && - (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) - ); - - if ((Table == NULL) || (*Table == NULL)) { - DEBUG ((DEBUG_ERROR, "ERROR: SRAT: Invalid Table Pointer\n")); - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - FreePool (*Table); - *Table = NULL; - return EFI_SUCCESS; -} - -/** The SRAT Table Generator revision. -*/ -#define SRAT_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the SRAT Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR SratGenerator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSrat), - // Generator Description - L"ACPI.STD.SRAT.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, - // ACPI Table Revision supported by this Generator - EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION, - // Minimum supported ACPI Table Revision - EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - SRAT_GENERATOR_REVISION, - // Build Table function - BuildSratTable, - // Free Resource function - FreeSratTableResources, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiSratLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&SratGenerator); - DEBUG ((DEBUG_INFO, "SRAT: Register Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiSratLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&SratGenerator); - DEBUG ((DEBUG_INFO, "SRAT: Deregister Generator. Status = %r\n", Status)); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c deleted file mode 100644 index 2deaa4640c..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c +++ /dev/null @@ -1,1705 +0,0 @@ -/** @file - SSDT Cpu Topology Table Generator. - - Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors - - ACPI for CoreSight version 1.2 Platform Design Document - (https://developer.arm.com/documentation/den0067/a/?lang=en) - - @par Glossary: - - ETE - Embedded Trace Extension. - - ETM - Embedded Trace Macrocell. -**/ - -#include -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include -#include - -#include "SsdtCpuTopologyGenerator.h" - -/** ARM standard SSDT Cpu Topology Table Generator. - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArmObjGicCInfo - - EArchCommonObjProcHierarchyInfo (OPTIONAL) along with - - EArchCommonObjCmRef (OPTIONAL) - - EArchCommonObjLpiInfo (OPTIONAL) - - GetEArmObjEtInfo (OPTIONAL) - - EArchCommonObjPsdInfo (OPTIONAL) -*/ - -/** This macro expands to a function that retrieves the GIC - CPU interface Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicCInfo, - CM_ARM_GICC_INFO - ); - -/** - This macro expands to a function that retrieves the Processor Hierarchy - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjProcHierarchyInfo, - CM_ARCH_COMMON_PROC_HIERARCHY_INFO - ); - -/** - This macro expands to a function that retrieves the cross-CM-object- - reference information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjCmRef, - CM_ARCH_COMMON_OBJ_REF - ); - -/** - This macro expands to a function that retrieves the Lpi - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjLpiInfo, - CM_ARCH_COMMON_LPI_INFO - ); - -/** - This macro expands to a function that retrieves the CPC - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjCpcInfo, - CM_ARCH_COMMON_CPC_INFO - ); - -/** - This macro expands to a function that retrieves the ET device - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjEtInfo, - CM_ARM_ET_INFO - ); - -/** - This macro expands to a function that retrieves the PSD - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPsdInfo, - CM_ARCH_COMMON_PSD_INFO - ); - -/** Initialize the TokenTable. - - One entry should be allocated for each CM_ARCH_COMMON_PROC_HIERARCHY_INFO - structure of the platform. The TokenTable allows to have a mapping: - Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). - - There will always be less sets of Lpi states (CM_ARCH_COMMON_OBJ_REF) - than the number of cpus/clusters (CM_ARCH_COMMON_PROC_HIERARCHY_INFO). - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] Count Number of entries to allocate in the TokenTable. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -TokenTableInitialize ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN UINT32 Count - ) -{ - CM_OBJECT_TOKEN *Table; - - if ((Generator == NULL) || - (Count == 0) || - (Count >= MAX_NODE_COUNT)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Table = AllocateZeroPool (sizeof (CM_OBJECT_TOKEN) * Count); - if (Table == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - - Generator->TokenTable.Table = Table; - - return EFI_SUCCESS; -} - -/** Free the TokenTable. - - @param [in] Generator The SSDT Cpu Topology generator. -**/ -STATIC -VOID -EFIAPI -TokenTableFree ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator - ) -{ - ASSERT (Generator != NULL); - ASSERT (Generator->TokenTable.Table != NULL); - - if (Generator->TokenTable.Table != NULL) { - FreePool (Generator->TokenTable.Table); - } -} - -/** Add a new entry to the TokenTable and return its index. - - If an entry with Token is already available in the table, - return its index without adding a new entry. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] Token New Token entry to add. - - @retval The index of the token entry in the TokenTable. -**/ -STATIC -UINT32 -EFIAPI -TokenTableAdd ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CM_OBJECT_TOKEN Token - ) -{ - CM_OBJECT_TOKEN *Table; - UINT32 Index; - UINT32 LastIndex; - - ASSERT (Generator != NULL); - ASSERT (Generator->TokenTable.Table != NULL); - - Table = Generator->TokenTable.Table; - LastIndex = Generator->TokenTable.LastIndex; - - // Search if there is already an entry with this Token. - for (Index = 0; Index < LastIndex; Index++) { - if (Table[Index] == Token) { - return Index; - } - } - - ASSERT (LastIndex < MAX_NODE_COUNT); - ASSERT (LastIndex < Generator->ProcNodeCount); - - // If no, create a new entry. - Table[LastIndex] = Token; - - return Generator->TokenTable.LastIndex++; -} - -/** Write a string 'Xxxx\0' in AslName (5 bytes long), - with 'X' being the leading char of the name, and - with 'xxx' being Value in hexadecimal. - - As 'xxx' in hexadecimal represents a number on 12 bits, - we have Value < (1 << 12). - - @param [in] LeadChar Leading char of the name. - @param [in] Value Hex value of the name. - Must be lower than (2 << 12). - @param [in, out] AslName Pointer to write the 'Xxxx' string to. - Must be at least 5 bytes long. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -WriteAslName ( - IN CHAR8 LeadChar, - IN UINT32 Value, - IN OUT CHAR8 *AslName - ) -{ - UINT8 Index; - - if ((Value >= MAX_NODE_COUNT) || - (AslName == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - AslName[0] = LeadChar; - AslName[AML_NAME_SEG_SIZE] = '\0'; - - for (Index = 0; Index < AML_NAME_SEG_SIZE - 1; Index++) { - AslName[AML_NAME_SEG_SIZE - Index - 1] = - AsciiFromHex (((Value >> (4 * Index)) & 0xF)); - } - - return EFI_SUCCESS; -} - -/** Create and add an _PSD Node to Cpu Node. - - For instance, transform an AML node from: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - } - - To: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - Name (_PSD, Package() - { - NumEntries, // Integer - Revision, // Integer - Domain, // Integer - CoordType, // Integer - NumProcessors, // Integer - }) - } - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object - describing the Cpu. - @param [in] Node CPU Node to which the _CPC node is - attached. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlPsdNode ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_ARM_GICC_INFO *GicCInfo, - IN AML_OBJECT_NODE_HANDLE *Node - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_PSD_INFO *PsdInfo; - - Status = GetEArchCommonObjPsdInfo ( - CfgMgrProtocol, - GicCInfo->PsdToken, - &PsdInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - Status = AmlCreatePsdNode ( - PsdInfo, - Node, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Create and add an _CPC Node to Cpu Node. - - For instance, transform an AML node from: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - } - - To: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - Name(_CPC, Package() - { - NumEntries, // Integer - Revision, // Integer - HighestPerformance, // Integer or Buffer (Resource Descriptor) - NominalPerformance, // Integer or Buffer (Resource Descriptor) - LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor) - LowestPerformance, // Integer or Buffer (Resource Descriptor) - GuaranteedPerformanceRegister, // Buffer (Resource Descriptor) - DesiredPerformanceRegister , // Buffer (Resource Descriptor) - MinimumPerformanceRegister , // Buffer (Resource Descriptor) - MaximumPerformanceRegister , // Buffer (Resource Descriptor) - PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor) - TimeWindowRegister, // Buffer (Resource Descriptor) - CounterWraparoundTime, // Integer or Buffer (Resource Descriptor) - ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor) - DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor) - PerformanceLimitedRegister, // Buffer (Resource Descriptor) - CPPCEnableRegister // Buffer (Resource Descriptor) - AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor) - AutonomousActivityWindowRegister, // Buffer (Resource Descriptor) - EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor) - ReferencePerformance // Integer or Buffer (Resource Descriptor) - LowestFrequency, // Integer or Buffer (Resource Descriptor) - NominalFrequency // Integer or Buffer (Resource Descriptor) - }) - } - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object - describing the Cpu. - @param [in] Node CPU Node to which the _CPC node is - attached. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlCpcNode ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_ARM_GICC_INFO *GicCInfo, - IN AML_OBJECT_NODE_HANDLE *Node - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_CPC_INFO *CpcInfo; - - Status = GetEArchCommonObjCpcInfo ( - CfgMgrProtocol, - GicCInfo->CpcToken, - &CpcInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCreateCpcNode ( - CpcInfo, - Node, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Create an embedded trace device and add it to the Cpu Node in the - AML namespace. - - This generates the following ASL code: - Device (E002) - { - Name (_UID, 2) - Name (_HID, "ARMHC500") - } - - Note: Currently we only support generating ETE nodes. Unlike ETM, - ETE has a system register interface and therefore does not need - the MMIO range to be described. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] ParentNode Parent node to attach the Cpu node to. - @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node. - @param [in] CpuName Value used to generate the node name. - @param [out] EtNodePtr If not NULL, return the created Cpu node. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlEtd ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN AML_NODE_HANDLE ParentNode, - IN CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 CpuName, - OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL - ) -{ - EFI_STATUS Status; - AML_OBJECT_NODE_HANDLE EtNode; - CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; - - ASSERT (Generator != NULL); - ASSERT (ParentNode != NULL); - - Status = WriteAslName ('E', CpuName, AslName); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameInteger ( - "_UID", - GicCInfo->AcpiProcessorUid, - EtNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameString ( - "_HID", - ACPI_HID_ET_DEVICE, - EtNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // If requested, return the handle to the EtNode. - if (EtNodePtr != NULL) { - *EtNodePtr = EtNode; - } - - return Status; -} - -/** Create and add an Embedded trace device to the Cpu Node. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object - describing the Cpu. - @param [in] CpuName Value used to generate the CPU node name. - @param [in] Node CPU Node to which the ET device node is - attached. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_UNSUPPORTED Feature Unsupported. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlEtNode ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 CpuName, - IN AML_OBJECT_NODE_HANDLE *Node - ) -{ - EFI_STATUS Status; - CM_ARM_ET_INFO *EtInfo; - - Status = GetEArmObjEtInfo ( - CfgMgrProtocol, - GicCInfo->EtToken, - &EtInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Currently we only support creation of a ETE Node. - if (EtInfo->EtType != ArmEtTypeEte) { - return EFI_UNSUPPORTED; - } - - Status = CreateAmlEtd ( - Generator, - Node, - GicCInfo, - CpuName, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Create and add an _LPI method to Cpu/Cluster Node. - - For instance, transform an AML node from: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - } - - To: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - Method (_LPI, 0, NotSerialized) - { - Return (\_SB.L003) - } - } - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO - describing the Cpu. - @param [in] Node Node to which the _LPI method is - attached. Can represent a Cpu or a - Cluster. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlLpiMethod ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, - IN AML_OBJECT_NODE_HANDLE *Node - ) -{ - EFI_STATUS Status; - UINT32 TokenIndex; - CHAR8 AslName[SB_SCOPE_PREFIX_SIZE + AML_NAME_SEG_SIZE]; - - ASSERT (Generator != NULL); - ASSERT (ProcHierarchyNodeInfo != NULL); - ASSERT (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN); - ASSERT (Node != NULL); - - TokenIndex = TokenTableAdd (Generator, ProcHierarchyNodeInfo->LpiToken); - - CopyMem (AslName, SB_SCOPE_PREFIX, SB_SCOPE_PREFIX_SIZE); - - Status = WriteAslName ( - 'L', - TokenIndex, - AslName + SB_SCOPE_PREFIX_SIZE - 1 - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: - // Method (_LPI, 0) { - // Return ([AslName]) - // } - Status = AmlCodeGenMethodRetNameString ( - "_LPI", - AslName, - 0, - FALSE, - 0, - Node, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - } - - return Status; -} - -/** Generate all the Lpi states under the '_SB' scope. - - This function generates the following ASL code: - Scope (\_SB) { - Name (L000, Package() { - 0, // Version - 0, // Level Index - X, // Count - Package() { - [An Lpi state] - }, - Package() { - [Another Lpi state] - }, - } // Name L000 - - Name (L001, Package() { - ... - } // Name L001 - - ... - } // Scope /_SB - - The Lpi states are fetched from the Configuration Manager. - The names of the Lpi states are generated from the TokenTable. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] ScopeNode Scope node handle ('\_SB' scope). - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -GenerateLpiStates ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN AML_OBJECT_NODE_HANDLE ScopeNode - ) -{ - EFI_STATUS Status; - - UINT32 Index; - UINT32 LastIndex; - - AML_OBJECT_NODE_HANDLE LpiNode; - CM_ARCH_COMMON_OBJ_REF *LpiRefInfo; - UINT32 LpiRefInfoCount; - UINT32 LpiRefIndex; - CM_ARCH_COMMON_LPI_INFO *LpiInfo; - CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; - - ASSERT (Generator != NULL); - ASSERT (Generator->TokenTable.Table != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ScopeNode != NULL); - - LastIndex = Generator->TokenTable.LastIndex; - - // For each entry in the TokenTable, create a name in the AML namespace - // under SB_SCOPE, to store the Lpi states associated with the LpiToken. - for (Index = 0; Index < LastIndex; Index++) { - Status = WriteAslName ('L', Index, AslName); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // We do not support the LevelId field for now, let it to 0. - Status = AmlCreateLpiNode (AslName, 0, 0, ScopeNode, &LpiNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Fetch the LPI objects referenced by the token. - Status = GetEArchCommonObjCmRef ( - CfgMgrProtocol, - Generator->TokenTable.Table[Index], - &LpiRefInfo, - &LpiRefInfoCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - for (LpiRefIndex = 0; LpiRefIndex < LpiRefInfoCount; LpiRefIndex++) { - // For each CM_ARCH_COMMON_LPI_INFO referenced by the token, - // add an Lpi state. - Status = GetEArchCommonObjLpiInfo ( - CfgMgrProtocol, - LpiRefInfo[LpiRefIndex].ReferenceToken, - &LpiInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlAddLpiState ( - LpiInfo->MinResidency, - LpiInfo->WorstCaseWakeLatency, - LpiInfo->Flags, - LpiInfo->ArchFlags, - LpiInfo->ResCntFreq, - LpiInfo->EnableParentState, - LpiInfo->IsInteger ? - NULL : - &LpiInfo->RegisterEntryMethod, - LpiInfo->IsInteger ? - LpiInfo->IntegerEntryMethod : - 0, - &LpiInfo->ResidencyCounterRegister, - &LpiInfo->UsageCounterRegister, - LpiInfo->StateName, - LpiNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } // for LpiRefIndex - } // for Index - - return EFI_SUCCESS; -} - -/** Create a Cpu in the AML namespace. - - This generates the following ASL code: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0007") - } - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] ParentNode Parent node to attach the Cpu node to. - @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node. - @param [in] CpuName Value used to generate the node name. - @param [out] CpuNodePtr If not NULL, return the created Cpu node. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlCpu ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN AML_NODE_HANDLE ParentNode, - IN CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 CpuName, - OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL - ) -{ - EFI_STATUS Status; - AML_OBJECT_NODE_HANDLE CpuNode; - CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; - - ASSERT (Generator != NULL); - ASSERT (ParentNode != NULL); - ASSERT (GicCInfo != NULL); - - Status = WriteAslName ('C', CpuName, AslName); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenDevice (AslName, ParentNode, &CpuNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameInteger ( - "_UID", - GicCInfo->AcpiProcessorUid, - CpuNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameString ( - "_HID", - ACPI_HID_PROCESSOR_DEVICE, - CpuNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // If requested, return the handle to the CpuNode. - if (CpuNodePtr != NULL) { - *CpuNodePtr = CpuNode; - } - - return Status; -} - -/** Create a Cpu in the AML namespace from a CM_ARCH_COMMON_PROC_HIERARCHY_INFO - CM object. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] ParentNode Parent node to attach the Cpu node to. - @param [in] CpuName Value used to generate the node name. - @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO - describing the Cpu. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlCpuFromProcHierarchy ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN AML_NODE_HANDLE ParentNode, - IN UINT32 CpuName, - IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo - ) -{ - EFI_STATUS Status; - CM_ARM_GICC_INFO *GicCInfo; - AML_OBJECT_NODE_HANDLE CpuNode; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ParentNode != NULL); - ASSERT (ProcHierarchyNodeInfo != NULL); - ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN); - - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - ProcHierarchyNodeInfo->AcpiIdObjectToken, - &GicCInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = CreateAmlCpu (Generator, ParentNode, GicCInfo, CpuName, &CpuNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // If a set of Lpi states is associated with the - // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them. - if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) { - Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - - if (GicCInfo->PsdToken != CM_NULL_TOKEN) { - Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - - // If a CPC info is associated with the - // GicCinfo, create an _CPC method returning them. - if (GicCInfo->CpcToken != CM_NULL_TOKEN) { - Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - - // Add an Embedded Trace node if present. - if (GicCInfo->EtToken != CM_NULL_TOKEN) { - Status = CreateAmlEtNode ( - Generator, - CfgMgrProtocol, - GicCInfo, - CpuName, - CpuNode - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - - return Status; -} - -/** Create a Processor Container in the AML namespace. - - Any CM_ARCH_COMMON_PROC_HIERARCHY_INFO object with the following flags is - assumed to be a processor container: - - EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL - - EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID - - EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF - - This generates the following ASL code: - Device (C002) - { - Name (_UID, 2) - Name (_HID, "ACPI0010") - } - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] ParentNode Parent node to attach the processor - container node to. - @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO object - used to create the node. - @param [in] ProcContainerName Name of the processor container. - @param [in] ProcContainerUid Uid of the processor container. - @param [out] ProcContainerNodePtr If success, contains the created processor - container node. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlProcessorContainer ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN AML_NODE_HANDLE ParentNode, - IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, - IN UINT16 ProcContainerName, - IN UINT32 ProcContainerUid, - OUT AML_OBJECT_NODE_HANDLE *ProcContainerNodePtr - ) -{ - EFI_STATUS Status; - AML_OBJECT_NODE_HANDLE ProcContainerNode; - CHAR8 AslNameProcContainer[AML_NAME_SEG_SIZE + 1]; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ParentNode != NULL); - ASSERT (ProcHierarchyNodeInfo != NULL); - ASSERT (ProcContainerNodePtr != NULL); - - Status = WriteAslName ('C', ProcContainerName, AslNameProcContainer); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenDevice (AslNameProcContainer, ParentNode, &ProcContainerNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Use the ProcContainerIndex for the _UID value as there is no AcpiProcessorUid - // and EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID is set for non-Cpus. - Status = AmlCodeGenNameInteger ( - "_UID", - ProcContainerUid, - ProcContainerNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameString ( - "_HID", - ACPI_HID_PROCESSOR_CONTAINER_DEVICE, - ProcContainerNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // If a set of Lpi states are associated with the - // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them. - if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) { - Status = CreateAmlLpiMethod ( - Generator, - ProcHierarchyNodeInfo, - ProcContainerNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } - - *ProcContainerNodePtr = ProcContainerNode; - - return Status; -} - -/** Check flags and topology of a ProcNode. - - @param [in] NodeFlags Flags of the ProcNode to check. - @param [in] IsLeaf The ProcNode is a leaf. - @param [in] NodeToken NodeToken of the ProcNode. - @param [in] ParentNodeToken Parent NodeToken of the ProcNode. - @param [in] PackageNodeSeen A parent of the ProcNode has the physical package flag set. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -CheckProcNode ( - UINT32 NodeFlags, - BOOLEAN IsLeaf, - CM_OBJECT_TOKEN NodeToken, - CM_OBJECT_TOKEN ParentNodeToken, - BOOLEAN PackageNodeSeen - ) -{ - BOOLEAN InvalidFlags; - BOOLEAN HasPhysicalPackageBit; - - HasPhysicalPackageBit = (NodeFlags & EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) == - EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL; - - // Only one Physical Package flag is allowed in the hierarchy - InvalidFlags = HasPhysicalPackageBit && PackageNodeSeen; - - // Check Leaf specific flags. - if (IsLeaf) { - InvalidFlags |= ((NodeFlags & PPTT_LEAF_MASK) != PPTT_LEAF_MASK); - // Must have Physical Package flag somewhere in the hierarchy - InvalidFlags |= !(HasPhysicalPackageBit || PackageNodeSeen); - } else { - InvalidFlags |= ((NodeFlags & PPTT_LEAF_MASK) != 0); - } - - if (InvalidFlags) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-CPU-TOPOLOGY: Invalid flags for ProcNode: 0x%p.\n", - (VOID *)NodeToken - )); - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - -/** Create an AML representation of the Cpu topology. - - A processor container is by extension any non-leave device in the cpu topology. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] NodeToken Token of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO currently handled. - @param [in] ParentNode Parent node to attach the created - node to. - @param [in,out] ProcContainerIndex Pointer to the current processor container - index to be used as UID. - @param [in] PackageNodeSeen A parent of the ProcNode has the physical package flag set. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlCpuTopologyTree ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_OBJECT_TOKEN NodeToken, - IN AML_NODE_HANDLE ParentNode, - IN OUT UINT32 *ProcContainerIndex, - IN BOOLEAN PackageNodeSeen - ) -{ - EFI_STATUS Status; - UINT32 Index; - UINT32 CpuIndex; - UINT32 ProcContainerName; - AML_OBJECT_NODE_HANDLE ProcContainerNode; - UINT32 Uid; - UINT16 Name; - BOOLEAN HasPhysicalPackageBit; - - ASSERT (Generator != NULL); - ASSERT (Generator->ProcNodeList != NULL); - ASSERT (Generator->ProcNodeCount != 0); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ParentNode != NULL); - ASSERT (ProcContainerIndex != NULL); - - CpuIndex = 0; - ProcContainerName = 0; - - for (Index = 0; Index < Generator->ProcNodeCount; Index++) { - // Find the children of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO - // currently being handled (i.e. ParentToken == NodeToken). - if (Generator->ProcNodeList[Index].ParentToken == NodeToken) { - // Only Cpus (leaf nodes in this tree) have a AcpiIdObjectToken. - // Create a Cpu node. - if (Generator->ProcNodeList[Index].AcpiIdObjectToken != CM_NULL_TOKEN) { - Status = CheckProcNode ( - Generator->ProcNodeList[Index].Flags, - TRUE, - Generator->ProcNodeList[Index].Token, - NodeToken, - PackageNodeSeen - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) { - Name = Generator->ProcNodeList[Index].OverrideName; - } else { - Name = CpuIndex; - } - - Status = CreateAmlCpuFromProcHierarchy ( - Generator, - CfgMgrProtocol, - ParentNode, - Name, - &Generator->ProcNodeList[Index] - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - CpuIndex++; - } else { - // If this is not a Cpu, then this is a processor container. - - Status = CheckProcNode ( - Generator->ProcNodeList[Index].Flags, - FALSE, - Generator->ProcNodeList[Index].Token, - NodeToken, - PackageNodeSeen - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) { - Name = Generator->ProcNodeList[Index].OverrideName; - Uid = Generator->ProcNodeList[Index].OverrideUid; - } else { - Name = ProcContainerName; - Uid = *ProcContainerIndex; - } - - Status = CreateAmlProcessorContainer ( - Generator, - CfgMgrProtocol, - ParentNode, - &Generator->ProcNodeList[Index], - Name, - Uid, - &ProcContainerNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Nodes must have a unique name in the ASL namespace. - // Reset the Cpu index whenever we create a new processor container. - (*ProcContainerIndex)++; - CpuIndex = 0; - - // And reset the cluster name whenever there is a package. - if (NodeToken == CM_NULL_TOKEN) { - ProcContainerName = 0; - } else { - ProcContainerName++; - } - - HasPhysicalPackageBit = (Generator->ProcNodeList[Index].Flags & EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) == - EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL; - - // Recursively continue creating an AML tree. - Status = CreateAmlCpuTopologyTree ( - Generator, - CfgMgrProtocol, - Generator->ProcNodeList[Index].Token, - ProcContainerNode, - ProcContainerIndex, - (PackageNodeSeen || HasPhysicalPackageBit) - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } - } // if ParentToken == NodeToken - } // for - - return EFI_SUCCESS; -} - -/** Create the processor hierarchy AML tree from - CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] ScopeNode Scope node handle ('\_SB' scope). - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateTopologyFromProcHierarchy ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN AML_OBJECT_NODE_HANDLE ScopeNode - ) -{ - EFI_STATUS Status; - UINT32 ProcContainerIndex; - - ASSERT (Generator != NULL); - ASSERT (Generator->ProcNodeCount != 0); - ASSERT (Generator->ProcNodeList != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ScopeNode != NULL); - - ProcContainerIndex = 0; - - Status = TokenTableInitialize (Generator, Generator->ProcNodeCount); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = CreateAmlCpuTopologyTree ( - Generator, - CfgMgrProtocol, - CM_NULL_TOKEN, - ScopeNode, - &ProcContainerIndex, - FALSE - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - - Status = GenerateLpiStates (Generator, CfgMgrProtocol, ScopeNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - -exit_handler: - TokenTableFree (Generator); - return Status; -} - -/** Create the processor hierarchy AML tree from CM_ARM_GICC_INFO - CM objects. - - A processor container is by extension any non-leave device in the cpu topology. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] ScopeNode Scope node handle ('\_SB' scope). - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateTopologyFromGicC ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN AML_OBJECT_NODE_HANDLE ScopeNode - ) -{ - EFI_STATUS Status; - CM_ARM_GICC_INFO *GicCInfo; - UINT32 GicCInfoCount; - UINT32 Index; - AML_OBJECT_NODE_HANDLE CpuNode; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ScopeNode != NULL); - - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicCInfo, - &GicCInfoCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // For each CM_ARM_GICC_INFO object, create an AML node. - for (Index = 0; Index < GicCInfoCount; Index++) { - Status = CreateAmlCpu ( - Generator, - ScopeNode, - &GicCInfo[Index], - Index, - &CpuNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - break; - } - - if (GicCInfo->PsdToken != CM_NULL_TOKEN) { - Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - - // If a CPC info is associated with the - // GicCinfo, create an _CPC method returning them. - if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) { - Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - break; - } - } - - if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) { - Status = CreateAmlEtNode ( - Generator, - CfgMgrProtocol, - &GicCInfo[Index], - Index, - CpuNode - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - } // for - - return Status; -} - -/** Construct the SSDT Cpu Topology ACPI table. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResources function. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [out] Table Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildSsdtCpuTopologyTable ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - EFI_STATUS Status; - AML_ROOT_NODE_HANDLE RootNode; - AML_OBJECT_NODE_HANDLE ScopeNode; - CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; - UINT32 ProcHierarchyNodeCount; - ACPI_CPU_TOPOLOGY_GENERATOR *Generator; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - Generator = (ACPI_CPU_TOPOLOGY_GENERATOR *)This; - - Status = AddSsdtAcpiHeader ( - CfgMgrProtocol, - This, - AcpiTableInfo, - &RootNode - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode); - if (EFI_ERROR (Status)) { - goto exit_handler; - } - - // Get the processor hierarchy info and update the processor topology - // structure count with Processor Hierarchy Nodes (Type 0) - Status = GetEArchCommonObjProcHierarchyInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &ProcHierarchyNodeList, - &ProcHierarchyNodeCount - ); - if (EFI_ERROR (Status) && - (Status != EFI_NOT_FOUND)) - { - goto exit_handler; - } - - if (Status == EFI_NOT_FOUND) { - // If hierarchy information is not found generate a flat topology - // using CM_ARM_GICC_INFO objects. - Status = CreateTopologyFromGicC ( - Generator, - CfgMgrProtocol, - ScopeNode - ); - if (EFI_ERROR (Status)) { - goto exit_handler; - } - } else { - // Generate the topology from CM_ARCH_COMMON_PROC_HIERARCHY_INFO objects. - Generator->ProcNodeList = ProcHierarchyNodeList; - Generator->ProcNodeCount = ProcHierarchyNodeCount; - - Status = CreateTopologyFromProcHierarchy ( - Generator, - CfgMgrProtocol, - ScopeNode - ); - if (EFI_ERROR (Status)) { - goto exit_handler; - } - } - - Status = AmlSerializeDefinitionBlock ( - RootNode, - Table - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-CPU-TOPOLOGY: Failed to Serialize SSDT Table Data." - " Status = %r\n", - Status - )); - goto exit_handler; - } - -exit_handler: - // Delete the RootNode and its attached children. - return AmlDeleteTree (RootNode); -} - -/** Free any resources allocated for constructing the - SSDT Cpu Topology ACPI table. - - @param [in] This Pointer to the table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to the ACPI Table. - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -FreeSsdtCpuTopologyTableResources ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table - ) -{ - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || (*Table == NULL)) { - DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CPU-TOPOLOGY: Invalid Table Pointer\n")); - ASSERT ((Table != NULL) && (*Table != NULL)); - return EFI_INVALID_PARAMETER; - } - - FreePool (*Table); - *Table = NULL; - return EFI_SUCCESS; -} - -/** This macro defines the SSDT Cpu Topology Table Generator revision. -*/ -#define SSDT_CPU_TOPOLOGY_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the SSDT Cpu Topology Table Generator. -*/ -STATIC -ACPI_CPU_TOPOLOGY_GENERATOR SsdtCpuTopologyGenerator = { - // ACPI table generator header - { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCpuTopology), - // Generator Description - L"ACPI.STD.SSDT.CPU.TOPOLOGY.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, - // ACPI Table Revision - Unused - 0, - // Minimum ACPI Table Revision - Unused - 0, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - SSDT_CPU_TOPOLOGY_GENERATOR_REVISION, - // Build Table function - BuildSsdtCpuTopologyTable, - // Free Resource function - FreeSsdtCpuTopologyTableResources, - // Extended build function not needed - NULL, - // Extended build function not implemented by the generator. - // Hence extended free resource function is not required. - NULL - }, - - // Private fields are defined from here. - - // TokenTable - { - // Table - NULL, - // LastIndex - 0 - }, - // ProcNodeList - NULL, - // ProcNodeCount - 0 -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiSsdtCpuTopologyLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&SsdtCpuTopologyGenerator.Header); - DEBUG (( - DEBUG_INFO, - "SSDT-CPU-TOPOLOGY: Register Generator. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiSsdtCpuTopologyLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&SsdtCpuTopologyGenerator.Header); - DEBUG (( - DEBUG_INFO, - "SSDT-CPU-TOPOLOGY: Deregister Generator. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h deleted file mode 100644 index 6fb44c7e58..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h +++ /dev/null @@ -1,147 +0,0 @@ -/** @file - SSDT Cpu Topology Table Generator. - - Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors - - ACPI for CoreSight version 1.2 Platform Design Document - (https://developer.arm.com/documentation/den0067/a/?lang=en) - - @par Glossary: - - ETE - Embedded Trace Extension. - - ETM - Embedded Trace Macrocell. -**/ - -#ifndef SSDT_CPU_TOPOLOGY_GENERATOR_H_ -#define SSDT_CPU_TOPOLOGY_GENERATOR_H_ - -#pragma pack(1) - -// Mask for the flags that need to be checked. -#define PPTT_PROCESSOR_MASK ( \ - (EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) | \ - (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \ - (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3)) - -// Mask for the cpu flags. -#define PPTT_CPU_PROCESSOR_MASK ( \ - (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \ - (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \ - (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3)) - -// Mask for the cluster flags. -// Even though a _UID is generated for clusters, it is simpler to use -// EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID and to not match the cluster id of -// the PPTT table (not sure the PPTT table is generated). -#define PPTT_CLUSTER_PROCESSOR_MASK ( \ - (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \ - (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID << 1) | \ - (EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF << 3)) - -// Leaf nodes specific mask. -#define PPTT_LEAF_MASK ((EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \ - (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3)) - -/** LPI states are stored in the ASL namespace at '\_SB_.Lxxx', - with xxx being the node index of the LPI state. -*/ -#define SB_SCOPE "\\_SB_" -#define SB_SCOPE_PREFIX SB_SCOPE "." -/// Size of the SB_SCOPE_PREFIX string. -#define SB_SCOPE_PREFIX_SIZE sizeof (SB_SCOPE_PREFIX) - -/// HID for a processor device. -#define ACPI_HID_PROCESSOR_DEVICE "ACPI0007" - -/// HID for a ETM/ETE device. -#define ACPI_HID_ET_DEVICE "ARMHC500" - -/// HID for a processor container device. -#define ACPI_HID_PROCESSOR_CONTAINER_DEVICE "ACPI0010" - -/** Node names of Cpus and Clusters are 'Cxxx', and 'Lxxx' for LPI states. - The 'xxx' is an index on 12 bits is given to node name, - thus the limitation in the number of nodes. -*/ -#define MAX_NODE_COUNT (1 << 12) - -/** A structure used to handle the Lpi structures referencing. - - A CM_ARCH_COMMON_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF. - This CM_ARCH_COMMON_OBJ_REF references CM_ARCH_COMMON_LPI_INFO structures. - - Example: - (Cpu0) (Cpu1) - CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM_ARCH_COMMON_PROC_HIERARCHY_INFO - | | - +---------------------------------------- - | - v - (List of references to Lpi states) - CM_ARCH_COMMON_OBJ_REF - | - +---------------------------------------- - | | - v v - (A first Lpi state) (A second Lpi state) - CM_ARCH_COMMON_LPI_INFO[0] CM_ARCH_COMMON_LPI_INFO[1] - - Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARCH_COMMON_PROC_HIERARCHY_INFO - structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the - TokenTable such as: - 0 <-> CM_ARCH_COMMON_OBJ_REF - - This will lead to the creation of this pseudo-ASL code where Cpu0 and Cpu1 - return the same object at \_SB.L000: - Scope (\_SB) { - Device (C000) { - [...] - Method (_LPI) { - Return (\_SB.L000) - } - } // C000 - - Device (C001) { - [...] - Method (_LPI) { - Return (\_SB.L000) - } - } // C001 - - // Lpi states - Name (L000, Package (0x05) { - [...] - } - } -*/ -typedef struct TokenTable { - /// TokenTable, a table allowing to map: - /// Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). - CM_OBJECT_TOKEN *Table; - - /// Last used index of the TokenTable. - /// LastIndex is bound by ProcNodeCount. - UINT32 LastIndex; -} TOKEN_TABLE; - -/** A structure holding the Cpu topology generator and additional private data. -*/ -typedef struct AcpiCpuTopologyGenerator { - /// ACPI Table generator header - ACPI_TABLE_GENERATOR Header; - - // Private fields are defined from here. - - /// Private object used to handle token referencing. - TOKEN_TABLE TokenTable; - /// List of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. - CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNodeList; - /// Count of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. - UINT32 ProcNodeCount; -} ACPI_CPU_TOPOLOGY_GENERATOR; - -#pragma pack() - -#endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf deleted file mode 100644 index 3e2d154749..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf +++ /dev/null @@ -1,33 +0,0 @@ -## @file -# Ssdt Cpu Topology Table Generator -# -# Copyright (c) 2021, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x0001001B - BASE_NAME = SsdtCpuTopologyLibArm - FILE_GUID = F2835EB6-4B05-48D4-A475-147DA0F3755C - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiSsdtCpuTopologyLibConstructor - DESTRUCTOR = AcpiSsdtCpuTopologyLibDestructor - -[Sources] - SsdtCpuTopologyGenerator.c - SsdtCpuTopologyGenerator.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - AcpiHelperLib - AmlLib - BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c deleted file mode 100644 index 2b488016e5..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c +++ /dev/null @@ -1,1247 +0,0 @@ -/** @file - SSDT Pcie Table Generator. - - Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - PCI Firmware Specification - Revision 3.0 - - ACPI 6.4 specification: - - s6.2.13 "_PRT (PCI Routing Table)" - - s6.1.1 "_ADR (Address)" - - linux kernel code - - Arm Base Boot Requirements v1.0 - - Arm Base System Architecture v1.0 -**/ - -#include -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include -#include -#include - -#include "SsdtPcieGenerator.h" - -#define PCI_MAX_DEVICE_COUNT_PER_BUS 32 -#define PCI_MAX_FUNCTION_COUNT_PER_DEVICE 8 - -/** ARM standard SSDT Pcie Table Generator. - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjCmRef - - EArchCommonObjPciConfigSpaceInfo - - EArchCommonObjPciAddressMapInfo - - EArchCommonObjPciInterruptMapInfo -*/ - -/** This macro expands to a function that retrieves the cross-CM-object- - reference information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjCmRef, - CM_ARCH_COMMON_OBJ_REF - ); - -/** This macro expands to a function that retrieves the Pci - Configuration Space Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPciConfigSpaceInfo, - CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO - ); - -/** This macro expands to a function that retrieves the Pci - Address Mapping Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPciAddressMapInfo, - CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO - ); - -/** This macro expands to a function that retrieves the Pci - Interrupt Mapping Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjPciInterruptMapInfo, - CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO - ); - -/** Initialize the MappingTable. - - @param [in] MappingTable The mapping table structure. - @param [in] Count Number of entries to allocate in the - MappingTable. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -MappingTableInitialize ( - IN MAPPING_TABLE *MappingTable, - IN UINT32 Count - ) -{ - UINT32 *Table; - - if ((MappingTable == NULL) || - (Count == 0)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Table = AllocateZeroPool (sizeof (*Table) * Count); - if (Table == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - - MappingTable->Table = Table; - MappingTable->LastIndex = 0; - MappingTable->MaxIndex = Count; - - return EFI_SUCCESS; -} - -/** Free the MappingTable. - - @param [in, out] MappingTable The mapping table structure. -**/ -STATIC -VOID -EFIAPI -MappingTableFree ( - IN OUT MAPPING_TABLE *MappingTable - ) -{ - ASSERT (MappingTable != NULL); - ASSERT (MappingTable->Table != NULL); - - if (MappingTable->Table != NULL) { - FreePool (MappingTable->Table); - } -} - -/** Add a new entry to the MappingTable and return its index. - - If an entry with [Integer] is already available in the table, - return its index without adding a new entry. - - @param [in] MappingTable The mapping table structure. - @param [in] Integer New Integer entry to add. - - @retval The index of the Integer entry in the MappingTable. -**/ -STATIC -UINT32 -EFIAPI -MappingTableAdd ( - IN MAPPING_TABLE *MappingTable, - IN UINT32 Integer - ) -{ - UINT32 *Table; - UINT32 Index; - UINT32 LastIndex; - - ASSERT (MappingTable != NULL); - ASSERT (MappingTable->Table != NULL); - - Table = MappingTable->Table; - LastIndex = MappingTable->LastIndex; - - // Search if there is already an entry with this Integer. - for (Index = 0; Index < LastIndex; Index++) { - if (Table[Index] == Integer) { - return Index; - } - } - - ASSERT (LastIndex < MappingTable->MaxIndex); - - // If no, create a new entry. - Table[LastIndex] = Integer; - - return MappingTable->LastIndex++; -} - -/** Generate required Pci device information. - - ASL code: - Name (_UID, ) // Uid of the Pci device - Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge - Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge - Name (_SEG, ) // PCI Segment Group number - Name (_BBN, ) // PCI Base Bus Number - Name (_CCA, 1) // Initially mark the PCI coherent - - @param [in] PciInfo Pci device information. - @param [in] Uid Unique Id of the Pci device. - @param [in, out] PciNode Pci node to amend. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -GeneratePciDeviceInfo ( - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, - IN UINT32 Uid, - IN OUT AML_OBJECT_NODE_HANDLE PciNode - ) -{ - EFI_STATUS Status; - UINT32 EisaId; - - ASSERT (PciInfo != NULL); - ASSERT (PciNode != NULL); - - // ASL: Name (_UID, ) - Status = AmlCodeGenNameInteger ("_UID", Uid, PciNode, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_HID, EISAID ("PNP0A08")) - Status = AmlGetEisaIdFromString ("PNP0A08", &EisaId); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameInteger ("_HID", EisaId, PciNode, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_CID, EISAID ("PNP0A03")) - Status = AmlGetEisaIdFromString ("PNP0A03", &EisaId); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameInteger ("_CID", EisaId, PciNode, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_SEG, ) - Status = AmlCodeGenNameInteger ( - "_SEG", - PciInfo->PciSegmentGroupNumber, - PciNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_BBN, ) - Status = AmlCodeGenNameInteger ( - "_BBN", - PciInfo->StartBusNumber, - PciNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_CCA, 1) - // Must be aligned with the IORT CCA property in - // "Table 14 Memory access properties" - Status = AmlCodeGenNameInteger ("_CCA", 1, PciNode, NULL); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Generate a _PRT object (Pci Routing Table) for the Pci device. - - Cf. ACPI 6.4 specification, s6.2.13 "_PRT (PCI Routing Table)" - - @param [in] Generator The SSDT Pci generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [in] PciInfo Pci device information. - @param [in] Uid Unique Id of the Pci device. - @param [in, out] PciNode Pci node to amend. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -GeneratePrt ( - IN ACPI_PCI_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, - IN UINT32 Uid, - IN OUT AML_OBJECT_NODE_HANDLE PciNode - ) -{ - EFI_STATUS Status; - INT32 Index; - AML_OBJECT_NODE_HANDLE PrtNode; - CM_ARCH_COMMON_OBJ_REF *RefInfo; - UINT32 RefCount; - CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *IrqMapInfo; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (PciInfo != NULL); - ASSERT (PciNode != NULL); - - PrtNode = NULL; - - // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the - // CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO objects. - Status = GetEArchCommonObjCmRef ( - CfgMgrProtocol, - PciInfo->InterruptMapToken, - &RefInfo, - &RefCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Initialized DeviceTable. - Status = MappingTableInitialize (&Generator->DeviceTable, RefCount); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler0; - } - - // ASL: Name (_PRT, Package () {}) - Status = AmlCodeGenNamePackage ("_PRT", NULL, &PrtNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - - for (Index = 0; Index < RefCount; Index++) { - // Get CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO structures one by one. - Status = GetEArchCommonObjPciInterruptMapInfo ( - CfgMgrProtocol, - RefInfo[Index].ReferenceToken, - &IrqMapInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - - // Check that the interrupts flags are SPIs, level high. - // Cf. Arm BSA v1.0, sE.6 "Legacy interrupts" - if ((Index > 0) && - (IrqMapInfo->IntcInterrupt.Interrupt >= 32) && - (IrqMapInfo->IntcInterrupt.Interrupt < 1020) && - ((IrqMapInfo->IntcInterrupt.Flags & 0xB) != 0)) - { - Status = EFI_INVALID_PARAMETER; - ASSERT_EFI_ERROR (Status); - goto exit_handler; - } - - // Add the device to the DeviceTable. - MappingTableAdd (&Generator->DeviceTable, IrqMapInfo->PciDevice); - - /* Add a _PRT entry. - ASL - Name (_PRT, Package () { - , - - }) - - Address is set as: - ACPI 6.4 specification, Table 6.2: "ADR Object Address Encodings" - High word-Device #, Low word-Function #. (for example, device 3, - function 2 is 0x00030002). To refer to all the functions on a device #, - use a function number of FFFF). - - Use the second model for _PRT object and describe a hardwired interrupt. - */ - Status = AmlAddPrtEntry ( - (IrqMapInfo->PciDevice << 16) | 0xFFFF, - IrqMapInfo->PciInterrupt, - NULL, - IrqMapInfo->IntcInterrupt.Interrupt, - PrtNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - } // for - - // Attach the _PRT entry. - Status = AmlAttachNode (PciNode, PrtNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - goto exit_handler; - } - - PrtNode = NULL; - - // Generate the Pci slots once all the device have been added. - Status = GeneratePciSlots (PciInfo, &Generator->DeviceTable, Uid, PciNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - -exit_handler: - MappingTableFree (&Generator->DeviceTable); -exit_handler0: - if (PrtNode != NULL) { - AmlDeleteTree (PrtNode); - } - - return Status; -} - -/** Generate a _CRS method for the Pci device. - - @param [in] Generator The SSDT Pci generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [in] PciInfo Pci device information. - @param [in, out] PciNode Pci node to amend. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -GeneratePciCrs ( - IN ACPI_PCI_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, - IN OUT AML_OBJECT_NODE_HANDLE PciNode - ) -{ - EFI_STATUS Status; - BOOLEAN Translation; - UINT32 Index; - CM_ARCH_COMMON_OBJ_REF *RefInfo; - UINT32 RefCount; - CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *AddrMapInfo; - AML_OBJECT_NODE_HANDLE CrsNode; - BOOLEAN IsPosDecode; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (PciInfo != NULL); - ASSERT (PciNode != NULL); - - // ASL: Name (_CRS, ResourceTemplate () {}) - Status = AmlCodeGenNameResourceTemplate ("_CRS", PciNode, &CrsNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: - // WordBusNumber ( // Bus numbers assigned to this root - // ResourceProducer, MinFixed, MaxFixed, PosDecode, - // 0, // AddressGranularity - // , // AddressMinimum - Minimum Bus Number - // , // AddressMaximum - Maximum Bus Number - // 0, // AddressTranslation - Set to 0 - // - + 1 // RangeLength - Number of Busses - // ) - Status = AmlCodeGenRdWordBusNumber ( - FALSE, - TRUE, - TRUE, - TRUE, - 0, - PciInfo->StartBusNumber, - PciInfo->EndBusNumber, - 0, - PciInfo->EndBusNumber - PciInfo->StartBusNumber + 1, - 0, - NULL, - CrsNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the - // CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO objects. - Status = GetEArchCommonObjCmRef ( - CfgMgrProtocol, - PciInfo->AddressMapToken, - &RefInfo, - &RefCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - for (Index = 0; Index < RefCount; Index++) { - // Get CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO structures one by one. - Status = GetEArchCommonObjPciAddressMapInfo ( - CfgMgrProtocol, - RefInfo[Index].ReferenceToken, - &AddrMapInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Translation = (AddrMapInfo->CpuAddress != AddrMapInfo->PciAddress); - if (AddrMapInfo->CpuAddress >= AddrMapInfo->PciAddress) { - IsPosDecode = TRUE; - } else { - IsPosDecode = FALSE; - } - - switch (AddrMapInfo->SpaceCode) { - case PCI_SS_IO: - Status = AmlCodeGenRdQWordIo ( - FALSE, - TRUE, - TRUE, - IsPosDecode, - 3, - 0, - AddrMapInfo->PciAddress, - AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, - Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, - AddrMapInfo->AddressSize, - 0, - NULL, - TRUE, - FALSE, - CrsNode, - NULL - ); - break; - - case PCI_SS_M32: - Status = AmlCodeGenRdDWordMemory ( - FALSE, - IsPosDecode, - TRUE, - TRUE, - AmlMemoryCacheable, - TRUE, - 0, - AddrMapInfo->PciAddress, - AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, - Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, - AddrMapInfo->AddressSize, - 0, - NULL, - AmlAddressRangeMemory, - TRUE, - CrsNode, - NULL - ); - break; - - case PCI_SS_M64: - Status = AmlCodeGenRdQWordMemory ( - FALSE, - IsPosDecode, - TRUE, - TRUE, - AmlMemoryCacheable, - TRUE, - 0, - AddrMapInfo->PciAddress, - AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, - Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, - AddrMapInfo->AddressSize, - 0, - NULL, - AmlAddressRangeMemory, - TRUE, - CrsNode, - NULL - ); - break; - - default: - Status = EFI_INVALID_PARAMETER; - } // switch - - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } // for - - return Status; -} - -/** Generate a RES0 device node to reserve PNP motherboard resources - for a given PCI node. - - @param [in] PciNode Parent PCI node handle of the generated - resource object. - @param [out] CrsNode CRS node of the AML tree to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid input parameter. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -GenerateMotherboardDevice ( - IN AML_OBJECT_NODE_HANDLE PciNode, - OUT AML_OBJECT_NODE_HANDLE *CrsNode - ) -{ - EFI_STATUS Status; - UINT32 EisaId; - AML_OBJECT_NODE_HANDLE ResNode; - - if (CrsNode == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // ASL: Device (RES0) {} - Status = AmlCodeGenDevice ("RES0", PciNode, &ResNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_HID, EISAID ("PNP0C02")) - Status = AmlGetEisaIdFromString ("PNP0C02", &EisaId); /* PNP Motherboard Resources */ - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameInteger ("_HID", EisaId, ResNode, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // ASL: Name (_CRS, ResourceTemplate () {}) - Status = AmlCodeGenNameResourceTemplate ("_CRS", ResNode, CrsNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - return Status; -} - -/** Reserves ECAM space for PCI config space - - @param [in] Generator The SSDT Pci generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [in] PciInfo Pci device information. - @param [in, out] PciNode RootNode of the AML tree to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -ReserveEcamSpace ( - IN ACPI_PCI_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, - IN OUT AML_OBJECT_NODE_HANDLE PciNode - ) -{ - EFI_STATUS Status; - AML_OBJECT_NODE_HANDLE CrsNode; - UINT64 AddressMinimum; - UINT64 AddressMaximum; - - Status = GenerateMotherboardDevice (PciNode, &CrsNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - AddressMinimum = PciInfo->BaseAddress + (PciInfo->StartBusNumber * - PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB); - AddressMaximum = PciInfo->BaseAddress + ((PciInfo->EndBusNumber + 1) * - PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB) - 1; - - Status = AmlCodeGenRdQWordMemory ( - FALSE, - TRUE, - TRUE, - TRUE, - AmlMemoryNonCacheable, - TRUE, - 0, - AddressMinimum, - AddressMaximum, - 0, // no translation - AddressMaximum - AddressMinimum + 1, - 0, - NULL, - AmlAddressRangeMemory, - TRUE, - CrsNode, - NULL - ); - - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - return Status; -} - -/** Generate a Pci device. - - @param [in] Generator The SSDT Pci generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [in] PciInfo Pci device information. - @param [in] Uid Unique Id of the Pci device. - @param [in, out] RootNode RootNode of the AML tree to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -GeneratePciDevice ( - IN ACPI_PCI_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, - IN UINT32 Uid, - IN OUT AML_ROOT_NODE_HANDLE *RootNode - ) -{ - EFI_STATUS Status; - - CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; - AML_OBJECT_NODE_HANDLE ScopeNode; - AML_OBJECT_NODE_HANDLE PciNode; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (PciInfo != NULL); - ASSERT (RootNode != NULL); - - PciNode = NULL; - - // ASL: Scope (\_SB) {} - Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Write the name of the PCI device. - CopyMem (AslName, "PCIx", AML_NAME_SEG_SIZE + 1); - AslName[AML_NAME_SEG_SIZE - 1] = AsciiFromHex (Uid & 0xF); - if (Uid > 0xF) { - AslName[AML_NAME_SEG_SIZE - 2] = AsciiFromHex ((Uid >> 4) & 0xF); - } - - // ASL: Device (PCIx) {} - Status = AmlCodeGenDevice (AslName, ScopeNode, &PciNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Populate the PCIx node with some Id values. - Status = GeneratePciDeviceInfo (PciInfo, Uid, PciNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Generate the Pci Routing Table (_PRT). - if (PciInfo->InterruptMapToken != CM_NULL_TOKEN) { - Status = GeneratePrt ( - Generator, - CfgMgrProtocol, - PciInfo, - Uid, - PciNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } - - // Generate the _CRS method. - Status = GeneratePciCrs (Generator, CfgMgrProtocol, PciInfo, PciNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the PNP Motherboard Resources Device to reserve ECAM space - Status = ReserveEcamSpace (Generator, CfgMgrProtocol, PciInfo, PciNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the template _OSC method. - Status = AddOscMethod (PciInfo, PciNode); - ASSERT_EFI_ERROR (Status); - - return Status; -} - -/** Build an Ssdt table describing a Pci device. - - @param [in] Generator The SSDT Pci generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [in] AcpiTableInfo Pointer to the ACPI table information. - @param [in] PciInfo Pci device information. - @param [in] Uid Unique Id of the Pci device. - @param [out] Table If success, contains the created SSDT table. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildSsdtPciTable ( - IN ACPI_PCI_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, - IN UINT32 Uid, - OUT EFI_ACPI_DESCRIPTION_HEADER **Table - ) -{ - EFI_STATUS Status; - EFI_STATUS Status1; - AML_ROOT_NODE_HANDLE RootNode; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (PciInfo != NULL); - ASSERT (Table != NULL); - - // Create a new Ssdt table. - Status = AddSsdtAcpiHeader ( - CfgMgrProtocol, - &Generator->Header, - AcpiTableInfo, - &RootNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = GeneratePciDevice ( - Generator, - CfgMgrProtocol, - PciInfo, - Uid, - RootNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - - // Serialize the tree. - Status = AmlSerializeDefinitionBlock ( - RootNode, - Table - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Failed to Serialize SSDT Table Data." - " Status = %r\n", - Status - )); - } - -exit_handler: - // Cleanup - Status1 = AmlDeleteTree (RootNode); - if (EFI_ERROR (Status1)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Failed to cleanup AML tree." - " Status = %r\n", - Status1 - )); - // If Status was success but we failed to delete the AML Tree - // return Status1 else return the original error code, i.e. Status. - if (!EFI_ERROR (Status)) { - return Status1; - } - } - - return Status; -} - -/** Construct SSDT tables describing Pci root complexes. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResourcesEx function. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI table information. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [out] Table Pointer to a list of generated ACPI table(s). - @param [out] TableCount Number of generated ACPI table(s). - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for - the requested object. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Could not find information. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. - @retval EFI_UNSUPPORTED Unsupported configuration. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildSsdtPciTableEx ( - IN CONST ACPI_TABLE_GENERATOR *This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, - OUT UINTN *CONST TableCount - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo; - UINT32 PciCount; - UINTN Index; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - ACPI_PCI_GENERATOR *Generator; - UINT32 Uid; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (TableCount != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - *TableCount = 0; - Generator = (ACPI_PCI_GENERATOR *)This; - - Status = GetEArchCommonObjPciConfigSpaceInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &PciInfo, - &PciCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (PciCount > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Too many Pci root complexes: %d." - " Maximum Pci root complexes supported = %d.\n", - PciCount, - MAX_PCI_ROOT_COMPLEXES_SUPPORTED - )); - return EFI_INVALID_PARAMETER; - } - - // Allocate a table to store pointers to the SSDT tables. - TableList = (EFI_ACPI_DESCRIPTION_HEADER **) - AllocateZeroPool ( - (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * PciCount) - ); - if (TableList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Failed to allocate memory for Table List." - " Status = %r\n", - Status - )); - return Status; - } - - // Setup the table list early so that appropriate cleanup - // can be done in case of failure. - *Table = TableList; - - for (Index = 0; Index < PciCount; Index++) { - if (PcdGetBool (PcdPciUseSegmentAsUid)) { - Uid = PciInfo[Index].PciSegmentGroupNumber; - if (Uid > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Pci root complexes segment number: %d." - " Greater than maximum number of Pci root complexes supported = %d.\n", - Uid, - MAX_PCI_ROOT_COMPLEXES_SUPPORTED - )); - return EFI_INVALID_PARAMETER; - } - } else { - Uid = Index; - } - - // Build a SSDT table describing the Pci devices. - Status = BuildSsdtPciTable ( - Generator, - CfgMgrProtocol, - AcpiTableInfo, - &PciInfo[Index], - Uid, - &TableList[Index] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Failed to build associated SSDT table." - " Status = %r\n", - Status - )); - goto error_handler; - } - - *TableCount += 1; - } // for - -error_handler: - // Note: Table list and Table count have been setup. The - // error handler does nothing here as the framework will invoke - // FreeSsdtPciTableEx () even on failure. - return Status; -} - -/** Free any resources allocated for constructing the tables. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to an array of pointers - to ACPI Table(s). - @param [in] TableCount Number of ACPI table(s). - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -FreeSsdtPciTableEx ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, - IN CONST UINTN TableCount - ) -{ - EFI_ACPI_DESCRIPTION_HEADER **TableList; - UINTN Index; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || - (*Table == NULL) || - (TableCount == 0)) - { - DEBUG ((DEBUG_ERROR, "ERROR: SSDT-PCI: Invalid Table Pointer\n")); - return EFI_INVALID_PARAMETER; - } - - TableList = *Table; - for (Index = 0; Index < TableCount; Index++) { - if ((TableList[Index] != NULL) && - (TableList[Index]->Signature == - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) - { - FreePool (TableList[Index]); - } else { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-PCI: Could not free SSDT table at index %d.", - Index - )); - return EFI_INVALID_PARAMETER; - } - } // for - - // Free the table list. - FreePool (*Table); - - return EFI_SUCCESS; -} - -/** This macro defines the SSDT Pci Table Generator revision. -*/ -#define SSDT_PCI_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the SSDT Pci Table Generator. -*/ -STATIC -ACPI_PCI_GENERATOR SsdtPcieGenerator = { - // ACPI table generator header - { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress), - // Generator Description - L"ACPI.STD.SSDT.PCI.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, - // ACPI Table Revision - Unused - 0, - // Minimum ACPI Table Revision - Unused - 0, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - SSDT_PCI_GENERATOR_REVISION, - // Build table function. Use the extended version instead. - NULL, - // Free table function. Use the extended version instead. - NULL, - // Extended Build table function. - BuildSsdtPciTableEx, - // Extended free function. - FreeSsdtPciTableEx - }, - - // Private fields are defined from here. - - // DeviceTable - { - // Table - NULL, - // LastIndex - 0, - // MaxIndex - 0 - }, -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiSsdtPcieLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&SsdtPcieGenerator.Header); - DEBUG (( - DEBUG_INFO, - "SSDT-PCI: Register Generator. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiSsdtPcieLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&SsdtPcieGenerator.Header); - DEBUG (( - DEBUG_INFO, - "SSDT-PCI: Deregister Generator. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h deleted file mode 100644 index 7410f9ffd4..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h +++ /dev/null @@ -1,55 +0,0 @@ -/** @file - SSDT Pcie Table Generator. - - Copyright (c) 2021, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - PCI Firmware Specification - Revision 3.0 - - ACPI 6.4 specification: - - s6.2.13 "_PRT (PCI Routing Table)" - - s6.1.1 "_ADR (Address)" - - linux kernel code - - Arm Base Boot Requirements v1.0 -**/ - -#ifndef SSDT_PCIE_GENERATOR_H_ -#define SSDT_PCIE_GENERATOR_H_ - -/** Pci address attributes. - - This can also be denoted as space code, address space or ss. -*/ -#define PCI_SS_CONFIG 0 -#define PCI_SS_IO 1 -#define PCI_SS_M32 2 -#define PCI_SS_M64 3 - -/** Maximum Pci root complexes supported by this generator. - - Note: This is not a hard limitation and can be extended if needed. - Corresponding changes would be needed to support the Name and - UID fields describing the Pci root complexes. -*/ -#define MAX_PCI_ROOT_COMPLEXES_SUPPORTED 256 - -// _SB scope of the AML namespace. -#define SB_SCOPE "\\_SB_" - -#pragma pack(1) - -/** A structure holding the Pcie generator and additional private data. -*/ -typedef struct AcpiPcieGenerator { - /// ACPI Table generator header - ACPI_TABLE_GENERATOR Header; - - // Private fields are defined from here. - - /// Table to map: Index <-> Pci device - MAPPING_TABLE DeviceTable; -} ACPI_PCI_GENERATOR; - -#pragma pack() - -#endif // SSDT_PCIE_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf deleted file mode 100644 index c2a1acb570..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf +++ /dev/null @@ -1,35 +0,0 @@ -## @file -# Ssdt Serial Port Table Generator -# -# Copyright (c) 2021, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x0001001B - BASE_NAME = SsdtPcieLibArm - FILE_GUID = E431D7FD-26BF-4E3D-9064-5B13B0439057 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiSsdtPcieLibConstructor - DESTRUCTOR = AcpiSsdtPcieLibDestructor - -[Sources] - SsdtPcieGenerator.c - SsdtPcieGenerator.h - -[Packages] - DynamicTablesPkg/DynamicTablesPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - AcpiHelperLib - AmlLib - BaseLib - SsdtPcieSupportLib - -[Pcd] - gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdPciUseSegmentAsUid diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c deleted file mode 100644 index 671ba05740..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c +++ /dev/null @@ -1,373 +0,0 @@ -/** @file - SSDT Serial Port Table Generator. - - Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include - -/** ARM standard SSDT Serial Port Table Generator - - Constructs SSDT tables describing serial ports (other than the serial ports - used by the SPCR or DBG2 tables). - -Requirements: - The following Configuration Manager Object(s) are required by - this Generator: - - EArchCommonObjSerialPortInfo -*/ - -/** This macro expands to a function that retrieves the Serial-port - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArchCommon, - EArchCommonObjSerialPortInfo, - CM_ARCH_COMMON_SERIAL_PORT_INFO - ); - -/** Starting value for the UID to represent the serial ports. - Note: The UID 0 and 1 are reserved for use by DBG2 port and SPCR - respectively. So, the UIDs for serial ports for general use - start at 2. -*/ -#define SERIAL_PORT_START_UID 2 - -/** Maximum serial ports supported by this generator. - This generator supports a maximum of 14 (16 - 2) serial ports. - The -2 here reflects the reservation for serial ports for the DBG2 - and SPCR ports regardless of whether the DBG2 or SPCR port is enabled. - Note: This is not a hard limitation and can be extended if needed. - Corresponding changes would be needed to support the Name and - UID fields describing the serial port. - -*/ -#define MAX_SERIAL_PORTS_SUPPORTED 14 - -/** Free any resources allocated for constructing the tables. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI Table Info. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Table Pointer to an array of pointers - to ACPI Table(s). - @param [in] TableCount Number of ACPI table(s). - - @retval EFI_SUCCESS The resources were freed successfully. - @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. -**/ -STATIC -EFI_STATUS -EFIAPI -FreeSsdtSerialPortTableEx ( - IN CONST ACPI_TABLE_GENERATOR *CONST This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, - IN CONST UINTN TableCount - ) -{ - EFI_STATUS Status; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - UINTN Index; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - if ((Table == NULL) || - (*Table == NULL) || - (TableCount == 0)) - { - DEBUG ((DEBUG_ERROR, "ERROR: SSDT-SERIAL-PORT: Invalid Table Pointer\n")); - return EFI_INVALID_PARAMETER; - } - - TableList = *Table; - - for (Index = 0; Index < TableCount; Index++) { - if ((TableList[Index] != NULL) && - (TableList[Index]->Signature == - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) - { - Status = FreeSsdtSerialPortTable (TableList[Index]); - } else { - Status = EFI_INVALID_PARAMETER; - } - - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-SERIAL-PORT: Could not free SSDT table at index %d." - " Status = %r\n", - Index, - Status - )); - return Status; - } - } // for - - // Free the table list. - FreePool (*Table); - - return EFI_SUCCESS; -} - -/** Construct SSDT tables describing serial-ports. - - This function invokes the Configuration Manager protocol interface - to get the required hardware information for generating the ACPI - table. - - If this function allocates any resources then they must be freed - in the FreeXXXXTableResourcesEx function. - - @param [in] This Pointer to the ACPI table generator. - @param [in] AcpiTableInfo Pointer to the ACPI table information. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol interface. - @param [out] Table Pointer to a list of generated ACPI table(s). - @param [out] TableCount Number of generated ACPI table(s). - - @retval EFI_SUCCESS Table generated successfully. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for - the requested object. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Could not find information. - @retval EFI_OUT_OF_RESOURCES Could not allocate memory. - @retval EFI_UNSUPPORTED Unsupported configuration. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildSsdtSerialPortTableEx ( - IN CONST ACPI_TABLE_GENERATOR *This, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, - OUT UINTN *CONST TableCount - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; - UINT32 SerialPortCount; - UINTN Index; - CHAR8 NewName[AML_NAME_SEG_SIZE + 1]; - UINT64 Uid; - EFI_ACPI_DESCRIPTION_HEADER **TableList; - - ASSERT (This != NULL); - ASSERT (AcpiTableInfo != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (Table != NULL); - ASSERT (TableCount != NULL); - ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); - ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); - - *Table = NULL; - - Status = GetEArchCommonObjSerialPortInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &SerialPortInfo, - &SerialPortCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-SERIAL-PORT: Failed to get serial port information." - " Status = %r\n", - Status - )); - return Status; - } - - if (SerialPortCount > MAX_SERIAL_PORTS_SUPPORTED) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-SERIAL-PORT: Too many serial ports: %d." - " Maximum serial ports supported = %d.\n", - SerialPortCount, - MAX_SERIAL_PORTS_SUPPORTED - )); - return EFI_INVALID_PARAMETER; - } - - // Validate the SerialPort info. - Status = ValidateSerialPortInfo (SerialPortInfo, SerialPortCount); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-SERIAL-PORT: Invalid serial port information. Status = %r\n", - Status - )); - return Status; - } - - // Allocate a table to store pointers to the SSDT tables. - TableList = (EFI_ACPI_DESCRIPTION_HEADER **) - AllocateZeroPool ( - (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * SerialPortCount) - ); - if (TableList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-SERIAL-PORT: Failed to allocate memory for Table List." - " Status = %r\n", - Status - )); - return Status; - } - - // Setup the table list early so that appropriate cleanup - // can be done in case of failure. - *Table = TableList; - - NewName[0] = 'C'; - NewName[1] = 'O'; - NewName[2] = 'M'; - NewName[4] = '\0'; - for (Index = 0; Index < SerialPortCount; Index++) { - Uid = SERIAL_PORT_START_UID + Index; - NewName[3] = AsciiFromHex ((UINT8)(Uid)); - - // Build a SSDT table describing the serial port. - Status = BuildSsdtSerialPortTable ( - AcpiTableInfo, - &SerialPortInfo[Index], - NewName, - Uid, - &TableList[Index] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SSDT-SERIAL-PORT: Failed to build associated SSDT table." - " Status = %r\n", - Status - )); - goto error_handler; - } - - // Increment the table count here so that appropriate cleanup - // can be done in case of failure. - *TableCount += 1; - } // for - -error_handler: - // Note: Table list and Serial port count has been setup. The - // error handler does nothing here as the framework will invoke - // FreeSsdtSerialPortTableEx() even on failure. - return Status; -} - -/** This macro defines the SSDT Serial Port Table Generator revision. -*/ -#define SSDT_SERIAL_GENERATOR_REVISION CREATE_REVISION (1, 0) - -/** The interface for the SSDT Serial Port Table Generator. -*/ -STATIC -CONST -ACPI_TABLE_GENERATOR SsdtSerialPortGenerator = { - // Generator ID - CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtSerialPort), - // Generator Description - L"ACPI.STD.SSDT.SERIAL.PORT.GENERATOR", - // ACPI Table Signature - EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, - // ACPI Table Revision - Unused - 0, - // Minimum ACPI Table Revision - Unused - 0, - // Creator ID - TABLE_GENERATOR_CREATOR_ID_ARM, - // Creator Revision - SSDT_SERIAL_GENERATOR_REVISION, - // Build table function. Use the extended version instead. - NULL, - // Free table function. Use the extended version instead. - NULL, - // Extended Build table function. - BuildSsdtSerialPortTableEx, - // Extended free function. - FreeSsdtSerialPortTableEx -}; - -/** Register the Generator with the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is registered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_ALREADY_STARTED The Generator for the Table ID - is already registered. -**/ -EFI_STATUS -EFIAPI -AcpiSsdtSerialPortLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = RegisterAcpiTableGenerator (&SsdtSerialPortGenerator); - DEBUG (( - DEBUG_INFO, - "SSDT-SERIAL-PORT: Register Generator. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - - return Status; -} - -/** Deregister the Generator from the ACPI Table Factory. - - @param [in] ImageHandle The handle to the image. - @param [in] SystemTable Pointer to the System Table. - - @retval EFI_SUCCESS The Generator is deregistered. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The Generator is not registered. -**/ -EFI_STATUS -EFIAPI -AcpiSsdtSerialPortLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = DeregisterAcpiTableGenerator (&SsdtSerialPortGenerator); - DEBUG (( - DEBUG_INFO, - "SSDT-SERIAL-PORT: Deregister Generator. Status = %r\n", - Status - )); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf deleted file mode 100644 index 36e61ea9b1..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf +++ /dev/null @@ -1,33 +0,0 @@ -## @file -# Ssdt Serial Port Table Generator -# -# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x0001001B - BASE_NAME = SsdtSerialPortLibArm - FILE_GUID = D1F92325-2DFB-435C-9B4C-A6B864F19230 - VERSION_STRING = 1.0 - MODULE_TYPE = DXE_DRIVER - LIBRARY_CLASS = NULL|DXE_DRIVER - CONSTRUCTOR = AcpiSsdtSerialPortLibConstructor - DESTRUCTOR = AcpiSsdtSerialPortLibDestructor - -[Sources] - SsdtSerialPortGenerator.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - DynamicTablesPkg/DynamicTablesPkg.dec - -[LibraryClasses] - AcpiHelperLib - AmlLib - BaseLib - SsdtSerialPortFixupLib diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf new file mode 100644 index 0000000000..f7b7c1c025 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf @@ -0,0 +1,43 @@ +## @file +# DBG2 Table Generator +# +# Copyright (c) 2017 - 2020, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = AcpiDbg2LibArm + FILE_GUID = A17BA4F0-3DEB-4FE5-BD27-EC008E541B22 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiDbg2LibConstructor + DESTRUCTOR = AcpiDbg2LibDestructor + +[Sources] + Dbg2Generator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + PL011UartLib + SsdtSerialPortFixupLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c new file mode 100644 index 0000000000..fbf2ba3733 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c @@ -0,0 +1,587 @@ +/** @file + DBG2 Table Generator + + Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015. + +**/ + +#include +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include + +/** ARM standard DBG2 Table Generator + + Constructs the DBG2 table for PL011 or SBSA UART peripherals. + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjSerialDebugPortInfo +*/ + +#pragma pack(1) + +/** The number of debug ports represented by the Table. +*/ +#define DBG2_NUM_DEBUG_PORTS 1 + +/** The number of Generic Address Registers + presented in the debug device information. +*/ +#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS 1 + +/** The index for the debug port 0 in the Debug port information list. +*/ +#define INDEX_DBG_PORT0 0 + +/** A string representing the name of the debug port 0. +*/ +#define NAME_STR_DBG_PORT0 "COM0" + +/** A string representing the full path name of the debug port 0. +*/ +#define NAMESPACE_STR_DBG_PORT0 "\\_SB_.COM0" + +/** An UID representing the debug port 0. +*/ +#define UID_DBG_PORT0 0 + +/** The length of the namespace string. +*/ +#define DBG2_NAMESPACESTRING_FIELD_SIZE sizeof (NAMESPACE_STR_DBG_PORT0) + +/** The PL011 UART address range length. +*/ +#define PL011_UART_LENGTH 0x1000 + +/** A structure that provides the OS with the required information + for initializing a debugger connection. +*/ +typedef struct { + /// The debug device information for the platform + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device; + + /// The base address register for the serial port + EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister; + + /// The address size + UINT32 AddressSize; + + /// The debug port name string + UINT8 NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE]; +} DBG2_DEBUG_DEVICE_INFORMATION; + +/** A structure representing the information about the debug port(s) + available on the platform. +*/ +typedef struct { + /// The DBG2 table header + EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE Description; + + /// Debug port information list + DBG2_DEBUG_DEVICE_INFORMATION Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS]; +} DBG2_TABLE; + +/** A helper macro used for initializing the debug port device + information structure. + + @param [in] SubType The DBG Port SubType. + @param [in] UartBase The UART port base address. + @param [in] UartAddrLen The UART port address range length. + @param [in] UartNameStr The UART port name string. +**/ +#define DBG2_DEBUG_PORT_DDI( \ + SubType, \ + UartBase, \ + UartAddrLen, \ + UartNameStr \ + ) {\ + { \ + /* UINT8 Revision */ \ + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, \ + /* UINT16 Length */ \ + sizeof (DBG2_DEBUG_DEVICE_INFORMATION), \ + /* UINT8 NumberofGenericAddressRegisters */ \ + DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS, \ + /* UINT16 NameSpaceStringLength */ \ + DBG2_NAMESPACESTRING_FIELD_SIZE, \ + /* UINT16 NameSpaceStringOffset */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), \ + /* UINT16 OemDataLength */ \ + 0, \ + /* UINT16 OemDataOffset */ \ + 0, \ + /* UINT16 Port Type */ \ + EFI_ACPI_DBG2_PORT_TYPE_SERIAL, \ + /* UINT16 Port Subtype */ \ + SubType, \ + /* UINT8 Reserved[2] */ \ + {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, \ + /* UINT16 BaseAddressRegister Offset */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), \ + /* UINT16 AddressSize Offset */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) \ + }, \ + /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \ + ARM_GAS32 (UartBase), \ + /* UINT32 AddressSize */ \ + UartAddrLen, \ + /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \ + UartNameStr \ + } + +/** The DBG2 Table template definition. + + Note: fields marked with "{Template}" will be set dynamically +*/ +STATIC +DBG2_TABLE AcpiDbg2 = { + { + ACPI_HEADER ( + EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, + DBG2_TABLE, + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION + ), + OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo), + DBG2_NUM_DEBUG_PORTS + }, + { + /* + * Debug port 1 + */ + DBG2_DEBUG_PORT_DDI ( + 0, // {Template}: Serial Port Subtype + 0, // {Template}: Serial Port Base Address + PL011_UART_LENGTH, + NAMESPACE_STR_DBG_PORT0 + ) + } +}; + +#pragma pack() + +/** This macro expands to a function that retrieves the Serial + debug port information from the Configuration Manager +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjSerialDebugPortInfo, + CM_ARCH_COMMON_SERIAL_PORT_INFO + ); + +/** Initialize the PL011/SBSA UART with the parameters obtained from + the Configuration Manager. + + @param [in] SerialPortInfo Pointer to the Serial Port Information. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER The parameters for serial port initialization + are invalid. +**/ +STATIC +EFI_STATUS +SetupDebugUart ( + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *CONST SerialPortInfo + ) +{ + EFI_STATUS Status; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + EFI_PARITY_TYPE Parity; + UINT8 DataBits; + EFI_STOP_BITS_TYPE StopBits; + + ASSERT (SerialPortInfo != NULL); + + // Initialize the Serial Debug UART + DEBUG ((DEBUG_INFO, "Initializing Serial Debug UART...\n")); + ReceiveFifoDepth = 0; // Use the default value for FIFO depth + Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); + DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); + StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); + + BaudRate = SerialPortInfo->BaudRate; + Status = PL011UartInitializePort ( + (UINTN)SerialPortInfo->BaseAddress, + SerialPortInfo->Clock, + &BaudRate, + &ReceiveFifoDepth, + &Parity, + &DataBits, + &StopBits + ); + + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Free any resources allocated for constructing the tables. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to ACPI Table(s). + @param [in] TableCount Number of ACPI table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeDbg2TableEx ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, + IN CONST UINTN TableCount + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || + (*Table == NULL) || + (TableCount != 2)) + { + DEBUG ((DEBUG_ERROR, "ERROR: DBG2: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + TableList = *Table; + + if ((TableList[1] == NULL) || + (TableList[1]->Signature != + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) + { + DEBUG ((DEBUG_ERROR, "ERROR: DBG2: Invalid SSDT table pointer.\n")); + return EFI_INVALID_PARAMETER; + } + + // Only need to free the SSDT table at index 1. The DBG2 table is static. + Status = FreeSsdtSerialPortTable (TableList[1]); + ASSERT_EFI_ERROR (Status); + + // Free the table list. + FreePool (*Table); + + return Status; +} + +/** Construct the DBG2 ACPI table and its associated SSDT table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResourcesEx function. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to a list of generated ACPI table(s). + @param [out] TableCount Number of generated ACPI table(s). + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Could not find information. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. + @retval EFI_UNSUPPORTED Unsupported configuration. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildDbg2TableEx ( + IN CONST ACPI_TABLE_GENERATOR *This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, + OUT UINTN *CONST TableCount + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 SerialPortCount; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + + Status = GetEArchCommonObjSerialDebugPortInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SerialPortInfo, + &SerialPortCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Failed to get serial port information. Status = %r\n", + Status + )); + return Status; + } + + if (SerialPortCount == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Serial port information not found. Status = %r\n", + EFI_NOT_FOUND + )); + return EFI_NOT_FOUND; + } + + // Only use the first DBG2 port information. + Status = ValidateSerialPortInfo (SerialPortInfo, 1); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Invalid serial port information. Status = %r\n", + Status + )); + return Status; + } + + // Allocate a table to store pointers to the DBG2 and SSDT tables. + TableList = (EFI_ACPI_DESCRIPTION_HEADER **) + AllocateZeroPool (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * 2); + if (TableList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Failed to allocate memory for Table List," \ + " Status = %r\n", + Status + )); + return Status; + } + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiDbg2, + AcpiTableInfo, + sizeof (DBG2_TABLE) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Update the base address + AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].BaseAddressRegister.Address = + SerialPortInfo->BaseAddress; + + // Set the access size + if (SerialPortInfo->AccessSize >= EFI_ACPI_6_3_QWORD) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Access size must be <= 3 (DWORD). Status = %r\n", + Status + )); + goto error_handler; + } else if (SerialPortInfo->AccessSize == EFI_ACPI_6_3_UNDEFINED) { + // 0 Undefined (legacy reasons) + // Default to DWORD access size as the access + // size field was introduced at a later date + // and some ConfigurationManager implementations + // may not be providing this field data + AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].BaseAddressRegister.AccessSize = + EFI_ACPI_6_3_DWORD; + } else { + AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].BaseAddressRegister.AccessSize = + SerialPortInfo->AccessSize; + } + + // Update the serial port subtype + AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].Dbg2Device.PortSubtype = + SerialPortInfo->PortSubtype; + + if ((SerialPortInfo->PortSubtype == + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) || + (SerialPortInfo->PortSubtype == + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) || + (SerialPortInfo->PortSubtype == + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART)) + { + // Initialize the serial port + Status = SetupDebugUart (SerialPortInfo); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Failed to configure debug serial port. Status = %r\n", + Status + )); + goto error_handler; + } + } + + TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiDbg2; + + // Build a SSDT table describing the serial port. + Status = BuildSsdtSerialPortTable ( + AcpiTableInfo, + SerialPortInfo, + NAME_STR_DBG_PORT0, + UID_DBG_PORT0, + &TableList[1] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: DBG2: Failed to build associated SSDT table. Status = %r\n", + Status + )); + goto error_handler; + } + + *TableCount = 2; + *Table = TableList; + + return Status; + +error_handler: + if (TableList != NULL) { + FreePool (TableList); + } + + return Status; +} + +/** This macro defines the DBG2 Table Generator revision. +*/ +#define DBG2_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the DBG2 Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR Dbg2Generator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2), + // Generator Description + L"ACPI.STD.DBG2.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + DBG2_GENERATOR_REVISION, + // Build table function. Use the extended version instead. + NULL, + // Free table function. Use the extended version instead. + NULL, + // Extended Build table function. + BuildDbg2TableEx, + // Extended free function. + FreeDbg2TableEx +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiDbg2LibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&Dbg2Generator); + DEBUG ((DEBUG_INFO, "DBG2: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiDbg2LibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&Dbg2Generator); + DEBUG ((DEBUG_INFO, "DBG2: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf new file mode 100644 index 0000000000..8fe34013d4 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf @@ -0,0 +1,36 @@ +## @file +# FADT Table Generator +# +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = AcpiFadtLibArm + FILE_GUID = 686FE5FE-B944-485F-8B1C-7D60E0056487 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiFadtLibConstructor + DESTRUCTOR = AcpiFadtLibDestructor + +[Sources] + FadtGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + +[Pcd] + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c new file mode 100644 index 0000000000..470f1acfd1 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c @@ -0,0 +1,713 @@ +/** @file + FADT Table Generator + + Copyright (c) 2017 - 2023, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification, Aug 29, 2022 + +**/ + +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +/** ARM standard FADT Generator + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjPowerManagementProfileInfo + - EArmObjBootArchInfo + - EArchCommonObjHypervisorVendorIdentity (OPTIONAL) +*/ + +/** This macro defines the FADT flag options for ARM Platforms. +*/ +#define FADT_FLAGS (EFI_ACPI_6_5_HW_REDUCED_ACPI | \ + EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE) + +/** This macro defines the valid mask for the FADT flag option + if HW_REDUCED_ACPI flag in the table is set. + + Invalid bits are: 1, 2, 3,7, 8, 13, 14,16, 17 and + 22-31 (reserved). + + Valid bits are: + EFI_ACPI_6_5_WBINVD BIT0 + EFI_ACPI_6_5_PWR_BUTTON BIT4 + EFI_ACPI_6_5_SLP_BUTTON BIT5 + EFI_ACPI_6_5_FIX_RTC BIT6 + EFI_ACPI_6_5_DCK_CAP BIT9 + EFI_ACPI_6_5_RESET_REG_SUP BIT10 + EFI_ACPI_6_5_SEALED_CASE BIT11 + EFI_ACPI_6_5_HEADLESS BIT12 + EFI_ACPI_6_5_USE_PLATFORM_CLOCK BIT15 + EFI_ACPI_6_5_FORCE_APIC_CLUSTER_MODEL BIT18 + EFI_ACPI_6_5_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 + EFI_ACPI_6_5_HW_REDUCED_ACPI BIT20 + EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE BIT21 +*/ +#define VALID_HARDWARE_REDUCED_FLAG_MASK ( \ + EFI_ACPI_6_5_WBINVD | \ + EFI_ACPI_6_5_PWR_BUTTON | \ + EFI_ACPI_6_5_SLP_BUTTON | \ + EFI_ACPI_6_5_FIX_RTC | \ + EFI_ACPI_6_5_DCK_CAP | \ + EFI_ACPI_6_5_RESET_REG_SUP | \ + EFI_ACPI_6_5_SEALED_CASE | \ + EFI_ACPI_6_5_HEADLESS | \ + EFI_ACPI_6_5_USE_PLATFORM_CLOCK | \ + EFI_ACPI_6_5_FORCE_APIC_CLUSTER_MODEL | \ + EFI_ACPI_6_5_FORCE_APIC_PHYSICAL_DESTINATION_MODE | \ + EFI_ACPI_6_5_HW_REDUCED_ACPI | \ + EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE) + +#pragma pack(1) + +/** The AcpiFadt is a template EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE + structure used for generating the FADT Table. + Note: fields marked with "{Template}" will be updated dynamically. +*/ +STATIC +EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = { + ACPI_HEADER ( + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE, + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_REVISION + ), + // UINT32 FirmwareCtrl + 0, + // UINT32 Dsdt + 0, + // UINT8 Reserved0 + EFI_ACPI_RESERVED_BYTE, + // UINT8 PreferredPmProfile + EFI_ACPI_6_5_PM_PROFILE_UNSPECIFIED, // {Template}: Power Management Profile + // UINT16 SciInt + 0, + // UINT32 SmiCmd + 0, + // UINT8 AcpiEnable + 0, + // UINT8 AcpiDisable + 0, + // UINT8 S4BiosReq + 0, + // UINT8 PstateCnt + 0, + // UINT32 Pm1aEvtBlk + 0, + // UINT32 Pm1bEvtBlk + 0, + // UINT32 Pm1aCntBlk + 0, + // UINT32 Pm1bCntBlk + 0, + // UINT32 Pm2CntBlk + 0, + // UINT32 PmTmrBlk + 0, + // UINT32 Gpe0Blk + 0, + // UINT32 Gpe1Blk + 0, + // UINT8 Pm1EvtLen + 0, + // UINT8 Pm1CntLen + 0, + // UINT8 Pm2CntLen + 0, + // UINT8 PmTmrLen + 0, + // UINT8 Gpe0BlkLen + 0, + // UINT8 Gpe1BlkLen + 0, + // UINT8 Gpe1Base + 0, + // UINT8 CstCnt + 0, + // UINT16 PLvl2Lat + 0, + // UINT16 PLvl3Lat + 0, + // UINT16 FlushSize + 0, + // UINT16 FlushStride + 0, + // UINT8 DutyOffset + 0, + // UINT8 DutyWidth + 0, + // UINT8 DayAlrm + 0, + // UINT8 MonAlrm + 0, + // UINT8 Century + 0, + // UINT16 IaPcBootArch + 0, + // UINT8 Reserved1 + 0, + // UINT32 Flags + FADT_FLAGS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg + NULL_GAS, + // UINT8 ResetValue + 0, + // UINT16 ArmBootArch + EFI_ACPI_6_5_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags + // UINT8 MinorRevision + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, // {Template} + // UINT64 XFirmwareCtrl + 0, + // UINT64 XDsdt + 0, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe0Blk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe1Blk + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepControlReg + NULL_GAS, + // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepStatusReg + NULL_GAS, + // UINT64 HypervisorVendorIdentity + EFI_ACPI_RESERVED_QWORD // {Template}: Hypervisor Vendor ID +}; + +#pragma pack() + +/** This macro expands to a function that retrieves the Power + Management Profile Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPowerManagementProfileInfo, + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO + ); + +/** This macro expands to a function that retrieves the Boot + Architecture Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjBootArchInfo, + CM_ARM_BOOT_ARCH_INFO + ); + +/** This macro expands to a function that retrieves the Hypervisor + Vendor ID from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjHypervisorVendorIdentity, + CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID + ); + +/** This macro expands to a function that retrieves the Fixed + feature flags for the platform from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjFixedFeatureFlags, + CM_ARCH_COMMON_FIXED_FEATURE_FLAGS + ); + +/** Update the Power Management Profile information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +FadtAddPmProfileInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO *PmProfile; + + ASSERT (CfgMgrProtocol != NULL); + + // Get the Power Management Profile from the Platform Configuration Manager + Status = GetEArchCommonObjPowerManagementProfileInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PmProfile, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Power Management Profile information." \ + " Status = %r\n", + Status + )); + goto error_handler; + } + + DEBUG (( + DEBUG_INFO, + "FADT: PreferredPmProfile = 0x%x\n", + PmProfile->PowerManagementProfile + )); + + AcpiFadt.PreferredPmProfile = PmProfile->PowerManagementProfile; + +error_handler: + return Status; +} + +/** Updates the Boot Architecture information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +FadtAddBootArchInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + CM_ARM_BOOT_ARCH_INFO *BootArchInfo; + + ASSERT (CfgMgrProtocol != NULL); + + // Get the Boot Architecture flags from the Platform Configuration Manager + Status = GetEArmObjBootArchInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &BootArchInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n", + Status + )); + goto error_handler; + } + + DEBUG (( + DEBUG_INFO, + "FADT BootArchFlag = 0x%x\n", + BootArchInfo->BootArchFlags + )); + + AcpiFadt.ArmBootArch = BootArchInfo->BootArchFlags; + +error_handler: + return Status; +} + +/** Update the Hypervisor Vendor ID in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +FadtAddHypervisorVendorId ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID *HypervisorVendorInfo; + + ASSERT (CfgMgrProtocol != NULL); + + // Get the Hypervisor Vendor ID from the Platform Configuration Manager + Status = GetEArchCommonObjHypervisorVendorIdentity ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &HypervisorVendorInfo, + NULL + ); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "INFO: FADT: Platform does not have a Hypervisor Vendor ID." + "Status = %r\n", + Status + )); + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Hypervisor Vendor ID. Status = %r\n", + Status + )); + } + + goto error_handler; + } + + DEBUG (( + DEBUG_INFO, + "FADT: EArchCommonObjHypervisorVendorIdentity = 0x%lx\n", + HypervisorVendorInfo->HypervisorVendorId + )); + + AcpiFadt.HypervisorVendorIdentity = HypervisorVendorInfo->HypervisorVendorId; + +error_handler: + return Status; +} + +/** Update the Fixed Feature Flags in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +FadtAddFixedFeatureFlags ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_FIXED_FEATURE_FLAGS *FixedFeatureFlags; + + ASSERT (CfgMgrProtocol != NULL); + + // Get the Fixed feature flags from the Platform Configuration Manager + Status = GetEArchCommonObjFixedFeatureFlags ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &FixedFeatureFlags, + NULL + ); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "INFO: FADT: Platform does not define additional Fixed feature flags." + "Status = %r\n", + Status + )); + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Fixed feature flags. Status = %r\n", + Status + )); + } + + goto error_handler; + } + + DEBUG (( + DEBUG_INFO, + "FADT: EArchCommonObjFixedFeatureFlags = 0x%x\n", + FixedFeatureFlags->Flags + )); + + if ((FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) != 0) { + DEBUG (( + DEBUG_WARN, + "FADT: Invalid Fixed feature flags defined by platform," + "Invalid Flags bits are = 0x%x\n", + (FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) + )); + } + + AcpiFadt.Flags |= (FixedFeatureFlags->Flags & + VALID_HARDWARE_REDUCED_FLAG_MASK); + +error_handler: + return Status; +} + +/** Construct the FADT table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildFadtTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiFadt, + AcpiTableInfo, + sizeof (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Update the MinorRevision for the FADT table if it has been specified + // otherwise default to the latest FADT minor revision supported. + // Note: + // Bits 0-3 - The low order bits correspond to the minor version of the + // specification version. + // Bits 4-7 - The high order bits correspond to the version of the ACPI + // specification errata. + if (AcpiTableInfo->MinorRevision != 0) { + if (((AcpiTableInfo->MinorRevision & 0xF) >= + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION) && + ((AcpiTableInfo->MinorRevision & 0xF) <= + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION)) + { + AcpiFadt.MinorVersion = AcpiTableInfo->MinorRevision; + } else { + DEBUG (( + DEBUG_WARN, + "WARNING: FADT: Unsupported FADT Minor Revision 0x%x specified, " \ + "defaulting to FADT Minor Revision 0x%x\n", + AcpiTableInfo->MinorRevision, + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION + )); + } + } + + // Update PmProfile Info + Status = FadtAddPmProfileInfo (CfgMgrProtocol); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Update BootArch Info + Status = FadtAddBootArchInfo (CfgMgrProtocol); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Add the Hypervisor Vendor Id if present + // Note if no hypervisor is present the zero bytes + // will be placed in this field. + Status = FadtAddHypervisorVendorId (CfgMgrProtocol); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "INFO: FADT: No Hypervisor Vendor ID found," \ + " assuming no Hypervisor is present in the firmware.\n" + )); + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Error reading Hypervisor Vendor ID, Status = %r", + Status + )); + goto error_handler; + } + } + + Status = FadtAddFixedFeatureFlags (CfgMgrProtocol); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "INFO: FADT: No Fixed feature flags found," \ + " assuming no additional flags are defined for the platform.\n" + )); + Status = EFI_SUCCESS; + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Error reading Fixed feature flags, Status = %r", + Status + )); + goto error_handler; + } + } + + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiFadt; +error_handler: + return Status; +} + +/** This macro defines the FADT Table Generator revision. +*/ +#define FADT_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the FADT Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR FadtGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt), + // Generator Description + L"ACPI.STD.FADT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + FADT_GENERATOR_REVISION, + // Build Table function + BuildFadtTable, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiFadtLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&FadtGenerator); + DEBUG ((DEBUG_INFO, "FADT: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiFadtLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&FadtGenerator); + DEBUG ((DEBUG_INFO, "FADT: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf new file mode 100644 index 0000000000..1c7f085274 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf @@ -0,0 +1,36 @@ +## @file +# MCFG Table Generator +# +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = AcpiMcfgLibArm + FILE_GUID = 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiMcfgLibConstructor + DESTRUCTOR = AcpiMcfgLibDestructor + +[Sources] + McfgGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + +[Pcd] + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c new file mode 100644 index 0000000000..722f9c17d5 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c @@ -0,0 +1,369 @@ +/** @file + MCFG Table Generator + + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - PCI Firmware Specification - Revision 3.2, January 26, 2015. + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +/** ARM standard MCFG Generator + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjPciConfigSpaceInfo +*/ + +#pragma pack(1) + +/** This typedef is used to shorten the name of the MCFG Table + header structure. +*/ +typedef + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER + MCFG_TABLE; + +/** This typedef is used to shorten the name of the Enhanced + Configuration Space address structure. +*/ +typedef + EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE + MCFG_CFG_SPACE_ADDR; + +#pragma pack() + +/** Retrieve the PCI Configuration Space Information. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPciConfigSpaceInfo, + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO + ); + +/** Add the PCI Enhanced Configuration Space Information to the MCFG Table. + + @param [in] Mcfg Pointer to MCFG Table. + @param [in] PciCfgSpaceOffset Offset for the PCI Configuration Space + Info structure in the MCFG Table. + @param [in] PciCfgSpaceInfoList Pointer to the PCI Configuration Space + Info List. + @param [in] PciCfgSpaceCount Count of PCI Configuration Space Info. +**/ +STATIC +VOID +AddPciConfigurationSpaceList ( + IN MCFG_TABLE *CONST Mcfg, + IN CONST UINT32 PciCfgSpaceOffset, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciCfgSpaceInfoList, + IN UINT32 PciCfgSpaceCount + ) +{ + MCFG_CFG_SPACE_ADDR *PciCfgSpace; + + ASSERT (Mcfg != NULL); + ASSERT (PciCfgSpaceInfoList != NULL); + + PciCfgSpace = (MCFG_CFG_SPACE_ADDR *)((UINT8 *)Mcfg + PciCfgSpaceOffset); + + while (PciCfgSpaceCount-- != 0) { + // Add PCI Configuration Space entry + PciCfgSpace->BaseAddress = PciCfgSpaceInfoList->BaseAddress; + PciCfgSpace->PciSegmentGroupNumber = + PciCfgSpaceInfoList->PciSegmentGroupNumber; + PciCfgSpace->StartBusNumber = PciCfgSpaceInfoList->StartBusNumber; + PciCfgSpace->EndBusNumber = PciCfgSpaceInfoList->EndBusNumber; + PciCfgSpace->Reserved = EFI_ACPI_RESERVED_DWORD; + PciCfgSpace++; + PciCfgSpaceInfoList++; + } +} + +/** Construct the MCFG ACPI table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildMcfgTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + UINT32 TableSize; + UINT32 ConfigurationSpaceCount; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfoList; + MCFG_TABLE *Mcfg; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: MCFG: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + Status = GetEArchCommonObjPciConfigSpaceInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PciConfigSpaceInfoList, + &ConfigurationSpaceCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MCFG: Failed to get PCI Configuration Space Information." \ + " Status = %r\n", + Status + )); + goto error_handler; + } + + if (ConfigurationSpaceCount == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MCFG: Configuration Space Count = %d\n", + ConfigurationSpaceCount + )); + Status = EFI_INVALID_PARAMETER; + ASSERT (ConfigurationSpaceCount != 0); + goto error_handler; + } + + DEBUG (( + DEBUG_INFO, + "MCFG: Configuration Space Count = %d\n", + ConfigurationSpaceCount + )); + + // Calculate the MCFG Table Size + TableSize = sizeof (MCFG_TABLE) + + ((sizeof (MCFG_CFG_SPACE_ADDR) * ConfigurationSpaceCount)); + + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: MCFG: Failed to allocate memory for MCFG Table, Size = %d," \ + " Status = %r\n", + TableSize, + Status + )); + goto error_handler; + } + + Mcfg = (MCFG_TABLE *)*Table; + DEBUG (( + DEBUG_INFO, + "MCFG: Mcfg = 0x%p TableSize = 0x%x\n", + Mcfg, + TableSize + )); + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + &Mcfg->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MCFG: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + Mcfg->Reserved = EFI_ACPI_RESERVED_QWORD; + + AddPciConfigurationSpaceList ( + Mcfg, + sizeof (MCFG_TABLE), + PciConfigSpaceInfoList, + ConfigurationSpaceCount + ); + + return EFI_SUCCESS; + +error_handler: + if (*Table != NULL) { + FreePool (*Table); + *Table = NULL; + } + + return Status; +} + +/** Free any resources allocated for constructing the MCFG + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +FreeMcfgTableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: MCFG: Invalid Table Pointer\n")); + ASSERT ((Table != NULL) && (*Table != NULL)); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** This macro defines the MCFG Table Generator revision. +*/ +#define MCFG_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the MCFG Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR McfgGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg), + // Generator Description + L"ACPI.STD.MCFG.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + MCFG_GENERATOR_REVISION, + // Build Table function + BuildMcfgTable, + // Free Resource function + FreeMcfgTableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiMcfgLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&McfgGenerator); + DEBUG ((DEBUG_INFO, "MCFG: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiMcfgLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&McfgGenerator); + DEBUG ((DEBUG_INFO, "MCFG: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf new file mode 100644 index 0000000000..da54585c2d --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf @@ -0,0 +1,30 @@ +## @file +# Pcct Table Generator +# +# Copyright (c) 2022, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = AcpiPcctLibArm + FILE_GUID = 38FE945C-D6ED-4CD6-8D20-FCEF3260D15A + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiPcctLibConstructor + DESTRUCTOR = AcpiPcctLibDestructor + +[Sources] + PcctGenerator.c + PcctGenerator.h + +[Packages] + DynamicTablesPkg/DynamicTablesPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c new file mode 100644 index 0000000000..205c444057 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c @@ -0,0 +1,1188 @@ +/** @file + PCCT Table Generator + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification - January 2021 + s14 PLATFORM COMMUNICATIONS CHANNEL (PCC) + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include "PcctGenerator.h" + +/** ARM standard PCCT Generator + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjPccSubspaceType0Info + - EArchCommonObjPccSubspaceType1Info + - EArchCommonObjPccSubspaceType2Info + - EArchCommonObjPccSubspaceType3Info + - EArchCommonObjPccSubspaceType4Info + - EArchCommonObjPccSubspaceType5Info +*/ + +/** This macro expands to a function that retrieves the PCC + Subspace of Type 0 Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType0Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO + ); + +/** This macro expands to a function that retrieves the PCC + Subspace of Type 1 Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType1Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO + ); + +/** This macro expands to a function that retrieves the PCC + Subspace of Type 2 Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType2Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO + ); + +/** This macro expands to a function that retrieves the PCC + Subspace of Type 3 Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType3Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO + ); + +/** This macro expands to a function that retrieves the PCC + Subspace of Type 4 Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType4Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO + ); + +/** This macro expands to a function that retrieves the PCC + Subspace of Type 5 Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPccSubspaceType5Info, + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO + ); + +/** The Platform is capable of generating an interrupt + to indicate completion of a command. + + Cf: s14.1.1 Platform Communications Channel Global Flags + Platform Interrupt flag + and s14.1.6 Extended PCC subspaces (types 3 and 4) + If a responder subspace is included in the PCCT, + then the global Platform Interrupt flag must be set to 1 + + Set this variable and populate the PCCT flag accordingly if either: + - One of the PCCT Subspace uses interrupts. + - A PCC Subspace of type 4 is used. +*/ +STATIC BOOLEAN mHasPlatformInterrupt; + +/** Initialize the MappingTable. + + @param [in] MappingTable The mapping table structure. + @param [in] Count Number of entries to allocate in the + MappingTable. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +MappingTableInitialize ( + IN MAPPING_TABLE *MappingTable, + IN UINT32 Count + ) +{ + VOID **Table; + + if ((MappingTable == NULL) || + (Count == 0)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Table = AllocateZeroPool (sizeof (*Table) * Count); + if (Table == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + MappingTable->Table = Table; + MappingTable->MaxIndex = Count; + + return EFI_SUCCESS; +} + +/** Free the MappingTable. + + @param [in, out] MappingTable The mapping table structure. +**/ +STATIC +VOID +EFIAPI +MappingTableFree ( + IN OUT MAPPING_TABLE *MappingTable + ) +{ + ASSERT (MappingTable != NULL); + ASSERT (MappingTable->Table != NULL); + + if (MappingTable->Table != NULL) { + FreePool (MappingTable->Table); + } +} + +/** Add a new entry for PccSubspace at Index. + + @param [in] MappingTable The mapping table structure. + @param [in] PccSubspace A pointer to + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO. + @param [in] Index Index at which PccSubspace must be added. + This is the Subspace Id. + + @retval EFI_SUCCESS Success. + @retval EFI_BUFFER_TOO_SMALL Buffer too small. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +MappingTableAdd ( + IN MAPPING_TABLE *MappingTable, + IN VOID *PccSubspace, + IN UINT32 Index + ) +{ + if ((MappingTable == NULL) || + (MappingTable->Table == NULL) || + (PccSubspace == NULL)) + { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + if ((Index >= MappingTable->MaxIndex) || + (MappingTable->Table[Index] != 0)) + { + ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL); + return EFI_BUFFER_TOO_SMALL; + } + + // Just map the Pcc Subspace in the Table. + MappingTable->Table[Index] = PccSubspace; + return EFI_SUCCESS; +} + +/** Parse the CmPccArray objects and add them to the MappingTable. + + @param [in] MappingTable The mapping table structure. + @param [in] CmPccArray Pointer to an array of + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO. + @param [in] CmPccCount Count of objects in CmPccArray. + + @retval EFI_SUCCESS Success. + @retval EFI_BUFFER_TOO_SMALL Buffer too small. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +MapPccSubspaceId ( + IN MAPPING_TABLE *MappingTable, + IN VOID *CmPccArray, + IN UINT32 CmPccCount + ) +{ + EFI_STATUS Status; + UINT8 *PccBuffer; + UINT32 Index; + UINT32 CmObjSize; + PCC_SUBSPACE_GENERIC_INFO *GenericPcc; + + if (CmPccCount == 0) { + return EFI_SUCCESS; + } + + if ((CmPccArray == NULL) || (MappingTable == NULL)) { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)CmPccArray; + + switch (GenericPcc->Type) { + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: + CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO); + break; + + default: + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + PccBuffer = (UINT8 *)CmPccArray; + + // Map the Pcc channel to their Subspace Id. + for (Index = 0; Index < CmPccCount; Index++) { + GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)PccBuffer; + + Status = MappingTableAdd ( + MappingTable, + PccBuffer, + GenericPcc->SubspaceId + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + PccBuffer += CmObjSize; + } + + return EFI_SUCCESS; +} + +/** Add one PCCT Subspace structure of Type 0 (Generic). + + @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. + @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +AddSubspaceStructType0 ( + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccCmObj, + IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi + ) +{ + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + + if ((PccCmObj == NULL) || + (PccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC) || + (PccAcpi == NULL)) + { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + Doorbell = &PccCmObj->DoorbellReg; + ChannelTiming = &PccCmObj->ChannelTiming; + + PccAcpi->Type = PccCmObj->Type; + PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC); + *(UINT32 *)&PccAcpi->Reserved[0] = EFI_ACPI_RESERVED_DWORD; + *(UINT16 *)&PccAcpi->Reserved[4] = EFI_ACPI_RESERVED_WORD; + PccAcpi->BaseAddress = PccCmObj->BaseAddress; + PccAcpi->AddressLength = PccCmObj->AddressLength; + + CopyMem ( + &PccAcpi->DoorbellRegister, + &Doorbell->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; + PccAcpi->DoorbellWrite = Doorbell->WriteMask; + + PccAcpi->NominalLatency = ChannelTiming->NominalLatency; + PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; + PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; + + return EFI_SUCCESS; +} + +/** Add one PCCT subspace structure of Type 1 (HW-Reduced). + + @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. + @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +AddSubspaceStructType1 ( + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccCmObj, + IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi + ) +{ + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + + if ((PccCmObj == NULL) || + (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS) || + (PccAcpi == NULL)) + { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + Doorbell = &GenericPccCmObj->DoorbellReg; + ChannelTiming = &GenericPccCmObj->ChannelTiming; + + PccAcpi->Type = GenericPccCmObj->Type; + PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); + PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; + PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; + PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; + PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; + PccAcpi->AddressLength = GenericPccCmObj->AddressLength; + + CopyMem ( + &PccAcpi->DoorbellRegister, + &Doorbell->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; + PccAcpi->DoorbellWrite = Doorbell->WriteMask; + + PccAcpi->NominalLatency = ChannelTiming->NominalLatency; + PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; + PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; + + if ((PccCmObj->PlatIrq.Interrupt != 0)) { + mHasPlatformInterrupt = TRUE; + } + + return EFI_SUCCESS; +} + +/** Add one PCCT subspace structure of Type 2 (HW-Reduced). + + @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. + @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +AddSubspaceStructType2 ( + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccCmObj, + IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi + ) +{ + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + + if ((PccCmObj == NULL) || + (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS) || + (PccAcpi == NULL)) + { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + Doorbell = &GenericPccCmObj->DoorbellReg; + PlatIrqAck = &PccCmObj->PlatIrqAckReg; + ChannelTiming = &GenericPccCmObj->ChannelTiming; + + PccAcpi->Type = GenericPccCmObj->Type; + PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); + PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; + PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; + PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; + PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; + PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; + PccAcpi->AddressLength = GenericPccCmObj->AddressLength; + + CopyMem ( + &PccAcpi->DoorbellRegister, + &Doorbell->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; + PccAcpi->DoorbellWrite = Doorbell->WriteMask; + + PccAcpi->NominalLatency = ChannelTiming->NominalLatency; + PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; + PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; + + CopyMem ( + &PccAcpi->PlatformInterruptAckRegister, + &PlatIrqAck->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask; + PccAcpi->PlatformInterruptAckWrite = PlatIrqAck->WriteMask; + + if ((PccCmObj->PlatIrq.Interrupt != 0)) { + mHasPlatformInterrupt = TRUE; + } + + return EFI_SUCCESS; +} + +/** Add one PCCT subspace structure of Type 3 or 4 (Extended). + + @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. + @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +AddSubspaceStructType34 ( + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccCmObj, + IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi + ) +{ + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_MAILBOX_REGISTER_INFO *PlatIrqAck; + PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; + PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate; + PCC_MAILBOX_REGISTER_INFO *ErrorStatus; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + + if ((PccCmObj == NULL) || + ((GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC) && + (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC)) || + (PccAcpi == NULL)) + { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + Doorbell = &GenericPccCmObj->DoorbellReg; + PlatIrqAck = &PccCmObj->PlatIrqAckReg; + CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg; + CmdCompleteUpdate = &PccCmObj->CmdCompleteUpdateReg; + ErrorStatus = &PccCmObj->ErrorStatusReg; + ChannelTiming = &GenericPccCmObj->ChannelTiming; + + PccAcpi->Type = GenericPccCmObj->Type; + PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); + PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; + PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; + PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; + PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; + PccAcpi->AddressLength = GenericPccCmObj->AddressLength; + + CopyMem ( + &PccAcpi->DoorbellRegister, + &Doorbell->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; + PccAcpi->DoorbellWrite = Doorbell->WriteMask; + + PccAcpi->NominalLatency = ChannelTiming->NominalLatency; + PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate; + PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; + + CopyMem ( + &PccAcpi->PlatformInterruptAckRegister, + &PlatIrqAck->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask; + PccAcpi->PlatformInterruptAckSet = PlatIrqAck->WriteMask; + + PccAcpi->Reserved1[0] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[3] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[4] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[5] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[6] = EFI_ACPI_RESERVED_BYTE; + PccAcpi->Reserved1[7] = EFI_ACPI_RESERVED_BYTE; + + CopyMem ( + &PccAcpi->CommandCompleteCheckRegister, + &CmdCompleteCheck->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask; + // No Write mask. + + CopyMem ( + &PccAcpi->CommandCompleteUpdateRegister, + &CmdCompleteUpdate->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->CommandCompleteUpdatePreserve = CmdCompleteUpdate->PreserveMask; + PccAcpi->CommandCompleteUpdateSet = CmdCompleteUpdate->WriteMask; + + CopyMem ( + &PccAcpi->ErrorStatusRegister, + &ErrorStatus->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask; + // No Write mask. + + if (GenericPccCmObj->Type == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) { + mHasPlatformInterrupt = TRUE; + } else if ((PccCmObj->PlatIrq.Interrupt != 0)) { + mHasPlatformInterrupt = TRUE; + } + + return EFI_SUCCESS; +} + +/** Add one PCCT subspace structure of Type 5 (HW-Registers). + + @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure. + @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +AddSubspaceStructType5 ( + IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccCmObj, + IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi + ) +{ + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj; + PCC_MAILBOX_REGISTER_INFO *Doorbell; + PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck; + PCC_MAILBOX_REGISTER_INFO *ErrorStatus; + PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming; + + GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj; + + if ((PccCmObj == NULL) || + (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS) || + (PccAcpi == NULL)) + { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + Doorbell = &GenericPccCmObj->DoorbellReg; + CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg; + ErrorStatus = &PccCmObj->ErrorStatusReg; + ChannelTiming = &GenericPccCmObj->ChannelTiming; + + PccAcpi->Type = GenericPccCmObj->Type; + PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS); + PccAcpi->Version = PccCmObj->Version; + PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; + PccAcpi->SharedMemoryRangeLength = GenericPccCmObj->AddressLength; + + CopyMem ( + &PccAcpi->DoorbellRegister, + &Doorbell->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->DoorbellPreserve = Doorbell->PreserveMask; + PccAcpi->DoorbellWrite = Doorbell->WriteMask; + + CopyMem ( + &PccAcpi->CommandCompleteCheckRegister, + &CmdCompleteCheck->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask; + // No Write mask. + + CopyMem ( + &PccAcpi->ErrorStatusRegister, + &ErrorStatus->Register, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + ); + PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask; + // No Write mask. + + PccAcpi->NominalLatency = ChannelTiming->NominalLatency; + // No MaximumPeriodicAccessRate. + PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime; + + return EFI_SUCCESS; +} + +/** Populate the PCCT table using the MappingTable. + + @param [in] MappingTable The mapping table structure. + @param [in] Pcc Pointer to an array of Pcc Subpace structures. + @param [in] Size Size of the Pcc array. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BUFFER_TOO_SMALL Buffer too small. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +PopulatePcctTable ( + IN MAPPING_TABLE *MappingTable, + IN VOID *Pcc, + IN UINT32 Size + ) +{ + EFI_STATUS Status; + UINT8 *PccBuffer; + UINT32 CmObjSize; + UINT32 Index; + UINT32 MaxIndex; + VOID **Table; + VOID *CurrentPccSubspace; + + ASSERT (MappingTable != NULL); + ASSERT (MappingTable->Table != NULL); + + PccBuffer = Pcc; + MaxIndex = MappingTable->MaxIndex; + Table = MappingTable->Table; + + for (Index = 0; Index < MaxIndex; Index++) { + CurrentPccSubspace = Table[Index]; + if (CurrentPccSubspace == NULL) { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + switch (((PCC_SUBSPACE_GENERIC_INFO *)CurrentPccSubspace)->Type) { + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: + Status = AddSubspaceStructType0 ( + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace, + (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *)PccBuffer + ); + + CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: + Status = AddSubspaceStructType1 ( + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace, + (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *)PccBuffer + ); + + CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: + Status = AddSubspaceStructType2 ( + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace, + (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)PccBuffer + ); + + CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: + Status = AddSubspaceStructType34 ( + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace, + (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *)PccBuffer + ); + + CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: + Status = AddSubspaceStructType34 ( + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace, + (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC *)PccBuffer + ); + + CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC); + break; + + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: + Status = AddSubspaceStructType5 ( + (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace, + (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *)PccBuffer + ); + + CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS); + break; + + default: + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } // switch + + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + if (Size < CmObjSize) { + ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL); + return EFI_BUFFER_TOO_SMALL; + } + + PccBuffer += CmObjSize; + Size -= CmObjSize; + } // for + + return EFI_SUCCESS; +} + +/** Construct the PCCT ACPI table. + + Called by the Dynamic Table Manager, this function invokes the + Configuration Manager protocol interface to get the required hardware + information for generating the ACPI table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. + @retval EFI_BUFFER_TOO_SMALL Buffer too small. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildPcctTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + ACPI_PCCT_GENERATOR *Generator; + UINT32 TableSize; + EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *Pcct; + UINT8 *Buffer; + + MAPPING_TABLE *MappingTable; + UINT32 MappingTableCount; + + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccType0; + UINT32 PccType0Count; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccType1; + UINT32 PccType1Count; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccType2; + UINT32 PccType2Count; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccType3; + UINT32 PccType3Count; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *PccType4; + UINT32 PccType4Count; + CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccType5; + UINT32 PccType5Count; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: PCCT: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; + } + + Generator = (ACPI_PCCT_GENERATOR *)This; + MappingTable = &Generator->MappingTable; + *Table = NULL; + + // First get all the Pcc Subpace CmObj of type X. + + Status = GetEArchCommonObjPccSubspaceType0Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PccType0, + &PccType0Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = GetEArchCommonObjPccSubspaceType1Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PccType1, + &PccType1Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = GetEArchCommonObjPccSubspaceType2Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PccType2, + &PccType2Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = GetEArchCommonObjPccSubspaceType3Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PccType3, + &PccType3Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = GetEArchCommonObjPccSubspaceType4Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PccType4, + &PccType4Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = GetEArchCommonObjPccSubspaceType5Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PccType5, + &PccType5Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + // Count the number of Pcc Subspaces. + MappingTableCount = PccType0Count; + MappingTableCount += PccType1Count; + MappingTableCount += PccType2Count; + MappingTableCount += PccType3Count; + MappingTableCount += PccType4Count; + MappingTableCount += PccType5Count; + + Status = MappingTableInitialize (MappingTable, MappingTableCount); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + // Map the Subspace Ids for all types. + + Status = MapPccSubspaceId (MappingTable, PccType0, PccType0Count); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = MapPccSubspaceId (MappingTable, PccType1, PccType1Count); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = MapPccSubspaceId (MappingTable, PccType2, PccType2Count); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = MapPccSubspaceId (MappingTable, PccType3, PccType3Count); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = MapPccSubspaceId (MappingTable, PccType4, PccType4Count); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Status = MapPccSubspaceId (MappingTable, PccType5, PccType5Count); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + // Compute the size of the PCCT table. + TableSize = sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER); + TableSize += PccType0Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC); + TableSize += PccType1Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); + TableSize += PccType2Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); + TableSize += PccType3Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); + TableSize += PccType4Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC); + TableSize += PccType5Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS); + + // Allocate a Buffer for the PCCT table. + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table == NULL) { + Status = EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Pcct = (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *)*Table; + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + &Pcct->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PCCT: Failed to add ACPI header. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + Buffer = (UINT8 *)Pcct; + Buffer += sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER); + TableSize -= sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER); + + // Populate the PCCT table by following the Subspace Id mapping. + Status = PopulatePcctTable (MappingTable, Buffer, TableSize); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto error_handler; + } + + // Setup the Reserved fields once mHasPlatformInterrupt hase been populated. + Pcct->Flags = mHasPlatformInterrupt; + Pcct->Reserved = EFI_ACPI_RESERVED_QWORD; + + MappingTableFree (MappingTable); + + return Status; + +error_handler: + DEBUG (( + DEBUG_ERROR, + "ERROR: PCCT: Failed to install table. Status = %r\n", + Status + )); + + if (*Table != NULL) { + FreePool (*Table); + *Table = NULL; + } + + MappingTableFree (MappingTable); + + return Status; +} + +/** Free any resources allocated for constructing the PCCT. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +FreePcctTableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: PCCT: Invalid Table Pointer\n")); + ASSERT ((Table != NULL) && (*Table != NULL)); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** This macro defines the PCCT Table Generator revision. +*/ +#define PCCT_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the PCCT Table Generator. +*/ +STATIC +ACPI_PCCT_GENERATOR PcctGenerator = { + // ACPI table generator header + { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPcct), + // Generator Description + L"ACPI.STD.PCCT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION, + // Minimum ACPI Table Revision supported by this Generator + EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + PCCT_GENERATOR_REVISION, + // Build Table function + BuildPcctTable, + // Free Resource function + FreePcctTableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL + }, + + // Private fields are defined from here. + + // Mapping Table + { + // Table + NULL, + // MaxIndex + 0, + }, +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiPcctLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&PcctGenerator.Header); + DEBUG ((DEBUG_INFO, "PCCT: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiPcctLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&PcctGenerator.Header); + DEBUG ((DEBUG_INFO, "PCCT: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h new file mode 100644 index 0000000000..b99bf91b41 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h @@ -0,0 +1,44 @@ +/** @file + PCCT Table Generator + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification - January 2021 + s14 PLATFORM COMMUNICATIONS CHANNEL (PCC) + +**/ + +#ifndef PCCT_GENERATOR_H_ +#define PCCT_GENERATOR_H_ + +#pragma pack(1) + +/** Structure used to map a Pcc Subspace to an index. +*/ +typedef struct MappingTable { + /// Mapping table for Subspace Ids. + /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer + VOID **Table; + + /// Number of entries in the Table. + UINT32 MaxIndex; +} MAPPING_TABLE; + +/** A structure holding the Pcct generator and additional private data. +*/ +typedef struct AcpiPcctGenerator { + /// ACPI Table generator header + ACPI_TABLE_GENERATOR Header; + + // Private fields are defined from here. + + /// Table to map: + /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer + MAPPING_TABLE MappingTable; +} ACPI_PCCT_GENERATOR; + +#pragma pack() + +#endif // PCCT_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf new file mode 100644 index 0000000000..2c7d19513d --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf @@ -0,0 +1,30 @@ +## @file +# PPTT Table Generator +# +# Copyright (c) 2019, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = AcpiPpttLibArm + FILE_GUID = FA102D52-5A92-4F95-A097-1D53F9CF5959 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiPpttLibConstructor + DESTRUCTOR = AcpiPpttLibDestructor + +[Sources] + PpttGenerator.c + PpttGenerator.h + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c new file mode 100644 index 0000000000..2b8088a07f --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c @@ -0,0 +1,1480 @@ +/** @file + PPTT Table Generator + + Copyright (c) 2021, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification, January 2021 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +#include "PpttGenerator.h" + +/** + ARM standard PPTT Generator + + Requirements: + The following Configuration Manager Object(s) are used by this Generator: + - EArchCommonObjProcHierarchyInfo (REQUIRED) + - EArchCommonObjCacheInfo + - EArchCommonObjCmRef + - EArmObjGicCInfo (REQUIRED) +*/ + +/** + This macro expands to a function that retrieves the Processor Hierarchy + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjProcHierarchyInfo, + CM_ARCH_COMMON_PROC_HIERARCHY_INFO + ); + +/** + This macro expands to a function that retrieves the cache information + from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjCacheInfo, + CM_ARCH_COMMON_CACHE_INFO + ); + +/** + This macro expands to a function that retrieves the cross-CM-object- + reference information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjCmRef, + CM_ARCH_COMMON_OBJ_REF + ); + +/** + This macro expands to a function that retrieves the GIC CPU interface + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicCInfo, + CM_ARM_GICC_INFO + ); + +/** + Returns the size of the PPTT Processor Hierarchy Node (Type 0) given a + Processor Hierarchy Info CM object. + + @param [in] Node Pointer to Processor Hierarchy Info CM object which + represents the Processor Hierarchy Node to be generated. + + @retval Size of the Processor Hierarchy Node in bytes. +**/ +STATIC +UINT32 +GetProcHierarchyNodeSize ( + IN CONST CM_ARCH_COMMON_PROC_HIERARCHY_INFO *Node + ) +{ + ASSERT (Node != NULL); + + // + + return sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR) + + (Node->NoOfPrivateResources * sizeof (UINT32)); +} + +/** + This macro expands to a function that retrieves the amount of memory required + to store the Processor Hierarchy Nodes (Type 0) and updates the Node Indexer. +*/ +GET_SIZE_OF_PPTT_STRUCTS ( + ProcHierarchyNodes, + GetProcHierarchyNodeSize (NodesToIndex), + CM_ARCH_COMMON_PROC_HIERARCHY_INFO + ); + +/** + This macro expands to a function that retrieves the amount of memory required + to store the Cache Type Structures (Type 1) and updates the Node Indexer. +*/ +GET_SIZE_OF_PPTT_STRUCTS ( + CacheTypeStructs, + sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE), + CM_ARCH_COMMON_CACHE_INFO + ); + +/** + Search the Node Indexer and return the indexed PPTT node with the given + Token. + + @param [in] NodeIndexer Pointer to the Node Indexer array. + @param [in] NodeCount Number of elements in Node Indexer. + @param [in] SearchToken Token used for Node Indexer lookup. + @param [out] IndexedNodeFound Pointer to the Node Indexer array element + with the given Token. + + @retval EFI_SUCCESS Success. + @retval EFI_NOT_FOUND No element with a matching token was + found in the Node Indexer array. +**/ +STATIC +EFI_STATUS +GetPpttNodeReferencedByToken ( + IN PPTT_NODE_INDEXER *NodeIndexer, + IN UINT32 NodeCount, + IN CONST CM_OBJECT_TOKEN SearchToken, + OUT PPTT_NODE_INDEXER **IndexedNodeFound + ) +{ + EFI_STATUS Status; + + ASSERT (NodeIndexer != NULL); + + DEBUG (( + DEBUG_INFO, + "PPTT: Node Indexer: SearchToken = %p\n", + SearchToken + )); + + while (NodeCount-- != 0) { + DEBUG (( + DEBUG_INFO, + "PPTT: Node Indexer: NodeIndexer->Token = %p. Offset = %d\n", + NodeIndexer->Token, + NodeIndexer->Offset + )); + + if (NodeIndexer->Token == SearchToken) { + *IndexedNodeFound = NodeIndexer; + Status = EFI_SUCCESS; + DEBUG (( + DEBUG_INFO, + "PPTT: Node Indexer: Token = %p. Found, Status = %r\n", + SearchToken, + Status + )); + return Status; + } + + NodeIndexer++; + } + + Status = EFI_NOT_FOUND; + DEBUG (( + DEBUG_ERROR, + "PPTT: Node Indexer: SearchToken = %p. Status = %r\n", + SearchToken, + Status + )); + + return Status; +} + +/** + Detect cycles in the processor and cache topology graph represented in + the PPTT table. + + @param [in] Generator Pointer to the PPTT Generator. + + @retval EFI_SUCCESS There are no cyclic references in the graph. + @retval EFI_INVALID_PARAMETER Processor or cache references form a cycle. +**/ +STATIC +EFI_STATUS +DetectCyclesInTopology ( + IN CONST ACPI_PPTT_GENERATOR *CONST Generator + ) +{ + EFI_STATUS Status; + PPTT_NODE_INDEXER *Iterator; + PPTT_NODE_INDEXER *CycleDetector; + UINT32 NodesRemaining; + + ASSERT (Generator != NULL); + + Iterator = Generator->NodeIndexer; + NodesRemaining = Generator->ProcTopologyStructCount; + + while (NodesRemaining != 0) { + DEBUG (( + DEBUG_INFO, + "INFO: PPTT: Cycle detection for element with index %d\n", + Generator->ProcTopologyStructCount - NodesRemaining + )); + + CycleDetector = Iterator; + + // Walk the topology tree + while (CycleDetector->TopologyParent != NULL) { + DEBUG (( + DEBUG_INFO, + "INFO: PPTT: %p -> %p\n", + CycleDetector->Token, + CycleDetector->TopologyParent->Token + )); + + // Check if we have already visited this node + if (CycleDetector->CycleDetectionStamp == NodesRemaining) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Cycle in processor and cache topology detected for " \ + "a chain of references originating from a node with: Token = %p " \ + "Status = %r\n", + Iterator->Token, + Status + )); + return Status; + } + + // Stamp the visited node + CycleDetector->CycleDetectionStamp = NodesRemaining; + CycleDetector = CycleDetector->TopologyParent; + } // Continue topology tree walk + + Iterator++; + NodesRemaining--; + } // Next Node Indexer + + return EFI_SUCCESS; +} + +/** + Update the array of private resources for a given Processor Hierarchy Node. + + @param [in] Generator Pointer to the PPTT Generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] PrivResArray Pointer to the array of private resources. + @param [in] PrivResCount Number of private resources. + @param [in] PrivResArrayToken Reference Token for the CM_ARCH_COMMON_OBJ_REF + array describing node's private resources. + + @retval EFI_SUCCESS Array updated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND A private resource was not found. +**/ +STATIC +EFI_STATUS +AddPrivateResources ( + IN CONST ACPI_PPTT_GENERATOR *CONST Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN UINT32 *PrivResArray, + IN UINT32 PrivResCount, + IN CONST CM_OBJECT_TOKEN PrivResArrayToken + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_OBJ_REF *CmObjRefs; + UINT32 CmObjRefCount; + PPTT_NODE_INDEXER *PpttNodeFound; + + ASSERT ( + (Generator != NULL) && + (CfgMgrProtocol != NULL) && + (PrivResArray != NULL) && + (PrivResCount != 0) + ); + + // Validate input arguments + if (PrivResArrayToken == CM_NULL_TOKEN) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The number of private resources is %d while " \ + "PrivResToken = CM_NULL_TOKEN. Status = %r\n", + PrivResCount, + Status + )); + return Status; + } + + CmObjRefCount = 0; + // Get the CM Object References + Status = GetEArchCommonObjCmRef ( + CfgMgrProtocol, + PrivResArrayToken, + &CmObjRefs, + &CmObjRefCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get CM Object References. " \ + "PrivResToken = %p. Status = %r\n", + PrivResArrayToken, + Status + )); + return Status; + } + + if (CmObjRefCount != PrivResCount) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The number of CM Object References retrieved and the " \ + "number of private resources don't match. CmObjRefCount = %d. " \ + "PrivResourceCount = %d. PrivResToken = %p. Status = %r\n", + CmObjRefCount, + PrivResCount, + PrivResArrayToken, + Status + )); + return Status; + } + + while (PrivResCount-- != 0) { + if (CmObjRefs->ReferenceToken == CM_NULL_TOKEN) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: CM_NULL_TOKEN provided as reference token for a " \ + "private resource. Status = %r\n", + Status + )); + return Status; + } + + // The Node indexer has the Processor hierarchy nodes at the begining + // followed by the cache structs. Therefore we can skip the Processor + // hierarchy nodes in the node indexer search. + Status = GetPpttNodeReferencedByToken ( + Generator->CacheStructIndexedList, + (Generator->ProcTopologyStructCount - + Generator->ProcHierarchyNodeCount), + CmObjRefs->ReferenceToken, + &PpttNodeFound + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get a private resource with Token = %p from " \ + "Node Indexer. Status = %r\n", + CmObjRefs->ReferenceToken, + Status + )); + return Status; + } + + // Update the offset of the private resources in the Processor + // Hierarchy Node structure + *(PrivResArray++) = PpttNodeFound->Offset; + CmObjRefs++; + } + + return EFI_SUCCESS; +} + +/** + Function to test if two indexed Processor Hierarchy Info objects map to the + same GIC CPU Interface Info object. + + This is a callback function that can be invoked by FindDuplicateValue (). + + @param [in] Object1 Pointer to the first indexed Processor Hierarchy + Info object. + @param [in] Object2 Pointer to the second indexed Processor Hierarchy + Info object. + @param [in] Index1 Index of Object1 to be displayed for debugging + purposes. + @param [in] Index2 Index of Object2 to be displayed for debugging + purposes. + + @retval TRUE Object1 and Object2 have the same + AcpiIdObjectToken. + @retval FALSE Object1 and Object2 have different + AcpiIdObjectTokens. +**/ +BOOLEAN +EFIAPI +IsAcpiIdObjectTokenEqual ( + IN CONST VOID *Object1, + IN CONST VOID *Object2, + IN UINTN Index1, + IN UINTN Index2 + ) +{ + PPTT_NODE_INDEXER *IndexedObject1; + PPTT_NODE_INDEXER *IndexedObject2; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode1; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode2; + + ASSERT ( + (Object1 != NULL) && + (Object2 != NULL) + ); + + IndexedObject1 = (PPTT_NODE_INDEXER *)Object1; + IndexedObject2 = (PPTT_NODE_INDEXER *)Object2; + ProcNode1 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject1->Object; + ProcNode2 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject2->Object; + + if (IS_ACPI_PROC_ID_VALID (ProcNode1) && + IS_ACPI_PROC_ID_VALID (ProcNode2) && + (ProcNode1->AcpiIdObjectToken != CM_NULL_TOKEN) && + (ProcNode2->AcpiIdObjectToken != CM_NULL_TOKEN) && + (ProcNode1->AcpiIdObjectToken == ProcNode2->AcpiIdObjectToken)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Two Processor Hierarchy Info objects (%d and %d) map to " \ + "the same ACPI ID reference object. ACPI Processor IDs are not unique. " \ + "AcpiIdObjectToken = %p.\n", + Index1, + Index2, + ProcNode1->AcpiIdObjectToken + )); + return TRUE; + } + + return FALSE; +} + +/** + Update the Processor Hierarchy Node (Type 0) information. + + This function populates the Processor Hierarchy Nodes with information from + the Configuration Manager and adds this information to the PPTT table. + + @param [in] Generator Pointer to the PPTT Generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Pptt Pointer to PPTT table structure. + @param [in] NodesStartOffset Offset from the start of PPTT table to the + start of Processor Hierarchy Nodes. + + @retval EFI_SUCCESS Node updated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. +**/ +STATIC +EFI_STATUS +AddProcHierarchyNodes ( + IN CONST ACPI_PPTT_GENERATOR *CONST Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt, + IN CONST UINT32 NodesStartOffset + ) +{ + EFI_STATUS Status; + EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *ProcStruct; + UINT32 *PrivateResources; + BOOLEAN IsAcpiIdObjectTokenDuplicated; + + CM_ARM_GICC_INFO *GicCInfoList; + UINT32 GicCInfoCount; + UINT32 UniqueGicCRefCount; + + PPTT_NODE_INDEXER *PpttNodeFound; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcInfoNode; + + PPTT_NODE_INDEXER *ProcNodeIterator; + UINT32 NodeCount; + UINT32 Length; + + ASSERT ( + (Generator != NULL) && + (CfgMgrProtocol != NULL) && + (Pptt != NULL) + ); + + ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)Pptt + + NodesStartOffset); + + ProcNodeIterator = Generator->ProcHierarchyNodeIndexedList; + NodeCount = Generator->ProcHierarchyNodeCount; + + // Check if every GICC Object is referenced by onlu one Proc Node + IsAcpiIdObjectTokenDuplicated = FindDuplicateValue ( + ProcNodeIterator, + NodeCount, + sizeof (PPTT_NODE_INDEXER), + IsAcpiIdObjectTokenEqual + ); + // Duplicate GIC CPU Interface Token was found so two PPTT Processor Hierarchy + // Nodes map to the same MADT GICC structure + if (IsAcpiIdObjectTokenDuplicated) { + return EFI_INVALID_PARAMETER; + } + + UniqueGicCRefCount = 0; + + while (NodeCount-- != 0) { + ProcInfoNode = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object; + + // Check if the private resource count is within the size limit + // imposed on the Processor Hierarchy node by the specification. + // Note: The length field is 8 bit wide while the number of private + // resource field is 32 bit wide. + Length = GetProcHierarchyNodeSize (ProcInfoNode); + if (Length > MAX_UINT8) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Too many private resources. Count = %d. " \ + "Maximum supported Processor Node size exceeded. " \ + "Token = %p. Status = %r\n", + ProcInfoNode->NoOfPrivateResources, + ProcInfoNode->ParentToken, + Status + )); + return Status; + } + + // Populate the node header + ProcStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR; + ProcStruct->Length = (UINT8)Length; + ProcStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE; + ProcStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE; + + // Populate the flags + ProcStruct->Flags.PhysicalPackage = ProcInfoNode->Flags & BIT0; + ProcStruct->Flags.AcpiProcessorIdValid = (ProcInfoNode->Flags & BIT1) >> 1; + ProcStruct->Flags.ProcessorIsAThread = (ProcInfoNode->Flags & BIT2) >> 2; + ProcStruct->Flags.NodeIsALeaf = (ProcInfoNode->Flags & BIT3) >> 3; + ProcStruct->Flags.IdenticalImplementation = + (ProcInfoNode->Flags & BIT4) >> 4; + ProcStruct->Flags.Reserved = 0; + + // Populate the parent reference + if (ProcInfoNode->ParentToken == CM_NULL_TOKEN) { + ProcStruct->Parent = 0; + } else { + Status = GetPpttNodeReferencedByToken ( + Generator->ProcHierarchyNodeIndexedList, + Generator->ProcHierarchyNodeCount, + ProcInfoNode->ParentToken, + &PpttNodeFound + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get parent processor hierarchy node " \ + "reference. ParentToken = %p. ChildToken = %p. Status = %r\n", + ProcInfoNode->ParentToken, + ProcInfoNode->Token, + Status + )); + return Status; + } + + // Test if the reference is to a 'leaf' node + if (IS_PROC_NODE_LEAF ( + ((CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)PpttNodeFound->Object) + )) + { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Reference to a leaf Processor Hierarchy Node. " \ + "ParentToken = %p. ChildToken = %p. Status = %r\n", + ProcInfoNode->ParentToken, + ProcInfoNode->Token, + Status + )); + return Status; + } + + // Update Proc Structure with the offset of the parent node + ProcStruct->Parent = PpttNodeFound->Offset; + + // Store the reference for the parent node in the Node Indexer + // so that this can be used later for cycle detection + ProcNodeIterator->TopologyParent = PpttNodeFound; + } + + // Populate ACPI Processor ID + if (!IS_ACPI_PROC_ID_VALID (ProcInfoNode)) { + // Default invalid ACPI Processor ID to 0 + ProcStruct->AcpiProcessorId = 0; + } else if (ProcInfoNode->AcpiIdObjectToken == CM_NULL_TOKEN) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no " \ + "ACPI ID Reference object token was provided. " \ + "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n", + ProcInfoNode->AcpiIdObjectToken, + ProcInfoNode->Token, + Status + )); + return Status; + } else { + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + ProcInfoNode->AcpiIdObjectToken, + &GicCInfoList, + &GicCInfoCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get ACPI ID Reference object token. " \ + "ACPI Processor ID can't be populated. " \ + "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n", + ProcInfoNode->AcpiIdObjectToken, + ProcInfoNode->Token, + Status + )); + return Status; + } + + if (GicCInfoCount != 1) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to find a unique GICC structure. " \ + "ACPI Processor ID can't be populated. " \ + "GICC Structure Count = %d. AcpiIdObjectToken = %p. RequestorToken = %p " \ + "Status = %r\n", + GicCInfoCount, + ProcInfoNode->AcpiIdObjectToken, + ProcInfoNode->Token, + Status + )); + return Status; + } + + // Update the ACPI Processor Id + ProcStruct->AcpiProcessorId = GicCInfoList->AcpiProcessorUid; + + // Increment the reference count for the number of + // Unique GICC objects that were retrieved. + UniqueGicCRefCount++; + } + + ProcStruct->NumberOfPrivateResources = ProcInfoNode->NoOfPrivateResources; + PrivateResources = (UINT32 *)((UINT8 *)ProcStruct + + sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR)); + + if (ProcStruct->NumberOfPrivateResources != 0) { + // Populate the private resources array + Status = AddPrivateResources ( + Generator, + CfgMgrProtocol, + PrivateResources, + ProcStruct->NumberOfPrivateResources, + ProcInfoNode->PrivateResourcesArrayToken + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to populate the private resources array. " \ + "Status = %r\n", + Status + )); + return Status; + } + } + + // Next Processor Hierarchy Node + ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)ProcStruct + + ProcStruct->Length); + ProcNodeIterator++; + } // Processor Hierarchy Node + + // Knowing the total number of GICC references made and that all GICC Token + // references are unique, we can test if no GICC instances have been left out. + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GicCInfoList, + &GicCInfoCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get GICC Info. Status = %r\n", + Status + )); + return Status; + } + + // MADT - PPTT cross validation + // This checks that one and only one GICC structure is referenced by a + // Processor Hierarchy Node in the PPTT. + // Since we have already checked that the GICC objects referenced by the + // Proc Nodes are unique, the UniqueGicCRefCount cannot be greater than + // the total number of GICC objects in the platform. + if (GicCInfoCount > UniqueGicCRefCount) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: %d GICC structure(s) exposed by MADT don't have " \ + "a corresponding Processor Hierarchy Node. Status = %r\n", + GicCInfoCount - UniqueGicCRefCount, + Status + )); + } + + return Status; +} + +/** + Test whether CacheId is unique among the CacheIdList. + + @param [in] CacheId Cache ID to check. + @param [in] CacheIdList List of already existing cache IDs. + @param [in] CacheIdListSize Size of CacheIdList. + + @retval TRUE CacheId does not exist in CacheIdList. + @retval FALSE CacheId already exists in CacheIdList. +**/ +STATIC +BOOLEAN +IsCacheIdUnique ( + IN CONST UINT32 CacheId, + IN CONST UINT32 *CacheIdList, + IN CONST UINT32 CacheIdListSize + ) +{ + UINT32 Index; + + for (Index = 0; Index < CacheIdListSize; Index++) { + if (CacheIdList[Index] == CacheId) { + return FALSE; + } + } + + return TRUE; +} + +/** + Update the Cache Type Structure (Type 1) information. + + This function populates the Cache Type Structures with information from + the Configuration Manager and adds this information to the PPTT table. + + @param [in] Generator Pointer to the PPTT Generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Pptt Pointer to PPTT table structure. + @param [in] NodesStartOffset Offset from the start of PPTT table to the + start of Cache Type Structures. + @param [in] Revision Revision of the PPTT table being requested. + + @retval EFI_SUCCESS Structures updated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND A required object was not found. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +STATIC +EFI_STATUS +AddCacheTypeStructures ( + IN CONST ACPI_PPTT_GENERATOR *CONST Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt, + IN CONST UINT32 NodesStartOffset, + IN CONST UINT32 Revision + ) +{ + EFI_STATUS Status; + EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *CacheStruct; + PPTT_NODE_INDEXER *PpttNodeFound; + CM_ARCH_COMMON_CACHE_INFO *CacheInfoNode; + PPTT_NODE_INDEXER *CacheNodeIterator; + UINT32 NodeCount; + BOOLEAN CacheIdUnique; + UINT32 NodeIndex; + UINT32 *FoundCacheIds; + + ASSERT ( + (Generator != NULL) && + (CfgMgrProtocol != NULL) && + (Pptt != NULL) + ); + + CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *)((UINT8 *)Pptt + + NodesStartOffset); + + CacheNodeIterator = Generator->CacheStructIndexedList; + NodeCount = Generator->CacheStructCount; + + FoundCacheIds = AllocateZeroPool (NodeCount * sizeof (*FoundCacheIds)); + if (FoundCacheIds == NULL) { + DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Failed to allocate resources.\n")); + return EFI_OUT_OF_RESOURCES; + } + + for (NodeIndex = 0; NodeIndex < NodeCount; NodeIndex++) { + CacheInfoNode = (CM_ARCH_COMMON_CACHE_INFO *)CacheNodeIterator->Object; + + // Populate the node header + CacheStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_CACHE; + CacheStruct->Length = sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE); + CacheStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE; + CacheStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE; + + // "On Arm-based systems, all cache properties must be provided in the + // table." (ACPI 6.4, Section 5.2.29.2) + CacheStruct->Flags.SizePropertyValid = 1; + CacheStruct->Flags.NumberOfSetsValid = 1; + CacheStruct->Flags.AssociativityValid = 1; + CacheStruct->Flags.AllocationTypeValid = 1; + CacheStruct->Flags.CacheTypeValid = 1; + CacheStruct->Flags.WritePolicyValid = 1; + CacheStruct->Flags.LineSizeValid = 1; + CacheStruct->Flags.CacheIdValid = 1; + CacheStruct->Flags.Reserved = 0; + + // Populate the reference to the next level of cache + if (CacheInfoNode->NextLevelOfCacheToken == CM_NULL_TOKEN) { + CacheStruct->NextLevelOfCache = 0; + } else { + Status = GetPpttNodeReferencedByToken ( + Generator->CacheStructIndexedList, + Generator->CacheStructCount, + CacheInfoNode->NextLevelOfCacheToken, + &PpttNodeFound + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get the reference to the Next Level of " \ + "Cache. NextLevelOfCacheToken = %p. RequestorToken = %p. " \ + "Status = %r\n", + CacheInfoNode->NextLevelOfCacheToken, + CacheInfoNode->Token, + Status + )); + goto cleanup; + } + + // Update Cache Structure with the offset for the next level of cache + CacheStruct->NextLevelOfCache = PpttNodeFound->Offset; + + // Store the next level of cache information in the Node Indexer + // so that this can be used later for cycle detection + CacheNodeIterator->TopologyParent = PpttNodeFound; + } + + CacheStruct->Size = CacheInfoNode->Size; + + // Validate and populate the 'Number of sets' field + if (CacheInfoNode->NumberOfSets > PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: When ARMv8.3-CCIDX is implemented the maximum number " \ + "of sets can be %d. NumberOfSets = %d. Status = %r\n", + PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX, + CacheInfoNode->NumberOfSets, + Status + )); + goto cleanup; + } + + if (CacheInfoNode->NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) { + DEBUG (( + DEBUG_INFO, + "INFO: PPTT: When ARMv8.3-CCIDX is not implemented the maximum " \ + "number of sets can be %d. NumberOfSets = %d\n", + PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX, + CacheInfoNode->NumberOfSets + )); + } + + CacheStruct->NumberOfSets = CacheInfoNode->NumberOfSets; + + // Validate Associativity field based on maximum associativity + // supported by ACPI Cache type structure. + if (CacheInfoNode->Associativity > MAX_UINT8) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The maximum associativity supported by ACPI " \ + "Cache type structure is %d. Associativity = %d, Status = %r\n", + MAX_UINT8, + CacheInfoNode->Associativity, + Status + )); + goto cleanup; + } + + // Validate the Associativity field based on the architecture specification + // The architecture supports much larger associativity values than the + // current ACPI specification. + // These checks will be needed in the future when the ACPI specification + // is extended. Disabling this code for now. + #if 0 + if (CacheInfoNode->Associativity > PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: When ARMv8.3-CCIDX is implemented the maximum cache " \ + "associativity can be %d. Associativity = %d. Status = %r\n", + PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX, + CacheInfoNode->Associativity, + Status + )); + goto cleanup; + } + + if (CacheInfoNode->Associativity > PPTT_ARM_CACHE_ASSOCIATIVITY_MAX) { + DEBUG (( + DEBUG_INFO, + "INFO: PPTT: When ARMv8.3-CCIDX is not implemented the maximum " \ + "cache associativity can be %d. Associativity = %d\n", + PPTT_ARM_CACHE_ASSOCIATIVITY_MAX, + CacheInfoNode->Associativity + )); + } + + #endif + + // Note a typecast is needed as the maximum associativity + // supported by ACPI Cache type structure is MAX_UINT8. + CacheStruct->Associativity = (UINT8)CacheInfoNode->Associativity; + + // Populate cache attributes + CacheStruct->Attributes.AllocationType = + CacheInfoNode->Attributes & (BIT0 | BIT1); + CacheStruct->Attributes.CacheType = + (CacheInfoNode->Attributes & (BIT2 | BIT3)) >> 2; + CacheStruct->Attributes.WritePolicy = + (CacheInfoNode->Attributes & BIT4) >> 4; + CacheStruct->Attributes.Reserved = 0; + + // Validate and populate cache line size + if ((CacheInfoNode->LineSize < PPTT_ARM_CACHE_LINE_SIZE_MIN) || + (CacheInfoNode->LineSize > PPTT_ARM_CACHE_LINE_SIZE_MAX)) + { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The cache line size must be between %d and %d bytes " \ + "on ARM Platforms. LineSize = %d. Status = %r\n", + PPTT_ARM_CACHE_LINE_SIZE_MIN, + PPTT_ARM_CACHE_LINE_SIZE_MAX, + CacheInfoNode->LineSize, + Status + )); + goto cleanup; + } + + if ((CacheInfoNode->LineSize & (CacheInfoNode->LineSize - 1)) != 0) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The cache line size is not a power of 2. " \ + "LineSize = %d. Status = %r\n", + CacheInfoNode->LineSize, + Status + )); + goto cleanup; + } + + CacheStruct->LineSize = CacheInfoNode->LineSize; + + if (Revision >= 3) { + // Validate and populate cache id + if (CacheInfoNode->CacheId == 0) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The cache id cannot be zero. Status = %r\n", + Status + )); + goto cleanup; + } + + CacheIdUnique = IsCacheIdUnique ( + CacheInfoNode->CacheId, + FoundCacheIds, + NodeIndex + ); + if (!CacheIdUnique) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: The cache id is not unique. " \ + "CacheId = %d. Status = %r\n", + CacheInfoNode->CacheId, + Status + )); + goto cleanup; + } + + // Store the cache id so we can check future cache ids for uniqueness + FoundCacheIds[NodeIndex] = CacheInfoNode->CacheId; + + CacheStruct->CacheId = CacheInfoNode->CacheId; + } + + // Next Cache Type Structure + CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *)((UINT8 *)CacheStruct + + CacheStruct->Length); + CacheNodeIterator++; + } // for Cache Type Structure + + Status = EFI_SUCCESS; + +cleanup: + FreePool (FoundCacheIds); + + return Status; +} + +/** + Construct the PPTT ACPI table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table generator to be used. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildPpttTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + UINT32 TableSize; + UINT32 ProcTopologyStructCount; + UINT32 ProcHierarchyNodeCount; + UINT32 CacheStructCount; + + UINT32 ProcHierarchyNodeOffset; + UINT32 CacheStructOffset; + + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; + CM_ARCH_COMMON_CACHE_INFO *CacheStructList; + + ACPI_PPTT_GENERATOR *Generator; + + // Pointer to the Node Indexer array + PPTT_NODE_INDEXER *NodeIndexer; + + EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *Pptt; + + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (Table != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Requested table revision = %d is not supported. " + "Supported table revisions: Minimum = %d. Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + Generator = (ACPI_PPTT_GENERATOR *)This; + *Table = NULL; + + // Get the processor hierarchy info and update the processor topology + // structure count with Processor Hierarchy Nodes (Type 0) + Status = GetEArchCommonObjProcHierarchyInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &ProcHierarchyNodeList, + &ProcHierarchyNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get processor hierarchy info. Status = %r\n", + Status + )); + goto error_handler; + } + + ProcTopologyStructCount = ProcHierarchyNodeCount; + Generator->ProcHierarchyNodeCount = ProcHierarchyNodeCount; + + // Get the cache info and update the processor topology structure count with + // Cache Type Structures (Type 1) + Status = GetEArchCommonObjCacheInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &CacheStructList, + &CacheStructCount + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to get cache info. Status = %r\n", + Status + )); + goto error_handler; + } + + ProcTopologyStructCount += CacheStructCount; + Generator->CacheStructCount = CacheStructCount; + + // Allocate Node Indexer array + NodeIndexer = (PPTT_NODE_INDEXER *)AllocateZeroPool ( + sizeof (PPTT_NODE_INDEXER) * + ProcTopologyStructCount + ); + if (NodeIndexer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to allocate memory for Node Indexer. Status = %r\n ", + Status + )); + goto error_handler; + } + + DEBUG ((DEBUG_INFO, "INFO: NodeIndexer = %p\n", NodeIndexer)); + Generator->ProcTopologyStructCount = ProcTopologyStructCount; + Generator->NodeIndexer = NodeIndexer; + + // Calculate the size of the PPTT table + TableSize = sizeof (EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER); + + // Include the size of Processor Hierarchy Nodes and index them + if (Generator->ProcHierarchyNodeCount != 0) { + ProcHierarchyNodeOffset = TableSize; + Generator->ProcHierarchyNodeIndexedList = NodeIndexer; + TableSize += GetSizeofProcHierarchyNodes ( + ProcHierarchyNodeOffset, + ProcHierarchyNodeList, + Generator->ProcHierarchyNodeCount, + &NodeIndexer + ); + + DEBUG (( + DEBUG_INFO, + " ProcHierarchyNodeCount = %d\n" \ + " ProcHierarchyNodeOffset = 0x%x\n" \ + " ProcHierarchyNodeIndexedList = 0x%p\n", + Generator->ProcHierarchyNodeCount, + ProcHierarchyNodeOffset, + Generator->ProcHierarchyNodeIndexedList + )); + } + + // Include the size of Cache Type Structures and index them + if (Generator->CacheStructCount != 0) { + CacheStructOffset = TableSize; + Generator->CacheStructIndexedList = NodeIndexer; + TableSize += GetSizeofCacheTypeStructs ( + CacheStructOffset, + CacheStructList, + Generator->CacheStructCount, + &NodeIndexer + ); + DEBUG (( + DEBUG_INFO, + " CacheStructCount = %d\n" \ + " CacheStructOffset = 0x%x\n" \ + " CacheStructIndexedList = 0x%p\n", + Generator->CacheStructCount, + CacheStructOffset, + Generator->CacheStructIndexedList + )); + } + + DEBUG (( + DEBUG_INFO, + "INFO: PPTT:\n" \ + " ProcTopologyStructCount = %d\n" \ + " TableSize = %d\n", + ProcTopologyStructCount, + TableSize + )); + + // Allocate the Buffer for the PPTT table + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to allocate memory for PPTT Table. " \ + "Size = %d. Status = %r\n", + TableSize, + Status + )); + goto error_handler; + } + + Pptt = (EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *)*Table; + + DEBUG (( + DEBUG_INFO, + "PPTT: Pptt = 0x%p. TableSize = 0x%x\n", + Pptt, + TableSize + )); + + // Add ACPI header + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + &Pptt->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Add Processor Hierarchy Nodes (Type 0) to the generated table + if (Generator->ProcHierarchyNodeCount != 0) { + Status = AddProcHierarchyNodes ( + Generator, + CfgMgrProtocol, + Pptt, + ProcHierarchyNodeOffset + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to add Processor Hierarchy Nodes. Status = %r\n", + Status + )); + goto error_handler; + } + } + + // Add Cache Type Structures (Type 1) to the generated table + if (Generator->CacheStructCount != 0) { + Status = AddCacheTypeStructures ( + Generator, + CfgMgrProtocol, + Pptt, + CacheStructOffset, + AcpiTableInfo->AcpiTableRevision + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Failed to add Cache Type Structures. Status = %r\n", + Status + )); + goto error_handler; + } + } + + // Validate CM object cross-references in PPTT + Status = DetectCyclesInTopology (Generator); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: PPTT: Invalid processor and cache topology. Status = %r\n", + Status + )); + goto error_handler; + } + + return Status; + +error_handler: + if (Generator->NodeIndexer != NULL) { + FreePool (Generator->NodeIndexer); + Generator->NodeIndexer = NULL; + } + + if (*Table != NULL) { + FreePool (*Table); + *Table = NULL; + } + + return Status; +} + +/** + Free any resources allocated for constructing the PPTT + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +FreePpttTableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ACPI_PPTT_GENERATOR *Generator; + + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + Generator = (ACPI_PPTT_GENERATOR *)This; + + // Free any memory allocated by the generator + if (Generator->NodeIndexer != NULL) { + FreePool (Generator->NodeIndexer); + Generator->NodeIndexer = NULL; + } + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Invalid Table Pointer\n")); + ASSERT ( + (Table != NULL) && + (*Table != NULL) + ); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** The PPTT Table Generator revision. +*/ +#define PPTT_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the PPTT Table Generator. +*/ +STATIC +ACPI_PPTT_GENERATOR PpttGenerator = { + // ACPI table generator header + { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt), + // Generator Description + L"ACPI.STD.PPTT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + PPTT_GENERATOR_REVISION, + // Build Table function + BuildPpttTable, + // Free Resource function + FreePpttTableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL + }, + + // PPTT Generator private data + + // Processor topology node count + 0, + // Count of Processor Hierarchy Nodes + 0, + // Count of Cache Structures + 0, + // Pointer to PPTT Node Indexer + NULL +}; + +/** + Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiPpttLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&PpttGenerator.Header); + DEBUG ((DEBUG_INFO, "PPTT: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiPpttLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&PpttGenerator.Header); + DEBUG ((DEBUG_INFO, "PPTT: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h new file mode 100644 index 0000000000..15b0a9871c --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h @@ -0,0 +1,185 @@ +/** @file + Header file for the dynamic PPTT generator + + Copyright (c) 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification, January 2019 + - ARM Architecture Reference Manual ARMv8 (D.a) + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#ifndef PPTT_GENERATOR_H_ +#define PPTT_GENERATOR_H_ + +#pragma pack(1) + +/// Cache parameters allowed by the architecture with +/// ARMv8.3-CCIDX (Cache extended number of sets) +/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0001 +#define PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX (1 << 24) +#define PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX (1 << 21) + +/// Cache parameters allowed by the architecture without +/// ARMv8.3-CCIDX (Cache extended number of sets) +/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0000 +#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX (1 << 15) +#define PPTT_ARM_CACHE_ASSOCIATIVITY_MAX (1 << 10) + +/// Common cache parameters +/// Derived from CCSIDR_EL1 +/// The LineSize is represented by bits 2:0 +/// (Log2(Number of bytes in cache line)) - 4 is used to represent +/// the LineSize bits. +#define PPTT_ARM_CACHE_LINE_SIZE_MAX (1 << 11) +#define PPTT_ARM_CACHE_LINE_SIZE_MIN (1 << 4) + +/// Test if the given Processor Hierarchy Info object has the 'Node is a Leaf' +/// flag set +#define IS_PROC_NODE_LEAF(Node) ((Node->Flags & BIT3) != 0) + +/// Test if the given Processor Hierarchy Info object has the 'ACPI Processor +/// ID valid' flag set +#define IS_ACPI_PROC_ID_VALID(Node) ((Node->Flags & BIT1) != 0) + +/** + The GET_SIZE_OF_PPTT_STRUCTS macro expands to a function that is used to + calculate the total memory requirement for the PPTT structures represented + by the given list of Configuration Manager Objects of the same type. This + function also indexes the input CM objects so that various other CM objects + (possibly of different type) can reference them. + + The size of memory needed for the specified type of PPTT structures is based + on the number and type of CM objects provided. The macro assumes that the + ACPI object PpttObjName has fixed size. + + The macro expands to a function which has the following prototype: + + STATIC + UINT32 + EFIAPI + GetSizeof ( + IN CONST UINT32 StartOffset, + IN CONST CmObjectType * Nodes, + IN UINT32 NodeCount, + IN OUT PPTT_NODE_INDEXER ** CONST NodeIndexer + ) + + Generated function parameters: + @param [in] StartOffset Offset from the start of PPTT to where + the PPTT structures will be placed. + @param [in] NodesToIndex Pointer to the list of CM objects to be + indexed and size-estimated. + @param [out] NodeCount Number of CM objects in NodesToIndex. + @param [in, out] NodeIndexer Pointer to the list of Node Indexer + elements to populate. + @retval Size Total memory requirement for the PPTT + structures described in NodesToIndex. + + Macro Parameters: + @param [in] PpttObjName Name for the type of PPTT structures which + size is estimated. + @param [in] PpttObjSize Expression to use to calculate the size of + of a single instance of the PPTT structure + which corresponds to the CM object being + indexed. + @param [in] CmObjectType Data type of the CM nodes in NodesToIndex. +**/ +#define GET_SIZE_OF_PPTT_STRUCTS( \ + PpttObjName, \ + PpttObjSize, \ + CmObjectType \ + ) \ +STATIC \ +UINT32 \ +GetSizeof##PpttObjName ( \ + IN CONST UINT32 StartOffset, \ + IN CONST CmObjectType * NodesToIndex, \ + IN UINT32 NodeCount, \ + IN OUT PPTT_NODE_INDEXER ** CONST NodeIndexer \ + ) \ +{ \ + UINT32 Size; \ + \ + ASSERT ( \ + (NodesToIndex != NULL) && \ + (NodeIndexer != NULL) \ + ); \ + \ + Size = 0; \ + while (NodeCount-- != 0) { \ + (*NodeIndexer)->Token = NodesToIndex->Token; \ + (*NodeIndexer)->Object = (VOID*)NodesToIndex; \ + (*NodeIndexer)->Offset = Size + StartOffset; \ + (*NodeIndexer)->CycleDetectionStamp = 0; \ + (*NodeIndexer)->TopologyParent = NULL; \ + DEBUG (( \ + DEBUG_INFO, \ + "PPTT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", \ + *NodeIndexer, \ + (*NodeIndexer)->Token, \ + (*NodeIndexer)->Object, \ + (*NodeIndexer)->Offset \ + )); \ + \ + Size += PpttObjSize; \ + (*NodeIndexer)++; \ + NodesToIndex++; \ + } \ + return Size; \ +} + +/** + A structure for indexing CM objects (nodes) used in PPTT generation. + + PPTT_NODE_INDEXER is a wrapper around CM objects which augments these objects + with additional information that enables generating PPTT structures with + correct cross-references. + + PPTT_NODE_INDEXER keeps track of each structure's offset from the base + address of the generated table. It also caches certain information and makes + PPTT cyclic reference detection possible. +*/ +typedef struct PpttNodeIndexer { + /// Unique identifier for the node + CM_OBJECT_TOKEN Token; + /// Pointer to the CM object being indexed + VOID *Object; + /// Offset from the start of the PPTT table to the PPTT structure which is + /// represented by Object + UINT32 Offset; + /// Field used to mark nodes as 'visited' when detecting cycles in processor + /// and cache topology + UINT32 CycleDetectionStamp; + /// Reference to a Node Indexer element which is the parent of this Node + /// Indexer element in the processor and cache topology + /// e.g For a hardware thread the TopologyParent would point to a CPU node + /// For a L1 cache the TopologyParent would point to a L2 cache + struct PpttNodeIndexer *TopologyParent; +} PPTT_NODE_INDEXER; + +typedef struct AcpiPpttGenerator { + /// ACPI Table generator header + ACPI_TABLE_GENERATOR Header; + /// PPTT structure count + UINT32 ProcTopologyStructCount; + /// Count of Processor Hierarchy Nodes + UINT32 ProcHierarchyNodeCount; + /// Count of Cache Structures + UINT32 CacheStructCount; + /// List of indexed CM objects for PPTT generation + PPTT_NODE_INDEXER *NodeIndexer; + /// Pointer to the start of Processor Hierarchy nodes in + /// the Node Indexer array + PPTT_NODE_INDEXER *ProcHierarchyNodeIndexedList; + /// Pointer to the start of Cache Structures in the Node Indexer array + PPTT_NODE_INDEXER *CacheStructIndexedList; +} ACPI_PPTT_GENERATOR; + +#pragma pack() + +#endif // PPTT_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf new file mode 100644 index 0000000000..f2ab1b7111 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf @@ -0,0 +1,36 @@ +## @file +# Raw Table Generator +# +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = AcpiRawLibArm + FILE_GUID = 20F31568-D687-49BA-B326-CCD9D38EDE16 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiRawLibConstructor + DESTRUCTOR = AcpiRawLibDestructor + +[Sources] + RawGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + +[Pcd] + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c new file mode 100644 index 0000000000..a8323ad4ea --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c @@ -0,0 +1,146 @@ +/** @file + MCFG Table Generator + + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +/** Construct the ACPI table using the ACPI table data provided. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildRawTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableData != NULL); + + if (AcpiTableInfo->AcpiTableData == NULL) { + *Table = NULL; + return EFI_INVALID_PARAMETER; + } + + *Table = AcpiTableInfo->AcpiTableData; + + return EFI_SUCCESS; +} + +/** This macro defines the Raw Generator revision. +*/ +#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the Raw Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR RawGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdRaw), + // Generator Description + L"ACPI.STD.RAW.GENERATOR", + // ACPI Table Signature - Unused + 0, + // ACPI Table Revision - Unused + 0, + // Minimum ACPI Table Revision - Unused + 0, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + RAW_GENERATOR_REVISION, + // Build Table function + BuildRawTable, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiRawLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&RawGenerator); + DEBUG ((DEBUG_INFO, "RAW: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiRawLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&RawGenerator); + DEBUG ((DEBUG_INFO, "RAW: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf new file mode 100644 index 0000000000..e11f878ec8 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf @@ -0,0 +1,37 @@ +## @file +# SPCR Table Generator +# +# Copyright (c) 2017 - 2020, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = AcpiSpcrLibArm + FILE_GUID = 55088136-7B78-4974-B1EE-F630150D0DE7 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSpcrLibConstructor + DESTRUCTOR = AcpiSpcrLibDestructor + +[Sources] + SpcrGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + SsdtSerialPortFixupLib + +[Pcd] + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c new file mode 100644 index 0000000000..6f027f3bf9 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c @@ -0,0 +1,482 @@ +/** @file + SPCR Table Generator + + Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Serial Port Console Redirection Table + Specification - Version 1.03 - August 10, 2015. + +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include + +/** ARM standard SPCR Table Generator + + Constructs the SPCR table for PL011 or SBSA UART peripherals. + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjConsolePortInfo + +NOTE: This implementation ignores the possibility that the Serial settings may + be modified from the UEFI Shell. A more complex handler would be needed + to (e.g.) recover serial port settings from the UART, or non-volatile + storage. +*/ + +#pragma pack(1) + +/** A string representing the name of the SPCR port. +*/ +#define NAME_STR_SPCR_PORT "COM1" + +/** An UID representing the SPCR port. +*/ +#define UID_SPCR_PORT 1 + +/** This macro defines the no flow control option. +*/ +#define SPCR_FLOW_CONTROL_NONE 0 + +/**A template for generating the SPCR Table. + + Note: fields marked "{Template}" will be updated dynamically. +*/ +STATIC +EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE AcpiSpcr = { + ACPI_HEADER ( + EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION + ), + 0, // {Template}: Serial Port Subtype + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + ARM_GAS32 (0), // {Template}: Serial Port Base Address + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC, + 0, // Not used on ARM + 0, // {Template}: Serial Port Interrupt + 0, // {Template}: Serial Port Baudrate + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, + SPCR_FLOW_CONTROL_NONE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI, + EFI_ACPI_RESERVED_BYTE, + 0xFFFF, + 0xFFFF, + 0x00, + 0x00, + 0x00, + 0x00000000, + 0x00, + EFI_ACPI_RESERVED_DWORD +}; + +#pragma pack() + +/** This macro expands to a function that retrieves the Serial + Port Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjConsolePortInfo, + CM_ARCH_COMMON_SERIAL_PORT_INFO + ) + +/** Free any resources allocated for constructing the tables. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to ACPI Table(s). + @param [in] TableCount Number of ACPI table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeSpcrTableEx ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, + IN CONST UINTN TableCount + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || + (*Table == NULL) || + (TableCount != 2)) + { + DEBUG ((DEBUG_ERROR, "ERROR: SPCR: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + TableList = *Table; + + if ((TableList[1] == NULL) || + (TableList[1]->Signature != + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) + { + DEBUG ((DEBUG_ERROR, "ERROR: SPCR: Invalid SSDT table pointer.\n")); + return EFI_INVALID_PARAMETER; + } + + // Only need to free the SSDT table at index 1. The SPCR table is static. + Status = FreeSsdtSerialPortTable (TableList[1]); + ASSERT_EFI_ERROR (Status); + + // Free the table list. + FreePool (*Table); + + return Status; +} + +/** Construct the SPCR ACPI table and its associated SSDT table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResourcesEx function. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to a list of generated ACPI table(s). + @param [out] TableCount Number of generated ACPI table(s). + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Could not find information. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. + @retval EFI_UNSUPPORTED Unsupported configuration. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSpcrTableEx ( + IN CONST ACPI_TABLE_GENERATOR *This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, + OUT UINTN *CONST TableCount + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 SerialPortCount; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Requested table revision = %d, is not supported." + "Supported table revision: Minimum = %d, Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + + Status = GetEArchCommonObjConsolePortInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SerialPortInfo, + &SerialPortCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Failed to get serial port information. Status = %r\n", + Status + )); + return Status; + } + + if (SerialPortCount == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Serial port information not found. Status = %r\n", + EFI_NOT_FOUND + )); + return EFI_NOT_FOUND; + } + + // Validate the SerialPort info. Only one SPCR port can be described. + // If platform provides description for multiple SPCR ports, use the + // first SPCR port information. + Status = ValidateSerialPortInfo (SerialPortInfo, 1); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Invalid serial port information. Status = %r\n", + Status + )); + return Status; + } + + // Allocate a table to store pointers to the SPCR and SSDT tables. + TableList = (EFI_ACPI_DESCRIPTION_HEADER **) + AllocateZeroPool (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * 2); + if (TableList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Failed to allocate memory for Table List," \ + " Status = %r\n", + Status + )); + return Status; + } + + // Build SPCR table. + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpcr, + AcpiTableInfo, + sizeof (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // The SPCR InterfaceType uses the same encoding as that of the + // DBG2 table Port Subtype field. However InterfaceType is 8-bit + // while the Port Subtype field in the DBG2 table is 16-bit. + if ((SerialPortInfo->PortSubtype & 0xFF00) != 0) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Invalid Port subtype (must be < 256). Status = %r\n", + Status + )); + goto error_handler; + } + + // Update the serial port subtype + AcpiSpcr.InterfaceType = (UINT8)SerialPortInfo->PortSubtype; + + // Update the base address + AcpiSpcr.BaseAddress.Address = SerialPortInfo->BaseAddress; + + // Set the access size + if (SerialPortInfo->AccessSize >= EFI_ACPI_6_3_QWORD) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Access size must be <= 3 (DWORD). Status = %r\n", + Status + )); + goto error_handler; + } else if (SerialPortInfo->AccessSize == EFI_ACPI_6_3_UNDEFINED) { + // 0 Undefined (legacy reasons) + // Default to DWORD access size as the access + // size field was introduced at a later date + // and some ConfigurationManager implementations + // may not be providing this field data + AcpiSpcr.BaseAddress.AccessSize = EFI_ACPI_6_3_DWORD; + } else { + AcpiSpcr.BaseAddress.AccessSize = SerialPortInfo->AccessSize; + } + + // Update the UART interrupt + AcpiSpcr.GlobalSystemInterrupt = SerialPortInfo->Interrupt; + + switch (SerialPortInfo->BaudRate) { + case 9600: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600; + break; + case 19200: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200; + break; + case 57600: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600; + break; + case 115200: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200; + break; + default: + Status = EFI_UNSUPPORTED; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Invalid Baud Rate %ld, Status = %r\n", + SerialPortInfo->BaudRate, + Status + )); + goto error_handler; + } // switch + + TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpcr; + + // Build a SSDT table describing the serial port. + Status = BuildSsdtSerialPortTable ( + AcpiTableInfo, + SerialPortInfo, + NAME_STR_SPCR_PORT, + UID_SPCR_PORT, + &TableList[1] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Failed to build associated SSDT table. Status = %r\n", + Status + )); + goto error_handler; + } + + *TableCount = 2; + *Table = TableList; + + return Status; + +error_handler: + if (TableList != NULL) { + FreePool (TableList); + } + + return Status; +} + +/** This macro defines the SPCR Table Generator revision. +*/ +#define SPCR_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the SPCR Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR SpcrGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr), + // Generator Description + L"ACPI.STD.SPCR.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SPCR_GENERATOR_REVISION, + // Build table function. Use the extended version instead. + NULL, + // Free table function. Use the extended version instead. + NULL, + // Extended Build table function. + BuildSpcrTableEx, + // Extended free function. + FreeSpcrTableEx +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSpcrLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SpcrGenerator); + DEBUG ((DEBUG_INFO, "SPCR: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSpcrLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SpcrGenerator); + DEBUG ((DEBUG_INFO, "SPCR: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf new file mode 100644 index 0000000000..5891dc4d1c --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf @@ -0,0 +1,29 @@ +## @file +# SRAT Table Generator +# +# Copyright (c) 2019, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = AcpiSratLibArm + FILE_GUID = 2CE21E0A-A39C-4B26-BC0E-526178036ACD + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSratLibConstructor + DESTRUCTOR = AcpiSratLibDestructor + +[Sources] + SratGenerator.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c new file mode 100644 index 0000000000..48c9970a71 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c @@ -0,0 +1,842 @@ +/** @file + SRAT Table Generator + + Copyright (c) 2019 - 2020, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification, January 2019 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +/** + ARM standard SRAT Generator + + Requirements: + The following Configuration Manager Object(s) are used by this Generator: + - EArmObjGicCInfo (REQUIRED) + - EArmObjGicItsInfo (OPTIONAL) + - EArchCommonObjMemoryAffinityInfo (OPTIONAL) + - EArchCommonObjGenericInitiatorAffinityInfo (OPTIONAL) + - EArchCommonObjDeviceHandleAcpi (OPTIONAL) + - EArchCommonObjDeviceHandlePci (OPTIONAL) +*/ + +/** This macro expands to a function that retrieves the GIC + CPU interface Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicCInfo, + CM_ARM_GICC_INFO + ); + +/** This macro expands to a function that retrieves the GIC + Interrupt Translation Service Information from the + Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicItsInfo, + CM_ARM_GIC_ITS_INFO + ); + +/** + This macro expands to a function that retrieves the Memory Affinity + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjMemoryAffinityInfo, + CM_ARCH_COMMON_MEMORY_AFFINITY_INFO + ); + +/** + This macro expands to a function that retrieves the Generic Initiator Affinity + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjGenericInitiatorAffinityInfo, + CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO + ); + +/** + This macro expands to a function that retrieves the ACPI Device Handle + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjDeviceHandleAcpi, + CM_ARCH_COMMON_DEVICE_HANDLE_ACPI + ); + +/** + This macro expands to a function that retrieves the PCI Device Handle + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjDeviceHandlePci, + CM_ARCH_COMMON_DEVICE_HANDLE_PCI + ); + +/** Return the PCI Device information in BDF format + + PCI Bus Number - Max 256 busses (Bits 15:8 of BDF) + PCI Device Number - Max 32 devices (Bits 7:3 of BDF) + PCI Function Number - Max 8 functions (Bits 2:0 of BDF) + + @param [in] DeviceHandlePci Pointer to the PCI Device Handle. + + @retval BDF value corresponding to the PCI Device Handle. +**/ +STATIC +UINT16 +GetBdf ( + IN CONST CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci + ) +{ + UINT16 Bdf; + + Bdf = (UINT16)DeviceHandlePci->BusNumber << 8; + Bdf |= (DeviceHandlePci->DeviceNumber & 0x1F) << 3; + Bdf |= DeviceHandlePci->FunctionNumber & 0x7; + return Bdf; +} + +/** Add the GICC Affinity Structures in the SRAT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + @param [in] GicCAffOffset Offset of the GICC Affinity + information in the SRAT Table. + @param [in] GicCInfo Pointer to the GIC CPU Information list. + @param [in] GicCCount Count of GIC CPU Interfaces. + + @retval EFI_SUCCESS Table generated successfully. +**/ +STATIC +EFI_STATUS +AddGICCAffinity ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, + IN CONST UINT32 GicCAffOffset, + IN CONST CM_ARM_GICC_INFO *GicCInfo, + IN UINT32 GicCCount + ) +{ + EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *GicCAff; + + ASSERT (Srat != NULL); + ASSERT (GicCInfo != NULL); + + GicCAff = (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)((UINT8 *)Srat + + GicCAffOffset); + + while (GicCCount-- != 0) { + DEBUG ((DEBUG_INFO, "SRAT: GicCAff = 0x%p\n", GicCAff)); + + GicCAff->Type = EFI_ACPI_6_3_GICC_AFFINITY; + GicCAff->Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE); + GicCAff->ProximityDomain = GicCInfo->ProximityDomain; + GicCAff->AcpiProcessorUid = GicCInfo->AcpiProcessorUid; + GicCAff->Flags = GicCInfo->AffinityFlags; + GicCAff->ClockDomain = GicCInfo->ClockDomain; + + // Next + GicCAff++; + GicCInfo++; + }// while + + return EFI_SUCCESS; +} + +/** Add the GIC ITS Affinity Structures in the SRAT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + @param [in] GicItsAffOffset Offset of the GIC ITS Affinity + information in the SRAT Table. + @param [in] GicItsInfo Pointer to the GIC ITS Information list. + @param [in] GicItsCount Count of GIC ITS. + + @retval EFI_SUCCESS Table generated successfully. +**/ +STATIC +EFI_STATUS +AddGICItsAffinity ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, + IN CONST UINT32 GicItsAffOffset, + IN CONST CM_ARM_GIC_ITS_INFO *GicItsInfo, + IN UINT32 GicItsCount + ) +{ + EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff; + + ASSERT (Srat != NULL); + ASSERT (GicItsInfo != NULL); + + GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat + + GicItsAffOffset); + + while (GicItsCount-- != 0) { + DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff)); + + GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY; + GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE); + GicItsAff->ProximityDomain = GicItsInfo->ProximityDomain; + GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE; + GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE; + GicItsAff->ItsId = GicItsInfo->GicItsId; + + // Next + GicItsAff++; + GicItsInfo++; + }// while + + return EFI_SUCCESS; +} + +/** Add the Memory Affinity Structures in the SRAT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + @param [in] MemAffOffset Offset of the Memory Affinity + information in the SRAT Table. + @param [in] MemAffInfo Pointer to the Memory Affinity Information list. + @param [in] MemAffCount Count of Memory Affinity objects. + + @retval EFI_SUCCESS Table generated successfully. +**/ +STATIC +EFI_STATUS +AddMemoryAffinity ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, + IN CONST UINT32 MemAffOffset, + IN CONST CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo, + IN UINT32 MemAffCount + ) +{ + EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *MemAff; + + ASSERT (Srat != NULL); + ASSERT (MemAffInfo != NULL); + + MemAff = (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *)((UINT8 *)Srat + + MemAffOffset); + + while (MemAffCount-- != 0) { + DEBUG ((DEBUG_INFO, "SRAT: MemAff = 0x%p\n", MemAff)); + + MemAff->Type = EFI_ACPI_6_3_MEMORY_AFFINITY; + MemAff->Length = sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE); + MemAff->ProximityDomain = MemAffInfo->ProximityDomain; + MemAff->Reserved1 = EFI_ACPI_RESERVED_WORD; + MemAff->AddressBaseLow = (UINT32)(MemAffInfo->BaseAddress & MAX_UINT32); + MemAff->AddressBaseHigh = (UINT32)(MemAffInfo->BaseAddress >> 32); + MemAff->LengthLow = (UINT32)(MemAffInfo->Length & MAX_UINT32); + MemAff->LengthHigh = (UINT32)(MemAffInfo->Length >> 32); + MemAff->Reserved2 = EFI_ACPI_RESERVED_DWORD; + MemAff->Flags = MemAffInfo->Flags; + MemAff->Reserved3 = EFI_ACPI_RESERVED_QWORD; + + // Next + MemAff++; + MemAffInfo++; + }// while + + return EFI_SUCCESS; +} + +/** Add the Generic Initiator Affinity Structures in the SRAT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + @param [in] GenInitAffOff Offset of the Generic Initiator Affinity + information in the SRAT Table. + @param [in] GenInitAffInfo Pointer to the Generic Initiator Affinity + Information list. + @param [in] GenInitAffCount Count of Generic Initiator Affinity + objects. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +AddGenericInitiatorAffinity ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, + IN CONST UINT32 GenInitAffOff, + IN CONST CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo, + IN UINT32 GenInitAffCount + ) +{ + EFI_STATUS Status; + EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *GenInitAff; + CM_ARCH_COMMON_DEVICE_HANDLE_ACPI *DeviceHandleAcpi; + CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci; + UINT32 DeviceHandleCount; + + ASSERT (Srat != NULL); + ASSERT (GenInitAffInfo != NULL); + + GenInitAff = (EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *)( + (UINT8 *)Srat + GenInitAffOff); + + while (GenInitAffCount-- != 0) { + DEBUG ((DEBUG_INFO, "SRAT: GenInitAff = 0x%p\n", GenInitAff)); + + GenInitAff->Type = EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY; + GenInitAff->Length = + sizeof (EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE); + GenInitAff->Reserved1 = EFI_ACPI_RESERVED_WORD; + GenInitAff->DeviceHandleType = GenInitAffInfo->DeviceHandleType; + GenInitAff->ProximityDomain = GenInitAffInfo->ProximityDomain; + + if (GenInitAffInfo->DeviceHandleToken == CM_NULL_TOKEN) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Invalid Device Handle Token.\n" + )); + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if (GenInitAffInfo->DeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) { + Status = GetEArchCommonObjDeviceHandleAcpi ( + CfgMgrProtocol, + GenInitAffInfo->DeviceHandleToken, + &DeviceHandleAcpi, + &DeviceHandleCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get ACPI Device Handle Inf." + " DeviceHandleToken = %p." + " Status = %r\n", + GenInitAffInfo->DeviceHandleToken, + Status + )); + return Status; + } + + // We are expecting only one device handle. + ASSERT (DeviceHandleCount == 1); + + // Populate the ACPI device handle information. + GenInitAff->DeviceHandle.Acpi.AcpiHid = DeviceHandleAcpi->Hid; + GenInitAff->DeviceHandle.Acpi.AcpiUid = DeviceHandleAcpi->Uid; + GenInitAff->DeviceHandle.Acpi.Reserved[0] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Acpi.Reserved[1] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Acpi.Reserved[2] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Acpi.Reserved[3] = EFI_ACPI_RESERVED_BYTE; + } else if (GenInitAffInfo->DeviceHandleType == + EFI_ACPI_6_3_PCI_DEVICE_HANDLE) + { + Status = GetEArchCommonObjDeviceHandlePci ( + CfgMgrProtocol, + GenInitAffInfo->DeviceHandleToken, + &DeviceHandlePci, + &DeviceHandleCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get ACPI Device Handle Inf." + " DeviceHandleToken = %p." + " Status = %r\n", + GenInitAffInfo->DeviceHandleToken, + Status + )); + return Status; + } + + // We are expecting only one device handle + ASSERT (DeviceHandleCount == 1); + + // Populate the ACPI device handle information. + GenInitAff->DeviceHandle.Pci.PciSegment = DeviceHandlePci->SegmentNumber; + GenInitAff->DeviceHandle.Pci.PciBdfNumber = GetBdf (DeviceHandlePci); + + GenInitAff->DeviceHandle.Pci.Reserved[0] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[1] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[2] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[3] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[4] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[5] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[6] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[7] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[8] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[9] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[10] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->DeviceHandle.Pci.Reserved[11] = EFI_ACPI_RESERVED_BYTE; + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Invalid Device Handle Type.\n" + )); + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + GenInitAff->Flags = GenInitAffInfo->Flags; + GenInitAff->Reserved2[0] = EFI_ACPI_RESERVED_BYTE; + GenInitAff->Reserved2[1] = EFI_ACPI_RESERVED_BYTE; + + // Next + GenInitAff++; + GenInitAffInfo++; + }// while + + return EFI_SUCCESS; +} + +/** Construct the SRAT ACPI table. + + Called by the Dynamic Table Manager, this function invokes the + Configuration Manager protocol interface to get the required hardware + information for generating the ACPI table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSratTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + UINT32 TableSize; + UINT32 GicCCount; + UINT32 GicItsCount; + UINT32 MemAffCount; + UINT32 GenInitiatorAffCount; + + UINT32 GicCAffOffset; + UINT32 GicItsAffOffset; + UINT32 MemAffOffset; + UINT32 GenInitiatorAffOffset; + + CM_ARM_GICC_INFO *GicCInfo; + CM_ARM_GIC_ITS_INFO *GicItsInfo; + CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo; + CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo; + + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *Srat; + + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (Table != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Requested table revision = %d is not supported. " + "Supported table revisions: Minimum = %d. Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GicCInfo, + &GicCCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get GICC Info. Status = %r\n", + Status + )); + goto error_handler; + } + + if (GicCCount == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: GIC CPU Interface information not provided.\n" + )); + ASSERT (0); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + Status = GetEArmObjGicItsInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GicItsInfo, + &GicItsCount + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get GIC ITS Info. Status = %r\n", + Status + )); + goto error_handler; + } + + Status = GetEArchCommonObjMemoryAffinityInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &MemAffInfo, + &MemAffCount + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get Memory Affinity Info. Status = %r\n", + Status + )); + goto error_handler; + } + + Status = GetEArchCommonObjGenericInitiatorAffinityInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GenInitiatorAffInfo, + &GenInitiatorAffCount + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get Generic Initiator Affinity Info." + " Status = %r\n", + Status + )); + goto error_handler; + } + + // Calculate the size of the SRAT table + TableSize = sizeof (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER); + + GicCAffOffset = TableSize; + TableSize += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) * GicCCount); + + if (GicItsCount != 0) { + GicItsAffOffset = TableSize; + TableSize += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) * + GicItsCount); + } + + if (MemAffCount != 0) { + MemAffOffset = TableSize; + TableSize += (sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE) * + MemAffCount); + } + + if (GenInitiatorAffCount != 0) { + GenInitiatorAffOffset = TableSize; + TableSize += (sizeof (EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE) * + GenInitiatorAffCount); + } + + // Allocate the Buffer for SRAT table + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to allocate memory for SRAT Table, Size = %d," \ + " Status = %r\n", + TableSize, + Status + )); + goto error_handler; + } + + Srat = (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *)*Table; + + DEBUG (( + DEBUG_INFO, + "SRAT: Srat = 0x%p TableSize = 0x%x\n", + Srat, + TableSize + )); + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + &Srat->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Setup the Reserved fields + // Reserved1 must be set to 1 for backward compatibility + Srat->Reserved1 = 1; + Srat->Reserved2 = EFI_ACPI_RESERVED_QWORD; + + Status = AddGICCAffinity ( + CfgMgrProtocol, + Srat, + GicCAffOffset, + GicCInfo, + GicCCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to add GICC Affinity structures. Status = %r\n", + Status + )); + goto error_handler; + } + + if (GicItsCount != 0) { + Status = AddGICItsAffinity ( + CfgMgrProtocol, + Srat, + GicItsAffOffset, + GicItsInfo, + GicItsCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to add GIC ITS Affinity structures. Status = %r\n", + Status + )); + goto error_handler; + } + } + + if (MemAffCount != 0) { + Status = AddMemoryAffinity ( + CfgMgrProtocol, + Srat, + MemAffOffset, + MemAffInfo, + MemAffCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to add Memory Affinity structures. Status = %r\n", + Status + )); + goto error_handler; + } + } + + if (GenInitiatorAffCount != 0) { + Status = AddGenericInitiatorAffinity ( + CfgMgrProtocol, + Srat, + GenInitiatorAffOffset, + GenInitiatorAffInfo, + GenInitiatorAffCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to add Generic Initiator Affinity structures." + " Status = %r\n", + Status + )); + goto error_handler; + } + } + + return Status; + +error_handler: + + if (*Table != NULL) { + FreePool (*Table); + *Table = NULL; + } + + return Status; +} + +/** Free any resources allocated for constructing the SRAT. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +FreeSratTableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: SRAT: Invalid Table Pointer\n")); + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** The SRAT Table Generator revision. +*/ +#define SRAT_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the SRAT Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR SratGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSrat), + // Generator Description + L"ACPI.STD.SRAT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SRAT_GENERATOR_REVISION, + // Build Table function + BuildSratTable, + // Free Resource function + FreeSratTableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSratLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SratGenerator); + DEBUG ((DEBUG_INFO, "SRAT: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSratLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SratGenerator); + DEBUG ((DEBUG_INFO, "SRAT: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c new file mode 100644 index 0000000000..2deaa4640c --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c @@ -0,0 +1,1705 @@ +/** @file + SSDT Cpu Topology Table Generator. + + Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors + - ACPI for CoreSight version 1.2 Platform Design Document + (https://developer.arm.com/documentation/den0067/a/?lang=en) + + @par Glossary: + - ETE - Embedded Trace Extension. + - ETM - Embedded Trace Macrocell. +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include + +#include "SsdtCpuTopologyGenerator.h" + +/** ARM standard SSDT Cpu Topology Table Generator. + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArmObjGicCInfo + - EArchCommonObjProcHierarchyInfo (OPTIONAL) along with + - EArchCommonObjCmRef (OPTIONAL) + - EArchCommonObjLpiInfo (OPTIONAL) + - GetEArmObjEtInfo (OPTIONAL) + - EArchCommonObjPsdInfo (OPTIONAL) +*/ + +/** This macro expands to a function that retrieves the GIC + CPU interface Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicCInfo, + CM_ARM_GICC_INFO + ); + +/** + This macro expands to a function that retrieves the Processor Hierarchy + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjProcHierarchyInfo, + CM_ARCH_COMMON_PROC_HIERARCHY_INFO + ); + +/** + This macro expands to a function that retrieves the cross-CM-object- + reference information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjCmRef, + CM_ARCH_COMMON_OBJ_REF + ); + +/** + This macro expands to a function that retrieves the Lpi + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjLpiInfo, + CM_ARCH_COMMON_LPI_INFO + ); + +/** + This macro expands to a function that retrieves the CPC + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjCpcInfo, + CM_ARCH_COMMON_CPC_INFO + ); + +/** + This macro expands to a function that retrieves the ET device + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjEtInfo, + CM_ARM_ET_INFO + ); + +/** + This macro expands to a function that retrieves the PSD + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPsdInfo, + CM_ARCH_COMMON_PSD_INFO + ); + +/** Initialize the TokenTable. + + One entry should be allocated for each CM_ARCH_COMMON_PROC_HIERARCHY_INFO + structure of the platform. The TokenTable allows to have a mapping: + Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). + + There will always be less sets of Lpi states (CM_ARCH_COMMON_OBJ_REF) + than the number of cpus/clusters (CM_ARCH_COMMON_PROC_HIERARCHY_INFO). + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] Count Number of entries to allocate in the TokenTable. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +TokenTableInitialize ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN UINT32 Count + ) +{ + CM_OBJECT_TOKEN *Table; + + if ((Generator == NULL) || + (Count == 0) || + (Count >= MAX_NODE_COUNT)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Table = AllocateZeroPool (sizeof (CM_OBJECT_TOKEN) * Count); + if (Table == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + Generator->TokenTable.Table = Table; + + return EFI_SUCCESS; +} + +/** Free the TokenTable. + + @param [in] Generator The SSDT Cpu Topology generator. +**/ +STATIC +VOID +EFIAPI +TokenTableFree ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator + ) +{ + ASSERT (Generator != NULL); + ASSERT (Generator->TokenTable.Table != NULL); + + if (Generator->TokenTable.Table != NULL) { + FreePool (Generator->TokenTable.Table); + } +} + +/** Add a new entry to the TokenTable and return its index. + + If an entry with Token is already available in the table, + return its index without adding a new entry. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] Token New Token entry to add. + + @retval The index of the token entry in the TokenTable. +**/ +STATIC +UINT32 +EFIAPI +TokenTableAdd ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CM_OBJECT_TOKEN Token + ) +{ + CM_OBJECT_TOKEN *Table; + UINT32 Index; + UINT32 LastIndex; + + ASSERT (Generator != NULL); + ASSERT (Generator->TokenTable.Table != NULL); + + Table = Generator->TokenTable.Table; + LastIndex = Generator->TokenTable.LastIndex; + + // Search if there is already an entry with this Token. + for (Index = 0; Index < LastIndex; Index++) { + if (Table[Index] == Token) { + return Index; + } + } + + ASSERT (LastIndex < MAX_NODE_COUNT); + ASSERT (LastIndex < Generator->ProcNodeCount); + + // If no, create a new entry. + Table[LastIndex] = Token; + + return Generator->TokenTable.LastIndex++; +} + +/** Write a string 'Xxxx\0' in AslName (5 bytes long), + with 'X' being the leading char of the name, and + with 'xxx' being Value in hexadecimal. + + As 'xxx' in hexadecimal represents a number on 12 bits, + we have Value < (1 << 12). + + @param [in] LeadChar Leading char of the name. + @param [in] Value Hex value of the name. + Must be lower than (2 << 12). + @param [in, out] AslName Pointer to write the 'Xxxx' string to. + Must be at least 5 bytes long. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +WriteAslName ( + IN CHAR8 LeadChar, + IN UINT32 Value, + IN OUT CHAR8 *AslName + ) +{ + UINT8 Index; + + if ((Value >= MAX_NODE_COUNT) || + (AslName == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + AslName[0] = LeadChar; + AslName[AML_NAME_SEG_SIZE] = '\0'; + + for (Index = 0; Index < AML_NAME_SEG_SIZE - 1; Index++) { + AslName[AML_NAME_SEG_SIZE - Index - 1] = + AsciiFromHex (((Value >> (4 * Index)) & 0xF)); + } + + return EFI_SUCCESS; +} + +/** Create and add an _PSD Node to Cpu Node. + + For instance, transform an AML node from: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + } + + To: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + Name (_PSD, Package() + { + NumEntries, // Integer + Revision, // Integer + Domain, // Integer + CoordType, // Integer + NumProcessors, // Integer + }) + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object + describing the Cpu. + @param [in] Node CPU Node to which the _CPC node is + attached. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlPsdNode ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_ARM_GICC_INFO *GicCInfo, + IN AML_OBJECT_NODE_HANDLE *Node + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_PSD_INFO *PsdInfo; + + Status = GetEArchCommonObjPsdInfo ( + CfgMgrProtocol, + GicCInfo->PsdToken, + &PsdInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status = AmlCreatePsdNode ( + PsdInfo, + Node, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Create and add an _CPC Node to Cpu Node. + + For instance, transform an AML node from: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + } + + To: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + Name(_CPC, Package() + { + NumEntries, // Integer + Revision, // Integer + HighestPerformance, // Integer or Buffer (Resource Descriptor) + NominalPerformance, // Integer or Buffer (Resource Descriptor) + LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor) + LowestPerformance, // Integer or Buffer (Resource Descriptor) + GuaranteedPerformanceRegister, // Buffer (Resource Descriptor) + DesiredPerformanceRegister , // Buffer (Resource Descriptor) + MinimumPerformanceRegister , // Buffer (Resource Descriptor) + MaximumPerformanceRegister , // Buffer (Resource Descriptor) + PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor) + TimeWindowRegister, // Buffer (Resource Descriptor) + CounterWraparoundTime, // Integer or Buffer (Resource Descriptor) + ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor) + DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor) + PerformanceLimitedRegister, // Buffer (Resource Descriptor) + CPPCEnableRegister // Buffer (Resource Descriptor) + AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor) + AutonomousActivityWindowRegister, // Buffer (Resource Descriptor) + EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor) + ReferencePerformance // Integer or Buffer (Resource Descriptor) + LowestFrequency, // Integer or Buffer (Resource Descriptor) + NominalFrequency // Integer or Buffer (Resource Descriptor) + }) + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object + describing the Cpu. + @param [in] Node CPU Node to which the _CPC node is + attached. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlCpcNode ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_ARM_GICC_INFO *GicCInfo, + IN AML_OBJECT_NODE_HANDLE *Node + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_CPC_INFO *CpcInfo; + + Status = GetEArchCommonObjCpcInfo ( + CfgMgrProtocol, + GicCInfo->CpcToken, + &CpcInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCreateCpcNode ( + CpcInfo, + Node, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Create an embedded trace device and add it to the Cpu Node in the + AML namespace. + + This generates the following ASL code: + Device (E002) + { + Name (_UID, 2) + Name (_HID, "ARMHC500") + } + + Note: Currently we only support generating ETE nodes. Unlike ETM, + ETE has a system register interface and therefore does not need + the MMIO range to be described. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] ParentNode Parent node to attach the Cpu node to. + @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node. + @param [in] CpuName Value used to generate the node name. + @param [out] EtNodePtr If not NULL, return the created Cpu node. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlEtd ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN AML_NODE_HANDLE ParentNode, + IN CM_ARM_GICC_INFO *GicCInfo, + IN UINT32 CpuName, + OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL + ) +{ + EFI_STATUS Status; + AML_OBJECT_NODE_HANDLE EtNode; + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + + ASSERT (Generator != NULL); + ASSERT (ParentNode != NULL); + + Status = WriteAslName ('E', CpuName, AslName); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameInteger ( + "_UID", + GicCInfo->AcpiProcessorUid, + EtNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameString ( + "_HID", + ACPI_HID_ET_DEVICE, + EtNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // If requested, return the handle to the EtNode. + if (EtNodePtr != NULL) { + *EtNodePtr = EtNode; + } + + return Status; +} + +/** Create and add an Embedded trace device to the Cpu Node. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object + describing the Cpu. + @param [in] CpuName Value used to generate the CPU node name. + @param [in] Node CPU Node to which the ET device node is + attached. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_UNSUPPORTED Feature Unsupported. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlEtNode ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_ARM_GICC_INFO *GicCInfo, + IN UINT32 CpuName, + IN AML_OBJECT_NODE_HANDLE *Node + ) +{ + EFI_STATUS Status; + CM_ARM_ET_INFO *EtInfo; + + Status = GetEArmObjEtInfo ( + CfgMgrProtocol, + GicCInfo->EtToken, + &EtInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Currently we only support creation of a ETE Node. + if (EtInfo->EtType != ArmEtTypeEte) { + return EFI_UNSUPPORTED; + } + + Status = CreateAmlEtd ( + Generator, + Node, + GicCInfo, + CpuName, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Create and add an _LPI method to Cpu/Cluster Node. + + For instance, transform an AML node from: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + } + + To: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + Method (_LPI, 0, NotSerialized) + { + Return (\_SB.L003) + } + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO + describing the Cpu. + @param [in] Node Node to which the _LPI method is + attached. Can represent a Cpu or a + Cluster. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlLpiMethod ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, + IN AML_OBJECT_NODE_HANDLE *Node + ) +{ + EFI_STATUS Status; + UINT32 TokenIndex; + CHAR8 AslName[SB_SCOPE_PREFIX_SIZE + AML_NAME_SEG_SIZE]; + + ASSERT (Generator != NULL); + ASSERT (ProcHierarchyNodeInfo != NULL); + ASSERT (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN); + ASSERT (Node != NULL); + + TokenIndex = TokenTableAdd (Generator, ProcHierarchyNodeInfo->LpiToken); + + CopyMem (AslName, SB_SCOPE_PREFIX, SB_SCOPE_PREFIX_SIZE); + + Status = WriteAslName ( + 'L', + TokenIndex, + AslName + SB_SCOPE_PREFIX_SIZE - 1 + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: + // Method (_LPI, 0) { + // Return ([AslName]) + // } + Status = AmlCodeGenMethodRetNameString ( + "_LPI", + AslName, + 0, + FALSE, + 0, + Node, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + } + + return Status; +} + +/** Generate all the Lpi states under the '_SB' scope. + + This function generates the following ASL code: + Scope (\_SB) { + Name (L000, Package() { + 0, // Version + 0, // Level Index + X, // Count + Package() { + [An Lpi state] + }, + Package() { + [Another Lpi state] + }, + } // Name L000 + + Name (L001, Package() { + ... + } // Name L001 + + ... + } // Scope /_SB + + The Lpi states are fetched from the Configuration Manager. + The names of the Lpi states are generated from the TokenTable. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ScopeNode Scope node handle ('\_SB' scope). + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +GenerateLpiStates ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_OBJECT_NODE_HANDLE ScopeNode + ) +{ + EFI_STATUS Status; + + UINT32 Index; + UINT32 LastIndex; + + AML_OBJECT_NODE_HANDLE LpiNode; + CM_ARCH_COMMON_OBJ_REF *LpiRefInfo; + UINT32 LpiRefInfoCount; + UINT32 LpiRefIndex; + CM_ARCH_COMMON_LPI_INFO *LpiInfo; + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + + ASSERT (Generator != NULL); + ASSERT (Generator->TokenTable.Table != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ScopeNode != NULL); + + LastIndex = Generator->TokenTable.LastIndex; + + // For each entry in the TokenTable, create a name in the AML namespace + // under SB_SCOPE, to store the Lpi states associated with the LpiToken. + for (Index = 0; Index < LastIndex; Index++) { + Status = WriteAslName ('L', Index, AslName); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // We do not support the LevelId field for now, let it to 0. + Status = AmlCreateLpiNode (AslName, 0, 0, ScopeNode, &LpiNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Fetch the LPI objects referenced by the token. + Status = GetEArchCommonObjCmRef ( + CfgMgrProtocol, + Generator->TokenTable.Table[Index], + &LpiRefInfo, + &LpiRefInfoCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + for (LpiRefIndex = 0; LpiRefIndex < LpiRefInfoCount; LpiRefIndex++) { + // For each CM_ARCH_COMMON_LPI_INFO referenced by the token, + // add an Lpi state. + Status = GetEArchCommonObjLpiInfo ( + CfgMgrProtocol, + LpiRefInfo[LpiRefIndex].ReferenceToken, + &LpiInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlAddLpiState ( + LpiInfo->MinResidency, + LpiInfo->WorstCaseWakeLatency, + LpiInfo->Flags, + LpiInfo->ArchFlags, + LpiInfo->ResCntFreq, + LpiInfo->EnableParentState, + LpiInfo->IsInteger ? + NULL : + &LpiInfo->RegisterEntryMethod, + LpiInfo->IsInteger ? + LpiInfo->IntegerEntryMethod : + 0, + &LpiInfo->ResidencyCounterRegister, + &LpiInfo->UsageCounterRegister, + LpiInfo->StateName, + LpiNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } // for LpiRefIndex + } // for Index + + return EFI_SUCCESS; +} + +/** Create a Cpu in the AML namespace. + + This generates the following ASL code: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] ParentNode Parent node to attach the Cpu node to. + @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node. + @param [in] CpuName Value used to generate the node name. + @param [out] CpuNodePtr If not NULL, return the created Cpu node. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlCpu ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN AML_NODE_HANDLE ParentNode, + IN CM_ARM_GICC_INFO *GicCInfo, + IN UINT32 CpuName, + OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL + ) +{ + EFI_STATUS Status; + AML_OBJECT_NODE_HANDLE CpuNode; + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + + ASSERT (Generator != NULL); + ASSERT (ParentNode != NULL); + ASSERT (GicCInfo != NULL); + + Status = WriteAslName ('C', CpuName, AslName); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenDevice (AslName, ParentNode, &CpuNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameInteger ( + "_UID", + GicCInfo->AcpiProcessorUid, + CpuNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameString ( + "_HID", + ACPI_HID_PROCESSOR_DEVICE, + CpuNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // If requested, return the handle to the CpuNode. + if (CpuNodePtr != NULL) { + *CpuNodePtr = CpuNode; + } + + return Status; +} + +/** Create a Cpu in the AML namespace from a CM_ARCH_COMMON_PROC_HIERARCHY_INFO + CM object. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ParentNode Parent node to attach the Cpu node to. + @param [in] CpuName Value used to generate the node name. + @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO + describing the Cpu. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlCpuFromProcHierarchy ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_NODE_HANDLE ParentNode, + IN UINT32 CpuName, + IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo + ) +{ + EFI_STATUS Status; + CM_ARM_GICC_INFO *GicCInfo; + AML_OBJECT_NODE_HANDLE CpuNode; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ParentNode != NULL); + ASSERT (ProcHierarchyNodeInfo != NULL); + ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN); + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + ProcHierarchyNodeInfo->AcpiIdObjectToken, + &GicCInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = CreateAmlCpu (Generator, ParentNode, GicCInfo, CpuName, &CpuNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // If a set of Lpi states is associated with the + // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them. + if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) { + Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + if (GicCInfo->PsdToken != CM_NULL_TOKEN) { + Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // If a CPC info is associated with the + // GicCinfo, create an _CPC method returning them. + if (GicCInfo->CpcToken != CM_NULL_TOKEN) { + Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // Add an Embedded Trace node if present. + if (GicCInfo->EtToken != CM_NULL_TOKEN) { + Status = CreateAmlEtNode ( + Generator, + CfgMgrProtocol, + GicCInfo, + CpuName, + CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + return Status; +} + +/** Create a Processor Container in the AML namespace. + + Any CM_ARCH_COMMON_PROC_HIERARCHY_INFO object with the following flags is + assumed to be a processor container: + - EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL + - EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID + - EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF + + This generates the following ASL code: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0010") + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ParentNode Parent node to attach the processor + container node to. + @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO object + used to create the node. + @param [in] ProcContainerName Name of the processor container. + @param [in] ProcContainerUid Uid of the processor container. + @param [out] ProcContainerNodePtr If success, contains the created processor + container node. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlProcessorContainer ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_NODE_HANDLE ParentNode, + IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo, + IN UINT16 ProcContainerName, + IN UINT32 ProcContainerUid, + OUT AML_OBJECT_NODE_HANDLE *ProcContainerNodePtr + ) +{ + EFI_STATUS Status; + AML_OBJECT_NODE_HANDLE ProcContainerNode; + CHAR8 AslNameProcContainer[AML_NAME_SEG_SIZE + 1]; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ParentNode != NULL); + ASSERT (ProcHierarchyNodeInfo != NULL); + ASSERT (ProcContainerNodePtr != NULL); + + Status = WriteAslName ('C', ProcContainerName, AslNameProcContainer); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenDevice (AslNameProcContainer, ParentNode, &ProcContainerNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Use the ProcContainerIndex for the _UID value as there is no AcpiProcessorUid + // and EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID is set for non-Cpus. + Status = AmlCodeGenNameInteger ( + "_UID", + ProcContainerUid, + ProcContainerNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameString ( + "_HID", + ACPI_HID_PROCESSOR_CONTAINER_DEVICE, + ProcContainerNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // If a set of Lpi states are associated with the + // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them. + if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) { + Status = CreateAmlLpiMethod ( + Generator, + ProcHierarchyNodeInfo, + ProcContainerNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } + + *ProcContainerNodePtr = ProcContainerNode; + + return Status; +} + +/** Check flags and topology of a ProcNode. + + @param [in] NodeFlags Flags of the ProcNode to check. + @param [in] IsLeaf The ProcNode is a leaf. + @param [in] NodeToken NodeToken of the ProcNode. + @param [in] ParentNodeToken Parent NodeToken of the ProcNode. + @param [in] PackageNodeSeen A parent of the ProcNode has the physical package flag set. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +CheckProcNode ( + UINT32 NodeFlags, + BOOLEAN IsLeaf, + CM_OBJECT_TOKEN NodeToken, + CM_OBJECT_TOKEN ParentNodeToken, + BOOLEAN PackageNodeSeen + ) +{ + BOOLEAN InvalidFlags; + BOOLEAN HasPhysicalPackageBit; + + HasPhysicalPackageBit = (NodeFlags & EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) == + EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL; + + // Only one Physical Package flag is allowed in the hierarchy + InvalidFlags = HasPhysicalPackageBit && PackageNodeSeen; + + // Check Leaf specific flags. + if (IsLeaf) { + InvalidFlags |= ((NodeFlags & PPTT_LEAF_MASK) != PPTT_LEAF_MASK); + // Must have Physical Package flag somewhere in the hierarchy + InvalidFlags |= !(HasPhysicalPackageBit || PackageNodeSeen); + } else { + InvalidFlags |= ((NodeFlags & PPTT_LEAF_MASK) != 0); + } + + if (InvalidFlags) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CPU-TOPOLOGY: Invalid flags for ProcNode: 0x%p.\n", + (VOID *)NodeToken + )); + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** Create an AML representation of the Cpu topology. + + A processor container is by extension any non-leave device in the cpu topology. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] NodeToken Token of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO currently handled. + @param [in] ParentNode Parent node to attach the created + node to. + @param [in,out] ProcContainerIndex Pointer to the current processor container + index to be used as UID. + @param [in] PackageNodeSeen A parent of the ProcNode has the physical package flag set. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlCpuTopologyTree ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_OBJECT_TOKEN NodeToken, + IN AML_NODE_HANDLE ParentNode, + IN OUT UINT32 *ProcContainerIndex, + IN BOOLEAN PackageNodeSeen + ) +{ + EFI_STATUS Status; + UINT32 Index; + UINT32 CpuIndex; + UINT32 ProcContainerName; + AML_OBJECT_NODE_HANDLE ProcContainerNode; + UINT32 Uid; + UINT16 Name; + BOOLEAN HasPhysicalPackageBit; + + ASSERT (Generator != NULL); + ASSERT (Generator->ProcNodeList != NULL); + ASSERT (Generator->ProcNodeCount != 0); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ParentNode != NULL); + ASSERT (ProcContainerIndex != NULL); + + CpuIndex = 0; + ProcContainerName = 0; + + for (Index = 0; Index < Generator->ProcNodeCount; Index++) { + // Find the children of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO + // currently being handled (i.e. ParentToken == NodeToken). + if (Generator->ProcNodeList[Index].ParentToken == NodeToken) { + // Only Cpus (leaf nodes in this tree) have a AcpiIdObjectToken. + // Create a Cpu node. + if (Generator->ProcNodeList[Index].AcpiIdObjectToken != CM_NULL_TOKEN) { + Status = CheckProcNode ( + Generator->ProcNodeList[Index].Flags, + TRUE, + Generator->ProcNodeList[Index].Token, + NodeToken, + PackageNodeSeen + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) { + Name = Generator->ProcNodeList[Index].OverrideName; + } else { + Name = CpuIndex; + } + + Status = CreateAmlCpuFromProcHierarchy ( + Generator, + CfgMgrProtocol, + ParentNode, + Name, + &Generator->ProcNodeList[Index] + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + CpuIndex++; + } else { + // If this is not a Cpu, then this is a processor container. + + Status = CheckProcNode ( + Generator->ProcNodeList[Index].Flags, + FALSE, + Generator->ProcNodeList[Index].Token, + NodeToken, + PackageNodeSeen + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) { + Name = Generator->ProcNodeList[Index].OverrideName; + Uid = Generator->ProcNodeList[Index].OverrideUid; + } else { + Name = ProcContainerName; + Uid = *ProcContainerIndex; + } + + Status = CreateAmlProcessorContainer ( + Generator, + CfgMgrProtocol, + ParentNode, + &Generator->ProcNodeList[Index], + Name, + Uid, + &ProcContainerNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Nodes must have a unique name in the ASL namespace. + // Reset the Cpu index whenever we create a new processor container. + (*ProcContainerIndex)++; + CpuIndex = 0; + + // And reset the cluster name whenever there is a package. + if (NodeToken == CM_NULL_TOKEN) { + ProcContainerName = 0; + } else { + ProcContainerName++; + } + + HasPhysicalPackageBit = (Generator->ProcNodeList[Index].Flags & EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) == + EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL; + + // Recursively continue creating an AML tree. + Status = CreateAmlCpuTopologyTree ( + Generator, + CfgMgrProtocol, + Generator->ProcNodeList[Index].Token, + ProcContainerNode, + ProcContainerIndex, + (PackageNodeSeen || HasPhysicalPackageBit) + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } + } // if ParentToken == NodeToken + } // for + + return EFI_SUCCESS; +} + +/** Create the processor hierarchy AML tree from + CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ScopeNode Scope node handle ('\_SB' scope). + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateTopologyFromProcHierarchy ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_OBJECT_NODE_HANDLE ScopeNode + ) +{ + EFI_STATUS Status; + UINT32 ProcContainerIndex; + + ASSERT (Generator != NULL); + ASSERT (Generator->ProcNodeCount != 0); + ASSERT (Generator->ProcNodeList != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ScopeNode != NULL); + + ProcContainerIndex = 0; + + Status = TokenTableInitialize (Generator, Generator->ProcNodeCount); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = CreateAmlCpuTopologyTree ( + Generator, + CfgMgrProtocol, + CM_NULL_TOKEN, + ScopeNode, + &ProcContainerIndex, + FALSE + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + + Status = GenerateLpiStates (Generator, CfgMgrProtocol, ScopeNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + +exit_handler: + TokenTableFree (Generator); + return Status; +} + +/** Create the processor hierarchy AML tree from CM_ARM_GICC_INFO + CM objects. + + A processor container is by extension any non-leave device in the cpu topology. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ScopeNode Scope node handle ('\_SB' scope). + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateTopologyFromGicC ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_OBJECT_NODE_HANDLE ScopeNode + ) +{ + EFI_STATUS Status; + CM_ARM_GICC_INFO *GicCInfo; + UINT32 GicCInfoCount; + UINT32 Index; + AML_OBJECT_NODE_HANDLE CpuNode; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ScopeNode != NULL); + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GicCInfo, + &GicCInfoCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // For each CM_ARM_GICC_INFO object, create an AML node. + for (Index = 0; Index < GicCInfoCount; Index++) { + Status = CreateAmlCpu ( + Generator, + ScopeNode, + &GicCInfo[Index], + Index, + &CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + break; + } + + if (GicCInfo->PsdToken != CM_NULL_TOKEN) { + Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // If a CPC info is associated with the + // GicCinfo, create an _CPC method returning them. + if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) { + Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + break; + } + } + + if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) { + Status = CreateAmlEtNode ( + Generator, + CfgMgrProtocol, + &GicCInfo[Index], + Index, + CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + } // for + + return Status; +} + +/** Construct the SSDT Cpu Topology ACPI table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSsdtCpuTopologyTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + AML_ROOT_NODE_HANDLE RootNode; + AML_OBJECT_NODE_HANDLE ScopeNode; + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList; + UINT32 ProcHierarchyNodeCount; + ACPI_CPU_TOPOLOGY_GENERATOR *Generator; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + Generator = (ACPI_CPU_TOPOLOGY_GENERATOR *)This; + + Status = AddSsdtAcpiHeader ( + CfgMgrProtocol, + This, + AcpiTableInfo, + &RootNode + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode); + if (EFI_ERROR (Status)) { + goto exit_handler; + } + + // Get the processor hierarchy info and update the processor topology + // structure count with Processor Hierarchy Nodes (Type 0) + Status = GetEArchCommonObjProcHierarchyInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &ProcHierarchyNodeList, + &ProcHierarchyNodeCount + ); + if (EFI_ERROR (Status) && + (Status != EFI_NOT_FOUND)) + { + goto exit_handler; + } + + if (Status == EFI_NOT_FOUND) { + // If hierarchy information is not found generate a flat topology + // using CM_ARM_GICC_INFO objects. + Status = CreateTopologyFromGicC ( + Generator, + CfgMgrProtocol, + ScopeNode + ); + if (EFI_ERROR (Status)) { + goto exit_handler; + } + } else { + // Generate the topology from CM_ARCH_COMMON_PROC_HIERARCHY_INFO objects. + Generator->ProcNodeList = ProcHierarchyNodeList; + Generator->ProcNodeCount = ProcHierarchyNodeCount; + + Status = CreateTopologyFromProcHierarchy ( + Generator, + CfgMgrProtocol, + ScopeNode + ); + if (EFI_ERROR (Status)) { + goto exit_handler; + } + } + + Status = AmlSerializeDefinitionBlock ( + RootNode, + Table + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CPU-TOPOLOGY: Failed to Serialize SSDT Table Data." + " Status = %r\n", + Status + )); + goto exit_handler; + } + +exit_handler: + // Delete the RootNode and its attached children. + return AmlDeleteTree (RootNode); +} + +/** Free any resources allocated for constructing the + SSDT Cpu Topology ACPI table. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +FreeSsdtCpuTopologyTableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CPU-TOPOLOGY: Invalid Table Pointer\n")); + ASSERT ((Table != NULL) && (*Table != NULL)); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** This macro defines the SSDT Cpu Topology Table Generator revision. +*/ +#define SSDT_CPU_TOPOLOGY_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the SSDT Cpu Topology Table Generator. +*/ +STATIC +ACPI_CPU_TOPOLOGY_GENERATOR SsdtCpuTopologyGenerator = { + // ACPI table generator header + { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCpuTopology), + // Generator Description + L"ACPI.STD.SSDT.CPU.TOPOLOGY.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision - Unused + 0, + // Minimum ACPI Table Revision - Unused + 0, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SSDT_CPU_TOPOLOGY_GENERATOR_REVISION, + // Build Table function + BuildSsdtCpuTopologyTable, + // Free Resource function + FreeSsdtCpuTopologyTableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL + }, + + // Private fields are defined from here. + + // TokenTable + { + // Table + NULL, + // LastIndex + 0 + }, + // ProcNodeList + NULL, + // ProcNodeCount + 0 +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtCpuTopologyLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SsdtCpuTopologyGenerator.Header); + DEBUG (( + DEBUG_INFO, + "SSDT-CPU-TOPOLOGY: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtCpuTopologyLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SsdtCpuTopologyGenerator.Header); + DEBUG (( + DEBUG_INFO, + "SSDT-CPU-TOPOLOGY: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h new file mode 100644 index 0000000000..6fb44c7e58 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h @@ -0,0 +1,147 @@ +/** @file + SSDT Cpu Topology Table Generator. + + Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors + - ACPI for CoreSight version 1.2 Platform Design Document + (https://developer.arm.com/documentation/den0067/a/?lang=en) + + @par Glossary: + - ETE - Embedded Trace Extension. + - ETM - Embedded Trace Macrocell. +**/ + +#ifndef SSDT_CPU_TOPOLOGY_GENERATOR_H_ +#define SSDT_CPU_TOPOLOGY_GENERATOR_H_ + +#pragma pack(1) + +// Mask for the flags that need to be checked. +#define PPTT_PROCESSOR_MASK ( \ + (EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) | \ + (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \ + (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3)) + +// Mask for the cpu flags. +#define PPTT_CPU_PROCESSOR_MASK ( \ + (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \ + (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \ + (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3)) + +// Mask for the cluster flags. +// Even though a _UID is generated for clusters, it is simpler to use +// EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID and to not match the cluster id of +// the PPTT table (not sure the PPTT table is generated). +#define PPTT_CLUSTER_PROCESSOR_MASK ( \ + (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \ + (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID << 1) | \ + (EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF << 3)) + +// Leaf nodes specific mask. +#define PPTT_LEAF_MASK ((EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \ + (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3)) + +/** LPI states are stored in the ASL namespace at '\_SB_.Lxxx', + with xxx being the node index of the LPI state. +*/ +#define SB_SCOPE "\\_SB_" +#define SB_SCOPE_PREFIX SB_SCOPE "." +/// Size of the SB_SCOPE_PREFIX string. +#define SB_SCOPE_PREFIX_SIZE sizeof (SB_SCOPE_PREFIX) + +/// HID for a processor device. +#define ACPI_HID_PROCESSOR_DEVICE "ACPI0007" + +/// HID for a ETM/ETE device. +#define ACPI_HID_ET_DEVICE "ARMHC500" + +/// HID for a processor container device. +#define ACPI_HID_PROCESSOR_CONTAINER_DEVICE "ACPI0010" + +/** Node names of Cpus and Clusters are 'Cxxx', and 'Lxxx' for LPI states. + The 'xxx' is an index on 12 bits is given to node name, + thus the limitation in the number of nodes. +*/ +#define MAX_NODE_COUNT (1 << 12) + +/** A structure used to handle the Lpi structures referencing. + + A CM_ARCH_COMMON_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF. + This CM_ARCH_COMMON_OBJ_REF references CM_ARCH_COMMON_LPI_INFO structures. + + Example: + (Cpu0) (Cpu1) + CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM_ARCH_COMMON_PROC_HIERARCHY_INFO + | | + +---------------------------------------- + | + v + (List of references to Lpi states) + CM_ARCH_COMMON_OBJ_REF + | + +---------------------------------------- + | | + v v + (A first Lpi state) (A second Lpi state) + CM_ARCH_COMMON_LPI_INFO[0] CM_ARCH_COMMON_LPI_INFO[1] + + Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARCH_COMMON_PROC_HIERARCHY_INFO + structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the + TokenTable such as: + 0 <-> CM_ARCH_COMMON_OBJ_REF + + This will lead to the creation of this pseudo-ASL code where Cpu0 and Cpu1 + return the same object at \_SB.L000: + Scope (\_SB) { + Device (C000) { + [...] + Method (_LPI) { + Return (\_SB.L000) + } + } // C000 + + Device (C001) { + [...] + Method (_LPI) { + Return (\_SB.L000) + } + } // C001 + + // Lpi states + Name (L000, Package (0x05) { + [...] + } + } +*/ +typedef struct TokenTable { + /// TokenTable, a table allowing to map: + /// Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures). + CM_OBJECT_TOKEN *Table; + + /// Last used index of the TokenTable. + /// LastIndex is bound by ProcNodeCount. + UINT32 LastIndex; +} TOKEN_TABLE; + +/** A structure holding the Cpu topology generator and additional private data. +*/ +typedef struct AcpiCpuTopologyGenerator { + /// ACPI Table generator header + ACPI_TABLE_GENERATOR Header; + + // Private fields are defined from here. + + /// Private object used to handle token referencing. + TOKEN_TABLE TokenTable; + /// List of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. + CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNodeList; + /// Count of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects. + UINT32 ProcNodeCount; +} ACPI_CPU_TOPOLOGY_GENERATOR; + +#pragma pack() + +#endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf new file mode 100644 index 0000000000..3e2d154749 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf @@ -0,0 +1,33 @@ +## @file +# Ssdt Cpu Topology Table Generator +# +# Copyright (c) 2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SsdtCpuTopologyLibArm + FILE_GUID = F2835EB6-4B05-48D4-A475-147DA0F3755C + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSsdtCpuTopologyLibConstructor + DESTRUCTOR = AcpiSsdtCpuTopologyLibDestructor + +[Sources] + SsdtCpuTopologyGenerator.c + SsdtCpuTopologyGenerator.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + AcpiHelperLib + AmlLib + BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c new file mode 100644 index 0000000000..2b488016e5 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c @@ -0,0 +1,1247 @@ +/** @file + SSDT Pcie Table Generator. + + Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - PCI Firmware Specification - Revision 3.0 + - ACPI 6.4 specification: + - s6.2.13 "_PRT (PCI Routing Table)" + - s6.1.1 "_ADR (Address)" + - linux kernel code + - Arm Base Boot Requirements v1.0 + - Arm Base System Architecture v1.0 +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SsdtPcieGenerator.h" + +#define PCI_MAX_DEVICE_COUNT_PER_BUS 32 +#define PCI_MAX_FUNCTION_COUNT_PER_DEVICE 8 + +/** ARM standard SSDT Pcie Table Generator. + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjCmRef + - EArchCommonObjPciConfigSpaceInfo + - EArchCommonObjPciAddressMapInfo + - EArchCommonObjPciInterruptMapInfo +*/ + +/** This macro expands to a function that retrieves the cross-CM-object- + reference information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjCmRef, + CM_ARCH_COMMON_OBJ_REF + ); + +/** This macro expands to a function that retrieves the Pci + Configuration Space Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPciConfigSpaceInfo, + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO + ); + +/** This macro expands to a function that retrieves the Pci + Address Mapping Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPciAddressMapInfo, + CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO + ); + +/** This macro expands to a function that retrieves the Pci + Interrupt Mapping Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjPciInterruptMapInfo, + CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO + ); + +/** Initialize the MappingTable. + + @param [in] MappingTable The mapping table structure. + @param [in] Count Number of entries to allocate in the + MappingTable. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +MappingTableInitialize ( + IN MAPPING_TABLE *MappingTable, + IN UINT32 Count + ) +{ + UINT32 *Table; + + if ((MappingTable == NULL) || + (Count == 0)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Table = AllocateZeroPool (sizeof (*Table) * Count); + if (Table == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + MappingTable->Table = Table; + MappingTable->LastIndex = 0; + MappingTable->MaxIndex = Count; + + return EFI_SUCCESS; +} + +/** Free the MappingTable. + + @param [in, out] MappingTable The mapping table structure. +**/ +STATIC +VOID +EFIAPI +MappingTableFree ( + IN OUT MAPPING_TABLE *MappingTable + ) +{ + ASSERT (MappingTable != NULL); + ASSERT (MappingTable->Table != NULL); + + if (MappingTable->Table != NULL) { + FreePool (MappingTable->Table); + } +} + +/** Add a new entry to the MappingTable and return its index. + + If an entry with [Integer] is already available in the table, + return its index without adding a new entry. + + @param [in] MappingTable The mapping table structure. + @param [in] Integer New Integer entry to add. + + @retval The index of the Integer entry in the MappingTable. +**/ +STATIC +UINT32 +EFIAPI +MappingTableAdd ( + IN MAPPING_TABLE *MappingTable, + IN UINT32 Integer + ) +{ + UINT32 *Table; + UINT32 Index; + UINT32 LastIndex; + + ASSERT (MappingTable != NULL); + ASSERT (MappingTable->Table != NULL); + + Table = MappingTable->Table; + LastIndex = MappingTable->LastIndex; + + // Search if there is already an entry with this Integer. + for (Index = 0; Index < LastIndex; Index++) { + if (Table[Index] == Integer) { + return Index; + } + } + + ASSERT (LastIndex < MappingTable->MaxIndex); + + // If no, create a new entry. + Table[LastIndex] = Integer; + + return MappingTable->LastIndex++; +} + +/** Generate required Pci device information. + + ASL code: + Name (_UID, ) // Uid of the Pci device + Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge + Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge + Name (_SEG, ) // PCI Segment Group number + Name (_BBN, ) // PCI Base Bus Number + Name (_CCA, 1) // Initially mark the PCI coherent + + @param [in] PciInfo Pci device information. + @param [in] Uid Unique Id of the Pci device. + @param [in, out] PciNode Pci node to amend. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +GeneratePciDeviceInfo ( + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN UINT32 Uid, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + EFI_STATUS Status; + UINT32 EisaId; + + ASSERT (PciInfo != NULL); + ASSERT (PciNode != NULL); + + // ASL: Name (_UID, ) + Status = AmlCodeGenNameInteger ("_UID", Uid, PciNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_HID, EISAID ("PNP0A08")) + Status = AmlGetEisaIdFromString ("PNP0A08", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameInteger ("_HID", EisaId, PciNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_CID, EISAID ("PNP0A03")) + Status = AmlGetEisaIdFromString ("PNP0A03", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameInteger ("_CID", EisaId, PciNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_SEG, ) + Status = AmlCodeGenNameInteger ( + "_SEG", + PciInfo->PciSegmentGroupNumber, + PciNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_BBN, ) + Status = AmlCodeGenNameInteger ( + "_BBN", + PciInfo->StartBusNumber, + PciNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_CCA, 1) + // Must be aligned with the IORT CCA property in + // "Table 14 Memory access properties" + Status = AmlCodeGenNameInteger ("_CCA", 1, PciNode, NULL); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Generate a _PRT object (Pci Routing Table) for the Pci device. + + Cf. ACPI 6.4 specification, s6.2.13 "_PRT (PCI Routing Table)" + + @param [in] Generator The SSDT Pci generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] PciInfo Pci device information. + @param [in] Uid Unique Id of the Pci device. + @param [in, out] PciNode Pci node to amend. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +GeneratePrt ( + IN ACPI_PCI_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN UINT32 Uid, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + EFI_STATUS Status; + INT32 Index; + AML_OBJECT_NODE_HANDLE PrtNode; + CM_ARCH_COMMON_OBJ_REF *RefInfo; + UINT32 RefCount; + CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *IrqMapInfo; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (PciInfo != NULL); + ASSERT (PciNode != NULL); + + PrtNode = NULL; + + // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the + // CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO objects. + Status = GetEArchCommonObjCmRef ( + CfgMgrProtocol, + PciInfo->InterruptMapToken, + &RefInfo, + &RefCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Initialized DeviceTable. + Status = MappingTableInitialize (&Generator->DeviceTable, RefCount); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler0; + } + + // ASL: Name (_PRT, Package () {}) + Status = AmlCodeGenNamePackage ("_PRT", NULL, &PrtNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + + for (Index = 0; Index < RefCount; Index++) { + // Get CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO structures one by one. + Status = GetEArchCommonObjPciInterruptMapInfo ( + CfgMgrProtocol, + RefInfo[Index].ReferenceToken, + &IrqMapInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + + // Check that the interrupts flags are SPIs, level high. + // Cf. Arm BSA v1.0, sE.6 "Legacy interrupts" + if ((Index > 0) && + (IrqMapInfo->IntcInterrupt.Interrupt >= 32) && + (IrqMapInfo->IntcInterrupt.Interrupt < 1020) && + ((IrqMapInfo->IntcInterrupt.Flags & 0xB) != 0)) + { + Status = EFI_INVALID_PARAMETER; + ASSERT_EFI_ERROR (Status); + goto exit_handler; + } + + // Add the device to the DeviceTable. + MappingTableAdd (&Generator->DeviceTable, IrqMapInfo->PciDevice); + + /* Add a _PRT entry. + ASL + Name (_PRT, Package () { + , + + }) + + Address is set as: + ACPI 6.4 specification, Table 6.2: "ADR Object Address Encodings" + High word-Device #, Low word-Function #. (for example, device 3, + function 2 is 0x00030002). To refer to all the functions on a device #, + use a function number of FFFF). + + Use the second model for _PRT object and describe a hardwired interrupt. + */ + Status = AmlAddPrtEntry ( + (IrqMapInfo->PciDevice << 16) | 0xFFFF, + IrqMapInfo->PciInterrupt, + NULL, + IrqMapInfo->IntcInterrupt.Interrupt, + PrtNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + } // for + + // Attach the _PRT entry. + Status = AmlAttachNode (PciNode, PrtNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto exit_handler; + } + + PrtNode = NULL; + + // Generate the Pci slots once all the device have been added. + Status = GeneratePciSlots (PciInfo, &Generator->DeviceTable, Uid, PciNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + +exit_handler: + MappingTableFree (&Generator->DeviceTable); +exit_handler0: + if (PrtNode != NULL) { + AmlDeleteTree (PrtNode); + } + + return Status; +} + +/** Generate a _CRS method for the Pci device. + + @param [in] Generator The SSDT Pci generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] PciInfo Pci device information. + @param [in, out] PciNode Pci node to amend. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +GeneratePciCrs ( + IN ACPI_PCI_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + EFI_STATUS Status; + BOOLEAN Translation; + UINT32 Index; + CM_ARCH_COMMON_OBJ_REF *RefInfo; + UINT32 RefCount; + CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *AddrMapInfo; + AML_OBJECT_NODE_HANDLE CrsNode; + BOOLEAN IsPosDecode; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (PciInfo != NULL); + ASSERT (PciNode != NULL); + + // ASL: Name (_CRS, ResourceTemplate () {}) + Status = AmlCodeGenNameResourceTemplate ("_CRS", PciNode, &CrsNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: + // WordBusNumber ( // Bus numbers assigned to this root + // ResourceProducer, MinFixed, MaxFixed, PosDecode, + // 0, // AddressGranularity + // , // AddressMinimum - Minimum Bus Number + // , // AddressMaximum - Maximum Bus Number + // 0, // AddressTranslation - Set to 0 + // - + 1 // RangeLength - Number of Busses + // ) + Status = AmlCodeGenRdWordBusNumber ( + FALSE, + TRUE, + TRUE, + TRUE, + 0, + PciInfo->StartBusNumber, + PciInfo->EndBusNumber, + 0, + PciInfo->EndBusNumber - PciInfo->StartBusNumber + 1, + 0, + NULL, + CrsNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the + // CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO objects. + Status = GetEArchCommonObjCmRef ( + CfgMgrProtocol, + PciInfo->AddressMapToken, + &RefInfo, + &RefCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + for (Index = 0; Index < RefCount; Index++) { + // Get CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO structures one by one. + Status = GetEArchCommonObjPciAddressMapInfo ( + CfgMgrProtocol, + RefInfo[Index].ReferenceToken, + &AddrMapInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Translation = (AddrMapInfo->CpuAddress != AddrMapInfo->PciAddress); + if (AddrMapInfo->CpuAddress >= AddrMapInfo->PciAddress) { + IsPosDecode = TRUE; + } else { + IsPosDecode = FALSE; + } + + switch (AddrMapInfo->SpaceCode) { + case PCI_SS_IO: + Status = AmlCodeGenRdQWordIo ( + FALSE, + TRUE, + TRUE, + IsPosDecode, + 3, + 0, + AddrMapInfo->PciAddress, + AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, + Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, + AddrMapInfo->AddressSize, + 0, + NULL, + TRUE, + FALSE, + CrsNode, + NULL + ); + break; + + case PCI_SS_M32: + Status = AmlCodeGenRdDWordMemory ( + FALSE, + IsPosDecode, + TRUE, + TRUE, + AmlMemoryCacheable, + TRUE, + 0, + AddrMapInfo->PciAddress, + AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, + Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, + AddrMapInfo->AddressSize, + 0, + NULL, + AmlAddressRangeMemory, + TRUE, + CrsNode, + NULL + ); + break; + + case PCI_SS_M64: + Status = AmlCodeGenRdQWordMemory ( + FALSE, + IsPosDecode, + TRUE, + TRUE, + AmlMemoryCacheable, + TRUE, + 0, + AddrMapInfo->PciAddress, + AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, + Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, + AddrMapInfo->AddressSize, + 0, + NULL, + AmlAddressRangeMemory, + TRUE, + CrsNode, + NULL + ); + break; + + default: + Status = EFI_INVALID_PARAMETER; + } // switch + + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } // for + + return Status; +} + +/** Generate a RES0 device node to reserve PNP motherboard resources + for a given PCI node. + + @param [in] PciNode Parent PCI node handle of the generated + resource object. + @param [out] CrsNode CRS node of the AML tree to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid input parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +GenerateMotherboardDevice ( + IN AML_OBJECT_NODE_HANDLE PciNode, + OUT AML_OBJECT_NODE_HANDLE *CrsNode + ) +{ + EFI_STATUS Status; + UINT32 EisaId; + AML_OBJECT_NODE_HANDLE ResNode; + + if (CrsNode == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // ASL: Device (RES0) {} + Status = AmlCodeGenDevice ("RES0", PciNode, &ResNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_HID, EISAID ("PNP0C02")) + Status = AmlGetEisaIdFromString ("PNP0C02", &EisaId); /* PNP Motherboard Resources */ + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameInteger ("_HID", EisaId, ResNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // ASL: Name (_CRS, ResourceTemplate () {}) + Status = AmlCodeGenNameResourceTemplate ("_CRS", ResNode, CrsNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + return Status; +} + +/** Reserves ECAM space for PCI config space + + @param [in] Generator The SSDT Pci generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] PciInfo Pci device information. + @param [in, out] PciNode RootNode of the AML tree to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +ReserveEcamSpace ( + IN ACPI_PCI_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + EFI_STATUS Status; + AML_OBJECT_NODE_HANDLE CrsNode; + UINT64 AddressMinimum; + UINT64 AddressMaximum; + + Status = GenerateMotherboardDevice (PciNode, &CrsNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + AddressMinimum = PciInfo->BaseAddress + (PciInfo->StartBusNumber * + PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB); + AddressMaximum = PciInfo->BaseAddress + ((PciInfo->EndBusNumber + 1) * + PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB) - 1; + + Status = AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + AmlMemoryNonCacheable, + TRUE, + 0, + AddressMinimum, + AddressMaximum, + 0, // no translation + AddressMaximum - AddressMinimum + 1, + 0, + NULL, + AmlAddressRangeMemory, + TRUE, + CrsNode, + NULL + ); + + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + return Status; +} + +/** Generate a Pci device. + + @param [in] Generator The SSDT Pci generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] PciInfo Pci device information. + @param [in] Uid Unique Id of the Pci device. + @param [in, out] RootNode RootNode of the AML tree to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +GeneratePciDevice ( + IN ACPI_PCI_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN UINT32 Uid, + IN OUT AML_ROOT_NODE_HANDLE *RootNode + ) +{ + EFI_STATUS Status; + + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + AML_OBJECT_NODE_HANDLE ScopeNode; + AML_OBJECT_NODE_HANDLE PciNode; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (PciInfo != NULL); + ASSERT (RootNode != NULL); + + PciNode = NULL; + + // ASL: Scope (\_SB) {} + Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Write the name of the PCI device. + CopyMem (AslName, "PCIx", AML_NAME_SEG_SIZE + 1); + AslName[AML_NAME_SEG_SIZE - 1] = AsciiFromHex (Uid & 0xF); + if (Uid > 0xF) { + AslName[AML_NAME_SEG_SIZE - 2] = AsciiFromHex ((Uid >> 4) & 0xF); + } + + // ASL: Device (PCIx) {} + Status = AmlCodeGenDevice (AslName, ScopeNode, &PciNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Populate the PCIx node with some Id values. + Status = GeneratePciDeviceInfo (PciInfo, Uid, PciNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Generate the Pci Routing Table (_PRT). + if (PciInfo->InterruptMapToken != CM_NULL_TOKEN) { + Status = GeneratePrt ( + Generator, + CfgMgrProtocol, + PciInfo, + Uid, + PciNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } + + // Generate the _CRS method. + Status = GeneratePciCrs (Generator, CfgMgrProtocol, PciInfo, PciNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the PNP Motherboard Resources Device to reserve ECAM space + Status = ReserveEcamSpace (Generator, CfgMgrProtocol, PciInfo, PciNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the template _OSC method. + Status = AddOscMethod (PciInfo, PciNode); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** Build an Ssdt table describing a Pci device. + + @param [in] Generator The SSDT Pci generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] PciInfo Pci device information. + @param [in] Uid Unique Id of the Pci device. + @param [out] Table If success, contains the created SSDT table. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSsdtPciTable ( + IN ACPI_PCI_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo, + IN UINT32 Uid, + OUT EFI_ACPI_DESCRIPTION_HEADER **Table + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + AML_ROOT_NODE_HANDLE RootNode; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (PciInfo != NULL); + ASSERT (Table != NULL); + + // Create a new Ssdt table. + Status = AddSsdtAcpiHeader ( + CfgMgrProtocol, + &Generator->Header, + AcpiTableInfo, + &RootNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = GeneratePciDevice ( + Generator, + CfgMgrProtocol, + PciInfo, + Uid, + RootNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + + // Serialize the tree. + Status = AmlSerializeDefinitionBlock ( + RootNode, + Table + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to Serialize SSDT Table Data." + " Status = %r\n", + Status + )); + } + +exit_handler: + // Cleanup + Status1 = AmlDeleteTree (RootNode); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to cleanup AML tree." + " Status = %r\n", + Status1 + )); + // If Status was success but we failed to delete the AML Tree + // return Status1 else return the original error code, i.e. Status. + if (!EFI_ERROR (Status)) { + return Status1; + } + } + + return Status; +} + +/** Construct SSDT tables describing Pci root complexes. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResourcesEx function. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to a list of generated ACPI table(s). + @param [out] TableCount Number of generated ACPI table(s). + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Could not find information. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. + @retval EFI_UNSUPPORTED Unsupported configuration. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSsdtPciTableEx ( + IN CONST ACPI_TABLE_GENERATOR *This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, + OUT UINTN *CONST TableCount + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo; + UINT32 PciCount; + UINTN Index; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + ACPI_PCI_GENERATOR *Generator; + UINT32 Uid; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + *TableCount = 0; + Generator = (ACPI_PCI_GENERATOR *)This; + + Status = GetEArchCommonObjPciConfigSpaceInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PciInfo, + &PciCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (PciCount > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Too many Pci root complexes: %d." + " Maximum Pci root complexes supported = %d.\n", + PciCount, + MAX_PCI_ROOT_COMPLEXES_SUPPORTED + )); + return EFI_INVALID_PARAMETER; + } + + // Allocate a table to store pointers to the SSDT tables. + TableList = (EFI_ACPI_DESCRIPTION_HEADER **) + AllocateZeroPool ( + (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * PciCount) + ); + if (TableList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to allocate memory for Table List." + " Status = %r\n", + Status + )); + return Status; + } + + // Setup the table list early so that appropriate cleanup + // can be done in case of failure. + *Table = TableList; + + for (Index = 0; Index < PciCount; Index++) { + if (PcdGetBool (PcdPciUseSegmentAsUid)) { + Uid = PciInfo[Index].PciSegmentGroupNumber; + if (Uid > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Pci root complexes segment number: %d." + " Greater than maximum number of Pci root complexes supported = %d.\n", + Uid, + MAX_PCI_ROOT_COMPLEXES_SUPPORTED + )); + return EFI_INVALID_PARAMETER; + } + } else { + Uid = Index; + } + + // Build a SSDT table describing the Pci devices. + Status = BuildSsdtPciTable ( + Generator, + CfgMgrProtocol, + AcpiTableInfo, + &PciInfo[Index], + Uid, + &TableList[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to build associated SSDT table." + " Status = %r\n", + Status + )); + goto error_handler; + } + + *TableCount += 1; + } // for + +error_handler: + // Note: Table list and Table count have been setup. The + // error handler does nothing here as the framework will invoke + // FreeSsdtPciTableEx () even on failure. + return Status; +} + +/** Free any resources allocated for constructing the tables. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to ACPI Table(s). + @param [in] TableCount Number of ACPI table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeSsdtPciTableEx ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, + IN CONST UINTN TableCount + ) +{ + EFI_ACPI_DESCRIPTION_HEADER **TableList; + UINTN Index; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || + (*Table == NULL) || + (TableCount == 0)) + { + DEBUG ((DEBUG_ERROR, "ERROR: SSDT-PCI: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + TableList = *Table; + for (Index = 0; Index < TableCount; Index++) { + if ((TableList[Index] != NULL) && + (TableList[Index]->Signature == + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) + { + FreePool (TableList[Index]); + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Could not free SSDT table at index %d.", + Index + )); + return EFI_INVALID_PARAMETER; + } + } // for + + // Free the table list. + FreePool (*Table); + + return EFI_SUCCESS; +} + +/** This macro defines the SSDT Pci Table Generator revision. +*/ +#define SSDT_PCI_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the SSDT Pci Table Generator. +*/ +STATIC +ACPI_PCI_GENERATOR SsdtPcieGenerator = { + // ACPI table generator header + { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress), + // Generator Description + L"ACPI.STD.SSDT.PCI.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision - Unused + 0, + // Minimum ACPI Table Revision - Unused + 0, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SSDT_PCI_GENERATOR_REVISION, + // Build table function. Use the extended version instead. + NULL, + // Free table function. Use the extended version instead. + NULL, + // Extended Build table function. + BuildSsdtPciTableEx, + // Extended free function. + FreeSsdtPciTableEx + }, + + // Private fields are defined from here. + + // DeviceTable + { + // Table + NULL, + // LastIndex + 0, + // MaxIndex + 0 + }, +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtPcieLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SsdtPcieGenerator.Header); + DEBUG (( + DEBUG_INFO, + "SSDT-PCI: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtPcieLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SsdtPcieGenerator.Header); + DEBUG (( + DEBUG_INFO, + "SSDT-PCI: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h new file mode 100644 index 0000000000..7410f9ffd4 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h @@ -0,0 +1,55 @@ +/** @file + SSDT Pcie Table Generator. + + Copyright (c) 2021, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - PCI Firmware Specification - Revision 3.0 + - ACPI 6.4 specification: + - s6.2.13 "_PRT (PCI Routing Table)" + - s6.1.1 "_ADR (Address)" + - linux kernel code + - Arm Base Boot Requirements v1.0 +**/ + +#ifndef SSDT_PCIE_GENERATOR_H_ +#define SSDT_PCIE_GENERATOR_H_ + +/** Pci address attributes. + + This can also be denoted as space code, address space or ss. +*/ +#define PCI_SS_CONFIG 0 +#define PCI_SS_IO 1 +#define PCI_SS_M32 2 +#define PCI_SS_M64 3 + +/** Maximum Pci root complexes supported by this generator. + + Note: This is not a hard limitation and can be extended if needed. + Corresponding changes would be needed to support the Name and + UID fields describing the Pci root complexes. +*/ +#define MAX_PCI_ROOT_COMPLEXES_SUPPORTED 256 + +// _SB scope of the AML namespace. +#define SB_SCOPE "\\_SB_" + +#pragma pack(1) + +/** A structure holding the Pcie generator and additional private data. +*/ +typedef struct AcpiPcieGenerator { + /// ACPI Table generator header + ACPI_TABLE_GENERATOR Header; + + // Private fields are defined from here. + + /// Table to map: Index <-> Pci device + MAPPING_TABLE DeviceTable; +} ACPI_PCI_GENERATOR; + +#pragma pack() + +#endif // SSDT_PCIE_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf new file mode 100644 index 0000000000..c2a1acb570 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf @@ -0,0 +1,35 @@ +## @file +# Ssdt Serial Port Table Generator +# +# Copyright (c) 2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SsdtPcieLibArm + FILE_GUID = E431D7FD-26BF-4E3D-9064-5B13B0439057 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSsdtPcieLibConstructor + DESTRUCTOR = AcpiSsdtPcieLibDestructor + +[Sources] + SsdtPcieGenerator.c + SsdtPcieGenerator.h + +[Packages] + DynamicTablesPkg/DynamicTablesPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + AcpiHelperLib + AmlLib + BaseLib + SsdtPcieSupportLib + +[Pcd] + gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdPciUseSegmentAsUid diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c new file mode 100644 index 0000000000..671ba05740 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c @@ -0,0 +1,373 @@ +/** @file + SSDT Serial Port Table Generator. + + Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include + +/** ARM standard SSDT Serial Port Table Generator + + Constructs SSDT tables describing serial ports (other than the serial ports + used by the SPCR or DBG2 tables). + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArchCommonObjSerialPortInfo +*/ + +/** This macro expands to a function that retrieves the Serial-port + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjSerialPortInfo, + CM_ARCH_COMMON_SERIAL_PORT_INFO + ); + +/** Starting value for the UID to represent the serial ports. + Note: The UID 0 and 1 are reserved for use by DBG2 port and SPCR + respectively. So, the UIDs for serial ports for general use + start at 2. +*/ +#define SERIAL_PORT_START_UID 2 + +/** Maximum serial ports supported by this generator. + This generator supports a maximum of 14 (16 - 2) serial ports. + The -2 here reflects the reservation for serial ports for the DBG2 + and SPCR ports regardless of whether the DBG2 or SPCR port is enabled. + Note: This is not a hard limitation and can be extended if needed. + Corresponding changes would be needed to support the Name and + UID fields describing the serial port. + +*/ +#define MAX_SERIAL_PORTS_SUPPORTED 14 + +/** Free any resources allocated for constructing the tables. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to ACPI Table(s). + @param [in] TableCount Number of ACPI table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeSsdtSerialPortTableEx ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table, + IN CONST UINTN TableCount + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + UINTN Index; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || + (*Table == NULL) || + (TableCount == 0)) + { + DEBUG ((DEBUG_ERROR, "ERROR: SSDT-SERIAL-PORT: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + TableList = *Table; + + for (Index = 0; Index < TableCount; Index++) { + if ((TableList[Index] != NULL) && + (TableList[Index]->Signature == + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) + { + Status = FreeSsdtSerialPortTable (TableList[Index]); + } else { + Status = EFI_INVALID_PARAMETER; + } + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-SERIAL-PORT: Could not free SSDT table at index %d." + " Status = %r\n", + Index, + Status + )); + return Status; + } + } // for + + // Free the table list. + FreePool (*Table); + + return EFI_SUCCESS; +} + +/** Construct SSDT tables describing serial-ports. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResourcesEx function. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to a list of generated ACPI table(s). + @param [out] TableCount Number of generated ACPI table(s). + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Could not find information. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. + @retval EFI_UNSUPPORTED Unsupported configuration. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSsdtSerialPortTableEx ( + IN CONST ACPI_TABLE_GENERATOR *This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER ***Table, + OUT UINTN *CONST TableCount + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo; + UINT32 SerialPortCount; + UINTN Index; + CHAR8 NewName[AML_NAME_SEG_SIZE + 1]; + UINT64 Uid; + EFI_ACPI_DESCRIPTION_HEADER **TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + *Table = NULL; + + Status = GetEArchCommonObjSerialPortInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SerialPortInfo, + &SerialPortCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-SERIAL-PORT: Failed to get serial port information." + " Status = %r\n", + Status + )); + return Status; + } + + if (SerialPortCount > MAX_SERIAL_PORTS_SUPPORTED) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-SERIAL-PORT: Too many serial ports: %d." + " Maximum serial ports supported = %d.\n", + SerialPortCount, + MAX_SERIAL_PORTS_SUPPORTED + )); + return EFI_INVALID_PARAMETER; + } + + // Validate the SerialPort info. + Status = ValidateSerialPortInfo (SerialPortInfo, SerialPortCount); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-SERIAL-PORT: Invalid serial port information. Status = %r\n", + Status + )); + return Status; + } + + // Allocate a table to store pointers to the SSDT tables. + TableList = (EFI_ACPI_DESCRIPTION_HEADER **) + AllocateZeroPool ( + (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * SerialPortCount) + ); + if (TableList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-SERIAL-PORT: Failed to allocate memory for Table List." + " Status = %r\n", + Status + )); + return Status; + } + + // Setup the table list early so that appropriate cleanup + // can be done in case of failure. + *Table = TableList; + + NewName[0] = 'C'; + NewName[1] = 'O'; + NewName[2] = 'M'; + NewName[4] = '\0'; + for (Index = 0; Index < SerialPortCount; Index++) { + Uid = SERIAL_PORT_START_UID + Index; + NewName[3] = AsciiFromHex ((UINT8)(Uid)); + + // Build a SSDT table describing the serial port. + Status = BuildSsdtSerialPortTable ( + AcpiTableInfo, + &SerialPortInfo[Index], + NewName, + Uid, + &TableList[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-SERIAL-PORT: Failed to build associated SSDT table." + " Status = %r\n", + Status + )); + goto error_handler; + } + + // Increment the table count here so that appropriate cleanup + // can be done in case of failure. + *TableCount += 1; + } // for + +error_handler: + // Note: Table list and Serial port count has been setup. The + // error handler does nothing here as the framework will invoke + // FreeSsdtSerialPortTableEx() even on failure. + return Status; +} + +/** This macro defines the SSDT Serial Port Table Generator revision. +*/ +#define SSDT_SERIAL_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the SSDT Serial Port Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR SsdtSerialPortGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtSerialPort), + // Generator Description + L"ACPI.STD.SSDT.SERIAL.PORT.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision - Unused + 0, + // Minimum ACPI Table Revision - Unused + 0, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SSDT_SERIAL_GENERATOR_REVISION, + // Build table function. Use the extended version instead. + NULL, + // Free table function. Use the extended version instead. + NULL, + // Extended Build table function. + BuildSsdtSerialPortTableEx, + // Extended free function. + FreeSsdtSerialPortTableEx +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtSerialPortLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SsdtSerialPortGenerator); + DEBUG (( + DEBUG_INFO, + "SSDT-SERIAL-PORT: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtSerialPortLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SsdtSerialPortGenerator); + DEBUG (( + DEBUG_INFO, + "SSDT-SERIAL-PORT: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf new file mode 100644 index 0000000000..36e61ea9b1 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf @@ -0,0 +1,33 @@ +## @file +# Ssdt Serial Port Table Generator +# +# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SsdtSerialPortLibArm + FILE_GUID = D1F92325-2DFB-435C-9B4C-A6B864F19230 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSsdtSerialPortLibConstructor + DESTRUCTOR = AcpiSsdtSerialPortLibDestructor + +[Sources] + SsdtSerialPortGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + AcpiHelperLib + AmlLib + BaseLib + SsdtSerialPortFixupLib -- cgit From b242de55e216f545da00b7f0bd0eb386bcfb780f Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: Acpi: Prepare common libraries to support other archs Allow other architectures to reuse ACPI common libraries by: - Removing the Arm prefix from the BASE_NAME - Moving Arm specific libraries/packages to ARM/AARCH64 specific sections in the .inf files Also remove the empty .inf sections. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf | 15 +++++++-------- .../Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf | 9 +-------- .../Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf | 9 +-------- .../Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf | 2 +- .../Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf | 2 +- .../Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf | 9 +-------- .../Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf | 9 +-------- .../Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf | 2 +- .../Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf | 6 ++++-- .../Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf | 2 +- .../Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf | 6 ++++-- 11 files changed, 23 insertions(+), 48 deletions(-) diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf index f7b7c1c025..32dcd20c08 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x00010019 - BASE_NAME = AcpiDbg2LibArm + BASE_NAME = AcpiDbg2Lib FILE_GUID = A17BA4F0-3DEB-4FE5-BD27-EC008E541B22 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -19,16 +19,20 @@ [Sources] Dbg2Generator.c +[Packages.ARM, Packages.AARCH64] + ArmPlatformPkg/ArmPlatformPkg.dec + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec DynamicTablesPkg/DynamicTablesPkg.dec +[LibraryClasses.ARM, LibraryClasses.AARCH64] + PL011UartLib + [LibraryClasses] BaseLib - PL011UartLib SsdtSerialPortFixupLib [FixedPcd] @@ -36,8 +40,3 @@ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf index 8fe34013d4..c9cd850faa 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x00010019 - BASE_NAME = AcpiFadtLibArm + BASE_NAME = AcpiFadtLib FILE_GUID = 686FE5FE-B944-485F-8B1C-7D60E0056487 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -27,10 +27,3 @@ [LibraryClasses] BaseLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf index 1c7f085274..36c343d387 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x00010019 - BASE_NAME = AcpiMcfgLibArm + BASE_NAME = AcpiMcfgLib FILE_GUID = 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -27,10 +27,3 @@ [LibraryClasses] BaseLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf index da54585c2d..666bdcab22 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x0001001B - BASE_NAME = AcpiPcctLibArm + BASE_NAME = AcpiPcctLib FILE_GUID = 38FE945C-D6ED-4CD6-8D20-FCEF3260D15A VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf index 2c7d19513d..a1c91a6eab 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x0001001B - BASE_NAME = AcpiPpttLibArm + BASE_NAME = AcpiPpttLib FILE_GUID = FA102D52-5A92-4F95-A097-1D53F9CF5959 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf index f2ab1b7111..8b461ea05b 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x00010019 - BASE_NAME = AcpiRawLibArm + BASE_NAME = AcpiRawLib FILE_GUID = 20F31568-D687-49BA-B326-CCD9D38EDE16 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -27,10 +27,3 @@ [LibraryClasses] BaseLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf index e11f878ec8..80a61022da 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x00010019 - BASE_NAME = AcpiSpcrLibArm + BASE_NAME = AcpiSpcrLib FILE_GUID = 55088136-7B78-4974-B1EE-F630150D0DE7 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -28,10 +28,3 @@ [LibraryClasses] BaseLib SsdtSerialPortFixupLib - -[Pcd] - -[Protocols] - -[Guids] - diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf index 5891dc4d1c..2f23f4e668 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x0001001B - BASE_NAME = AcpiSratLibArm + BASE_NAME = AcpiSratLib FILE_GUID = 2CE21E0A-A39C-4B26-BC0E-526178036ACD VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf index 3e2d154749..2d38fb30fb 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x0001001B - BASE_NAME = SsdtCpuTopologyLibArm + BASE_NAME = SsdtCpuTopologyLib FILE_GUID = F2835EB6-4B05-48D4-A475-147DA0F3755C VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -20,11 +20,13 @@ SsdtCpuTopologyGenerator.c SsdtCpuTopologyGenerator.h +[Packages.ARM, Packages.AARCH64] + ArmPlatformPkg/ArmPlatformPkg.dec + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec DynamicTablesPkg/DynamicTablesPkg.dec [LibraryClasses] diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf index c2a1acb570..440b0d7212 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x0001001B - BASE_NAME = SsdtPcieLibArm + BASE_NAME = SsdtPcieLib FILE_GUID = E431D7FD-26BF-4E3D-9064-5B13B0439057 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf index 36e61ea9b1..24d7db5645 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf @@ -8,7 +8,7 @@ [Defines] INF_VERSION = 0x0001001B - BASE_NAME = SsdtSerialPortLibArm + BASE_NAME = SsdtSerialPortLib FILE_GUID = D1F92325-2DFB-435C-9B4C-A6B864F19230 VERSION_STRING = 1.0 MODULE_TYPE = DXE_DRIVER @@ -19,11 +19,13 @@ [Sources] SsdtSerialPortGenerator.c +[Packages.ARM, Packages.AARCH64] + ArmPlatformPkg/ArmPlatformPkg.dec + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec DynamicTablesPkg/DynamicTablesPkg.dec [LibraryClasses] -- cgit From e69e1eea2c30d986297e59c208474da11c8629da Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: AcpiFadtLib: Prepare to support other archs Allow other architectures to reuse the AcpiFadtLib by extracting the Arm specific part of the table generation. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf | 7 ++ .../Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c | 126 +++++++++++++++++++++ .../Acpi/Common/AcpiFadtLib/FadtGenerator.c | 86 ++------------ .../Acpi/Common/AcpiFadtLib/FadtGenerator.h | 35 ++++++ .../Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c | 47 ++++++++ 5 files changed, 225 insertions(+), 76 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf index c9cd850faa..67c7fdbd23 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf @@ -18,6 +18,13 @@ [Sources] FadtGenerator.c + FadtGenerator.h + +[Sources.ARM, Sources.AARCH64] + Arm/ArmFadtGenerator.c + +[Sources.IA32, Sources.X64] + FadtGeneratorNull.c [Packages] MdePkg/MdePkg.dec diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c new file mode 100644 index 0000000000..2d2afe98ab --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c @@ -0,0 +1,126 @@ +/** @file + ARM FADT Table Helpers + + Copyright (c) 2017 - 2023, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification, Aug 29, 2022 + +**/ + +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include "FadtGenerator.h" + +/** ARM Standard FADT Generator + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArmObjBootArchInfo +*/ + +/** This macro expands to a function that retrieves the Boot + Architecture Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjBootArchInfo, + CM_ARM_BOOT_ARCH_INFO + ); + +/** This macro defines the FADT flag options for ARM Platforms. +*/ +#define FADT_FLAGS (EFI_ACPI_6_5_HW_REDUCED_ACPI | \ + EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE) + +/** Updates the Architecture specific information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Fadt Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +ArmFadtBootArchInfoUpdate ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt + ) +{ + EFI_STATUS Status; + CM_ARM_BOOT_ARCH_INFO *BootArchInfo; + + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Fadt != NULL); + + // Get the Boot Architecture flags from the Platform Configuration Manager + Status = GetEArmObjBootArchInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &BootArchInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n", + Status + )); + return Status; + } + + DEBUG (( + DEBUG_INFO, + "FADT BootArchFlag = 0x%x\n", + BootArchInfo->BootArchFlags + )); + + Fadt->ArmBootArch = BootArchInfo->BootArchFlags; + + return Status; +} + +/** Updates the Architecture specific information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Fadt Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +FadtArchUpdate ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt + ) +{ + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Fadt != NULL); + + Fadt->Flags = FADT_FLAGS; + + return ArmFadtBootArchInfoUpdate (CfgMgrProtocol, Fadt); +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c index 470f1acfd1..c2140ef414 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c @@ -19,22 +19,17 @@ #include #include #include +#include "FadtGenerator.h" -/** ARM standard FADT Generator +/** Standard FADT Generator Requirements: The following Configuration Manager Object(s) are required by this Generator: - EArchCommonObjPowerManagementProfileInfo - - EArmObjBootArchInfo - EArchCommonObjHypervisorVendorIdentity (OPTIONAL) */ -/** This macro defines the FADT flag options for ARM Platforms. -*/ -#define FADT_FLAGS (EFI_ACPI_6_5_HW_REDUCED_ACPI | \ - EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE) - /** This macro defines the valid mask for the FADT flag option if HW_REDUCED_ACPI flag in the table is set. @@ -159,13 +154,13 @@ EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = { // UINT8 Reserved1 0, // UINT32 Flags - FADT_FLAGS, + 0, // EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg NULL_GAS, // UINT8 ResetValue 0, // UINT16 ArmBootArch - EFI_ACPI_6_5_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags + 0, // {Template}: ARM Boot Architecture Flags // UINT8 MinorRevision EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, // {Template} // UINT64 XFirmwareCtrl @@ -207,15 +202,6 @@ GET_OBJECT_LIST ( CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO ); -/** This macro expands to a function that retrieves the Boot - Architecture Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjBootArchInfo, - CM_ARM_BOOT_ARCH_INFO - ); - /** This macro expands to a function that retrieves the Hypervisor Vendor ID from the Configuration Manager. */ @@ -287,58 +273,6 @@ error_handler: return Status; } -/** Updates the Boot Architecture information in the FADT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -FadtAddBootArchInfo ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - CM_ARM_BOOT_ARCH_INFO *BootArchInfo; - - ASSERT (CfgMgrProtocol != NULL); - - // Get the Boot Architecture flags from the Platform Configuration Manager - Status = GetEArmObjBootArchInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &BootArchInfo, - NULL - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n", - Status - )); - goto error_handler; - } - - DEBUG (( - DEBUG_INFO, - "FADT BootArchFlag = 0x%x\n", - BootArchInfo->BootArchFlags - )); - - AcpiFadt.ArmBootArch = BootArchInfo->BootArchFlags; - -error_handler: - return Status; -} - /** Update the Hypervisor Vendor ID in the FADT Table. @param [in] CfgMgrProtocol Pointer to the Configuration Manager @@ -577,12 +511,6 @@ BuildFadtTable ( goto error_handler; } - // Update BootArch Info - Status = FadtAddBootArchInfo (CfgMgrProtocol); - if (EFI_ERROR (Status)) { - goto error_handler; - } - // Add the Hypervisor Vendor Id if present // Note if no hypervisor is present the zero bytes // will be placed in this field. @@ -623,6 +551,12 @@ BuildFadtTable ( } } + // Update Arch specific Info + Status = FadtArchUpdate (CfgMgrProtocol, &AcpiFadt); + if (EFI_ERROR (Status)) { + goto error_handler; + } + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiFadt; error_handler: return Status; diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h new file mode 100644 index 0000000000..08ac59e006 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h @@ -0,0 +1,35 @@ +/** @file + FADT Table Generator + + Copyright (c) 2017 - 2023, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification, Aug 29, 2022 + +**/ + +#ifndef FADT_GENERATOR_H_ +#define FADT_GENERATOR_H_ + +/** Updates the Architecture specific information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Fadt Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +FadtArchUpdate ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt + ); + +#endif // FADT_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c new file mode 100644 index 0000000000..7868aae742 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c @@ -0,0 +1,47 @@ +/** @file + Common FADT Table Helpers + + Copyright (c) 2017 - 2023, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification, Aug 29, 2022 + +**/ + +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include "FadtGenerator.h" + +/** Updates the Architecture specific information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Fadt Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Success. + @retval EFI_UNSUPPORTED Unsupported. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +FadtArchUpdate ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt + ) +{ + // Not implemented. + return EFI_UNSUPPORTED; +} -- cgit From 2e6076edafe50a8e55501b4f9b1eb839e3d07aea Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: AcpiDbg2Lib: Prepare to support other archs Allow other architectures to reuse the AcpiDbg2Lib by extracting the Arm specific part of the table generation. Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf | 7 +++ .../Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c | 67 ++++++++++++++++++++++ .../Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c | 24 +++++--- .../Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h | 56 ++++++++++++++++++ .../Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c | 60 +++++++++++++++++++ 5 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf index 32dcd20c08..ed049ea4a2 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf @@ -18,6 +18,13 @@ [Sources] Dbg2Generator.c + Dbg2Generator.h + +[Sources.ARM, Sources.AARCH64] + Arm/ArmDbg2Generator.c + +[Sources.IA32, Sources.X86] + Dbg2GeneratorNull.c [Packages.ARM, Packages.AARCH64] ArmPlatformPkg/ArmPlatformPkg.dec diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c new file mode 100644 index 0000000000..a063f49829 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c @@ -0,0 +1,67 @@ +/** @file + Arm DBG2 Table Generator + + Copyright (c) 2024, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015. +**/ + +#include +#include +#include +#include "Dbg2Generator.h" + +/** + Initialise the serial port to the specified settings. + The serial port is re-configured only if the specified settings + are different from the current settings. + All unspecified settings will be set to the default values. + + @param SerialPortInfo CM_ARCH_COMMON_SERIAL_PORT_INFO object describing + the serial port. + @param BaudRate The baud rate of the serial device. If the + baud rate is not supported, the speed will be + reduced to the nearest supported one and the + variable's value will be updated accordingly. + @param ReceiveFifoDepth The number of characters the device will + buffer on input. Value of 0 will use the + device's default FIFO depth. + @param Parity If applicable, this is the EFI_PARITY_TYPE + that is computed or checked as each character + is transmitted or received. If the device + does not support parity, the value is the + default parity value. + @param DataBits The number of data bits in each character. + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number + of stop bits per character. + If the device does not support stop bits, the + value is the default stop bit value. + + @retval RETURN_SUCCESS All attributes were set correctly on the + serial device. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an + unsupported value. +**/ +RETURN_STATUS +EFIAPI +Dbg2InitializePort ( + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + return PL011UartInitializePort ( + (UINTN)SerialPortInfo->BaseAddress, + SerialPortInfo->Clock, + BaudRate, + ReceiveFifoDepth, + Parity, + DataBits, + StopBits + ); +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c index fbf2ba3733..6f49e6a270 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -26,9 +25,11 @@ #include #include +#include "Dbg2Generator.h" + /** ARM standard DBG2 Table Generator - Constructs the DBG2 table for PL011 or SBSA UART peripherals. + Constructs the DBG2 table for corresponding DBG2 peripheral. Requirements: The following Configuration Manager Object(s) are required by @@ -169,7 +170,7 @@ DBG2_TABLE AcpiDbg2 = { DBG2_DEBUG_PORT_DDI ( 0, // {Template}: Serial Port Subtype 0, // {Template}: Serial Port Base Address - PL011_UART_LENGTH, + 0, // {Template}: Serial Port Base Address Size NAMESPACE_STR_DBG_PORT0 ) } @@ -186,7 +187,7 @@ GET_OBJECT_LIST ( CM_ARCH_COMMON_SERIAL_PORT_INFO ); -/** Initialize the PL011/SBSA UART with the parameters obtained from +/** Initialize the DBG2 UART with the parameters obtained from the Configuration Manager. @param [in] SerialPortInfo Pointer to the Serial Port Information. @@ -218,9 +219,8 @@ SetupDebugUart ( StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); BaudRate = SerialPortInfo->BaudRate; - Status = PL011UartInitializePort ( - (UINTN)SerialPortInfo->BaseAddress, - SerialPortInfo->Clock, + Status = Dbg2InitializePort ( + SerialPortInfo, &BaudRate, &ReceiveFifoDepth, &Parity, @@ -460,6 +460,9 @@ BuildDbg2TableEx ( (SerialPortInfo->PortSubtype == EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART)) { + // Setup the PL011 length. + AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].AddressSize = PL011_UART_LENGTH; + // Initialize the serial port Status = SetupDebugUart (SerialPortInfo); if (EFI_ERROR (Status)) { @@ -470,6 +473,13 @@ BuildDbg2TableEx ( )); goto error_handler; } + } else if ((SerialPortInfo->PortSubtype == + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS)) + { + AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].AddressSize = SIZE_4KB; + } else { + // Try to catch other serial ports, but don't return an error. + ASSERT (0); } TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiDbg2; diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h new file mode 100644 index 0000000000..5424be47b8 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h @@ -0,0 +1,56 @@ +/** @file + DBG2 Table Generator + + Copyright (c) 2024, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015. +**/ + +#ifndef DBG2_GENERATOR_H_ +#define DBG2_GENERATOR_H_ + +/** + Initialise the serial port to the specified settings. + The serial port is re-configured only if the specified settings + are different from the current settings. + All unspecified settings will be set to the default values. + + @param SerialPortInfo CM_ARCH_COMMON_SERIAL_PORT_INFO object describing + the serial port. + @param BaudRate The baud rate of the serial device. If the + baud rate is not supported, the speed will be + reduced to the nearest supported one and the + variable's value will be updated accordingly. + @param ReceiveFifoDepth The number of characters the device will + buffer on input. Value of 0 will use the + device's default FIFO depth. + @param Parity If applicable, this is the EFI_PARITY_TYPE + that is computed or checked as each character + is transmitted or received. If the device + does not support parity, the value is the + default parity value. + @param DataBits The number of data bits in each character. + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number + of stop bits per character. + If the device does not support stop bits, the + value is the default stop bit value. + + @retval RETURN_SUCCESS All attributes were set correctly on the + serial device. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an + unsupported value. +**/ +RETURN_STATUS +EFIAPI +Dbg2InitializePort ( + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ); + +#endif // DBG2_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c new file mode 100644 index 0000000000..3219f6f909 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c @@ -0,0 +1,60 @@ +/** @file + Common DBG2 Table Generator + + Copyright (c) 2024, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015. +**/ + +#include +#include +#include "Dbg2Generator.h" + +/** + Initialise the serial port to the specified settings. + The serial port is re-configured only if the specified settings + are different from the current settings. + All unspecified settings will be set to the default values. + + @param SerialPortInfo CM_ARCH_COMMON_SERIAL_PORT_INFO object describing + the serial port. + @param BaudRate The baud rate of the serial device. If the + baud rate is not supported, the speed will be + reduced to the nearest supported one and the + variable's value will be updated accordingly. + @param ReceiveFifoDepth The number of characters the device will + buffer on input. Value of 0 will use the + device's default FIFO depth. + @param Parity If applicable, this is the EFI_PARITY_TYPE + that is computed or checked as each character + is transmitted or received. If the device + does not support parity, the value is the + default parity value. + @param DataBits The number of data bits in each character. + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number + of stop bits per character. + If the device does not support stop bits, the + value is the default stop bit value. + + @retval RETURN_SUCCESS All attributes were set correctly on the + serial device. + @retval RETURN_UNSUPPORTED Not supported. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an + unsupported value. +**/ +RETURN_STATUS +EFIAPI +Dbg2InitializePort ( + IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo, + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + // Not implemented. + return RETURN_UNSUPPORTED; +} -- cgit From acaf99827f4d6c386e2ce45239f058493660a282 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: AcpiSpcrLib: Prepare to support other archs Remove the Arm name from the generator to show the generator can be used by other archs. Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c index 6f027f3bf9..065729d7ee 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c @@ -26,7 +26,7 @@ #include #include -/** ARM standard SPCR Table Generator +/** Standard SPCR Table Generator Constructs the SPCR table for PL011 or SBSA UART peripherals. -- cgit From c6e0eed07264fb5bd92198cf5c9b1c95715a1962 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: AcpiSratLib: Prepare to support other archs Allow other architectures to reuse the AcpiSratLib by extracting the Arm specific part of the table generation. Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Acpi/Common/AcpiSratLib/AcpiSratLib.inf | 7 + .../Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c | 262 +++++++++++++++++++++ .../Acpi/Common/AcpiSratLib/SratGenerator.c | 214 ++--------------- .../Acpi/Common/AcpiSratLib/SratGenerator.h | 59 +++++ .../Acpi/Common/AcpiSratLib/SratGeneratorNull.c | 79 +++++++ 5 files changed, 424 insertions(+), 197 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf index 2f23f4e668..14e435e325 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf @@ -18,6 +18,13 @@ [Sources] SratGenerator.c + SratGenerator.h + +[Sources.ARM, Sources.AARCH64] + Arm/ArmSratGenerator.c + +[Sources.IA32, Sources.X64] + SratGeneratorNull.c [Packages] EmbeddedPkg/EmbeddedPkg.dec diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c new file mode 100644 index 0000000000..3d36b25e18 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c @@ -0,0 +1,262 @@ +/** @file + Arm SRAT Table Generator + + Copyright (c) 2019 - 2020, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification, January 2019 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +#include "SratGenerator.h" + +/** + ARM standard SRAT Generator + + Requirements: + The following Configuration Manager Object(s) are used by this Generator: + - EArmObjGicCInfo (REQUIRED) + - EArmObjGicItsInfo (OPTIONAL) +*/ + +/** This macro expands to a function that retrieves the GIC + CPU interface Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicCInfo, + CM_ARM_GICC_INFO + ); + +/** This macro expands to a function that retrieves the GIC + Interrupt Translation Service Information from the + Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicItsInfo, + CM_ARM_GIC_ITS_INFO + ); + +/** Enum of the Arm specific CM objects required to + build the arch specific information of the SRAT table. +*/ +typedef enum ArmSratSubTableType { + EArmGicCSubTableType, + EArmGicItsSubTableType, + EArmSubTableTypeMax, +} EARM_SRAT_SUB_TABLE_TYPE; + +typedef struct SratSubTable { + /// Start offset of the arch specific sub-table. + UINT32 Offset; + + /// Count + UINT32 Count; + + /// Array of CmInfo objects of the relevant type. + VOID *CmInfo; +} SRAT_SUB_TABLE; + +STATIC SRAT_SUB_TABLE mSratSubTable[EArmSubTableTypeMax]; + +/** Reserve arch sub-tables space. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + @param [in, out] ArchOffset On input, contains the offset where arch specific + sub-tables can be written. It is expected that + there enough space to write all the arch specific + sub-tables from this offset onward. + On ouput, contains the ending offset of the arch + specific sub-tables. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +ArchReserveOffsets ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT UINT32 *ArchOffset + ) +{ + EFI_STATUS Status; + + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ArchOffset != NULL); + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + (CM_ARM_GICC_INFO **)&mSratSubTable[EArmGicCSubTableType].CmInfo, + &mSratSubTable[EArmGicCSubTableType].Count + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get GICC Info. Status = %r\n", + Status + )); + return Status; + } + + if (mSratSubTable[EArmGicCSubTableType].Count == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: GIC CPU Interface information not provided.\n" + )); + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Status = GetEArmObjGicItsInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + (CM_ARM_GIC_ITS_INFO **)&mSratSubTable[EArmGicItsSubTableType].CmInfo, + &mSratSubTable[EArmGicItsSubTableType].Count + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to get GIC ITS Info. Status = %r\n", + Status + )); + return Status; + } + + mSratSubTable[EArmGicCSubTableType].Offset = *ArchOffset; + *ArchOffset += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) * + mSratSubTable[EArmGicCSubTableType].Count); + + if (mSratSubTable[EArmGicItsSubTableType].Count != 0) { + mSratSubTable[EArmGicItsSubTableType].Offset = *ArchOffset; + *ArchOffset += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) * + mSratSubTable[EArmGicItsSubTableType].Count); + } + + return EFI_SUCCESS; +} + +/** Add the GICC Affinity Structures in the SRAT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. +**/ +STATIC +VOID +EFIAPI +AddGICCAffinity ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat + ) +{ + EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *GicCAff; + CM_ARM_GICC_INFO *GicCInfo; + + GicCInfo = mSratSubTable[EArmGicCSubTableType].CmInfo; + GicCAff = (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)((UINT8 *)Srat + + mSratSubTable[EArmGicCSubTableType].Offset); + + while (mSratSubTable[EArmGicCSubTableType].Count-- != 0) { + DEBUG ((DEBUG_INFO, "SRAT: GicCAff = 0x%p\n", GicCAff)); + + GicCAff->Type = EFI_ACPI_6_3_GICC_AFFINITY; + GicCAff->Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE); + GicCAff->ProximityDomain = GicCInfo->ProximityDomain; + GicCAff->AcpiProcessorUid = GicCInfo->AcpiProcessorUid; + GicCAff->Flags = GicCInfo->AffinityFlags; + GicCAff->ClockDomain = GicCInfo->ClockDomain; + + // Next + GicCAff++; + GicCInfo++; + }// while +} + +/** Add the GIC ITS Affinity Structures in the SRAT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. +**/ +STATIC +VOID +EFIAPI +AddGICItsAffinity ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat + ) +{ + EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff; + CM_ARM_GIC_ITS_INFO *GicItsInfo; + + GicItsInfo = mSratSubTable[EArmGicItsSubTableType].CmInfo; + GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat + + mSratSubTable[EArmGicItsSubTableType].Offset); + + while (mSratSubTable[EArmGicItsSubTableType].Count-- != 0) { + DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff)); + + GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY; + GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE); + GicItsAff->ProximityDomain = GicItsInfo->ProximityDomain; + GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE; + GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE; + GicItsAff->ItsId = GicItsInfo->GicItsId; + + // Next + GicItsAff++; + GicItsInfo++; + }// while +} + +/** Add the arch specific sub-tables to the SRAT table. + + These sub-tables are written in the space reserved beforehand. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + + @retval EFI_SUCCESS Table generated successfully. +**/ +EFI_STATUS +EFIAPI +AddArchObjects ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat + ) +{ + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Srat != NULL); + + AddGICCAffinity (CfgMgrProtocol, Srat); + + if (mSratSubTable[EArmGicCSubTableType].Count != 0) { + AddGICItsAffinity (CfgMgrProtocol, Srat); + } + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c index 48c9970a71..dcdacc4e96 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c @@ -25,38 +25,19 @@ #include #include +#include "SratGenerator.h" + /** - ARM standard SRAT Generator + Standard SRAT Generator Requirements: The following Configuration Manager Object(s) are used by this Generator: - - EArmObjGicCInfo (REQUIRED) - - EArmObjGicItsInfo (OPTIONAL) - EArchCommonObjMemoryAffinityInfo (OPTIONAL) - EArchCommonObjGenericInitiatorAffinityInfo (OPTIONAL) - EArchCommonObjDeviceHandleAcpi (OPTIONAL) - EArchCommonObjDeviceHandlePci (OPTIONAL) */ -/** This macro expands to a function that retrieves the GIC - CPU interface Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicCInfo, - CM_ARM_GICC_INFO - ); - -/** This macro expands to a function that retrieves the GIC - Interrupt Translation Service Information from the - Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicItsInfo, - CM_ARM_GIC_ITS_INFO - ); - /** This macro expands to a function that retrieves the Memory Affinity information from the Configuration Manager. @@ -121,102 +102,6 @@ GetBdf ( return Bdf; } -/** Add the GICC Affinity Structures in the SRAT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Srat Pointer to the SRAT Table. - @param [in] GicCAffOffset Offset of the GICC Affinity - information in the SRAT Table. - @param [in] GicCInfo Pointer to the GIC CPU Information list. - @param [in] GicCCount Count of GIC CPU Interfaces. - - @retval EFI_SUCCESS Table generated successfully. -**/ -STATIC -EFI_STATUS -AddGICCAffinity ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, - IN CONST UINT32 GicCAffOffset, - IN CONST CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 GicCCount - ) -{ - EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *GicCAff; - - ASSERT (Srat != NULL); - ASSERT (GicCInfo != NULL); - - GicCAff = (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)((UINT8 *)Srat + - GicCAffOffset); - - while (GicCCount-- != 0) { - DEBUG ((DEBUG_INFO, "SRAT: GicCAff = 0x%p\n", GicCAff)); - - GicCAff->Type = EFI_ACPI_6_3_GICC_AFFINITY; - GicCAff->Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE); - GicCAff->ProximityDomain = GicCInfo->ProximityDomain; - GicCAff->AcpiProcessorUid = GicCInfo->AcpiProcessorUid; - GicCAff->Flags = GicCInfo->AffinityFlags; - GicCAff->ClockDomain = GicCInfo->ClockDomain; - - // Next - GicCAff++; - GicCInfo++; - }// while - - return EFI_SUCCESS; -} - -/** Add the GIC ITS Affinity Structures in the SRAT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Srat Pointer to the SRAT Table. - @param [in] GicItsAffOffset Offset of the GIC ITS Affinity - information in the SRAT Table. - @param [in] GicItsInfo Pointer to the GIC ITS Information list. - @param [in] GicItsCount Count of GIC ITS. - - @retval EFI_SUCCESS Table generated successfully. -**/ -STATIC -EFI_STATUS -AddGICItsAffinity ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, - IN CONST UINT32 GicItsAffOffset, - IN CONST CM_ARM_GIC_ITS_INFO *GicItsInfo, - IN UINT32 GicItsCount - ) -{ - EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff; - - ASSERT (Srat != NULL); - ASSERT (GicItsInfo != NULL); - - GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat + - GicItsAffOffset); - - while (GicItsCount-- != 0) { - DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff)); - - GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY; - GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE); - GicItsAff->ProximityDomain = GicItsInfo->ProximityDomain; - GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE; - GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE; - GicItsAff->ItsId = GicItsInfo->GicItsId; - - // Next - GicItsAff++; - GicItsInfo++; - }// while - - return EFI_SUCCESS; -} - /** Add the Memory Affinity Structures in the SRAT Table. @param [in] CfgMgrProtocol Pointer to the Configuration Manager @@ -455,18 +340,12 @@ BuildSratTable ( { EFI_STATUS Status; UINT32 TableSize; - UINT32 GicCCount; - UINT32 GicItsCount; UINT32 MemAffCount; UINT32 GenInitiatorAffCount; - UINT32 GicCAffOffset; - UINT32 GicItsAffOffset; UINT32 MemAffOffset; UINT32 GenInitiatorAffOffset; - CM_ARM_GICC_INFO *GicCInfo; - CM_ARM_GIC_ITS_INFO *GicItsInfo; CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo; CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo; @@ -497,46 +376,6 @@ BuildSratTable ( *Table = NULL; - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicCInfo, - &GicCCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get GICC Info. Status = %r\n", - Status - )); - goto error_handler; - } - - if (GicCCount == 0) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: GIC CPU Interface information not provided.\n" - )); - ASSERT (0); - Status = EFI_INVALID_PARAMETER; - goto error_handler; - } - - Status = GetEArmObjGicItsInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicItsInfo, - &GicItsCount - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to get GIC ITS Info. Status = %r\n", - Status - )); - goto error_handler; - } - Status = GetEArchCommonObjMemoryAffinityInfo ( CfgMgrProtocol, CM_NULL_TOKEN, @@ -571,13 +410,18 @@ BuildSratTable ( // Calculate the size of the SRAT table TableSize = sizeof (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER); - GicCAffOffset = TableSize; - TableSize += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) * GicCCount); - - if (GicItsCount != 0) { - GicItsAffOffset = TableSize; - TableSize += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) * - GicItsCount); + // Place the Arch specific subtables/structures first and + // reserve the offsets. The common subtables/structures + // are placed next. + Status = ArchReserveOffsets (CfgMgrProtocol, &TableSize); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SRAT: Failed to reserve arch offsets." + " Status = %r\n", + Status + )); + goto error_handler; } if (MemAffCount != 0) { @@ -636,40 +480,16 @@ BuildSratTable ( Srat->Reserved1 = 1; Srat->Reserved2 = EFI_ACPI_RESERVED_QWORD; - Status = AddGICCAffinity ( - CfgMgrProtocol, - Srat, - GicCAffOffset, - GicCInfo, - GicCCount - ); + Status = AddArchObjects (CfgMgrProtocol, Srat); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, - "ERROR: SRAT: Failed to add GICC Affinity structures. Status = %r\n", + "ERROR: SRAT: Failed to add arch objects header. Status = %r\n", Status )); goto error_handler; } - if (GicItsCount != 0) { - Status = AddGICItsAffinity ( - CfgMgrProtocol, - Srat, - GicItsAffOffset, - GicItsInfo, - GicItsCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SRAT: Failed to add GIC ITS Affinity structures. Status = %r\n", - Status - )); - goto error_handler; - } - } - if (MemAffCount != 0) { Status = AddMemoryAffinity ( CfgMgrProtocol, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h new file mode 100644 index 0000000000..106d008494 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h @@ -0,0 +1,59 @@ +/** @file + SRAT Table Generator + + Copyright (c) 2019 - 2020, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification, January 2019 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#ifndef SRAT_GENERATOR_H_ +#define SRAT_GENERATOR_H_ + +/** Reserve arch sub-tables space. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + @param [in, out] ArchOffset On input, contains the offset where arch specific + sub-tables can be written. It is expected that + there enough space to write all the arch specific + sub-tables from this offset onward. + On ouput, contains the ending offset of the arch + specific sub-tables. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +ArchReserveOffsets ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT UINT32 *ArchOffset + ); + +/** Add the arch specific sub-tables to the SRAT table. + + These sub-tables are written in the space reserved beforehand. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + + @retval EFI_SUCCESS Table generated successfully. +**/ +EFI_STATUS +EFIAPI +AddArchObjects ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat + ); + +#endif // SRAT_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c new file mode 100644 index 0000000000..4ebdf97fd6 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c @@ -0,0 +1,79 @@ +/** @file + Common SRAT Table Generator + + Copyright (c) 2019 - 2020, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification, January 2019 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +#include "SratGenerator.h" + +/** Reserve arch sub-tables space. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + @param [in, out] ArchOffset On input, contains the offset where arch specific + sub-tables can be written. It is expected that + there enough space to write all the arch specific + sub-tables from this offset onward. + On ouput, contains the ending offset of the arch + specific sub-tables. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_UNSUPPORTED Not supported. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object information is not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +ArchReserveOffsets ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT UINT32 *ArchOffset + ) +{ + // Not implemented. + return EFI_UNSUPPORTED; +} + +/** Add the arch specific sub-tables to the SRAT table. + + These sub-tables are written in the space reserved beforehand. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Srat Pointer to the SRAT Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_UNSUPPORTED Not supported. +**/ +EFI_STATUS +EFIAPI +AddArchObjects ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat + ) +{ + // Not implemented. + return EFI_UNSUPPORTED; +} -- cgit From dfd867bd8381d1bc6ee4ea9e6f5ea65116e4b452 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: AcpiSsdtCpuTopologyLib: Avoid dependency on GICC The GICC is an ARM specific structure. Other architectures have different local interrupt controller structures from which CPU topology can be created. Avoid the GICC reference in common code by: - creating a wrapper CreateTopologyFromIntC() instead of CreateTopologyFromGicC() so that different archs can implement it differently. - implementing arch specific functions to get the AcpiProcessorUid, CpcToken, EtToken and use them instead of using the GicC CM object directly. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Arm/ArmSsdtCpuTopologyGenerator.c | 408 +++++++++++++++++++++ .../SsdtCpuTopologyGenerator.c | 341 ++--------------- .../SsdtCpuTopologyGenerator.h | 196 ++++++++++ .../AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf | 3 + 4 files changed, 647 insertions(+), 301 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c new file mode 100644 index 0000000000..140a2e4911 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c @@ -0,0 +1,408 @@ +/** @file + ARM SSDT Cpu Topology Table Generator Helpers. + + Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors + - ACPI for CoreSight version 1.2 Platform Design Document + (https://developer.arm.com/documentation/den0067/a/?lang=en) + + @par Glossary: + - ETE - Embedded Trace Extension. + - ETM - Embedded Trace Macrocell. +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include + +#include "SsdtCpuTopologyGenerator.h" + +/** ARM SSDT Cpu Topology Table Generator. + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArmObjGicCInfo + - EArmObjEtInfo (OPTIONAL) +*/ + +/** This macro expands to a function that retrieves the GIC + CPU interface Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjGicCInfo, + CM_ARM_GICC_INFO + ); + +/** + This macro expands to a function that retrieves the ET device + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjEtInfo, + CM_ARM_ET_INFO + ); + +/** Create an embedded trace device and add it to the Cpu Node in the + AML namespace. + + This generates the following ASL code: + Device (E002) + { + Name (_UID, 2) + Name (_HID, "ARMHC500") + } + + Note: Currently we only support generating ETE nodes. Unlike ETM, + ETE has a system register interface and therefore does not need + the MMIO range to be described. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] ParentNode Parent node to attach the Cpu node to. + @param [in] AcpiProcessorUid ACPI Processor UID of the CPU. + @param [in] CpuName Value used to generate the node name. + @param [out] EtNodePtr If not NULL, return the created Cpu node. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlEtd ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN AML_NODE_HANDLE ParentNode, + IN UINT32 AcpiProcessorUid, + IN UINT32 CpuName, + OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL + ) +{ + EFI_STATUS Status; + AML_OBJECT_NODE_HANDLE EtNode; + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + + ASSERT (Generator != NULL); + ASSERT (ParentNode != NULL); + + Status = WriteAslName ('E', CpuName, AslName); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameInteger ( + "_UID", + AcpiProcessorUid, + EtNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = AmlCodeGenNameString ( + "_HID", + ACPI_HID_ET_DEVICE, + EtNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // If requested, return the handle to the EtNode. + if (EtNodePtr != NULL) { + *EtNodePtr = EtNode; + } + + return Status; +} + +/** Create and add an Embedded trace device to the Cpu Node. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiProcessorUid ACPI processor Uid of the local intc (gicc, other) + describing the Cpu. + @param [in] EtToken Embedded Trace Token of the CPU. + @param [in] CpuName Value used to generate the CPU node name. + @param [in] CpuNode CPU Node to which the ET device node is + attached. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_UNSUPPORTED Feature Unsupported. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateAmlEtNode ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN UINT32 AcpiProcessorUid, + IN CM_OBJECT_TOKEN EtToken, + IN UINT32 CpuName, + IN AML_OBJECT_NODE_HANDLE *CpuNode + ) +{ + EFI_STATUS Status; + CM_ARM_ET_INFO *EtInfo; + + Status = GetEArmObjEtInfo ( + CfgMgrProtocol, + EtToken, + &EtInfo, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Currently we only support creation of a ETE Node. + if (EtInfo->EtType != ArmEtTypeEte) { + return EFI_UNSUPPORTED; + } + + Status = CreateAmlEtd ( + Generator, + CpuNode, + AcpiProcessorUid, + CpuName, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Create the processor hierarchy AML tree from arch specific CM objects. + + The Arm architecture will use the CM_ARM_GICC_INFO CM objects for instance. + A processor container is by extension any non-leave device in the cpu topology. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ScopeNode Scope node handle ('\_SB' scope). + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +CreateTopologyFromIntC ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_OBJECT_NODE_HANDLE ScopeNode + ) +{ + EFI_STATUS Status; + CM_ARM_GICC_INFO *GicCInfo; + UINT32 GicCInfoCount; + UINT32 Index; + AML_OBJECT_NODE_HANDLE CpuNode; + + ASSERT (Generator != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (ScopeNode != NULL); + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GicCInfo, + &GicCInfoCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // For each CM_ARM_GICC_INFO object, create an AML node. + for (Index = 0; Index < GicCInfoCount; Index++) { + Status = CreateAmlCpu ( + Generator, + ScopeNode, + GicCInfo[Index].AcpiProcessorUid, + Index, + &CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + break; + } + + // If a CPC info is associated with the + // GicCinfo, create an _CPC method returning them. + if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) { + Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo[Index].CpcToken, CpuNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + break; + } + } + + if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) { + Status = CreateAmlEtNode ( + Generator, + CfgMgrProtocol, + GicCInfo[Index].AcpiProcessorUid, + GicCInfo[Index].EtToken, + Index, + CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + } // for + + return Status; +} + +/** Get generic interrupt information from arch specific CM objects. + + The AcpiProcessorUid, CpcToken, etc. are held in arch specific CM objects, + in the CM_ARM_GICC_INFO CM object for Arm for instance. + This wrapper allows to get this information from each arch object. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the + other fields from. + @param [out] AcpiProcessorUid AcpiProcessorUid of the CPU identified by + the AcpiIdObjectToken. + @param [out] CpcToken CpcToken of the CPU identified by + the AcpiIdObjectToken. + @param [out] PsdToken PsdToken of the CPU identified by + the AcpiIdObjectToken. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. +**/ +EFI_STATUS +EFIAPI +GetIntCInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_OBJECT_TOKEN AcpiIdObjectToken, + OUT UINT32 *AcpiProcessorUid, + OUT CM_OBJECT_TOKEN *CpcToken, + OUT CM_OBJECT_TOKEN *PsdToken + ) +{ + EFI_STATUS Status; + CM_ARM_GICC_INFO *GicCInfo; + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + AcpiIdObjectToken, + &GicCInfo, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (AcpiProcessorUid != NULL) { + *AcpiProcessorUid = GicCInfo->AcpiProcessorUid; + } + + if (CpcToken != NULL) { + *CpcToken = GicCInfo->CpcToken; + } + + if (PsdToken != NULL) { + *PsdToken = GicCInfo->PsdToken; + } + + return Status; +} + +/** Add arch specific information to a CPU node in the asl description. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the + other fields from. + @param [in] CpuName Value used to generate the CPU node name. + @param [out] CpuNode CPU Node to which the ET device node is + attached. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Feature Unsupported. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +AddArchAmlCpuInfo ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_OBJECT_TOKEN AcpiIdObjectToken, + IN UINT32 CpuName, + OUT AML_OBJECT_NODE_HANDLE *CpuNode + ) +{ + EFI_STATUS Status; + CM_ARM_GICC_INFO *GicCInfo; + + Status = GetEArmObjGicCInfo ( + CfgMgrProtocol, + AcpiIdObjectToken, + &GicCInfo, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Add an Embedded Trace node if present. + if (GicCInfo->EtToken != CM_NULL_TOKEN) { + Status = CreateAmlEtNode ( + Generator, + CfgMgrProtocol, + GicCInfo->AcpiProcessorUid, + GicCInfo->EtToken, + CpuName, + CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c index 2deaa4640c..7459513193 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c @@ -32,28 +32,17 @@ #include "SsdtCpuTopologyGenerator.h" -/** ARM standard SSDT Cpu Topology Table Generator. +/** SSDT Cpu Topology Table Generator. Requirements: The following Configuration Manager Object(s) are required by this Generator: - - EArmObjGicCInfo - EArchCommonObjProcHierarchyInfo (OPTIONAL) along with - EArchCommonObjCmRef (OPTIONAL) - EArchCommonObjLpiInfo (OPTIONAL) - - GetEArmObjEtInfo (OPTIONAL) - EArchCommonObjPsdInfo (OPTIONAL) */ -/** This macro expands to a function that retrieves the GIC - CPU interface Information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjGicCInfo, - CM_ARM_GICC_INFO - ); - /** This macro expands to a function that retrieves the Processor Hierarchy information from the Configuration Manager. @@ -94,16 +83,6 @@ GET_OBJECT_LIST ( CM_ARCH_COMMON_CPC_INFO ); -/** - This macro expands to a function that retrieves the ET device - information from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceArm, - EArmObjEtInfo, - CM_ARM_ET_INFO - ); - /** This macro expands to a function that retrieves the PSD information from the Configuration Manager. @@ -238,7 +217,6 @@ TokenTableAdd ( @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER Invalid parameter. **/ -STATIC EFI_STATUS EFIAPI WriteAslName ( @@ -294,8 +272,7 @@ WriteAslName ( @param [in] Generator The SSDT Cpu Topology generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. - @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object - describing the Cpu. + @param [in] PsdToken Token to identify the Psd information. @param [in] Node CPU Node to which the _CPC node is attached. @@ -309,7 +286,7 @@ EFIAPI CreateAmlPsdNode ( IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_ARM_GICC_INFO *GicCInfo, + IN CM_OBJECT_TOKEN PsdToken, IN AML_OBJECT_NODE_HANDLE *Node ) { @@ -318,7 +295,7 @@ CreateAmlPsdNode ( Status = GetEArchCommonObjPsdInfo ( CfgMgrProtocol, - GicCInfo->PsdToken, + PsdToken, &PsdInfo, NULL ); @@ -381,7 +358,7 @@ CreateAmlPsdNode ( @param [in] Generator The SSDT Cpu Topology generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. - @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object + @param [in] CpcToken CPC token of the INTC info describing the Cpu. @param [in] Node CPU Node to which the _CPC node is attached. @@ -390,13 +367,12 @@ CreateAmlPsdNode ( @retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. **/ -STATIC EFI_STATUS EFIAPI CreateAmlCpcNode ( IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_ARM_GICC_INFO *GicCInfo, + IN CM_OBJECT_TOKEN CpcToken, IN AML_OBJECT_NODE_HANDLE *Node ) { @@ -405,7 +381,7 @@ CreateAmlCpcNode ( Status = GetEArchCommonObjCpcInfo ( CfgMgrProtocol, - GicCInfo->CpcToken, + CpcToken, &CpcInfo, NULL ); @@ -423,147 +399,6 @@ CreateAmlCpcNode ( return Status; } -/** Create an embedded trace device and add it to the Cpu Node in the - AML namespace. - - This generates the following ASL code: - Device (E002) - { - Name (_UID, 2) - Name (_HID, "ARMHC500") - } - - Note: Currently we only support generating ETE nodes. Unlike ETM, - ETE has a system register interface and therefore does not need - the MMIO range to be described. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] ParentNode Parent node to attach the Cpu node to. - @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node. - @param [in] CpuName Value used to generate the node name. - @param [out] EtNodePtr If not NULL, return the created Cpu node. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlEtd ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN AML_NODE_HANDLE ParentNode, - IN CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 CpuName, - OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL - ) -{ - EFI_STATUS Status; - AML_OBJECT_NODE_HANDLE EtNode; - CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; - - ASSERT (Generator != NULL); - ASSERT (ParentNode != NULL); - - Status = WriteAslName ('E', CpuName, AslName); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameInteger ( - "_UID", - GicCInfo->AcpiProcessorUid, - EtNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = AmlCodeGenNameString ( - "_HID", - ACPI_HID_ET_DEVICE, - EtNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // If requested, return the handle to the EtNode. - if (EtNodePtr != NULL) { - *EtNodePtr = EtNode; - } - - return Status; -} - -/** Create and add an Embedded trace device to the Cpu Node. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object - describing the Cpu. - @param [in] CpuName Value used to generate the CPU node name. - @param [in] Node CPU Node to which the ET device node is - attached. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_UNSUPPORTED Feature Unsupported. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateAmlEtNode ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CM_ARM_GICC_INFO *GicCInfo, - IN UINT32 CpuName, - IN AML_OBJECT_NODE_HANDLE *Node - ) -{ - EFI_STATUS Status; - CM_ARM_ET_INFO *EtInfo; - - Status = GetEArmObjEtInfo ( - CfgMgrProtocol, - GicCInfo->EtToken, - &EtInfo, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Currently we only support creation of a ETE Node. - if (EtInfo->EtType != ArmEtTypeEte) { - return EFI_UNSUPPORTED; - } - - Status = CreateAmlEtd ( - Generator, - Node, - GicCInfo, - CpuName, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} - /** Create and add an _LPI method to Cpu/Cluster Node. For instance, transform an AML node from: @@ -789,23 +624,22 @@ GenerateLpiStates ( Name (_HID, "ACPI0007") } - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] ParentNode Parent node to attach the Cpu node to. - @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node. - @param [in] CpuName Value used to generate the node name. - @param [out] CpuNodePtr If not NULL, return the created Cpu node. + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] ParentNode Parent node to attach the Cpu node to. + @param [in] AcpiProcessorUid ACPI processor UID of the CPU. + @param [in] CpuName Value used to generate the node name. + @param [out] CpuNodePtr If not NULL, return the created Cpu node. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. **/ -STATIC EFI_STATUS EFIAPI CreateAmlCpu ( IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, IN AML_NODE_HANDLE ParentNode, - IN CM_ARM_GICC_INFO *GicCInfo, + IN UINT32 AcpiProcessorUid, IN UINT32 CpuName, OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL ) @@ -816,7 +650,6 @@ CreateAmlCpu ( ASSERT (Generator != NULL); ASSERT (ParentNode != NULL); - ASSERT (GicCInfo != NULL); Status = WriteAslName ('C', CpuName, AslName); if (EFI_ERROR (Status)) { @@ -832,7 +665,7 @@ CreateAmlCpu ( Status = AmlCodeGenNameInteger ( "_UID", - GicCInfo->AcpiProcessorUid, + AcpiProcessorUid, CpuNode, NULL ); @@ -887,8 +720,10 @@ CreateAmlCpuFromProcHierarchy ( ) { EFI_STATUS Status; - CM_ARM_GICC_INFO *GicCInfo; AML_OBJECT_NODE_HANDLE CpuNode; + UINT32 AcpiProcessorUid; + CM_OBJECT_TOKEN CpcToken; + CM_OBJECT_TOKEN PsdToken; ASSERT (Generator != NULL); ASSERT (CfgMgrProtocol != NULL); @@ -896,18 +731,19 @@ CreateAmlCpuFromProcHierarchy ( ASSERT (ProcHierarchyNodeInfo != NULL); ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN); - Status = GetEArmObjGicCInfo ( + Status = GetIntCInfo ( CfgMgrProtocol, ProcHierarchyNodeInfo->AcpiIdObjectToken, - &GicCInfo, - NULL + &AcpiProcessorUid, + &CpcToken, + &PsdToken ); if (EFI_ERROR (Status)) { ASSERT (0); return Status; } - Status = CreateAmlCpu (Generator, ParentNode, GicCInfo, CpuName, &CpuNode); + Status = CreateAmlCpu (Generator, ParentNode, AcpiProcessorUid, CpuName, &CpuNode); if (EFI_ERROR (Status)) { ASSERT (0); return Status; @@ -923,8 +759,8 @@ CreateAmlCpuFromProcHierarchy ( } } - if (GicCInfo->PsdToken != CM_NULL_TOKEN) { - Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); + if (PsdToken != CM_NULL_TOKEN) { + Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, PsdToken, CpuNode); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; @@ -932,28 +768,26 @@ CreateAmlCpuFromProcHierarchy ( } // If a CPC info is associated with the - // GicCinfo, create an _CPC method returning them. - if (GicCInfo->CpcToken != CM_NULL_TOKEN) { - Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); + // IntcInfo, create an _CPC method returning them. + if (CpcToken != CM_NULL_TOKEN) { + Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, CpcToken, CpuNode); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } } - // Add an Embedded Trace node if present. - if (GicCInfo->EtToken != CM_NULL_TOKEN) { - Status = CreateAmlEtNode ( - Generator, - CfgMgrProtocol, - GicCInfo, - CpuName, - CpuNode - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } + // Add arch specific information if necessary. + Status = AddArchAmlCpuInfo ( + Generator, + CfgMgrProtocol, + ProcHierarchyNodeInfo->AcpiIdObjectToken, + CpuName, + CpuNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; } return Status; @@ -1342,100 +1176,6 @@ exit_handler: return Status; } -/** Create the processor hierarchy AML tree from CM_ARM_GICC_INFO - CM objects. - - A processor container is by extension any non-leave device in the cpu topology. - - @param [in] Generator The SSDT Cpu Topology generator. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] ScopeNode Scope node handle ('\_SB' scope). - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. -**/ -STATIC -EFI_STATUS -EFIAPI -CreateTopologyFromGicC ( - IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN AML_OBJECT_NODE_HANDLE ScopeNode - ) -{ - EFI_STATUS Status; - CM_ARM_GICC_INFO *GicCInfo; - UINT32 GicCInfoCount; - UINT32 Index; - AML_OBJECT_NODE_HANDLE CpuNode; - - ASSERT (Generator != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (ScopeNode != NULL); - - Status = GetEArmObjGicCInfo ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &GicCInfo, - &GicCInfoCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // For each CM_ARM_GICC_INFO object, create an AML node. - for (Index = 0; Index < GicCInfoCount; Index++) { - Status = CreateAmlCpu ( - Generator, - ScopeNode, - &GicCInfo[Index], - Index, - &CpuNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - break; - } - - if (GicCInfo->PsdToken != CM_NULL_TOKEN) { - Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - - // If a CPC info is associated with the - // GicCinfo, create an _CPC method returning them. - if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) { - Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - break; - } - } - - if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) { - Status = CreateAmlEtNode ( - Generator, - CfgMgrProtocol, - &GicCInfo[Index], - Index, - CpuNode - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - } - } // for - - return Status; -} - /** Construct the SSDT Cpu Topology ACPI table. This function invokes the Configuration Manager protocol interface @@ -1514,9 +1254,8 @@ BuildSsdtCpuTopologyTable ( } if (Status == EFI_NOT_FOUND) { - // If hierarchy information is not found generate a flat topology - // using CM_ARM_GICC_INFO objects. - Status = CreateTopologyFromGicC ( + // If hierarchy information is not found generate a flat topology. + Status = CreateTopologyFromIntC ( Generator, CfgMgrProtocol, ScopeNode diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h index 6fb44c7e58..a5d80177f2 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h @@ -144,4 +144,200 @@ typedef struct AcpiCpuTopologyGenerator { #pragma pack() +/** Write a string 'Xxxx\0' in AslName (5 bytes long), + with 'X' being the leading char of the name, and + with 'xxx' being Value in hexadecimal. + + As 'xxx' in hexadecimal represents a number on 12 bits, + we have Value < (1 << 12). + + @param [in] LeadChar Leading char of the name. + @param [in] Value Hex value of the name. + Must be lower than (2 << 12). + @param [in, out] AslName Pointer to write the 'Xxxx' string to. + Must be at least 5 bytes long. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +WriteAslName ( + IN CHAR8 LeadChar, + IN UINT32 Value, + IN OUT CHAR8 *AslName + ); + +/** Get generic interrupt information from arch specific CM objects. + + The AcpiProcessorUid, CpcToken, etc. are held in arch specific CM objects, + in the CM_ARM_GICC_INFO CM object for Arm for instance. + This wrapper allows to get this information from each arch object. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiProcessorUid ACPI processor Uid of the local intc (gicc, other) + other fields from. + @param [out] AcpiProcessorUid AcpiProcessorUid of the CPU identified by + the AcpiIdObjectToken. + @param [out] CpcToken CpcToken of the CPU identified by + the AcpiIdObjectToken. + @param [out] PsdToken PsdToken of the CPU identified by + the AcpiIdObjectToken. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. +**/ +EFI_STATUS +EFIAPI +GetIntCInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_OBJECT_TOKEN AcpiIdObjectToken, + OUT UINT32 *AcpiProcessorUid, + OUT CM_OBJECT_TOKEN *CpcToken, + OUT CM_OBJECT_TOKEN *PsdToken + ); + +/** Create and add an _CPC Node to Cpu Node. + + For instance, transform an AML node from: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + } + + To: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + Name(_CPC, Package() + { + NumEntries, // Integer + Revision, // Integer + HighestPerformance, // Integer or Buffer (Resource Descriptor) + NominalPerformance, // Integer or Buffer (Resource Descriptor) + LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor) + LowestPerformance, // Integer or Buffer (Resource Descriptor) + GuaranteedPerformanceRegister, // Buffer (Resource Descriptor) + DesiredPerformanceRegister , // Buffer (Resource Descriptor) + MinimumPerformanceRegister , // Buffer (Resource Descriptor) + MaximumPerformanceRegister , // Buffer (Resource Descriptor) + PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor) + TimeWindowRegister, // Buffer (Resource Descriptor) + CounterWraparoundTime, // Integer or Buffer (Resource Descriptor) + ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor) + DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor) + PerformanceLimitedRegister, // Buffer (Resource Descriptor) + CPPCEnableRegister // Buffer (Resource Descriptor) + AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor) + AutonomousActivityWindowRegister, // Buffer (Resource Descriptor) + EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor) + ReferencePerformance // Integer or Buffer (Resource Descriptor) + LowestFrequency, // Integer or Buffer (Resource Descriptor) + NominalFrequency // Integer or Buffer (Resource Descriptor) + }) + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] CpcToken CPC token of the INTC info + describing the Cpu. + @param [in] Node CPU Node to which the _CPC node is + attached. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +CreateAmlCpcNode ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_OBJECT_TOKEN CpcToken, + IN AML_OBJECT_NODE_HANDLE *Node + ); + +/** Create a Cpu in the AML namespace. + + This generates the following ASL code: + Device (C002) + { + Name (_UID, 2) + Name (_HID, "ACPI0007") + } + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] ParentNode Parent node to attach the Cpu node to. + @param [in] AcpiProcessorUid ACPI processor UID of the CPU. + @param [in] CpuName Value used to generate the node name. + @param [out] CpuNodePtr If not NULL, return the created Cpu node. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +CreateAmlCpu ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN AML_NODE_HANDLE ParentNode, + IN UINT32 AcpiProcessorUid, + IN UINT32 CpuName, + OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL + ); + +/** Create the processor hierarchy AML tree from arch specific CM objects. + + The Arm architecture will use the CM_ARM_GICC_INFO CM objects for instance. + A processor container is by extension any non-leave device in the cpu topology. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] ScopeNode Scope node handle ('\_SB' scope). + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +CreateTopologyFromIntC ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN AML_OBJECT_NODE_HANDLE ScopeNode + ); + +/** Add arch specific information to a CPU node in the asl description. + + @param [in] Generator The SSDT Cpu Topology generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the + other fields from. + @param [in] CpuName Value used to generate the CPU node name. + @param [out] CpuNode CPU Node to which the ET device node is + attached. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Feature Unsupported. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. +**/ +EFI_STATUS +EFIAPI +AddArchAmlCpuInfo ( + IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CM_OBJECT_TOKEN AcpiIdObjectToken, + IN UINT32 CpuName, + OUT AML_OBJECT_NODE_HANDLE *CpuNode + ); + #endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf index 2d38fb30fb..93ede691cd 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf @@ -20,6 +20,9 @@ SsdtCpuTopologyGenerator.c SsdtCpuTopologyGenerator.h +[Sources.ARM, Sources.AARCH64] + Arm/ArmSsdtCpuTopologyGenerator.c + [Packages.ARM, Packages.AARCH64] ArmPlatformPkg/ArmPlatformPkg.dec -- cgit From 47b830db58cec598ebb144a46054c357401a8441 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: DynamicTableManagerDxe: Refactor PresenceArray Mandatory ACPI tables depend on the architectures. Different architectures might also want to check other tables. Move mAcpiVerifyTables containing the list of ACPI tables to check to an arch specific file and introduce GetAcpiTablePresenceInfo() to get get the relevant information from the array. Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Arm/ArmDynamicTableManager.c | 63 +++++++++++++++++++ .../DynamicTableManagerDxe.c | 70 +++++++--------------- .../DynamicTableManagerDxe.h | 63 +++++++++++++++++++ .../DynamicTableManagerDxe.inf | 7 +++ .../DynamicTableManagerNull.c | 59 ++++++++++++++++++ 5 files changed, 212 insertions(+), 50 deletions(-) create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c new file mode 100644 index 0000000000..4874fe883f --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c @@ -0,0 +1,63 @@ +/** @file + ARM Dynamic Table Manager Dxe + + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include +#include "DynamicTableManagerDxe.h" + +/// +/// Array containing the ACPI tables to check. +/// We require the FADT, MADT, GTDT and the DSDT tables to boot. +/// This list also include optional ACPI tables: DBG2, SPCR. +/// The FADT table must be placed at index 0. +/// +STATIC ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[] = { + { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }, + { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, "MADT", TRUE, 0 }, + { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, "GTDT", TRUE, 0 }, + { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, "DSDT", TRUE, 0 }, + { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, "DBG2", FALSE, 0 }, + { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, "SPCR", FALSE, 0 }, +}; + +/** Get the arch specific ACPI table presence information. + + @param [out] PresenceArray Array containing the ACPI tables to check. + @param [out] PresenceArrayCount Count of elements in the PresenceArray. + @param [out] FadtIndex Index of the FADT table in the PresenceArray. + -1 if absent. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +EFIAPI +GetAcpiTablePresenceInfo ( + OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray, + OUT UINT32 *PresenceArrayCount, + OUT INT32 *FadtIndex + ) +{ + *PresenceArray = mAcpiVerifyTables; + *PresenceArrayCount = ARRAY_SIZE (mAcpiVerifyTables); + *FadtIndex = ACPI_TABLE_VERIFY_FADT; + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c index 1e9b811c40..dfccccb839 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c @@ -23,57 +23,15 @@ #include #include -/// -/// Bit definitions for acceptable ACPI table presence formats. -/// Currently only ACPI tables present in the ACPI info list and -/// already installed will count towards "Table Present" during -/// verification routine. -/// -#define ACPI_TABLE_PRESENT_INFO_LIST BIT0 -#define ACPI_TABLE_PRESENT_INSTALLED BIT1 - -/// -/// Order of ACPI table being verified during presence inspection. -/// -#define ACPI_TABLE_VERIFY_FADT 0 -#define ACPI_TABLE_VERIFY_MADT 1 -#define ACPI_TABLE_VERIFY_GTDT 2 -#define ACPI_TABLE_VERIFY_DSDT 3 -#define ACPI_TABLE_VERIFY_DBG2 4 -#define ACPI_TABLE_VERIFY_SPCR 5 -#define ACPI_TABLE_VERIFY_COUNT 6 - -/// -/// Private data structure to verify the presence of mandatory -/// or optional ACPI tables. -/// -typedef struct { - /// ESTD ID for the ACPI table of interest. - ESTD_ACPI_TABLE_ID EstdTableId; - /// Standard UINT32 ACPI signature. - UINT32 AcpiTableSignature; - /// 4 character ACPI table name (the 5th char8 is for null terminator). - CHAR8 AcpiTableName[sizeof (UINT32) + 1]; - /// Indicator on whether the ACPI table is required. - BOOLEAN IsMandatory; - /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_* - /// This field should be initialized to 0 and will be populated during - /// verification routine. - UINT16 Presence; -} ACPI_TABLE_PRESENCE_INFO; +#include "DynamicTableManagerDxe.h" /// /// We require the FADT, MADT, GTDT and the DSDT tables to boot. /// This list also include optional ACPI tables: DBG2, SPCR. /// -ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[ACPI_TABLE_VERIFY_COUNT] = { - { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }, - { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, "MADT", TRUE, 0 }, - { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, "GTDT", TRUE, 0 }, - { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, "DSDT", TRUE, 0 }, - { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, "DBG2", FALSE, 0 }, - { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, "SPCR", FALSE, 0 }, -}; +STATIC ACPI_TABLE_PRESENCE_INFO *mAcpiVerifyTables; +STATIC UINT32 mAcpiVerifyTablesCount; +STATIC INT32 mAcpiVerifyTablesFadtIndex; /** This macro expands to a function that retrieves the ACPI Table List from the Configuration Manager. @@ -472,7 +430,7 @@ VerifyMandatoryTablesArePresent ( // Check against the statically initialized ACPI tables to see if they are in ACPI info list while (AcpiTableCount-- != 0) { - for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { + for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) { if (AcpiTableInfo[AcpiTableCount].AcpiTableSignature == mAcpiVerifyTables[Index].AcpiTableSignature) { mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INFO_LIST; // Found this table, skip the rest. @@ -491,7 +449,7 @@ VerifyMandatoryTablesArePresent ( return Status; } - for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { + for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) { Handle = 0; InstalledTableIndex = 0; do { @@ -511,7 +469,7 @@ VerifyMandatoryTablesArePresent ( // Reset the return Status value to EFI_SUCCESS. We do not fully care if the table look up has failed. Status = EFI_SUCCESS; - for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { + for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) { if (mAcpiVerifyTables[Index].Presence == 0) { if (mAcpiVerifyTables[Index].IsMandatory) { DEBUG ((DEBUG_ERROR, "ERROR: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName)); @@ -623,7 +581,9 @@ ProcessAcpiTables ( } // Add the FADT Table first. - if ((mAcpiVerifyTables[ACPI_TABLE_VERIFY_FADT].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0) { + if ((mAcpiVerifyTablesFadtIndex >= 0) && + ((mAcpiVerifyTables[mAcpiVerifyTablesFadtIndex].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0)) + { // FADT is not yet installed for (Idx = 0; Idx < AcpiTableCount; Idx++) { if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == @@ -785,6 +745,16 @@ DynamicTableManagerDxeInitialize ( CfgMfrInfo->OemId[5] )); + Status = GetAcpiTablePresenceInfo ( + &mAcpiVerifyTables, + &mAcpiVerifyTablesCount, + &mAcpiVerifyTablesFadtIndex + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol); if (EFI_ERROR (Status)) { DEBUG (( diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h new file mode 100644 index 0000000000..a12a775af1 --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h @@ -0,0 +1,63 @@ +/** @file + Dynamic Table Manager Dxe + + Copyright (c) 2017 - 2024, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef DYNAMIC_TABLE_MANAGER_DXE_H_ +#define DYNAMIC_TABLE_MANAGER_DXE_H_ + +#include + +/// +/// Bit definitions for acceptable ACPI table presence formats. +/// Currently only ACPI tables present in the ACPI info list and +/// already installed will count towards "Table Present" during +/// verification routine. +/// +#define ACPI_TABLE_PRESENT_INFO_LIST BIT0 +#define ACPI_TABLE_PRESENT_INSTALLED BIT1 + +/// The FADT table must be placed at index 0 in mAcpiVerifyTables. +#define ACPI_TABLE_VERIFY_FADT 0 + +/// +/// Private data structure to verify the presence of mandatory +/// or optional ACPI tables. +/// +typedef struct { + /// ESTD ID for the ACPI table of interest. + ESTD_ACPI_TABLE_ID EstdTableId; + /// Standard UINT32 ACPI signature. + UINT32 AcpiTableSignature; + /// 4 character ACPI table name (the 5th char8 is for null terminator). + CHAR8 AcpiTableName[sizeof (UINT32) + 1]; + /// Indicator on whether the ACPI table is required. + BOOLEAN IsMandatory; + /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_* + /// This field should be initialized to 0 and will be populated during + /// verification routine. + UINT16 Presence; +} ACPI_TABLE_PRESENCE_INFO; + +/** Get the arch specific ACPI table presence information. + + @param [out] PresenceArray Array containing the ACPI tables to check. + @param [out] PresenceArrayCount Count of elements in the PresenceArray. + @param [out] FadtIndex Index of the FADT table in the PresenceArray. + -1 if absent. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +EFIAPI +GetAcpiTablePresenceInfo ( + OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray, + OUT UINT32 *PresenceArrayCount, + OUT INT32 *FadtIndex + ); + +#endif // DYNAMIC_TABLE_MANAGER_DXE_H_ diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf index ad8b3d037c..00d03e75be 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf @@ -22,6 +22,13 @@ [Sources] DynamicTableManagerDxe.c + DynamicTableManagerDxe.h + +[Sources.ARM, Sources.AARCH64] + Arm/ArmDynamicTableManager.c + +[Sources.IA32, Sources.X64] + DynamicTableManagerNull.c [Packages] MdePkg/MdePkg.dec diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c new file mode 100644 index 0000000000..d9b727468a --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c @@ -0,0 +1,59 @@ +/** @file + Common Dynamic Table Manager Dxe + + Copyright (c) 2024, Arm Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include +#include "DynamicTableManagerDxe.h" + +/// +/// Array containing the ACPI tables to check. +/// This is a dummy list only existing for build purpose. +/// The FADT table must be placed at index 0. +/// +ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[] = { + { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }, +}; + +/** Get the arch specific ACPI table presence information. + + @param [out] PresenceArray Array containing the ACPI tables to check. + @param [out] PresenceArrayCount Count of elements in the PresenceArray. + @param [out] FadtIndex Index of the FADT table in the PresenceArray. + -1 if absent. + + @retval EFI_SUCCESS Success. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +GetAcpiTablePresenceInfo ( + OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray, + OUT UINT32 *PresenceArrayCount, + OUT INT32 *FadtIndex + ) +{ + // Dummy function - Not Implemented. + *PresenceArray = mAcpiVerifyTables; + *PresenceArrayCount = ARRAY_SIZE (mAcpiVerifyTables); + *FadtIndex = ACPI_TABLE_VERIFY_FADT; + + return EFI_UNSUPPORTED; +} -- cgit From e2fda42a221a69140c42224e94bc5808a038e676 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Move ARM parsers to Arm directory Create an Arm directory in the FdtHwInfoParserLib as a preparation step to support other architectures. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Arm/BootArch/ArmBootArchParser.c | 159 ++++ .../Arm/BootArch/ArmBootArchParser.h | 45 + .../Arm/GenericTimer/ArmGenericTimerParser.c | 258 ++++++ .../Arm/GenericTimer/ArmGenericTimerParser.h | 66 ++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c | 903 +++++++++++++++++++++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h | 68 ++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c | 171 ++++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h | 50 ++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c | 218 +++++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h | 72 ++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c | 218 +++++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h | 48 ++ .../Arm/Gic/ArmGicMsiFrameParser.c | 217 +++++ .../Arm/Gic/ArmGicMsiFrameParser.h | 50 ++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c | 238 ++++++ .../FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h | 47 ++ .../BootArch/ArmBootArchParser.c | 159 ---- .../BootArch/ArmBootArchParser.h | 45 - .../Library/FdtHwInfoParserLib/FdtHwInfoParser.c | 6 +- .../FdtHwInfoParserLib/FdtHwInfoParserLib.inf | 32 +- .../GenericTimer/ArmGenericTimerParser.c | 258 ------ .../GenericTimer/ArmGenericTimerParser.h | 66 -- .../Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c | 903 --------------------- .../Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h | 68 -- .../Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c | 171 ---- .../Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h | 50 -- .../FdtHwInfoParserLib/Gic/ArmGicDispatcher.c | 218 ----- .../FdtHwInfoParserLib/Gic/ArmGicDispatcher.h | 72 -- .../FdtHwInfoParserLib/Gic/ArmGicItsParser.c | 218 ----- .../FdtHwInfoParserLib/Gic/ArmGicItsParser.h | 48 -- .../FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c | 217 ----- .../FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h | 50 -- .../Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c | 238 ------ .../Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h | 47 -- .../Pci/ArmPciConfigSpaceParser.c | 2 +- 35 files changed, 2848 insertions(+), 2848 deletions(-) create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c new file mode 100644 index 0000000000..d217e33424 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c @@ -0,0 +1,159 @@ +/** @file + Arm boot architecture parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/arm/psci.yaml +**/ + +#include "FdtHwInfoParser.h" +#include "CmObjectDescUtility.h" +#include "Arm/BootArch/ArmBootArchParser.h" + +/** List of "compatible" property values for Psci nodes. + + Other "compatible" values are not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR PsciCompatibleStr[] = { + { "arm,psci-0.2" }, + { "arm,psci" } +}; + +/** COMPATIBILITY_INFO structure for the PsciCompatibleInfo. +*/ +STATIC CONST COMPATIBILITY_INFO PsciCompatibleInfo = { + ARRAY_SIZE (PsciCompatibleStr), + PsciCompatibleStr +}; + +/** List of PSCI method strings. +*/ +STATIC CONST CHAR8 *PsciMethod[] = { + "smc", + "hvc" +}; + +/** Parse a Psci node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] PsciNode Offset of a Psci node. + @param [in] BootArchInfo The CM_ARM_BOOT_ARCH_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +PsciNodeParser ( + IN CONST VOID *Fdt, + IN INT32 PsciNode, + IN CM_ARM_BOOT_ARCH_INFO *BootArchInfo + ) +{ + CONST VOID *Data; + INT32 DataSize; + + if ((Fdt == NULL) || + (BootArchInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Default to parking protocol + BootArchInfo->BootArchFlags = 0; + + Data = fdt_getprop (Fdt, PsciNode, "method", &DataSize); + if ((Data == NULL) || (DataSize < 0)) { + ASSERT (0); + return EFI_ABORTED; + } + + // Check PSCI conduit. + if (AsciiStrnCmp (Data, PsciMethod[0], DataSize) == 0) { + BootArchInfo->BootArchFlags = EFI_ACPI_6_3_ARM_PSCI_COMPLIANT; + } else if (AsciiStrnCmp (Data, PsciMethod[1], DataSize) == 0) { + BootArchInfo->BootArchFlags = (EFI_ACPI_6_3_ARM_PSCI_COMPLIANT | + EFI_ACPI_6_3_ARM_PSCI_USE_HVC); + } + + return EFI_SUCCESS; +} + +/** CM_ARM_BOOT_ARCH_INFO parser function. + + The following structure is populated: + typedef struct CmArmBootArchInfo { + UINT16 BootArchFlags; // {Populated} + } CM_ARM_BOOT_ARCH_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmBootArchInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + INT32 PsciNode; + CM_ARM_BOOT_ARCH_INFO BootArchInfo; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&BootArchInfo, sizeof (CM_ARM_BOOT_ARCH_INFO)); + + PsciNode = FdtBranch; + Status = FdtGetNextCompatNodeInBranch ( + FdtParserHandle->Fdt, + FdtBranch, + &PsciCompatibleInfo, + &PsciNode + ); + if (EFI_ERROR (Status)) { + // Error, or no node found. + ASSERT (Status == EFI_NOT_FOUND); + return Status; + } + + // Parse the psci node. + Status = PsciNodeParser (FdtParserHandle->Fdt, PsciNode, &BootArchInfo); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARM_OBJECT_ID (EArmObjBootArchInfo), + &BootArchInfo, + sizeof (CM_ARM_BOOT_ARCH_INFO), + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h new file mode 100644 index 0000000000..51654f0e1e --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h @@ -0,0 +1,45 @@ +/** @file + Arm boot architecture parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/arm/psci.yaml +**/ + +#ifndef ARM_BOOT_ARCH_PARSER_H_ +#define ARM_BOOT_ARCH_PARSER_H_ + +/** CM_ARM_BOOT_ARCH_INFO parser function. + + The following structure is populated: + typedef struct CmArmBootArchInfo { + UINT16 BootArchFlags; // {Populated} + } CM_ARM_BOOT_ARCH_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmBootArchInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_BOOT_ARCH_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c new file mode 100644 index 0000000000..6488399ed8 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c @@ -0,0 +1,258 @@ +/** @file + Arm generic timer parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml +**/ + +#include "FdtHwInfoParser.h" +#include "CmObjectDescUtility.h" +#include "Arm/GenericTimer/ArmGenericTimerParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" + +/** List of "compatible" property values for timer nodes. + + Other "compatible" values are not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR TimerCompatibleStr[] = { + { "arm,armv7-timer" }, + { "arm,armv8-timer" } +}; + +/** Timer compatiblity information. +*/ +STATIC CONST COMPATIBILITY_INFO TimerCompatibleInfo = { + ARRAY_SIZE (TimerCompatibleStr), + TimerCompatibleStr +}; + +/** Parse a timer node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] TimerNode Offset of a timer node. + @param [in] GenericTimerInfo The CM_ARM_BOOT_ARCH_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +TimerNodeParser ( + IN CONST VOID *Fdt, + IN INT32 TimerNode, + IN CM_ARM_GENERIC_TIMER_INFO *GenericTimerInfo + ) +{ + EFI_STATUS Status; + CONST UINT32 *Data; + INT32 IntcNode; + UINT32 GicVersion; + INT32 DataSize; + INT32 IntCells; + BOOLEAN AlwaysOnTimer; + + if ((Fdt == NULL) || + (GenericTimerInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Data = fdt_getprop (Fdt, TimerNode, "always-on", &DataSize); + if ((Data == NULL) || (DataSize < 0)) { + AlwaysOnTimer = FALSE; + } else { + AlwaysOnTimer = TRUE; + } + + // Get the associated interrupt-controller. + Status = FdtGetIntcParentNode (Fdt, TimerNode, &IntcNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Check that the interrupt-controller node is a Gic. + Status = GetGicVersion (Fdt, IntcNode, &GicVersion); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Get the number of cells used to encode an interrupt. + Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + Data = fdt_getprop (Fdt, TimerNode, "interrupts", &DataSize); + if ((Data == NULL) || + (DataSize != (FdtMaxTimerItem * IntCells * sizeof (UINT32)))) + { + // If error or not FdtMaxTimerItem interrupts. + ASSERT (0); + return EFI_ABORTED; + } + + GenericTimerInfo->SecurePL1TimerGSIV = + FdtGetInterruptId (&Data[FdtSecureTimerIrq * IntCells]); + GenericTimerInfo->SecurePL1TimerFlags = + FdtGetInterruptFlags (&Data[FdtSecureTimerIrq * IntCells]); + GenericTimerInfo->NonSecurePL1TimerGSIV = + FdtGetInterruptId (&Data[FdtNonSecureTimerIrq * IntCells]); + GenericTimerInfo->NonSecurePL1TimerFlags = + FdtGetInterruptFlags (&Data[FdtNonSecureTimerIrq * IntCells]); + GenericTimerInfo->VirtualTimerGSIV = + FdtGetInterruptId (&Data[FdtVirtualTimerIrq * IntCells]); + GenericTimerInfo->VirtualTimerFlags = + FdtGetInterruptFlags (&Data[FdtVirtualTimerIrq * IntCells]); + GenericTimerInfo->NonSecurePL2TimerGSIV = + FdtGetInterruptId (&Data[FdtHypervisorTimerIrq * IntCells]); + GenericTimerInfo->NonSecurePL2TimerFlags = + FdtGetInterruptFlags (&Data[FdtHypervisorTimerIrq * IntCells]); + + if (AlwaysOnTimer) { + GenericTimerInfo->SecurePL1TimerFlags |= BIT2; + GenericTimerInfo->NonSecurePL1TimerFlags |= BIT2; + GenericTimerInfo->VirtualTimerFlags |= BIT2; + GenericTimerInfo->NonSecurePL2TimerFlags |= BIT2; + } + + // Setup default values + // The CntControlBase & CntReadBase Physical Address are optional if + // the system implements EL3 (Security Extensions). So, initialise + // these to their default value. + GenericTimerInfo->CounterControlBaseAddress = 0xFFFFFFFFFFFFFFFF; + GenericTimerInfo->CounterReadBaseAddress = 0xFFFFFFFFFFFFFFFF; + + // For systems not implementing ARMv8.1 VHE, this field is 0. + GenericTimerInfo->VirtualPL2TimerGSIV = 0; + GenericTimerInfo->VirtualPL2TimerFlags = 0; + + return EFI_SUCCESS; +} + +/** CM_ARM_GENERIC_TIMER_INFO parser function. + + The following structure is populated: + typedef struct CmArmGenericTimerInfo { + UINT64 CounterControlBaseAddress; // {default} + UINT64 CounterReadBaseAddress; // {default} + UINT32 SecurePL1TimerGSIV; // {Populated} + UINT32 SecurePL1TimerFlags; // {Populated} + UINT32 NonSecurePL1TimerGSIV; // {Populated} + UINT32 NonSecurePL1TimerFlags; // {Populated} + UINT32 VirtualTimerGSIV; // {Populated} + UINT32 VirtualTimerFlags; // {Populated} + UINT32 NonSecurePL2TimerGSIV; // {Populated} + UINT32 NonSecurePL2TimerFlags; // {Populated} + UINT32 VirtualPL2TimerGSIV; // {default} + UINT32 VirtualPL2TimerFlags; // {default} + } CM_ARM_GENERIC_TIMER_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGenericTimerInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + UINT32 Index; + INT32 TimerNode; + UINT32 TimerNodeCount; + CM_ARM_GENERIC_TIMER_INFO GenericTimerInfo; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + Status = FdtCountCompatNodeInBranch ( + Fdt, + FdtBranch, + &TimerCompatibleInfo, + &TimerNodeCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (TimerNodeCount == 0) { + return EFI_NOT_FOUND; + } + + // Parse each timer node in the branch. + TimerNode = FdtBranch; + for (Index = 0; Index < TimerNodeCount; Index++) { + ZeroMem (&GenericTimerInfo, sizeof (CM_ARM_GENERIC_TIMER_INFO)); + + Status = FdtGetNextCompatNodeInBranch ( + Fdt, + FdtBranch, + &TimerCompatibleInfo, + &TimerNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + Status = TimerNodeParser (Fdt, TimerNode, &GenericTimerInfo); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARM_OBJECT_ID (EArmObjGenericTimerInfo), + &GenericTimerInfo, + sizeof (CM_ARM_GENERIC_TIMER_INFO), + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } // for + + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h new file mode 100644 index 0000000000..d7fa278c90 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h @@ -0,0 +1,66 @@ +/** @file + Arm generic timer parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml +**/ + +#ifndef ARM_GENERIC_TIMER_PARSER_H_ +#define ARM_GENERIC_TIMER_PARSER_H_ + +/** An enum listing the FDT interrupt items. +*/ +typedef enum FdtTimerInterruptItems { + FdtSecureTimerIrq, ///< Secure timer IRQ + FdtNonSecureTimerIrq, ///< Non-secure timer IRQ + FdtVirtualTimerIrq, ///< Virtual timer IRQ + FdtHypervisorTimerIrq, ///< Hypervisor timer IRQ + FdtMaxTimerItem ///< Max timer item +} FDT_TIMER_INTERRUPT_ITEMS; + +/** CM_ARM_BOOT_ARCH_INFO parser function. + + The following structure is populated: + typedef struct CmArmGenericTimerInfo { + UINT64 CounterControlBaseAddress; // {default} + UINT64 CounterReadBaseAddress; // {default} + UINT32 SecurePL1TimerGSIV; // {Populated} + UINT32 SecurePL1TimerFlags; // {Populated} + UINT32 NonSecurePL1TimerGSIV; // {Populated} + UINT32 NonSecurePL1TimerFlags; // {Populated} + UINT32 VirtualTimerGSIV; // {Populated} + UINT32 VirtualTimerFlags; // {Populated} + UINT32 NonSecurePL2TimerGSIV; // {Populated} + UINT32 NonSecurePL2TimerFlags; // {Populated} + UINT32 VirtualPL2TimerGSIV; // {default} + UINT32 VirtualPL2TimerFlags; // {default} + } CM_ARM_GENERIC_TIMER_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGenericTimerInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GENERIC_TIMER_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c new file mode 100644 index 0000000000..cf577b4724 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c @@ -0,0 +1,903 @@ +/** @file + Arm Gic cpu parser. + + Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/arm/cpus.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml + - linux/Documentation/devicetree/bindings/arm/pmu.yaml +**/ + +#include "FdtHwInfoParser.h" +#include "CmObjectDescUtility.h" +#include "Arm/Gic/ArmGicCParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" + +/** List of "compatible" property values for CPU nodes. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR CpuCompatibleStr[] = { + { "arm,arm-v7" }, + { "arm,arm-v8" }, + { "arm,armv8" }, + { "arm,cortex-a15" }, + { "arm,cortex-a7" }, + { "arm,cortex-a57" } +}; + +/** COMPATIBILITY_INFO structure for CPU nodes. +*/ +STATIC CONST COMPATIBILITY_INFO CpuCompatibleInfo = { + ARRAY_SIZE (CpuCompatibleStr), + CpuCompatibleStr +}; + +/** Pmu compatible strings. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR PmuCompatibleStr[] = { + { "arm,armv8-pmuv3" } +}; + +/** COMPATIBILITY_INFO structure for the PmuCompatibleStr. +*/ +CONST COMPATIBILITY_INFO PmuCompatibleInfo = { + ARRAY_SIZE (PmuCompatibleStr), + PmuCompatibleStr +}; + +/** Parse a "cpu" node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] CpuNode Offset of a cpu node. + @param [in] GicVersion Version of the GIC. + @param [in] AddressCells Number of address cells used for the reg + property. + @param [out] GicCInfo CM_ARM_GICC_INFO structure to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Unsupported. +**/ +STATIC +EFI_STATUS +EFIAPI +CpuNodeParser ( + IN CONST VOID *Fdt, + IN INT32 CpuNode, + IN UINT32 GicVersion, + IN UINT32 AddressCells, + OUT CM_ARM_GICC_INFO *GicCInfo + ) +{ + CONST UINT8 *Data; + INT32 DataSize; + UINT32 ProcUid; + UINT64 MpIdr; + UINT64 CheckAffMask; + + MpIdr = 0; + CheckAffMask = ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2; + + if (GicCInfo == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Data = fdt_getprop (Fdt, CpuNode, "reg", &DataSize); + if ((Data == NULL) || + ((DataSize != sizeof (UINT32)) && + (DataSize != sizeof (UINT64)))) + { + ASSERT (0); + return EFI_ABORTED; + } + + /* If cpus node's #address-cells property is set to 2 + The first reg cell bits [7:0] must be set to + bits [39:32] of MPIDR_EL1. + The second reg cell bits [23:0] must be set to + bits [23:0] of MPIDR_EL1. + */ + if (AddressCells == 2) { + MpIdr = fdt64_to_cpu (*((UINT64 *)Data)); + CheckAffMask |= ARM_CORE_AFF3; + } else { + MpIdr = fdt32_to_cpu (*((UINT32 *)Data)); + } + + if ((MpIdr & ~CheckAffMask) != 0) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // To fit the Affinity [0-3] a 32bits value, place the Aff3 on bits + // [31:24] instead of their original place ([39:32]). + ProcUid = MpIdr | ((MpIdr & ARM_CORE_AFF3) >> 8); + + /* ACPI 6.3, s5.2.12.14 GIC CPU Interface (GICC) Structure: + GIC 's CPU Interface Number. In GICv1/v2 implementations, + this value matches the bit index of the associated processor + in the GIC distributor's GICD_ITARGETSR register. For + GICv3/4 implementations this field must be provided by the + platform, if compatibility mode is supported. If it is not supported + by the implementation, then this field must be zero. + + Note: We do not support compatibility mode for GicV3 + */ + if (GicVersion == 2) { + GicCInfo->CPUInterfaceNumber = ProcUid; + } else { + GicCInfo->CPUInterfaceNumber = 0; + } + + GicCInfo->AcpiProcessorUid = ProcUid; + GicCInfo->Flags = EFI_ACPI_6_3_GIC_ENABLED; + GicCInfo->MPIDR = MpIdr; + + return EFI_SUCCESS; +} + +/** Parse a "cpus" node and its children "cpu" nodes. + + Create as many CM_ARM_GICC_INFO structures as "cpu" nodes. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] CpusNode Offset of a cpus node. + @param [in] GicVersion Version of the GIC. + @param [out] NewGicCmObjDesc If success, CM_OBJ_DESCRIPTOR containing + all the created CM_ARM_GICC_INFO. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Unsupported. +**/ +STATIC +EFI_STATUS +EFIAPI +CpusNodeParser ( + IN CONST VOID *Fdt, + IN INT32 CpusNode, + IN UINT32 GicVersion, + OUT CM_OBJ_DESCRIPTOR **NewGicCmObjDesc + ) +{ + EFI_STATUS Status; + INT32 CpuNode; + UINT32 CpuNodeCount; + INT32 AddressCells; + + UINT32 Index; + CM_ARM_GICC_INFO *GicCInfoBuffer; + UINT32 GicCInfoBufferSize; + + if (NewGicCmObjDesc == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + AddressCells = fdt_address_cells (Fdt, CpusNode); + if (AddressCells < 0) { + ASSERT (0); + return EFI_ABORTED; + } + + // Count the number of "cpu" nodes under the "cpus" node. + Status = FdtCountNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNodeCount); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (CpuNodeCount == 0) { + ASSERT (0); + return EFI_NOT_FOUND; + } + + // Allocate memory for CpuNodeCount CM_ARM_GICC_INFO structures. + GicCInfoBufferSize = CpuNodeCount * sizeof (CM_ARM_GICC_INFO); + GicCInfoBuffer = AllocateZeroPool (GicCInfoBufferSize); + if (GicCInfoBuffer == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + CpuNode = CpusNode; + for (Index = 0; Index < CpuNodeCount; Index++) { + Status = FdtGetNextNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + goto exit_handler; + } + + // Parse the "cpu" node. + if (!FdtNodeIsCompatible (Fdt, CpuNode, &CpuCompatibleInfo)) { + ASSERT (0); + Status = EFI_UNSUPPORTED; + goto exit_handler; + } + + Status = CpuNodeParser ( + Fdt, + CpuNode, + GicVersion, + AddressCells, + &GicCInfoBuffer[Index] + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + } // for + + Status = CreateCmObjDesc ( + CREATE_CM_ARM_OBJECT_ID (EArmObjGicCInfo), + CpuNodeCount, + GicCInfoBuffer, + GicCInfoBufferSize, + NewGicCmObjDesc + ); + ASSERT_EFI_ERROR (Status); + +exit_handler: + FreePool (GicCInfoBuffer); + return Status; +} + +/** Parse a Gic compatible interrupt-controller node, + extracting GicC information generic to Gic v2 and v3. + + This function modifies a CM_OBJ_DESCRIPTOR object. + The following CM_ARM_GICC_INFO fields are patched: + - VGICMaintenanceInterrupt; + - Flags; + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] GicIntcNode Offset of a Gic compatible + interrupt-controller node. + @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicCIntcNodeParser ( + IN CONST VOID *Fdt, + IN INT32 GicIntcNode, + IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc + ) +{ + EFI_STATUS Status; + INT32 IntCells; + CM_ARM_GICC_INFO *GicCInfo; + + CONST UINT8 *Data; + INT32 DataSize; + + if (GicCCmObjDesc == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Get the number of cells used to encode an interrupt. + Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Get the GSIV maintenance interrupt. + // According to the DT bindings, this could be the: + // "Interrupt source of the parent interrupt controller on secondary GICs" + // but it is assumed that only one Gic is available. + Data = fdt_getprop (Fdt, GicIntcNode, "interrupts", &DataSize); + if ((Data != NULL) && (DataSize == (IntCells * sizeof (UINT32)))) { + GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; + GicCInfo->VGICMaintenanceInterrupt = + FdtGetInterruptId ((CONST UINT32 *)Data); + GicCInfo->Flags = DT_IRQ_IS_EDGE_TRIGGERED ( + fdt32_to_cpu (((UINT32 *)Data)[IRQ_FLAGS_OFFSET]) + ) ? + EFI_ACPI_6_3_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS : + 0; + return Status; + } else if (DataSize < 0) { + // This property is optional and was not found. Just return. + return Status; + } + + // The property exists and its size doesn't match for one interrupt. + ASSERT (0); + return EFI_ABORTED; +} + +/** Parse a Gic compatible interrupt-controller node, + extracting GicCv2 information. + + This function modifies a CM_OBJ_DESCRIPTOR object. + The following CM_ARM_GICC_INFO fields are patched: + - PhysicalAddress; + - GICH; + - GICV; + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] Gicv2IntcNode Offset of a Gicv2 compatible + interrupt-controller node. + @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicCv2IntcNodeParser ( + IN CONST VOID *Fdt, + IN INT32 Gicv2IntcNode, + IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc + ) +{ + EFI_STATUS Status; + UINT32 Index; + CM_ARM_GICC_INFO *GicCInfo; + INT32 AddressCells; + INT32 SizeCells; + + CONST UINT8 *GicCValue; + CONST UINT8 *GicVValue; + CONST UINT8 *GicHValue; + + CONST UINT8 *Data; + INT32 DataSize; + UINT32 RegSize; + UINT32 RegCount; + + if (GicCCmObjDesc == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; + GicVValue = NULL; + GicHValue = NULL; + + // Get the #address-cells and #size-cells property values. + Status = FdtGetParentAddressInfo ( + Fdt, + Gicv2IntcNode, + &AddressCells, + &SizeCells + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2) || + (SizeCells < 1) || + (SizeCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + RegSize = (AddressCells + SizeCells) * sizeof (UINT32); + + Data = fdt_getprop (Fdt, Gicv2IntcNode, "reg", &DataSize); + if ((Data == NULL) || + (DataSize < 0) || + ((DataSize % RegSize) != 0)) + { + // If error or wrong size. + ASSERT (0); + return EFI_ABORTED; + } + + RegCount = DataSize/RegSize; + + switch (RegCount) { + case 4: + { + // GicV is at index 3 in the reg property. GicV is optional. + GicVValue = Data + (sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET (3, AddressCells, SizeCells)); + // fall-through. + } + case 3: + { + // GicH is at index 2 in the reg property. GicH is optional. + GicHValue = Data + (sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET (2, AddressCells, SizeCells)); + // fall-through. + } + case 2: + { + // GicC is at index 1 in the reg property. GicC is mandatory. + GicCValue = Data + (sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells)); + break; + } + default: + { + // Not enough or too much information. + ASSERT (0); + return EFI_ABORTED; + } + } + + // Patch the relevant fields of the CM_ARM_GICC_INFO objects. + for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { + if (AddressCells == 2) { + GicCInfo[Index].PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)GicCValue); + GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : + fdt64_to_cpu (*(UINT64 *)GicHValue); + GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : + fdt64_to_cpu (*(UINT64 *)GicVValue); + } else { + GicCInfo[Index].PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)GicCValue); + GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : + fdt32_to_cpu (*(UINT32 *)GicHValue); + GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : + fdt32_to_cpu (*(UINT32 *)GicVValue); + } + } // for + + return EFI_SUCCESS; +} + +/** Parse a Gic compatible interrupt-controller node, + extracting GicCv3 information. + + This function modifies a CM_OBJ_DESCRIPTOR object. + The following CM_ARM_GICC_INFO fields are patched: + - PhysicalAddress; + - GICH; + - GICV; + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] Gicv3IntcNode Offset of a Gicv3 compatible + interrupt-controller node. + @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicCv3IntcNodeParser ( + IN CONST VOID *Fdt, + IN INT32 Gicv3IntcNode, + IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc + ) +{ + EFI_STATUS Status; + UINT32 Index; + CM_ARM_GICC_INFO *GicCInfo; + INT32 AddressCells; + INT32 SizeCells; + UINT32 AdditionalRedistReg; + + CONST UINT8 *GicCValue; + CONST UINT8 *GicVValue; + CONST UINT8 *GicHValue; + + CONST UINT8 *Data; + INT32 DataSize; + UINT32 RegSize; + UINT32 RegCount; + + if (GicCCmObjDesc == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; + GicCValue = NULL; + GicVValue = NULL; + GicHValue = NULL; + + // Get the #address-cells and #size-cells property values. + Status = FdtGetParentAddressInfo ( + Fdt, + Gicv3IntcNode, + &AddressCells, + &SizeCells + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2) || + (SizeCells < 1) || + (SizeCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + // The "#redistributor-regions" property is optional. + Data = fdt_getprop (Fdt, Gicv3IntcNode, "#redistributor-regions", &DataSize); + if ((Data != NULL) && (DataSize == sizeof (UINT32))) { + ASSERT (fdt32_to_cpu (*(UINT32 *)Data) > 1); + AdditionalRedistReg = fdt32_to_cpu (*(UINT32 *)Data) - 1; + } else { + AdditionalRedistReg = 0; + } + + RegSize = (AddressCells + SizeCells) * sizeof (UINT32); + + /* + Ref: linux/blob/master/Documentation/devicetree/bindings/ + interrupt-controller/arm%2Cgic-v3.yaml + + reg: + description: | + Specifies base physical address(s) and size of the GIC + registers, in the following order: + - GIC Distributor interface (GICD) + - GIC Redistributors (GICR), one range per redistributor region + - GIC CPU interface (GICC) + - GIC Hypervisor interface (GICH) + - GIC Virtual CPU interface (GICV) + GICC, GICH and GICV are optional. + minItems: 2 + maxItems: 4096 + */ + Data = fdt_getprop (Fdt, Gicv3IntcNode, "reg", &DataSize); + if ((Data == NULL) || + (DataSize < 0) || + ((DataSize % RegSize) != 0)) + { + // If error or wrong size. + ASSERT (0); + return EFI_ABORTED; + } + + RegCount = (DataSize / RegSize) - AdditionalRedistReg; + + // The GicD and GicR info is mandatory. + switch (RegCount) { + case 5: + { + // GicV is at index 4 in the reg property. GicV is optional. + GicVValue = Data + (sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET ( + 4 + AdditionalRedistReg, + AddressCells, + SizeCells + )); + // fall-through. + } + case 4: + { + // GicH is at index 3 in the reg property. GicH is optional. + GicHValue = Data + (sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET ( + 3 + AdditionalRedistReg, + AddressCells, + SizeCells + )); + // fall-through. + } + case 3: + { + // GicC is at index 2 in the reg property. GicC is optional. + // Even though GicC is optional, it is made mandatory in this parser. + GicCValue = Data + (sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET ( + 2 + AdditionalRedistReg, + AddressCells, + SizeCells + )); + // fall-through + } + case 2: + { + // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object. + // GicD is described by the CM_ARM_GICD_INFO object. + break; + } + default: + { + // Not enough or too much information. + ASSERT (0); + return EFI_ABORTED; + } + } + + // Patch the relevant fields of the CM_ARM_GICC_INFO objects. + if (AddressCells == 2) { + for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { + // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object. + GicCInfo[Index].GICRBaseAddress = 0; + GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 : + fdt64_to_cpu (*(UINT64 *)GicCValue); + GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : + fdt64_to_cpu (*(UINT64 *)GicHValue); + GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : + fdt64_to_cpu (*(UINT64 *)GicVValue); + } + } else { + for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { + // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object. + GicCInfo[Index].GICRBaseAddress = 0; + GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 : + fdt32_to_cpu (*(UINT32 *)GicCValue); + GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : + fdt32_to_cpu (*(UINT32 *)GicHValue); + GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : + fdt32_to_cpu (*(UINT32 *)GicVValue); + } + } + + return EFI_SUCCESS; +} + +/** Parse a Pmu compatible node, extracting Pmu information. + + This function modifies a CM_OBJ_DESCRIPTOR object. + The following CM_ARM_GICC_INFO fields are patched: + - PerformanceInterruptGsiv; + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] GicIntcNode Offset of a Gic compatible + interrupt-controller node. + @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicCPmuNodeParser ( + IN CONST VOID *Fdt, + IN INT32 GicIntcNode, + IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc + ) +{ + EFI_STATUS Status; + INT32 IntCells; + INT32 PmuNode; + UINT32 PmuNodeCount; + UINT32 PmuIrq; + UINT32 Index; + CM_ARM_GICC_INFO *GicCInfo; + CONST UINT8 *Data; + INT32 DataSize; + + if (GicCCmObjDesc == NULL) { + ASSERT (GicCCmObjDesc != NULL); + return EFI_INVALID_PARAMETER; + } + + GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; + PmuNode = 0; + + // Count the number of pmu nodes. + Status = FdtCountCompatNodeInBranch ( + Fdt, + 0, + &PmuCompatibleInfo, + &PmuNodeCount + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + if (PmuNodeCount == 0) { + return EFI_NOT_FOUND; + } + + Status = FdtGetNextCompatNodeInBranch ( + Fdt, + 0, + &PmuCompatibleInfo, + &PmuNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + } + + // Get the number of cells used to encode an interrupt. + Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Data = fdt_getprop (Fdt, PmuNode, "interrupts", &DataSize); + if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) { + // If error or not 1 interrupt. + ASSERT (Data != NULL); + ASSERT (DataSize == (IntCells * sizeof (UINT32))); + return EFI_ABORTED; + } + + PmuIrq = FdtGetInterruptId ((CONST UINT32 *)Data); + + // Only supports PPI 23 for now. + // According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23. A non BSA + // compliant system may assign a different IRQ for the PMU, however this + // is not implemented for now. + if (PmuIrq != BSA_PMU_IRQ) { + ASSERT (PmuIrq == BSA_PMU_IRQ); + return EFI_ABORTED; + } + + for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { + GicCInfo[Index].PerformanceInterruptGsiv = PmuIrq; + } + + return EFI_SUCCESS; +} + +/** CM_ARM_GICC_INFO parser function. + + This parser expects FdtBranch to be the "\cpus" node node. + At most one CmObj is created. + The following structure is populated: + typedef struct CmArmGicCInfo { + UINT32 CPUInterfaceNumber; // {Populated} + UINT32 AcpiProcessorUid; // {Populated} + UINT32 Flags; // {Populated} + UINT32 ParkingProtocolVersion; // {default = 0} + UINT32 PerformanceInterruptGsiv; // {Populated} + UINT64 ParkedAddress; // {default = 0} + UINT64 PhysicalBaseAddress; // {Populated} + UINT64 GICV; // {Populated} + UINT64 GICH; // {Populated} + UINT32 VGICMaintenanceInterrupt; // {Populated} + UINT64 GICRBaseAddress; // {default = 0} + UINT64 MPIDR; // {Populated} + UINT8 ProcessorPowerEfficiencyClass; // {default = 0} + UINT16 SpeOverflowInterrupt; // {default = 0} + UINT32 ProximityDomain; // {default = 0} + UINT32 ClockDomain; // {default = 0} + UINT32 AffinityFlags; // {default = 0} + } CM_ARM_GICC_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicCInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + INT32 IntcNode; + UINT32 GicVersion; + CM_OBJ_DESCRIPTOR *NewCmObjDesc; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + NewCmObjDesc = NULL; + + // The FdtBranch points to the Cpus Node. + // Get the interrupt-controller node associated to the "cpus" node. + Status = FdtGetIntcParentNode (Fdt, FdtBranch, &IntcNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + Status = GetGicVersion (Fdt, IntcNode, &GicVersion); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Parse the "cpus" nodes and its children "cpu" nodes, + // and create a CM_OBJ_DESCRIPTOR. + Status = CpusNodeParser (Fdt, FdtBranch, GicVersion, &NewCmObjDesc); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Parse the interrupt-controller node according to the Gic version. + switch (GicVersion) { + case 2: + { + Status = GicCv2IntcNodeParser (Fdt, IntcNode, NewCmObjDesc); + break; + } + case 3: + { + Status = GicCv3IntcNodeParser (Fdt, IntcNode, NewCmObjDesc); + break; + } + default: + { + // Unsupported Gic version. + ASSERT (0); + Status = EFI_UNSUPPORTED; + } + } + + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + + // Parse the Gic information common to Gic v2 and v3. + Status = GicCIntcNodeParser (Fdt, IntcNode, NewCmObjDesc); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + + // Parse the Pmu Interrupt. + Status = GicCPmuNodeParser (Fdt, IntcNode, NewCmObjDesc); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT_EFI_ERROR (Status); + goto exit_handler; + } + + // Add all the CmObjs to the Configuration Manager. + Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + +exit_handler: + FreeCmObjDesc (NewCmObjDesc); + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h new file mode 100644 index 0000000000..539f39cecb --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h @@ -0,0 +1,68 @@ +/** @file + Arm Gic cpu parser. + + Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#ifndef ARM_GICC_PARSER_H_ +#define ARM_GICC_PARSER_H_ + +/* According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23. +*/ +#define BSA_PMU_IRQ 23 + +/** CM_ARM_GICC_INFO parser function. + + This parser expects FdtBranch to be the "\cpus" node node. + At most one CmObj is created. + The following structure is populated: + typedef struct CmArmGicCInfo { + UINT32 CPUInterfaceNumber; // {Populated} + UINT32 AcpiProcessorUid; // {Populated} + UINT32 Flags; // {Populated} + UINT32 ParkingProtocolVersion; // {default = 0} + UINT32 PerformanceInterruptGsiv; // {Populated} + UINT64 ParkedAddress; // {default = 0} + UINT64 PhysicalBaseAddress; // {Populated} + UINT64 GICV; // {Populated} + UINT64 GICH; // {Populated} + UINT32 VGICMaintenanceInterrupt; // {Populated} + UINT64 GICRBaseAddress; // {default = 0} + UINT64 MPIDR; // {Populated} + UINT8 ProcessorPowerEfficiencyClass; // {default = 0} + UINT16 SpeOverflowInterrupt; // {default = 0} + UINT32 ProximityDomain; // {default = 0} + UINT32 ClockDomain; // {default = 0} + UINT32 AffinityFlags; // {default = 0} + } CM_ARM_GICC_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicCInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GICC_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c new file mode 100644 index 0000000000..906ef8b858 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c @@ -0,0 +1,171 @@ +/** @file + Arm Gic Distributor Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#include "CmObjectDescUtility.h" +#include "FdtHwInfoParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" +#include "Arm/Gic/ArmGicDParser.h" + +/** Parse a Gic compatible interrupt-controller node, + extracting GicD information. + + This parser is valid for Gic v2 and v3. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] GicIntcNode Offset of a Gic compatible + interrupt-controller node. + @param [in] GicDInfo The CM_ARM_GICD_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicDIntcNodeParser ( + IN CONST VOID *Fdt, + IN INT32 GicIntcNode, + IN CM_ARM_GICD_INFO *GicDInfo + ) +{ + EFI_STATUS Status; + INT32 AddressCells; + CONST UINT8 *Data; + INT32 DataSize; + + if ((Fdt == NULL) || + (GicDInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Status = FdtGetParentAddressInfo (Fdt, GicIntcNode, &AddressCells, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + Data = fdt_getprop (Fdt, GicIntcNode, "reg", &DataSize); + if ((Data == NULL) || (DataSize < (INT32)(AddressCells * sizeof (UINT32)))) { + // If error or not enough space. + ASSERT (0); + return EFI_ABORTED; + } + + if (AddressCells == 2) { + GicDInfo->PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); + } else { + GicDInfo->PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); + } + + return Status; +} + +/** CM_ARM_GICD_INFO parser function. + + This parser expects FdtBranch to be a Gic interrupt-controller node. + At most one CmObj is created. + The following structure is populated: + typedef struct CmArmGicDInfo { + UINT64 PhysicalBaseAddress; // {Populated} + UINT32 SystemVectorBase; + UINT8 GicVersion; // {Populated} + } CM_ARM_GICD_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicDInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + UINT32 GicVersion; + CM_ARM_GICD_INFO GicDInfo; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + if (!FdtNodeHasProperty (Fdt, FdtBranch, "interrupt-controller")) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Get the Gic version of the interrupt-controller. + Status = GetGicVersion (Fdt, FdtBranch, &GicVersion); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + ZeroMem (&GicDInfo, sizeof (GicDInfo)); + GicDInfo.GicVersion = GicVersion; + + // Parse the interrupt-controller depending on its Gic version. + switch (GicVersion) { + case 2: + case 3: + { + // Set the Gic version, then parse the GicD information. + Status = GicDIntcNodeParser (Fdt, FdtBranch, &GicDInfo); + break; + } + default: + { + // Unsupported Gic version. + ASSERT (0); + return EFI_UNSUPPORTED; + } + } + + // Add the CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARM_OBJECT_ID (EArmObjGicDInfo), + &GicDInfo, + sizeof (CM_ARM_GICD_INFO), + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h new file mode 100644 index 0000000000..b9581f0eb9 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h @@ -0,0 +1,50 @@ +/** @file + Arm Gic Distributor Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#ifndef ARM_GICD_PARSER_H_ +#define ARM_GICD_PARSER_H_ + +/** CM_ARM_GICD_INFO parser function. + + This parser expects FdtBranch to be a Gic interrupt-controller node. + At most one CmObj is created. + The following structure is populated: + typedef struct CmArmGicDInfo { + UINT64 PhysicalBaseAddress; // {Populated} + UINT32 SystemVectorBase; + UINT8 GicVersion; // {Populated} + } CM_ARM_GICD_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicDInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GICD_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c new file mode 100644 index 0000000000..ca34d24a78 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c @@ -0,0 +1,218 @@ +/** @file + Arm Gic dispatcher. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#include "FdtHwInfoParser.h" +#include "Arm/Gic/ArmGicCParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" +#include "Arm/Gic/ArmGicDParser.h" +#include "Arm/Gic/ArmGicItsParser.h" +#include "Arm/Gic/ArmGicMsiFrameParser.h" +#include "Arm/Gic/ArmGicRParser.h" + +/** List of "compatible" property values for GicV2 interrupt nodes. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR GicV2CompatibleStr[] = { + { "arm,cortex-a15-gic" } +}; + +/** COMPATIBILITY_INFO structure for the GICv2. +*/ +CONST COMPATIBILITY_INFO GicV2CompatibleInfo = { + ARRAY_SIZE (GicV2CompatibleStr), + GicV2CompatibleStr +}; + +/** List of "compatible" property values for GicV3 interrupt nodes. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR GicV3CompatibleStr[] = { + { "arm,gic-v3" } +}; + +/** COMPATIBILITY_INFO structure for the GICv3. +*/ +CONST COMPATIBILITY_INFO GicV3CompatibleInfo = { + ARRAY_SIZE (GicV3CompatibleStr), + GicV3CompatibleStr +}; + +/** Get the Gic version of am interrupt-controller node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] IntcNode Interrupt-controller node. + @param [out] GicVersion If success, contains the Gic version of the + interrupt-controller node. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +GetGicVersion ( + IN CONST VOID *Fdt, + IN INT32 IntcNode, + OUT UINT32 *GicVersion + ) +{ + if ((Fdt == NULL) || + (GicVersion == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if (FdtNodeIsCompatible (Fdt, IntcNode, &GicV2CompatibleInfo)) { + *GicVersion = 2; + } else if (FdtNodeIsCompatible (Fdt, IntcNode, &GicV3CompatibleInfo)) { + *GicVersion = 3; + } else { + // Unsupported Gic version. + ASSERT (0); + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** Gic dispatcher. + + This disptacher populates the following structures: + - CM_ARM_GICC_INFO + - CM_ARM_GICD_INFO + - CM_ARM_GIC_MSI_FRAME_INFO + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicDispatcher ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + INT32 CpusNode; + INT32 IntcNode; + UINT32 GicVersion; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + // The "cpus" node resides at the root of the DT. Fetch it. + CpusNode = fdt_path_offset (Fdt, "/cpus"); + if (CpusNode < 0) { + return EFI_NOT_FOUND; + } + + // Get the interrupt-controller node associated to the "cpus" node. + Status = FdtGetIntcParentNode (Fdt, CpusNode, &IntcNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + Status = GetGicVersion (Fdt, IntcNode, &GicVersion); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Parse the GicC information. + Status = ArmGicCInfoParser (FdtParserHandle, CpusNode); + if (EFI_ERROR (Status)) { + // Don't try to parse GicD and GicMsiFrame information + // if no GicC information is found. Return. + ASSERT (Status == EFI_NOT_FOUND); + return Status; + } + + // Parse the GicD information of the "cpus" interrupt-controller node. + Status = ArmGicDInfoParser (FdtParserHandle, IntcNode); + if (EFI_ERROR (Status)) { + // EFI_NOT_FOUND is not tolerated at this point. + ASSERT (0); + return Status; + } + + switch (GicVersion) { + case 4: + case 3: + { + // Parse the GicR information of the interrupt-controller node. + Status = ArmGicRInfoParser (FdtParserHandle, IntcNode); + if (EFI_ERROR (Status)) { + // EFI_NOT_FOUND is not tolerated at this point. + ASSERT (0); + return Status; + } + + // Parse the GicIts information of the interrupt-controller node. + Status = ArmGicItsInfoParser (FdtParserHandle, IntcNode); + if (EFI_ERROR (Status) && + (Status != EFI_NOT_FOUND)) + { + ASSERT (0); + return Status; + } + + break; + } + case 2: + { + // Parse the GicMsiFrame information. + Status = ArmGicMsiFrameInfoParser (FdtParserHandle, IntcNode); + if (EFI_ERROR (Status) && + (Status != EFI_NOT_FOUND)) + { + ASSERT (0); + return Status; + } + + break; + } + default: + { + ASSERT (0); + return EFI_UNSUPPORTED; + } + } + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h new file mode 100644 index 0000000000..aa942f7d1f --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h @@ -0,0 +1,72 @@ +/** @file + Arm Gic dispatcher. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#ifndef ARM_GIC_DISPATCHER_H_ +#define ARM_GIC_DISPATCHER_H_ + +#include +#include "FdtUtility.h" + +/** COMPATIBILITY_INFO structure for the GICv2. +*/ +extern CONST COMPATIBILITY_INFO GicV2CompatibleInfo; + +/** Get the Gic version of the interrupt-controller node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] IntcNode Interrupt-controller node. + @param [out] GicVersion If success, contains the Gic version of the + interrupt-controller node. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +GetGicVersion ( + IN CONST VOID *Fdt, + IN INT32 IntcNode, + OUT UINT32 *GicVersion + ); + +/** Gic dispatcher. + + This disptacher populates the following structures: + - CM_ARM_GICC_INFO + - CM_ARM_GICD_INFO + - CM_ARM_GIC_MSI_FRAME_INFO + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicDispatcher ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GIC_DISPATCHER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c new file mode 100644 index 0000000000..6d4bde6a14 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c @@ -0,0 +1,218 @@ +/** @file + Arm Gic Interrupt Translation Service Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#include "CmObjectDescUtility.h" +#include "FdtHwInfoParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" +#include "Arm/Gic/ArmGicItsParser.h" + +/** Parse a Gic compatible interrupt-controller node, + extracting GicIts information. + + This parser is valid for Gic v3 and higher. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] GicIntcNode Offset of a Gic compatible + interrupt-controller node. + @param [in] GicItsId Id for the Gic ITS node. + @param [in] GicItsInfo The CM_ARM_GIC_ITS_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicItsIntcNodeParser ( + IN CONST VOID *Fdt, + IN INT32 GicIntcNode, + IN UINT32 GicItsId, + IN CM_ARM_GIC_ITS_INFO *GicItsInfo + ) +{ + EFI_STATUS Status; + INT32 AddressCells; + CONST UINT8 *Data; + INT32 DataSize; + + if ((Fdt == NULL) || + (GicItsInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Status = FdtGetParentAddressInfo (Fdt, GicIntcNode, &AddressCells, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + Data = fdt_getprop (Fdt, GicIntcNode, "reg", &DataSize); + if ((Data == NULL) || (DataSize < (INT32)(AddressCells * sizeof (UINT32)))) { + // If error or not enough space. + ASSERT (0); + return EFI_ABORTED; + } + + if (AddressCells == 2) { + GicItsInfo->PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); + } else { + GicItsInfo->PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); + } + + // Gic Its Id + GicItsInfo->GicItsId = GicItsId; + + // {default = 0} + GicItsInfo->ProximityDomain = 0; + return Status; +} + +/** CM_ARM_GIC_ITS_INFO parser function. + + This parser expects FdtBranch to be a Gic interrupt-controller node. + Gic version must be v3 or higher. + typedef struct CmArmGicItsInfo { + UINT32 GicItsId; // {Populated} + UINT64 PhysicalBaseAddress; // {Populated} + UINT32 ProximityDomain; // {default = 0} + } CM_ARM_GIC_ITS_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicItsInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + UINT32 GicVersion; + CM_ARM_GIC_ITS_INFO GicItsInfo; + UINT32 Index; + INT32 GicItsNode; + UINT32 GicItsNodeCount; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + if (!FdtNodeHasProperty (Fdt, FdtBranch, "interrupt-controller")) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Get the Gic version of the interrupt-controller. + Status = GetGicVersion (Fdt, FdtBranch, &GicVersion); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (GicVersion < 3) { + ASSERT (0); + return EFI_UNSUPPORTED; + } + + // Count the nodes with the "msi-controller" property. + // The interrupt-controller itself can have this property, + // but the first node is skipped in the search. + Status = FdtCountPropNodeInBranch ( + Fdt, + FdtBranch, + "msi-controller", + &GicItsNodeCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (GicItsNodeCount == 0) { + return EFI_NOT_FOUND; + } + + GicItsNode = FdtBranch; + for (Index = 0; Index < GicItsNodeCount; Index++) { + ZeroMem (&GicItsInfo, sizeof (CM_ARM_GIC_ITS_INFO)); + + Status = FdtGetNextPropNodeInBranch ( + Fdt, + FdtBranch, + "msi-controller", + &GicItsNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + Status = GicItsIntcNodeParser ( + Fdt, + GicItsNode, + Index, + &GicItsInfo + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARM_OBJECT_ID (EArmObjGicItsInfo), + &GicItsInfo, + sizeof (CM_ARM_GIC_ITS_INFO), + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } // for + + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h new file mode 100644 index 0000000000..be944493e4 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h @@ -0,0 +1,48 @@ +/** @file + Arm Gic Interrupt Translation Service Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#ifndef ARM_GIC_ITS_PARSER_H_ +#define ARM_GIC_ITS_PARSER_H_ + +/** CM_ARM_GIC_ITS_INFO parser function. + + This parser expects FdtBranch to be a Gic interrupt-controller node. + Gic version must be v3 or higher. + typedef struct CmArmGicItsInfo { + UINT32 GicItsId; // {Populated} + UINT64 PhysicalBaseAddress; // {Populated} + UINT32 ProximityDomain; // {default = 0} + } CM_ARM_GIC_ITS_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicItsInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GIC_ITS_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c new file mode 100644 index 0000000000..dff5beff91 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c @@ -0,0 +1,217 @@ +/** @file + Arm Gic Msi frame Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#include "CmObjectDescUtility.h" +#include "FdtHwInfoParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" +#include "Arm/Gic/ArmGicMsiFrameParser.h" + +/** List of "compatible" property values for Msi-frame nodes. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR MsiFrameCompatibleStr[] = { + { "arm,gic-v2m-frame" } +}; + +/** COMPATIBILITY_INFO structure for the MSI frame. +*/ +STATIC CONST COMPATIBILITY_INFO MsiFrameCompatibleInfo = { + ARRAY_SIZE (MsiFrameCompatibleStr), + MsiFrameCompatibleStr +}; + +/** Parse a Msi frame node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] MsiFrameNode Offset of a Msi frame node. + @param [in] MsiFrameId Frame ID. + @param [out] MsiFrameInfo The CM_ARM_GIC_MSI_FRAME_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +MsiFrameNodeParser ( + IN CONST VOID *Fdt, + IN INT32 MsiFrameNode, + IN UINT32 MsiFrameId, + OUT CM_ARM_GIC_MSI_FRAME_INFO *MsiFrameInfo + ) +{ + EFI_STATUS Status; + INT32 AddressCells; + CONST UINT8 *Data; + INT32 DataSize; + + if ((Fdt == NULL) || + (MsiFrameInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Status = FdtGetParentAddressInfo (Fdt, MsiFrameNode, &AddressCells, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + Data = fdt_getprop (Fdt, MsiFrameNode, "reg", &DataSize); + if ((Data == NULL) || (DataSize < (INT32)(AddressCells * sizeof (UINT32)))) { + // If error or not enough space. + ASSERT (0); + return EFI_ABORTED; + } + + if (AddressCells == 2) { + MsiFrameInfo->PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); + } else { + MsiFrameInfo->PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); + } + + MsiFrameInfo->GicMsiFrameId = MsiFrameId; + + return EFI_SUCCESS; +} + +/** CM_ARM_GIC_MSI_FRAME_INFO parser function. + + The following structure is populated: + typedef struct CmArmGicMsiFrameInfo { + UINT32 GicMsiFrameId; // {Populated} + UINT64 PhysicalBaseAddress; // {Populated} + UINT32 Flags; // {default = 0} + UINT16 SPICount; + UINT16 SPIBase; + } CM_ARM_GIC_MSI_FRAME_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicMsiFrameInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + INT32 MsiFrameNode; + UINT32 MsiFrameNodeCount; + + UINT32 Index; + CM_ARM_GIC_MSI_FRAME_INFO MsiFrameInfo; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + // Count the number of nodes having the "interrupt-controller" property. + Status = FdtCountPropNodeInBranch ( + Fdt, + FdtBranch, + "msi-controller", + &MsiFrameNodeCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (MsiFrameNodeCount == 0) { + return EFI_NOT_FOUND; + } + + // Parse each node having the "msi-controller" property. + MsiFrameNode = FdtBranch; + for (Index = 0; Index < MsiFrameNodeCount; Index++) { + ZeroMem (&MsiFrameInfo, sizeof (CM_ARM_GIC_MSI_FRAME_INFO)); + + Status = FdtGetNextPropNodeInBranch ( + Fdt, + FdtBranch, + "msi-controller", + &MsiFrameNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + if (!FdtNodeIsCompatible (Fdt, MsiFrameNode, &MsiFrameCompatibleInfo)) { + ASSERT (0); + Status = EFI_UNSUPPORTED; + return Status; + } + + // Parse the Msi information. + Status = MsiFrameNodeParser ( + Fdt, + MsiFrameNode, + Index, + &MsiFrameInfo + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARM_OBJECT_ID (EArmObjGicMsiFrameInfo), + &MsiFrameInfo, + sizeof (CM_ARM_GIC_MSI_FRAME_INFO), + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } // for + + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h new file mode 100644 index 0000000000..2821a784f7 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h @@ -0,0 +1,50 @@ +/** @file + Arm Gic Msi frame Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#ifndef ARM_GIC_MSI_FRAME_PARSER_H_ +#define ARM_GIC_MSI_FRAME_PARSER_H_ + +/** CM_ARM_GIC_MSI_FRAME_INFO parser function. + + The following structure is populated: + typedef struct CmArmGicMsiFrameInfo { + UINT32 GicMsiFrameId; // {Populated} + UINT64 PhysicalBaseAddress; // {Populated} + UINT32 Flags; // {default = 0} + UINT16 SPICount; + UINT16 SPIBase; + } CM_ARM_GIC_MSI_FRAME_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicMsiFrameInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GIC_MSI_FRAME_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c new file mode 100644 index 0000000000..de2e1dd1f1 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c @@ -0,0 +1,238 @@ +/** @file + Arm Gic Redistributor Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#include "CmObjectDescUtility.h" +#include "FdtHwInfoParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" +#include "Arm/Gic/ArmGicRParser.h" + +/** Parse a Gic compatible interrupt-controller node, + extracting GicR information. + + This parser is valid for Gic v3 and higher. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] GicIntcNode Offset of a Gic compatible + interrupt-controller node. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GicRIntcNodeParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 GicIntcNode + ) +{ + EFI_STATUS Status; + UINT32 Index; + UINT32 RedistReg; + UINT32 RegSize; + INT32 AddressCells; + INT32 SizeCells; + CONST UINT8 *Data; + INT32 DataSize; + CM_ARM_GIC_REDIST_INFO GicRInfo; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + Status = FdtGetParentAddressInfo ( + Fdt, + GicIntcNode, + &AddressCells, + &SizeCells + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2) || + (SizeCells < 1) || + (SizeCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + // The "#redistributor-regions" property is optional. + // It indicates the number of GicR. + Data = fdt_getprop (Fdt, GicIntcNode, "#redistributor-regions", &DataSize); + if ((Data != NULL) && (DataSize == sizeof (UINT32))) { + // If available, must be on one cell. + RedistReg = fdt32_to_cpu (*(UINT32 *)Data); + } else { + // The DT Spec says GicR is mandatory so we will + // always have one. + RedistReg = 1; + } + + /* + Ref: linux/blob/master/Documentation/devicetree/bindings/ + interrupt-controller/arm%2Cgic-v3.yaml + + reg: + description: | + Specifies base physical address(s) and size of the GIC + registers, in the following order: + - GIC Distributor interface (GICD) + - GIC Redistributors (GICR), one range per redistributor region + - GIC CPU interface (GICC) + - GIC Hypervisor interface (GICH) + - GIC Virtual CPU interface (GICV) + GICC, GICH and GICV are optional. + minItems: 2 + maxItems: 4096 + + Example: + interrupt-controller@2c010000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + interrupt-controller; + redistributor-stride = <0x0 0x40000>; // 256kB stride + #redistributor-regions = <2>; + reg = <0x2c010000 0x10000>, // GICD + <0x2d000000 0x800000>, // GICR 1: CPUs 0-31 + <0x2e000000 0x800000>, // GICR 2: CPUs 32-63 + <0x2c040000 0x2000>, // GICC + <0x2c060000 0x2000>, // GICH + <0x2c080000 0x2000>; // GICV + interrupts = <1 9 4>; + ... + } + */ + RegSize = (AddressCells + SizeCells) * sizeof (UINT32); + Data = fdt_getprop (Fdt, GicIntcNode, "reg", &DataSize); + if ((Data == NULL) || + (DataSize < 0) || + ((DataSize % RegSize) != 0)) + { + // If error or wrong size. + ASSERT (0); + return EFI_ABORTED; + } + + Data += GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells) + * sizeof (UINT32); + for (Index = 0; Index < RedistReg; Index++) { + ZeroMem (&GicRInfo, sizeof (CM_ARM_GIC_REDIST_INFO)); + + if (AddressCells == 2) { + GicRInfo.DiscoveryRangeBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); + } else { + GicRInfo.DiscoveryRangeBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); + } + + Data += sizeof (UINT32) * AddressCells; + + if (SizeCells == 2) { + GicRInfo.DiscoveryRangeLength = (UINT32)fdt64_to_cpu (*(UINT64 *)Data); + } else { + GicRInfo.DiscoveryRangeLength = fdt32_to_cpu (*(UINT32 *)Data); + } + + // Add the CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARM_OBJECT_ID (EArmObjGicRedistributorInfo), + &GicRInfo, + sizeof (CM_ARM_GIC_REDIST_INFO), + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Data += sizeof (UINT32) * SizeCells; + } // for + + return Status; +} + +/** CM_ARM_GIC_REDIST_INFO parser function. + + This parser expects FdtBranch to be a Gic interrupt-controller node. + Gic version must be v3 or higher. + typedef struct CmArmGicRedistInfo { + UINT64 DiscoveryRangeBaseAddress; // {Populated} + UINT32 DiscoveryRangeLength; // {Populated} + } CM_ARM_GIC_REDIST_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicRInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + UINT32 GicVersion; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + if (!FdtNodeHasProperty (Fdt, FdtBranch, "interrupt-controller")) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Get the Gic version of the interrupt-controller. + Status = GetGicVersion (Fdt, FdtBranch, &GicVersion); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (GicVersion < 3) { + ASSERT (0); + return EFI_UNSUPPORTED; + } + + Status = GicRIntcNodeParser (FdtParserHandle, FdtBranch); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h new file mode 100644 index 0000000000..c2b7eabfed --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h @@ -0,0 +1,47 @@ +/** @file + Arm Gic Redistributor Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +**/ + +#ifndef ARM_GICR_PARSER_H_ +#define ARM_GICR_PARSER_H_ + +/** CM_ARM_GIC_REDIST_INFO parser function. + + This parser expects FdtBranch to be a Gic interrupt-controller node. + Gic version must be v3 or higher. + typedef struct CmArmGicRedistInfo { + UINT64 DiscoveryRangeBaseAddress; // {Populated} + UINT32 DiscoveryRangeLength; // {Populated} + } CM_ARM_GIC_REDIST_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArmGicRInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // ARM_GICR_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c deleted file mode 100644 index b07b6b8b66..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c +++ /dev/null @@ -1,159 +0,0 @@ -/** @file - Arm boot architecture parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/arm/psci.yaml -**/ - -#include "FdtHwInfoParser.h" -#include "CmObjectDescUtility.h" -#include "BootArch/ArmBootArchParser.h" - -/** List of "compatible" property values for Psci nodes. - - Other "compatible" values are not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR PsciCompatibleStr[] = { - { "arm,psci-0.2" }, - { "arm,psci" } -}; - -/** COMPATIBILITY_INFO structure for the PsciCompatibleInfo. -*/ -STATIC CONST COMPATIBILITY_INFO PsciCompatibleInfo = { - ARRAY_SIZE (PsciCompatibleStr), - PsciCompatibleStr -}; - -/** List of PSCI method strings. -*/ -STATIC CONST CHAR8 *PsciMethod[] = { - "smc", - "hvc" -}; - -/** Parse a Psci node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] PsciNode Offset of a Psci node. - @param [in] BootArchInfo The CM_ARM_BOOT_ARCH_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -PsciNodeParser ( - IN CONST VOID *Fdt, - IN INT32 PsciNode, - IN CM_ARM_BOOT_ARCH_INFO *BootArchInfo - ) -{ - CONST VOID *Data; - INT32 DataSize; - - if ((Fdt == NULL) || - (BootArchInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Default to parking protocol - BootArchInfo->BootArchFlags = 0; - - Data = fdt_getprop (Fdt, PsciNode, "method", &DataSize); - if ((Data == NULL) || (DataSize < 0)) { - ASSERT (0); - return EFI_ABORTED; - } - - // Check PSCI conduit. - if (AsciiStrnCmp (Data, PsciMethod[0], DataSize) == 0) { - BootArchInfo->BootArchFlags = EFI_ACPI_6_3_ARM_PSCI_COMPLIANT; - } else if (AsciiStrnCmp (Data, PsciMethod[1], DataSize) == 0) { - BootArchInfo->BootArchFlags = (EFI_ACPI_6_3_ARM_PSCI_COMPLIANT | - EFI_ACPI_6_3_ARM_PSCI_USE_HVC); - } - - return EFI_SUCCESS; -} - -/** CM_ARM_BOOT_ARCH_INFO parser function. - - The following structure is populated: - typedef struct CmArmBootArchInfo { - UINT16 BootArchFlags; // {Populated} - } CM_ARM_BOOT_ARCH_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmBootArchInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - INT32 PsciNode; - CM_ARM_BOOT_ARCH_INFO BootArchInfo; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - ZeroMem (&BootArchInfo, sizeof (CM_ARM_BOOT_ARCH_INFO)); - - PsciNode = FdtBranch; - Status = FdtGetNextCompatNodeInBranch ( - FdtParserHandle->Fdt, - FdtBranch, - &PsciCompatibleInfo, - &PsciNode - ); - if (EFI_ERROR (Status)) { - // Error, or no node found. - ASSERT (Status == EFI_NOT_FOUND); - return Status; - } - - // Parse the psci node. - Status = PsciNodeParser (FdtParserHandle->Fdt, PsciNode, &BootArchInfo); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjBootArchInfo), - &BootArchInfo, - sizeof (CM_ARM_BOOT_ARCH_INFO), - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h deleted file mode 100644 index 51654f0e1e..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h +++ /dev/null @@ -1,45 +0,0 @@ -/** @file - Arm boot architecture parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/arm/psci.yaml -**/ - -#ifndef ARM_BOOT_ARCH_PARSER_H_ -#define ARM_BOOT_ARCH_PARSER_H_ - -/** CM_ARM_BOOT_ARCH_INFO parser function. - - The following structure is populated: - typedef struct CmArmBootArchInfo { - UINT16 BootArchFlags; // {Populated} - } CM_ARM_BOOT_ARCH_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmBootArchInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_BOOT_ARCH_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c index 376de078bc..78bf9c9efa 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c @@ -6,9 +6,9 @@ **/ #include "FdtHwInfoParser.h" -#include "BootArch/ArmBootArchParser.h" -#include "GenericTimer/ArmGenericTimerParser.h" -#include "Gic/ArmGicDispatcher.h" +#include "Arm/BootArch/ArmBootArchParser.h" +#include "Arm/GenericTimer/ArmGenericTimerParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" #include "Pci/ArmPciConfigSpaceParser.h" #include "Serial/ArmSerialPortParser.h" diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf index d2c171acca..fa768cf664 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf @@ -22,22 +22,22 @@ FdtHwInfoParser.h FdtUtility.c FdtUtility.h - BootArch/ArmBootArchParser.c - BootArch/ArmBootArchParser.h - GenericTimer/ArmGenericTimerParser.c - GenericTimer/ArmGenericTimerParser.h - Gic/ArmGicCParser.c - Gic/ArmGicCParser.h - Gic/ArmGicDispatcher.c - Gic/ArmGicDispatcher.h - Gic/ArmGicDParser.c - Gic/ArmGicDParser.h - Gic/ArmGicItsParser.c - Gic/ArmGicItsParser.h - Gic/ArmGicMsiFrameParser.c - Gic/ArmGicMsiFrameParser.h - Gic/ArmGicRParser.c - Gic/ArmGicRParser.h + Arm/BootArch/ArmBootArchParser.c + Arm/BootArch/ArmBootArchParser.h + Arm/GenericTimer/ArmGenericTimerParser.c + Arm/GenericTimer/ArmGenericTimerParser.h + Arm/Gic/ArmGicCParser.c + Arm/Gic/ArmGicCParser.h + Arm/Gic/ArmGicDispatcher.c + Arm/Gic/ArmGicDispatcher.h + Arm/Gic/ArmGicDParser.c + Arm/Gic/ArmGicDParser.h + Arm/Gic/ArmGicItsParser.c + Arm/Gic/ArmGicItsParser.h + Arm/Gic/ArmGicMsiFrameParser.c + Arm/Gic/ArmGicMsiFrameParser.h + Arm/Gic/ArmGicRParser.c + Arm/Gic/ArmGicRParser.h Pci/ArmPciConfigSpaceParser.c Pci/ArmPciConfigSpaceParser.h Serial/ArmSerialPortParser.c diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c deleted file mode 100644 index 988a81221d..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c +++ /dev/null @@ -1,258 +0,0 @@ -/** @file - Arm generic timer parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml -**/ - -#include "FdtHwInfoParser.h" -#include "CmObjectDescUtility.h" -#include "GenericTimer/ArmGenericTimerParser.h" -#include "Gic/ArmGicDispatcher.h" - -/** List of "compatible" property values for timer nodes. - - Other "compatible" values are not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR TimerCompatibleStr[] = { - { "arm,armv7-timer" }, - { "arm,armv8-timer" } -}; - -/** Timer compatiblity information. -*/ -STATIC CONST COMPATIBILITY_INFO TimerCompatibleInfo = { - ARRAY_SIZE (TimerCompatibleStr), - TimerCompatibleStr -}; - -/** Parse a timer node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] TimerNode Offset of a timer node. - @param [in] GenericTimerInfo The CM_ARM_BOOT_ARCH_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -TimerNodeParser ( - IN CONST VOID *Fdt, - IN INT32 TimerNode, - IN CM_ARM_GENERIC_TIMER_INFO *GenericTimerInfo - ) -{ - EFI_STATUS Status; - CONST UINT32 *Data; - INT32 IntcNode; - UINT32 GicVersion; - INT32 DataSize; - INT32 IntCells; - BOOLEAN AlwaysOnTimer; - - if ((Fdt == NULL) || - (GenericTimerInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Data = fdt_getprop (Fdt, TimerNode, "always-on", &DataSize); - if ((Data == NULL) || (DataSize < 0)) { - AlwaysOnTimer = FALSE; - } else { - AlwaysOnTimer = TRUE; - } - - // Get the associated interrupt-controller. - Status = FdtGetIntcParentNode (Fdt, TimerNode, &IntcNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Check that the interrupt-controller node is a Gic. - Status = GetGicVersion (Fdt, IntcNode, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Get the number of cells used to encode an interrupt. - Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - Data = fdt_getprop (Fdt, TimerNode, "interrupts", &DataSize); - if ((Data == NULL) || - (DataSize != (FdtMaxTimerItem * IntCells * sizeof (UINT32)))) - { - // If error or not FdtMaxTimerItem interrupts. - ASSERT (0); - return EFI_ABORTED; - } - - GenericTimerInfo->SecurePL1TimerGSIV = - FdtGetInterruptId (&Data[FdtSecureTimerIrq * IntCells]); - GenericTimerInfo->SecurePL1TimerFlags = - FdtGetInterruptFlags (&Data[FdtSecureTimerIrq * IntCells]); - GenericTimerInfo->NonSecurePL1TimerGSIV = - FdtGetInterruptId (&Data[FdtNonSecureTimerIrq * IntCells]); - GenericTimerInfo->NonSecurePL1TimerFlags = - FdtGetInterruptFlags (&Data[FdtNonSecureTimerIrq * IntCells]); - GenericTimerInfo->VirtualTimerGSIV = - FdtGetInterruptId (&Data[FdtVirtualTimerIrq * IntCells]); - GenericTimerInfo->VirtualTimerFlags = - FdtGetInterruptFlags (&Data[FdtVirtualTimerIrq * IntCells]); - GenericTimerInfo->NonSecurePL2TimerGSIV = - FdtGetInterruptId (&Data[FdtHypervisorTimerIrq * IntCells]); - GenericTimerInfo->NonSecurePL2TimerFlags = - FdtGetInterruptFlags (&Data[FdtHypervisorTimerIrq * IntCells]); - - if (AlwaysOnTimer) { - GenericTimerInfo->SecurePL1TimerFlags |= BIT2; - GenericTimerInfo->NonSecurePL1TimerFlags |= BIT2; - GenericTimerInfo->VirtualTimerFlags |= BIT2; - GenericTimerInfo->NonSecurePL2TimerFlags |= BIT2; - } - - // Setup default values - // The CntControlBase & CntReadBase Physical Address are optional if - // the system implements EL3 (Security Extensions). So, initialise - // these to their default value. - GenericTimerInfo->CounterControlBaseAddress = 0xFFFFFFFFFFFFFFFF; - GenericTimerInfo->CounterReadBaseAddress = 0xFFFFFFFFFFFFFFFF; - - // For systems not implementing ARMv8.1 VHE, this field is 0. - GenericTimerInfo->VirtualPL2TimerGSIV = 0; - GenericTimerInfo->VirtualPL2TimerFlags = 0; - - return EFI_SUCCESS; -} - -/** CM_ARM_GENERIC_TIMER_INFO parser function. - - The following structure is populated: - typedef struct CmArmGenericTimerInfo { - UINT64 CounterControlBaseAddress; // {default} - UINT64 CounterReadBaseAddress; // {default} - UINT32 SecurePL1TimerGSIV; // {Populated} - UINT32 SecurePL1TimerFlags; // {Populated} - UINT32 NonSecurePL1TimerGSIV; // {Populated} - UINT32 NonSecurePL1TimerFlags; // {Populated} - UINT32 VirtualTimerGSIV; // {Populated} - UINT32 VirtualTimerFlags; // {Populated} - UINT32 NonSecurePL2TimerGSIV; // {Populated} - UINT32 NonSecurePL2TimerFlags; // {Populated} - UINT32 VirtualPL2TimerGSIV; // {default} - UINT32 VirtualPL2TimerFlags; // {default} - } CM_ARM_GENERIC_TIMER_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGenericTimerInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - UINT32 Index; - INT32 TimerNode; - UINT32 TimerNodeCount; - CM_ARM_GENERIC_TIMER_INFO GenericTimerInfo; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - Status = FdtCountCompatNodeInBranch ( - Fdt, - FdtBranch, - &TimerCompatibleInfo, - &TimerNodeCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (TimerNodeCount == 0) { - return EFI_NOT_FOUND; - } - - // Parse each timer node in the branch. - TimerNode = FdtBranch; - for (Index = 0; Index < TimerNodeCount; Index++) { - ZeroMem (&GenericTimerInfo, sizeof (CM_ARM_GENERIC_TIMER_INFO)); - - Status = FdtGetNextCompatNodeInBranch ( - Fdt, - FdtBranch, - &TimerCompatibleInfo, - &TimerNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - Status = TimerNodeParser (Fdt, TimerNode, &GenericTimerInfo); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjGenericTimerInfo), - &GenericTimerInfo, - sizeof (CM_ARM_GENERIC_TIMER_INFO), - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } // for - - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h deleted file mode 100644 index d7fa278c90..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h +++ /dev/null @@ -1,66 +0,0 @@ -/** @file - Arm generic timer parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml -**/ - -#ifndef ARM_GENERIC_TIMER_PARSER_H_ -#define ARM_GENERIC_TIMER_PARSER_H_ - -/** An enum listing the FDT interrupt items. -*/ -typedef enum FdtTimerInterruptItems { - FdtSecureTimerIrq, ///< Secure timer IRQ - FdtNonSecureTimerIrq, ///< Non-secure timer IRQ - FdtVirtualTimerIrq, ///< Virtual timer IRQ - FdtHypervisorTimerIrq, ///< Hypervisor timer IRQ - FdtMaxTimerItem ///< Max timer item -} FDT_TIMER_INTERRUPT_ITEMS; - -/** CM_ARM_BOOT_ARCH_INFO parser function. - - The following structure is populated: - typedef struct CmArmGenericTimerInfo { - UINT64 CounterControlBaseAddress; // {default} - UINT64 CounterReadBaseAddress; // {default} - UINT32 SecurePL1TimerGSIV; // {Populated} - UINT32 SecurePL1TimerFlags; // {Populated} - UINT32 NonSecurePL1TimerGSIV; // {Populated} - UINT32 NonSecurePL1TimerFlags; // {Populated} - UINT32 VirtualTimerGSIV; // {Populated} - UINT32 VirtualTimerFlags; // {Populated} - UINT32 NonSecurePL2TimerGSIV; // {Populated} - UINT32 NonSecurePL2TimerFlags; // {Populated} - UINT32 VirtualPL2TimerGSIV; // {default} - UINT32 VirtualPL2TimerFlags; // {default} - } CM_ARM_GENERIC_TIMER_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGenericTimerInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GENERIC_TIMER_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c deleted file mode 100644 index ee82f7a0b4..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c +++ /dev/null @@ -1,903 +0,0 @@ -/** @file - Arm Gic cpu parser. - - Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/arm/cpus.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml - - linux/Documentation/devicetree/bindings/arm/pmu.yaml -**/ - -#include "FdtHwInfoParser.h" -#include "CmObjectDescUtility.h" -#include "Gic/ArmGicCParser.h" -#include "Gic/ArmGicDispatcher.h" - -/** List of "compatible" property values for CPU nodes. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR CpuCompatibleStr[] = { - { "arm,arm-v7" }, - { "arm,arm-v8" }, - { "arm,armv8" }, - { "arm,cortex-a15" }, - { "arm,cortex-a7" }, - { "arm,cortex-a57" } -}; - -/** COMPATIBILITY_INFO structure for CPU nodes. -*/ -STATIC CONST COMPATIBILITY_INFO CpuCompatibleInfo = { - ARRAY_SIZE (CpuCompatibleStr), - CpuCompatibleStr -}; - -/** Pmu compatible strings. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR PmuCompatibleStr[] = { - { "arm,armv8-pmuv3" } -}; - -/** COMPATIBILITY_INFO structure for the PmuCompatibleStr. -*/ -CONST COMPATIBILITY_INFO PmuCompatibleInfo = { - ARRAY_SIZE (PmuCompatibleStr), - PmuCompatibleStr -}; - -/** Parse a "cpu" node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] CpuNode Offset of a cpu node. - @param [in] GicVersion Version of the GIC. - @param [in] AddressCells Number of address cells used for the reg - property. - @param [out] GicCInfo CM_ARM_GICC_INFO structure to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED Unsupported. -**/ -STATIC -EFI_STATUS -EFIAPI -CpuNodeParser ( - IN CONST VOID *Fdt, - IN INT32 CpuNode, - IN UINT32 GicVersion, - IN UINT32 AddressCells, - OUT CM_ARM_GICC_INFO *GicCInfo - ) -{ - CONST UINT8 *Data; - INT32 DataSize; - UINT32 ProcUid; - UINT64 MpIdr; - UINT64 CheckAffMask; - - MpIdr = 0; - CheckAffMask = ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2; - - if (GicCInfo == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Data = fdt_getprop (Fdt, CpuNode, "reg", &DataSize); - if ((Data == NULL) || - ((DataSize != sizeof (UINT32)) && - (DataSize != sizeof (UINT64)))) - { - ASSERT (0); - return EFI_ABORTED; - } - - /* If cpus node's #address-cells property is set to 2 - The first reg cell bits [7:0] must be set to - bits [39:32] of MPIDR_EL1. - The second reg cell bits [23:0] must be set to - bits [23:0] of MPIDR_EL1. - */ - if (AddressCells == 2) { - MpIdr = fdt64_to_cpu (*((UINT64 *)Data)); - CheckAffMask |= ARM_CORE_AFF3; - } else { - MpIdr = fdt32_to_cpu (*((UINT32 *)Data)); - } - - if ((MpIdr & ~CheckAffMask) != 0) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // To fit the Affinity [0-3] a 32bits value, place the Aff3 on bits - // [31:24] instead of their original place ([39:32]). - ProcUid = MpIdr | ((MpIdr & ARM_CORE_AFF3) >> 8); - - /* ACPI 6.3, s5.2.12.14 GIC CPU Interface (GICC) Structure: - GIC 's CPU Interface Number. In GICv1/v2 implementations, - this value matches the bit index of the associated processor - in the GIC distributor's GICD_ITARGETSR register. For - GICv3/4 implementations this field must be provided by the - platform, if compatibility mode is supported. If it is not supported - by the implementation, then this field must be zero. - - Note: We do not support compatibility mode for GicV3 - */ - if (GicVersion == 2) { - GicCInfo->CPUInterfaceNumber = ProcUid; - } else { - GicCInfo->CPUInterfaceNumber = 0; - } - - GicCInfo->AcpiProcessorUid = ProcUid; - GicCInfo->Flags = EFI_ACPI_6_3_GIC_ENABLED; - GicCInfo->MPIDR = MpIdr; - - return EFI_SUCCESS; -} - -/** Parse a "cpus" node and its children "cpu" nodes. - - Create as many CM_ARM_GICC_INFO structures as "cpu" nodes. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] CpusNode Offset of a cpus node. - @param [in] GicVersion Version of the GIC. - @param [out] NewGicCmObjDesc If success, CM_OBJ_DESCRIPTOR containing - all the created CM_ARM_GICC_INFO. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED Unsupported. -**/ -STATIC -EFI_STATUS -EFIAPI -CpusNodeParser ( - IN CONST VOID *Fdt, - IN INT32 CpusNode, - IN UINT32 GicVersion, - OUT CM_OBJ_DESCRIPTOR **NewGicCmObjDesc - ) -{ - EFI_STATUS Status; - INT32 CpuNode; - UINT32 CpuNodeCount; - INT32 AddressCells; - - UINT32 Index; - CM_ARM_GICC_INFO *GicCInfoBuffer; - UINT32 GicCInfoBufferSize; - - if (NewGicCmObjDesc == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - AddressCells = fdt_address_cells (Fdt, CpusNode); - if (AddressCells < 0) { - ASSERT (0); - return EFI_ABORTED; - } - - // Count the number of "cpu" nodes under the "cpus" node. - Status = FdtCountNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNodeCount); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (CpuNodeCount == 0) { - ASSERT (0); - return EFI_NOT_FOUND; - } - - // Allocate memory for CpuNodeCount CM_ARM_GICC_INFO structures. - GicCInfoBufferSize = CpuNodeCount * sizeof (CM_ARM_GICC_INFO); - GicCInfoBuffer = AllocateZeroPool (GicCInfoBufferSize); - if (GicCInfoBuffer == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - - CpuNode = CpusNode; - for (Index = 0; Index < CpuNodeCount; Index++) { - Status = FdtGetNextNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - goto exit_handler; - } - - // Parse the "cpu" node. - if (!FdtNodeIsCompatible (Fdt, CpuNode, &CpuCompatibleInfo)) { - ASSERT (0); - Status = EFI_UNSUPPORTED; - goto exit_handler; - } - - Status = CpuNodeParser ( - Fdt, - CpuNode, - GicVersion, - AddressCells, - &GicCInfoBuffer[Index] - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - } // for - - Status = CreateCmObjDesc ( - CREATE_CM_ARM_OBJECT_ID (EArmObjGicCInfo), - CpuNodeCount, - GicCInfoBuffer, - GicCInfoBufferSize, - NewGicCmObjDesc - ); - ASSERT_EFI_ERROR (Status); - -exit_handler: - FreePool (GicCInfoBuffer); - return Status; -} - -/** Parse a Gic compatible interrupt-controller node, - extracting GicC information generic to Gic v2 and v3. - - This function modifies a CM_OBJ_DESCRIPTOR object. - The following CM_ARM_GICC_INFO fields are patched: - - VGICMaintenanceInterrupt; - - Flags; - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] GicIntcNode Offset of a Gic compatible - interrupt-controller node. - @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicCIntcNodeParser ( - IN CONST VOID *Fdt, - IN INT32 GicIntcNode, - IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc - ) -{ - EFI_STATUS Status; - INT32 IntCells; - CM_ARM_GICC_INFO *GicCInfo; - - CONST UINT8 *Data; - INT32 DataSize; - - if (GicCCmObjDesc == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Get the number of cells used to encode an interrupt. - Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Get the GSIV maintenance interrupt. - // According to the DT bindings, this could be the: - // "Interrupt source of the parent interrupt controller on secondary GICs" - // but it is assumed that only one Gic is available. - Data = fdt_getprop (Fdt, GicIntcNode, "interrupts", &DataSize); - if ((Data != NULL) && (DataSize == (IntCells * sizeof (UINT32)))) { - GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; - GicCInfo->VGICMaintenanceInterrupt = - FdtGetInterruptId ((CONST UINT32 *)Data); - GicCInfo->Flags = DT_IRQ_IS_EDGE_TRIGGERED ( - fdt32_to_cpu (((UINT32 *)Data)[IRQ_FLAGS_OFFSET]) - ) ? - EFI_ACPI_6_3_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS : - 0; - return Status; - } else if (DataSize < 0) { - // This property is optional and was not found. Just return. - return Status; - } - - // The property exists and its size doesn't match for one interrupt. - ASSERT (0); - return EFI_ABORTED; -} - -/** Parse a Gic compatible interrupt-controller node, - extracting GicCv2 information. - - This function modifies a CM_OBJ_DESCRIPTOR object. - The following CM_ARM_GICC_INFO fields are patched: - - PhysicalAddress; - - GICH; - - GICV; - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] Gicv2IntcNode Offset of a Gicv2 compatible - interrupt-controller node. - @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicCv2IntcNodeParser ( - IN CONST VOID *Fdt, - IN INT32 Gicv2IntcNode, - IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc - ) -{ - EFI_STATUS Status; - UINT32 Index; - CM_ARM_GICC_INFO *GicCInfo; - INT32 AddressCells; - INT32 SizeCells; - - CONST UINT8 *GicCValue; - CONST UINT8 *GicVValue; - CONST UINT8 *GicHValue; - - CONST UINT8 *Data; - INT32 DataSize; - UINT32 RegSize; - UINT32 RegCount; - - if (GicCCmObjDesc == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; - GicVValue = NULL; - GicHValue = NULL; - - // Get the #address-cells and #size-cells property values. - Status = FdtGetParentAddressInfo ( - Fdt, - Gicv2IntcNode, - &AddressCells, - &SizeCells - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2) || - (SizeCells < 1) || - (SizeCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - RegSize = (AddressCells + SizeCells) * sizeof (UINT32); - - Data = fdt_getprop (Fdt, Gicv2IntcNode, "reg", &DataSize); - if ((Data == NULL) || - (DataSize < 0) || - ((DataSize % RegSize) != 0)) - { - // If error or wrong size. - ASSERT (0); - return EFI_ABORTED; - } - - RegCount = DataSize/RegSize; - - switch (RegCount) { - case 4: - { - // GicV is at index 3 in the reg property. GicV is optional. - GicVValue = Data + (sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET (3, AddressCells, SizeCells)); - // fall-through. - } - case 3: - { - // GicH is at index 2 in the reg property. GicH is optional. - GicHValue = Data + (sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET (2, AddressCells, SizeCells)); - // fall-through. - } - case 2: - { - // GicC is at index 1 in the reg property. GicC is mandatory. - GicCValue = Data + (sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells)); - break; - } - default: - { - // Not enough or too much information. - ASSERT (0); - return EFI_ABORTED; - } - } - - // Patch the relevant fields of the CM_ARM_GICC_INFO objects. - for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { - if (AddressCells == 2) { - GicCInfo[Index].PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)GicCValue); - GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : - fdt64_to_cpu (*(UINT64 *)GicHValue); - GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : - fdt64_to_cpu (*(UINT64 *)GicVValue); - } else { - GicCInfo[Index].PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)GicCValue); - GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : - fdt32_to_cpu (*(UINT32 *)GicHValue); - GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : - fdt32_to_cpu (*(UINT32 *)GicVValue); - } - } // for - - return EFI_SUCCESS; -} - -/** Parse a Gic compatible interrupt-controller node, - extracting GicCv3 information. - - This function modifies a CM_OBJ_DESCRIPTOR object. - The following CM_ARM_GICC_INFO fields are patched: - - PhysicalAddress; - - GICH; - - GICV; - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] Gicv3IntcNode Offset of a Gicv3 compatible - interrupt-controller node. - @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicCv3IntcNodeParser ( - IN CONST VOID *Fdt, - IN INT32 Gicv3IntcNode, - IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc - ) -{ - EFI_STATUS Status; - UINT32 Index; - CM_ARM_GICC_INFO *GicCInfo; - INT32 AddressCells; - INT32 SizeCells; - UINT32 AdditionalRedistReg; - - CONST UINT8 *GicCValue; - CONST UINT8 *GicVValue; - CONST UINT8 *GicHValue; - - CONST UINT8 *Data; - INT32 DataSize; - UINT32 RegSize; - UINT32 RegCount; - - if (GicCCmObjDesc == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; - GicCValue = NULL; - GicVValue = NULL; - GicHValue = NULL; - - // Get the #address-cells and #size-cells property values. - Status = FdtGetParentAddressInfo ( - Fdt, - Gicv3IntcNode, - &AddressCells, - &SizeCells - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2) || - (SizeCells < 1) || - (SizeCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - // The "#redistributor-regions" property is optional. - Data = fdt_getprop (Fdt, Gicv3IntcNode, "#redistributor-regions", &DataSize); - if ((Data != NULL) && (DataSize == sizeof (UINT32))) { - ASSERT (fdt32_to_cpu (*(UINT32 *)Data) > 1); - AdditionalRedistReg = fdt32_to_cpu (*(UINT32 *)Data) - 1; - } else { - AdditionalRedistReg = 0; - } - - RegSize = (AddressCells + SizeCells) * sizeof (UINT32); - - /* - Ref: linux/blob/master/Documentation/devicetree/bindings/ - interrupt-controller/arm%2Cgic-v3.yaml - - reg: - description: | - Specifies base physical address(s) and size of the GIC - registers, in the following order: - - GIC Distributor interface (GICD) - - GIC Redistributors (GICR), one range per redistributor region - - GIC CPU interface (GICC) - - GIC Hypervisor interface (GICH) - - GIC Virtual CPU interface (GICV) - GICC, GICH and GICV are optional. - minItems: 2 - maxItems: 4096 - */ - Data = fdt_getprop (Fdt, Gicv3IntcNode, "reg", &DataSize); - if ((Data == NULL) || - (DataSize < 0) || - ((DataSize % RegSize) != 0)) - { - // If error or wrong size. - ASSERT (0); - return EFI_ABORTED; - } - - RegCount = (DataSize / RegSize) - AdditionalRedistReg; - - // The GicD and GicR info is mandatory. - switch (RegCount) { - case 5: - { - // GicV is at index 4 in the reg property. GicV is optional. - GicVValue = Data + (sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET ( - 4 + AdditionalRedistReg, - AddressCells, - SizeCells - )); - // fall-through. - } - case 4: - { - // GicH is at index 3 in the reg property. GicH is optional. - GicHValue = Data + (sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET ( - 3 + AdditionalRedistReg, - AddressCells, - SizeCells - )); - // fall-through. - } - case 3: - { - // GicC is at index 2 in the reg property. GicC is optional. - // Even though GicC is optional, it is made mandatory in this parser. - GicCValue = Data + (sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET ( - 2 + AdditionalRedistReg, - AddressCells, - SizeCells - )); - // fall-through - } - case 2: - { - // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object. - // GicD is described by the CM_ARM_GICD_INFO object. - break; - } - default: - { - // Not enough or too much information. - ASSERT (0); - return EFI_ABORTED; - } - } - - // Patch the relevant fields of the CM_ARM_GICC_INFO objects. - if (AddressCells == 2) { - for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { - // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object. - GicCInfo[Index].GICRBaseAddress = 0; - GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 : - fdt64_to_cpu (*(UINT64 *)GicCValue); - GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : - fdt64_to_cpu (*(UINT64 *)GicHValue); - GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : - fdt64_to_cpu (*(UINT64 *)GicVValue); - } - } else { - for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { - // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object. - GicCInfo[Index].GICRBaseAddress = 0; - GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 : - fdt32_to_cpu (*(UINT32 *)GicCValue); - GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 : - fdt32_to_cpu (*(UINT32 *)GicHValue); - GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 : - fdt32_to_cpu (*(UINT32 *)GicVValue); - } - } - - return EFI_SUCCESS; -} - -/** Parse a Pmu compatible node, extracting Pmu information. - - This function modifies a CM_OBJ_DESCRIPTOR object. - The following CM_ARM_GICC_INFO fields are patched: - - PerformanceInterruptGsiv; - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] GicIntcNode Offset of a Gic compatible - interrupt-controller node. - @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicCPmuNodeParser ( - IN CONST VOID *Fdt, - IN INT32 GicIntcNode, - IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc - ) -{ - EFI_STATUS Status; - INT32 IntCells; - INT32 PmuNode; - UINT32 PmuNodeCount; - UINT32 PmuIrq; - UINT32 Index; - CM_ARM_GICC_INFO *GicCInfo; - CONST UINT8 *Data; - INT32 DataSize; - - if (GicCCmObjDesc == NULL) { - ASSERT (GicCCmObjDesc != NULL); - return EFI_INVALID_PARAMETER; - } - - GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data; - PmuNode = 0; - - // Count the number of pmu nodes. - Status = FdtCountCompatNodeInBranch ( - Fdt, - 0, - &PmuCompatibleInfo, - &PmuNodeCount - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - if (PmuNodeCount == 0) { - return EFI_NOT_FOUND; - } - - Status = FdtGetNextCompatNodeInBranch ( - Fdt, - 0, - &PmuCompatibleInfo, - &PmuNode - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - } - - // Get the number of cells used to encode an interrupt. - Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - Data = fdt_getprop (Fdt, PmuNode, "interrupts", &DataSize); - if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) { - // If error or not 1 interrupt. - ASSERT (Data != NULL); - ASSERT (DataSize == (IntCells * sizeof (UINT32))); - return EFI_ABORTED; - } - - PmuIrq = FdtGetInterruptId ((CONST UINT32 *)Data); - - // Only supports PPI 23 for now. - // According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23. A non BSA - // compliant system may assign a different IRQ for the PMU, however this - // is not implemented for now. - if (PmuIrq != BSA_PMU_IRQ) { - ASSERT (PmuIrq == BSA_PMU_IRQ); - return EFI_ABORTED; - } - - for (Index = 0; Index < GicCCmObjDesc->Count; Index++) { - GicCInfo[Index].PerformanceInterruptGsiv = PmuIrq; - } - - return EFI_SUCCESS; -} - -/** CM_ARM_GICC_INFO parser function. - - This parser expects FdtBranch to be the "\cpus" node node. - At most one CmObj is created. - The following structure is populated: - typedef struct CmArmGicCInfo { - UINT32 CPUInterfaceNumber; // {Populated} - UINT32 AcpiProcessorUid; // {Populated} - UINT32 Flags; // {Populated} - UINT32 ParkingProtocolVersion; // {default = 0} - UINT32 PerformanceInterruptGsiv; // {Populated} - UINT64 ParkedAddress; // {default = 0} - UINT64 PhysicalBaseAddress; // {Populated} - UINT64 GICV; // {Populated} - UINT64 GICH; // {Populated} - UINT32 VGICMaintenanceInterrupt; // {Populated} - UINT64 GICRBaseAddress; // {default = 0} - UINT64 MPIDR; // {Populated} - UINT8 ProcessorPowerEfficiencyClass; // {default = 0} - UINT16 SpeOverflowInterrupt; // {default = 0} - UINT32 ProximityDomain; // {default = 0} - UINT32 ClockDomain; // {default = 0} - UINT32 AffinityFlags; // {default = 0} - } CM_ARM_GICC_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicCInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - INT32 IntcNode; - UINT32 GicVersion; - CM_OBJ_DESCRIPTOR *NewCmObjDesc; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - NewCmObjDesc = NULL; - - // The FdtBranch points to the Cpus Node. - // Get the interrupt-controller node associated to the "cpus" node. - Status = FdtGetIntcParentNode (Fdt, FdtBranch, &IntcNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - Status = GetGicVersion (Fdt, IntcNode, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Parse the "cpus" nodes and its children "cpu" nodes, - // and create a CM_OBJ_DESCRIPTOR. - Status = CpusNodeParser (Fdt, FdtBranch, GicVersion, &NewCmObjDesc); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Parse the interrupt-controller node according to the Gic version. - switch (GicVersion) { - case 2: - { - Status = GicCv2IntcNodeParser (Fdt, IntcNode, NewCmObjDesc); - break; - } - case 3: - { - Status = GicCv3IntcNodeParser (Fdt, IntcNode, NewCmObjDesc); - break; - } - default: - { - // Unsupported Gic version. - ASSERT (0); - Status = EFI_UNSUPPORTED; - } - } - - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - - // Parse the Gic information common to Gic v2 and v3. - Status = GicCIntcNodeParser (Fdt, IntcNode, NewCmObjDesc); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - - // Parse the Pmu Interrupt. - Status = GicCPmuNodeParser (Fdt, IntcNode, NewCmObjDesc); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT_EFI_ERROR (Status); - goto exit_handler; - } - - // Add all the CmObjs to the Configuration Manager. - Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - -exit_handler: - FreeCmObjDesc (NewCmObjDesc); - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h deleted file mode 100644 index 539f39cecb..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h +++ /dev/null @@ -1,68 +0,0 @@ -/** @file - Arm Gic cpu parser. - - Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#ifndef ARM_GICC_PARSER_H_ -#define ARM_GICC_PARSER_H_ - -/* According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23. -*/ -#define BSA_PMU_IRQ 23 - -/** CM_ARM_GICC_INFO parser function. - - This parser expects FdtBranch to be the "\cpus" node node. - At most one CmObj is created. - The following structure is populated: - typedef struct CmArmGicCInfo { - UINT32 CPUInterfaceNumber; // {Populated} - UINT32 AcpiProcessorUid; // {Populated} - UINT32 Flags; // {Populated} - UINT32 ParkingProtocolVersion; // {default = 0} - UINT32 PerformanceInterruptGsiv; // {Populated} - UINT64 ParkedAddress; // {default = 0} - UINT64 PhysicalBaseAddress; // {Populated} - UINT64 GICV; // {Populated} - UINT64 GICH; // {Populated} - UINT32 VGICMaintenanceInterrupt; // {Populated} - UINT64 GICRBaseAddress; // {default = 0} - UINT64 MPIDR; // {Populated} - UINT8 ProcessorPowerEfficiencyClass; // {default = 0} - UINT16 SpeOverflowInterrupt; // {default = 0} - UINT32 ProximityDomain; // {default = 0} - UINT32 ClockDomain; // {default = 0} - UINT32 AffinityFlags; // {default = 0} - } CM_ARM_GICC_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicCInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GICC_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c deleted file mode 100644 index b7f5696729..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c +++ /dev/null @@ -1,171 +0,0 @@ -/** @file - Arm Gic Distributor Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#include "CmObjectDescUtility.h" -#include "FdtHwInfoParser.h" -#include "Gic/ArmGicDispatcher.h" -#include "Gic/ArmGicDParser.h" - -/** Parse a Gic compatible interrupt-controller node, - extracting GicD information. - - This parser is valid for Gic v2 and v3. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] GicIntcNode Offset of a Gic compatible - interrupt-controller node. - @param [in] GicDInfo The CM_ARM_GICD_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicDIntcNodeParser ( - IN CONST VOID *Fdt, - IN INT32 GicIntcNode, - IN CM_ARM_GICD_INFO *GicDInfo - ) -{ - EFI_STATUS Status; - INT32 AddressCells; - CONST UINT8 *Data; - INT32 DataSize; - - if ((Fdt == NULL) || - (GicDInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Status = FdtGetParentAddressInfo (Fdt, GicIntcNode, &AddressCells, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - Data = fdt_getprop (Fdt, GicIntcNode, "reg", &DataSize); - if ((Data == NULL) || (DataSize < (INT32)(AddressCells * sizeof (UINT32)))) { - // If error or not enough space. - ASSERT (0); - return EFI_ABORTED; - } - - if (AddressCells == 2) { - GicDInfo->PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); - } else { - GicDInfo->PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); - } - - return Status; -} - -/** CM_ARM_GICD_INFO parser function. - - This parser expects FdtBranch to be a Gic interrupt-controller node. - At most one CmObj is created. - The following structure is populated: - typedef struct CmArmGicDInfo { - UINT64 PhysicalBaseAddress; // {Populated} - UINT32 SystemVectorBase; - UINT8 GicVersion; // {Populated} - } CM_ARM_GICD_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicDInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - UINT32 GicVersion; - CM_ARM_GICD_INFO GicDInfo; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - if (!FdtNodeHasProperty (Fdt, FdtBranch, "interrupt-controller")) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Get the Gic version of the interrupt-controller. - Status = GetGicVersion (Fdt, FdtBranch, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - ZeroMem (&GicDInfo, sizeof (GicDInfo)); - GicDInfo.GicVersion = GicVersion; - - // Parse the interrupt-controller depending on its Gic version. - switch (GicVersion) { - case 2: - case 3: - { - // Set the Gic version, then parse the GicD information. - Status = GicDIntcNodeParser (Fdt, FdtBranch, &GicDInfo); - break; - } - default: - { - // Unsupported Gic version. - ASSERT (0); - return EFI_UNSUPPORTED; - } - } - - // Add the CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjGicDInfo), - &GicDInfo, - sizeof (CM_ARM_GICD_INFO), - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h deleted file mode 100644 index b9581f0eb9..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h +++ /dev/null @@ -1,50 +0,0 @@ -/** @file - Arm Gic Distributor Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#ifndef ARM_GICD_PARSER_H_ -#define ARM_GICD_PARSER_H_ - -/** CM_ARM_GICD_INFO parser function. - - This parser expects FdtBranch to be a Gic interrupt-controller node. - At most one CmObj is created. - The following structure is populated: - typedef struct CmArmGicDInfo { - UINT64 PhysicalBaseAddress; // {Populated} - UINT32 SystemVectorBase; - UINT8 GicVersion; // {Populated} - } CM_ARM_GICD_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicDInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GICD_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c deleted file mode 100644 index 1f3af1f968..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c +++ /dev/null @@ -1,218 +0,0 @@ -/** @file - Arm Gic dispatcher. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#include "FdtHwInfoParser.h" -#include "Gic/ArmGicCParser.h" -#include "Gic/ArmGicDispatcher.h" -#include "Gic/ArmGicDParser.h" -#include "Gic/ArmGicItsParser.h" -#include "Gic/ArmGicMsiFrameParser.h" -#include "Gic/ArmGicRParser.h" - -/** List of "compatible" property values for GicV2 interrupt nodes. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR GicV2CompatibleStr[] = { - { "arm,cortex-a15-gic" } -}; - -/** COMPATIBILITY_INFO structure for the GICv2. -*/ -CONST COMPATIBILITY_INFO GicV2CompatibleInfo = { - ARRAY_SIZE (GicV2CompatibleStr), - GicV2CompatibleStr -}; - -/** List of "compatible" property values for GicV3 interrupt nodes. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR GicV3CompatibleStr[] = { - { "arm,gic-v3" } -}; - -/** COMPATIBILITY_INFO structure for the GICv3. -*/ -CONST COMPATIBILITY_INFO GicV3CompatibleInfo = { - ARRAY_SIZE (GicV3CompatibleStr), - GicV3CompatibleStr -}; - -/** Get the Gic version of am interrupt-controller node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] IntcNode Interrupt-controller node. - @param [out] GicVersion If success, contains the Gic version of the - interrupt-controller node. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -GetGicVersion ( - IN CONST VOID *Fdt, - IN INT32 IntcNode, - OUT UINT32 *GicVersion - ) -{ - if ((Fdt == NULL) || - (GicVersion == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - if (FdtNodeIsCompatible (Fdt, IntcNode, &GicV2CompatibleInfo)) { - *GicVersion = 2; - } else if (FdtNodeIsCompatible (Fdt, IntcNode, &GicV3CompatibleInfo)) { - *GicVersion = 3; - } else { - // Unsupported Gic version. - ASSERT (0); - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -/** Gic dispatcher. - - This disptacher populates the following structures: - - CM_ARM_GICC_INFO - - CM_ARM_GICD_INFO - - CM_ARM_GIC_MSI_FRAME_INFO - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicDispatcher ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - INT32 CpusNode; - INT32 IntcNode; - UINT32 GicVersion; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - // The "cpus" node resides at the root of the DT. Fetch it. - CpusNode = fdt_path_offset (Fdt, "/cpus"); - if (CpusNode < 0) { - return EFI_NOT_FOUND; - } - - // Get the interrupt-controller node associated to the "cpus" node. - Status = FdtGetIntcParentNode (Fdt, CpusNode, &IntcNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - Status = GetGicVersion (Fdt, IntcNode, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Parse the GicC information. - Status = ArmGicCInfoParser (FdtParserHandle, CpusNode); - if (EFI_ERROR (Status)) { - // Don't try to parse GicD and GicMsiFrame information - // if no GicC information is found. Return. - ASSERT (Status == EFI_NOT_FOUND); - return Status; - } - - // Parse the GicD information of the "cpus" interrupt-controller node. - Status = ArmGicDInfoParser (FdtParserHandle, IntcNode); - if (EFI_ERROR (Status)) { - // EFI_NOT_FOUND is not tolerated at this point. - ASSERT (0); - return Status; - } - - switch (GicVersion) { - case 4: - case 3: - { - // Parse the GicR information of the interrupt-controller node. - Status = ArmGicRInfoParser (FdtParserHandle, IntcNode); - if (EFI_ERROR (Status)) { - // EFI_NOT_FOUND is not tolerated at this point. - ASSERT (0); - return Status; - } - - // Parse the GicIts information of the interrupt-controller node. - Status = ArmGicItsInfoParser (FdtParserHandle, IntcNode); - if (EFI_ERROR (Status) && - (Status != EFI_NOT_FOUND)) - { - ASSERT (0); - return Status; - } - - break; - } - case 2: - { - // Parse the GicMsiFrame information. - Status = ArmGicMsiFrameInfoParser (FdtParserHandle, IntcNode); - if (EFI_ERROR (Status) && - (Status != EFI_NOT_FOUND)) - { - ASSERT (0); - return Status; - } - - break; - } - default: - { - ASSERT (0); - return EFI_UNSUPPORTED; - } - } - - return EFI_SUCCESS; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h deleted file mode 100644 index aa942f7d1f..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h +++ /dev/null @@ -1,72 +0,0 @@ -/** @file - Arm Gic dispatcher. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#ifndef ARM_GIC_DISPATCHER_H_ -#define ARM_GIC_DISPATCHER_H_ - -#include -#include "FdtUtility.h" - -/** COMPATIBILITY_INFO structure for the GICv2. -*/ -extern CONST COMPATIBILITY_INFO GicV2CompatibleInfo; - -/** Get the Gic version of the interrupt-controller node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] IntcNode Interrupt-controller node. - @param [out] GicVersion If success, contains the Gic version of the - interrupt-controller node. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -GetGicVersion ( - IN CONST VOID *Fdt, - IN INT32 IntcNode, - OUT UINT32 *GicVersion - ); - -/** Gic dispatcher. - - This disptacher populates the following structures: - - CM_ARM_GICC_INFO - - CM_ARM_GICD_INFO - - CM_ARM_GIC_MSI_FRAME_INFO - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicDispatcher ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GIC_DISPATCHER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c deleted file mode 100644 index f23818fbd0..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c +++ /dev/null @@ -1,218 +0,0 @@ -/** @file - Arm Gic Interrupt Translation Service Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#include "CmObjectDescUtility.h" -#include "FdtHwInfoParser.h" -#include "Gic/ArmGicDispatcher.h" -#include "Gic/ArmGicItsParser.h" - -/** Parse a Gic compatible interrupt-controller node, - extracting GicIts information. - - This parser is valid for Gic v3 and higher. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] GicIntcNode Offset of a Gic compatible - interrupt-controller node. - @param [in] GicItsId Id for the Gic ITS node. - @param [in] GicItsInfo The CM_ARM_GIC_ITS_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicItsIntcNodeParser ( - IN CONST VOID *Fdt, - IN INT32 GicIntcNode, - IN UINT32 GicItsId, - IN CM_ARM_GIC_ITS_INFO *GicItsInfo - ) -{ - EFI_STATUS Status; - INT32 AddressCells; - CONST UINT8 *Data; - INT32 DataSize; - - if ((Fdt == NULL) || - (GicItsInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Status = FdtGetParentAddressInfo (Fdt, GicIntcNode, &AddressCells, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - Data = fdt_getprop (Fdt, GicIntcNode, "reg", &DataSize); - if ((Data == NULL) || (DataSize < (INT32)(AddressCells * sizeof (UINT32)))) { - // If error or not enough space. - ASSERT (0); - return EFI_ABORTED; - } - - if (AddressCells == 2) { - GicItsInfo->PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); - } else { - GicItsInfo->PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); - } - - // Gic Its Id - GicItsInfo->GicItsId = GicItsId; - - // {default = 0} - GicItsInfo->ProximityDomain = 0; - return Status; -} - -/** CM_ARM_GIC_ITS_INFO parser function. - - This parser expects FdtBranch to be a Gic interrupt-controller node. - Gic version must be v3 or higher. - typedef struct CmArmGicItsInfo { - UINT32 GicItsId; // {Populated} - UINT64 PhysicalBaseAddress; // {Populated} - UINT32 ProximityDomain; // {default = 0} - } CM_ARM_GIC_ITS_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicItsInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - UINT32 GicVersion; - CM_ARM_GIC_ITS_INFO GicItsInfo; - UINT32 Index; - INT32 GicItsNode; - UINT32 GicItsNodeCount; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - if (!FdtNodeHasProperty (Fdt, FdtBranch, "interrupt-controller")) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Get the Gic version of the interrupt-controller. - Status = GetGicVersion (Fdt, FdtBranch, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (GicVersion < 3) { - ASSERT (0); - return EFI_UNSUPPORTED; - } - - // Count the nodes with the "msi-controller" property. - // The interrupt-controller itself can have this property, - // but the first node is skipped in the search. - Status = FdtCountPropNodeInBranch ( - Fdt, - FdtBranch, - "msi-controller", - &GicItsNodeCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (GicItsNodeCount == 0) { - return EFI_NOT_FOUND; - } - - GicItsNode = FdtBranch; - for (Index = 0; Index < GicItsNodeCount; Index++) { - ZeroMem (&GicItsInfo, sizeof (CM_ARM_GIC_ITS_INFO)); - - Status = FdtGetNextPropNodeInBranch ( - Fdt, - FdtBranch, - "msi-controller", - &GicItsNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - Status = GicItsIntcNodeParser ( - Fdt, - GicItsNode, - Index, - &GicItsInfo - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjGicItsInfo), - &GicItsInfo, - sizeof (CM_ARM_GIC_ITS_INFO), - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } // for - - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h deleted file mode 100644 index be944493e4..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - Arm Gic Interrupt Translation Service Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#ifndef ARM_GIC_ITS_PARSER_H_ -#define ARM_GIC_ITS_PARSER_H_ - -/** CM_ARM_GIC_ITS_INFO parser function. - - This parser expects FdtBranch to be a Gic interrupt-controller node. - Gic version must be v3 or higher. - typedef struct CmArmGicItsInfo { - UINT32 GicItsId; // {Populated} - UINT64 PhysicalBaseAddress; // {Populated} - UINT32 ProximityDomain; // {default = 0} - } CM_ARM_GIC_ITS_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicItsInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GIC_ITS_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c deleted file mode 100644 index c474cb25fe..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c +++ /dev/null @@ -1,217 +0,0 @@ -/** @file - Arm Gic Msi frame Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#include "CmObjectDescUtility.h" -#include "FdtHwInfoParser.h" -#include "Gic/ArmGicDispatcher.h" -#include "Gic/ArmGicMsiFrameParser.h" - -/** List of "compatible" property values for Msi-frame nodes. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR MsiFrameCompatibleStr[] = { - { "arm,gic-v2m-frame" } -}; - -/** COMPATIBILITY_INFO structure for the MSI frame. -*/ -STATIC CONST COMPATIBILITY_INFO MsiFrameCompatibleInfo = { - ARRAY_SIZE (MsiFrameCompatibleStr), - MsiFrameCompatibleStr -}; - -/** Parse a Msi frame node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] MsiFrameNode Offset of a Msi frame node. - @param [in] MsiFrameId Frame ID. - @param [out] MsiFrameInfo The CM_ARM_GIC_MSI_FRAME_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -MsiFrameNodeParser ( - IN CONST VOID *Fdt, - IN INT32 MsiFrameNode, - IN UINT32 MsiFrameId, - OUT CM_ARM_GIC_MSI_FRAME_INFO *MsiFrameInfo - ) -{ - EFI_STATUS Status; - INT32 AddressCells; - CONST UINT8 *Data; - INT32 DataSize; - - if ((Fdt == NULL) || - (MsiFrameInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Status = FdtGetParentAddressInfo (Fdt, MsiFrameNode, &AddressCells, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - Data = fdt_getprop (Fdt, MsiFrameNode, "reg", &DataSize); - if ((Data == NULL) || (DataSize < (INT32)(AddressCells * sizeof (UINT32)))) { - // If error or not enough space. - ASSERT (0); - return EFI_ABORTED; - } - - if (AddressCells == 2) { - MsiFrameInfo->PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); - } else { - MsiFrameInfo->PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); - } - - MsiFrameInfo->GicMsiFrameId = MsiFrameId; - - return EFI_SUCCESS; -} - -/** CM_ARM_GIC_MSI_FRAME_INFO parser function. - - The following structure is populated: - typedef struct CmArmGicMsiFrameInfo { - UINT32 GicMsiFrameId; // {Populated} - UINT64 PhysicalBaseAddress; // {Populated} - UINT32 Flags; // {default = 0} - UINT16 SPICount; - UINT16 SPIBase; - } CM_ARM_GIC_MSI_FRAME_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicMsiFrameInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - INT32 MsiFrameNode; - UINT32 MsiFrameNodeCount; - - UINT32 Index; - CM_ARM_GIC_MSI_FRAME_INFO MsiFrameInfo; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - // Count the number of nodes having the "interrupt-controller" property. - Status = FdtCountPropNodeInBranch ( - Fdt, - FdtBranch, - "msi-controller", - &MsiFrameNodeCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (MsiFrameNodeCount == 0) { - return EFI_NOT_FOUND; - } - - // Parse each node having the "msi-controller" property. - MsiFrameNode = FdtBranch; - for (Index = 0; Index < MsiFrameNodeCount; Index++) { - ZeroMem (&MsiFrameInfo, sizeof (CM_ARM_GIC_MSI_FRAME_INFO)); - - Status = FdtGetNextPropNodeInBranch ( - Fdt, - FdtBranch, - "msi-controller", - &MsiFrameNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - if (!FdtNodeIsCompatible (Fdt, MsiFrameNode, &MsiFrameCompatibleInfo)) { - ASSERT (0); - Status = EFI_UNSUPPORTED; - return Status; - } - - // Parse the Msi information. - Status = MsiFrameNodeParser ( - Fdt, - MsiFrameNode, - Index, - &MsiFrameInfo - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjGicMsiFrameInfo), - &MsiFrameInfo, - sizeof (CM_ARM_GIC_MSI_FRAME_INFO), - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } // for - - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h deleted file mode 100644 index 2821a784f7..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h +++ /dev/null @@ -1,50 +0,0 @@ -/** @file - Arm Gic Msi frame Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#ifndef ARM_GIC_MSI_FRAME_PARSER_H_ -#define ARM_GIC_MSI_FRAME_PARSER_H_ - -/** CM_ARM_GIC_MSI_FRAME_INFO parser function. - - The following structure is populated: - typedef struct CmArmGicMsiFrameInfo { - UINT32 GicMsiFrameId; // {Populated} - UINT64 PhysicalBaseAddress; // {Populated} - UINT32 Flags; // {default = 0} - UINT16 SPICount; - UINT16 SPIBase; - } CM_ARM_GIC_MSI_FRAME_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicMsiFrameInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GIC_MSI_FRAME_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c deleted file mode 100644 index 0f9c7bb3fe..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c +++ /dev/null @@ -1,238 +0,0 @@ -/** @file - Arm Gic Redistributor Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#include "CmObjectDescUtility.h" -#include "FdtHwInfoParser.h" -#include "Gic/ArmGicDispatcher.h" -#include "Gic/ArmGicRParser.h" - -/** Parse a Gic compatible interrupt-controller node, - extracting GicR information. - - This parser is valid for Gic v3 and higher. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] GicIntcNode Offset of a Gic compatible - interrupt-controller node. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GicRIntcNodeParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 GicIntcNode - ) -{ - EFI_STATUS Status; - UINT32 Index; - UINT32 RedistReg; - UINT32 RegSize; - INT32 AddressCells; - INT32 SizeCells; - CONST UINT8 *Data; - INT32 DataSize; - CM_ARM_GIC_REDIST_INFO GicRInfo; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - Status = FdtGetParentAddressInfo ( - Fdt, - GicIntcNode, - &AddressCells, - &SizeCells - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2) || - (SizeCells < 1) || - (SizeCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - // The "#redistributor-regions" property is optional. - // It indicates the number of GicR. - Data = fdt_getprop (Fdt, GicIntcNode, "#redistributor-regions", &DataSize); - if ((Data != NULL) && (DataSize == sizeof (UINT32))) { - // If available, must be on one cell. - RedistReg = fdt32_to_cpu (*(UINT32 *)Data); - } else { - // The DT Spec says GicR is mandatory so we will - // always have one. - RedistReg = 1; - } - - /* - Ref: linux/blob/master/Documentation/devicetree/bindings/ - interrupt-controller/arm%2Cgic-v3.yaml - - reg: - description: | - Specifies base physical address(s) and size of the GIC - registers, in the following order: - - GIC Distributor interface (GICD) - - GIC Redistributors (GICR), one range per redistributor region - - GIC CPU interface (GICC) - - GIC Hypervisor interface (GICH) - - GIC Virtual CPU interface (GICV) - GICC, GICH and GICV are optional. - minItems: 2 - maxItems: 4096 - - Example: - interrupt-controller@2c010000 { - compatible = "arm,gic-v3"; - #interrupt-cells = <4>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - interrupt-controller; - redistributor-stride = <0x0 0x40000>; // 256kB stride - #redistributor-regions = <2>; - reg = <0x2c010000 0x10000>, // GICD - <0x2d000000 0x800000>, // GICR 1: CPUs 0-31 - <0x2e000000 0x800000>, // GICR 2: CPUs 32-63 - <0x2c040000 0x2000>, // GICC - <0x2c060000 0x2000>, // GICH - <0x2c080000 0x2000>; // GICV - interrupts = <1 9 4>; - ... - } - */ - RegSize = (AddressCells + SizeCells) * sizeof (UINT32); - Data = fdt_getprop (Fdt, GicIntcNode, "reg", &DataSize); - if ((Data == NULL) || - (DataSize < 0) || - ((DataSize % RegSize) != 0)) - { - // If error or wrong size. - ASSERT (0); - return EFI_ABORTED; - } - - Data += GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells) - * sizeof (UINT32); - for (Index = 0; Index < RedistReg; Index++) { - ZeroMem (&GicRInfo, sizeof (CM_ARM_GIC_REDIST_INFO)); - - if (AddressCells == 2) { - GicRInfo.DiscoveryRangeBaseAddress = fdt64_to_cpu (*(UINT64 *)Data); - } else { - GicRInfo.DiscoveryRangeBaseAddress = fdt32_to_cpu (*(UINT32 *)Data); - } - - Data += sizeof (UINT32) * AddressCells; - - if (SizeCells == 2) { - GicRInfo.DiscoveryRangeLength = (UINT32)fdt64_to_cpu (*(UINT64 *)Data); - } else { - GicRInfo.DiscoveryRangeLength = fdt32_to_cpu (*(UINT32 *)Data); - } - - // Add the CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARM_OBJECT_ID (EArmObjGicRedistributorInfo), - &GicRInfo, - sizeof (CM_ARM_GIC_REDIST_INFO), - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Data += sizeof (UINT32) * SizeCells; - } // for - - return Status; -} - -/** CM_ARM_GIC_REDIST_INFO parser function. - - This parser expects FdtBranch to be a Gic interrupt-controller node. - Gic version must be v3 or higher. - typedef struct CmArmGicRedistInfo { - UINT64 DiscoveryRangeBaseAddress; // {Populated} - UINT32 DiscoveryRangeLength; // {Populated} - } CM_ARM_GIC_REDIST_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicRInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - UINT32 GicVersion; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - if (!FdtNodeHasProperty (Fdt, FdtBranch, "interrupt-controller")) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Get the Gic version of the interrupt-controller. - Status = GetGicVersion (Fdt, FdtBranch, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (GicVersion < 3) { - ASSERT (0); - return EFI_UNSUPPORTED; - } - - Status = GicRIntcNodeParser (FdtParserHandle, FdtBranch); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h deleted file mode 100644 index c2b7eabfed..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h +++ /dev/null @@ -1,47 +0,0 @@ -/** @file - Arm Gic Redistributor Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml -**/ - -#ifndef ARM_GICR_PARSER_H_ -#define ARM_GICR_PARSER_H_ - -/** CM_ARM_GIC_REDIST_INFO parser function. - - This parser expects FdtBranch to be a Gic interrupt-controller node. - Gic version must be v3 or higher. - typedef struct CmArmGicRedistInfo { - UINT64 DiscoveryRangeBaseAddress; // {Populated} - UINT32 DiscoveryRangeLength; // {Populated} - } CM_ARM_GIC_REDIST_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmGicRInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_GICR_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c index b064e62c17..5d11863dfe 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c @@ -17,7 +17,7 @@ #include "FdtHwInfoParser.h" #include "Pci/ArmPciConfigSpaceParser.h" -#include "Gic/ArmGicDispatcher.h" +#include "Arm/Gic/ArmGicDispatcher.h" /** List of "compatible" property values for host PCIe bridges nodes. -- cgit From 4bb08e8863894a1dbdbe10f278c2057d02a60db7 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Refactor to prepare for other archs To allow other architectures to potentially re-use the serial port parser and make the code arch neutral, make the MainDispatcher() function arch specific. Other architectures can choose which parse/dispatcher are desired to be called through the configuration of the HwInfoParserTable. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c | 83 ++++++++++++++++++++++ .../Library/FdtHwInfoParserLib/FdtHwInfoParser.c | 78 +------------------- .../Library/FdtHwInfoParserLib/FdtHwInfoParser.h | 27 +++++++ .../FdtHwInfoParserLib/FdtHwInfoParserLib.inf | 15 ++-- 4 files changed, 121 insertions(+), 82 deletions(-) create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c new file mode 100644 index 0000000000..403402731a --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c @@ -0,0 +1,83 @@ +/** @file + Arm Flattened Device Tree parser library for KvmTool. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "FdtHwInfoParser.h" +#include "Arm/BootArch/ArmBootArchParser.h" +#include "Arm/GenericTimer/ArmGenericTimerParser.h" +#include "Arm/Gic/ArmGicDispatcher.h" +#include "Pci/ArmPciConfigSpaceParser.h" +#include "Serial/ArmSerialPortParser.h" + +/** Ordered table of parsers/dispatchers. + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. +*/ +STATIC CONST FDT_HW_INFO_PARSER_FUNC HwInfoParserTable[] = { + ArmBootArchInfoParser, + ArmGenericTimerInfoParser, + ArmGicDispatcher, + ArmPciConfigInfoParser, + SerialPortDispatcher +}; + +/** Main dispatcher: sequentially call the parsers/dispatchers + of the HwInfoParserTable. + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArchFdtHwInfoMainDispatcher ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + UINT32 Index; + + if (fdt_check_header (FdtParserHandle->Fdt) < 0) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + for (Index = 0; Index < ARRAY_SIZE (HwInfoParserTable); Index++) { + Status = HwInfoParserTable[Index]( + FdtParserHandle, + FdtBranch + ); + if (EFI_ERROR (Status) && + (Status != EFI_NOT_FOUND)) + { + // If EFI_NOT_FOUND, the parser didn't find information in the DT. + // Don't trigger an error. + ASSERT (0); + return Status; + } + } // for + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c index 78bf9c9efa..8e980dabe3 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c @@ -6,82 +6,6 @@ **/ #include "FdtHwInfoParser.h" -#include "Arm/BootArch/ArmBootArchParser.h" -#include "Arm/GenericTimer/ArmGenericTimerParser.h" -#include "Arm/Gic/ArmGicDispatcher.h" -#include "Pci/ArmPciConfigSpaceParser.h" -#include "Serial/ArmSerialPortParser.h" - -/** Ordered table of parsers/dispatchers. - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. -*/ -STATIC CONST FDT_HW_INFO_PARSER_FUNC HwInfoParserTable[] = { - ArmBootArchInfoParser, - ArmGenericTimerInfoParser, - ArmGicDispatcher, - ArmPciConfigInfoParser, - SerialPortDispatcher -}; - -/** Main dispatcher: sequentially call the parsers/dispatchers - of the HwInfoParserTable. - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -STATIC -EFI_STATUS -EFIAPI -MainDispatcher ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - UINT32 Index; - - if (fdt_check_header (FdtParserHandle->Fdt) < 0) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - for (Index = 0; Index < ARRAY_SIZE (HwInfoParserTable); Index++) { - Status = HwInfoParserTable[Index]( - FdtParserHandle, - FdtBranch - ); - if (EFI_ERROR (Status) && - (Status != EFI_NOT_FOUND)) - { - // If EFI_NOT_FOUND, the parser didn't find information in the DT. - // Don't trigger an error. - ASSERT (0); - return Status; - } - } // for - - return EFI_SUCCESS; -} /** Initialise the HwInfoParser. @@ -159,7 +83,7 @@ HwInfoParse ( } // Call all the parsers from the root node (-1). - Status = MainDispatcher ( + Status = ArchFdtHwInfoMainDispatcher ( (FDT_HW_INFO_PARSER_HANDLE)ParserHandle, -1 ); diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h index 8a8cf38581..90850b356a 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h @@ -60,4 +60,31 @@ EFI_STATUS IN INT32 FdtBranch ); +/** Main dispatcher: sequentially call the parsers/dispatchers + of the HwInfoParserTable. + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +ArchFdtHwInfoMainDispatcher ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + #endif // FDT_HW_INFO_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf index fa768cf664..3abc6a0fd2 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf @@ -22,6 +22,13 @@ FdtHwInfoParser.h FdtUtility.c FdtUtility.h + Pci/ArmPciConfigSpaceParser.c + Pci/ArmPciConfigSpaceParser.h + Serial/ArmSerialPortParser.c + Serial/ArmSerialPortParser.h + +[Sources.ARM, Sources.AARCH64] + Arm/ArmFdtHwInfoParser.c Arm/BootArch/ArmBootArchParser.c Arm/BootArch/ArmBootArchParser.h Arm/GenericTimer/ArmGenericTimerParser.c @@ -38,13 +45,11 @@ Arm/Gic/ArmGicMsiFrameParser.h Arm/Gic/ArmGicRParser.c Arm/Gic/ArmGicRParser.h - Pci/ArmPciConfigSpaceParser.c - Pci/ArmPciConfigSpaceParser.h - Serial/ArmSerialPortParser.c - Serial/ArmSerialPortParser.h -[Packages] +[Packages.ARM, Packages.AARCH64] ArmPkg/ArmPkg.dec + +[Packages] DynamicTablesPkg/DynamicTablesPkg.dec EmbeddedPkg/EmbeddedPkg.dec MdeModulePkg/MdeModulePkg.dec -- cgit From f16817ec8491847c8544a9ef44b1777c9daf4ccc Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Make Pci parser arch neutral To allow other architectures to potentially re-use the serial port parser and make the code arch neutral, remove the Arm prefixes. Also remove the check searching for a GIC version. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c | 4 +- .../FdtHwInfoParserLib/FdtHwInfoParserLib.inf | 4 +- .../Pci/ArmPciConfigSpaceParser.c | 815 --------------------- .../Pci/ArmPciConfigSpaceParser.h | 143 ---- .../FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c | 806 ++++++++++++++++++++ .../FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h | 143 ++++ 6 files changed, 953 insertions(+), 962 deletions(-) delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c index 403402731a..49a7636dad 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c @@ -9,7 +9,7 @@ #include "Arm/BootArch/ArmBootArchParser.h" #include "Arm/GenericTimer/ArmGenericTimerParser.h" #include "Arm/Gic/ArmGicDispatcher.h" -#include "Pci/ArmPciConfigSpaceParser.h" +#include "Pci/PciConfigSpaceParser.h" #include "Serial/ArmSerialPortParser.h" /** Ordered table of parsers/dispatchers. @@ -25,7 +25,7 @@ STATIC CONST FDT_HW_INFO_PARSER_FUNC HwInfoParserTable[] = { ArmBootArchInfoParser, ArmGenericTimerInfoParser, ArmGicDispatcher, - ArmPciConfigInfoParser, + PciConfigInfoParser, SerialPortDispatcher }; diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf index 3abc6a0fd2..55ec7d97fa 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf @@ -22,8 +22,8 @@ FdtHwInfoParser.h FdtUtility.c FdtUtility.h - Pci/ArmPciConfigSpaceParser.c - Pci/ArmPciConfigSpaceParser.h + Pci/PciConfigSpaceParser.c + Pci/PciConfigSpaceParser.h Serial/ArmSerialPortParser.c Serial/ArmSerialPortParser.h diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c deleted file mode 100644 index 5d11863dfe..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c +++ /dev/null @@ -1,815 +0,0 @@ -/** @file - Arm PCI Configuration Space Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml - - PCI Firmware Specification - Revision 3.0 - - Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9 - - Devicetree Specification Release v0.3 - - linux kernel code -**/ - -#include "CmObjectDescUtility.h" -#include - -#include "FdtHwInfoParser.h" -#include "Pci/ArmPciConfigSpaceParser.h" -#include "Arm/Gic/ArmGicDispatcher.h" - -/** List of "compatible" property values for host PCIe bridges nodes. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR PciCompatibleStr[] = { - { "pci-host-ecam-generic" } -}; - -/** COMPATIBILITY_INFO structure for the PCIe. -*/ -STATIC CONST COMPATIBILITY_INFO PciCompatibleInfo = { - ARRAY_SIZE (PciCompatibleStr), - PciCompatibleStr -}; - -/** Get the Segment group (also called: Domain Id) of a host-pci node. - - kernel/Documentation/devicetree/bindings/pci/pci.txt: - "It is required to either not set this property at all or set it for all - host bridges in the system" - - The function checks the "linux,pci-domain" property of the host-pci node. - Either all host-pci nodes must have this property, or none of them. If the - property is available, read it. Otherwise dynamically assign the Ids. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] HostPciNode Offset of a host-pci node. - @param [out] SegGroup Segment group assigned to the host-pci controller. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -GetPciSegGroup ( - IN CONST VOID *Fdt, - IN INT32 HostPciNode, - OUT INT32 *SegGroup - ) -{ - CONST UINT8 *Data; - INT32 DataSize; - STATIC INT32 LocalSegGroup = 0; - - if ((Fdt == NULL) || - (SegGroup == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Data = fdt_getprop (Fdt, HostPciNode, "linux,pci-domain", &DataSize); - if ((Data == NULL) || (DataSize < 0)) { - // Did not find property, assign the DomainIds ourselves. - if (LocalSegGroup < 0) { - // "linux,pci-domain" property was defined for another node. - ASSERT (0); - return EFI_ABORTED; - } - - *SegGroup = LocalSegGroup++; - return EFI_SUCCESS; - } - - if ((DataSize > sizeof (UINT32)) || - (LocalSegGroup > 0)) - { - // Property on more than 1 cell or - // "linux,pci-domain" property was not defined for a node. - ASSERT (0); - return EFI_ABORTED; - } - - // If one node has the "linux,pci-domain" property, then all the host-pci - // nodes must have it. - LocalSegGroup = -1; - - *SegGroup = fdt32_to_cpu (*(UINT32 *)Data); - return EFI_SUCCESS; -} - -/** Parse the bus-range controlled by this host-pci node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] HostPciNode Offset of a host-pci node. - @param [in, out] PciInfo PCI_PARSER_TABLE structure storing - information about the current host-pci. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -PopulateBusRange ( - IN CONST VOID *Fdt, - IN INT32 HostPciNode, - IN OUT PCI_PARSER_TABLE *PciInfo - ) -{ - CONST UINT8 *Data; - INT32 DataSize; - UINT32 StartBus; - UINT32 EndBus; - - if ((Fdt == NULL) || - (PciInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Data = fdt_getprop (Fdt, HostPciNode, "bus-range", &DataSize); - if ((Data == NULL) || (DataSize < 0)) { - // No evidence this property is mandatory. Use default values. - StartBus = 0; - EndBus = 255; - } else if (DataSize == (2 * sizeof (UINT32))) { - // If available, the property is on two integers. - StartBus = fdt32_to_cpu (((UINT32 *)Data)[0]); - EndBus = fdt32_to_cpu (((UINT32 *)Data)[1]); - } else { - ASSERT (0); - return EFI_ABORTED; - } - - PciInfo->PciConfigSpaceInfo.StartBusNumber = StartBus; - PciInfo->PciConfigSpaceInfo.EndBusNumber = EndBus; - - return EFI_SUCCESS; -} - -/** Parse the PCI address map. - - The PCI address map is available in the "ranges" device-tree property. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] HostPciNode Offset of a host-pci node. - @param [in] AddressCells # of cells used to encode an address on - the parent bus. - @param [in, out] PciInfo PCI_PARSER_TABLE structure storing - information about the current host-pci. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES An allocation has failed. -**/ -STATIC -EFI_STATUS -EFIAPI -ParseAddressMap ( - IN CONST VOID *Fdt, - IN INT32 HostPciNode, - IN INT32 AddressCells, - IN OUT PCI_PARSER_TABLE *PciInfo - ) -{ - CONST UINT8 *Data; - INT32 DataSize; - UINT32 Index; - UINT32 Offset; - UINT32 AddressMapSize; - UINT32 Count; - UINT32 PciAddressAttr; - - CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *PciAddressMapInfo; - UINT32 BufferSize; - - // The mapping is done on AddressMapSize bytes. - AddressMapSize = (PCI_ADDRESS_CELLS + AddressCells + PCI_SIZE_CELLS) * - sizeof (UINT32); - - Data = fdt_getprop (Fdt, HostPciNode, "ranges", &DataSize); - if ((Data == NULL) || - (DataSize < 0) || - ((DataSize % AddressMapSize) != 0)) - { - // If error or not on AddressMapSize bytes. - ASSERT (0); - return EFI_ABORTED; - } - - Count = DataSize / AddressMapSize; - - // Allocate a buffer to store each address mapping. - BufferSize = Count * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO); - PciAddressMapInfo = AllocateZeroPool (BufferSize); - if (PciAddressMapInfo == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - - for (Index = 0; Index < Count; Index++) { - Offset = Index * AddressMapSize; - - // Pci address attributes - PciAddressAttr = fdt32_to_cpu (*(UINT32 *)&Data[Offset]); - PciAddressMapInfo[Index].SpaceCode = READ_PCI_SS (PciAddressAttr); - Offset += sizeof (UINT32); - - // Pci address - PciAddressMapInfo[Index].PciAddress = - fdt64_to_cpu (*(UINT64 *)&Data[Offset]); - Offset += (PCI_ADDRESS_CELLS - 1) * sizeof (UINT32); - - // Cpu address - if (AddressCells == 2) { - PciAddressMapInfo[Index].CpuAddress = - fdt64_to_cpu (*(UINT64 *)&Data[Offset]); - } else { - PciAddressMapInfo[Index].CpuAddress = - fdt32_to_cpu (*(UINT32 *)&Data[Offset]); - } - - Offset += AddressCells * sizeof (UINT32); - - // Address size - PciAddressMapInfo[Index].AddressSize = - fdt64_to_cpu (*(UINT64 *)&Data[Offset]); - Offset += PCI_SIZE_CELLS * sizeof (UINT32); - } // for - - PciInfo->Mapping[PciMappingTableAddress].ObjectId = - CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciAddressMapInfo); - PciInfo->Mapping[PciMappingTableAddress].Size = - sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO) * Count; - PciInfo->Mapping[PciMappingTableAddress].Data = PciAddressMapInfo; - PciInfo->Mapping[PciMappingTableAddress].Count = Count; - - return EFI_SUCCESS; -} - -/** Parse the PCI interrupt map. - - The PCI interrupt map is available in the "interrupt-map" - and "interrupt-map-mask" device-tree properties. - - Cf Devicetree Specification Release v0.3, - s2.4.3 Interrupt Nexus Properties - - An interrupt-map must be as: - interrupt-map = < [child unit address] [child interrupt specifier] - [interrupt-parent] - [parent unit address] [parent interrupt specifier] > - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] HostPciNode Offset of a host-pci node. - @param [in, out] PciInfo PCI_PARSER_TABLE structure storing - information about the current host-pci. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_OUT_OF_RESOURCES An allocation has failed. -**/ -STATIC -EFI_STATUS -EFIAPI -ParseIrqMap ( - IN CONST VOID *Fdt, - IN INT32 HostPciNode, - IN OUT PCI_PARSER_TABLE *PciInfo - ) -{ - EFI_STATUS Status; - CONST UINT8 *Data; - INT32 DataSize; - UINT32 Index; - UINT32 Offset; - - INT32 IntcNode; - INT32 IntcAddressCells; - INT32 IntcCells; - - INT32 PciIntCells; - INT32 IntcPhandle; - - INT32 IrqMapSize; - UINT32 IrqMapCount; - CONST UINT8 *IrqMapMask; - INT32 IrqMapMaskSize; - - INT32 PHandleOffset; - UINT32 GicVersion; - - UINT32 PciAddressAttr; - - CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *PciInterruptMapInfo; - UINT32 BufferSize; - - Data = fdt_getprop (Fdt, HostPciNode, "interrupt-map", &DataSize); - if ((Data == NULL) || (DataSize <= 0)) { - DEBUG (( - DEBUG_WARN, - "Fdt parser: No Legacy interrupts found for PCI configuration space at " - "address: 0x%lx, group segment: %d\n", - PciInfo->PciConfigSpaceInfo.BaseAddress, - PciInfo->PciConfigSpaceInfo.PciSegmentGroupNumber - )); - return EFI_NOT_FOUND; - } - - // PCI interrupts are expected to be on 1 cell. Check it. - Status = FdtGetInterruptCellsInfo (Fdt, HostPciNode, &PciIntCells); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (PciIntCells != PCI_INTERRUPTS_CELLS) { - ASSERT (0); - return EFI_ABORTED; - } - - IrqMapMask = fdt_getprop ( - Fdt, - HostPciNode, - "interrupt-map-mask", - &IrqMapMaskSize - ); - if ((IrqMapMask == NULL) || - (IrqMapMaskSize != - (PCI_ADDRESS_CELLS + PCI_INTERRUPTS_CELLS) * sizeof (UINT32))) - { - ASSERT (0); - return EFI_ABORTED; - } - - // Get the interrupt-controller of the first irq mapping. - PHandleOffset = (PCI_ADDRESS_CELLS + PciIntCells) * sizeof (UINT32); - if (PHandleOffset > DataSize) { - ASSERT (0); - return EFI_ABORTED; - } - - IntcPhandle = fdt32_to_cpu (*(UINT32 *)&Data[PHandleOffset]); - IntcNode = fdt_node_offset_by_phandle (Fdt, IntcPhandle); - if (IntcNode < 0) { - ASSERT (0); - return EFI_ABORTED; - } - - // Only support Gic(s) for now. - Status = GetGicVersion (Fdt, IntcNode, &GicVersion); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Get the "address-cells" property of the IntcNode. - Status = FdtGetAddressInfo (Fdt, IntcNode, &IntcAddressCells, NULL); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Get the "interrupt-cells" property of the IntcNode. - Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntcCells); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // An irq mapping is done on IrqMapSize bytes - // (which includes 1 cell for the PHandle). - IrqMapSize = (PCI_ADDRESS_CELLS + PciIntCells + 1 - + IntcAddressCells + IntcCells) * sizeof (UINT32); - if ((DataSize % IrqMapSize) != 0) { - // The mapping is not done on IrqMapSize bytes. - ASSERT (0); - return EFI_ABORTED; - } - - IrqMapCount = DataSize / IrqMapSize; - - // We assume the same interrupt-controller is used for all the mappings. - // Check this is correct. - for (Index = 0; Index < IrqMapCount; Index++) { - if (IntcPhandle != fdt32_to_cpu ( - *(UINT32 *)&Data[(Index * IrqMapSize) + PHandleOffset] - )) - { - ASSERT (0); - return EFI_ABORTED; - } - } - - // Allocate a buffer to store each interrupt mapping. - IrqMapCount = DataSize / IrqMapSize; - BufferSize = IrqMapCount * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO); - PciInterruptMapInfo = AllocateZeroPool (BufferSize); - if (PciInterruptMapInfo == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - - for (Index = 0; Index < IrqMapCount; Index++) { - Offset = Index * IrqMapSize; - - // Pci address attributes - PciAddressAttr = fdt32_to_cpu ( - (*(UINT32 *)&Data[Offset]) & - (*(UINT32 *)&IrqMapMask[0]) - ); - PciInterruptMapInfo[Index].PciBus = READ_PCI_BBBBBBBB (PciAddressAttr); - PciInterruptMapInfo[Index].PciDevice = READ_PCI_DDDDD (PciAddressAttr); - Offset += PCI_ADDRESS_CELLS * sizeof (UINT32); - - // Pci irq - PciInterruptMapInfo[Index].PciInterrupt = fdt32_to_cpu ( - (*(UINT32 *)&Data[Offset]) & - (*(UINT32 *)&IrqMapMask[3 * sizeof (UINT32)]) - ); - // -1 to translate from device-tree (INTA=1) to ACPI (INTA=0) irq IDs. - PciInterruptMapInfo[Index].PciInterrupt -= 1; - Offset += PCI_INTERRUPTS_CELLS * sizeof (UINT32); - - // PHandle (skip it) - Offset += sizeof (UINT32); - - // "Parent unit address" (skip it) - Offset += IntcAddressCells * sizeof (UINT32); - - // Interrupt controller interrupt and flags - PciInterruptMapInfo[Index].IntcInterrupt.Interrupt = - FdtGetInterruptId ((UINT32 *)&Data[Offset]); - PciInterruptMapInfo[Index].IntcInterrupt.Flags = - FdtGetInterruptFlags ((UINT32 *)&Data[Offset]); - } // for - - PciInfo->Mapping[PciMappingTableInterrupt].ObjectId = - CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciInterruptMapInfo); - PciInfo->Mapping[PciMappingTableInterrupt].Size = - sizeof (CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO) * IrqMapCount; - PciInfo->Mapping[PciMappingTableInterrupt].Data = PciInterruptMapInfo; - PciInfo->Mapping[PciMappingTableInterrupt].Count = IrqMapCount; - - return Status; -} - -/** Parse a Host-pci node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] HostPciNode Offset of a host-pci node. - @param [in, out] PciInfo The CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES An allocation has failed. -**/ -STATIC -EFI_STATUS -EFIAPI -PciNodeParser ( - IN CONST VOID *Fdt, - IN INT32 HostPciNode, - IN OUT PCI_PARSER_TABLE *PciInfo - ) -{ - EFI_STATUS Status; - INT32 AddressCells; - INT32 SizeCells; - CONST UINT8 *Data; - INT32 DataSize; - INT32 SegGroup; - - if ((Fdt == NULL) || - (PciInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Segment Group / DomainId - Status = GetPciSegGroup (Fdt, HostPciNode, &SegGroup); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - PciInfo->PciConfigSpaceInfo.PciSegmentGroupNumber = SegGroup; - - // Bus range - Status = PopulateBusRange (Fdt, HostPciNode, PciInfo); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = FdtGetParentAddressInfo ( - Fdt, - HostPciNode, - &AddressCells, - &SizeCells - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Only support 32/64 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2) || - (SizeCells < 1) || - (SizeCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - Data = fdt_getprop (Fdt, HostPciNode, "reg", &DataSize); - if ((Data == NULL) || - (DataSize != ((AddressCells + SizeCells) * sizeof (UINT32)))) - { - // If error or wrong size. - ASSERT (0); - return EFI_ABORTED; - } - - // Base address - if (AddressCells == 2) { - PciInfo->PciConfigSpaceInfo.BaseAddress = fdt64_to_cpu (*(UINT64 *)Data); - } else { - PciInfo->PciConfigSpaceInfo.BaseAddress = fdt32_to_cpu (*(UINT32 *)Data); - } - - // Address map - Status = ParseAddressMap ( - Fdt, - HostPciNode, - AddressCells, - PciInfo - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Irq map - Status = ParseIrqMap ( - Fdt, - HostPciNode, - PciInfo - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - ASSERT (0); - } - - return EFI_SUCCESS; -} - -/** Add the parsed Pci information to the Configuration Manager. - - CmObj of the following types are concerned: - - EArchCommonObjPciConfigSpaceInfo - - EArchCommonObjPciAddressMapInfo - - EArchCommonObjPciInterruptMapInfo - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] PciTableInfo PCI_PARSER_TABLE structure containing the - CmObjs to add. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES An allocation has failed. -**/ -STATIC -EFI_STATUS -EFIAPI -PciInfoAdd ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN PCI_PARSER_TABLE *PciTableInfo - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo; - - if ((FdtParserHandle == NULL) || - (PciTableInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - PciConfigSpaceInfo = &PciTableInfo->PciConfigSpaceInfo; - - // Add the address map space CmObj to the Configuration Manager. - Status = AddMultipleCmObjWithCmObjRef ( - FdtParserHandle, - &PciTableInfo->Mapping[PciMappingTableAddress], - &PciConfigSpaceInfo->AddressMapToken - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add the interrupt map space CmObj to the Configuration Manager. - // Possible to have no legacy interrupts, or no device described and - // thus no interrupt-mapping. - if (PciTableInfo->Mapping[PciMappingTableInterrupt].Count != 0) { - Status = AddMultipleCmObjWithCmObjRef ( - FdtParserHandle, - &PciTableInfo->Mapping[PciMappingTableInterrupt], - &PciConfigSpaceInfo->InterruptMapToken - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } - - // Add the configuration space CmObj to the Configuration Manager. - Status = AddSingleCmObj ( - FdtParserHandle, - CREATE_CM_ARCH_COMMON_OBJECT_ID ( - EArchCommonObjPciConfigSpaceInfo - ), - &PciTableInfo->PciConfigSpaceInfo, - sizeof (CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO), - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** Free the CmObjDesc of the ParserTable. - - @param [in] PciTableInfo PCI_PARSER_TABLE structure containing the - CmObjs to free. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER Invalid parameter. -**/ -STATIC -EFI_STATUS -EFIAPI -FreeParserTable ( - IN PCI_PARSER_TABLE *PciTableInfo - ) -{ - UINT32 Index; - VOID *Data; - - if (PciTableInfo == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - for (Index = 0; Index < PciMappingTableMax; Index++) { - Data = PciTableInfo->Mapping[Index].Data; - if (Data != NULL) { - FreePool (Data); - } - } - - return EFI_SUCCESS; -} - -/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function. - - The following structure is populated: - typedef struct CmArchCommonPciConfigSpaceInfo { - UINT64 BaseAddress; // {Populated} - UINT16 PciSegmentGroupNumber; // {Populated} - UINT8 StartBusNumber; // {Populated} - UINT8 EndBusNumber; // {Populated} - } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; - - typedef struct CmArchCommonPciAddressMapInfo { - UINT8 SpaceCode; // {Populated} - UINT64 PciAddress; // {Populated} - UINT64 CpuAddress; // {Populated} - UINT64 AddressSize; // {Populated} - } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; - - typedef struct CmArchCommonPciInterruptMapInfo { - UINT8 PciBus; // {Populated} - UINT8 PciDevice; // {Populated} - UINT8 PciInterrupt; // {Populated} - CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} - } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmPciConfigInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - UINT32 Index; - INT32 PciNode; - UINT32 PciNodeCount; - PCI_PARSER_TABLE PciTableInfo; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - // Only search host-pci devices. - // PCI Firmware Specification Revision 3.0, s4.1.2. "MCFG Table Description": - // "This table directly refers to PCI Segment Groups defined in the system - // via the _SEG object in the ACPI name space for the applicable host bridge - // device." - Status = FdtCountCompatNodeInBranch ( - Fdt, - FdtBranch, - &PciCompatibleInfo, - &PciNodeCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (PciNodeCount == 0) { - return EFI_NOT_FOUND; - } - - // Parse each host-pci node in the branch. - PciNode = FdtBranch; - for (Index = 0; Index < PciNodeCount; Index++) { - ZeroMem (&PciTableInfo, sizeof (PCI_PARSER_TABLE)); - - Status = FdtGetNextCompatNodeInBranch ( - Fdt, - FdtBranch, - &PciCompatibleInfo, - &PciNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - Status = PciNodeParser (Fdt, PciNode, &PciTableInfo); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto error_handler; - } - - // Add Pci information to the Configuration Manager. - Status = PciInfoAdd (FdtParserHandle, &PciTableInfo); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto error_handler; - } - - Status = FreeParserTable (&PciTableInfo); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - } // for - - return Status; - -error_handler: - FreeParserTable (&PciTableInfo); - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h deleted file mode 100644 index e680138385..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h +++ /dev/null @@ -1,143 +0,0 @@ -/** @file - Arm PCI Configuration Space Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml - - PCI Firmware Specification - Revision 3.0 - - Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9 - - Devicetree Specification Release v0.3 - - linux kernel code -**/ - -#ifndef ARM_PCI_CONFIG_SPACE_PARSER_H_ -#define ARM_PCI_CONFIG_SPACE_PARSER_H_ - -/** Read LEN bits at OFF offsets bits of the ADDR. - - @param [in] ADDR Address to read the bits from. - @param [in] OFF Offset of the bits to read. - @param [in] LEN Number of bits to read. - - @return The bits read. -**/ -#define READ_BITS(ADDR, OFF, LEN) (((ADDR) >> (OFF)) & ((1<<(LEN))-1)) - -/* Pci address attributes. -*/ -/// 0 if relocatable. -#define READ_PCI_N(ADDR) READ_BITS((ADDR), 31, 1) -/// 1 if prefetchable. -#define READ_PCI_P(ADDR) READ_BITS((ADDR), 30, 1) -/// 1 if aliased. -#define READ_PCI_T(ADDR) READ_BITS((ADDR), 29, 1) - -/** Space code. - - 00: Configuration Space - 01: I/O Space - 10: 32-bit-address Memory Space - 11: 64-bit-address Memory Space -*/ -#define READ_PCI_SS(ADDR) READ_BITS((ADDR), 24, 2) -/// Bus number. -#define READ_PCI_BBBBBBBB(ADDR) READ_BITS((ADDR), 16, 8) -/// Device number. -#define READ_PCI_DDDDD(ADDR) READ_BITS((ADDR), 11, 5) - -/** Number of device-tree cells used for PCI nodes properties. - - Values are well defined, except the "#interrupt-cells" which - is assumed to be 1. -*/ -#define PCI_ADDRESS_CELLS 3U -#define PCI_SIZE_CELLS 2U -#define PCI_INTERRUPTS_CELLS 1U - -/** PCI interrupt flags for device-tree. - - Local Bus Specification Revision 3.0, s2.2.6., Interrupt Pins: - - 'Interrupts on PCI are optional and defined as "level sensitive," - asserted low (negative true)' -*/ -#define DT_PCI_IRQ_FLAGS(x) (((x) & 0xF) == BIT0) - -/** Indexes in the mapping table. -*/ -typedef enum PciMappingTable { - PciMappingTableAddress, ///< 0 - Address mapping - PciMappingTableInterrupt, ///< 1 - Interrupt mapping - PciMappingTableMax, ///< 2 - Max -} PCI_MAPPING_TABLE; - -#pragma pack(1) - -/** PCI parser table - - Multiple address-map and interrupt map can correspond to - one host-pci device. This structure allows to temporarily - store the CmObjects created and generate tokens once - the whole device tree is parsed. -*/ -typedef struct PciParserTable { - /// PCI Configuration Space Info - CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo; - - /// Store the address mapping and interrupt mapping as CmObjDesc - /// before adding them to the Configuration Manager. - CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax]; -} PCI_PARSER_TABLE; - -#pragma pack() - -/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function. - - The following structure is populated: - typedef struct CmArchCommonPciConfigSpaceInfo { - UINT64 BaseAddress; // {Populated} - UINT16 PciSegmentGroupNumber; // {Populated} - UINT8 StartBusNumber; // {Populated} - UINT8 EndBusNumber; // {Populated} - } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; - - typedef struct CmArchCommonPciAddressMapInfo { - UINT8 SpaceCode; // {Populated} - UINT64 PciAddress; // {Populated} - UINT64 CpuAddress; // {Populated} - UINT64 AddressSize; // {Populated} - } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; - - typedef struct CmArchCommonPciInterruptMapInfo { - UINT8 PciBus; // {Populated} - UINT8 PciDevice; // {Populated} - UINT8 PciInterrupt; // {Populated} - CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} - } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -ArmPciConfigInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_PCI_CONFIG_SPACE_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c new file mode 100644 index 0000000000..76f9efdf64 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c @@ -0,0 +1,806 @@ +/** @file + PCI Configuration Space Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml + - PCI Firmware Specification - Revision 3.0 + - Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9 + - Devicetree Specification Release v0.3 + - linux kernel code +**/ + +#include "CmObjectDescUtility.h" +#include + +#include "FdtHwInfoParser.h" +#include "Pci/PciConfigSpaceParser.h" + +/** List of "compatible" property values for host PCIe bridges nodes. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR PciCompatibleStr[] = { + { "pci-host-ecam-generic" } +}; + +/** COMPATIBILITY_INFO structure for the PCIe. +*/ +STATIC CONST COMPATIBILITY_INFO PciCompatibleInfo = { + ARRAY_SIZE (PciCompatibleStr), + PciCompatibleStr +}; + +/** Get the Segment group (also called: Domain Id) of a host-pci node. + + kernel/Documentation/devicetree/bindings/pci/pci.txt: + "It is required to either not set this property at all or set it for all + host bridges in the system" + + The function checks the "linux,pci-domain" property of the host-pci node. + Either all host-pci nodes must have this property, or none of them. If the + property is available, read it. Otherwise dynamically assign the Ids. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] HostPciNode Offset of a host-pci node. + @param [out] SegGroup Segment group assigned to the host-pci controller. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +GetPciSegGroup ( + IN CONST VOID *Fdt, + IN INT32 HostPciNode, + OUT INT32 *SegGroup + ) +{ + CONST UINT8 *Data; + INT32 DataSize; + STATIC INT32 LocalSegGroup = 0; + + if ((Fdt == NULL) || + (SegGroup == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Data = fdt_getprop (Fdt, HostPciNode, "linux,pci-domain", &DataSize); + if ((Data == NULL) || (DataSize < 0)) { + // Did not find property, assign the DomainIds ourselves. + if (LocalSegGroup < 0) { + // "linux,pci-domain" property was defined for another node. + ASSERT (0); + return EFI_ABORTED; + } + + *SegGroup = LocalSegGroup++; + return EFI_SUCCESS; + } + + if ((DataSize > sizeof (UINT32)) || + (LocalSegGroup > 0)) + { + // Property on more than 1 cell or + // "linux,pci-domain" property was not defined for a node. + ASSERT (0); + return EFI_ABORTED; + } + + // If one node has the "linux,pci-domain" property, then all the host-pci + // nodes must have it. + LocalSegGroup = -1; + + *SegGroup = fdt32_to_cpu (*(UINT32 *)Data); + return EFI_SUCCESS; +} + +/** Parse the bus-range controlled by this host-pci node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] HostPciNode Offset of a host-pci node. + @param [in, out] PciInfo PCI_PARSER_TABLE structure storing + information about the current host-pci. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +PopulateBusRange ( + IN CONST VOID *Fdt, + IN INT32 HostPciNode, + IN OUT PCI_PARSER_TABLE *PciInfo + ) +{ + CONST UINT8 *Data; + INT32 DataSize; + UINT32 StartBus; + UINT32 EndBus; + + if ((Fdt == NULL) || + (PciInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Data = fdt_getprop (Fdt, HostPciNode, "bus-range", &DataSize); + if ((Data == NULL) || (DataSize < 0)) { + // No evidence this property is mandatory. Use default values. + StartBus = 0; + EndBus = 255; + } else if (DataSize == (2 * sizeof (UINT32))) { + // If available, the property is on two integers. + StartBus = fdt32_to_cpu (((UINT32 *)Data)[0]); + EndBus = fdt32_to_cpu (((UINT32 *)Data)[1]); + } else { + ASSERT (0); + return EFI_ABORTED; + } + + PciInfo->PciConfigSpaceInfo.StartBusNumber = StartBus; + PciInfo->PciConfigSpaceInfo.EndBusNumber = EndBus; + + return EFI_SUCCESS; +} + +/** Parse the PCI address map. + + The PCI address map is available in the "ranges" device-tree property. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] HostPciNode Offset of a host-pci node. + @param [in] AddressCells # of cells used to encode an address on + the parent bus. + @param [in, out] PciInfo PCI_PARSER_TABLE structure storing + information about the current host-pci. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES An allocation has failed. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseAddressMap ( + IN CONST VOID *Fdt, + IN INT32 HostPciNode, + IN INT32 AddressCells, + IN OUT PCI_PARSER_TABLE *PciInfo + ) +{ + CONST UINT8 *Data; + INT32 DataSize; + UINT32 Index; + UINT32 Offset; + UINT32 AddressMapSize; + UINT32 Count; + UINT32 PciAddressAttr; + + CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *PciAddressMapInfo; + UINT32 BufferSize; + + // The mapping is done on AddressMapSize bytes. + AddressMapSize = (PCI_ADDRESS_CELLS + AddressCells + PCI_SIZE_CELLS) * + sizeof (UINT32); + + Data = fdt_getprop (Fdt, HostPciNode, "ranges", &DataSize); + if ((Data == NULL) || + (DataSize < 0) || + ((DataSize % AddressMapSize) != 0)) + { + // If error or not on AddressMapSize bytes. + ASSERT (0); + return EFI_ABORTED; + } + + Count = DataSize / AddressMapSize; + + // Allocate a buffer to store each address mapping. + BufferSize = Count * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO); + PciAddressMapInfo = AllocateZeroPool (BufferSize); + if (PciAddressMapInfo == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < Count; Index++) { + Offset = Index * AddressMapSize; + + // Pci address attributes + PciAddressAttr = fdt32_to_cpu (*(UINT32 *)&Data[Offset]); + PciAddressMapInfo[Index].SpaceCode = READ_PCI_SS (PciAddressAttr); + Offset += sizeof (UINT32); + + // Pci address + PciAddressMapInfo[Index].PciAddress = + fdt64_to_cpu (*(UINT64 *)&Data[Offset]); + Offset += (PCI_ADDRESS_CELLS - 1) * sizeof (UINT32); + + // Cpu address + if (AddressCells == 2) { + PciAddressMapInfo[Index].CpuAddress = + fdt64_to_cpu (*(UINT64 *)&Data[Offset]); + } else { + PciAddressMapInfo[Index].CpuAddress = + fdt32_to_cpu (*(UINT32 *)&Data[Offset]); + } + + Offset += AddressCells * sizeof (UINT32); + + // Address size + PciAddressMapInfo[Index].AddressSize = + fdt64_to_cpu (*(UINT64 *)&Data[Offset]); + Offset += PCI_SIZE_CELLS * sizeof (UINT32); + } // for + + PciInfo->Mapping[PciMappingTableAddress].ObjectId = + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciAddressMapInfo); + PciInfo->Mapping[PciMappingTableAddress].Size = + sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO) * Count; + PciInfo->Mapping[PciMappingTableAddress].Data = PciAddressMapInfo; + PciInfo->Mapping[PciMappingTableAddress].Count = Count; + + return EFI_SUCCESS; +} + +/** Parse the PCI interrupt map. + + The PCI interrupt map is available in the "interrupt-map" + and "interrupt-map-mask" device-tree properties. + + Cf Devicetree Specification Release v0.3, + s2.4.3 Interrupt Nexus Properties + + An interrupt-map must be as: + interrupt-map = < [child unit address] [child interrupt specifier] + [interrupt-parent] + [parent unit address] [parent interrupt specifier] > + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] HostPciNode Offset of a host-pci node. + @param [in, out] PciInfo PCI_PARSER_TABLE structure storing + information about the current host-pci. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_OUT_OF_RESOURCES An allocation has failed. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseIrqMap ( + IN CONST VOID *Fdt, + IN INT32 HostPciNode, + IN OUT PCI_PARSER_TABLE *PciInfo + ) +{ + EFI_STATUS Status; + CONST UINT8 *Data; + INT32 DataSize; + UINT32 Index; + UINT32 Offset; + + INT32 IntcNode; + INT32 IntcAddressCells; + INT32 IntcCells; + + INT32 PciIntCells; + INT32 IntcPhandle; + + INT32 IrqMapSize; + UINT32 IrqMapCount; + CONST UINT8 *IrqMapMask; + INT32 IrqMapMaskSize; + + INT32 PHandleOffset; + + UINT32 PciAddressAttr; + + CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *PciInterruptMapInfo; + UINT32 BufferSize; + + Data = fdt_getprop (Fdt, HostPciNode, "interrupt-map", &DataSize); + if ((Data == NULL) || (DataSize <= 0)) { + DEBUG (( + DEBUG_WARN, + "Fdt parser: No Legacy interrupts found for PCI configuration space at " + "address: 0x%lx, group segment: %d\n", + PciInfo->PciConfigSpaceInfo.BaseAddress, + PciInfo->PciConfigSpaceInfo.PciSegmentGroupNumber + )); + return EFI_NOT_FOUND; + } + + // PCI interrupts are expected to be on 1 cell. Check it. + Status = FdtGetInterruptCellsInfo (Fdt, HostPciNode, &PciIntCells); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (PciIntCells != PCI_INTERRUPTS_CELLS) { + ASSERT (0); + return EFI_ABORTED; + } + + IrqMapMask = fdt_getprop ( + Fdt, + HostPciNode, + "interrupt-map-mask", + &IrqMapMaskSize + ); + if ((IrqMapMask == NULL) || + (IrqMapMaskSize != + (PCI_ADDRESS_CELLS + PCI_INTERRUPTS_CELLS) * sizeof (UINT32))) + { + ASSERT (0); + return EFI_ABORTED; + } + + // Get the interrupt-controller of the first irq mapping. + PHandleOffset = (PCI_ADDRESS_CELLS + PciIntCells) * sizeof (UINT32); + if (PHandleOffset > DataSize) { + ASSERT (0); + return EFI_ABORTED; + } + + IntcPhandle = fdt32_to_cpu (*(UINT32 *)&Data[PHandleOffset]); + IntcNode = fdt_node_offset_by_phandle (Fdt, IntcPhandle); + if (IntcNode < 0) { + ASSERT (0); + return EFI_ABORTED; + } + + // Get the "address-cells" property of the IntcNode. + Status = FdtGetAddressInfo (Fdt, IntcNode, &IntcAddressCells, NULL); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Get the "interrupt-cells" property of the IntcNode. + Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntcCells); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // An irq mapping is done on IrqMapSize bytes + // (which includes 1 cell for the PHandle). + IrqMapSize = (PCI_ADDRESS_CELLS + PciIntCells + 1 + + IntcAddressCells + IntcCells) * sizeof (UINT32); + if ((DataSize % IrqMapSize) != 0) { + // The mapping is not done on IrqMapSize bytes. + ASSERT (0); + return EFI_ABORTED; + } + + IrqMapCount = DataSize / IrqMapSize; + + // We assume the same interrupt-controller is used for all the mappings. + // Check this is correct. + for (Index = 0; Index < IrqMapCount; Index++) { + if (IntcPhandle != fdt32_to_cpu ( + *(UINT32 *)&Data[(Index * IrqMapSize) + PHandleOffset] + )) + { + ASSERT (0); + return EFI_ABORTED; + } + } + + // Allocate a buffer to store each interrupt mapping. + IrqMapCount = DataSize / IrqMapSize; + BufferSize = IrqMapCount * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO); + PciInterruptMapInfo = AllocateZeroPool (BufferSize); + if (PciInterruptMapInfo == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < IrqMapCount; Index++) { + Offset = Index * IrqMapSize; + + // Pci address attributes + PciAddressAttr = fdt32_to_cpu ( + (*(UINT32 *)&Data[Offset]) & + (*(UINT32 *)&IrqMapMask[0]) + ); + PciInterruptMapInfo[Index].PciBus = READ_PCI_BBBBBBBB (PciAddressAttr); + PciInterruptMapInfo[Index].PciDevice = READ_PCI_DDDDD (PciAddressAttr); + Offset += PCI_ADDRESS_CELLS * sizeof (UINT32); + + // Pci irq + PciInterruptMapInfo[Index].PciInterrupt = fdt32_to_cpu ( + (*(UINT32 *)&Data[Offset]) & + (*(UINT32 *)&IrqMapMask[3 * sizeof (UINT32)]) + ); + // -1 to translate from device-tree (INTA=1) to ACPI (INTA=0) irq IDs. + PciInterruptMapInfo[Index].PciInterrupt -= 1; + Offset += PCI_INTERRUPTS_CELLS * sizeof (UINT32); + + // PHandle (skip it) + Offset += sizeof (UINT32); + + // "Parent unit address" (skip it) + Offset += IntcAddressCells * sizeof (UINT32); + + // Interrupt controller interrupt and flags + PciInterruptMapInfo[Index].IntcInterrupt.Interrupt = + FdtGetInterruptId ((UINT32 *)&Data[Offset]); + PciInterruptMapInfo[Index].IntcInterrupt.Flags = + FdtGetInterruptFlags ((UINT32 *)&Data[Offset]); + } // for + + PciInfo->Mapping[PciMappingTableInterrupt].ObjectId = + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciInterruptMapInfo); + PciInfo->Mapping[PciMappingTableInterrupt].Size = + sizeof (CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO) * IrqMapCount; + PciInfo->Mapping[PciMappingTableInterrupt].Data = PciInterruptMapInfo; + PciInfo->Mapping[PciMappingTableInterrupt].Count = IrqMapCount; + + return Status; +} + +/** Parse a Host-pci node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] HostPciNode Offset of a host-pci node. + @param [in, out] PciInfo The CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES An allocation has failed. +**/ +STATIC +EFI_STATUS +EFIAPI +PciNodeParser ( + IN CONST VOID *Fdt, + IN INT32 HostPciNode, + IN OUT PCI_PARSER_TABLE *PciInfo + ) +{ + EFI_STATUS Status; + INT32 AddressCells; + INT32 SizeCells; + CONST UINT8 *Data; + INT32 DataSize; + INT32 SegGroup; + + if ((Fdt == NULL) || + (PciInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Segment Group / DomainId + Status = GetPciSegGroup (Fdt, HostPciNode, &SegGroup); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + PciInfo->PciConfigSpaceInfo.PciSegmentGroupNumber = SegGroup; + + // Bus range + Status = PopulateBusRange (Fdt, HostPciNode, PciInfo); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = FdtGetParentAddressInfo ( + Fdt, + HostPciNode, + &AddressCells, + &SizeCells + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Only support 32/64 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2) || + (SizeCells < 1) || + (SizeCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + Data = fdt_getprop (Fdt, HostPciNode, "reg", &DataSize); + if ((Data == NULL) || + (DataSize != ((AddressCells + SizeCells) * sizeof (UINT32)))) + { + // If error or wrong size. + ASSERT (0); + return EFI_ABORTED; + } + + // Base address + if (AddressCells == 2) { + PciInfo->PciConfigSpaceInfo.BaseAddress = fdt64_to_cpu (*(UINT64 *)Data); + } else { + PciInfo->PciConfigSpaceInfo.BaseAddress = fdt32_to_cpu (*(UINT32 *)Data); + } + + // Address map + Status = ParseAddressMap ( + Fdt, + HostPciNode, + AddressCells, + PciInfo + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Irq map + Status = ParseIrqMap ( + Fdt, + HostPciNode, + PciInfo + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + ASSERT (0); + } + + return EFI_SUCCESS; +} + +/** Add the parsed Pci information to the Configuration Manager. + + CmObj of the following types are concerned: + - EArchCommonObjPciConfigSpaceInfo + - EArchCommonObjPciAddressMapInfo + - EArchCommonObjPciInterruptMapInfo + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] PciTableInfo PCI_PARSER_TABLE structure containing the + CmObjs to add. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES An allocation has failed. +**/ +STATIC +EFI_STATUS +EFIAPI +PciInfoAdd ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN PCI_PARSER_TABLE *PciTableInfo + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo; + + if ((FdtParserHandle == NULL) || + (PciTableInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + PciConfigSpaceInfo = &PciTableInfo->PciConfigSpaceInfo; + + // Add the address map space CmObj to the Configuration Manager. + Status = AddMultipleCmObjWithCmObjRef ( + FdtParserHandle, + &PciTableInfo->Mapping[PciMappingTableAddress], + &PciConfigSpaceInfo->AddressMapToken + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add the interrupt map space CmObj to the Configuration Manager. + // Possible to have no legacy interrupts, or no device described and + // thus no interrupt-mapping. + if (PciTableInfo->Mapping[PciMappingTableInterrupt].Count != 0) { + Status = AddMultipleCmObjWithCmObjRef ( + FdtParserHandle, + &PciTableInfo->Mapping[PciMappingTableInterrupt], + &PciConfigSpaceInfo->InterruptMapToken + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } + + // Add the configuration space CmObj to the Configuration Manager. + Status = AddSingleCmObj ( + FdtParserHandle, + CREATE_CM_ARCH_COMMON_OBJECT_ID ( + EArchCommonObjPciConfigSpaceInfo + ), + &PciTableInfo->PciConfigSpaceInfo, + sizeof (CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO), + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Free the CmObjDesc of the ParserTable. + + @param [in] PciTableInfo PCI_PARSER_TABLE structure containing the + CmObjs to free. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeParserTable ( + IN PCI_PARSER_TABLE *PciTableInfo + ) +{ + UINT32 Index; + VOID *Data; + + if (PciTableInfo == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + for (Index = 0; Index < PciMappingTableMax; Index++) { + Data = PciTableInfo->Mapping[Index].Data; + if (Data != NULL) { + FreePool (Data); + } + } + + return EFI_SUCCESS; +} + +/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function. + + The following structure is populated: + typedef struct CmArchCommonPciConfigSpaceInfo { + UINT64 BaseAddress; // {Populated} + UINT16 PciSegmentGroupNumber; // {Populated} + UINT8 StartBusNumber; // {Populated} + UINT8 EndBusNumber; // {Populated} + } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; + + typedef struct CmArchCommonPciAddressMapInfo { + UINT8 SpaceCode; // {Populated} + UINT64 PciAddress; // {Populated} + UINT64 CpuAddress; // {Populated} + UINT64 AddressSize; // {Populated} + } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; + + typedef struct CmArchCommonPciInterruptMapInfo { + UINT8 PciBus; // {Populated} + UINT8 PciDevice; // {Populated} + UINT8 PciInterrupt; // {Populated} + CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} + } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +PciConfigInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + UINT32 Index; + INT32 PciNode; + UINT32 PciNodeCount; + PCI_PARSER_TABLE PciTableInfo; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + // Only search host-pci devices. + // PCI Firmware Specification Revision 3.0, s4.1.2. "MCFG Table Description": + // "This table directly refers to PCI Segment Groups defined in the system + // via the _SEG object in the ACPI name space for the applicable host bridge + // device." + Status = FdtCountCompatNodeInBranch ( + Fdt, + FdtBranch, + &PciCompatibleInfo, + &PciNodeCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (PciNodeCount == 0) { + return EFI_NOT_FOUND; + } + + // Parse each host-pci node in the branch. + PciNode = FdtBranch; + for (Index = 0; Index < PciNodeCount; Index++) { + ZeroMem (&PciTableInfo, sizeof (PCI_PARSER_TABLE)); + + Status = FdtGetNextCompatNodeInBranch ( + Fdt, + FdtBranch, + &PciCompatibleInfo, + &PciNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + Status = PciNodeParser (Fdt, PciNode, &PciTableInfo); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto error_handler; + } + + // Add Pci information to the Configuration Manager. + Status = PciInfoAdd (FdtParserHandle, &PciTableInfo); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto error_handler; + } + + Status = FreeParserTable (&PciTableInfo); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + } // for + + return Status; + +error_handler: + FreeParserTable (&PciTableInfo); + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h new file mode 100644 index 0000000000..aeffe7ac35 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h @@ -0,0 +1,143 @@ +/** @file + PCI Configuration Space Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml + - PCI Firmware Specification - Revision 3.0 + - Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9 + - Devicetree Specification Release v0.3 + - linux kernel code +**/ + +#ifndef PCI_CONFIG_SPACE_PARSER_H_ +#define PCI_CONFIG_SPACE_PARSER_H_ + +/** Read LEN bits at OFF offsets bits of the ADDR. + + @param [in] ADDR Address to read the bits from. + @param [in] OFF Offset of the bits to read. + @param [in] LEN Number of bits to read. + + @return The bits read. +**/ +#define READ_BITS(ADDR, OFF, LEN) (((ADDR) >> (OFF)) & ((1<<(LEN))-1)) + +/* Pci address attributes. +*/ +/// 0 if relocatable. +#define READ_PCI_N(ADDR) READ_BITS((ADDR), 31, 1) +/// 1 if prefetchable. +#define READ_PCI_P(ADDR) READ_BITS((ADDR), 30, 1) +/// 1 if aliased. +#define READ_PCI_T(ADDR) READ_BITS((ADDR), 29, 1) + +/** Space code. + + 00: Configuration Space + 01: I/O Space + 10: 32-bit-address Memory Space + 11: 64-bit-address Memory Space +*/ +#define READ_PCI_SS(ADDR) READ_BITS((ADDR), 24, 2) +/// Bus number. +#define READ_PCI_BBBBBBBB(ADDR) READ_BITS((ADDR), 16, 8) +/// Device number. +#define READ_PCI_DDDDD(ADDR) READ_BITS((ADDR), 11, 5) + +/** Number of device-tree cells used for PCI nodes properties. + + Values are well defined, except the "#interrupt-cells" which + is assumed to be 1. +*/ +#define PCI_ADDRESS_CELLS 3U +#define PCI_SIZE_CELLS 2U +#define PCI_INTERRUPTS_CELLS 1U + +/** PCI interrupt flags for device-tree. + + Local Bus Specification Revision 3.0, s2.2.6., Interrupt Pins: + - 'Interrupts on PCI are optional and defined as "level sensitive," + asserted low (negative true)' +*/ +#define DT_PCI_IRQ_FLAGS(x) (((x) & 0xF) == BIT0) + +/** Indexes in the mapping table. +*/ +typedef enum PciMappingTable { + PciMappingTableAddress, ///< 0 - Address mapping + PciMappingTableInterrupt, ///< 1 - Interrupt mapping + PciMappingTableMax, ///< 2 - Max +} PCI_MAPPING_TABLE; + +#pragma pack(1) + +/** PCI parser table + + Multiple address-map and interrupt map can correspond to + one host-pci device. This structure allows to temporarily + store the CmObjects created and generate tokens once + the whole device tree is parsed. +*/ +typedef struct PciParserTable { + /// PCI Configuration Space Info + CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo; + + /// Store the address mapping and interrupt mapping as CmObjDesc + /// before adding them to the Configuration Manager. + CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax]; +} PCI_PARSER_TABLE; + +#pragma pack() + +/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function. + + The following structure is populated: + typedef struct CmArchCommonPciConfigSpaceInfo { + UINT64 BaseAddress; // {Populated} + UINT16 PciSegmentGroupNumber; // {Populated} + UINT8 StartBusNumber; // {Populated} + UINT8 EndBusNumber; // {Populated} + } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO; + + typedef struct CmArchCommonPciAddressMapInfo { + UINT8 SpaceCode; // {Populated} + UINT64 PciAddress; // {Populated} + UINT64 CpuAddress; // {Populated} + UINT64 AddressSize; // {Populated} + } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO; + + typedef struct CmArchCommonPciInterruptMapInfo { + UINT8 PciBus; // {Populated} + UINT8 PciDevice; // {Populated} + UINT8 PciInterrupt; // {Populated} + CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated} + } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +PciConfigInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // PCI_CONFIG_SPACE_PARSER_H_ -- cgit From a7cc72c36010a939eb5eaba7fb03cdab476de0f6 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Make Serial Port parser arch neutral To allow other architectures to potentially re-use the serial port parser and make the code arch neutral, remove the Arm prefixes. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c | 2 +- .../FdtHwInfoParserLib/FdtHwInfoParserLib.inf | 4 +- .../Serial/ArmSerialPortParser.c | 634 --------------------- .../Serial/ArmSerialPortParser.h | 47 -- .../FdtHwInfoParserLib/Serial/SerialPortParser.c | 634 +++++++++++++++++++++ .../FdtHwInfoParserLib/Serial/SerialPortParser.h | 47 ++ 6 files changed, 684 insertions(+), 684 deletions(-) delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c delete mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c index 49a7636dad..2c9105ed10 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c @@ -10,7 +10,7 @@ #include "Arm/GenericTimer/ArmGenericTimerParser.h" #include "Arm/Gic/ArmGicDispatcher.h" #include "Pci/PciConfigSpaceParser.h" -#include "Serial/ArmSerialPortParser.h" +#include "Serial/SerialPortParser.h" /** Ordered table of parsers/dispatchers. diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf index 55ec7d97fa..d3010af527 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf @@ -24,8 +24,8 @@ FdtUtility.h Pci/PciConfigSpaceParser.c Pci/PciConfigSpaceParser.h - Serial/ArmSerialPortParser.c - Serial/ArmSerialPortParser.h + Serial/SerialPortParser.c + Serial/SerialPortParser.h [Sources.ARM, Sources.AARCH64] Arm/ArmFdtHwInfoParser.c diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c deleted file mode 100644 index f17ad2e842..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c +++ /dev/null @@ -1,634 +0,0 @@ -/** @file - Arm Serial Port Parser. - - Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/serial/serial.yaml - - linux/Documentation/devicetree/bindings/serial/8250.txt - - linux/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt - - linux/Documentation/devicetree/bindings/serial/pl011.yaml -**/ - -#include - -#include "CmObjectDescUtility.h" -#include "FdtHwInfoParser.h" -#include "Serial/ArmSerialPortParser.h" - -/** List of "compatible" property values for serial port nodes. - - Any other "compatible" value is not supported by this module. -*/ -STATIC CONST COMPATIBILITY_STR SerialCompatibleStr[] = { - { "ns16550a" }, - { "arm,sbsa-uart" }, - { "arm,pl011" } -}; - -/** COMPATIBILITY_INFO structure for the SerialCompatible. -*/ -CONST COMPATIBILITY_INFO SerialCompatibleInfo = { - ARRAY_SIZE (SerialCompatibleStr), - SerialCompatibleStr -}; - -/** 16550 UART compatible strings. - - Any string of this list must be part of SerialCompatible. -*/ -STATIC CONST COMPATIBILITY_STR Serial16550CompatibleStr[] = { - { "ns16550a" } -}; - -/** COMPATIBILITY_INFO structure for the Serial16550Compatible. -*/ -CONST COMPATIBILITY_INFO Serial16550CompatibleInfo = { - ARRAY_SIZE (Serial16550CompatibleStr), - Serial16550CompatibleStr -}; - -/** SBSA UART compatible strings. - - Include PL011 as SBSA uart is a subset of PL011. - - Any string of this list must be part of SerialCompatible. -*/ -STATIC CONST COMPATIBILITY_STR SerialSbsaCompatibleStr[] = { - { "arm,sbsa-uart" }, - { "arm,pl011" } -}; - -/** COMPATIBILITY_INFO structure for the SerialSbsaCompatible. -*/ -CONST COMPATIBILITY_INFO SerialSbsaCompatibleInfo = { - ARRAY_SIZE (SerialSbsaCompatibleStr), - SerialSbsaCompatibleStr -}; - -/** Parse a serial port node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [in] SerialPortNode Offset of a serial-port node. - @param [in] SerialPortInfo The CM_ARCH_COMMON_SERIAL_PORT_INFO to populate. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED Unsupported. -**/ -STATIC -EFI_STATUS -EFIAPI -SerialPortNodeParser ( - IN CONST VOID *Fdt, - IN INT32 SerialPortNode, - IN CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo - ) -{ - EFI_STATUS Status; - INT32 IntcNode; - CONST UINT8 *SizeValue; - - INT32 AddressCells; - INT32 SizeCells; - INT32 IntCells; - - CONST UINT8 *Data; - INT32 DataSize; - UINT8 AccessSize; - - if ((Fdt == NULL) || - (SerialPortInfo == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Status = FdtGetParentAddressInfo ( - Fdt, - SerialPortNode, - &AddressCells, - &SizeCells - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Don't support more than 64 bits and less than 32 bits addresses. - if ((AddressCells < 1) || - (AddressCells > 2) || - (SizeCells < 1) || - (SizeCells > 2)) - { - ASSERT (0); - return EFI_ABORTED; - } - - Data = fdt_getprop (Fdt, SerialPortNode, "reg", &DataSize); - if ((Data == NULL) || - (DataSize < (INT32)(sizeof (UINT32) * - GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells)) - 1)) - { - // If error or not enough space. - ASSERT (0); - return EFI_ABORTED; - } - - if (AddressCells == 2) { - SerialPortInfo->BaseAddress = fdt64_to_cpu (*(UINT64 *)Data); - } else { - SerialPortInfo->BaseAddress = fdt32_to_cpu (*(UINT32 *)Data); - } - - SizeValue = Data + (sizeof (UINT32) * - GET_DT_REG_SIZE_OFFSET (0, AddressCells, SizeCells)); - if (SizeCells == 2) { - SerialPortInfo->BaseAddressLength = fdt64_to_cpu (*(UINT64 *)SizeValue); - } else { - SerialPortInfo->BaseAddressLength = fdt32_to_cpu (*(UINT32 *)SizeValue); - } - - // Get the associated interrupt-controller. - Status = FdtGetIntcParentNode (Fdt, SerialPortNode, &IntcNode); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - return Status; - } - - // Get the number of cells used to encode an interrupt. - Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Data = fdt_getprop (Fdt, SerialPortNode, "interrupts", &DataSize); - if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) { - // If error or not 1 interrupt. - ASSERT (0); - return EFI_ABORTED; - } - - SerialPortInfo->Interrupt = FdtGetInterruptId ((CONST UINT32 *)Data); - - // Note: clock-frequency is optional for SBSA UART. - Data = fdt_getprop (Fdt, SerialPortNode, "clock-frequency", &DataSize); - if (Data != NULL) { - if (DataSize < sizeof (UINT32)) { - // If error or not enough space. - ASSERT (0); - return EFI_ABORTED; - } else if (fdt_node_offset_by_phandle (Fdt, fdt32_to_cpu (*Data)) >= 0) { - // "clock-frequency" can be a "clocks phandle to refer to the clk used". - // This is not supported. - ASSERT (0); - return EFI_UNSUPPORTED; - } - - SerialPortInfo->Clock = fdt32_to_cpu (*(UINT32 *)Data); - } - - if (FdtNodeIsCompatible (Fdt, SerialPortNode, &Serial16550CompatibleInfo)) { - SerialPortInfo->PortSubtype = - EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS; - - /* reg-io-width: - description: | - The size (in bytes) of the IO accesses that should be performed on the - device. There are some systems that require 32-bit accesses to the - UART. - */ - Data = fdt_getprop (Fdt, SerialPortNode, "reg-io-width", &DataSize); - if (Data != NULL) { - if (DataSize < sizeof (UINT32)) { - // If error or not enough space. - ASSERT (0); - return EFI_ABORTED; - } - - AccessSize = fdt32_to_cpu (*(UINT32 *)Data); - if (AccessSize > EFI_ACPI_6_3_QWORD) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - SerialPortInfo->AccessSize = AccessSize; - } else { - // 8250/16550 defaults to byte access. - SerialPortInfo->AccessSize = EFI_ACPI_6_3_BYTE; - } - } else if (FdtNodeIsCompatible ( - Fdt, - SerialPortNode, - &SerialSbsaCompatibleInfo - )) - { - SerialPortInfo->PortSubtype = - EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART; - } else { - ASSERT (0); - return EFI_UNSUPPORTED; - } - - // Set Baudrate to 115200 by default - SerialPortInfo->BaudRate = 115200; - return EFI_SUCCESS; -} - -/** Find the console serial-port node in the DT. - - This function fetches the node referenced in the "stdout-path" - property of the "chosen" node. - - @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). - @param [out] SerialConsoleNode If success, contains the node offset - of the console serial-port node. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. -**/ -STATIC -EFI_STATUS -EFIAPI -GetSerialConsoleNode ( - IN CONST VOID *Fdt, - OUT INT32 *SerialConsoleNode - ) -{ - CONST CHAR8 *Prop; - INT32 PropSize; - CONST CHAR8 *Path; - INT32 PathLen; - INT32 ChosenNode; - - if ((Fdt == NULL) || - (SerialConsoleNode == NULL)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // The "chosen" node resides at the root of the DT. Fetch it. - ChosenNode = fdt_path_offset (Fdt, "/chosen"); - if (ChosenNode < 0) { - return EFI_NOT_FOUND; - } - - Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize); - if ((Prop == NULL) || (PropSize < 0)) { - return EFI_NOT_FOUND; - } - - // Determine the actual path length, as a colon terminates the path. - Path = ScanMem8 (Prop, PropSize, ':'); - if (Path == NULL) { - PathLen = (UINT32)AsciiStrLen (Prop); - } else { - PathLen = (INT32)(Path - Prop); - } - - // Aliases cannot start with a '/', so it must be the actual path. - if (Prop[0] == '/') { - *SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen); - return EFI_SUCCESS; - } - - // Lookup the alias, as this contains the actual path. - Path = fdt_get_alias_namelen (Fdt, Prop, PathLen); - if (Path == NULL) { - return EFI_NOT_FOUND; - } - - *SerialConsoleNode = fdt_path_offset (Fdt, Path); - return EFI_SUCCESS; -} - -/** CM_ARCH_COMMON_SERIAL_PORT_INFO dispatcher function (for a generic serial-port). - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] GenericSerialInfo Pointer to a serial port info list. - @param [in] NodeCount Count of serial ports to dispatch. - @param [in] SerialObjectId Serial port object ID. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -STATIC -EFI_STATUS -EFIAPI -ArmSerialPortInfoDispatch ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo, - IN INT32 NodeCount, - IN EARCH_COMMON_OBJECT_ID SerialObjectId - ) -{ - EFI_STATUS Status; - CM_OBJ_DESCRIPTOR *NewCmObjDesc; - - if ((GenericSerialInfo == NULL) || (NodeCount == 0)) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - if ((SerialObjectId != EArchCommonObjSerialPortInfo) && - (SerialObjectId != EArchCommonObjSerialDebugPortInfo) && - (SerialObjectId != EArchCommonObjConsolePortInfo)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Dispatch the Generic Serial ports - Status = CreateCmObjDesc ( - CREATE_CM_ARCH_COMMON_OBJECT_ID (SerialObjectId), - NodeCount, - GenericSerialInfo, - sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) * NodeCount, - &NewCmObjDesc - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - // Add all the CmObjs to the Configuration Manager. - Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL); - ASSERT_EFI_ERROR (Status); - FreeCmObjDesc (NewCmObjDesc); - return Status; -} - -/** CM_ARCH_COMMON_SERIAL_PORT_INFO parser function (for debug/console serial-port). - - This parser expects FdtBranch to be the debug serial-port node. - At most one CmObj is created. - The following structure is populated: - typedef struct EArchCommonSerialPortInfo { - UINT64 BaseAddress; // {Populated} - UINT32 Interrupt; // {Populated} - UINT64 BaudRate; // {default} - UINT32 Clock; // {Populated} - UINT16 PortSubtype; // {Populated} - UINT64 BaseAddressLength // {Populated} - } CM_ARCH_COMMON_SERIAL_PORT_INFO; - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - @param [in] SerialObjectId ArchCommon Namespace Object ID for the serial - port. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -STATIC -EFI_STATUS -EFIAPI -ArmSerialPortInfoParser ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch, - IN EARCH_COMMON_OBJECT_ID SerialObjectId - ) -{ - EFI_STATUS Status; - CM_ARCH_COMMON_SERIAL_PORT_INFO SerialInfo; - - if ((SerialObjectId != EArchCommonObjSerialDebugPortInfo) && - (SerialObjectId != EArchCommonObjConsolePortInfo)) - { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - ZeroMem (&SerialInfo, sizeof (SerialInfo)); - - Status = SerialPortNodeParser ( - FdtParserHandle->Fdt, - FdtBranch, - &SerialInfo - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - Status = ArmSerialPortInfoDispatch ( - FdtParserHandle, - &SerialInfo, - 1, - SerialObjectId - ); - ASSERT_EFI_ERROR (Status); - return Status; -} - -/** SerialPort dispatcher. - - This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for - the following CM_OBJ_ID: - - EArchCommonObjConsolePortInfo - - EArchCommonObjSerialDebugPortInfo - - EArchCommonObjSerialPortInfo - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -SerialPortDispatcher ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ) -{ - EFI_STATUS Status; - INT32 SerialConsoleNode; - INT32 SerialDebugNode; - INT32 SerialNode; - UINT32 Index; - UINT32 SerialNodeCount; - UINT32 SerialNodesRemaining; - CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo; - UINT32 GenericSerialIndex; - VOID *Fdt; - - if (FdtParserHandle == NULL) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - Fdt = FdtParserHandle->Fdt; - - // Count the number of serial-ports. - Status = FdtCountCompatNodeInBranch ( - Fdt, - FdtBranch, - &SerialCompatibleInfo, - &SerialNodeCount - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - if (SerialNodeCount == 0) { - return EFI_NOT_FOUND; - } - - // Track remaining nodes separately as SerialNodeCount - // is used in for loop below and reducing SerialNodeCount - // would result in the Generic Serial port nodes not - // being found if the serial console port node is among - // the first few serial nodes. - SerialNodesRemaining = SerialNodeCount; - - // Identify the serial console port. - Status = GetSerialConsoleNode (Fdt, &SerialConsoleNode); - if (Status == EFI_NOT_FOUND) { - // No serial console. - SerialConsoleNode = -1; - } else if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } else { - // Parse the console serial-port. - Status = ArmSerialPortInfoParser ( - FdtParserHandle, - SerialConsoleNode, - EArchCommonObjConsolePortInfo - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - return Status; - } - - SerialNodesRemaining--; - } - - GenericSerialInfo = NULL; - if (SerialNodesRemaining > 1) { - // We have more than one serial port remaining. - // This means that the first serial port will - // be reserved as a debug port, and the remaining - // will be for general purpose use. - SerialNodesRemaining--; - GenericSerialInfo = AllocateZeroPool ( - SerialNodesRemaining * - sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) - ); - if (GenericSerialInfo == NULL) { - ASSERT (0); - return EFI_OUT_OF_RESOURCES; - } - } - - SerialNode = FdtBranch; - SerialDebugNode = -1; - GenericSerialIndex = 0; - for (Index = 0; Index < SerialNodeCount; Index++) { - // Search the next serial-port node in the branch. - Status = FdtGetNextCompatNodeInBranch ( - Fdt, - FdtBranch, - &SerialCompatibleInfo, - &SerialNode - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - if (Status == EFI_NOT_FOUND) { - // Should have found the node. - Status = EFI_ABORTED; - } - - goto exit_handler; - } - - // Ignore the serial console node. - if (SerialNode == SerialConsoleNode) { - continue; - } else if (SerialDebugNode == -1) { - // The first serial-port node, not being the console serial-port, - // will be the debug serial-port. - SerialDebugNode = SerialNode; - Status = ArmSerialPortInfoParser ( - FdtParserHandle, - SerialDebugNode, - EArchCommonObjSerialDebugPortInfo - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - } else { - if (GenericSerialInfo == NULL) { - // Should not be possible. - ASSERT (0); - Status = EFI_ABORTED; - goto exit_handler; - } - - Status = SerialPortNodeParser ( - Fdt, - SerialNode, - &GenericSerialInfo[GenericSerialIndex++] - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - goto exit_handler; - } - } - } // for - - if (GenericSerialIndex > 0) { - Status = ArmSerialPortInfoDispatch ( - FdtParserHandle, - GenericSerialInfo, - GenericSerialIndex, - EArchCommonObjSerialPortInfo - ); - } - -exit_handler: - if (GenericSerialInfo != NULL) { - FreePool (GenericSerialInfo); - } - - return Status; -} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h deleted file mode 100644 index 037c409d45..0000000000 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h +++ /dev/null @@ -1,47 +0,0 @@ -/** @file - Arm Serial Port Parser. - - Copyright (c) 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - linux/Documentation/devicetree/bindings/serial/serial.yaml - - linux/Documentation/devicetree/bindings/serial/8250.txt -**/ - -#ifndef ARM_SERIAL_PORT_PARSER_H_ -#define ARM_SERIAL_PORT_PARSER_H_ - -/** SerialPort dispatcher. - - This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for - the following CM_OBJ_ID: - - EArchCommonObjConsolePortInfo - - EArchCommonObjSerialDebugPortInfo - - EArchCommonObjSerialPortInfo - - A parser parses a Device Tree to populate a specific CmObj type. None, - one or many CmObj can be created by the parser. - The created CmObj are then handed to the parser's caller through the - HW_INFO_ADD_OBJECT interface. - This can also be a dispatcher. I.e. a function that not parsing a - Device Tree but calling other parsers. - - @param [in] FdtParserHandle A handle to the parser instance. - @param [in] FdtBranch When searching for DT node name, restrict - the search to this Device Tree branch. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ABORTED An error occurred. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND Not found. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -SerialPortDispatcher ( - IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, - IN INT32 FdtBranch - ); - -#endif // ARM_SERIAL_PORT_PARSER_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c new file mode 100644 index 0000000000..2d0dccea3d --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c @@ -0,0 +1,634 @@ +/** @file + Serial Port Parser. + + Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/serial/serial.yaml + - linux/Documentation/devicetree/bindings/serial/8250.txt + - linux/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt + - linux/Documentation/devicetree/bindings/serial/pl011.yaml +**/ + +#include + +#include "CmObjectDescUtility.h" +#include "FdtHwInfoParser.h" +#include "Serial/SerialPortParser.h" + +/** List of "compatible" property values for serial port nodes. + + Any other "compatible" value is not supported by this module. +*/ +STATIC CONST COMPATIBILITY_STR SerialCompatibleStr[] = { + { "ns16550a" }, + { "arm,sbsa-uart" }, + { "arm,pl011" } +}; + +/** COMPATIBILITY_INFO structure for the SerialCompatible. +*/ +CONST COMPATIBILITY_INFO SerialCompatibleInfo = { + ARRAY_SIZE (SerialCompatibleStr), + SerialCompatibleStr +}; + +/** 16550 UART compatible strings. + + Any string of this list must be part of SerialCompatible. +*/ +STATIC CONST COMPATIBILITY_STR Serial16550CompatibleStr[] = { + { "ns16550a" } +}; + +/** COMPATIBILITY_INFO structure for the Serial16550Compatible. +*/ +CONST COMPATIBILITY_INFO Serial16550CompatibleInfo = { + ARRAY_SIZE (Serial16550CompatibleStr), + Serial16550CompatibleStr +}; + +/** SBSA UART compatible strings. + + Include PL011 as SBSA uart is a subset of PL011. + + Any string of this list must be part of SerialCompatible. +*/ +STATIC CONST COMPATIBILITY_STR SerialSbsaCompatibleStr[] = { + { "arm,sbsa-uart" }, + { "arm,pl011" } +}; + +/** COMPATIBILITY_INFO structure for the SerialSbsaCompatible. +*/ +CONST COMPATIBILITY_INFO SerialSbsaCompatibleInfo = { + ARRAY_SIZE (SerialSbsaCompatibleStr), + SerialSbsaCompatibleStr +}; + +/** Parse a serial port node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [in] SerialPortNode Offset of a serial-port node. + @param [in] SerialPortInfo The CM_ARCH_COMMON_SERIAL_PORT_INFO to populate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Unsupported. +**/ +STATIC +EFI_STATUS +EFIAPI +SerialPortNodeParser ( + IN CONST VOID *Fdt, + IN INT32 SerialPortNode, + IN CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo + ) +{ + EFI_STATUS Status; + INT32 IntcNode; + CONST UINT8 *SizeValue; + + INT32 AddressCells; + INT32 SizeCells; + INT32 IntCells; + + CONST UINT8 *Data; + INT32 DataSize; + UINT8 AccessSize; + + if ((Fdt == NULL) || + (SerialPortInfo == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Status = FdtGetParentAddressInfo ( + Fdt, + SerialPortNode, + &AddressCells, + &SizeCells + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Don't support more than 64 bits and less than 32 bits addresses. + if ((AddressCells < 1) || + (AddressCells > 2) || + (SizeCells < 1) || + (SizeCells > 2)) + { + ASSERT (0); + return EFI_ABORTED; + } + + Data = fdt_getprop (Fdt, SerialPortNode, "reg", &DataSize); + if ((Data == NULL) || + (DataSize < (INT32)(sizeof (UINT32) * + GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells)) - 1)) + { + // If error or not enough space. + ASSERT (0); + return EFI_ABORTED; + } + + if (AddressCells == 2) { + SerialPortInfo->BaseAddress = fdt64_to_cpu (*(UINT64 *)Data); + } else { + SerialPortInfo->BaseAddress = fdt32_to_cpu (*(UINT32 *)Data); + } + + SizeValue = Data + (sizeof (UINT32) * + GET_DT_REG_SIZE_OFFSET (0, AddressCells, SizeCells)); + if (SizeCells == 2) { + SerialPortInfo->BaseAddressLength = fdt64_to_cpu (*(UINT64 *)SizeValue); + } else { + SerialPortInfo->BaseAddressLength = fdt32_to_cpu (*(UINT32 *)SizeValue); + } + + // Get the associated interrupt-controller. + Status = FdtGetIntcParentNode (Fdt, SerialPortNode, &IntcNode); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + return Status; + } + + // Get the number of cells used to encode an interrupt. + Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Data = fdt_getprop (Fdt, SerialPortNode, "interrupts", &DataSize); + if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) { + // If error or not 1 interrupt. + ASSERT (0); + return EFI_ABORTED; + } + + SerialPortInfo->Interrupt = FdtGetInterruptId ((CONST UINT32 *)Data); + + // Note: clock-frequency is optional for SBSA UART. + Data = fdt_getprop (Fdt, SerialPortNode, "clock-frequency", &DataSize); + if (Data != NULL) { + if (DataSize < sizeof (UINT32)) { + // If error or not enough space. + ASSERT (0); + return EFI_ABORTED; + } else if (fdt_node_offset_by_phandle (Fdt, fdt32_to_cpu (*Data)) >= 0) { + // "clock-frequency" can be a "clocks phandle to refer to the clk used". + // This is not supported. + ASSERT (0); + return EFI_UNSUPPORTED; + } + + SerialPortInfo->Clock = fdt32_to_cpu (*(UINT32 *)Data); + } + + if (FdtNodeIsCompatible (Fdt, SerialPortNode, &Serial16550CompatibleInfo)) { + SerialPortInfo->PortSubtype = + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS; + + /* reg-io-width: + description: | + The size (in bytes) of the IO accesses that should be performed on the + device. There are some systems that require 32-bit accesses to the + UART. + */ + Data = fdt_getprop (Fdt, SerialPortNode, "reg-io-width", &DataSize); + if (Data != NULL) { + if (DataSize < sizeof (UINT32)) { + // If error or not enough space. + ASSERT (0); + return EFI_ABORTED; + } + + AccessSize = fdt32_to_cpu (*(UINT32 *)Data); + if (AccessSize > EFI_ACPI_6_3_QWORD) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + SerialPortInfo->AccessSize = AccessSize; + } else { + // 8250/16550 defaults to byte access. + SerialPortInfo->AccessSize = EFI_ACPI_6_3_BYTE; + } + } else if (FdtNodeIsCompatible ( + Fdt, + SerialPortNode, + &SerialSbsaCompatibleInfo + )) + { + SerialPortInfo->PortSubtype = + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART; + } else { + ASSERT (0); + return EFI_UNSUPPORTED; + } + + // Set Baudrate to 115200 by default + SerialPortInfo->BaudRate = 115200; + return EFI_SUCCESS; +} + +/** Find the console serial-port node in the DT. + + This function fetches the node referenced in the "stdout-path" + property of the "chosen" node. + + @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). + @param [out] SerialConsoleNode If success, contains the node offset + of the console serial-port node. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. +**/ +STATIC +EFI_STATUS +EFIAPI +GetSerialConsoleNode ( + IN CONST VOID *Fdt, + OUT INT32 *SerialConsoleNode + ) +{ + CONST CHAR8 *Prop; + INT32 PropSize; + CONST CHAR8 *Path; + INT32 PathLen; + INT32 ChosenNode; + + if ((Fdt == NULL) || + (SerialConsoleNode == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // The "chosen" node resides at the root of the DT. Fetch it. + ChosenNode = fdt_path_offset (Fdt, "/chosen"); + if (ChosenNode < 0) { + return EFI_NOT_FOUND; + } + + Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize); + if ((Prop == NULL) || (PropSize < 0)) { + return EFI_NOT_FOUND; + } + + // Determine the actual path length, as a colon terminates the path. + Path = ScanMem8 (Prop, PropSize, ':'); + if (Path == NULL) { + PathLen = (UINT32)AsciiStrLen (Prop); + } else { + PathLen = (INT32)(Path - Prop); + } + + // Aliases cannot start with a '/', so it must be the actual path. + if (Prop[0] == '/') { + *SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen); + return EFI_SUCCESS; + } + + // Lookup the alias, as this contains the actual path. + Path = fdt_get_alias_namelen (Fdt, Prop, PathLen); + if (Path == NULL) { + return EFI_NOT_FOUND; + } + + *SerialConsoleNode = fdt_path_offset (Fdt, Path); + return EFI_SUCCESS; +} + +/** CM_ARCH_COMMON_SERIAL_PORT_INFO dispatcher function (for a generic serial-port). + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] GenericSerialInfo Pointer to a serial port info list. + @param [in] NodeCount Count of serial ports to dispatch. + @param [in] SerialObjectId Serial port object ID. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +STATIC +EFI_STATUS +EFIAPI +SerialPortInfoDispatch ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo, + IN INT32 NodeCount, + IN EARCH_COMMON_OBJECT_ID SerialObjectId + ) +{ + EFI_STATUS Status; + CM_OBJ_DESCRIPTOR *NewCmObjDesc; + + if ((GenericSerialInfo == NULL) || (NodeCount == 0)) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if ((SerialObjectId != EArchCommonObjSerialPortInfo) && + (SerialObjectId != EArchCommonObjSerialDebugPortInfo) && + (SerialObjectId != EArchCommonObjConsolePortInfo)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Dispatch the Generic Serial ports + Status = CreateCmObjDesc ( + CREATE_CM_ARCH_COMMON_OBJECT_ID (SerialObjectId), + NodeCount, + GenericSerialInfo, + sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) * NodeCount, + &NewCmObjDesc + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + // Add all the CmObjs to the Configuration Manager. + Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL); + ASSERT_EFI_ERROR (Status); + FreeCmObjDesc (NewCmObjDesc); + return Status; +} + +/** CM_ARCH_COMMON_SERIAL_PORT_INFO parser function (for debug/console serial-port). + + This parser expects FdtBranch to be the debug serial-port node. + At most one CmObj is created. + The following structure is populated: + typedef struct EArchCommonSerialPortInfo { + UINT64 BaseAddress; // {Populated} + UINT32 Interrupt; // {Populated} + UINT64 BaudRate; // {default} + UINT32 Clock; // {Populated} + UINT16 PortSubtype; // {Populated} + UINT64 BaseAddressLength // {Populated} + } CM_ARCH_COMMON_SERIAL_PORT_INFO; + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + @param [in] SerialObjectId ArchCommon Namespace Object ID for the serial + port. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +STATIC +EFI_STATUS +EFIAPI +SerialPortInfoParser ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch, + IN EARCH_COMMON_OBJECT_ID SerialObjectId + ) +{ + EFI_STATUS Status; + CM_ARCH_COMMON_SERIAL_PORT_INFO SerialInfo; + + if ((SerialObjectId != EArchCommonObjSerialDebugPortInfo) && + (SerialObjectId != EArchCommonObjConsolePortInfo)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&SerialInfo, sizeof (SerialInfo)); + + Status = SerialPortNodeParser ( + FdtParserHandle->Fdt, + FdtBranch, + &SerialInfo + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + Status = SerialPortInfoDispatch ( + FdtParserHandle, + &SerialInfo, + 1, + SerialObjectId + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** SerialPort dispatcher. + + This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for + the following CM_OBJ_ID: + - EArchCommonObjConsolePortInfo + - EArchCommonObjSerialDebugPortInfo + - EArchCommonObjSerialPortInfo + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +SerialPortDispatcher ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ) +{ + EFI_STATUS Status; + INT32 SerialConsoleNode; + INT32 SerialDebugNode; + INT32 SerialNode; + UINT32 Index; + UINT32 SerialNodeCount; + UINT32 SerialNodesRemaining; + CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo; + UINT32 GenericSerialIndex; + VOID *Fdt; + + if (FdtParserHandle == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + Fdt = FdtParserHandle->Fdt; + + // Count the number of serial-ports. + Status = FdtCountCompatNodeInBranch ( + Fdt, + FdtBranch, + &SerialCompatibleInfo, + &SerialNodeCount + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + if (SerialNodeCount == 0) { + return EFI_NOT_FOUND; + } + + // Track remaining nodes separately as SerialNodeCount + // is used in for loop below and reducing SerialNodeCount + // would result in the Generic Serial port nodes not + // being found if the serial console port node is among + // the first few serial nodes. + SerialNodesRemaining = SerialNodeCount; + + // Identify the serial console port. + Status = GetSerialConsoleNode (Fdt, &SerialConsoleNode); + if (Status == EFI_NOT_FOUND) { + // No serial console. + SerialConsoleNode = -1; + } else if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } else { + // Parse the console serial-port. + Status = SerialPortInfoParser ( + FdtParserHandle, + SerialConsoleNode, + EArchCommonObjConsolePortInfo + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + SerialNodesRemaining--; + } + + GenericSerialInfo = NULL; + if (SerialNodesRemaining > 1) { + // We have more than one serial port remaining. + // This means that the first serial port will + // be reserved as a debug port, and the remaining + // will be for general purpose use. + SerialNodesRemaining--; + GenericSerialInfo = AllocateZeroPool ( + SerialNodesRemaining * + sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) + ); + if (GenericSerialInfo == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + } + + SerialNode = FdtBranch; + SerialDebugNode = -1; + GenericSerialIndex = 0; + for (Index = 0; Index < SerialNodeCount; Index++) { + // Search the next serial-port node in the branch. + Status = FdtGetNextCompatNodeInBranch ( + Fdt, + FdtBranch, + &SerialCompatibleInfo, + &SerialNode + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + if (Status == EFI_NOT_FOUND) { + // Should have found the node. + Status = EFI_ABORTED; + } + + goto exit_handler; + } + + // Ignore the serial console node. + if (SerialNode == SerialConsoleNode) { + continue; + } else if (SerialDebugNode == -1) { + // The first serial-port node, not being the console serial-port, + // will be the debug serial-port. + SerialDebugNode = SerialNode; + Status = SerialPortInfoParser ( + FdtParserHandle, + SerialDebugNode, + EArchCommonObjSerialDebugPortInfo + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + } else { + if (GenericSerialInfo == NULL) { + // Should not be possible. + ASSERT (0); + Status = EFI_ABORTED; + goto exit_handler; + } + + Status = SerialPortNodeParser ( + Fdt, + SerialNode, + &GenericSerialInfo[GenericSerialIndex++] + ); + if (EFI_ERROR (Status)) { + ASSERT (0); + goto exit_handler; + } + } + } // for + + if (GenericSerialIndex > 0) { + Status = SerialPortInfoDispatch ( + FdtParserHandle, + GenericSerialInfo, + GenericSerialIndex, + EArchCommonObjSerialPortInfo + ); + } + +exit_handler: + if (GenericSerialInfo != NULL) { + FreePool (GenericSerialInfo); + } + + return Status; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h new file mode 100644 index 0000000000..22c686d5d4 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h @@ -0,0 +1,47 @@ +/** @file + Serial Port Parser. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - linux/Documentation/devicetree/bindings/serial/serial.yaml + - linux/Documentation/devicetree/bindings/serial/8250.txt +**/ + +#ifndef SERIAL_PORT_PARSER_H_ +#define SERIAL_PORT_PARSER_H_ + +/** SerialPort dispatcher. + + This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for + the following CM_OBJ_ID: + - EArchCommonObjConsolePortInfo + - EArchCommonObjSerialDebugPortInfo + - EArchCommonObjSerialPortInfo + + A parser parses a Device Tree to populate a specific CmObj type. None, + one or many CmObj can be created by the parser. + The created CmObj are then handed to the parser's caller through the + HW_INFO_ADD_OBJECT interface. + This can also be a dispatcher. I.e. a function that not parsing a + Device Tree but calling other parsers. + + @param [in] FdtParserHandle A handle to the parser instance. + @param [in] FdtBranch When searching for DT node name, restrict + the search to this Device Tree branch. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ABORTED An error occurred. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_NOT_FOUND Not found. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +EFIAPI +SerialPortDispatcher ( + IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, + IN INT32 FdtBranch + ); + +#endif // SERIAL_PORT_PARSER_H_ -- cgit From 5782aef055fe76c99acdfd2e27051c148782ad66 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Move ArmLib.h to ArmGicCParser.c ArmLib.h is required only for building GIC in ARM. So, move it to ARM specific file. Otherwise, FdtHwInfoParserInclude.h being a common header across architectures will have issue on other architectures. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c | 1 + DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c index cf577b4724..3955219146 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c @@ -11,6 +11,7 @@ - linux/Documentation/devicetree/bindings/arm/pmu.yaml **/ +#include #include "FdtHwInfoParser.h" #include "CmObjectDescUtility.h" #include "Arm/Gic/ArmGicCParser.h" diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h index 583f290095..60f671eccc 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h @@ -10,7 +10,6 @@ #include #include -#include #include #include -- cgit From d8aa665b31e309a31b59b97d04ba8d003f4fe84e Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Move IRQ map to arch folder The interrupts property in DT is arch specific. Move the current implementation and the way to decode the property to the Arm folder to prepare for other architecture support. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar Reviewed-by: Sunil V L --- .../FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c | 85 ++++++++++++++++++++++ .../FdtHwInfoParserLib/FdtHwInfoParserLib.inf | 1 + .../Library/FdtHwInfoParserLib/FdtUtility.c | 71 ------------------ 3 files changed, 86 insertions(+), 71 deletions(-) create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c new file mode 100644 index 0000000000..21b1306e57 --- /dev/null +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c @@ -0,0 +1,85 @@ +/** @file + Flattened device tree utility. + + Copyright (c) 2021, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Device tree Specification - Release v0.3 + - linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml + - linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml +**/ + +#include +#include "FdtUtility.h" + +/** Get the interrupt Id of an interrupt described in a fdt. + + Data must describe a GIC interrupt. A GIC interrupt is on at least + 3 UINT32 cells. + This function DOES NOT SUPPORT extended SPI range and extended PPI range. + + @param [in] Data Pointer to the first cell of an "interrupts" property. + + @retval The interrupt id. +**/ +UINT32 +EFIAPI +FdtGetInterruptId ( + UINT32 CONST *Data + ) +{ + UINT32 IrqType; + UINT32 IrqId; + + ASSERT (Data != NULL); + + IrqType = fdt32_to_cpu (Data[IRQ_TYPE_OFFSET]); + IrqId = fdt32_to_cpu (Data[IRQ_NUMBER_OFFSET]); + + switch (IrqType) { + case DT_SPI_IRQ: + IrqId += SPI_OFFSET; + break; + + case DT_PPI_IRQ: + IrqId += PPI_OFFSET; + break; + + default: + ASSERT (0); + IrqId = 0; + } + + return IrqId; +} + +/** Get the ACPI interrupt flags of an interrupt described in a fdt. + + Data must describe a GIC interrupt. A GIC interrupt is on at least + 3 UINT32 cells. + + PPI interrupt cpu mask on bits [15:8] are ignored. + + @param [in] Data Pointer to the first cell of an "interrupts" property. + + @retval The interrupt flags (for ACPI). +**/ +UINT32 +EFIAPI +FdtGetInterruptFlags ( + UINT32 CONST *Data + ) +{ + UINT32 IrqFlags; + UINT32 AcpiIrqFlags; + + ASSERT (Data != NULL); + + IrqFlags = fdt32_to_cpu (Data[IRQ_FLAGS_OFFSET]); + + AcpiIrqFlags = DT_IRQ_IS_EDGE_TRIGGERED (IrqFlags) ? BIT0 : 0; + AcpiIrqFlags |= DT_IRQ_IS_ACTIVE_LOW (IrqFlags) ? BIT1 : 0; + + return AcpiIrqFlags; +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf index d3010af527..c8511ab4dd 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf @@ -28,6 +28,7 @@ Serial/SerialPortParser.h [Sources.ARM, Sources.AARCH64] + Arm/ArmFdtInterrupt.c Arm/ArmFdtHwInfoParser.c Arm/BootArch/ArmBootArchParser.c Arm/BootArch/ArmBootArchParser.h diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c index 5314cf3808..bab2285759 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c @@ -13,77 +13,6 @@ #include #include "FdtUtility.h" -/** Get the interrupt Id of an interrupt described in a fdt. - - Data must describe a GIC interrupt. A GIC interrupt is on at least - 3 UINT32 cells. - This function DOES NOT SUPPORT extended SPI range and extended PPI range. - - @param [in] Data Pointer to the first cell of an "interrupts" property. - - @retval The interrupt id. -**/ -UINT32 -EFIAPI -FdtGetInterruptId ( - UINT32 CONST *Data - ) -{ - UINT32 IrqType; - UINT32 IrqId; - - ASSERT (Data != NULL); - - IrqType = fdt32_to_cpu (Data[IRQ_TYPE_OFFSET]); - IrqId = fdt32_to_cpu (Data[IRQ_NUMBER_OFFSET]); - - switch (IrqType) { - case DT_SPI_IRQ: - IrqId += SPI_OFFSET; - break; - - case DT_PPI_IRQ: - IrqId += PPI_OFFSET; - break; - - default: - ASSERT (0); - IrqId = 0; - } - - return IrqId; -} - -/** Get the ACPI interrupt flags of an interrupt described in a fdt. - - Data must describe a GIC interrupt. A GIC interrupt is on at least - 3 UINT32 cells. - - PPI interrupt cpu mask on bits [15:8] are ignored. - - @param [in] Data Pointer to the first cell of an "interrupts" property. - - @retval The interrupt flags (for ACPI). -**/ -UINT32 -EFIAPI -FdtGetInterruptFlags ( - UINT32 CONST *Data - ) -{ - UINT32 IrqFlags; - UINT32 AcpiIrqFlags; - - ASSERT (Data != NULL); - - IrqFlags = fdt32_to_cpu (Data[IRQ_FLAGS_OFFSET]); - - AcpiIrqFlags = DT_IRQ_IS_EDGE_TRIGGERED (IrqFlags) ? BIT0 : 0; - AcpiIrqFlags |= DT_IRQ_IS_ACTIVE_LOW (IrqFlags) ? BIT1 : 0; - - return AcpiIrqFlags; -} - /** Check whether a node has the input name. @param [in] Fdt Pointer to a Flattened Device Tree. -- cgit From 40a0dbdd18fe6303a71113e7e9c49f45042e692b Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 10 Jun 2024 14:00:00 +0200 Subject: DynamicTablesPkg: FdtHwInfoParserLib: Create wrapper to get INTC addr cells Parent interrupt controller's address cells is arch specific. So, create a wrapper function which can be implemented differently for different archs. Move current implementation to ARM specific file. Suggested-by: Sunil V L Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar Reviewed-by: Sunil V L --- .../Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c | 2 +- .../FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c | 33 ++++++++++++++++++++++ .../Library/FdtHwInfoParserLib/FdtUtility.h | 30 ++++++++++++++++++++ .../FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c | 2 +- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c index 2b488016e5..5b6d551562 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c @@ -974,7 +974,7 @@ BuildSsdtPciTableEx ( EFI_STATUS Status; CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo; UINT32 PciCount; - UINTN Index; + UINT32 Index; EFI_ACPI_DESCRIPTION_HEADER **TableList; ACPI_PCI_GENERATOR *Generator; UINT32 Uid; diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c index 21b1306e57..71774fae71 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c @@ -83,3 +83,36 @@ FdtGetInterruptFlags ( return AcpiIrqFlags; } + +/** For relevant architectures, get the "#address-cells" and/or "#size-cells" + property of the node. + + According to the Device Tree specification, s2.3.5 "#address-cells and + #size-cells": + "If missing, a client program should assume a default value of 2 for + #address-cells, and a value of 1 for #size-cells." + + @param [in] Fdt Pointer to a Flattened Device Tree. + @param [in] Node Offset of the node having to get the + "#address-cells" and "#size-cells" + properties from. + @param [out] AddressCells If success, number of address-cells. + If the property is not available, + default value is 2. + @param [out] SizeCells If success, number of size-cells. + If the property is not available, + default value is 1. + + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +FdtGetIntcAddressCells ( + IN CONST VOID *Fdt, + IN INT32 Node, + OUT INT32 *AddressCells, OPTIONAL + OUT INT32 *SizeCells OPTIONAL + ) +{ + return FdtGetAddressInfo (Fdt, Node, AddressCells, SizeCells); +} diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h index 3f5d131d9a..2d7048753b 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h @@ -455,4 +455,34 @@ FdtGetParentAddressInfo ( OUT INT32 *SizeCells OPTIONAL ); +/** For relevant architectures, get the "#address-cells" and/or "#size-cells" + property of the node. + + According to the Device Tree specification, s2.3.5 "#address-cells and + #size-cells": + "If missing, a client program should assume a default value of 2 for + #address-cells, and a value of 1 for #size-cells." + + @param [in] Fdt Pointer to a Flattened Device Tree. + @param [in] Node Offset of the node having to get the + "#address-cells" and "#size-cells" + properties from. + @param [out] AddressCells If success, number of address-cells. + If the property is not available, + default value is 2. + @param [out] SizeCells If success, number of size-cells. + If the property is not available, + default value is 1. + + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +FdtGetIntcAddressCells ( + IN CONST VOID *Fdt, + IN INT32 Node, + OUT INT32 *AddressCells, OPTIONAL + OUT INT32 *SizeCells OPTIONAL + ); + #endif // FDT_UTILITY_H_ diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c index 76f9efdf64..7f536c0ac6 100644 --- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c +++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c @@ -365,7 +365,7 @@ ParseIrqMap ( } // Get the "address-cells" property of the IntcNode. - Status = FdtGetAddressInfo (Fdt, IntcNode, &IntcAddressCells, NULL); + Status = FdtGetIntcAddressCells (Fdt, IntcNode, &IntcAddressCells, NULL); if (EFI_ERROR (Status)) { ASSERT (0); return Status; -- cgit From 7537028fa5ab071d9ae686212437b92f1a0ce490 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 3 Jul 2024 11:53:39 +0200 Subject: DynamicTablesPkg: Fix conversion compiler warnings Some CM objects fields are wider than the targeted field in ACPI tables. Some assignments are also subject to data loss and trigger the following warnings: - '<': signed/unsigned mismatch - '=': conversion from 'UINTxx' to 'UINTyy', possible loss of data with xx > yy. Add checks/cast to remove the warnings. Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- .../Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c | 15 +++++++++++---- .../AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c | 6 ++++-- .../Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c | 15 ++++++++++----- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c index 205c444057..ef5d8823c2 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c @@ -379,10 +379,12 @@ AddSubspaceStructType1 ( Doorbell = &GenericPccCmObj->DoorbellReg; ChannelTiming = &GenericPccCmObj->ChannelTiming; + ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0); + PccAcpi->Type = GenericPccCmObj->Type; PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS); PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; - PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; + PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags; PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; PccAcpi->AddressLength = GenericPccCmObj->AddressLength; @@ -441,10 +443,12 @@ AddSubspaceStructType2 ( PlatIrqAck = &PccCmObj->PlatIrqAckReg; ChannelTiming = &GenericPccCmObj->ChannelTiming; + ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0); + PccAcpi->Type = GenericPccCmObj->Type; PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS); PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; - PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; + PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags; PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; @@ -519,13 +523,16 @@ AddSubspaceStructType34 ( ErrorStatus = &PccCmObj->ErrorStatusReg; ChannelTiming = &GenericPccCmObj->ChannelTiming; + ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0); + ASSERT ((GenericPccCmObj->AddressLength & ~MAX_UINT32) == 0); + PccAcpi->Type = GenericPccCmObj->Type; PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC); PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt; - PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags; + PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags; PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE; PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress; - PccAcpi->AddressLength = GenericPccCmObj->AddressLength; + PccAcpi->AddressLength = (UINT32)GenericPccCmObj->AddressLength; CopyMem ( &PccAcpi->DoorbellRegister, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c index 7459513193..9097ac3deb 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c @@ -1026,7 +1026,8 @@ CreateAmlCpuTopologyTree ( if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) { Name = Generator->ProcNodeList[Index].OverrideName; } else { - Name = CpuIndex; + ASSERT ((CpuIndex & ~MAX_UINT16) == 0); + Name = (UINT16)CpuIndex; } Status = CreateAmlCpuFromProcHierarchy ( @@ -1061,7 +1062,8 @@ CreateAmlCpuTopologyTree ( Name = Generator->ProcNodeList[Index].OverrideName; Uid = Generator->ProcNodeList[Index].OverrideUid; } else { - Name = ProcContainerName; + ASSERT ((ProcContainerName & ~MAX_UINT16) == 0); + Name = (UINT16)ProcContainerName; Uid = *ProcContainerIndex; } diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c index 5b6d551562..618056e85a 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c @@ -311,7 +311,7 @@ GeneratePrt ( ) { EFI_STATUS Status; - INT32 Index; + UINT32 Index; AML_OBJECT_NODE_HANDLE PrtNode; CM_ARCH_COMMON_OBJ_REF *RefInfo; UINT32 RefCount; @@ -561,6 +561,11 @@ GeneratePciCrs ( break; case PCI_SS_M32: + ASSERT ((AddrMapInfo->PciAddress & ~MAX_UINT32) == 0); + ASSERT (((AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1) & ~MAX_UINT32) == 0); + ASSERT (((Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0) & ~MAX_UINT32) == 0); + ASSERT ((AddrMapInfo->AddressSize & ~MAX_UINT32) == 0); + Status = AmlCodeGenRdDWordMemory ( FALSE, IsPosDecode, @@ -569,10 +574,10 @@ GeneratePciCrs ( AmlMemoryCacheable, TRUE, 0, - AddrMapInfo->PciAddress, - AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1, - Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0, - AddrMapInfo->AddressSize, + (UINT32)(AddrMapInfo->PciAddress), + (UINT32)(AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1), + (UINT32)(Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0), + (UINT32)(AddrMapInfo->AddressSize), 0, NULL, AmlAddressRangeMemory, -- cgit From be1d408773504df8b95a2a81be7b558276ba5356 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 3 Jul 2024 11:53:40 +0200 Subject: DynamicTablesPkg: Add EFIAPI to generators hooks For X64 builds, the EFIAPI is replaced by '(__attribute__((ms_abi))'. This might lead to build error for some ACPI tablte generators due to function prototype mismatch. Add the EFIAPI to ACPI table generator hooks: - ACPI_TABLE_GENERATOR_BUILD_TABLEEX - ACPI_TABLE_GENERATOR_FREE_TABLEEX Signed-off-by: Pierre Gondois Reviewed-by: Sami Mujawar --- DynamicTablesPkg/Include/AcpiTableGenerator.h | 8 ++++---- DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c | 1 + DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c | 1 + DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c | 1 + DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c | 1 + .../Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c | 1 + 6 files changed, 9 insertions(+), 4 deletions(-) diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index d0eda011c3..f5c6179be0 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -214,7 +214,7 @@ typedef struct AcpiTableGenerator ACPI_TABLE_GENERATOR; @return EFI_SUCCESS If the table is generated successfully or other failure codes as returned by the generator. **/ -typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLE) ( +typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_BUILD_TABLE)( IN CONST ACPI_TABLE_GENERATOR *This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, @@ -234,7 +234,7 @@ typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLE) ( @return EFI_SUCCESS If freed successfully or other failure codes as returned by the generator. **/ -typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLE) ( +typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_FREE_TABLE)( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, @@ -257,7 +257,7 @@ typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLE) ( @return EFI_SUCCESS If the table is generated successfully or other failure codes as returned by the generator. **/ -typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLEEX) ( +typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_BUILD_TABLEEX)( IN CONST ACPI_TABLE_GENERATOR *This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, @@ -280,7 +280,7 @@ typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLEEX) ( @return EFI_SUCCESS If freed successfully or other failure codes as returned by the generator. **/ -typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLEEX) ( +typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_FREE_TABLEEX)( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c index 722f9c17d5..40dea304e3 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c @@ -261,6 +261,7 @@ error_handler: **/ STATIC EFI_STATUS +EFIAPI FreeMcfgTableResources ( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c index ef5d8823c2..36e6807023 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c @@ -1075,6 +1075,7 @@ error_handler: **/ STATIC EFI_STATUS +EFIAPI FreePcctTableResources ( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c index 2b8088a07f..fd465cbab0 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c @@ -1342,6 +1342,7 @@ error_handler: **/ STATIC EFI_STATUS +EFIAPI FreePpttTableResources ( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c index dcdacc4e96..1a9434e6bd 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c @@ -552,6 +552,7 @@ error_handler: **/ STATIC EFI_STATUS +EFIAPI FreeSratTableResources ( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c index 9097ac3deb..24b06d01dc 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c @@ -1313,6 +1313,7 @@ exit_handler: **/ STATIC EFI_STATUS +EFIAPI FreeSsdtCpuTopologyTableResources ( IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, -- cgit From 909abd7104b87986ad22e92b4cb07d30a8cca11b Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Mon, 29 Jul 2024 09:29:14 -0700 Subject: EmbeddedPkg: NonCoherentDmaLib: Set EFI_MEMORY_XP Capability on DMA Buffer Commit 8984fba2f22a2cd44e1189403e3553f447b82852 added setting the EFI_MEMORY_XP attribute on DMA buffers. However, it did not ensure that the XP capability was set on that region. This patch adds setting the XP capability before attempting to set the attribute. If setting the capability fails, it defaults to the old behavior of not setting the XP bit. Signed-off-by: Oliver Smith-Denny --- .../Library/NonCoherentDmaLib/NonCoherentDmaLib.c | 36 +++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c index 0a21d72290..403cc8e2fd 100644 --- a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c +++ b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c @@ -500,10 +500,12 @@ DmaAllocateAlignedBuffer ( { EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; VOID *Allocation; - UINT64 MemType; + UINT64 Attributes; UNCACHED_ALLOCATION *Alloc; EFI_STATUS Status; + Attributes = EFI_MEMORY_XP; + if (Alignment == 0) { Alignment = EFI_PAGE_SIZE; } @@ -534,9 +536,9 @@ DmaAllocateAlignedBuffer ( // Choose a suitable uncached memory type that is supported by the region if (GcdDescriptor.Capabilities & EFI_MEMORY_WC) { - MemType = EFI_MEMORY_WC; + Attributes |= EFI_MEMORY_WC; } else if (GcdDescriptor.Capabilities & EFI_MEMORY_UC) { - MemType = EFI_MEMORY_UC; + Attributes |= EFI_MEMORY_UC; } else { Status = EFI_UNSUPPORTED; goto FreeBuffer; @@ -553,11 +555,37 @@ DmaAllocateAlignedBuffer ( InsertHeadList (&UncachedAllocationList, &Alloc->Link); + // Ensure that EFI_MEMORY_XP is in the capability set + if ((GcdDescriptor.Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) { + Status = gDS->SetMemorySpaceCapabilities ( + (PHYSICAL_ADDRESS)(UINTN)Allocation, + EFI_PAGES_TO_SIZE (Pages), + GcdDescriptor.Capabilities | EFI_MEMORY_XP + ); + + // if we were to fail setting the capability, this would indicate an internal failure of the GCD code. We should + // assert here to let a platform know something went crazy, but for a release build we can let the allocation occur + // without the EFI_MEMORY_XP bit set, as that was the existing behavior + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n", + __func__, + Allocation, + EFI_PAGES_TO_SIZE (Pages) + )); + + ASSERT_EFI_ERROR (Status); + + Attributes &= ~EFI_MEMORY_XP; + } + } + // Remap the region with the new attributes and mark it non-executable Status = gDS->SetMemorySpaceAttributes ( (PHYSICAL_ADDRESS)(UINTN)Allocation, EFI_PAGES_TO_SIZE (Pages), - MemType | EFI_MEMORY_XP + Attributes ); if (EFI_ERROR (Status)) { goto FreeAlloc; -- cgit From 84fc1ec52fc0f650187359bb081ee5a9400d9675 Mon Sep 17 00:00:00 2001 From: Herman Li Date: Sat, 15 Jun 2024 23:58:55 +0800 Subject: MdePkg: Update HEST Revision As 2 This modification come from ACPI 6.5 spec. Besides, Starting with revision 2 of HEST, the Error Source Structures must be sorted in Type ascending order for Error Source Structure Types of less than 12. Signed-off-by: Herman Li --- MdePkg/Include/IndustryStandard/Acpi65.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 387af78cfe..685e08167c 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -1949,7 +1949,7 @@ typedef struct { /// /// HEST Version (as defined in ACPI 6.5 spec.) /// -#define EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 +#define EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x02 // // Error Source structure types. -- cgit From 621a30c676d55bfe0049f65e98f65104528218db Mon Sep 17 00:00:00 2001 From: Abhishek Mainkar Date: Mon, 15 Jul 2024 23:09:12 +0000 Subject: MdePkg: IORT header update for IORT Rev E.f spec The IO Remapping Table, Platform Design Document, Revision E.f, April 2024 (https://developer.arm.com/documentation/den0049/ef/) added CANWBS Memory access flag. Therefore, update the IORT header file to add support for CANWBS Memory access flag. Signed-off-by: Abhishek Mainkar --- MdePkg/Include/IndustryStandard/IoRemappingTable.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/IoRemappingTable.h b/MdePkg/Include/IndustryStandard/IoRemappingTable.h index 544aa67a05..7900bb5bbd 100644 --- a/MdePkg/Include/IndustryStandard/IoRemappingTable.h +++ b/MdePkg/Include/IndustryStandard/IoRemappingTable.h @@ -43,8 +43,9 @@ #define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_RA BIT2 #define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_AHO BIT3 -#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM BIT0 -#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS BIT1 +#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM BIT0 +#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS BIT1 +#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CANWBS BIT2 #define EFI_ACPI_IORT_SMMUv1v2_MODEL_v1 0x0 #define EFI_ACPI_IORT_SMMUv1v2_MODEL_v2 0x1 -- cgit From 91a822749a6664dcaf0f67a837dcf0cd05783d17 Mon Sep 17 00:00:00 2001 From: wilson_chen Date: Fri, 26 Jul 2024 17:31:46 +0800 Subject: BaseTools: fix build error with TOOL_CHAIN_TAG VS2015 & VS2015x86 Start the build with TOOL_CHAIN_TAG VS2015 by launch: Build -t VS2015 ERROR: Would get following build error message: 'c:\Program' is not recognized as an internal or external command, operable program or batch file. NMAKE : fatal error U1077: '"c:\Program Files\Windows Kits\8.1\bin\x86\\rc.exe' : return code '0x1' Stop. Fix the build error, Tested : TOOL_CHAIN_TAG = VS2015 (>Build -t VS2015) TOOL_CHAIN_TAG = VS2015x86 (>Build -t VS2015x86) Signed-off-by: wilson_chen --- BaseTools/Conf/tools_def.template | 4 ++-- BaseTools/set_vsprefix_envs.bat | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 13cf0f91b6..76aaae7261 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -67,8 +67,8 @@ DEFINE WINSDK_BIN = ENV(WINSDK_PREFIX) DEFINE WINSDKx86_BIN = ENV(WINSDKx86_PREFIX) # Microsoft Visual Studio 2015 Professional Edition -DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x86\ -DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x64 +DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x64 +DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x86 # Microsoft Visual Studio 2017/2019/2022 Professional Edition DEFINE WINSDK10_BIN = ENV(WINSDK10_PREFIX)DEF(VS_HOST) diff --git a/BaseTools/set_vsprefix_envs.bat b/BaseTools/set_vsprefix_envs.bat index 39e4e004b5..df2c771951 100644 --- a/BaseTools/set_vsprefix_envs.bat +++ b/BaseTools/set_vsprefix_envs.bat @@ -35,10 +35,18 @@ if defined VS140COMNTOOLS ( set "VS2015_PREFIX=%VS140COMNTOOLS:~0,-14%" ) if not defined WINSDK81_PREFIX ( - set "WINSDK81_PREFIX=c:\Program Files\Windows Kits\8.1\bin\" + if exist "%ProgramFiles%\Windows Kits\8.1\bin" ( + set "WINSDK81_PREFIX=%ProgramFiles%\Windows Kits\8.1\bin\" + ) else if exist "%ProgramFiles(x86)%\Windows Kits\8.1\bin" ( + set "WINSDK81_PREFIX=%ProgramFiles(x86)%\Windows Kits\8.1\bin\" + ) ) if not defined WINSDK81x86_PREFIX ( - set "WINSDK81x86_PREFIX=c:\Program Files (x86)\Windows Kits\8.1\bin\" + if exist "%ProgramFiles(x86)%\Windows Kits\8.1\bin" ( + set "WINSDK81x86_PREFIX=%ProgramFiles(x86)%\Windows Kits\8.1\bin\" + ) else if exist "%ProgramFiles%\Windows Kits\8.1\bin" ( + set "WINSDK81x86_PREFIX=%ProgramFiles%\Windows Kits\8.1\bin\" + ) ) ) else ( if /I "%1"=="VS2015" goto ToolNotInstall -- cgit From 5b08df03f8193261e4837ed4e91ff81fa7d17e4d Mon Sep 17 00:00:00 2001 From: Awiral Shrivastava Date: Fri, 5 Jul 2024 08:37:41 +0530 Subject: MdeModulePkg: Optimize PEI Core Migration Algorithm REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4750 Migrate the FV that doesn't contain the currently executing PEI Core when permanent memory is initialized but PEI Core is still potentially running from faster memory (Tepmorary RAM). This may reduce the time required to migrate FVs to permanent memory. The FV containing PEI Core is migrated after the PEI Core reentry when it is executed from permanent memory. This may or may not improve performance depending on the behavior of temporary RAM and the actual performance changes must be measured with the feature enabled and disabled. This migration algorithm is only used for FVs specified in the gEdkiiMigrationInfoGuid HOB and built with flag FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY. Signed-off-by: Awiral Shrivastava --- MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 37 +++++++++++++++++++++------ MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 16 ++++++++++++ MdeModulePkg/Include/Guid/MigratedFvInfo.h | 3 ++- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c index ca37bde482..79ff8d1cf9 100644 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c @@ -1205,16 +1205,21 @@ EvacuateTempRam ( PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE)SecCoreData->BootFirmwareVolumeBase; } - for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) { - if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) { - CopyMem (&PeiCoreFvHandle, &Private->Fv[FvIndex], sizeof (PEI_CORE_FV_HANDLE)); - break; + if (Private->PeimDispatcherReenter) { + // + // PEI_CORE should be migrated after dispatcher re-enters from main memory. + // + for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) { + if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) { + CopyMem (&PeiCoreFvHandle, &Private->Fv[FvIndex], sizeof (PEI_CORE_FV_HANDLE)); + break; + } } - } - Status = EFI_SUCCESS; + Status = EFI_SUCCESS; - ConvertPeiCorePpiPointers (Private, &PeiCoreFvHandle); + ConvertPeiCorePpiPointers (Private, &PeiCoreFvHandle); + } Hob.Raw = GetFirstGuidHob (&gEdkiiMigrationInfoGuid); if (Hob.Raw != NULL) { @@ -1237,6 +1242,14 @@ EvacuateTempRam ( ) { if ((MigrationInfo == NULL) || (MigrationInfo->MigrateAll == TRUE)) { + if (!Private->PeimDispatcherReenter) { + // + // Migration before dispatcher reentery is supported only when gEdkiiMigrationInfoGuid + // HOB is built for selective FV migration. + // + return EFI_SUCCESS; + } + // // Migrate all FVs and copy raw data // @@ -1253,10 +1266,18 @@ EvacuateTempRam ( } } - if (Index == MigrationInfo->ToMigrateFvCount) { + if ((Index == MigrationInfo->ToMigrateFvCount) || + ((!Private->PeimDispatcherReenter) && + (((FvMigrationFlags & FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY) == 0) || + (FvHeader == PeiCoreFvHandle.FvHandle)))) + { // // This FV is not expected to migrate // + // FV should not be migrated before dispatcher reentry if any of the below condition is true: + // a. MigrationInfo HOB is not built with flag FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY. + // b. FV contains currently executing PEI Core. + // continue; } } diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index 0e3d9a8438..61f5699e1f 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -323,6 +323,21 @@ PeiCore ( // OldCoreData->PeiMemoryInstalled = TRUE; + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) { + DEBUG ((DEBUG_VERBOSE, "Early Migration - PPI lists before temporary RAM evacuation:\n")); + DumpPpiList (OldCoreData); + + // + // Migrate installed content from Temporary RAM to Permanent RAM at this + // stage when PEI core still runs from a cached location. + // FVs that doesn't contain PEI_CORE should be migrated here. + // + EvacuateTempRam (OldCoreData, SecCoreData); + + DEBUG ((DEBUG_VERBOSE, "Early Migration - PPI lists after temporary RAM evacuation:\n")); + DumpPpiList (OldCoreData); + } + // // Indicate that PeiCore reenter // @@ -451,6 +466,7 @@ PeiCore ( // // Migrate installed content from Temporary RAM to Permanent RAM + // FVs containing PEI_CORE should be migrated here. // EvacuateTempRam (&PrivateData, SecCoreData); diff --git a/MdeModulePkg/Include/Guid/MigratedFvInfo.h b/MdeModulePkg/Include/Guid/MigratedFvInfo.h index 255e278235..99681fb88a 100644 --- a/MdeModulePkg/Include/Guid/MigratedFvInfo.h +++ b/MdeModulePkg/Include/Guid/MigratedFvInfo.h @@ -18,7 +18,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // 1: FV raw data will be copied to permanent memory for later phase use (such as // FV measurement). // -#define FLAGS_FV_RAW_DATA_COPY BIT0 +#define FLAGS_FV_RAW_DATA_COPY BIT0 +#define FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY BIT1 /// /// In real use cases, not all FVs need migrate to permanent memory before TempRam tears -- cgit From bc1c890e8ea08c133806ed2f5f681e7af64bddb2 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Sat, 27 Jul 2024 18:08:34 +0800 Subject: MdeModulePkg: Add the PcdUfsInitialCompletionTimeout in DEC File REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4820 - Add the PCD to indicate the UFS device initialize completion time - Default value of this PCD value is 600ms Signed-off-by: Jason1 Lin --- MdeModulePkg/MdeModulePkg.dec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 3b484db913..693e45911b 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1704,6 +1704,11 @@ # @Prompt SPI NOR Flash Operation Delay in Microseconds (16 us) gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationDelayMicroseconds|0x00000010|UINT32|0x00000035 + ## Indicate the default timeout value for UFS device initial completetion in microseconds. + # + # @Prompt UFS device initial completion timoeout (us), default value is 600ms. + gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout|600000|UINT32|0x00000036 + [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] ## This PCD defines the Console output row. The default value is 25 according to UEFI spec. # This PCD could be set to 0 then console output would be at max column and max row. -- cgit From 5289ad177d4f2d587a47185e0567b9d7e579e4e8 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Sat, 27 Jul 2024 18:11:35 +0800 Subject: MdeModulePkg/UfsBlockIoPei: Migrate UFS Initial Completion Timeout to PCD - Remove the hardcoded definition (UFS_INIT_COMPLETION_TIMEOUT) - Migrate the UFS initial completion timeout into PCD value Signed-off-by: Jason1 Lin --- MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c | 5 +---- MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h | 4 ++-- MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf | 5 ++++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c index 4dbd033d41..e04a93da6a 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c @@ -1036,6 +1036,7 @@ UfsFinishDeviceInitialization ( UINT32 Timeout; DeviceInitStatus = 0xFF; + Timeout = PcdGet32 (PcdUfsInitialCompletionTimeout); // // The host enables the device initialization completion by setting fDeviceInit flag. @@ -1045,10 +1046,6 @@ UfsFinishDeviceInitialization ( return Status; } - // - // There are cards that can take upto 600ms to clear fDeviceInit flag. - // - Timeout = UFS_INIT_COMPLETION_TIMEOUT; do { Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus); if (EFI_ERROR (Status)) { diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h index 489b6c34ec..869332fbe3 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -31,8 +32,7 @@ #define UFS_PEIM_HC_SIG SIGNATURE_32 ('U', 'F', 'S', 'H') -#define UFS_PEIM_MAX_LUNS 8 -#define UFS_INIT_COMPLETION_TIMEOUT 600000 +#define UFS_PEIM_MAX_LUNS 8 typedef struct { UINT8 Lun[UFS_PEIM_MAX_LUNS]; diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf index 6e1cbfde12..5da906e24d 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf @@ -41,6 +41,7 @@ IoLib TimerLib BaseMemoryLib + PcdLib PeimEntryPoint PeiServicesLib DebugLib @@ -52,9 +53,11 @@ gEdkiiIoMmuPpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout ## CONSUMES + [Depex] gEfiPeiMemoryDiscoveredPpiGuid AND gEdkiiPeiUfsHostControllerPpiGuid [UserExtensions.TianoCore."ExtraFiles"] UfsBlockIoPeiExtra.uni - -- cgit From f8f34edd9db82882fd70f14cb97ab28e9bb0b9a3 Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Sat, 27 Jul 2024 18:38:13 +0800 Subject: MdeModulePkg/UfsPassThruDxe: Migrate UFS Initial Completion Timeout to PCD - Remove the hardcoded definition (UFS_INIT_COMPLETION_TIMEOUT) - Migrate the UFS initial completion timeout into PCD value Signed-off-by: Jason1 Lin --- MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c | 5 +---- MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h | 6 +++--- MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf | 4 ++++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c index 880e7d8511..816532d20e 100644 --- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c +++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c @@ -759,6 +759,7 @@ UfsFinishDeviceInitialization ( UINT32 Timeout; DeviceInitStatus = 0xFF; + Timeout = PcdGet32 (PcdUfsInitialCompletionTimeout); // // The host enables the device initialization completion by setting fDeviceInit flag. @@ -768,10 +769,6 @@ UfsFinishDeviceInitialization ( return Status; } - // - // There are cards that can take upto 600ms to clear fDeviceInit flag. - // - Timeout = UFS_INIT_COMPLETION_TIMEOUT; do { Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus); if (EFI_ERROR (Status)) { diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h index bc1139da6e..d380650319 100644 --- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h +++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "UfsPassThruHci.h" @@ -38,9 +39,8 @@ // Lun 10: BOOT // Lun 11: RPMB // -#define UFS_MAX_LUNS 12 -#define UFS_WLUN_PREFIX 0xC1 -#define UFS_INIT_COMPLETION_TIMEOUT 600000 +#define UFS_MAX_LUNS 12 +#define UFS_WLUN_PREFIX 0xC1 typedef struct { UINT8 Lun[UFS_MAX_LUNS]; diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf index 92dc25714b..0e12b7a8b4 100644 --- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf +++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf @@ -48,6 +48,7 @@ UefiDriverEntryPoint DebugLib DevicePathLib + PcdLib TimerLib [Protocols] @@ -56,5 +57,8 @@ gEdkiiUfsHostControllerProtocolGuid ## TO_START gEdkiiUfsHcPlatformProtocolGuid ## SOMETIMES_CONSUMES +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout ## CONSUMES + [UserExtensions.TianoCore."ExtraFiles"] UfsPassThruExtra.uni -- cgit From 9df400fd4d75831e02428e9ccb3dcfce85ceab82 Mon Sep 17 00:00:00 2001 From: Sean Brogan Date: Mon, 22 Jul 2024 14:42:52 -0700 Subject: MdeModulePkg: NvmExpressDxe: Add Timeout Status Codes Add Report status code events to Nvme to trigger when timeouts occur. This improves traceability when critical errors happen. Signed-off-by: Oliver Smith-Denny --- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c index 2ff2cb0e8d..f818e48fc1 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c @@ -824,6 +824,8 @@ NvmExpressPassThru ( // CopyMem (Packet->NvmeCompletion, (VOID *)Cq, sizeof (EFI_NVM_EXPRESS_COMPLETION)); } else { + ReportStatusCode ((EFI_ERROR_MAJOR | EFI_ERROR_CODE), (EFI_IO_BUS_SCSI | EFI_IOB_EC_INTERFACE_ERROR)); + // // Timeout occurs for an NVMe command. Reset the controller to abort the // outstanding commands. -- cgit From e2528a52093ba06886d2e1838255bf64b8875aac Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Thu, 25 Jul 2024 13:11:56 +0100 Subject: OvmfPkg: remove last instances of EFI_D_ Change debug print levels to modern DEBUG_ format. Signed-off-by: Leif Lindholm --- OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c | 2 +- OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c b/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c index 5a1a69dcc3..b4dc927a0e 100644 --- a/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c +++ b/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c @@ -89,7 +89,7 @@ FreeResources: FailedAllocate: DEBUG (( - EFI_D_ERROR, + DEBUG_ERROR, "%a: Failed to allocate memory for hardware info\n", __func__ )); diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c index 0925ab1166..d1cce9a089 100644 --- a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c @@ -49,7 +49,7 @@ InitRtc ( MmioWrite32 (mRtcBase + RTC_CTRL_REG, Val); mInitialized = TRUE; } else { - DebugPrint (EFI_D_INFO, "RTC register address not found!\n"); + DebugPrint (DEBUG_INFO, "RTC register address not found!\n"); ASSERT (FALSE); } } -- cgit From 03f49e44096fc25c33f96a11b3da93abc93dad34 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Thu, 25 Jul 2024 13:13:04 +0100 Subject: UefiCpuPkg: remove last instances of EFI_D_ Change debug print levels to modern DEBUG_ format. Signed-off-by: Leif Lindholm --- UefiCpuPkg/CpuDxe/LoongArch64/Exception.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c b/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c index 754549cd0e..0662b6fec3 100644 --- a/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c +++ b/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c @@ -137,7 +137,7 @@ InitializeExceptions ( // Status = UpdateExceptionStartEntry (); if (EFI_ERROR (Status)) { - DebugPrint (EFI_D_ERROR, "[%a]: Exception start entry code out of bounds!\n", __func__); + DebugPrint (DEBUG_ERROR, "[%a]: Exception start entry code out of bounds!\n", __func__); ASSERT_EFI_ERROR (Status); } @@ -150,7 +150,7 @@ InitializeExceptions ( // // Enable interrupts // - DebugPrint (EFI_D_INFO, "InitializeExceptions,IrqEnabled = %x\n", IrqEnabled); + DebugPrint (DEBUG_INFO, "InitializeExceptions,IrqEnabled = %x\n", IrqEnabled); if (!IrqEnabled) { Status = Cpu->EnableInterrupt (Cpu); } -- cgit From f9b021f84fbb75d3c6f50bc079b49b816a210ec4 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 25 Jul 2024 12:23:23 +0200 Subject: OvmfPkg/LoongArchVirtQemu: Drop bogus references to EfiResetSystemLib These libraries do not implement EfiResetSystemLib to begin with, and this library class is going to be dropped. So drop these bogus references first. Signed-off-by: Ard Biesheuvel --- OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc | 2 -- 1 file changed, 2 deletions(-) diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc index d1efc48d35..29c945b0ee 100644 --- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc +++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc @@ -131,7 +131,6 @@ FdtSerialPortAddressLib | OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf - EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf UefiLib | MdePkg/Library/UefiLib/UefiLib.inf @@ -248,7 +247,6 @@ RealTimeClockLib | OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf VariablePolicyLib | MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf - EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf !if $(TARGET) != RELEASE DebugLib | MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf -- cgit From 02f7ecbbb2da356585f5c4df4a5e7aa64a6b985d Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 25 Jul 2024 12:27:08 +0200 Subject: EmbeddedPkg: Retire EfiResetSystemLib and ResetRuntimeDxe Retire the ancient reset runtime DXE in EmbeddedPkg, and the associated EfiResetSystemLib library class and template implementation. These are incomplete and have been superseded by a generic implementation in MdeModulePkg. Signed-off-by: Ard Biesheuvel --- EmbeddedPkg/EmbeddedPkg.dec | 1 - EmbeddedPkg/EmbeddedPkg.dsc | 3 - EmbeddedPkg/Include/Library/EfiResetSystemLib.h | 48 ------------ .../TemplateResetSystemLib/ResetSystemLib.c | 91 ---------------------- .../TemplateResetSystemLib.inf | 30 ------- EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf | 45 ----------- EmbeddedPkg/ResetRuntimeDxe/reset.c | 64 --------------- 7 files changed, 282 deletions(-) delete mode 100644 EmbeddedPkg/Include/Library/EfiResetSystemLib.h delete mode 100644 EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c delete mode 100644 EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf delete mode 100644 EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf delete mode 100644 EmbeddedPkg/ResetRuntimeDxe/reset.c diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index 3497fa1df7..bb0b677bdc 100644 --- a/EmbeddedPkg/EmbeddedPkg.dec +++ b/EmbeddedPkg/EmbeddedPkg.dec @@ -33,7 +33,6 @@ [LibraryClasses.common] PrePiLib|Include/Library/PrePiLib.h RealTimeClockLib|Include/Library/RealTimeClockLib.h - EfiResetSystemLib|Include/Library/EfiResetSystemLib.h GdbSerialLib|Include/Library/GdbSerialLib.h DebugAgentTimerLib|Include/Library/DebugAgentTimerLib.h NorFlashInfoLib|Include/Library/NorFlashInfoLib.h diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index ef66aea29d..e89bfae72c 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -66,7 +66,6 @@ SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf - EfiResetSystemLib|EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf GdbSerialLib|EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf @@ -211,7 +210,6 @@ EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf EmbeddedPkg/Library/PrePiLib/PrePiLib.inf - EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf EmbeddedPkg/Library/CoherentDmaLib/CoherentDmaLib.inf EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf @@ -220,7 +218,6 @@ EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf - EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf { diff --git a/EmbeddedPkg/Include/Library/EfiResetSystemLib.h b/EmbeddedPkg/Include/Library/EfiResetSystemLib.h deleted file mode 100644 index 5bfebfc638..0000000000 --- a/EmbeddedPkg/Include/Library/EfiResetSystemLib.h +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __EFI_RESET_SYSTEM_LIB_H___ -#define __EFI_RESET_SYSTEM_LIB_H___ - -/** - Resets the entire platform. - - @param ResetType The type of reset to perform. - @param ResetStatus The status code for the reset. - @param DataSize The size, in bytes, of WatchdogData. - @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - Unicode string, optionally followed by additional binary data. - -**/ -EFI_STATUS -EFIAPI -LibResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN CHAR16 *ResetData OPTIONAL - ); - -/** - Initialize any infrastructure required for LibResetSystem () to function. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -LibInitializeResetSystem ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -#endif diff --git a/EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c b/EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c deleted file mode 100644 index 60bbaeb6a8..0000000000 --- a/EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c +++ /dev/null @@ -1,91 +0,0 @@ -/** @file - Template library implementation to support ResetSystem Runtime call. - - Fill in the templates with what ever makes you system reset. - - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include - -/** - Resets the entire platform. - - @param ResetType The type of reset to perform. - @param ResetStatus The status code for the reset. - @param DataSize The size, in bytes, of WatchdogData. - @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - Unicode string, optionally followed by additional binary data. - -**/ -EFI_STATUS -EFIAPI -LibResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN CHAR16 *ResetData OPTIONAL - ) -{ - UINTN Address; - UINT8 Data; - - switch (ResetType) { - case EfiResetCold: - // system power cycle - - // Example using IoLib functions to do IO. - Address = 0x12345678; - Data = MmioRead8 (Address); - MmioWrite8 (Address, Data | 0x01); - - // Note this is a bad example asa MmioOr8 (Address, 0x01) does the same thing - break; - - case EfiResetWarm: - // not a full power cycle, maybe memory stays around. - // if not support do the same thing as EfiResetCold. - break; - - case EfiResetShutdown: - // turn off the system. - // if not support do the same thing as EfiResetCold. - break; - - default: - return EFI_INVALID_PARAMETER; - } - - // - // If we reset, we would not have returned... - // - return EFI_DEVICE_ERROR; -} - -/** - Initialize any infrastructure required for LibResetSystem () to function. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -LibInitializeResetSystem ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EFI_SUCCESS; -} diff --git a/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf b/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf deleted file mode 100644 index cd7a9f845d..0000000000 --- a/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf +++ /dev/null @@ -1,30 +0,0 @@ -#/** @file -# Memory Status Code Library for UEFI drivers -# -# Lib to provide memory journal status code reporting Routines -# Copyright (c) 2006, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = TemplateResetSystemLib - FILE_GUID = 40BAFDE5-4CC8-4FBE-A8BA-071890076E50 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = EfiResetSystemLib - - -[Sources.common] - ResetSystemLib.c - -[Packages] - MdePkg/MdePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - -[LibraryClasses] - IoLib - DebugLib diff --git a/EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf b/EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf deleted file mode 100644 index fdb93bf179..0000000000 --- a/EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf +++ /dev/null @@ -1,45 +0,0 @@ -#/** @file -# Reset Architectural Protocol Driver as defined in PI -# -# This Reset module simulates system reset by process exit on NT. -# Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = Reset - FILE_GUID = 16036A73-E8EF-46D0-953C-9B8E96527D13 - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = InitializeReset - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 -# - -[Sources.common] - reset.c - -[Packages] - MdePkg/MdePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - -[LibraryClasses] - UefiBootServicesTableLib - UefiDriverEntryPoint - DebugLib - EfiResetSystemLib - -[Protocols] - gEfiResetArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED - -[Depex] - TRUE - diff --git a/EmbeddedPkg/ResetRuntimeDxe/reset.c b/EmbeddedPkg/ResetRuntimeDxe/reset.c deleted file mode 100644 index 213963b519..0000000000 --- a/EmbeddedPkg/ResetRuntimeDxe/reset.c +++ /dev/null @@ -1,64 +0,0 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include -#include - -/** - Resets the entire platform. - - @param ResetType The type of reset to perform. - @param ResetStatus The status code for the reset. - @param DataSize The size, in bytes, of WatchdogData. - @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - Unicode string, optionally followed by additional binary data. - -**/ -VOID -EFIAPI -ResetSystemViaLib ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - LibResetSystem (ResetType, ResetStatus, DataSize, ResetData); - return; -} - -EFI_STATUS -EFIAPI -InitializeReset ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - - LibInitializeResetSystem (ImageHandle, SystemTable); - - SystemTable->RuntimeServices->ResetSystem = ResetSystemViaLib; - - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiResetArchProtocolGuid, - NULL, - NULL - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} -- cgit From b342070ce63075e7691cbd086ef8567cb02c372e Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 15 Apr 2024 09:46:29 +0100 Subject: OvmfPkg: Use heap memory for virtio-blk request The storage space for virtio-blk request header being shared with the host was from the stack as the request structure was a local function variable. A bug in the VMM can corrupt the stack space, and such issues can be very hard to debug. Note: This is only an issue with a normal guest VM (non-CCA). A CCA guest VM would perform bounce buffering for sharing the data and therefore not have this issue. Instead of using the stack for sharing the data with the host, memory can be allocated from the heap pool. However, pool allocations are not any safer in terms of pages being shared between different allocations, and so mapping a pool allocation for DMA may expose it to potential corruption by the VMM in exactly the same way. The only difference is the potential impact on program behaviour, which is much higher with the stack. Additionally, for guest-side corruption heap allocations can take advantage by turning on heap guard to help find the bug. Therefore, minor improvement can be achieved by allocating memory for the virtio-blk request header from the heap for sharing with the host. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Sami Mujawar --- OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c index 74ed52f9da..f881cde4c5 100644 --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c @@ -13,6 +13,7 @@ Copyright (C) 2012, Red Hat, Inc. Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Inc, All rights reserved.
+ Copyright (c) 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -240,7 +241,7 @@ SynchronousRequest ( ) { UINT32 BlockSize; - volatile VIRTIO_BLK_REQ Request; + volatile VIRTIO_BLK_REQ *Request; volatile UINT8 *HostStatus; VOID *HostStatusBuffer; DESC_INDICES Indices; @@ -273,15 +274,20 @@ SynchronousRequest ( // ASSERT (BufferSize % BlockSize == 0); + Request = AllocateZeroPool (sizeof (*Request)); + if (Request == NULL) { + return EFI_DEVICE_ERROR; + } + // // Prepare virtio-blk request header, setting zero size for flush. // IO Priority is homogeneously 0. // - Request.Type = RequestIsWrite ? - (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) : - VIRTIO_BLK_T_IN; - Request.IoPrio = 0; - Request.Sector = MultU64x32 (Lba, BlockSize / 512); + Request->Type = RequestIsWrite ? + (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) : + VIRTIO_BLK_T_IN; + Request->IoPrio = 0; + Request->Sector = MultU64x32 (Lba, BlockSize / 512); // // Host status is bi-directional (we preset with a value and expect the @@ -294,7 +300,8 @@ SynchronousRequest ( &HostStatusBuffer ); if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; + goto FreeBlkRequest; } HostStatus = HostStatusBuffer; @@ -306,8 +313,8 @@ SynchronousRequest ( Status = VirtioMapAllBytesInSharedBuffer ( Dev->VirtIo, VirtioOperationBusMasterRead, - (VOID *)&Request, - sizeof Request, + (VOID *)Request, + sizeof (*Request), &RequestDeviceAddress, &RequestMapping ); @@ -372,7 +379,7 @@ SynchronousRequest ( VirtioAppendDesc ( &Dev->Ring, RequestDeviceAddress, - sizeof Request, + sizeof (*Request), VRING_DESC_F_NEXT, &Indices ); @@ -454,6 +461,9 @@ FreeHostStatusBuffer: HostStatusBuffer ); +FreeBlkRequest: + FreePool ((VOID *)Request); + return Status; } -- cgit From 1fc55a3933b0d17430c2857629ee54abefaad7eb Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Mon, 15 Apr 2024 09:51:13 +0100 Subject: OvmfPkg: Use heap memory for virtio-scsi request The storage space for virtio-scsi request header being shared with the host was from the stack as the request structure was a local function variable. A bug in the VMM can corrupt the stack space, and such issues can be very hard to debug. Note: This is only an issue with a normal guest VM (non-CCA). A CCA guest VM would perform bounce buffering for sharing the data and therefore not have this issue. Instead of using the stack for sharing the data with the host, memory can be allocated from the heap pool. However, pool allocations are not any safer in terms of pages being shared between different allocations, and so mapping a pool allocation for DMA may expose it to potential corruption by the VMM in exactly the same way. The only difference is the potential impact on program behaviour, which is much higher with the stack. Additionally, for guest-side corruption heap allocations can take advantage by turning on heap guard to help find the bug. Therefore, minor improvement can be achieved by allocating memory for the virtio-scsi request header from the heap for sharing with the host. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Gerd Hoffmann Signed-off-by: Sami Mujawar --- OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c index 3705f5fc14..11e4d8703d 100644 --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c @@ -28,6 +28,7 @@ Copyright (C) 2012, Red Hat, Inc. Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Inc, All rights reserved.
+ Copyright (c) 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -430,7 +431,7 @@ VirtioScsiPassThru ( VSCSI_DEV *Dev; UINT16 TargetValue; EFI_STATUS Status; - volatile VIRTIO_SCSI_REQ Request; + volatile VIRTIO_SCSI_REQ *Request; volatile VIRTIO_SCSI_RESP *Response; VOID *ResponseBuffer; DESC_INDICES Indices; @@ -455,7 +456,10 @@ VirtioScsiPassThru ( InDataDeviceAddress = 0; OutDataDeviceAddress = 0; - ZeroMem ((VOID *)&Request, sizeof (Request)); + Request = AllocateZeroPool (sizeof (*Request)); + if (Request == NULL) { + return EFI_OUT_OF_RESOURCES; + } Dev = VIRTIO_SCSI_FROM_PASS_THRU (This); CopyMem (&TargetValue, Target, sizeof TargetValue); @@ -464,9 +468,9 @@ VirtioScsiPassThru ( OutDataBufferIsMapped = FALSE; InDataNumPages = 0; - Status = PopulateRequest (Dev, TargetValue, Lun, Packet, &Request); + Status = PopulateRequest (Dev, TargetValue, Lun, Packet, Request); if (EFI_ERROR (Status)) { - return Status; + goto FreeScsiRequest; } // @@ -475,13 +479,14 @@ VirtioScsiPassThru ( Status = VirtioMapAllBytesInSharedBuffer ( Dev->VirtIo, VirtioOperationBusMasterRead, - (VOID *)&Request, - sizeof Request, + (VOID *)Request, + sizeof (*Request), &RequestDeviceAddress, &RequestMapping ); if (EFI_ERROR (Status)) { - return ReportHostAdapterError (Packet); + Status = ReportHostAdapterError (Packet); + goto FreeScsiRequest; } // @@ -702,6 +707,9 @@ FreeInDataBuffer: UnmapRequestBuffer: Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RequestMapping); +FreeScsiRequest: + FreePool ((VOID *)Request); + return Status; } -- cgit From 3ada6c0db6a416a5bd539de6693a60cd57133e0b Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 15 Apr 2024 13:23:17 +0800 Subject: StandaloneMmPkg: Add LockBox Dependency Library The LockBox Dependency Library is designed for standalone MM environments where gBS are not accessible to indicates that LockBox API is readyfor use. For DXE drivers use lockbox APIs via a communication mechanism triggering an SMI, it's must to have the corresponding SMI handler pre-installed for interrupt management. To ensure orderly operations and proper notification, besides specified the guid in the [Depex] section of the .inf file. The installation of smi handler, along with the LockBox protocol marked by gEfiLockBoxProtocolGuid, must be informed to the DXE driver. This protocol installation signifies that the LockBox API is ready for use, and this functionality is implemented in the constructor of this library. Cc: Liming Gao Cc: Jiaxin Wu Cc: Ray Ni Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Reviewed-by: Jiaxin Wu Signed-off-by: Yuanhao Xie --- .../SmmLockBoxMmDependency.c | 50 ++++++++++++++++++++++ .../SmmLockBoxMmDependency.inf | 34 +++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c create mode 100644 StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf diff --git a/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c new file mode 100644 index 0000000000..143a62c200 --- /dev/null +++ b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c @@ -0,0 +1,50 @@ +/** @file + LockBox Dependency DXE Library. + + By installing the LockBox protocol with the gEfiLockBoxProtocolGuid, + it signals that the LockBox API is fully operational and ready for use. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +/** + The constructor function of SmmLockBoxMmDependency. + + It attempts to install the gEfiLockBoxProtocolGuid protocol into the system's DXE database + with NULL as notify. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the Management mode System Table. + + @retval EFI_SUCCESS The protocol was successfully installed into the DXE database. + @retval Others An error occurred while installing the protocol. +**/ +EFI_STATUS +EFIAPI +SmmLockBoxMmDependencyConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install NULL to DXE data base as notify + // + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEfiLockBoxProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf new file mode 100644 index 0000000000..14931a2925 --- /dev/null +++ b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf @@ -0,0 +1,34 @@ +## @file +# LockBox Dependency DXE Library. +# +# By installing the LockBox protocol with the gEfiLockBoxProtocolGuid, +# it signals that the LockBox API is fully operational and ready for use. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = SmmLockBoxMmDependency + FILE_GUID = c45ce910-7f8b-4f49-88e2-2c26c5743ee2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL + CONSTRUCTOR = SmmLockBoxMmDependencyConstructor + +[Sources] + SmmLockBoxMmDependency.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Protocols] + gEfiLockBoxProtocolGuid + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib -- cgit From a9158fe9a670cebbb9d361a1b7fc3075fdf33393 Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Fri, 5 Jul 2024 14:08:25 +0800 Subject: StandaloneMmPkg: Enable SmmLockBoxMmDependency. Cc: Liming Gao Cc: Jiaxin Wu Cc: Ray Ni Cc: Ard Biesheuvel Cc: Sami Mujawar Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Signed-off-by: Yuanhao Xie --- StandaloneMmPkg/StandaloneMmPkg.dsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index f548bf87d4..39aea898bb 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -1,7 +1,7 @@ ## @file # Standalone MM Platform. # -# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.
# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
# Copyright (C) Microsoft Corporation
# @@ -118,6 +118,7 @@ StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf + StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf [Components.AARCH64, Components.ARM] StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf -- cgit From eed43245dfdd6d616f7a7d72ba4ca52de3d59584 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 26 Jul 2024 11:50:33 -0400 Subject: CodeQlQueries.qls: Pin to the 1.1.0 codeq/cpp-queries pack The codeql/cpp-queries pack used in CodeQlQueries.qls was versioned 1.1.0 for the CodeQL CLI v2.18.1 release currently used. https://github.com/github/codeql/blob/codeql-cli/v2.18.1/cpp/ql/src/qlpack.yml This change pins that pack version to prevent the CodeQL CLI and pack from getting out of sync until explicitly updated. Signed-off-by: Michael Kubacki --- BaseTools/Plugin/CodeQL/CodeQlQueries.qls | 2 +- BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml | 7 +++++++ BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml | 7 +++++++ BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml | 7 +++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/BaseTools/Plugin/CodeQL/CodeQlQueries.qls b/BaseTools/Plugin/CodeQL/CodeQlQueries.qls index 34fa6b3665..0da9baf95d 100644 --- a/BaseTools/Plugin/CodeQL/CodeQlQueries.qls +++ b/BaseTools/Plugin/CodeQL/CodeQlQueries.qls @@ -2,7 +2,7 @@ - description: C++ queries - queries: '.' - from: codeql/cpp-queries + from: codeql/cpp-queries@1.1.0 ########################################################################################## # Queries diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml index 842c144f0b..3be80cb647 100644 --- a/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml +++ b/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml @@ -8,6 +8,13 @@ # In an environment where a platform might build in different operating systems, it is recommended to set # the scope for the appropriate CodeQL external dependency based on the host operating system being used. # +# ****VERSION UPDATE INSTRUCTIONS**** +# +# When updating the CodeQL CLI used here, update the corresponding codeql/cpp-queries version in CodeQlQueries.qls. +# Visit the `qlpack.yml` in the release branch for the CodeQL CLI to get the version to use there. For example, the +# CodeQL CLI 2.18.1 file is https://github.com/github/codeql/blob/codeql-cli-2.18.1/cpp/ql/src/qlpack.yml and the +# pack version there is 1.1.0. +# # Copyright (c) Microsoft Corporation. All rights reserved. # SPDX-License-Identifier: BSD-2-Clause-Patent ## diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml index 1972cde74b..e3fd40c2e1 100644 --- a/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml +++ b/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml @@ -6,6 +6,13 @@ # systems, it is recommended to set the scope for the appropriate CodeQL external dependency based on the # host operating system being used. # +# ****VERSION UPDATE INSTRUCTIONS**** +# +# When updating the CodeQL CLI used here, update the corresponding codeql/cpp-queries version in CodeQlQueries.qls. +# Visit the `qlpack.yml` in the release branch for the CodeQL CLI to get the version to use there. For example, the +# CodeQL CLI 2.18.1 file is https://github.com/github/codeql/blob/codeql-cli-2.18.1/cpp/ql/src/qlpack.yml and the +# pack version there is 1.1.0. +# # Copyright (c) Microsoft Corporation. All rights reserved. # SPDX-License-Identifier: BSD-2-Clause-Patent ## diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml index 28ad30e790..5e6add84f4 100644 --- a/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml +++ b/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml @@ -6,6 +6,13 @@ # systems, it is recommended to set the scope for the appropriate CodeQL external dependency based on the # host operating system being used. # +# ****VERSION UPDATE INSTRUCTIONS**** +# +# When updating the CodeQL CLI used here, update the corresponding codeql/cpp-queries version in CodeQlQueries.qls. +# Visit the `qlpack.yml` in the release branch for the CodeQL CLI to get the version to use there. For example, the +# CodeQL CLI 2.18.1 file is https://github.com/github/codeql/blob/codeql-cli-2.18.1/cpp/ql/src/qlpack.yml and the +# pack version there is 1.1.0. +# # Copyright (c) Microsoft Corporation. All rights reserved. # SPDX-License-Identifier: BSD-2-Clause-Patent ## -- cgit From 7e5a5ae154cb4c1e5c3d148a2ba21cc2764e96e6 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 30 Jul 2024 23:56:29 -0400 Subject: MdePkg/Acpi65.h: Fix GUID value Commit c5ef1f0 added Acpi65.h by copying and updating text from Acpi64.h. In that process, `0x624B` was updated to `0x6.5B` likely due to a find/replace regex being used. This restores the value. Signed-off-by: Michael Kubacki --- MdePkg/Include/IndustryStandard/Acpi65.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 685e08167c..218f909160 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -1621,7 +1621,7 @@ typedef struct { #define EFI_ACPI_6_5_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_5_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_5_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} -#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x6.5B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} +#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} -- cgit From 85fad9912c860927aec3953e213662ea1f397c23 Mon Sep 17 00:00:00 2001 From: Sachin Ganesh Date: Fri, 19 Jul 2024 14:26:47 +0530 Subject: MdePkg: Add PCI Express 6.0 Header Support PCI Express 6.0 Specification introduces new registers and modifies fields in existing ones. This commit syncs PciE headers with the spec update. Cc: Sergiy Yakovlev Cc: Felix Polyudov Cc: Dhanaraj V Cc: Ray Ni Cc: Liming Gao Signed-off-by: Sachin Ganesh --- MdePkg/Include/IndustryStandard/Pci.h | 2 +- MdePkg/Include/IndustryStandard/PciExpress21.h | 72 ++++++++++----- MdePkg/Include/IndustryStandard/PciExpress60.h | 121 +++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 22 deletions(-) create mode 100644 MdePkg/Include/IndustryStandard/PciExpress60.h diff --git a/MdePkg/Include/IndustryStandard/Pci.h b/MdePkg/Include/IndustryStandard/Pci.h index 42c00ac762..4220ad8a6f 100644 --- a/MdePkg/Include/IndustryStandard/Pci.h +++ b/MdePkg/Include/IndustryStandard/Pci.h @@ -9,7 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _PCI_H_ #define _PCI_H_ -#include +#include #include #endif diff --git a/MdePkg/Include/IndustryStandard/PciExpress21.h b/MdePkg/Include/IndustryStandard/PciExpress21.h index 341e3e5639..b437ca5c1e 100644 --- a/MdePkg/Include/IndustryStandard/PciExpress21.h +++ b/MdePkg/Include/IndustryStandard/PciExpress21.h @@ -40,7 +40,7 @@ typedef union { UINT16 SlotImplemented : 1; UINT16 InterruptMessageNumber : 5; UINT16 Undefined : 1; - UINT16 Reserved : 1; + UINT16 FlitModeSupported : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_CAPABILITY; @@ -64,11 +64,13 @@ typedef union { UINT32 EndpointL1AcceptableLatency : 3; UINT32 Undefined : 3; UINT32 RoleBasedErrorReporting : 1; - UINT32 Reserved : 2; + UINT32 ErrCorSubclassCapable : 1; + UINT32 RxMpsFixed : 1; UINT32 CapturedSlotPowerLimitValue : 8; UINT32 CapturedSlotPowerLimitScale : 2; UINT32 FunctionLevelReset : 1; - UINT32 Reserved2 : 3; + UINT32 MixedMpsSupported : 1; + UINT32 Reserved2 : 2; } Bits; UINT32 Uint32; } PCI_REG_PCIE_DEVICE_CAPABILITY; @@ -111,13 +113,14 @@ typedef union { typedef union { struct { - UINT16 CorrectableError : 1; - UINT16 NonFatalError : 1; - UINT16 FatalError : 1; - UINT16 UnsupportedRequest : 1; - UINT16 AuxPower : 1; - UINT16 TransactionsPending : 1; - UINT16 Reserved : 10; + UINT16 CorrectableError : 1; + UINT16 NonFatalError : 1; + UINT16 FatalError : 1; + UINT16 UnsupportedRequest : 1; + UINT16 AuxPower : 1; + UINT16 TransactionsPending : 1; + UINT16 EmergencyPowerReductionDetected : 1; + UINT16 Reserved : 9; } Bits; UINT16 Uint16; } PCI_REG_PCIE_DEVICE_STATUS; @@ -146,7 +149,7 @@ typedef union { typedef union { struct { UINT16 AspmControl : 2; - UINT16 Reserved : 1; + UINT16 PtmPropagationDelayB : 1; UINT16 ReadCompletionBoundary : 1; UINT16 LinkDisable : 1; UINT16 RetrainLink : 1; @@ -156,6 +159,9 @@ typedef union { UINT16 HardwareAutonomousWidthDisable : 1; UINT16 LinkBandwidthManagementInterrupt : 1; UINT16 LinkAutonomousBandwidthInterrupt : 1; + UINT16 SrisClocking : 1; + UINT16 FlitModeDisable : 1; + UINT16 DrsSignalingControl : 2; } Bits; UINT16 Uint16; } PCI_REG_PCIE_LINK_CONTROL; @@ -205,7 +211,9 @@ typedef union { UINT16 PowerController : 1; UINT16 ElectromechanicalInterlock : 1; UINT16 DataLinkLayerStateChanged : 1; - UINT16 Reserved : 3; + UINT16 AutoSlotPowerLimitDisable : 1; + UINT16 InbandPdDisable : 1; + UINT16 Reserved : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_SLOT_CONTROL; @@ -233,7 +241,8 @@ typedef union { UINT16 SystemErrorOnFatalError : 1; UINT16 PmeInterrupt : 1; UINT16 CrsSoftwareVisibility : 1; - UINT16 Reserved : 11; + UINT16 NoNfmSubtree : 1; + UINT16 Reserved : 10; } Bits; UINT16 Uint16; } PCI_REG_PCIE_ROOT_CONTROL; @@ -268,7 +277,7 @@ typedef union { UINT32 NoRoEnabledPrPrPassing : 1; UINT32 LtrMechanism : 1; UINT32 TphCompleter : 2; - UINT32 LnSystemCLS : 2; + UINT32 Reserved : 2; UINT32 TenBitTagCompleterSupported : 1; UINT32 TenBitTagRequesterSupported : 1; UINT32 Obff : 2; @@ -277,7 +286,9 @@ typedef union { UINT32 MaxEndEndTlpPrefixes : 2; UINT32 EmergencyPowerReductionSupported : 2; UINT32 EmergencyPowerReductionInitializationRequired : 1; - UINT32 Reserved3 : 4; + UINT32 Reserved2 : 1; + UINT32 DmwrCompleter : 1; + UINT32 DmwrLengths : 2; UINT32 FrsSupported : 1; } Bits; UINT32 Uint32; @@ -330,10 +341,15 @@ typedef union { typedef union { struct { - UINT32 Reserved : 1; - UINT32 LinkSpeedsVector : 7; - UINT32 Crosslink : 1; - UINT32 Reserved2 : 23; + UINT32 Reserved : 1; + UINT32 LinkSpeedsVector : 7; + UINT32 Crosslink : 1; + UINT32 LowerSkpOsGeneration : 7; + UINT32 LowerSkpOsReception : 7; + UINT32 RetimerPresenceDetect : 1; + UINT32 TwoRetimersPresenceDetect : 1; + UINT32 Reserved2 : 6; + UINT32 DrsSupported : 1; } Bits; UINT32 Uint32; } PCI_REG_PCIE_LINK_CAPABILITY2; @@ -360,11 +376,25 @@ typedef union { UINT16 EqualizationPhase2Successful : 1; UINT16 EqualizationPhase3Successful : 1; UINT16 LinkEqualizationRequest : 1; - UINT16 Reserved : 10; + UINT16 RetimerPresence : 1; + UINT16 TwoRetimersPresence : 1; + UINT16 CrosslinkResolution : 2; + UINT16 FlitModeStatus : 1; + UINT16 Reserved : 1; + UINT16 DownstreamComponentPresence : 3; + UINT16 DRSMessageReceived : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_LINK_STATUS2; +typedef union { + struct { + UINT32 InbandPdDisable : 1; + UINT32 Reserved : 30; + } Bits; + UINT32 Uint32; +} PCI_REG_PCIE_SLOT_CAPABILITY2; + typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; PCI_REG_PCIE_CAPABILITY Capability; @@ -386,7 +416,7 @@ typedef struct { PCI_REG_PCIE_LINK_CAPABILITY2 LinkCapability2; PCI_REG_PCIE_LINK_CONTROL2 LinkControl2; PCI_REG_PCIE_LINK_STATUS2 LinkStatus2; - UINT32 SlotCapability2; + PCI_REG_PCIE_SLOT_CAPABILITY2 SlotCapability2; UINT16 SlotControl2; UINT16 SlotStatus2; } PCI_CAPABILITY_PCIEXP; diff --git a/MdePkg/Include/IndustryStandard/PciExpress60.h b/MdePkg/Include/IndustryStandard/PciExpress60.h new file mode 100644 index 0000000000..5427ddde38 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/PciExpress60.h @@ -0,0 +1,121 @@ +/** @file +Support for the PCI Express 6.0 standard. + +This header file may not define all structures. Please extend as required. + +Copyright (c) 2024, American Megatrends International LLC. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCIEXPRESS60_H_ +#define PCIEXPRESS60_H_ + +#include + +/// The Physical Layer PCI Express Extended Capability definitions. +/// +/// Based on section 7.7.7 of PCI Express Base Specification 6.0. +///@{ +#define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_64_0_ID 0x0031 +#define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_64_0_VER1 0x1 + +// Register offsets from Physical Layer PCI-E Ext Cap Header +#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES_OFFSET 0x04 +#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL_OFFSET 0x08 +#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS_OFFSET 0x0C +#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL_OFFSET 0x10 + +#define PCI_EXPRESS_EXTENDED_CAPABILITY_DEVICE3_ID 0x002F +#define PCI_EXPRESS_EXTENDED_CAPABILITY_DEVICE3_VER1 0x1 + +#define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_3_OFFSET 0x04 +#define EFI_PCIE_CAPABILITY_DEVICE_CONTROL_3_OFFSET 0x08 +#define EFI_PCIE_CAPABILITY_DEVICE_STATUS_3_OFFSET 0x0C + +#pragma pack(1) + +typedef union { + struct { + UINT32 Reserved : 32; // Reserved bit 0:31 + } Bits; + UINT32 Uint32; +} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES; + +typedef union { + struct { + UINT32 Reserved : 32; // Reserved bit 0:31 + } Bits; + UINT32 Uint32; +} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL; + +typedef union { + struct { + UINT32 EqualizationComplete : 1; // bit 0 + UINT32 EqualizationPhase1Success : 1; // bit 1 + UINT32 EqualizationPhase2Success : 1; // bit 2 + UINT32 EqualizationPhase3Success : 1; // bit 3 + UINT32 LinkEqualizationRequest : 1; // bit 4 + UINT32 TransmitterPrecodingOn : 1; // bit 5 + UINT32 TransmitterPrecodeRequest : 1; // bit 6 + UINT32 NoEqualizationNeededRcvd : 1; // bit 7 + UINT32 Reserved : 24; // Reserved bit 8:31 + } Bits; + UINT32 Uint32; +} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS; + +typedef union { + struct { + UINT8 DownstreamPortTransmitterPreset : 4; // bit 0..3 + UINT8 UpstreamPortTransmitterPreset : 4; // bit 4..7 + } Bits; + UINT8 Uint8; +} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL; + +typedef struct { + PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; + PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES Capablities; + PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL Control; + PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS Status; + PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL LaneEqualizationControl[1]; +} PCI_EXPRESS_EXTENDED_CAPABILITIES_PHYSICAL_LAYER_64_0; +///@} + +typedef union { + struct { + UINT32 DmwrRequestRouting : 1; // bit 0 + UINT32 FourteenBitTagCompleter : 1; // bit 1 + UINT32 FourteenBitTagRequester : 1; // bit 2 + UINT32 ReceiverL0p : 1; // bit 3 + UINT32 PortL0pExitLatencyLatency : 3; // bit 4..6 + UINT32 RetimerL0pExit : 3; // bit 7..9 + UINT32 Reserved : 22; // bit 10..31 + } Bits; + UINT32 Uint32; +} PCI_REG_PCIE_DEVICE_CAPABILITY3; + +typedef union { + struct { + UINT32 DmwrRequesterEnable : 1; // bit 0 + UINT32 DmwrEgressBlocking : 1; // bit 1 + UINT32 FourteenBitTagRequesterEnable : 1; // bit 2 + UINT32 L0pEnable : 1; // bit 3 + UINT32 TargetLinkWidth : 3; // bit 4..6 + UINT32 Reserved : 25; // bit 7..31 + } Bits; + UINT32 Uint32; +} PCI_REG_PCIE_DEVICE_CONTROL3; + +typedef union { + struct { + UINT32 InitialLinkWidth : 3; // bit 0..2 + UINT32 SegmentCaptured : 1; // bit 3 + UINT32 RemoteL0pSupported : 1; // bit 4 + UINT32 Reserved : 27; // bit 5..31 + } Bits; + UINT32 Uint32; +} PCI_REG_PCIE_DEVICE_STATUS3; + +#pragma pack() + +#endif -- cgit From 71b9bda1ace32a479d471f26b0e516d0618053bc Mon Sep 17 00:00:00 2001 From: Antaeus Kleinert-Strand <59579659+antklein@users.noreply.github.com> Date: Thu, 26 Oct 2023 15:03:19 -0700 Subject: BaseTools/Scripts/BinToPcd.py: Update regex strings to use raw strings. With Python 3.12 invalid escape sequences now generate warning messages. This change fixes the problem exposed by the warning message. ``` BaseTools/Scripts\BinToPcd.py:40: SyntaxWarning: invalid escape sequence BaseTools\Scripts\BinToPcd.py:46: SyntaxWarning: invalid escape sequence ``` Signed-off-by: Aaron Pop --- BaseTools/Scripts/BinToPcd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/Scripts/BinToPcd.py b/BaseTools/Scripts/BinToPcd.py index be726cc6d8..43fc458b04 100644 --- a/BaseTools/Scripts/BinToPcd.py +++ b/BaseTools/Scripts/BinToPcd.py @@ -37,13 +37,13 @@ if __name__ == '__main__': return Value def ValidatePcdName (Argument): - if re.split ('[a-zA-Z\_][a-zA-Z0-9\_]*\.[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']: + if re.split (r'[a-zA-Z\_][a-zA-Z0-9\_]*\.[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']: Message = '{Argument} is not in the form .'.format (Argument = Argument) raise argparse.ArgumentTypeError (Message) return Argument def ValidateGuidName (Argument): - if re.split ('[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']: + if re.split (r'[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']: Message = '{Argument} is not a valid GUID C name'.format (Argument = Argument) raise argparse.ArgumentTypeError (Message) return Argument -- cgit From a72d93e1631852b19e2a996fa5fa81109d5c25f4 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Thu, 2 Nov 2023 13:53:54 +0100 Subject: MdePkg/BaseLib: AARCH64: Add ArmReadCntPctReg() To enable AARCH64 native instruction support for Openssl, some interfaces must be implemented. OPENSSL_rdtsc() requests an access to a counter to get some non-trusted entropy. Add ArmReadCntPctReg() to read system count. A similar ArmReadCntPct() function is available in the ArmPkg, but the CryptoPkg where OPENSSL_rdtsc will reside cannot rely on the ArmPkg. Signed-off-by: Pierre Gondois --- MdePkg/Include/Library/BaseLib.h | 15 +++++++++++ MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S | 30 ++++++++++++++++++++++ .../Library/BaseLib/AArch64/ArmReadCntPctReg.asm | 30 ++++++++++++++++++++++ MdePkg/Library/BaseLib/BaseLib.inf | 4 ++- 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 95f805599d..024608fe4b 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -7,6 +7,7 @@ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
Copyright (c) Microsoft Corporation.
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
+Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -126,6 +127,20 @@ typedef struct { #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8 +/** + Reads the current value of CNTPCT_EL0 register. + + Reads and returns the current value of CNTPCT_EL0. + This function is only available on AARCH64. + + @return The current value of CNTPCT_EL0 +**/ +UINT64 +EFIAPI +ArmReadCntPctReg ( + VOID + ); + #endif // defined (MDE_CPU_AARCH64) #if defined (MDE_CPU_RISCV64) diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S new file mode 100644 index 0000000000..cfabd7ad8f --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------ +# +# ArmReadCntPctReg() for AArch64 +# +# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +GCC_ASM_EXPORT(ArmReadCntPctReg) + +#/** +# Reads the CNTPCT_EL0 Register. +# +# @return The contents of the CNTPCT_EL0 register. +# +#**/ +#UINT64 +#EFIAPI +#ArmReadCntPctReg ( +# VOID +# ); +# +ASM_PFX(ArmReadCntPctReg): + AARCH64_BTI(c) + mrs x0, cntpct_el0 + ret diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm new file mode 100644 index 0000000000..98823fdd5e --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm @@ -0,0 +1,30 @@ +;------------------------------------------------------------------------------ +; +; ArmReadCntPctReg() for AArch64 +; +; Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + + EXPORT ArmReadCntPctReg + AREA BaseLib_LowLevel, CODE, READONLY + +;/** +; Reads the CNTPCT_EL0 Register. +; +; @return The contents of the CNTPCT_EL0 register. +; +;**/ +;UINT64 +;EFIAPI +;ArmReadCntPctReg ( +; VOID +; ); +; +ArmReadCntPctReg + mrs x0, cntpct_el0 + ret + + END diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 26e66a8d67..96fc722a07 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -3,7 +3,7 @@ # # Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
-# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# Portions copyright (c) 2011 - 2024, Arm Limited. All rights reserved.
# Copyright (c) 2020 - 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -378,6 +378,7 @@ AArch64/SetJumpLongJump.S | GCC AArch64/CpuBreakpoint.S | GCC AArch64/SpeculationBarrier.S | GCC + AArch64/ArmReadCntPctReg.S | GCC AArch64/MemoryFence.asm | MSFT AArch64/SwitchStack.asm | MSFT @@ -387,6 +388,7 @@ AArch64/SetJumpLongJump.asm | MSFT AArch64/CpuBreakpoint.asm | MSFT AArch64/SpeculationBarrier.asm | MSFT + AArch64/ArmReadCntPctReg.asm | MSFT [Sources.RISCV64] Math64.c -- cgit From 30e53f8b5efe0112eda7014cf846007fb0fb425f Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 4 Oct 2023 14:26:05 +0200 Subject: MdePkg/BaseLib: AARCH64: Add ArmReadIdAA64Isar0Reg() To enable AARCH64 native instruction support for Openssl, some interfaces must be implemented. OPENSSL_cpuid_setup() allows to probe the supported features of the platform. Add ArmReadIdAA64Isar0Reg() to read the AA64Isar0, containing Arm64 instruction capabilities. A similar ArmReadIdAA64Isar0() function is available in the ArmPkg, but the CryptoPkg where OPENSSL_cpuid_setup will reside cannot rely on the ArmPkg. Signed-off-by: Pierre Gondois --- MdePkg/Include/Library/BaseLib.h | 72 ++++++++++++++++++++++ .../BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S | 30 +++++++++ .../BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm | 30 +++++++++ MdePkg/Library/BaseLib/BaseLib.inf | 2 + 4 files changed, 134 insertions(+) create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 024608fe4b..aec84c0184 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -141,6 +141,78 @@ ArmReadCntPctReg ( VOID ); +// +// Bit shifts for the ID_AA64ISAR0_EL1 register. +// +#define ARM_ID_AA64ISAR0_EL1_AES_SHIFT (4U) +#define ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT (8U) +#define ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT (12U) +#define ARM_ID_AA64ISAR0_EL1_CRC32_SHIFT (16U) +#define ARM_ID_AA64ISAR0_EL1_ATOMIC_SHIFT (20U) +#define ARM_ID_AA64ISAR0_EL1_RDM_SHIFT (28U) +#define ARM_ID_AA64ISAR0_EL1_SHA3_SHIFT (32U) +#define ARM_ID_AA64ISAR0_EL1_SM3_SHIFT (36U) +#define ARM_ID_AA64ISAR0_EL1_SM4_SHIFT (40U) +#define ARM_ID_AA64ISAR0_EL1_DP_SHIFT (44U) +#define ARM_ID_AA64ISAR0_EL1_FHM_SHIFT (48U) +#define ARM_ID_AA64ISAR0_EL1_TS_SHIFT (52U) +#define ARM_ID_AA64ISAR0_EL1_TLB_SHIFT (56U) +#define ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT (60U) + +// +// Bit masks for the ID_AA64ISAR0_EL1 fields. +// +#define ARM_ID_AA64ISAR0_EL1_AES_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SHA1_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SHA2_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_CRC32_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_ATOMIC_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_RDM_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SHA3_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SM3_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SM4_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_DP_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_FHM_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_TS_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_TLB_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_RNDR_MASK (0xFU) + +// +// Bit masks for the ID_AA64ISAR0_EL1 field values. +// +#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_AES_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_SHA1_FEAT_SHA1_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA256_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_CRC32_HAVE_CRC32_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_ATOMIC_FEAT_LSE_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_RDM_FEAT_RDM_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SHA3_FEAT_SHA3_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SM3_FEAT_SM3_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SM4_FEAT_SM4_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_DP_FEAT_DOTPROD_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_FHM_FEAT_FHM_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM2_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIOS_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIRANGE_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_RNDR_FEAT_RNG_MASK (0x1U) + +/** + Reads the current value of ID_AA64ISAR0_EL1 register. + + Reads and returns the current value of ID_AA64ISAR0_EL1. + This function is only available on AARCH64. + + @return The current value of ID_AA64ISAR0_EL1 +**/ +UINT64 +EFIAPI +ArmReadIdAA64Isar0Reg ( + VOID + ); + #endif // defined (MDE_CPU_AARCH64) #if defined (MDE_CPU_RISCV64) diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S new file mode 100644 index 0000000000..4e61b869a4 --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------ +# +# ArmReadIdAA64Isar0Reg() for AArch64 +# +# Copyright (c) 2021, NUVIA Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +GCC_ASM_EXPORT(ArmReadIdAA64Isar0Reg) + +#/** +# Reads the ID_AA64ISAR0 Register. +# +# @return The contents of the ID_AA64ISAR0 register. +# +#**/ +#UINT64 +#EFIAPI +#ArmReadIdAA64Isar0Reg ( +# VOID +# ); +# +ASM_PFX(ArmReadIdAA64Isar0Reg): + AARCH64_BTI(c) + mrs x0, id_aa64isar0_el1 + ret diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm new file mode 100644 index 0000000000..790fb905d0 --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm @@ -0,0 +1,30 @@ +;------------------------------------------------------------------------------ +; +; ArmReadIdAA64Isar0Reg() for AArch64 +; +; Copyright (c) 2021, NUVIA Inc. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + + EXPORT ArmReadIdAA64Isar0Reg + AREA BaseLib_LowLevel, CODE, READONLY + +;/** +; Reads the ID_AA64ISAR0 Register. +; +; @return The contents of the ID_AA64ISAR0 register. +; +;**/ +;UINT64 +;EFIAPI +;ArmReadIdAA64Isar0Reg ( +; VOID +; ); +; +ArmReadIdAA64Isar0Reg + mrs x0, id_aa64isar0_el1 + ret + + END diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 96fc722a07..e3336c5dfb 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -379,6 +379,7 @@ AArch64/CpuBreakpoint.S | GCC AArch64/SpeculationBarrier.S | GCC AArch64/ArmReadCntPctReg.S | GCC + AArch64/ArmReadIdAA64Isar0Reg.S | GCC AArch64/MemoryFence.asm | MSFT AArch64/SwitchStack.asm | MSFT @@ -389,6 +390,7 @@ AArch64/CpuBreakpoint.asm | MSFT AArch64/SpeculationBarrier.asm | MSFT AArch64/ArmReadCntPctReg.asm | MSFT + AArch64/ArmReadIdAA64Isar0Reg.asm | MSFT [Sources.RISCV64] Math64.c -- cgit From 1715d672310a318ce441d27a3515d371329f8b5b Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 4 Oct 2023 14:27:17 +0200 Subject: MdePkg/BaseRngLib: Prefer ArmReadIdAA64Isar0Reg() over ArmReadIdIsar0() A ArmReadIdAA64Isar0Reg() function was recently added to BaseLib. Use it instead of its ArmReadIdIsar0() equivalent, which was private to the BaseRngLib library. This also allows to avoid the confusion between the following registers: - ID_ISAR0_EL1: allows to probe for Divide instructions, Debug instructions, ... - ID_AA64ISAR0_EL1: AARCH64 specific register allowing to probe for AESE, RNDR, ... instructions Signed-off-by: Pierre Gondois --- MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S | 30 ---------------------- .../Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm | 30 ---------------------- MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 12 --------- MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 10 ++------ MdePkg/Library/BaseRngLib/BaseRngLib.inf | 2 -- 5 files changed, 2 insertions(+), 82 deletions(-) delete mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S delete mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S deleted file mode 100644 index d30b63fe5c..0000000000 --- a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S +++ /dev/null @@ -1,30 +0,0 @@ -#------------------------------------------------------------------------------ -# -# ArmReadIdIsar0() for AArch64 -# -# Copyright (c) 2021, NUVIA Inc. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#------------------------------------------------------------------------------ - -.text -.p2align 2 -GCC_ASM_EXPORT(ArmReadIdIsar0) - -#/** -# Reads the ID_AA64ISAR0 Register. -# -# @return The contents of the ID_AA64ISAR0 register. -# -#**/ -#UINT64 -#EFIAPI -#ArmReadIdIsar0 ( -# VOID -# ); -# -ASM_PFX(ArmReadIdIsar0): - AARCH64_BTI(c) - mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register - ret diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm deleted file mode 100644 index 1d9f9a808c..0000000000 --- a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm +++ /dev/null @@ -1,30 +0,0 @@ -;------------------------------------------------------------------------------ -; -; ArmReadIdIsar0() for AArch64 -; -; Copyright (c) 2021, NUVIA Inc. All rights reserved.
-; -; SPDX-License-Identifier: BSD-2-Clause-Patent -; -;------------------------------------------------------------------------------ - - EXPORT ArmReadIdIsar0 - AREA BaseLib_LowLevel, CODE, READONLY - -;/** -; Reads the ID_AA64ISAR0 Register. -; -; @return The contents of the ID_AA64ISAR0 register. -; -;**/ -;UINT64 -;EFIAPI -;ArmReadIdIsar0 ( -; VOID -; ); -; -ArmReadIdIsar0 - mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register - ret - - END diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h index 2d6ef48ab9..b4b3c97071 100644 --- a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h +++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h @@ -27,16 +27,4 @@ ArmRndr ( OUT UINT64 *Rand ); -/** - Reads the ID_AA64ISAR0 Register. - - @return The contents of the ID_AA64ISAR0 register. - -**/ -UINT64 -EFIAPI -ArmReadIdIsar0 ( - VOID - ); - #endif /* ARM_RNG_H_ */ diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c index 3a556a2e3f..2c53443840 100644 --- a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c +++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c @@ -21,11 +21,6 @@ STATIC BOOLEAN mRndrSupported; -// -// Bit mask used to determine if RNDR instruction is supported. -// -#define RNDR_MASK ((UINT64)MAX_UINT16 << 60U) - /** The constructor function checks whether or not RNDR instruction is supported by the host hardware. @@ -49,9 +44,8 @@ BaseRngLibConstructor ( // Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by // MSR. A non-zero value indicates that the processor supports the RNDR instruction. // - Isar0 = ArmReadIdIsar0 (); - - mRndrSupported = ((Isar0 & RNDR_MASK) != 0); + Isar0 = ArmReadIdAA64Isar0Reg (); + mRndrSupported = !!((Isar0 >> ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT) & ARM_ID_AA64ISAR0_EL1_RNDR_MASK); return EFI_SUCCESS; } diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf b/MdePkg/Library/BaseRngLib/BaseRngLib.inf index a1614a900f..53833a76b2 100644 --- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf +++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -38,10 +38,8 @@ AArch64/Rndr.c AArch64/ArmRng.h - AArch64/ArmReadIdIsar0.S | GCC AArch64/ArmRng.S | GCC - AArch64/ArmReadIdIsar0.asm | MSFT AArch64/ArmRng.asm | MSFT [Guids.AARCH64] -- cgit From 952ecf53f9cbe80b0ec033e7acb29733bd1afed9 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 4 Oct 2023 15:19:20 +0200 Subject: CryptoPkg/OpensslLib: Add native instruction support for AARCH64 Add native instruction support for AARCH64. Signed-off-by: Pierre Gondois --- CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf | 23 ++++++++++++++++++++-- .../Library/OpensslLib/OpensslLibFullAccel.inf | 23 ++++++++++++++++++++-- CryptoPkg/Library/OpensslLib/UefiAsm.conf | 6 ++++++ CryptoPkg/Library/OpensslLib/configure.py | 6 +++++- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf index a37347fbbf..6d328dddb1 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf @@ -1,10 +1,11 @@ ## @file # This module provides OpenSSL Library implementation with TLS features # along with performance optimized implementations of SHA1, SHA256, SHA512, -# AESNI, VPAED, and GHASH for IA32 and X64. +# AESNI, VPAED, and GHASH for IA32 and X64 and AARCH64. # # Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.
# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -24,9 +25,10 @@ DEFINE OPENSSL_FLAGS = -DL_ENDIAN -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DEDK2_OPENSSL_NOEC=1 DEFINE OPENSSL_FLAGS_IA32 = -DAES_ASM -DGHASH_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM DEFINE OPENSSL_FLAGS_X64 = -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DKECCAK1600_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM + DEFINE OPENSSL_FLAGS_AARCH64 = # -# VALID_ARCHITECTURES = IA32 X64 +# VALID_ARCHITECTURES = IA32 X64 AARCH64 # [Sources] @@ -1326,6 +1328,10 @@ $(OPENSSL_GEN_PATH)/X64-GCC/crypto/sha/sha512-x86_64.s | GCC # Autogenerated files list ends here +[Sources.AARCH64] +# Autogenerated files list starts here +# Autogenerated files list ends here + [Packages] MdePkg/MdePkg.dec CryptoPkg/CryptoPkg.dec @@ -1403,3 +1409,16 @@ # commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.) XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -w -std=c99 -Wno-error=uninitialized XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -w -std=c99 -Wno-error=uninitialized + + GCC:*_*_AARCH64_CC_FLAGS = $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_AARCH64) -Wno-error=format -Wno-format -D_BITS_STDINT_UINTN_H -D_BITS_STDINT_INTN_H + + # + # AARCH64 uses strict alignment and avoids SIMD registers for code that may execute + # with the MMU off. This involves SEC, PEI_CORE and PEIM modules as well as BASE + # libraries, given that they may be included into such modules. + # This library, even though of the BASE type, is never used in such cases, and + # avoiding the SIMD register file (which is shared with the FPU) prevents the + # compiler from successfully building some of the OpenSSL source files that + # use floating point types, so clear the flags here. + # + GCC:*_*_AARCH64_CC_XIPFLAGS == diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf index 780d5febd7..e9f0fa94bf 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf @@ -1,7 +1,7 @@ ## @file # This module provides OpenSSL Library implementation with ECC and TLS # features along with performance optimized implementations of SHA1, -# SHA256, SHA512 AESNI, VPAED, and GHASH for IA32 and X64. +# SHA256, SHA512 AESNI, VPAED, and GHASH for IA32 and X64 and AARCH64. # # This library should be used if a module module needs ECC in TLS, or # asymmetric cryptography services such as X509 certificate or PEM format @@ -10,6 +10,7 @@ # # Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.
# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -29,9 +30,10 @@ DEFINE OPENSSL_FLAGS = -DL_ENDIAN -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE DEFINE OPENSSL_FLAGS_IA32 = -DAES_ASM -DGHASH_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM DEFINE OPENSSL_FLAGS_X64 = -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DKECCAK1600_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM + DEFINE OPENSSL_FLAGS_AARCH64 = # -# VALID_ARCHITECTURES = IA32 X64 +# VALID_ARCHITECTURES = IA32 X64 AARCH64 # [Sources] @@ -1429,6 +1431,10 @@ $(OPENSSL_GEN_PATH)/X64-GCC/crypto/sha/sha512-x86_64.s | GCC # Autogenerated files list ends here +[Sources.AARCH64] +# Autogenerated files list starts here +# Autogenerated files list ends here + [Packages] MdePkg/MdePkg.dec CryptoPkg/CryptoPkg.dec @@ -1506,3 +1512,16 @@ # commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.) XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -w -std=c99 -Wno-error=uninitialized XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -w -std=c99 -Wno-error=uninitialized + + GCC:*_*_AARCH64_CC_FLAGS = $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_AARCH64) -Wno-error=format -Wno-format -D_BITS_STDINT_UINTN_H -D_BITS_STDINT_INTN_H + + # + # AARCH64 uses strict alignment and avoids SIMD registers for code that may execute + # with the MMU off. This involves SEC, PEI_CORE and PEIM modules as well as BASE + # libraries, given that they may be included into such modules. + # This library, even though of the BASE type, is never used in such cases, and + # avoiding the SIMD register file (which is shared with the FPU) prevents the + # compiler from successfully building some of the OpenSSL source files that + # use floating point types, so clear the flags here. + # + GCC:*_*_AARCH64_CC_XIPFLAGS == diff --git a/CryptoPkg/Library/OpensslLib/UefiAsm.conf b/CryptoPkg/Library/OpensslLib/UefiAsm.conf index 907582f93e..98a8eb01ac 100644 --- a/CryptoPkg/Library/OpensslLib/UefiAsm.conf +++ b/CryptoPkg/Library/OpensslLib/UefiAsm.conf @@ -2,6 +2,7 @@ # UEFI assembly openssl configuration targets. # # Copyright (c) 2020, Intel Corporation. All rights reserved.
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -28,4 +29,9 @@ my %targets = ( perlasm_scheme => "elf", asm_arch => "x86_64", }, + "UEFI-AARCH64-GCC" => { + inherit_from => [ "UEFI" ], + asm_arch => "aarch64", + perlasm_scheme => "linux64-aarch64", + }, ); diff --git a/CryptoPkg/Library/OpensslLib/configure.py b/CryptoPkg/Library/OpensslLib/configure.py index 4243ca4c25..dc09124f44 100755 --- a/CryptoPkg/Library/OpensslLib/configure.py +++ b/CryptoPkg/Library/OpensslLib/configure.py @@ -262,6 +262,7 @@ def sources_filter_fn(filename): 'provider_predefined.c', 'ecp_nistz256.c', 'x86_64-gcc.c', + 'armcap.c', ] for item in exclude: if item in filename: @@ -353,7 +354,8 @@ def main(): sources = {} defines = {} for asm in [ 'UEFI-IA32-MSFT', 'UEFI-IA32-GCC', - 'UEFI-X64-MSFT', 'UEFI-X64-GCC']: + 'UEFI-X64-MSFT', 'UEFI-X64-GCC', + 'UEFI-AARCH64-GCC']: (uefi, arch, cc) = asm.split('-') archcc = f'{arch}-{cc}' @@ -375,6 +377,8 @@ def main(): x64accel = sources['X64'] + sources['X64-MSFT'] + sources['X64-GCC'] update_inf(inf, ia32accel, 'IA32', defines['IA32']) update_inf(inf, x64accel, 'X64', defines['X64']) + aarch64accel = sources['AARCH64'] + sources['AARCH64-GCC'] + update_inf(inf, aarch64accel, 'AARCH64', defines['AARCH64']) # noaccel - ec enabled openssl_configure(openssldir, 'UEFI', ec = True); -- cgit From 9403422f214acf2a82821836bbf6dcdee2beb491 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Mon, 23 Oct 2023 14:29:14 +0200 Subject: CryptoPkg/OpensslLib: Generate files for AARCH64 native support Generate AARCH64 related files and update .inf files, running: python CryptoPkg/Library/OpensslLib/configure.py Signed-off-by: Pierre Gondois --- .../OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S | 3180 ++++++++++ .../AARCH64-GCC/crypto/aes/vpaes-armv8.S | 1196 ++++ .../OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S | 129 + .../OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S | 2124 +++++++ .../AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S | 4242 +++++++++++++ .../AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S | 6389 ++++++++++++++++++++ .../AARCH64-GCC/crypto/modes/ghashv8-armx.S | 552 ++ .../AARCH64-GCC/crypto/sha/keccak1600-armv8.S | 1009 ++++ .../OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S | 1211 ++++ .../AARCH64-GCC/crypto/sha/sha256-armv8.S | 2051 +++++++ .../AARCH64-GCC/crypto/sha/sha512-armv8.S | 1606 +++++ CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf | 621 +- .../Library/OpensslLib/OpensslLibFullAccel.inf | 670 +- 13 files changed, 24978 insertions(+), 2 deletions(-) create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S new file mode 100644 index 0000000000..5c50b4a018 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S @@ -0,0 +1,3180 @@ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=7 +.arch armv8-a+crypto +.text +.align 5 +.Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.globl aes_v8_set_encrypt_key +.type aes_v8_set_encrypt_key,%function +.align 5 +aes_v8_set_encrypt_key: +.Lenc_key: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x3,#-1 + cmp x0,#0 + b.eq .Lenc_key_abort + cmp x2,#0 + b.eq .Lenc_key_abort + mov x3,#-2 + cmp w1,#128 + b.lt .Lenc_key_abort + cmp w1,#256 + b.gt .Lenc_key_abort + tst w1,#0x3f + b.ne .Lenc_key_abort + + adr x3,.Lrcon + cmp w1,#192 + + eor v0.16b,v0.16b,v0.16b + ld1 {v3.16b},[x0],#16 + mov w1,#8 // reuse w1 + ld1 {v1.4s,v2.4s},[x3],#32 + + b.lt .Loop128 + b.eq .L192 + b .L256 + +.align 4 +.Loop128: + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + b.ne .Loop128 + + ld1 {v1.4s},[x3] + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2] + add x2,x2,#0x50 + + mov w12,#10 + b .Ldone + +.align 4 +.L192: + ld1 {v4.8b},[x0],#8 + movi v6.16b,#8 // borrow v6.16b + st1 {v3.4s},[x2],#16 + sub v2.16b,v2.16b,v6.16b // adjust the mask + +.Loop192: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 +#ifdef __ARMEB__ + st1 {v4.4s},[x2],#16 + sub x2,x2,#8 +#else + st1 {v4.8b},[x2],#8 +#endif + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + + dup v5.4s,v3.s[3] + eor v5.16b,v5.16b,v4.16b + eor v6.16b,v6.16b,v1.16b + ext v4.16b,v0.16b,v4.16b,#12 + shl v1.16b,v1.16b,#1 + eor v4.16b,v4.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + eor v4.16b,v4.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.ne .Loop192 + + mov w12,#12 + add x2,x2,#0x20 + b .Ldone + +.align 4 +.L256: + ld1 {v4.16b},[x0] + mov w1,#7 + mov w12,#14 + st1 {v3.4s},[x2],#16 + +.Loop256: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.eq .Ldone + + dup v6.4s,v3.s[3] // just splat + ext v5.16b,v0.16b,v4.16b,#12 + aese v6.16b,v0.16b + + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + + eor v4.16b,v4.16b,v6.16b + b .Loop256 + +.Ldone: + str w12,[x2] + mov x3,#0 + +.Lenc_key_abort: + mov x0,x3 // return value + ldr x29,[sp],#16 + ret +.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key + +.globl aes_v8_set_decrypt_key +.type aes_v8_set_decrypt_key,%function +.align 5 +aes_v8_set_decrypt_key: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + bl .Lenc_key + + cmp x0,#0 + b.ne .Ldec_key_abort + + sub x2,x2,#240 // restore original x2 + mov x4,#-16 + add x0,x2,x12,lsl#4 // end of key schedule + + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + +.Loop_imc: + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + aesimc v0.16b,v0.16b + aesimc v1.16b,v1.16b + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + cmp x0,x2 + b.hi .Loop_imc + + ld1 {v0.4s},[x2] + aesimc v0.16b,v0.16b + st1 {v0.4s},[x0] + + eor x0,x0,x0 // return value +.Ldec_key_abort: + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key +.globl aes_v8_encrypt +.type aes_v8_encrypt,%function +.align 5 +aes_v8_encrypt: + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_enc: + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aese v2.16b,v1.16b + aesmc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_enc + + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aese v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_v8_encrypt,.-aes_v8_encrypt +.globl aes_v8_decrypt +.type aes_v8_decrypt,%function +.align 5 +aes_v8_decrypt: + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_dec: + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aesd v2.16b,v1.16b + aesimc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_dec + + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aesd v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_v8_decrypt,.-aes_v8_decrypt +.globl aes_v8_ecb_encrypt +.type aes_v8_ecb_encrypt,%function +.align 5 +aes_v8_ecb_encrypt: + subs x2,x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lecb_big_size + ld1 {v0.16b},[x0] + cmp w4,#0 // en- or decrypting? + ldr w5,[x3,#240] + ld1 {v5.4s,v6.4s},[x3],#32 // load key schedule... + + b.eq .Lecb_small_dec + aese v0.16b,v5.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v6.16b + aesmc v0.16b,v0.16b + subs w5,w5,#10 // if rounds==10, jump to aes-128-ecb processing + b.eq .Lecb_128_enc +.Lecb_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w5,w5,#2 // bias + b.gt .Lecb_round_loop +.Lecb_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + st1 {v0.16b},[x1] + b .Lecb_Final_abort +.Lecb_small_dec: + aesd v0.16b,v5.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v6.16b + aesimc v0.16b,v0.16b + subs w5,w5,#10 // bias + b.eq .Lecb_128_dec +.Lecb_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w5,w5,#2 // bias + b.gt .Lecb_dec_round_loop +.Lecb_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + st1 {v0.16b},[x1] + b .Lecb_Final_abort +.Lecb_big_size: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x8,#16 + b.lo .Lecb_done + csel x8,xzr,x8,eq + + cmp w4,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq .Lecb_dec + + ld1 {v1.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v1.16b,v1.16b + orr v24.16b,v1.16b,v1.16b + orr v1.16b,v0.16b,v0.16b + b.lo .Lecb_enc_tail + + orr v1.16b,v3.16b,v3.16b + ld1 {v24.16b},[x0],#16 + cmp x2,#32 + b.lo .Loop3x_ecb_enc + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + +.Loop5x_ecb_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_ecb_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + cmp x2,#0x40 // because .Lecb_enc_tail4x + sub x2,x2,#0x50 + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lecb_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v23.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + ld1 {v29.16b},[x0],#16 + cbz x6,.Lecb_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v7.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v7.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v7.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v7.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v7.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_ecb_enc + + add x2,x2,#0x50 + cbz x2,.Lecb_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + b.lo .Lecb_enc_tail + + b .Loop3x_ecb_enc + +.align 4 +.Lecb_enc_tail4x: + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + eor v30.16b,v7.16b,v25.16b + eor v31.16b,v7.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b .Lecb_done +.align 4 +.Loop3x_ecb_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ecb_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + subs x2,x2,#0x30 + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + mov x7,x3 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v7.16b,v0.16b + eor v5.16b,v7.16b,v1.16b + eor v24.16b,v24.16b,v7.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs .Loop3x_ecb_enc + + cmn x2,#0x30 + b.eq .Lecb_done + nop + +.Lecb_enc_tail: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lecb_enc_tail + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq .Lecb_enc_one + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lecb_done + +.Lecb_enc_one: + eor v5.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + b .Lecb_done +.align 5 +.Lecb_dec: + ld1 {v1.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v1.16b,v1.16b + orr v24.16b,v1.16b,v1.16b + orr v1.16b,v0.16b,v0.16b + b.lo .Lecb_dec_tail + + orr v1.16b,v3.16b,v3.16b + ld1 {v24.16b},[x0],#16 + cmp x2,#32 + b.lo .Loop3x_ecb_dec + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + +.Loop5x_ecb_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_ecb_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + cmp x2,#0x40 // because .Lecb_tail4x + sub x2,x2,#0x50 + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lecb_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v23.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + ld1 {v29.16b},[x0],#16 + cbz x6,.Lecb_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v7.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v7.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v7.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v7.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v7.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_ecb_dec + + add x2,x2,#0x50 + cbz x2,.Lecb_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + b.lo .Lecb_dec_tail + + b .Loop3x_ecb_dec + +.align 4 +.Lecb_tail4x: + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + eor v30.16b,v7.16b,v25.16b + eor v31.16b,v7.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b .Lecb_done +.align 4 +.Loop3x_ecb_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ecb_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + subs x2,x2,#0x30 + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v7.16b,v0.16b + eor v5.16b,v7.16b,v1.16b + eor v24.16b,v24.16b,v7.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs .Loop3x_ecb_dec + + cmn x2,#0x30 + b.eq .Lecb_done + nop + +.Lecb_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lecb_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq .Lecb_dec_one + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lecb_done + +.Lecb_dec_one: + eor v5.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + +.Lecb_done: + ldr x29,[sp],#16 +.Lecb_Final_abort: + ret +.size aes_v8_ecb_encrypt,.-aes_v8_ecb_encrypt +.globl aes_v8_cbc_encrypt +.type aes_v8_cbc_encrypt,%function +.align 5 +aes_v8_cbc_encrypt: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lcbc_abort + csel x8,xzr,x8,eq + + cmp w5,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v6.16b},[x4] + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq .Lcbc_dec + + cmp w5,#2 + eor v0.16b,v0.16b,v6.16b + eor v5.16b,v16.16b,v7.16b + b.eq .Lcbc_enc128 + + ld1 {v2.4s,v3.4s},[x7] + add x7,x3,#16 + add x6,x3,#16*4 + add x12,x3,#16*5 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + add x14,x3,#16*6 + add x3,x3,#16*7 + b .Lenter_cbc_enc + +.align 4 +.Loop_cbc_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x6] + cmp w5,#4 + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x12] + b.eq .Lcbc_enc192 + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x14] + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3] + nop + +.Lcbc_enc192: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x7] // re-pre-load rndkey[1] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc + + st1 {v6.16b},[x1],#16 + b .Lcbc_done + +.align 5 +.Lcbc_enc128: + ld1 {v2.4s,v3.4s},[x7] + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + b .Lenter_cbc_enc128 +.Loop_cbc_enc128: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc128: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc128 + + st1 {v6.16b},[x1],#16 + b .Lcbc_done +.align 5 +.Lcbc_dec: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + b.lo .Lcbc_dec_tail + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + orr v27.16b,v24.16b,v24.16b + cmp x2,#32 + b.lo .Loop3x_cbc_dec + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + orr v28.16b,v25.16b,v25.16b + orr v29.16b,v26.16b,v26.16b + +.Loop5x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + cmp x2,#0x40 // because .Lcbc_tail4x + sub x2,x2,#0x50 + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lcbc_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v6.16b,v7.16b + aesd v0.16b,v23.16b + eor v5.16b,v2.16b,v7.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + eor v17.16b,v3.16b,v7.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + eor v30.16b,v27.16b,v7.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + eor v31.16b,v28.16b,v7.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + orr v6.16b,v29.16b,v29.16b + ld1 {v29.16b},[x0],#16 + cbz x6,.Lcbc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v5.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v17.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v30.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_cbc_dec + + add x2,x2,#0x50 + cbz x2,.Lcbc_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v2.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v3.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + orr v27.16b,v29.16b,v29.16b + b.lo .Lcbc_dec_tail + + b .Loop3x_cbc_dec + +.align 4 +.Lcbc_tail4x: + eor v5.16b,v4.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + eor v30.16b,v30.16b,v25.16b + eor v31.16b,v31.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b .Lcbc_done +.align 4 +.Loop3x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + eor v5.16b,v2.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v3.16b,v7.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + orr v6.16b,v27.16b,v27.16b + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs .Loop3x_cbc_dec + + cmn x2,#0x30 + b.eq .Lcbc_done + nop + +.Lcbc_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lcbc_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v3.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq .Lcbc_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v27.16b,v27.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lcbc_done + +.Lcbc_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v27.16b,v27.16b + st1 {v5.16b},[x1],#16 + +.Lcbc_done: + st1 {v6.16b},[x4] +.Lcbc_abort: + ldr x29,[sp],#16 + ret +.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt +.globl aes_v8_ctr32_encrypt_blocks +.type aes_v8_ctr32_encrypt_blocks,%function +.align 5 +aes_v8_ctr32_encrypt_blocks: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + ldr w5,[x3,#240] + + ldr w8, [x4, #12] +#ifdef __ARMEB__ + ld1 {v0.16b},[x4] +#else + ld1 {v0.4s},[x4] +#endif + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#4 + mov x12,#16 + cmp x2,#2 + add x7,x3,x5,lsl#4 // pointer to last 5 round keys + sub w5,w5,#2 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + add x7,x3,#32 + mov w6,w5 + csel x12,xzr,x12,lo +#ifndef __ARMEB__ + rev w8, w8 +#endif + orr v1.16b,v0.16b,v0.16b + add w10, w8, #1 + orr v18.16b,v0.16b,v0.16b + add w8, w8, #2 + orr v6.16b,v0.16b,v0.16b + rev w10, w10 + mov v1.s[3],w10 + b.ls .Lctr32_tail + rev w12, w8 + sub x2,x2,#3 // bias + mov v18.s[3],w12 + cmp x2,#32 + b.lo .Loop3x_ctr32 + + add w13,w8,#1 + add w14,w8,#2 + orr v24.16b,v0.16b,v0.16b + rev w13,w13 + orr v25.16b,v0.16b,v0.16b + rev w14,w14 + mov v24.s[3],w13 + sub x2,x2,#2 // bias + mov v25.s[3],w14 + add w8,w8,#2 + b .Loop5x_ctr32 + +.align 4 +.Loop5x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_ctr32 + + mov x7,x3 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + add w9,w8,#1 + add w10,w8,#2 + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + add w12,w8,#3 + add w13,w8,#4 + aese v18.16b,v20.16b + aesmc v18.16b,v18.16b + add w14,w8,#5 + rev w9,w9 + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + rev w10,w10 + rev w12,w12 + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + rev w13,w13 + rev w14,w14 + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v18.16b,v21.16b + aesmc v18.16b,v18.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0],#16 + aese v18.16b,v22.16b + aesmc v18.16b,v18.16b + ld1 {v19.16b},[x0],#16 + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + ld1 {v26.16b},[x0],#16 + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + ld1 {v27.16b},[x0],#16 + + aese v0.16b,v23.16b + eor v2.16b,v2.16b,v7.16b + aese v1.16b,v23.16b + eor v3.16b,v3.16b,v7.16b + aese v18.16b,v23.16b + eor v19.16b,v19.16b,v7.16b + aese v24.16b,v23.16b + eor v26.16b,v26.16b,v7.16b + aese v25.16b,v23.16b + eor v27.16b,v27.16b,v7.16b + + eor v2.16b,v2.16b,v0.16b + orr v0.16b,v6.16b,v6.16b + eor v3.16b,v3.16b,v1.16b + orr v1.16b,v6.16b,v6.16b + eor v19.16b,v19.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + eor v26.16b,v26.16b,v24.16b + orr v24.16b,v6.16b,v6.16b + eor v27.16b,v27.16b,v25.16b + orr v25.16b,v6.16b,v6.16b + + st1 {v2.16b},[x1],#16 + mov v0.s[3],w9 + st1 {v3.16b},[x1],#16 + mov v1.s[3],w10 + st1 {v19.16b},[x1],#16 + mov v18.s[3],w12 + st1 {v26.16b},[x1],#16 + mov v24.s[3],w13 + st1 {v27.16b},[x1],#16 + mov v25.s[3],w14 + + mov w6,w5 + cbz x2,.Lctr32_done + + add w8,w8,#5 + subs x2,x2,#5 + b.hs .Loop5x_ctr32 + + add x2,x2,#5 + sub w8,w8,#5 + + cmp x2,#2 + mov x12,#16 + csel x12,xzr,x12,lo + b.ls .Lctr32_tail + + sub x2,x2,#3 // bias + add w8,w8,#3 + b .Loop3x_ctr32 + +.align 4 +.Loop3x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ctr32 + + aese v0.16b,v16.16b + aesmc v4.16b,v0.16b + aese v1.16b,v16.16b + aesmc v5.16b,v1.16b + ld1 {v2.16b},[x0],#16 + orr v0.16b,v6.16b,v6.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + orr v1.16b,v6.16b,v6.16b + aese v4.16b,v17.16b + aesmc v4.16b,v4.16b + aese v5.16b,v17.16b + aesmc v5.16b,v5.16b + ld1 {v19.16b},[x0],#16 + mov x7,x3 + aese v18.16b,v17.16b + aesmc v17.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + add w9,w8,#1 + aese v4.16b,v20.16b + aesmc v4.16b,v4.16b + aese v5.16b,v20.16b + aesmc v5.16b,v5.16b + eor v2.16b,v2.16b,v7.16b + add w10,w8,#2 + aese v17.16b,v20.16b + aesmc v17.16b,v17.16b + eor v3.16b,v3.16b,v7.16b + add w8,w8,#3 + aese v4.16b,v21.16b + aesmc v4.16b,v4.16b + aese v5.16b,v21.16b + aesmc v5.16b,v5.16b + eor v19.16b,v19.16b,v7.16b + rev w9,w9 + aese v17.16b,v21.16b + aesmc v17.16b,v17.16b + mov v0.s[3], w9 + rev w10,w10 + aese v4.16b,v22.16b + aesmc v4.16b,v4.16b + aese v5.16b,v22.16b + aesmc v5.16b,v5.16b + mov v1.s[3], w10 + rev w12,w8 + aese v17.16b,v22.16b + aesmc v17.16b,v17.16b + mov v18.s[3], w12 + subs x2,x2,#3 + aese v4.16b,v23.16b + aese v5.16b,v23.16b + aese v17.16b,v23.16b + + eor v2.16b,v2.16b,v4.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + st1 {v2.16b},[x1],#16 + eor v3.16b,v3.16b,v5.16b + mov w6,w5 + st1 {v3.16b},[x1],#16 + eor v19.16b,v19.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v19.16b},[x1],#16 + b.hs .Loop3x_ctr32 + + adds x2,x2,#3 + b.eq .Lctr32_done + cmp x2,#1 + mov x12,#16 + csel x12,xzr,x12,eq + +.Lctr32_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lctr32_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v2.16b},[x0],x12 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0] + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + eor v2.16b,v2.16b,v7.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + eor v3.16b,v3.16b,v7.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + cmp x2,#1 + eor v2.16b,v2.16b,v0.16b + eor v3.16b,v3.16b,v1.16b + st1 {v2.16b},[x1],#16 + b.eq .Lctr32_done + st1 {v3.16b},[x1] + +.Lctr32_done: + ldr x29,[sp],#16 + ret +.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks +.globl aes_v8_xts_encrypt +.type aes_v8_xts_encrypt,%function +.align 5 +aes_v8_xts_encrypt: + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_enc_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +.Loop_enc_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_enc_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aese v0.16b,v28.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v29.16b + aesmc v0.16b,v0.16b + subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing + b.eq .Lxts_128_enc +.Lxts_enc_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt .Lxts_enc_round_loop +.Lxts_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + st1 {v0.16b},[x1] + b .Lxts_enc_final_abort + +.align 4 +.Lxts_enc_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + // tailcnt store the tail value of length%16. + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lxts_abort + csel x8,xzr,x8,eq + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +.Loop_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // next starting point + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + + // Encryption +.Lxts_enc: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo .Lxts_inner_enc_tail + eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv + eor v24.16b,v24.16b,v8.16b + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // the third block + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo .Lxts_outer_enc_tail + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + + ld1 {v25.16b},[x0],#16 + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b .Loop5x_xts_enc + +.align 4 +.Loop5x_xts_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_xts_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + subs x2,x2,#0x50 // because .Lxts_enc_tail4x + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lxts_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aese v0.16b,v23.16b + // The iv for first block of one iteration + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,.Lxts_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_xts_enc + + + // If left 4 blocks, borrow the five block's processing. + cmn x2,#0x10 + b.ne .Loop5x_enc_after + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq .Loop5x_xts_enc + +.Loop5x_enc_after: + add x2,x2,#0x50 + cbz x2,.Lxts_enc_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo .Lxts_inner_enc_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b .Lxts_outer_enc_tail + +.align 4 +.Lxts_enc_tail4x: + add x0,x0,#16 + eor v5.16b,v1.16b,v5.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b .Lxts_enc_done +.align 4 +.Lxts_outer_enc_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_outer_enc_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + //mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + + add x6,x6,#0x20 + add x0,x0,x6 + mov x7,x3 + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + add w6,w5,#2 + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + cmn x2,#0x30 + b.eq .Lxts_enc_done +.Lxts_encxor_one: + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +.Lxts_inner_enc_tail: + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq .Lxts_enc_tail_loop + eor v24.16b,v29.16b,v6.16b +.Lxts_enc_tail_loop: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_enc_tail_loop + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq .Lxts_enc_one + eor v5.16b,v5.16b,v1.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + st1 {v17.16b},[x1],#16 + fmov x9,d8 + fmov x10,v8.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b .Lxts_enc_done + +.Lxts_enc_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v6.16b,v6.16b + st1 {v5.16b},[x1],#16 + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b .Lxts_enc_done +.align 5 +.Lxts_enc_done: + // Process the tail block with cipher stealing. + tst x21,#0xf + b.eq .Lxts_abort + + mov x20,x0 + mov x13,x1 + sub x1,x1,#16 +.composite_enc_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_enc_loop +.Lxts_enc_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Encrypt the composite block to get the last second encrypted text block + ldr w6,[x3,#240] // load key schedule... + ld1 {v0.4s},[x3],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x3],#16 // load key schedule... +.Loop_final_enc: + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 + subs w6,w6,#2 + aese v26.16b,v1.16b + aesmc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 + b.gt .Loop_final_enc + + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aese v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +.Lxts_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 +.Lxts_enc_final_abort: + ret +.size aes_v8_xts_encrypt,.-aes_v8_xts_encrypt +.globl aes_v8_xts_decrypt +.type aes_v8_xts_decrypt,%function +.align 5 +aes_v8_xts_decrypt: + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_dec_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +.Loop_dec_small_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_dec_small_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aesd v0.16b,v28.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v29.16b + aesimc v0.16b,v0.16b + subs w6,w6,#10 // bias + b.eq .Lxts_128_dec +.Lxts_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt .Lxts_dec_round_loop +.Lxts_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v6.16b,v0.16b + st1 {v0.16b},[x1] + b .Lxts_dec_final_abort +.Lxts_dec_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lxts_dec_abort + + // Encrypt the iv with key2, as the first XEX iv + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +.Loop_dec_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_dec_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // load rounds number + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 // load key schedule... + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + + add x7,x3,#32 + mov w6,w5 + b .Lxts_dec + + // Decryption +.align 5 +.Lxts_dec: + tst x21,#0xf + b.eq .Lxts_dec_begin + subs x2,x2,#16 + csel x8,xzr,x8,eq + ld1 {v0.16b},[x0],#16 + b.lo .Lxts_done + sub x0,x0,#16 +.Lxts_dec_begin: + ld1 {v0.16b},[x0],x8 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + ld1 {v24.16b},[x0],#16 + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo .Lxts_inner_dec_tail + eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv + eor v24.16b,v24.16b,v8.16b + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // third block xox with third iv + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo .Lxts_outer_dec_tail + + ld1 {v25.16b},[x0],#16 + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b .Loop5x_xts_dec + +.align 4 +.Loop5x_xts_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 // load key schedule... + b.gt .Loop5x_xts_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + subs x2,x2,#0x50 // because .Lxts_dec_tail4x + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lxts_dec_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aesd v0.16b,v23.16b + // The iv for first block of next iteration. + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,.Lxts_dec_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_xts_dec + + cmn x2,#0x10 + b.ne .Loop5x_dec_after + // If x2(x2) equal to -0x10, the left blocks is 4. + // After specially processing, utilize the five blocks processing again. + // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b. + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq .Loop5x_xts_dec + +.Loop5x_dec_after: + add x2,x2,#0x50 + cbz x2,.Lxts_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo .Lxts_inner_dec_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b .Lxts_outer_dec_tail + +.align 4 +.Lxts_dec_tail4x: + add x0,x0,#16 + tst x21,#0xf + eor v5.16b,v1.16b,v4.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b.eq .Lxts_dec_abort + ld1 {v0.16b},[x0],#16 + b .Lxts_done +.align 4 +.Lxts_outer_dec_tail: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_outer_dec_tail + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + add x6,x6,#0x20 + add x0,x0,x6 // x0 is adjusted to the last data + + mov x7,x3 + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + + cmn x2,#0x30 + add x2,x2,#0x30 + b.eq .Lxts_done + sub x2,x2,#0x30 + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +.Lxts_inner_dec_tail: + // x2 == -0x10 means two blocks left. + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq .Lxts_dec_tail_loop + eor v24.16b,v29.16b,v6.16b +.Lxts_dec_tail_loop: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_dec_tail_loop + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq .Lxts_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v9.16b,v9.16b + orr v8.16b,v10.16b,v10.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + add x2,x2,#16 + b .Lxts_done + +.Lxts_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + orr v8.16b,v9.16b,v9.16b + st1 {v5.16b},[x1],#16 + add x2,x2,#32 + +.Lxts_done: + tst x21,#0xf + b.eq .Lxts_dec_abort + // Processing the last two blocks with cipher stealing. + mov x7,x3 + cbnz x2,.Lxts_dec_1st_done + ld1 {v0.16b},[x0],#16 + + // Decrypt the last secod block to get the last plain text block +.Lxts_dec_1st_done: + eor v26.16b,v0.16b,v8.16b + ldr w6,[x3,#240] + ld1 {v0.4s},[x3],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x3],#16 +.Loop_final_2nd_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 // load key schedule... + b.gt .Loop_final_2nd_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v8.16b + st1 {v26.16b},[x1] + + mov x20,x0 + add x13,x1,#16 + + // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks + // to get the last encrypted block. +.composite_dec_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_dec_loop +.Lxts_dec_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Decrypt the composite block to get the last second plain text block + ldr w6,[x7,#240] + ld1 {v0.4s},[x7],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x7],#16 +.Loop_final_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x7],#16 // load key schedule... + b.gt .Loop_final_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +.Lxts_dec_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 + +.Lxts_dec_final_abort: + ret +.size aes_v8_xts_decrypt,.-aes_v8_xts_decrypt +#endif diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S new file mode 100644 index 0000000000..229dad24d3 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S @@ -0,0 +1,1196 @@ +.text + +.type _vpaes_consts,%object +.align 7 // totally strategic alignment +_vpaes_consts: +.Lk_mc_forward: // mc_forward +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 +.Lk_mc_backward: // mc_backward +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F +.Lk_sr: // sr +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +// +// "Hot" constants +// +.Lk_inv: // inv, inva +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 +.Lk_ipt: // input transform (lo, hi) +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 +.Lk_sbo: // sbou, sbot +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA +.Lk_sb1: // sb1u, sb1t +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.Lk_sb2: // sb2u, sb2t +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + +// +// Decryption stuff +// +.Lk_dipt: // decryption input transform +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 +.Lk_dsbo: // decryption sbox final output +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +.Lk_dsb9: // decryption sbox output *9*u, *9*t +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd: // decryption sbox output *D*u, *D*t +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb: // decryption sbox output *B*u, *B*t +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe: // decryption sbox output *E*u, *E*t +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 + +// +// Key schedule constants +// +.Lk_dksd: // decryption key schedule: invskew x*D +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb: // decryption key schedule: invskew x*B +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse: // decryption key schedule: invskew x*E + 0x63 +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9: // decryption key schedule: invskew x*9 +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +.Lk_rcon: // rcon +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_opt: // output transform +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 +.Lk_deskew: // deskew tables: inverts the sbox's "skew" +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,56,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 2 +.size _vpaes_consts,.-_vpaes_consts +.align 6 +// +// _aes_preheat +// +// Fills register %r10 -> .aes_consts (so you can -fPIC) +// and %xmm9-%xmm15 as specified below. +// +.type _vpaes_encrypt_preheat,%function +.align 4 +_vpaes_encrypt_preheat: + adr x10, .Lk_inv + movi v17.16b, #0x0f + ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x10],#64 // .Lk_ipt, .Lk_sbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10] // .Lk_sb1, .Lk_sb2 + ret +.size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat + +// +// _aes_encrypt_core +// +// AES-encrypt %xmm0. +// +// Inputs: +// %xmm0 = input +// %xmm9-%xmm15 as in _vpaes_preheat +// (%rdx) = scheduled keys +// +// Output in %xmm0 +// Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +// Preserves %xmm6 - %xmm8 so you get some local vectors +// +// +.type _vpaes_encrypt_core,%function +.align 4 +_vpaes_encrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adr x11, .Lk_mc_forward+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b .Lenc_entry + +.align 4 +.Lenc_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + sub w8, w8, #1 // nr-- + +.Lenc_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v5.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, .Lenc_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + ret +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + +.globl vpaes_encrypt +.type vpaes_encrypt,%function +.align 4 +vpaes_encrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_encrypt_preheat + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_encrypt,.-vpaes_encrypt + +.type _vpaes_encrypt_2x,%function +.align 4 +_vpaes_encrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adr x11, .Lk_mc_forward+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + tbl v9.16b, {v20.16b}, v9.16b + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + tbl v10.16b, {v21.16b}, v8.16b + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v8.16b, v9.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b .Lenc_2x_entry + +.align 4 +.Lenc_2x_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + tbl v12.16b, {v25.16b}, v10.16b + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + tbl v8.16b, {v24.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + tbl v13.16b, {v27.16b}, v10.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + tbl v10.16b, {v26.16b}, v11.16b + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + tbl v11.16b, {v8.16b}, v1.16b + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + eor v10.16b, v10.16b, v13.16b + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + tbl v8.16b, {v8.16b}, v4.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + eor v11.16b, v11.16b, v10.16b + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + tbl v12.16b, {v11.16b},v1.16b + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + eor v8.16b, v8.16b, v11.16b + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + eor v8.16b, v8.16b, v12.16b + sub w8, w8, #1 // nr-- + +.Lenc_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v5.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + tbl v13.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v13.16b + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v13.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, .Lenc_2x_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + tbl v8.16b, {v23.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v0.16b, {v0.16b},v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v1.16b + ret +.size _vpaes_encrypt_2x,.-_vpaes_encrypt_2x + +.type _vpaes_decrypt_preheat,%function +.align 4 +_vpaes_decrypt_preheat: + adr x10, .Lk_inv + movi v17.16b, #0x0f + adr x11, .Lk_dipt + ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x11],#64 // .Lk_dipt, .Lk_dsbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x11],#64 // .Lk_dsb9, .Lk_dsbd + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x11] // .Lk_dsbb, .Lk_dsbe + ret +.size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat + +// +// Decryption core +// +// Same API as encryption core. +// +.type _vpaes_decrypt_core,%function +.align 4 +_vpaes_decrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adr x10, .Lk_sr + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adr x10, .Lk_mc_forward+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b .Ldec_entry + +.align 4 +.Ldec_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + sub w8, w8, #1 // sub $1,%rax # nr-- + +.Ldec_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, .Ldec_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + ret +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + +.globl vpaes_decrypt +.type vpaes_decrypt,%function +.align 4 +vpaes_decrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_decrypt_preheat + bl _vpaes_decrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_decrypt,.-vpaes_decrypt + +// v14-v15 input, v0-v1 output +.type _vpaes_decrypt_2x,%function +.align 4 +_vpaes_decrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adr x10, .Lk_sr + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adr x10, .Lk_mc_forward+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v2.16b, {v20.16b},v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + tbl v10.16b, {v20.16b},v9.16b + ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b},v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + tbl v8.16b, {v21.16b},v8.16b + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v10.16b, v10.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b .Ldec_2x_entry + +.align 4 +.Ldec_2x_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v12.16b, {v24.16b}, v10.16b + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + tbl v9.16b, {v25.16b}, v11.16b + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + eor v8.16b, v12.16b, v16.16b + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v12.16b, {v26.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + tbl v9.16b, {v27.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v12.16b, {v28.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + tbl v9.16b, {v29.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v12.16b, {v30.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + tbl v9.16b, {v31.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + sub w8, w8, #1 // sub $1,%rax # nr-- + +.Ldec_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v2.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + tbl v10.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v10.16b + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v10.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, .Ldec_2x_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + tbl v9.16b, {v23.16b}, v11.16b + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + eor v8.16b, v9.16b, v12.16b + tbl v0.16b, {v0.16b},v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v2.16b + ret +.size _vpaes_decrypt_2x,.-_vpaes_decrypt_2x +//////////////////////////////////////////////////////// +// // +// AES key schedule // +// // +//////////////////////////////////////////////////////// +.type _vpaes_key_preheat,%function +.align 4 +_vpaes_key_preheat: + adr x10, .Lk_inv + movi v16.16b, #0x5b // .Lk_s63 + adr x11, .Lk_sb1 + movi v17.16b, #0x0f // .Lk_s0F + ld1 {v18.2d,v19.2d,v20.2d,v21.2d}, [x10] // .Lk_inv, .Lk_ipt + adr x10, .Lk_dksd + ld1 {v22.2d,v23.2d}, [x11] // .Lk_sb1 + adr x11, .Lk_mc_forward + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10],#64 // .Lk_dksd, .Lk_dksb + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x10],#64 // .Lk_dkse, .Lk_dks9 + ld1 {v8.2d}, [x10] // .Lk_rcon + ld1 {v9.2d}, [x11] // .Lk_mc_forward[0] + ret +.size _vpaes_key_preheat,.-_vpaes_key_preheat + +.type _vpaes_schedule_core,%function +.align 4 +_vpaes_schedule_core: +.inst 0xd503233f // paciasp + stp x29, x30, [sp,#-16]! + add x29,sp,#0 + + bl _vpaes_key_preheat // load the tables + + ld1 {v0.16b}, [x0],#16 // vmovdqu (%rdi), %xmm0 # load key (unaligned) + + // input transform + mov v3.16b, v0.16b // vmovdqa %xmm0, %xmm3 + bl _vpaes_schedule_transform + mov v7.16b, v0.16b // vmovdqa %xmm0, %xmm7 + + adr x10, .Lk_sr // lea .Lk_sr(%rip),%r10 + add x8, x8, x10 + cbnz w3, .Lschedule_am_decrypting + + // encrypting, output zeroth round key after transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) + b .Lschedule_go + +.Lschedule_am_decrypting: + // decrypting, output zeroth round key after shiftrows + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + eor x8, x8, #0x30 // xor $0x30, %r8 + +.Lschedule_go: + cmp w1, #192 // cmp $192, %esi + b.hi .Lschedule_256 + b.eq .Lschedule_192 + // 128: fall though + +// +// .schedule_128 +// +// 128-bit specific part of key schedule. +// +// This schedule is really simple, because all its parts +// are accomplished by the subroutines. +// +.Lschedule_128: + mov x0, #10 // mov $10, %esi + +.Loop_schedule_128: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle // write output + b .Loop_schedule_128 + +// +// .aes_schedule_192 +// +// 192-bit specific part of key schedule. +// +// The main body of this schedule is the same as the 128-bit +// schedule, but with more smearing. The long, high side is +// stored in %xmm7 as before, and the short, low side is in +// the high bits of %xmm6. +// +// This schedule is somewhat nastier, however, because each +// round produces 192 bits of key material, or 1.5 round keys. +// Therefore, on each cycle we do 2 rounds and produce 3 round +// keys. +// +.align 4 +.Lschedule_192: + sub x0, x0, #8 + ld1 {v0.16b}, [x0] // vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + bl _vpaes_schedule_transform // input transform + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save short part + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 # clear 4 + ins v6.d[0], v4.d[0] // vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros + mov x0, #4 // mov $4, %esi + +.Loop_schedule_192: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + ext v0.16b, v6.16b, v0.16b, #8 // vpalignr $8,%xmm6,%xmm0,%xmm0 + bl _vpaes_schedule_mangle // save key n + bl _vpaes_schedule_192_smear + bl _vpaes_schedule_mangle // save key n+1 + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle // save key n+2 + bl _vpaes_schedule_192_smear + b .Loop_schedule_192 + +// +// .aes_schedule_256 +// +// 256-bit specific part of key schedule. +// +// The structure here is very similar to the 128-bit +// schedule, but with an additional "low side" in +// %xmm6. The low side's rounds are the same as the +// high side's, except no rcon and no rotation. +// +.align 4 +.Lschedule_256: + ld1 {v0.16b}, [x0] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + bl _vpaes_schedule_transform // input transform + mov x0, #7 // mov $7, %esi + +.Loop_schedule_256: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_mangle // output low result + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + // high round + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle + + // low round. swap xmm7 and xmm6 + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + movi v4.16b, #0 + mov v5.16b, v7.16b // vmovdqa %xmm7, %xmm5 + mov v7.16b, v6.16b // vmovdqa %xmm6, %xmm7 + bl _vpaes_schedule_low_round + mov v7.16b, v5.16b // vmovdqa %xmm5, %xmm7 + + b .Loop_schedule_256 + +// +// .aes_schedule_mangle_last +// +// Mangler for last round of key schedule +// Mangles %xmm0 +// when encrypting, outputs out(%xmm0) ^ 63 +// when decrypting, outputs unskew(%xmm0) +// +// Always called right before return... jumps to cleanup and exits +// +.align 4 +.Lschedule_mangle_last: + // schedule last round key from xmm0 + adr x11, .Lk_deskew // lea .Lk_deskew(%rip),%r11 # prepare to deskew + cbnz w3, .Lschedule_mangle_last_dec + + // encrypting + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10),%xmm1 + adr x11, .Lk_opt // lea .Lk_opt(%rip), %r11 # prepare to output transform + add x2, x2, #32 // add $32, %rdx + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 # output permute + +.Lschedule_mangle_last_dec: + ld1 {v20.2d,v21.2d}, [x11] // reload constants + sub x2, x2, #16 // add $-16, %rdx + eor v0.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm0 + bl _vpaes_schedule_transform // output transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) # save last key + + // cleanup + eor v0.16b, v0.16b, v0.16b // vpxor %xmm0, %xmm0, %xmm0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v2.16b, v2.16b, v2.16b // vpxor %xmm2, %xmm2, %xmm2 + eor v3.16b, v3.16b, v3.16b // vpxor %xmm3, %xmm3, %xmm3 + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 + eor v5.16b, v5.16b, v5.16b // vpxor %xmm5, %xmm5, %xmm5 + eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6 + eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7 + ldp x29, x30, [sp],#16 +.inst 0xd50323bf // autiasp + ret +.size _vpaes_schedule_core,.-_vpaes_schedule_core + +// +// .aes_schedule_192_smear +// +// Smear the short, low side in the 192-bit key schedule. +// +// Inputs: +// %xmm7: high side, b a x y +// %xmm6: low side, d c 0 0 +// %xmm13: 0 +// +// Outputs: +// %xmm6: b+c+d b+c 0 0 +// %xmm0: b+c+d b+c b a +// +.type _vpaes_schedule_192_smear,%function +.align 4 +_vpaes_schedule_192_smear: + movi v1.16b, #0 + dup v0.4s, v7.s[3] + ins v1.s[3], v6.s[2] // vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 + ins v0.s[0], v7.s[2] // vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + eor v6.16b, v6.16b, v1.16b // vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v6.16b, v6.16b, v0.16b // vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a + mov v0.16b, v6.16b // vmovdqa %xmm6, %xmm0 + ins v6.d[0], v1.d[0] // vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros + ret +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + +// +// .aes_schedule_round +// +// Runs one main round of the key schedule on %xmm0, %xmm7 +// +// Specifically, runs subbytes on the high dword of %xmm0 +// then rotates it by one byte and xors into the low dword of +// %xmm7. +// +// Adds rcon from low byte of %xmm8, then rotates %xmm8 for +// next rcon. +// +// Smears the dwords of %xmm7 by xoring the low into the +// second low, result into third, result into highest. +// +// Returns results in %xmm7 = %xmm0. +// Clobbers %xmm1-%xmm4, %r11. +// +.type _vpaes_schedule_round,%function +.align 4 +_vpaes_schedule_round: + // extract rcon from xmm8 + movi v4.16b, #0 // vpxor %xmm4, %xmm4, %xmm4 + ext v1.16b, v8.16b, v4.16b, #15 // vpalignr $15, %xmm8, %xmm4, %xmm1 + ext v8.16b, v8.16b, v8.16b, #15 // vpalignr $15, %xmm8, %xmm8, %xmm8 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + + // rotate + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + ext v0.16b, v0.16b, v0.16b, #1 // vpalignr $1, %xmm0, %xmm0, %xmm0 + + // fall through... + + // low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + // smear xmm7 + ext v1.16b, v4.16b, v7.16b, #12 // vpslldq $4, %xmm7, %xmm1 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + ext v4.16b, v4.16b, v7.16b, #8 // vpslldq $8, %xmm7, %xmm4 + + // subbytes + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + eor v7.16b, v7.16b, v4.16b // vpxor %xmm4, %xmm7, %xmm7 + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v7.16b, v7.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm7, %xmm7 + tbl v3.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak + eor v3.16b, v3.16b, v1.16b // vpxor %xmm1, %xmm3, %xmm3 # 2 = io + eor v2.16b, v2.16b, v0.16b // vpxor %xmm0, %xmm2, %xmm2 # 3 = jo + tbl v4.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou + tbl v1.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t + eor v1.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output + + // add in smeared stuff + eor v0.16b, v1.16b, v7.16b // vpxor %xmm7, %xmm1, %xmm0 + eor v7.16b, v1.16b, v7.16b // vmovdqa %xmm0, %xmm7 + ret +.size _vpaes_schedule_round,.-_vpaes_schedule_round + +// +// .aes_schedule_transform +// +// Linear-transform %xmm0 according to tables at (%r11) +// +// Requires that %xmm9 = 0x0F0F... as in preheat +// Output in %xmm0 +// Clobbers %xmm1, %xmm2 +// +.type _vpaes_schedule_transform,%function +.align 4 +_vpaes_schedule_transform: + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + // vmovdqa (%r11), %xmm2 # lo + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + // vmovdqa 16(%r11), %xmm1 # hi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + ret +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + +// +// .aes_schedule_mangle +// +// Mangle xmm0 from (basis-transformed) standard version +// to our version. +// +// On encrypt, +// xor with 0x63 +// multiply by circulant 0,1,1,1 +// apply shiftrows transform +// +// On decrypt, +// xor with 0x63 +// multiply by "inverse mixcolumns" circulant E,B,D,9 +// deskew +// apply shiftrows transform +// +// +// Writes out to (%rdx), and increments or decrements it +// Keeps track of round number mod 4 in %r8 +// Preserves xmm0 +// Clobbers xmm1-xmm5 +// +.type _vpaes_schedule_mangle,%function +.align 4 +_vpaes_schedule_mangle: + mov v4.16b, v0.16b // vmovdqa %xmm0, %xmm4 # save xmm0 for later + // vmovdqa .Lk_mc_forward(%rip),%xmm5 + cbnz w3, .Lschedule_mangle_dec + + // encrypting + eor v4.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm4 + add x2, x2, #16 // add $16, %rdx + tbl v4.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm4 + tbl v1.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm1 + tbl v3.16b, {v1.16b}, v9.16b // vpshufb %xmm5, %xmm1, %xmm3 + eor v4.16b, v4.16b, v1.16b // vpxor %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v3.16b, v3.16b, v4.16b // vpxor %xmm4, %xmm3, %xmm3 + + b .Lschedule_mangle_both +.align 4 +.Lschedule_mangle_dec: + // inverse mix columns + // lea .Lk_dksd(%rip),%r11 + ushr v1.16b, v4.16b, #4 // vpsrlb $4, %xmm4, %xmm1 # 1 = hi + and v4.16b, v4.16b, v17.16b // vpand %xmm9, %xmm4, %xmm4 # 4 = lo + + // vmovdqa 0x00(%r11), %xmm2 + tbl v2.16b, {v24.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + // vmovdqa 0x10(%r11), %xmm3 + tbl v3.16b, {v25.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x20(%r11), %xmm2 + tbl v2.16b, {v26.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x30(%r11), %xmm3 + tbl v3.16b, {v27.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x40(%r11), %xmm2 + tbl v2.16b, {v28.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x50(%r11), %xmm3 + tbl v3.16b, {v29.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + + // vmovdqa 0x60(%r11), %xmm2 + tbl v2.16b, {v30.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + // vmovdqa 0x70(%r11), %xmm4 + tbl v4.16b, {v31.16b}, v1.16b // vpshufb %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + eor v3.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm3 + + sub x2, x2, #16 // add $-16, %rdx + +.Lschedule_mangle_both: + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + add x8, x8, #64-16 // add $-16, %r8 + and x8, x8, #~(1<<6) // and $0x30, %r8 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + ret +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + +.globl vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,%function +.align 4 +vpaes_set_encrypt_key: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov w3, #0 // mov $0,%ecx + mov x8, #0x30 // mov $0x30,%r8d + bl _vpaes_schedule_core + eor x0, x0, x0 + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key + +.globl vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,%function +.align 4 +vpaes_set_decrypt_key: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + lsl w9, w9, #4 // shl $4,%eax + add x2, x2, #16 // lea 16(%rdx,%rax),%rdx + add x2, x2, x9 + + mov w3, #1 // mov $1,%ecx + lsr w8, w1, #1 // shr $1,%r8d + and x8, x8, #32 // and $32,%r8d + eor x8, x8, #32 // xor $32,%r8d # nbits==192?0:32 + bl _vpaes_schedule_core + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key +.globl vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,%function +.align 4 +vpaes_cbc_encrypt: + cbz x2, .Lcbc_abort + cmp w5, #0 // check direction + b.eq vpaes_cbc_decrypt + +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x17, x2 // reassign + mov x2, x3 // reassign + + ld1 {v0.16b}, [x4] // load ivec + bl _vpaes_encrypt_preheat + b .Lcbc_enc_loop + +.align 4 +.Lcbc_enc_loop: + ld1 {v7.16b}, [x0],#16 // load input + eor v7.16b, v7.16b, v0.16b // xor with ivec + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 // save output + subs x17, x17, #16 + b.hi .Lcbc_enc_loop + + st1 {v0.16b}, [x4] // write ivec + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp +.Lcbc_abort: + ret +.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt + +.type vpaes_cbc_decrypt,%function +.align 4 +vpaes_cbc_decrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 // reassign + mov x2, x3 // reassign + ld1 {v6.16b}, [x4] // load ivec + bl _vpaes_decrypt_preheat + tst x17, #16 + b.eq .Lcbc_dec_loop2x + + ld1 {v7.16b}, [x0], #16 // load input + bl _vpaes_decrypt_core + eor v0.16b, v0.16b, v6.16b // xor with ivec + orr v6.16b, v7.16b, v7.16b // next ivec value + st1 {v0.16b}, [x1], #16 + subs x17, x17, #16 + b.ls .Lcbc_dec_done + +.align 4 +.Lcbc_dec_loop2x: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_decrypt_2x + eor v0.16b, v0.16b, v6.16b // xor with ivec + eor v1.16b, v1.16b, v14.16b + orr v6.16b, v15.16b, v15.16b + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lcbc_dec_loop2x + +.Lcbc_dec_done: + st1 {v6.16b}, [x4] + + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt +.globl vpaes_ecb_encrypt +.type vpaes_ecb_encrypt,%function +.align 4 +vpaes_ecb_encrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 + mov x2, x3 + bl _vpaes_encrypt_preheat + tst x17, #16 + b.eq .Lecb_enc_loop + + ld1 {v7.16b}, [x0],#16 + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 + subs x17, x17, #16 + b.ls .Lecb_enc_done + +.align 4 +.Lecb_enc_loop: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_encrypt_2x + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lecb_enc_loop + +.Lecb_enc_done: + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_ecb_encrypt,.-vpaes_ecb_encrypt + +.globl vpaes_ecb_decrypt +.type vpaes_ecb_decrypt,%function +.align 4 +vpaes_ecb_decrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 + mov x2, x3 + bl _vpaes_decrypt_preheat + tst x17, #16 + b.eq .Lecb_dec_loop + + ld1 {v7.16b}, [x0],#16 + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 + subs x17, x17, #16 + b.ls .Lecb_dec_done + +.align 4 +.Lecb_dec_loop: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_decrypt_2x + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lecb_dec_loop + +.Lecb_dec_done: + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_ecb_decrypt,.-vpaes_ecb_decrypt diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S new file mode 100644 index 0000000000..297d5075f9 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S @@ -0,0 +1,129 @@ +#include "arm_arch.h" + +.text +.arch armv8-a+crypto + +.align 5 +.globl _armv7_neon_probe +.type _armv7_neon_probe,%function +_armv7_neon_probe: + orr v15.16b, v15.16b, v15.16b + ret +.size _armv7_neon_probe,.-_armv7_neon_probe + +.globl _armv7_tick +.type _armv7_tick,%function +_armv7_tick: +#ifdef __APPLE__ + mrs x0, CNTPCT_EL0 +#else + mrs x0, CNTVCT_EL0 +#endif + ret +.size _armv7_tick,.-_armv7_tick + +.globl _armv8_aes_probe +.type _armv8_aes_probe,%function +_armv8_aes_probe: + aese v0.16b, v0.16b + ret +.size _armv8_aes_probe,.-_armv8_aes_probe + +.globl _armv8_sha1_probe +.type _armv8_sha1_probe,%function +_armv8_sha1_probe: + sha1h s0, s0 + ret +.size _armv8_sha1_probe,.-_armv8_sha1_probe + +.globl _armv8_sha256_probe +.type _armv8_sha256_probe,%function +_armv8_sha256_probe: + sha256su0 v0.4s, v0.4s + ret +.size _armv8_sha256_probe,.-_armv8_sha256_probe + +.globl _armv8_pmull_probe +.type _armv8_pmull_probe,%function +_armv8_pmull_probe: + pmull v0.1q, v0.1d, v0.1d + ret +.size _armv8_pmull_probe,.-_armv8_pmull_probe + +.globl _armv8_sha512_probe +.type _armv8_sha512_probe,%function +_armv8_sha512_probe: +.long 0xcec08000 // sha512su0 v0.2d,v0.2d + ret +.size _armv8_sha512_probe,.-_armv8_sha512_probe + +.globl _armv8_cpuid_probe +.type _armv8_cpuid_probe,%function +_armv8_cpuid_probe: + mrs x0, midr_el1 + ret +.size _armv8_cpuid_probe,.-_armv8_cpuid_probe + +.globl OPENSSL_cleanse +.type OPENSSL_cleanse,%function +.align 5 +OPENSSL_cleanse: + cbz x1,.Lret // len==0? + cmp x1,#15 + b.hi .Lot // len>15 + nop +.Little: + strb wzr,[x0],#1 // store byte-by-byte + subs x1,x1,#1 + b.ne .Little +.Lret: ret + +.align 4 +.Lot: tst x0,#7 + b.eq .Laligned // inp is aligned + strb wzr,[x0],#1 // store byte-by-byte + sub x1,x1,#1 + b .Lot + +.align 4 +.Laligned: + str xzr,[x0],#8 // store word-by-word + sub x1,x1,#8 + tst x1,#-8 + b.ne .Laligned // len>=8 + cbnz x1,.Little // len!=0? + ret +.size OPENSSL_cleanse,.-OPENSSL_cleanse + +.globl CRYPTO_memcmp +.type CRYPTO_memcmp,%function +.align 4 +CRYPTO_memcmp: + eor w3,w3,w3 + cbz x2,.Lno_data // len==0? + cmp x2,#16 + b.ne .Loop_cmp + ldp x8,x9,[x0] + ldp x10,x11,[x1] + eor x8,x8,x10 + eor x9,x9,x11 + orr x8,x8,x9 + mov x0,#1 + cmp x8,#0 + csel x0,xzr,x0,eq + ret + +.align 4 +.Loop_cmp: + ldrb w4,[x0],#1 + ldrb w5,[x1],#1 + eor w4,w4,w5 + orr w3,w3,w4 + subs x2,x2,#1 + b.ne .Loop_cmp + +.Lno_data: + neg w0,w3 + lsr w0,w0,#31 + ret +.size CRYPTO_memcmp,.-CRYPTO_memcmp diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S new file mode 100644 index 0000000000..7448af982c --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S @@ -0,0 +1,2124 @@ +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armv8_rsa_neonized +#endif +.text + +.globl bn_mul_mont +.type bn_mul_mont,%function +.align 5 +bn_mul_mont: +.Lbn_mul_mont: + tst x5,#3 + b.ne .Lmul_mont + cmp x5,#32 + b.le .Lscalar_impl +#ifndef __KERNEL__ + adrp x17,OPENSSL_armv8_rsa_neonized + ldr w17,[x17,#:lo12:OPENSSL_armv8_rsa_neonized] + cbnz w17, bn_mul8x_mont_neon +#endif + +.Lscalar_impl: + tst x5,#7 + b.eq __bn_sqr8x_mont + tst x5,#3 + b.eq __bn_mul4x_mont + +.Lmul_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + ldr x9,[x2],#8 // bp[0] + sub x22,sp,x5,lsl#3 + ldp x7,x8,[x1],#16 // ap[0..1] + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + and x22,x22,#-16 // ABI says so + ldp x13,x14,[x3],#16 // np[0..1] + + mul x6,x7,x9 // ap[0]*bp[0] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + mul x10,x8,x9 // ap[1]*bp[0] + umulh x11,x8,x9 + + mul x15,x6,x4 // "tp[0]"*n0 + mov sp,x22 // alloca + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 // discarded + // (*) As for removal of first multiplication and addition + // instructions. The outcome of first addition is + // guaranteed to be zero, which leaves two computationally + // significant outcomes: it either carries or not. Then + // question is when does it carry? Is there alternative + // way to deduce it? If you follow operations, you can + // observe that condition for carry is quite simple: + // x6 being non-zero. So that carry can be calculated + // by adding -1 to x6. That's what next instruction does. + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + adc x13,x13,xzr + cbz x21,.L1st_skip + +.L1st: + ldr x8,[x1],#8 + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + ldr x14,[x3],#8 + adds x12,x16,x13 + mul x10,x8,x9 // ap[j]*bp[0] + adc x13,x17,xzr + umulh x11,x8,x9 + + adds x12,x12,x6 + mul x16,x14,x15 // np[j]*m1 + adc x13,x13,xzr + umulh x17,x14,x15 + str x12,[x22],#8 // tp[j-1] + cbnz x21,.L1st + +.L1st_skip: + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adc x13,x17,xzr + + adds x12,x12,x6 + sub x20,x5,#8 // i=num-1 + adcs x13,x13,x7 + + adc x19,xzr,xzr // upmost overflow bit + stp x12,x13,[x22] + +.Louter: + ldr x9,[x2],#8 // bp[i] + ldp x7,x8,[x1],#16 + ldr x23,[sp] // tp[0] + add x22,sp,#8 + + mul x6,x7,x9 // ap[0]*bp[i] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + ldp x13,x14,[x3],#16 + mul x10,x8,x9 // ap[1]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x15,x6,x4 + sub x20,x20,#8 // i-- + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + cbz x21,.Linner_skip + +.Linner: + ldr x8,[x1],#8 + adc x13,x13,xzr + ldr x23,[x22],#8 // tp[j] + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + adds x12,x16,x13 + ldr x14,[x3],#8 + adc x13,x17,xzr + + mul x10,x8,x9 // ap[j]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x16,x14,x15 // np[j]*m1 + adds x12,x12,x6 + umulh x17,x14,x15 + stur x12,[x22,#-16] // tp[j-1] + cbnz x21,.Linner + +.Linner_skip: + ldr x23,[x22],#8 // tp[j] + adc x13,x13,xzr + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adcs x13,x17,x19 + adc x19,xzr,xzr + + adds x6,x6,x23 + adc x7,x7,xzr + + adds x12,x12,x6 + adcs x13,x13,x7 + adc x19,x19,xzr // upmost overflow bit + stp x12,x13,[x22,#-16] + + cbnz x20,.Louter + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x14,[x3],#8 // np[0] + subs x21,x5,#8 // j=num-1 and clear borrow + mov x1,x0 +.Lsub: + sbcs x8,x23,x14 // tp[j]-np[j] + ldr x23,[x22],#8 + sub x21,x21,#8 // j-- + ldr x14,[x3],#8 + str x8,[x1],#8 // rp[j]=tp[j]-np[j] + cbnz x21,.Lsub + + sbcs x8,x23,x14 + sbcs x19,x19,xzr // did it borrow? + str x8,[x1],#8 // rp[num-1] + + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x8,[x0],#8 // rp[0] + sub x5,x5,#8 // num-- + nop +.Lcond_copy: + sub x5,x5,#8 // num-- + csel x14,x23,x8,lo // did it borrow? + ldr x23,[x22],#8 + ldr x8,[x0],#8 + stur xzr,[x22,#-16] // wipe tp + stur x14,[x0,#-16] + cbnz x5,.Lcond_copy + + csel x14,x23,x8,lo + stur xzr,[x22,#-8] // wipe tp + stur x14,[x0,#-8] + + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldr x29,[sp],#64 + ret +.size bn_mul_mont,.-bn_mul_mont +.type bn_mul8x_mont_neon,%function +.align 5 +bn_mul8x_mont_neon: + stp x29,x30,[sp,#-80]! + mov x16,sp + stp d8,d9,[sp,#16] + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + lsl x5,x5,#1 + eor v14.16b,v14.16b,v14.16b + +.align 4 +.LNEON_8n: + eor v6.16b,v6.16b,v6.16b + sub x7,sp,#128 + eor v7.16b,v7.16b,v7.16b + sub x7,x7,x5,lsl#4 + eor v8.16b,v8.16b,v8.16b + and x7,x7,#-64 + eor v9.16b,v9.16b,v9.16b + mov sp,x7 // alloca + eor v10.16b,v10.16b,v10.16b + add x7,x7,#256 + eor v11.16b,v11.16b,v11.16b + sub x8,x5,#8 + eor v12.16b,v12.16b,v12.16b + eor v13.16b,v13.16b,v13.16b + +.LNEON_8n_init: + st1 {v6.2d,v7.2d},[x7],#32 + subs x8,x8,#8 + st1 {v8.2d,v9.2d},[x7],#32 + st1 {v10.2d,v11.2d},[x7],#32 + st1 {v12.2d,v13.2d},[x7],#32 + bne .LNEON_8n_init + + add x6,sp,#256 + ld1 {v0.4s,v1.4s},[x1],#32 + add x10,sp,#8 + ldr s30,[x4],#4 + mov x9,x5 + b .LNEON_8n_outer + +.align 4 +.LNEON_8n_outer: + ldr s28,[x2],#4 // *b++ + uxtl v28.4s,v28.4h + add x7,sp,#128 + ld1 {v2.4s,v3.4s},[x3],#32 + + umlal v6.2d,v28.2s,v0.s[0] + umlal v7.2d,v28.2s,v0.s[1] + umlal v8.2d,v28.2s,v0.s[2] + shl v29.2d,v6.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v9.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v6.2d + umlal v10.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v11.2d,v28.2s,v1.s[1] + st1 {v28.2s},[sp] // put aside smashed b[8*i+0] + umlal v12.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v13.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v6.2d,v29.2s,v2.s[0] + umlal v7.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v8.2d,v29.2s,v2.s[2] + ushr v15.2d,v6.2d,#16 + umlal v9.2d,v29.2s,v2.s[3] + umlal v10.2d,v29.2s,v3.s[0] + ext v6.16b,v6.16b,v6.16b,#8 + add v6.2d,v6.2d,v15.2d + umlal v11.2d,v29.2s,v3.s[1] + ushr v6.2d,v6.2d,#16 + umlal v12.2d,v29.2s,v3.s[2] + umlal v13.2d,v29.2s,v3.s[3] + add v16.2d,v7.2d,v6.2d + ins v7.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+0] + umlal v7.2d,v28.2s,v0.s[0] + ld1 {v6.2d},[x6],#16 + umlal v8.2d,v28.2s,v0.s[1] + umlal v9.2d,v28.2s,v0.s[2] + shl v29.2d,v7.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v10.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v7.2d + umlal v11.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v12.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+1] + umlal v13.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v6.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v7.2d,v29.2s,v2.s[0] + umlal v8.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v9.2d,v29.2s,v2.s[2] + ushr v15.2d,v7.2d,#16 + umlal v10.2d,v29.2s,v2.s[3] + umlal v11.2d,v29.2s,v3.s[0] + ext v7.16b,v7.16b,v7.16b,#8 + add v7.2d,v7.2d,v15.2d + umlal v12.2d,v29.2s,v3.s[1] + ushr v7.2d,v7.2d,#16 + umlal v13.2d,v29.2s,v3.s[2] + umlal v6.2d,v29.2s,v3.s[3] + add v16.2d,v8.2d,v7.2d + ins v8.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+1] + umlal v8.2d,v28.2s,v0.s[0] + ld1 {v7.2d},[x6],#16 + umlal v9.2d,v28.2s,v0.s[1] + umlal v10.2d,v28.2s,v0.s[2] + shl v29.2d,v8.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v11.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v8.2d + umlal v12.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v13.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+2] + umlal v6.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v7.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v8.2d,v29.2s,v2.s[0] + umlal v9.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v10.2d,v29.2s,v2.s[2] + ushr v15.2d,v8.2d,#16 + umlal v11.2d,v29.2s,v2.s[3] + umlal v12.2d,v29.2s,v3.s[0] + ext v8.16b,v8.16b,v8.16b,#8 + add v8.2d,v8.2d,v15.2d + umlal v13.2d,v29.2s,v3.s[1] + ushr v8.2d,v8.2d,#16 + umlal v6.2d,v29.2s,v3.s[2] + umlal v7.2d,v29.2s,v3.s[3] + add v16.2d,v9.2d,v8.2d + ins v9.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+2] + umlal v9.2d,v28.2s,v0.s[0] + ld1 {v8.2d},[x6],#16 + umlal v10.2d,v28.2s,v0.s[1] + umlal v11.2d,v28.2s,v0.s[2] + shl v29.2d,v9.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v12.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v9.2d + umlal v13.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v6.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+3] + umlal v7.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v8.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v9.2d,v29.2s,v2.s[0] + umlal v10.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v11.2d,v29.2s,v2.s[2] + ushr v15.2d,v9.2d,#16 + umlal v12.2d,v29.2s,v2.s[3] + umlal v13.2d,v29.2s,v3.s[0] + ext v9.16b,v9.16b,v9.16b,#8 + add v9.2d,v9.2d,v15.2d + umlal v6.2d,v29.2s,v3.s[1] + ushr v9.2d,v9.2d,#16 + umlal v7.2d,v29.2s,v3.s[2] + umlal v8.2d,v29.2s,v3.s[3] + add v16.2d,v10.2d,v9.2d + ins v10.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+3] + umlal v10.2d,v28.2s,v0.s[0] + ld1 {v9.2d},[x6],#16 + umlal v11.2d,v28.2s,v0.s[1] + umlal v12.2d,v28.2s,v0.s[2] + shl v29.2d,v10.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v13.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v10.2d + umlal v6.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v7.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+4] + umlal v8.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v9.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v10.2d,v29.2s,v2.s[0] + umlal v11.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v12.2d,v29.2s,v2.s[2] + ushr v15.2d,v10.2d,#16 + umlal v13.2d,v29.2s,v2.s[3] + umlal v6.2d,v29.2s,v3.s[0] + ext v10.16b,v10.16b,v10.16b,#8 + add v10.2d,v10.2d,v15.2d + umlal v7.2d,v29.2s,v3.s[1] + ushr v10.2d,v10.2d,#16 + umlal v8.2d,v29.2s,v3.s[2] + umlal v9.2d,v29.2s,v3.s[3] + add v16.2d,v11.2d,v10.2d + ins v11.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+4] + umlal v11.2d,v28.2s,v0.s[0] + ld1 {v10.2d},[x6],#16 + umlal v12.2d,v28.2s,v0.s[1] + umlal v13.2d,v28.2s,v0.s[2] + shl v29.2d,v11.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v6.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v11.2d + umlal v7.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v8.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+5] + umlal v9.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v10.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v11.2d,v29.2s,v2.s[0] + umlal v12.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v13.2d,v29.2s,v2.s[2] + ushr v15.2d,v11.2d,#16 + umlal v6.2d,v29.2s,v2.s[3] + umlal v7.2d,v29.2s,v3.s[0] + ext v11.16b,v11.16b,v11.16b,#8 + add v11.2d,v11.2d,v15.2d + umlal v8.2d,v29.2s,v3.s[1] + ushr v11.2d,v11.2d,#16 + umlal v9.2d,v29.2s,v3.s[2] + umlal v10.2d,v29.2s,v3.s[3] + add v16.2d,v12.2d,v11.2d + ins v12.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+5] + umlal v12.2d,v28.2s,v0.s[0] + ld1 {v11.2d},[x6],#16 + umlal v13.2d,v28.2s,v0.s[1] + umlal v6.2d,v28.2s,v0.s[2] + shl v29.2d,v12.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v7.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v12.2d + umlal v8.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v9.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+6] + umlal v10.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v11.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v12.2d,v29.2s,v2.s[0] + umlal v13.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v6.2d,v29.2s,v2.s[2] + ushr v15.2d,v12.2d,#16 + umlal v7.2d,v29.2s,v2.s[3] + umlal v8.2d,v29.2s,v3.s[0] + ext v12.16b,v12.16b,v12.16b,#8 + add v12.2d,v12.2d,v15.2d + umlal v9.2d,v29.2s,v3.s[1] + ushr v12.2d,v12.2d,#16 + umlal v10.2d,v29.2s,v3.s[2] + umlal v11.2d,v29.2s,v3.s[3] + add v16.2d,v13.2d,v12.2d + ins v13.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+6] + umlal v13.2d,v28.2s,v0.s[0] + ld1 {v12.2d},[x6],#16 + umlal v6.2d,v28.2s,v0.s[1] + umlal v7.2d,v28.2s,v0.s[2] + shl v29.2d,v13.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v8.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v13.2d + umlal v9.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v10.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+7] + umlal v11.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v12.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[sp] // pull smashed b[8*i+0] + umlal v13.2d,v29.2s,v2.s[0] + ld1 {v0.4s,v1.4s},[x1],#32 + umlal v6.2d,v29.2s,v2.s[1] + umlal v7.2d,v29.2s,v2.s[2] + mov v5.16b,v13.16b + ushr v5.2d,v5.2d,#16 + ext v13.16b,v13.16b,v13.16b,#8 + umlal v8.2d,v29.2s,v2.s[3] + umlal v9.2d,v29.2s,v3.s[0] + add v13.2d,v13.2d,v5.2d + umlal v10.2d,v29.2s,v3.s[1] + ushr v13.2d,v13.2d,#16 + eor v15.16b,v15.16b,v15.16b + ins v13.d[1],v15.d[0] + umlal v11.2d,v29.2s,v3.s[2] + umlal v12.2d,v29.2s,v3.s[3] + add v6.2d,v6.2d,v13.2d + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+7] + add x10,sp,#8 // rewind + sub x8,x5,#8 + b .LNEON_8n_inner + +.align 4 +.LNEON_8n_inner: + subs x8,x8,#8 + umlal v6.2d,v28.2s,v0.s[0] + ld1 {v13.2d},[x6] + umlal v7.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+0] + umlal v8.2d,v28.2s,v0.s[2] + ld1 {v2.4s,v3.4s},[x3],#32 + umlal v9.2d,v28.2s,v0.s[3] + b.eq .LInner_jump + add x6,x6,#16 // don't advance in last iteration +.LInner_jump: + umlal v10.2d,v28.2s,v1.s[0] + umlal v11.2d,v28.2s,v1.s[1] + umlal v12.2d,v28.2s,v1.s[2] + umlal v13.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+1] + umlal v6.2d,v29.2s,v2.s[0] + umlal v7.2d,v29.2s,v2.s[1] + umlal v8.2d,v29.2s,v2.s[2] + umlal v9.2d,v29.2s,v2.s[3] + umlal v10.2d,v29.2s,v3.s[0] + umlal v11.2d,v29.2s,v3.s[1] + umlal v12.2d,v29.2s,v3.s[2] + umlal v13.2d,v29.2s,v3.s[3] + st1 {v6.2d},[x7],#16 + umlal v7.2d,v28.2s,v0.s[0] + ld1 {v6.2d},[x6] + umlal v8.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+1] + umlal v9.2d,v28.2s,v0.s[2] + b.eq .LInner_jump1 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump1: + umlal v10.2d,v28.2s,v0.s[3] + umlal v11.2d,v28.2s,v1.s[0] + umlal v12.2d,v28.2s,v1.s[1] + umlal v13.2d,v28.2s,v1.s[2] + umlal v6.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+2] + umlal v7.2d,v29.2s,v2.s[0] + umlal v8.2d,v29.2s,v2.s[1] + umlal v9.2d,v29.2s,v2.s[2] + umlal v10.2d,v29.2s,v2.s[3] + umlal v11.2d,v29.2s,v3.s[0] + umlal v12.2d,v29.2s,v3.s[1] + umlal v13.2d,v29.2s,v3.s[2] + umlal v6.2d,v29.2s,v3.s[3] + st1 {v7.2d},[x7],#16 + umlal v8.2d,v28.2s,v0.s[0] + ld1 {v7.2d},[x6] + umlal v9.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+2] + umlal v10.2d,v28.2s,v0.s[2] + b.eq .LInner_jump2 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump2: + umlal v11.2d,v28.2s,v0.s[3] + umlal v12.2d,v28.2s,v1.s[0] + umlal v13.2d,v28.2s,v1.s[1] + umlal v6.2d,v28.2s,v1.s[2] + umlal v7.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+3] + umlal v8.2d,v29.2s,v2.s[0] + umlal v9.2d,v29.2s,v2.s[1] + umlal v10.2d,v29.2s,v2.s[2] + umlal v11.2d,v29.2s,v2.s[3] + umlal v12.2d,v29.2s,v3.s[0] + umlal v13.2d,v29.2s,v3.s[1] + umlal v6.2d,v29.2s,v3.s[2] + umlal v7.2d,v29.2s,v3.s[3] + st1 {v8.2d},[x7],#16 + umlal v9.2d,v28.2s,v0.s[0] + ld1 {v8.2d},[x6] + umlal v10.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+3] + umlal v11.2d,v28.2s,v0.s[2] + b.eq .LInner_jump3 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump3: + umlal v12.2d,v28.2s,v0.s[3] + umlal v13.2d,v28.2s,v1.s[0] + umlal v6.2d,v28.2s,v1.s[1] + umlal v7.2d,v28.2s,v1.s[2] + umlal v8.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+4] + umlal v9.2d,v29.2s,v2.s[0] + umlal v10.2d,v29.2s,v2.s[1] + umlal v11.2d,v29.2s,v2.s[2] + umlal v12.2d,v29.2s,v2.s[3] + umlal v13.2d,v29.2s,v3.s[0] + umlal v6.2d,v29.2s,v3.s[1] + umlal v7.2d,v29.2s,v3.s[2] + umlal v8.2d,v29.2s,v3.s[3] + st1 {v9.2d},[x7],#16 + umlal v10.2d,v28.2s,v0.s[0] + ld1 {v9.2d},[x6] + umlal v11.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+4] + umlal v12.2d,v28.2s,v0.s[2] + b.eq .LInner_jump4 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump4: + umlal v13.2d,v28.2s,v0.s[3] + umlal v6.2d,v28.2s,v1.s[0] + umlal v7.2d,v28.2s,v1.s[1] + umlal v8.2d,v28.2s,v1.s[2] + umlal v9.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+5] + umlal v10.2d,v29.2s,v2.s[0] + umlal v11.2d,v29.2s,v2.s[1] + umlal v12.2d,v29.2s,v2.s[2] + umlal v13.2d,v29.2s,v2.s[3] + umlal v6.2d,v29.2s,v3.s[0] + umlal v7.2d,v29.2s,v3.s[1] + umlal v8.2d,v29.2s,v3.s[2] + umlal v9.2d,v29.2s,v3.s[3] + st1 {v10.2d},[x7],#16 + umlal v11.2d,v28.2s,v0.s[0] + ld1 {v10.2d},[x6] + umlal v12.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+5] + umlal v13.2d,v28.2s,v0.s[2] + b.eq .LInner_jump5 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump5: + umlal v6.2d,v28.2s,v0.s[3] + umlal v7.2d,v28.2s,v1.s[0] + umlal v8.2d,v28.2s,v1.s[1] + umlal v9.2d,v28.2s,v1.s[2] + umlal v10.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+6] + umlal v11.2d,v29.2s,v2.s[0] + umlal v12.2d,v29.2s,v2.s[1] + umlal v13.2d,v29.2s,v2.s[2] + umlal v6.2d,v29.2s,v2.s[3] + umlal v7.2d,v29.2s,v3.s[0] + umlal v8.2d,v29.2s,v3.s[1] + umlal v9.2d,v29.2s,v3.s[2] + umlal v10.2d,v29.2s,v3.s[3] + st1 {v11.2d},[x7],#16 + umlal v12.2d,v28.2s,v0.s[0] + ld1 {v11.2d},[x6] + umlal v13.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+6] + umlal v6.2d,v28.2s,v0.s[2] + b.eq .LInner_jump6 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump6: + umlal v7.2d,v28.2s,v0.s[3] + umlal v8.2d,v28.2s,v1.s[0] + umlal v9.2d,v28.2s,v1.s[1] + umlal v10.2d,v28.2s,v1.s[2] + umlal v11.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+7] + umlal v12.2d,v29.2s,v2.s[0] + umlal v13.2d,v29.2s,v2.s[1] + umlal v6.2d,v29.2s,v2.s[2] + umlal v7.2d,v29.2s,v2.s[3] + umlal v8.2d,v29.2s,v3.s[0] + umlal v9.2d,v29.2s,v3.s[1] + umlal v10.2d,v29.2s,v3.s[2] + umlal v11.2d,v29.2s,v3.s[3] + st1 {v12.2d},[x7],#16 + umlal v13.2d,v28.2s,v0.s[0] + ld1 {v12.2d},[x6] + umlal v6.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+7] + umlal v7.2d,v28.2s,v0.s[2] + b.eq .LInner_jump7 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump7: + umlal v8.2d,v28.2s,v0.s[3] + umlal v9.2d,v28.2s,v1.s[0] + umlal v10.2d,v28.2s,v1.s[1] + umlal v11.2d,v28.2s,v1.s[2] + umlal v12.2d,v28.2s,v1.s[3] + b.ne .LInner_after_rewind8 + sub x1,x1,x5,lsl#2 // rewind +.LInner_after_rewind8: + umlal v13.2d,v29.2s,v2.s[0] + ld1 {v28.2s},[sp] // pull smashed b[8*i+0] + umlal v6.2d,v29.2s,v2.s[1] + ld1 {v0.4s,v1.4s},[x1],#32 + umlal v7.2d,v29.2s,v2.s[2] + add x10,sp,#8 // rewind + umlal v8.2d,v29.2s,v2.s[3] + umlal v9.2d,v29.2s,v3.s[0] + umlal v10.2d,v29.2s,v3.s[1] + umlal v11.2d,v29.2s,v3.s[2] + st1 {v13.2d},[x7],#16 + umlal v12.2d,v29.2s,v3.s[3] + + bne .LNEON_8n_inner + add x6,sp,#128 + st1 {v6.2d,v7.2d},[x7],#32 + eor v2.16b,v2.16b,v2.16b // v2 + st1 {v8.2d,v9.2d},[x7],#32 + eor v3.16b,v3.16b,v3.16b // v3 + st1 {v10.2d,v11.2d},[x7],#32 + st1 {v12.2d},[x7] + + subs x9,x9,#8 + ld1 {v6.2d,v7.2d},[x6],#32 + ld1 {v8.2d,v9.2d},[x6],#32 + ld1 {v10.2d,v11.2d},[x6],#32 + ld1 {v12.2d,v13.2d},[x6],#32 + + b.eq .LInner_8n_jump_2steps + sub x3,x3,x5,lsl#2 // rewind + b .LNEON_8n_outer + +.LInner_8n_jump_2steps: + add x7,sp,#128 + st1 {v2.2d,v3.2d}, [sp],#32 // start wiping stack frame + mov v5.16b,v6.16b + ushr v15.2d,v6.2d,#16 + ext v6.16b,v6.16b,v6.16b,#8 + st1 {v2.2d,v3.2d}, [sp],#32 + add v6.2d,v6.2d,v15.2d + st1 {v2.2d,v3.2d}, [sp],#32 + ushr v15.2d,v6.2d,#16 + st1 {v2.2d,v3.2d}, [sp],#32 + zip1 v6.4h,v5.4h,v6.4h + ins v15.d[1],v14.d[0] + + mov x8,x5 + b .LNEON_tail_entry + +.align 4 +.LNEON_tail: + add v6.2d,v6.2d,v15.2d + mov v5.16b,v6.16b + ushr v15.2d,v6.2d,#16 + ext v6.16b,v6.16b,v6.16b,#8 + ld1 {v8.2d,v9.2d}, [x6],#32 + add v6.2d,v6.2d,v15.2d + ld1 {v10.2d,v11.2d}, [x6],#32 + ushr v15.2d,v6.2d,#16 + ld1 {v12.2d,v13.2d}, [x6],#32 + zip1 v6.4h,v5.4h,v6.4h + ins v15.d[1],v14.d[0] + +.LNEON_tail_entry: + add v7.2d,v7.2d,v15.2d + st1 {v6.s}[0], [x7],#4 + ushr v15.2d,v7.2d,#16 + mov v5.16b,v7.16b + ext v7.16b,v7.16b,v7.16b,#8 + add v7.2d,v7.2d,v15.2d + ushr v15.2d,v7.2d,#16 + zip1 v7.4h,v5.4h,v7.4h + ins v15.d[1],v14.d[0] + add v8.2d,v8.2d,v15.2d + st1 {v7.s}[0], [x7],#4 + ushr v15.2d,v8.2d,#16 + mov v5.16b,v8.16b + ext v8.16b,v8.16b,v8.16b,#8 + add v8.2d,v8.2d,v15.2d + ushr v15.2d,v8.2d,#16 + zip1 v8.4h,v5.4h,v8.4h + ins v15.d[1],v14.d[0] + add v9.2d,v9.2d,v15.2d + st1 {v8.s}[0], [x7],#4 + ushr v15.2d,v9.2d,#16 + mov v5.16b,v9.16b + ext v9.16b,v9.16b,v9.16b,#8 + add v9.2d,v9.2d,v15.2d + ushr v15.2d,v9.2d,#16 + zip1 v9.4h,v5.4h,v9.4h + ins v15.d[1],v14.d[0] + add v10.2d,v10.2d,v15.2d + st1 {v9.s}[0], [x7],#4 + ushr v15.2d,v10.2d,#16 + mov v5.16b,v10.16b + ext v10.16b,v10.16b,v10.16b,#8 + add v10.2d,v10.2d,v15.2d + ushr v15.2d,v10.2d,#16 + zip1 v10.4h,v5.4h,v10.4h + ins v15.d[1],v14.d[0] + add v11.2d,v11.2d,v15.2d + st1 {v10.s}[0], [x7],#4 + ushr v15.2d,v11.2d,#16 + mov v5.16b,v11.16b + ext v11.16b,v11.16b,v11.16b,#8 + add v11.2d,v11.2d,v15.2d + ushr v15.2d,v11.2d,#16 + zip1 v11.4h,v5.4h,v11.4h + ins v15.d[1],v14.d[0] + add v12.2d,v12.2d,v15.2d + st1 {v11.s}[0], [x7],#4 + ushr v15.2d,v12.2d,#16 + mov v5.16b,v12.16b + ext v12.16b,v12.16b,v12.16b,#8 + add v12.2d,v12.2d,v15.2d + ushr v15.2d,v12.2d,#16 + zip1 v12.4h,v5.4h,v12.4h + ins v15.d[1],v14.d[0] + add v13.2d,v13.2d,v15.2d + st1 {v12.s}[0], [x7],#4 + ushr v15.2d,v13.2d,#16 + mov v5.16b,v13.16b + ext v13.16b,v13.16b,v13.16b,#8 + add v13.2d,v13.2d,v15.2d + ushr v15.2d,v13.2d,#16 + zip1 v13.4h,v5.4h,v13.4h + ins v15.d[1],v14.d[0] + ld1 {v6.2d,v7.2d}, [x6],#32 + subs x8,x8,#8 + st1 {v13.s}[0], [x7],#4 + bne .LNEON_tail + + st1 {v15.s}[0], [x7],#4 // top-most bit + sub x3,x3,x5,lsl#2 // rewind x3 + subs x1,sp,#0 // clear carry flag + add x2,sp,x5,lsl#2 + +.LNEON_sub: + ldp w4,w5,[x1],#8 + ldp w6,w7,[x1],#8 + ldp w8,w9,[x3],#8 + ldp w10,w11,[x3],#8 + sbcs w8,w4,w8 + sbcs w9,w5,w9 + sbcs w10,w6,w10 + sbcs w11,w7,w11 + sub x17,x2,x1 + stp w8,w9,[x0],#8 + stp w10,w11,[x0],#8 + cbnz x17,.LNEON_sub + + ldr w10, [x1] // load top-most bit + mov x11,sp + eor v0.16b,v0.16b,v0.16b + sub x11,x2,x11 // this is num*4 + eor v1.16b,v1.16b,v1.16b + mov x1,sp + sub x0,x0,x11 // rewind x0 + mov x3,x2 // second 3/4th of frame + sbcs w10,w10,wzr // result is carry flag + +.LNEON_copy_n_zap: + ldp w4,w5,[x1],#8 + ldp w6,w7,[x1],#8 + ldp w8,w9,[x0],#8 + ldp w10,w11,[x0] + sub x0,x0,#8 + b.cs .LCopy_1 + mov w8,w4 + mov w9,w5 + mov w10,w6 + mov w11,w7 +.LCopy_1: + st1 {v0.2d,v1.2d}, [x3],#32 // wipe + st1 {v0.2d,v1.2d}, [x3],#32 // wipe + ldp w4,w5,[x1],#8 + ldp w6,w7,[x1],#8 + stp w8,w9,[x0],#8 + stp w10,w11,[x0],#8 + sub x1,x1,#32 + ldp w8,w9,[x0],#8 + ldp w10,w11,[x0] + sub x0,x0,#8 + b.cs .LCopy_2 + mov w8, w4 + mov w9, w5 + mov w10, w6 + mov w11, w7 +.LCopy_2: + st1 {v0.2d,v1.2d}, [x1],#32 // wipe + st1 {v0.2d,v1.2d}, [x3],#32 // wipe + sub x17,x2,x1 // preserves carry + stp w8,w9,[x0],#8 + stp w10,w11,[x0],#8 + cbnz x17,.LNEON_copy_n_zap + + mov sp,x16 + ldp d14,d15,[sp,#64] + ldp d12,d13,[sp,#48] + ldp d10,d11,[sp,#32] + ldp d8,d9,[sp,#16] + ldr x29,[sp],#80 + ret // bx lr + +.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon +.type __bn_sqr8x_mont,%function +.align 5 +__bn_sqr8x_mont: + cmp x1,x2 + b.ne __bn_mul4x_mont +.Lsqr8x_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x3,[sp,#96] // offload rp and np + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + ldp x12,x13,[x1,#8*6] + + sub x2,sp,x5,lsl#4 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + mov sp,x2 // alloca + sub x27,x5,#8*8 + b .Lsqr8x_zero_start + +.Lsqr8x_zero: + sub x27,x27,#8*8 + stp xzr,xzr,[x2,#8*0] + stp xzr,xzr,[x2,#8*2] + stp xzr,xzr,[x2,#8*4] + stp xzr,xzr,[x2,#8*6] +.Lsqr8x_zero_start: + stp xzr,xzr,[x2,#8*8] + stp xzr,xzr,[x2,#8*10] + stp xzr,xzr,[x2,#8*12] + stp xzr,xzr,[x2,#8*14] + add x2,x2,#8*16 + cbnz x27,.Lsqr8x_zero + + add x3,x1,x5 + add x1,x1,#8*8 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + mov x23,xzr + mov x24,xzr + mov x25,xzr + mov x26,xzr + mov x2,sp + str x4,[x29,#112] // offload n0 + + // Multiply everything but a[i]*a[i] +.align 4 +.Lsqr8x_outer_loop: + // a[1]a[0] (i) + // a[2]a[0] + // a[3]a[0] + // a[4]a[0] + // a[5]a[0] + // a[6]a[0] + // a[7]a[0] + // a[2]a[1] (ii) + // a[3]a[1] + // a[4]a[1] + // a[5]a[1] + // a[6]a[1] + // a[7]a[1] + // a[3]a[2] (iii) + // a[4]a[2] + // a[5]a[2] + // a[6]a[2] + // a[7]a[2] + // a[4]a[3] (iv) + // a[5]a[3] + // a[6]a[3] + // a[7]a[3] + // a[5]a[4] (v) + // a[6]a[4] + // a[7]a[4] + // a[6]a[5] (vi) + // a[7]a[5] + // a[7]a[6] (vii) + + mul x14,x7,x6 // lo(a[1..7]*a[0]) (i) + mul x15,x8,x6 + mul x16,x9,x6 + mul x17,x10,x6 + adds x20,x20,x14 // t[1]+lo(a[1]*a[0]) + mul x14,x11,x6 + adcs x21,x21,x15 + mul x15,x12,x6 + adcs x22,x22,x16 + mul x16,x13,x6 + adcs x23,x23,x17 + umulh x17,x7,x6 // hi(a[1..7]*a[0]) + adcs x24,x24,x14 + umulh x14,x8,x6 + adcs x25,x25,x15 + umulh x15,x9,x6 + adcs x26,x26,x16 + umulh x16,x10,x6 + stp x19,x20,[x2],#8*2 // t[0..1] + adc x19,xzr,xzr // t[8] + adds x21,x21,x17 // t[2]+lo(a[1]*a[0]) + umulh x17,x11,x6 + adcs x22,x22,x14 + umulh x14,x12,x6 + adcs x23,x23,x15 + umulh x15,x13,x6 + adcs x24,x24,x16 + mul x16,x8,x7 // lo(a[2..7]*a[1]) (ii) + adcs x25,x25,x17 + mul x17,x9,x7 + adcs x26,x26,x14 + mul x14,x10,x7 + adc x19,x19,x15 + + mul x15,x11,x7 + adds x22,x22,x16 + mul x16,x12,x7 + adcs x23,x23,x17 + mul x17,x13,x7 + adcs x24,x24,x14 + umulh x14,x8,x7 // hi(a[2..7]*a[1]) + adcs x25,x25,x15 + umulh x15,x9,x7 + adcs x26,x26,x16 + umulh x16,x10,x7 + adcs x19,x19,x17 + umulh x17,x11,x7 + stp x21,x22,[x2],#8*2 // t[2..3] + adc x20,xzr,xzr // t[9] + adds x23,x23,x14 + umulh x14,x12,x7 + adcs x24,x24,x15 + umulh x15,x13,x7 + adcs x25,x25,x16 + mul x16,x9,x8 // lo(a[3..7]*a[2]) (iii) + adcs x26,x26,x17 + mul x17,x10,x8 + adcs x19,x19,x14 + mul x14,x11,x8 + adc x20,x20,x15 + + mul x15,x12,x8 + adds x24,x24,x16 + mul x16,x13,x8 + adcs x25,x25,x17 + umulh x17,x9,x8 // hi(a[3..7]*a[2]) + adcs x26,x26,x14 + umulh x14,x10,x8 + adcs x19,x19,x15 + umulh x15,x11,x8 + adcs x20,x20,x16 + umulh x16,x12,x8 + stp x23,x24,[x2],#8*2 // t[4..5] + adc x21,xzr,xzr // t[10] + adds x25,x25,x17 + umulh x17,x13,x8 + adcs x26,x26,x14 + mul x14,x10,x9 // lo(a[4..7]*a[3]) (iv) + adcs x19,x19,x15 + mul x15,x11,x9 + adcs x20,x20,x16 + mul x16,x12,x9 + adc x21,x21,x17 + + mul x17,x13,x9 + adds x26,x26,x14 + umulh x14,x10,x9 // hi(a[4..7]*a[3]) + adcs x19,x19,x15 + umulh x15,x11,x9 + adcs x20,x20,x16 + umulh x16,x12,x9 + adcs x21,x21,x17 + umulh x17,x13,x9 + stp x25,x26,[x2],#8*2 // t[6..7] + adc x22,xzr,xzr // t[11] + adds x19,x19,x14 + mul x14,x11,x10 // lo(a[5..7]*a[4]) (v) + adcs x20,x20,x15 + mul x15,x12,x10 + adcs x21,x21,x16 + mul x16,x13,x10 + adc x22,x22,x17 + + umulh x17,x11,x10 // hi(a[5..7]*a[4]) + adds x20,x20,x14 + umulh x14,x12,x10 + adcs x21,x21,x15 + umulh x15,x13,x10 + adcs x22,x22,x16 + mul x16,x12,x11 // lo(a[6..7]*a[5]) (vi) + adc x23,xzr,xzr // t[12] + adds x21,x21,x17 + mul x17,x13,x11 + adcs x22,x22,x14 + umulh x14,x12,x11 // hi(a[6..7]*a[5]) + adc x23,x23,x15 + + umulh x15,x13,x11 + adds x22,x22,x16 + mul x16,x13,x12 // lo(a[7]*a[6]) (vii) + adcs x23,x23,x17 + umulh x17,x13,x12 // hi(a[7]*a[6]) + adc x24,xzr,xzr // t[13] + adds x23,x23,x14 + sub x27,x3,x1 // done yet? + adc x24,x24,x15 + + adds x24,x24,x16 + sub x14,x3,x5 // rewinded ap + adc x25,xzr,xzr // t[14] + add x25,x25,x17 + + cbz x27,.Lsqr8x_outer_break + + mov x4,x6 + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x0,x1 + adcs x26,xzr,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved below + mov x27,#-8*8 + + // a[8]a[0] + // a[9]a[0] + // a[a]a[0] + // a[b]a[0] + // a[c]a[0] + // a[d]a[0] + // a[e]a[0] + // a[f]a[0] + // a[8]a[1] + // a[f]a[1]........................ + // a[8]a[2] + // a[f]a[2]........................ + // a[8]a[3] + // a[f]a[3]........................ + // a[8]a[4] + // a[f]a[4]........................ + // a[8]a[5] + // a[f]a[5]........................ + // a[8]a[6] + // a[f]a[6]........................ + // a[8]a[7] + // a[f]a[7]........................ +.Lsqr8x_mul: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,.Lsqr8x_mul + // note that carry flag is guaranteed + // to be zero at this point + cmp x1,x3 // done yet? + b.eq .Lsqr8x_break + + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + ldur x4,[x0,#-8*8] + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b .Lsqr8x_mul + +.align 4 +.Lsqr8x_break: + ldp x6,x7,[x0,#8*0] + add x1,x0,#8*8 + ldp x8,x9,[x0,#8*2] + sub x14,x3,x1 // is it last iteration? + ldp x10,x11,[x0,#8*4] + sub x15,x2,x14 + ldp x12,x13,[x0,#8*6] + cbz x14,.Lsqr8x_outer_loop + + stp x19,x20,[x2,#8*0] + ldp x19,x20,[x15,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x15,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x15,#8*4] + stp x25,x26,[x2,#8*6] + mov x2,x15 + ldp x25,x26,[x15,#8*6] + b .Lsqr8x_outer_loop + +.align 4 +.Lsqr8x_outer_break: + // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0] + ldp x7,x9,[x14,#8*0] // recall that x14 is &a[0] + ldp x15,x16,[sp,#8*1] + ldp x11,x13,[x14,#8*2] + add x1,x14,#8*4 + ldp x17,x14,[sp,#8*3] + + stp x19,x20,[x2,#8*0] + mul x19,x7,x7 + stp x21,x22,[x2,#8*2] + umulh x7,x7,x7 + stp x23,x24,[x2,#8*4] + mul x8,x9,x9 + stp x25,x26,[x2,#8*6] + mov x2,sp + umulh x9,x9,x9 + adds x20,x7,x15,lsl#1 + extr x15,x16,x15,#63 + sub x27,x5,#8*4 + +.Lsqr4x_shift_n_add: + adcs x21,x8,x15 + extr x16,x17,x16,#63 + sub x27,x27,#8*4 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + ldp x7,x9,[x1],#8*2 + umulh x11,x11,x11 + mul x12,x13,x13 + umulh x13,x13,x13 + extr x17,x14,x17,#63 + stp x19,x20,[x2,#8*0] + adcs x23,x10,x17 + extr x14,x15,x14,#63 + stp x21,x22,[x2,#8*2] + adcs x24,x11,x14 + ldp x17,x14,[x2,#8*7] + extr x15,x16,x15,#63 + adcs x25,x12,x15 + extr x16,x17,x16,#63 + adcs x26,x13,x16 + ldp x15,x16,[x2,#8*9] + mul x6,x7,x7 + ldp x11,x13,[x1],#8*2 + umulh x7,x7,x7 + mul x8,x9,x9 + umulh x9,x9,x9 + stp x23,x24,[x2,#8*4] + extr x17,x14,x17,#63 + stp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + adcs x19,x6,x17 + extr x14,x15,x14,#63 + adcs x20,x7,x14 + ldp x17,x14,[x2,#8*3] + extr x15,x16,x15,#63 + cbnz x27,.Lsqr4x_shift_n_add + ldp x1,x4,[x29,#104] // pull np and n0 + + adcs x21,x8,x15 + extr x16,x17,x16,#63 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + umulh x11,x11,x11 + stp x19,x20,[x2,#8*0] + mul x12,x13,x13 + umulh x13,x13,x13 + stp x21,x22,[x2,#8*2] + extr x17,x14,x17,#63 + adcs x23,x10,x17 + extr x14,x15,x14,#63 + ldp x19,x20,[sp,#8*0] + adcs x24,x11,x14 + extr x15,x16,x15,#63 + ldp x6,x7,[x1,#8*0] + adcs x25,x12,x15 + extr x16,xzr,x16,#63 + ldp x8,x9,[x1,#8*2] + adc x26,x13,x16 + ldp x10,x11,[x1,#8*4] + + // Reduce by 512 bits per iteration + mul x28,x4,x19 // t[0]*n0 + ldp x12,x13,[x1,#8*6] + add x3,x1,x5 + ldp x21,x22,[sp,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[sp,#8*4] + stp x25,x26,[x2,#8*6] + ldp x25,x26,[sp,#8*6] + add x1,x1,#8*8 + mov x30,xzr // initial top-most carry + mov x2,sp + mov x27,#8 + +.Lsqr8x_reduction: + // (*) mul x14,x6,x28 // lo(n[0-7])*lo(t[0]*n0) + mul x15,x7,x28 + sub x27,x27,#1 + mul x16,x8,x28 + str x28,[x2],#8 // put aside t[0]*n0 for tail processing + mul x17,x9,x28 + // (*) adds xzr,x19,x14 + subs xzr,x19,#1 // (*) + mul x14,x10,x28 + adcs x19,x20,x15 + mul x15,x11,x28 + adcs x20,x21,x16 + mul x16,x12,x28 + adcs x21,x22,x17 + mul x17,x13,x28 + adcs x22,x23,x14 + umulh x14,x6,x28 // hi(n[0-7])*lo(t[0]*n0) + adcs x23,x24,x15 + umulh x15,x7,x28 + adcs x24,x25,x16 + umulh x16,x8,x28 + adcs x25,x26,x17 + umulh x17,x9,x28 + adc x26,xzr,xzr + adds x19,x19,x14 + umulh x14,x10,x28 + adcs x20,x20,x15 + umulh x15,x11,x28 + adcs x21,x21,x16 + umulh x16,x12,x28 + adcs x22,x22,x17 + umulh x17,x13,x28 + mul x28,x4,x19 // next t[0]*n0 + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adc x26,x26,x17 + cbnz x27,.Lsqr8x_reduction + + ldp x14,x15,[x2,#8*0] + ldp x16,x17,[x2,#8*2] + mov x0,x2 + sub x27,x3,x1 // done yet? + adds x19,x19,x14 + adcs x20,x20,x15 + ldp x14,x15,[x2,#8*4] + adcs x21,x21,x16 + adcs x22,x22,x17 + ldp x16,x17,[x2,#8*6] + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adcs x26,x26,x17 + //adc x28,xzr,xzr // moved below + cbz x27,.Lsqr8x8_post_condition + + ldur x4,[x2,#-8*8] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + mov x27,#-8*8 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + +.Lsqr8x_tail: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,.Lsqr8x_tail + // note that carry flag is guaranteed + // to be zero at this point + ldp x6,x7,[x2,#8*0] + sub x27,x3,x1 // done yet? + sub x16,x3,x5 // rewinded np + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + cbz x27,.Lsqr8x_tail_break + + ldur x4,[x0,#-8*8] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b .Lsqr8x_tail + +.align 4 +.Lsqr8x_tail_break: + ldr x4,[x29,#112] // pull n0 + add x27,x2,#8*8 // end of current t[num] window + + subs xzr,x30,#1 // "move" top-most carry to carry bit + adcs x14,x19,x6 + adcs x15,x20,x7 + ldp x19,x20,[x0,#8*0] + adcs x21,x21,x8 + ldp x6,x7,[x16,#8*0] // recall that x16 is &n[0] + adcs x22,x22,x9 + ldp x8,x9,[x16,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x16,#8*4] + adcs x25,x25,x12 + adcs x26,x26,x13 + ldp x12,x13,[x16,#8*6] + add x1,x16,#8*8 + adc x30,xzr,xzr // top-most carry + mul x28,x4,x19 + stp x14,x15,[x2,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x0,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x0,#8*4] + cmp x27,x29 // did we hit the bottom? + stp x25,x26,[x2,#8*6] + mov x2,x0 // slide the window + ldp x25,x26,[x0,#8*6] + mov x27,#8 + b.ne .Lsqr8x_reduction + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x0,[x29,#96] // pull rp + add x2,x2,#8*8 + subs x14,x19,x6 + sbcs x15,x20,x7 + sub x27,x5,#8*8 + mov x3,x0 // x0 copy + +.Lsqr8x_sub: + sbcs x16,x21,x8 + ldp x6,x7,[x1,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x1,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x10,x11,[x1,#8*4] + sbcs x17,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + ldp x19,x20,[x2,#8*0] + sub x27,x27,#8*8 + ldp x21,x22,[x2,#8*2] + ldp x23,x24,[x2,#8*4] + ldp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + stp x14,x15,[x0,#8*4] + sbcs x14,x19,x6 + stp x16,x17,[x0,#8*6] + add x0,x0,#8*8 + sbcs x15,x20,x7 + cbnz x27,.Lsqr8x_sub + + sbcs x16,x21,x8 + mov x2,sp + add x1,sp,x5 + ldp x6,x7,[x3,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x3,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x19,x20,[x1,#8*0] + sbcs x17,x26,x13 + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + stp x14,x15,[x0,#8*4] + stp x16,x17,[x0,#8*6] + + sub x27,x5,#8*4 +.Lsqr4x_cond_copy: + sub x27,x27,#8*4 + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + ldp x6,x7,[x3,#8*4] + ldp x19,x20,[x1,#8*4] + csel x16,x21,x8,lo + stp xzr,xzr,[x2,#8*2] + add x2,x2,#8*4 + csel x17,x22,x9,lo + ldp x8,x9,[x3,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + stp xzr,xzr,[x1,#8*0] + stp xzr,xzr,[x1,#8*2] + cbnz x27,.Lsqr4x_cond_copy + + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + stp xzr,xzr,[x2,#8*2] + csel x16,x21,x8,lo + csel x17,x22,x9,lo + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + + b .Lsqr8x_done + +.align 4 +.Lsqr8x8_post_condition: + adc x28,xzr,xzr + ldr x30,[x29,#8] // pull return address + // x19-7,x28 hold result, x6-7 hold modulus + subs x6,x19,x6 + ldr x1,[x29,#96] // pull rp + sbcs x7,x20,x7 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x8 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x9 + stp xzr,xzr,[sp,#8*4] + sbcs x10,x23,x10 + stp xzr,xzr,[sp,#8*6] + sbcs x11,x24,x11 + stp xzr,xzr,[sp,#8*8] + sbcs x12,x25,x12 + stp xzr,xzr,[sp,#8*10] + sbcs x13,x26,x13 + stp xzr,xzr,[sp,#8*12] + sbcs x28,x28,xzr // did it borrow? + stp xzr,xzr,[sp,#8*14] + + // x6-7 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + csel x10,x23,x10,lo + csel x11,x24,x11,lo + stp x8,x9,[x1,#8*2] + csel x12,x25,x12,lo + csel x13,x26,x13,lo + stp x10,x11,[x1,#8*4] + stp x12,x13,[x1,#8*6] + +.Lsqr8x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size __bn_sqr8x_mont,.-__bn_sqr8x_mont +.type __bn_mul4x_mont,%function +.align 5 +__bn_mul4x_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + sub x26,sp,x5,lsl#3 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + sub sp,x26,#8*4 // alloca + + add x10,x2,x5 + add x27,x1,x5 + stp x0,x10,[x29,#96] // offload rp and &b[num] + + ldr x24,[x2,#8*0] // b[0] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + ldp x14,x15,[x3,#8*0] // n[0..3] + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + mov x28,#0 + mov x26,sp + +.Loop_mul4x_1st_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[0]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[0]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + // (*) mul x10,x14,x25 // lo(n[0..3]*t[0]*n0) + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0) + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + sub x10,x27,x1 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_1st_reduction + + cbz x10,.Lmul4x4_post_condition + + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldr x25,[sp] // a[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.Loop_mul4x_1st_tail: + mul x10,x6,x24 // lo(a[4..7]*b[i]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[i]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*a[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*a[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + adcs x23,x23,x0 + umulh x13,x17,x25 + adc x0,xzr,xzr + ldr x25,[sp,x28] // next t[0]*n0 + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_1st_tail + + sub x11,x27,x5 // rewinded x1 + cbz x10,.Lmul4x_proceed + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b .Loop_mul4x_1st_tail + +.align 5 +.Lmul4x_proceed: + ldr x24,[x2,#8*4]! // *++b + adc x30,x0,xzr + ldp x6,x7,[x11,#8*0] // a[0..3] + sub x3,x3,x5 // rewind np + ldp x8,x9,[x11,#8*2] + add x1,x11,#8*4 + + stp x19,x20,[x26,#8*0] // result!!! + ldp x19,x20,[sp,#8*4] // t[0..3] + stp x21,x22,[x26,#8*2] // result!!! + ldp x21,x22,[sp,#8*6] + + ldp x14,x15,[x3,#8*0] // n[0..3] + mov x26,sp + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + +.align 4 +.Loop_mul4x_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[4]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + // (*) mul x10,x14,x25 + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 // lo(n[0..3]*t[0]*n0 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0 + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_reduction + + adc x0,x0,xzr + ldp x10,x11,[x26,#8*4] // t[4..7] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + + ldr x25,[sp] // t[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.align 4 +.Loop_mul4x_tail: + mul x10,x6,x24 // lo(a[4..7]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[4]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*t[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*t[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + umulh x13,x17,x25 + adcs x23,x23,x0 + ldr x25,[sp,x28] // next a[0]*n0 + adc x0,xzr,xzr + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_tail + + sub x11,x3,x5 // rewinded np? + adc x0,x0,xzr + cbz x10,.Loop_mul4x_break + + ldp x10,x11,[x26,#8*4] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b .Loop_mul4x_tail + +.align 4 +.Loop_mul4x_break: + ldp x12,x13,[x29,#96] // pull rp and &b[num] + adds x19,x19,x30 + add x2,x2,#8*4 // bp++ + adcs x20,x20,xzr + sub x1,x1,x5 // rewind ap + adcs x21,x21,xzr + stp x19,x20,[x26,#8*0] // result!!! + adcs x22,x22,xzr + ldp x19,x20,[sp,#8*4] // t[0..3] + adc x30,x0,xzr + stp x21,x22,[x26,#8*2] // result!!! + cmp x2,x13 // done yet? + ldp x21,x22,[sp,#8*6] + ldp x14,x15,[x11,#8*0] // n[0..3] + ldp x16,x17,[x11,#8*2] + add x3,x11,#8*4 + b.eq .Lmul4x_post + + ldr x24,[x2] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + adds x1,x1,#8*4 // clear carry bit + mov x0,xzr + mov x26,sp + b .Loop_mul4x_reduction + +.align 4 +.Lmul4x_post: + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + mov x0,x12 + mov x27,x12 // x0 copy + subs x10,x19,x14 + add x26,sp,#8*8 + sbcs x11,x20,x15 + sub x28,x5,#8*4 + +.Lmul4x_sub: + sbcs x12,x21,x16 + ldp x14,x15,[x3,#8*0] + sub x28,x28,#8*4 + ldp x19,x20,[x26,#8*0] + sbcs x13,x22,x17 + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + ldp x21,x22,[x26,#8*2] + add x26,x26,#8*4 + stp x10,x11,[x0,#8*0] + sbcs x10,x19,x14 + stp x12,x13,[x0,#8*2] + add x0,x0,#8*4 + sbcs x11,x20,x15 + cbnz x28,.Lmul4x_sub + + sbcs x12,x21,x16 + mov x26,sp + add x1,sp,#8*4 + ldp x6,x7,[x27,#8*0] + sbcs x13,x22,x17 + stp x10,x11,[x0,#8*0] + ldp x8,x9,[x27,#8*2] + stp x12,x13,[x0,#8*2] + ldp x19,x20,[x1,#8*0] + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + + sub x28,x5,#8*4 +.Lmul4x_cond_copy: + sub x28,x28,#8*4 + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + ldp x6,x7,[x27,#8*4] + ldp x19,x20,[x1,#8*4] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*2] + add x26,x26,#8*4 + csel x13,x22,x9,lo + ldp x8,x9,[x27,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + add x27,x27,#8*4 + cbnz x28,.Lmul4x_cond_copy + + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + stp xzr,xzr,[x26,#8*2] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*3] + csel x13,x22,x9,lo + stp xzr,xzr,[x26,#8*4] + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + + b .Lmul4x_done + +.align 4 +.Lmul4x4_post_condition: + adc x0,x0,xzr + ldr x1,[x29,#96] // pull rp + // x19-3,x0 hold result, x14-7 hold modulus + subs x6,x19,x14 + ldr x30,[x29,#8] // pull return address + sbcs x7,x20,x15 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x16 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x17 + stp xzr,xzr,[sp,#8*4] + sbcs xzr,x0,xzr // did it borrow? + stp xzr,xzr,[sp,#8*6] + + // x6-3 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + stp x8,x9,[x1,#8*2] + +.Lmul4x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size __bn_mul4x_mont,.-__bn_mul4x_mont +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 4 diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S new file mode 100644 index 0000000000..efd46af5e4 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S @@ -0,0 +1,4242 @@ +#include "arm_arch.h" + +.text +.globl ecp_nistz256_precomputed +.type ecp_nistz256_precomputed,%object +.align 12 +ecp_nistz256_precomputed: +.byte 0x3c,0x4d,0x27,0xcc,0xf5,0x4a,0x4f,0x8f,0xe8,0xc8,0x04,0x68,0x09,0x4a,0x5b,0x80,0x9d,0x7a,0xe8,0x31,0x08,0x76,0x68,0x19,0x9f,0x08,0xb4,0x1f,0x32,0x43,0x89,0xd8,0x34,0xd3,0xf5,0xb7,0xb5,0xee,0x42,0x3e,0x91,0x01,0x06,0x7c,0xbf,0xd9,0x97,0x12,0xd3,0x1a,0xc9,0x04,0x8d,0x53,0x83,0x14,0x28,0xf0,0x8e,0x19,0xcc,0x91,0xe5,0x80 +.byte 0x14,0xd6,0xc1,0x8d,0x61,0x66,0x3b,0xa7,0x20,0x1e,0xe4,0x77,0xd7,0x66,0x05,0xfb,0x5c,0xa9,0x9a,0x7a,0xb2,0x30,0x50,0x28,0x87,0x80,0xfe,0xcd,0xe1,0xb3,0xff,0xa3,0x45,0x3c,0x7e,0x9b,0x08,0xc0,0xc1,0x9f,0x2e,0xad,0x7d,0x89,0x79,0x90,0x60,0xc6,0xac,0x17,0x64,0x59,0x4d,0xcf,0x56,0x7a,0xca,0x82,0xaa,0x6e,0x04,0x2f,0x1f,0x8b +.byte 0xa9,0xdd,0xeb,0x91,0x5c,0x77,0x17,0x99,0x4e,0xc2,0x45,0x69,0x2e,0xcf,0x60,0xc6,0x3c,0xad,0x65,0x33,0x35,0x6f,0xe4,0xd0,0x37,0x1f,0xe2,0x2c,0x66,0x98,0x55,0xe3,0x66,0xa2,0xc6,0x21,0xce,0x63,0x59,0x2e,0xd2,0x2b,0x8a,0x5a,0xcd,0xee,0xa7,0xad,0xf6,0x8c,0x3f,0x44,0x6c,0x12,0x30,0x8d,0xca,0xea,0x46,0x8a,0x4c,0x96,0xf9,0x96 +.byte 0x18,0x10,0x4e,0x46,0xc4,0x3e,0xa0,0x94,0x26,0x9d,0x62,0xd2,0x4b,0xb0,0xbc,0x0b,0xd5,0x56,0xa5,0xd2,0xc1,0x2f,0x2d,0x15,0xd8,0xed,0x97,0x17,0xcb,0x32,0x67,0xc5,0x0f,0x7c,0xde,0xa8,0x8c,0x4d,0xa0,0xb8,0x2e,0xed,0x24,0xd5,0xd5,0x49,0xca,0x77,0x1f,0x48,0x3b,0x83,0x54,0xb2,0xe7,0x7e,0x7a,0xa7,0x5c,0xed,0x7f,0xa1,0x9f,0x05 +.byte 0xd4,0xd4,0x90,0x0d,0xae,0x37,0x4e,0xd1,0x8f,0xd1,0x0a,0xa7,0x63,0x5b,0xb7,0x65,0xcb,0xc8,0xba,0x29,0xec,0x35,0x53,0xb2,0xac,0x32,0xf4,0xb7,0x6a,0xb1,0x69,0xcf,0x56,0x14,0x7f,0xd6,0xc5,0xca,0x88,0x1d,0x49,0xcf,0xfd,0x1f,0xcc,0xb1,0x13,0x30,0x42,0xd0,0x1c,0x6e,0x38,0x8e,0xf9,0x40,0xe7,0xe8,0xd6,0x28,0x1a,0x75,0x31,0xf3 +.byte 0x30,0x46,0x3f,0xb5,0x8a,0x47,0x35,0x4c,0x6e,0xdb,0x26,0x1a,0x25,0xa3,0xd8,0x0b,0x1d,0x51,0x12,0x91,0x4c,0x11,0x76,0x83,0x19,0xad,0x2a,0x3e,0xb4,0x1c,0x3c,0xfc,0x14,0x20,0x84,0x58,0x7b,0xc3,0x94,0x68,0x60,0x5c,0x3f,0x7c,0x26,0xb5,0x75,0x41,0x0b,0xc2,0xec,0xf3,0x96,0x5b,0xbb,0x41,0x32,0x00,0x4e,0x68,0xeb,0xf1,0xd9,0x96 +.byte 0xe7,0x00,0xac,0xb0,0x1b,0x39,0x46,0xf1,0xc9,0x18,0x7d,0xb7,0xc4,0x42,0xbc,0x8b,0x09,0x3e,0xa9,0x97,0x2e,0xc6,0xf8,0x38,0xa3,0xe4,0x2c,0x52,0x5d,0x24,0xf7,0xc5,0x15,0xab,0x16,0x5e,0x46,0x2c,0xd8,0xd7,0x4d,0xb3,0xf2,0xfd,0xe4,0x75,0x3c,0x34,0x95,0xb9,0x8c,0x92,0x35,0x42,0x8b,0xc4,0xc8,0x6c,0xd4,0x1e,0x67,0x35,0xd3,0x6d +.byte 0x79,0x85,0xff,0x74,0xbe,0x40,0x07,0x27,0x75,0x2c,0xea,0x04,0xcc,0xa2,0x72,0x80,0x97,0x5f,0xfe,0x8a,0x56,0x0f,0xf4,0x6d,0xa4,0x61,0x04,0x4b,0x5e,0xb4,0xe2,0xd8,0x87,0xb6,0xfd,0x3d,0x00,0x8a,0xa9,0xe4,0x62,0x5f,0x4f,0xec,0x1e,0x40,0x28,0x6b,0x21,0x0f,0x50,0x26,0x97,0xa0,0x25,0x8f,0x3e,0xf2,0x69,0xdc,0x36,0xe5,0xb8,0xdb +.byte 0x01,0x7d,0xfb,0x73,0x7d,0x3e,0xf7,0x55,0x41,0x39,0xe0,0x33,0x0d,0xe3,0x4b,0x6b,0x7b,0x3e,0x6e,0xdc,0x7d,0x9a,0x6e,0x35,0xb0,0x38,0x13,0x92,0x80,0xa1,0xe6,0xbf,0x03,0x9d,0xb7,0x7f,0x55,0xce,0x46,0x3c,0x22,0xc7,0xfa,0xfb,0x18,0xba,0x06,0xa0,0x09,0x78,0x3f,0xc0,0x79,0x5f,0xe6,0x6a,0x29,0xaf,0xd1,0xc7,0x84,0xa7,0xed,0xb9 +.byte 0xb6,0x82,0x81,0xc1,0x53,0xee,0x00,0x34,0xa8,0x81,0xdf,0x5a,0xd3,0x07,0x7e,0x2e,0x17,0x40,0xa1,0x2b,0xf4,0x2a,0x1f,0x9a,0x67,0x75,0x73,0xa8,0x58,0x65,0x17,0xdf,0xf1,0x84,0x76,0xc5,0x8d,0x48,0x93,0xe1,0x28,0xa5,0x73,0x10,0x6e,0x9e,0x39,0x03,0x69,0x52,0xdf,0xf9,0x46,0x7c,0x5b,0xf3,0x5b,0x9a,0x63,0xd9,0x4f,0xf5,0x8e,0x73 +.byte 0xed,0x33,0x7d,0x23,0xb9,0x6c,0x3c,0x9b,0xa7,0xcf,0x7f,0x34,0x6f,0x97,0xe2,0xfe,0x0a,0x8b,0xe1,0x86,0x83,0x91,0x2e,0xdd,0x6b,0xb1,0xbf,0xa6,0x92,0x4f,0x30,0x79,0x68,0x91,0x3e,0x06,0x17,0xe9,0x0b,0x25,0x07,0xa6,0x88,0x91,0x6c,0x6e,0xc8,0xd8,0xdc,0x68,0x5e,0x45,0xf2,0x55,0xef,0x56,0x38,0x29,0xd0,0x89,0x40,0x58,0x51,0x9f +.byte 0x5f,0xa4,0x08,0xc6,0x94,0x34,0xd2,0x6f,0x59,0x0f,0x6e,0xca,0x85,0x7f,0x56,0x3f,0xac,0x8f,0x25,0x0f,0x47,0xe3,0x9e,0x40,0xed,0xd8,0xae,0x30,0x0d,0xb4,0x47,0x40,0x4b,0xa3,0x23,0x1b,0x7f,0x0f,0xff,0xdf,0x6f,0x1d,0x87,0xb2,0x94,0xa0,0x36,0xbb,0x53,0x13,0x1e,0xaf,0x92,0xf8,0x07,0x95,0xc7,0xe4,0xa8,0x41,0xa9,0xed,0xf0,0x08 +.byte 0xfc,0xc1,0x4a,0xed,0x9a,0x4f,0x13,0xc5,0xed,0x8a,0x95,0xf5,0x69,0xf7,0xee,0x75,0xb6,0x4d,0xba,0x8f,0x65,0x23,0xe8,0x50,0x9e,0x7a,0xd7,0x28,0x3a,0x49,0xe7,0x4c,0x7c,0xc6,0x64,0xbd,0x8c,0x17,0x14,0x0b,0xb5,0xe3,0xb4,0xab,0x0b,0x9a,0xa9,0x29,0x84,0xaa,0xba,0x69,0xc4,0x2e,0xbf,0xca,0x57,0x0d,0xd3,0x36,0x21,0x61,0x00,0x13 +.byte 0x95,0xe3,0xf8,0xa6,0x64,0x74,0x02,0xb5,0xbf,0x86,0x07,0xde,0x67,0x48,0x23,0xe0,0x24,0x96,0x3a,0x86,0xb2,0xfa,0xa7,0x75,0xb4,0x26,0x42,0xcb,0x96,0x4e,0xf7,0x90,0xae,0xa5,0xe4,0xd0,0x45,0x31,0xe7,0x0f,0xe0,0xcb,0xbf,0x94,0x94,0x33,0x4f,0x65,0x04,0xfb,0xc0,0xc4,0x3f,0x51,0xa5,0xf3,0xea,0xc8,0xd5,0x23,0x66,0xe0,0x48,0x09 +.byte 0xba,0x6a,0x27,0x50,0xec,0xae,0xd2,0x2a,0xe6,0xf9,0xe4,0xde,0x35,0x6e,0xcc,0x82,0x76,0xfc,0x36,0x16,0xe1,0x9f,0xc7,0x0d,0xc1,0xc9,0x6a,0x23,0xbe,0xa1,0x3c,0xfd,0xce,0xa7,0x2e,0x91,0x36,0x23,0x5a,0x20,0xdf,0x55,0xc5,0x91,0x32,0x5c,0x62,0x49,0xe7,0x8b,0x0b,0x0e,0x9c,0x2e,0xee,0x1f,0xfe,0xca,0x00,0xfc,0x55,0xd7,0x9c,0x0a +.byte 0x75,0xaa,0xb0,0x46,0x90,0x55,0x2b,0x46,0xab,0x98,0x9d,0xab,0x0e,0x12,0x03,0x58,0xf1,0x4a,0x68,0x59,0x74,0xc9,0x37,0x6d,0x6f,0xe6,0xd3,0x73,0xf1,0xa3,0xdd,0xbe,0x85,0xca,0x74,0xc6,0xb6,0x51,0x6f,0x83,0x6f,0xa1,0x80,0x00,0x00,0x78,0x0a,0xa7,0xff,0xa7,0xe2,0x2e,0x5f,0x4f,0x31,0xbb,0x1b,0x99,0x21,0x33,0x59,0x6e,0x03,0x38 +.byte 0x10,0xd9,0x98,0xf2,0x0c,0xad,0x08,0x6b,0x00,0x49,0xb5,0x5e,0x11,0x60,0x70,0x49,0xff,0x79,0xac,0xba,0x30,0x3d,0x69,0x9f,0xaf,0xfb,0xd7,0xeb,0xe2,0xcd,0x0d,0x97,0xb9,0x94,0xc8,0x6e,0x06,0x3b,0x64,0x80,0x71,0x8f,0x81,0xb0,0x58,0xe0,0xc7,0xbd,0x27,0x6a,0xd4,0xb7,0xd9,0x6c,0xc1,0x44,0x38,0xe1,0x36,0xbc,0x0a,0x33,0x26,0x01 +.byte 0x25,0x90,0xbc,0x0a,0xc2,0xa3,0xbb,0xfc,0xeb,0x0b,0x1a,0x38,0x98,0x26,0x93,0xf5,0x2d,0x29,0x41,0x83,0x3b,0xba,0x40,0x46,0xf3,0xf6,0xfd,0x53,0xb9,0x7a,0x60,0x01,0x8a,0x8d,0xb4,0x57,0xd8,0xf3,0x36,0x72,0x22,0x2f,0x59,0xd3,0x7f,0x25,0xf2,0x05,0x61,0xfa,0x18,0x28,0xac,0xd5,0x14,0x00,0xaf,0x8b,0x7c,0x39,0xb5,0xa2,0xcb,0x1e +.byte 0x62,0x14,0xcb,0x10,0x76,0x17,0x23,0x2c,0xc8,0x25,0xac,0x37,0x9e,0x83,0x81,0x83,0xfe,0x2e,0x2c,0xd2,0x3f,0xf8,0x58,0x2b,0xf1,0x7f,0x4f,0xe1,0x17,0xc7,0xf7,0xad,0x57,0x67,0xc2,0x57,0x77,0x2e,0xfb,0xf2,0xce,0xa9,0x74,0x81,0x47,0xf8,0x5a,0x88,0x76,0xb1,0x43,0x75,0xc8,0xc4,0xc8,0x60,0x1e,0xd7,0xd1,0x1c,0xce,0x89,0x82,0xc6 +.byte 0x77,0x8d,0x87,0xe8,0xd0,0x5b,0x0c,0xf0,0x44,0x48,0x8d,0xee,0x55,0xc6,0xe4,0x2c,0x2c,0x41,0x75,0x5d,0x5a,0xd2,0xa3,0x1d,0x32,0x85,0x08,0xcf,0x03,0x3a,0x3c,0xfe,0x65,0x75,0xef,0xd2,0xa6,0x22,0x16,0x66,0x39,0x30,0x05,0xe3,0x57,0xab,0x71,0x6d,0x28,0xd5,0x2f,0xc6,0xa8,0x25,0x46,0x14,0xfd,0x7e,0xa2,0x67,0x7e,0x20,0x91,0xc2 +.byte 0x2b,0x03,0xdd,0xac,0xaa,0x1a,0xb5,0x2a,0x04,0xd6,0x15,0x9d,0x3f,0x54,0x24,0x7c,0x75,0xab,0x77,0xd9,0x6c,0x85,0xa2,0xf9,0x33,0xeb,0xeb,0xc0,0x27,0xcd,0x9d,0x58,0xae,0xa3,0x34,0x10,0xae,0x85,0x7d,0x4c,0x15,0x4c,0x90,0x46,0xe0,0x5b,0xec,0xa7,0xb2,0x68,0x85,0x01,0xed,0xf9,0x4a,0x85,0xe3,0xb6,0xea,0xe2,0x53,0xc0,0x32,0x83 +.byte 0x73,0x05,0x77,0xac,0xb5,0x96,0xaa,0xf0,0x9c,0x2c,0xa4,0xd2,0xd4,0xbf,0x74,0x2f,0x39,0x47,0x22,0x99,0x50,0x06,0x5f,0xcb,0x99,0xc5,0xc9,0x2e,0x70,0xd6,0x68,0x6a,0xc4,0x73,0x41,0xcb,0x8b,0xfd,0x23,0x98,0x11,0x59,0xad,0x20,0x8a,0x0d,0xaf,0xaa,0xd0,0xe2,0xeb,0x32,0x8b,0x6f,0x0e,0x43,0x12,0xe3,0x27,0x8f,0xf6,0xa4,0x76,0x0b +.byte 0xfb,0x22,0xad,0xda,0x1c,0x0a,0x3e,0x90,0xc0,0x7d,0xf3,0x09,0xbc,0x17,0x33,0xef,0xf1,0xf2,0x84,0x80,0x2a,0x0b,0x82,0xd7,0x95,0xc7,0xd2,0x08,0x4a,0xf4,0xf5,0x6d,0x09,0x06,0x8e,0xe4,0x74,0x63,0x8f,0x09,0xca,0xe2,0xd9,0x0e,0x1e,0x03,0x20,0x1b,0x4c,0xfb,0x1d,0x5a,0x2e,0x28,0xeb,0x84,0x82,0x6f,0x97,0x6f,0xcd,0x7a,0xc3,0xa7 +.byte 0x79,0x73,0x66,0x0c,0x94,0xd5,0xf4,0x8f,0x2c,0x73,0x1f,0x24,0xbc,0x17,0xee,0xd5,0xb0,0xa6,0xb8,0x04,0x6d,0x6a,0xd0,0x61,0xe3,0x1a,0x49,0x97,0x94,0xc5,0x8e,0xbc,0xac,0x5b,0x0b,0x0a,0xc5,0x74,0x06,0x89,0xee,0xc2,0xb7,0x5f,0x1b,0xa1,0x6b,0x1a,0xff,0xed,0xda,0x90,0x91,0xc1,0x0d,0x6a,0x06,0xd6,0xcb,0x02,0x71,0x17,0x95,0x7d +.byte 0xc6,0x3b,0x7e,0x6b,0xc8,0x73,0x03,0x0d,0x6b,0x8f,0x73,0x56,0x59,0x2e,0x09,0x23,0x4e,0xda,0xfc,0x4e,0xfc,0xa4,0x42,0x15,0x2e,0x10,0x6a,0x97,0x48,0x3c,0xb4,0xa4,0x0c,0x64,0x21,0xc3,0xeb,0x6c,0xac,0x27,0x4f,0x43,0x94,0x91,0x78,0xdc,0xfd,0xad,0x2b,0xa7,0x43,0x42,0xb0,0x51,0xdd,0x63,0xcc,0xcd,0xb7,0x15,0xfa,0x13,0x8d,0xc7 +.byte 0x55,0x3a,0x74,0x17,0x23,0x36,0x3e,0x23,0xe1,0x42,0x90,0xe1,0xb7,0xc7,0xda,0xb7,0x57,0xeb,0xc3,0xfb,0x62,0x58,0xbf,0x31,0x2a,0xfb,0xc7,0xdb,0x3d,0xfc,0x87,0x32,0xb1,0x3e,0xe5,0x3d,0x94,0x3d,0x86,0x32,0x61,0xfe,0x19,0xd2,0x32,0x31,0x8b,0x43,0xdb,0xab,0xa4,0xe5,0x34,0xc8,0x30,0xae,0x8c,0x02,0x53,0x99,0x35,0xb4,0x56,0x38 +.byte 0x37,0xcf,0xff,0xb0,0x05,0x21,0x12,0x65,0xc4,0xb3,0x9c,0x83,0x95,0x12,0xd3,0x03,0x7a,0x80,0x97,0x5b,0x67,0x33,0x27,0xfc,0x43,0xf2,0xf7,0xaa,0x60,0xb6,0xfc,0x55,0x44,0x30,0xa3,0x4a,0xa3,0x60,0x31,0xf7,0x01,0xfa,0xb0,0x8d,0x82,0x29,0xa7,0x03,0xb7,0x7e,0x3f,0xe5,0x66,0x26,0xb7,0x51,0xcf,0x8d,0xdd,0x6f,0x83,0x39,0xfc,0x9b +.byte 0xa5,0x3d,0xb6,0x41,0x89,0x54,0xc3,0xb2,0xf0,0x24,0x64,0xcb,0x53,0xfd,0x0a,0x91,0x6c,0x6f,0x28,0xfe,0xc1,0xe9,0x17,0x2e,0x65,0x55,0x2e,0xf2,0x48,0x52,0xb1,0x69,0xf0,0xdd,0x42,0xd5,0xdf,0x7c,0x36,0x75,0xdb,0x5b,0x3d,0xa9,0x6d,0xa4,0xeb,0x47,0x4f,0x2b,0x5c,0xd0,0x30,0xee,0xa7,0x74,0x6a,0x64,0x8a,0xbc,0x9b,0xe5,0x82,0x56 +.byte 0x76,0xe4,0x3f,0xf5,0x05,0x59,0x19,0x1e,0x80,0x47,0xf1,0x77,0xac,0x32,0x43,0x80,0x0a,0x1b,0x28,0xb6,0xf4,0xe8,0x7c,0x2f,0xeb,0xa8,0x4b,0x6a,0x59,0xb5,0xf8,0x77,0x68,0xd4,0x86,0x6c,0x87,0xdc,0xc4,0x00,0x4f,0xce,0xdb,0xf6,0x34,0xc3,0x74,0x02,0x08,0xdb,0x0d,0x34,0x8d,0xea,0x49,0x4a,0x30,0x5f,0x1b,0xcd,0xa6,0x3a,0x34,0x94 +.byte 0x5f,0x32,0x6a,0x62,0x96,0x4b,0x51,0x89,0x30,0xc9,0x90,0xdf,0x77,0x73,0x0e,0x3c,0x5c,0xbd,0x5c,0xee,0xd9,0x77,0xea,0x23,0x42,0xaa,0xa5,0x6b,0xf9,0x8c,0xc4,0x70,0x68,0xdd,0x0b,0x65,0xa3,0xc7,0xe4,0x7b,0x0a,0x89,0x85,0x25,0x7d,0x84,0x99,0x39,0xe6,0xb8,0xbe,0x7f,0x31,0x0f,0x84,0x0c,0x98,0x72,0xab,0x4c,0x44,0xb0,0xa4,0x83 +.byte 0x90,0xbb,0x93,0x73,0x07,0x07,0xba,0x63,0x5b,0x61,0x70,0xe1,0x84,0xae,0xaa,0xd6,0xa3,0x5a,0x54,0xd1,0xea,0xc7,0x2c,0x7b,0x67,0x4b,0x8a,0x7f,0x66,0x28,0x8d,0x22,0xec,0x82,0x64,0x69,0x63,0xf0,0x53,0x2d,0x10,0x9c,0x9c,0x34,0x4f,0xc6,0x96,0x40,0xdb,0xce,0x0e,0xf7,0x3a,0x8a,0xee,0x3f,0x32,0x5f,0x2b,0x0c,0x4a,0xbc,0x63,0xfb +.byte 0x18,0xf6,0x26,0x57,0xc9,0x13,0x13,0xb7,0xe0,0xcc,0x3e,0x4e,0x73,0xfa,0xe2,0x54,0xc1,0x67,0xfe,0xe2,0xec,0xfd,0xaf,0xf9,0x96,0x99,0x9f,0xe9,0xe2,0xd0,0x94,0x39,0x33,0xc9,0xca,0x35,0x27,0xad,0x58,0x46,0x98,0x64,0x17,0x5f,0xe9,0xce,0x4b,0xc8,0xab,0x0d,0xd2,0x88,0xec,0xbb,0x5c,0xba,0xc1,0x30,0x4c,0xd4,0x99,0x0d,0x07,0x95 +.byte 0x0a,0xa5,0xeb,0xa6,0x10,0x4b,0x4d,0x77,0x14,0x76,0x88,0x43,0x7f,0x6b,0x5d,0x9b,0x87,0x1d,0x6b,0x5d,0xb9,0x04,0xa9,0xc7,0x28,0x18,0x70,0xa1,0x99,0xbc,0x99,0xf5,0xf1,0x71,0xa9,0x3a,0xb6,0xe5,0x98,0x98,0x8f,0x7a,0x6c,0xda,0x1a,0x63,0x0e,0xf1,0xe8,0x10,0xa3,0x7c,0x64,0x7e,0xde,0x2a,0x59,0x1b,0x04,0xca,0x69,0x8e,0xba,0x2f +.byte 0x56,0xe1,0xa7,0xab,0x4f,0xe4,0x9d,0x49,0x33,0x9e,0x4e,0x5b,0xe1,0x58,0xc4,0x3f,0x99,0x5a,0x69,0x00,0xe5,0x5f,0x85,0xcb,0x62,0x80,0x5e,0x3d,0x88,0x0a,0x32,0x42,0xc1,0xf9,0x6a,0xa0,0xeb,0x65,0x2f,0x17,0x62,0x25,0x96,0x50,0xa2,0x6e,0xd6,0xdf,0x09,0xb7,0x1e,0x68,0xb2,0x10,0x2b,0xf3,0x9e,0xb2,0x67,0x75,0x9b,0xe3,0x76,0xfe +.byte 0x95,0xbe,0x83,0xcb,0xba,0x77,0x5b,0x2d,0x5f,0xdd,0x94,0xbb,0x0e,0x5d,0x83,0xa2,0xe7,0x48,0x4c,0x84,0x86,0x41,0x47,0x4b,0x96,0x24,0x89,0xa8,0x20,0x04,0xa5,0xef,0x8e,0xb6,0xeb,0xcd,0x3c,0x77,0xc5,0x65,0x5c,0xff,0xa6,0x0d,0x2b,0x58,0x21,0x5a,0x11,0xe2,0x24,0x64,0x1c,0xd6,0x18,0x9a,0xac,0x3f,0x42,0x0e,0xeb,0x32,0x3e,0xed +.byte 0xce,0x61,0xc9,0xe4,0xe7,0xd3,0x3f,0x53,0xa4,0x80,0x2b,0x1c,0xc0,0x99,0x63,0x52,0x93,0x5e,0xdc,0x78,0xe2,0x35,0x9e,0xb2,0xb4,0x1d,0x09,0xd1,0x5c,0x1c,0x4e,0xdb,0x3a,0x5d,0x8c,0x94,0x7d,0xfe,0x63,0xf2,0xa3,0xe9,0x61,0x73,0x78,0xc1,0xd9,0x17,0x5e,0x9a,0x73,0x58,0xc3,0xe7,0xa0,0x1f,0x2a,0x62,0x15,0xf8,0xdb,0xbb,0x38,0x80 +.byte 0x57,0xd3,0x1f,0x4c,0x4a,0x20,0x30,0xa9,0x7a,0x78,0x61,0xd9,0x90,0xb7,0x4f,0xd6,0x46,0x72,0xe7,0x41,0xb2,0xbb,0xfb,0x50,0xfe,0xe1,0xba,0x3e,0x73,0x2f,0x81,0x6d,0x2b,0x0b,0x90,0xbd,0x8a,0x3b,0x23,0x88,0xa2,0x7d,0x62,0x87,0x96,0xc9,0xcc,0x66,0x28,0x89,0xa7,0x29,0x41,0xd2,0xc5,0x5b,0xdb,0xc4,0x0c,0xbb,0x19,0x4e,0xd5,0x12 +.byte 0x53,0x48,0x5c,0xf2,0x9b,0x62,0xd0,0xa3,0x77,0x40,0x85,0x12,0x2b,0x2d,0x52,0x1b,0x31,0xbd,0xe9,0x1c,0xd4,0x87,0xa4,0xd7,0xc9,0x14,0xb7,0x39,0x66,0x8c,0xfe,0x3e,0x83,0x00,0x01,0xae,0x44,0x2d,0x7d,0xa1,0xda,0x66,0xb0,0x66,0xcb,0x62,0x55,0x9f,0x92,0x80,0x4e,0x8d,0x7f,0x70,0x95,0xc2,0xf2,0x1b,0xe9,0x35,0xf8,0x42,0x04,0x65 +.byte 0xf2,0x36,0x4c,0x96,0x30,0xd3,0x47,0x9d,0xb7,0x2b,0x76,0xac,0x75,0xb5,0xb8,0xf1,0x7d,0xa2,0x36,0xef,0x9d,0xa7,0x60,0x51,0x8d,0xcf,0x00,0x3d,0xdb,0xcc,0xe9,0xe2,0xc4,0x7b,0x3a,0xeb,0x2b,0xc3,0xd8,0x0b,0xb0,0x58,0x41,0xa0,0x47,0xab,0x07,0xf5,0x7c,0x9e,0x0b,0x7a,0x16,0x8f,0xb4,0xca,0x09,0xed,0x84,0xa1,0xfa,0xdc,0x7c,0x3c +.byte 0xdd,0x2f,0xb0,0x2d,0xeb,0x93,0x28,0xf5,0x1e,0x0c,0x1a,0x0c,0x35,0x27,0x40,0xf2,0x22,0x66,0x2d,0x82,0xf2,0x94,0x03,0xa5,0x4b,0x84,0x92,0x1d,0x98,0xd5,0xd9,0x09,0x6a,0xfd,0x65,0xe5,0xa1,0x0e,0xe2,0xd9,0xb6,0xd1,0xba,0xbf,0xc7,0x42,0x22,0x39,0x83,0xbf,0x37,0xf6,0x80,0xc2,0xea,0xdf,0xb9,0x33,0xa0,0xaf,0xd7,0xe3,0x70,0x9a +.byte 0x5c,0xf8,0x1a,0x47,0x2b,0xb5,0xdd,0x15,0xe3,0x08,0xc8,0x37,0xe3,0xc2,0x25,0x87,0x0e,0x3c,0xc5,0xae,0x61,0xa4,0x4a,0x56,0x50,0x08,0x58,0x68,0xa3,0x4a,0x28,0x08,0xef,0x92,0xd5,0x13,0x50,0x09,0x76,0x34,0x47,0xae,0xa8,0x7f,0xa5,0x2b,0x13,0xb7,0x5a,0x96,0x65,0x62,0xf2,0xaa,0xb4,0x4b,0x2a,0xad,0xea,0x2c,0x0d,0x1e,0x97,0x82 +.byte 0xe4,0x6f,0xfe,0xf4,0x88,0x14,0x7b,0xba,0x45,0xbe,0x61,0x56,0xd2,0x37,0x1b,0x65,0xb8,0x0b,0x77,0xcb,0x3c,0xfe,0x9f,0xe3,0x39,0xc5,0xfb,0x2a,0x18,0x9b,0x60,0x99,0xd5,0x6f,0x52,0xfe,0xd8,0x04,0x88,0x1c,0x9a,0x50,0xe5,0x3b,0x33,0x3f,0xca,0xc5,0x5b,0x9c,0x5f,0x35,0x13,0x65,0xa6,0x21,0x78,0x19,0xeb,0xff,0x35,0x70,0x81,0xaf +.byte 0x19,0x23,0x61,0xd6,0xeb,0xff,0xa6,0x9e,0x5d,0x3f,0x7f,0x89,0x2e,0x22,0xa4,0x0b,0x9c,0x4f,0xa9,0xff,0xbb,0x23,0x29,0xa1,0xf4,0x8a,0xb7,0x4b,0xfb,0xbf,0xeb,0x0a,0x47,0x87,0x78,0x2b,0x20,0x38,0x82,0xab,0x7e,0x2c,0xdc,0x08,0x2b,0xb4,0xae,0xd8,0x64,0x44,0x1a,0xdf,0x21,0x62,0x27,0xf2,0x61,0x63,0x37,0xad,0xd4,0x06,0x4e,0xae +.byte 0xba,0xeb,0x08,0xfa,0xe5,0xad,0x5d,0xcf,0xce,0x38,0xe5,0xca,0x74,0x83,0x42,0x4b,0xe8,0x8f,0xfb,0xff,0x83,0x4d,0x27,0x88,0x43,0x62,0xdd,0x80,0xa2,0x06,0x98,0x48,0x58,0x6f,0x54,0x16,0x6f,0xbf,0x81,0x36,0xc8,0xf3,0xea,0x4b,0xf7,0x5a,0x7b,0xb7,0xf4,0xa4,0x5e,0x22,0x52,0xe7,0x9e,0xb1,0xb6,0x7a,0xa8,0x22,0xee,0x68,0x82,0x8f +.byte 0xe4,0xcb,0xad,0x71,0xef,0x53,0xf2,0x7d,0xed,0x91,0x9e,0xf6,0x90,0x9e,0x54,0x19,0x30,0xaf,0x4a,0x17,0xc0,0x6a,0x9c,0x49,0x12,0x8b,0x6f,0xc7,0x47,0x1e,0xa2,0x64,0x28,0x1f,0x0c,0xd3,0x3e,0x59,0x66,0x8c,0x2e,0x11,0x52,0x6c,0x69,0x66,0x10,0xfb,0x27,0xe6,0x1c,0xae,0x6f,0x44,0x87,0x86,0x0d,0x3e,0xd3,0xa0,0x80,0xef,0x30,0xb9 +.byte 0xb8,0xd7,0x47,0x84,0x68,0x2b,0xf2,0x32,0x7b,0x89,0x93,0xd2,0x83,0x56,0x35,0xc3,0xbf,0x5c,0x24,0xec,0xad,0x2d,0xa4,0x49,0x63,0x89,0xc6,0xf9,0x24,0x51,0x1c,0x9b,0xd1,0xcb,0x30,0x82,0xda,0xb3,0xa7,0xe1,0x4d,0x96,0xd0,0x44,0x44,0x1d,0x4e,0xd7,0x7d,0x7a,0x51,0x2e,0x2f,0xc4,0x9f,0xdb,0x06,0x53,0xfc,0x51,0x56,0xe5,0xb9,0x6b +.byte 0x4a,0x2c,0x3e,0x62,0xc5,0x9c,0x42,0xe3,0xaf,0x3a,0x0f,0x0e,0x74,0x29,0x66,0x70,0x75,0x2a,0x06,0xd4,0x0f,0x0c,0xfd,0xea,0xcc,0x39,0xd0,0xa7,0x47,0x75,0x92,0x44,0x09,0xa2,0x3c,0x4e,0xad,0xaa,0xc4,0xc6,0xf9,0x35,0x82,0x23,0x25,0x43,0x94,0x26,0x14,0xde,0xf1,0xb9,0xb8,0xe0,0x75,0xe0,0x48,0x70,0x8a,0xc6,0x3c,0x72,0x98,0x72 +.byte 0x8b,0x15,0x58,0x17,0x73,0x29,0x67,0x21,0x56,0xc4,0x25,0x17,0x68,0xbe,0xd7,0x36,0x05,0x4b,0x58,0xa2,0x1b,0x64,0xe5,0x11,0x96,0x5a,0x3b,0xa6,0x90,0xb6,0x2d,0x7e,0x55,0xbb,0x31,0x93,0xe7,0xcc,0x2e,0x74,0xb6,0x9b,0x4d,0x04,0xc5,0x45,0x9b,0x0b,0x26,0xef,0x61,0x23,0x3d,0x7e,0xee,0x01,0x57,0xfa,0x77,0x12,0x47,0x64,0xac,0x8f +.byte 0x25,0xbe,0x8e,0x2e,0x68,0x11,0x95,0xf0,0x1a,0xd2,0x3d,0x66,0xc1,0xdb,0x97,0x9e,0xbb,0xba,0xc1,0x66,0xa4,0xb5,0x71,0x01,0xee,0xf5,0xbb,0x1e,0x9f,0x41,0xfc,0x40,0x74,0x26,0xf7,0xc6,0x2c,0x9c,0x1c,0x59,0xce,0xcf,0x18,0x17,0x81,0x5d,0xd4,0xe3,0xd8,0x46,0x62,0x9e,0x97,0xb1,0xca,0xac,0x01,0x3e,0xf8,0x96,0xa2,0xee,0xe0,0xf8 +.byte 0xf3,0x2d,0xe9,0xd2,0x1f,0x9f,0x41,0xbb,0x2f,0xe5,0x64,0x6d,0x5b,0xe7,0x47,0x0e,0x83,0x7b,0x08,0x5e,0x29,0x35,0x2f,0x75,0x31,0x44,0x4c,0xb7,0x61,0xa4,0x03,0x2e,0x15,0x94,0x7a,0xa0,0x46,0x31,0x7b,0x43,0xd9,0x14,0xa3,0x34,0x0c,0x83,0x93,0x75,0x8e,0x3a,0x1c,0xc3,0xe1,0x36,0x18,0x96,0x7a,0xfb,0x77,0xad,0xbb,0xe9,0x0d,0x4b +.byte 0x21,0x04,0x2e,0xdd,0x7a,0x63,0xc9,0x60,0xb1,0x9b,0xad,0xde,0x1f,0x65,0x8a,0x58,0x18,0x84,0x95,0xa9,0xac,0x3a,0xac,0xcb,0xb7,0xa9,0xeb,0x0c,0x7c,0x3a,0x98,0x9a,0x3f,0x56,0x23,0x51,0x58,0x59,0x4e,0xf5,0x57,0x60,0xe6,0x9d,0xf8,0xf7,0xed,0x9d,0x81,0x14,0x68,0xbe,0xaf,0x19,0xe5,0xb5,0x9b,0x5f,0xe4,0x51,0x44,0x4b,0x23,0x42 +.byte 0xdd,0x92,0x1a,0xe5,0x7e,0xef,0x77,0xbe,0x88,0x77,0x1e,0x8a,0xbd,0x2a,0x77,0xb1,0x0d,0x1b,0xe3,0x8a,0x7f,0x15,0x71,0x93,0xc9,0x5f,0x78,0x2d,0x77,0x9b,0x0c,0xad,0x76,0x3c,0x6b,0xe2,0x15,0x8e,0xe1,0x5e,0x1d,0x90,0xa5,0xd6,0xc7,0x55,0x5d,0x52,0xf7,0xcc,0x82,0x9b,0xdc,0x1d,0x80,0xa4,0xc7,0xbe,0x7c,0x4f,0xda,0x81,0x91,0x78 +.byte 0x88,0x0e,0x31,0xde,0x87,0x4c,0xdc,0x84,0x9a,0x65,0x89,0xfa,0x22,0x3e,0xde,0x3b,0x7f,0x7f,0x9b,0x3f,0x3e,0xda,0x13,0x31,0x59,0x7b,0x08,0x48,0x39,0x37,0xfd,0x1a,0x4f,0xa3,0x12,0xba,0xe5,0xd6,0xfa,0xa3,0x59,0x0b,0x3b,0x7d,0xde,0xc0,0x51,0xce,0x92,0x6b,0x3d,0x4b,0xd2,0xa4,0x68,0xc2,0x32,0x2d,0x01,0xbd,0x66,0x98,0x8f,0xa0 +.byte 0x86,0xfb,0x08,0x36,0xa9,0xd4,0x3b,0x7b,0x01,0x2d,0xaa,0x8c,0x64,0x19,0xa6,0x62,0x24,0x92,0x5e,0xc5,0x02,0x17,0x8e,0xf0,0x88,0xe9,0xd1,0x8b,0x69,0xda,0xed,0x9c,0x60,0x32,0xab,0xc0,0xbc,0x84,0x64,0x6e,0x32,0xb2,0xcd,0x24,0xf6,0xb2,0x9d,0xf5,0xf5,0x71,0xe2,0x01,0xbc,0x77,0x6a,0x5b,0x26,0x56,0xf7,0x04,0x84,0xff,0x7c,0xa4 +.byte 0xe8,0xa8,0x82,0x6c,0x40,0x24,0x93,0x3c,0x6e,0x7d,0x0d,0x22,0xd0,0xe4,0xef,0xc4,0x4e,0x26,0x66,0x61,0x75,0xe9,0x06,0x69,0x06,0xfd,0x97,0x68,0x96,0x67,0xec,0x96,0x09,0x73,0xe4,0x0a,0x3e,0xaa,0xb8,0x25,0x77,0x00,0x91,0x7a,0x2e,0xc8,0x81,0x75,0x78,0xb7,0xa5,0x27,0x55,0xf2,0xcf,0x9a,0xab,0xab,0x51,0x0a,0x65,0x47,0xbf,0x10 +.byte 0xd2,0x19,0x78,0x6b,0x35,0xf4,0xef,0x12,0x2b,0x5f,0x0c,0x28,0x7c,0xe8,0x64,0x55,0x2f,0x26,0x85,0x91,0x7a,0x9d,0x48,0x76,0x12,0x14,0x2d,0x4a,0x8a,0xd6,0xfa,0x7b,0xf9,0xc7,0x24,0x45,0xf6,0xbd,0x47,0xab,0xc6,0x4b,0x9e,0x39,0x77,0x57,0x04,0xa8,0x4d,0x43,0x99,0x5c,0xb1,0x3d,0xc2,0x4e,0xc5,0x17,0x66,0xc4,0xb6,0xdd,0x92,0x80 +.byte 0x85,0x3b,0x07,0x63,0x16,0x5f,0x67,0x76,0x9b,0xb5,0x8e,0xca,0x97,0xbb,0xf4,0x20,0xd0,0x4d,0x7b,0xd0,0xa3,0x74,0x6f,0x8a,0x68,0xc7,0x31,0x78,0x1b,0x72,0x45,0xa4,0xc4,0xf8,0xf8,0x26,0xa8,0x4d,0x08,0x2f,0x7b,0x3d,0xa0,0x2a,0xb5,0x65,0x27,0xc2,0x36,0x13,0x2d,0x8d,0x83,0xeb,0xf4,0x08,0x26,0x41,0x8b,0x32,0xf3,0x09,0x70,0x70 +.byte 0x5d,0x8a,0xcc,0xb8,0xe9,0xf7,0x08,0xdf,0x5f,0x4a,0xb8,0x8a,0xb7,0x1b,0xad,0xe2,0xc3,0x39,0x59,0xe0,0x7f,0xd0,0x66,0x7b,0x99,0x5a,0xde,0x52,0xe2,0x1f,0x47,0xc2,0x63,0x74,0x7a,0xa5,0x88,0xc3,0x24,0x70,0x4a,0x7d,0xdd,0xa4,0xe6,0xf8,0xfd,0x5c,0xfa,0x8c,0x4c,0x0f,0x52,0x95,0xf3,0x2c,0x76,0x47,0x7a,0xe8,0xdb,0xe0,0x9b,0x49 +.byte 0x88,0x5b,0x87,0x5a,0xd1,0x07,0x24,0x06,0x83,0x3b,0x25,0x23,0xe7,0xaa,0x79,0xef,0x74,0x02,0x12,0xfe,0x47,0x5c,0x77,0x73,0xf7,0x2e,0x4b,0x58,0x3b,0x60,0x7b,0x91,0x2f,0x0d,0xb4,0x6d,0x00,0x80,0x19,0xaa,0x88,0xbc,0xb2,0x7b,0xd9,0xb7,0xdd,0x32,0x47,0x62,0xf5,0x0f,0x46,0x95,0x4c,0x6c,0x01,0x67,0xfb,0xe4,0x2b,0xac,0x95,0x84 +.byte 0x25,0x0a,0xe5,0x4c,0x2d,0x4a,0x6e,0x77,0xfd,0xeb,0xe1,0x53,0xc9,0x2e,0x70,0x01,0x32,0x05,0x6d,0xc5,0xc9,0x5d,0x90,0xca,0x56,0xd1,0xd8,0x40,0x2a,0x51,0x4d,0x95,0xc3,0x57,0x8b,0xdd,0x62,0x9c,0x69,0xd1,0x03,0x89,0x95,0x38,0x2c,0xc1,0x6d,0x41,0xf2,0xc3,0xa2,0x9c,0x43,0xea,0xf1,0x02,0x00,0x56,0x46,0xbb,0x87,0x35,0x40,0x0e +.byte 0x18,0x51,0x29,0x39,0xbb,0x6d,0x15,0xf2,0xcd,0x54,0x23,0x95,0x69,0xdc,0x0a,0xb2,0x26,0xd9,0x25,0xe1,0xf1,0x07,0x7b,0x5e,0xc3,0x30,0x68,0x5f,0x2a,0xce,0x91,0x92,0x03,0x0c,0x62,0x11,0x43,0x80,0xe5,0x12,0xec,0xe3,0x4f,0x90,0xfe,0x38,0x6e,0xe9,0x7e,0x94,0x83,0x26,0x59,0x3f,0x3f,0x81,0xc6,0x94,0x98,0x09,0x80,0xff,0x01,0x44 +.byte 0xff,0x77,0x6a,0x4c,0x76,0x91,0xd9,0x12,0x59,0x9a,0x00,0x7c,0x87,0x06,0x17,0xf7,0x12,0xc7,0xee,0x04,0xd5,0x8d,0x68,0xc5,0x8d,0x80,0x10,0xcc,0x14,0x45,0xe8,0xd7,0x43,0x10,0x01,0x9e,0x61,0xc2,0xc0,0x66,0xfe,0xcf,0x5f,0x9f,0xcb,0xa3,0xf8,0xc7,0x07,0x41,0xe3,0xf2,0xda,0x6e,0x01,0x76,0xc6,0x49,0x49,0x01,0xc7,0xcf,0x6a,0x20 +.byte 0x71,0xc5,0xf0,0xb1,0xa0,0xc9,0xed,0xec,0x66,0x71,0x93,0xf5,0xc0,0x27,0x42,0xed,0xd5,0x6f,0x20,0xe1,0x86,0x3e,0xd0,0x5d,0x94,0x17,0x43,0xb4,0x98,0x0d,0x8a,0x31,0x6c,0x59,0xa9,0x0b,0xb3,0xa4,0x0b,0x46,0x0b,0xa8,0x79,0x62,0x3a,0x3d,0xbf,0xef,0x94,0xd3,0x31,0xf2,0xa1,0x55,0xe8,0x92,0x44,0x37,0x62,0x82,0x1b,0x60,0x87,0x67 +.byte 0x85,0x78,0xd5,0x84,0x73,0xa4,0xea,0x56,0x08,0x78,0x68,0x7f,0xfb,0x15,0x20,0x64,0xeb,0x6c,0xf7,0x5e,0xc0,0x79,0x83,0x59,0x7b,0xed,0x2d,0xa9,0x37,0x46,0xf3,0x62,0xb1,0xa1,0x2b,0x48,0x58,0xd9,0x0c,0x03,0xf7,0xf3,0x47,0xeb,0xd7,0x03,0x9b,0x85,0xd3,0xd7,0xd7,0x7e,0xfb,0x1a,0x25,0x83,0xda,0x06,0xa0,0x04,0x0d,0x6b,0x90,0x29 +.byte 0x2a,0xfc,0xcd,0x96,0xe9,0x17,0x4f,0xdd,0x2c,0x90,0xdf,0xf1,0xe3,0x08,0x0a,0xb8,0x0c,0x59,0x2a,0x83,0x62,0x94,0x00,0xd3,0x80,0x1a,0x31,0xd7,0x17,0x70,0xc7,0xa2,0x20,0x17,0x65,0x88,0xae,0x11,0x25,0xc9,0xba,0x76,0xa7,0x61,0x60,0xd1,0x59,0x50,0x22,0xdd,0xaa,0xcf,0x9d,0xc1,0x36,0x7d,0xf9,0x7b,0x69,0xc0,0x98,0xba,0x40,0xd5 +.byte 0xd6,0x46,0x93,0x92,0x7d,0x37,0x3f,0x3a,0x04,0x9a,0x84,0xaf,0x8e,0x61,0x04,0x26,0x54,0x33,0x84,0xc0,0xac,0x21,0x51,0xd7,0x9a,0x93,0x6e,0xf2,0x09,0x87,0xc5,0x35,0xa8,0x96,0xb0,0x64,0x90,0x35,0x52,0xed,0x0e,0xbc,0xdb,0xa6,0x06,0x3e,0xe7,0xea,0x57,0x4b,0xd7,0xc5,0x1c,0x76,0x3d,0x0d,0xc3,0x1f,0x8e,0x4f,0x12,0xdb,0x3a,0x21 +.byte 0x2a,0x69,0xc2,0x94,0xda,0x4c,0x91,0xcc,0xa8,0x36,0x89,0xd7,0x78,0xa8,0x74,0x79,0x63,0x92,0xeb,0x39,0x3b,0x84,0x8c,0xe5,0xc6,0x26,0xf0,0xef,0xcc,0xc1,0x72,0x4b,0x8e,0xcd,0xe4,0xd9,0x00,0x80,0xbc,0xdf,0xe2,0x61,0x53,0x04,0x81,0xb0,0x13,0xc5,0x6c,0x77,0x74,0xa3,0x0c,0x5b,0xef,0xef,0xea,0xc7,0x5b,0xeb,0xbf,0xee,0x54,0xd7 +.byte 0x7a,0x69,0x6e,0x39,0xc2,0xed,0x08,0x44,0x82,0x08,0x16,0x8b,0xf1,0x74,0x5f,0xeb,0x60,0xd5,0x46,0x63,0x80,0x39,0xe9,0x91,0x0a,0x17,0x8b,0xd4,0x09,0xdc,0xa6,0xab,0x6a,0xbc,0xf8,0xe9,0x09,0x19,0xc1,0x83,0x9f,0xdf,0xad,0x6c,0x31,0x94,0xb9,0xc5,0x77,0x83,0xd1,0xd8,0x76,0xeb,0x12,0x3c,0x00,0x31,0xea,0xac,0x97,0x39,0x16,0xd5 +.byte 0x81,0xfa,0x6d,0x10,0x5b,0x3e,0x20,0xe1,0x88,0x5c,0x4b,0xf3,0x04,0xd4,0xc3,0xb9,0xec,0xe5,0xb0,0x13,0xf5,0x09,0x5c,0xe8,0x27,0xe2,0xde,0x9b,0xac,0x2e,0xf2,0xe5,0x2c,0x33,0x4b,0x4f,0xec,0xc7,0x08,0xf9,0xc2,0xd3,0x1b,0x4d,0x81,0x69,0x14,0xa1,0xc5,0x0f,0xb2,0x57,0x8b,0xcc,0xca,0x3b,0xc9,0x9c,0x1f,0xee,0x06,0x4d,0xc7,0x62 +.byte 0xcb,0x8f,0x49,0x81,0xfb,0xa5,0x68,0x81,0x36,0x38,0x33,0x6b,0x9e,0x58,0xd4,0x24,0x67,0xf1,0x30,0xd6,0x08,0x61,0x5a,0x7f,0x2e,0x4e,0xf1,0xd6,0x64,0x75,0x72,0xb0,0xdf,0xcd,0xae,0x04,0x41,0xbd,0x04,0x2c,0x96,0x36,0x34,0x32,0xec,0xbd,0xd0,0xbf,0x8e,0xe8,0x47,0xe3,0x22,0xdd,0x79,0x53,0xcc,0x6a,0x25,0xf1,0x5e,0x63,0x09,0x98 +.byte 0xc5,0x6d,0x0a,0xe3,0x30,0xd6,0x52,0x70,0x21,0xb2,0xef,0x15,0x66,0x4a,0x2d,0x2b,0x5c,0xcb,0x39,0x1b,0x91,0x10,0xa6,0x02,0x22,0xd0,0xcc,0x32,0x50,0x5c,0x70,0x72,0xd1,0x03,0xb3,0x2d,0x2e,0x33,0xed,0xae,0x7a,0x07,0x3f,0x70,0x38,0x35,0xfc,0xcf,0xdb,0xfe,0x7b,0x26,0xd9,0x38,0x1e,0x52,0x07,0x2f,0x72,0x81,0xcc,0xd3,0x21,0x00 +.byte 0x63,0x48,0x38,0x44,0xb8,0x35,0xf2,0x4f,0xe5,0x33,0x8c,0xb3,0x07,0x0c,0xac,0x3d,0x73,0xe8,0xe3,0xb3,0x43,0xc5,0xb4,0x32,0xf4,0x41,0xdf,0x7b,0x06,0x3a,0xb8,0x67,0x17,0xc5,0xec,0x46,0x30,0xc0,0xa4,0x29,0x40,0xe4,0x8a,0xa3,0x14,0x84,0xa6,0x84,0xc7,0x5d,0x4b,0x57,0x37,0x9c,0x42,0xe6,0xa4,0x20,0xf7,0x5d,0xef,0x21,0xe2,0x80 +.byte 0x54,0x6d,0xf5,0xb5,0xbe,0xa3,0x95,0xcf,0x98,0xf8,0x38,0x46,0xa2,0x90,0x57,0x09,0x8f,0xb0,0x6d,0x01,0x5f,0x95,0x5a,0x78,0xf6,0xfd,0x01,0x0f,0xfd,0xa5,0xe2,0xcf,0x54,0xa3,0x2b,0xc1,0x30,0xbe,0x6d,0x1a,0xd3,0xdb,0x5a,0x17,0x43,0x46,0x93,0x81,0x0c,0x85,0x04,0x13,0xda,0xb4,0xde,0x81,0x48,0x5c,0xbc,0x42,0x9e,0x6d,0x6c,0x82 +.byte 0xff,0xa5,0x51,0xb1,0xd3,0xd2,0x3d,0x82,0x82,0xb4,0x96,0xb1,0x38,0x5d,0xc9,0x55,0xcb,0x9f,0xe5,0x47,0xd4,0x52,0x0f,0x76,0x54,0xec,0x39,0xb6,0x40,0xc3,0xc5,0xaa,0xc2,0x30,0x02,0xa0,0x68,0xc3,0x22,0x63,0x5a,0x8c,0x62,0x6d,0x40,0xc5,0xde,0x06,0x29,0x44,0x5d,0x2b,0x18,0x0a,0xa5,0x43,0x47,0xfe,0x5f,0x0f,0x63,0xa4,0x3c,0xa1 +.byte 0x62,0xcb,0x70,0x1d,0xf8,0x0e,0xc9,0xbe,0x27,0x0e,0x87,0x81,0x69,0x4c,0xea,0xbe,0xf9,0x9b,0xda,0xb6,0x9b,0xd0,0xdd,0xa0,0x1e,0x60,0x38,0x88,0x85,0x25,0x53,0xee,0x2c,0x77,0x53,0x82,0xb0,0x88,0x19,0x87,0x2a,0x77,0x7b,0x37,0x4b,0x4c,0xf4,0x96,0x5f,0x73,0xa1,0xbb,0x5c,0xfc,0x7e,0xbb,0xed,0x6f,0xb7,0x6f,0x9d,0x55,0xde,0xd3 +.byte 0xac,0xb9,0x8e,0x36,0x0f,0x3d,0xea,0x87,0xcd,0x19,0x33,0x1d,0xa8,0xee,0xfc,0xcd,0xe5,0x53,0x7b,0xdf,0x37,0x49,0x2d,0x73,0xf5,0x36,0xdd,0x42,0xc6,0x88,0x0d,0xf5,0xf2,0xba,0x2e,0x81,0xed,0x88,0x27,0x8d,0xe5,0x3f,0x83,0x5e,0xde,0x63,0x8f,0x67,0x2b,0x85,0xf3,0x2a,0x9b,0x26,0x3e,0x2b,0xe2,0x29,0xc5,0x5e,0x21,0x04,0xfe,0x5b +.byte 0xb9,0xd8,0xa7,0x7b,0xdf,0xcf,0x61,0xd6,0xaf,0x9b,0x17,0xcb,0xaf,0x8f,0x71,0xb3,0xc2,0x9d,0x9a,0x55,0x1d,0x3e,0x1d,0x17,0x25,0xc8,0x44,0x71,0x29,0x2f,0xc8,0x01,0x3b,0xe4,0xc4,0x2e,0xcc,0x3b,0xdb,0x34,0xbb,0xc0,0xcc,0xb6,0x07,0xe3,0x86,0x4c,0x62,0x02,0xe8,0xc3,0x11,0x85,0x6c,0x18,0x80,0xa3,0xbd,0x02,0x30,0x68,0x36,0xa3 +.byte 0xb6,0xc6,0xbd,0x82,0x43,0x40,0xed,0xa1,0xcf,0xc5,0xce,0xe4,0x27,0x8a,0xeb,0x8c,0x59,0xea,0x4a,0x81,0xd9,0x35,0x87,0x7d,0x6d,0xb2,0x8f,0x67,0x37,0x1f,0x11,0x60,0x0d,0xed,0x34,0xd5,0xa0,0x7b,0x46,0x71,0x68,0x19,0x69,0xd3,0x65,0x1d,0x47,0xf1,0x7e,0x16,0xd8,0xec,0xbb,0x52,0xc3,0x7b,0x62,0x5a,0xb3,0x60,0x67,0x2e,0xfd,0x57 +.byte 0xf2,0xfb,0x3d,0x63,0xe6,0x82,0x20,0xff,0x31,0x90,0x1d,0x5e,0x4f,0x04,0x9a,0xf8,0xb2,0x0c,0x84,0xff,0x7d,0xe2,0xec,0x4b,0x09,0xbb,0xdf,0xae,0xc5,0xaf,0xcb,0x8b,0xb5,0x5d,0xa8,0x53,0x78,0xf9,0xb9,0x43,0x71,0xa6,0xc2,0x10,0xfa,0xad,0xda,0xba,0x46,0x13,0x72,0x97,0xef,0x6f,0xe3,0x4f,0x5f,0xf9,0xec,0x25,0xdb,0xcd,0xca,0x33 +.byte 0x7e,0x50,0x73,0x5b,0xd0,0x9f,0xea,0xd5,0xd9,0x29,0xe8,0x1b,0xc1,0xf8,0x40,0xbf,0x50,0xdb,0x8e,0x39,0x0b,0xb7,0x6c,0xf1,0x34,0x0b,0x1f,0x88,0x27,0x4b,0xea,0x1d,0xb2,0x36,0x07,0x4b,0x22,0xa9,0xd0,0xf8,0xf2,0x13,0x8e,0x97,0x9d,0xd9,0x53,0xd3,0xdc,0x63,0x40,0x11,0xc7,0x74,0x9e,0xd9,0x83,0x01,0xae,0x36,0xcb,0x35,0x9a,0x0c +.byte 0xb5,0x15,0x0a,0xf5,0x41,0xa5,0x6c,0x72,0x40,0x80,0xf0,0x15,0xc0,0x80,0x23,0x0b,0xab,0x98,0xfc,0xab,0x81,0xe0,0x8b,0x61,0x91,0x18,0xd2,0x23,0x71,0xed,0x32,0x80,0x26,0x86,0x96,0xe9,0x90,0x5e,0x43,0xd2,0x89,0x8f,0x89,0x57,0x73,0xca,0xe1,0x42,0xa9,0xa9,0xed,0xdd,0xc5,0x9f,0xf7,0x00,0x0d,0xa3,0xe5,0xc8,0x6f,0x0c,0x14,0xa4 +.byte 0x9d,0x5a,0x14,0xaf,0x96,0x3a,0xb2,0x64,0xa7,0xac,0x20,0xa9,0x01,0x4c,0xec,0x64,0xc6,0x9b,0xfd,0x04,0xc5,0x2e,0xe7,0xdd,0xa5,0x8e,0xe7,0xe7,0x76,0x53,0x59,0x95,0x14,0x07,0xed,0xe9,0x96,0xd0,0x2d,0xc8,0x9d,0xa2,0x11,0xe3,0x02,0x20,0x68,0x09,0x25,0x69,0x07,0x88,0xdb,0x26,0x36,0xf5,0x8e,0xc3,0xf0,0x70,0x8c,0xeb,0xe6,0xcd +.byte 0xad,0xf3,0x49,0x6e,0x8a,0x54,0xa6,0xdd,0x97,0x8e,0x37,0x28,0x3a,0x6d,0xc4,0xdd,0x99,0x85,0xf7,0x96,0x63,0xb4,0xa2,0xdf,0xff,0x81,0x17,0xa1,0x22,0xb1,0x43,0x5b,0x29,0xdb,0x92,0x91,0xc9,0xc6,0x8d,0x29,0x1d,0x6e,0xe3,0x44,0x3e,0xe4,0x20,0xd5,0xf4,0x4a,0xfa,0xae,0xf6,0x2c,0xff,0x80,0xc9,0xce,0x7f,0x13,0x1e,0xd7,0x24,0xa2 +.byte 0xb3,0x90,0xb8,0x20,0x18,0xe5,0x6c,0x0e,0xf5,0xc6,0x26,0xd6,0xe9,0xe8,0x55,0xe4,0x3f,0x49,0x13,0xe2,0xca,0xef,0x9b,0xc0,0x8f,0x24,0x50,0x37,0xef,0x21,0xff,0x79,0xb7,0x5d,0x86,0x03,0xfb,0x85,0x75,0x74,0xbf,0xc5,0x3a,0x30,0xcc,0x00,0xc3,0x0d,0x4f,0x91,0xd6,0x31,0x19,0xd6,0xcd,0x0e,0x1c,0x53,0x88,0x75,0xb8,0xf9,0x68,0x7a +.byte 0xa4,0x3e,0x8d,0xed,0xba,0x05,0xb4,0x6c,0xe0,0x45,0x9c,0x41,0x34,0x24,0x82,0xaf,0x9a,0xcf,0x9e,0xd2,0x27,0x5c,0x7f,0xb3,0xcb,0xe5,0xad,0xb4,0x8e,0x74,0x9d,0xe4,0xba,0x55,0xb3,0xd3,0x32,0xbc,0x62,0x11,0xb3,0xa4,0x82,0xf0,0xd8,0xfc,0x79,0x03,0x70,0xae,0x7f,0x7f,0xc8,0x50,0xb5,0xbe,0x47,0x14,0x31,0xd7,0x16,0x65,0x52,0x3b +.byte 0xbb,0x42,0x38,0x23,0x77,0x4d,0x38,0x0b,0x0a,0x61,0x94,0xac,0xa3,0xc9,0xd7,0x99,0x4f,0x34,0x3a,0x88,0xe8,0x1d,0x0b,0x97,0x48,0x6d,0x5c,0x61,0x4c,0x3f,0xc2,0x7c,0x6c,0x63,0x00,0xdd,0x59,0xae,0xcd,0x17,0x0a,0x21,0x27,0x98,0x15,0x23,0x6d,0x84,0x7e,0x24,0xd4,0x7f,0x1b,0x3a,0x98,0x52,0xc3,0x60,0x33,0xd6,0xc1,0xfe,0x68,0xa8 +.byte 0x49,0x3d,0x7e,0x53,0xee,0x0d,0xed,0x89,0x9a,0x9a,0xe6,0xa1,0x47,0xc7,0xba,0xf3,0x73,0x5b,0xef,0x33,0x51,0x8c,0x1f,0x84,0xa6,0xef,0x77,0x94,0x2d,0xd6,0xda,0x8f,0x85,0x8c,0xd3,0xb6,0x02,0x68,0x9e,0x57,0xb6,0xd9,0x1a,0x8c,0xb5,0xf4,0x61,0x39,0x29,0xb5,0xb7,0x0d,0x0d,0xa6,0x81,0x87,0x54,0xc0,0xca,0x67,0x09,0xca,0x20,0xf3 +.byte 0x37,0x7e,0x03,0x3e,0x31,0x8c,0x51,0x89,0x06,0x81,0xf6,0x7b,0x8b,0xe3,0x4f,0xd0,0xb8,0x0c,0x34,0x7c,0xd6,0xfc,0x25,0xf8,0x00,0xa6,0x10,0x15,0x0d,0xeb,0x22,0x72,0x03,0x79,0x1c,0x84,0x1d,0x3d,0x10,0xaf,0x43,0x6d,0xd7,0xed,0x10,0x2c,0x14,0x26,0xd4,0xa1,0xee,0x6c,0x7f,0x52,0xe4,0x83,0xcc,0x5f,0x1a,0x4b,0xd0,0xc8,0xfb,0x27 +.byte 0x17,0x2c,0xf6,0x90,0x02,0xb4,0xb0,0x63,0x7c,0x14,0xec,0x9e,0x08,0x60,0xec,0x45,0x85,0xc6,0x76,0x42,0x4f,0x1c,0x5f,0x48,0x7f,0x87,0xef,0x8c,0x04,0x23,0x3c,0xda,0x39,0xbc,0xec,0x09,0xda,0xeb,0x9b,0x72,0x7a,0xb4,0x20,0x1c,0xb2,0xdd,0x2e,0x63,0x72,0xd7,0xb1,0xfe,0x5b,0x21,0x28,0xfb,0xeb,0x45,0x31,0x89,0xe5,0x3e,0xa0,0x85 +.byte 0xa6,0x96,0xdb,0x42,0xd5,0xb4,0x27,0x78,0x10,0xa0,0xcb,0x69,0x68,0x1e,0x76,0xed,0xbc,0x3c,0xa1,0x04,0x10,0x81,0x2a,0x4f,0x52,0x78,0x1e,0xae,0x5a,0x47,0x69,0x81,0xee,0xd3,0x14,0x1a,0x68,0x19,0x75,0x92,0x72,0x47,0x61,0x70,0xcf,0x96,0x35,0xa6,0xbb,0x00,0xaf,0x3e,0x90,0x86,0x22,0x9b,0x72,0x8a,0xa1,0x05,0xe2,0xfb,0xdc,0x30 +.byte 0xd5,0xdd,0x46,0x1f,0xf6,0x33,0x43,0xd1,0x59,0xc4,0x93,0x89,0x36,0x6a,0x7b,0x76,0xa7,0x40,0x6c,0xb1,0x9c,0xce,0x3a,0x8c,0xb6,0xd5,0xd1,0x0a,0x78,0xf6,0x08,0xfb,0xf5,0x9c,0xee,0x74,0x0d,0x39,0x51,0x6d,0x0e,0xa6,0xe9,0x22,0xd8,0x30,0xdf,0x16,0xf7,0xe3,0xbd,0xbb,0xe6,0x45,0xb8,0x9c,0xb5,0x49,0xf0,0xe8,0x7c,0xce,0x25,0xf8 +.byte 0x46,0xc0,0x59,0xc2,0xbc,0xdd,0xea,0x3e,0xeb,0x2e,0xf5,0xfd,0xd9,0x05,0x8a,0x2f,0xa3,0xa4,0x63,0xa6,0x50,0x08,0xce,0x2a,0x69,0xe7,0x58,0x57,0xa1,0xb2,0x44,0x41,0x04,0xfc,0x61,0xb1,0xb8,0x19,0x27,0x14,0x71,0x2f,0x55,0x64,0x28,0xa0,0xcc,0x47,0x0c,0xd4,0xed,0xfd,0x07,0x99,0xc6,0x9e,0xdc,0x5f,0x19,0x03,0x1a,0x00,0xda,0xf6 +.byte 0x2c,0x95,0xb0,0xd2,0xaa,0xfb,0xbc,0x1a,0xf3,0x62,0xaf,0x9c,0x38,0xde,0x61,0x30,0xd5,0x56,0x82,0x4b,0xf6,0xeb,0x34,0xc0,0xdc,0x51,0x97,0x89,0x80,0x47,0x9d,0x2a,0xae,0x0e,0x92,0x48,0xd2,0x9d,0x5a,0x67,0xef,0x33,0xa3,0xbe,0xdd,0x80,0x64,0x9c,0xc1,0xaf,0xf9,0x1a,0x4b,0x55,0x67,0x88,0x37,0x37,0xff,0x98,0xe3,0x9e,0xa9,0x4e +.byte 0x1f,0xa1,0x32,0x70,0xa3,0xbb,0xdc,0x6e,0xb3,0x6d,0xfe,0x8f,0x74,0x89,0xed,0xe1,0x13,0x3c,0x8f,0x08,0x75,0x84,0x84,0xee,0xac,0xcc,0xa5,0x47,0x9f,0x3e,0xb9,0xed,0x26,0x20,0xf7,0x7b,0xfb,0x8a,0x48,0x58,0x51,0x24,0xf9,0xeb,0x66,0x6d,0xd6,0x83,0x24,0xff,0x9f,0x0d,0x38,0x9c,0xf9,0x24,0x99,0x12,0x49,0xb6,0xdd,0xce,0x44,0xe7 +.byte 0x31,0x3d,0x4b,0x23,0x8a,0xd5,0x62,0xa2,0xdb,0x78,0x56,0x3a,0x62,0xc8,0x59,0x5f,0xcc,0x58,0x76,0x19,0x5d,0x48,0x4a,0xc2,0x87,0x21,0xc3,0x3d,0x3a,0x38,0xbd,0x20,0xfd,0xc3,0xa6,0xab,0x32,0xb8,0xc8,0xd1,0x5c,0xa5,0xb4,0x64,0x60,0xd2,0x87,0xb7,0xe9,0xc2,0x2b,0xb2,0x75,0x04,0xf4,0x6e,0x96,0x99,0x5d,0x08,0xff,0xa3,0x45,0x8a +.byte 0xad,0x7c,0xee,0x94,0x4e,0x45,0x86,0xad,0x0a,0x7a,0x5c,0x8f,0xff,0x28,0xb3,0x3c,0xf8,0x5e,0xb3,0x1e,0x5c,0xe0,0x22,0xf7,0x4e,0xe4,0xdf,0x1f,0xd2,0xa2,0x37,0x4a,0x87,0xa6,0x16,0x80,0x0c,0xc3,0x75,0x18,0xe4,0x76,0x8f,0xc3,0x1b,0xee,0xb1,0xe4,0x4b,0xeb,0x6f,0x15,0x48,0x60,0xaf,0x8e,0x0e,0xeb,0xbe,0x26,0xa3,0xbd,0x2a,0xb5 +.byte 0x6d,0x8b,0xd1,0xa1,0x0f,0x8e,0xaa,0xaa,0xb8,0x8d,0x84,0xe7,0x65,0x40,0x60,0x3d,0x59,0xb7,0x1c,0xef,0x08,0x0e,0x6f,0x21,0xb4,0xe6,0x10,0xda,0x59,0x9a,0x0f,0xe6,0xba,0xfd,0xed,0x7f,0xc1,0xe3,0x7a,0xb7,0x21,0x5d,0xcf,0x1c,0xbd,0xd2,0x59,0xc0,0x31,0xa5,0x8a,0x39,0x86,0x9e,0x7e,0x6a,0xcb,0x87,0x6f,0x01,0xba,0xa4,0x06,0x6b +.byte 0x3b,0x5d,0x68,0x85,0x11,0xd2,0x2a,0x3c,0x8e,0x3a,0x8c,0x8b,0x59,0xa0,0x4a,0xfb,0x76,0x85,0xe6,0x47,0xc3,0xf4,0xc4,0xe6,0xcc,0x7b,0xff,0x71,0x03,0xd1,0xc2,0x01,0xe4,0x5e,0x49,0x31,0xa6,0x0e,0x17,0x9b,0x42,0xdc,0x75,0xd6,0xfe,0x09,0x0b,0x6d,0x21,0x46,0xfe,0x40,0xcd,0x7c,0xdb,0xca,0xc9,0xba,0x64,0x83,0xd3,0xf7,0x0b,0xad +.byte 0xff,0xfd,0xe3,0xd9,0x49,0x7f,0x5d,0x48,0xaa,0xac,0xe5,0x74,0x2a,0x14,0x6f,0x64,0x21,0x81,0x09,0xcd,0x2d,0x19,0xf5,0x56,0x85,0xa8,0xec,0x98,0x65,0x46,0x99,0xec,0xbe,0xe3,0x86,0xd3,0x41,0x8b,0xe4,0x76,0x9b,0x5b,0x98,0x33,0x9e,0xdb,0xc9,0xde,0x89,0xfa,0x60,0x58,0xa8,0x2f,0x7a,0xca,0x30,0x91,0xc8,0x26,0x14,0x9c,0xd6,0x6d +.byte 0xc2,0x3c,0xca,0xe0,0x9a,0x13,0x72,0x63,0x5e,0x20,0xfd,0xa0,0xca,0xb2,0xed,0x37,0xc5,0xd4,0x4e,0xec,0x1f,0x74,0x25,0x37,0xe2,0xbe,0xb1,0x7f,0x52,0x26,0x28,0x4f,0x02,0xe5,0x6a,0x27,0xf3,0xc4,0x9c,0x69,0x09,0xac,0xff,0x77,0x9c,0xa4,0x1d,0xe7,0xa1,0x7c,0x37,0x70,0x3b,0x3c,0xc4,0x16,0x8f,0x5d,0xe5,0x05,0xa9,0x2c,0x91,0x2e +.byte 0x87,0xb0,0xa9,0x2e,0x32,0x73,0x5c,0x15,0x1e,0xbe,0x01,0xc9,0xd8,0x2e,0x26,0xf4,0x05,0x2d,0xe0,0xc0,0x38,0x81,0x61,0xf4,0x37,0x08,0xa0,0xc0,0x28,0x0a,0xb6,0xd4,0xcc,0x2c,0xc6,0xd4,0xda,0x48,0x49,0xcf,0x76,0x91,0x23,0x51,0x91,0xe7,0x50,0x94,0xae,0xb7,0x15,0x26,0xaa,0x82,0xd0,0x97,0xe8,0x5e,0xaa,0xfc,0xaa,0x60,0x62,0x81 +.byte 0x80,0xfd,0xfd,0xaf,0x65,0xcc,0x29,0x27,0x95,0xad,0x56,0xb9,0x85,0x66,0x49,0x62,0xb3,0x1a,0xf4,0x54,0xc7,0x5d,0x7f,0x73,0xe0,0xd2,0xc8,0x18,0x95,0x62,0x2f,0x5c,0x96,0xfb,0x63,0x15,0x46,0x07,0x5f,0x3e,0x52,0x18,0xf8,0x5d,0x45,0x0b,0xb6,0xf7,0xc5,0x3d,0x16,0xaa,0x0b,0x8f,0x9d,0x16,0xc8,0x93,0x13,0xd2,0xba,0x7a,0x52,0x1a +.byte 0x7a,0x73,0xc4,0xca,0xfb,0x04,0xaf,0x6f,0x3e,0xfa,0xff,0x29,0x09,0xe2,0x74,0x35,0xc1,0xfc,0x21,0xcf,0x5f,0xf7,0x82,0x55,0x75,0x27,0xc9,0x91,0xc5,0xbf,0xe6,0x68,0xb6,0x0f,0x10,0x0e,0x91,0x30,0xb7,0x05,0xca,0x59,0x4a,0x7f,0xb0,0xf6,0xaf,0xf1,0x5d,0xc9,0xc5,0x06,0xc5,0xf4,0xe1,0x75,0x16,0x9a,0x2c,0xc0,0x3f,0xc1,0x98,0x91 +.byte 0xb7,0xe6,0xb1,0xf2,0xf9,0xfa,0x6d,0x27,0x98,0x33,0x8b,0x73,0x7a,0x57,0x12,0x6f,0x80,0x11,0x28,0x17,0x7d,0xf1,0x26,0xaa,0x05,0xf1,0x6e,0x86,0x98,0xe7,0xf6,0x9f,0x9c,0x06,0x8f,0xec,0xd7,0x2d,0xb0,0x83,0xdf,0x23,0x80,0x34,0xd3,0xd7,0xf7,0xd5,0x0d,0x52,0x18,0xcd,0xc7,0xe7,0x15,0xc9,0x1b,0xae,0x58,0xcf,0xc5,0xdd,0x25,0x2a +.byte 0xff,0xa5,0xf3,0x6d,0x20,0xfd,0xda,0xfd,0x78,0x30,0x14,0x1f,0xb3,0x47,0xe3,0x2d,0x54,0x87,0xdc,0x30,0xbe,0x41,0xc0,0x48,0x52,0x82,0x49,0x78,0xad,0xfd,0x24,0xad,0xd6,0xc1,0x14,0x1e,0xa0,0xc1,0x3d,0x82,0x59,0x01,0x9b,0xc3,0xf4,0xf7,0x26,0xce,0x92,0x50,0x13,0x47,0xe0,0xf3,0xfa,0xd9,0x61,0x19,0x80,0x12,0xee,0x73,0x45,0x5b +.byte 0x34,0xfc,0xb2,0x84,0xb2,0x3f,0xdc,0x77,0x8e,0x2d,0xb3,0x62,0xb9,0x03,0x2d,0xb6,0x2a,0x17,0xcd,0xfb,0x54,0xc2,0x5e,0xb9,0xcf,0xd6,0x05,0xe2,0xac,0x3f,0xce,0x50,0x0f,0xa1,0x3e,0x67,0x68,0x46,0x0c,0xab,0xa1,0xdc,0x2a,0x26,0x1f,0x22,0x1b,0xa7,0xc9,0x3b,0x6c,0x97,0x5d,0x5c,0x7d,0x1a,0x46,0x4a,0x99,0x92,0x85,0x87,0x35,0x6c +.byte 0x78,0x9d,0xb0,0x39,0xd6,0x3b,0x52,0x60,0xb4,0xba,0xcc,0x2e,0xe9,0xe1,0x91,0x51,0xc1,0x52,0xc7,0x5d,0x84,0x95,0x54,0x25,0xdd,0xcd,0x40,0x35,0xa1,0xc8,0x7e,0xff,0x82,0x55,0x9f,0x64,0xef,0xa7,0xc1,0x79,0x57,0xc7,0x44,0xa8,0x1c,0x06,0xaa,0x2a,0x05,0x65,0x6c,0xdc,0x90,0x7d,0x2e,0x53,0x3c,0x56,0xe1,0x30,0xdf,0xcb,0x75,0x3d +.byte 0x36,0x88,0xfd,0x72,0x2d,0xc7,0x8e,0x2f,0x11,0x5a,0x2e,0xa9,0xd6,0x37,0x4b,0x31,0x4e,0x6e,0xa0,0x4a,0xd9,0xa9,0x48,0x18,0x50,0xb1,0x28,0xf6,0x74,0x03,0x44,0xa7,0x06,0x55,0x86,0x1a,0x1b,0x07,0x79,0xc4,0x25,0xba,0x5d,0xce,0xa2,0x96,0x7d,0x62,0xa7,0x21,0xf0,0xa7,0xc2,0x91,0x03,0x38,0x37,0x0b,0x20,0x40,0x88,0x7b,0x28,0xf4 +.byte 0xf3,0xc2,0xb0,0x4b,0xf6,0xef,0x2f,0xd9,0xb5,0x81,0x17,0x95,0x42,0x98,0x7f,0x18,0xd4,0x7e,0xa1,0x85,0xbf,0x62,0xdc,0x40,0xe4,0xd3,0xcc,0x78,0x01,0xec,0x12,0xcc,0x04,0x5b,0xfe,0xdb,0x39,0x7c,0x1e,0x56,0x7c,0x72,0x57,0xb9,0xdf,0x9d,0x43,0xd4,0xe3,0x1f,0xbf,0x69,0xfb,0x43,0x23,0xd8,0x75,0x81,0xe8,0x39,0x0f,0xe4,0xe9,0x51 +.byte 0xea,0xb7,0xa7,0xc6,0x17,0xc6,0x75,0x4c,0xa8,0x17,0x41,0x1c,0x55,0x8e,0x8d,0xf3,0x64,0xbc,0xc3,0x33,0xa7,0xc1,0xbe,0xa2,0x89,0x75,0xd6,0xda,0xad,0x44,0xd5,0xdd,0x18,0xe2,0xfc,0x1d,0xa1,0xbc,0x1a,0xb8,0x40,0x1a,0x4f,0x44,0x4b,0x56,0xe9,0xf4,0xa8,0x16,0xe6,0xc9,0x40,0x90,0x9b,0x49,0xae,0x62,0x12,0x3d,0x50,0x2e,0x7b,0x60 +.byte 0x6f,0x04,0x01,0x2c,0x83,0x2a,0xd2,0x92,0x63,0xa2,0xe2,0x39,0x9a,0xc4,0x1e,0x5a,0x53,0x3f,0x4d,0x69,0xfa,0x0a,0x22,0x13,0x80,0xa4,0x6e,0xfb,0x09,0xcb,0x35,0xd7,0x12,0xa4,0xcd,0xfc,0x0b,0x06,0xa6,0x5e,0xc6,0x4a,0x22,0x56,0x5d,0x7f,0x70,0xd0,0xf8,0xe6,0x96,0x77,0xce,0xd9,0x69,0x6c,0x06,0xac,0xaa,0x94,0x6d,0x57,0x1b,0x28 +.byte 0xb4,0x07,0x50,0x19,0xd1,0x86,0xba,0xe6,0xe6,0x31,0x74,0x1d,0x3d,0xe8,0xe2,0x7b,0xfe,0xc9,0x41,0x89,0x20,0x5b,0x6a,0xc0,0x18,0x16,0xee,0x35,0xfa,0x56,0x35,0x3e,0x53,0x99,0xfb,0x8d,0xae,0x75,0x4f,0xc5,0x8d,0xff,0x23,0xd5,0x42,0xf4,0x81,0x5c,0x8b,0x71,0x7a,0x22,0xb0,0x6b,0x45,0x86,0xa6,0xc6,0xdb,0xa6,0x83,0x01,0x28,0xde +.byte 0x38,0xaa,0x6e,0xf8,0x5a,0xf2,0xcc,0x3c,0xc5,0x65,0x78,0x37,0xe8,0x8a,0x59,0xf3,0xfe,0x8b,0xcd,0xf6,0x31,0x46,0xdc,0x72,0x19,0xf7,0x73,0xac,0x5c,0xf1,0xe3,0xfd,0x85,0x51,0xec,0x92,0x3a,0xf3,0xd7,0xb2,0x95,0x53,0x79,0x48,0xd3,0x29,0x84,0xec,0xc5,0x0a,0x71,0x15,0x52,0x69,0x6a,0xe1,0xab,0x69,0x94,0xc2,0x51,0xdf,0x27,0xd8 +.byte 0xb1,0x05,0xc4,0x12,0xea,0x1e,0xda,0x6e,0xf2,0xf5,0x8a,0xa8,0x72,0x74,0x5a,0xe5,0x45,0x5b,0x5f,0xf9,0xb0,0x56,0x5c,0x85,0xf7,0x63,0x8d,0x1d,0xbf,0xe9,0x7c,0x97,0xe9,0x37,0xb3,0x5b,0x4b,0x57,0xfc,0xf4,0x58,0x84,0x26,0x55,0x07,0xc7,0x0a,0xfe,0x5a,0x58,0xd0,0xd8,0x19,0xf4,0x02,0xad,0x2c,0x4e,0xbd,0xe1,0x07,0x48,0x3b,0xc4 +.byte 0xd6,0x23,0x3a,0x63,0xc3,0xf5,0x17,0x46,0x03,0xa4,0x9a,0x10,0xf9,0xac,0x70,0x9c,0x13,0x10,0x94,0xda,0x17,0xc5,0xbb,0x87,0x0f,0x9b,0x4f,0x54,0x55,0x6b,0x57,0x2d,0x12,0x0b,0xa7,0x9c,0x77,0x6d,0x67,0xb0,0x03,0xdf,0xc6,0xa2,0x76,0x96,0x0c,0xac,0x30,0xbc,0xa2,0x55,0x23,0x01,0xae,0x51,0x50,0xd4,0xab,0xd0,0xee,0x75,0xf1,0x96 +.byte 0x75,0xf5,0x2e,0xae,0x52,0x31,0x0b,0x0a,0x8a,0xdb,0x4c,0x4d,0x4c,0x80,0xfc,0xd7,0x68,0x05,0x54,0x47,0xa5,0xc4,0xb1,0x63,0x87,0x43,0x1b,0xe1,0x0b,0x4f,0xff,0x0c,0x02,0xf7,0x00,0xd4,0x8d,0x6e,0xa1,0x21,0x91,0x62,0xec,0x55,0xd5,0x72,0x70,0x59,0x7a,0xa4,0x0e,0x78,0x7a,0x87,0x1f,0x71,0x35,0x3b,0xf7,0x1f,0x66,0x8c,0x90,0xf9 +.byte 0x6d,0x1f,0x74,0x47,0x41,0xf5,0x21,0x98,0x0d,0x42,0x61,0x21,0x0b,0x62,0x59,0xc7,0x5e,0x58,0x37,0xfb,0xee,0xbb,0xa0,0x45,0xa8,0x84,0xae,0x41,0x29,0xc9,0x88,0x64,0x69,0x75,0xc1,0x5f,0x63,0x7c,0x00,0x1c,0x35,0x61,0x9e,0xad,0x19,0xd7,0xd8,0xf1,0x64,0x57,0x10,0x87,0x73,0xa8,0x8b,0x39,0x9b,0x1c,0x1a,0xc2,0x1b,0x01,0x1a,0x41 +.byte 0x26,0x58,0x93,0x8f,0xed,0xf9,0xe7,0xfe,0xcc,0x27,0x1b,0x6b,0xb8,0x28,0x5a,0x0b,0x04,0xa0,0x94,0x23,0x4b,0x21,0x5f,0xb3,0xc9,0xb6,0x7b,0x36,0x5a,0x67,0x6b,0xd2,0xc2,0x53,0x97,0x5d,0xa5,0x43,0xd3,0x79,0x83,0xe2,0x3b,0xe0,0xaf,0x5f,0xbd,0xf3,0xb0,0xfc,0x04,0x95,0x06,0x17,0x0c,0xe2,0x68,0xe8,0xf3,0x90,0xc7,0x2b,0x7b,0xcc +.byte 0xaa,0xce,0xf5,0x0b,0x3c,0x3f,0x10,0xa7,0x31,0x9d,0xf0,0x1e,0x3e,0x74,0x57,0xbd,0x87,0xe7,0x37,0xd0,0x37,0x09,0xae,0x03,0x96,0xb1,0xad,0x8f,0x2d,0x72,0xdc,0x0f,0xdf,0xd9,0xfb,0xcc,0xb8,0x48,0x62,0xf7,0xad,0x05,0x4d,0xc6,0xe5,0x92,0xe3,0x95,0xa0,0x74,0x7a,0xa6,0x84,0x13,0x68,0x17,0xaa,0x8f,0x40,0x2a,0x8d,0x2b,0x66,0xdc +.byte 0xf8,0xf6,0x6d,0x7c,0x7e,0x40,0x22,0x05,0x16,0x20,0xbc,0xe5,0xc2,0x87,0xe2,0xd5,0xbd,0x47,0xd5,0x69,0x95,0x12,0x25,0x1c,0xaa,0x9d,0xb5,0x73,0x08,0xaf,0xfb,0x46,0xa5,0x11,0x2c,0x93,0xc6,0xfc,0xc0,0x5e,0x0e,0x99,0x1c,0x80,0x5f,0xe5,0xc8,0x52,0x73,0x35,0x4d,0xbc,0x70,0xeb,0x40,0xc9,0x47,0x8a,0x8f,0x19,0xd9,0xa9,0xec,0x4b +.byte 0x88,0x53,0x56,0x08,0x4a,0xa2,0x32,0x1f,0xe2,0xbb,0x68,0x35,0xfd,0xf2,0x0e,0x0f,0x7f,0xc8,0xf1,0x59,0xac,0x97,0x8f,0x84,0x69,0xb6,0xb9,0x5f,0x84,0xe9,0xf2,0xf9,0x09,0xf6,0xf1,0x31,0xd7,0x1a,0xa8,0x25,0x32,0x5f,0xb1,0xa7,0x84,0x15,0xfa,0x07,0xa8,0x53,0xce,0x2a,0x26,0xe0,0x4d,0x07,0x4f,0x45,0x63,0x76,0xfd,0xe3,0xb4,0x4e +.byte 0x81,0x5e,0xe6,0x01,0x9c,0xf5,0x82,0x2d,0x71,0x0f,0x98,0xb4,0x72,0x06,0xbc,0x89,0x89,0x60,0x5f,0xd9,0x92,0xcf,0xb9,0x41,0xe3,0x13,0xaa,0xe4,0x80,0xb5,0x75,0xf4,0x9a,0x1b,0xc2,0xa3,0xa4,0xa9,0x0f,0x15,0xdc,0x26,0xdd,0x20,0x10,0x27,0xbd,0x06,0x77,0x12,0xa5,0xb3,0xde,0x9f,0xbf,0xc4,0xb6,0x1d,0x76,0xdc,0x16,0x00,0x2e,0xe2 +.byte 0x00,0x4d,0xb3,0x62,0x57,0x73,0x1e,0x90,0xe2,0xaa,0x4c,0x47,0xdf,0x6b,0x2d,0x66,0x2f,0x82,0x55,0x91,0x26,0x33,0xb9,0x3a,0xc7,0xf1,0x0a,0xda,0x9b,0x6b,0x05,0x82,0x0f,0x0e,0x30,0x74,0x0b,0xea,0x0f,0x49,0x55,0x3b,0xe7,0x42,0x48,0xca,0x82,0x3e,0x8c,0xbc,0xe2,0x88,0x43,0x44,0x0d,0x37,0x9b,0xd1,0xfc,0xf1,0x45,0x46,0x0e,0xe1 +.byte 0xec,0x91,0x39,0x96,0x7d,0xbc,0xd5,0xb1,0x11,0x55,0x54,0x49,0x4f,0x18,0xed,0xec,0x58,0xdb,0xb3,0x7d,0x64,0x8d,0xfc,0x65,0x1f,0xf0,0xe0,0xc0,0x41,0xc0,0x19,0xeb,0x16,0x16,0x71,0x36,0x88,0xcf,0x75,0x3d,0x9c,0xe6,0xa0,0x84,0x54,0x26,0x64,0x95,0x9a,0xe1,0x0b,0x51,0xcf,0x9a,0x55,0x60,0x4d,0x9d,0x1d,0x37,0x71,0xa8,0x94,0x0a +.byte 0x20,0xeb,0xf2,0x91,0x14,0xfc,0x12,0xb0,0x1e,0xe3,0x5e,0x3a,0xbb,0x22,0xde,0x20,0xb1,0x58,0xef,0x0b,0xb1,0xc2,0x2f,0xea,0xd8,0xdb,0x1d,0x3a,0x67,0x7b,0xbd,0x26,0xfa,0x4a,0x3c,0x3d,0xbd,0x87,0x4c,0xba,0x57,0xdf,0xfb,0x1d,0xf7,0x26,0x5f,0x52,0x4e,0xdd,0x9b,0x38,0x62,0xed,0x48,0xc1,0xae,0x7f,0xa8,0x13,0x05,0x09,0xff,0xc0 +.byte 0xd3,0x49,0x75,0x1f,0x6a,0xe0,0x79,0x94,0xc1,0xe9,0xe3,0xf5,0x33,0x40,0xd4,0x6b,0xfe,0x4d,0x6e,0x84,0xb9,0x20,0x68,0x2b,0x6c,0xb3,0xf1,0xb1,0x1c,0xfd,0x93,0x14,0x7f,0x35,0x9b,0xd5,0x07,0x15,0x87,0x56,0xb9,0x45,0x22,0x64,0x73,0xdb,0x34,0x35,0xca,0x15,0x4e,0xa2,0xa2,0xe2,0x7a,0x6e,0x14,0x46,0xf5,0xf1,0x70,0xd3,0x3a,0x2e +.byte 0x38,0x9d,0xf6,0xc6,0x29,0xd5,0x7f,0xc7,0x77,0x2c,0x33,0x55,0x1c,0xc2,0xf1,0xaf,0x8e,0x4d,0x1b,0x22,0x36,0x35,0x93,0x47,0xa5,0x59,0xb4,0x94,0x0f,0x2d,0x66,0x24,0x6f,0x57,0xa4,0x95,0xf3,0xd7,0xf3,0x59,0x9d,0xc0,0xda,0xa7,0xf7,0xf2,0x8d,0x93,0xc9,0x90,0x91,0x9e,0x12,0x3f,0x34,0x01,0x90,0x8b,0x13,0x09,0x3d,0x2f,0xa8,0x31 +.byte 0xfa,0x39,0x4a,0x7d,0x0d,0x34,0xa3,0xf1,0x75,0xdb,0xa2,0xd2,0x5c,0xf1,0x72,0xfd,0x7f,0x7b,0x15,0x92,0xf0,0x71,0xd6,0xa0,0x74,0x53,0x61,0x67,0xa4,0x8b,0x72,0x3a,0x66,0x0a,0xce,0xc9,0x1c,0x5b,0x4d,0xaa,0x0a,0x3a,0x91,0x0a,0xbb,0xef,0x6e,0x8d,0x00,0xc0,0xa1,0x89,0xa9,0xbd,0x5a,0x2d,0xf8,0x7c,0x1f,0xb2,0x5a,0x73,0x33,0xe7 +.byte 0xb3,0xfd,0xd4,0xe3,0x81,0x69,0x30,0xc1,0xf8,0x97,0x7b,0xf3,0x63,0xaa,0xd5,0x5a,0x98,0x95,0xb3,0x65,0x2d,0xf9,0x68,0x2e,0x2c,0x26,0xe6,0x77,0x8f,0x76,0x7a,0x02,0xc7,0x50,0x28,0x40,0xcf,0x44,0x66,0x18,0x54,0x52,0xef,0x79,0x26,0xc2,0x76,0x5b,0x71,0x92,0x49,0xba,0xe1,0xd7,0xf2,0xdd,0x57,0xe0,0x78,0x6e,0xb6,0xdd,0x0d,0x20 +.byte 0x85,0xf9,0x34,0x9e,0x65,0x6b,0x9f,0x41,0x24,0xe2,0xb1,0x2a,0xef,0x8b,0xd2,0x19,0x81,0x73,0x56,0x5a,0x84,0xd3,0x46,0xf8,0x74,0xe3,0x1f,0x3d,0xd9,0x16,0x86,0x38,0xf6,0x7c,0x04,0xab,0x9a,0x64,0x0e,0x48,0x06,0x4c,0x61,0xcd,0x2d,0x4d,0xef,0x6f,0xd6,0x7d,0x31,0x1c,0x56,0x65,0xc4,0xf1,0xa7,0x15,0xac,0xa4,0xe2,0x8b,0x83,0x5e +.byte 0x64,0x36,0x2e,0x77,0x94,0x2e,0x2e,0xa3,0x62,0xcf,0x6e,0x7a,0x6d,0x39,0xaf,0xf7,0x96,0x88,0x31,0x14,0x58,0x46,0x30,0x0c,0x36,0x3a,0x4c,0x53,0xe0,0xa7,0x24,0x76,0x84,0x0f,0xfb,0x7e,0x55,0xa0,0x0f,0x63,0xfc,0xd6,0x1f,0x58,0x68,0xb5,0xcc,0x77,0x4f,0x16,0x91,0xa7,0xfd,0x62,0xb3,0x88,0x13,0x7c,0xcb,0x63,0x6d,0xe4,0x38,0x4c +.byte 0x6e,0x3b,0xf7,0xe3,0x8d,0x52,0x84,0x61,0x19,0x12,0x51,0xbe,0xed,0x32,0x3d,0x77,0xdd,0xa1,0xc3,0x59,0x65,0x79,0xa1,0x6b,0xbc,0x65,0x6c,0xe3,0x7e,0x60,0x49,0xbd,0xcf,0x6f,0x61,0x97,0x98,0xbe,0x74,0x38,0xd1,0x09,0xc1,0x59,0xe5,0x7f,0xfe,0xbf,0xfd,0x60,0x1b,0x96,0x00,0x46,0x56,0x4d,0x81,0x4c,0x70,0x59,0x39,0x66,0x13,0x58 +.byte 0xe7,0x62,0x3a,0xfc,0x1b,0xe5,0xf9,0x03,0xd4,0x4b,0xab,0x1d,0x56,0x22,0x4a,0x09,0xa5,0xdd,0xac,0x39,0xbe,0x27,0x39,0xb3,0xe8,0xad,0xe0,0x07,0x86,0x10,0xce,0xa9,0x4e,0x8b,0x47,0x8d,0xb8,0x63,0x2f,0x61,0x1a,0x8b,0xd4,0xd3,0xfe,0x73,0x82,0x5a,0xd6,0xa9,0x46,0x56,0xa7,0x81,0xe9,0xda,0xb9,0x17,0xa7,0xc8,0x0f,0x24,0x16,0x6a +.byte 0x12,0xfe,0xc3,0x65,0x85,0x77,0xab,0x89,0x44,0x1b,0xa3,0x8b,0xfd,0x07,0xf4,0x77,0xaa,0xe1,0x71,0x33,0x74,0x93,0xdc,0x90,0x53,0x39,0x47,0x8c,0xea,0x18,0xe1,0x6a,0xed,0x8c,0x56,0x08,0x2f,0xa1,0x1f,0x22,0xf2,0xc0,0x12,0xcd,0xb7,0xdf,0xb6,0x3c,0xd6,0x22,0x6c,0x5b,0x00,0x0f,0xdb,0x66,0x5b,0x54,0x35,0x48,0x37,0x8c,0x79,0x74 +.byte 0xd1,0xb0,0x15,0x01,0x22,0x3a,0x7c,0x17,0x8c,0x20,0x06,0x9b,0x13,0x6e,0xee,0xbf,0xb4,0xac,0x01,0x61,0xb9,0x28,0x65,0x8e,0x53,0x12,0x4f,0xe0,0x5f,0xfc,0xdb,0x40,0x6c,0xa2,0x19,0x64,0x49,0x7a,0xc7,0xc5,0xc8,0x53,0x6e,0xd5,0x68,0xe1,0x61,0xe5,0x87,0xc2,0x99,0x59,0x4c,0x27,0xc8,0xd0,0xd0,0x10,0xce,0x9f,0x09,0xff,0xf5,0xa8 +.byte 0xf8,0x79,0xf6,0x0f,0x73,0xda,0x8a,0x36,0x8e,0x48,0x7e,0xbd,0x98,0x76,0x57,0xfa,0x5c,0xec,0xa5,0x3d,0x30,0xfe,0xa3,0xe5,0x27,0x87,0xcf,0x26,0xfe,0x61,0xe4,0xed,0xd1,0xfb,0xfc,0x91,0x5d,0xb6,0x70,0x2c,0x2c,0x59,0x14,0xd5,0x1d,0x9a,0xb9,0x2c,0xef,0x24,0x7b,0x10,0x8d,0x99,0x63,0xaa,0x82,0xf0,0x1c,0xe8,0xa0,0x00,0xa5,0xa7 +.byte 0xf8,0xc0,0x35,0x9e,0x12,0x18,0xaf,0x42,0x9d,0xe5,0x2b,0x72,0x6c,0x31,0xd8,0x8f,0x6c,0xde,0x2e,0x37,0xa6,0x73,0x06,0xe7,0x90,0x43,0x79,0x99,0x64,0xd1,0x17,0xa1,0x43,0x6d,0xd4,0x90,0x50,0xf2,0xcc,0x0b,0x73,0x49,0x9e,0x14,0x7c,0x49,0x92,0x05,0x0e,0x8c,0xda,0xb7,0x18,0xf0,0xcc,0xea,0xe4,0x32,0x58,0xc7,0xbd,0x8e,0xca,0x35 +.byte 0x52,0x9f,0xec,0x5d,0xa0,0x6c,0x83,0x61,0x07,0x74,0x37,0x4a,0x10,0xa0,0x98,0x83,0x3a,0x65,0x17,0x63,0xd0,0x22,0x96,0xb5,0xed,0xbb,0xbb,0x1c,0x18,0x8a,0x49,0x3d,0x0f,0xcc,0x24,0xb3,0x9b,0xb6,0x23,0x2e,0x9d,0x97,0xe7,0x31,0xf8,0x36,0x6d,0x7b,0xa1,0xf1,0x02,0xde,0x7c,0xad,0x77,0x5d,0x85,0x7c,0x39,0x61,0xc7,0xd7,0x3f,0x70 +.byte 0x1c,0xe1,0x0e,0x49,0xf4,0xcd,0xab,0xfd,0x4d,0x2f,0xc7,0xb7,0x53,0xfc,0xed,0xeb,0x41,0x2a,0x80,0x40,0xf3,0x47,0xf8,0x15,0xa0,0x4c,0x8b,0x34,0xf6,0x6a,0xb8,0x30,0x09,0x4d,0xe6,0x60,0xb7,0x24,0x6b,0x4c,0x26,0xdf,0x83,0x37,0xc7,0x96,0xba,0x35,0xda,0x29,0x4e,0xca,0x52,0xf7,0x41,0xd3,0x98,0x27,0xb2,0x9e,0xec,0xcc,0x12,0xdc +.byte 0x77,0xfd,0x11,0xbd,0xbd,0xbb,0x5e,0x0c,0x37,0x29,0xd2,0x4f,0x7d,0x5c,0x97,0xad,0x72,0x93,0x4a,0xfa,0x17,0x07,0x07,0x26,0xee,0xa7,0x29,0x2e,0xdb,0xf6,0x60,0x65,0x2d,0x85,0xbe,0x27,0x4d,0xf7,0x2b,0xb4,0x81,0xf5,0x3a,0x1d,0xae,0x25,0x8b,0x60,0xc2,0x75,0x3a,0xfd,0xf9,0x4d,0x90,0x7a,0x8a,0x3a,0xf6,0xa9,0xf0,0x11,0xd2,0xb9 +.byte 0xdb,0x23,0x40,0x9d,0x33,0xc3,0xbf,0x60,0x95,0x9c,0x6f,0xa9,0x82,0x42,0xe5,0x67,0x52,0x36,0xea,0x68,0x64,0x24,0x85,0x46,0x7e,0x2a,0x1a,0x6a,0x4b,0xa8,0xb0,0xa0,0x9c,0xb8,0x4a,0xb6,0x2e,0xb2,0x6b,0xf4,0x63,0x9f,0x54,0xb5,0x6f,0x1b,0xf5,0x71,0x7e,0xf8,0xef,0xb2,0x92,0xe2,0xcf,0x65,0xb4,0x02,0x9b,0x75,0x4b,0xf9,0x6b,0xa1 +.byte 0x24,0x3b,0xea,0x7f,0x31,0x08,0xd4,0xdc,0xab,0x12,0xc0,0xca,0x64,0xee,0xfa,0x61,0x1c,0x0f,0x24,0xc3,0x8c,0xbd,0xc8,0xd2,0x42,0xf7,0x1f,0x2e,0xd3,0xd1,0x51,0x86,0xfb,0xa2,0x95,0xc5,0x8c,0x5b,0x61,0x14,0xc9,0xe4,0x07,0xa1,0xf7,0x39,0x11,0x40,0x68,0xd6,0xe2,0x38,0x96,0x6f,0x99,0xf1,0xd2,0xfb,0x8e,0xb8,0x3d,0xf2,0x8a,0x4e +.byte 0x3e,0x54,0xd9,0x0e,0xd1,0xc9,0x31,0x04,0xa4,0xee,0xbe,0x51,0xcf,0x5f,0xd1,0xc8,0x13,0x96,0x9d,0x9b,0xdf,0x32,0xa9,0x38,0x8f,0xbc,0x7e,0x22,0x1a,0x52,0x5f,0x14,0x61,0xeb,0x78,0xf4,0x01,0xe9,0x5c,0x18,0x1c,0xb5,0xe1,0x80,0x06,0x3e,0x8e,0x72,0x33,0xf9,0xaa,0x49,0xec,0x5b,0x7a,0x04,0xf2,0x9b,0x48,0x8a,0x58,0x14,0x4b,0x7e +.byte 0x4d,0x26,0x0b,0xe0,0xf0,0x69,0xa3,0x36,0x75,0x3e,0x73,0xec,0x53,0x20,0x35,0x8e,0xfa,0x40,0xf0,0xcd,0x70,0xe1,0xe4,0x64,0x89,0x14,0x55,0xd7,0x20,0xe8,0xbd,0xc2,0x85,0xa8,0x4d,0x51,0x96,0x27,0x54,0x50,0xc7,0xa1,0x9c,0x35,0x52,0x1f,0x8b,0x6f,0xa2,0x62,0x36,0x94,0x02,0xb1,0x01,0xc6,0x4e,0x53,0x83,0x65,0x98,0x25,0x6d,0x26 +.byte 0x6d,0xef,0x4e,0x7a,0xe0,0x56,0x6a,0x6c,0x23,0xe8,0xa6,0x97,0xc1,0xf2,0xb1,0x2d,0x03,0x29,0xef,0xa0,0x6d,0x86,0x8d,0x5a,0x00,0x83,0x14,0xed,0xd4,0x1e,0x79,0xc4,0xb4,0x42,0xfd,0x53,0xaa,0xab,0xd7,0xa3,0xf9,0x7d,0x15,0x26,0xab,0x81,0xc4,0x7a,0x96,0x14,0x94,0x71,0xe1,0x7f,0xc1,0x67,0x5f,0x5f,0x11,0xb4,0x72,0x03,0xf8,0x9b +.byte 0x2f,0x82,0xa3,0x4e,0xda,0xfd,0x2a,0x31,0xf1,0x74,0x6d,0x96,0x7a,0x9c,0xf9,0x01,0xd9,0x55,0x8e,0x52,0xe4,0xae,0x22,0x14,0x7b,0xc0,0x5a,0xc4,0x31,0x23,0x9a,0x2e,0x9d,0x86,0x86,0xd5,0x66,0xc8,0x8b,0xdb,0x49,0x5f,0xca,0x57,0x51,0x50,0x75,0x3f,0xeb,0xb1,0xe5,0x84,0x42,0x8f,0x0f,0xca,0x86,0xcf,0xb0,0x17,0x06,0x06,0x46,0x8c +.byte 0x4a,0x84,0xde,0x28,0x84,0x24,0x7f,0x33,0x48,0xe8,0x89,0x87,0x1f,0x02,0x07,0x4f,0x36,0xa9,0xdc,0x8a,0x42,0xb6,0xc7,0x9c,0x47,0xd4,0xd4,0x2d,0xc0,0x17,0xb0,0xe6,0x23,0xb7,0xae,0x0d,0x9f,0x38,0x0a,0xdf,0x7f,0x73,0xbf,0x93,0x19,0x05,0x23,0xbf,0xc0,0x53,0x2d,0xcd,0x3e,0x73,0x01,0x78,0xa7,0xdc,0x6c,0x85,0x1d,0x25,0xc5,0x54 +.byte 0x68,0x95,0xc1,0x20,0x65,0xd9,0x01,0x85,0x7d,0xc9,0xba,0x63,0x43,0x7a,0x23,0xbb,0x95,0x3a,0x76,0x2d,0x75,0x1e,0xac,0x66,0x3e,0x20,0x30,0x8d,0x37,0x64,0x3c,0xc7,0x6f,0x36,0xb8,0x34,0x60,0xd2,0xb4,0x54,0x07,0x52,0x6c,0xfa,0x04,0xfe,0x2b,0x71,0x03,0x03,0x97,0xfc,0x4a,0xf9,0x4d,0x44,0x1a,0xf9,0xd7,0x4b,0xe5,0xe1,0xf9,0xb9 +.byte 0x41,0xa0,0x5b,0xa2,0x69,0x48,0xba,0xeb,0xcc,0x4e,0x55,0x4b,0xbd,0x41,0x09,0xa8,0x90,0x5c,0xc6,0xe3,0x20,0x0c,0x8f,0xfc,0x7e,0x0e,0x4f,0x3d,0x47,0x65,0x40,0x1e,0x79,0x9a,0xe0,0x8f,0x8f,0xe9,0xcb,0xaa,0x04,0xb8,0xd9,0x91,0x30,0x2a,0x4c,0x17,0x44,0xc0,0x03,0x4c,0x37,0xd3,0xdb,0x20,0xe5,0x8e,0x70,0x87,0x57,0x4f,0x8a,0xcf +.byte 0xee,0x64,0xbc,0xef,0x0f,0x9e,0xcf,0x95,0x5e,0x11,0x4f,0x7a,0x35,0x53,0x8c,0x85,0x6a,0xff,0x72,0x1b,0x35,0x51,0x89,0xf8,0x94,0x65,0x97,0xec,0xfe,0xbd,0x00,0x29,0x3d,0xe8,0x96,0x23,0xa4,0xe3,0xcf,0x81,0xb2,0x8f,0x73,0x4c,0x05,0xc3,0xcc,0x37,0x22,0x97,0xa0,0xda,0x49,0xb2,0xbd,0x07,0x2b,0x26,0xa0,0x6f,0x6b,0x1f,0xa6,0x15 +.byte 0xe3,0x6e,0x12,0xa4,0x51,0x1b,0x72,0x22,0x08,0xfe,0xf7,0x93,0x1a,0x9f,0x62,0x12,0xd4,0x11,0x1f,0xd1,0x80,0xeb,0xa4,0xb1,0xf4,0x37,0x3b,0x60,0xd8,0x2b,0x53,0xae,0x69,0xf8,0x48,0x38,0xf4,0x20,0x28,0xe1,0xfb,0x6a,0xec,0x6e,0x11,0x2e,0x2c,0x59,0x62,0x23,0x8a,0x82,0xc4,0x33,0x7b,0xdc,0x33,0x99,0x41,0x29,0x4f,0xa1,0x6e,0x3a +.byte 0x48,0x13,0x1c,0x1f,0xa3,0x1f,0xd2,0x02,0x79,0xe1,0xe4,0xb9,0x99,0xa4,0x50,0xea,0x53,0x96,0x4e,0x82,0x7c,0xee,0x65,0x07,0x26,0x87,0xf9,0x9d,0x45,0x17,0x37,0x61,0x7e,0x5f,0xb9,0xd2,0x55,0x3c,0x45,0xf7,0xec,0x33,0x08,0xa3,0x41,0x24,0x8f,0xb2,0x75,0x41,0xb6,0xa2,0x21,0xfe,0x94,0x7e,0x1e,0xe6,0x03,0x6e,0xf4,0xeb,0x23,0x59 +.byte 0x51,0x25,0x99,0x19,0x6d,0xf7,0xe3,0x22,0xd8,0x41,0x0f,0xd5,0xaf,0x0d,0xc6,0x3f,0x8e,0x36,0xee,0x90,0x23,0x67,0x03,0xcb,0xe3,0xaf,0xc4,0xf8,0x22,0x1f,0xd8,0x3e,0x94,0xdf,0x13,0xc9,0x4f,0x17,0x22,0x8c,0x93,0x6b,0x3f,0x60,0x1a,0xbd,0xfa,0x9f,0xe6,0x43,0x45,0xe1,0x0a,0x95,0x21,0x06,0x52,0xbd,0x58,0x56,0x84,0x56,0x36,0xf3 +.byte 0x55,0x58,0x46,0x62,0x6c,0xb3,0xa0,0x29,0x5a,0xfc,0xb4,0x87,0x5f,0x89,0xa5,0xab,0x6d,0x5a,0x44,0xc5,0xc8,0x50,0x83,0xe1,0x41,0xd4,0x97,0x6c,0x08,0xb1,0x43,0x33,0x0d,0x3a,0x8b,0x31,0xa1,0xae,0x77,0x71,0xb7,0x67,0x65,0xd7,0xa7,0xc9,0x6c,0x4a,0x9b,0x80,0xd5,0xbf,0xae,0x0f,0x9b,0xce,0x1a,0xa3,0x26,0xc6,0x19,0xa1,0x8d,0x12 +.byte 0xd9,0x09,0xae,0xac,0x9f,0x4b,0xab,0xaf,0xf6,0xc5,0x9e,0x26,0xe6,0x23,0xcb,0x3e,0x60,0x1e,0x3d,0xa1,0xec,0x59,0xca,0xf1,0x87,0x0e,0xaf,0x47,0x5f,0xab,0x17,0x99,0xbd,0x87,0x1c,0x1d,0x00,0xd6,0xb2,0x59,0x56,0xdd,0x49,0x20,0xb5,0x91,0xf8,0x0c,0xf1,0x80,0xc6,0x37,0x92,0xd7,0x2c,0x02,0x0d,0x47,0x1b,0x1b,0x6b,0x3f,0x60,0xd0 +.byte 0x21,0x9b,0x49,0x47,0x3c,0xaa,0x83,0x44,0x1b,0x92,0x8e,0xec,0x63,0x40,0xd6,0x9a,0x48,0x7c,0x5e,0x97,0xe4,0xf0,0x84,0x36,0x30,0x11,0x0b,0x7c,0x79,0x3b,0xff,0xdf,0x77,0xf6,0xc9,0xdb,0x49,0xdd,0x2a,0xe7,0xca,0x9a,0x5b,0xef,0xd4,0x84,0xe2,0x44,0x8b,0xef,0x4e,0x0d,0x13,0xd6,0xbb,0xba,0x29,0x02,0xae,0xfc,0x55,0x24,0xfa,0x4b +.byte 0x7d,0x71,0xc9,0xde,0x71,0x36,0xbc,0xac,0x31,0x5c,0xf8,0x20,0xdd,0xb8,0xae,0x03,0xd3,0xb0,0xdc,0x27,0x7f,0xc5,0xff,0xda,0x8a,0x36,0x2d,0x8f,0xae,0xbd,0xf8,0x92,0x28,0x8e,0x0c,0xc3,0xaf,0x4e,0x33,0xf0,0x71,0xdb,0xad,0x4d,0xc1,0xef,0x52,0x1c,0x84,0xdc,0x0d,0xf3,0xab,0xb9,0x0b,0xe0,0x18,0xa5,0x06,0xdc,0x78,0x41,0x73,0x35 +.byte 0x95,0x37,0x84,0xba,0xc1,0x4e,0x0a,0xe4,0x4d,0x05,0xfe,0x9d,0x74,0x68,0x4a,0x35,0xf0,0x15,0xaa,0x7b,0xfe,0x08,0x47,0xb2,0x84,0x65,0x1d,0x0d,0x9f,0xe7,0xe0,0x04,0xf9,0x1c,0xac,0x66,0xb3,0x75,0x96,0x8f,0x25,0xb6,0x29,0x53,0x52,0x50,0x7a,0x50,0xd1,0x89,0xc7,0x05,0xfb,0x3a,0xb0,0xfa,0x6b,0x96,0x9d,0xfc,0xb0,0xcd,0x68,0x21 +.byte 0x61,0xf6,0x65,0x64,0xa7,0xc6,0x56,0xbd,0xf0,0x9b,0x4a,0x9a,0xe2,0x8c,0xd8,0x88,0x70,0x82,0x0c,0x87,0x51,0x77,0x23,0xd8,0xd8,0xf8,0x4a,0xfe,0xf4,0x6d,0x3f,0x2a,0x36,0x0c,0x67,0x85,0x43,0x13,0x83,0xd5,0xe9,0x32,0xff,0x8c,0xec,0xd4,0x7f,0xd2,0x32,0x4d,0x4e,0xec,0x76,0x55,0xf9,0x0d,0xb7,0x57,0x6c,0xc4,0xd6,0x22,0xd3,0x6e +.byte 0x71,0x23,0x68,0x45,0x03,0x37,0x27,0x3d,0x56,0x89,0xbb,0x7c,0xf1,0xa8,0x09,0xd6,0xb2,0xc5,0xe6,0xf6,0x72,0x77,0x3e,0xb0,0x8a,0x3d,0x17,0xbd,0xd5,0x0d,0xdb,0x62,0xa7,0x07,0x66,0x35,0x19,0x12,0xff,0xcf,0xdd,0xb3,0x09,0xa3,0x58,0x5b,0x0d,0x87,0x76,0x33,0x28,0x98,0x91,0x48,0xac,0xa1,0x22,0x9f,0xda,0x36,0x03,0x8a,0xc1,0x5e +.byte 0x6c,0x2e,0x42,0x8e,0x1a,0x7d,0x75,0x69,0xb2,0xcf,0xb0,0x14,0x80,0xa8,0x91,0xc2,0xbc,0x24,0x8f,0x25,0x9a,0x9e,0xa3,0x4d,0x46,0x55,0x53,0x05,0x0c,0xf8,0xdb,0xe0,0xee,0xe4,0x32,0xff,0x39,0x74,0x9a,0xa8,0xf7,0xa4,0x6e,0x5b,0x9a,0x89,0x33,0x40,0xf4,0xce,0x54,0x4a,0x18,0xdb,0x11,0xe4,0x83,0x69,0x52,0xef,0x12,0xc6,0x13,0x6e +.byte 0x2a,0x14,0xb9,0x8e,0x38,0x8d,0x6b,0xef,0x02,0xc8,0x66,0xf0,0x78,0xaa,0xa6,0x04,0xa3,0xa5,0x1d,0xdb,0xac,0x02,0x23,0x4c,0x2a,0xa5,0xbf,0x66,0xa4,0x47,0xa9,0x8e,0x50,0xd2,0xf8,0xf5,0x0d,0x0f,0xc9,0x07,0xd8,0x1a,0x94,0x84,0xcf,0xb3,0x56,0x53,0x5f,0x83,0x1d,0x30,0xb6,0x94,0x36,0xf4,0x16,0x72,0x8c,0x6d,0x49,0xe4,0x6d,0x93 +.byte 0xb1,0xa1,0x97,0x70,0x75,0x47,0x3a,0x7e,0xa6,0x39,0x1d,0xf5,0xcc,0x37,0xaa,0x90,0x53,0xe1,0x9b,0xcb,0x9a,0x97,0x7d,0x18,0x4a,0x3c,0x1f,0x05,0xf4,0xe3,0x6f,0x7a,0x19,0x84,0xbc,0x68,0xa4,0x6e,0x5a,0xb5,0x7a,0x51,0xda,0xf5,0x75,0x1e,0xfe,0xb0,0x73,0x43,0x39,0x98,0xb7,0x1e,0x17,0x36,0x35,0x15,0x64,0x90,0xb6,0x83,0x43,0x8f +.byte 0xcd,0xb6,0x8c,0xc4,0xe4,0xee,0x0e,0x1c,0xbd,0x3a,0xe6,0x6e,0x44,0x73,0x88,0x30,0xa0,0xf0,0x97,0xf5,0x5e,0x12,0xea,0xd9,0xd7,0xb5,0xc5,0x1d,0xc7,0xc8,0x55,0xbb,0x2c,0x64,0x43,0x50,0x15,0x71,0x02,0xd3,0xf9,0xb4,0xe7,0x2f,0x0f,0x98,0x9e,0x87,0x40,0x2a,0x61,0x06,0x44,0xc2,0x47,0xaf,0x44,0x4f,0xdd,0xa3,0xb0,0xb2,0x8d,0x8c +.byte 0x83,0x96,0xd3,0x2a,0x38,0xdf,0x87,0x5d,0x1c,0x64,0xc8,0x4f,0x3c,0x41,0xc7,0xf8,0x64,0x58,0xa6,0x9b,0xcb,0xcd,0x77,0xdb,0x38,0xe7,0x30,0xb6,0x91,0x88,0xd8,0x9d,0x29,0x71,0x12,0x9e,0xdf,0x20,0xd9,0x14,0xa3,0xa0,0xbd,0x0a,0x99,0x67,0x0a,0xe1,0xe9,0xba,0xd0,0x1b,0xba,0xc8,0x8d,0x76,0x10,0xe8,0x30,0xa1,0x93,0xf4,0x95,0x6a +.byte 0x12,0xd5,0x95,0x31,0x7f,0xdb,0x33,0xfc,0xbf,0x7a,0xbe,0xe4,0xfa,0x50,0x1b,0x24,0x75,0x9b,0xf8,0x81,0x34,0xc8,0xfb,0xda,0x3c,0x6f,0x3b,0x9a,0xb2,0x6f,0x94,0x0c,0xd9,0xc3,0x05,0xd6,0x96,0x10,0x27,0xdb,0xd6,0x88,0x72,0xe4,0x8f,0xfc,0xd3,0x52,0xf8,0x63,0xb2,0xce,0xf1,0x2a,0xbc,0x1c,0x23,0x9d,0xfb,0x27,0xdd,0x8d,0xe4,0xcc +.byte 0x63,0xcf,0xad,0xe6,0xe9,0x4f,0xb8,0x8a,0x20,0x47,0x75,0x73,0x3f,0x27,0x07,0x5d,0x8c,0x8c,0x6e,0x7a,0x91,0xe2,0xf6,0xd5,0x70,0xd8,0x00,0xe5,0x0f,0xde,0x78,0xd8,0xb4,0xd3,0x18,0x5a,0x24,0x43,0x91,0x0c,0xbe,0x8b,0x1b,0x88,0x48,0x7e,0x94,0x05,0xd0,0xec,0xd2,0x71,0x26,0xc7,0x70,0xeb,0x8a,0x83,0x01,0x52,0xdb,0xe5,0x76,0x31 +.byte 0x19,0x14,0x13,0x90,0x5b,0x5a,0x94,0x89,0xe2,0x4e,0x2d,0x17,0xf6,0xbc,0x67,0xee,0x51,0xd4,0x00,0x83,0xe5,0x18,0xa5,0x54,0x6c,0xd2,0x7a,0x1f,0xdb,0x6f,0xed,0x7f,0x07,0xbb,0x9f,0x3a,0xc2,0x8c,0x04,0xf9,0x9a,0x55,0xe3,0x70,0xf3,0x36,0xfd,0x44,0x05,0xd9,0xf3,0xe1,0x87,0x2c,0x29,0xec,0x30,0x8b,0xb7,0xde,0x27,0xa4,0xcd,0xdf +.byte 0x64,0x0b,0x62,0xdf,0x34,0xa0,0xf5,0xa1,0x69,0xc9,0x0b,0x00,0x81,0xf4,0x03,0x5e,0xef,0xb8,0x26,0x49,0x71,0x5e,0xcd,0x76,0xa2,0x38,0x25,0x1f,0x92,0xc3,0xbf,0xdb,0xb3,0x29,0x37,0x06,0xc5,0xc2,0x3b,0xd8,0xbd,0x55,0xf2,0x7f,0xd5,0xd5,0x34,0x32,0xf1,0xa0,0x92,0x9b,0x1c,0xee,0x6f,0x48,0x40,0x6b,0xd1,0x45,0x09,0x3f,0xaf,0xdc +.byte 0xe1,0xac,0x75,0x9a,0x33,0xf7,0x50,0x4f,0x2c,0x3c,0x30,0x69,0x69,0x84,0xcb,0xe9,0xca,0xdf,0x8d,0x02,0x5d,0x30,0x71,0x99,0x7b,0xd5,0xb2,0x55,0xdd,0x9c,0x2f,0xae,0x11,0x41,0x01,0x6b,0xf7,0x95,0xe3,0xda,0xe3,0xcc,0xa4,0x17,0xd0,0x50,0xf9,0x4c,0x31,0x2b,0x4e,0xf7,0x49,0xbb,0x75,0x8f,0x28,0x19,0x9f,0x89,0x7b,0x78,0x80,0x41 +.byte 0x50,0x5a,0x5c,0x1e,0x82,0x93,0x9f,0x4f,0x61,0x96,0x29,0x0c,0x25,0xb3,0xe6,0xff,0x86,0x90,0x78,0x09,0x04,0xf9,0x2a,0x3d,0xa1,0xd5,0x68,0xa8,0x0d,0xd9,0x41,0x01,0xdc,0x41,0x01,0xff,0x20,0xc0,0x63,0x0b,0x4d,0xd5,0x80,0x78,0x82,0x05,0x51,0x62,0x09,0xf9,0x11,0xbd,0xde,0xc0,0x7d,0x3f,0xf2,0x30,0xfb,0x41,0x68,0x39,0xb0,0xc2 +.byte 0x2e,0x33,0x4e,0xa7,0x85,0x01,0x6b,0xd1,0xf9,0x78,0xef,0xe9,0x7c,0x0e,0xaf,0x13,0x1a,0xf5,0x97,0xde,0xf0,0xbb,0x67,0xf9,0x9b,0xab,0xee,0x86,0x73,0x9b,0x23,0x6c,0x56,0x0d,0xa0,0xda,0x4c,0xff,0x2b,0xc5,0x92,0xdb,0xee,0xbd,0xba,0x3a,0x54,0x21,0xc0,0x5c,0xfe,0x21,0xf1,0xbd,0xac,0xaf,0xa3,0x7a,0x52,0x62,0x15,0x8b,0x8f,0xb5 +.byte 0x82,0xc6,0x1a,0xfb,0x22,0xbc,0xa2,0x05,0x42,0xfe,0xb4,0x12,0x6b,0xad,0xa9,0x76,0xb7,0x6b,0x1c,0xd8,0x34,0x5c,0x7d,0xd5,0xa9,0x0d,0x91,0xf6,0xc1,0x47,0x69,0xbc,0x43,0x8f,0xb7,0xfc,0x84,0x2e,0xa0,0x8e,0x3f,0x52,0x3b,0xbd,0x1f,0x28,0x6b,0xc8,0x13,0x37,0xd6,0x44,0xe9,0x8d,0x08,0x92,0x96,0xe5,0x2c,0x57,0x34,0x59,0x21,0x04 +.byte 0xa8,0xaa,0x56,0x25,0xa4,0xc8,0xae,0x68,0x17,0x9e,0xa4,0xf4,0x42,0x64,0x57,0x4b,0x54,0x85,0x8a,0xd1,0x09,0x09,0x25,0x18,0x05,0xb0,0x09,0x9d,0xd9,0x75,0x21,0xd3,0x75,0x31,0xf8,0x35,0x46,0xc8,0xd4,0x47,0x9d,0x87,0xeb,0x40,0x95,0x19,0x24,0x7c,0x6e,0xe9,0xd5,0x14,0xaa,0xc3,0xbe,0x22,0x18,0xc1,0xa0,0x5f,0x34,0x98,0xc2,0x4d +.byte 0x3f,0xa6,0x09,0x57,0x1b,0x75,0xc6,0x89,0xee,0xf0,0xbd,0xbc,0x1a,0xd3,0xea,0x6e,0x82,0x06,0x90,0x4f,0xbb,0x61,0xac,0xbb,0x3e,0x8c,0x94,0xea,0x69,0x58,0x26,0x2e,0x17,0x78,0xad,0x14,0xa4,0x79,0x14,0xbd,0xc1,0x78,0xf9,0xbb,0x11,0x7e,0x8d,0xbf,0x3e,0xc8,0xc5,0x69,0xd7,0x5a,0x4c,0x4b,0x86,0x25,0x4c,0xe9,0x3a,0xc2,0xd9,0xf8 +.byte 0xbf,0x5e,0x46,0x4f,0xca,0xba,0x25,0x58,0x73,0x82,0x02,0x8a,0x41,0x9e,0x2d,0xa9,0x08,0xb4,0x60,0x2a,0x11,0x2c,0x2f,0x3d,0x5e,0x68,0xd8,0xa9,0x2e,0x1c,0xfa,0xdc,0xda,0xfb,0xfb,0xf3,0xb2,0x66,0xd3,0x57,0xe6,0x09,0xeb,0xe5,0xf4,0xed,0x2d,0xb7,0x3a,0xce,0x69,0x2d,0xb4,0x79,0x1a,0x99,0x9d,0xc8,0x99,0x9f,0x9b,0x78,0xd4,0x8a +.byte 0x73,0xd5,0x89,0x9f,0xda,0xdf,0xd0,0xca,0x6b,0x63,0x5a,0x1e,0xe0,0x2f,0x01,0xa4,0xd0,0x62,0xc0,0x5f,0x4e,0xd9,0xd3,0x47,0xe4,0x68,0x73,0x8c,0x87,0x50,0x91,0xec,0x8e,0x0b,0xa7,0xf0,0x4c,0x32,0x19,0xaa,0x00,0xbd,0xe4,0x20,0xab,0x5c,0x00,0xdb,0x18,0xc0,0xff,0xc1,0xc0,0x8f,0xa2,0x8c,0x47,0x91,0x86,0xde,0xa9,0x09,0xb5,0x86 +.byte 0xcc,0x1d,0x7f,0x4b,0x7d,0x16,0xf6,0x21,0xd0,0xf8,0xaa,0x16,0x20,0xa9,0xac,0x3e,0xef,0x56,0xee,0x0e,0x1d,0xd6,0x44,0x7d,0xa9,0x84,0x41,0x8d,0x69,0x69,0x92,0x74,0x87,0x3b,0x8a,0xbf,0x40,0x29,0x45,0xf9,0xa8,0x52,0x8c,0x99,0x95,0xe7,0x6a,0xcd,0x3f,0x74,0x2d,0xde,0x82,0x47,0x41,0xa6,0xd9,0x5a,0x30,0x6c,0x20,0x98,0x3f,0xfb +.byte 0x66,0x08,0x73,0x68,0xe1,0xcd,0xfd,0x3c,0x4f,0x33,0x6b,0x42,0xa4,0xab,0x78,0x22,0xb5,0xd9,0x6f,0x99,0xcb,0x85,0x6a,0x14,0xb9,0xd3,0x0f,0xfb,0xd7,0x07,0x7b,0xbe,0x6a,0xd9,0xba,0xde,0x98,0xac,0xd8,0xe5,0x40,0xcd,0x59,0x7f,0x88,0x3c,0x4e,0xfa,0xfe,0xbe,0x48,0x21,0xb5,0x40,0xd5,0xc8,0x1e,0x8a,0x56,0xd9,0xec,0x25,0xad,0x5e +.byte 0x31,0xf3,0xf2,0x3d,0x0b,0x56,0xb5,0x20,0x08,0xd3,0x02,0x81,0x93,0x29,0x3d,0xbd,0x0a,0x9c,0x26,0x74,0xdb,0x6b,0x7e,0xd1,0x4a,0x1a,0x1c,0x47,0x49,0x34,0xba,0x08,0x7a,0x6a,0xb3,0xd6,0x3b,0xd0,0x28,0x50,0xa1,0xd8,0x17,0x85,0x61,0xab,0x24,0x22,0xda,0xc8,0xb4,0x1b,0x07,0x2e,0x67,0x77,0x84,0xdc,0x6f,0xfd,0x51,0xa5,0xe8,0x34 +.byte 0x63,0xbd,0xae,0xae,0xc7,0x84,0x1d,0x60,0xc8,0x8f,0xde,0x22,0xfd,0x85,0xb4,0x12,0xb4,0x04,0x5b,0xe7,0xb5,0x58,0xf8,0x56,0x66,0xa3,0xb7,0x1e,0x54,0xd0,0xdb,0x12,0xaa,0x9c,0x89,0x5b,0xfa,0xf4,0xe7,0xe2,0xf4,0x9c,0x08,0xa8,0xbe,0x6b,0xe3,0xce,0x6a,0x88,0xb5,0x74,0xb9,0x49,0xaa,0x7b,0xcd,0xbc,0x17,0x81,0x61,0xe2,0x28,0x6f +.byte 0x4b,0xe8,0xa4,0x55,0xc5,0x1e,0x69,0x21,0x8f,0xfd,0xa8,0xd0,0xb9,0x6f,0x1b,0xfe,0x8c,0x5e,0xf9,0x7d,0xd9,0xc2,0xbe,0x0f,0x6f,0xbd,0xa7,0x94,0x10,0x4e,0xe0,0x5a,0xbb,0xa3,0x40,0x9a,0x5a,0xad,0x10,0x97,0x92,0x3b,0xbd,0xa7,0x75,0x77,0xc6,0xa6,0xde,0x42,0x00,0x3b,0xf7,0xe4,0xf4,0xd7,0xdd,0xaa,0x31,0x1e,0x64,0xae,0x17,0x0a +.byte 0x25,0xa0,0x94,0x5f,0x3c,0xbc,0x3d,0x00,0x00,0xd3,0xba,0x7b,0x98,0x81,0xe1,0xdf,0xba,0x60,0x08,0x2a,0xe5,0x66,0x08,0x3e,0xfa,0x81,0x0a,0x89,0x4e,0xe5,0x3b,0xc3,0xdf,0x21,0x9b,0x54,0xa3,0xb3,0xc3,0xc1,0xce,0xb4,0xaa,0x06,0xee,0x2e,0x34,0x55,0xcc,0x8b,0x0f,0xcd,0x1d,0x1b,0xd9,0x9e,0x59,0xf0,0x93,0xc9,0xba,0x35,0x5c,0x99 +.byte 0xf6,0x86,0x9e,0xe9,0xf8,0x84,0x80,0x05,0x76,0x6f,0x8b,0x38,0xb6,0xe0,0xdf,0x0c,0xb3,0xc7,0x6e,0x62,0x53,0xe4,0x69,0x0a,0xc1,0xcf,0x5b,0x84,0x75,0x78,0x56,0x35,0xa5,0x26,0xc6,0xae,0x76,0x2e,0xc8,0x29,0x8d,0x16,0xd1,0x4f,0x27,0x36,0x22,0x41,0x31,0xfb,0xbe,0xd0,0xf9,0x0a,0x06,0xbf,0x59,0x6e,0x06,0x20,0x0d,0x52,0x66,0x63 +.byte 0x38,0x2a,0xb6,0x15,0x0f,0x51,0x14,0x0b,0xd1,0x63,0x40,0x2a,0xfe,0x88,0x51,0x53,0x5d,0x82,0x4e,0x1b,0x91,0x30,0x7a,0x09,0xec,0xb6,0x53,0x10,0x87,0xba,0x34,0x1f,0x8a,0xf7,0x85,0x31,0x77,0x76,0xba,0x55,0x07,0x6b,0x80,0x5d,0x14,0x23,0x50,0xef,0x07,0x91,0xc5,0x71,0x3a,0x55,0x44,0x9d,0xbf,0xe6,0xab,0xde,0x7c,0xdd,0xe0,0xcb +.byte 0xcc,0xc1,0x78,0xb4,0x8c,0xd1,0x35,0x73,0x80,0x9c,0x44,0xff,0xf8,0x8a,0xaa,0x9a,0x94,0xcf,0xc9,0x51,0xfc,0xa5,0x3d,0x86,0xd6,0x67,0x71,0x1b,0xdb,0x83,0xb2,0x67,0xb0,0x17,0xce,0x13,0x1b,0x7a,0x84,0xc8,0xaf,0x69,0x7e,0xf0,0xab,0xc5,0x8c,0x37,0x12,0x43,0x33,0x5f,0xaa,0xde,0xcf,0x4c,0x73,0x7f,0x6b,0x80,0x18,0x27,0x72,0x62 +.byte 0xe8,0x3d,0x1c,0x94,0x91,0xfa,0x33,0xef,0x13,0x94,0x7f,0xb6,0x53,0xe3,0xd7,0x73,0x05,0x3e,0xe8,0x45,0xde,0x1e,0x1d,0xa4,0x41,0x11,0x0a,0x7f,0x62,0x6e,0x9f,0x9f,0xec,0xe9,0x87,0xe0,0x5d,0xbb,0xbc,0x0b,0x37,0xa2,0xf3,0x68,0x8a,0x24,0xec,0x98,0xe5,0x5d,0xbf,0xa1,0x60,0x2b,0xc2,0x74,0x4b,0x8b,0x85,0x44,0x28,0x02,0xd5,0xb9 +.byte 0xae,0x00,0x37,0x1e,0x0b,0x46,0xe6,0x40,0xf1,0xdc,0xa0,0xfc,0xae,0x04,0x7f,0xb6,0x46,0xa3,0x22,0x79,0x92,0xda,0x89,0xa0,0x38,0xf0,0xa2,0x4a,0x76,0x79,0x0c,0x46,0x4d,0xa9,0xe6,0x75,0xff,0x01,0xb3,0xe4,0x13,0xc2,0x53,0xe9,0x6d,0x1f,0xdd,0x88,0xcf,0x10,0xf5,0x16,0xef,0x05,0x59,0x51,0x15,0x49,0x17,0xda,0xff,0x0e,0xb3,0xb9 +.byte 0xae,0x79,0xc6,0xb1,0x94,0x08,0x09,0x30,0x9f,0x2a,0xfd,0x55,0xc0,0x41,0x8c,0xe5,0x0e,0xee,0xc2,0xa0,0x05,0x36,0x66,0x8d,0x9a,0xcc,0xc9,0xeb,0x1d,0x34,0xc0,0x1a,0x29,0xc2,0xcd,0xb7,0x25,0xd3,0x83,0xf8,0x1e,0xa0,0xf4,0x50,0xd4,0x08,0x0d,0xcb,0x6a,0x2f,0xa5,0x8b,0x30,0x94,0x89,0xea,0x94,0x6c,0x00,0x7e,0x7f,0xb5,0x4d,0x61 +.byte 0xa7,0x9d,0x94,0xcc,0x14,0x8f,0x75,0x1f,0xef,0x2b,0xbe,0x37,0xdd,0x19,0x41,0x2e,0x90,0x36,0x27,0xa5,0xa9,0x6c,0x75,0x8c,0x2d,0xe3,0x97,0x74,0x91,0xf3,0xb8,0xcb,0xcb,0x74,0xba,0xf0,0x57,0x70,0x89,0xee,0x4d,0xc5,0xfe,0x3e,0x60,0xe3,0x5b,0x28,0x36,0x91,0x6f,0xcd,0x6c,0x33,0xb6,0x44,0x0c,0xce,0x81,0xe4,0xdb,0x84,0xbe,0x4e +.byte 0xef,0xb8,0x75,0xf7,0x8b,0xb0,0xb7,0x0d,0x00,0x13,0x54,0x39,0xfd,0x9e,0x86,0x5c,0x59,0xd0,0x84,0x0f,0x97,0xc0,0xf8,0xfa,0x4a,0xcf,0x57,0xb8,0x24,0xf0,0xa8,0x40,0x70,0x9d,0xc4,0xe5,0xc7,0xc9,0xcb,0xb6,0xf4,0x0b,0xb5,0xcc,0xe0,0x90,0x2b,0x42,0x81,0xd6,0x59,0x2e,0x11,0xbd,0xe8,0xf5,0xef,0xa8,0x2b,0xdb,0x93,0x62,0x1e,0xef +.byte 0x3a,0x5f,0xf5,0x47,0x15,0x1f,0x03,0x6f,0x40,0x85,0xff,0x50,0x89,0x2e,0x72,0x8f,0x5c,0x0d,0x61,0x84,0x8d,0x8a,0x8f,0x2a,0x47,0x7c,0x97,0xfe,0x8a,0x97,0x6c,0xd5,0x1c,0x97,0xfa,0x59,0xbe,0x2c,0x0f,0x4d,0x85,0x7f,0x18,0xe3,0xea,0xe8,0xde,0x5a,0xf3,0x67,0xe1,0x71,0x7e,0x81,0xa3,0x74,0x0d,0xf4,0x3d,0x5a,0xec,0xc1,0xcf,0x6f +.byte 0x08,0x0f,0x5a,0x63,0x72,0x0b,0x46,0x5d,0x38,0x80,0xea,0xb7,0x12,0x5d,0xce,0x37,0x26,0xaa,0xd3,0x0d,0x93,0x4a,0x34,0x20,0xd5,0x51,0x54,0x1c,0x5e,0x53,0xa9,0xed,0x26,0x3c,0x29,0xaf,0xbe,0x73,0x34,0xa5,0xc3,0xbf,0x8c,0x8a,0xc3,0x30,0x89,0xaf,0xa9,0x2d,0x28,0x35,0x7d,0x6b,0x84,0x23,0x22,0xee,0x8c,0x82,0x04,0xbd,0x26,0x52 +.byte 0x26,0x73,0x76,0x05,0x35,0x0c,0xec,0xf7,0x54,0xb2,0x17,0x68,0xe9,0x68,0x67,0xbb,0x0d,0x98,0x19,0x32,0xa7,0xdb,0xf9,0xef,0x42,0xe7,0xc2,0xe2,0x39,0x9c,0xae,0xbb,0xdb,0x91,0x28,0x82,0x88,0x23,0x61,0x50,0x6d,0x61,0x39,0x73,0xf8,0x6a,0xee,0xf3,0xa9,0x2c,0x78,0x0d,0x5a,0xed,0xb1,0x08,0x8f,0x24,0xe5,0xb7,0xa4,0xdf,0x65,0x9a +.byte 0x72,0x3a,0x39,0x9c,0xf4,0x43,0xdc,0x8a,0xa3,0x3d,0xb5,0x1e,0x7b,0xe5,0x83,0x11,0x07,0xab,0x62,0x7e,0xac,0xab,0x52,0x94,0x0b,0xaf,0xdf,0x54,0x18,0xf1,0xc0,0x9f,0x1c,0x33,0x02,0xd9,0x62,0xc3,0xcc,0xaf,0x32,0x09,0x35,0x77,0xad,0x72,0xd6,0xb5,0x2d,0xaf,0xf9,0x39,0xfb,0x95,0xbb,0xf9,0x84,0x80,0x84,0xc8,0xc6,0x6d,0xb5,0x79 +.byte 0x25,0xf4,0x6c,0x71,0x26,0xda,0x74,0x86,0xad,0x52,0x47,0x8b,0x46,0x32,0xf6,0x2c,0x89,0xdb,0x93,0x1f,0x46,0x83,0x91,0x19,0xd2,0x0c,0x29,0x97,0x5f,0xa9,0x2b,0x87,0x0c,0x87,0x89,0xe6,0x63,0xa1,0x36,0xfb,0xfa,0xb4,0xb8,0x8e,0x5f,0xe9,0x8f,0x62,0xd2,0x81,0x1d,0x7b,0xc6,0x14,0x37,0x56,0x73,0x64,0x3d,0x0a,0xfd,0xe5,0x94,0x01 +.byte 0x09,0xc8,0x0d,0xa8,0x92,0xda,0x43,0xc4,0x41,0xca,0x3c,0x27,0x2c,0xbb,0xc4,0xb2,0x77,0x13,0xa6,0xb0,0x0e,0x97,0x6a,0xb2,0x83,0xe5,0x5e,0xa3,0xc0,0xe8,0x5e,0x0b,0xe6,0x00,0x04,0x6c,0x1b,0xac,0x84,0xab,0xd3,0xac,0x5f,0x39,0xc2,0xf8,0xfd,0x66,0xf7,0x97,0xd7,0xb9,0x6b,0xd8,0x2a,0x49,0xf7,0x67,0xd8,0xd5,0xa4,0x89,0x57,0xa6 +.byte 0x8f,0x7c,0xcf,0xaf,0xfe,0x3c,0x92,0xc8,0x23,0x2c,0x26,0x83,0x86,0x16,0x97,0x34,0x71,0x3e,0x82,0x2b,0xc7,0x75,0x5a,0x59,0xb3,0x44,0xdd,0x4e,0xd4,0x6d,0x1b,0x9f,0x3c,0x35,0xc4,0xe4,0xf2,0x95,0xb6,0x90,0x95,0xa7,0xc4,0x03,0x10,0x7d,0x3d,0xeb,0x74,0x29,0xaa,0x0c,0xd3,0x27,0xcd,0x3a,0x85,0x3c,0x88,0xd5,0x9a,0x46,0x84,0x8e +.byte 0x36,0xde,0xe3,0x6a,0x27,0xbf,0xc3,0xd0,0x3e,0xa3,0x0e,0x62,0x1f,0xdf,0x4c,0x02,0xa7,0x11,0x91,0xb0,0x6b,0x50,0xc1,0xe0,0x18,0x5a,0xc0,0x10,0xc7,0x1c,0xb6,0x36,0xac,0xe7,0x7d,0xad,0x34,0x63,0x4f,0x17,0xcc,0x41,0x30,0xec,0xd7,0x14,0xb9,0xfe,0x07,0x5c,0x3d,0xbe,0x08,0x77,0x5b,0xdf,0xa3,0x20,0x56,0x55,0xa2,0x8a,0xe7,0x0d +.byte 0xf6,0xfc,0x91,0x37,0xb8,0x92,0x6c,0xd9,0x5c,0xb0,0xc2,0xf7,0xc0,0x38,0xfa,0x54,0xc6,0xa1,0xd3,0x4d,0xae,0x49,0x0d,0xd1,0xc0,0xef,0xbe,0x27,0xce,0x23,0x8e,0xf2,0x9b,0x68,0x02,0x67,0x8f,0x53,0x9d,0xf6,0x23,0x57,0x85,0xdd,0x8d,0xd7,0xcb,0x47,0xf1,0xd8,0x17,0xd8,0x46,0x72,0x28,0x4b,0xac,0x94,0xd3,0x5d,0x53,0x4f,0x06,0x19 +.byte 0xc6,0x0e,0x0b,0x9f,0x58,0xc6,0x3f,0xea,0x4e,0x83,0x5e,0xd3,0xcc,0x44,0x55,0xa3,0xc7,0x24,0x19,0xea,0x1b,0x18,0xc1,0x18,0x5f,0x21,0x67,0x73,0x32,0x4e,0x31,0x69,0x05,0x40,0x79,0x7c,0x05,0x13,0xdd,0x50,0xea,0xfa,0xc2,0x26,0xe2,0x33,0xff,0x34,0x0d,0xda,0x77,0x27,0xe0,0xe7,0xa6,0x7b,0x8e,0xcd,0xdb,0x92,0x48,0x3a,0x2d,0x52 +.byte 0xf5,0x59,0xca,0xc7,0x47,0xda,0xb7,0xc7,0x8c,0x37,0x5e,0x29,0x30,0xf5,0x57,0x74,0x8b,0x10,0xcb,0x20,0x31,0x4b,0x12,0xe3,0x84,0xd2,0xb2,0xc3,0xd0,0xe3,0x94,0x18,0xa2,0xdc,0x8f,0x4d,0xc3,0x0a,0x43,0x07,0x2c,0x6b,0x41,0x64,0xc0,0x35,0x8f,0x37,0x9b,0xd7,0x78,0xab,0xd0,0xdc,0x1f,0x77,0x55,0xab,0x71,0xc8,0x99,0x98,0x00,0x29 +.byte 0x1c,0xab,0x3c,0x5f,0x82,0x96,0xc2,0xc8,0x9b,0xd4,0x68,0x3f,0x3d,0xe6,0x5a,0x4c,0x1c,0x7b,0x51,0xa3,0x79,0xe8,0x0e,0x8a,0x78,0xdc,0x98,0x63,0x80,0x74,0x32,0x9d,0x7c,0x3a,0x79,0x54,0xa7,0x4c,0xa4,0x4e,0xfc,0xa5,0x8a,0xa4,0x19,0xce,0x84,0xbb,0x8a,0xb9,0x93,0x4a,0x2d,0x82,0x5d,0x1d,0xf8,0x2f,0x85,0xb3,0x90,0x32,0x61,0x6d +.byte 0x13,0x33,0xac,0xbc,0x5d,0x3a,0x54,0x45,0x04,0x50,0x30,0x30,0xc7,0x58,0xbe,0xed,0xdd,0xa1,0xae,0x6d,0xe5,0xde,0xed,0x63,0x9f,0xd4,0x2b,0x8d,0x1f,0x69,0xde,0xda,0x55,0x3f,0x3b,0xe7,0xc8,0x73,0xc0,0x68,0x18,0x6a,0xb3,0xfb,0xce,0xaf,0x46,0x0a,0xcc,0x81,0xa8,0x96,0x6d,0xb6,0xa4,0x74,0xf3,0x8c,0x95,0x2d,0xa1,0xfe,0x09,0xb8 +.byte 0xdb,0x3c,0xcd,0xdc,0x5b,0x0e,0x2d,0xff,0x89,0x8a,0xfd,0x7a,0xe9,0x69,0x0b,0xdd,0x4e,0x9b,0x94,0x64,0xe4,0xb6,0x5d,0x69,0xef,0x9c,0xf6,0xe6,0x44,0x73,0xd5,0x86,0x47,0x63,0x77,0x3e,0x74,0xaa,0xf3,0x6b,0x1f,0x37,0xbf,0xef,0xa2,0xff,0x86,0x61,0x78,0xc4,0xb5,0xbd,0x5a,0x43,0x49,0x80,0x16,0xf2,0x4c,0xec,0x1e,0x07,0x0f,0x41 +.byte 0x60,0x6f,0x3a,0xd2,0xab,0x85,0xc0,0x5c,0xfc,0x9f,0x48,0xad,0x5e,0xe0,0x7d,0x66,0x8e,0x46,0xf1,0xc3,0xb0,0xbc,0x5e,0x3b,0x10,0x7c,0xfc,0xa3,0x27,0xbd,0x8f,0xae,0xd9,0x61,0x39,0xbf,0xca,0x27,0xbb,0xe7,0xda,0x59,0xa8,0x63,0x38,0x16,0xd9,0xb5,0xa6,0xd9,0x1c,0x2b,0xa1,0x42,0xec,0x50,0xd7,0x63,0x09,0x22,0xe0,0x0c,0xb8,0xec +.byte 0x12,0x9b,0xdb,0x8a,0xd3,0x02,0xcf,0x32,0xa9,0x88,0xa4,0x31,0xc8,0xa9,0xf4,0x03,0xf2,0x9d,0xe1,0x41,0xf0,0x0f,0x23,0x65,0xa8,0x99,0x55,0x87,0xf2,0x17,0x66,0xf0,0x94,0xe8,0xe9,0xb6,0xfd,0x10,0xb9,0x55,0xf4,0xda,0x06,0x7a,0xbe,0xe2,0xd3,0xfa,0xb8,0xf7,0x85,0xdf,0xee,0x39,0xdc,0x0f,0xda,0x87,0xf5,0x66,0xd8,0x1b,0x5c,0x0c +.byte 0x13,0xe8,0xa2,0xcd,0xdf,0x47,0x33,0xd7,0xf4,0x5c,0x79,0xc7,0xf4,0x68,0xe4,0x2d,0xa1,0xde,0x5c,0x06,0x1c,0x85,0xf1,0x2a,0xf9,0x73,0x44,0xbc,0xd3,0x57,0x4f,0x0f,0xcd,0xcc,0x40,0xeb,0x9d,0x35,0x8e,0xdf,0x1d,0x4a,0x61,0xd0,0x66,0xb5,0x16,0xce,0x45,0xc0,0xbf,0x01,0xe3,0xb2,0x51,0xba,0x53,0x18,0x2a,0xff,0x19,0xea,0x41,0xa2 +.byte 0xac,0x0b,0x50,0xd3,0xc1,0x6a,0x9c,0xb0,0x34,0x6f,0xa0,0xcb,0xc7,0xc6,0x79,0x5d,0x17,0x3a,0x4c,0xa3,0x16,0xdc,0xac,0x10,0xf0,0x24,0xad,0x9a,0x5b,0xa9,0x7e,0x45,0xcd,0xe9,0xad,0x87,0x04,0xbc,0x2a,0x05,0x59,0xd1,0xdb,0x86,0x22,0x40,0xdf,0xb1,0xff,0x8d,0x3c,0xf8,0x6a,0xf3,0xcb,0x60,0xf9,0x35,0xa6,0x42,0x81,0xcb,0x0f,0x7c +.byte 0xf7,0x24,0x3b,0x0c,0x94,0x32,0xd9,0xec,0xcf,0xd1,0x31,0x3e,0x3e,0xeb,0xa9,0xf2,0x1f,0x2d,0xa7,0x89,0xf7,0x67,0x7d,0x90,0x9d,0x40,0xf2,0xdb,0x07,0x8f,0xb8,0x6f,0xfd,0x78,0x6e,0xd0,0x9e,0xd5,0x7d,0xb0,0x7d,0x65,0xdc,0x6e,0x50,0xec,0x7a,0x5c,0x2c,0x3e,0x6f,0x64,0xa3,0x10,0x34,0xf7,0x71,0xc8,0x82,0xb6,0x96,0xb8,0xb1,0x2a +.byte 0xb4,0x03,0x95,0x75,0x90,0xac,0x6c,0x81,0x17,0x97,0x06,0xd0,0xb8,0xc5,0x98,0xc5,0x9e,0x46,0x07,0x13,0x02,0x9e,0x47,0x69,0xba,0x85,0x2d,0x09,0x86,0x50,0xe4,0x76,0xb1,0xa2,0xbe,0x8b,0x91,0x6b,0x3b,0x76,0xa3,0xb7,0xf5,0x7f,0xfe,0xf1,0xa4,0xf3,0xc3,0x53,0x64,0xef,0x97,0x86,0x96,0x8b,0xc4,0xae,0x06,0x8b,0xe8,0x3c,0xdc,0xff +.byte 0xfa,0xad,0xcb,0xcb,0x53,0x15,0xf2,0xcc,0x9f,0x48,0xf9,0x57,0x6a,0xcd,0xb2,0xee,0x46,0xc0,0xbf,0x82,0x58,0x60,0xda,0x2f,0xbd,0xde,0xc7,0x41,0xcb,0xf1,0x38,0x56,0x9d,0x38,0x38,0x3d,0xea,0x5e,0x38,0xf1,0xd0,0x02,0x35,0xee,0x4c,0x2f,0x1d,0x19,0xbd,0x08,0x01,0xc3,0x8f,0x75,0xe2,0xf3,0x93,0xbb,0x76,0x6b,0xd7,0x87,0x76,0x7f +.byte 0x3b,0x29,0x08,0x9f,0x3a,0xa5,0x44,0x96,0x5a,0xb3,0x78,0xa9,0xbe,0xf7,0x5d,0xda,0x06,0x37,0x98,0x5d,0xbe,0x6e,0xec,0x58,0x53,0xd1,0xa5,0xd7,0x7a,0x16,0xb1,0x59,0x98,0x42,0x37,0x76,0x1b,0xd6,0x2e,0xa7,0xdc,0x45,0xa6,0x9c,0x9c,0x99,0x24,0x0e,0x22,0xae,0x94,0x65,0xeb,0x4e,0x64,0xc3,0xb0,0xac,0x19,0x41,0xf1,0x62,0x65,0xb2 +.byte 0x35,0xf5,0x2f,0xdb,0xd2,0xf0,0x78,0x19,0x35,0x04,0x6f,0x9c,0xf4,0xaf,0x81,0x68,0x4f,0x8b,0x85,0xfa,0x31,0x23,0x06,0xeb,0x37,0x86,0x43,0x51,0xb3,0xd2,0x2a,0xd7,0xd5,0xa9,0x33,0xba,0xfd,0xb5,0x0e,0x6d,0x9a,0x91,0xf9,0xe7,0x27,0xb7,0xff,0xe6,0xe7,0x34,0xc5,0x1a,0xa3,0x45,0x3b,0x71,0x34,0x87,0x7e,0xe7,0xab,0x74,0xc5,0xff +.byte 0xeb,0x23,0x8f,0x3f,0x5d,0x1c,0x91,0x47,0xeb,0x3e,0x5f,0x5a,0xa6,0x5a,0xde,0xa9,0x5f,0xf4,0x8f,0x95,0xc6,0x25,0x3c,0xd5,0xaf,0xfd,0x4d,0x33,0x68,0xe1,0xa3,0x51,0x1b,0x07,0xad,0xb9,0xec,0xf1,0x50,0x51,0xbf,0xeb,0xe8,0x58,0x2a,0x50,0x0e,0x9d,0xc2,0x8a,0x83,0x8c,0xb0,0xb8,0xde,0x1d,0x7b,0x0f,0xff,0xfc,0xfc,0x31,0xe5,0x62 +.byte 0x40,0xc8,0x28,0x30,0x31,0xc9,0x82,0xab,0xbe,0x50,0xe5,0xfe,0x1f,0x49,0x17,0xf9,0xea,0x23,0xc7,0x6d,0x8d,0x63,0xc3,0x70,0x40,0x32,0x0b,0x48,0x7a,0xd9,0x03,0x52,0x1b,0xf4,0x90,0xd6,0x6d,0xd2,0xfc,0xec,0x24,0x7f,0x21,0x2e,0xd4,0xb5,0x60,0x44,0xd9,0x83,0xb0,0x3e,0x75,0x8a,0x6a,0x09,0xab,0xa8,0x4f,0x48,0x3c,0x2b,0x89,0x30 +.byte 0x29,0xdb,0x1a,0x8e,0x68,0xe4,0x89,0xed,0x10,0xe8,0x46,0xa7,0xf9,0x5f,0x7d,0x42,0xe0,0x8d,0xbc,0x3d,0x4d,0xd8,0x06,0x4a,0xf9,0xbb,0x97,0xa7,0xdb,0x24,0x0b,0xfc,0x49,0x92,0x5d,0x80,0xf8,0xed,0x57,0xc7,0x1e,0x82,0xed,0x41,0xb8,0xfd,0x71,0xb9,0xa5,0x11,0x52,0xdd,0x1e,0xa4,0xf1,0x02,0xc7,0x54,0x7c,0xdc,0x37,0x9f,0xfe,0x37 +.byte 0xe8,0xa5,0xcf,0xb0,0x3d,0x25,0x3f,0x24,0xfe,0xf2,0x63,0x97,0x3c,0x13,0xdc,0x31,0x78,0x07,0xf1,0x8e,0xee,0xc6,0x00,0xf8,0xfd,0x84,0x53,0x4d,0x92,0xa1,0xef,0xd0,0xb1,0x12,0x0a,0x12,0x91,0xeb,0x52,0xdd,0x6e,0x15,0x98,0xd2,0xe1,0x53,0x7a,0x0e,0x02,0x83,0xd3,0xd1,0xde,0x72,0x6e,0x5b,0x4b,0x8d,0x40,0xe3,0x2d,0x22,0x59,0x9d +.byte 0xee,0xbe,0x43,0x18,0x62,0x8c,0x77,0x18,0x91,0xf5,0x9e,0xbc,0x3e,0x8b,0x77,0xb6,0xdb,0x5c,0xcb,0xcd,0xdb,0x36,0xea,0xf5,0x1d,0x9b,0xa7,0x13,0xef,0xda,0xd0,0xe8,0xd8,0xb2,0x4c,0xc6,0x19,0x3d,0x77,0x2d,0x0d,0xad,0xe4,0x32,0x24,0xe9,0xd4,0x7f,0x72,0x1d,0xc6,0x6e,0x83,0x7d,0xb8,0x62,0x64,0x9d,0x9a,0xd7,0x13,0x93,0x92,0xf1 +.byte 0x37,0x98,0xcf,0x44,0x66,0xab,0xd1,0x61,0x6c,0x08,0xa7,0x41,0x4e,0x37,0xc1,0x67,0xfb,0x7c,0x22,0x8f,0xbd,0x93,0xb2,0x09,0x13,0xa0,0x48,0x60,0xaf,0xda,0x73,0x2b,0xa3,0x2a,0xf3,0x4d,0x8e,0x22,0x5b,0x7a,0x32,0xe6,0xca,0xff,0x0e,0xa1,0x0a,0x15,0x33,0x31,0x50,0x71,0x1c,0x85,0x26,0x9b,0x19,0xf2,0xe3,0x69,0x4e,0x2d,0xff,0x79 +.byte 0x80,0xfe,0x2c,0x2f,0x7a,0x49,0x95,0xf3,0x0e,0x78,0xb1,0x0c,0x1c,0x45,0x59,0x68,0x2a,0x37,0xf2,0x48,0x6f,0xd9,0x32,0xf7,0xfc,0xdc,0xbe,0xe3,0xdd,0x61,0x17,0xc0,0x08,0x9d,0xbc,0x2d,0x8d,0x24,0x1c,0xbb,0x53,0xbe,0x37,0x59,0x30,0x87,0xa0,0x14,0xf5,0x08,0xcf,0xd1,0xcc,0x84,0xa7,0x0f,0x69,0xe0,0x77,0x8c,0x0d,0xdc,0x82,0xe5 +.byte 0x88,0x9a,0x58,0x05,0xe3,0x4f,0xdd,0x55,0x1e,0x6e,0x90,0xd5,0x3c,0xa6,0xa6,0x10,0x24,0xe5,0x58,0x97,0xdc,0x31,0x87,0x39,0xdc,0x3a,0xe6,0x24,0x64,0x23,0x45,0xd8,0x01,0x1b,0xf6,0x38,0x68,0x9e,0x62,0x53,0x00,0x97,0x71,0x04,0xb5,0x3b,0x54,0xdb,0xb5,0xcb,0x30,0x91,0x14,0xce,0x94,0xd5,0xe0,0x96,0x70,0x99,0xa5,0xed,0x69,0x32 +.byte 0xc7,0xb7,0x14,0xff,0xc0,0xde,0x19,0x5d,0x31,0xdb,0xa7,0xc0,0x7a,0x94,0xec,0x60,0xfc,0x52,0x71,0x69,0x9b,0xd8,0xbe,0x97,0x0b,0xb5,0x70,0xa7,0x47,0x11,0x37,0x84,0xda,0x3c,0x23,0xfe,0xf2,0x53,0xad,0x55,0x71,0x1e,0x70,0x9b,0x7b,0x61,0x97,0xf8,0x71,0xc4,0xad,0x72,0x98,0x43,0x0c,0x33,0x30,0x2c,0xb2,0xd6,0x21,0x8d,0xbb,0x1b +.byte 0x85,0x82,0x24,0x14,0x85,0x95,0x88,0xff,0x3f,0x8c,0x88,0x96,0xa0,0xf8,0xd7,0x36,0x78,0x37,0x6d,0x92,0x09,0x04,0x76,0x27,0xb9,0xd5,0xea,0x0f,0x07,0x9f,0xe1,0x49,0x0e,0xd1,0x9c,0x46,0xcd,0x2b,0x7a,0x57,0xb6,0x56,0x39,0xe5,0x59,0x6b,0x1b,0x39,0xbf,0x15,0x3b,0x56,0xf5,0xc2,0x08,0x96,0xf5,0x63,0x4c,0x31,0x33,0x65,0x8b,0x74 +.byte 0x4e,0xde,0xa8,0x20,0xe0,0x7c,0x27,0xee,0x91,0x74,0xe8,0x24,0xb3,0xcf,0xa3,0xd4,0xf1,0xb9,0x18,0x43,0x05,0x5d,0x13,0x36,0x82,0xd1,0xbf,0x16,0x89,0x48,0x83,0xf0,0xcc,0x5c,0xbb,0x75,0x7e,0x71,0xc0,0x73,0xd1,0xf5,0x00,0x38,0x7f,0x10,0x98,0xd6,0xb9,0x14,0xea,0xd3,0x3f,0x0f,0xe3,0x61,0x1a,0x5e,0x21,0xd0,0x11,0x58,0x68,0x47 +.byte 0xf2,0xe5,0xe9,0x65,0x9a,0xc1,0xf4,0xa0,0x98,0x8e,0x9f,0x7f,0xbe,0x7e,0xd0,0xb6,0x88,0x4e,0xce,0xc1,0x8b,0xd4,0xd3,0x93,0xb7,0xd8,0xf3,0x0b,0xf3,0x73,0xc9,0x08,0x2f,0xcf,0xd8,0xbd,0xa6,0x1d,0x7c,0xfa,0x44,0x82,0x9f,0x03,0xca,0x56,0x3b,0xbf,0x4d,0x1e,0xbc,0x06,0xc2,0x37,0xfb,0xde,0xd3,0xa9,0xe3,0xae,0x61,0xef,0x26,0x7d +.byte 0xbd,0x2f,0xee,0x2d,0xe1,0x65,0x71,0x77,0xab,0x9c,0x96,0x4f,0x00,0xe2,0xde,0xd7,0x05,0x54,0x00,0xb6,0xaf,0x12,0x0c,0x79,0x1a,0xed,0x20,0x72,0xc7,0x3b,0x3a,0x10,0x15,0x74,0xff,0xbd,0xf8,0xaa,0x8f,0x3a,0x83,0x39,0x24,0xfa,0x53,0x2d,0xc3,0x61,0xfc,0x12,0x6b,0x54,0x33,0xbf,0x83,0xc9,0x59,0x00,0xf0,0xdc,0xa8,0x64,0xbc,0xb5 +.byte 0xc3,0x96,0x60,0x3e,0x7b,0xe2,0x08,0x19,0x92,0x17,0x80,0x9b,0x0c,0x09,0x49,0x68,0x8b,0x15,0xe3,0xce,0x0c,0xfa,0x0c,0x8b,0xf0,0xdc,0x58,0xb0,0x7b,0x82,0x85,0xd2,0x56,0x1c,0xfb,0xb5,0xd0,0x0e,0x0a,0x55,0x61,0xda,0xd8,0x20,0xc1,0x79,0x70,0x3c,0x69,0x8e,0x49,0x5f,0x1c,0xdb,0x22,0xb8,0xdd,0x4c,0x4f,0xca,0xe9,0x0f,0x9a,0x4e +.byte 0xff,0x56,0xbc,0xcf,0x72,0x09,0xa6,0x41,0x38,0xf0,0x7d,0xe7,0x45,0x0a,0x71,0x2c,0x92,0xdd,0x21,0x17,0xb2,0x3b,0x31,0x3c,0x91,0x11,0x69,0x29,0x50,0x31,0xe6,0xa6,0x10,0xc7,0x35,0xe8,0x44,0xec,0x74,0xa3,0x7e,0xb6,0x34,0xe5,0xb7,0xba,0xdf,0x5b,0x2f,0x85,0x02,0x6c,0xb0,0x71,0xb1,0x43,0xff,0x0e,0x47,0x04,0x63,0x4d,0x5b,0x81 +.byte 0x81,0x28,0x8b,0x84,0x79,0xad,0x2a,0x45,0x00,0x1c,0x0c,0x9f,0xef,0x35,0xbb,0x6d,0xc5,0x6a,0x6b,0xef,0x2b,0xae,0x78,0x66,0x05,0x7a,0x61,0x4c,0xe9,0x5e,0xf7,0x95,0x66,0x7e,0x1a,0xa7,0xdf,0x4c,0x4d,0x7c,0x66,0xa5,0x38,0x84,0x86,0x8d,0x66,0xcc,0x7f,0x32,0xb2,0x9c,0xc5,0x0d,0x3d,0xb7,0xb1,0xa6,0xc5,0x80,0x68,0xaf,0x79,0x81 +.byte 0x15,0x8f,0xec,0x50,0x5c,0x1b,0x57,0x31,0xd2,0xb9,0x16,0x66,0xf8,0x16,0xfd,0xcd,0xc7,0xa8,0x84,0x6f,0x35,0xea,0x3f,0xa4,0x72,0x8d,0xad,0xf4,0xd1,0x14,0x46,0xcc,0x06,0xed,0x71,0x39,0x07,0x99,0x28,0xc8,0xf9,0xc4,0xc2,0xec,0xde,0xb8,0x92,0xae,0xc5,0xf8,0xb2,0x49,0xc9,0x32,0x58,0xec,0x9f,0xb0,0x59,0xaf,0x49,0xef,0xe8,0x0d +.byte 0x4c,0x56,0x8d,0xf7,0x57,0xb0,0x09,0xbe,0xc2,0x6a,0x62,0xc4,0x87,0xf3,0x20,0x07,0xc9,0xe3,0x3b,0x31,0xcc,0x8d,0xcf,0x5d,0x18,0x00,0x2a,0x9f,0xde,0x80,0x1a,0x7e,0x95,0x93,0xd1,0xbd,0xe6,0xd4,0x69,0x37,0x96,0xbb,0x70,0xc5,0x3c,0x87,0x8f,0xff,0x95,0x97,0xfe,0x95,0x56,0x7b,0xba,0x03,0x3d,0x29,0x0f,0xdb,0xd0,0x65,0x4f,0xf8 +.byte 0xa8,0xf3,0x42,0x09,0xb5,0x81,0x34,0xc6,0xa9,0x60,0xb9,0xef,0x3e,0x9d,0xc5,0x42,0x1e,0x79,0x5d,0x2b,0xf2,0x46,0x0d,0xeb,0x88,0x84,0x8f,0xad,0x60,0x69,0x57,0x49,0x33,0xb4,0xdd,0xfe,0x10,0x65,0x65,0x51,0xaf,0x68,0xa0,0xce,0xbd,0xe1,0x6e,0x03,0xe1,0x5f,0xba,0x3f,0x36,0xca,0xed,0x20,0x95,0xfa,0xff,0x3c,0x65,0xa8,0xb1,0x6b +.byte 0xc5,0x91,0xa0,0xd5,0x36,0x38,0x1c,0x38,0xe9,0x1d,0x1b,0x67,0x4c,0x17,0xd3,0x29,0x92,0xa2,0x27,0x76,0x3d,0xe2,0x26,0x37,0x2a,0x2c,0xf6,0xee,0x64,0x40,0x8a,0x1c,0x2b,0xc1,0xd3,0x28,0xd0,0xcf,0x2d,0xc2,0x45,0xf4,0x37,0x5a,0x63,0xfb,0x18,0x67,0x01,0x0a,0xe8,0xe2,0x41,0xf7,0x15,0x47,0xa7,0xe9,0xc8,0x05,0xbc,0xc7,0x8f,0xf0 +.byte 0xc3,0xc5,0x9a,0x4e,0x0d,0x7b,0xf0,0x20,0x8c,0x21,0x49,0x99,0x0d,0xf7,0x34,0x84,0x35,0xfb,0x11,0x33,0xd6,0x46,0x14,0x3c,0xf1,0xb3,0x37,0xac,0x75,0x63,0xe7,0x1a,0x19,0xa4,0x49,0xf2,0x58,0x1d,0x56,0x55,0x64,0x46,0x25,0xff,0x7d,0x90,0x34,0x21,0x5d,0x00,0xa1,0xa8,0xaa,0xe0,0x93,0xe7,0xda,0x11,0x34,0x1d,0xa3,0x0c,0x67,0xae +.byte 0xf5,0x60,0x72,0x14,0xdf,0x08,0xf6,0x72,0x3e,0x48,0x41,0x3d,0x00,0x58,0xfb,0x0c,0x15,0x80,0x2d,0xd9,0x72,0x47,0xa6,0x20,0x6a,0x74,0x9e,0x06,0xb9,0xac,0x68,0x3a,0xe7,0xf1,0x19,0xb8,0x0b,0x66,0x07,0x4d,0xa0,0xb5,0xab,0xea,0x70,0xa1,0xdf,0x41,0x76,0x85,0x18,0x5b,0x6f,0x78,0x5a,0x5d,0x08,0xe0,0x1b,0xd8,0x06,0x73,0x1e,0x16 +.byte 0xcb,0xdb,0x02,0xf8,0x96,0x64,0x65,0xc5,0xc1,0x52,0xd4,0xd8,0xb3,0x1e,0xd4,0x09,0xfd,0xa7,0x30,0x41,0x5a,0xce,0x53,0x4d,0x11,0xc8,0xdd,0x13,0x50,0xd5,0x2e,0xa0,0xe6,0x48,0x49,0x31,0x4b,0x1d,0xce,0xfc,0x42,0xed,0x8f,0xc8,0xb3,0x0a,0xae,0x1d,0x4c,0x1e,0x4f,0x39,0xa4,0x37,0xc8,0x54,0xdf,0x40,0xa6,0x42,0x61,0x7d,0x34,0xd4 +.byte 0x75,0x0a,0x9f,0xf0,0x33,0x54,0xf3,0xc4,0xdc,0x4e,0x2f,0x81,0xc2,0x20,0xaa,0x4f,0xa0,0xae,0xa6,0xb8,0x50,0xf8,0x45,0xf1,0xf2,0xd1,0xd2,0xcf,0xc8,0xf0,0xf4,0x54,0x37,0xdc,0xfb,0x13,0xdf,0x38,0xc2,0x3f,0xe0,0x59,0xb5,0x9a,0x0f,0x27,0x87,0xd4,0xd3,0xdc,0xfd,0xda,0x1d,0xfa,0xdd,0x12,0xe0,0x7f,0x34,0x01,0xde,0x28,0xf5,0x0e +.byte 0xff,0x59,0xc7,0xbd,0x6a,0xe4,0x0c,0x85,0x7b,0x87,0xf9,0xd7,0xe2,0xed,0xb2,0xf7,0xb7,0x13,0xfb,0xfc,0x4d,0x25,0x52,0xfd,0x23,0x6b,0x10,0xd0,0x80,0xd8,0xbd,0xbd,0xf0,0x87,0xfc,0x38,0x85,0x83,0x20,0x5f,0x7c,0x26,0x14,0x93,0xd3,0xe1,0xdc,0xa4,0xda,0xa7,0xf9,0xfd,0x6c,0x9a,0x2b,0x75,0x82,0xf1,0x9f,0x1b,0x0c,0x43,0xd4,0x2d +.byte 0x5b,0x0c,0x54,0x7e,0x61,0x24,0x8e,0x50,0x25,0xd8,0x54,0xfd,0x30,0xec,0x4c,0xa8,0xb6,0xf0,0x35,0x67,0xf7,0xe4,0x3c,0xfd,0xc8,0x40,0xf4,0x2d,0xc5,0x4d,0xc3,0x29,0xc2,0x88,0x60,0xab,0xd9,0x2a,0xe8,0x31,0xcc,0x0c,0x9f,0x97,0xa8,0x2e,0xaa,0xa5,0xb6,0xee,0x3c,0x71,0xa9,0xff,0x90,0xb4,0x43,0x2e,0x16,0x80,0x8c,0xfe,0xb5,0x7a +.byte 0x40,0x58,0xd5,0x98,0x7e,0xca,0xaf,0x95,0xee,0x00,0x26,0x8d,0x5b,0xba,0x33,0xee,0x35,0xb5,0x9b,0xf8,0x08,0x1e,0x15,0x2d,0x01,0xb1,0x83,0xa6,0x57,0x58,0xd1,0xf3,0xa4,0xf1,0x3a,0x00,0xf4,0x40,0xee,0x35,0x3a,0x20,0xc2,0x13,0x1e,0xda,0x32,0xc2,0x35,0x74,0x29,0xce,0x51,0x3f,0xec,0xb2,0xd7,0x23,0xa7,0xc6,0xef,0x70,0xb9,0x88 +.byte 0x6f,0xa8,0xf5,0x5b,0xff,0xc5,0xf5,0xb4,0x3b,0x12,0x75,0x20,0xbf,0x61,0x8a,0xb1,0xae,0x01,0x9b,0x17,0xf4,0xf3,0x2d,0xfb,0x44,0xe8,0xac,0x29,0x81,0xc2,0x6d,0x50,0x05,0x11,0xd9,0x43,0xf8,0xc7,0x58,0x5d,0xbc,0x2d,0xc0,0x83,0xd2,0x81,0x41,0x1c,0x46,0x62,0x60,0x6e,0x65,0x52,0x4b,0x1c,0x88,0x72,0x1b,0x0e,0x8e,0x7d,0xa2,0xb5 +.byte 0x4e,0x28,0x32,0xf2,0xb1,0xfa,0xf1,0x4b,0xc5,0x85,0x95,0x2c,0x08,0x78,0x85,0x68,0xe5,0x20,0x23,0x8b,0xc4,0xf5,0xb2,0xdb,0xc1,0xdd,0xe5,0x69,0xa4,0x97,0xa9,0x6c,0x2e,0x3a,0x25,0x1c,0x24,0x54,0x97,0x3e,0x8d,0x61,0x61,0xa3,0x60,0xf5,0xd2,0x4e,0x90,0x25,0x06,0x09,0x31,0x7b,0x96,0xce,0xcc,0xb7,0xbc,0x63,0x9f,0x04,0x7d,0xec +.byte 0xa1,0x4a,0x65,0xd3,0x26,0xe1,0xbf,0xf9,0x88,0xea,0x5c,0x5d,0xfe,0xe9,0x60,0x77,0xbd,0xf2,0xa0,0x11,0x91,0x24,0xca,0xa1,0x0d,0x05,0x7b,0xe2,0x7d,0x22,0x2e,0xd2,0xc9,0x4b,0x78,0xce,0x0c,0x7b,0x49,0xaf,0xd6,0x59,0x5f,0xb4,0xbd,0x2e,0x4a,0x22,0xcb,0x5d,0x1c,0xd5,0xde,0xea,0x86,0x74,0xd5,0x15,0x52,0x59,0xfc,0x3d,0x7b,0x1c +.byte 0x3f,0x14,0xec,0xf2,0xc8,0x3c,0x88,0xbf,0x89,0xd5,0x23,0xc3,0x94,0x3c,0x28,0x04,0x91,0x6c,0x36,0x35,0x4b,0x75,0xf8,0xdc,0xf3,0xff,0xba,0x8c,0xa4,0xc7,0x85,0xc5,0x1a,0x30,0x4b,0x7c,0xc5,0x2f,0xb9,0x2a,0x14,0xaa,0x65,0xe3,0x92,0xdc,0xe1,0xed,0x3f,0xb6,0xff,0x0e,0x74,0xe0,0xb3,0xc9,0x4b,0xd1,0x96,0xfc,0x49,0x72,0xbe,0xb0 +.byte 0xc8,0x4a,0xd5,0xf0,0xb3,0x58,0x29,0x35,0x97,0xd4,0x5c,0xc7,0x0b,0x27,0x1d,0x14,0xdb,0xb7,0x5c,0x7e,0x6d,0xc1,0x56,0xa9,0x80,0x72,0x7d,0x75,0xc2,0x2f,0x07,0x28,0xb4,0xff,0xef,0xa7,0x34,0xed,0x31,0x44,0x85,0xe6,0xc3,0xa4,0x5f,0xe2,0xe8,0xab,0xd1,0x59,0xe7,0x32,0x20,0xd1,0xcc,0xef,0x6f,0xe1,0x10,0x89,0x6c,0x0c,0xf3,0x5f +.byte 0xe8,0xc7,0x1c,0x3b,0xeb,0x3e,0xa5,0x53,0x2d,0x48,0x64,0x92,0xa0,0xec,0xf3,0x75,0x5b,0x5b,0xe2,0x83,0x87,0x04,0xa7,0xd8,0x1b,0x44,0xfb,0x42,0xee,0xd8,0xf2,0x98,0xff,0x30,0xc8,0x09,0xf8,0x1a,0x95,0x46,0x2d,0xe7,0x43,0x10,0x90,0xf4,0x2c,0x8f,0x0b,0x60,0x6d,0xeb,0xbf,0x19,0xc1,0x9d,0x5c,0xc0,0xff,0xb1,0x86,0xbc,0x01,0x73 +.byte 0x35,0x1f,0xd8,0xf4,0xa1,0xd4,0x7f,0x2d,0x1b,0xf9,0xa6,0x78,0x1a,0x2e,0x2c,0xe2,0xcc,0x8b,0x5f,0xbb,0xb9,0x80,0x31,0x32,0xa5,0x5d,0x70,0x59,0xae,0xe3,0xac,0xab,0xde,0x38,0x09,0x07,0x57,0x5f,0xbf,0xe8,0xa0,0xb8,0xd0,0x03,0xac,0x02,0x0d,0x7f,0x7e,0x0c,0xd2,0xcf,0x46,0x01,0x07,0x9f,0x16,0xf6,0x2b,0x94,0xaf,0xae,0x66,0x09 +.byte 0xca,0x4c,0x5f,0x37,0x53,0xa6,0x50,0x82,0x3a,0x0a,0x7b,0xb3,0x52,0x2e,0x0f,0xe4,0x64,0xab,0x40,0x21,0x2d,0xb7,0x20,0x9b,0xe3,0x2f,0xec,0x2b,0xb3,0x31,0x60,0x51,0x2e,0xb6,0x68,0xac,0xae,0xee,0x2d,0x28,0x5b,0xe0,0xa7,0x85,0xab,0x95,0xba,0x53,0x8c,0xc0,0xf8,0x16,0x8f,0x42,0x01,0xef,0x00,0x32,0x44,0x8e,0x41,0xc9,0x05,0x5b +.byte 0xe0,0x3f,0xe1,0xd8,0xd4,0x97,0x8e,0xa0,0x14,0x84,0xce,0x5c,0xef,0xbe,0xa4,0xae,0x18,0x91,0xd9,0x48,0x9b,0xc3,0x7a,0x8f,0xfb,0xb3,0x3e,0xa9,0x87,0x74,0x84,0xd2,0xc6,0x7c,0xc9,0xce,0x01,0xa5,0xcc,0xff,0x5a,0xe8,0x94,0x98,0x54,0x2a,0x6e,0xd9,0x58,0x75,0xd4,0xdd,0x6c,0x7d,0x83,0x32,0xc9,0x4e,0x35,0x2c,0x51,0x26,0x68,0x1f +.byte 0x95,0x20,0x82,0x54,0x0a,0xad,0x5e,0xe2,0xba,0xf9,0xa3,0x54,0x24,0x93,0x4a,0x62,0xff,0x28,0x05,0xd2,0x22,0x62,0x82,0xd4,0x2d,0xe2,0xec,0x66,0xc5,0xee,0x63,0xd0,0xf6,0x93,0xa8,0x37,0xbf,0xdd,0xe0,0x95,0x0b,0x19,0xa1,0x9d,0x9a,0xf8,0x94,0x1a,0x3a,0x50,0x9e,0x66,0x75,0x8c,0x25,0xbd,0x18,0xb0,0x58,0x76,0x7f,0x2d,0x3d,0x06 +.byte 0x02,0xb3,0xcf,0xa3,0x14,0x6e,0xe7,0xc8,0xcd,0xe6,0xbe,0xae,0x92,0xd6,0xa2,0xfe,0x12,0xf0,0xdf,0x9f,0x9e,0xad,0x77,0x77,0xfb,0xfc,0x36,0xb7,0x82,0x9c,0xf1,0x51,0xc2,0x58,0xa0,0xf3,0xa0,0xd6,0x6e,0x64,0x28,0xac,0x09,0x8f,0x7b,0xef,0x19,0x87,0x76,0xb9,0x4e,0xca,0x1f,0x05,0xb6,0x00,0x4a,0x14,0x83,0xaf,0xff,0xd9,0xa1,0xc6 +.byte 0x0f,0x98,0x3a,0xcf,0x85,0x18,0xea,0xa6,0x9a,0x1e,0xae,0x7c,0xaa,0xae,0xef,0x89,0x5e,0x14,0x5d,0x2f,0x73,0x8f,0xd1,0xf0,0x77,0xcd,0x45,0x92,0x7f,0xee,0xb9,0x7c,0xc2,0x3c,0xff,0x56,0x56,0xa5,0xa5,0x49,0xe4,0x20,0xd6,0xa2,0xb6,0xe4,0xfc,0x86,0x53,0xce,0x9e,0x2b,0x7b,0xcb,0xcf,0x6a,0xd5,0x62,0xb7,0x34,0x0e,0x39,0xe2,0xaa +.byte 0x1c,0x24,0x30,0x71,0x94,0xb3,0x57,0xd8,0xe8,0xd4,0xc5,0x4f,0x33,0x2c,0x73,0x7e,0x48,0xba,0xb3,0x55,0x84,0x6d,0x10,0xcf,0x8f,0xf2,0xb6,0xdb,0x4e,0xcf,0x49,0x08,0xf6,0x5a,0x3c,0x7e,0xef,0x3f,0x5c,0x11,0x09,0xfe,0x26,0xfb,0xff,0x30,0xcb,0x81,0x12,0xea,0x1e,0xa9,0x6e,0xf8,0xea,0x4f,0x92,0x2c,0x23,0x99,0x35,0xa5,0x59,0xca +.byte 0x1d,0x66,0x72,0xad,0x5b,0x7c,0xb3,0x4a,0x7c,0x76,0x4c,0xf6,0xc1,0xec,0x68,0x5f,0x2c,0x17,0xbe,0x92,0xe1,0xa1,0xee,0x40,0x24,0x25,0x6b,0xc5,0x0b,0x6f,0x06,0xc0,0x05,0x8c,0x23,0x24,0x76,0xea,0xe9,0xb9,0xa1,0x3d,0x59,0x15,0xe7,0x65,0x47,0x5a,0x75,0x9b,0xc8,0x7b,0x86,0x97,0xf4,0x4a,0xa3,0xec,0x54,0x0e,0x66,0xef,0xda,0x41 +.byte 0xb8,0x3b,0xa6,0x86,0x63,0xe1,0x4e,0x89,0x92,0x40,0xf4,0x8b,0x32,0x47,0x3b,0x4b,0xb4,0xe6,0xd8,0x4b,0x1c,0xac,0x03,0xab,0xde,0x2e,0x63,0x96,0x3f,0x27,0xa1,0x32,0x11,0x35,0x24,0x6a,0xe9,0x0b,0x73,0x61,0x4e,0xd8,0xdc,0x91,0x98,0x01,0x8a,0x0d,0x61,0xec,0x39,0xbe,0x3b,0xb9,0x78,0x77,0xea,0xaa,0xa2,0x12,0x20,0x92,0x98,0x16 +.byte 0x27,0x3b,0xd1,0xfa,0x59,0xef,0x81,0x38,0x9f,0x42,0xe8,0xb4,0xab,0x4f,0x26,0x9a,0xe7,0x0b,0x05,0x03,0xfa,0xe1,0xe1,0x3d,0x45,0xac,0x7d,0x40,0xcc,0x2f,0xf2,0xb0,0x33,0x42,0x14,0xbd,0x91,0x3e,0xe1,0xb7,0x17,0x25,0xc3,0x92,0xcb,0x9e,0x44,0x1e,0x13,0x93,0x98,0x1f,0x96,0x64,0x3a,0xaa,0x53,0x9a,0x18,0xc0,0x34,0x3c,0x47,0x94 +.byte 0x14,0x70,0x67,0x76,0x2a,0x82,0xd3,0x6a,0x18,0x13,0xe7,0x01,0x8d,0x97,0x52,0x51,0x8e,0x08,0xde,0x44,0xb0,0x74,0x07,0x58,0x35,0xc2,0x29,0xb5,0xd7,0x00,0x46,0x31,0x34,0xd7,0x1f,0xdd,0xaa,0x5c,0x27,0xc7,0x37,0x71,0xe8,0xbe,0xad,0x89,0xf1,0xb2,0xd1,0x46,0x33,0x0c,0x2f,0x26,0x21,0x5e,0xc9,0xda,0x25,0xcd,0xd0,0x17,0x23,0x87 +.byte 0x15,0xc2,0xa0,0x1a,0x9f,0x6e,0xfb,0x63,0xe9,0x69,0xdf,0x79,0x18,0x33,0x2f,0x47,0xca,0x54,0x23,0x7e,0x4f,0x6e,0x38,0x06,0x99,0xfb,0xcd,0x22,0xdb,0x4b,0x3f,0x8a,0x05,0x2e,0x5c,0x56,0x65,0xb7,0xab,0x57,0x8b,0xdd,0x28,0xab,0x7e,0x77,0x32,0x0f,0xc6,0x3c,0xf3,0xde,0x43,0xb0,0x13,0x3b,0xbd,0x28,0x3a,0x8b,0xd5,0x6b,0x1d,0x5d +.byte 0x20,0x1a,0x5f,0xa6,0x01,0xed,0x88,0x7f,0x87,0x55,0x38,0xc2,0x0d,0x03,0x6c,0x41,0x6a,0x43,0xdf,0x09,0xf3,0x58,0x69,0x13,0xa1,0xd6,0x39,0x0c,0x8e,0x8f,0x40,0x67,0xe8,0x0e,0x9b,0x9b,0x42,0x30,0xd7,0xae,0x04,0x75,0x66,0xfb,0x4a,0xa7,0xe0,0xe9,0xea,0x6d,0x28,0x4f,0xc0,0x5c,0xd4,0xd4,0xb7,0x60,0x5a,0x35,0xc1,0xe8,0x5f,0xc3 +.byte 0x4f,0x7a,0x5d,0x8d,0xc2,0x29,0x6e,0x36,0x50,0x5b,0x82,0x63,0xf2,0xda,0x8d,0x02,0x61,0x09,0x69,0x0a,0x47,0x9d,0x58,0xf3,0xf6,0xe0,0xc0,0x09,0xd9,0x3b,0x8d,0xf5,0xba,0xf6,0xc4,0xf0,0x65,0x89,0x7b,0xdd,0x93,0x6b,0x6e,0x21,0xa1,0x2a,0x66,0xe0,0x8f,0x62,0xb0,0x49,0x60,0xa3,0x48,0x42,0x62,0xcc,0x26,0x1f,0x59,0x3a,0x7b,0xa7 +.byte 0x82,0x10,0x5f,0xc6,0xf8,0xa2,0xc0,0x07,0x7b,0x26,0x26,0x11,0xe2,0x5b,0xb8,0x86,0xb7,0x66,0xcf,0x0a,0xcc,0x6f,0xe8,0x02,0x22,0x4c,0x13,0x75,0xdc,0x68,0xf0,0x7c,0x0c,0x46,0x9a,0xa2,0x4c,0xf5,0x50,0x3f,0xf9,0xbc,0x01,0xb1,0xa1,0x28,0x90,0x07,0x6b,0x17,0x69,0x89,0x7b,0xe5,0x0a,0xf7,0x7b,0xe1,0x94,0x30,0xfc,0xd3,0x8d,0xd3 +.byte 0x99,0x37,0x91,0xd5,0xdf,0x59,0x2a,0x4f,0xfe,0x6c,0x37,0x4b,0x78,0x2c,0xa9,0x28,0x6a,0x5c,0xd6,0xe1,0x0b,0xad,0xae,0x62,0x7c,0x09,0xb8,0x90,0x3f,0x29,0x37,0x7b,0x79,0xee,0x55,0x02,0x05,0xef,0x28,0xa2,0xc7,0x07,0x2b,0xe6,0xab,0x87,0x9d,0x8f,0x4c,0x0f,0xc1,0x75,0x5d,0x88,0x7f,0x26,0xe0,0x1e,0xf8,0x3f,0xb5,0x2a,0x6c,0xe6 +.byte 0x7f,0x85,0xae,0x55,0x7b,0x58,0x34,0x4c,0x81,0x05,0x21,0xa1,0x5e,0xd7,0xb6,0x20,0x6e,0xf9,0x60,0x15,0xa4,0xb2,0x8f,0x68,0xd2,0x23,0x9f,0xbf,0xfa,0x6a,0xcb,0x87,0x7d,0x41,0x4a,0xae,0x28,0x4f,0x9e,0xbb,0x69,0x1c,0x37,0xb2,0xc9,0xd2,0x21,0xa1,0x2b,0x6b,0x5d,0xff,0xd6,0xdb,0x8f,0x21,0xd9,0x17,0xd6,0xe6,0x74,0xf2,0x20,0x0e +.byte 0x06,0xb5,0x0c,0xdc,0x74,0x4e,0x93,0xcb,0x27,0xc7,0x4b,0xf3,0xef,0x46,0xa8,0xf0,0x58,0x1c,0xa0,0x65,0x09,0x84,0xc7,0x2e,0xba,0x51,0xd9,0xd4,0x53,0x20,0xc7,0x20,0x85,0x93,0x2b,0xf3,0x42,0x93,0x7b,0x22,0x1c,0x8d,0x22,0x76,0xcf,0xde,0x6a,0xa1,0x76,0xea,0x65,0x20,0x2f,0x2e,0xdb,0x85,0xdd,0x73,0x43,0xf8,0xe0,0xe3,0x3a,0xe5 +.byte 0x02,0x57,0x96,0x54,0xbc,0xaf,0xa4,0xd5,0xda,0x9d,0x9d,0x8b,0x85,0x01,0x7c,0x72,0x03,0xfe,0x39,0x46,0xab,0x04,0xcc,0x62,0x71,0xf5,0xa5,0x67,0xd7,0xfc,0xc0,0xb6,0x95,0x74,0xdf,0x1c,0xfe,0x1c,0x5b,0x25,0xae,0x42,0x75,0x00,0x71,0x3c,0xec,0xfc,0x3c,0x7b,0x0f,0xec,0x44,0xc7,0xec,0x9b,0x86,0xf5,0x3d,0x47,0x15,0xf0,0x25,0xba +.byte 0x43,0xc8,0x68,0x15,0x4f,0xeb,0x35,0x76,0x2d,0x04,0xb7,0x9b,0xb8,0xa7,0x0d,0xb3,0xb4,0xf2,0x93,0x85,0xb1,0xb8,0x81,0x7c,0xd6,0x5f,0xbd,0xc2,0xcc,0xf4,0x0e,0x98,0x2c,0x06,0x54,0x2f,0x5e,0x49,0x94,0x93,0x78,0xa0,0x0a,0x33,0x2e,0x3f,0xb2,0xa7,0x81,0xed,0xe9,0xb6,0xb5,0x86,0x4b,0xa5,0xc0,0x51,0x30,0x9d,0xe2,0x9f,0xc2,0x56 +.byte 0x92,0x6b,0x96,0xca,0xcb,0x65,0x5c,0x0e,0xf4,0x91,0x2b,0x89,0xf4,0x27,0x55,0x26,0xd7,0x7b,0x00,0x19,0x1f,0x67,0x4e,0x43,0x24,0x81,0x05,0xb7,0xc6,0x41,0x1a,0x39,0x3d,0x40,0x3e,0x8a,0x03,0x94,0x63,0x1b,0xb1,0x87,0xb6,0xe1,0x52,0xd0,0xe8,0xbb,0x0e,0x37,0x72,0xe5,0xde,0x86,0xc0,0xdf,0x5b,0xc2,0xc6,0x0a,0x67,0xa7,0x4c,0x03 +.byte 0xb6,0xd8,0x7f,0x1d,0xb3,0xe3,0x84,0xb7,0x5c,0x04,0x15,0xe0,0xd0,0xae,0x44,0xac,0x39,0xa5,0xa2,0x86,0xc8,0xad,0x27,0xa0,0x36,0xa1,0x6e,0xaa,0x87,0x7a,0x43,0xae,0xa0,0x45,0x1a,0xac,0x04,0xe2,0x55,0xf2,0x9a,0x97,0x67,0xfb,0x01,0x8f,0xb8,0x80,0x9c,0x27,0x1d,0xbe,0xa3,0xf1,0x6d,0x66,0xf2,0x1a,0x99,0x99,0xf6,0xa5,0xba,0x58 +.byte 0x28,0x58,0xb5,0x44,0x5b,0x38,0x4a,0x3f,0x37,0x85,0x7e,0x36,0x8e,0x16,0xb9,0x1e,0x0b,0xbf,0x7d,0x0a,0x0c,0x83,0x53,0x0d,0xcc,0x37,0xe1,0x42,0xbb,0x0d,0xfc,0x01,0x25,0x10,0xbe,0xb5,0x83,0x2f,0xa5,0x42,0x98,0xbc,0xd6,0x50,0x75,0xda,0x32,0x2b,0x3f,0xd6,0xc1,0x1a,0xe7,0x0b,0x80,0x07,0x6f,0xfe,0x77,0x9e,0xe9,0x1e,0x45,0x65 +.byte 0x68,0x92,0x34,0x8b,0xce,0xf3,0xcd,0x94,0x17,0xe0,0x41,0x92,0x96,0xb5,0xd1,0x98,0xd1,0x25,0xd1,0x3d,0x76,0x88,0x86,0xb1,0x01,0x80,0xc7,0xde,0x60,0x20,0xb8,0x03,0xe7,0x3f,0x44,0x39,0xb1,0xb8,0x19,0x53,0x5a,0xc6,0xa0,0x18,0x8e,0x0e,0xb6,0xfd,0x7e,0xe7,0x7e,0x8a,0xeb,0x4c,0x35,0x4a,0x0f,0x52,0x81,0x68,0x12,0xe4,0x46,0x2e +.byte 0x20,0xb4,0x41,0x59,0xb3,0x16,0x02,0x9f,0xdb,0xe8,0xea,0xfd,0xe3,0x5d,0x14,0xd0,0x97,0x52,0x66,0xcb,0xb4,0x48,0xa3,0x05,0xab,0x73,0x8e,0x2c,0x46,0xc2,0x94,0xd5,0xc8,0x57,0xc4,0x13,0xa4,0x0b,0x7c,0x34,0xbf,0xb4,0x07,0x28,0x92,0xe2,0x1d,0x00,0xa6,0xf0,0xb0,0xbf,0xdd,0x5d,0x20,0x05,0x9f,0x53,0xcf,0x07,0xf7,0xe8,0x79,0x04 +.byte 0x57,0xd1,0xac,0x9c,0xdd,0xae,0xcd,0x8b,0x04,0x0a,0x2d,0x0a,0x0f,0x21,0x09,0xc8,0x0d,0xfa,0x23,0x26,0xe3,0xdb,0x84,0xc8,0x8e,0x9c,0x96,0x93,0x4f,0xcc,0x2f,0x96,0xed,0x04,0x91,0x0d,0xc7,0xbb,0x27,0xa3,0x6b,0x9d,0xe2,0x15,0x83,0x31,0x78,0xb5,0xb9,0x6d,0xb1,0x6c,0xa2,0x3e,0xf5,0x45,0x77,0xf4,0x96,0x3a,0xe6,0x10,0x08,0xfd +.byte 0x23,0xcc,0xda,0x27,0x73,0x67,0xbb,0x8b,0x59,0xe2,0xcf,0xda,0x57,0xf9,0x17,0xeb,0xeb,0x98,0x39,0x48,0xbf,0x3d,0x5b,0x7b,0xc2,0x11,0x4b,0xd6,0xb6,0x8a,0x14,0xb3,0xf5,0xc3,0x18,0xff,0xde,0x62,0x98,0x4a,0x1d,0x6b,0x4e,0x00,0x4f,0x7d,0x2f,0x67,0xf4,0x22,0x1e,0xdb,0x69,0xd5,0x87,0xfd,0xee,0x97,0x56,0xd4,0x00,0x0c,0x9e,0x22 +.byte 0x11,0xda,0x8e,0x3b,0x91,0xad,0xf1,0xb6,0x0a,0xba,0xe7,0xc6,0x14,0x0e,0xc4,0x85,0x5f,0x7d,0x69,0x7d,0x73,0x9c,0x83,0x6a,0x69,0xef,0x10,0xb0,0xe6,0x33,0x32,0x0f,0xd8,0x54,0xa4,0x9d,0x39,0xaf,0xfc,0x6d,0x4f,0xeb,0x34,0x89,0x2e,0xb0,0xa1,0xcd,0xe1,0x5b,0xab,0xe1,0xff,0x82,0x85,0x6b,0x5e,0xa9,0x9e,0x43,0x02,0x0d,0x38,0x33 +.byte 0xe1,0xbc,0xa4,0x77,0x8a,0x5e,0x54,0xa8,0xcf,0xc9,0x76,0xcb,0x73,0x21,0x1f,0xa7,0x1e,0x5c,0x0a,0xd6,0xa2,0x36,0x6f,0x07,0xa1,0x6b,0x0d,0x5a,0x21,0x3a,0xc3,0xc0,0xcd,0x9d,0xed,0x83,0x96,0x89,0xaa,0x55,0x56,0xfd,0x0a,0x97,0x3a,0x50,0xfd,0x95,0x3f,0xb7,0xfa,0x87,0x7d,0xa6,0x5d,0x12,0x65,0x3f,0x61,0x4f,0x86,0xdd,0x58,0x64 +.byte 0xd7,0xde,0xd6,0xb9,0x68,0x87,0xde,0xba,0x96,0xf5,0x1c,0xec,0x8e,0x81,0xfc,0xca,0x77,0xe2,0x85,0x11,0x93,0xc7,0xf2,0x0f,0x77,0xbb,0x7c,0xed,0x20,0x7a,0xe3,0xc5,0x76,0xff,0x04,0xc7,0xe6,0x7a,0xa1,0xfe,0x58,0x52,0x1b,0xec,0x27,0xbb,0xd4,0x27,0x7c,0xc7,0x4a,0xfb,0x07,0x62,0x99,0x36,0xff,0x6e,0x71,0x2f,0xbd,0x25,0xff,0x8d +.byte 0x97,0x14,0x56,0x23,0x7f,0x13,0x89,0x10,0xd8,0x29,0x1f,0x91,0x56,0x52,0x85,0xa7,0xd3,0x04,0xc9,0xe2,0x09,0xa2,0x0f,0xaa,0x28,0xb1,0x79,0xf9,0x08,0xf4,0x14,0x57,0xc4,0x54,0xd7,0x69,0xb0,0x37,0xf0,0x80,0x90,0xce,0x75,0x81,0xe7,0x75,0x0f,0x7f,0x71,0x58,0x3b,0x78,0x53,0x9b,0x4a,0x5e,0xcc,0x23,0x04,0x9e,0x0c,0xd7,0xd8,0x69 +.byte 0x90,0xdf,0x36,0x99,0x90,0xd3,0xfa,0x35,0xf7,0x13,0x64,0xb0,0xc0,0x70,0x0c,0xd4,0x87,0xc0,0xca,0xd8,0xca,0x8a,0xc3,0x9a,0xfa,0x73,0x34,0x18,0xe9,0x3a,0x85,0x42,0xc5,0xe1,0xaa,0xb5,0x87,0xac,0x43,0x9c,0xfa,0x7e,0x05,0x35,0xed,0x7e,0x0d,0x38,0x82,0x17,0x7f,0x22,0xa2,0x3d,0xd3,0x0d,0xd1,0xff,0x0a,0x68,0x52,0xd2,0x17,0x59 +.byte 0xaa,0x57,0xbd,0xd3,0xea,0x0c,0xe8,0xb0,0x22,0x13,0x59,0x42,0x46,0x34,0x58,0xa9,0x16,0xc5,0x9f,0x88,0x8f,0x75,0x02,0xbf,0x63,0xda,0x28,0xba,0x9a,0xcf,0xbb,0x73,0x58,0xb1,0x13,0xf2,0x68,0xd8,0x6b,0xfd,0x49,0x50,0xcf,0x09,0xea,0x6a,0xff,0x20,0x39,0xc5,0xae,0x70,0x79,0xea,0xec,0x9d,0x09,0xf8,0x51,0x1f,0xfd,0x01,0xd5,0x9f +.byte 0xec,0x29,0x36,0xfc,0x39,0xb4,0x4c,0x1f,0xe6,0xb4,0xcc,0x97,0x21,0xe5,0x19,0xe9,0x7a,0x60,0x6d,0x39,0x3c,0x31,0xd4,0x43,0x76,0xba,0x10,0xd9,0x3f,0x75,0x7a,0xa6,0x1d,0x02,0x88,0x3d,0xa5,0x9f,0x91,0x61,0x4e,0x32,0xec,0xf5,0xd3,0xe4,0x65,0xf7,0x0e,0x3b,0x8a,0x8f,0x22,0x31,0x71,0x8f,0xf1,0x5f,0x7b,0x04,0x88,0xf9,0x88,0x67 +.byte 0x14,0x85,0x74,0x9e,0x54,0x0b,0xed,0x7a,0x48,0xcd,0xcf,0xd2,0x05,0x38,0xd5,0x58,0xa2,0xaf,0x6a,0x28,0x21,0xfd,0x38,0x4e,0x83,0x06,0x15,0x60,0xfb,0x89,0x2a,0x72,0xfe,0x75,0xc7,0xa4,0xae,0xe4,0x5b,0xbb,0xde,0x54,0xde,0x77,0xbb,0x9d,0xd2,0x07,0x05,0x61,0x53,0x65,0x31,0xd4,0x3a,0x8a,0x7d,0x9d,0x30,0x09,0x25,0x28,0x72,0x19 +.byte 0xe4,0xae,0x1d,0xbf,0xa7,0xef,0x75,0xd0,0xe3,0xdc,0x0b,0xd1,0x17,0x9c,0xc6,0xdf,0x65,0x9a,0x7c,0x9d,0x0b,0x9a,0x3d,0x8f,0xb0,0xf5,0x51,0x46,0x6b,0x12,0x0d,0xe6,0xa9,0x3a,0xb5,0xe9,0x52,0x85,0xa5,0x25,0x1f,0xc9,0x8b,0xff,0xe3,0x37,0x25,0x97,0xd8,0x91,0x17,0xed,0xcf,0x2a,0x6d,0x4f,0xef,0x74,0x5e,0x92,0xa2,0x2d,0x84,0xa6 +.byte 0x09,0xc4,0xfc,0x36,0x95,0x54,0x25,0x9e,0xeb,0xd9,0xea,0x5a,0x01,0x0c,0x54,0xdb,0x82,0x01,0xed,0x0b,0xf7,0x9f,0x0d,0x8f,0x2e,0xee,0x7c,0x6e,0xb3,0xe7,0xe8,0x04,0xef,0x8d,0x5e,0xfe,0x3d,0x96,0x3a,0x65,0xd3,0xb2,0x11,0x75,0x1c,0x6f,0x2a,0xd3,0x26,0x1f,0x5f,0x35,0x02,0x0b,0x9f,0x38,0x5b,0xa5,0x3a,0x90,0x3e,0x03,0x9f,0x50 +.byte 0xf2,0xd7,0xe4,0x3c,0xd3,0x28,0x67,0x0a,0x5a,0xe8,0x59,0x6f,0x38,0x8f,0x8b,0x0d,0xe4,0x1c,0xfc,0x6e,0x07,0x69,0x7b,0xfb,0x04,0x30,0xe7,0xa6,0x13,0xfb,0x33,0xa0,0x52,0x6a,0xec,0x64,0xad,0x90,0xbd,0xba,0x15,0x12,0x48,0xed,0xd1,0x94,0x2d,0xe7,0x19,0x28,0x5e,0x7a,0x94,0xf4,0x79,0xd7,0x79,0xc9,0xf6,0x16,0xb4,0x88,0xee,0x15 +.byte 0xa2,0x68,0xe3,0x1d,0xd0,0xd2,0x63,0x78,0x7c,0xb3,0x30,0xac,0x63,0x7a,0x36,0xc5,0x50,0xbf,0x57,0xf6,0xfe,0x4e,0x43,0x4e,0xf9,0xc4,0xa2,0x2a,0xa7,0xa4,0x2c,0x18,0xb9,0x43,0x7b,0xe8,0xf6,0x14,0x4f,0x07,0x6e,0x65,0x9a,0xdd,0x10,0x2a,0x4c,0xa4,0x58,0x86,0x19,0xad,0x6d,0x5e,0x30,0xfb,0x5f,0xb6,0x9f,0x2a,0xac,0x90,0x0d,0xae +.byte 0xf9,0xab,0xc1,0x33,0xd3,0x73,0x1d,0x46,0xe5,0xc8,0x1e,0x1d,0x61,0xf1,0xda,0x53,0x3e,0x61,0xf0,0x9a,0xe4,0xb7,0x04,0xe9,0x5e,0xf6,0x11,0xa6,0x56,0x39,0xed,0xfb,0x06,0xd0,0x92,0xb9,0xb8,0xb5,0x3b,0x39,0xec,0xa5,0xc0,0xb1,0x7e,0x7e,0xfb,0x89,0x86,0xa8,0x70,0x47,0xa5,0x60,0x8c,0xf8,0x47,0x31,0x04,0x54,0x29,0xf3,0xa2,0x79 +.byte 0xac,0x24,0xda,0x33,0x6c,0x1c,0x34,0xc2,0xa0,0x96,0x27,0xbb,0x31,0xbf,0xc1,0xd9,0xc8,0x35,0xbc,0xb3,0x13,0x8a,0xb6,0x25,0x92,0xdc,0xcc,0x3b,0x8a,0x65,0xf3,0xf9,0xd1,0x2a,0xcd,0xb0,0xf4,0xd7,0x44,0xa0,0x27,0xfc,0x0e,0x69,0x46,0x0b,0x56,0x5b,0x58,0x40,0xd9,0xc4,0x37,0x9b,0x4d,0xa1,0x45,0xd8,0xab,0x4d,0x02,0x31,0x4f,0x93 +.byte 0x56,0xd0,0x26,0x99,0x1c,0xc7,0x2b,0xc2,0x80,0xb4,0xbd,0x6e,0xfe,0xa1,0xf7,0x8f,0x13,0x74,0x2c,0xa8,0x63,0xb1,0x3d,0x6d,0x32,0x4a,0x80,0x6a,0x7f,0xcf,0x6c,0x51,0xa9,0x21,0x34,0x4e,0x13,0x19,0x8f,0x33,0xfc,0x06,0x46,0x05,0xf0,0xcf,0xf1,0xce,0x20,0xe0,0x40,0xf2,0x0a,0xd0,0xf6,0xcc,0xcc,0xc2,0xc7,0x07,0x2e,0x9e,0x0a,0x1e +.byte 0x53,0x59,0xbb,0xe3,0x02,0xc8,0x20,0x9f,0x3c,0xe6,0xec,0xf7,0x8a,0x6d,0x3c,0x0f,0xb3,0x14,0x66,0x5c,0x51,0xbe,0x82,0xc2,0x0b,0x10,0x63,0xa9,0xd4,0x7f,0x12,0x88,0x13,0x81,0x8a,0x06,0x8a,0x7f,0xc8,0x89,0xe7,0xbd,0xce,0x51,0xdc,0x93,0x03,0x07,0x6f,0x8c,0xe6,0xcc,0x0d,0x45,0xa8,0xfc,0x02,0xe2,0x3e,0xa7,0xc8,0x83,0x77,0x98 +.byte 0x91,0x4e,0x1f,0x8d,0xed,0xa5,0x38,0x54,0x0e,0x4e,0x53,0x1c,0x0c,0x47,0x11,0x59,0x54,0x15,0xb5,0x47,0xb0,0x21,0xa1,0x3d,0xaa,0xef,0xee,0x9e,0x26,0x3c,0x39,0x75,0xff,0x1a,0x8c,0xbb,0x1a,0x49,0x62,0x21,0x76,0xe8,0x3d,0x10,0x55,0xf5,0x5a,0x44,0xf0,0xb3,0x81,0xd0,0x35,0x96,0x95,0x63,0xf7,0x50,0xb1,0xa0,0xf0,0x29,0x97,0xc9 +.byte 0x27,0x73,0xd8,0x29,0xef,0x74,0xd2,0x6d,0xf4,0xfb,0x72,0xa9,0x4f,0x12,0xd5,0xfd,0xc9,0xba,0xf0,0xbd,0xfd,0x5e,0x5c,0xfa,0x53,0xe3,0x96,0xab,0x57,0xc3,0xb6,0xe8,0x0e,0x43,0xe4,0x77,0x97,0x04,0x69,0xff,0x72,0xd0,0xd8,0xab,0xb9,0x19,0x25,0x89,0xf7,0xbb,0x01,0x03,0xf2,0xc6,0x8d,0xd5,0x86,0xe3,0xfe,0x9c,0xff,0x78,0xd7,0xfc +.byte 0xda,0xd4,0x69,0x8e,0xd6,0x31,0xfb,0x15,0xd3,0x38,0xfd,0x53,0xe2,0x4e,0xce,0xcc,0xfe,0x17,0xc5,0x88,0x92,0x28,0x98,0xb7,0xcf,0x7b,0x53,0x7b,0x96,0x14,0xaf,0xeb,0x5b,0x2d,0x16,0x41,0xcc,0x7b,0x65,0xe1,0x73,0x81,0x4e,0x8f,0xc3,0xad,0xe1,0x3f,0x0c,0xa7,0xbe,0x38,0xed,0x02,0x67,0xf5,0xfa,0x1d,0xb0,0xd5,0x4c,0xe1,0xd8,0x62 +.byte 0xc9,0xb5,0xf8,0x84,0xc4,0x51,0x57,0x14,0x11,0xf8,0x7d,0x1d,0xe7,0x81,0x85,0x61,0xa9,0x9f,0xc8,0x45,0xb9,0x2d,0x8a,0xc9,0xa3,0xfe,0x5a,0xf9,0xe0,0x1c,0x80,0xd8,0x77,0xaa,0x85,0xca,0x93,0x9a,0x2e,0x10,0x03,0x71,0x3d,0xb1,0x2a,0x64,0x2e,0xad,0x64,0xba,0x5c,0xaa,0x8a,0xc2,0x2a,0x80,0x28,0x2e,0xf9,0x93,0xe1,0x71,0x72,0xae +.byte 0xda,0xd8,0x4f,0x4c,0xec,0xb5,0xe3,0x05,0x10,0x5f,0x4c,0xe6,0xe1,0xf4,0x07,0x63,0x75,0x6f,0xc5,0xf9,0xcd,0xfc,0xfc,0x35,0x2f,0xe4,0xca,0x4b,0xfc,0xc3,0x20,0x8b,0x5c,0x4a,0x3c,0xf8,0x92,0xca,0x2b,0xb0,0xce,0xd9,0x4b,0xf0,0x44,0xcb,0x4e,0x83,0xf3,0x9d,0xb0,0xd4,0xab,0xba,0x2a,0x76,0xaa,0x87,0xcd,0xa2,0xd1,0x3f,0xa0,0xb9 +.byte 0xdb,0x7e,0x67,0x2d,0x92,0x4c,0xeb,0x3c,0xa6,0x8c,0x62,0x80,0x18,0x78,0x2b,0x9d,0x8f,0x5e,0xc3,0xa5,0x3b,0x10,0xb3,0x8a,0x3b,0x00,0x96,0xb2,0xab,0xce,0x8d,0xff,0x3c,0xee,0xeb,0x4f,0xfb,0xab,0x96,0x38,0x4c,0x15,0x6e,0x7c,0xf3,0x31,0x5f,0x8f,0x99,0x88,0x52,0x48,0x8b,0x71,0x1b,0x31,0x3f,0x7c,0xe4,0xae,0x9c,0x7b,0xeb,0x64 +.byte 0xe3,0x80,0xd4,0x56,0x9a,0x6a,0xd9,0xca,0xc5,0xf0,0x86,0xe7,0xda,0x80,0x8f,0x17,0x61,0xca,0x24,0x0b,0xb6,0xf9,0x24,0xc5,0x7a,0x28,0x42,0x32,0x7f,0x2b,0xde,0x44,0x30,0xed,0x69,0x63,0x07,0x3f,0xca,0x7b,0x02,0xea,0x6e,0xef,0x27,0x1d,0x76,0x32,0xc2,0x81,0x3d,0x03,0x9a,0xe7,0x0d,0x28,0x07,0x03,0x0c,0x65,0x73,0x58,0x26,0xc6 +.byte 0xfe,0xcc,0x33,0x7f,0x33,0xad,0xea,0x81,0x05,0xcc,0x61,0x1e,0x78,0x69,0x70,0xc9,0x1f,0x6e,0x4f,0xb8,0x19,0x42,0x03,0x03,0x9d,0x56,0x87,0x0e,0x9a,0x32,0x3a,0xba,0xb9,0x11,0x66,0x9f,0x4d,0xd1,0xb0,0x11,0xbf,0x46,0xfc,0xcf,0xe5,0xef,0xf1,0x61,0xeb,0xad,0x31,0x7c,0x0d,0x66,0x0d,0xa9,0x1f,0xe4,0xf9,0x80,0x9e,0xae,0x9e,0x34 +.byte 0x1e,0x95,0x6c,0xa2,0x77,0x69,0x84,0x77,0xb7,0xe8,0xca,0x1f,0xea,0xc1,0x34,0xe6,0x0d,0x4f,0xba,0x77,0x2b,0x8c,0xbe,0xff,0xc4,0x06,0xa3,0xb6,0x1a,0xbe,0x55,0x99,0x57,0x6f,0x54,0x24,0x93,0x7a,0x0d,0x52,0xd6,0xbb,0xd2,0x9c,0xd5,0x76,0x6a,0x22,0x66,0xdc,0x43,0x9a,0x7b,0x1b,0x11,0x80,0x02,0x0c,0x8f,0xc6,0xc6,0x02,0x42,0x29 +.byte 0x00,0xc4,0xb2,0xa1,0x6a,0x7f,0xa9,0x60,0x8d,0x41,0x4f,0xd3,0xde,0x33,0x5a,0x44,0x31,0xb0,0xdc,0xc0,0x0c,0x31,0x03,0x96,0x71,0x0a,0xce,0xe3,0x0b,0xc7,0xe3,0x5d,0xe0,0x88,0x4b,0xfd,0x4c,0x1a,0xce,0xaa,0x89,0xc6,0x99,0xa8,0xd3,0x1e,0xe9,0x6c,0x2a,0xbd,0x26,0x81,0x03,0x6a,0xf2,0xf2,0x0f,0x1e,0x9d,0x8a,0x59,0x45,0xbf,0x6d +.byte 0xb7,0xc8,0xec,0x77,0xb0,0x70,0x1a,0x31,0x21,0xeb,0x25,0x12,0xff,0x13,0x33,0x6b,0x47,0x34,0xd8,0x66,0x11,0x8a,0xc9,0x93,0x5b,0x2c,0x55,0x42,0xb2,0x9b,0x60,0xc6,0xba,0xab,0x12,0x12,0x5d,0x0a,0xd4,0x54,0x79,0x17,0x6d,0x31,0x7d,0x4f,0xf2,0x94,0x16,0x65,0x62,0x38,0x76,0x3a,0x7d,0x55,0x05,0xd9,0x17,0x45,0x62,0xb4,0x1d,0x31 +.byte 0x34,0x40,0xd3,0x8e,0xf9,0x29,0x4d,0x3f,0x93,0x9a,0x2e,0xa4,0x75,0x66,0xf6,0x62,0x8f,0xf9,0x8d,0x79,0x4b,0x51,0x7e,0xfb,0xeb,0x9a,0x86,0x96,0x01,0x79,0xbe,0xe4,0x42,0xb3,0xc8,0x28,0x9e,0xed,0xa8,0xb6,0x6d,0xd3,0x31,0xed,0x30,0x9e,0x6a,0x5b,0x02,0x4b,0xbd,0xb3,0xf2,0xf0,0x9d,0x50,0x09,0x40,0x71,0xfe,0x4b,0x91,0xc9,0xd6 +.byte 0x07,0x87,0x9e,0xdb,0xa9,0xcd,0x0b,0x95,0x18,0x5a,0x55,0x10,0xaa,0xe1,0x70,0xe9,0x2e,0xc2,0x31,0x6b,0x48,0x84,0x2f,0xe5,0x7b,0xdd,0x4c,0x03,0xed,0xb6,0xb6,0x64,0x24,0x38,0x7a,0x5a,0x15,0x35,0x9d,0x66,0x08,0x4d,0xa6,0x3c,0x96,0x1a,0xcd,0x02,0x61,0x40,0xde,0xac,0xc3,0x15,0x8c,0xca,0xe6,0x62,0xe9,0x61,0x68,0xf6,0x60,0xd3 +.byte 0x7e,0x5f,0x44,0xcf,0x09,0x01,0x60,0xc2,0xb1,0xfc,0x2f,0x41,0x4c,0xc1,0x06,0x72,0xcc,0xde,0x25,0xe0,0x8c,0x34,0xb8,0xe0,0xb2,0xeb,0x05,0x5d,0x9e,0x7e,0xf7,0x1e,0x24,0xcd,0x1b,0x14,0x3f,0x1b,0x13,0xc0,0x64,0x38,0x43,0x95,0xba,0x7b,0x61,0xa0,0xdc,0xe0,0xf5,0x80,0x13,0xa1,0xc5,0x48,0x92,0xc5,0xd5,0xd0,0x87,0x0c,0x73,0xae +.byte 0xe2,0xb3,0xe8,0x70,0x4a,0x7e,0xa0,0x13,0xc3,0xc6,0x9c,0x77,0x51,0xca,0x88,0xcf,0xe0,0x1e,0xff,0x6c,0xe2,0xc3,0x33,0xce,0x7f,0x3e,0x7d,0xd5,0x37,0x23,0x09,0xb7,0xbd,0xb7,0xec,0x9a,0x29,0xd6,0x4f,0xea,0x79,0x24,0x4c,0x09,0x74,0x9c,0x97,0x3b,0x08,0x1f,0x82,0xcc,0xae,0xc4,0x3f,0xcf,0xc6,0xcb,0xaf,0x8c,0x89,0x15,0x79,0xeb +.byte 0x88,0xb9,0x03,0xab,0xc6,0xf8,0x6e,0x54,0xde,0x50,0x6e,0xcf,0x8a,0x4b,0x3f,0x64,0xd0,0xcb,0x69,0xc2,0xe3,0x40,0x4a,0x94,0xe2,0x04,0xfa,0x9b,0x4a,0xf6,0x2b,0x93,0x0c,0x0e,0xf8,0x68,0xbc,0x6e,0x6c,0xe6,0xd9,0xb6,0x04,0x40,0xf4,0x60,0xbc,0xc1,0x1e,0x67,0x1f,0xce,0x5c,0x4d,0xba,0x78,0xa8,0xf5,0x96,0x00,0xb9,0x61,0x82,0x65 +.byte 0xb2,0x1d,0x42,0xb8,0x88,0x66,0x43,0xd9,0xfe,0xe0,0x86,0xef,0x5d,0x4d,0xcc,0xeb,0x57,0x9a,0x2b,0x27,0xf2,0xcf,0x68,0xc3,0x05,0x92,0x4d,0x4d,0xb7,0x46,0x7e,0xfd,0xb7,0x4a,0x4d,0x6f,0xac,0xc8,0x8d,0xf2,0xcd,0x52,0xcf,0x91,0x77,0x2d,0x68,0x06,0x7a,0xc9,0xf3,0x17,0xc6,0x8f,0x8f,0xb5,0x8f,0x74,0xfa,0x90,0xcc,0xfc,0xaf,0x4e +.byte 0xd2,0x29,0xd9,0x57,0x71,0xe9,0x52,0xd8,0x50,0xfa,0x4d,0x13,0x7c,0x42,0x15,0x22,0x65,0x26,0x08,0xda,0xaa,0x53,0xcf,0xeb,0xd1,0x87,0xd5,0x7c,0x4e,0x66,0x1c,0x7d,0xc9,0x03,0x59,0xf8,0x09,0x3e,0x1b,0x94,0x4c,0x39,0x56,0xeb,0xfd,0xb6,0xd0,0xf9,0x76,0x8b,0x5d,0x6e,0x44,0x15,0xcf,0x27,0x7f,0x69,0x9a,0x00,0x96,0xbe,0x80,0x5e +.byte 0xbb,0x5a,0x05,0xea,0x15,0xdd,0x44,0x69,0x9e,0x64,0xcd,0xba,0xf2,0x6f,0x67,0x10,0xc5,0xa1,0x75,0x85,0x5f,0xdc,0x61,0x43,0x34,0xc3,0x52,0x06,0xd4,0xe9,0x9f,0xdf,0xd4,0xa6,0x96,0xac,0xb1,0x21,0xdd,0x20,0x46,0x20,0x89,0x5f,0x0e,0x9d,0xa8,0xc7,0x75,0x3a,0x54,0x9e,0x7c,0x3a,0xd5,0xb2,0x68,0x77,0x06,0x1b,0x1c,0xbd,0xb3,0x02 +.byte 0xb5,0xdd,0x87,0x55,0x6b,0x00,0x9f,0x2c,0x30,0xb7,0x4e,0xc3,0x67,0x38,0x37,0x61,0x81,0x68,0xcb,0x14,0x81,0x27,0xd7,0x38,0x18,0x81,0x68,0x45,0xca,0xf4,0xaa,0xae,0x58,0x9e,0xf8,0xbe,0xe9,0x1e,0x05,0x19,0xf0,0xea,0x89,0xf8,0xa1,0x9c,0x7b,0x63,0xc1,0xcd,0x81,0xc8,0x95,0x56,0x81,0x81,0x29,0xb0,0x4d,0xbf,0xe6,0x8d,0xa3,0xb3 +.byte 0xfa,0xae,0x13,0xc8,0xca,0x4d,0x5c,0x5e,0xd9,0x17,0xf8,0x87,0xdb,0x5b,0xe2,0xd9,0xba,0xe3,0xe8,0xdb,0xcb,0x74,0x36,0x7e,0x0e,0x3a,0x94,0x6a,0xe9,0x9e,0x50,0x8e,0xf4,0xd4,0x15,0xb7,0x50,0x60,0x3f,0x14,0x72,0x41,0x9d,0x51,0x63,0x8c,0x31,0x95,0xf2,0xbc,0x14,0xc7,0x64,0x2c,0xee,0x0b,0xe6,0xde,0xf6,0x33,0x85,0x65,0x00,0x54 +.byte 0x54,0x84,0x85,0x94,0x87,0xa0,0xc3,0x95,0x4e,0x74,0xcb,0x2d,0x82,0x9e,0x46,0x7f,0xf5,0x64,0x60,0xfe,0x1a,0x37,0xee,0xa7,0xb6,0x85,0xb5,0x4e,0x30,0x11,0x39,0x4b,0xe9,0x57,0x18,0x3a,0x2c,0x6b,0xb9,0x8e,0x5a,0x54,0xa9,0x31,0xf7,0xe1,0xe0,0xc7,0x52,0xfe,0x76,0x9b,0xc6,0xfe,0xde,0xe0,0xe9,0xf9,0xf6,0x10,0xda,0xef,0x72,0x24 +.byte 0x9c,0xbe,0x4a,0xba,0x58,0x21,0x1b,0xe3,0x1d,0x80,0x10,0x76,0x70,0xde,0x8f,0xf3,0x07,0x93,0x01,0xe0,0xb4,0xd9,0x7d,0x60,0x0d,0x08,0x07,0xa4,0x6d,0x9b,0x2b,0x8c,0x9a,0x58,0x65,0x5e,0x29,0xf1,0x24,0xb2,0x31,0xfb,0xb7,0xad,0xf0,0x50,0x8e,0x25,0x1b,0x75,0xc5,0x82,0x88,0x8c,0x68,0x14,0x2c,0x28,0xa2,0xb6,0x93,0x14,0xe3,0x28 +.byte 0xd0,0x95,0x6f,0x79,0x91,0x03,0x75,0x82,0x5c,0x20,0x46,0x0d,0x53,0x40,0x2c,0x88,0x62,0xa4,0x8c,0xd5,0xf1,0xc1,0xbf,0xde,0x57,0x91,0xb2,0xa6,0x66,0x29,0xf0,0x6b,0xb8,0x5e,0x78,0x5f,0xd1,0x76,0x98,0xf2,0x56,0xc2,0x5f,0x48,0x1f,0xa6,0x98,0xb0,0x87,0x53,0x13,0x1d,0x1a,0xa7,0xdf,0xa5,0xea,0x37,0x12,0x6d,0x64,0x53,0xdc,0x04 +.byte 0x2d,0xb9,0xeb,0x78,0x89,0x7b,0x70,0xd2,0x6d,0x45,0x8d,0x45,0x50,0x57,0xc7,0xb2,0xaf,0xdd,0x72,0x0f,0x9f,0x1b,0x29,0x61,0x68,0xb5,0x4a,0xd4,0xe9,0xd7,0x10,0xe7,0xcd,0xe8,0x22,0xd3,0x54,0x0c,0x0b,0x32,0x77,0x7d,0x3e,0xed,0x6e,0x79,0x4b,0x7b,0x99,0x1f,0x9e,0xbe,0xe7,0x12,0x7c,0x94,0x36,0x1c,0x20,0x8a,0xd0,0xab,0xda,0x95 +.byte 0xf6,0x4f,0xbe,0x6f,0x44,0x0b,0xa3,0x7b,0x4d,0x00,0xf6,0xdf,0x6f,0xc8,0x50,0x9e,0x3e,0x0c,0x1e,0xfe,0xb8,0x39,0x9f,0x83,0x4f,0xb3,0x1f,0x7e,0x53,0x54,0x64,0x04,0xa3,0xf7,0x79,0x01,0x71,0xce,0x18,0x0d,0x47,0x4e,0xae,0x88,0x6a,0xe7,0x26,0x4e,0x59,0xee,0x3a,0x03,0xc2,0x4d,0x0c,0x29,0xf0,0x96,0x9d,0xc0,0xa3,0xb3,0x82,0xf9 +.byte 0xc4,0xf8,0x8b,0xae,0x68,0x47,0x39,0xdc,0x10,0xd7,0x09,0xb4,0x86,0x87,0xfa,0x7e,0x0c,0xe4,0xee,0x3a,0x35,0x1a,0x0e,0x95,0x88,0xce,0xe7,0x9e,0xcc,0xa5,0x58,0x98,0x48,0xbd,0x9c,0x27,0xe6,0xb9,0xf7,0xca,0x66,0xee,0x54,0x87,0xd0,0x6d,0xab,0x31,0x1a,0x57,0x33,0x8b,0x89,0xa0,0xc0,0x18,0x9a,0x87,0x5e,0x58,0x02,0xe5,0x50,0x47 +.byte 0x0f,0x60,0x53,0x9d,0x99,0xe4,0x0a,0xfa,0x4a,0xc3,0x77,0x4b,0x4d,0x4e,0x0c,0xbb,0x68,0xd9,0xb3,0xd3,0x59,0x78,0xdf,0x65,0x97,0x6e,0x22,0x5b,0x24,0x26,0xf9,0x2a,0x14,0x73,0xa7,0xec,0x65,0xfc,0xdf,0x7d,0x35,0x0d,0x44,0x1b,0x4b,0xad,0x6b,0x8f,0x0e,0xa3,0x3b,0x6b,0x40,0xb3,0xe3,0xd9,0x41,0xba,0xbf,0x95,0xbb,0x6e,0x91,0xf6 +.byte 0x63,0xb3,0xde,0xdb,0xc2,0x6f,0xfe,0x00,0xf1,0x53,0x96,0x37,0xa4,0x27,0x48,0x3e,0xf9,0x32,0x23,0x90,0x90,0xe0,0x01,0xde,0x08,0xad,0xc4,0x6c,0x25,0x7a,0x7f,0x2f,0xb7,0xb7,0xc6,0xaf,0xeb,0x91,0x9c,0xa2,0x9c,0xf7,0x7f,0x9f,0x74,0x9b,0x7d,0x54,0x66,0xf9,0xe0,0x73,0xb4,0x15,0x2b,0xaa,0x71,0x50,0xd0,0x74,0x5d,0xcd,0x1c,0x09 +.byte 0x4c,0x80,0xcc,0xdc,0x10,0xd9,0x96,0xb3,0xdc,0x09,0x73,0x1f,0x36,0x4c,0x1b,0x86,0x25,0x13,0x7c,0xd2,0xc6,0x9d,0x5a,0xce,0xd6,0x22,0x97,0x66,0x7b,0x7b,0x84,0xba,0x69,0xd2,0x87,0x9b,0x08,0xda,0x77,0x66,0x90,0xbc,0x7c,0x3c,0x5d,0x43,0x92,0x5f,0x05,0xfb,0x23,0x46,0x88,0xf7,0xa4,0x10,0xbd,0x7d,0x00,0x29,0x2d,0xa5,0x6a,0xab +.byte 0xcc,0xdd,0xcf,0x1e,0x2b,0x9b,0x5f,0xa9,0x94,0x14,0x99,0x6e,0x3b,0x41,0x52,0x61,0x16,0x17,0x44,0xcf,0x5b,0x34,0x5c,0x27,0x29,0x4a,0xc3,0xba,0x9a,0x0c,0x20,0x17,0x2b,0x92,0xd9,0xf1,0x76,0x51,0xd8,0xa5,0x4a,0x4b,0x4a,0x0b,0xe4,0x6b,0x93,0x61,0xc7,0xb3,0x23,0x7a,0x24,0xfa,0x5e,0xee,0x80,0x10,0x65,0x44,0xa5,0xed,0x72,0xd9 +.byte 0x8a,0x06,0x2a,0x86,0xa9,0x26,0x50,0xa1,0xb2,0xb2,0x8b,0x7b,0x4a,0x29,0xf1,0x18,0xef,0xff,0x61,0xf1,0xa1,0x48,0x0f,0x84,0x8c,0xef,0xd8,0x02,0x65,0x44,0x11,0xf2,0xe1,0xba,0x98,0x03,0xbe,0x5a,0x5d,0xb8,0x0a,0x88,0xd8,0x4a,0x49,0x4c,0x70,0xa6,0x98,0x81,0x36,0x56,0x92,0xde,0xcb,0xaf,0x33,0xf5,0x1c,0x0a,0xce,0x7a,0xc0,0xff +.byte 0x24,0x54,0xd3,0x9a,0x0f,0x82,0x76,0xe5,0x0e,0x82,0xb4,0xfe,0xc2,0xac,0xe4,0xba,0xa3,0x4c,0x8a,0x0d,0xa7,0x3e,0x2b,0x71,0x73,0x5f,0xd2,0x35,0xd3,0xae,0xc0,0x3e,0x6f,0x67,0x98,0x51,0xa6,0xdf,0xb2,0xf4,0xd2,0xc1,0x43,0xe2,0x0a,0x7c,0xa0,0xb6,0xff,0xfc,0xc0,0x88,0xe5,0x34,0x20,0x79,0x50,0xc3,0x06,0x5b,0x20,0x9f,0x05,0x33 +.byte 0x22,0x30,0xaf,0xc4,0xc3,0x17,0x09,0xbb,0x30,0x0f,0x42,0xb7,0xc1,0xe0,0x4c,0x71,0xc5,0xf7,0x96,0xb4,0xd4,0x0f,0x44,0x47,0xa3,0x06,0x17,0xbd,0x0f,0x7c,0xc6,0x53,0x07,0x34,0x9a,0x9a,0x2f,0x3f,0x01,0xea,0xdf,0x1c,0x06,0x33,0x15,0x9c,0x5a,0xe3,0x33,0x29,0xce,0x40,0x4b,0xb1,0x99,0xe0,0x80,0x6e,0x0c,0xa1,0x4c,0x34,0x01,0x21 +.byte 0x12,0xbe,0x67,0x26,0xe6,0xdb,0xab,0x8d,0x45,0xdd,0x12,0x60,0x02,0x1a,0xdd,0x85,0xd6,0x33,0x78,0x23,0xe1,0x58,0x2a,0x46,0xf0,0xc2,0x4d,0x71,0x59,0x5b,0x8d,0x65,0xa7,0x97,0xf4,0x71,0x88,0x7d,0x60,0xe0,0x2d,0x2d,0x09,0x2f,0x26,0x15,0xa7,0xbf,0x30,0x0b,0x99,0x08,0xd7,0x85,0xfc,0x0c,0x19,0x31,0xde,0x5e,0x55,0x91,0x13,0x45 +.byte 0x3a,0x6d,0xd0,0x61,0x02,0x81,0xa0,0x42,0x7d,0xd8,0x7d,0x41,0x11,0xd2,0x25,0xb7,0x15,0xa1,0x16,0x3e,0x70,0x77,0x1b,0x80,0xb7,0xf1,0x24,0x8e,0x70,0x8d,0x73,0x6d,0xba,0xf1,0x46,0x32,0x60,0xe4,0xc8,0x4d,0x69,0xc8,0x10,0xf8,0x2d,0x53,0xe1,0x81,0x96,0x20,0x9d,0x59,0x74,0xae,0x93,0x92,0x44,0x5a,0x09,0x79,0x20,0xcb,0xff,0xb2 +.byte 0x08,0x7a,0x81,0xee,0x98,0x83,0x0b,0xa4,0x15,0xb0,0xaa,0x55,0xb0,0xb5,0x60,0x09,0x21,0xeb,0xe2,0x9b,0x57,0x41,0xb9,0xb4,0xd9,0xbe,0x7d,0x60,0x5d,0x25,0xde,0x9f,0x9e,0x5b,0x7c,0xee,0xeb,0x87,0x54,0x6a,0xc3,0xcf,0xec,0x57,0xce,0x97,0x2e,0x47,0x84,0x4c,0x15,0xf4,0xf5,0xe9,0xd4,0x45,0x23,0x20,0xf0,0x0f,0xda,0x97,0xc2,0xb9 +.byte 0xb2,0xe2,0x44,0xea,0xbd,0x95,0x73,0xcc,0x94,0x03,0x0b,0x97,0xeb,0x03,0xc1,0x51,0xc8,0x14,0xa6,0x7d,0x18,0x30,0xa1,0xda,0xa3,0xcd,0x78,0x67,0xb0,0xc1,0x6c,0x88,0xdd,0xd6,0x52,0x4b,0x85,0x1d,0x4a,0xaa,0x44,0xec,0x3b,0xff,0x00,0xd8,0x9e,0x18,0xf8,0xac,0x4f,0x73,0x6d,0xc7,0x4b,0x59,0x15,0x85,0x87,0x02,0xd8,0xf1,0xe6,0xfb +.byte 0x66,0x57,0xcf,0x06,0x84,0x50,0xc5,0x67,0x94,0xc6,0x96,0xb2,0x1a,0x37,0x06,0x3d,0x21,0xf2,0x1e,0xb4,0xe7,0xcb,0x36,0x8b,0xa3,0xe3,0x84,0xa0,0x9a,0x31,0xdb,0x87,0xf9,0xb0,0xef,0x06,0xfe,0xb0,0x8a,0x32,0x53,0xb4,0x41,0x79,0x6b,0xf7,0x7c,0xf7,0x9c,0xc1,0xea,0x61,0xf3,0x75,0xac,0x1f,0x92,0x75,0x44,0x58,0x9a,0x20,0xa4,0x20 +.byte 0xe3,0x19,0x1c,0x0d,0x27,0xe5,0x2e,0xbd,0x14,0xcb,0x40,0x3f,0x1c,0x19,0x7c,0xf9,0x92,0x13,0x1a,0x71,0x87,0xaf,0x77,0x0f,0x50,0x92,0x06,0x75,0x2d,0x75,0xe0,0x2e,0x37,0x54,0xcd,0xac,0xcb,0xca,0x7c,0x0e,0x66,0x53,0x10,0x50,0x70,0x9a,0xa4,0x79,0x76,0x87,0x71,0x4a,0x55,0xd4,0xa3,0x83,0xb3,0x04,0xed,0xa9,0xd6,0x84,0x7d,0x1a +.byte 0x64,0x5d,0xf7,0x4f,0x55,0x97,0x5e,0x26,0x9c,0x03,0x42,0x0a,0x16,0xd3,0xdf,0xc8,0x07,0xb8,0xb3,0xe9,0xac,0xa9,0x99,0x83,0x32,0x5b,0x83,0xde,0x7f,0x2b,0x70,0xca,0x15,0x09,0x33,0x0e,0x28,0xc9,0x89,0xc6,0xa6,0x47,0xd1,0x56,0x04,0x40,0x5d,0xd2,0x17,0x1d,0x32,0x21,0x6d,0xb2,0xc7,0x89,0x14,0x98,0xc6,0x58,0xc4,0xca,0xda,0x0f +.byte 0x32,0xdd,0xe1,0xe1,0x9a,0x25,0x09,0x31,0x16,0xf1,0x48,0x40,0x1c,0xc2,0xf9,0xd0,0xba,0xec,0x07,0x94,0xea,0x17,0xcf,0x6e,0xbc,0xfd,0x70,0xb4,0xbb,0x40,0xae,0xc3,0xae,0xf7,0x56,0xf5,0x13,0x55,0xfb,0x4b,0x81,0x5d,0xab,0xf2,0x3f,0xd7,0xa7,0xe6,0xcf,0x17,0xef,0x1f,0x71,0x1b,0x92,0x67,0xd3,0xd2,0xed,0x89,0x14,0x8f,0x8d,0x83 +.byte 0xef,0x7f,0xca,0x65,0x6d,0x79,0x13,0x5f,0x6e,0xf9,0x5d,0x9a,0x68,0x54,0x71,0x5c,0x9d,0x03,0x7c,0x73,0x7a,0xc2,0x17,0x9b,0x5a,0x7d,0x45,0x24,0x0c,0x41,0x13,0xe4,0xcb,0xdb,0x7b,0xc6,0xfb,0x93,0x48,0xca,0xd3,0x01,0x68,0x3f,0x36,0xc0,0x4b,0x1d,0xfa,0x9f,0x25,0x0e,0xcc,0xd0,0xf7,0xa0,0x7a,0x14,0xac,0xd7,0x6e,0x00,0x9f,0xf1 +.byte 0xc0,0xdc,0xfc,0x3b,0xd9,0xbf,0x68,0xfd,0x65,0x34,0x66,0x18,0xe5,0x02,0x9a,0x2d,0xff,0xaa,0xf7,0x73,0x58,0x21,0xe3,0xff,0x23,0x0f,0x63,0x1f,0xf3,0x8b,0x08,0xc7,0x00,0x46,0xe7,0xef,0x85,0x5f,0x7f,0xd9,0x5f,0xc2,0x36,0xe2,0xb6,0xa3,0x00,0xcb,0xff,0xe0,0x22,0x28,0x8c,0xb1,0xb1,0x17,0x91,0x4a,0x4a,0xc8,0x77,0x5a,0xa9,0xb2 +.byte 0x6e,0xb7,0xf0,0x4f,0x70,0x34,0x7f,0x87,0x2a,0x0c,0xcb,0x16,0x24,0x9b,0x41,0xb2,0x3e,0x0a,0xc1,0x33,0xf3,0xbb,0x48,0x17,0x2f,0xe6,0xfc,0xf4,0x27,0xc0,0xdb,0x58,0x24,0x9b,0x99,0x43,0x25,0xfb,0xd3,0xcf,0x1c,0x5a,0x5f,0xbe,0x28,0x3a,0x84,0x51,0x19,0xc3,0x53,0x6b,0xc8,0x73,0x44,0x6e,0x3d,0x7e,0x01,0x37,0xc2,0x2b,0xf7,0xa8 +.byte 0x1f,0x8e,0xd8,0x02,0x5a,0xae,0x56,0x81,0x2b,0x46,0x1b,0x7d,0xca,0x27,0x1f,0x48,0x99,0x24,0x54,0x59,0x08,0xfd,0xb7,0xdf,0x0a,0x77,0xef,0x4e,0x89,0x21,0x71,0x71,0x3f,0x8c,0xd7,0x52,0x89,0x7a,0x0d,0x68,0x09,0xc8,0x88,0x9c,0x0c,0x60,0xca,0x77,0x96,0xeb,0x05,0xeb,0xeb,0x60,0x5b,0x68,0x51,0x2c,0xcb,0x8f,0xca,0x3b,0x18,0x39 +.byte 0x28,0x8f,0xda,0x17,0x9b,0x53,0x71,0x26,0xa9,0x19,0xfb,0x1e,0x4a,0xd0,0x14,0x93,0x1c,0xee,0xe1,0x21,0xea,0xb3,0x16,0x47,0xaf,0x50,0xe5,0xe5,0xd3,0x21,0x8c,0x67,0x46,0x5d,0x97,0x19,0xda,0x6e,0xd9,0x70,0x7d,0x9f,0xd6,0x25,0xd0,0xfb,0x01,0x62,0x0a,0x9e,0x49,0x3d,0x33,0x0d,0x35,0xe5,0xae,0xfd,0xeb,0xb5,0x9b,0xd8,0xc1,0x2a +.byte 0xee,0x4d,0xf2,0xfc,0x16,0x51,0xab,0x58,0x7a,0x9e,0x5c,0xca,0x0a,0x92,0xbb,0xbb,0xa8,0x5b,0xfb,0xf9,0x33,0x67,0x0e,0x13,0x4c,0x83,0x3a,0x25,0x84,0x23,0xe1,0x41,0xfb,0xf1,0x42,0xc1,0x8d,0x58,0x0c,0x5e,0x75,0x09,0x34,0x58,0x96,0x32,0x54,0xb6,0xd8,0xaa,0x48,0xc1,0xed,0xc0,0x92,0x5a,0xec,0xeb,0xb1,0x75,0x59,0xf6,0x35,0xf5 +.byte 0xfd,0x7d,0x96,0x9b,0x83,0x38,0x31,0x10,0xa4,0xd7,0xfb,0x28,0xf0,0xc9,0xe4,0x33,0x5d,0x66,0x81,0x9c,0x31,0x9a,0xe9,0x9a,0x5e,0x70,0xf7,0x61,0xf9,0x93,0xaf,0x2b,0xbd,0x78,0x9e,0xdc,0x61,0xe0,0xa9,0xd1,0xa0,0x8e,0x3a,0x5f,0xb1,0x71,0xe7,0x9e,0xfd,0x81,0xee,0xf0,0xd6,0x63,0xec,0x4a,0xca,0x30,0xaf,0xb6,0x2d,0xaa,0x2d,0xa1 +.byte 0x5a,0x38,0xb5,0xc6,0x3f,0x5f,0x63,0x48,0xd3,0x18,0xeb,0xe3,0x36,0xca,0x91,0x86,0x4b,0x6f,0x57,0x66,0x47,0x2f,0xce,0xe4,0x44,0x26,0xe4,0xfd,0x8c,0xde,0x74,0xdc,0x17,0x0e,0x7d,0x6a,0xcf,0x89,0x0e,0x7f,0x09,0x65,0xf8,0xeb,0x58,0x00,0x3d,0xc5,0x1b,0x14,0xc5,0xca,0xca,0x28,0xbc,0xb7,0x63,0x6f,0x3b,0xa4,0x62,0x23,0x0e,0xd5 +.byte 0x04,0x76,0x0c,0xe8,0xea,0x64,0x10,0x3a,0x76,0x03,0xd6,0xea,0x69,0x52,0x14,0xa7,0x5e,0x40,0x7e,0x14,0xdb,0x7f,0xbf,0xe8,0xf6,0xf0,0xdd,0x5e,0xac,0x55,0x44,0xfb,0x28,0xf3,0x16,0xcb,0xed,0x8f,0x10,0x01,0x91,0xac,0x2c,0x27,0x46,0x0c,0x51,0xd6,0xf6,0x30,0xa3,0x34,0xd0,0x5e,0x93,0xe8,0x4e,0xc0,0xb4,0x9b,0xc1,0xe8,0x20,0x7d +.byte 0xb7,0x68,0xdd,0xf1,0xc4,0x60,0x20,0x97,0xdd,0x5c,0x7c,0x9b,0xea,0xc0,0x22,0x84,0x2c,0x65,0x78,0xbd,0x18,0xa1,0x62,0x7e,0x06,0x49,0x96,0xde,0xd1,0x89,0x06,0x0d,0x35,0xa0,0xcc,0x22,0xd3,0xf5,0xa6,0x4b,0xb6,0xca,0x43,0x34,0x5a,0x3d,0x39,0x95,0x0b,0x95,0xbe,0xdc,0xe6,0x61,0x72,0xbe,0x2f,0x19,0x1c,0xe8,0x22,0x5e,0x18,0xc9 +.byte 0x59,0x4a,0x08,0xa3,0x85,0x5c,0x06,0x36,0x00,0x2e,0x84,0x3e,0x3e,0x07,0x5b,0xfa,0xda,0xbb,0xbb,0x57,0x20,0x6f,0x1b,0x8d,0xe5,0xc5,0xdb,0x8d,0x23,0x1a,0xfc,0x67,0xa9,0xc8,0xea,0xe1,0x54,0xbb,0x8a,0x8a,0x0b,0xa6,0x02,0x35,0xd6,0xd5,0x4d,0xff,0x09,0x79,0x31,0x9a,0xc2,0xad,0xa7,0x66,0xb5,0x3c,0xbd,0xb7,0xcb,0x17,0x30,0x4b +.byte 0x56,0xf5,0xd2,0x51,0x90,0xbb,0x47,0x00,0xc0,0xf3,0x8b,0xd7,0x10,0x33,0x6d,0xe8,0xe4,0xcf,0xd6,0xbf,0x35,0x75,0x8d,0x40,0x55,0xd7,0x5d,0xb0,0x40,0xf6,0x95,0xfb,0x1a,0x97,0x24,0xb8,0xc1,0x91,0x5f,0x66,0x6c,0xc7,0xdb,0x16,0xba,0xb8,0x07,0xf8,0xf8,0x91,0xb2,0x8c,0x26,0xb9,0xa2,0x59,0xb0,0xde,0x49,0x63,0xcc,0x7c,0x4c,0x48 +.byte 0xb5,0xe4,0xf9,0x81,0x28,0x48,0x9f,0xa0,0xa4,0xf8,0x0d,0xcc,0x7b,0xf3,0xce,0x08,0x85,0x73,0x4a,0x64,0xfc,0xa8,0xc0,0xae,0x7a,0xbf,0xa5,0x3f,0x45,0xaf,0xe7,0x7f,0x41,0x61,0x34,0x08,0x6e,0x09,0x0d,0x9d,0xea,0x90,0xbe,0x62,0x7c,0x38,0x92,0xa7,0x63,0xfa,0x03,0x80,0x10,0xc4,0x53,0x46,0x0b,0x44,0x88,0xea,0x50,0xb6,0x82,0xf8 +.byte 0x0b,0x2d,0x93,0x63,0x82,0x80,0x2b,0x61,0x3e,0x17,0xd1,0xd8,0x6c,0xb1,0xb4,0xbd,0xfd,0xad,0x1c,0x10,0x30,0xc1,0x78,0xd4,0x5f,0x21,0x49,0x54,0x7a,0x08,0x2b,0x25,0x3b,0xc9,0xb7,0x0a,0xf2,0x37,0x83,0xc0,0x43,0x73,0xee,0xd6,0x8b,0x92,0x15,0xde,0xfe,0x14,0xf1,0xfb,0x8b,0x4a,0x85,0x8d,0x78,0xe6,0x36,0x1a,0xbb,0x32,0x6c,0xdd +.byte 0x43,0x76,0xad,0x68,0x90,0x08,0xd2,0xbd,0x24,0x41,0xd4,0x93,0x17,0xa8,0x9f,0xeb,0x33,0x25,0x1f,0x1a,0xfd,0x45,0x20,0xc1,0x47,0xf1,0x25,0x09,0x89,0x14,0x9e,0x4c,0x88,0xa4,0x1c,0xb8,0xba,0x84,0xd5,0x7d,0x73,0xb2,0x9c,0x48,0x9f,0x84,0x31,0xd3,0x2c,0xe1,0x94,0x61,0x3e,0x5f,0x37,0x25,0xc7,0xb7,0x2d,0xc3,0xa9,0xaf,0xcc,0x0e +.byte 0xe6,0xc7,0x9a,0xa7,0x06,0xe3,0x41,0xb8,0xa6,0xa8,0x9a,0xe7,0x76,0xef,0x83,0x5a,0x80,0xa4,0xe3,0x0c,0x04,0xa2,0x0b,0x91,0x33,0x34,0x17,0xa4,0x02,0x2d,0x12,0x84,0x67,0x85,0x6b,0xc0,0x3a,0x0d,0x16,0xf2,0x66,0x04,0x71,0xe9,0xec,0xa6,0xbb,0x58,0x42,0x92,0x70,0xf5,0x0d,0x52,0xcd,0x1e,0x2d,0xd4,0x28,0x0f,0x68,0x35,0xd9,0xa4 +.byte 0x40,0x09,0x30,0xe9,0xbb,0xaf,0x77,0x63,0x4f,0xba,0x56,0x97,0xe8,0x92,0xcc,0xba,0xdb,0xe4,0xe0,0xdf,0x19,0x21,0x71,0x23,0x3d,0xd0,0xb1,0x25,0xd3,0xf8,0x53,0x01,0x30,0x9a,0xea,0x84,0x1b,0x18,0x68,0x4a,0xb9,0x9e,0x60,0xc4,0xfc,0xf7,0x56,0xb7,0x49,0xe1,0x50,0x38,0x7d,0x3d,0x87,0xa2,0xad,0x38,0x5c,0x0c,0x53,0x21,0xa0,0x56 +.byte 0x3a,0x94,0xd7,0xa8,0x23,0x96,0xa9,0x66,0x4e,0x88,0xae,0x4b,0x6e,0xcb,0xc6,0xa6,0xdb,0x1f,0x2e,0xae,0xe7,0x24,0xe2,0x1e,0xf7,0x3a,0x14,0x48,0x5e,0xfa,0x90,0x0a,0x84,0xa6,0x1c,0xaa,0x60,0xc0,0x2c,0x69,0xe8,0x36,0xb3,0xee,0x55,0x2a,0xf7,0x90,0xa1,0x92,0x4f,0x29,0x1e,0x49,0x6e,0x73,0x22,0x1f,0x8b,0x0c,0xb6,0xf4,0x3c,0xbf +.byte 0x82,0x47,0x49,0xc3,0x94,0x0e,0xcf,0x9b,0x86,0x88,0xc2,0xd0,0xd7,0xa7,0x43,0xfb,0x89,0x4b,0xbd,0x5d,0x4c,0x6b,0x7a,0xc7,0x74,0x1b,0xfb,0x48,0x12,0x68,0x61,0x91,0xf9,0xf3,0xb6,0x7f,0x4f,0x72,0x89,0xf0,0x72,0x46,0xf7,0x6f,0x84,0xd1,0x38,0x6d,0xd9,0x1b,0xa5,0xd1,0xe2,0x29,0xe0,0xa6,0xbf,0x1c,0xbd,0xfb,0xdd,0xdc,0xa5,0xae +.byte 0x7a,0x9c,0xd0,0xc3,0xfa,0x6f,0x72,0xa3,0xa2,0x8b,0x87,0x0d,0x9a,0x6a,0xfc,0x53,0x9a,0x08,0x61,0x86,0x67,0x2a,0x90,0x6a,0x09,0x20,0x8e,0xde,0x32,0x35,0x34,0x75,0xc0,0xa8,0xab,0x1b,0xc4,0x7c,0xc8,0xd9,0x90,0xcf,0x32,0x27,0x6c,0x68,0xf9,0x18,0x14,0x05,0x57,0x39,0xc6,0x9e,0x5e,0x38,0x07,0xdb,0x81,0xb4,0xa4,0x54,0x06,0xd6 +.byte 0x79,0x78,0x0e,0xc8,0xb9,0x56,0xda,0x08,0x2e,0x77,0x26,0xcc,0xf7,0xa5,0x2d,0xd8,0x91,0xa6,0xfc,0x25,0x0e,0x91,0xdd,0x3c,0xa8,0x14,0x7a,0x95,0x05,0x5b,0x15,0x7d,0x1d,0x9b,0x3c,0x8c,0xfd,0xdc,0xa5,0xcd,0xec,0xea,0x7a,0x2b,0x7e,0x79,0x21,0x54,0xea,0x7f,0x52,0xb4,0xbb,0x4f,0x07,0x95,0x39,0x4a,0xaf,0x2e,0xb4,0x1e,0x9e,0xc6 +.byte 0x0a,0x07,0x58,0xd4,0xa5,0x44,0x73,0xa8,0x84,0x26,0x67,0xb8,0x0f,0xc7,0x6b,0xa7,0x28,0xf6,0x05,0x91,0x3e,0x22,0xcd,0xd7,0xf5,0xfc,0xae,0x22,0x42,0x96,0x3b,0x57,0x91,0xce,0x44,0xd0,0xfd,0xc3,0x4c,0x8b,0x8b,0x67,0xfe,0x03,0x86,0x92,0x34,0xf7,0xf9,0x53,0xb3,0xdf,0x36,0xcf,0x16,0x1c,0x68,0x36,0x17,0x1f,0x41,0x56,0x1d,0xda +.byte 0x90,0xb3,0xab,0x03,0x97,0x88,0x23,0x65,0x89,0x72,0xe3,0x6d,0x8e,0x37,0x5d,0xee,0x89,0x81,0x11,0x27,0x8b,0xf0,0x9b,0xef,0xa2,0x34,0x45,0xcc,0x41,0xcf,0x2a,0x88,0x70,0xe4,0x78,0xfc,0xe1,0xb5,0x51,0x70,0x84,0x64,0xd1,0x10,0x71,0x5d,0xa4,0xb4,0x6d,0xb5,0x98,0x6e,0xcc,0x9a,0x62,0x14,0x30,0xce,0x1a,0xff,0x49,0xd6,0xaa,0xcc +.byte 0xe1,0x99,0x42,0xb1,0xfe,0x77,0x8a,0x2d,0xdb,0xc0,0x0d,0x50,0x53,0x0d,0x92,0xe5,0x2b,0xd0,0x78,0x83,0x08,0x4a,0x0c,0x1d,0x5b,0x03,0x22,0x65,0x3d,0x9e,0xdb,0xcf,0x01,0x61,0xf7,0x6d,0x2b,0x99,0xef,0xba,0x80,0x50,0xda,0xda,0x2d,0xbf,0x00,0xdf,0x6f,0xec,0x95,0xbc,0x5b,0x4e,0xda,0x83,0xe4,0x5d,0xf0,0xa7,0x1b,0x27,0xf1,0x76 +.byte 0x04,0x5d,0x3d,0x2c,0x12,0x15,0xad,0xef,0x47,0xdc,0x22,0x9b,0xc2,0x80,0x91,0xf3,0xbf,0x16,0xe9,0xd3,0x35,0x94,0x4b,0xfd,0xa3,0xa1,0xee,0x98,0xad,0x99,0xea,0x07,0xe1,0x0f,0xa7,0xbd,0x0b,0xfb,0xc0,0xd5,0xb0,0x49,0x37,0xc6,0x5f,0xe7,0x18,0xc1,0x60,0xe9,0x1d,0x5e,0x0e,0xea,0x73,0xf2,0xa1,0x75,0x7e,0x39,0x51,0x07,0x1e,0xcb +.byte 0x2a,0x5b,0x26,0x75,0xbe,0x02,0x5e,0xde,0x6c,0x37,0xb1,0x3c,0x1f,0x25,0x65,0x7d,0x9e,0x5d,0xa1,0x0b,0x98,0x27,0x53,0xb9,0xbb,0xc2,0x3e,0x8d,0x2d,0x5e,0x5c,0xbf,0xed,0x66,0xe8,0xd1,0x7d,0xaa,0xef,0xca,0x0e,0xd0,0x78,0x2b,0x89,0x07,0x76,0xb6,0xc3,0x92,0x42,0x3a,0x84,0x1d,0x81,0xc1,0xe8,0x1a,0xb8,0xe6,0xf1,0x43,0xcc,0x7a +.byte 0x59,0x4d,0x9f,0x00,0xfe,0x6a,0xe5,0x42,0x71,0x3c,0xcb,0xc8,0x45,0x18,0xf0,0xf2,0x81,0x9d,0x5a,0xb7,0x8d,0xbe,0x31,0xcb,0x7d,0xca,0xb7,0x19,0x57,0xb1,0x61,0x36,0x90,0x42,0xe2,0xc3,0xf5,0xa5,0x4b,0xc3,0xd4,0xe7,0x6c,0xb6,0x0c,0x06,0x19,0x4b,0x54,0x8f,0x2d,0xdc,0xc5,0x2b,0xff,0x1c,0x61,0x29,0xda,0x95,0x4f,0xa1,0x21,0x25 +.byte 0x24,0xbe,0xc7,0x34,0x2f,0xbf,0x33,0x6d,0x82,0x8f,0xf1,0xa9,0x97,0x5a,0x49,0x7f,0x60,0x00,0xf2,0x3e,0x7b,0x64,0xdf,0xc8,0xd3,0x5f,0x6e,0x1f,0xfb,0x71,0x80,0xf3,0x55,0x42,0xbe,0x32,0x7b,0xa9,0xeb,0xf6,0x31,0xe2,0xf0,0xd1,0xe9,0xbe,0x96,0x0e,0xb3,0xdf,0x3e,0xb2,0x2c,0xc3,0xce,0xbd,0xe7,0xfe,0x1c,0xed,0x2c,0x0b,0xaa,0x32 +.byte 0x76,0x82,0xb4,0x6b,0x18,0xa7,0x68,0x19,0xb7,0x27,0x21,0x4c,0xb0,0x22,0x98,0x58,0xd5,0x90,0x80,0xab,0xa1,0xfe,0x83,0xc5,0x66,0xf6,0x3e,0xa2,0xa9,0x6f,0x73,0xce,0x7f,0x0c,0xe6,0xde,0xee,0xb0,0xe6,0x2a,0xcc,0xcc,0xb0,0x53,0x8c,0xce,0xc8,0xdc,0xea,0x83,0xb4,0x0e,0x69,0x8d,0x90,0x86,0xaa,0xe3,0x3b,0xfb,0x88,0xe2,0xe8,0x27 +.byte 0x65,0x36,0x07,0xb3,0x91,0x0e,0x5a,0x6b,0x9f,0x0f,0xbd,0x81,0xb3,0x54,0x65,0x71,0xa4,0x2c,0x8e,0xda,0x47,0x04,0xce,0xfe,0x00,0x52,0xf1,0xdf,0x82,0x27,0x70,0x2a,0xb1,0x79,0x2f,0x27,0x7f,0xae,0x9e,0x5c,0x36,0xec,0xa0,0x2a,0xf3,0x74,0x78,0x01,0x17,0x74,0x2a,0x21,0x4f,0xb8,0xd2,0xe4,0xfe,0x5b,0x06,0x14,0xa5,0xb1,0xb1,0xff +.byte 0xee,0x79,0xf7,0x18,0xb9,0x31,0xa4,0x63,0x47,0x1c,0xdf,0x38,0x04,0x2d,0x18,0xca,0x14,0xf8,0x2f,0xec,0x0d,0x58,0xad,0xbb,0xf4,0x45,0x11,0x0e,0xfa,0x17,0x4c,0x5e,0xd4,0xa6,0xde,0xe4,0x13,0x44,0x2c,0xb9,0xfd,0xcd,0x41,0xe7,0xf9,0xda,0xbc,0x28,0x8f,0x0c,0x41,0x4d,0xa7,0x0d,0xf5,0x96,0xd7,0x8f,0x10,0x96,0xfb,0x75,0x75,0x86 +.byte 0xc9,0x6e,0x23,0x92,0x71,0x69,0x7b,0x94,0x61,0x1c,0x3f,0xcf,0x66,0x34,0x62,0x68,0x5d,0xee,0x7b,0x34,0x5d,0x2a,0x39,0xbb,0x6a,0x34,0xea,0x6e,0xe3,0xe9,0xdb,0xe4,0x34,0x6e,0x29,0x0b,0x21,0x38,0xe7,0x5b,0x79,0x37,0x54,0xf0,0xed,0xaa,0x07,0x2b,0x21,0x29,0x67,0xfe,0x7d,0xa5,0x99,0x0e,0x5d,0x05,0xe7,0x61,0x6e,0xd1,0x4a,0x15 +.byte 0x4a,0x56,0xb1,0x13,0x49,0x8c,0xf4,0x4f,0xd7,0xe9,0x68,0xae,0x09,0x37,0xd3,0x96,0x21,0xe8,0x1f,0x9f,0xa9,0xc6,0x54,0x57,0x63,0x09,0x1e,0x71,0xf2,0x48,0x9e,0x50,0xbb,0xb3,0xf1,0x4e,0x2d,0x1d,0x79,0x69,0x0a,0xa2,0xa9,0xdd,0x1b,0x55,0x62,0x6b,0x0d,0xcc,0x9c,0xb1,0x5e,0xc8,0x4c,0x4f,0x62,0x3c,0xc4,0xa3,0xb4,0xe4,0x34,0xec +.byte 0x9d,0x0c,0x1b,0x46,0x60,0x68,0xd5,0x04,0xd7,0x1b,0x3c,0x7a,0x98,0x0c,0xd9,0x87,0x2b,0x4f,0x97,0x5b,0x56,0x65,0xb0,0x06,0x6e,0x9e,0x06,0x37,0x0e,0xd2,0xa1,0x52,0xf5,0xaa,0x2b,0xec,0xbd,0x0f,0xb6,0xba,0x48,0x63,0x57,0x51,0xe3,0x00,0x53,0xf5,0x77,0xb2,0xa4,0xb1,0x44,0x01,0x3e,0xcf,0xe9,0x2a,0x7a,0xf5,0x19,0x5e,0x43,0x36 +.byte 0xe0,0x38,0x41,0xbc,0xda,0xb5,0xd0,0x69,0xdf,0xd2,0x04,0xd4,0xf8,0x38,0x37,0x1c,0x90,0x30,0xf2,0x3d,0x03,0xe4,0x3f,0x84,0x2c,0x9a,0xa4,0x8a,0x00,0x4e,0x49,0x24,0x62,0x06,0xb4,0x9d,0x33,0x8a,0x8e,0xd2,0xbd,0x1b,0xa1,0x83,0x0b,0xa5,0xa2,0x5c,0xcf,0xb1,0x65,0x85,0x92,0x1f,0xb0,0x2e,0x3b,0xb2,0xf3,0x80,0xff,0x9d,0x41,0x4d +.byte 0xcd,0x25,0x09,0x02,0x85,0xb3,0xa8,0x49,0x12,0x10,0xe7,0x5c,0x94,0x13,0x4b,0x52,0x53,0x35,0x9c,0xbc,0x7a,0xad,0x04,0x19,0x54,0x8a,0xbc,0x42,0x73,0xf1,0x0a,0x22,0x75,0xbf,0x3b,0x12,0xa8,0xa4,0x47,0x5c,0x95,0x48,0x60,0x71,0x5c,0x9a,0x39,0x5c,0xdb,0x44,0xe8,0x74,0x92,0x3e,0x2b,0x3b,0x1b,0xb7,0x21,0x98,0xe1,0x87,0x32,0xaf +.byte 0x4a,0xe3,0xda,0x4a,0x46,0xde,0x15,0x4c,0xdc,0xc6,0x60,0xe6,0xd7,0x92,0x29,0x05,0x21,0x22,0x9b,0xaf,0xc4,0xd7,0x6a,0xea,0x2c,0x82,0x5d,0xc7,0x81,0xe2,0x67,0x85,0xd2,0x16,0x6f,0x83,0xa8,0x82,0x5f,0x8f,0xf5,0x3a,0x50,0xba,0x04,0xcb,0x76,0x4d,0x80,0x16,0x12,0x72,0xa8,0x6c,0xac,0x78,0xf1,0x8c,0x93,0xab,0xe0,0xb5,0xdc,0xd1 +.byte 0xa5,0x40,0x0e,0x50,0x88,0xd2,0x9d,0x56,0xf6,0xa0,0xd4,0x45,0xcf,0xef,0x16,0x1a,0xa4,0xaa,0x91,0x5c,0xa3,0x8f,0x84,0xf8,0x3e,0x30,0x1f,0x5f,0x55,0xf9,0xd3,0x3d,0xb8,0x64,0xbb,0x3c,0x91,0xe4,0x0d,0xa5,0x43,0x14,0x75,0xe7,0xec,0x8c,0x12,0x56,0x34,0xb0,0xa9,0xae,0x93,0x91,0x34,0xfc,0x78,0xa3,0x81,0x51,0x45,0x7d,0x9f,0x7d +.byte 0x5e,0xc7,0x5e,0x51,0x17,0xfa,0x02,0x5d,0xb2,0xf7,0x79,0x4b,0x49,0xd2,0x1b,0x6f,0xfd,0x9e,0xff,0x75,0x74,0xf0,0x26,0x7e,0xd7,0x65,0xb0,0xf3,0x0a,0x0c,0xd2,0xa2,0x26,0x98,0x03,0x26,0xb5,0x67,0xc4,0xc0,0xed,0x80,0xd4,0x20,0xf6,0x7e,0x17,0x54,0xeb,0xde,0xc3,0x86,0x51,0xda,0xf7,0xe5,0xc7,0xfe,0xfc,0x71,0x83,0x80,0xbe,0xde +.byte 0x4b,0xda,0x83,0x76,0x63,0x04,0x03,0xdd,0xe0,0xe0,0x4e,0xb6,0x32,0xd5,0xd0,0xce,0xd7,0xaa,0xcd,0x5f,0x64,0xa6,0xd8,0x9e,0xc5,0x97,0x30,0xad,0xf1,0x82,0x8f,0x7c,0x18,0xec,0x30,0x1d,0x2d,0xb6,0xdb,0x33,0x65,0xed,0xe2,0x24,0xd8,0xba,0x0a,0x1f,0x79,0x2a,0x1c,0xe1,0x4e,0x04,0xa6,0x74,0x74,0x37,0x42,0x94,0xc4,0x99,0x0e,0xf8 +.byte 0x3f,0xf3,0xff,0xeb,0x7f,0x95,0x9c,0x47,0x56,0x68,0x6a,0x0d,0x6e,0x66,0x71,0x3b,0x51,0xd5,0x12,0x7e,0x59,0x39,0x43,0xb5,0x53,0xd3,0x1d,0xa2,0xe9,0xa1,0xc8,0x8d,0xf2,0x8e,0xa1,0x9c,0x36,0xdd,0xda,0xd3,0x61,0xd8,0xe9,0x76,0x5e,0xcb,0x0a,0x52,0xc8,0x5a,0x25,0x00,0x21,0xea,0x6a,0x96,0xde,0x02,0x76,0x02,0x63,0x73,0x28,0x63 +.byte 0x46,0x37,0xe1,0x75,0x2f,0x42,0x8f,0xee,0x2c,0x84,0x82,0x43,0x43,0x2d,0xa9,0x13,0x50,0x46,0x54,0xed,0x76,0xbd,0x10,0x1c,0x9b,0xa1,0x42,0x97,0x68,0xca,0x84,0x2e,0x1d,0x6f,0x86,0x67,0xaf,0xb7,0x20,0xc1,0x7c,0xab,0x70,0x20,0xa1,0x79,0x71,0xe4,0xb7,0x45,0x8a,0x04,0xd3,0x70,0x10,0xa8,0x28,0xc3,0x56,0xff,0x43,0x36,0x13,0x88 +.byte 0xb6,0x2d,0xfd,0x7f,0xbc,0xc9,0x1d,0x11,0x9a,0x7c,0xd0,0xfc,0x11,0xac,0x54,0xd5,0xc3,0x03,0xd1,0xe3,0x9e,0xff,0x03,0xdb,0xd9,0xd8,0x77,0x96,0x08,0xf4,0x1b,0xd9,0xfa,0x70,0xed,0xab,0x53,0x78,0xca,0x28,0xa7,0x29,0x49,0x45,0x37,0x10,0x8f,0x61,0x7d,0x11,0x99,0x2e,0xe8,0x5d,0x45,0x3a,0xe7,0xd2,0x6c,0xb6,0x03,0xc4,0x6d,0xaa +.byte 0x52,0x60,0x8c,0xc6,0x9c,0x17,0xba,0xf6,0x3b,0xd4,0x4b,0x26,0x63,0x92,0x8c,0xb9,0x6a,0xf2,0x26,0x91,0x9d,0x8d,0x99,0x39,0x26,0x7d,0xb5,0x4f,0x4c,0xc6,0x0e,0x2e,0xe1,0xc6,0xcb,0x98,0x93,0x71,0x9b,0xaa,0x01,0x40,0x70,0x93,0x2a,0xe8,0x27,0xc5,0x20,0xa7,0xd2,0x06,0x8b,0xb0,0x29,0xcd,0x4f,0x2c,0x5a,0xde,0x35,0xc7,0x2a,0x8e +.byte 0xa7,0xae,0x02,0xfa,0x8e,0x4d,0xf3,0x77,0x67,0xe0,0xcb,0x84,0x69,0xc6,0x05,0xe4,0x84,0xe3,0x6e,0x02,0x6c,0x3b,0x93,0x30,0x3e,0x89,0x2c,0xc7,0xa5,0x7e,0xaa,0x58,0x59,0x25,0xf6,0xff,0x56,0x9a,0x4a,0x70,0xbf,0x88,0x20,0x8d,0x51,0x5e,0x08,0x13,0x26,0x2c,0x5d,0x88,0x13,0x3e,0x32,0x7a,0xf6,0x17,0x5c,0xdb,0xc4,0xcd,0x5a,0x16 +.byte 0x65,0xe4,0x34,0xeb,0x21,0x6d,0xb9,0x30,0x5d,0xc0,0xa2,0xea,0x4f,0x63,0x0e,0xbe,0x32,0x91,0x89,0x6f,0x96,0x40,0xf3,0x5f,0xa3,0xf2,0x15,0xc3,0x3c,0x3c,0xb8,0x2f,0x0d,0xc2,0xcd,0x4e,0xa0,0xa5,0xf6,0x78,0x40,0x0b,0x90,0x11,0x52,0xff,0x8f,0x7f,0x6a,0x0c,0xd6,0x3b,0x64,0x80,0x47,0xfa,0x70,0xbe,0x01,0xdc,0xdf,0x5b,0x75,0x7c +.byte 0xca,0x66,0xf0,0x2a,0x53,0x89,0x55,0x87,0xf8,0xec,0xd1,0x18,0x22,0x0c,0xd5,0x0e,0xc8,0x1c,0xbc,0x1e,0x66,0x14,0x44,0x10,0x3c,0xd4,0x2e,0xca,0x0b,0xd8,0x3f,0x81,0xd8,0x9f,0x81,0xf6,0x62,0x23,0xe4,0xc7,0x0d,0xb0,0x1b,0x00,0xd8,0xf4,0x1a,0xdd,0x9b,0xa1,0x74,0xeb,0xf0,0x65,0x5c,0x82,0x00,0x17,0xa6,0x68,0x29,0xd5,0xa4,0x64 +.byte 0xd3,0x15,0x90,0xd0,0x91,0x17,0xfc,0xd2,0xd7,0xad,0x4b,0xd8,0x41,0x03,0x51,0xfd,0x61,0xac,0x34,0xd4,0xff,0xaa,0xb1,0x64,0x6c,0x79,0x78,0xf7,0x6b,0x18,0x03,0x2b,0x6b,0x9a,0xd7,0xce,0x55,0x6e,0xdd,0xab,0x2e,0xbc,0x27,0x3a,0x8c,0xa5,0x8d,0xf0,0x55,0x81,0x0c,0x6e,0x8d,0xd8,0xd2,0x24,0x5e,0x2e,0x56,0xa8,0x1e,0x9c,0x98,0x88 +.byte 0xd3,0xbe,0x90,0x56,0x70,0xe5,0xcc,0x49,0x2a,0x13,0x98,0x99,0xbd,0xc9,0x9f,0x53,0x85,0x07,0xbe,0x54,0xa7,0x4c,0xd6,0x96,0x7d,0x8f,0x24,0x79,0x67,0xb2,0x62,0x4c,0x6a,0xc1,0x6c,0xb7,0xdc,0xe9,0x21,0xe3,0x27,0xc7,0x53,0xff,0xe7,0xd1,0xea,0x60,0xa8,0x56,0x08,0x5c,0x29,0x0a,0x04,0x0c,0xda,0x7a,0x70,0x8c,0x3d,0x55,0x3f,0xcf +.byte 0x9e,0xea,0x74,0x8b,0xbc,0xf0,0xf1,0x3a,0x86,0x22,0xe5,0x54,0xa7,0x70,0xc2,0xcd,0xb8,0x9f,0x4e,0x9f,0x48,0xa8,0xc0,0x82,0x0d,0x73,0x8b,0x3c,0xfc,0x20,0xf4,0xbe,0x79,0xde,0x8e,0x3c,0x26,0x85,0xde,0x74,0xd1,0xe3,0xd5,0x8f,0x39,0x71,0x46,0x8c,0xbd,0x68,0x28,0x2d,0x36,0x0d,0x66,0xc1,0x0b,0x96,0x3e,0x11,0x2e,0x44,0x17,0xd5 +.byte 0xfe,0x0d,0x70,0x84,0x96,0x20,0x34,0x2f,0xbe,0xf0,0xf5,0x9b,0xb4,0x5a,0xa9,0x50,0x6a,0xda,0xdb,0x69,0xea,0xef,0xa9,0xaa,0x06,0xc0,0x68,0xa4,0x61,0x1b,0x4b,0xf8,0x0b,0x56,0x91,0xc8,0x6f,0x39,0x15,0xe2,0xcc,0xbf,0x2b,0x36,0x96,0x0c,0x84,0xfb,0x3d,0x4b,0x09,0xe3,0xc2,0x4b,0x05,0x5e,0xfa,0x30,0x75,0xc5,0x54,0xa5,0xbd,0x45 +.byte 0x1e,0x14,0x72,0xd6,0xfd,0xe0,0x8f,0x7b,0x46,0x9b,0x11,0x07,0x27,0x03,0xe1,0x2d,0xcc,0x0a,0x01,0x49,0x61,0xc4,0x61,0x78,0x06,0x5f,0xaa,0x01,0x5b,0x68,0xd7,0x29,0xb4,0x9e,0xd3,0xaf,0xc7,0x45,0xf0,0x23,0xaf,0x28,0xcd,0x96,0x23,0x61,0xb2,0xb4,0x21,0x96,0x5d,0x91,0x3e,0x71,0xb5,0x41,0xf1,0x29,0xf4,0x5b,0x45,0x77,0x16,0x00 +.byte 0x9d,0x39,0x2a,0x1c,0x38,0x6d,0x36,0x97,0x98,0x4c,0x84,0xfc,0xf5,0xf1,0x59,0x7a,0x8c,0x21,0xfb,0xbc,0x9b,0x0c,0x8d,0x60,0xb6,0xc4,0xe3,0x4b,0x33,0x4f,0x04,0x4c,0x27,0xd2,0xa0,0xe1,0x71,0x0b,0x6d,0x40,0x8d,0xba,0xb3,0x11,0x9b,0x07,0x97,0x82,0x01,0x47,0xaa,0x2a,0xd4,0xcc,0x02,0xd3,0x86,0x86,0xb5,0xd7,0x5d,0xbc,0xd0,0x0f +.byte 0x97,0x5c,0xe5,0xac,0xc6,0x53,0xb3,0x39,0x09,0x68,0x2e,0xcc,0xf3,0x43,0xba,0xed,0x15,0x90,0xbe,0x9d,0xeb,0xa4,0xfb,0x4a,0x20,0xcf,0x10,0xb9,0x47,0x99,0xb0,0x89,0x26,0xb9,0xbd,0x4b,0xf6,0xa5,0xbd,0x2f,0xad,0x1a,0x75,0xe8,0xff,0xc6,0x6b,0x6a,0x31,0xbe,0xec,0xd2,0xc4,0x39,0x9e,0x3b,0x05,0x3f,0x24,0xba,0xf1,0x4d,0x0c,0x0c +.byte 0x05,0x60,0x60,0x22,0x0c,0x1b,0x0b,0x6c,0x80,0xd5,0xe8,0x8f,0x81,0xee,0x80,0x41,0x4a,0x69,0x47,0xc6,0x4c,0xeb,0xf6,0x2b,0x91,0x7c,0x9f,0x22,0x74,0x7b,0x43,0x95,0x56,0x55,0xba,0x85,0x23,0xb3,0xc3,0xee,0x6a,0xcc,0x49,0x2c,0x6c,0x86,0x6d,0x60,0x5d,0x84,0x0c,0x3c,0x88,0x61,0x58,0x1d,0xfc,0x00,0x2c,0x84,0x49,0x4d,0x95,0x75 +.byte 0xc0,0x03,0x02,0x59,0xc0,0xe9,0x84,0xea,0xce,0x3f,0x8b,0x76,0xbf,0x19,0xaa,0x13,0x1b,0x8d,0x9f,0xb2,0xeb,0xb3,0x02,0x87,0xee,0xfe,0x73,0xdb,0xc4,0x19,0x27,0xaf,0x15,0x8d,0xf4,0x58,0x97,0x43,0xb9,0x45,0x32,0x5f,0x24,0x2d,0x08,0xfe,0xec,0xf2,0xf1,0x34,0x99,0x7a,0x66,0x44,0x3d,0xd4,0xf7,0x82,0xcf,0xca,0x6f,0x53,0x9f,0x0a +.byte 0x74,0x79,0x9b,0x45,0x5b,0x07,0x92,0x35,0xc6,0xf4,0xd1,0x90,0x2b,0x62,0xec,0x93,0x7b,0x05,0x90,0x75,0xb7,0xb6,0xd9,0x6c,0x30,0xdd,0x9b,0x2a,0x32,0xb1,0xba,0xab,0x1a,0x6c,0x2b,0xd8,0xfb,0x39,0x8e,0x80,0x98,0x6c,0xd0,0xb3,0xf3,0x76,0xe2,0xe6,0x5e,0xee,0xd0,0x29,0xd7,0x57,0x8f,0xc3,0x13,0xcb,0x45,0x90,0x3e,0xa2,0x54,0x88 +.byte 0xd5,0x50,0xd3,0x75,0xed,0x2d,0xa6,0x50,0x11,0x6b,0xb0,0xb6,0xf0,0x1d,0xc9,0x3d,0x1d,0x2a,0xda,0x5e,0x43,0x44,0xf4,0xef,0x3e,0xc7,0xa9,0xe0,0x6d,0x3c,0x38,0xbf,0x84,0x72,0xaf,0xea,0x60,0x15,0x03,0x14,0x77,0xb7,0xb3,0x15,0x4c,0xbc,0xbf,0x55,0x86,0x24,0x73,0x97,0x22,0x9d,0x59,0xa0,0x39,0x76,0x38,0xd1,0x1f,0x25,0xb0,0x64 +.byte 0xf3,0x10,0x67,0xf2,0x7c,0x11,0xf2,0xce,0xbe,0xaf,0x5e,0x2e,0xc5,0xc1,0x01,0xfa,0x80,0xf9,0x87,0xfc,0x5c,0xfd,0x66,0x50,0x01,0xc2,0x00,0x92,0x84,0x0f,0xdc,0xfc,0x10,0xa5,0x6e,0x45,0xf5,0xff,0x58,0x78,0x45,0x5e,0x50,0xbe,0xe3,0xc7,0x25,0x1e,0xdf,0x7f,0x68,0x6f,0xa5,0xb8,0xf8,0x69,0x89,0x5a,0x55,0x65,0xf4,0x96,0xe5,0x7a +.byte 0xa6,0x89,0x69,0x8d,0xdd,0x4f,0x24,0x5a,0x29,0x92,0x1e,0xca,0x74,0x65,0x7f,0xb8,0x32,0x75,0xb5,0x7b,0x15,0xea,0xeb,0xcc,0xf1,0x23,0x69,0xc7,0x58,0x1c,0x3a,0xaa,0x27,0x0a,0x11,0x79,0xcf,0xc9,0xb6,0xbd,0x9d,0x56,0x47,0x36,0x6b,0x7f,0x82,0xb5,0xa7,0x9f,0x79,0x72,0x16,0xba,0x50,0xef,0x37,0x68,0xdf,0xe0,0xd8,0x0c,0x16,0xcc +.byte 0x50,0x6c,0x25,0x63,0xc2,0xd6,0x7b,0xef,0xd9,0xa1,0xef,0x62,0x81,0x97,0x51,0x49,0x69,0xe3,0x13,0x6c,0x1a,0xd0,0x64,0x1b,0x3e,0x48,0x25,0x5b,0x34,0xe9,0xee,0x41,0x34,0xfb,0x8e,0x9d,0x3c,0xbc,0xc8,0xcf,0xe7,0xf8,0x72,0x21,0x0f,0x95,0xde,0x57,0xd7,0x2f,0x80,0x97,0xbd,0x8f,0x2c,0xde,0x19,0xa3,0xba,0x5c,0x92,0xa3,0x75,0x83 +.byte 0xe3,0xc9,0x33,0x3f,0x8f,0x09,0xfa,0x0b,0x60,0x0a,0x2f,0xb3,0x45,0x9d,0x8e,0x9d,0xa3,0x66,0x2d,0xda,0x37,0xe0,0x21,0x52,0x74,0x9d,0x59,0xa4,0x9e,0xea,0x15,0x22,0xb0,0xbf,0x3c,0xd4,0x59,0xef,0x27,0x60,0xf7,0xbf,0x5d,0x1d,0x36,0x9a,0xa5,0xfb,0x53,0x90,0x40,0x83,0x3a,0x20,0x3d,0x6b,0x47,0xbc,0xc3,0xe6,0x07,0xfe,0xd0,0x8e +.byte 0x40,0x42,0x65,0x2b,0x27,0xba,0x69,0x61,0x03,0x36,0x58,0x35,0x7e,0x82,0x53,0xb5,0xe2,0x25,0x31,0xc3,0x77,0xc1,0x91,0x13,0xa4,0x92,0x52,0xea,0x9f,0x43,0x44,0x6b,0x43,0xe9,0x11,0xd4,0x3d,0x53,0xba,0x6b,0x96,0xb5,0x96,0x29,0xa3,0x2a,0x0a,0xf2,0xb5,0x0c,0x5d,0x62,0x37,0xe0,0xd6,0xa2,0xbf,0xcd,0xf9,0x58,0x7f,0xa2,0xfd,0x54 +.byte 0x6a,0xa1,0x90,0xa5,0x61,0x9e,0xa6,0xc2,0xb9,0x80,0x7a,0xb8,0xaf,0x60,0x68,0xa7,0x27,0x77,0x41,0x03,0x4e,0xc1,0x96,0x46,0x23,0x1b,0xff,0xa1,0x37,0x28,0x33,0x27,0xc2,0x99,0xf7,0xcb,0x7f,0x1a,0xfb,0x41,0xc3,0x59,0x11,0xf8,0x39,0x50,0xbd,0x90,0x61,0x4a,0x67,0x4a,0x07,0x5f,0xb1,0x07,0x66,0x0b,0x52,0xad,0x90,0xc2,0xd7,0x4e +.byte 0x42,0x9e,0xcc,0x5c,0xeb,0xf2,0xdc,0xaa,0x52,0xcf,0x0e,0x7d,0xae,0x3e,0x1a,0x2c,0x9e,0x79,0xfb,0x29,0x10,0x29,0x61,0xa4,0x93,0x9d,0xa9,0xe9,0x71,0xc5,0xf7,0x07,0x13,0xe9,0xbd,0x2e,0x2d,0x0c,0xd6,0xaf,0x54,0x48,0x58,0xc2,0x91,0x37,0xf4,0x61,0x3a,0x96,0x81,0xdc,0x82,0x02,0xff,0xc9,0xf7,0xf7,0x9f,0x9f,0x28,0xd1,0xb1,0xe3 +.byte 0x2b,0x3d,0x85,0xef,0x15,0x82,0x3b,0x9a,0x17,0xee,0x7f,0xd3,0xa5,0x7c,0x41,0x27,0xc9,0x4c,0xe9,0x7a,0x30,0x9f,0xc5,0x34,0xaf,0xc8,0x1c,0x8a,0x7c,0xa6,0xf4,0xdc,0xa6,0xdb,0x68,0xc1,0xa1,0x13,0xb0,0x54,0x49,0x25,0x43,0xc0,0xd4,0x93,0xd6,0x70,0x53,0x3e,0x5f,0xd5,0x42,0x6e,0x78,0xb8,0x15,0x07,0x6a,0x91,0xe8,0xf1,0x2f,0xcf +.byte 0x07,0x84,0x25,0xb3,0x20,0xb9,0x35,0x25,0xbb,0x26,0x96,0x02,0x25,0xd5,0x83,0x23,0x71,0x6d,0x62,0xa7,0x99,0x73,0x63,0x2a,0x51,0x25,0x34,0x3d,0x51,0x95,0xc7,0x9b,0x01,0x0a,0xab,0x11,0xb2,0x32,0xcd,0xe3,0xef,0x63,0xa4,0x6d,0xdb,0x7b,0xf6,0x5f,0xc5,0xf3,0xe5,0x8c,0x6b,0x0a,0x04,0x33,0x53,0x0d,0xf6,0x13,0x8c,0xb8,0xc7,0xba +.byte 0xc2,0xf0,0xd4,0xa7,0x1a,0xce,0x7c,0x54,0x72,0x2b,0x89,0xf4,0x05,0x5c,0x30,0x42,0xe5,0x58,0x65,0x3a,0x2e,0xf9,0x40,0xab,0x2b,0xf9,0xc3,0x99,0x40,0x3c,0xb1,0x7b,0x2c,0xdc,0xfe,0x41,0x21,0x71,0x00,0x75,0xbd,0xea,0xf3,0x84,0x88,0x6b,0x9c,0xe2,0x80,0x2f,0xad,0x9f,0x9d,0x0a,0xdf,0xb5,0x38,0x61,0x89,0xfb,0x67,0x45,0x9c,0x39 +.byte 0xf9,0x84,0x54,0xc4,0xd6,0x6f,0x00,0x39,0x90,0x82,0xfa,0xce,0xae,0xe8,0xaf,0xa4,0x97,0x3a,0xfe,0x71,0xaf,0x5e,0x00,0xd1,0x9e,0x33,0x41,0x63,0xca,0xa5,0x5a,0x8b,0x09,0x2a,0x26,0xef,0x96,0xb7,0x5d,0xc4,0x92,0xfa,0x51,0xdb,0x1d,0x63,0x5f,0x7c,0x94,0x53,0x84,0xed,0xa3,0x99,0x07,0x9f,0xdc,0x55,0xb3,0x31,0x67,0x1a,0x63,0x05 +.byte 0xec,0x36,0x79,0x57,0xf8,0x39,0xc3,0xdd,0xd5,0x6a,0x21,0xfc,0x54,0xe6,0x28,0xc4,0xf1,0xd2,0xce,0x02,0x43,0x50,0x30,0x15,0x4d,0x3c,0xd0,0x1c,0xf6,0x7e,0xd0,0xa4,0x86,0xe7,0xf5,0xc2,0x06,0xc5,0xc4,0xa8,0xe2,0xd3,0xc7,0xcf,0xbd,0xab,0x9f,0xe3,0x42,0xc4,0xcd,0x65,0xfa,0xd3,0xcd,0xdf,0x55,0xc4,0xce,0x6e,0xe8,0xfc,0x96,0x0f +.byte 0xe2,0x92,0xca,0xde,0x37,0x7c,0xc9,0x80,0x4a,0x54,0xe9,0xfd,0x3c,0x4b,0x81,0xb8,0xd9,0x1a,0xf1,0x91,0x5d,0x9d,0xef,0x3e,0xd1,0x78,0xe2,0x1e,0x0e,0x09,0x62,0xdd,0xc6,0xb9,0xde,0x29,0xba,0xb0,0x62,0x49,0x53,0xb6,0x8d,0x9f,0xbf,0x4d,0x77,0xa4,0xd1,0x0b,0xf0,0x31,0x2e,0xe5,0x71,0x2e,0x18,0xa4,0xa7,0xcb,0xa6,0x30,0x24,0x11 +.byte 0x8d,0x16,0x21,0x71,0x6a,0x19,0xde,0x3c,0x5a,0x00,0xa6,0xe2,0x43,0x98,0xe8,0x83,0x10,0x76,0xef,0xca,0x67,0x61,0x80,0x98,0x48,0x06,0xa9,0xcd,0x13,0xa6,0x1e,0x5b,0x2b,0xef,0xb7,0x3a,0x24,0xf7,0x10,0x8d,0xc2,0xaa,0x9c,0x78,0x0d,0xd1,0x54,0xb1,0x4e,0x5a,0x21,0xc2,0xb4,0x11,0x15,0xdb,0xb3,0x9c,0xe4,0xf1,0xfc,0xa5,0x66,0x0c +.byte 0x56,0x34,0x05,0x14,0x88,0x2c,0xfc,0x3f,0x97,0x30,0xd5,0xd0,0xba,0xa3,0xf1,0x47,0xc0,0xf1,0x59,0x3c,0xda,0x1a,0xc1,0x90,0xae,0x4b,0x26,0xd3,0x5f,0xc9,0x8f,0x62,0x56,0x9c,0x64,0xec,0xda,0x63,0x37,0xa1,0xa2,0x87,0x74,0xcb,0xcc,0x27,0xcb,0x2a,0x97,0x57,0xa3,0xb9,0xac,0xe2,0xbd,0x97,0x93,0x21,0xb9,0x8b,0x82,0xa1,0xe7,0x76 +.byte 0xc1,0x49,0xd6,0xb2,0x52,0x7b,0xd6,0xbb,0x31,0x0f,0x87,0xc0,0xaa,0x91,0x70,0x19,0x76,0xa5,0xea,0xf0,0x87,0x47,0x50,0xc1,0xff,0xf7,0xa6,0x6c,0x65,0xff,0xdf,0x83,0x5c,0x54,0xf0,0xb1,0x18,0xe0,0x13,0x58,0x74,0xc0,0x67,0x0e,0xb8,0xdc,0x59,0x6c,0x19,0xf4,0xee,0x3a,0x07,0x63,0x68,0x1d,0x62,0x60,0xb5,0x71,0xce,0x21,0x61,0x8c +.byte 0xa5,0x74,0x9b,0x77,0x8e,0x15,0x20,0x18,0x19,0x96,0xf6,0xfa,0xd2,0x6c,0x03,0xcb,0xcb,0x8c,0x91,0x0d,0x29,0x91,0x70,0xc5,0x96,0x60,0x18,0xad,0x65,0x66,0x43,0xf9,0x13,0x97,0xe3,0xe3,0xcb,0xbf,0x68,0x0b,0xb2,0x87,0x9c,0xfa,0x96,0x48,0x14,0xef,0x6e,0xbd,0x45,0xb9,0x2f,0xbb,0x80,0x80,0xc5,0xf6,0x22,0x41,0x9a,0xec,0xdd,0x41 +.byte 0xfc,0xf3,0x0d,0x8e,0x2e,0x3c,0xda,0xef,0x2c,0xbd,0xbc,0x0e,0x88,0xd2,0x97,0x3d,0x40,0x37,0xa6,0xde,0x1d,0x00,0xeb,0x39,0xea,0x44,0xee,0x8a,0x2f,0x77,0xea,0xea,0x1d,0x90,0xd1,0xec,0xe4,0x31,0x0c,0xde,0x6f,0x55,0x17,0x5c,0x1e,0x19,0x91,0xac,0x36,0x00,0x26,0x17,0xa6,0xcd,0x8b,0xe2,0x72,0x6f,0x8f,0x3c,0xc6,0x76,0x6e,0x3d +.byte 0x4e,0x93,0xb3,0x8b,0xad,0x24,0x17,0x39,0xc0,0xfe,0xba,0x90,0xc5,0xbd,0x4b,0xe4,0xae,0xac,0xf6,0x55,0x72,0x3e,0xf0,0x12,0x32,0x5a,0xdd,0x8a,0x3f,0x67,0xb6,0xdf,0xf6,0x11,0x02,0xf5,0x84,0xcc,0x7d,0x36,0xe7,0x1b,0xf0,0x9a,0x52,0xbe,0xf3,0x06,0xd6,0xdb,0x02,0xd4,0x80,0x0b,0xcd,0xf0,0xfe,0xec,0x86,0x3f,0x89,0x34,0xcb,0x88 +.byte 0x34,0x28,0x57,0x00,0x33,0xeb,0x4f,0xfa,0xdb,0xd8,0x09,0xd9,0x56,0x53,0xc1,0x02,0xc0,0xa8,0x4c,0xdc,0xfd,0x26,0xb3,0x55,0x1d,0x47,0x0d,0x68,0x50,0xb8,0xa3,0xb4,0xf1,0x31,0xfa,0x16,0x33,0x94,0x40,0x95,0x53,0x9c,0x9f,0x5b,0x25,0x47,0xb1,0x27,0xbc,0x38,0x7d,0x23,0x01,0x7f,0x70,0x7a,0x61,0x0e,0x46,0x5c,0xcc,0xd7,0xcc,0x15 +.byte 0x15,0x0a,0xed,0x4c,0x99,0x66,0x3a,0xc3,0xc1,0x9a,0x7a,0x38,0x6a,0x0c,0xde,0x13,0x67,0x65,0xfc,0x06,0x99,0x7c,0xa5,0x90,0x8a,0x90,0x58,0xce,0xf3,0x23,0x76,0xfc,0x03,0xfb,0xb3,0x36,0x54,0xa9,0x33,0x35,0xfe,0xe3,0x3d,0x53,0x7e,0xe0,0xae,0xcf,0xc0,0xa2,0xe1,0x28,0xb9,0x97,0x96,0x87,0x90,0xa1,0x13,0xd0,0x1d,0x5b,0x43,0xf1 +.byte 0xa5,0xfa,0x81,0x83,0xe7,0x7b,0xa1,0x5f,0x9f,0xf5,0xd3,0xb6,0x80,0x8b,0x91,0xed,0x31,0x14,0x05,0x78,0x85,0x9d,0xea,0x59,0x69,0xa5,0x29,0xc5,0xf1,0xd7,0x9d,0xa3,0x8b,0x9d,0xe0,0x8d,0xc3,0x4e,0x2d,0xfa,0x1c,0x6c,0xd2,0xd7,0xcb,0xda,0x86,0x5d,0xb3,0x1a,0xb4,0x12,0xe3,0xa8,0xd7,0xe1,0x84,0xce,0x0e,0x06,0xd0,0x9e,0xf0,0xb1 +.byte 0x5b,0x2f,0x77,0x10,0x6f,0x41,0x2f,0x5b,0x48,0x43,0xf3,0xef,0xdb,0x09,0xdb,0x01,0x89,0xfc,0x7a,0x4a,0xc0,0x96,0x33,0xdf,0xbe,0x49,0x85,0xa7,0x88,0x93,0x05,0xf2,0x15,0x12,0x85,0x04,0x20,0x7d,0x8c,0xe2,0x0a,0xea,0xfe,0xed,0xbf,0x98,0xdb,0x9d,0x1f,0xaf,0x0f,0xbf,0xf7,0x12,0x4f,0x69,0x4e,0x87,0x09,0xf0,0xae,0x2a,0x4d,0x4c +.byte 0xbf,0xaa,0x08,0x2c,0x78,0x2d,0xbe,0xb9,0xf5,0x3c,0x4c,0xcd,0x75,0x93,0xc3,0x3c,0xc2,0x86,0x47,0xca,0xc1,0x9c,0x1c,0xe5,0x0d,0x8d,0x36,0x9c,0x44,0x40,0x89,0xfa,0x17,0x57,0x08,0xd4,0x22,0x9a,0x5b,0x94,0xbf,0x39,0xcd,0xbe,0xf7,0xd1,0xcd,0x35,0x74,0xdf,0xfa,0x5d,0x00,0xaa,0xaa,0x82,0x6d,0x9b,0xf8,0x69,0x51,0x9c,0xaa,0xaa +.byte 0xc8,0x2c,0xa2,0x68,0x57,0x3c,0x5f,0x10,0xa2,0x7b,0xee,0xc9,0x97,0x8d,0x5c,0x41,0x08,0x0d,0x30,0xd5,0x2b,0x5f,0x8d,0xdd,0xdc,0x2c,0xa8,0x52,0x6e,0xea,0x61,0x77,0xca,0x75,0xc3,0x56,0x6e,0x17,0x51,0x0e,0x00,0xb6,0x18,0xa0,0xe5,0x9d,0x49,0x4e,0x20,0x78,0x1e,0x5f,0x3e,0xec,0xc3,0x4a,0x41,0xf3,0xfe,0x89,0x64,0xac,0x4c,0x4d +.byte 0xa8,0x73,0x4f,0x31,0xc4,0xe2,0x62,0x69,0x2b,0x40,0xdf,0xef,0xed,0xf0,0x62,0x4e,0xc3,0x65,0xcc,0xcb,0xef,0xc1,0x28,0x61,0x71,0xac,0xa5,0x89,0x52,0x7b,0x32,0x59,0xc2,0x16,0x1a,0x63,0x18,0xb0,0xd8,0xe4,0x28,0x92,0xff,0x45,0xc1,0x24,0x56,0x86,0x66,0x23,0x7a,0xff,0xf7,0x33,0x30,0xdc,0xd1,0x7d,0xaf,0x68,0x10,0x4b,0xde,0x3e +.byte 0x4a,0x70,0xbe,0x31,0x1a,0x37,0x28,0xee,0xe0,0xba,0x65,0x8b,0x7d,0xea,0x07,0xce,0xf2,0x51,0x3d,0xcb,0xb2,0x33,0xd8,0xf3,0xa4,0xa0,0xcd,0x53,0x76,0xf9,0x46,0x5b,0x82,0xf9,0x9d,0x0e,0x29,0x5b,0xcf,0x76,0xd4,0x5c,0x47,0xf1,0x98,0x02,0x5a,0x16,0x18,0xf2,0x61,0x6d,0x3e,0x64,0x7f,0xbe,0x13,0x18,0xc2,0x45,0xd2,0x87,0x17,0xff +.byte 0xf1,0x01,0x0b,0x5d,0x21,0x0d,0x73,0x9a,0xeb,0x82,0xc4,0x9a,0xb3,0xe4,0x31,0x44,0x58,0xa2,0xfd,0x76,0xf6,0xbe,0x6f,0x75,0xcc,0xbb,0xe3,0xa2,0xa9,0x78,0x0f,0x4b,0x1d,0x47,0x2d,0x32,0x2c,0x45,0x5e,0xcd,0x8f,0x13,0xe2,0x9a,0x9d,0xa2,0xce,0x73,0x54,0x20,0xc0,0x44,0x1c,0x26,0xde,0x0d,0x72,0xb2,0xfa,0x4d,0x32,0x35,0xac,0x69 +.byte 0x4d,0x16,0x4a,0xd5,0x51,0x33,0xc1,0xe0,0x90,0x9c,0x93,0x66,0xed,0x16,0xac,0x7e,0x79,0x2b,0x0f,0xb4,0x42,0xaf,0x80,0x22,0x80,0x07,0x7d,0x72,0xe4,0xb3,0x3a,0x2c,0xb8,0x68,0x14,0x4d,0x31,0x5f,0xbb,0xac,0x43,0x3b,0x28,0xd6,0x81,0x81,0x26,0xe5,0xc4,0x67,0x7c,0x4a,0x42,0xc4,0x1a,0x59,0x04,0x2d,0xb8,0x26,0xfc,0x4e,0xc7,0xfc +.byte 0x11,0x61,0xe3,0x4b,0x2c,0x3f,0xdb,0x43,0xe4,0x24,0xb4,0xd1,0xc0,0xc0,0x01,0xe1,0xeb,0x84,0x0b,0x6d,0x93,0x83,0x07,0x9f,0x01,0xb8,0x9d,0xe5,0x7e,0x4d,0xa2,0x05,0x3e,0xf2,0x40,0x59,0x88,0xc8,0x8c,0x62,0x44,0x95,0x20,0x96,0x28,0xa9,0x3f,0x7c,0xed,0x85,0x03,0x65,0x49,0xf7,0x94,0x3d,0x51,0xe2,0x8e,0x21,0x19,0x7b,0x55,0x5f +.byte 0x55,0x70,0xf8,0xf0,0xce,0xd9,0x1a,0x10,0xbb,0xfe,0x65,0x72,0x8a,0x5b,0x6c,0x27,0xd3,0x57,0x61,0x07,0x7b,0x85,0xd6,0x21,0xd2,0x07,0x81,0xaa,0x17,0x73,0xb5,0xef,0x2d,0x84,0x7b,0x8f,0xe0,0xb3,0x9e,0x9f,0x31,0x82,0x33,0x07,0x14,0x84,0x79,0x18,0xc4,0xec,0x20,0xb5,0xec,0x21,0x4b,0x51,0x78,0x96,0xc6,0xe7,0xf0,0x6a,0x7a,0xb5 +.byte 0xe5,0xc2,0xef,0x24,0x4c,0x57,0xb6,0xf5,0xee,0xe5,0x69,0x2b,0x73,0x9e,0x66,0x91,0x9d,0xd4,0x24,0x58,0x4b,0x72,0x68,0xf6,0x62,0xb4,0x0c,0xe3,0xbd,0x1f,0x0b,0x42,0x6c,0xf9,0x6e,0x6a,0x64,0x64,0x69,0xa5,0x6d,0xe7,0x38,0x9f,0xb2,0x65,0x35,0x6b,0xd9,0x20,0x84,0xe4,0x5f,0x8b,0xfd,0x58,0xab,0x5f,0xe1,0x4c,0xf7,0xd7,0xf5,0xe7 +.byte 0xae,0xe8,0xc1,0x68,0xfe,0x0c,0xb1,0xe2,0xe4,0xca,0xf0,0xf1,0x20,0xbc,0xf9,0x99,0xef,0x4e,0x63,0xca,0x89,0xe4,0x7c,0x17,0x49,0x40,0x47,0xce,0x67,0x8e,0xbd,0xd0,0x96,0x8b,0x5a,0x0d,0x2f,0xd0,0x8f,0x4f,0x42,0x06,0x01,0x8e,0x47,0x35,0x13,0x9e,0xd1,0x24,0x85,0xe4,0x17,0x59,0xe8,0x1c,0xb3,0x25,0x53,0xf9,0xb4,0x96,0xb1,0x33 +.byte 0x97,0xb2,0x60,0xc7,0xb3,0x48,0xa2,0xfc,0x7f,0x86,0x94,0x2a,0xd3,0x94,0xfe,0x6d,0xa6,0x7a,0xa1,0xe1,0x96,0x5b,0xe8,0xe4,0x91,0xfb,0xf3,0x2c,0x84,0xb4,0x2f,0xbe,0xc9,0xdd,0x1c,0x9f,0x72,0x12,0xcb,0xbd,0x22,0x07,0xc4,0xec,0x05,0xe8,0x32,0x47,0x21,0x27,0xf6,0xc1,0x36,0x59,0x25,0x6c,0xbe,0xb9,0x3e,0xd4,0x1b,0x59,0x11,0x27 +.byte 0x6b,0xa3,0x64,0x71,0x98,0xeb,0x21,0x65,0xc0,0x4c,0x30,0xbd,0x51,0x2b,0xc3,0xfb,0xb1,0x33,0x56,0x1e,0xf0,0x92,0x0f,0x4b,0x63,0x3a,0x9c,0xfb,0xd1,0xac,0x8c,0xf0,0x3e,0xb7,0x0b,0xd2,0x52,0x62,0xd8,0x37,0x9a,0xef,0x79,0xdc,0xcb,0x87,0x1e,0x3d,0x9d,0x91,0x12,0xba,0x78,0x8a,0x11,0x57,0x96,0x44,0x8e,0x2b,0xd2,0xe3,0x4d,0x27 +.byte 0xec,0xba,0xef,0x1c,0x04,0x8d,0x56,0x56,0x11,0x74,0xc0,0xcc,0x1f,0x3d,0x7a,0xad,0x79,0x49,0x59,0xa3,0x71,0xe0,0xf5,0x89,0x89,0x8f,0xcf,0x1e,0x63,0x77,0x91,0x91,0xf1,0x0c,0x1c,0xcc,0x77,0x00,0xd7,0x28,0x9f,0x68,0xbc,0xb6,0x9d,0x33,0x43,0xb2,0x4a,0x72,0x3e,0x57,0x26,0xd0,0x00,0x93,0xc9,0x4c,0xc9,0x53,0x52,0xd9,0xe2,0x31 +.byte 0xc5,0x7f,0xf6,0xb6,0xc2,0x10,0x51,0x67,0xae,0x63,0x35,0x74,0xcc,0xd4,0x05,0xb3,0x08,0x23,0x35,0x37,0x8e,0xf1,0xbb,0x1d,0x56,0xff,0x62,0xa2,0x13,0x7b,0x01,0x75,0x6d,0xb3,0x92,0x51,0xdc,0x6e,0x08,0x76,0x25,0x52,0xbf,0x9a,0xea,0x89,0x0f,0x96,0xcc,0x79,0xd4,0x72,0xcf,0x65,0x79,0x4e,0x40,0xa3,0xae,0x67,0x0c,0x82,0x85,0x05 +.byte 0xfd,0x43,0x84,0x17,0x24,0x79,0xa9,0xa7,0x7f,0x24,0x76,0x57,0x66,0x11,0xd5,0x33,0x30,0x42,0x5b,0x5f,0x7c,0x04,0x4b,0x45,0xc3,0x69,0x20,0x02,0x92,0xe3,0x6a,0x06,0x8f,0xdf,0x30,0xf6,0x17,0x8f,0xc6,0x8c,0x5e,0x42,0xf3,0x59,0x7a,0x3a,0x55,0x3a,0xc1,0x96,0xd5,0x67,0x3d,0xab,0x32,0xee,0xf0,0x08,0x28,0x73,0xb0,0x11,0x1a,0x92 +.byte 0x4d,0xcc,0x0c,0x86,0xb2,0xa1,0xbf,0x9f,0xcd,0xc7,0x1c,0xbc,0xee,0x39,0x77,0x75,0xfc,0xe6,0x3b,0x62,0xf2,0xaf,0xd5,0xb6,0x77,0x2d,0x86,0x38,0x13,0x00,0xdb,0x71,0x4a,0x87,0x03,0x6d,0x99,0x28,0xf8,0x6a,0x23,0x2e,0xe2,0xb8,0x9c,0x18,0x02,0x00,0x9e,0x5b,0xf0,0x6f,0x9b,0x32,0xdc,0x6b,0x61,0xeb,0xeb,0xe9,0xfc,0xee,0x44,0xbc +.byte 0x4a,0x88,0x04,0xc0,0x10,0xc8,0x65,0x6c,0xa4,0xae,0x9a,0x36,0xb6,0x68,0xd5,0xbf,0x6d,0xe3,0x6f,0x5d,0xad,0xd6,0xf9,0xc8,0x06,0x36,0x25,0x64,0xc9,0x5b,0x71,0x7f,0xbf,0xe3,0x56,0x31,0x2a,0x93,0x47,0x46,0x39,0x91,0x80,0xc5,0xdd,0xdd,0xa1,0x25,0x85,0xd9,0x05,0x49,0x4f,0x1b,0xeb,0x2f,0x6e,0xd9,0xe4,0x65,0x3d,0xcd,0xbd,0x47 +.byte 0x37,0x27,0xb0,0xd1,0x9b,0xa4,0x89,0xd5,0xa0,0x0f,0x8b,0xc5,0xfd,0x91,0xa8,0x86,0x22,0x65,0xf1,0xe1,0x1e,0xb6,0xf7,0x50,0xe6,0x1e,0xf0,0x2b,0x9d,0x02,0xc9,0xe8,0x2a,0xb8,0x9b,0x89,0x28,0x25,0x43,0xcf,0x23,0x08,0xe2,0xa7,0x70,0x31,0x89,0xab,0x5b,0xd9,0x2e,0xa9,0xe4,0xe9,0x1d,0x63,0x7f,0xc6,0xc1,0xfb,0x63,0x45,0x9c,0xf1 +.byte 0xd4,0xc3,0x56,0xb6,0xad,0xb3,0x00,0xce,0x12,0x9e,0x63,0x33,0x25,0xd3,0xb2,0xee,0xa7,0x6b,0xa1,0xfd,0x20,0xa3,0xb2,0x07,0x1a,0x9d,0xed,0xe0,0x1d,0x70,0x5b,0x9f,0xc0,0xbc,0x83,0x09,0x94,0x47,0x8c,0x05,0xef,0x73,0x96,0x31,0xc7,0x35,0xc2,0x2c,0x00,0x2a,0x68,0xd1,0xc4,0xb3,0x3d,0x84,0x44,0x8c,0x93,0xfd,0x64,0x00,0x77,0x46 +.byte 0x18,0xac,0x83,0x9d,0xe5,0xe5,0x46,0x61,0x37,0x72,0x9f,0x0e,0x76,0x55,0xf7,0xca,0x36,0x57,0x24,0x16,0xfc,0x11,0x27,0xaa,0x44,0xa4,0xb0,0x58,0x41,0x46,0x94,0xc7,0x3b,0x9c,0xa3,0xe4,0x89,0xd9,0xdb,0x7b,0x64,0x69,0x84,0x9f,0xc8,0x09,0x6f,0xf7,0xf0,0x58,0x10,0x56,0x9f,0x26,0xf0,0x74,0x0c,0x76,0xcb,0x9d,0x45,0x3d,0xe7,0x94 +.byte 0x54,0xa3,0x84,0x08,0xb5,0x9c,0xff,0xdb,0xba,0x62,0x5e,0x87,0x0d,0x11,0x5d,0x96,0x06,0xd6,0xec,0xf4,0x3e,0x9d,0x66,0xbd,0xc4,0x64,0xed,0x03,0xe0,0xad,0x3f,0x4e,0xb4,0xef,0x16,0xdd,0xee,0xd6,0x00,0x27,0x62,0x74,0x0a,0xe0,0x68,0x72,0x4c,0x6d,0x62,0x15,0x87,0x6a,0xf0,0x25,0x9f,0x33,0x1d,0x92,0x3b,0xa3,0xa4,0xf1,0x81,0xdf +.byte 0xa8,0xed,0xaf,0xa5,0x8d,0x19,0x20,0x72,0x03,0x91,0xf0,0x34,0x60,0x70,0xbe,0xaa,0xdf,0xaa,0x24,0x1a,0x1f,0x1a,0x8d,0xb0,0x7b,0xef,0x10,0x43,0x69,0x24,0x74,0xf2,0x72,0x71,0xa1,0x8f,0x85,0x75,0x3e,0x8c,0xf6,0x0e,0x88,0xe2,0x1d,0x5c,0xb8,0xf1,0xc4,0x8a,0x21,0x76,0x20,0x50,0x3f,0xb3,0x8b,0x9f,0xa4,0x45,0x9e,0x07,0x60,0x22 +.byte 0x2c,0xa6,0xb1,0xc2,0xd2,0xcb,0xc6,0xd8,0xe9,0x94,0x66,0xfb,0x10,0x73,0x92,0x25,0x7e,0x31,0x42,0xf4,0x4a,0x75,0xac,0x78,0x43,0xcb,0xc0,0xc9,0xb0,0xaf,0xb4,0x22,0x8f,0x51,0x36,0x0f,0x5a,0xb8,0xbb,0x44,0x03,0x09,0xd0,0xf9,0x04,0xc8,0x73,0x8e,0xa1,0x76,0x27,0xde,0x72,0xf4,0x3a,0x79,0x63,0x85,0x32,0x09,0xad,0x12,0xe4,0xd7 +.byte 0x8f,0x8e,0x24,0x03,0x4f,0xde,0x39,0xac,0x81,0xe8,0x64,0x09,0x17,0xd7,0x99,0xe6,0x62,0xb7,0x53,0x20,0x9f,0xb9,0x3a,0xb9,0xb1,0x81,0xfa,0x6e,0x33,0xe7,0x4a,0xca,0xd7,0xa7,0xfa,0x7a,0xbf,0x0b,0x0a,0x99,0x3c,0xc7,0xbd,0xef,0xc7,0x90,0xda,0x62,0x30,0xc6,0x94,0x94,0x6b,0xee,0xbd,0xb7,0x0d,0x86,0xc5,0xb1,0x9a,0xb9,0x86,0x34 +.byte 0xc2,0x81,0x2b,0x09,0x7a,0x88,0x09,0x65,0xcf,0x51,0x78,0x19,0x1d,0x5a,0x62,0x2f,0xb3,0x43,0x8d,0xf5,0x9d,0x26,0x2f,0x4a,0x27,0x96,0x22,0x1b,0x4c,0xc8,0xd9,0x73,0x4b,0x32,0x01,0x11,0x7b,0x59,0x85,0xda,0x50,0x92,0x17,0x45,0xd4,0x1f,0xcf,0x98,0xf6,0x2c,0x69,0xba,0x43,0x22,0xdc,0x36,0x31,0xfb,0x1e,0xe8,0x54,0x24,0x0f,0x24 +.byte 0x4c,0xcd,0xbe,0xdb,0xd8,0x23,0x69,0xe2,0x97,0xf5,0x66,0xb2,0x66,0x6c,0xf2,0x90,0xd0,0x15,0x14,0x9a,0x47,0x65,0x97,0xb0,0xf2,0x3e,0x35,0x09,0xd2,0x3d,0x01,0x9c,0xb3,0xfd,0xf3,0x32,0x46,0x4e,0x11,0xab,0x88,0x9e,0x04,0x6d,0xf0,0xe1,0x9d,0x48,0x01,0x24,0xc3,0x87,0xdf,0x58,0xb6,0x6d,0x6d,0x4f,0xb9,0x1b,0x13,0xee,0x03,0x5b +.byte 0x75,0x39,0x28,0x31,0x90,0x70,0x49,0x10,0x71,0x87,0x76,0x30,0xac,0x88,0xb0,0xf6,0x6c,0xaf,0x5b,0xf4,0xf3,0xe7,0x25,0x75,0x8c,0xa3,0xf4,0xa7,0xd8,0x94,0x78,0xc8,0x77,0xc1,0x48,0x6c,0x62,0xf6,0x2c,0xb5,0x41,0x59,0xf6,0xd3,0xae,0x1b,0x55,0xed,0xdf,0xd1,0x59,0x63,0x76,0x03,0x65,0xd3,0xd0,0xcd,0xb6,0x5b,0x8f,0x1a,0x78,0x88 +.byte 0x78,0x07,0x14,0x3f,0xc3,0xd4,0x1c,0x69,0xd8,0x15,0x25,0xca,0x76,0x15,0x24,0x7d,0xed,0x69,0x2a,0xb5,0x04,0xd2,0x3b,0xbd,0x7a,0xb2,0xae,0x04,0x51,0x85,0x2b,0x1b,0xb0,0x3f,0x6d,0xbc,0xa0,0xc7,0x19,0x40,0xab,0x75,0x51,0x4b,0xa8,0x5a,0xd7,0xb5,0xc7,0xa8,0xfc,0x4a,0xcf,0xa9,0x9c,0xe6,0x2e,0x35,0x51,0x3b,0x05,0x41,0x43,0x7c +.byte 0x1f,0x2e,0x16,0x5d,0x2f,0xa8,0xe9,0xce,0x6d,0x06,0xa7,0x5a,0xed,0x07,0x39,0xe4,0x7e,0xc3,0x01,0x2d,0x97,0xe4,0xc1,0x89,0x2c,0xb4,0xb1,0xb5,0x7f,0x0a,0xe2,0x9f,0x82,0x36,0xee,0x9b,0x76,0xbc,0x9d,0x37,0xdf,0x5e,0x81,0x95,0x9b,0x2b,0xc4,0x58,0x20,0x6a,0xd2,0xc7,0xb6,0x82,0xe6,0xa2,0x52,0x73,0x4a,0xaf,0x37,0x5a,0xf6,0x6b +.byte 0xc4,0x2b,0x53,0x4e,0xca,0x44,0x17,0x9f,0x1c,0xeb,0x4d,0xf2,0xd1,0xb0,0x35,0xaa,0xc3,0xfe,0x77,0x34,0x2a,0x4a,0xe8,0x85,0x96,0x2f,0xa4,0x7d,0xdf,0xd0,0x6a,0x4a,0x0c,0x9b,0xd9,0x6a,0x00,0x92,0xb4,0xb1,0x9f,0xc3,0x56,0xee,0xcb,0xa5,0x3a,0x37,0x68,0xc8,0x7c,0x1e,0xa8,0x0a,0x3d,0xbc,0xd1,0xd0,0xd7,0x8b,0x32,0x34,0x20,0xfc +.byte 0xd3,0x9e,0xf5,0x18,0x3a,0xb9,0x87,0xae,0xde,0x6c,0xc0,0x7d,0xbd,0x20,0x00,0xe5,0x7b,0xcb,0xf9,0x7d,0x70,0x9a,0x10,0x45,0xc9,0x33,0x13,0x9d,0x2c,0x16,0x67,0xe6,0x36,0x38,0xcf,0xa2,0xf1,0xad,0xec,0x48,0x7f,0x9b,0x2a,0xdc,0x13,0xe2,0xee,0xef,0xf2,0x5c,0x3f,0x52,0x3a,0x72,0x79,0x9b,0xba,0x50,0xb2,0x2b,0xfb,0x97,0x8e,0xe6 +.byte 0x27,0x39,0x63,0x72,0x05,0x11,0x7d,0x2e,0xa8,0x44,0x08,0xf7,0xf3,0x26,0xe5,0xe4,0x6c,0x98,0x7b,0xb1,0x42,0x6d,0x74,0xd4,0x3b,0xfa,0x35,0xfa,0x0a,0xac,0x5e,0x9e,0x8f,0xc7,0x07,0xc5,0x50,0x25,0xfd,0xbf,0x13,0x52,0x3d,0xf1,0x18,0x1e,0x19,0x8c,0xf3,0x8b,0x4d,0xc8,0xfb,0x76,0xa4,0xe3,0x3f,0xb2,0x47,0x9c,0x50,0x97,0x32,0x65 +.byte 0x9e,0x42,0x81,0x21,0xd1,0x92,0xd2,0x81,0x4a,0x93,0x68,0xa2,0xc1,0x76,0xc8,0x40,0xce,0xfe,0x4e,0xc5,0xa7,0xb2,0x77,0x9f,0xc8,0xe5,0x41,0xb1,0xda,0x15,0xf6,0xfa,0x21,0x3f,0x11,0x5c,0xc6,0x62,0xda,0x01,0x7f,0x0f,0x9f,0x9e,0x98,0xfe,0x38,0x53,0x6c,0x7f,0xba,0x8b,0x55,0x01,0x36,0x33,0x41,0x5e,0xa9,0x78,0xbf,0x2e,0x60,0x4f +.byte 0xcb,0xe9,0x27,0x09,0x8c,0x01,0x2d,0x82,0x7d,0x3f,0xaf,0x8f,0x1e,0x37,0x79,0x35,0xfb,0xce,0x83,0xc5,0xf8,0xc5,0x54,0xfd,0x50,0xec,0x31,0xd1,0xb5,0x8a,0x4d,0x37,0xf6,0x7f,0x0e,0xbe,0x35,0xdd,0xa8,0x9e,0x5e,0xb9,0x3c,0xf4,0x2b,0xd2,0x97,0x56,0xd0,0x28,0xcb,0x60,0x27,0xcf,0x27,0x68,0x8a,0xa1,0xbf,0x9f,0xa3,0x45,0x4a,0x44 +.byte 0x71,0xe2,0xb2,0x9c,0x69,0x0b,0x18,0x69,0xcf,0x03,0xcc,0xc3,0x93,0xe0,0xf5,0xb7,0x4e,0xa4,0xdc,0x96,0xe0,0x2e,0xf8,0x3b,0xc6,0x67,0x30,0x06,0x5e,0xb9,0xb9,0x7d,0xaf,0x97,0x38,0x9a,0xf4,0x22,0x20,0x5a,0x9e,0x83,0x26,0x3c,0xcc,0x93,0x84,0x20,0x15,0x2e,0x85,0x23,0x17,0x1d,0x28,0xb4,0xe2,0x8f,0x2d,0x22,0x99,0x66,0xfd,0x6a +.byte 0xa8,0xe6,0xb7,0x19,0x18,0xec,0xbd,0x54,0xc2,0xcc,0xb7,0xb4,0x6b,0x10,0xdd,0xb5,0xe3,0x3b,0xb7,0x77,0xbf,0x66,0x65,0x82,0x6a,0xc6,0x0d,0x26,0xe6,0xe8,0xe1,0x96,0xe4,0x0b,0x3c,0xe3,0xf2,0xfb,0xd6,0x91,0x5d,0xb6,0x08,0x15,0x67,0x10,0xfa,0xf8,0xdc,0x72,0x84,0xca,0x48,0x29,0x75,0x98,0x62,0x30,0x43,0xa9,0xf1,0xde,0x58,0xb5 +.byte 0x6e,0x67,0x53,0x62,0x0d,0x06,0xa8,0x97,0x35,0x04,0x02,0x34,0x3f,0xd7,0x77,0x38,0xed,0x51,0x32,0x7c,0x6f,0x25,0x94,0x04,0x30,0xa5,0xfc,0xf1,0xb0,0x65,0x77,0x16,0xec,0xb0,0xf9,0x6d,0xaf,0xbc,0x75,0x6e,0x29,0x44,0x20,0x86,0x36,0xbe,0x22,0xe0,0xe1,0xc4,0x0c,0x97,0x10,0x45,0x3e,0x06,0xc3,0xee,0xa5,0x1f,0x97,0xc7,0xde,0xdb +.byte 0xf1,0x05,0xe3,0xb7,0x24,0xc5,0xa5,0xca,0x4e,0x8e,0x9e,0x44,0x7e,0x98,0xb1,0x3c,0xe9,0xa6,0xe5,0xa6,0x08,0xcb,0x08,0xd7,0xf6,0x38,0x37,0xa4,0x46,0xd1,0xdc,0x53,0x6f,0x6c,0x3f,0xca,0xa1,0x9b,0x7c,0xa6,0x44,0xd4,0x08,0x33,0xd2,0xf8,0x32,0xd2,0x4f,0x60,0x75,0x0f,0x49,0xf1,0x70,0x52,0x56,0x16,0x5b,0x3e,0x34,0x0e,0xe4,0x94 +.byte 0xc3,0xa9,0xd4,0x1c,0x9e,0xa4,0x10,0xce,0xc1,0x69,0x5b,0x3a,0xc9,0xd5,0xab,0x98,0x81,0x78,0x42,0x7e,0xf2,0x76,0x10,0xad,0x97,0x85,0x98,0x2f,0xe2,0x3f,0xb1,0x1d,0xc0,0x4d,0xa4,0x0b,0x54,0x7e,0x19,0x16,0x0a,0x71,0x74,0x37,0xfd,0x67,0x23,0x86,0xb2,0x3b,0x1e,0x49,0x92,0x92,0x1b,0x5f,0x65,0x56,0x76,0x6d,0x97,0x3b,0x91,0xc0 +.byte 0x5a,0x7e,0xf1,0x5b,0xe9,0x83,0xb9,0x67,0x2f,0xe1,0x0c,0xcf,0xe9,0x51,0x26,0x45,0x03,0x06,0x63,0xa4,0xb2,0x06,0xe0,0x8e,0xa3,0xbf,0xf5,0x7c,0x19,0xdf,0xfe,0x38,0x28,0x98,0xa1,0x23,0x16,0x69,0xc4,0x9f,0x20,0xe4,0x42,0x27,0x4e,0x7b,0xc9,0x42,0x5e,0xd2,0xb9,0xbf,0x33,0x03,0xbb,0x96,0x6d,0x80,0x65,0x90,0x3b,0x82,0x5b,0x68 +.byte 0x46,0x4f,0xe3,0xe0,0x0e,0xc5,0x90,0x91,0x80,0xf8,0xf4,0x9c,0xfe,0x03,0xaf,0x31,0x44,0xb7,0xfc,0x1f,0x65,0xc8,0x65,0x68,0xcc,0x27,0xb4,0x0d,0x81,0x14,0x9e,0x52,0xab,0xdd,0x71,0xf6,0xd9,0xcf,0x29,0x04,0xcd,0xae,0x6f,0xd6,0x41,0xb5,0xfd,0x1d,0x0f,0xbf,0x71,0xc2,0x60,0x98,0xb9,0xc0,0x6e,0x8a,0x2c,0x7d,0xec,0x31,0xa5,0xea +.byte 0x1a,0xb1,0xe4,0xc2,0x36,0xcb,0xf0,0xf4,0x3f,0x1d,0x03,0x01,0xcd,0xac,0xd0,0x9d,0x2e,0xa3,0xc4,0x54,0x49,0x75,0x90,0xac,0x7e,0x1e,0xc3,0x90,0xab,0x55,0xb0,0x34,0x0d,0xd6,0x99,0xb5,0x40,0xda,0xdd,0x30,0x57,0x61,0x15,0xec,0x8f,0x8c,0xc7,0xda,0xfc,0xf5,0x0a,0x86,0xd8,0x6b,0x0f,0x6e,0x09,0xb8,0x50,0x2a,0xea,0x51,0x84,0x33 +.byte 0x7a,0x97,0x0c,0x56,0x61,0x2c,0xd9,0x83,0xb9,0xb1,0x53,0x31,0x72,0x20,0x79,0x85,0x7f,0xdc,0xb8,0xfe,0xfa,0x9a,0xd4,0x6a,0x3c,0xc7,0xcc,0x75,0x20,0xba,0x9c,0xb9,0x1a,0xff,0x9c,0xbe,0xfd,0x87,0xb4,0xd7,0xe8,0x5e,0x22,0x6a,0x1b,0x91,0x52,0x6a,0x58,0xbc,0xf4,0xde,0xcc,0x18,0x37,0x0e,0xf5,0x22,0x91,0xd2,0x4f,0x08,0x91,0x62 +.byte 0x1c,0xb7,0xa0,0x7e,0x66,0x97,0xda,0xa0,0x3c,0xc8,0xe8,0xdc,0x61,0xa4,0x64,0x8b,0x0a,0x43,0x90,0x0c,0x78,0xd9,0x96,0x8a,0xb0,0x17,0x0f,0x32,0x17,0x11,0x82,0x69,0x9d,0x7c,0xa9,0xfd,0x9b,0xe3,0xeb,0x0d,0x44,0x1d,0xcb,0xf6,0xee,0x26,0x6b,0xd5,0x4c,0x49,0x69,0x18,0xd7,0xf3,0x63,0xd9,0x7e,0x83,0xdd,0xa3,0x2d,0xdf,0x88,0x10 +.byte 0xd1,0x5c,0xb0,0x7e,0x44,0xfe,0x64,0x39,0x33,0x05,0x04,0x54,0x74,0x4d,0xd5,0xbc,0xdf,0x19,0x52,0x81,0x60,0x92,0xc5,0x4e,0xa4,0xff,0xf0,0xa2,0xfd,0x88,0x96,0xde,0xb4,0x8d,0x58,0x06,0xfb,0x96,0x6f,0x0e,0xb0,0x4a,0x2b,0xed,0x15,0xa7,0xfb,0x9f,0xf2,0x30,0xc4,0xce,0x02,0x4d,0x83,0xb8,0x5d,0x10,0x60,0xb8,0xbc,0x05,0xa2,0xd4 +.byte 0xf1,0xae,0x46,0x56,0xb9,0xac,0x68,0x79,0x41,0x90,0xee,0x79,0xda,0x3a,0x91,0x7a,0xf6,0xdb,0xe3,0xea,0x91,0x48,0x77,0x4a,0xa3,0xab,0x9c,0x99,0x49,0x1f,0xc9,0xcd,0xe7,0x2e,0xe3,0xe7,0x78,0x6d,0x07,0x1b,0xc6,0x08,0x48,0xd8,0x20,0xff,0x19,0x8a,0x73,0x1d,0xc6,0xa1,0xd4,0x95,0x33,0xf7,0x45,0xab,0xea,0x05,0x3e,0xdf,0xde,0x68 +.byte 0xb2,0xb6,0xef,0x71,0xb4,0xd1,0x09,0x4b,0x43,0x16,0x35,0x1a,0xb6,0xcb,0x78,0x63,0xca,0x9e,0x9a,0xe3,0x86,0xb2,0x8e,0x7b,0x68,0x89,0xa7,0x5c,0xd3,0x06,0x21,0x88,0x94,0xde,0xa1,0xb1,0x3a,0xe8,0xb7,0xfa,0x58,0xc5,0xc8,0x01,0xfa,0x56,0xe4,0x0e,0x6b,0xeb,0x5d,0x67,0xf4,0x63,0xd4,0x44,0xe2,0xe7,0x42,0xfe,0x09,0x58,0xdf,0xd9 +.byte 0x1d,0xb7,0x14,0x91,0xac,0x88,0x49,0xf6,0x7c,0x03,0x92,0x11,0xb4,0x66,0x68,0x6c,0x94,0x2a,0x22,0xaf,0xa6,0xb1,0x29,0x2a,0xae,0xdd,0xa8,0x65,0xe4,0xa9,0x39,0x00,0x1e,0xca,0x17,0x99,0xba,0xd6,0xf2,0x20,0x21,0xbf,0x1a,0xab,0xca,0x7c,0x92,0x22,0xee,0x3c,0x0c,0xc6,0x63,0xcc,0x86,0xfe,0xc0,0x8f,0xac,0x18,0x4e,0x2b,0xa5,0x2e +.byte 0x46,0x57,0x8a,0xbf,0xdc,0xd1,0xd2,0x2c,0x5b,0xe2,0x96,0x81,0xca,0x41,0xb5,0x17,0x38,0x4a,0xa4,0xd2,0x0e,0xac,0x5d,0xe9,0x44,0x63,0x1b,0xb8,0x81,0xd6,0x69,0x1c,0x99,0xc5,0xdb,0xdd,0x18,0xc1,0x6d,0x28,0x7d,0x36,0x52,0x82,0xaa,0x1a,0x10,0x01,0x9d,0xf1,0x7b,0x09,0x69,0x56,0xb1,0x31,0xa3,0x54,0x3c,0x56,0xf9,0x82,0x8c,0x06 +.byte 0x5a,0x32,0x2d,0xc0,0x7c,0x7e,0x91,0x6d,0x73,0x7b,0x7c,0x45,0x0b,0x2c,0x2a,0x4f,0x3c,0xea,0x6b,0x2b,0x84,0x76,0xab,0x8d,0x4c,0x5c,0x64,0xa3,0x97,0x9f,0x56,0x20,0x05,0xf9,0xc2,0x20,0xf3,0xd0,0x6a,0x7f,0x7d,0x12,0xfc,0x20,0x52,0x5d,0xff,0x92,0xaf,0x4e,0x7f,0x8f,0x2f,0xd0,0x73,0x06,0x23,0x09,0xce,0x11,0xc0,0x1b,0x48,0x7d +.byte 0x11,0x51,0x06,0x0e,0x05,0x95,0xca,0x42,0x71,0x87,0xa3,0xa3,0xc1,0x27,0xf8,0xb1,0x24,0x92,0x38,0x95,0xf6,0x8f,0x3b,0x70,0x74,0x19,0x9b,0x08,0xb3,0x49,0xe9,0x57,0xd4,0xce,0x5b,0xdd,0xab,0x95,0x26,0xe9,0x70,0x21,0xef,0x16,0xdd,0x36,0x89,0xe5,0x9e,0xaf,0xc5,0x28,0x0c,0xd3,0x67,0x64,0xbc,0xfb,0x18,0x17,0x15,0x1e,0xa7,0xb7 +.byte 0x72,0x3d,0xfd,0x10,0x5c,0xa2,0xc1,0xbf,0x62,0x79,0x2b,0xa7,0xb9,0x1f,0x73,0xe6,0x11,0xd8,0xbc,0x74,0x6c,0x45,0x95,0xef,0xa2,0xda,0x90,0xc3,0x00,0x00,0xbb,0xc7,0x28,0x36,0x82,0xd4,0x5e,0x5c,0x11,0xea,0x7c,0xf6,0x79,0x66,0xff,0x93,0x77,0x49,0x05,0xc9,0xc1,0x8d,0x5c,0xf6,0xff,0xb9,0xf9,0xcd,0xb3,0x01,0x83,0x83,0x43,0x2d +.byte 0xa1,0x90,0x73,0xc9,0x32,0xae,0xdb,0xd0,0xf3,0x61,0x63,0x72,0x06,0xde,0x21,0x7b,0x3b,0x2d,0xec,0xd3,0x1d,0xfe,0xbd,0x6e,0xd8,0xe3,0x39,0xe0,0xa1,0x9f,0x67,0xaf,0xab,0x79,0xbc,0x59,0xf9,0xa7,0xdf,0x28,0x75,0xea,0x34,0x6b,0x25,0xde,0x49,0x1b,0x07,0x95,0x19,0x47,0x86,0x46,0x7b,0x68,0x30,0x70,0xec,0x9c,0x05,0xb6,0xc9,0x00 +.byte 0x68,0x10,0x4b,0xc4,0xe5,0xf1,0x67,0x3f,0xd4,0x3c,0xd6,0x49,0x98,0x71,0x23,0xff,0x07,0x6e,0x01,0x01,0x08,0x08,0x3d,0x8a,0xa1,0x71,0xdf,0x25,0x1a,0xef,0x60,0x86,0x6d,0x1c,0xd9,0x90,0x29,0x95,0xf2,0x4c,0x96,0xd3,0x17,0xe8,0x96,0x32,0x25,0x8c,0x65,0x38,0xbc,0x44,0x6a,0x5a,0xef,0x5a,0x72,0x12,0x43,0x2b,0xaf,0xc3,0xdc,0xb3 +.byte 0x6c,0x9f,0x57,0x61,0x2f,0x12,0x3f,0x72,0x16,0x4f,0x34,0xe3,0xb5,0xca,0x72,0xca,0x1c,0xdb,0xd2,0x8d,0x70,0x1f,0x19,0x75,0xb3,0x1b,0xdf,0xdb,0xb3,0xbf,0x6c,0x9a,0x70,0x64,0xa8,0xac,0x30,0x2d,0x4b,0x30,0xf5,0x4f,0x12,0x19,0xbd,0x65,0x25,0x70,0x33,0xe1,0x6f,0x18,0xdf,0x17,0xec,0xa3,0x80,0x51,0x6e,0xbb,0x33,0xa5,0xa8,0x58 +.byte 0x95,0x3c,0xab,0x86,0xd1,0x33,0xbe,0x55,0x04,0x8c,0x20,0x0d,0xfc,0x1a,0xa9,0x9d,0xb1,0x16,0x42,0x56,0x20,0xcc,0xa6,0x73,0xa0,0x85,0x3d,0xbf,0x1e,0xe0,0x01,0x51,0xd2,0xd7,0x2e,0x9d,0xd8,0x3c,0xea,0x03,0xf9,0x9a,0xbf,0x19,0x17,0x04,0x99,0xaf,0x8b,0xfc,0x9c,0x86,0xdf,0x58,0x78,0xfc,0x54,0x0d,0xac,0x26,0x27,0x2f,0x2e,0xbc +.byte 0xdd,0x4a,0xd5,0x6f,0x7c,0xd8,0x93,0xe3,0x51,0x9e,0xcc,0xc8,0xd2,0xfe,0x68,0xfb,0x5b,0x22,0xda,0xef,0x76,0xb9,0xc3,0xdd,0x13,0x52,0x24,0xb6,0x23,0x1f,0x69,0x22,0xb6,0xf5,0x86,0xff,0x2e,0x6e,0xd0,0xe0,0x21,0xbc,0x31,0x81,0xb5,0xc5,0xdb,0x36,0x58,0x44,0xe7,0xb8,0xf7,0xfd,0xd3,0x34,0xee,0xab,0xe6,0x99,0xf2,0x84,0x86,0x9b +.byte 0x67,0x45,0x08,0x07,0x66,0xae,0x6a,0x55,0xa2,0x74,0x46,0xda,0x02,0x82,0x67,0x93,0x60,0x64,0x5d,0x1f,0xac,0xe7,0x36,0xb6,0xcd,0x31,0x28,0x78,0x93,0xcd,0x54,0xe9,0x42,0xbb,0xb4,0xb3,0x15,0x72,0x12,0x31,0x85,0x15,0x68,0x3a,0x31,0x35,0xd6,0xc9,0x0d,0x3f,0xa0,0x4b,0x36,0x03,0xda,0xfd,0x7a,0xd6,0xce,0x0c,0xf5,0x14,0x23,0x71 +.byte 0x47,0x85,0x64,0xe7,0xe7,0x8b,0x8e,0x25,0x03,0x32,0x5f,0xa9,0x3b,0xdb,0x2b,0x27,0x7c,0x02,0xfb,0x79,0xd7,0x7a,0x76,0x75,0x69,0xfd,0x74,0x24,0xd2,0x72,0x8c,0xdd,0xc5,0xa1,0x45,0x90,0x50,0x65,0x95,0x41,0xae,0x7e,0x5c,0x83,0x3e,0x24,0x3c,0x02,0xa9,0x37,0x49,0x36,0x63,0x2f,0x18,0x92,0x3a,0x8a,0xe5,0x2a,0x6a,0x5c,0xa7,0x3e +.byte 0x98,0x24,0xfd,0xd9,0x3b,0x2d,0x4c,0xe2,0x8e,0x05,0x5b,0xdd,0x47,0x0f,0x19,0x5a,0x62,0x94,0xd6,0x6e,0x45,0xd8,0x99,0x43,0x78,0xa0,0xb1,0xdf,0x68,0x8a,0x56,0xa8,0xfb,0x2e,0x52,0x4e,0xfa,0x21,0xec,0x62,0x14,0xf5,0x90,0xdb,0x8c,0x02,0xa7,0xff,0x29,0x22,0xb8,0x40,0x87,0x58,0xda,0x4e,0xfd,0xab,0xeb,0xa2,0x40,0xce,0xfc,0x58 +.byte 0x46,0x37,0x3f,0x04,0x4e,0x36,0x76,0x44,0x3c,0xfc,0x54,0xb8,0x6f,0x4b,0x66,0x6a,0x4a,0x78,0x8f,0x33,0x86,0x07,0xe4,0x3c,0xb5,0x0f,0x86,0x2e,0x21,0x7e,0x44,0xce,0x18,0x77,0xe0,0xcc,0xd7,0x7f,0xc9,0xac,0xb7,0x2b,0x94,0xb5,0x91,0xcd,0x2c,0xfa,0xc7,0x98,0xbd,0xb0,0x2a,0x85,0x77,0xcf,0x82,0xd9,0xae,0x76,0x33,0x34,0xc0,0x9d +.byte 0x3a,0xbc,0x27,0xbc,0x97,0x25,0xf4,0xf1,0x43,0x53,0xac,0xf6,0xde,0xf5,0x1f,0xa6,0x6a,0xd5,0xe3,0x11,0x32,0x49,0x46,0x5b,0x56,0x68,0x07,0xdb,0x03,0xad,0xc2,0x35,0x16,0x8f,0x01,0xcc,0x8a,0xd2,0x0c,0x6b,0xb2,0x62,0x73,0x99,0xb5,0x74,0xf1,0x4b,0x2e,0xbc,0x8e,0xed,0xc0,0x55,0x56,0x40,0xae,0x24,0xf2,0x7e,0x1f,0xba,0x9d,0xc4 +.byte 0xd1,0x69,0xd3,0xba,0x21,0x83,0xf5,0xc4,0xbf,0x78,0x96,0x74,0xa1,0xd8,0x8c,0x35,0xba,0x9f,0xa0,0x0f,0xb5,0x6a,0xb2,0x72,0x52,0xfa,0x02,0x71,0xbb,0x79,0x61,0xbd,0xa9,0xee,0x22,0x7c,0xc5,0xac,0x6b,0x52,0x67,0xab,0xc4,0xd2,0x8d,0x26,0x1c,0x2b,0xaf,0x0c,0xa4,0xce,0xb5,0x11,0x99,0x4d,0x22,0x69,0x68,0xe0,0xc6,0x3e,0x84,0x3d +.byte 0xeb,0xad,0xc9,0x5b,0xb5,0xb4,0xba,0x06,0x9b,0x0a,0xb2,0x54,0x89,0xf2,0xb0,0x5f,0x41,0xb4,0x8b,0x21,0x31,0x29,0x94,0x52,0x1e,0xa7,0xc4,0xc2,0x97,0xb9,0x74,0x95,0xa3,0x30,0xfb,0x02,0x77,0x01,0x4f,0x32,0x03,0x34,0x8f,0x51,0x2d,0x10,0x61,0xee,0xc5,0x2f,0x89,0x42,0x3c,0xbe,0xed,0x66,0xa6,0x7a,0x10,0xc6,0x06,0x7e,0xb2,0x3d +.byte 0xf2,0xc9,0xd1,0x08,0x97,0x6c,0x6f,0x6d,0x06,0x9d,0x72,0xd0,0x5e,0x79,0x3b,0xa5,0xa5,0xd0,0xdc,0xc6,0xda,0x73,0xd2,0xf3,0x0a,0xfd,0x94,0xc2,0x9c,0x4b,0x85,0x38,0x8d,0xb2,0xfb,0x29,0xdd,0x90,0xc2,0xb7,0x8f,0x2c,0x52,0xa2,0x32,0x5e,0xa1,0x0f,0x62,0x38,0x58,0xfa,0x46,0x4e,0x87,0x4b,0xcf,0xc5,0xe9,0xfc,0xf2,0x97,0x62,0xdd +.byte 0x92,0xd2,0x41,0x7b,0xa2,0x2a,0xae,0x6e,0x4d,0xbc,0xef,0x43,0x18,0x6e,0xbb,0xe5,0x06,0x45,0x53,0xa1,0x00,0xef,0xf5,0x4b,0xad,0xbd,0xa5,0x2c,0x77,0x0a,0x37,0x04,0x22,0x95,0xeb,0x7b,0xc1,0x3c,0x20,0x0a,0x44,0xdf,0xa2,0x23,0xc9,0xfc,0x85,0xf3,0x5b,0x9b,0x0f,0x40,0x2a,0xe3,0xc7,0x5a,0xa1,0xf6,0xe4,0x39,0x2a,0xfe,0xd7,0xe7 +.byte 0x33,0xd8,0xbc,0xd6,0x1f,0xef,0xac,0xa9,0x3f,0x2d,0x55,0xb0,0x85,0x74,0xef,0xeb,0xcd,0x9b,0x23,0xa3,0xe6,0x19,0xde,0xea,0x7c,0x9c,0x83,0x48,0x4b,0x12,0xfd,0xe3,0xcb,0x1b,0x70,0x2d,0x9f,0x2c,0x13,0x82,0x87,0x68,0xca,0x60,0x5e,0xc0,0x2e,0x60,0xde,0xf2,0x6b,0x78,0x0a,0x63,0xaa,0x9c,0x9b,0x61,0x63,0xc7,0x0c,0x98,0x92,0x68 +.byte 0xc7,0x44,0x00,0x6a,0x76,0x43,0xa0,0x61,0x7c,0x37,0x62,0x1a,0xd4,0x9b,0x58,0x59,0xe5,0xae,0x78,0x79,0x80,0xf0,0x75,0x68,0x9e,0xab,0x02,0xb8,0x00,0xc5,0x33,0x0d,0xea,0xb1,0x91,0x0f,0x17,0x57,0x96,0x23,0x8d,0x36,0x4d,0x89,0x94,0x42,0xc9,0x61,0x6e,0xf6,0x9f,0x37,0xee,0xa5,0x4b,0x3d,0x06,0x08,0xee,0x9a,0x7c,0x73,0xa9,0x58 +.byte 0xcd,0xcb,0x78,0xa9,0x3d,0x5c,0x11,0x0e,0x5a,0xd9,0xb0,0x7b,0xc4,0x3e,0x83,0xdc,0xe2,0x11,0xe9,0x6d,0x8a,0x8b,0x24,0x28,0x1d,0x7e,0x45,0x1b,0x05,0x5a,0x6b,0x97,0x1c,0x25,0x15,0x84,0x5c,0x3f,0x95,0x44,0xd5,0x4f,0x3c,0x4b,0x52,0xb1,0x0b,0x6a,0xb3,0xae,0x4e,0x1b,0x12,0xcf,0x16,0x78,0xd7,0xcb,0x32,0x43,0x39,0x88,0xf4,0x5e +.byte 0x26,0x29,0xe7,0x93,0x08,0x19,0x14,0x88,0x8f,0x54,0x91,0x13,0xb6,0x57,0xd1,0x87,0xd4,0x9d,0xf7,0xec,0x9b,0x22,0x6b,0x91,0x79,0x9d,0x6c,0x32,0x47,0x4a,0x79,0x55,0x7d,0xac,0x87,0x98,0x59,0x97,0xa5,0x71,0xbc,0xbf,0x1b,0xf0,0x6f,0xbb,0x81,0x8e,0xc2,0xef,0x7c,0x63,0x2f,0x80,0x37,0xb6,0xc5,0xae,0x59,0x5e,0x57,0x5e,0x1f,0x3a +.byte 0xe5,0x6b,0x6b,0x5e,0xdb,0x8e,0xd2,0x87,0xf7,0x94,0x7b,0x11,0x0e,0x4b,0xa6,0x9f,0x49,0xc6,0x68,0xc7,0x52,0x5f,0x28,0x87,0x33,0x84,0x52,0x5f,0xc8,0x5f,0x81,0x85,0x10,0xe8,0x92,0xce,0x13,0x6c,0x01,0x28,0x5e,0x59,0x8f,0xbb,0xa9,0x9c,0xdc,0x85,0xd3,0x73,0xa0,0x5a,0xbf,0x5b,0x04,0x80,0x99,0x90,0xc8,0x16,0x44,0x0d,0x09,0x01 +.byte 0xcd,0x24,0xe7,0x59,0xe7,0x42,0xe0,0xdd,0x01,0x93,0x1f,0x9e,0x1f,0x36,0xdb,0xcd,0x49,0xdb,0xea,0xa9,0x63,0x71,0xb9,0x2c,0xcd,0xca,0x1a,0x64,0xe1,0x95,0xbe,0xe1,0x64,0x2e,0xc7,0x59,0x15,0x61,0xe1,0xf9,0x45,0x0f,0x2a,0x3a,0x85,0xf8,0x7c,0x06,0xae,0x53,0x84,0xd2,0xe7,0xee,0x8b,0xbf,0x7a,0x72,0xa3,0x57,0xf1,0xc2,0x12,0x40 +.byte 0x9c,0x93,0xe1,0x04,0x81,0xde,0xc6,0xa8,0xae,0x4f,0x5c,0x31,0x93,0xc7,0x11,0x1d,0x89,0x70,0x85,0xd5,0x6f,0xab,0x58,0x1f,0x3f,0x76,0x45,0x7e,0x19,0xd0,0x6c,0xc1,0x41,0xa9,0x64,0x0a,0x79,0xb5,0xe0,0x9e,0xbc,0x4f,0x10,0x0c,0xac,0xfc,0x54,0xad,0xcf,0xb8,0xd0,0xfd,0x9b,0xed,0xea,0x54,0x05,0xbf,0x4f,0x91,0xbd,0x16,0x4a,0x57 +.byte 0xa9,0xda,0x38,0xb9,0x40,0x0d,0x63,0x68,0x83,0x7d,0xec,0x1c,0xe6,0x7f,0x9c,0xec,0x16,0x4e,0x0b,0xd0,0x91,0xb4,0x2c,0x04,0x65,0xb8,0x12,0xdf,0x3f,0xff,0x6a,0x08,0x4e,0x65,0xdf,0x09,0xa5,0xea,0xb1,0xac,0xa9,0x67,0xd2,0xbb,0x73,0x51,0xd2,0x37,0x72,0xfc,0x3f,0x69,0xe2,0x3f,0x01,0x94,0x3a,0xf7,0x23,0x0e,0x5d,0x23,0x44,0x82 +.byte 0xc7,0x38,0x35,0x9f,0xfa,0x13,0x15,0x47,0x0d,0x18,0xab,0x02,0x39,0x6e,0xb2,0x7c,0x29,0x11,0x9a,0x5a,0x01,0x2d,0xb2,0x10,0xea,0x9d,0xb7,0x37,0x4b,0xf2,0x2b,0x76,0x22,0xf7,0xaf,0x8a,0x5f,0x1d,0x6b,0xb2,0x13,0x9e,0x84,0xf5,0xbc,0x6e,0xad,0x66,0x5c,0x1b,0x5d,0x12,0xb0,0xe1,0x48,0x94,0x83,0xa0,0x26,0x54,0xd2,0xfd,0x3c,0x8d +.byte 0x81,0xac,0x31,0x9a,0x15,0xc6,0xd8,0xd5,0x07,0x1b,0x21,0x3f,0x04,0x40,0x3a,0x60,0x80,0x5f,0x1f,0x42,0x3e,0xd7,0x2b,0x7a,0x5f,0x71,0x93,0xb4,0x9d,0xf0,0x8b,0x5e,0xf1,0xc6,0x19,0x0a,0xa9,0x43,0xac,0xb2,0xc1,0x73,0x0d,0x44,0x6a,0x92,0x22,0xd0,0xda,0x40,0x14,0x7d,0x88,0xd1,0x5e,0x10,0xc9,0xa4,0x4d,0xd8,0xe0,0x7d,0x74,0x1b +.byte 0x2b,0xcb,0x50,0x24,0xbd,0x50,0x4a,0xe4,0xed,0x0e,0xe8,0xc0,0x5b,0x50,0x6d,0xf5,0x68,0x59,0xd1,0xc3,0x6f,0x32,0x86,0x29,0xe0,0x32,0x3f,0x05,0x86,0xa2,0x7f,0x93,0xd8,0xb7,0x02,0x68,0xb3,0x16,0xaa,0x0c,0xd3,0x4d,0xec,0x9a,0x66,0x06,0x7c,0x74,0x35,0x6f,0xde,0x8b,0xd9,0xdb,0x79,0x0a,0x15,0x84,0xc4,0x63,0xba,0x42,0xa2,0x3c +.byte 0x29,0xc8,0x65,0xdc,0x06,0x60,0x0a,0x08,0x4e,0x80,0x33,0x5c,0xfa,0x4b,0x91,0xdb,0xf6,0x57,0xd6,0x25,0x7d,0x70,0x80,0x09,0xb2,0x27,0xdb,0x80,0x4c,0xa7,0xe8,0x35,0xf5,0x18,0x2d,0x10,0x62,0x22,0xf9,0xb1,0x22,0xf3,0x9b,0x74,0xa0,0xc5,0x25,0xd3,0x44,0xc9,0x27,0x7c,0xba,0x01,0xfe,0x32,0x23,0xf7,0x90,0x90,0xbc,0x0d,0xad,0x9e +.byte 0x22,0x77,0xc5,0xfb,0xf2,0x0e,0xda,0xe5,0x7c,0xb4,0xbb,0xed,0xd4,0xfd,0xb0,0xfb,0x4a,0x4c,0x2a,0x32,0x2d,0x81,0xcd,0xef,0x74,0x3c,0x6a,0x9a,0x0c,0x95,0x58,0x25,0xd0,0x3a,0xb4,0x84,0x8f,0xa5,0xef,0xad,0x91,0xd7,0x2d,0xae,0x61,0xaf,0x9d,0x3f,0x03,0xa8,0xab,0xa4,0x66,0xd4,0x73,0x3a,0x84,0x0d,0x4c,0x6a,0xca,0xbd,0x0c,0x3c +.byte 0xdc,0x1d,0x37,0xea,0xe6,0x5a,0x7f,0x15,0xbe,0x9d,0xc7,0xce,0xbd,0x46,0x97,0xd3,0x07,0x19,0x82,0xaf,0x58,0x39,0x39,0x95,0x5d,0x4b,0x8e,0x1b,0xe9,0xf1,0xf6,0xa9,0xb3,0xfc,0xe6,0xe0,0x68,0x2c,0xbb,0xfa,0xd9,0x9b,0xc1,0x69,0xf3,0x5a,0x8f,0x67,0xd5,0x9c,0x11,0x1e,0x02,0x20,0x20,0xfe,0x4b,0xc9,0x8b,0x62,0x17,0x9a,0xfa,0x47 +.byte 0x7f,0xa2,0x8b,0xc1,0x3b,0x02,0x78,0x38,0xff,0xce,0xe1,0x54,0x40,0x3f,0x27,0x5c,0x9d,0xdd,0x56,0x38,0x48,0xea,0x39,0xbe,0xa0,0x76,0x43,0x82,0xef,0x74,0x50,0xdf,0xda,0x4c,0xca,0x47,0x46,0x7e,0xc5,0xff,0xce,0x66,0xdf,0xeb,0x5b,0x6e,0x45,0x77,0x19,0xac,0x01,0x1f,0x20,0xa1,0xad,0x01,0x5f,0x87,0x3e,0x3a,0xd0,0x83,0x13,0x17 +.byte 0x53,0x40,0xfe,0x26,0x99,0x42,0xfa,0x54,0xa8,0x82,0x79,0xa7,0x44,0xd0,0x9e,0x59,0x64,0x77,0xec,0x70,0x0e,0xcd,0xb9,0xb1,0xc2,0xe2,0x39,0x93,0xb7,0xd1,0xd5,0x67,0x9f,0xb0,0x5b,0xd9,0x50,0x8b,0x17,0xec,0xbc,0x83,0x64,0x35,0xaa,0x43,0x3f,0x4c,0x8c,0x56,0x83,0x76,0xa2,0x72,0x30,0xe7,0xe8,0x9f,0x88,0x35,0x8e,0x8d,0x11,0x31 +.byte 0x8e,0xb5,0x71,0x75,0x31,0xc8,0x28,0x15,0x50,0xe6,0x0a,0x00,0x4d,0x75,0x51,0x7c,0x33,0x14,0x96,0xff,0xe8,0xf3,0xa0,0xb1,0x9c,0xeb,0x9d,0x8a,0x45,0xcf,0x62,0x82,0xeb,0xce,0xea,0xa5,0xb9,0x10,0x83,0x54,0x79,0xf8,0xcf,0x67,0x82,0x1d,0xea,0xce,0x86,0xcf,0xc3,0x94,0xf0,0xe8,0xf4,0x80,0x8b,0x84,0x96,0x06,0x2e,0xe4,0x58,0x21 +.byte 0x98,0x42,0x1a,0xb7,0x8c,0x5d,0x30,0x15,0x83,0xe8,0x17,0xd4,0xb8,0x7b,0x90,0x57,0x35,0x72,0x6d,0x1b,0x7c,0xc0,0x88,0x0a,0xa2,0xea,0xcd,0x58,0xcc,0xf1,0xb4,0x8b,0xcd,0x66,0x3c,0xa5,0xb0,0xd4,0xc9,0xcc,0x42,0x1d,0xef,0x3b,0x42,0x22,0x9b,0xfb,0x45,0x24,0xcc,0x66,0xd7,0x67,0x73,0xb2,0x12,0x03,0xf6,0xa3,0x06,0x61,0xe2,0xab +.byte 0x91,0x8e,0x33,0x0b,0x9f,0x6a,0x80,0x5e,0x0f,0x68,0x41,0x5a,0x7e,0xd8,0xe2,0x32,0x50,0xc2,0x88,0x60,0xca,0xe3,0x23,0x86,0xff,0xdc,0x0c,0x19,0xbb,0xba,0x01,0xa3,0x41,0x89,0xf0,0x79,0x55,0x79,0xa6,0xa4,0x66,0x7b,0x46,0xde,0xac,0xae,0xb1,0xde,0xe1,0x1e,0x8d,0x62,0xc1,0xd6,0xeb,0x39,0x2f,0x1d,0x50,0x27,0x53,0xc9,0xea,0xb6 +.byte 0xd3,0x91,0x9b,0xdd,0xc1,0x68,0x8c,0xb6,0xe1,0x5e,0x9f,0xea,0xbe,0x98,0x88,0xeb,0xa8,0x77,0xf6,0x69,0x64,0xab,0x99,0xf3,0x7a,0x08,0xff,0x8c,0xa6,0x17,0x1b,0x2e,0x6e,0xcc,0xd8,0x33,0x30,0xef,0x5a,0x86,0x07,0x49,0xa5,0x13,0x08,0xbc,0xd6,0x88,0x7e,0x19,0xe0,0x1c,0x23,0xa9,0xe5,0x0a,0xa7,0xaf,0x8a,0xe9,0x81,0x3f,0xd8,0x99 +.byte 0xa6,0x01,0x6b,0xec,0x14,0x08,0x90,0xb1,0x76,0x16,0x3a,0xcb,0x34,0x0b,0x91,0x26,0xe9,0xec,0xe5,0xbc,0xd6,0xdc,0xf0,0xa9,0xfd,0xf2,0xe9,0xcc,0xa1,0x9d,0x7f,0x32,0x0d,0x0a,0x2a,0x92,0xff,0xc4,0x38,0xf8,0x9e,0x31,0x78,0x47,0xbf,0x3f,0x27,0x71,0xe1,0x7a,0x33,0x48,0x91,0xe8,0x8e,0x1a,0x66,0xcf,0xa1,0x61,0xc2,0x62,0x30,0x7c +.byte 0x69,0x35,0x21,0x67,0x9b,0xa7,0x1c,0x72,0x06,0xd8,0x28,0x94,0x6e,0x6d,0xf0,0x22,0x85,0xb4,0x6c,0x89,0xe8,0x2e,0x3a,0xc5,0xdc,0xe3,0xe3,0x0c,0x8a,0xba,0x1c,0x57,0x86,0xef,0x55,0x6a,0x24,0x59,0x5e,0x6e,0x47,0xb8,0xad,0xc5,0x10,0xff,0xbe,0x2d,0x93,0x09,0xfe,0x17,0x03,0x16,0x4d,0x4a,0x9a,0x15,0x38,0x94,0x38,0x18,0x45,0xa7 +.byte 0xcf,0xe4,0x16,0xd3,0x26,0x72,0x49,0xe7,0x89,0x9a,0xb4,0xc7,0x78,0xc3,0x18,0x3b,0xc8,0x08,0x9d,0x66,0x0f,0x48,0xc8,0x23,0x91,0x57,0x61,0xf1,0xf3,0x01,0x3e,0x0a,0xa3,0x4c,0x6c,0x34,0x5b,0x98,0x40,0x47,0x42,0xc1,0xeb,0x58,0x58,0xff,0x1f,0x4b,0x5f,0xf1,0x29,0x2e,0x7e,0x76,0x15,0x56,0x17,0x9c,0xe7,0x55,0x09,0x22,0x0a,0xa2 +.byte 0xd8,0xbf,0xd9,0x44,0x49,0xa9,0x24,0xd7,0x4f,0x12,0x04,0xa2,0x18,0x1c,0xdc,0x54,0xc0,0x22,0x27,0x3c,0xeb,0x1f,0x02,0xae,0xb3,0x33,0xb2,0xa2,0x84,0x23,0x76,0xc6,0x2b,0x94,0x53,0xae,0x7b,0xee,0xbb,0x81,0x64,0x8a,0x3f,0xe0,0x75,0x6b,0x2c,0xd5,0x60,0xad,0x49,0x0c,0xf8,0x65,0x64,0x1a,0x83,0xc7,0xb9,0xd9,0x01,0x5b,0xde,0xb0 +.byte 0x76,0x9b,0x1c,0x0d,0x89,0x2d,0xd5,0x09,0xc7,0xa9,0xbb,0x0a,0x54,0x5c,0xd4,0x5b,0xbf,0xbc,0x5e,0x00,0x29,0x0b,0x30,0x19,0x73,0x66,0xfd,0x3f,0xdb,0xd4,0x1b,0xd4,0xc0,0x27,0xde,0x49,0x90,0x5f,0x65,0x87,0x3c,0xc4,0x43,0xd0,0x49,0x76,0x64,0x39,0x88,0xd7,0x0e,0xfc,0x27,0x52,0xb1,0x8d,0xd0,0x27,0x29,0x84,0xe3,0x49,0xb9,0x0c +.byte 0x2d,0x4e,0x73,0x95,0x57,0xa8,0x07,0xa0,0xe1,0x5b,0x5a,0xb6,0xbc,0xa1,0x7f,0xfd,0x4b,0x9c,0x4d,0x7d,0x0c,0x5c,0x4c,0x4b,0x42,0x70,0xc3,0x0a,0xc1,0x89,0x12,0xb5,0x46,0x04,0x3c,0x56,0x25,0xc6,0x8f,0x49,0x7d,0x3b,0xf1,0xcd,0xfc,0xb8,0xa6,0x66,0xb1,0xc2,0xa3,0xa7,0x98,0x93,0x0e,0xdb,0xcd,0xce,0xdf,0x7f,0x68,0x5e,0xea,0xf2 +.byte 0x85,0x61,0x8f,0xd6,0x23,0xb4,0x5f,0x2f,0xf8,0x78,0x47,0x15,0x59,0x2d,0xca,0x35,0x0f,0xf5,0x91,0x74,0x3b,0x32,0xe1,0xcf,0x54,0x1b,0xf4,0x9d,0xdb,0x20,0x5e,0xf8,0x71,0x10,0xa3,0x31,0xf1,0xb8,0x98,0x8d,0x76,0x70,0xce,0x4c,0xed,0xd3,0x81,0x6b,0xd5,0x8d,0x73,0x5f,0x8c,0x66,0x7c,0x87,0x73,0xfa,0x20,0xbe,0xcd,0xba,0x41,0x88 +.byte 0x46,0xc3,0x38,0xc0,0xd9,0x08,0x79,0x30,0xda,0x7f,0x2a,0xc0,0x72,0x47,0xb0,0xc9,0x41,0x68,0xb1,0xe8,0xb4,0x86,0xcb,0x5d,0xb0,0x5b,0x7a,0x26,0xfd,0xf2,0x1b,0x4e,0x1f,0x4c,0x6a,0x8a,0x84,0xd4,0x07,0x2f,0xf4,0x06,0x73,0x3d,0x1c,0x55,0x04,0x6a,0xa5,0x8a,0xbb,0xaa,0x8a,0x8d,0x8f,0x05,0xcc,0x63,0x04,0xe0,0xc6,0x6f,0x6b,0xf8 +.byte 0x24,0x56,0xbb,0x9d,0xa9,0xe5,0x4c,0xac,0x9d,0xbe,0xfd,0x70,0x9d,0x1f,0x98,0xc4,0xfc,0xdb,0x3c,0x45,0xe7,0xbb,0xea,0x51,0xb6,0x56,0xe0,0x2c,0xb2,0x77,0x1b,0x80,0x9b,0x43,0xa7,0xb2,0x9a,0x40,0x8f,0xdb,0x2d,0x51,0x7b,0x2c,0x89,0xfd,0x14,0xf5,0x77,0xbf,0x40,0x3d,0x32,0xe0,0x10,0x32,0xcd,0xc4,0x3f,0xe2,0xe8,0xb4,0xdf,0xc2 +.byte 0x43,0x7a,0x0b,0x17,0x72,0xa1,0x0e,0xd6,0x66,0x35,0x8f,0xf4,0x21,0xf1,0xe3,0x46,0x13,0xd7,0xcd,0xc7,0x7b,0xb4,0x9b,0x39,0x1e,0x33,0x3c,0x18,0x15,0x7a,0xea,0x77,0xc5,0x57,0x4d,0xf9,0x35,0x8a,0xc1,0xb5,0x78,0x5d,0xc3,0x3e,0xd5,0xfd,0xb5,0x50,0xee,0x44,0x24,0xa2,0x55,0xb6,0xd8,0x3d,0x5d,0x75,0x2a,0x26,0x37,0xe7,0x85,0xb3 +.byte 0xff,0x70,0x5d,0x99,0x8d,0x99,0xba,0x9d,0x09,0x97,0xf2,0x67,0xe5,0xa3,0x86,0x06,0x21,0xb4,0x03,0x9b,0x63,0x76,0x1f,0xf8,0x09,0xd8,0x4e,0x22,0xcb,0x48,0xcf,0x79,0x72,0xc9,0x3f,0x84,0x5e,0xb8,0x39,0x87,0x27,0x92,0x1e,0x59,0xdf,0xc2,0xe6,0xd2,0xc4,0x5f,0xad,0x6e,0x9c,0xa4,0xec,0xd5,0x7d,0xf6,0x2b,0x9b,0x93,0x56,0xcd,0xa3 +.byte 0xc5,0xfa,0x82,0x39,0x46,0x29,0x57,0x43,0x08,0xe2,0xe1,0x3e,0x80,0x3b,0x8e,0x08,0xe5,0xc5,0xfe,0x05,0x17,0xaf,0xe0,0xf0,0xb7,0x5b,0x34,0x33,0x59,0xfa,0x93,0xbf,0x6a,0xb3,0x6c,0xbc,0x99,0x62,0x34,0x2c,0xf2,0x3b,0x62,0xf2,0x1c,0x48,0x07,0xc9,0x60,0x03,0xa5,0xe1,0x66,0x8d,0x84,0x36,0xc7,0xf9,0xc6,0x3b,0xa9,0xee,0x0f,0x48 +.byte 0xff,0xff,0xad,0x95,0x21,0xb5,0x12,0x63,0x7d,0x0f,0x0d,0x09,0x63,0x51,0x64,0x69,0xb4,0x95,0xd3,0x25,0xf0,0x3b,0x6d,0xc4,0xdd,0x8c,0x80,0x0d,0x3b,0xd2,0x4b,0xe0,0x67,0xcb,0xcd,0x7d,0x2e,0xbd,0x61,0x4b,0x0c,0x32,0x1f,0xfd,0xd2,0x31,0xed,0xa8,0xaa,0x98,0xf4,0x85,0x21,0xbc,0x08,0x14,0x2f,0xbb,0xbf,0x01,0xba,0x24,0x5e,0x5c +.byte 0xf3,0x72,0xed,0x05,0xec,0xf3,0xd1,0x9b,0xb0,0x63,0x8a,0x14,0xd1,0x9e,0xae,0x9b,0xce,0x4d,0x6c,0xb6,0x7a,0x78,0x9e,0x1d,0xcd,0x1e,0x50,0x66,0x26,0x70,0x74,0x2b,0x43,0x6a,0xc7,0xd7,0xe9,0xa2,0xcf,0xf3,0x09,0x9a,0x81,0x80,0x04,0xb8,0x5a,0x4f,0x2e,0x10,0x35,0xb2,0xb0,0xc6,0x40,0x97,0xa5,0x6a,0x24,0x5a,0x6b,0x97,0xc7,0xc0 +.byte 0x24,0x50,0x8d,0x65,0x21,0x25,0xce,0xb9,0x19,0xfc,0x40,0x08,0xcf,0xfd,0x1c,0xc4,0x30,0xd4,0x06,0x70,0xac,0x8a,0x3c,0x3f,0xfc,0xc3,0xeb,0xdd,0x43,0x56,0x4a,0xf6,0x50,0x92,0x9d,0xce,0x9c,0xea,0x15,0xdd,0x7c,0x5e,0x40,0xf5,0x7e,0x41,0x70,0xdd,0xc7,0x62,0x21,0x5a,0x20,0xc8,0x71,0x10,0x97,0xd5,0x12,0xfa,0x31,0x96,0xfb,0x38 +.byte 0x17,0x66,0x73,0x32,0x7a,0x93,0xf0,0x82,0xb9,0xf1,0x24,0xc5,0x64,0x0b,0xa9,0x24,0x4a,0x47,0xac,0xfb,0xf1,0x55,0xd7,0xb3,0x9a,0x64,0x63,0x0b,0x2e,0x13,0x9e,0x1a,0xee,0x21,0xd0,0x70,0x5c,0x0c,0x25,0xe7,0x38,0x23,0xd7,0x2f,0x6a,0x20,0x59,0xef,0x70,0xb2,0x8e,0xb4,0x15,0xee,0x6f,0x70,0xd0,0x75,0x19,0x9d,0x42,0xa7,0x17,0xad +.byte 0x99,0xaa,0x0d,0xa3,0x87,0x3d,0xf1,0x7b,0x0e,0xfa,0x62,0x9a,0x20,0x64,0x17,0x64,0x07,0xc2,0x84,0x13,0xb2,0x59,0x81,0x66,0x45,0xab,0x47,0x6d,0xfc,0x7b,0x60,0x05,0xac,0x30,0xb2,0x86,0x7e,0x34,0x6b,0xaf,0x37,0x00,0xa6,0x47,0x4c,0xb9,0x10,0xbd,0x9e,0xce,0x47,0x9e,0xc2,0x0e,0xfd,0x47,0xfa,0xd8,0x08,0xd1,0xc2,0xaa,0x6d,0x8c +.byte 0x91,0x2c,0x18,0x32,0x52,0x84,0x47,0x71,0x3b,0xc9,0xa1,0xf5,0xfc,0x90,0xb8,0x79,0xbf,0xe5,0x59,0x1b,0x91,0x22,0xcb,0xd3,0x87,0x7e,0xd4,0xb5,0x33,0xb2,0xfc,0x7c,0xee,0x22,0xfb,0xe8,0xb0,0x3c,0xa7,0x8b,0x05,0xd7,0x7f,0x17,0x52,0xbe,0xb6,0xe0,0x1e,0x47,0xce,0xfd,0x79,0xdf,0x16,0x5f,0x01,0x70,0x0c,0x47,0x5a,0x01,0x96,0x08 +.byte 0x3e,0x9b,0xc4,0xb2,0x58,0x73,0xc4,0x38,0xd6,0xf2,0x1b,0x0a,0x2c,0xb9,0x2a,0x96,0xb5,0x89,0x2d,0x33,0xdf,0xa4,0x5f,0x24,0x1b,0x79,0x0e,0xb6,0x9f,0xec,0x46,0xd3,0x27,0x4a,0xc1,0x26,0x94,0x95,0x41,0xd5,0xb3,0x84,0x74,0x62,0x47,0xc5,0x4d,0xb4,0xe2,0xe7,0xdb,0xc3,0xc3,0x7b,0x33,0x2a,0xbf,0x69,0xf6,0x5e,0xdc,0xfe,0xa4,0x81 +.byte 0x91,0xf3,0xa8,0x26,0x82,0x44,0x37,0xea,0xe1,0x20,0xff,0x52,0x33,0x5b,0x0b,0x6f,0xf8,0x33,0x4e,0x02,0x4d,0x38,0x93,0xcd,0xc0,0xfc,0x73,0x1a,0xf9,0xf6,0x9f,0x53,0xfc,0xf7,0xe2,0x4b,0x25,0xdd,0xa7,0x4d,0x1e,0x5c,0x17,0xc3,0xa0,0x41,0x1d,0x67,0x45,0xff,0xcb,0x41,0x49,0xc4,0x18,0x68,0x7e,0x7f,0xb6,0x6f,0xdb,0xbc,0x73,0x2f +.byte 0xc7,0x9a,0x46,0x8c,0x0b,0x57,0xa3,0xd3,0x0a,0x34,0xb7,0x27,0x67,0xbb,0xe1,0x64,0xa7,0x7e,0x79,0xac,0x4f,0x09,0x54,0x9b,0x43,0x5e,0x9a,0x33,0x02,0x45,0xdc,0x85,0x0b,0x59,0x8d,0x78,0xe8,0xd8,0xb5,0xd3,0x31,0x9d,0x2a,0x60,0x5b,0x91,0xed,0xf1,0xf1,0x37,0x3f,0xdb,0xda,0xd6,0xd1,0x8f,0x14,0x7e,0xe1,0xfc,0x92,0x60,0xa5,0x33 +.byte 0x86,0xef,0x29,0xbf,0x94,0x84,0x2b,0x24,0x20,0xb4,0x5e,0x23,0x34,0x08,0x63,0xc9,0xe6,0x80,0xa0,0x27,0x27,0x2f,0xab,0xc0,0x52,0x44,0x66,0x29,0x32,0x2e,0x91,0x96,0x02,0x1c,0x3b,0xb4,0x6e,0x33,0x49,0x5b,0x60,0x6f,0x14,0x93,0x65,0x0d,0x97,0x01,0xfb,0xf9,0x42,0x74,0xb6,0x21,0xf7,0xc2,0x5d,0xbf,0x91,0x2b,0xf5,0xb1,0x4e,0xe2 +.byte 0xd6,0x24,0x57,0x41,0x7a,0xcb,0xdd,0xb6,0x96,0x8b,0xfc,0x42,0x19,0x21,0x7f,0x41,0x32,0x3d,0x69,0x9b,0xee,0xda,0x97,0x45,0x26,0x71,0x0d,0x12,0xf0,0x20,0x7f,0x44,0x0f,0x4c,0xd2,0xd3,0x34,0x93,0xc7,0xe5,0xe7,0x83,0x62,0x13,0x0b,0x7d,0xc6,0xe4,0xd2,0xae,0x53,0x2e,0xd1,0x18,0x81,0xd0,0x81,0xf6,0xc0,0x98,0xaf,0x1d,0xb2,0x8a +.byte 0xcb,0xd3,0xde,0x1d,0x53,0x71,0x92,0x0e,0x4b,0x8c,0x7c,0x8e,0x65,0xf6,0xe2,0xc2,0x5a,0x4f,0x8c,0x59,0x0f,0x35,0x5e,0xe4,0x43,0x50,0xab,0xb7,0xdd,0xfc,0x66,0xf9,0xb1,0x9b,0x6b,0x1b,0xaf,0x2e,0x85,0xe6,0x3e,0x4c,0xa2,0xd4,0x55,0x47,0xb9,0x66,0x66,0x7b,0xa3,0xb2,0xd5,0x8a,0x8e,0x88,0x0e,0xfb,0x4e,0xad,0xf4,0x39,0xd2,0xd6 +.byte 0x39,0xef,0xe0,0xee,0x0f,0xf3,0x94,0x47,0xa7,0x32,0x24,0x9a,0xb0,0x82,0x08,0x67,0x00,0x3f,0xe6,0x95,0x76,0x84,0x0a,0x5c,0xb7,0x74,0xc1,0x64,0x5e,0x7c,0xba,0x0b,0x2e,0x6f,0x26,0xc3,0x20,0x2e,0x95,0xc1,0xf0,0x8c,0x55,0x4a,0x45,0x26,0xe6,0xf3,0x55,0x78,0xbd,0xd4,0xdb,0x07,0xbd,0xff,0x61,0x51,0xde,0x7f,0xdb,0x56,0x73,0x6b +.byte 0x9c,0xa4,0xb0,0x72,0xa7,0xd0,0x93,0x4d,0x1d,0x3a,0x92,0x78,0xde,0x77,0x65,0xe8,0x07,0x41,0x92,0xc1,0xbb,0x69,0x79,0x20,0x43,0xab,0x21,0x2e,0x6d,0xdf,0x43,0xeb,0x73,0x49,0x12,0x1f,0x53,0x75,0x01,0xed,0xce,0xf4,0x05,0x05,0x2b,0xc7,0x2a,0x65,0x29,0xe8,0xcf,0x5b,0xf0,0xc1,0x5b,0xd8,0xa8,0xac,0xbb,0xe3,0xac,0x29,0x0a,0x90 +.byte 0x79,0x2f,0x5b,0x92,0x14,0xf2,0xc7,0x2d,0xe5,0x33,0x6e,0x5e,0x31,0xe2,0xab,0xdf,0x21,0x71,0x4a,0x44,0xaa,0xc6,0xe9,0xb8,0x51,0x1d,0xe2,0xf3,0x07,0x19,0xa1,0x98,0x9e,0x8a,0xed,0xe4,0x9e,0x52,0x16,0x1f,0x2f,0xd3,0x4c,0x97,0x1e,0x38,0x49,0x84,0x2e,0x45,0xb5,0x4b,0x4f,0xfe,0xdb,0x25,0x3e,0xa9,0x6e,0x7d,0x60,0x3b,0xa7,0x7e +.byte 0xda,0x32,0x1a,0xd6,0x04,0xbe,0x0c,0x92,0x4e,0x6d,0x85,0xf9,0x9c,0x26,0x9a,0x88,0xf5,0x50,0x95,0x7b,0x9e,0x43,0x07,0x97,0xd4,0xdb,0xa0,0x6e,0x30,0x5d,0x44,0xa9,0x41,0xc2,0xdf,0xdf,0x37,0x35,0xc4,0x85,0x83,0x08,0xea,0x22,0xfa,0xae,0xdd,0x95,0xe5,0x35,0x47,0x23,0x86,0x27,0xfa,0x71,0x88,0xa0,0x12,0x00,0xe0,0xa7,0xd1,0x1b +.byte 0x5e,0x78,0x6f,0x38,0x30,0xa9,0x80,0x75,0xd7,0x61,0xcc,0xfd,0x33,0xd2,0xb8,0xf8,0xd7,0x12,0xf5,0x03,0xf9,0x53,0x6d,0x3b,0x6b,0xff,0x24,0x0a,0x3b,0xe8,0x2a,0xe9,0xae,0xb7,0xc3,0xe3,0x0f,0x26,0x71,0x55,0xc5,0x03,0x60,0xf4,0x47,0x01,0xa3,0x69,0xb2,0x98,0x75,0x5b,0x90,0x4a,0xf9,0x61,0x49,0xd6,0xc4,0xdb,0xab,0x04,0x0c,0x47 +.byte 0x1e,0x31,0x75,0xfa,0xa2,0xc5,0xfa,0x66,0x0c,0x4a,0x93,0xa0,0xea,0x56,0xf9,0x49,0xd4,0xc7,0xcc,0x2c,0xe5,0xdc,0xab,0x61,0x8e,0x0c,0xf3,0x2f,0xb5,0x9f,0x36,0xa1,0x05,0xab,0xb6,0xbc,0x4a,0x6d,0x97,0xe7,0x19,0xe5,0xfe,0x92,0xa5,0x94,0xd5,0xc0,0xf5,0x31,0xf6,0x8a,0xf7,0x24,0x62,0xdd,0x56,0x12,0x84,0xf5,0xc6,0xa0,0x37,0xa3 +.byte 0xfc,0xbd,0x16,0x2a,0xa6,0x36,0x8e,0xd4,0x29,0xfe,0xc4,0xc5,0xcb,0xdd,0xdd,0x8b,0x7e,0xa6,0x9d,0x08,0x28,0x10,0x6b,0xff,0xd7,0x79,0x48,0x35,0x2f,0xbe,0x34,0x9a,0xfb,0xd0,0x7d,0x5c,0xad,0xf0,0xde,0x96,0xea,0x2d,0xc5,0x8b,0xa9,0x7a,0x8b,0xbe,0x97,0xde,0x7a,0x95,0xc7,0x95,0xd9,0x86,0xde,0x3c,0x8d,0x15,0x8e,0x45,0x69,0x27 +.byte 0xd4,0x27,0xa8,0xe3,0xa9,0x1e,0xa0,0x95,0x74,0xf1,0x8b,0xbe,0x3b,0xff,0xa3,0xf6,0x23,0x78,0xd9,0xbd,0xc2,0x44,0x3a,0x93,0xb5,0xa6,0x87,0x7c,0x65,0xd1,0xd8,0xd5,0x43,0x2a,0xb2,0xc8,0x65,0x86,0x83,0x06,0xf7,0x33,0x88,0x3b,0xc0,0x2c,0xb3,0x3b,0x23,0xa3,0x67,0x15,0x49,0x09,0x02,0xbb,0x11,0x08,0xe3,0x37,0x9a,0x9b,0x67,0x8e +.byte 0x63,0xc3,0x8b,0xff,0x21,0xa6,0xbe,0x3b,0xa6,0x57,0xc1,0x56,0x2a,0x02,0xdb,0x24,0x50,0x4a,0x4f,0x60,0x49,0x03,0xcf,0xba,0x55,0x1c,0x64,0xfe,0x0c,0x58,0xb4,0xb0,0x89,0x91,0xd5,0xbc,0xbc,0x85,0xe6,0x96,0x32,0x89,0x1f,0xa0,0x48,0xd1,0x6e,0xa7,0x03,0x86,0x8a,0xf2,0x5f,0xc3,0x5a,0x57,0x8a,0xa3,0x4a,0x61,0x90,0x18,0xb2,0x0d +.byte 0xc7,0x94,0xb9,0x3e,0x40,0x8b,0x1d,0x54,0xd0,0x4c,0xe7,0x2a,0xd5,0x85,0xa7,0x93,0x07,0x10,0x58,0xc4,0x8a,0x18,0x0a,0x49,0x30,0x87,0x93,0x0e,0xcf,0xc7,0x95,0x9f,0xd1,0x3f,0x9b,0x06,0xe3,0xf9,0x4f,0x16,0x58,0x04,0xb4,0xf0,0xf0,0xf3,0x3a,0xab,0x4a,0x35,0xf1,0xec,0x23,0x15,0x0c,0x24,0xba,0x90,0xdc,0xd1,0xfe,0x47,0xca,0xb2 +.byte 0x95,0x33,0x30,0x45,0xba,0x18,0x15,0xec,0x58,0x36,0x02,0xdf,0x28,0x09,0x74,0x4b,0x09,0x01,0x24,0x0f,0x00,0x7b,0xb3,0x65,0x45,0x42,0x63,0x15,0xf8,0x50,0x8b,0x4f,0x28,0x73,0x03,0x3a,0x31,0xe5,0x0d,0x56,0x8f,0x6b,0x4b,0x9e,0xda,0x71,0xee,0x68,0xba,0x85,0x81,0x3d,0x5d,0x74,0x5e,0xda,0x60,0x87,0xf4,0x5a,0x38,0xad,0xc5,0x3f +.byte 0xb5,0x15,0x02,0x59,0x1c,0xd2,0x93,0x66,0x54,0x65,0xf1,0xe7,0x9b,0xf0,0x30,0x2d,0x9e,0xba,0xc5,0x86,0xf4,0xf6,0xc7,0x92,0x73,0x12,0x3b,0x28,0x21,0x1b,0x3d,0x84,0xc0,0x1a,0x7d,0x35,0x8b,0xd4,0x35,0x39,0x35,0xa6,0x51,0xd9,0x19,0x8b,0x92,0xa3,0xea,0x8c,0x7e,0x25,0x05,0x1f,0x1d,0x8f,0x4d,0xba,0xdf,0x20,0x8c,0x8d,0xe2,0xac +.byte 0xdd,0x3d,0xf1,0x04,0x3f,0x77,0x4b,0x8f,0x39,0x7d,0x01,0xb7,0x71,0x4b,0x7b,0xe1,0x6f,0xd4,0x28,0x1a,0x57,0x96,0x4d,0xe2,0x84,0xf6,0x64,0x10,0xbb,0x0f,0xbc,0xe0,0x19,0xed,0x92,0x9e,0x60,0x15,0x78,0xd1,0x30,0xc0,0x53,0x4b,0x94,0xca,0x4b,0x5a,0x44,0x8b,0xa9,0xda,0x2f,0x08,0x70,0x94,0xe4,0x54,0xe1,0x28,0x6e,0xdd,0x34,0x56 +.byte 0x54,0xb0,0xd4,0x87,0x00,0x72,0x1e,0x46,0x10,0x3a,0x27,0x5d,0xc6,0xb5,0x72,0x20,0x2b,0xbe,0x17,0x01,0xbb,0x04,0x11,0x16,0x7d,0xbf,0x91,0xd3,0x7b,0x44,0x58,0x13,0x2a,0x9c,0xda,0x9d,0x26,0x46,0xf5,0x5f,0x51,0xef,0x6c,0xf6,0x36,0xdb,0xb7,0x21,0xde,0xdb,0x87,0xa0,0xd8,0x60,0x24,0x86,0x6d,0x64,0x85,0x9e,0x94,0xd9,0x21,0x0d +.byte 0xed,0xda,0x33,0xea,0x3c,0xdf,0x74,0xe3,0xa5,0xc7,0xc7,0x9e,0xe5,0xb1,0x29,0xdf,0xfa,0x20,0x25,0xcd,0x13,0x08,0xee,0xe6,0xba,0xf1,0x62,0x39,0xcf,0xe3,0x29,0xb8,0xaa,0x65,0x43,0x8a,0x48,0xb5,0xb5,0x70,0x35,0x66,0x42,0xf4,0x32,0x70,0x0b,0x0c,0xa7,0x46,0x79,0xdf,0xb2,0x80,0x13,0x72,0x7a,0xeb,0xf9,0x52,0xcb,0xb8,0x9f,0x4b +.byte 0x4f,0x29,0x2b,0xb3,0x94,0x02,0x0a,0xe1,0x20,0xe5,0x91,0x15,0x6a,0xa1,0x0c,0x71,0x96,0x77,0x01,0x80,0xf7,0x51,0x0b,0xaf,0x54,0x9b,0x3c,0x7b,0x91,0xd2,0xbd,0xaf,0x13,0xa5,0x32,0x17,0x7c,0xca,0xd0,0x22,0xd5,0xe5,0x83,0x44,0x24,0x5c,0xcc,0x24,0x31,0xcd,0x81,0x4e,0x96,0xcd,0x60,0x9f,0x7a,0xe7,0x2e,0x89,0x16,0xd5,0x66,0x6b +.byte 0xac,0x31,0x11,0x7c,0x76,0xc6,0xde,0xbe,0x46,0x55,0x20,0xdf,0x9d,0x2c,0x33,0xa5,0x80,0x76,0xb1,0xc9,0x1c,0x84,0x17,0x4d,0x15,0xe6,0x6d,0xce,0xed,0xea,0xc7,0xe6,0xff,0x01,0x10,0x60,0x26,0xf7,0x63,0x5f,0x91,0x89,0x7e,0xc1,0x7c,0x76,0x67,0x7b,0x7e,0xfa,0x28,0xa0,0xa7,0x82,0x1b,0x28,0x82,0x6a,0x4f,0x78,0x61,0x48,0xbf,0x13 +.byte 0x0b,0x71,0x0c,0xad,0xee,0xd7,0xf8,0xcc,0x0f,0x77,0x74,0x7d,0x2b,0x8a,0x09,0xd8,0x47,0xa0,0xfc,0x45,0x40,0x24,0xf3,0xce,0xdb,0x81,0xa1,0x50,0x9e,0x0a,0xd0,0x58,0xf7,0xaf,0xf1,0x09,0x12,0xa8,0x24,0xb2,0x34,0x99,0x67,0x17,0x53,0x1f,0x9d,0x09,0x7b,0xcb,0x83,0x6e,0x6a,0x0b,0xbf,0x8f,0x6e,0x3d,0xdb,0x29,0xe5,0xd0,0x06,0xdb +.byte 0xb8,0xf2,0xf3,0x43,0x4e,0xa7,0xf3,0x73,0x93,0xe8,0xab,0x2f,0xc8,0x75,0xce,0x62,0xda,0x74,0x39,0x57,0xe4,0xe4,0xb1,0x41,0x8f,0x9d,0xda,0x43,0xb4,0x2c,0x4b,0xd5,0x1c,0x10,0xf0,0x29,0x6b,0x94,0x15,0x04,0x3c,0xd3,0x45,0x73,0x29,0xb3,0x60,0x87,0x93,0xdb,0xbf,0x60,0x4e,0xdf,0x4d,0xbb,0xde,0xb2,0x57,0x67,0x14,0x0d,0x0b,0x60 +.byte 0x63,0xd5,0xc6,0x81,0x82,0xd6,0x0c,0xe6,0x4c,0x43,0x13,0x02,0x74,0x56,0x20,0x6b,0x21,0x28,0xe6,0xe2,0x0b,0xc1,0x7a,0xc3,0x08,0x60,0x82,0xe0,0x4f,0xbf,0x1e,0x3f,0xf0,0xa9,0xb2,0x2e,0x0c,0xbf,0xd6,0x03,0x1d,0x0d,0xd6,0x1c,0x36,0xb5,0xb2,0x14,0x56,0x21,0xc2,0xe0,0x1e,0xff,0xee,0x8a,0x70,0xae,0x3f,0x1e,0xe5,0xac,0x05,0x46 +.byte 0x6b,0x81,0x32,0xce,0x50,0xbb,0x82,0x66,0x32,0x93,0x46,0xf7,0xee,0x77,0x1c,0x9a,0x2f,0x31,0x60,0xa2,0x09,0x7c,0x14,0xd9,0x81,0xe9,0x19,0x27,0x31,0x5e,0xa0,0x98,0x71,0x42,0x2f,0x30,0x71,0xd6,0x31,0x94,0xe0,0x61,0xed,0x50,0x66,0xfa,0xba,0x12,0x5e,0xc6,0xc8,0x67,0xe5,0x8e,0xfd,0x34,0xa9,0xeb,0xde,0x25,0x43,0xbf,0xe7,0xb5 +.byte 0x16,0xf5,0x62,0x66,0x5d,0x0b,0x13,0x9a,0xd4,0x8c,0x2b,0x8f,0xe6,0x91,0x33,0xcb,0xa0,0x70,0x48,0x3e,0x22,0x7d,0xe4,0xf3,0x75,0xc9,0x49,0x82,0x50,0xc9,0x90,0x04,0x32,0xab,0x99,0x6e,0xf1,0xf0,0x0b,0x60,0x80,0x35,0x25,0x45,0x88,0xe9,0x82,0x06,0xe1,0xbb,0x85,0x11,0x40,0xf8,0x0e,0xbd,0x19,0x7a,0xdd,0x78,0xf9,0xc2,0x46,0xe4 +.byte 0xb5,0x27,0xfb,0xb6,0xba,0xbc,0x7d,0xb8,0x27,0xe7,0xbf,0xfe,0x8e,0xfe,0x7e,0x83,0x63,0x43,0x92,0x26,0xf0,0xbb,0xde,0xb6,0x93,0x4f,0x55,0x0c,0x07,0x99,0x3c,0x98,0xa1,0x8c,0x73,0xc1,0x4c,0x9a,0x09,0xa8,0xea,0x16,0x0b,0x49,0x2a,0x43,0xee,0x90,0x61,0x6f,0x09,0x1b,0xc3,0x2d,0x62,0x4b,0xfc,0x90,0xa1,0x8e,0x84,0x2e,0x90,0x8d +.byte 0x5f,0x80,0xff,0x6a,0x3c,0x61,0x0f,0xf2,0xac,0x70,0x20,0xc1,0xf2,0x85,0xcf,0x94,0xc8,0x94,0xe7,0xa0,0x04,0xdf,0xaf,0xef,0x26,0xd2,0xbc,0x07,0x70,0xc1,0x48,0xd6,0x87,0xd6,0xbe,0xea,0x95,0x6a,0xce,0xa2,0x48,0xac,0x46,0x46,0xb1,0x74,0x70,0x96,0x6c,0x26,0x58,0x75,0x9d,0x84,0xd7,0xd9,0x17,0x9a,0x46,0xe9,0xd7,0x3d,0xde,0xfd +.byte 0x7e,0xf4,0xd8,0x7e,0xf8,0x8f,0x1c,0xb5,0xfb,0xe9,0xc4,0xca,0xba,0x52,0x5f,0x17,0xee,0x75,0x7d,0x1d,0x50,0x16,0x9f,0x16,0x1e,0x00,0x8b,0xc1,0x2f,0xab,0x73,0x65,0x88,0x7b,0x80,0xa6,0x71,0xb7,0xfb,0xb0,0xda,0xd1,0x96,0x18,0x5c,0x48,0x6e,0x18,0x45,0x59,0x45,0xef,0x5c,0x65,0x35,0x99,0x5e,0xb9,0xd4,0x1a,0x07,0x7d,0x1e,0xa6 +.byte 0x69,0x42,0x9d,0xfa,0xec,0x02,0xdc,0xc4,0x19,0x6b,0x9c,0xb1,0x5e,0xa3,0xb4,0x6d,0xb4,0xa6,0x25,0xa8,0xe4,0x3f,0x3d,0x6e,0x2c,0x95,0xf7,0xcd,0xa5,0x4e,0x32,0xca,0x7e,0xe0,0x7b,0x11,0xf9,0x0a,0xe1,0x61,0x41,0x60,0xec,0xb3,0xb1,0x92,0x89,0x33,0x17,0xe9,0xaf,0x70,0x7f,0x1c,0x07,0xb5,0x24,0x3a,0x37,0x84,0x38,0xf5,0xb6,0x11 +.byte 0xfc,0x0c,0x12,0xc1,0xfc,0xa9,0x82,0x67,0x4d,0x17,0xe8,0xea,0xd0,0x62,0x17,0xb2,0x9c,0x59,0x01,0x87,0xfb,0x54,0x8e,0xa7,0xa5,0x85,0xa9,0x8a,0xec,0xfe,0x29,0xc0,0x73,0xc6,0xa0,0xbf,0x66,0x9a,0xc5,0xf8,0xee,0xa4,0xcb,0x09,0x44,0x74,0xfe,0x32,0xf5,0x42,0xea,0xf0,0xa6,0xec,0x74,0xea,0x14,0x5c,0x43,0x51,0xfa,0x3a,0x48,0x1e +.byte 0xa0,0x2e,0x59,0x2e,0xdb,0x3a,0x19,0xfe,0x1f,0x95,0x25,0xee,0x27,0x2b,0x99,0xb4,0xe1,0xd0,0xe6,0x33,0x91,0xa1,0xaf,0x30,0xa0,0x89,0x00,0x3c,0x13,0x31,0x18,0x70,0x90,0x42,0x55,0x0a,0xc9,0xc5,0x0c,0x43,0xa5,0xee,0xd6,0x90,0x07,0xae,0xc4,0x8c,0xdc,0xe4,0x07,0xbb,0x61,0x70,0xd1,0x10,0xe4,0x68,0x96,0x70,0x78,0xab,0xe9,0x3a +.byte 0x6e,0xc7,0x75,0x93,0xa0,0xba,0xff,0x6a,0x2d,0x57,0xaa,0x93,0x09,0xc3,0x6b,0x81,0xf3,0xde,0xc2,0xee,0xac,0x86,0x0a,0xfb,0xad,0xdb,0x6f,0x2a,0xa0,0x15,0x7b,0x96,0x77,0x38,0xf8,0x86,0x51,0x33,0x7a,0x6f,0x1c,0xf8,0xd5,0x15,0xcd,0x76,0x7f,0x37,0x68,0x82,0xdf,0xab,0xc3,0xdb,0xbe,0xeb,0x2b,0xa8,0x34,0x72,0x20,0x34,0xfb,0x12 +.byte 0x64,0x17,0x05,0x64,0xc0,0xa1,0xca,0xd3,0xac,0x27,0xc2,0x68,0x28,0x40,0x42,0xe2,0x0a,0xdd,0xd7,0xd6,0xf6,0x92,0x95,0x3c,0x10,0x17,0x4e,0xef,0x75,0xae,0x98,0x2d,0x10,0xc8,0xa8,0xac,0x15,0xf7,0x5b,0x81,0xc1,0xdf,0x5e,0xbe,0x88,0x49,0xe3,0xd1,0x88,0x1c,0xcb,0xce,0x20,0x01,0x12,0x60,0x57,0x0b,0xf6,0x32,0x57,0xaf,0x59,0xef +.byte 0xc9,0xe7,0xbf,0x62,0xf3,0xb6,0xe6,0x5c,0xee,0x36,0x7e,0x11,0x90,0xd1,0xeb,0xfa,0x62,0x0b,0xc6,0xf3,0x1a,0xd5,0x8b,0x95,0xec,0xb4,0x38,0xfe,0x45,0xb0,0xb5,0xff,0x84,0x0a,0x27,0x3a,0xa2,0x5a,0x2a,0xc9,0xa4,0xc0,0x11,0xc6,0x61,0x13,0xb7,0x53,0xa3,0x47,0x45,0x6d,0xc6,0xa9,0x00,0xd1,0x40,0xf4,0x77,0xac,0xb3,0xd3,0x26,0x99 +.byte 0xf1,0x36,0x59,0x28,0xb4,0xd0,0xdd,0x0e,0xed,0x53,0x33,0x45,0x71,0x9c,0x5c,0x11,0x27,0x2c,0x2f,0x10,0x9e,0x5b,0x8a,0x5b,0xc5,0x1f,0x36,0xc9,0x2a,0xba,0xc7,0xa5,0x31,0xd7,0x9f,0x2b,0x0a,0x09,0xcb,0x7c,0x4f,0xa2,0xdc,0xc5,0x64,0x0d,0xe6,0xfe,0xb0,0x9d,0x3b,0xf0,0xa7,0x19,0x8c,0x84,0x21,0x6b,0x9e,0x1c,0xb5,0x7b,0x66,0x77 +.byte 0xd0,0x85,0xb4,0x22,0x93,0x6e,0x84,0x29,0x9b,0x60,0x90,0x37,0x9d,0x8c,0x94,0x95,0x95,0x3b,0xf1,0x2d,0x56,0x5b,0x53,0x60,0x2d,0xe5,0x7f,0x80,0x71,0x56,0xa7,0x6e,0x66,0x76,0x1f,0xaa,0x0d,0xba,0xfb,0x0e,0xcf,0x20,0x68,0x74,0x2b,0x99,0x13,0xe1,0xa8,0x33,0xc9,0xf6,0xbc,0xd3,0xf4,0x46,0x01,0x02,0x85,0x27,0xf4,0x20,0x97,0xa3 +.byte 0xba,0xbc,0x47,0x30,0x48,0xed,0x60,0xe6,0xca,0xbf,0x76,0x8c,0x2c,0x6a,0x43,0x32,0xfd,0x90,0x04,0x95,0xc2,0x42,0xcb,0xca,0xc4,0x33,0xe1,0xd3,0x23,0x92,0xa1,0xde,0x09,0x38,0xce,0x00,0x93,0xb3,0xed,0x82,0x8e,0xfb,0xce,0x4c,0x9a,0x10,0x6e,0xce,0x4a,0x37,0x05,0x75,0x37,0x58,0xc3,0x8e,0x57,0x50,0xa0,0x7d,0x80,0x2d,0x51,0xea +.byte 0x08,0xcd,0x1b,0xd2,0x81,0x85,0x19,0xc1,0xe8,0xce,0x31,0x18,0xcf,0x54,0x37,0x96,0x77,0x3d,0x64,0xfb,0xc2,0xa9,0xdb,0xb8,0x37,0x03,0x83,0x34,0x3c,0x25,0x6a,0x22,0x33,0xfa,0x27,0x70,0xc7,0x0a,0x27,0x12,0x1e,0xb3,0xd0,0x59,0x6f,0xa3,0xc5,0x73,0x95,0x4c,0x1f,0xf1,0x3c,0xb3,0xc2,0xa2,0xc6,0x45,0x17,0x53,0xa8,0xfc,0x00,0xff +.byte 0x77,0x40,0x28,0xd2,0x53,0x90,0x92,0xe9,0x86,0x6c,0xa5,0x40,0xce,0xbc,0x79,0x6f,0x8f,0x12,0xef,0x1b,0x38,0x1f,0xb3,0x24,0xf0,0x75,0x17,0x20,0x9e,0x03,0x9c,0x2b,0x51,0x57,0x93,0x44,0xce,0x74,0xc9,0x12,0xe7,0xcb,0x2f,0x5e,0x1b,0x95,0xf2,0x4d,0x2e,0x51,0x8d,0x52,0xd5,0x21,0xe3,0x1b,0x33,0xe7,0xf2,0x18,0x61,0xa2,0x53,0xdb +.byte 0x73,0xaa,0x6a,0x6c,0xf9,0xf4,0xef,0x3d,0x40,0xa3,0x00,0x80,0x82,0xed,0xe6,0x66,0xd1,0xd6,0xe9,0x93,0xd8,0x92,0xfa,0xdf,0xf9,0x9c,0x7a,0xfb,0x2b,0xc7,0xa7,0x73,0x67,0x2b,0xed,0x76,0xb1,0x52,0xaa,0xcf,0x34,0x84,0xa1,0x6d,0x56,0x85,0xef,0xcb,0xbc,0xa3,0xc6,0xf3,0x5a,0x88,0x04,0xd5,0xd8,0xf1,0x7b,0xf8,0x11,0x6f,0xa0,0x44 +.byte 0xa5,0x0f,0x76,0xed,0xd7,0x98,0xe3,0xda,0xb8,0x1b,0xc7,0xe6,0x89,0x08,0x19,0x1f,0xf8,0xe3,0x32,0x32,0xa5,0x3c,0x71,0x9f,0x11,0xde,0x50,0x29,0xb0,0x54,0x7e,0x3b,0x5e,0xeb,0xf7,0xab,0xa8,0xa0,0x35,0x96,0xc7,0xc5,0xea,0x60,0xc0,0x37,0xca,0x61,0x55,0x96,0xac,0xb4,0xd0,0x29,0x9a,0x1a,0x3f,0x9e,0xf5,0xf5,0x3d,0xed,0xc5,0x7c +.byte 0x2c,0x9d,0x67,0xf8,0x4d,0x82,0x6e,0x2a,0x9a,0xfc,0x5f,0xdc,0x02,0xb0,0x3d,0xa5,0x1c,0x08,0x5d,0x4a,0xaa,0xd0,0x38,0xfb,0xbc,0xbb,0x7f,0x37,0xfb,0xec,0xc0,0x62,0x79,0xaa,0xde,0xfd,0x23,0x9c,0x4c,0x4a,0xe1,0x48,0x40,0x36,0xc0,0x0a,0x6f,0x43,0xb7,0xad,0x4c,0xf6,0x56,0xb5,0x44,0xf4,0x72,0xcd,0x13,0x10,0xea,0x0d,0x24,0xc1 +.byte 0xa9,0x36,0x3b,0x36,0xf2,0x6e,0xf9,0x0a,0x67,0xcd,0x02,0x67,0xb3,0x5c,0x63,0x3a,0x7c,0xc1,0x3b,0xf2,0x1d,0x3d,0xf1,0xff,0xbf,0xf7,0x97,0x9f,0x30,0x1f,0xaa,0xd8,0xdb,0x53,0x9b,0x0a,0xbd,0x38,0xd8,0xb6,0xf1,0x4a,0x78,0x1a,0xc2,0x46,0xd2,0x0c,0xa8,0xcd,0x7b,0x39,0xc7,0x42,0x55,0xc8,0x3e,0x02,0x1d,0xf4,0xad,0x55,0x01,0x6a +.byte 0x11,0x2d,0xfa,0x67,0x48,0xae,0x45,0x31,0x9b,0x09,0x7d,0xd9,0xdd,0xaf,0x5c,0xd5,0x40,0x51,0x2a,0xa1,0x0f,0xb3,0x6e,0xc2,0x94,0xfe,0xde,0x70,0xaf,0x6c,0xea,0x5f,0x7d,0x3c,0x72,0x85,0x86,0x24,0x20,0x0a,0x7a,0xe7,0x69,0x32,0x66,0x7d,0x34,0x13,0x60,0x62,0xc7,0x68,0x32,0xde,0x34,0x30,0x36,0xc8,0x8e,0xb7,0x13,0x66,0xf1,0xce +.byte 0x5f,0x7a,0x3a,0xfe,0x62,0xd6,0x72,0xb6,0x1b,0x80,0x43,0x8a,0x3e,0x13,0x15,0xe4,0x1c,0x7b,0x08,0x70,0x0b,0x6e,0xb3,0xfe,0x07,0x91,0x23,0x21,0x57,0x48,0xc6,0xa9,0xa3,0xa8,0xc7,0x19,0x89,0x8a,0x49,0x12,0x25,0x88,0xd2,0x11,0xa5,0xa8,0x9e,0x0e,0xa7,0x71,0xfe,0xaf,0x88,0xee,0xa7,0x1c,0x3b,0x27,0x27,0x7e,0x79,0x92,0xed,0x77 +.byte 0x74,0x65,0xbd,0x46,0x41,0x25,0xd9,0x8b,0x21,0x73,0x9f,0xaa,0x35,0xa0,0x22,0xb3,0xc8,0x71,0x28,0x72,0xd2,0xcb,0xf4,0x2a,0x06,0x0a,0x63,0x96,0x55,0x2e,0x83,0x0b,0xe8,0x07,0x99,0x9d,0x59,0xde,0xde,0x62,0xbd,0xb4,0x3e,0x70,0x15,0xed,0x95,0xa8,0x2f,0xb7,0xa2,0xb6,0x65,0x56,0x9d,0xe5,0x81,0xa0,0x05,0x5b,0xce,0x00,0xd4,0xb9 +.byte 0x28,0x5a,0xc1,0x9a,0x74,0xc6,0xd7,0x27,0xdd,0x7c,0xbe,0xe8,0x0d,0x47,0xfc,0x81,0x05,0x6b,0x4f,0x68,0xc7,0xcc,0x5d,0xd5,0x66,0x83,0x34,0x72,0x35,0xab,0x39,0x64,0x19,0x67,0xbd,0xff,0x15,0x44,0x20,0x18,0x2a,0xaf,0xbc,0x58,0x94,0xdb,0x18,0x50,0x55,0x11,0x6a,0xc4,0x1d,0xee,0xe2,0xe0,0x75,0x73,0xf1,0xa1,0x83,0xf4,0xcb,0x40 +.byte 0x96,0xf4,0x77,0x45,0x61,0x8b,0x1a,0x8c,0x0c,0xfc,0xd2,0x7e,0x0b,0x1e,0x18,0xd2,0x95,0xa5,0x4c,0x5b,0xd6,0x9d,0x40,0x8b,0xc0,0x51,0xe8,0x2d,0xe5,0x16,0xbf,0xd7,0x98,0x8a,0xa0,0x46,0x1f,0xc4,0xe9,0x12,0x31,0x40,0xc5,0x2d,0x59,0xf8,0x9b,0x5f,0xe3,0x3a,0x10,0xdf,0xda,0x72,0x9e,0xab,0x13,0x7b,0x8f,0xc8,0x52,0x9f,0x58,0x45 +.byte 0x7a,0xe6,0x3a,0xbb,0xdd,0x1d,0xc7,0x3b,0xc4,0x26,0xdc,0x99,0x29,0xf2,0x74,0x16,0x84,0xe9,0x8a,0x86,0xc0,0x1e,0x49,0x96,0x2f,0x5c,0x2a,0x49,0x71,0x88,0xe6,0x82,0xb2,0x18,0x88,0xc1,0x86,0xcb,0x26,0x3c,0xa5,0x50,0x31,0x22,0x9a,0x8f,0x45,0x2b,0xde,0xf0,0x86,0x8e,0x13,0x86,0xc4,0x4a,0x9b,0x35,0x27,0x93,0x0b,0x13,0xc8,0xef +.byte 0x96,0x74,0x97,0x85,0x09,0xc0,0xa0,0x32,0xfe,0xc3,0xe3,0x92,0x2e,0xe8,0x54,0xbd,0xc2,0x23,0xeb,0x4b,0x02,0xf5,0x5a,0x0b,0x0d,0x58,0x50,0x45,0xe7,0x01,0xd4,0x17,0x00,0xdb,0x0d,0xd4,0x2e,0xa0,0xde,0x38,0xf4,0xb1,0x1e,0xd0,0xf0,0xa3,0x6b,0x21,0x0c,0xbd,0xae,0x84,0x7e,0x42,0x36,0x4f,0x2e,0x46,0xae,0x23,0x91,0xb9,0x06,0xac +.byte 0x86,0x7f,0x29,0xca,0xfb,0xe9,0xde,0xdb,0x90,0xfe,0x6f,0xbc,0xdb,0x3c,0x48,0x3d,0x6e,0x06,0x68,0x49,0xbb,0x43,0x8d,0x9d,0xc4,0x5f,0x45,0xcb,0x77,0x28,0xe0,0x35,0xd1,0xb4,0x25,0xb2,0x45,0x6d,0xb4,0x89,0x53,0x26,0x33,0x98,0x83,0x45,0x9d,0xf5,0xad,0xf9,0xa7,0x59,0xb6,0x6e,0xa8,0x25,0xa5,0xef,0xee,0xf6,0x6a,0xd5,0x6c,0x60 +.byte 0x9a,0xea,0x78,0x9e,0xe4,0xa2,0x29,0x0b,0x70,0xb3,0x6e,0x3a,0xfd,0x07,0xc7,0x7f,0x1b,0x07,0xc7,0xca,0x1b,0xb8,0x08,0xe1,0xc9,0x94,0xb2,0x62,0x7c,0x04,0x96,0xa6,0xda,0x65,0x28,0xfd,0xf9,0x70,0x22,0xb7,0x21,0xd3,0xa6,0x38,0x0f,0x1e,0x88,0x7e,0x73,0xec,0x04,0x99,0x8b,0x23,0x91,0x13,0xe6,0x4f,0x74,0x81,0xcc,0x1f,0xdd,0xaf +.byte 0x58,0xc4,0x80,0x00,0x4d,0x1d,0xbe,0x84,0x7d,0xfe,0x85,0xe7,0x77,0x20,0x3c,0x65,0x4e,0x0e,0x2e,0x5d,0xc1,0xd9,0xcb,0xf7,0xbb,0xc8,0x8d,0xbf,0x16,0xa8,0x1e,0x63,0xf5,0x10,0x5e,0xa5,0x9c,0x63,0xb6,0x9a,0xeb,0x98,0xa8,0xb1,0x59,0x82,0x66,0x51,0xae,0x3c,0xfc,0xa8,0x11,0x92,0xf4,0x45,0x88,0x7c,0x03,0x6f,0xe6,0x87,0xe4,0xa8 +.byte 0x79,0xbf,0xb3,0x0d,0xd6,0x0b,0x8d,0xa3,0x16,0x2a,0xfb,0x79,0xb9,0xe7,0xdb,0xa7,0xdb,0x94,0xd3,0xe6,0x3a,0xdd,0xe9,0x5f,0x30,0x7d,0x68,0x90,0x35,0xfd,0x18,0x91,0x8e,0xc5,0x12,0xd6,0xf9,0x98,0xa0,0x5b,0xcd,0x81,0x76,0x84,0x08,0xd0,0xab,0x59,0x2d,0x3b,0x8a,0xf9,0xd9,0x95,0xde,0x8b,0xbb,0x92,0xef,0x35,0xc3,0x3e,0x46,0x73 +.byte 0xf3,0x3b,0x09,0xbf,0x22,0x2b,0x9c,0x0f,0x70,0x9a,0x16,0x0e,0x4b,0xa7,0x1a,0x96,0x98,0xb7,0x5a,0x40,0x06,0x81,0xf4,0xac,0xa6,0xe6,0xab,0xf2,0xda,0x87,0x18,0x61,0xcb,0xc1,0x67,0xbd,0x2f,0x6f,0x06,0x21,0xaf,0x73,0x98,0xe1,0x3f,0x7a,0x17,0x7f,0x44,0xcb,0x1d,0xdd,0x60,0xb3,0x2c,0x58,0x20,0x8a,0x04,0x74,0x56,0x9b,0x26,0x51 +.byte 0x61,0xb0,0x07,0x50,0x53,0x83,0x31,0x42,0x59,0xb3,0x33,0xfa,0xfe,0xbc,0xad,0x7f,0x99,0x9b,0x86,0xf1,0xaa,0x85,0xf1,0xbb,0xc0,0x0c,0x91,0x8d,0x1a,0x0f,0x8f,0x9f,0xfe,0x62,0x2b,0x35,0xae,0xcc,0x8c,0x09,0xe3,0x29,0x96,0xd1,0xbe,0x7f,0x25,0xd6,0x03,0xf0,0x4c,0x53,0xad,0x5b,0x56,0x66,0x68,0x9a,0xa3,0xc4,0x07,0x71,0xde,0x49 +.byte 0x82,0xbb,0xf7,0x9a,0x2b,0x96,0xcf,0x50,0xf6,0x00,0xf7,0x0b,0x27,0xdd,0xf5,0xf6,0xc5,0xc8,0xbd,0x2a,0xa2,0x06,0x2c,0x42,0x3f,0xa0,0xf8,0xcc,0x1d,0x64,0xcf,0xbc,0xb4,0xc4,0x63,0xde,0x6b,0xd3,0xb4,0x61,0xdf,0xbd,0x73,0x50,0x34,0xc3,0x20,0x45,0x06,0x73,0x9b,0xf0,0xfb,0xa6,0x2b,0xec,0x92,0x32,0xa9,0x1f,0x4f,0x1e,0x38,0x78 +.byte 0x2a,0xd2,0x7c,0x1d,0x89,0xf9,0x70,0xbc,0xef,0x09,0x77,0xd3,0x6a,0x56,0xa1,0x8b,0x4b,0x23,0x1b,0xb1,0x2f,0xec,0x84,0xe5,0x59,0xc5,0x20,0x23,0xbc,0x3f,0x0a,0x43,0x97,0x1c,0x5e,0xf7,0xee,0xfe,0x0b,0x2a,0x42,0x08,0x2a,0x39,0x91,0xce,0x8a,0x33,0x9f,0x63,0x77,0x6d,0xf6,0xf3,0x0e,0x1d,0xb3,0xfb,0xcf,0x2f,0x7f,0x95,0xc2,0x71 +.byte 0x1c,0xa0,0x0b,0xc6,0xb8,0xde,0x4d,0xd8,0xcc,0x4c,0x4f,0xaf,0x07,0x87,0x6d,0x3b,0xab,0x95,0xab,0xa1,0x6a,0x50,0x9f,0x7c,0x35,0xb6,0x65,0xdd,0xe3,0x06,0xe5,0xb3,0x42,0x5f,0x4d,0xe5,0x3e,0xfa,0x6c,0xdf,0x19,0x58,0xd1,0xf6,0xc6,0x94,0x1c,0xce,0x30,0x90,0xd3,0xeb,0xa3,0x7c,0xe5,0x3f,0x57,0x99,0x2e,0x22,0x0a,0x94,0x2f,0xfe +.byte 0x39,0x16,0xe6,0xfa,0xd0,0xb5,0xf9,0xb4,0x88,0x61,0xa4,0xa8,0xc3,0xb8,0xb7,0x52,0xaf,0x90,0xc1,0xe0,0x19,0x78,0x04,0x2b,0x71,0x04,0x03,0x2f,0x63,0xbe,0x40,0xf5,0x82,0x3b,0x1b,0x6b,0xde,0x6d,0x1e,0x86,0x87,0x82,0xc3,0x31,0x97,0x20,0xdd,0xdd,0xce,0x61,0x64,0x99,0xf6,0xbe,0xbf,0xec,0x37,0x54,0x8b,0x92,0x29,0xda,0xc5,0x7b +.byte 0x4d,0xc5,0xaf,0xb8,0x4e,0x4b,0x4a,0x2b,0x35,0x30,0xf5,0x19,0x9e,0x32,0xd8,0x2e,0xc1,0x19,0xfe,0xd1,0x61,0xb0,0xaa,0x05,0x58,0x15,0xd9,0x0e,0x4e,0xca,0x4e,0x10,0x83,0xe6,0xe6,0x57,0xe8,0x8d,0x13,0xb4,0x6f,0x85,0x59,0xf2,0x83,0xc8,0x37,0xaa,0xa2,0xe5,0xc8,0x77,0x06,0x82,0x21,0x5d,0x84,0x58,0x67,0x9b,0xcc,0x9c,0xfc,0x1b +.byte 0x28,0x2f,0xac,0xc8,0x96,0x91,0x26,0x46,0x42,0x2b,0x68,0x57,0xb0,0x79,0x1e,0xb1,0x9b,0x92,0x2c,0xeb,0x67,0x00,0xd4,0x26,0x7d,0xca,0x45,0x97,0x55,0xea,0x2a,0x20,0x70,0x7c,0x20,0x14,0x38,0x40,0x3d,0x4f,0xf5,0x3a,0x1f,0x0a,0xe3,0x9a,0x48,0xcc,0xb2,0x7d,0xee,0x5b,0x48,0x90,0x0d,0x12,0x77,0xd8,0xd3,0xb6,0xd7,0x66,0x9e,0x48 +.byte 0xbb,0x92,0xc1,0x7c,0x4e,0x90,0x4d,0xd5,0x96,0x99,0xea,0x86,0x2d,0xb9,0x5a,0x50,0x05,0xc2,0x6b,0xa7,0x0c,0x43,0x44,0x22,0x09,0xb9,0xc0,0x56,0x47,0x5f,0xdf,0xaf,0x6b,0x91,0xe2,0xd7,0x45,0x77,0x17,0x7a,0x71,0x6d,0x27,0x93,0xe2,0xc6,0x10,0x2f,0xc8,0x3b,0x75,0x78,0x11,0xae,0x07,0xe6,0xba,0x64,0xd4,0x06,0xfa,0xf9,0x1d,0x74 +.byte 0x9e,0x4f,0x6d,0x02,0xfc,0x40,0x80,0x9a,0x2e,0xd4,0x15,0x32,0x15,0xe8,0x97,0x0a,0xd4,0x65,0x6a,0x87,0xd3,0x66,0x4b,0xb8,0x66,0x84,0x8e,0xb9,0x4b,0xa7,0xcf,0x58,0x13,0x66,0x3a,0x4e,0xa5,0x76,0x17,0x13,0x92,0x79,0x42,0x67,0x6d,0xb6,0x65,0xec,0xc8,0xb5,0x5f,0x17,0x2a,0x2d,0x4b,0x19,0xe9,0x00,0x6e,0x38,0xaf,0xe9,0x06,0xb6 +.byte 0xe8,0x99,0x69,0x8a,0x74,0xe7,0x7e,0x70,0x69,0x4b,0xbc,0xce,0x5d,0x61,0x94,0x1b,0x47,0x41,0x38,0x5f,0x2e,0xcf,0x2b,0xe1,0xcd,0xa3,0x98,0x71,0xf7,0x09,0x65,0xfe,0x5f,0x62,0x4b,0x9e,0x91,0x88,0x35,0xa2,0x66,0x02,0x1d,0xc9,0x93,0x0c,0x19,0x50,0x4b,0x95,0x71,0x79,0xdd,0x74,0xe1,0xda,0x5a,0xb7,0x38,0x70,0x61,0x18,0x3f,0x68 +.byte 0x08,0x34,0xd8,0xfe,0xbb,0xd1,0xbf,0x57,0xed,0xc2,0x52,0x6d,0x54,0x3e,0xcb,0x0c,0x32,0xc7,0x09,0xa9,0x31,0x10,0xe8,0xbd,0x70,0xe3,0x0e,0xe9,0x4f,0x7a,0xd6,0x42,0x45,0x2e,0x1b,0x3c,0x0d,0x15,0x6d,0xb4,0xad,0xe9,0xc5,0xa2,0x12,0x77,0x34,0x43,0x20,0x95,0xc1,0xb7,0x51,0x72,0xed,0x78,0xa0,0xae,0x3c,0xae,0xb4,0xd4,0xda,0x58 +.byte 0x83,0x62,0xa9,0xc6,0x01,0x3d,0x14,0x19,0x07,0x00,0x3c,0x82,0x16,0x7e,0x8a,0x91,0x78,0xa1,0x65,0x0b,0x5b,0x3a,0x40,0x72,0xe5,0xf0,0xd4,0x82,0x04,0xe4,0x01,0xf1,0x84,0x87,0x96,0x26,0x91,0x66,0x77,0xf7,0x59,0xd6,0xc2,0xca,0x29,0x3b,0x68,0x2a,0x27,0x99,0x64,0x86,0xc2,0x96,0xbf,0x11,0x3c,0xa8,0x0c,0xf7,0x86,0xb8,0xc1,0x40 +.byte 0x15,0x1a,0x84,0xe3,0x93,0x23,0x73,0xa9,0x8b,0xbd,0xb4,0x8a,0xe4,0xf1,0xa5,0x8f,0x56,0xa3,0xdc,0x77,0xbd,0x7d,0x15,0x74,0x2b,0x18,0x92,0x56,0x45,0xbc,0xaf,0xf2,0x55,0xce,0x9d,0xc2,0xab,0x39,0x90,0xec,0x78,0x3f,0xa5,0x14,0xeb,0x40,0x2f,0x01,0xca,0xeb,0xad,0x73,0x85,0xbc,0xe1,0x91,0xaa,0x77,0xa9,0x6c,0x02,0x66,0x6a,0x65 +.byte 0x63,0x6c,0x50,0x62,0x83,0x83,0xef,0x16,0x4f,0x21,0xfd,0x28,0x8e,0x52,0x66,0x5b,0x6f,0x8f,0xbe,0x8d,0x17,0xb9,0xd5,0x99,0xf7,0x39,0xd1,0xbc,0xa2,0x43,0xd7,0x0a,0x80,0xea,0x42,0xf8,0x38,0x53,0x95,0x07,0x6f,0xb7,0x7c,0xc1,0x16,0x88,0xc8,0xb7,0x59,0xde,0x76,0x51,0x2f,0x92,0xd0,0x40,0xfd,0xd9,0x2d,0xca,0x9e,0x8d,0x28,0xae +.byte 0x48,0xc1,0x0a,0xe0,0x76,0x9c,0x02,0x0b,0xc5,0xd1,0xf9,0x83,0x90,0x86,0xa4,0xeb,0x5c,0x64,0x65,0xf8,0x98,0x38,0xc5,0xce,0xef,0x6f,0xc3,0x88,0xb6,0x2f,0x8a,0x40,0x55,0x52,0x47,0x06,0x75,0x16,0x46,0x9c,0xff,0x3c,0x68,0x97,0xc3,0xfb,0x10,0x11,0x7b,0xba,0x04,0xcc,0xad,0xba,0xcf,0xf0,0xae,0xba,0xe6,0x59,0x9c,0xf5,0x27,0xeb +.byte 0xdd,0x5c,0x86,0x25,0xa1,0xb6,0xb8,0x1c,0x94,0x98,0xa5,0x79,0x82,0x4e,0xdf,0x09,0x3f,0x2f,0x8a,0x4e,0x1b,0x5a,0xab,0xd4,0xe6,0x21,0xb3,0x02,0x19,0x39,0xa9,0x2e,0x0e,0xae,0x86,0x30,0xc7,0xa0,0x00,0xed,0x72,0xdc,0x71,0x77,0x42,0x76,0x54,0x68,0xb2,0x8d,0x5d,0xc3,0x5c,0x86,0xf8,0xb1,0x6c,0x67,0xdf,0x24,0x40,0x6a,0x2b,0x1d +.byte 0xbc,0x0d,0x25,0x7d,0x9e,0x1c,0xbd,0x18,0x85,0xda,0x7a,0x86,0x5e,0xed,0x10,0x80,0x83,0xa6,0xef,0x1e,0x93,0xac,0xce,0xe6,0x32,0x35,0xdf,0xb8,0xc7,0x9b,0xf0,0x0f,0x9d,0x37,0xbd,0xd9,0x58,0x33,0x19,0xa1,0x23,0x51,0x5f,0xa7,0x5a,0x99,0x7e,0x2a,0xfd,0x85,0x3c,0x26,0xad,0xcc,0x7e,0x07,0x32,0x7b,0x24,0x5a,0x6b,0x4b,0x71,0x4e +.byte 0xca,0x8b,0xc4,0x03,0x26,0x76,0x02,0x68,0x0d,0xa1,0x09,0xe0,0x2e,0xa4,0x82,0x88,0x05,0x5a,0xc4,0xcb,0x31,0x9d,0x56,0xda,0x0d,0x00,0x04,0xbc,0x07,0xca,0x1f,0xdf,0x9e,0x44,0xed,0x36,0xbd,0xa0,0x22,0xff,0x78,0xd1,0xcb,0x62,0xe0,0x0d,0x2e,0xdc,0x2e,0x36,0x28,0x8e,0xd3,0xa9,0xe0,0x38,0xd4,0xc5,0x2b,0xee,0xaf,0xa4,0x08,0x7d +.byte 0xed,0x2c,0x8a,0xf5,0x86,0x5e,0xed,0x2a,0x0d,0xbf,0xe6,0xfb,0x6f,0xc4,0x02,0x75,0x36,0xe5,0x7b,0xe9,0x4a,0xb3,0xf1,0xf4,0x86,0x6c,0x9a,0x6e,0xaa,0x7a,0xbe,0x4b,0xd6,0xf2,0x6b,0xcb,0x78,0x6f,0xf9,0x42,0x1a,0x19,0x7b,0x7e,0xba,0x59,0x02,0x8b,0xe3,0x5c,0x44,0xa4,0x84,0xa8,0x4a,0x67,0x93,0xee,0xc4,0x17,0x07,0x26,0xfe,0x86 +.byte 0xf1,0xc6,0xba,0xbf,0xc4,0x3d,0x33,0x41,0x4d,0xc4,0xf0,0xa8,0x6d,0xe1,0x06,0x16,0x2d,0xc9,0x5d,0x2a,0xf5,0x4a,0xc6,0xd2,0x8c,0x98,0x55,0xe8,0x8d,0xd0,0x31,0x5f,0xc7,0x05,0xd1,0xca,0xd2,0x72,0xe6,0xd0,0xcb,0x62,0x79,0xac,0x60,0x59,0x94,0x59,0x48,0x9e,0x91,0x17,0xa7,0xa0,0xac,0x4a,0xe5,0x08,0xe5,0x52,0xa4,0xd4,0x83,0x8c +.byte 0x83,0x57,0xe7,0xe5,0xfc,0x9b,0x43,0x78,0xc8,0x7e,0x94,0xc4,0x35,0x3e,0xac,0x4a,0x8d,0x60,0x80,0xdc,0x72,0xe3,0x15,0x09,0x2a,0xbd,0xcc,0x9a,0xe4,0x1a,0x18,0xa8,0xf1,0x29,0x9b,0xca,0x58,0x0b,0x6d,0x7b,0x33,0x91,0x05,0x27,0x6a,0x48,0xbe,0xac,0x08,0xa5,0x2a,0x64,0xf5,0xae,0x2a,0x90,0xf1,0x2d,0x3f,0xa8,0xff,0x17,0x92,0xc4 +.byte 0xec,0x3a,0x09,0xbf,0xae,0xd3,0xe2,0x1c,0x3c,0xc8,0x6f,0x91,0x72,0x99,0xe3,0x82,0x30,0x4f,0x40,0x5c,0x0c,0x8d,0xfd,0xbe,0x10,0xbc,0xce,0x1e,0x0a,0x09,0xbf,0xde,0xdc,0x72,0x7e,0x4c,0xbc,0xec,0x34,0xe2,0x96,0x8a,0xc6,0xee,0x19,0x6c,0xa8,0xf1,0xa5,0xb2,0x71,0x88,0x13,0xe8,0x11,0xda,0x3b,0x77,0x10,0x9c,0x9f,0x74,0x49,0x21 +.byte 0x16,0xcf,0x6f,0x05,0xc5,0xc1,0x4d,0xfe,0xe7,0x4d,0x67,0xe8,0x12,0x14,0xf7,0xaf,0x66,0x8d,0x55,0x34,0x00,0x18,0x10,0x6e,0x6a,0xd2,0x4c,0xd9,0xd3,0x15,0x40,0xbf,0xce,0x7b,0x10,0x69,0xbd,0x15,0x0e,0x60,0x2b,0x76,0x50,0x80,0x92,0x02,0x3c,0x0f,0xea,0x47,0x03,0xd9,0xf6,0x2c,0x00,0xde,0x29,0xb9,0x2e,0xf6,0x80,0x10,0x81,0x28 +.byte 0x6f,0x41,0xfc,0x88,0x65,0xe9,0xb5,0xd4,0x78,0x53,0xff,0x04,0xc4,0xdd,0xd7,0x35,0x34,0x59,0x85,0x33,0x01,0x33,0x67,0xe1,0x4e,0xc2,0xac,0xe6,0x24,0x24,0xb6,0x83,0x48,0x08,0x0c,0x73,0xe5,0x9c,0x98,0xe4,0x4c,0x3c,0x1f,0x6e,0x77,0xea,0x8c,0x76,0x23,0xbb,0x41,0x5e,0xc1,0x8a,0xba,0x3e,0xe5,0x3e,0x86,0x89,0xab,0x32,0x65,0x1b +.byte 0x00,0x92,0x56,0xe0,0x62,0xc1,0x8f,0xeb,0x15,0x7f,0x86,0xdf,0xa2,0xc2,0x8d,0xf5,0xb5,0x88,0x72,0x8c,0xba,0x92,0x30,0x53,0x58,0x3e,0x0b,0xe6,0x4f,0xd4,0xef,0x34,0xab,0xbb,0x61,0xe0,0x31,0x3c,0xe7,0xb2,0x5f,0x64,0xcb,0x52,0xc7,0x1d,0x95,0x96,0xd2,0x8c,0x87,0x34,0x92,0xf2,0xad,0xd9,0x78,0x1d,0xa1,0x67,0x58,0xfa,0xfb,0x06 +.byte 0xc8,0x7f,0x9e,0xf7,0x02,0x12,0xd9,0x8c,0x68,0xbc,0x2b,0xd3,0xe1,0x0e,0x1e,0xbd,0x33,0x7a,0xfd,0x03,0x41,0xb9,0x72,0x2e,0x63,0xfe,0xb1,0x39,0xc3,0x0f,0xa0,0xa9,0x76,0x4f,0x7b,0xab,0xae,0xda,0x22,0xec,0x83,0x32,0xb0,0xec,0xd1,0xfd,0xc2,0x28,0x1e,0x42,0x29,0x31,0xd5,0xb3,0x33,0xcd,0x13,0x1d,0x9f,0xac,0x73,0x27,0xf7,0xea +.byte 0xc6,0x66,0xd2,0x32,0x91,0x60,0x35,0xf4,0x28,0x34,0x43,0x6a,0x74,0x8c,0x05,0x2a,0x84,0x34,0xfd,0x84,0xa5,0xcb,0x1d,0x2b,0x41,0x28,0xa6,0x19,0xed,0xcd,0xad,0xea,0x6e,0xf7,0x14,0x18,0xac,0x56,0x9a,0xf5,0xaa,0x7d,0x4e,0x8a,0x99,0xd1,0xda,0x41,0xaf,0xe8,0xfc,0xef,0x66,0x88,0xd0,0xed,0xfd,0xae,0x2a,0x85,0xc0,0x60,0xa2,0x30 +.byte 0x5d,0x1b,0x48,0xf6,0x3e,0xcf,0x56,0xdf,0x53,0xdc,0x2d,0xf5,0xfd,0x7f,0x2a,0x2a,0x4d,0x4f,0x11,0xcc,0xea,0x72,0xdb,0xb9,0xeb,0x92,0x0e,0x9f,0xc1,0x26,0xe9,0xbf,0x25,0x6a,0x27,0xe1,0x63,0x9b,0xdd,0x62,0x38,0xad,0xd3,0xb2,0x75,0x62,0x45,0xbf,0xbf,0xf4,0xe2,0xd6,0x97,0xe9,0xeb,0xeb,0x98,0xab,0x73,0xdc,0x8a,0xde,0xaa,0x3b +.byte 0x69,0xfd,0x61,0x6f,0xbb,0xfc,0x28,0xc0,0xff,0x37,0x2e,0xeb,0x31,0x59,0x57,0xfb,0xd3,0x0e,0xed,0x01,0x66,0x50,0x63,0x53,0xa2,0xd1,0x24,0x8c,0xc8,0x8d,0x80,0x03,0x2a,0x1e,0x11,0x3a,0xb9,0x6c,0xf4,0x5f,0x58,0xa2,0xd6,0x58,0x6b,0x85,0x61,0xd1,0xe7,0xdc,0x90,0x07,0x34,0x6e,0xb9,0x0b,0x0d,0xcb,0xd5,0xe3,0xc6,0x9d,0xb8,0x51 +.byte 0x37,0x61,0xd0,0x6c,0x2e,0xed,0xe0,0xbc,0x55,0x74,0x63,0x1b,0x42,0x17,0x6a,0x9c,0x91,0x1b,0x96,0x76,0xc8,0xe4,0x2b,0x2e,0x90,0xd9,0xe5,0x3f,0x56,0x1b,0x2f,0x93,0x81,0x86,0x2a,0xb4,0xdf,0x93,0xcb,0xfa,0x01,0x85,0xd9,0x26,0x46,0x46,0x97,0x2a,0x2e,0xb3,0x91,0xe4,0xcf,0xd9,0x01,0x5a,0x37,0xa6,0xca,0x5e,0xed,0xa9,0x94,0x35 +.byte 0x2c,0x69,0x5b,0x1e,0xf8,0x38,0x61,0x41,0x10,0xf6,0xe9,0x6e,0x96,0xee,0xe6,0x5f,0x78,0x14,0x93,0x12,0xd2,0x57,0xe5,0xf4,0x58,0x46,0xca,0xc8,0x75,0x59,0xbd,0xd0,0xe4,0x70,0x35,0xa5,0x4a,0xfd,0x54,0xe2,0x91,0x76,0x0e,0xe6,0xe3,0xbb,0x31,0x65,0x4b,0x18,0xa8,0xb4,0xfa,0xa6,0x7d,0x7a,0xa9,0x47,0x3d,0x2b,0x2e,0x66,0xac,0x5b +.byte 0x3e,0x5e,0x8c,0x27,0x0c,0x33,0x04,0x03,0x4e,0x5f,0xcd,0x6b,0x9c,0xaa,0x13,0x83,0x38,0xe9,0x38,0xcf,0x03,0x70,0x5a,0x0f,0x18,0xf5,0xec,0x64,0xf3,0x0c,0xe8,0xb1,0xa9,0x07,0x70,0xf7,0xde,0x0c,0x35,0xf5,0xe2,0xcd,0xed,0xe6,0x4d,0xac,0x5c,0x4d,0x3e,0x03,0x96,0x90,0x7b,0x4c,0x3e,0x18,0x42,0xc0,0xa7,0x23,0x12,0x8e,0x54,0xc1 +.byte 0xa1,0x2f,0x82,0x13,0xe6,0x1f,0x74,0xae,0x7b,0x4a,0xa4,0xbb,0xdc,0xc0,0x68,0x0f,0x83,0xbc,0xda,0xce,0xa2,0xe7,0xbe,0x18,0xcd,0x8b,0x35,0x05,0xa3,0x4b,0x6f,0xf0,0x53,0x12,0x42,0x2f,0x3c,0x09,0x87,0xb7,0xe3,0x36,0x29,0xe1,0xa2,0xb6,0x60,0x05,0xb9,0x66,0x80,0xe9,0xec,0x40,0x2a,0x55,0x78,0x5f,0x1c,0x5f,0xc3,0xc7,0x49,0x69 +.byte 0x87,0x97,0x5f,0xa5,0x31,0xa8,0x83,0x66,0x5a,0xd7,0xaf,0xf0,0x15,0xf3,0x01,0x62,0x9a,0x88,0x76,0x0f,0xb3,0xdf,0xf1,0xc6,0x34,0xc3,0xac,0x68,0x60,0x9a,0x91,0x03,0x13,0xea,0x0e,0x36,0x9c,0xf5,0x51,0xb7,0x0c,0xa4,0xeb,0xf0,0x41,0x85,0x54,0x05,0xed,0x7a,0xc2,0xba,0x3b,0xb8,0x1c,0x41,0x0d,0xbb,0xad,0x16,0x7e,0x64,0x4f,0x88 +.byte 0x7a,0x17,0xae,0x76,0x55,0x78,0x93,0xe8,0x99,0xa1,0x70,0x1f,0xf6,0x8a,0xb9,0xeb,0x41,0xb9,0x08,0xb8,0x9d,0x78,0x57,0xa1,0xe1,0x23,0xa0,0x03,0xd3,0x16,0xbc,0x16,0x24,0xed,0xc5,0x12,0x16,0x0a,0x8a,0x23,0x11,0x22,0xc2,0xfe,0x49,0x9d,0x3d,0x10,0x3d,0x4b,0xeb,0xab,0xcb,0x21,0x9d,0x9d,0xb1,0x64,0x87,0xe5,0x4d,0xb9,0xe7,0x10 +.byte 0x05,0xa0,0x55,0x2f,0xdf,0x53,0x5e,0x03,0xec,0x7e,0xe4,0x1f,0x9b,0x16,0x0c,0xfc,0xd9,0xf9,0x66,0x39,0x93,0x9e,0x49,0x34,0x97,0xd6,0xa5,0x56,0x00,0xf1,0xaf,0x08,0xeb,0x58,0xcf,0x87,0x02,0xc4,0xf1,0x24,0xe8,0x29,0x83,0xc9,0x5d,0x56,0x68,0xa2,0xaa,0xba,0xb3,0x86,0x23,0x59,0x8d,0x32,0x96,0x4a,0xbb,0xe9,0xf2,0x53,0xb2,0x87 +.byte 0x4a,0xf5,0xdc,0x23,0xd4,0x2f,0x36,0x70,0xb5,0x1d,0xee,0x47,0x51,0x6c,0x35,0x2a,0xad,0x35,0x74,0x1b,0x98,0xb5,0x33,0x2c,0x6d,0x4c,0xf8,0x39,0x07,0x92,0x6c,0xc7,0x65,0x10,0x64,0xcd,0x53,0xa3,0xcb,0xcc,0xe4,0xb2,0x46,0xb3,0xb7,0x44,0x01,0x92,0x44,0x12,0x23,0x25,0x3e,0x00,0xe3,0xeb,0x5f,0xe5,0x76,0x48,0x4e,0x4a,0x7f,0x36 +.byte 0xf0,0x0b,0x5e,0xc0,0x97,0x0d,0xc8,0xcf,0xd5,0xb8,0xc0,0x11,0x8d,0xb9,0x1e,0x31,0x0f,0x84,0x36,0x2e,0xe0,0x42,0xe6,0x02,0x9d,0xa4,0xdb,0xa2,0x76,0xfd,0xa1,0x95,0xe0,0x49,0xe6,0xf1,0xd2,0xae,0x27,0x6b,0x11,0x05,0x47,0xb0,0xaa,0x61,0x01,0xd4,0xe6,0xcd,0x9d,0x7e,0x33,0x5d,0xec,0x22,0x96,0x59,0xb7,0xc5,0x50,0x83,0xa4,0x66 +.byte 0x56,0xc7,0x43,0xa6,0xf7,0x5d,0xb2,0x45,0xc0,0x96,0xa0,0x5b,0xb8,0xed,0xae,0x29,0xb3,0x7d,0xbd,0x01,0xde,0xc0,0xe7,0xcc,0xe9,0x55,0x32,0x32,0xbf,0xdd,0x03,0x1b,0xb0,0x4e,0xff,0x53,0x1f,0x4b,0xc6,0xec,0x16,0x9d,0x5b,0x78,0x74,0xc4,0x75,0x51,0x8a,0x1c,0xae,0x6b,0xcd,0x9c,0x77,0x47,0xbf,0xd1,0x38,0x3e,0x9e,0xc0,0xad,0x16 +.byte 0xb7,0x15,0x6b,0xdc,0xad,0xe9,0x13,0xbc,0x48,0xc1,0xaf,0x69,0xce,0xc4,0xcc,0x9b,0x73,0xf9,0xd5,0x7c,0xab,0xf0,0xf1,0x9b,0xea,0xc6,0x0b,0x19,0x47,0x42,0xc1,0xa0,0x02,0x64,0x17,0xce,0x88,0x4f,0x16,0xa6,0xed,0xdb,0xfe,0x61,0xd3,0xd6,0xc0,0x11,0x30,0x16,0xd2,0x45,0xb3,0x7e,0x52,0xd0,0x94,0x77,0xf0,0x0e,0xbf,0x16,0xc0,0x4a +.byte 0x2a,0x5c,0xac,0x55,0x57,0xb1,0x41,0xb6,0xa3,0x68,0x8c,0x0a,0x66,0x15,0xb4,0xf5,0xd9,0x9a,0xa9,0x68,0xf2,0xbc,0x06,0xc5,0x7c,0xd1,0x18,0x55,0x9a,0x2d,0x94,0x2e,0x04,0x4b,0x7d,0x3c,0xb1,0xe3,0x03,0x7a,0xa7,0xe3,0xe5,0x63,0x49,0x7c,0x3f,0x0a,0xc5,0xbd,0xd3,0x0f,0x04,0xfd,0x99,0xf7,0xe6,0x05,0x35,0x66,0x17,0x05,0x85,0x3b +.byte 0x98,0x92,0x11,0x26,0xe2,0x21,0x52,0x1b,0x54,0x08,0xc8,0xf0,0x4e,0x75,0x22,0x3f,0xe8,0xb6,0x35,0xa4,0x02,0x52,0x70,0xc2,0xce,0x5a,0x00,0xe2,0xe2,0x92,0x8c,0x97,0xa7,0x1d,0x42,0x52,0x8b,0xf1,0x81,0xa7,0xce,0x60,0x46,0xbe,0xf0,0x1d,0x34,0xdf,0x73,0x2a,0xd6,0x9a,0x2d,0xf9,0xe3,0x91,0x05,0xe4,0x1f,0x31,0x11,0x30,0xb0,0xff +.byte 0x8f,0x61,0x74,0xf4,0xef,0xcd,0xf6,0xa4,0x9a,0xd2,0x5e,0xba,0x27,0xe8,0x78,0x38,0xfc,0x75,0xff,0x3b,0x6c,0xde,0x4a,0x46,0x47,0x8e,0x97,0x28,0xe4,0x23,0xe0,0x10,0x07,0xca,0xcb,0x6d,0xed,0x29,0xc0,0xee,0x98,0x96,0x7c,0x90,0x1f,0x89,0x12,0x0f,0xd5,0x28,0xcf,0x6e,0x4b,0x9b,0x2d,0xb3,0xcd,0x97,0xb8,0xeb,0x58,0x23,0x26,0xb1 +.byte 0xb4,0x95,0x11,0x1e,0xee,0x00,0xde,0x24,0x28,0xa6,0x3f,0x15,0xa2,0x9a,0xcb,0x9d,0xe3,0x04,0x5d,0xc3,0x60,0x97,0x14,0x2c,0x84,0x2b,0x69,0x9c,0x2a,0xbf,0x08,0xba,0xc4,0x38,0x36,0xaa,0x89,0x11,0x32,0x63,0x01,0xa2,0x44,0x5f,0x50,0xf0,0x5b,0x11,0x15,0xc8,0x80,0xc9,0xa6,0xe7,0x5d,0x70,0xa8,0x34,0x42,0x97,0x2a,0x60,0x99,0x20 +.byte 0xa6,0x60,0xc0,0x70,0x8d,0x2f,0x3f,0x8a,0x14,0x80,0x8a,0xbe,0x05,0xb3,0x50,0x16,0xaf,0x32,0xb4,0x35,0x3e,0x1d,0x31,0x42,0xdd,0x50,0xeb,0x04,0x82,0x4c,0x83,0x3d,0x8f,0xb6,0x1e,0xc2,0xa9,0xd2,0x30,0xba,0x33,0xdb,0x97,0x6d,0x2d,0x97,0x59,0x33,0xc0,0xf8,0xa5,0x59,0xc5,0x44,0x9c,0xf1,0x06,0xc4,0xf2,0x31,0x3e,0xff,0xb8,0x12 +.byte 0x00,0x4d,0x6c,0x2d,0xa1,0xc7,0x83,0xea,0x55,0x93,0x0e,0x89,0x76,0xbf,0x56,0x2a,0x99,0x62,0x54,0xad,0x2c,0xe8,0xf0,0xf9,0x70,0x18,0xa5,0x2b,0x24,0xac,0x59,0xc9,0x84,0xe3,0x1a,0x9d,0xa0,0xdb,0x1b,0x7f,0xd5,0x7e,0xb5,0xe0,0x86,0x36,0xc5,0x71,0x6a,0xab,0xdb,0xa5,0x84,0xf1,0x9e,0x9e,0xf6,0x1b,0xab,0x47,0x94,0x38,0x8e,0x5d +.byte 0x55,0xb4,0xf5,0xc3,0x59,0xc2,0x2c,0x6d,0x9d,0x28,0x7d,0x33,0xcd,0xc7,0xd6,0xdf,0x10,0xda,0x7c,0xd0,0x6c,0x91,0x88,0xd6,0x6b,0xe7,0x72,0x75,0x18,0xb1,0x87,0xe4,0xbb,0x10,0xe0,0xa3,0x0f,0xea,0x65,0x0a,0x70,0xc8,0xee,0x52,0x05,0x0a,0x27,0x39,0x66,0xda,0xd6,0xa6,0xfe,0x97,0x24,0x09,0x9d,0x20,0x76,0x4e,0x97,0x9d,0xa9,0x9f +.byte 0x76,0x20,0x27,0x57,0x5b,0xf4,0x76,0x1a,0x4b,0xcf,0x13,0x6c,0x9e,0x63,0x53,0x97,0xca,0x10,0xd6,0x90,0x7d,0xfc,0xe3,0x03,0x2c,0x6c,0x79,0x93,0x1a,0xae,0x0f,0x43,0xdb,0x75,0xde,0x56,0xa6,0x69,0x93,0xce,0x2d,0x94,0x56,0x77,0x90,0x19,0x71,0x7f,0x7a,0x99,0xbd,0x9c,0x79,0x62,0x00,0x49,0x3a,0x62,0x49,0x4b,0x92,0x65,0x8b,0xe2 +.byte 0xa8,0x3d,0xa5,0x89,0x23,0xac,0xea,0xf1,0xbf,0x38,0x84,0xd7,0xe2,0x65,0xb6,0xc7,0xbc,0x02,0x11,0xfd,0xe3,0x4c,0x57,0x38,0xd4,0x36,0x54,0xe8,0xbb,0x63,0x17,0xe9,0xda,0x82,0x50,0xf1,0x8c,0x34,0x4d,0x75,0x2a,0x64,0x49,0xaf,0x98,0xc3,0x1d,0xad,0x31,0xf3,0x90,0x23,0x39,0xf5,0xb5,0xf4,0x37,0x88,0x67,0x12,0x5d,0xfc,0xee,0xe5 +.byte 0x44,0x52,0x2c,0x78,0xb1,0x90,0xc1,0xc2,0x77,0x6e,0x31,0x3e,0xa0,0x36,0x87,0xb0,0xc6,0x6c,0x94,0xc2,0x43,0x4a,0x7b,0xa2,0x73,0xe7,0xa0,0xc3,0x4c,0xaf,0x4f,0xa6,0x92,0x1c,0x9a,0x6d,0xee,0xe8,0x4d,0xe1,0xe0,0xc7,0x67,0xcf,0xcf,0x7d,0x7f,0x0f,0x07,0x0d,0x6c,0x06,0x06,0xc2,0xc9,0x28,0xfc,0x8d,0xcd,0x23,0x01,0x97,0x5b,0x4d +.byte 0x1c,0xdb,0x34,0x51,0x6e,0xe2,0x56,0x24,0xd7,0xbd,0x12,0xc4,0x2f,0xb4,0x3b,0x02,0xaa,0x47,0xda,0x61,0xf6,0xca,0x44,0xa8,0x02,0xbf,0xbc,0x58,0xfb,0xa2,0xff,0xf3,0x54,0x59,0x5f,0xd7,0xa0,0x7c,0x83,0xa6,0xef,0xeb,0x71,0x51,0x74,0xa1,0x27,0x10,0x97,0x13,0x1f,0x42,0x91,0xdd,0xa8,0xf8,0xc7,0x60,0x90,0xca,0x2e,0xc8,0xaf,0x9f +.byte 0x65,0x1f,0x24,0x0a,0x30,0x5f,0xb9,0x4c,0xfb,0xcb,0xa3,0x96,0x5e,0xad,0xab,0xac,0x09,0x91,0xf5,0x96,0x1f,0xe0,0x96,0x14,0xc5,0xa0,0x26,0xa1,0xf1,0x91,0x80,0x38,0x7f,0x38,0xdc,0x98,0x96,0x20,0x46,0x50,0x20,0xd2,0x20,0xce,0x79,0xd5,0x81,0x60,0x97,0xb2,0xb0,0xeb,0x58,0x75,0x3c,0x99,0xf0,0xe0,0xfd,0xfc,0x90,0xc5,0xd1,0x3d +.byte 0x68,0x07,0xfd,0xa1,0x3f,0xeb,0x47,0xd0,0x58,0xe3,0xfa,0xbe,0xbf,0x20,0xdf,0x66,0x08,0x91,0xa4,0x5c,0x52,0x3e,0xdf,0x5c,0xb8,0xee,0xca,0xa6,0x89,0x06,0x97,0xb4,0x8d,0x60,0x35,0xb1,0xff,0x1e,0x39,0xf2,0x67,0xbc,0x71,0xee,0xeb,0x48,0x94,0x19,0x1a,0xee,0xc5,0xe2,0x7e,0x0d,0xf1,0xca,0xe8,0x2c,0xb0,0xaa,0x02,0x58,0x23,0x23 +.byte 0xce,0x37,0x5e,0xcb,0x58,0x40,0x2e,0x1a,0xa6,0x09,0x11,0x95,0xc4,0x6f,0x10,0xb0,0x15,0x22,0x48,0x67,0x74,0x6c,0x2f,0x4f,0x4a,0xb4,0x01,0xe5,0xa3,0x77,0xab,0xad,0xa4,0x04,0x22,0x71,0x58,0x4a,0x71,0xb1,0xe8,0xdf,0x43,0x18,0x0e,0x95,0x7c,0x8c,0x23,0x3a,0xf3,0x9c,0x20,0x60,0x20,0x69,0x51,0x28,0x7e,0x13,0x67,0x5c,0x7d,0x35 +.byte 0xfa,0x1b,0x04,0x8b,0xcf,0x42,0x6e,0x15,0x55,0xcd,0x04,0xdb,0x73,0xdb,0x47,0x5f,0x83,0x6e,0xd1,0x5a,0x15,0xa2,0xbb,0xf7,0xbb,0x84,0x58,0xce,0x75,0xe8,0xd2,0x92,0xd5,0xb7,0x76,0xf2,0x94,0x67,0x27,0x5f,0x32,0x91,0x3a,0xaf,0xd4,0x31,0xf8,0x92,0xce,0x63,0xb7,0x45,0x27,0xb4,0xb8,0x7a,0x1e,0x4e,0xde,0xcb,0xc8,0x5e,0xd3,0xbb +.byte 0x52,0x91,0xd5,0x72,0xad,0x98,0xec,0x07,0xa1,0x56,0xb4,0x8e,0x04,0xfa,0x48,0x3f,0x17,0x07,0xf7,0xef,0x92,0x61,0x69,0xaf,0xdd,0xfc,0x76,0x03,0xe2,0xe9,0xe2,0xbe,0x5c,0xf2,0x8a,0xc5,0x99,0x51,0x7f,0xa4,0xf1,0xac,0x16,0xec,0x16,0xf5,0xb8,0x95,0x88,0x87,0xdb,0x27,0x2e,0x63,0x12,0x31,0x7d,0x6b,0x2b,0xa0,0x9b,0xb5,0xf9,0x82 +.byte 0x42,0x04,0x94,0xee,0x60,0x6e,0x4e,0x54,0x9b,0xfd,0xeb,0x01,0x3a,0xad,0x42,0xeb,0x08,0x3c,0x6a,0xa3,0xf2,0x46,0xfb,0x18,0x59,0x2c,0xa3,0x0b,0x22,0x1d,0x5d,0x47,0xa6,0x8c,0x06,0x9c,0xa1,0xcc,0x20,0x67,0xbd,0xf0,0x5b,0x94,0x9f,0xc6,0x10,0x8c,0xc8,0x15,0x52,0xe3,0x19,0xa1,0x89,0xfd,0x99,0xad,0x4f,0x10,0x51,0x0a,0xe4,0x4b +.byte 0x02,0x7b,0x0d,0x73,0x2d,0xae,0xa4,0x68,0x1d,0xb6,0xcf,0x58,0x67,0xc0,0xd0,0xca,0x11,0x34,0x31,0x9e,0xa3,0xbc,0x12,0x28,0x1e,0x8e,0x5a,0x63,0xf5,0xda,0xf2,0x36,0x94,0x63,0x2c,0x39,0x3d,0xf9,0x80,0x9f,0xbf,0x8d,0xef,0x1f,0x15,0xc8,0xdb,0x62,0x58,0x7d,0xdc,0x0a,0x7f,0x87,0xaf,0x6d,0x2e,0xac,0x92,0x4f,0x51,0xdf,0x5e,0x75 +.byte 0x5e,0x0f,0x7c,0x51,0x49,0x88,0x0f,0x7b,0x49,0xa5,0x7c,0x41,0x4e,0x2a,0x0f,0xd0,0x0f,0x78,0xeb,0x42,0xfc,0x07,0x8a,0x8b,0x4e,0x3e,0xf2,0x42,0xc5,0x21,0x01,0x66,0xe2,0x50,0xf6,0x3d,0x28,0x1e,0xbf,0xdc,0x71,0x7f,0xc5,0x6e,0xc1,0xab,0x1a,0x33,0x49,0xdd,0xa2,0xb9,0x52,0xbe,0x93,0x97,0x97,0x7a,0xf0,0x22,0xa8,0xc5,0x01,0xc6 +.byte 0x76,0x6f,0xb6,0x2c,0x09,0x80,0x62,0x5b,0x84,0x05,0x7f,0x79,0x28,0x04,0x67,0xa2,0x0f,0xfc,0xbb,0x17,0xe2,0x85,0xe3,0xa0,0xf3,0x44,0x47,0x96,0x68,0x80,0xb2,0xbf,0xba,0x63,0x53,0x38,0x6c,0x3b,0xcd,0x3c,0xa4,0x10,0x48,0x80,0xd8,0x49,0x5a,0xf0,0x5c,0x38,0x02,0x02,0x5b,0xf2,0x77,0xa4,0xfd,0x16,0xfd,0x13,0xc8,0x8b,0x9b,0xcd +.byte 0xe1,0x8d,0x70,0xb6,0x3d,0x24,0x65,0xda,0x1a,0x42,0x6f,0x90,0x64,0x9a,0x9b,0xda,0x54,0x44,0xc0,0xe0,0xd7,0xfb,0x73,0x10,0x3c,0xcf,0xa6,0x04,0x99,0xd9,0x45,0xe5,0x74,0xfe,0xdf,0x81,0xac,0xc8,0x30,0xe5,0x66,0x45,0x02,0xca,0xcd,0xd7,0xe6,0x7b,0x0d,0xda,0xe1,0xa0,0xa1,0xa1,0x87,0x34,0x63,0x0b,0xa7,0x82,0x39,0x83,0xba,0x18 +.byte 0x0b,0x16,0x35,0x11,0x53,0x8d,0xbe,0x7d,0xa8,0x7e,0x3f,0xf4,0x71,0xc9,0x37,0x6f,0x1a,0xd9,0x3f,0x8e,0xc4,0xc1,0xd3,0x80,0xdf,0xee,0x0e,0x6b,0x23,0xf7,0xbc,0x42,0x93,0x7a,0x36,0x6f,0x03,0x24,0xb4,0x9c,0x62,0xa0,0xed,0xed,0x0b,0x66,0xa8,0x25,0xe6,0x1a,0xd4,0x13,0xd1,0x16,0x14,0x2b,0x90,0x7d,0x2e,0xa4,0xda,0xb2,0xf9,0x33 +.byte 0x54,0xf9,0x0a,0x04,0x27,0x03,0x14,0xd2,0xd7,0xe2,0xc1,0xaa,0xb6,0xe8,0xe5,0x4c,0xf2,0xdb,0x4c,0xc8,0xb3,0xa4,0xeb,0xbf,0x12,0x5c,0x9d,0x65,0xaa,0x9a,0x66,0x77,0x42,0xb4,0xd5,0x5b,0x1f,0x3b,0xd7,0x91,0x89,0x57,0x2f,0xd0,0x86,0x99,0xb2,0xc8,0xc1,0x31,0xde,0x33,0x43,0x36,0x81,0xdb,0x97,0x7b,0x17,0x3b,0xa5,0x99,0xdb,0x63 +.byte 0x2b,0x48,0x4c,0xa6,0x5c,0x6c,0xd8,0xc9,0x6e,0x72,0x39,0xbe,0x6e,0x55,0x7e,0x9d,0xb7,0x20,0x8d,0x8f,0x81,0x20,0x78,0xae,0xc6,0x1d,0xe0,0x2d,0xb1,0xe7,0x64,0xbb,0xd4,0xc8,0x08,0x61,0x14,0x29,0x08,0xbc,0x1a,0xeb,0xfa,0x64,0x33,0x91,0x7d,0x91,0x41,0x65,0x8e,0x4c,0x0c,0xb2,0x79,0xc3,0x01,0x68,0xfc,0xd6,0xbb,0x50,0xcc,0x07 +.byte 0xa5,0xf6,0x2c,0x5e,0x10,0xd6,0xa3,0x62,0x18,0xec,0xa2,0xf2,0x6b,0xad,0xcd,0x02,0x01,0x75,0xbb,0x36,0x27,0x56,0x0f,0x55,0x03,0xe0,0x57,0xe1,0x72,0xeb,0x66,0x00,0x21,0xff,0x9a,0xbc,0xc1,0x1e,0x2c,0x93,0xe6,0x4d,0x93,0x28,0x10,0x7d,0x67,0x6c,0xf1,0xa4,0xe6,0x3a,0xa6,0x30,0xc8,0x50,0x1d,0x8b,0x6e,0x7b,0x76,0x98,0x14,0x4e +.byte 0xed,0x84,0x67,0x2a,0x5f,0xac,0x0b,0x7b,0x47,0x40,0xb3,0x2d,0x7a,0xc1,0x23,0xdc,0x62,0xf8,0x8e,0x90,0x77,0xd4,0xf9,0x00,0x4b,0x67,0x04,0x72,0xf8,0xc9,0x2c,0x2d,0x0e,0x3c,0x3c,0xf3,0xfc,0xa8,0xe2,0x49,0xa4,0x00,0x82,0x98,0x72,0xa9,0xec,0xea,0xbd,0x3a,0x4e,0xd7,0x32,0xf1,0x11,0xf0,0x0d,0x9e,0xa2,0xe8,0xfe,0xcc,0x67,0xec +.byte 0xfc,0xd6,0xfe,0x83,0x5e,0x7c,0x2b,0xb3,0x42,0xf4,0x2d,0x9a,0xbe,0x20,0xd1,0x81,0x62,0xe9,0x59,0x19,0x28,0xdf,0x97,0x10,0x54,0xf7,0xde,0x60,0x51,0x6a,0xce,0x32,0x03,0x75,0x5c,0x25,0x25,0x82,0x9c,0x07,0xf7,0x2d,0xa8,0x1b,0x9f,0xd3,0x32,0x46,0x25,0x1f,0xb1,0xc5,0xbb,0x28,0x14,0x3e,0xed,0xa8,0x83,0x20,0xf4,0x9c,0x75,0xf4 +.byte 0xe6,0xc4,0x2d,0x05,0x88,0x31,0xfd,0x48,0xca,0x6c,0x7f,0xab,0xb4,0x77,0x93,0x1d,0x87,0xc3,0x4e,0xb8,0xad,0xb4,0x3d,0x37,0x7a,0xd2,0x77,0xff,0xc2,0xcb,0x9c,0xc7,0xbf,0x02,0x02,0x70,0xc9,0x9f,0x77,0x8a,0x7d,0xa7,0x9a,0x10,0xd1,0x0e,0xb7,0xec,0x61,0xee,0x77,0x24,0xe9,0x3d,0xcd,0x12,0xca,0xee,0x50,0xb0,0x27,0x5d,0xe5,0xac +.byte 0xa3,0x92,0xc7,0xd0,0x23,0x54,0xb1,0xe5,0x50,0xc3,0x15,0xd7,0x66,0x32,0x38,0x34,0xb1,0x59,0x1b,0xc3,0x59,0xe8,0xad,0x59,0x90,0x58,0x6e,0x02,0x40,0xb1,0x51,0x65,0x78,0x25,0x26,0x01,0xdd,0xcf,0x04,0xa2,0xfe,0xc3,0xbb,0x80,0x1c,0xb0,0x4e,0x9c,0x49,0x48,0xa3,0xe2,0xcc,0x81,0xc5,0xa8,0xd4,0xd5,0xe4,0xab,0x39,0xe7,0xe8,0x97 +.byte 0xc7,0x51,0xb4,0x5e,0x3f,0xe6,0xa7,0xcc,0x45,0x18,0xa2,0x6a,0xb3,0xa8,0x0b,0x7d,0xce,0x1a,0x97,0x4a,0x67,0xe1,0x3c,0x7c,0x4e,0xad,0x90,0xcf,0x2a,0x8f,0xb8,0xb6,0x96,0xaa,0x9a,0xc3,0x73,0xe6,0x71,0xdb,0x11,0x9b,0xd9,0xd9,0xfe,0xba,0x4a,0xf0,0x77,0xa4,0x15,0xb5,0xca,0xe1,0xb4,0x16,0x06,0x46,0xdf,0xc5,0x49,0x07,0x66,0xb3 +.byte 0xf5,0x30,0xe3,0xfb,0x44,0xac,0x80,0x3a,0x21,0xd9,0x5b,0x22,0x54,0x3a,0xae,0xbe,0xbd,0xf0,0x99,0x8d,0xb5,0x2a,0xf7,0xc9,0xf2,0xd3,0xfb,0x07,0x7c,0xd7,0x75,0x30,0x2a,0xcd,0x80,0xa8,0x2a,0x6a,0xb9,0x47,0xe2,0xa1,0xb0,0x76,0x6a,0x0f,0x9f,0x4a,0x56,0x3e,0xde,0xb3,0x89,0x12,0x25,0x63,0x1a,0x9d,0xea,0x64,0x08,0xc5,0x78,0xa7 +.byte 0x53,0xce,0xf8,0xb2,0xe5,0x97,0x3a,0xeb,0xd1,0x92,0xe1,0x4d,0xe0,0xf5,0x93,0x39,0x73,0xad,0x67,0xc9,0x0e,0x6b,0x16,0x4a,0x00,0xaa,0xb4,0xe6,0xa6,0xa5,0x67,0x95,0x90,0x04,0x5e,0x4d,0xc3,0x7f,0x6b,0xa1,0x50,0xb0,0x3b,0x72,0x0d,0xb3,0xec,0x9a,0x18,0x92,0x65,0x0c,0x2d,0x0f,0x94,0xd6,0x0f,0x95,0xba,0x4b,0xe6,0xc3,0x07,0x22 +.byte 0x0d,0x40,0xd4,0x0d,0x97,0x44,0xba,0x54,0x8c,0xf8,0x97,0x52,0x1f,0xa7,0xb2,0xe8,0x1b,0x0a,0xd5,0xde,0xff,0x1b,0x33,0x60,0x6a,0x28,0x68,0x36,0xb9,0x5a,0x3e,0x43,0x84,0x9a,0xb1,0x3d,0x3d,0xdb,0x1b,0xa2,0xc5,0x0e,0x2d,0xb5,0x5a,0xa5,0x36,0xe7,0xbf,0x7e,0xc3,0x76,0xad,0x1e,0xb5,0x49,0xc2,0xd5,0xa2,0x69,0x97,0x45,0x43,0x3e +.byte 0xeb,0xcd,0xdf,0x4f,0xab,0xb3,0xe8,0x49,0xaa,0x9c,0x9c,0x58,0x1e,0xc8,0x1c,0x79,0xe9,0x16,0x1d,0xfe,0x54,0xac,0x55,0x18,0x10,0x73,0x97,0xdc,0xbe,0x45,0x63,0xfb,0x48,0x41,0x88,0xb4,0x0b,0x3a,0x1d,0x65,0x40,0x1b,0x10,0x66,0xeb,0xbe,0xed,0xc7,0x6c,0xd5,0x0c,0x19,0x85,0x23,0xb1,0x38,0xb3,0x4b,0xcd,0xc7,0xc5,0x06,0x18,0x40 +.byte 0xbd,0xef,0x9f,0x2e,0x3a,0x71,0x33,0x05,0x30,0x71,0xca,0xe9,0x7a,0x2c,0xe7,0x83,0x4e,0x3d,0x4b,0xc8,0xc7,0xcb,0x74,0x9c,0xa2,0xc7,0xbb,0x8c,0x44,0x0d,0xd8,0xb3,0x01,0x7c,0xdf,0x79,0xee,0x47,0xcb,0x91,0x6f,0xc3,0xfd,0x0f,0xfb,0xf8,0x6b,0x9b,0x00,0xaf,0xf6,0x69,0x82,0xa5,0x58,0x54,0x22,0x7f,0x4b,0xee,0xa7,0x03,0xdb,0xb6 +.byte 0x5f,0x12,0xe1,0x04,0x43,0x17,0xec,0xd4,0xdd,0x39,0x28,0xfa,0xa3,0x09,0x5e,0x14,0xaf,0x6b,0xfe,0x0c,0x65,0x01,0x13,0x75,0x3d,0xe7,0x6d,0xd9,0xda,0x1d,0x13,0xc1,0x56,0x40,0x50,0x95,0x65,0x8f,0xad,0x51,0x3f,0x13,0x05,0x2f,0x83,0xcd,0xca,0x8b,0x75,0xa2,0x39,0x61,0xde,0xd7,0x36,0xf9,0x1d,0x43,0x5b,0xc4,0x9a,0xc9,0xfc,0xa8 +.byte 0xf4,0x76,0x90,0x91,0xe8,0x52,0x5b,0x84,0xe7,0xc9,0x8e,0x7d,0x84,0xba,0xb1,0x32,0x12,0xce,0x06,0x9e,0x98,0x83,0x1f,0x7f,0x31,0xd7,0xf0,0x8a,0xa2,0xca,0xae,0xb3,0x50,0x51,0x93,0xfb,0x2f,0x43,0x0a,0xee,0x06,0x85,0xec,0xb8,0xf1,0x73,0xb1,0x65,0x37,0x05,0x8e,0x68,0xf7,0x7a,0xff,0xe7,0x17,0x08,0x5e,0x19,0x75,0x3d,0xf9,0x5e +.byte 0xd5,0x25,0xf6,0x3b,0x99,0xb9,0x96,0x42,0x7a,0x37,0x8f,0x0d,0xde,0x22,0x83,0x89,0xf0,0x77,0x1f,0x22,0x42,0xc7,0xb5,0x70,0xcb,0xfd,0xf0,0xa9,0x87,0x8e,0x1f,0x01,0x9a,0x26,0xa6,0x8c,0x41,0xb9,0x12,0xd6,0xf2,0x5b,0xe5,0xfd,0xdc,0x74,0xbd,0xa1,0xc8,0xf7,0x3b,0x8c,0xe1,0x1d,0x42,0xb4,0x07,0x24,0x18,0x84,0x94,0x8a,0xce,0x00 +.byte 0xbd,0xd7,0xb0,0xfd,0x8f,0x0a,0xd3,0x75,0xa4,0xe8,0xfc,0x09,0xa9,0xa3,0x57,0x68,0x79,0x0e,0xef,0x37,0x46,0xd5,0x3b,0x8c,0x0d,0x67,0xbc,0x2c,0x5d,0x3e,0xf7,0xcc,0x9c,0x9e,0x81,0x62,0xc8,0xec,0x38,0x20,0x07,0x66,0xe4,0x83,0x15,0x13,0x3b,0x47,0x23,0xd9,0x46,0xaf,0x65,0xe1,0x40,0x2d,0x14,0x84,0x72,0xc1,0xbf,0xbe,0x81,0xc4 +.byte 0xcb,0x04,0x16,0x5e,0x2f,0x60,0x3a,0x8e,0x1a,0xd3,0xa2,0x00,0x25,0x6c,0xb7,0xdb,0x0d,0x20,0x99,0xb8,0x45,0x54,0xbf,0xc4,0x52,0x52,0x92,0x7d,0xcd,0xa1,0x9a,0x12,0x5e,0x27,0xe9,0xcf,0x79,0x9d,0xa8,0x6c,0xcd,0x37,0x20,0x08,0x09,0xc6,0x94,0x53,0x00,0x04,0xf5,0x3b,0xea,0x00,0x1b,0xc3,0x02,0xff,0xbc,0x18,0x1f,0xb7,0xf7,0x26 +.byte 0xe8,0x8b,0xc4,0x5f,0xf7,0xbe,0x9b,0xb3,0xba,0xae,0xbd,0x9c,0x3f,0x95,0xf7,0xcd,0x2b,0x40,0xf4,0x1c,0x6f,0xd7,0x52,0xe1,0xa7,0xdc,0x79,0xa4,0x88,0xff,0xfc,0xcf,0xfb,0xbb,0xe6,0xef,0xb6,0x31,0xac,0x24,0xa7,0x40,0xea,0x76,0xa2,0x34,0x6c,0xb1,0xfb,0x96,0x6b,0xfa,0xdd,0x60,0x70,0x73,0xb8,0xfd,0x66,0x3d,0xf9,0x63,0xc9,0x04 +.byte 0x70,0x20,0x35,0xca,0x04,0xb8,0xb3,0x4f,0x24,0x64,0x54,0xc2,0xd9,0x4d,0x8b,0xad,0x07,0xad,0xc5,0xb9,0x84,0xac,0x7c,0x65,0x4b,0x98,0x1d,0x09,0x23,0x95,0x5c,0x85,0x26,0xe5,0x8e,0xec,0xeb,0xc3,0xd5,0x15,0x9c,0x37,0x4e,0xf3,0x3c,0x97,0x92,0x75,0x99,0x48,0x48,0x52,0x4b,0x7b,0x93,0x54,0xd7,0x4f,0x7f,0xe5,0x51,0xdc,0x74,0x85 +.byte 0x9a,0xae,0xbd,0xf8,0xe6,0xe8,0x3f,0x1b,0xee,0x8b,0xf4,0xd8,0x5c,0x6c,0x46,0x6e,0x1d,0xaf,0x67,0x27,0x9a,0x39,0x4e,0x6b,0x99,0xcc,0xc0,0x66,0x54,0xbf,0x60,0xf6,0x24,0x64,0xfd,0x16,0xbf,0x56,0xb2,0x07,0x87,0x46,0xa6,0xef,0x40,0x67,0x78,0x2f,0x78,0x49,0x81,0x25,0xbd,0xa1,0xcf,0x78,0x68,0x25,0x8e,0x93,0x0a,0x4b,0xe1,0x92 +.byte 0x33,0x9c,0x13,0x70,0xd4,0xdf,0x74,0x34,0x8f,0x21,0xb9,0x51,0xd7,0x74,0xa9,0x02,0x6e,0xdd,0xb2,0xb4,0x6e,0x2a,0x95,0xdb,0xe4,0xaf,0x17,0xf5,0x9b,0xa5,0xc1,0x72,0x36,0x35,0x02,0x37,0x1c,0x38,0xaa,0x81,0x76,0xc6,0x1c,0xc3,0x2c,0xc5,0x45,0xaf,0x03,0xea,0xe6,0x14,0x51,0x44,0x84,0x9e,0x32,0xfe,0x4b,0x47,0xe9,0xb4,0x12,0x96 +.byte 0x13,0x6f,0x4c,0xed,0xe4,0xb0,0x79,0x7b,0xe5,0xc0,0x37,0x87,0x78,0x28,0x42,0xf7,0xd4,0xde,0xfc,0xd2,0x23,0x11,0x09,0xa5,0x11,0xc3,0xc4,0xf5,0xe0,0x2b,0x47,0x01,0x63,0xf2,0x85,0x1f,0x45,0x28,0xae,0xd3,0x29,0x04,0x1a,0x4b,0x83,0xab,0xf2,0x35,0x3a,0x40,0x2c,0x8d,0xb3,0xc7,0x47,0x0d,0xd1,0x3c,0xd0,0x1c,0x6b,0x5d,0x9b,0x4e +.byte 0xdf,0x36,0x8d,0xc6,0x54,0x9e,0x61,0x51,0xf1,0xd2,0xa4,0x39,0xad,0x4a,0x14,0xa1,0x0b,0xd3,0xae,0x91,0x1a,0x29,0xeb,0xc5,0x75,0x88,0x13,0x1e,0x96,0xdd,0x6f,0x86,0x92,0xaa,0x37,0x16,0x95,0x86,0xbc,0xb1,0x35,0xbf,0x5f,0x75,0x40,0x46,0xe1,0x6f,0x2f,0x33,0x2d,0x13,0x35,0xef,0xca,0x09,0x04,0xe4,0x42,0xef,0x69,0x66,0xda,0xa6 +.byte 0x01,0xda,0x09,0xfd,0xb1,0x40,0x8d,0xaa,0xdd,0x08,0x0d,0xf5,0xf1,0xd6,0xc6,0x11,0x3b,0xbd,0xd3,0x04,0x70,0x76,0xaf,0xec,0x9b,0xcc,0x6a,0x1d,0xeb,0x95,0x4a,0x01,0x0a,0x03,0x62,0x00,0x32,0xb3,0xe0,0xd1,0x36,0xb6,0xeb,0xde,0x4b,0x5f,0x35,0x79,0x07,0x4a,0x0d,0xa1,0x8c,0xde,0x6b,0xd2,0xca,0x71,0x64,0x73,0xf7,0x9c,0x1d,0x95 +.byte 0x5c,0xdc,0xb9,0x4f,0x00,0x2e,0x86,0x3d,0x81,0x7b,0x05,0xa5,0x9e,0x03,0xa3,0x62,0xcf,0x22,0x78,0x0b,0xfe,0x09,0x3e,0x62,0x93,0x19,0x6e,0x47,0x7d,0x92,0x4a,0x0b,0xae,0xcb,0x37,0x4d,0x5a,0x3a,0x7a,0x68,0xde,0xb2,0x7e,0xd7,0xda,0x5c,0x45,0xd2,0x0f,0x1d,0x03,0xbc,0xed,0xd8,0xe5,0x2e,0x26,0x10,0x82,0x46,0x5a,0xe0,0x13,0x32 +.byte 0xf8,0xb9,0x18,0x8c,0xbd,0xb4,0xb3,0x8c,0x2f,0xb0,0x5d,0x0b,0xf3,0x8f,0x5a,0xda,0x8b,0xda,0x39,0xfe,0xe6,0x66,0x95,0x3f,0xfe,0x49,0x89,0xbf,0x43,0x36,0x77,0xc7,0x6d,0xea,0x92,0x5c,0x71,0xa6,0x29,0x50,0xb0,0x2f,0xed,0x89,0x9f,0x2c,0xd6,0x6b,0xfa,0xbe,0x62,0x9f,0x62,0xc7,0xe3,0x2e,0xd4,0xf2,0x2c,0x9c,0x98,0x37,0x38,0x5e +.byte 0x81,0x6c,0x9e,0xcc,0xff,0x0f,0xfa,0xfa,0xe8,0xdd,0x2e,0x2d,0xb5,0x92,0x44,0x5e,0x2f,0xe1,0xd0,0x6c,0xc3,0xb9,0x11,0x95,0x70,0x4b,0x01,0xa0,0xc1,0x5e,0xe8,0x1d,0x40,0x16,0x9b,0x6e,0x29,0x1b,0x13,0xb9,0xda,0x39,0xbd,0x40,0x42,0xe2,0x06,0x35,0x57,0x2f,0xa8,0xf5,0xa7,0x00,0x60,0x07,0x26,0x21,0x6b,0xe6,0x23,0xa2,0x2a,0x70 +.byte 0xeb,0x85,0xcb,0xa9,0x73,0x31,0x62,0xf7,0xb0,0x90,0xd7,0x26,0xc1,0xd3,0xd7,0xcc,0x15,0x72,0x86,0xa6,0x0f,0x4a,0x24,0x14,0x5d,0xcd,0xbe,0xad,0x7d,0xf0,0x05,0x39,0x0c,0x10,0xbe,0x11,0x9a,0x36,0x9f,0x60,0x41,0xc6,0x7c,0xab,0x54,0x8a,0xac,0xc4,0xea,0xbd,0x43,0xeb,0x19,0x5a,0x8d,0x05,0xd1,0x83,0x58,0x92,0xb8,0xc6,0x75,0x56 +.byte 0x2c,0x58,0xb8,0x2d,0xe1,0x42,0xb4,0x0b,0xc9,0x97,0x79,0xb8,0x62,0xd0,0x15,0xd1,0x5d,0x0d,0x57,0x83,0xe4,0xba,0x73,0xa2,0x27,0xb8,0x56,0x64,0x28,0xaf,0xd2,0x58,0xe3,0xe6,0x12,0x01,0x6e,0x6a,0xfb,0x81,0x57,0xcd,0x32,0xc2,0x42,0x2a,0xe2,0x51,0x4a,0x4c,0xf8,0x69,0x0e,0xc0,0xe6,0x9f,0xf4,0x46,0x4b,0x60,0xcc,0x41,0x03,0xa4 +.byte 0x14,0xf0,0x15,0xb5,0xe5,0x39,0xfd,0x69,0xee,0xce,0x23,0x3a,0x50,0x66,0xdb,0xf4,0xe4,0x31,0x23,0xe9,0x06,0x93,0xdd,0x38,0xbc,0x2d,0xb9,0xf2,0x64,0x39,0x2f,0x1b,0xa9,0x71,0x0c,0x68,0xf7,0xb0,0x5b,0x74,0xe5,0x08,0xc6,0x5d,0xbe,0xb8,0xf7,0x40,0x0e,0xb4,0xe6,0x76,0x0c,0x14,0x8f,0x9d,0x25,0x95,0x6c,0x05,0x78,0x68,0x8a,0xa6 +.byte 0x80,0x24,0x8a,0x0b,0x6a,0xd7,0xfc,0xec,0x36,0xba,0x57,0xdd,0x49,0x82,0x3c,0x5f,0x9d,0xf4,0x57,0xac,0x16,0x99,0xed,0x73,0xa6,0xb0,0x2c,0x23,0xdb,0xf8,0x45,0x22,0xf4,0x82,0x16,0xc4,0x68,0x2f,0xe7,0x8c,0x85,0x6e,0x3c,0x43,0xdd,0x3d,0xea,0x90,0xeb,0xf4,0xef,0xf1,0x36,0x48,0x15,0x29,0x07,0x96,0x51,0xb5,0x78,0xa1,0xa3,0x59 +.byte 0x18,0x4d,0x11,0x5d,0x5e,0x67,0x69,0x28,0x29,0xcb,0xeb,0xbc,0x8f,0x17,0x12,0x57,0xaf,0xda,0xb5,0x86,0xef,0x59,0xdf,0xb1,0x6b,0x6a,0x33,0x66,0x67,0xd1,0x42,0xee,0xec,0x65,0xf2,0xeb,0x97,0x17,0x4e,0x01,0x3f,0x4d,0xb4,0x06,0x8e,0xf9,0xa8,0x79,0xb6,0xf1,0x67,0x8b,0xff,0x0b,0x5f,0x93,0x70,0x76,0x54,0xae,0x7b,0x0d,0x4a,0xbc +.byte 0xf7,0xdc,0x11,0x64,0xb3,0x6a,0xd1,0x69,0x45,0x1b,0x57,0xfc,0xb5,0xfe,0x86,0xb2,0xd6,0xde,0x82,0x23,0x86,0x6b,0x21,0x78,0x8b,0x2e,0x96,0xf8,0x04,0x8b,0xba,0x15,0xae,0x33,0x91,0x27,0x88,0xe3,0xc1,0xe7,0xf8,0xc3,0xa6,0xb6,0x73,0xec,0x84,0x95,0x22,0x45,0x58,0xb1,0x50,0x99,0xde,0x8a,0x37,0x41,0x9f,0xb8,0x27,0xd6,0xd8,0xaa +.byte 0x0f,0x0e,0xac,0xe4,0xd0,0x38,0xcf,0x2f,0x03,0x6f,0x3d,0x8a,0xd7,0x51,0xd6,0xf3,0x17,0x76,0xb5,0x0f,0xc5,0xf8,0xa7,0x0a,0x91,0xaa,0x8d,0xbc,0x15,0xd6,0x46,0xb9,0xdc,0x18,0x47,0x9c,0xd9,0x13,0xa5,0xb1,0xb5,0x45,0x2f,0x03,0x32,0x5c,0x8b,0xac,0x42,0x5b,0xd9,0x1a,0x41,0x1e,0x27,0xf9,0x92,0x72,0xc1,0xc7,0xc1,0x50,0x25,0x22 +.byte 0x7a,0x00,0x41,0x1f,0x2d,0x28,0xaf,0x41,0x96,0x8e,0x97,0x3b,0x36,0x80,0x16,0xe6,0x51,0x8f,0x07,0x13,0xd9,0x81,0x79,0x94,0x92,0xaa,0xb9,0xb6,0x39,0xf2,0x4d,0x24,0x6b,0x77,0x25,0x7e,0x47,0x6c,0xc7,0x62,0x3d,0x96,0x21,0xac,0x1a,0xf0,0x5f,0x5d,0x5a,0x7e,0x17,0xdd,0x47,0xd5,0x19,0x0a,0x85,0x3e,0xd5,0x6b,0x52,0x12,0xe2,0xbc +.byte 0x43,0x79,0x28,0x1d,0x72,0xcc,0xa6,0x6c,0xea,0x9b,0xe9,0x04,0x34,0x2c,0x41,0x3a,0x64,0xe8,0xcb,0x12,0xfa,0xd5,0x45,0xad,0xe8,0x3e,0xa2,0x5c,0xb8,0x83,0x52,0xdb,0x0c,0x98,0x24,0x76,0xd2,0x00,0x62,0xff,0xac,0xd7,0x11,0xee,0xcf,0xfb,0xdd,0x65,0xd2,0x75,0xb0,0x25,0x4e,0x76,0x3f,0xa2,0x1a,0xae,0xee,0xc1,0x59,0x1b,0x0c,0x42 +.byte 0x70,0x42,0x06,0x00,0x64,0x31,0xe0,0xce,0x3a,0x91,0x5e,0x9d,0x56,0x83,0xab,0xa7,0x73,0xc2,0x15,0x29,0xba,0xf9,0x1d,0xc8,0x4b,0xc6,0x3a,0x9e,0xab,0xd7,0xfd,0x17,0x8d,0x80,0xf0,0xa1,0x8a,0x5a,0x7a,0x80,0xd8,0x1f,0xa9,0x5b,0xec,0x68,0x99,0x3a,0x66,0xcc,0x5a,0xdf,0x5f,0xe9,0xd5,0x6a,0xf2,0x2c,0x7e,0xf8,0xa7,0xdf,0x0c,0x59 +.byte 0xbd,0x85,0xf0,0xc9,0x91,0x44,0x9c,0x86,0x24,0x60,0xfb,0xe9,0xff,0x3c,0xa7,0xa7,0x6d,0x4b,0x17,0xb3,0x24,0x99,0x14,0xbc,0x64,0xd0,0x41,0xaa,0xcd,0x26,0xd3,0xa3,0x51,0xeb,0x25,0x1d,0xb2,0x7d,0xf1,0xf3,0xf3,0xf0,0x3a,0xe0,0xb5,0xa9,0x24,0xc3,0x78,0x4a,0xef,0x9b,0x34,0x93,0xf8,0x0c,0x71,0x10,0x5b,0xf0,0xe7,0x08,0x4d,0x5f +.byte 0x74,0xbf,0x18,0x8b,0x48,0x8d,0xd7,0x23,0x81,0xed,0xa2,0x29,0xa9,0xdb,0x91,0xf6,0x61,0x7c,0xca,0x1e,0xe0,0xa7,0x21,0x9d,0xfc,0x04,0x3a,0x87,0xbb,0xf9,0xa4,0x3b,0xbb,0xc4,0x89,0xa1,0x7f,0xdc,0x83,0xfa,0x5e,0x0f,0xcf,0xdf,0xf6,0x41,0xd3,0xa3,0x76,0x76,0x44,0x3e,0x01,0xee,0xce,0xf6,0xc3,0xb9,0x49,0x43,0x6e,0xee,0x09,0x4c +.byte 0x87,0xe6,0xa3,0xf5,0xa0,0x8d,0x99,0xb3,0x3b,0xd6,0xeb,0x27,0xf9,0x34,0x68,0xc8,0x04,0x80,0xb2,0x4d,0xb6,0xde,0x98,0x81,0xe0,0xec,0xc9,0x06,0xde,0x86,0xee,0xf0,0x87,0xb8,0x67,0x0e,0xce,0xf8,0xc5,0xb1,0xd2,0xe1,0xe3,0x53,0x1d,0xbe,0x6c,0xdd,0x5e,0x83,0x02,0xf5,0xc8,0xda,0xcf,0x3c,0xcb,0x88,0x2c,0xca,0x65,0x65,0x9e,0x71 +.byte 0x4e,0xf2,0x98,0x96,0xb2,0x54,0xb4,0x96,0xdc,0x84,0xb5,0x39,0x74,0x9b,0x61,0xcf,0x52,0xef,0xb3,0x0c,0x62,0xc9,0x92,0xe1,0xe5,0x6f,0x2f,0x0c,0x61,0x0d,0x6f,0xfd,0xd8,0x84,0x25,0xba,0x20,0x59,0x00,0xf5,0xa9,0xf1,0x77,0x6e,0x9a,0x3d,0x93,0x69,0xde,0xaf,0x9a,0xe6,0xe3,0xfd,0xb9,0xd3,0x04,0x82,0x18,0xa1,0x5b,0x9b,0xe0,0x29 +.byte 0x4c,0x64,0xf5,0x95,0x57,0x25,0xd3,0x04,0x8b,0x4a,0xe9,0x57,0x6f,0xd1,0x8c,0x40,0x73,0x49,0x32,0x93,0x3f,0x26,0xb4,0x6b,0xd3,0xd4,0x90,0xb7,0xe1,0xaf,0xa0,0x9a,0xc0,0x86,0xb7,0x5e,0xec,0x29,0xaa,0x03,0x4e,0x56,0xb5,0xcd,0x46,0x7d,0xe0,0x26,0x3d,0x5f,0xd3,0x55,0x86,0x68,0x4a,0xc5,0x42,0x5d,0x60,0x3a,0x39,0x6f,0x45,0xb9 +.byte 0x6a,0xea,0xf4,0x05,0xc8,0x24,0xf8,0xcd,0xe5,0xeb,0xca,0x3a,0xe7,0xb4,0x59,0x83,0x5a,0xa5,0x1d,0xe4,0x6a,0xaa,0x35,0x00,0x42,0x32,0xa5,0x6c,0x3e,0xc1,0xc2,0xc4,0x9d,0x2e,0x43,0x57,0x79,0x52,0xf6,0x1e,0x02,0xb8,0x9b,0xcd,0xf0,0x3d,0x57,0xa3,0x6f,0xf7,0x12,0x54,0x6c,0x63,0x0d,0xb2,0xba,0xff,0xa1,0xf6,0xf5,0xdf,0xa5,0xed +.byte 0xda,0xdf,0x56,0x72,0x1e,0xc5,0x3f,0xad,0xd0,0xf9,0x38,0x94,0x51,0xe3,0xa4,0xb4,0xbf,0xd5,0x24,0x2a,0x90,0xfe,0xd4,0x34,0x6c,0xa8,0xc8,0x1c,0x9a,0xaf,0xac,0xff,0x5b,0x67,0x44,0x4c,0x4d,0xa7,0x59,0x2c,0x9f,0x67,0x07,0x25,0xe1,0x7f,0x4e,0x4a,0xaa,0x8f,0x5d,0xd1,0x26,0x0d,0x73,0x9b,0x69,0x5d,0xdf,0xb2,0xa5,0x89,0xbb,0x82 +.byte 0x0b,0x09,0xf3,0x11,0x76,0x5d,0x2d,0xad,0xc3,0xc1,0x15,0xbc,0xaf,0xa2,0xe6,0xd5,0xb0,0x6d,0x80,0xa6,0xda,0xfa,0x3b,0x9c,0xaf,0xff,0x98,0x40,0x83,0x3a,0xe1,0xb8,0x98,0x0e,0x97,0x00,0x89,0xfb,0x37,0xcb,0x81,0x36,0x34,0x33,0xbb,0x5c,0xd0,0x51,0x37,0xd6,0xb5,0x6c,0x3a,0x61,0x0a,0x27,0x23,0x96,0xa9,0x79,0x8d,0xf0,0xbe,0x31 +.byte 0xba,0xdc,0x89,0x4e,0x88,0x98,0xe4,0x10,0x15,0x8a,0xe1,0xae,0xe8,0x6d,0xa4,0x61,0x56,0x14,0x84,0x59,0x64,0xc2,0xaa,0xd8,0xfd,0x19,0xfc,0x17,0xf1,0xfc,0x6d,0x17,0xcb,0xea,0x7a,0x47,0x00,0x75,0x17,0xf3,0x62,0xfe,0x3a,0xbc,0x28,0x1a,0x0e,0x88,0x48,0x63,0x4a,0xcb,0x20,0x46,0xa4,0x75,0xf8,0xf1,0x7a,0xd6,0x92,0x7f,0x92,0xfa +.byte 0x91,0x95,0x2f,0xbc,0x5b,0x42,0xf1,0x55,0xaf,0x91,0xa2,0x3b,0x29,0x5c,0xc8,0x5e,0x97,0x91,0xa2,0x2e,0xd2,0xa8,0x1c,0xf6,0x16,0xc5,0x15,0xf2,0x42,0xb3,0x41,0x59,0x52,0x8d,0x94,0x52,0xc4,0xc6,0x2c,0xdd,0x6f,0x01,0xea,0x62,0x42,0x83,0x7e,0x2e,0xf8,0xb8,0xc1,0xf3,0x71,0xd1,0x11,0x14,0x7a,0x3d,0xcd,0xec,0xe0,0x79,0x8b,0xbd +.byte 0x28,0x12,0x60,0xf0,0x66,0xf1,0x1c,0x1c,0x19,0x07,0x8c,0x26,0xff,0xcc,0x72,0x9a,0xbd,0x12,0xe6,0x2b,0x2b,0xb1,0x32,0x04,0x98,0x92,0xd9,0x24,0x97,0x59,0x46,0xc6,0x11,0xe1,0x31,0x14,0x46,0x27,0x96,0xb1,0x06,0x81,0xd5,0xe8,0xff,0x45,0x3d,0x3c,0x04,0x9a,0xd8,0x0b,0x1f,0x41,0x03,0xba,0x1b,0x3e,0x4e,0xd5,0x7d,0x48,0x00,0x68 +.byte 0xb3,0xe8,0xe0,0xc8,0x3c,0xcf,0xdc,0xbe,0x29,0x90,0x64,0x51,0x18,0xdc,0xcd,0x87,0xcb,0xa8,0x3d,0xf8,0xb4,0x73,0x11,0xdc,0x7a,0xcb,0xa4,0x81,0x9e,0x3a,0x72,0xde,0x18,0x36,0x86,0x15,0x91,0xbc,0xeb,0x7f,0xe2,0xfb,0x6b,0xf1,0x5a,0x3d,0x05,0x50,0xeb,0xcf,0xd2,0xcc,0xf2,0x62,0xb1,0x32,0x46,0x14,0x95,0x4e,0xdf,0x73,0x64,0x61 +.byte 0x5f,0x3d,0xbf,0x52,0x3e,0xa7,0x55,0x01,0x9a,0xd8,0x01,0xef,0xf7,0x60,0x6f,0x83,0x43,0x6b,0x4c,0xa2,0xc8,0x04,0x34,0x70,0x70,0xa1,0x99,0xc9,0xa7,0x54,0x1e,0x87,0x99,0xb3,0xec,0xfe,0xe9,0x2d,0x39,0xef,0x6f,0x4d,0x8c,0xf2,0x4b,0xd2,0x12,0x5d,0xb6,0xa7,0x0b,0x04,0x3b,0x69,0xdd,0x9a,0x18,0x2d,0xd9,0x22,0x00,0x38,0x15,0x9a +.byte 0x6e,0x6c,0x0c,0x84,0x32,0x32,0xb2,0xf9,0x61,0xef,0x74,0x35,0xec,0xcc,0xd7,0xbc,0x9d,0xe9,0xcd,0xe3,0xa0,0xa5,0x15,0x0a,0xfe,0x1f,0x37,0x35,0x2b,0x7c,0x42,0x50,0x81,0x67,0x52,0xb7,0xa7,0x9e,0x8f,0xda,0x64,0xc0,0xc0,0xc3,0x93,0xc7,0x9d,0x41,0xb8,0x4b,0x69,0x80,0x13,0x88,0x8a,0x07,0xf9,0x47,0xad,0xc9,0x4f,0x3d,0xc7,0xba +.byte 0xd2,0xf2,0x7a,0xa0,0x38,0xbe,0xe1,0xfa,0x83,0xda,0x79,0x29,0x7f,0x4c,0xfa,0x0e,0x9b,0x59,0x1e,0x89,0x76,0x05,0x60,0x84,0x13,0x63,0x11,0x14,0x20,0xa9,0x2b,0xd0,0xc3,0x58,0xcc,0x73,0x3e,0x2c,0xa8,0xa7,0xa5,0xd0,0x2f,0x03,0xfc,0xa9,0x5d,0xdd,0xcd,0x40,0x91,0x90,0x1f,0xda,0x0a,0x73,0x58,0xd8,0x84,0x05,0x45,0x01,0x84,0x52 +.byte 0x8b,0x9b,0x17,0x98,0xa8,0xc4,0xc3,0xb5,0x94,0xd5,0x32,0x86,0xe9,0x10,0xe5,0xa5,0x99,0x8d,0x57,0x3e,0x32,0x25,0xfa,0xb4,0x5c,0x3a,0x5f,0xa6,0x2d,0x7d,0x4e,0xd3,0x7b,0xee,0x41,0x23,0x5e,0xc2,0xc9,0x91,0xf4,0x21,0xe0,0x4f,0x0d,0x87,0x30,0x53,0xf1,0x0e,0x63,0xe8,0x5b,0x3d,0xee,0x4a,0xc8,0x78,0x38,0xa2,0xa4,0xe8,0x72,0x41 +.byte 0xf1,0x37,0x30,0xe3,0x3d,0x93,0xc6,0x4b,0x10,0x0d,0xf6,0x20,0x15,0x0a,0x77,0x41,0xd5,0x7d,0xcb,0xf9,0xda,0x3b,0x17,0xa6,0xf1,0xe4,0x56,0xd4,0x65,0x7b,0x33,0xe4,0xef,0x34,0xfb,0x8c,0x9f,0x87,0x86,0xfc,0xce,0x90,0x60,0x77,0x57,0xc0,0xe4,0x37,0x2c,0xdf,0x41,0x95,0x85,0x89,0x4e,0x77,0x3f,0xa0,0xc7,0x55,0x4c,0x3f,0xa8,0x10 +.byte 0xd2,0x87,0x7e,0xd2,0x97,0xa1,0x6c,0xe7,0xec,0xaa,0xf6,0x93,0x13,0x2e,0x10,0xed,0x5b,0x7a,0xed,0x53,0xb4,0x55,0xaa,0xb4,0x67,0x78,0x07,0x5f,0xc2,0xd2,0xf1,0x7b,0x98,0xf0,0x82,0xf6,0x7c,0xb2,0xd4,0xa8,0xc2,0x53,0x39,0x21,0x7f,0xa0,0x76,0x37,0x1a,0x69,0xb3,0x49,0xd4,0xc3,0xd1,0xcb,0x31,0x76,0xec,0xaf,0x75,0x66,0x31,0x65 +.byte 0xeb,0x44,0x63,0xa0,0x13,0xf5,0x9e,0x67,0x40,0x41,0x76,0xce,0xd3,0xd6,0x91,0xb1,0x3a,0x07,0xff,0x38,0x1e,0xaf,0x55,0x57,0x55,0xd1,0x94,0x63,0xd3,0x81,0x16,0x59,0x68,0x01,0xe8,0x6d,0x7d,0x7a,0xa1,0x39,0xb9,0xa2,0xba,0x79,0x9d,0x69,0x00,0x13,0x59,0x2f,0x3d,0xef,0x10,0xe7,0x3c,0x02,0x7d,0xa3,0xa8,0xee,0x31,0x1a,0xad,0xa6 +.byte 0xdb,0x1b,0xe3,0x4a,0xdd,0x60,0xfb,0x4e,0xa6,0x49,0xbb,0xea,0x34,0x5d,0x21,0xac,0x83,0xa4,0xb5,0x23,0x8e,0x69,0xb3,0x25,0x14,0x8d,0xc2,0x89,0x8d,0xcf,0x38,0x46,0x18,0xb6,0x0c,0xce,0x45,0x22,0xeb,0xb5,0xb2,0xed,0xe5,0x0f,0x35,0x8f,0xdd,0xa1,0x15,0xd6,0x50,0x5b,0xe1,0x04,0xa7,0x32,0xc0,0xc9,0x03,0x56,0xc2,0x33,0xe8,0x16 +.byte 0x1c,0xd4,0x7a,0xfd,0x6b,0x4d,0x04,0xc0,0x9e,0xf8,0x32,0x9f,0x52,0x24,0xac,0xc5,0xb0,0xa1,0x63,0x77,0xc9,0x14,0xaf,0x46,0x60,0x67,0x52,0x81,0xbb,0x3f,0xf5,0x7f,0xad,0xef,0x7c,0x3a,0x71,0xc1,0x1e,0xea,0x4a,0xe0,0xd7,0xdd,0x31,0xf2,0x4b,0xdf,0x53,0x8a,0xc9,0x59,0x7a,0xb2,0x6f,0x7e,0xc0,0x00,0xa4,0x0d,0x09,0x9c,0xf7,0x22 +.byte 0x22,0xa9,0x37,0xde,0x3b,0xe1,0x74,0x85,0xcf,0xc5,0xb7,0x7b,0x0a,0xfd,0x6b,0xfa,0x98,0x49,0xa9,0x7f,0x52,0x23,0x0e,0xc0,0x4a,0xb3,0x81,0xa6,0x96,0x46,0x24,0xe7,0x01,0xd1,0xf2,0xac,0x31,0xb2,0x5e,0x61,0xe3,0xab,0xf8,0x1b,0x28,0xca,0xa2,0x78,0x3c,0xdf,0x8a,0xc1,0x17,0x46,0x9d,0xbd,0x69,0x31,0x41,0x8b,0xc1,0xc8,0xaa,0x68 +.byte 0xd5,0x35,0x65,0x49,0xfe,0xc6,0xa4,0x99,0xcc,0x62,0x4b,0x81,0x1c,0x21,0xa4,0xd8,0xe3,0xb3,0xe9,0x7c,0xf8,0x33,0x2f,0x21,0xa5,0x88,0xf2,0x8e,0x7d,0xee,0x00,0x00,0x62,0xcf,0x07,0x37,0x00,0x68,0x6c,0xb5,0x2d,0xc6,0x1b,0xcc,0x86,0x71,0xf0,0x4f,0x68,0xaf,0x0c,0x9a,0x25,0x69,0x71,0x2d,0xb5,0x87,0x90,0x02,0xd3,0xfc,0xbb,0x63 +.byte 0xa9,0xf1,0x13,0x4f,0xda,0x71,0x69,0x5c,0x0b,0xfd,0x3f,0x6c,0x2f,0x0b,0x4f,0x07,0x72,0x2d,0x2f,0x77,0xcb,0xa4,0xe4,0xbd,0x30,0xc7,0xe4,0xd9,0xf9,0x5d,0x2f,0x65,0xe4,0x41,0x5c,0xbc,0x03,0xa2,0x01,0xf9,0xfa,0x06,0x14,0x52,0x08,0x44,0x67,0x75,0x4e,0xbd,0x66,0x4a,0x26,0x3a,0x49,0xc4,0xba,0x02,0xb3,0x8e,0xa2,0x42,0xe7,0x92 +.byte 0x03,0x6d,0x61,0x10,0x73,0xd0,0x6f,0xe1,0x6e,0x67,0xff,0xb0,0x29,0x62,0x70,0x3c,0xeb,0x80,0xed,0x11,0x06,0xd6,0x18,0x60,0xe1,0x3d,0x21,0xa9,0xe9,0xd2,0x92,0x00,0x9e,0x13,0xf2,0x5d,0x38,0x71,0xdf,0xf3,0x5f,0x8a,0x90,0x45,0xf0,0x47,0x1f,0x0b,0x2d,0x12,0xf7,0x10,0x07,0x6a,0x52,0xe8,0xe2,0x26,0x9b,0x4b,0x7a,0x5f,0x97,0xb6 +.byte 0xf1,0x6d,0x47,0x3a,0x1e,0xc8,0x1d,0x78,0x5b,0x0a,0xb8,0x03,0xb1,0xe1,0xe7,0xc8,0xf0,0xe7,0x00,0xac,0xfc,0xd7,0x4a,0xde,0xaa,0xcd,0x0f,0xaf,0xf7,0x56,0x8e,0xed,0xfb,0xbe,0x7e,0xfe,0x62,0x75,0x7a,0x07,0x96,0xff,0xc3,0x21,0x35,0x71,0xb9,0x73,0x41,0xc2,0xb0,0xa8,0x6a,0x65,0x48,0xc4,0x50,0x31,0xe2,0xba,0xf4,0xe9,0x6c,0x03 +.byte 0x26,0x2c,0x77,0xfe,0x1a,0xd5,0x96,0xf6,0x6d,0xe4,0x14,0xfc,0xe2,0x1d,0x20,0x0c,0x14,0xa2,0x39,0x63,0xe5,0x16,0xef,0x6a,0xeb,0xe1,0x69,0xb8,0x67,0xa0,0x91,0xc1,0x8f,0xed,0xff,0xdf,0x26,0x1f,0xc3,0xb7,0x5d,0xe9,0xd2,0x72,0xe2,0x54,0x27,0x46,0x4f,0x33,0x25,0x59,0xaf,0xfa,0x87,0x4b,0x5a,0xda,0x7d,0x15,0x71,0x5d,0xb4,0x8d +.byte 0x95,0xb6,0x09,0x5b,0x8b,0xeb,0xe6,0xba,0xc8,0x2f,0x8f,0x9e,0xa8,0xab,0x6a,0xa6,0x26,0xb6,0xf5,0x80,0xd0,0x7d,0xe7,0x4c,0x18,0x5a,0x72,0x8f,0x3e,0x90,0xe5,0xa1,0x16,0x33,0x66,0xc3,0x7b,0xf6,0xb6,0xdd,0x15,0x94,0x6d,0xca,0x8b,0xd7,0xa5,0x05,0xfb,0x5f,0x4e,0x94,0x6a,0xcc,0x54,0xed,0xeb,0xc0,0xb1,0xe1,0xc9,0x7f,0xc4,0x90 +.byte 0x2f,0x50,0x34,0x81,0x3c,0x83,0x47,0x3c,0x5a,0xb2,0x33,0x63,0xb6,0xa7,0xfb,0x59,0x70,0x87,0xea,0x7f,0x30,0x22,0xb4,0x54,0x48,0xfb,0x40,0xd2,0x7b,0xc9,0x49,0x80,0x18,0x27,0xc2,0x75,0x09,0x06,0x0a,0x83,0x1e,0x7a,0xf1,0x97,0xa1,0xc2,0x34,0x3f,0x6d,0xd6,0x2d,0xfe,0x5d,0x8b,0xfd,0x64,0x5d,0x6f,0x7f,0xbf,0x4e,0x01,0xb7,0x46 +.byte 0xfb,0xf7,0xd5,0x6f,0x5f,0x74,0xc8,0xca,0x9a,0x2e,0x74,0x08,0xe9,0x3d,0x8b,0xfd,0x97,0x38,0x72,0x67,0xbb,0x8a,0x34,0xee,0xf5,0x3a,0x2b,0x5e,0x64,0x64,0x06,0x7c,0x60,0x0f,0x7a,0x88,0x45,0x1b,0x69,0x90,0xb8,0xb0,0x4d,0x71,0x80,0x77,0xa8,0xaa,0x9f,0xd3,0xc6,0xfb,0xb8,0x12,0x1e,0x0c,0xf4,0x94,0x67,0x44,0xdc,0xb1,0x95,0x0e +.byte 0x51,0xd1,0x06,0x69,0x92,0xbf,0xe6,0x67,0xe3,0xcd,0x0b,0x87,0x03,0x12,0x2e,0xa7,0x23,0x72,0x13,0xe9,0x89,0xcf,0x15,0x43,0xc0,0xa7,0x68,0xbd,0xce,0xec,0x28,0xb6,0x85,0x36,0xbe,0x52,0x5d,0x57,0xfa,0x7d,0x72,0xd1,0x4b,0x88,0xc9,0x64,0xbc,0x7a,0x18,0xe5,0x0e,0xab,0x19,0x81,0xee,0x11,0xbe,0xe0,0x68,0x44,0x81,0x49,0x3f,0xd8 +.byte 0x12,0xd1,0x8b,0xc1,0xe0,0x51,0xf7,0xc3,0x64,0xa7,0xc5,0x61,0x9b,0x32,0x6d,0xf0,0x6c,0xa6,0xaf,0xf9,0x4a,0xdf,0x94,0xaf,0xc8,0xf2,0x86,0xb1,0x4e,0x2e,0xa9,0xb4,0x35,0x82,0x15,0x8a,0x58,0xf3,0x03,0x2f,0x78,0x07,0x8f,0xb9,0x16,0x7c,0x42,0xfa,0x36,0xaa,0xa5,0x66,0x62,0x44,0xca,0xa6,0x55,0x95,0x27,0xdb,0x48,0xea,0x0a,0x1d +.byte 0x5a,0xae,0x5c,0xad,0x99,0xfe,0x00,0xf1,0xb9,0x94,0xda,0x09,0x48,0x52,0x9d,0xfc,0xb4,0xb2,0x80,0x19,0x16,0xf8,0xcd,0x68,0x10,0xec,0x1c,0x16,0x3f,0xbb,0x42,0xb4,0x10,0xe3,0xdb,0xaa,0xe4,0x3f,0x2e,0x8e,0xb5,0xce,0xba,0x8f,0xf2,0xb5,0x76,0x98,0x15,0xa7,0x77,0x4b,0x1c,0x30,0xb7,0x6f,0xc9,0xa9,0xa4,0x64,0x59,0xab,0x3a,0x43 +.byte 0x74,0x33,0xab,0xe1,0x3e,0x5e,0x79,0x1c,0xa5,0xb4,0x87,0xe1,0xcb,0xea,0x0e,0x02,0x4b,0x01,0x84,0xbc,0xdc,0x75,0xf4,0x2c,0x2b,0x8d,0xc8,0x5f,0xb5,0xba,0x6b,0xb2,0x4a,0x7c,0xe7,0xaa,0x61,0xa5,0x0c,0xf8,0x02,0x73,0xec,0x11,0x13,0x6b,0x31,0x07,0xaa,0x79,0x78,0x86,0x01,0x77,0x5e,0xa3,0x09,0xd1,0xec,0xaf,0x7d,0xb7,0x65,0xa9 +.byte 0xd8,0x99,0xd2,0xd7,0x6d,0x32,0x97,0x0f,0x0e,0x51,0x0d,0x69,0x81,0x7a,0x94,0x48,0x31,0xe1,0xff,0x26,0x4d,0x30,0x49,0x93,0xfb,0x6e,0xdb,0xea,0xaf,0xcb,0xb4,0xa9,0xc9,0x9f,0xeb,0xca,0x52,0x36,0x26,0xac,0x47,0xda,0x02,0x3d,0xd0,0x93,0x8b,0x61,0x78,0x26,0x54,0x32,0xe8,0x14,0xac,0xf3,0xd2,0x46,0x04,0x12,0x89,0x9f,0xf6,0x11 +.byte 0xf5,0x64,0x83,0x66,0x00,0x50,0x55,0x05,0xb5,0xf6,0x58,0x9f,0xbf,0x4b,0x95,0xf1,0x7f,0x0b,0xb4,0xf7,0x63,0xea,0x6f,0xf7,0xb0,0x20,0x53,0xfe,0x95,0xbc,0xc4,0xe2,0xff,0x75,0xbd,0xab,0x73,0x68,0x44,0x18,0xf7,0x6b,0x04,0x46,0xde,0x6c,0x65,0xb2,0x22,0x4e,0x25,0x8e,0xba,0x7c,0x3a,0x6f,0x80,0x99,0xb4,0xe7,0xf9,0x97,0x68,0x40 +.byte 0xa9,0x96,0xfc,0x6b,0xcf,0x08,0x75,0xe4,0xda,0x6f,0xaf,0x71,0x4f,0x31,0x62,0x31,0x18,0xbf,0xb9,0xa0,0xcc,0x9e,0xa7,0xa2,0x27,0x2a,0xb8,0x6b,0xc0,0x93,0xf5,0x1f,0x41,0x25,0xa7,0x4d,0x9f,0xb4,0x12,0x5c,0x27,0x38,0x5d,0x80,0x88,0xa3,0xb8,0xb2,0xc3,0xd2,0xfb,0x1d,0xba,0x7b,0xac,0x51,0x0b,0x71,0x58,0x3f,0xe5,0xfa,0x36,0xb8 +.byte 0xc7,0x90,0x46,0xd0,0x5a,0x94,0xf0,0x7d,0x6e,0x6c,0x4c,0xb1,0xfa,0xdb,0x97,0x1e,0x19,0xf2,0x1f,0x4e,0x05,0x25,0x0e,0xbd,0x47,0x94,0x2a,0xd3,0x1a,0xbe,0x4a,0x04,0xaa,0x57,0x02,0xc9,0x42,0xc1,0x74,0xcd,0xe1,0x78,0x8b,0xff,0xc1,0xc6,0x17,0x4e,0x71,0xc4,0x2c,0x00,0x23,0x56,0x57,0x1f,0x47,0xd8,0x93,0x80,0xc1,0xc5,0x7b,0xd9 +.byte 0x25,0x30,0xac,0x72,0x37,0x00,0xd2,0xbc,0xc7,0x33,0x73,0xf9,0x14,0x86,0x7c,0xb0,0x28,0x14,0x5d,0xbf,0xbd,0x98,0x1c,0x00,0x05,0x19,0x2b,0x0a,0x55,0xad,0xb4,0x06,0x28,0x58,0x03,0xa1,0xe6,0x27,0xa3,0x32,0x5f,0x41,0xd5,0x6a,0x0b,0xbc,0x0f,0xaa,0xf5,0xc1,0xa7,0x09,0x2f,0x86,0xda,0x56,0xb0,0x04,0x49,0xd4,0x20,0xc6,0xa2,0x6c +.byte 0x27,0x56,0x4e,0xcd,0x22,0x46,0xac,0x0f,0xd3,0x99,0x69,0x83,0xc4,0xae,0x9f,0x88,0xed,0x9c,0xba,0xfb,0xf3,0x66,0xc7,0x3d,0x65,0x55,0xd0,0xe3,0x04,0x03,0x6a,0x02,0x5c,0xbf,0x9f,0x23,0x34,0x79,0xe1,0xbe,0x7d,0xad,0xb4,0xc7,0x9e,0x4d,0x80,0x73,0x6d,0xe5,0x37,0x03,0xac,0xa3,0xf4,0x93,0xad,0x1e,0xf3,0xcd,0xb8,0xe2,0xeb,0x30 +.byte 0xc7,0x50,0xfe,0x0a,0x63,0x5e,0x0f,0xc9,0xd0,0x06,0x58,0xc1,0x6e,0x65,0x54,0x54,0x5d,0xaf,0xf1,0xe8,0x3e,0x95,0xe3,0x70,0x40,0x8e,0xb8,0x4d,0x76,0xda,0xa8,0xe8,0x9e,0x88,0xd8,0xaf,0x67,0x83,0x3b,0x77,0x65,0x58,0x00,0xbb,0xf7,0xe9,0x52,0xf0,0xba,0x0d,0x0a,0x59,0x28,0xe4,0xa7,0xfb,0x06,0xe5,0x34,0xbe,0xcf,0x10,0x7c,0x73 +.byte 0xa8,0xf3,0xa2,0x93,0x96,0x9e,0x4f,0x9b,0x3c,0xd1,0x9f,0x64,0x5b,0x8c,0xc1,0x89,0x66,0x67,0x13,0x52,0xb2,0xaa,0x6b,0x8e,0xea,0x97,0x27,0x20,0x2e,0x64,0xec,0xf0,0x72,0xc9,0x54,0x8a,0xed,0x78,0x3a,0xd7,0x4f,0xc2,0xba,0xc3,0xb8,0x64,0x7f,0xe4,0x5f,0x3d,0xf7,0xe5,0xd9,0xf1,0x8d,0xb1,0xd2,0xf6,0xcc,0x34,0xd8,0x7d,0x16,0xca +.byte 0x47,0xaf,0x85,0xe5,0x4a,0x57,0xb9,0x5a,0x9e,0xff,0xb8,0x83,0xec,0x7c,0xb8,0x07,0xf5,0xd3,0x31,0x31,0x2b,0xf0,0x40,0x46,0xc3,0x63,0x27,0xe4,0xb0,0x3b,0x84,0x0d,0x50,0x05,0x80,0x0c,0xfa,0x8b,0x0e,0x33,0x6b,0x10,0xd4,0xf5,0x4f,0x8b,0x2d,0x9e,0xc5,0x01,0x92,0x52,0x62,0x1a,0x89,0x1e,0xca,0x48,0xc3,0xd6,0xfa,0xd2,0x94,0x7c +.byte 0x77,0x6e,0xa7,0xeb,0xd7,0x4f,0xe8,0xc8,0xc2,0x71,0xb2,0x9e,0x86,0x30,0x18,0xfd,0x4c,0x56,0x4c,0xd0,0xa4,0x84,0x37,0x02,0x02,0x6a,0x8d,0x57,0x6b,0xc2,0x06,0xd1,0x8a,0xdb,0xa0,0xcc,0x31,0xf9,0xcf,0xbf,0xf2,0x29,0x7c,0x26,0xac,0x1f,0x03,0x20,0x26,0x76,0x03,0x6f,0xa5,0xb5,0x33,0xfb,0x02,0xe8,0xf6,0xe9,0x5e,0xb1,0x36,0x7c +.byte 0x96,0x56,0xb1,0x98,0x2d,0x9c,0x38,0x9b,0xd4,0x56,0x28,0xcc,0xdb,0x08,0xd3,0x42,0x00,0x35,0x24,0xd9,0x74,0xa2,0x0d,0x55,0x21,0x06,0xb7,0xf9,0x6a,0xa0,0x81,0xc1,0x2d,0xb6,0x67,0x91,0x92,0x24,0x36,0xfd,0x2e,0xd8,0xc0,0xcb,0xc8,0x87,0x1a,0x41,0x11,0x70,0xbf,0xd2,0xe7,0x82,0x10,0x74,0xdf,0x65,0x46,0x19,0x6b,0xb4,0x89,0xeb +.byte 0x9e,0xcf,0x79,0x35,0xba,0x25,0x75,0x32,0x64,0x6a,0xfb,0xaf,0xe5,0xed,0x85,0x98,0x34,0x75,0x31,0x40,0xbb,0xd8,0xe3,0xf5,0xa7,0xa2,0x9a,0x9e,0xcd,0xc4,0xf8,0xd8,0x15,0x6c,0x64,0x0c,0x6c,0x16,0x60,0xe9,0x40,0xf4,0x7a,0x14,0x37,0x7b,0x45,0x9b,0x0e,0x29,0x7a,0x1a,0x88,0x10,0xb9,0x2b,0xee,0x13,0xbd,0x8a,0xde,0x7a,0xe9,0x30 +.byte 0xe8,0x39,0x77,0x74,0xf5,0x2f,0xe3,0x10,0x19,0x89,0x28,0x21,0x3a,0x68,0x38,0xb4,0x4d,0x20,0x8d,0x7d,0xec,0x3f,0xf7,0x61,0xbf,0x53,0x32,0x3b,0xb8,0x6a,0xc9,0x58,0xeb,0xd4,0x33,0x0e,0xee,0xc7,0xb9,0x5e,0x3d,0x17,0x7e,0x36,0xa2,0xa6,0x94,0xb1,0x56,0xb6,0x8e,0x94,0x05,0x50,0x69,0x52,0x4f,0x31,0xe5,0x97,0x18,0xde,0x8f,0xb7 +.byte 0xff,0x2e,0x6f,0x1b,0x6a,0xda,0xfd,0xa1,0xd1,0x9a,0x4e,0x6a,0x1b,0x46,0x71,0x52,0x76,0x66,0xf9,0x70,0x8d,0x7d,0x97,0xb0,0xc3,0x8d,0xbc,0x35,0x26,0xe8,0x0b,0x80,0xc7,0x58,0x19,0x22,0x70,0x33,0x06,0xeb,0xcf,0x26,0x22,0xe0,0x97,0x91,0xbf,0xd6,0x94,0x05,0xe1,0x84,0xe2,0x31,0x66,0x57,0xc7,0x1e,0x36,0x30,0x50,0xaf,0x72,0xb3 +.byte 0x31,0xad,0x84,0xcc,0xb5,0x76,0x03,0xe1,0x56,0x97,0x87,0x36,0xf5,0xaa,0x97,0x99,0x38,0xa5,0xf5,0xb7,0x42,0x86,0x3b,0x2f,0x8a,0xb9,0x8e,0x6a,0x0b,0xe0,0xca,0xbc,0x4c,0x6c,0xc1,0x3f,0xbe,0x45,0xef,0xd2,0x57,0xcd,0x29,0xfb,0xfb,0xa5,0x79,0xf2,0xb1,0xbb,0x4b,0x55,0x26,0x2f,0x5c,0x84,0x5e,0x6a,0xc6,0xa9,0xd5,0x23,0xe4,0xd1 +.byte 0xe5,0xf0,0xbc,0x50,0x6a,0x2a,0xaf,0xa2,0x7c,0xcc,0x36,0x95,0xf9,0x5c,0x04,0x6d,0x04,0x31,0xbe,0x1d,0xb2,0x50,0x97,0x8f,0xdf,0x8a,0xed,0x4e,0x4e,0x0a,0x0b,0xfc,0xfc,0x1d,0xa9,0x6a,0x76,0x6a,0x33,0xd7,0x0a,0xcf,0xd5,0xdd,0xc6,0x62,0xe5,0x59,0x02,0xba,0x9c,0x43,0x32,0x8a,0x0e,0x47,0x91,0x00,0x07,0x47,0x93,0xc4,0xad,0x29 +.byte 0x33,0x57,0x15,0x45,0x44,0xb9,0xf3,0xc4,0xe6,0xd2,0xb9,0x3a,0x44,0x16,0x32,0x8d,0x57,0x78,0xac,0xf5,0xdb,0xa2,0x93,0x97,0x64,0x08,0x9b,0x66,0x4b,0xa0,0x64,0xab,0xa0,0xd6,0x0e,0x2c,0xa1,0x25,0x16,0x5c,0x6f,0x82,0xff,0x8e,0x89,0xfb,0xca,0x03,0xa6,0xf8,0xa1,0xf6,0x87,0x02,0x5c,0x90,0xcb,0x33,0xa0,0xc0,0x90,0xc2,0x1f,0xdd +.byte 0x5c,0x50,0x93,0xf2,0x8b,0x87,0xa1,0x73,0xda,0x5f,0xa3,0x20,0xd4,0xe7,0x45,0xd7,0xea,0x4b,0x5d,0xd6,0x80,0xfc,0x2d,0xdc,0x45,0x6a,0xf6,0xaf,0xd4,0x7a,0x91,0x64,0x15,0x17,0xbf,0xc7,0x58,0x54,0x7c,0x08,0x42,0x4f,0x8d,0xab,0x9b,0xd0,0x1d,0x57,0x71,0x50,0xa7,0xe3,0xb4,0xf2,0x14,0x0c,0xd7,0x2f,0x7c,0x8b,0x17,0x61,0x98,0xfa +.byte 0x19,0x34,0xb9,0x65,0xc5,0x5c,0xfe,0xa3,0x80,0x6f,0x99,0xec,0xfa,0x06,0x22,0x71,0xa9,0x10,0x2a,0xcf,0x12,0xb3,0x17,0xe5,0x59,0x3a,0xaa,0xcb,0x55,0x5f,0x45,0x9d,0xe9,0x29,0x56,0x34,0x11,0x62,0x6e,0x0a,0x95,0x12,0x5d,0xd4,0xa2,0x28,0x05,0xf1,0x0f,0x2d,0xa0,0x1e,0xe1,0x2b,0x42,0x6c,0xf0,0xe6,0x47,0xe0,0xb2,0xbd,0x89,0x20 +.byte 0x5e,0x24,0x05,0xec,0xf1,0x33,0xfc,0xa9,0x2f,0xef,0x3a,0x1f,0xfe,0x39,0xfe,0x01,0x09,0x0a,0x2a,0xe0,0x96,0x1e,0xde,0xad,0x96,0xaa,0x48,0xeb,0x8a,0xe6,0x54,0xbb,0x5d,0x7a,0xbe,0x4a,0xbf,0x96,0xf6,0x15,0x7a,0x70,0x6f,0xee,0xe7,0xf5,0x53,0xaf,0xe1,0xbb,0xaf,0x58,0x51,0xd4,0xa0,0xc6,0x44,0x03,0x47,0x33,0xce,0x58,0x62,0xd3 +.byte 0x93,0x21,0xa5,0xa5,0xb4,0xef,0x1d,0x93,0xcc,0x8c,0xf7,0x14,0xe3,0xec,0x40,0x52,0x47,0xe6,0xbc,0xe6,0x85,0x69,0xd0,0x15,0xad,0x24,0x21,0x4f,0x26,0x01,0x60,0x0f,0x0f,0xcb,0x7e,0x14,0x01,0xe1,0x90,0x11,0x06,0x17,0x38,0x2d,0xd8,0x26,0xe2,0x7c,0xd6,0xef,0xe0,0x59,0xf0,0x8c,0x2a,0xbd,0xba,0xe5,0x8b,0x07,0x56,0xd3,0x35,0xb3 +.byte 0x64,0x83,0x9e,0xb9,0xb9,0xeb,0x88,0x03,0xff,0x14,0xf3,0x8b,0x14,0xd3,0xa4,0xac,0x08,0xd9,0x75,0xf6,0x2c,0x9d,0x7f,0xc8,0x9d,0x11,0x3b,0xd1,0x71,0x14,0x4b,0x2a,0x6d,0x20,0x83,0x32,0x35,0x7e,0x1f,0x20,0xa6,0x69,0xbf,0xcf,0x22,0xd9,0xa2,0x57,0x4b,0x66,0xb1,0x9f,0x5a,0xa8,0xaa,0xb8,0x11,0x1d,0x45,0x28,0xac,0x86,0x09,0x37 +.byte 0xe9,0x1f,0xef,0xb4,0xe0,0x6f,0x75,0xad,0xe5,0xd8,0x25,0x06,0x19,0xb4,0xa8,0x07,0x78,0x79,0x43,0x63,0x40,0x26,0xbd,0x28,0x50,0x2d,0x29,0x26,0xf9,0xfc,0x5c,0x71,0x8f,0xfd,0x62,0x12,0x7c,0xd0,0x67,0xb3,0x65,0xef,0x31,0xc0,0x99,0xc1,0x54,0xfc,0x32,0x6e,0x25,0x56,0x77,0x6e,0xc1,0x6b,0x11,0x50,0x7c,0xa1,0x0b,0x97,0x8a,0xfe +.byte 0x0f,0x5b,0x16,0x93,0x83,0xe0,0xd8,0xb7,0xbf,0xa8,0x90,0x6d,0xd6,0x8b,0x4b,0xd9,0x17,0xbb,0xe8,0xd9,0xbb,0x5f,0x39,0x4a,0x33,0x7c,0xb3,0x12,0x99,0x1e,0xfc,0xb2,0x05,0x91,0x67,0xdf,0x8d,0x0b,0x55,0xfb,0xd1,0x8d,0x0c,0x9b,0x80,0x81,0xee,0x8c,0x05,0xe2,0x16,0x30,0xad,0x1f,0x88,0x04,0x75,0xc1,0xe5,0xec,0x32,0xf8,0xa0,0x5b +.byte 0x21,0xf6,0xd8,0x13,0x26,0xe4,0xa1,0x32,0xa8,0x93,0x91,0x5d,0x33,0x45,0x83,0x72,0x52,0x59,0x23,0x84,0xf6,0x7b,0xe2,0x90,0x20,0xc6,0x40,0x33,0xa9,0x94,0xcd,0xb9,0xab,0xe4,0x44,0x0b,0x06,0xbb,0x4c,0x2c,0x2a,0x5e,0x4d,0x57,0xb7,0xe0,0xb8,0x86,0x74,0xab,0xea,0x37,0x1c,0xa0,0xa6,0x21,0x33,0xc7,0xf5,0x24,0x7d,0x14,0xc8,0x8b +.byte 0x9d,0x8f,0x31,0x23,0x29,0x9d,0x11,0x42,0x07,0xe8,0x2c,0xec,0x7d,0x70,0x8d,0xb5,0xa4,0xca,0x33,0x30,0x03,0x75,0x17,0xa1,0x10,0xe7,0x6b,0x87,0xf9,0x0b,0xef,0x43,0xef,0xf8,0x24,0xc2,0xf1,0x7a,0x1a,0x70,0x7e,0x2f,0xd4,0xeb,0x97,0x40,0xa6,0xe6,0x2d,0xc1,0xd8,0x3b,0xee,0xa4,0xda,0xd3,0x50,0x41,0x18,0xbf,0xad,0x66,0x02,0x85 +.byte 0x60,0x14,0xcf,0xce,0x50,0x88,0x5e,0xb6,0x73,0x11,0xbb,0x6a,0xca,0xb1,0x46,0x8e,0xbb,0x58,0x2c,0x63,0x61,0x20,0xec,0xc9,0x98,0x0c,0xdb,0x5c,0xe5,0x47,0xb5,0x89,0xe9,0x14,0xc8,0xbc,0x35,0xf2,0xa7,0x2d,0x84,0xcc,0x61,0xc8,0xb6,0x9d,0xeb,0xcb,0x8b,0x73,0x90,0x6d,0x06,0xc9,0x42,0xcf,0xd2,0x15,0x80,0x2d,0x39,0xeb,0x71,0x83 +.byte 0x27,0x0d,0x85,0xf9,0xa3,0xce,0xef,0x29,0x3b,0x10,0xb7,0xe9,0xd0,0x86,0x6e,0x88,0x1e,0x3b,0xdd,0xaf,0x52,0xde,0xa2,0xa4,0x13,0x3c,0x1f,0xcb,0x84,0x74,0x12,0x04,0x91,0x40,0xb8,0x1b,0x15,0xfd,0xdb,0xe8,0x74,0xcc,0x4d,0x41,0xb5,0x5a,0x92,0xd3,0x71,0xf7,0x57,0xa5,0xf7,0x18,0x5a,0x57,0x36,0xde,0x8f,0xb2,0x81,0x59,0xc8,0x5c +.byte 0x22,0xcf,0xdc,0x7d,0xff,0x83,0xf2,0xad,0x8c,0x7b,0xd5,0x04,0xc4,0xb9,0x79,0x4a,0x12,0xa7,0xb1,0x7e,0x57,0xa5,0x6b,0x56,0x8a,0x11,0x96,0x57,0xde,0x35,0xdd,0xef,0x9b,0x03,0x41,0xde,0x61,0x5b,0x73,0x8c,0x6a,0x0c,0x6f,0xae,0x45,0x4b,0x56,0x4d,0xbe,0x8a,0x3f,0xdb,0x79,0x58,0x88,0xad,0xcb,0xfa,0x66,0x06,0x0e,0x74,0x21,0x1d +.byte 0xe1,0x94,0xd7,0x06,0xea,0x60,0xe2,0x7d,0x70,0xcf,0xa9,0x4f,0xe6,0x9b,0xba,0x19,0x71,0x69,0x94,0x66,0x5a,0xb8,0x49,0x0c,0xd1,0x9a,0xc4,0x5f,0xa7,0xf4,0x9e,0x3d,0x9e,0xc2,0xd8,0x0e,0xd2,0x6d,0xc6,0xc8,0x99,0xc3,0x5e,0x3b,0xb9,0xd8,0x48,0xc0,0x38,0x48,0x95,0x89,0xff,0x7e,0x1d,0x80,0x53,0xac,0x7b,0xd7,0xfc,0x6f,0x5d,0x25 +.byte 0x2f,0xcf,0x15,0xdb,0x1a,0x64,0xc1,0x16,0x91,0x65,0x84,0x99,0x0a,0xc1,0xbf,0x4d,0x11,0xa5,0x55,0x55,0x35,0x93,0x6f,0x47,0xf1,0x75,0xb8,0xb6,0x11,0x9d,0x6e,0x3b,0xd1,0x11,0x20,0xa2,0xa2,0x5c,0x33,0x85,0x09,0xb8,0x13,0xc9,0xdd,0xf2,0xd4,0x32,0x37,0xf2,0xef,0x47,0xfa,0x25,0x1a,0xcc,0xdf,0xf4,0xe4,0x2c,0x2c,0x7f,0x23,0xb6 +.byte 0xa8,0xd4,0x6a,0xd4,0xb4,0x06,0x2e,0xb0,0xaa,0xa1,0x18,0x8a,0x5c,0xc6,0xb2,0x4c,0x71,0x92,0x4a,0xdc,0x81,0x20,0x51,0x8d,0x3f,0x71,0x7d,0x8c,0x25,0x79,0x07,0x14,0xa9,0x7a,0x8b,0xda,0x00,0xfc,0x51,0xdb,0xa0,0x50,0x2b,0x15,0x39,0xf6,0xad,0xdc,0x9e,0x22,0x93,0x2f,0x43,0xd8,0x5c,0xa2,0x5e,0xfa,0x70,0x8c,0xe0,0x6b,0x0e,0x93 +.byte 0x6c,0x89,0xfe,0x22,0x4c,0xec,0xb0,0x7e,0xc1,0x06,0x69,0xf7,0x2f,0x3e,0xe5,0xa4,0x45,0x53,0xab,0x9c,0xf5,0x40,0x05,0x53,0x64,0xc6,0xa7,0xf9,0xc4,0xd6,0x89,0xd9,0x47,0x72,0x8e,0x42,0xf9,0x64,0x12,0xeb,0xd9,0x25,0xdc,0x4c,0xc6,0xea,0x9c,0x4b,0x93,0xb4,0xa2,0xa6,0xae,0x95,0xc1,0x84,0x75,0xc9,0x22,0xe3,0x22,0x81,0x31,0xd1 +.byte 0xfd,0x2e,0x91,0x4a,0xc3,0x00,0xa6,0x57,0xbb,0x89,0x9f,0x2d,0xc3,0x2e,0x1f,0xa2,0x47,0xc4,0xa3,0xcd,0x2b,0xc2,0x29,0xaf,0x89,0xce,0x2e,0x87,0x8e,0xd8,0xfc,0xee,0xab,0x8a,0xbd,0x2f,0xee,0xcf,0x94,0xe0,0x74,0x70,0x86,0x00,0x42,0x11,0x8b,0x6c,0x81,0xd4,0x82,0xf2,0x29,0x3e,0x9c,0x68,0x71,0xaa,0x20,0x0a,0x51,0x5d,0x80,0x4c +.byte 0xca,0x04,0x23,0x23,0xe2,0x69,0xb3,0xf5,0x65,0x98,0x19,0xee,0xa9,0x4d,0xd8,0xe0,0x06,0x4b,0x17,0xed,0xfa,0xf2,0xe3,0xd3,0x69,0x48,0xe4,0x4e,0xc0,0x5a,0x16,0x90,0xdb,0xb6,0x32,0x6e,0x6b,0xd7,0x7a,0xb6,0xd4,0x82,0xe4,0xcc,0x31,0x31,0x5c,0x18,0x84,0xef,0x75,0x9f,0xda,0xf6,0x62,0x2d,0x96,0x4d,0xa1,0x3c,0xb5,0x4a,0xbb,0xbf +.byte 0x9d,0xb3,0x33,0x00,0xc1,0x73,0xc5,0xb2,0xeb,0x85,0x74,0xb0,0x68,0xed,0x16,0x66,0x71,0xc9,0x7e,0x6f,0x74,0xa6,0xe7,0xed,0xf0,0xfa,0xab,0x41,0xdd,0x10,0xf9,0xff,0x4c,0xb6,0x4f,0x15,0xe3,0x77,0x31,0x17,0x5c,0x5a,0xef,0xb2,0xa9,0x44,0xbe,0x97,0xa9,0x75,0x5a,0xb7,0xe0,0x16,0x17,0x37,0x1b,0x71,0x03,0xb9,0xaa,0x7b,0x7b,0x52 +.byte 0x46,0x58,0x6b,0x9b,0x87,0x27,0xa6,0x8a,0x0e,0x84,0x03,0x45,0x95,0x04,0xf1,0x7e,0xb6,0xf6,0x79,0xd5,0x66,0x6d,0x50,0x8c,0x5a,0x67,0xe0,0xdd,0x69,0xd8,0x92,0x75,0x15,0xcb,0xa5,0x05,0xfe,0x7a,0xc1,0xd6,0x11,0x57,0x10,0xa3,0xc3,0xb6,0xe9,0xe3,0x97,0xa5,0x46,0xc9,0xe9,0x9b,0x68,0xb6,0x55,0x0b,0xf2,0x17,0x9d,0x0e,0x7f,0xd9 +.byte 0x26,0x0c,0x01,0xff,0x95,0xe1,0x05,0xb7,0xbf,0x0d,0x77,0x12,0x96,0x03,0x71,0x01,0xc9,0x98,0xb4,0x44,0x94,0xc0,0xad,0x3d,0xfc,0x6f,0xe5,0x0c,0xa4,0x65,0xd7,0xe7,0x76,0x7c,0xb8,0xa0,0x0a,0xcd,0xe8,0x01,0x26,0x8e,0x94,0xec,0x94,0x65,0x86,0xee,0x4d,0x3b,0xc5,0xb5,0x2e,0x51,0xb7,0xa9,0x68,0xcd,0x14,0x90,0xd8,0x36,0xfb,0x52 +.byte 0x04,0x52,0xb4,0xca,0x9b,0xbf,0xc6,0x94,0x28,0xc5,0x7e,0x27,0x73,0xae,0x6d,0xba,0xe7,0x56,0xce,0x2e,0x00,0xeb,0x36,0x19,0xd7,0x4f,0x20,0x5e,0xfd,0x0f,0xd4,0x4c,0x02,0xaf,0xdb,0x74,0xef,0xf0,0x73,0x1e,0x2a,0x1a,0xe7,0x3a,0xe0,0xa5,0x89,0xcf,0x1a,0x66,0xbd,0x72,0x65,0xb4,0xf4,0x86,0x33,0x44,0xee,0x35,0xf6,0x09,0xbe,0x13 +.byte 0x96,0x84,0x04,0x95,0x3f,0x35,0xbb,0x01,0x2c,0x78,0x25,0xe8,0x1e,0x46,0xdb,0xd9,0xb1,0xe8,0xfb,0x2b,0xa8,0x59,0x72,0x5f,0x91,0xd3,0x7c,0x21,0x95,0xa9,0x50,0xa2,0x45,0x6f,0x48,0x0c,0xf2,0x51,0x10,0x3c,0xcd,0xea,0xeb,0x5d,0xc7,0xf9,0x0e,0xae,0x1a,0x02,0x05,0x15,0x12,0x10,0xc0,0x35,0x12,0x97,0xcd,0x5b,0x61,0x4f,0xd1,0xd3 +.byte 0x5b,0xec,0x2b,0xa0,0x20,0x03,0x2b,0xf3,0xe6,0x71,0x23,0xca,0x1d,0x48,0x64,0x3f,0x7e,0x52,0x8b,0xf9,0x96,0x33,0x31,0xbc,0xbd,0x73,0x2f,0xa6,0x80,0xb8,0x0b,0x3a,0xd7,0xf8,0x05,0xf0,0x06,0xc7,0xa5,0xce,0x6a,0x6a,0x62,0xae,0x06,0x93,0xa4,0x5f,0x0b,0x5d,0x4d,0xb8,0xa4,0xfa,0x2e,0xfc,0xb6,0x58,0x8c,0x2a,0x46,0xa4,0x55,0x1f +.byte 0x9b,0x9b,0x13,0xdd,0x17,0x2a,0x3d,0x04,0x51,0xb6,0xbe,0x9c,0xca,0xf3,0x23,0xb6,0x7b,0x7a,0x92,0xb7,0x2f,0xf9,0x69,0x9a,0xee,0xb3,0xa1,0x60,0x56,0xcf,0x9d,0xab,0xfe,0x86,0x7a,0x41,0x94,0x15,0xbe,0xa3,0xa5,0x85,0x09,0xfb,0x7b,0x89,0xbd,0xc3,0x09,0x10,0xa6,0xfc,0x41,0x8e,0x57,0x27,0xdc,0x58,0xf4,0x01,0x7c,0x31,0x5e,0xca +.byte 0xaf,0x31,0x2f,0x98,0x8b,0xbe,0x19,0x16,0xa1,0x81,0x7e,0xb3,0xa9,0xc5,0x15,0xd2,0xad,0x51,0xa1,0x73,0x56,0xd3,0x6a,0x15,0x35,0xe3,0xb1,0xdb,0x83,0x4c,0xe2,0x85,0x8c,0x03,0x12,0xc4,0x64,0x69,0xc0,0x23,0x16,0x7b,0x68,0x46,0x44,0x22,0x84,0xa6,0xb5,0xe4,0x90,0x91,0xc1,0xdd,0x25,0x7c,0x54,0x0e,0xce,0x5b,0x11,0xe4,0x50,0x1c +.byte 0x3c,0x0d,0xc7,0xc1,0x0c,0x10,0x2d,0x8b,0xb7,0xde,0xe2,0x4f,0x7e,0x22,0x53,0xfc,0x07,0x55,0x19,0x14,0x3b,0x33,0xf5,0xf3,0xd8,0x7b,0x5e,0x40,0xa2,0x81,0x6d,0x40,0x0d,0x20,0x36,0x4b,0xa1,0x34,0x34,0xac,0x43,0x59,0xb5,0xb1,0x90,0x8b,0x48,0xcf,0x15,0x57,0x17,0x0e,0xd0,0xbf,0x28,0xcd,0xa4,0x77,0x4d,0xae,0x09,0x4c,0x67,0x51 +.byte 0x18,0xaa,0xb4,0xc9,0x35,0x41,0x0b,0x34,0x4d,0xb3,0xef,0x3f,0x46,0x97,0x6e,0xae,0x75,0xd7,0x6a,0x2b,0x22,0x9c,0xef,0x8e,0xaf,0x72,0xb0,0x14,0x90,0xbd,0x11,0x90,0xde,0x9a,0x02,0x8c,0x20,0xf5,0xc7,0x33,0x4d,0x94,0x88,0x9a,0x6c,0x18,0xb4,0xc0,0xa9,0x94,0x07,0x9a,0x4b,0x10,0x8f,0xe8,0x25,0xcd,0x9b,0xf5,0xfa,0x91,0x8a,0xc0 +.byte 0x93,0x61,0x1c,0x00,0xd1,0x34,0x9a,0x29,0xa3,0x35,0x38,0xe4,0xa7,0x9f,0xb6,0x88,0x0f,0xad,0x88,0x96,0xa0,0x73,0xe7,0x10,0xea,0x36,0xe8,0x88,0x6c,0x7f,0x03,0xbc,0xfe,0xe0,0xb2,0x4b,0x24,0x98,0xf6,0x73,0x6f,0xab,0x00,0x1e,0x26,0x83,0x0d,0x86,0x5b,0xa6,0x51,0x8f,0x5f,0xa9,0x8f,0xf4,0xa0,0x51,0xff,0xe0,0x64,0x09,0x95,0xfb +.byte 0x56,0x53,0x18,0x61,0xea,0xc5,0x33,0xe8,0x6f,0x8a,0x07,0x97,0x1a,0x6c,0xb5,0xf8,0x73,0xae,0xe4,0x4e,0x6d,0xb2,0x83,0x20,0xfa,0xfd,0x79,0xa6,0x6c,0xaa,0x9b,0x7b,0x2c,0xfe,0x63,0x73,0xbc,0x87,0xd4,0x56,0xd1,0xb1,0xf1,0x0f,0x72,0x2c,0x2f,0xf0,0xf0,0x53,0xe2,0x6c,0x19,0x0d,0x9c,0xad,0xc8,0x0a,0x62,0x72,0xcb,0xc3,0x12,0x90 +.byte 0x4c,0x26,0xe3,0xa0,0x07,0x35,0xee,0xaf,0x81,0x35,0x07,0xa9,0x31,0xa0,0x59,0xc8,0x40,0xa5,0x45,0xb6,0x6d,0x3e,0xa2,0x5f,0x6a,0x79,0x74,0x65,0xa1,0xe3,0x1c,0xca,0xae,0xcc,0xa6,0xb6,0x0a,0x12,0x99,0x8e,0xc3,0xef,0x43,0xcf,0x42,0x92,0xa4,0x12,0xa3,0x8b,0x97,0x7d,0x6f,0xe0,0x35,0xed,0xac,0x69,0xae,0x8c,0xe1,0x32,0x11,0xa4 +.byte 0xe0,0x76,0x7f,0x75,0x92,0xda,0xfe,0x94,0x33,0xeb,0xe1,0xa4,0x3c,0x95,0x7c,0xc6,0xbc,0x3d,0xf2,0x39,0xa1,0x29,0x39,0x24,0x09,0xd4,0x52,0x68,0xfb,0x80,0xd0,0xd4,0x57,0xc6,0x4c,0xa5,0xa6,0x90,0xa6,0x61,0x15,0x2f,0xd3,0x35,0x36,0xf5,0x16,0xb3,0x65,0x0a,0xc4,0xcb,0x7f,0x73,0xe4,0xba,0x9a,0xd8,0x8b,0xc3,0x01,0xa0,0x08,0x57 +.byte 0x9e,0x26,0x54,0xbc,0x55,0xd1,0x5f,0xaa,0xb5,0x0d,0x42,0x75,0x04,0x76,0x8c,0xef,0xcf,0x64,0x3a,0x2e,0x4c,0x78,0xe5,0x37,0x8d,0x55,0xec,0xc1,0x7b,0xce,0x5f,0x5f,0x43,0x8b,0xdd,0x46,0x43,0xf5,0xa8,0x41,0xa6,0x82,0x1b,0x12,0xcb,0xcb,0x6d,0xa1,0x6c,0xb6,0x79,0x46,0x12,0x89,0x12,0x61,0xd6,0x4f,0xf9,0x43,0x2d,0x27,0xa9,0x61 +.byte 0x2e,0x2a,0x29,0x1b,0x6d,0xad,0x32,0x0b,0x6c,0x7c,0xf4,0xb8,0x98,0x91,0xbb,0x78,0xda,0x85,0xe8,0xfb,0x4e,0x11,0xc4,0x2a,0x07,0x54,0xa0,0x67,0x73,0x1b,0xa4,0x60,0x15,0x5c,0x83,0xbf,0x3f,0xd9,0x61,0x30,0x02,0xbb,0xa6,0x67,0xcd,0x0c,0xd1,0xb4,0x11,0x7e,0xca,0xf4,0x1e,0xed,0x83,0x34,0x66,0x54,0x23,0x39,0x36,0x8c,0xa0,0xc6 +.byte 0xef,0xad,0xa1,0x95,0x04,0x20,0x46,0x42,0xa8,0x99,0xd2,0x98,0xc6,0x0a,0x92,0x11,0xd1,0x84,0x4a,0xbf,0x25,0xe5,0xcf,0x78,0x98,0x81,0x80,0xaa,0x31,0x0a,0xa4,0xfb,0xef,0x35,0xfa,0xa4,0xac,0x5f,0x01,0x6b,0xb7,0x8e,0x86,0xc1,0x46,0x97,0x88,0xe2,0xaa,0x3b,0x1f,0xb5,0xf8,0xa9,0x90,0xf0,0x45,0x6d,0xdd,0xa3,0xdd,0xd8,0xef,0x36 +.byte 0x6f,0x87,0x55,0xf6,0x96,0xcd,0x88,0x43,0x03,0x97,0x82,0xea,0x5a,0x1c,0xa1,0x1a,0x7b,0x1b,0xa7,0xfc,0xaa,0x86,0xb4,0x71,0xde,0x0d,0x0a,0x52,0x98,0xd2,0x65,0x5d,0xa4,0xea,0x91,0xc9,0xe4,0x8b,0xd0,0xdb,0x85,0xe3,0x86,0x85,0x50,0xe1,0x41,0x1f,0x48,0x97,0x64,0xec,0x34,0xe4,0x54,0x42,0xf4,0x01,0xed,0x6f,0x4d,0xe3,0x1f,0x86 +.byte 0x14,0xbc,0x01,0x9c,0x7f,0x02,0x0c,0x65,0x94,0xd2,0x90,0x2c,0x1b,0xab,0x41,0x88,0xad,0x58,0xb5,0x71,0xd3,0xd6,0xe1,0x3f,0xf3,0x3c,0xb6,0xab,0x22,0x08,0x17,0xc7,0xf5,0x7e,0x34,0x56,0xae,0x1d,0x1e,0x7e,0xdb,0x24,0xe2,0xc2,0x38,0xf3,0x4d,0x46,0xe4,0x45,0xcb,0xb7,0x2f,0x0f,0x96,0x72,0x7e,0x31,0x89,0x17,0x9c,0xed,0x85,0xb9 +.byte 0xc8,0x8f,0x65,0x93,0xfb,0xb8,0x9e,0x41,0xa2,0xc1,0xcf,0xdb,0xe2,0x4c,0x26,0x4a,0xc7,0x2a,0x72,0xf6,0x28,0xbc,0x18,0x22,0xde,0xa1,0xfa,0x46,0xbe,0x95,0xc8,0xe2,0x19,0xbb,0x20,0x7b,0xd5,0xf8,0x34,0x15,0xaa,0xec,0xe2,0x9e,0xa9,0x3d,0xa1,0xd9,0xaa,0xc9,0x18,0x39,0x07,0x5c,0x81,0x61,0xe7,0x00,0xc5,0x57,0x3e,0xca,0x4d,0x89 +.byte 0x33,0x02,0xa6,0xc8,0x15,0xb7,0x24,0xdd,0x5c,0x55,0x56,0x11,0x5c,0x17,0x1b,0xda,0xc6,0xd5,0x46,0x6e,0x9f,0x70,0xe7,0x1e,0x41,0xee,0x91,0x1a,0xa0,0xad,0x35,0x64,0xdf,0x4a,0x18,0x03,0xa7,0xa8,0x88,0x8f,0x65,0xbc,0x76,0x34,0x08,0xab,0x50,0xc6,0xd3,0x08,0x7c,0xc1,0x4f,0x77,0xcd,0x1a,0xc6,0xed,0x35,0xea,0x4e,0x8a,0x6a,0x38 +.byte 0xa3,0xa3,0xd8,0xa9,0xa2,0x68,0xa7,0xd8,0xe0,0xc8,0x3f,0xfe,0xe7,0x73,0xc6,0x6b,0xd8,0x0c,0xd5,0x8f,0x81,0xe7,0x37,0x08,0x93,0x28,0x73,0xef,0xc4,0x91,0x52,0xa5,0x30,0xff,0x47,0x95,0x02,0x0d,0x8c,0xfd,0xc9,0x28,0x60,0xa9,0xad,0x30,0x00,0xcc,0x3a,0x00,0xbb,0x25,0xab,0xd0,0xf8,0x25,0x46,0x20,0xc0,0x67,0x9b,0xd6,0x10,0xa6 +.byte 0x84,0x6f,0x66,0x60,0x66,0x75,0xb6,0xfb,0x39,0x3a,0x9f,0x7d,0x32,0x7f,0x12,0x6f,0x8c,0xed,0x79,0x40,0x47,0xa3,0x27,0x17,0xa8,0xa4,0x02,0x93,0xb9,0x32,0x03,0x34,0x06,0x76,0x71,0x40,0x90,0x2b,0xe7,0xd0,0x3f,0x59,0xa7,0xfb,0x3a,0x7b,0xc8,0xa5,0x86,0x21,0x0d,0xf6,0xc6,0x49,0x07,0x56,0xe9,0xfc,0xac,0x61,0x30,0xa5,0x7e,0x90 +.byte 0x10,0xc8,0xdb,0x15,0x2b,0x75,0x27,0x77,0x51,0x42,0xcf,0x50,0xe8,0x6c,0x0b,0xb7,0x17,0x1a,0x89,0x7d,0xfe,0xd2,0x75,0xfa,0xb7,0xe5,0x68,0x10,0x1c,0x27,0x85,0x8b,0x52,0x7d,0x87,0x57,0x50,0x77,0x25,0x9d,0xcc,0x08,0x6a,0xad,0x63,0xf8,0x8e,0xe0,0x21,0x62,0x56,0x48,0x29,0xed,0x81,0x1d,0x6b,0x60,0x55,0x78,0x6a,0xce,0xd6,0x79 +.byte 0xe1,0x66,0x18,0x9f,0x71,0xf7,0x0c,0xec,0x35,0x53,0xef,0x39,0xfe,0x57,0x71,0xc0,0x49,0x4b,0x55,0xe8,0x3d,0x9b,0xe3,0x9a,0xbb,0xf8,0x61,0x31,0xa1,0x94,0x94,0x8a,0xb1,0xd2,0x0f,0x01,0xe0,0xd4,0x26,0xa0,0x59,0x70,0xd0,0x5e,0xb8,0x6f,0x63,0x7b,0x71,0x49,0xe1,0x98,0xfb,0xdb,0x22,0x26,0x18,0x16,0x31,0x08,0x90,0x32,0xd5,0x7a +.byte 0xc0,0xd8,0xeb,0xae,0x93,0x3d,0x46,0xeb,0x0e,0xdd,0x08,0xa2,0xde,0x4e,0xc1,0x88,0x26,0xc2,0xf8,0xc6,0x5e,0x8a,0x9b,0x0d,0x9f,0x2b,0xcf,0x4e,0x13,0x43,0x4a,0x65,0xf6,0x47,0x1a,0x0a,0xae,0xf9,0x9f,0x7c,0xc5,0x18,0x65,0x09,0xcb,0x85,0x7d,0x33,0x36,0x43,0x19,0x99,0x20,0xa2,0x64,0xb2,0xf5,0x20,0xd2,0x74,0xc6,0x2c,0x29,0x46 +.byte 0xde,0xa7,0x4a,0x7f,0x3b,0x05,0x3e,0x11,0xb6,0xc1,0x98,0xfb,0xf5,0x9d,0x93,0x95,0x76,0x11,0x80,0x41,0x44,0xd3,0x2f,0xf4,0xfd,0x92,0x1e,0xd7,0xa7,0x5f,0x02,0x4a,0xbc,0xb7,0x96,0x33,0xc0,0x0d,0x2d,0x97,0xb8,0xd4,0x67,0x7a,0x4c,0x74,0x93,0xa7,0x8d,0x68,0x78,0xed,0xc8,0xc9,0x02,0x6e,0xae,0x10,0x97,0x7c,0x56,0x11,0x2a,0x29 +.byte 0x87,0x5c,0x21,0xec,0x75,0x9c,0x17,0x17,0x8d,0x45,0x08,0x31,0x36,0x64,0xc0,0xf7,0x95,0xb6,0x72,0xcf,0xac,0xd8,0x52,0x02,0x6f,0x3b,0x14,0x34,0x30,0xcc,0x39,0x7c,0xe4,0x1f,0x38,0x23,0xcf,0x1f,0xb7,0x7e,0x92,0x66,0xf7,0xda,0x9f,0x27,0xbb,0x83,0x45,0x71,0x67,0x63,0x6c,0x85,0x64,0x34,0xa8,0x93,0x5a,0x13,0x0c,0xff,0x8b,0x3a +.byte 0x2a,0x10,0x1d,0xb6,0x43,0xef,0x57,0xf3,0xf0,0x29,0x2e,0x59,0x72,0x2e,0xc3,0xb6,0xd3,0xd0,0xdd,0x17,0x19,0x82,0x49,0x05,0xd4,0xfc,0xd6,0x2e,0x5d,0xd7,0x0c,0xb6,0x18,0xd5,0x08,0xbb,0xe5,0x3b,0x2e,0x85,0x62,0xc0,0x1e,0xa3,0xb8,0x92,0x21,0x06,0xfa,0xf1,0x2d,0xab,0x62,0x67,0x62,0xee,0x13,0x7f,0x07,0xb6,0x24,0x64,0x94,0x4f +.byte 0x69,0xb9,0x7a,0xdc,0x23,0x5e,0x19,0x96,0xc5,0x4d,0xcb,0xee,0x2d,0x4a,0x7d,0x1d,0xd2,0x72,0x18,0x8f,0x43,0x8f,0x76,0xbf,0x30,0xd8,0xf1,0xfe,0x9c,0xe7,0x63,0x38,0xff,0x1a,0x3f,0x40,0xbd,0x73,0x66,0xf7,0xa9,0xd9,0x17,0x4a,0x8a,0x79,0x04,0x0e,0x20,0xe1,0x39,0x49,0xd9,0x30,0x9c,0x52,0xf9,0x14,0x8f,0xdc,0x9d,0x52,0xd5,0x34 +.byte 0xaa,0x58,0xfe,0x5d,0x68,0xcb,0xab,0x3b,0x3c,0x9e,0x25,0xde,0x6d,0xdd,0x58,0x0d,0x1b,0x99,0xa9,0xcc,0x26,0x4e,0xc0,0x3c,0x8b,0x1e,0xaa,0x52,0x3d,0x4d,0xb8,0x27,0xc1,0xd1,0xa2,0xaa,0x78,0xb9,0xee,0x5f,0x26,0x46,0x5f,0x41,0x0d,0xe1,0x70,0x7d,0xcd,0x3f,0x4a,0xca,0xb2,0xca,0x2f,0x36,0x1f,0x68,0xe6,0x66,0x8a,0xf6,0xe3,0x94 +.byte 0xe5,0xab,0x90,0xeb,0x2f,0xe8,0xb2,0x6c,0xa9,0x69,0xd2,0xe0,0x5f,0x4a,0x65,0xa8,0x6b,0xc1,0xfb,0x03,0x51,0x17,0x3b,0xf8,0xe0,0x67,0xc3,0x5a,0xe8,0x18,0xdf,0xc1,0xf8,0x7f,0x44,0x68,0x4a,0x01,0xbe,0xf8,0xa5,0x7a,0xb9,0x3b,0x0f,0x05,0x8e,0x4b,0x28,0x14,0x61,0x2f,0x2e,0xc7,0xf2,0x96,0xc7,0x60,0x99,0xc4,0xbf,0xe8,0x37,0x98 +.byte 0x00,0x34,0xf7,0x5a,0xd7,0x6f,0x90,0xc4,0x19,0xb5,0x07,0xd1,0x76,0x6e,0x65,0xcc,0xf6,0x51,0x88,0x5c,0x81,0x91,0xa8,0x4d,0xb7,0x33,0x53,0xb6,0x93,0x42,0x52,0x82,0xfa,0x2b,0xca,0xa0,0xbd,0xf3,0x09,0x2b,0x0f,0x09,0x02,0xdd,0x29,0x5f,0xa6,0x49,0x7b,0x97,0xe8,0x96,0xbf,0x6f,0x76,0xb7,0xa2,0x76,0x58,0xda,0x1d,0xb2,0xdb,0x6d +.byte 0x9d,0x3b,0x32,0x6e,0x9c,0xea,0x45,0xfd,0x33,0xeb,0x41,0x91,0x91,0x52,0x2b,0x68,0xa3,0xf3,0xc6,0x92,0x43,0x13,0x49,0x8a,0x10,0xb1,0x2f,0x9a,0x0f,0xe1,0x94,0x21,0x18,0x76,0x87,0xaf,0x50,0xe4,0x71,0x5d,0x0a,0xba,0x75,0xaa,0x17,0xf5,0x37,0xf2,0x84,0x9b,0x29,0xdf,0x44,0x60,0xd0,0xac,0xcf,0x25,0x87,0x66,0x64,0x1f,0x0d,0xba +.byte 0xb3,0xdb,0x14,0xb6,0x1f,0x00,0x70,0x98,0x83,0x1d,0x9e,0xbd,0xf9,0x17,0xf4,0x57,0xae,0xa8,0xae,0x7b,0xa7,0xde,0x1f,0x31,0xc6,0x29,0xb2,0xf7,0xef,0x36,0x31,0xe7,0x50,0x33,0x69,0x4e,0x8c,0xb5,0xe4,0xdd,0x74,0x87,0xc8,0xf5,0x22,0x1b,0x4b,0xec,0xc4,0xe1,0x5a,0x7d,0x5a,0xe8,0xb9,0x2f,0xf4,0xd1,0x83,0xa2,0xb7,0x97,0xe0,0x1e +.byte 0xf7,0x3a,0x74,0xef,0x5f,0xb3,0x30,0xce,0xfa,0x23,0xd5,0x98,0x56,0x19,0x24,0xb5,0xc7,0x60,0x8b,0x03,0x8e,0xe7,0xdf,0x2c,0x36,0x4c,0x3b,0x3b,0x84,0x45,0x97,0x40,0x29,0x30,0x98,0xc3,0xc0,0xa2,0xf0,0xdf,0x69,0x47,0x95,0x26,0xdb,0x6c,0xcc,0xff,0x2d,0x32,0xaa,0xa7,0xb8,0x6b,0x24,0xec,0xff,0x94,0x4d,0x36,0xdd,0x7b,0x4d,0xc5 +.byte 0x8d,0xe2,0x3c,0x14,0x5a,0x37,0x75,0x1f,0xd6,0x98,0x7d,0xd3,0xdc,0xb0,0x24,0x69,0xe7,0x65,0x60,0x2a,0xe7,0x00,0x5b,0x68,0x99,0xa0,0x9e,0x10,0xf0,0x5c,0xa8,0x39,0x85,0x59,0xde,0xe4,0x46,0xf3,0xde,0xda,0xc0,0xb1,0xd2,0xf1,0xd2,0x05,0xd5,0xd4,0x2c,0x2e,0x7e,0x44,0x5c,0x52,0x80,0x85,0xbb,0x54,0x97,0xb6,0xad,0x6d,0x57,0x49 +.byte 0xed,0x67,0xaf,0x27,0xb4,0x5b,0xce,0x0f,0x3c,0x58,0xa2,0x24,0x22,0xa2,0xcb,0xfc,0x4e,0x8e,0xc2,0x3c,0x32,0xc6,0x07,0xc4,0xc6,0xc0,0x50,0xc3,0xe3,0x1b,0x96,0x76,0x62,0xf9,0xea,0x5e,0xdc,0xc5,0x96,0xe8,0xaa,0x20,0x26,0xac,0x44,0xfb,0xf2,0x16,0x72,0x72,0x4c,0x5c,0xee,0x51,0x07,0xb0,0x74,0xf6,0xde,0xd7,0x5d,0x73,0xf4,0xe9 +.byte 0x0d,0x29,0x06,0x5f,0xca,0xe2,0xbb,0xa4,0x3e,0xdc,0xf7,0x74,0x99,0x53,0x7a,0x52,0x60,0x46,0xaa,0xf0,0x34,0x97,0x0c,0x81,0x5b,0xd8,0x95,0x52,0x76,0x55,0xcb,0xc4,0x6d,0x50,0x26,0x3f,0x7e,0xc2,0x93,0x6e,0x14,0x0c,0xd7,0x49,0x5f,0x52,0x8f,0x34,0x49,0xb4,0xe7,0x12,0xfe,0xae,0xd1,0xfa,0xfc,0xc5,0x80,0x38,0x26,0x9c,0xf1,0x81 +.byte 0x01,0x58,0x15,0x99,0x29,0x8d,0x1b,0x2d,0x74,0xca,0xf1,0xf4,0xfa,0xcd,0xae,0xfa,0xa9,0x1d,0xbb,0xf1,0x55,0x2e,0x69,0x46,0x6e,0xe4,0x91,0xa3,0x48,0xb5,0xaa,0xb3,0x85,0xab,0x14,0xd2,0x84,0x8c,0xb1,0xb6,0x0c,0xa5,0x4a,0x90,0xed,0x6e,0xdf,0x1e,0x15,0x36,0x7b,0xa3,0x59,0xd6,0x8d,0x7d,0x7b,0x12,0x7c,0x9a,0x40,0x8a,0x28,0xde +.byte 0xb5,0xbc,0xc4,0x52,0x96,0xfb,0x62,0x1f,0xc9,0xe0,0xc9,0x1d,0xc7,0xc4,0xcb,0x8a,0x96,0x21,0x42,0x7c,0x0a,0xdd,0x42,0x74,0xcf,0xc4,0x57,0x8f,0x28,0x0a,0x7c,0x4f,0x49,0x5a,0xc6,0x21,0xb2,0xd4,0xd0,0x61,0xa5,0x35,0xbd,0x4a,0x0c,0x16,0x68,0x1f,0xe3,0xff,0x3f,0x72,0xf0,0x1d,0x50,0x26,0x48,0x91,0x27,0x1b,0x2b,0x0d,0x8b,0xf2 +.byte 0xa0,0xc0,0xa0,0x5d,0xdb,0xcf,0x71,0x41,0x83,0x00,0xb9,0x3c,0xe0,0x4a,0x96,0x43,0xf8,0x64,0x0f,0x42,0xc5,0x75,0xec,0x26,0x62,0x99,0x13,0xeb,0xf9,0xa6,0x86,0xe4,0xc9,0xaf,0x3c,0x2c,0xc9,0x4f,0x89,0xf4,0xc0,0x46,0x99,0xb8,0xd1,0x9e,0x7b,0xb7,0x41,0x0a,0x5f,0x40,0x98,0x65,0x29,0xdd,0x60,0x6b,0x27,0xbf,0x66,0x08,0x32,0xc2 +.byte 0xcf,0xea,0x91,0x44,0x45,0x49,0x1c,0xb4,0x16,0x7f,0x11,0x1a,0x8c,0xb4,0x59,0x54,0xc6,0xcf,0x40,0xd2,0xe9,0xc1,0x54,0x9c,0xe2,0x6e,0xd5,0xfe,0xfb,0x4a,0xa3,0x98,0x63,0xef,0x86,0xe0,0x63,0x30,0x32,0x5a,0xbd,0xd4,0x7c,0xe8,0xbe,0xf1,0xed,0xa2,0x19,0x98,0xc8,0x34,0x65,0x4c,0xef,0x1a,0xb3,0xbc,0x87,0xbe,0x6b,0x75,0x2c,0xe5 +.byte 0x54,0xcc,0xe5,0x69,0xb2,0xc8,0xdb,0x57,0xf8,0xa7,0x82,0x07,0xf7,0x20,0x95,0x7f,0x6d,0x7b,0x33,0x66,0x67,0xa1,0x38,0x0e,0x9c,0x3b,0x22,0xab,0xc1,0xd3,0xed,0x87,0x32,0xfb,0x4a,0x5d,0xad,0x3a,0xe1,0x90,0xa6,0xe3,0x4d,0x6b,0x00,0xe4,0x5c,0x66,0x59,0x90,0x63,0x24,0x5b,0xe1,0x3b,0x69,0xb6,0xc9,0x05,0x83,0x3a,0x7b,0xf4,0xa5 +.byte 0xc8,0x47,0xf9,0x8e,0xab,0x92,0xbd,0xd3,0x41,0xc7,0x61,0xf4,0xce,0x30,0xdb,0xae,0x27,0x69,0x0f,0xcc,0x69,0x50,0xe8,0x18,0xf2,0x39,0x04,0x5a,0x29,0x12,0x61,0x46,0x5c,0x1b,0x2e,0x15,0x9c,0xfa,0x73,0x50,0xe3,0x51,0xda,0x4d,0x88,0x25,0xb2,0xff,0x55,0x27,0xce,0x86,0xca,0xe6,0x2a,0xb8,0x0c,0xa7,0xd0,0x06,0xbf,0x70,0xb5,0x6b +.byte 0x80,0x44,0x65,0x5d,0x23,0xfa,0x0d,0x74,0x5c,0xfc,0xc7,0x86,0x5e,0x23,0x8a,0xf1,0xff,0x80,0xf0,0x19,0xaa,0x98,0xae,0x56,0xcf,0x12,0x74,0x6c,0x70,0xb2,0x39,0xbe,0x66,0x71,0xee,0xe3,0x43,0x3b,0xfa,0x79,0xa9,0x7e,0x69,0x6a,0x19,0x42,0xd5,0x0e,0x1e,0x92,0xfe,0x8a,0x0f,0xca,0x74,0xf2,0x68,0x71,0xf5,0xcb,0x05,0x94,0xc1,0x06 +.byte 0x1b,0xae,0x55,0xe9,0x16,0x03,0xa9,0x97,0xad,0x49,0xaf,0x88,0x8c,0x26,0x33,0x4d,0x46,0x75,0xb3,0x9c,0xee,0x70,0xe1,0x57,0x43,0xeb,0x59,0xff,0x77,0x89,0x8a,0x77,0x3f,0x7e,0xe6,0xbe,0xa2,0x05,0xb1,0xe3,0x41,0x5e,0xc7,0xd4,0x14,0xda,0xc0,0x84,0xd0,0x05,0x50,0xdd,0x62,0xdb,0x4c,0x3b,0x16,0xb0,0xe0,0xf5,0x2b,0xf1,0x83,0xea +.byte 0x7b,0x89,0xbb,0xde,0x57,0xdb,0xc0,0xb9,0x7d,0xdf,0x53,0x0f,0x6c,0xc5,0x5a,0x0b,0x36,0xeb,0xa3,0xc3,0xe6,0xc5,0x80,0x98,0xf3,0x87,0x29,0x97,0xc9,0x2e,0xd6,0x3b,0x43,0x2a,0x36,0x3b,0xba,0x43,0x85,0xf5,0x0d,0x18,0x2e,0x78,0x43,0xae,0xa4,0x24,0x6d,0xdc,0xab,0x05,0x94,0x09,0x94,0x27,0x17,0xef,0xbc,0x7e,0x52,0xa4,0x80,0xda +.byte 0x28,0xf5,0xc3,0x20,0x99,0xbb,0x5d,0xb6,0x7e,0x0e,0x59,0x3b,0x5e,0x1d,0x1b,0x4f,0xd1,0x91,0xe4,0xe4,0xc7,0x35,0xc7,0x2e,0xc1,0xba,0x60,0x05,0xa4,0xd5,0xca,0x5f,0x09,0xbf,0x79,0x06,0xcb,0xa7,0x32,0x7c,0xf4,0xdc,0xa8,0xb3,0x8b,0x26,0x59,0x6d,0xcb,0x74,0x37,0x56,0x51,0x96,0x0b,0x44,0xf1,0x95,0x16,0xe3,0x9b,0x9b,0x3b,0xb3 +.byte 0xea,0x6a,0x1b,0x76,0x99,0x69,0xd6,0x5b,0x10,0x5a,0x91,0x23,0xb5,0xc3,0xf9,0x6a,0xba,0xc4,0xe6,0x18,0x28,0x50,0x9d,0x09,0x14,0xbe,0xed,0x73,0xd2,0x51,0xff,0xf8,0x14,0x2b,0x8b,0xdd,0x2a,0x1a,0x8e,0x48,0xae,0xd8,0xdf,0xb9,0x5b,0xcb,0x8f,0xc2,0x8c,0xd6,0xb3,0xfb,0x40,0x2f,0xb0,0x6c,0x9a,0xea,0xd0,0x14,0x8c,0xc5,0xc7,0xc7 +.byte 0xf8,0xf5,0x4f,0xe2,0xd7,0x41,0xcd,0xb6,0x34,0x3e,0x81,0x19,0x09,0xa2,0x51,0xb4,0x60,0xfb,0xf2,0x6c,0xe6,0xae,0x68,0x47,0xb9,0x93,0x7b,0xc9,0xe7,0x00,0xc4,0xa7,0xf2,0xef,0x8b,0xd8,0xfc,0x9f,0xe5,0x6d,0x48,0xe2,0x6c,0x32,0x73,0x5c,0x30,0x7c,0x12,0x13,0xca,0xc3,0x31,0xc3,0xa2,0xb4,0xf7,0x23,0xc4,0xd0,0x47,0x39,0x93,0xc8 +.byte 0xa0,0x7b,0xb4,0x09,0x3f,0xe8,0x15,0x15,0x9c,0xa7,0xe6,0xa8,0xbe,0xba,0x60,0xf9,0x28,0x88,0x66,0x7b,0x62,0x32,0x17,0x18,0x68,0x87,0x53,0xf5,0xbc,0xf5,0x77,0x17,0xa1,0x3f,0x62,0xd1,0x10,0x0a,0x54,0x96,0x9c,0x31,0xc3,0xb7,0x1d,0xaf,0xc7,0xb3,0x27,0x9e,0x46,0xfe,0x7e,0x9b,0x88,0xf2,0x9e,0x6e,0x19,0x0f,0xb1,0x88,0xe4,0x08 +.byte 0x76,0x7c,0x77,0x46,0x09,0xa7,0x9e,0xf4,0xd9,0xbf,0x67,0xe8,0x9d,0x6a,0x75,0xa7,0xf5,0xee,0x29,0xba,0x84,0xa0,0x44,0x46,0x35,0x4c,0x22,0xef,0xb3,0xea,0xb0,0xf2,0xd6,0x78,0x20,0x97,0x28,0x5c,0x7e,0x90,0x06,0x80,0x19,0x63,0xa4,0x8a,0xef,0x0a,0xea,0x88,0xa9,0xa2,0xae,0x23,0x2e,0x40,0xce,0xc5,0xc2,0xbf,0xfe,0x5a,0x8f,0x14 +.byte 0xb8,0x66,0x1a,0x2d,0xdb,0x43,0x39,0xbd,0xe7,0x7b,0xbc,0x41,0x58,0x74,0x56,0xd1,0xe7,0xd0,0xba,0x24,0xd2,0x41,0xbf,0xd0,0x4e,0x97,0x38,0x8f,0x6b,0x6f,0xe2,0x7d,0x6d,0x32,0x94,0x43,0xa7,0x66,0xf7,0x90,0x21,0xe0,0xdd,0x19,0x48,0x72,0xc1,0xa5,0xbc,0x9c,0xe2,0xdd,0x2c,0x6e,0x50,0x45,0x2c,0xa0,0x95,0xcb,0x1d,0x2c,0x1d,0xa6 +.byte 0xbe,0x9c,0xd4,0x6c,0x07,0x2e,0x5e,0xc8,0xc1,0x05,0x61,0x7d,0x44,0x28,0xe6,0xad,0xf0,0x9d,0x2d,0x3d,0xce,0x90,0x7d,0x79,0x2e,0xf3,0x08,0xbe,0x7a,0xa9,0x58,0x04,0xa7,0x39,0x05,0xdd,0xb4,0x87,0x6c,0x7b,0xd5,0xb3,0x2d,0x6b,0x43,0xf4,0x37,0xd9,0x6f,0x5c,0xa2,0x23,0x92,0x53,0xb9,0xd7,0x1b,0x2d,0x5d,0xcd,0x6d,0x3f,0xef,0xc8 +.byte 0x66,0x91,0x10,0x1b,0xc5,0x24,0x50,0x87,0x70,0x93,0x03,0x3f,0x7b,0x40,0xc8,0x0c,0x9b,0xec,0x3d,0x82,0x27,0x96,0x2a,0xbe,0xca,0xaf,0x1b,0xbf,0xef,0x14,0x0c,0xdc,0xa6,0xc7,0x48,0x18,0xce,0x8e,0x43,0x58,0x97,0xb3,0x5e,0xd6,0xc9,0x70,0x65,0xd0,0x0e,0x17,0xac,0xa0,0x6b,0xc9,0x55,0x30,0x12,0x7c,0xbe,0xe5,0x46,0xfc,0xd8,0x3f +.byte 0x0e,0xd7,0x96,0x16,0x32,0x8e,0xb7,0x2d,0x07,0xd1,0x26,0x98,0x70,0x4c,0xb1,0x6f,0x92,0x32,0x75,0x4f,0x57,0x6b,0x78,0xe0,0xc5,0x9b,0xf0,0x08,0x59,0x0b,0xfa,0x2d,0x79,0xbe,0xde,0x44,0x3d,0x65,0x77,0x27,0x3b,0xd9,0xea,0x55,0x79,0x22,0xe8,0xf7,0x62,0xb1,0xe3,0x32,0x4e,0x03,0x17,0x65,0xd3,0x5d,0xee,0xa0,0x9b,0xc2,0xbd,0x9f +.byte 0xcd,0xdc,0xde,0xd7,0x6c,0x95,0x7a,0xf1,0x09,0x4c,0x14,0xb9,0x37,0x1d,0xd0,0xdd,0x4b,0x2e,0x93,0x0b,0xfa,0x08,0x40,0x01,0x36,0xdf,0x89,0x46,0xa6,0xbb,0x19,0xd9,0x4f,0xf9,0xe1,0x7b,0x03,0xc9,0xef,0x01,0x25,0xe9,0x6d,0x95,0x84,0x7f,0xf8,0x8e,0x02,0xfd,0x6f,0x30,0xed,0x1b,0x98,0xd0,0xb3,0xdd,0x92,0x65,0x46,0x49,0x61,0xde +.byte 0x76,0xf5,0x4b,0x29,0x03,0x6f,0x79,0xee,0xbe,0x7a,0x07,0x6e,0xa8,0x29,0xb8,0x03,0xb4,0x6c,0x50,0x1f,0x4a,0xa2,0xaf,0xbd,0xde,0x18,0x72,0x90,0xa2,0x12,0xa9,0x59,0x7b,0xf6,0x96,0x2d,0xda,0x3d,0x90,0xba,0x7c,0x79,0x3e,0x6e,0xef,0x94,0x37,0xe2,0xef,0x6b,0x2a,0x74,0x6b,0x52,0xa0,0xc2,0x1e,0xa1,0x24,0x59,0x84,0xeb,0xdc,0xd0 +.byte 0x34,0x60,0xa8,0x81,0xaf,0xdd,0x57,0xc2,0xa6,0x02,0x7f,0xcf,0x9e,0x64,0x28,0x18,0x7c,0x95,0x98,0x90,0x7a,0x76,0x3f,0x78,0x16,0x2c,0xe0,0xa7,0xdf,0x0d,0x4d,0x5e,0xcc,0x0d,0x73,0x12,0x26,0xd7,0xe9,0x32,0x3e,0xa1,0xa9,0xde,0x29,0xb2,0x3b,0x6f,0x3b,0x6e,0x12,0x0c,0x10,0x34,0x86,0xf2,0xa0,0xd4,0x9c,0xf6,0x14,0x5a,0x41,0x06 +.byte 0x31,0xb1,0xe4,0x31,0x52,0xf4,0xcb,0xe3,0x39,0xcd,0x0b,0xc2,0xca,0x90,0xba,0xb3,0x21,0xbf,0x94,0x13,0x75,0x3b,0x0e,0x0a,0xc0,0x05,0x35,0xe6,0x28,0x74,0x63,0xc5,0x34,0x44,0xd8,0x9a,0x0e,0xec,0xb3,0x1b,0x30,0x58,0xfc,0xa0,0xc4,0xd1,0x26,0x50,0x6b,0x22,0x88,0xfc,0xad,0xa9,0xb4,0x3e,0x36,0xb6,0xb1,0x6d,0x62,0x7e,0x60,0x8f +.byte 0xf5,0x17,0x65,0x1c,0xf6,0x51,0x4d,0x89,0x4a,0x7e,0x5d,0x23,0x3b,0x83,0x1f,0xa6,0xc8,0xd2,0x1a,0x90,0xd3,0x53,0xfc,0x48,0x64,0x94,0x6e,0x1c,0x72,0xef,0x5d,0xd4,0x23,0xa2,0x3a,0x93,0xe4,0x29,0x33,0x8a,0xbd,0xe5,0x17,0xc2,0xe9,0x18,0x6a,0x81,0x1e,0x5b,0x03,0x41,0x45,0x35,0x14,0xe7,0xc8,0x45,0x5c,0x37,0x69,0x77,0x62,0xf8 +.byte 0xd7,0xec,0x9d,0x62,0x2e,0xfa,0x43,0x3a,0xdc,0x8b,0x86,0x86,0x1b,0x31,0x71,0x0e,0x92,0x59,0xf7,0xef,0x96,0xfd,0x04,0x1e,0x1d,0x74,0x7d,0x08,0x06,0x21,0x54,0x39,0xd3,0x9f,0x30,0xa1,0x19,0x7f,0xc8,0x19,0x16,0xd1,0x21,0x2a,0xf3,0x21,0xce,0x19,0x1a,0xde,0x70,0x1b,0x87,0x05,0x9e,0xe8,0xf3,0xfd,0x1d,0xaa,0x61,0x6c,0xfb,0xdf +.byte 0x50,0x9a,0xa0,0x32,0x4e,0xe4,0x68,0xda,0x0e,0x2f,0x2a,0x70,0xe1,0x51,0x66,0xb4,0x2d,0x5b,0xb6,0x32,0x3f,0xcb,0xc0,0xaf,0x01,0x03,0xcd,0xd6,0xb8,0x4e,0x3d,0x24,0x17,0xe2,0x30,0x3b,0xa4,0x08,0x0e,0x6a,0xcf,0xbe,0xc2,0x5c,0x79,0x5d,0x25,0xe2,0xae,0xa7,0x7f,0x42,0xff,0xa9,0xa5,0x05,0xbf,0xf4,0x92,0x30,0xaa,0x1d,0x96,0x7a +.byte 0x49,0xbc,0x1c,0xaa,0x5c,0x8d,0xe8,0xf3,0xd3,0x1a,0x67,0x7f,0x47,0x09,0x90,0x35,0x82,0x4e,0xcc,0x2e,0x50,0xfe,0x2c,0xb9,0x29,0x39,0xff,0x49,0x8f,0x7e,0x89,0x8d,0x4a,0x15,0xd1,0xd6,0x83,0xdb,0x25,0xac,0xc1,0x81,0x23,0x70,0x3f,0xb9,0xce,0x7f,0x03,0x46,0xa8,0x39,0xab,0xff,0x71,0xc9,0x7b,0x3c,0xb3,0x5e,0x9f,0xfe,0x8a,0x0a +.byte 0x39,0xad,0x6a,0xc1,0x8e,0x5a,0xa8,0x71,0xb7,0x01,0x25,0x28,0x15,0xd9,0x0a,0xae,0xc1,0xf9,0x23,0x1c,0xc1,0xe8,0x86,0x1d,0xb8,0x71,0x6e,0xa2,0xa4,0x67,0x22,0x4d,0x0e,0xd2,0xaa,0x70,0x26,0x23,0xfc,0x15,0xed,0x67,0x11,0x87,0x69,0x6f,0xc6,0x4c,0xe1,0x4b,0x04,0x86,0xe9,0x56,0x40,0xea,0x07,0xb1,0x6f,0xe9,0x8f,0xdd,0x2f,0xce +.byte 0x8d,0xca,0x0a,0x58,0x01,0x44,0x2c,0x74,0xd0,0x14,0x07,0x9a,0xb7,0x5a,0xc1,0xea,0xa9,0xdd,0xa4,0x94,0x84,0xc2,0x11,0xa5,0xe2,0x00,0xd8,0xfc,0x77,0xb9,0x5e,0xe6,0x72,0xef,0xc5,0x38,0xe0,0x90,0x11,0x16,0xfd,0xa7,0x77,0xbd,0x4c,0x1d,0xeb,0x32,0x54,0xdb,0x2a,0x43,0xa1,0x87,0xbb,0x2e,0x79,0x22,0x4d,0xb3,0xdf,0x1a,0xee,0x75 +.byte 0xb0,0xdd,0xf2,0x09,0x05,0xf4,0x6a,0x3c,0x86,0xc6,0xe7,0x60,0x2a,0xee,0xb6,0x55,0xae,0xdc,0xce,0xf8,0xe4,0xd7,0xdf,0x72,0x42,0x91,0x6d,0xc4,0xd8,0x60,0xf1,0xe8,0x06,0x71,0x38,0xa3,0x03,0x3e,0x1b,0x14,0x47,0x74,0x93,0xb5,0x61,0x28,0xde,0x23,0x8f,0xbe,0x88,0x5e,0xdf,0x87,0x47,0xd4,0x5f,0x91,0x40,0xeb,0x02,0xda,0x27,0x3b +.byte 0x65,0x9f,0xd8,0xf1,0x78,0x7f,0xba,0x9b,0x35,0xb3,0x10,0xaf,0x7f,0x51,0x37,0xa5,0x63,0x64,0x1f,0xf1,0xc3,0x1b,0x9e,0xe4,0xdd,0x93,0x8c,0x3a,0x98,0x20,0x9a,0x75,0x22,0x7b,0x48,0x0a,0x9d,0x55,0xed,0x07,0x1a,0x79,0x3b,0x98,0xe3,0x16,0x9b,0x16,0x2c,0xb2,0x03,0xc1,0xf5,0x6c,0xac,0x00,0x6a,0xb6,0xc1,0xc2,0x49,0x4d,0x9d,0xf5 +.byte 0x0e,0x7b,0x60,0x09,0xcc,0xa7,0x35,0xbb,0x70,0x34,0x18,0x49,0x2c,0xf1,0x41,0x4f,0xce,0x68,0x03,0x60,0x14,0xa7,0x2e,0x59,0x0f,0xa2,0xc4,0x2f,0x33,0xf0,0xb6,0xa4,0x31,0x75,0xdc,0xb4,0x88,0xe4,0xe3,0x0e,0x4b,0x3f,0x58,0xd0,0xa4,0xea,0x9a,0xef,0x47,0xb7,0xf7,0x20,0x71,0x52,0xd3,0x8a,0x1c,0xd9,0x2d,0x88,0x05,0x03,0x8a,0x1c +.byte 0x3d,0x69,0xf0,0x39,0xf0,0x25,0xad,0x95,0xd4,0x47,0x3c,0xbb,0xfa,0x48,0xd7,0x8e,0xf5,0xdc,0x33,0x43,0x0a,0xbb,0xf0,0xd3,0xb1,0xc3,0x94,0x81,0xcd,0x22,0x79,0xdc,0xd0,0x92,0x8b,0xd3,0xc3,0xac,0x73,0x72,0x83,0xaa,0xa2,0x52,0x13,0x27,0x0e,0xc5,0x8c,0xa5,0x69,0x21,0x6e,0x9c,0x9d,0x9b,0xeb,0x7a,0x19,0xfe,0xb6,0xdb,0x4e,0xc1 +.byte 0xa6,0xec,0x42,0xb0,0x86,0x69,0x60,0xde,0x36,0x11,0x6a,0x86,0xd7,0xbf,0x15,0x48,0xa2,0x73,0x8f,0x68,0xde,0xd6,0xb2,0x6d,0xe0,0xc5,0x1f,0x1f,0xd5,0xc5,0xef,0xce,0xa1,0x90,0x5c,0xe6,0x6c,0x15,0x73,0xa7,0xcc,0x2d,0xe8,0xcf,0x4c,0xc8,0x17,0x3c,0xfa,0x5e,0xdb,0x4f,0x54,0xf3,0xa3,0xff,0x50,0x3e,0x42,0x60,0x0d,0xf3,0xf7,0xbb +.byte 0xc6,0xf5,0xe7,0x63,0x50,0x49,0xc1,0x94,0x60,0x68,0xbd,0x62,0xc0,0x81,0x80,0x16,0xfd,0x65,0xfb,0x2e,0x23,0x67,0xb3,0xb6,0xf8,0x95,0xfa,0x00,0x3f,0x1d,0x10,0x16,0xd5,0xd9,0x66,0xf8,0x25,0xb4,0xce,0xf2,0x2e,0x4f,0xa2,0x21,0x14,0xbd,0x2c,0x63,0xec,0x44,0x57,0x07,0x87,0x3c,0x2f,0x22,0xcf,0x48,0xd3,0x20,0x51,0xfc,0x5d,0xd5 +.byte 0x9f,0x67,0x9c,0xaf,0xe3,0x89,0x36,0xc5,0xfa,0x7c,0xca,0x07,0xdc,0x56,0x2a,0x4e,0xa5,0x76,0xe6,0x09,0x99,0xfb,0xb7,0xba,0xaa,0x0b,0x9c,0xe2,0x0f,0x73,0xab,0x9b,0xbe,0x6f,0x50,0xe3,0xf7,0x28,0x32,0xf2,0xab,0x86,0xa3,0x89,0x3a,0xea,0xd7,0x52,0x52,0x6e,0xed,0x1b,0x94,0xf0,0x59,0x9d,0xbb,0x7a,0x88,0x6f,0xbf,0xaf,0x6a,0x87 +.byte 0x47,0x34,0x7f,0xf4,0x8b,0x0d,0x33,0x12,0x2b,0x67,0x6b,0xc9,0x1d,0x18,0x23,0x2e,0x54,0xee,0x07,0x28,0xbd,0x9d,0xa1,0xaf,0x85,0x7a,0x0f,0xe5,0x5d,0xf7,0x8b,0xca,0xd9,0x3d,0x8f,0x4f,0xcc,0xce,0xc3,0x6e,0x3a,0x40,0x08,0xd2,0x14,0xf0,0x28,0x9b,0xc0,0x4a,0x7a,0x3c,0xc2,0xed,0xe0,0x20,0x04,0xf5,0xf9,0xee,0xb8,0x35,0x94,0xbc +.byte 0x53,0x46,0xf2,0x1a,0xab,0xe9,0xde,0xd8,0x27,0x67,0x0d,0x63,0x2a,0x7b,0x3a,0x38,0x91,0xbc,0x48,0x2c,0x38,0x09,0xa0,0xe3,0x66,0xe3,0xeb,0xb9,0x02,0x2d,0x80,0x87,0x81,0x4f,0x5c,0x1c,0xfd,0x2b,0x0f,0x99,0x37,0x3a,0xfa,0x0f,0x8e,0x8c,0x87,0x76,0x72,0xd3,0xcf,0xc8,0x1e,0x8a,0x3b,0x97,0xa0,0xe6,0x32,0x66,0x3c,0x55,0x2c,0xfb +.byte 0xa9,0x41,0xfd,0xf9,0xd4,0x50,0xe0,0x5b,0x03,0xb7,0x1e,0x49,0xfa,0x59,0xeb,0x55,0xb1,0x21,0xd0,0x52,0xeb,0xe6,0x0f,0x21,0x81,0x4f,0x82,0x9a,0x8f,0x67,0x3d,0x0d,0x1d,0x11,0x1f,0x70,0x59,0x09,0x87,0x99,0xe5,0xf2,0x89,0xa6,0x56,0x8d,0x52,0x55,0xa8,0x91,0x5d,0x51,0x48,0xec,0x66,0x05,0xd6,0x18,0xd1,0x61,0x02,0x5a,0x80,0xcc +.byte 0xee,0xf3,0x3b,0x8e,0x73,0x2a,0xb1,0x22,0xda,0x1d,0xca,0xb2,0xd6,0x7f,0xd7,0x7d,0xaf,0x23,0x8d,0xff,0x24,0x8e,0x5e,0x38,0x29,0x23,0x1f,0xbc,0xfd,0xe4,0x3d,0xcd,0x66,0xe3,0xe1,0x0f,0x85,0xe3,0xda,0x34,0xc6,0xba,0x60,0x5f,0xaf,0x32,0x79,0x34,0xc0,0x01,0x93,0xae,0x1e,0x72,0x7f,0xd2,0x32,0xa1,0xdc,0x0b,0xca,0xee,0x5a,0x7a +.byte 0x09,0x98,0x2a,0x46,0x0a,0xe7,0xfd,0x0f,0x76,0xa0,0x3b,0x2b,0x3d,0xe5,0xcd,0x04,0xa2,0x5e,0x9b,0xba,0x4a,0xd5,0x0a,0xce,0x94,0x77,0xbb,0x24,0xa4,0x12,0xbc,0x24,0xb6,0x60,0x40,0x62,0xd2,0x70,0x0e,0x3f,0x62,0x72,0x2f,0xa1,0xc9,0x12,0x03,0x0f,0x39,0x57,0x77,0x7c,0x5c,0x31,0x13,0xcb,0x8c,0x2c,0x84,0xfd,0x7b,0x6f,0x60,0xbb +.byte 0x1a,0x0b,0x65,0x8c,0xc1,0xe6,0x4b,0x60,0x8c,0xe7,0x3e,0x94,0x2a,0xcc,0x70,0x9f,0xd0,0xfd,0x00,0x0e,0x36,0xb2,0xf1,0x62,0x78,0x6a,0xc8,0x9b,0xbe,0x8b,0x54,0xa7,0xad,0xee,0x3e,0x8e,0x1c,0x23,0xbe,0xa2,0x73,0x43,0xbe,0x15,0x32,0x84,0xdd,0x22,0x75,0xd5,0x9a,0xfb,0x93,0x38,0x55,0x2f,0xa4,0x34,0x4c,0x33,0xc3,0xd7,0x7c,0x9f +.byte 0x42,0x2f,0x9f,0xf6,0x27,0x90,0x15,0x6b,0x14,0x4f,0xbc,0x4b,0x07,0x42,0x24,0x98,0xa6,0xc4,0x4c,0x2f,0x22,0xd9,0x80,0x99,0x97,0x6b,0x7d,0xe8,0x2b,0x31,0x37,0xfe,0xd1,0x8b,0xbd,0xbf,0x08,0x4a,0x56,0x3d,0xff,0xb5,0x12,0x6d,0xc4,0xcf,0xbc,0x75,0xe9,0xe6,0x6f,0x1a,0x30,0x34,0x5b,0x2c,0x1d,0x8f,0x85,0xa0,0xe8,0xfd,0xfd,0xe2 +.byte 0xe7,0x13,0x73,0xcd,0x63,0x63,0x90,0xa5,0xa4,0x3f,0x91,0x65,0x77,0xd4,0xed,0x0c,0x1d,0x06,0x95,0x93,0x74,0x85,0xec,0x31,0xde,0xc9,0xb9,0x2e,0x7c,0x6d,0x2c,0x0d,0x15,0xb7,0x6b,0x0c,0xd2,0xe8,0xa8,0xcb,0x90,0x5c,0x11,0x53,0xc5,0x9d,0x54,0xf4,0x90,0xf7,0xc8,0x17,0x65,0xc0,0x3f,0xea,0xf6,0x28,0x8e,0xf0,0x1c,0x51,0xcc,0xfd +.byte 0x99,0x67,0x3d,0xa5,0x82,0x1f,0xb3,0x75,0x08,0x27,0x85,0xa9,0x7b,0x54,0x91,0x6e,0x80,0x9a,0xdb,0x6c,0x17,0x4a,0x36,0x73,0x0e,0x61,0x2e,0x01,0xae,0x32,0xf8,0x54,0xdb,0xcf,0x24,0xa5,0x13,0xb1,0x7e,0x0b,0xf5,0xe7,0x0e,0x27,0x9a,0xef,0x01,0x0b,0x34,0x4f,0x91,0xc2,0x93,0xe0,0xe6,0x14,0x64,0xf8,0x7b,0x41,0x37,0x22,0x39,0xad +.byte 0xf4,0xa9,0x3b,0xfb,0x7e,0x2b,0xd8,0x2b,0x0f,0x7e,0x40,0x55,0x5a,0x48,0x61,0x2f,0x95,0x5e,0x5c,0x25,0xe5,0x06,0x89,0x17,0x23,0xb6,0x1b,0x38,0x2e,0x7b,0x45,0xa5,0x11,0x0a,0x8d,0xd3,0x8d,0xb6,0x8d,0x47,0xc5,0x4f,0x8f,0x8b,0xe2,0x03,0x85,0xa1,0x5a,0xa2,0x8d,0xca,0x4d,0xef,0xc9,0xde,0x7d,0x06,0xa1,0x3f,0x21,0xb9,0x38,0x7b +.byte 0x91,0xf7,0x5c,0x9f,0x97,0xe3,0xeb,0x5d,0xea,0x5e,0xc1,0xa5,0x30,0xb0,0x7f,0xe0,0x4c,0xef,0xe5,0xe3,0xa0,0x2d,0x23,0xb6,0x08,0x21,0xe6,0x67,0x35,0x82,0x07,0x59,0x02,0xd4,0x68,0xa5,0xf1,0x42,0x70,0xb4,0x5e,0x54,0xed,0x1e,0x99,0xb2,0x55,0xf1,0x69,0x2e,0x7c,0xaa,0x6c,0x5e,0xd4,0xfa,0x16,0xa7,0x1f,0xdb,0x46,0x70,0x65,0x26 +.byte 0x98,0xf1,0xb6,0x42,0xb3,0x48,0x99,0x7c,0x07,0xbe,0x2b,0xee,0xb4,0xc1,0xf0,0xb7,0x47,0xf8,0xcf,0xe4,0x8d,0x34,0xa6,0xe5,0x17,0x9a,0xb7,0x2c,0x2e,0x03,0x30,0xfd,0xfb,0x42,0xe7,0xa1,0xe0,0x34,0x49,0x64,0xd8,0x0c,0xd5,0xb8,0x77,0x9f,0x0e,0xe2,0x73,0x0d,0x20,0x0c,0x21,0x07,0xaf,0x0f,0x93,0x94,0xd6,0xdc,0xe3,0xac,0x8d,0x8e +.byte 0xae,0x87,0xbd,0x2c,0x19,0x66,0xef,0x90,0x4a,0xd9,0xb0,0xf6,0xac,0x3a,0xe2,0xb5,0x2e,0xb4,0x63,0x91,0xf1,0x8b,0xac,0xce,0x51,0xc2,0xe0,0x02,0x7d,0xf8,0xab,0xe4,0xd6,0x85,0xd6,0xbb,0xd7,0x72,0xd0,0x5f,0x4e,0x90,0x09,0xcc,0x51,0xee,0x5b,0xad,0xb2,0xf6,0x16,0x37,0x09,0xa8,0xfc,0x74,0xa5,0x2e,0x26,0x27,0xff,0x53,0xd4,0x45 +.byte 0x82,0xb1,0xb6,0x16,0x65,0xc6,0xbb,0x54,0x0b,0x89,0xa1,0x0e,0x09,0x7c,0xc9,0xc9,0x48,0xa7,0x51,0x78,0x1d,0x3a,0x30,0xc5,0xe7,0x02,0x9e,0x91,0xd6,0x39,0xc8,0x35,0xf0,0x33,0xab,0xf6,0x0f,0xf9,0xce,0xef,0x26,0x46,0x48,0x56,0xbc,0x45,0x44,0xe2,0xd7,0xfc,0xdf,0xb2,0x95,0x20,0x07,0xeb,0x47,0x1c,0xde,0x88,0x5e,0x08,0xee,0xa1 +.byte 0x56,0x9a,0x5d,0x8f,0x35,0xc5,0xb3,0xd3,0x7d,0xe3,0x25,0x82,0xcc,0xcb,0xad,0xd8,0xef,0x83,0x76,0x08,0x55,0x9e,0xf4,0x00,0x1f,0x92,0x24,0x0e,0xf6,0x96,0x98,0x34,0x10,0x10,0x93,0x27,0x3b,0x96,0xbd,0x75,0x45,0x9d,0xad,0xc1,0x79,0xa7,0x09,0x68,0x0a,0xbc,0x14,0xe9,0x62,0xf6,0x5e,0x4e,0x6d,0xfb,0xf2,0x25,0x20,0x8b,0x53,0xa6 +.byte 0xc2,0x31,0x71,0xaa,0xfa,0xa2,0x1c,0xa1,0xb3,0xa2,0xd7,0x22,0x5a,0x72,0x61,0x5c,0x30,0x75,0xcc,0x82,0xb0,0xd0,0x07,0x8c,0x95,0x11,0x57,0xa4,0xe2,0x42,0xf3,0x3d,0x87,0x56,0x45,0x38,0xd6,0x1b,0x2b,0x26,0x11,0x99,0xce,0xcc,0x2e,0x96,0x1b,0xa1,0x06,0xa1,0xa9,0x65,0xe1,0x1f,0x53,0xb6,0x1e,0x5c,0x44,0x40,0xa2,0xf2,0x03,0xe7 +.byte 0x39,0x24,0x59,0x5f,0xdd,0x30,0xf0,0x78,0x9f,0x34,0xf1,0xd3,0x5d,0x9a,0xdd,0xf9,0x02,0x16,0x4b,0xfa,0x8d,0xab,0x2f,0x96,0xdb,0x67,0xf6,0x1e,0x7a,0xf8,0xd8,0xe6,0x71,0xdc,0x1a,0xbf,0x44,0xd2,0xbd,0xb3,0x6d,0x47,0x69,0xe0,0x14,0xef,0xe5,0x5e,0x0a,0xe9,0x1a,0x8b,0x3f,0x67,0x1e,0x1c,0x37,0x86,0x25,0x02,0x52,0x3f,0xf5,0xde +.byte 0xe0,0xbe,0x1d,0x61,0x44,0x3d,0xd2,0xe9,0x26,0x3d,0x4b,0xa4,0xb1,0xb9,0x62,0xc5,0x70,0xfb,0x1d,0xaf,0xe6,0x19,0x97,0x0f,0x6e,0x6d,0x4e,0xdf,0x5f,0xc9,0xb2,0xb0,0xb9,0x4b,0x72,0xc7,0x60,0x5d,0xf8,0x7d,0x3b,0xd8,0x74,0x29,0xf2,0x56,0x25,0xd9,0xd9,0x12,0x3a,0x50,0x01,0x54,0xd3,0x0e,0x4c,0xbd,0xc9,0xf5,0x66,0xc4,0x4b,0xa2 +.byte 0x68,0x31,0xb1,0x9d,0x47,0xd8,0x28,0xce,0x6b,0xe4,0x5f,0x78,0x75,0x22,0x7d,0x44,0x08,0x71,0xfb,0xd8,0xa0,0x6e,0xd1,0xbd,0x64,0x4e,0x00,0x99,0xf7,0x85,0xad,0x31,0xde,0x5c,0x4c,0x7c,0xc3,0x89,0x49,0x9f,0xea,0x22,0x86,0xa0,0x48,0x48,0xcf,0x47,0xfb,0x68,0x04,0x4c,0x05,0x62,0x57,0x60,0x9b,0xa0,0x37,0x41,0x77,0xe4,0x7d,0x3e +.byte 0x36,0xda,0xd5,0xfd,0x68,0x47,0x8c,0x68,0x61,0x4c,0xea,0x38,0x20,0xa5,0xe4,0x12,0x6e,0xd5,0x14,0x37,0x01,0xcf,0xbd,0xdd,0x55,0x97,0xb4,0x30,0xf0,0x65,0x15,0xee,0x1f,0xc8,0x5b,0x07,0x82,0xae,0x43,0xad,0x11,0xda,0x0e,0x61,0x23,0x0a,0x5f,0x52,0xf9,0x9d,0xc5,0x98,0x4e,0xaf,0x77,0x21,0xc8,0x9f,0x6d,0x25,0x94,0x4f,0x91,0x1a +.byte 0xb4,0x2d,0xe3,0x15,0xe5,0xe6,0x25,0xb8,0x8e,0xd8,0x33,0xe3,0x05,0x01,0x7b,0x6b,0xa8,0x39,0x44,0x4b,0x58,0x3c,0x17,0x53,0x17,0x5c,0xbc,0xd5,0xcd,0xd4,0x29,0xe7,0x17,0x7a,0x69,0xa6,0x75,0x8e,0x0a,0x00,0x41,0xbe,0xb4,0x8d,0x79,0x1d,0xac,0x2a,0x0f,0x9b,0x7b,0x5a,0xe8,0x17,0xe2,0xb3,0x1d,0x03,0xde,0x5a,0x7c,0x31,0x18,0x8c +.byte 0x1c,0xf9,0x19,0x7b,0x37,0x1f,0x53,0x77,0xce,0x1f,0xad,0xb6,0x0d,0x21,0xe1,0xb0,0xf9,0x42,0x52,0x99,0x02,0xa8,0x58,0xab,0x94,0xf8,0x9f,0x99,0x2d,0x1e,0x68,0x4f,0x5a,0x91,0x2b,0xdf,0xe8,0xe6,0x34,0xb6,0x80,0x9b,0xb1,0x0e,0x87,0xec,0x29,0x17,0x4d,0x98,0x2d,0x40,0xd0,0xf7,0xca,0x55,0x9d,0x56,0x19,0xd5,0x7c,0x4e,0x2e,0x75 +.byte 0x5d,0xe7,0x3e,0xed,0x47,0xdc,0xb1,0x04,0xe5,0x61,0x0f,0xe7,0xc4,0x16,0x71,0xf4,0xf8,0x8a,0xf1,0xfc,0xd5,0xdb,0xeb,0x0b,0x82,0x0f,0xfe,0x64,0xa2,0xb0,0x53,0xab,0xf5,0x01,0xc2,0x8f,0xa0,0x4d,0x5d,0x1b,0x54,0x32,0x48,0xca,0x8a,0x42,0x59,0x4a,0x85,0x68,0x75,0xd1,0x1b,0x03,0x11,0xfe,0x28,0xd7,0xd5,0x37,0x81,0x7a,0xfb,0x84 +.byte 0xfd,0xa8,0x98,0x54,0xf7,0x81,0xb0,0x2d,0x2d,0x5d,0x95,0x0a,0x5b,0x80,0x13,0x95,0xad,0x8f,0x88,0xaa,0x38,0x7e,0xbc,0x88,0xc2,0xf6,0xa6,0x1e,0x6d,0x78,0xc9,0x4f,0xa9,0xb3,0xaa,0x23,0x0c,0x62,0x19,0x6f,0x26,0x5d,0xca,0x36,0x23,0xf8,0xd1,0x76,0x80,0x32,0x59,0xa0,0x47,0x86,0xee,0xc9,0x0f,0x1d,0x37,0xd9,0xc9,0x4e,0x65,0x22 +.byte 0x17,0x95,0x88,0x85,0xb3,0x8a,0x5d,0xb9,0xe6,0x3b,0x6c,0x02,0x81,0x61,0xe0,0xab,0x19,0x6c,0x9a,0x29,0x33,0xf1,0x7b,0x0c,0x22,0x16,0x0c,0xd6,0xfa,0xc2,0x84,0xe5,0x74,0x9e,0x8e,0xf8,0xdb,0x44,0x68,0xa0,0x58,0x52,0x9f,0xad,0xe6,0x2b,0x23,0x70,0xf3,0x6e,0xdc,0xf1,0x2d,0xa5,0xc2,0x7f,0xef,0x5f,0x58,0xc2,0x96,0x66,0x67,0x4b +.byte 0x7c,0xe0,0xd7,0x96,0xda,0xf7,0xd7,0x7a,0x7d,0xb4,0x4f,0x48,0xbd,0x87,0x6b,0xf4,0xbd,0xd1,0x45,0xdc,0xba,0x4f,0xd2,0x00,0x7f,0xde,0x3c,0x57,0xd7,0x3b,0x5b,0xa9,0xf3,0x17,0x76,0x47,0x0c,0xcf,0x48,0x07,0xa8,0xc3,0x30,0x60,0xc6,0x98,0x20,0x29,0xba,0x5f,0x76,0x6d,0x63,0x5f,0x87,0x7e,0x36,0xbc,0xa3,0xe4,0xd6,0x6a,0x55,0x73 +.byte 0x8b,0x8b,0x62,0x40,0xc5,0x7e,0xa3,0x33,0x04,0xce,0xe2,0x9d,0x9f,0x67,0x1c,0xf0,0xa1,0x78,0xd2,0x0b,0x58,0xc1,0x2e,0xec,0x78,0x0a,0xc9,0x0b,0x1d,0xfb,0xcc,0x72,0xd8,0xe4,0x15,0xcb,0x09,0x8b,0xd9,0x33,0xa9,0xb6,0x24,0x7e,0x59,0x48,0xbf,0xda,0xdb,0x5c,0x99,0xd1,0x92,0x1b,0xb6,0xf6,0x75,0x78,0x53,0x69,0x89,0x27,0x6b,0x3c +.byte 0xfb,0xd2,0xa7,0xeb,0xc5,0xf7,0xea,0x8b,0x38,0x59,0x8e,0x02,0xc7,0x6e,0x96,0x8a,0x85,0x1c,0x91,0x1b,0x97,0x97,0x9e,0xa7,0x9d,0x10,0xa4,0x4a,0x6e,0xa8,0x51,0x05,0xbe,0x5f,0x9a,0x5b,0x94,0xf2,0x2c,0xa1,0x1e,0x33,0xc5,0xe8,0x92,0xb8,0xd2,0xfa,0x27,0x07,0x12,0xa1,0xdc,0x24,0x43,0x28,0x06,0xe5,0x43,0x57,0x8f,0x66,0x72,0x2f +.byte 0x26,0xf7,0xea,0xa1,0xcf,0x57,0xd6,0xa6,0xf7,0x37,0x1d,0x6e,0xd9,0xde,0x1a,0x8c,0xf5,0x01,0x76,0xc3,0x56,0x40,0x57,0x3d,0x4a,0x14,0x04,0xf2,0xfc,0xba,0x3b,0x60,0xf1,0x88,0x1e,0x16,0x08,0x99,0x90,0xfe,0x27,0xaa,0x04,0x53,0xd8,0x7e,0x0c,0x58,0x6a,0xd9,0x5a,0xe4,0x11,0xd4,0xcc,0x48,0xbe,0x03,0x08,0xbc,0x61,0x47,0xdd,0xde +.byte 0x5f,0x03,0xc7,0x8f,0x9c,0x08,0x93,0xe3,0xaa,0xee,0x9c,0xe3,0xc6,0x06,0x78,0xda,0x0a,0xdd,0xb0,0xc3,0xf3,0x0b,0xe5,0xa0,0x5f,0x1e,0x3e,0xb3,0x15,0x7f,0xf1,0xf4,0x38,0xb2,0xed,0xf2,0xa6,0x8b,0x1d,0x78,0xb6,0x03,0x19,0xcd,0x17,0xb4,0x18,0x17,0x49,0x61,0x17,0xbd,0xbe,0x4b,0x04,0x00,0xce,0x4b,0xcc,0x47,0x61,0x76,0x85,0xdc +.byte 0x2b,0x85,0x48,0x82,0xf4,0x9b,0xb4,0x62,0x53,0xc7,0x06,0x50,0xf2,0x3e,0xba,0x6d,0xf2,0x19,0x0f,0x7f,0x84,0xce,0xa6,0x4d,0x96,0x97,0x94,0x12,0xb6,0xd0,0xd6,0xa4,0xc1,0xcc,0x14,0x54,0xf6,0x7a,0xf1,0x94,0x62,0xa1,0xc7,0x22,0x9b,0x0d,0x0e,0x69,0xcf,0x38,0x5c,0xda,0x9f,0xc0,0xfa,0x93,0x81,0x24,0xce,0x9f,0xf3,0xc2,0x66,0xad +.byte 0x06,0x21,0xf2,0x48,0x6c,0x4a,0x0d,0xb8,0x41,0x86,0xaf,0xb7,0x6c,0x65,0xcb,0x83,0xd8,0x75,0x11,0x60,0xfa,0x06,0xe5,0xd2,0x11,0x87,0x29,0xb8,0x41,0xcb,0x17,0xb5,0xbd,0xbd,0xf9,0xd5,0xbc,0x89,0xb6,0x60,0x65,0x59,0xbb,0x38,0x9d,0x70,0xf9,0x81,0x6b,0xe6,0x12,0x80,0x08,0x73,0x9f,0xfb,0x2f,0x72,0x4e,0x18,0xff,0x65,0xab,0xa6 +.byte 0xaa,0x78,0xf1,0xa4,0xe9,0x1a,0x7d,0xa5,0xdd,0x91,0x77,0xa9,0xa3,0xf3,0xe3,0xe5,0x5a,0xa2,0x0d,0x3a,0x2a,0x4a,0x11,0x9a,0x8d,0xc3,0x00,0x6e,0xd4,0x4f,0xb9,0xe7,0x39,0x78,0x89,0x64,0xb2,0xc8,0xfd,0x1f,0xe6,0xa9,0x54,0x17,0x83,0x3f,0xeb,0x97,0x77,0xac,0xc8,0xba,0x0e,0x77,0x02,0xb0,0x29,0xbe,0x51,0x62,0xef,0xa5,0xd5,0xab +.byte 0x79,0x98,0xab,0x7a,0x1e,0x13,0xe8,0x87,0x4f,0x61,0xa3,0x37,0xdf,0xe6,0xda,0xb9,0xf5,0x69,0xf7,0x7a,0xee,0xd6,0x5f,0x6a,0xb3,0x95,0x55,0x59,0xd1,0x6c,0x5b,0xd5,0xba,0x8b,0x74,0x85,0xbf,0x1e,0xe5,0xb3,0x24,0x28,0x4b,0xc8,0x4a,0xec,0xa1,0x1d,0xda,0x99,0x3f,0xdf,0xfc,0xe6,0x2e,0x1b,0xa4,0xba,0x1a,0x03,0x89,0xb7,0x93,0x4e +.byte 0xaf,0x40,0xb0,0x7e,0x3f,0x34,0x0d,0x94,0x75,0x8c,0x8a,0xfb,0x88,0xcd,0xd3,0xc2,0x61,0x95,0x63,0x51,0xaa,0x78,0x1f,0x24,0x95,0x5a,0xb5,0x98,0x9a,0xd4,0xb8,0x34,0xe1,0x47,0x1c,0x68,0x0f,0x08,0xf1,0x69,0xe6,0xd4,0xaf,0x23,0xf6,0x32,0x71,0x51,0x01,0xa9,0xf2,0xa1,0x45,0x0b,0x75,0x82,0x09,0xe4,0x9c,0x2a,0x1d,0x0b,0xd6,0xd2 +.byte 0x26,0xe8,0x30,0x44,0xdf,0xa3,0x2b,0x97,0x11,0xc7,0xe7,0x47,0xfd,0xc7,0xbf,0x59,0xf3,0x28,0x32,0x46,0xc0,0xc4,0x7a,0x96,0x08,0x0d,0x2c,0xa1,0x82,0x6c,0x0a,0x33,0x82,0x55,0xd7,0xcf,0x3e,0x08,0xbb,0x22,0x15,0x96,0x12,0x66,0xd2,0xae,0x21,0x3a,0x54,0x6a,0xe0,0x33,0x0c,0xa4,0x96,0x4b,0x5d,0xf2,0x86,0xb9,0x70,0xe4,0x65,0x45 +.byte 0xe4,0x2f,0xa7,0xb4,0xc1,0xd5,0x9a,0x02,0xa1,0x5b,0x4e,0x58,0xca,0xf8,0x63,0xae,0x45,0x1c,0xf4,0xa7,0xc8,0xa5,0x84,0x23,0x87,0xcb,0x3e,0x88,0xca,0xe9,0xa9,0x49,0xc5,0xc6,0x63,0x37,0x99,0xe0,0x27,0x03,0x96,0x7b,0x73,0x8c,0x36,0xde,0x89,0x80,0x30,0x2c,0x00,0x94,0x0b,0xfb,0x1f,0x39,0xe0,0xed,0xb6,0x31,0x21,0x90,0xfe,0xa4 +.byte 0xee,0xa5,0xe5,0x7b,0x9a,0x11,0x41,0x51,0xab,0x89,0x54,0xe0,0x8d,0x5f,0x10,0x1b,0x76,0x27,0x77,0x3d,0xb0,0x58,0x86,0x7b,0xb7,0x45,0xfb,0xd0,0x81,0xa8,0xcd,0xc0,0xc8,0x5f,0xfb,0xfe,0x8c,0x0a,0x3d,0x5d,0x61,0x4b,0x9b,0x32,0x75,0x66,0xa9,0xac,0x32,0x35,0xe9,0x1a,0xdf,0x06,0x8d,0x13,0x5d,0x40,0xcb,0x7d,0x50,0x3e,0x54,0xab +.byte 0x04,0xbc,0x83,0x32,0x8f,0xf5,0x93,0x1d,0x9b,0x5a,0xe1,0x19,0x70,0x4a,0xba,0xfc,0x4c,0x6a,0xf3,0xd6,0xd1,0xfd,0x48,0xd0,0x7c,0xa4,0xab,0x0b,0xb6,0x5f,0xe1,0x31,0xce,0x99,0x10,0x98,0xfc,0x6e,0x1c,0xaa,0x9c,0x34,0xa2,0x55,0xdc,0xe0,0x81,0x1b,0x9e,0xff,0x75,0x2e,0x25,0xe9,0x2c,0x20,0x83,0xf6,0x66,0xf9,0x63,0x31,0xfe,0xa7 +.byte 0xbf,0x4d,0xfd,0xff,0x0b,0x93,0x84,0xd4,0xb4,0x72,0x13,0x38,0x90,0x75,0xc9,0xff,0x61,0x4b,0xf9,0x55,0x62,0x58,0xf0,0x60,0xce,0x2d,0xec,0x94,0x06,0x0a,0xde,0x48,0xc0,0x46,0x89,0xfb,0x5c,0xf7,0x9f,0x37,0xad,0xd2,0xff,0xbe,0xfb,0x81,0x21,0xe0,0x20,0x43,0x88,0xad,0x40,0x47,0x7a,0xa9,0x30,0x88,0x10,0x16,0x41,0xf8,0x25,0xe0 +.byte 0x8f,0xc2,0xe3,0x9f,0x48,0xd3,0xfe,0x61,0x70,0xb9,0xa1,0x9e,0xaa,0xa6,0x73,0xcf,0xc3,0xd6,0xab,0x69,0x65,0x4a,0x3c,0xec,0x28,0x02,0x63,0x62,0xa1,0xb6,0xa3,0xd5,0x8c,0x9e,0x11,0x81,0x98,0x12,0x4f,0xec,0xb6,0xe5,0x3a,0x96,0xa1,0x11,0x13,0x77,0x5f,0x0f,0x19,0x40,0x14,0x28,0xcc,0xf1,0x3e,0x19,0x1d,0x78,0x31,0xac,0x5c,0xce +.byte 0xd7,0x29,0xfa,0x02,0x3b,0x29,0xd8,0x3a,0x37,0xcb,0x94,0xb2,0x38,0xc7,0x7f,0x3a,0x46,0xd2,0xb7,0xfe,0xfb,0x54,0x7c,0x01,0xa2,0x9b,0x53,0x57,0x04,0x73,0x4e,0x06,0x90,0xe5,0x78,0x0a,0x45,0x67,0x12,0x83,0xd7,0x31,0x59,0xa4,0x76,0xaa,0x7c,0xde,0x72,0x92,0x11,0x94,0x4c,0x6a,0xe4,0x35,0x35,0x3a,0x2e,0xef,0x7c,0xc1,0x91,0x76 +.byte 0xd0,0xfe,0x84,0xd1,0xa1,0xf9,0x03,0xc3,0xba,0x09,0xbb,0x2c,0xe2,0xb5,0x06,0x7e,0x23,0xb7,0xe0,0xc1,0xd3,0xfd,0x55,0x01,0xf3,0xba,0xc5,0x1b,0xf8,0x02,0x60,0x92,0x0a,0x93,0x1c,0xc4,0x19,0x03,0x88,0xf5,0x45,0xe5,0x8f,0x7d,0xce,0x2c,0x87,0x2e,0xf6,0x55,0x8c,0xf9,0xb0,0xd2,0x72,0x2d,0x93,0x6d,0x28,0x6e,0x8e,0x3a,0xed,0x68 +.byte 0x02,0xda,0x80,0xd0,0x71,0x4a,0x8f,0x06,0x59,0x38,0x89,0x81,0xcb,0x1a,0x74,0x1e,0x62,0xa3,0xa5,0xb8,0x85,0xc3,0xd2,0x04,0x3d,0x3b,0x93,0x36,0x0c,0x12,0x55,0xfb,0x7b,0xc8,0xa3,0x25,0xa7,0x93,0xb0,0x3e,0x49,0x86,0xbf,0x76,0x8f,0xc4,0x4c,0xfe,0xce,0x4a,0xf6,0x2f,0x15,0x33,0x06,0x3a,0x35,0x49,0xe7,0x08,0xff,0x99,0xac,0xf6 +.byte 0x20,0x6d,0xab,0xb2,0x05,0xa9,0xe4,0x06,0x57,0x9c,0xf4,0x76,0x8c,0x82,0x64,0xd5,0x67,0xe0,0xad,0xe1,0x69,0xdc,0x9e,0x2c,0x59,0x92,0x3a,0xc8,0xc1,0x0a,0x61,0x89,0x45,0x9f,0x8b,0xf8,0x64,0x0a,0x5a,0x75,0x55,0x37,0x24,0xe1,0x42,0x43,0x7c,0x9c,0xcd,0x4e,0x9e,0x19,0xfb,0xd9,0x15,0x29,0x30,0x52,0x33,0xf3,0xc8,0x88,0xdb,0xaa +.byte 0x07,0x27,0xfb,0x2b,0x0c,0xc0,0xa1,0x5f,0x51,0xf1,0x54,0xf8,0x90,0x0a,0x35,0x07,0x6e,0x9c,0x64,0xd8,0x4f,0x2d,0xb3,0x61,0xbc,0x18,0x1f,0x22,0x84,0x94,0x4b,0x85,0xfc,0x4a,0xf9,0xe5,0xfc,0xdd,0x7a,0x07,0xa2,0xbb,0xbe,0x7e,0x1f,0x4e,0xf9,0x29,0xb8,0xde,0x56,0xe9,0x04,0xc1,0xc2,0xb6,0xa8,0xc7,0xb6,0x83,0xf2,0x85,0x3d,0x35 +.byte 0xe3,0xeb,0x2f,0x2f,0x3c,0x1a,0x3a,0xf1,0x61,0x1f,0xe8,0xf0,0xce,0xa2,0x29,0xda,0x3f,0x38,0xf5,0x82,0x7a,0xb8,0x55,0xf1,0x1a,0x6e,0x5b,0x5c,0xd0,0xc8,0xc8,0x3a,0xe2,0xaf,0xb4,0x6f,0xba,0xe4,0x03,0x78,0x5f,0x47,0x4b,0xaf,0xfe,0x2a,0x7e,0x27,0xba,0x17,0xb4,0x92,0x27,0x70,0x13,0xd9,0xbb,0x6b,0x1c,0x9a,0x3e,0x29,0x85,0x9a +.byte 0xb7,0x64,0x5b,0x6d,0x7b,0xec,0xb2,0x26,0x3a,0x4b,0xb7,0x17,0xaf,0xb5,0xa1,0xbc,0x4d,0x67,0x4c,0x86,0xd1,0x53,0x2e,0x5d,0x64,0xe8,0x55,0xd9,0xbb,0xae,0xc1,0x55,0x41,0x99,0x8e,0x4d,0xed,0x3d,0x9e,0xea,0xe3,0xf2,0x76,0x45,0x6d,0xaa,0xbb,0x89,0x0b,0xc0,0x13,0xfe,0x99,0x2c,0xb0,0xd2,0xa9,0xeb,0x58,0x57,0x4d,0x88,0x2e,0x04 +.byte 0x4f,0x7a,0x76,0xaa,0x3a,0xa6,0x08,0x93,0x42,0x74,0x2f,0x3a,0x35,0xb0,0x36,0xcc,0x77,0xec,0x54,0x41,0x2e,0x81,0xf6,0x9f,0xf3,0xe7,0x23,0xc0,0x3f,0xa4,0x52,0x83,0x38,0xe2,0x12,0xed,0xdb,0x23,0xa0,0x0b,0xbf,0x61,0x98,0x89,0xb0,0xa4,0x3d,0xa9,0x6a,0x73,0xa1,0x99,0xc9,0x9e,0x68,0x45,0x37,0x4b,0x6c,0x87,0xfb,0x93,0xf2,0xaa +.byte 0xe8,0x1d,0x53,0x6c,0x4b,0xda,0xc5,0x6f,0xaa,0xde,0x99,0xd2,0xba,0x7c,0x27,0xc2,0x4e,0xd5,0x5b,0xc8,0x13,0x9e,0xa2,0x10,0x6a,0xbb,0x39,0xf9,0xa7,0x55,0x0a,0x65,0x88,0x3c,0x9b,0xff,0x83,0x4e,0xf7,0x9c,0x99,0x69,0xbd,0x64,0x0d,0xd1,0xc0,0xb0,0x43,0xd6,0x63,0x50,0x13,0x68,0x8d,0xd1,0x7e,0x56,0x93,0xb5,0x8e,0x8f,0x12,0xe5 +.byte 0x37,0x96,0x21,0x64,0xd5,0x0b,0xf6,0x27,0xf8,0xaa,0x34,0x8e,0xc4,0x2b,0x7b,0x6a,0x7c,0x89,0x4e,0x15,0x15,0x3d,0x17,0x93,0xd4,0x99,0xfe,0x97,0x95,0x20,0x85,0xcc,0xd4,0xcd,0x73,0x67,0x80,0x22,0x06,0xed,0x5e,0xce,0x90,0x59,0x01,0x31,0x24,0x17,0x37,0x4a,0x63,0x96,0xc2,0xf3,0xe0,0x21,0x0a,0x3b,0x9f,0x94,0xad,0xd6,0xa4,0xa9 +.byte 0xa2,0x54,0x0d,0x2a,0xb3,0x5c,0xfa,0xbe,0xeb,0x21,0xd6,0x13,0x22,0xa5,0x95,0x5e,0x25,0x72,0xf9,0x18,0x1f,0x50,0x64,0x04,0x5b,0xe8,0x0e,0x1f,0x6c,0xe1,0x4e,0xf5,0x7f,0xf0,0x13,0x4f,0xda,0x75,0xab,0x5a,0x98,0xd3,0x07,0x32,0x96,0x2a,0xc7,0x1e,0x0f,0x14,0xdb,0x96,0x5f,0xac,0xc1,0xef,0x5b,0x2d,0xd6,0x6d,0x13,0x01,0xd9,0x04 +.byte 0x9c,0xcd,0xe5,0x5e,0xbe,0x3a,0x47,0x14,0x09,0xbe,0x11,0xad,0x87,0x3f,0x0e,0xe1,0xcb,0x97,0xd0,0x6e,0x1f,0x49,0x07,0xd1,0x8c,0x2b,0xe0,0xf0,0xb2,0xaa,0x8b,0x70,0x18,0x7f,0x29,0xcc,0xc4,0x23,0x66,0x48,0xc4,0xb5,0x5e,0xf1,0x10,0xd7,0x1d,0x2a,0xba,0xe4,0x12,0x64,0x1d,0xf5,0x03,0x35,0x71,0x57,0x5d,0xf4,0xa4,0xb5,0x99,0x0b +.byte 0x4c,0x80,0x65,0x07,0x2f,0xbc,0xf7,0x28,0x8b,0xc0,0x8f,0x84,0x63,0x7e,0xf5,0x01,0x23,0x8c,0xaf,0x71,0x35,0xd4,0xe1,0x70,0xc7,0xef,0x1f,0x66,0xa9,0x34,0x57,0xaa,0x9a,0xbb,0x80,0x43,0x15,0x96,0xc4,0x03,0xd9,0xae,0xbe,0x89,0x1c,0xa1,0x9f,0x65,0x61,0xe5,0x90,0x9f,0xa6,0xf4,0x3b,0xde,0xa1,0xd1,0xf1,0xf9,0x2d,0xd7,0xa7,0x7e +.byte 0x3d,0x42,0x3d,0x1b,0x99,0xed,0x49,0x2e,0x92,0x6b,0x47,0x0e,0x0b,0x90,0x56,0xe0,0x1b,0x6b,0xfe,0x97,0xfe,0x9b,0xa2,0x50,0xcc,0xbf,0xea,0xae,0xe8,0xf0,0xc4,0xe5,0x81,0x20,0x4a,0xb0,0xf7,0xa5,0x23,0x24,0xf6,0x3f,0x9e,0x9c,0xcc,0xce,0xe4,0x95,0x49,0xea,0x66,0x4a,0x35,0x31,0xf3,0x03,0xc3,0x08,0xf9,0x5f,0x95,0x4c,0xbc,0x84 +.byte 0x13,0xbe,0x7f,0x35,0xbb,0xd7,0x35,0x3c,0xfb,0x05,0x43,0x95,0xbf,0x87,0xf2,0xc3,0x2d,0xef,0x13,0x1d,0x65,0x17,0x82,0x75,0x3d,0x67,0x51,0xcd,0x6e,0x42,0x5f,0x49,0x53,0x8b,0xaf,0x34,0x7d,0xa8,0xc1,0x45,0xcd,0x3d,0x29,0x00,0xa3,0xf3,0xbb,0x44,0x00,0x05,0x57,0xa5,0xeb,0xfd,0x98,0xa6,0xae,0xc6,0xc4,0x6c,0x6d,0x7d,0xf6,0x3e +.byte 0x82,0x1d,0x12,0xe7,0xcd,0xd2,0xd5,0xfe,0x41,0xf8,0xa4,0xb3,0x6a,0x04,0x13,0x28,0x10,0x40,0x27,0xc9,0x43,0x74,0xcf,0xaf,0x9b,0x60,0x17,0x43,0x8f,0xd7,0xb7,0x56,0x72,0xf3,0x48,0x0a,0xe6,0x36,0xf2,0x3f,0x51,0xf9,0x6e,0xc8,0xa3,0x04,0x8c,0x01,0x86,0x6e,0x83,0x27,0xe2,0xba,0xf2,0x8f,0x8f,0xa1,0x39,0xe7,0x17,0xdd,0x06,0x10 +.byte 0x0c,0x7f,0xfa,0x22,0x5d,0x88,0x35,0xc6,0xcd,0x60,0xa2,0xf0,0xfd,0xc9,0xed,0x85,0xac,0x88,0xfd,0x7d,0xc0,0x77,0x1b,0x80,0x3d,0x21,0x1e,0x8e,0x4d,0xdb,0x20,0xe2,0x38,0xad,0xd4,0xb5,0x2b,0x2b,0x31,0xbc,0x7b,0x02,0xa2,0x25,0x50,0xc0,0x01,0x20,0x76,0x6f,0x98,0x0b,0x3d,0x46,0xed,0xbb,0x2b,0x39,0x74,0x30,0xce,0x3e,0x6d,0x91 +.byte 0xa1,0x89,0x83,0xde,0x69,0x93,0x1a,0x14,0xa1,0xb0,0xaa,0x80,0xb0,0x1c,0x02,0x3f,0x13,0x9a,0x15,0x7f,0xb4,0x02,0x8f,0x30,0x0b,0xee,0xd9,0x72,0xcb,0x74,0x95,0x4a,0x39,0xb3,0x4e,0x78,0x12,0xb1,0x77,0x89,0xc0,0xaf,0x17,0xfd,0xc1,0x68,0x65,0xd1,0x08,0xae,0x56,0x5c,0xe0,0xe7,0x6f,0xb3,0x1e,0x10,0xce,0xd8,0xdf,0xee,0x67,0xad +.byte 0xd8,0x08,0xe0,0x79,0x36,0xe4,0x57,0x1c,0x45,0x22,0xa7,0x44,0xa8,0x12,0x37,0x92,0x85,0x9f,0x3a,0x48,0xd0,0xfd,0xb3,0x40,0x20,0x10,0xed,0x11,0xe0,0x9a,0xa6,0x09,0x5b,0xe9,0x21,0x95,0xe1,0x45,0x19,0x39,0xcc,0x85,0x5f,0xa5,0x6b,0x46,0x37,0xe1,0xa1,0x17,0x3f,0xb6,0xe9,0xb0,0x81,0x25,0xf6,0xd1,0xb8,0x22,0x5a,0x27,0x48,0x83 +.byte 0x01,0x36,0xd4,0xb8,0xc0,0x9f,0x37,0x52,0x22,0xd2,0x69,0x7b,0x3d,0xfb,0x31,0xc1,0xa3,0xb4,0xa1,0x1d,0x0e,0x24,0x9a,0xda,0x02,0x15,0x4b,0x46,0x24,0x0e,0xb1,0x79,0xc2,0x5b,0x01,0x60,0x4a,0x24,0x8a,0xbb,0x70,0xaa,0xf4,0x45,0xc1,0x0d,0x04,0x26,0x3f,0x74,0xbd,0xdd,0x33,0xaa,0xd6,0x62,0x56,0xb1,0xe7,0x2d,0x7b,0x66,0xa2,0x40 +.byte 0xb4,0xe4,0xbd,0x8e,0x35,0xba,0xf1,0x2f,0x59,0xa7,0x01,0x6d,0x5a,0xa7,0xa6,0x3b,0x82,0xa3,0xb4,0x54,0x51,0x33,0x6b,0xfb,0x78,0x4a,0x74,0x88,0x7f,0x55,0xea,0x08,0x8e,0x19,0x78,0xbc,0x80,0x19,0x2f,0x41,0x97,0x20,0xa0,0x9e,0xbf,0x44,0xae,0x2e,0x26,0x66,0xe3,0x25,0xa0,0x92,0xa9,0xbe,0x8c,0x0d,0x96,0xec,0x93,0x99,0xe2,0xe7 +.byte 0x81,0xd5,0x10,0x62,0x3a,0x97,0x38,0x51,0x36,0x11,0x00,0xe0,0xc1,0x3a,0xc5,0xd4,0xa5,0x19,0xf4,0x82,0x66,0x0c,0xf9,0xb3,0x04,0x3e,0x57,0xc3,0x43,0xab,0xc6,0x52,0x95,0x8f,0xd3,0xf1,0xde,0xd9,0x57,0x6d,0x32,0x4f,0xc7,0x8c,0x1b,0x7a,0x53,0x6a,0xcf,0x56,0xea,0x61,0xb4,0xe5,0x64,0x2d,0x02,0x26,0x5b,0xcf,0x1c,0xc7,0x37,0xc3 +.byte 0x41,0xd2,0x1b,0x6c,0x5b,0x47,0xb8,0x73,0x89,0xfe,0x0e,0x7a,0x35,0x05,0xfc,0xea,0x6a,0x34,0x74,0x69,0xf0,0x12,0x29,0xa9,0x33,0xce,0x93,0x15,0xa0,0x68,0xb3,0x46,0x43,0xdb,0x8d,0xfa,0xef,0x93,0x66,0x72,0x18,0xae,0xe4,0xab,0xf4,0x8a,0xd1,0xb5,0x42,0xbd,0x2d,0xda,0xcb,0xf6,0x44,0x25,0xb1,0x01,0x8a,0xff,0xd5,0x34,0x16,0xec +.byte 0x7e,0x38,0x7b,0x50,0x41,0x61,0xf9,0xdf,0x4c,0x3e,0x02,0xd6,0xc3,0xce,0x19,0x9f,0x12,0x45,0x0c,0x99,0xb1,0xd9,0xeb,0xb9,0xe3,0xd5,0xb6,0x2b,0x25,0x8c,0x0b,0x04,0xf8,0x8d,0x41,0x41,0x3d,0x39,0x1b,0x7f,0x88,0xa7,0x8f,0x61,0x30,0xfe,0x67,0x75,0x35,0xd1,0x41,0x90,0xda,0x73,0x80,0xcf,0xc9,0xf6,0x44,0x00,0x67,0xcd,0xca,0xaf +.byte 0x6d,0x84,0x39,0x9a,0xb2,0xbb,0xfc,0xac,0x9b,0xb2,0x95,0x2f,0xc9,0x06,0x3a,0xa4,0x7b,0x9a,0x25,0xc6,0xe5,0xdb,0x7a,0xc6,0x8b,0x84,0x6a,0xb7,0x1e,0x22,0xaa,0x10,0x96,0xd3,0x55,0x50,0xa2,0x02,0x04,0x69,0x92,0xd7,0x6b,0x1f,0x9b,0x45,0x07,0x71,0xda,0xdc,0x76,0xc5,0xb8,0x34,0xa2,0x32,0x33,0x16,0x2e,0xb0,0x2a,0x90,0x43,0x40 +.byte 0x92,0x77,0x74,0x4e,0xdc,0xb4,0xe2,0x7d,0xc1,0x57,0xaf,0xf4,0x2c,0x20,0x65,0x77,0x88,0xc9,0x6e,0x69,0x38,0xc8,0x19,0x95,0x32,0x54,0x59,0x7f,0x37,0xd7,0x3c,0x07,0x05,0x87,0x2b,0xf9,0x58,0x74,0xc7,0x61,0x13,0x3d,0xc2,0xd9,0xec,0x3b,0x36,0x9f,0x8e,0xae,0x52,0xdd,0x5c,0xaa,0x29,0x6b,0x31,0x34,0x48,0x61,0x34,0x62,0x56,0xce +.byte 0x25,0xa8,0xc0,0x62,0xf5,0x35,0x58,0x4d,0x8e,0x61,0xd4,0xae,0x25,0x50,0xee,0x45,0xdd,0x14,0x7d,0x46,0x81,0x47,0xc3,0x3f,0x3f,0x81,0xdb,0x9a,0x59,0x56,0x4f,0x45,0xed,0x9c,0xe2,0xfc,0x96,0xff,0x5d,0x37,0x70,0xad,0xd2,0xeb,0xd9,0x2d,0x2a,0xaf,0xb9,0x16,0x4a,0x79,0x5d,0x76,0xb5,0x8f,0x74,0x19,0x6f,0x74,0x7d,0x4a,0xee,0x83 +.byte 0xa5,0x81,0xf3,0xd5,0xa0,0x43,0x5e,0x46,0xba,0xbe,0x49,0xa8,0xce,0x72,0x36,0x32,0xcd,0x8c,0x9b,0xa0,0xf9,0x5d,0xb7,0xb9,0xc7,0x8c,0xb2,0x59,0xb4,0x44,0xc1,0x90,0x53,0x92,0xd2,0xa8,0x4c,0xf9,0x35,0x40,0x32,0xd1,0xf0,0x2f,0xcb,0x6a,0x0b,0xe0,0xbe,0x34,0xc9,0x82,0x18,0x8d,0xfb,0xfc,0x50,0x8d,0x67,0xd5,0x86,0xd4,0xf1,0xb1 +.byte 0xaa,0x2f,0x9c,0xbc,0x52,0xbb,0x9f,0x17,0x1c,0x74,0x1d,0xdf,0x2d,0x1a,0x94,0x43,0x9b,0x80,0xb9,0x48,0xa3,0xaf,0x4b,0x30,0x0d,0xd9,0x3f,0x11,0x48,0x79,0x60,0xcc,0x25,0x6a,0xdb,0x8a,0xda,0xab,0xda,0x09,0x7c,0x9c,0x4a,0xaf,0xf9,0x0d,0xfb,0x7a,0x92,0x61,0xa5,0x17,0xf8,0x79,0x1b,0x00,0x52,0x56,0x5e,0x27,0x22,0x37,0xf4,0xbe +.byte 0x52,0x36,0xd3,0xdc,0x9a,0x33,0xf5,0x44,0x0e,0x53,0x0b,0xf6,0x9b,0xb0,0xb6,0x11,0xe4,0xd5,0x45,0x2e,0xdc,0xdb,0x46,0x18,0x9a,0x90,0x8b,0xcc,0xfe,0xc6,0x94,0x4f,0x97,0xb9,0x42,0xb6,0xd3,0x8f,0x7c,0x20,0xd1,0xa8,0xe6,0x85,0xce,0x65,0xeb,0x95,0x38,0x11,0x5c,0x1a,0x9d,0x34,0x25,0xc2,0xf0,0x33,0xbb,0x2c,0xc9,0x8d,0x0a,0x7a +.byte 0xb1,0x90,0x9f,0x24,0xed,0x35,0x3c,0x7e,0x71,0x82,0x12,0x3a,0x79,0x29,0xc8,0xa7,0x3e,0xa2,0x4e,0x50,0x03,0x94,0x7a,0x94,0xb7,0x2b,0x61,0x95,0x3d,0x5e,0x60,0x1c,0x68,0x51,0x82,0x73,0xe0,0x4a,0x2a,0x48,0x26,0xda,0xa3,0x53,0x8c,0x83,0xba,0x9f,0x95,0x37,0x5e,0x68,0x54,0x19,0x21,0xf8,0x31,0xaf,0x6b,0xfc,0x3a,0x3e,0xe3,0x3f +.byte 0xdb,0x16,0xb5,0x7e,0x13,0xf8,0xfd,0x7f,0x36,0xd6,0x8e,0x33,0xaa,0xe9,0xa4,0xa7,0xfd,0xf0,0x32,0xa6,0xdf,0xfa,0x22,0x7d,0xff,0x2a,0xe6,0x0d,0x6f,0xe2,0x21,0x54,0x6c,0x1a,0x99,0x17,0x56,0xad,0xce,0x39,0x6b,0x1a,0xe8,0x27,0x13,0x12,0x9c,0x4b,0x84,0x69,0x73,0xde,0x44,0x14,0xb2,0x7c,0x44,0x54,0x91,0x4f,0xeb,0x83,0xec,0x04 +.byte 0x73,0x85,0xb1,0xa8,0x44,0x72,0xa7,0x77,0xaf,0x0c,0xe0,0x52,0x65,0x04,0xe7,0x2a,0xee,0x0c,0x20,0x83,0x32,0x34,0x17,0x00,0x61,0xf9,0xf5,0x42,0x03,0xa4,0xb8,0x02,0x6f,0xb2,0xd3,0x65,0x51,0x2a,0x8e,0xdf,0x28,0x78,0x8a,0x8a,0x00,0xfb,0x24,0xd6,0xd5,0x86,0xaa,0xfb,0x86,0x93,0x5d,0x11,0xa4,0xf3,0xfd,0x36,0x18,0xf3,0x61,0xea +.byte 0x33,0xa8,0x0c,0xf0,0xb4,0x68,0xee,0xd3,0xe3,0x4f,0x22,0x24,0xde,0x1f,0x29,0x84,0x8b,0x5b,0x73,0x15,0xd6,0x62,0xa3,0x71,0x7d,0xf0,0x65,0x36,0xca,0x68,0x8a,0x6d,0x61,0x9c,0x0d,0x53,0xdd,0xf4,0x12,0xb3,0x5f,0xf0,0xb1,0x86,0xd6,0xe2,0xd6,0x80,0x4a,0x01,0x09,0x99,0x65,0xdb,0xae,0xe6,0xfc,0x68,0x5b,0xf9,0x10,0x99,0x8b,0x9f +.byte 0x08,0x52,0x09,0xae,0x59,0x4d,0x6c,0xf9,0x91,0x2b,0x57,0xea,0xf0,0xa3,0xdb,0xb8,0x99,0x29,0x2f,0xab,0x95,0x01,0x7d,0xec,0xd8,0x77,0x73,0x75,0x4f,0x88,0x44,0x69,0x76,0xc9,0x3c,0xf0,0x2d,0x7b,0x0d,0xbe,0xd4,0x88,0x0d,0xbc,0xa0,0x52,0xf4,0x2a,0xd1,0x62,0x2a,0xa9,0xe2,0x41,0x2f,0x52,0xce,0x96,0x7d,0x65,0x9b,0x74,0x82,0xde +.byte 0x43,0x4d,0xf8,0x8e,0x77,0x1c,0x18,0xf5,0x7e,0xab,0x94,0x3e,0xe7,0x90,0x2b,0xa1,0x16,0x00,0x7f,0x9c,0x9d,0x86,0xd1,0x74,0x7e,0xf7,0xbd,0x5a,0xa7,0x2f,0x0f,0xb0,0x5c,0xfc,0xfb,0x59,0x00,0xf3,0x84,0x09,0x77,0x66,0x17,0xf6,0x5d,0x0e,0xe2,0xe2,0xd4,0xb3,0x9e,0x79,0x88,0x66,0xa5,0x8e,0x30,0xae,0xca,0x7e,0x2b,0x32,0xa2,0x89 +.byte 0xe9,0x7e,0x59,0x21,0xd5,0x99,0xc7,0x10,0xa8,0x6f,0x95,0x8d,0x84,0xb4,0xcf,0x61,0xe7,0x5c,0x09,0xf3,0xbc,0xeb,0xf6,0x0c,0x84,0x1a,0x8d,0x13,0xf8,0x49,0x22,0xeb,0x09,0x55,0xef,0x56,0x12,0x21,0xcb,0x61,0x87,0xbf,0xef,0x43,0x5b,0x82,0xa8,0xc2,0xa2,0x5e,0xad,0x54,0x9a,0xcc,0x95,0xa2,0x01,0x05,0xb2,0xbb,0x26,0xa8,0xfd,0x6b +.byte 0x66,0x95,0x9c,0x0b,0x7b,0x23,0x32,0xff,0xdd,0x6c,0x18,0x1e,0x77,0x01,0x3c,0x82,0xaa,0x97,0x28,0x0f,0x93,0xa5,0x6c,0x85,0xe5,0x94,0x40,0xe0,0xa3,0x01,0x57,0x56,0x43,0x40,0xdd,0xa9,0xaf,0x21,0x79,0x10,0x8b,0xff,0x4b,0x51,0xe4,0xa2,0xe5,0xd7,0x0c,0xe2,0x9e,0x1e,0x38,0xdb,0x64,0xe1,0xb1,0x5b,0xe5,0x40,0xab,0xf6,0x05,0xd2 +.byte 0xba,0x85,0x78,0x61,0x2d,0x2e,0x07,0x06,0x6d,0x86,0x59,0xaa,0xd9,0x2c,0xfb,0x83,0x34,0xd0,0x2d,0x1d,0xad,0x5f,0xe4,0xac,0x05,0x46,0x3a,0x7b,0xd9,0xef,0x9f,0x2b,0x0c,0x18,0x21,0xf1,0x24,0x8a,0xb4,0x6e,0xd2,0x98,0x75,0x08,0x96,0x0c,0x7b,0x41,0xb7,0xf7,0x1f,0xcd,0xa8,0x1f,0x44,0xb1,0xed,0xdc,0x0e,0xcb,0x94,0xa0,0xb8,0x62 +.byte 0x67,0xdc,0x24,0xde,0x9e,0xe9,0x89,0xcd,0x92,0x7c,0x91,0x15,0xff,0xbd,0xfd,0xee,0xf8,0x29,0xd7,0xf9,0xe8,0x51,0xe7,0xc8,0x21,0xc5,0x20,0xe4,0xb8,0xa6,0xdb,0xfb,0x09,0x65,0x1c,0x3b,0x9e,0x39,0x44,0xcf,0xf5,0xc2,0x7b,0xf3,0x14,0x7d,0x69,0xf2,0xd0,0x97,0x63,0xf1,0xa7,0x81,0x56,0xfb,0xdf,0x4d,0x83,0x55,0x4f,0xde,0x50,0x7d +.byte 0xfe,0xb0,0xc0,0xc8,0x3b,0x3d,0x78,0x74,0x58,0x74,0x5e,0xfc,0xb7,0x0d,0x9a,0x26,0x3b,0x39,0xb6,0xf7,0xe0,0xe4,0x12,0x3c,0xd6,0x88,0x1c,0x9b,0x51,0x89,0xe7,0x53,0xcd,0x24,0x2e,0x34,0xa2,0xee,0xfa,0x5a,0x87,0xe5,0x7e,0xd5,0xf2,0x2f,0x15,0x99,0x57,0x5d,0x31,0x02,0xf8,0x08,0x38,0xea,0x8c,0x30,0x21,0xb0,0xff,0x94,0x51,0xcf +.byte 0x23,0xb7,0x02,0x5d,0xa3,0x75,0x7f,0x9d,0x66,0x49,0xe5,0xbe,0xc7,0x06,0x5e,0x1d,0xc9,0xe2,0x82,0x8a,0xc4,0x17,0x83,0x7e,0x65,0x6d,0x85,0x26,0x66,0xc0,0xf4,0xa5,0x1c,0x6e,0xba,0x32,0xfa,0x41,0x7b,0x2b,0x64,0x98,0x58,0x8c,0xce,0x2f,0xf3,0x56,0xf0,0x67,0xef,0x73,0x79,0xc4,0xc2,0x07,0xd7,0x85,0x1d,0x75,0x38,0x1e,0x15,0x82 +.byte 0x9d,0xf3,0xdd,0x3a,0x72,0xa3,0x23,0x0e,0x4a,0x1a,0x3a,0x97,0xc8,0xf1,0xf1,0x58,0x5d,0x1f,0xae,0x6d,0xc8,0x03,0xe0,0x7b,0x0f,0xf5,0x6f,0x35,0x41,0x8d,0xd5,0x03,0x85,0xdd,0xeb,0x3d,0x73,0xb1,0x93,0x35,0xc0,0x0f,0xfb,0x42,0xd4,0xf1,0x6b,0x35,0xe2,0x96,0xc5,0xd9,0xf2,0x69,0xbb,0x70,0x5e,0xf0,0x0c,0xe6,0xb5,0x81,0x94,0xc9 +.byte 0x29,0xa1,0x34,0x89,0xd9,0x9c,0x49,0x01,0x37,0x56,0x16,0x30,0x47,0x6f,0xe4,0x7c,0x5b,0xdd,0xfb,0x80,0x7f,0x0c,0x38,0x53,0x3d,0x57,0xf7,0xc4,0x80,0xf9,0x12,0x3a,0x9f,0xf9,0xb0,0xb6,0x94,0x6d,0xde,0x41,0x4e,0x30,0xac,0x1f,0x25,0x34,0xa0,0x95,0xe8,0x00,0x86,0x32,0x40,0xbb,0xc1,0x49,0x2d,0x07,0x49,0xb8,0x5f,0xcd,0x1b,0xd3 +.byte 0x0e,0x0c,0x54,0x0f,0xe4,0x20,0xe5,0xa1,0xed,0x98,0x65,0x5a,0xe7,0xce,0x68,0x9c,0x4c,0x48,0x03,0x9c,0x5b,0x68,0x4b,0x75,0x71,0x11,0x40,0x69,0xca,0x9a,0x3a,0xb2,0x3d,0x35,0x2c,0x70,0x35,0x8b,0x80,0x53,0x86,0x30,0x7d,0x4c,0xe9,0xc0,0x30,0x60,0xd0,0x06,0xbe,0xc2,0xad,0x39,0xcc,0xb2,0xec,0x90,0xcc,0xbd,0x7c,0xb5,0x57,0x20 +.byte 0x34,0x2e,0xfc,0xce,0xff,0xe3,0xd9,0xac,0xb8,0x62,0x6b,0x45,0x22,0x34,0xdf,0x8e,0x4b,0xf1,0x80,0x28,0x8d,0x0f,0xd5,0x3b,0x61,0x3e,0x91,0xa1,0xb1,0x85,0x27,0x78,0x88,0xbc,0xc4,0xb1,0xa1,0xbe,0x4f,0xc3,0xfd,0x1f,0xb9,0x30,0x31,0x2f,0xc1,0x9d,0xa3,0xb6,0x29,0xa4,0x60,0x82,0x73,0x93,0x74,0xea,0x97,0x67,0xf2,0xa3,0x97,0x50 +.byte 0x2f,0x9f,0x7b,0x23,0x18,0xb6,0xb4,0xee,0x15,0xa0,0xa4,0x07,0x1a,0xe9,0xb6,0x63,0x7e,0x88,0x40,0x57,0x86,0x79,0x6b,0x75,0xbe,0x57,0x8f,0xfe,0x0d,0xdf,0x4c,0x7f,0x39,0x9a,0x97,0xa6,0x87,0xc5,0xfd,0x52,0x77,0x36,0xc9,0x66,0x63,0xcf,0xc7,0x34,0x3b,0xf4,0x7a,0x12,0x56,0xf0,0xbc,0x7a,0x1a,0xa2,0xa2,0x51,0xb8,0xc1,0x70,0x81 +.byte 0xcf,0x1d,0xb5,0xe2,0x82,0xbb,0xfc,0xa3,0x80,0x18,0xf8,0x4b,0x76,0x9c,0xdf,0x9d,0x6c,0xf1,0xd8,0x2a,0xab,0x0c,0x12,0x02,0x29,0x09,0xfd,0x28,0xfb,0x57,0x38,0x05,0x2c,0xc5,0x67,0xd1,0xaa,0xbc,0x98,0xe6,0x22,0x78,0x06,0x4f,0x69,0x6a,0x63,0x1a,0x13,0x0b,0xa5,0xd2,0x61,0xc7,0x45,0x5b,0x21,0xab,0xbf,0x7b,0x7f,0x8c,0x2c,0xba +.byte 0x93,0x9f,0x41,0x67,0xc4,0x5f,0x53,0xac,0x90,0x05,0x86,0xb5,0x80,0x1f,0x5b,0x35,0x4f,0x92,0xf5,0xa8,0x5f,0xfb,0x56,0xdd,0x2d,0x9b,0xea,0xcb,0x0f,0x98,0x3c,0x4e,0xf1,0xa5,0x2c,0x37,0x70,0xe3,0x5c,0xaf,0x96,0x36,0xa8,0x2a,0xec,0xe0,0x2c,0x00,0xcd,0xaf,0x03,0x1d,0x05,0x2f,0x8c,0xe7,0xfe,0x4d,0xe9,0x97,0x6d,0xe1,0xf9,0x23 +.byte 0x60,0x08,0xea,0xfb,0x27,0xc8,0xf9,0xdf,0x49,0xfe,0xd9,0x48,0x35,0x6b,0x43,0xc5,0x19,0x90,0xb1,0xf1,0xee,0x84,0x7a,0x57,0xfa,0xa5,0xd6,0xd8,0xc9,0xf0,0x8a,0xe7,0x13,0x84,0xfc,0x28,0x54,0xae,0x99,0xfd,0x91,0xbe,0x91,0x27,0x98,0x28,0xdc,0xd7,0x2e,0xc1,0x21,0xcb,0x31,0xf8,0x47,0xe6,0x77,0x6d,0xee,0x7b,0x12,0xe4,0x9e,0x9d +.byte 0x07,0x46,0xa9,0x15,0x0b,0x3c,0xbe,0xc7,0x2d,0xe5,0xd6,0x25,0x4c,0xea,0x61,0xdc,0x18,0xb2,0x9d,0xb0,0x9a,0xff,0xa3,0x5f,0x2b,0xab,0x52,0x7d,0x1b,0xc3,0xa3,0x41,0x8f,0x5a,0x29,0xbd,0xc4,0x56,0x54,0x43,0x2d,0x61,0x07,0xed,0xd1,0x81,0x45,0xdb,0x61,0x0f,0xda,0xea,0xa6,0x1e,0xf9,0x9c,0xc0,0x8c,0xc4,0x8e,0xc7,0xca,0x38,0xe2 +.byte 0x45,0xde,0xdc,0xc5,0xc6,0xb0,0x43,0x17,0x8b,0xb1,0x58,0xd1,0x10,0x8e,0xa5,0x17,0x37,0x85,0xca,0x61,0x67,0x5c,0xd0,0x72,0x22,0x6b,0xd3,0x3b,0x53,0xbc,0xfb,0xe1,0x1e,0xa4,0x1b,0xd3,0xc3,0x8a,0x50,0x03,0x39,0xf5,0x36,0xdf,0x51,0x2e,0x05,0x4a,0xa8,0xdb,0x91,0x87,0xae,0xfe,0x3f,0x5c,0x35,0x5e,0xf9,0x8f,0x43,0x9e,0x92,0x36 +.byte 0x91,0x27,0x90,0xe8,0x7c,0xcc,0xc4,0x9c,0x13,0xbb,0x61,0x40,0xec,0x4f,0x49,0xcf,0x04,0x38,0x77,0x3b,0xb5,0xf8,0x69,0x8d,0xbb,0xb2,0x30,0x32,0x42,0x4d,0x7d,0x6c,0x56,0xdc,0xf4,0x8f,0xfc,0xb8,0x53,0xc5,0x11,0x17,0x23,0x94,0xf9,0x6d,0x6f,0xee,0xee,0x31,0xbf,0xce,0x11,0x8b,0x9e,0xd7,0xa5,0x09,0x36,0x89,0x72,0x25,0x18,0x1f +.byte 0x13,0xa7,0xdf,0xc5,0x91,0x7e,0xd6,0x2b,0xb8,0x08,0x9c,0x12,0x83,0x21,0x97,0x3d,0xad,0xac,0x1c,0x54,0xf3,0x65,0x04,0x2f,0x09,0xd1,0xd2,0xe5,0xce,0x24,0xb1,0xd9,0xe4,0x38,0x1f,0xb4,0xce,0xea,0x27,0x7f,0x5f,0x16,0x52,0xa4,0x2f,0x2f,0xaf,0x91,0xec,0x7a,0x21,0xf7,0xa1,0x38,0x78,0x78,0xc5,0xa9,0x94,0x63,0x87,0xf8,0x95,0x9e +.byte 0xf9,0x82,0x98,0x6d,0x9d,0x48,0x80,0xaa,0x7a,0x36,0xf9,0x5f,0xfb,0x39,0x3d,0xae,0xbc,0xcd,0xfc,0x67,0x46,0x07,0x7e,0xdf,0xef,0xff,0x8d,0x67,0xe7,0xd9,0x60,0x90,0x7b,0x49,0x10,0x65,0x3a,0x60,0x87,0x7a,0xed,0x9a,0x44,0x48,0x81,0xcc,0xad,0xe4,0x6a,0x62,0xf8,0x02,0x6f,0x41,0x8a,0x8d,0x44,0x28,0x1a,0xb8,0x52,0x60,0x4b,0x3f +.byte 0xfc,0xdd,0x33,0xad,0x14,0xb1,0x34,0x63,0x1f,0xdc,0xeb,0x9a,0x3f,0x99,0x82,0x28,0x36,0x6f,0x8e,0xd7,0x39,0x2e,0xc0,0x37,0xfb,0xad,0x57,0x6c,0x82,0x1a,0xc6,0xe4,0x4b,0xca,0x00,0x68,0x57,0x34,0xf0,0x57,0x6a,0xcb,0x50,0x5d,0x8d,0xfa,0xcd,0x89,0x41,0x91,0x23,0x98,0x1f,0x4f,0x18,0xb6,0xd2,0x9d,0xde,0x2f,0x5c,0xe6,0x08,0x76 +.byte 0x97,0xba,0x24,0x4e,0x84,0xd7,0xeb,0x80,0xde,0xec,0xee,0x51,0x5a,0x0e,0x5f,0xb7,0x37,0xda,0xa5,0x94,0x2b,0x6d,0x73,0xb7,0x6c,0x22,0x95,0x3a,0xaa,0x5c,0x6f,0x89,0x90,0xec,0xb3,0x31,0x00,0x37,0x28,0x18,0xbb,0x98,0x23,0xfc,0x3e,0x21,0x7c,0xaa,0x44,0x54,0x7b,0xe6,0xa0,0x17,0x58,0xef,0x11,0x3f,0x48,0xb8,0xa8,0x15,0x4a,0x92 +.byte 0xa9,0x39,0xe2,0xa6,0x38,0x03,0xa6,0xd3,0x79,0x8b,0x38,0x06,0xaf,0x4b,0xd4,0xab,0x0a,0x13,0xff,0x2d,0xfa,0xab,0x4b,0x64,0x9e,0xb0,0x3d,0xba,0x18,0x01,0xfd,0xc3,0x6a,0x6f,0x21,0x9c,0xf5,0x2f,0xab,0x2d,0x42,0x12,0xc9,0x72,0xde,0x83,0x42,0x6a,0xf0,0xd4,0x96,0x73,0xf1,0x93,0xa3,0x2d,0x9b,0xb4,0x94,0x51,0x0c,0x6e,0x8e,0xf0 +.byte 0x5e,0xbf,0x98,0xbf,0x08,0x0f,0xd8,0x6c,0x65,0x4e,0xb5,0x47,0xeb,0x7c,0x1b,0x73,0xe0,0xe6,0x2c,0x03,0xd2,0x2a,0x32,0xff,0xa7,0x03,0x6d,0x38,0x47,0x56,0x4b,0x25,0x0b,0x39,0x73,0x87,0x4b,0xa5,0x12,0x79,0x79,0xf3,0x88,0x37,0xe2,0x4f,0xb8,0xbf,0x70,0x0e,0xf7,0x8c,0xe6,0xa3,0xbc,0x35,0x10,0xcd,0x72,0x56,0xd6,0x83,0xc1,0x0b +.byte 0x5b,0xf3,0xa8,0x74,0xc7,0xb9,0x84,0xc8,0x6c,0xff,0x66,0xad,0x95,0x6f,0xbc,0x82,0x84,0x2a,0x11,0x40,0xf9,0xa8,0x3f,0x05,0xf9,0xab,0x19,0x55,0xce,0x80,0x90,0x65,0x49,0x3d,0xe1,0x54,0x2c,0x1a,0xdb,0xf3,0xaa,0x2f,0xeb,0xf5,0x10,0x1f,0x8c,0x35,0x46,0x68,0xb1,0x4c,0x52,0xe7,0xe9,0x58,0x78,0x33,0xfd,0xc6,0x13,0x0e,0x69,0xae +.byte 0xf4,0x1a,0x8a,0x77,0x8f,0xcc,0x98,0x74,0x88,0x20,0x84,0x5b,0x83,0x54,0xa9,0xee,0xc2,0x0f,0x8a,0x46,0xb1,0xc7,0xfb,0xfd,0xf2,0x2c,0xaf,0xfa,0x72,0x34,0x7a,0x79,0x50,0x10,0xc6,0x04,0xfd,0x0a,0x1e,0x4a,0xb5,0xf5,0xe7,0x4d,0x98,0x80,0x5d,0x0b,0x81,0x23,0xc3,0x6e,0xbf,0xc8,0xcd,0x35,0x96,0x5a,0x58,0xec,0xef,0x6a,0x8d,0x48 +.byte 0xda,0x48,0xbb,0x8f,0xcc,0x1f,0x86,0xff,0x7a,0x27,0xef,0xe6,0xb7,0xc7,0x2a,0x47,0x8d,0x6c,0x4a,0xc6,0x0a,0x32,0x67,0x1d,0x2f,0x83,0x3d,0x46,0x41,0x46,0x1c,0x75,0x7b,0x29,0x89,0xa2,0x65,0x9b,0x53,0x3d,0xd9,0x90,0x83,0xce,0xab,0x07,0xbb,0x46,0x61,0xb1,0x54,0xbd,0xc9,0x98,0xf7,0x96,0x76,0x03,0xdc,0x1f,0x1b,0xf2,0x5c,0x07 +.byte 0xdd,0x24,0x94,0x72,0x1e,0x94,0xb1,0x14,0x0b,0x40,0x77,0xde,0x3d,0x3f,0x1c,0xf0,0x8f,0xa4,0xcb,0x34,0xb5,0x2b,0x72,0x53,0x78,0xf3,0x3f,0x8e,0x47,0x30,0xb2,0x7e,0x73,0x3f,0x9a,0xef,0x19,0xb1,0xef,0x82,0x99,0xd4,0x17,0x60,0x94,0xf6,0x15,0x75,0x50,0x1f,0xb3,0xdd,0xae,0x1f,0xf8,0x63,0x9a,0x30,0x2c,0xf0,0xdd,0xbf,0x49,0x70 +.byte 0xd7,0x86,0x4a,0x5c,0x46,0x10,0x48,0x46,0x02,0x18,0xa4,0x39,0xb6,0x75,0x11,0x21,0xae,0x62,0x64,0xd8,0x85,0xc8,0xda,0xd2,0xd6,0x69,0xcc,0x37,0x57,0x49,0x73,0x1a,0x10,0x7b,0xd7,0x58,0xdd,0x0b,0xf3,0x16,0xe7,0x62,0x2c,0x32,0x92,0x0e,0x70,0x6f,0x77,0x74,0x0d,0xff,0xc2,0x8d,0x3b,0x3f,0x29,0x28,0x8f,0x88,0xb8,0x02,0x5b,0x3a +.byte 0x8b,0x65,0x89,0x92,0x2f,0xc7,0x30,0x73,0xc3,0x20,0xbc,0xa4,0xe4,0x5e,0xea,0xf8,0x21,0xb6,0xc5,0x47,0x56,0x35,0x8f,0xf6,0xd5,0xdd,0x77,0x1d,0xdf,0xd0,0x27,0xa3,0x04,0xb9,0xd0,0xc4,0x28,0x16,0xa5,0xaf,0x47,0x55,0x85,0x93,0x38,0xf4,0xac,0x13,0x30,0x7d,0x77,0x1f,0x3d,0xd5,0xd7,0x22,0xbe,0xe2,0x4e,0x6d,0x4b,0x0e,0xbe,0x1d +.byte 0x43,0x79,0x34,0x95,0x6f,0x38,0xa1,0xb3,0xa0,0xed,0xf6,0x17,0xf4,0x24,0x70,0x26,0x18,0x3e,0x1c,0xde,0xdc,0xa9,0x67,0x12,0xd3,0xc8,0xd7,0x70,0x13,0xa5,0xb3,0x25,0xe1,0x0a,0xe9,0xf6,0x4e,0x56,0x82,0x17,0xdc,0xbc,0x96,0x2f,0x59,0x03,0x9b,0xf4,0xc3,0x66,0xd2,0x90,0x95,0x1d,0xe0,0x99,0xfb,0xd8,0xa8,0x14,0xc7,0xa6,0x12,0x6b +.byte 0x08,0x6a,0xc8,0x0f,0x34,0x2a,0xb6,0xc4,0x9a,0xcd,0x61,0xf7,0x61,0xa3,0x59,0x29,0x11,0x30,0x76,0xb5,0x97,0xbc,0x2f,0x87,0xd8,0x12,0xb3,0x1d,0x99,0x8d,0x5d,0x57,0x0c,0xda,0xb0,0x9f,0x51,0x1a,0xb5,0xc6,0x94,0xc3,0xe9,0x5a,0x72,0x0c,0x37,0x76,0xb6,0x3c,0x00,0x02,0x69,0xad,0x8e,0x66,0x8b,0x5c,0x13,0x48,0xb7,0x9e,0xc5,0x7e +.byte 0xe0,0x35,0x07,0xd2,0x04,0x9c,0x35,0x95,0x8b,0x55,0x87,0x03,0x32,0x36,0xeb,0x11,0x88,0x54,0x8d,0x3e,0x88,0x46,0xc2,0xfe,0x24,0xa4,0x4b,0x92,0x19,0x44,0x6c,0xc9,0x69,0x32,0x22,0x95,0x5b,0xda,0x58,0xa4,0x00,0x33,0x83,0x2d,0xa4,0x17,0x2e,0x00,0x4d,0x9a,0x7d,0xef,0x04,0xa8,0x8b,0xf2,0x7c,0xb9,0xdb,0x54,0xcf,0x63,0x14,0x52 +.byte 0x5b,0x79,0xf6,0x89,0x5c,0xfa,0x8a,0x85,0x88,0x7f,0xca,0xed,0xfb,0x62,0xbc,0x1d,0x0d,0x90,0x51,0x27,0x45,0x74,0xa0,0x55,0xfc,0x60,0xea,0xef,0x6e,0x40,0xeb,0x0b,0x61,0x45,0x44,0xee,0xb6,0x20,0x4c,0xe1,0x08,0x62,0x29,0xdd,0xd0,0xa1,0xd5,0x7f,0x42,0xb9,0x0f,0x12,0xef,0xfb,0x13,0xa2,0xf1,0x85,0xaa,0x56,0x18,0x6c,0x70,0x7a +.byte 0x4d,0x52,0x76,0xce,0xa9,0xed,0x0a,0xcc,0x55,0xf0,0x01,0x99,0x44,0xe9,0xc4,0x74,0x33,0x2a,0xce,0x53,0xf3,0x4f,0x8f,0x1c,0x67,0x39,0x2b,0x0e,0x46,0xe2,0x49,0x06,0x52,0xbf,0xc4,0x3f,0x93,0x84,0x46,0x0a,0x9b,0xcb,0x1d,0xa5,0x66,0x9c,0x3e,0x3d,0xd1,0x92,0xda,0xe2,0x11,0x5b,0x89,0x7a,0xc4,0x33,0xba,0xa9,0x19,0xfd,0x3c,0xe3 +.byte 0xf0,0xa0,0x9b,0x83,0x50,0xce,0xa9,0x62,0xe3,0x85,0xc6,0xc4,0xe5,0x22,0xbb,0x1a,0x8e,0x04,0xb5,0x4d,0xca,0x18,0x7d,0xb0,0x99,0x50,0x78,0x88,0x69,0x43,0xe0,0xfd,0x90,0xa6,0xbf,0xdc,0xe3,0x03,0xf2,0x5d,0xa1,0xa2,0x88,0xc7,0xab,0xa9,0xc2,0xda,0x3f,0xff,0x79,0xa6,0x07,0xfd,0xc4,0xb1,0xfb,0x47,0x3d,0x75,0x82,0x26,0x52,0x85 +.byte 0x3f,0xf9,0xc9,0x85,0x46,0x24,0xe9,0x0f,0x96,0x8c,0xbb,0x02,0x83,0x60,0x69,0x49,0x8c,0x38,0xd1,0x4e,0xd0,0x63,0x2c,0xb6,0x12,0xb2,0x8e,0x4b,0xd3,0xe3,0xdf,0x20,0x00,0x99,0xf1,0x06,0x93,0xbf,0x27,0x42,0x8b,0xe3,0x8d,0x4c,0x3b,0x05,0x62,0x64,0x21,0xb1,0xfe,0xce,0x08,0xd2,0x23,0x69,0x11,0x74,0x31,0x3a,0x90,0x10,0x07,0x1a +.byte 0xd5,0xf5,0xc2,0x09,0x61,0x67,0x65,0x99,0x3a,0xf3,0x9e,0x4a,0xd8,0xa1,0xb2,0x50,0xf4,0x07,0xf0,0x7b,0x89,0x6d,0x4d,0x6a,0xd4,0x54,0xb9,0x3c,0xd5,0x4e,0x1c,0x12,0x0f,0x19,0x92,0x97,0x21,0x65,0x83,0x33,0x20,0x92,0x95,0xd4,0x0e,0x78,0xf4,0x92,0x16,0x36,0xd8,0x1b,0xd8,0xbf,0x41,0xe4,0xfb,0xb9,0x81,0x26,0x72,0x7e,0x1b,0x58 +.byte 0x05,0x45,0x97,0x66,0xf2,0x23,0x16,0xca,0x4e,0x95,0xc2,0x6c,0x60,0x84,0x5f,0x77,0x82,0x44,0x0e,0xf7,0x30,0xaa,0x51,0xa9,0x85,0x8b,0x03,0xfc,0x3d,0x6d,0x66,0x91,0x37,0xa5,0x1c,0xf8,0xcf,0x9d,0xd8,0xcd,0x8c,0xa1,0x29,0xbd,0xb5,0x4f,0x47,0xba,0xd1,0x55,0x3b,0x4e,0xc9,0xce,0x4c,0xcf,0x2e,0x19,0xa0,0x95,0xe6,0xcb,0x36,0x97 +.byte 0x3e,0x23,0xbe,0x09,0xfd,0x38,0x47,0x00,0x03,0xec,0x49,0xbb,0x49,0x1f,0x45,0x84,0x0f,0x1e,0x74,0xab,0xc9,0x07,0x00,0x04,0x70,0xe9,0xbd,0x61,0xb1,0x92,0xee,0x67,0x9a,0x5e,0x90,0xdc,0xe7,0x99,0x36,0xd0,0x58,0x15,0xe5,0x15,0xa2,0x1d,0x61,0x18,0x39,0x5f,0x6c,0xc7,0xbe,0xd0,0x23,0x1e,0x41,0xc8,0xaa,0x8e,0xbf,0xb8,0xdb,0x90 +.byte 0x8c,0x60,0x07,0x1e,0xe9,0x6c,0xe4,0xde,0xec,0x73,0x34,0x94,0x54,0xa4,0x6b,0x49,0xcf,0x87,0xb5,0x88,0x98,0xe6,0x2c,0xce,0xb7,0x76,0xa5,0x29,0xf1,0x29,0x50,0xc5,0x9e,0x13,0xe4,0x61,0x6a,0x54,0xb2,0x26,0xfa,0xfa,0x4a,0x41,0x3b,0x0a,0xf5,0x9a,0x60,0xbb,0xfc,0x1e,0x5d,0x21,0x7e,0x91,0x51,0xd6,0x5e,0x92,0xf9,0x21,0x80,0xa8 +.byte 0x35,0xc0,0xbb,0x7a,0xeb,0x75,0xb4,0xa3,0xd3,0x8d,0xaf,0x07,0x53,0x65,0x36,0x11,0xf9,0xb6,0x69,0x29,0x1e,0x5d,0x8f,0x57,0x5d,0xed,0x42,0xf9,0xd5,0xf6,0xc3,0x1e,0x29,0xc4,0x49,0x04,0xe4,0xfb,0xbf,0x9b,0x4a,0x7b,0xdd,0x57,0x51,0xfe,0xc4,0xd1,0xd9,0xe9,0x8f,0x94,0x78,0xbc,0x5c,0xeb,0xb6,0xbc,0x51,0xb0,0x82,0x87,0x47,0xb4 +.byte 0xf7,0xf9,0x02,0xd7,0xac,0x23,0xc0,0xe5,0x9a,0xc3,0x2f,0xd2,0xb8,0xb2,0x62,0xb9,0xdb,0x49,0x85,0x77,0x92,0xa6,0xe5,0x24,0x43,0x4d,0x0d,0x67,0x94,0x01,0x29,0xd6,0x2e,0xee,0xd9,0x2e,0x97,0x0e,0x20,0x7f,0x84,0x19,0x3c,0x3a,0x6f,0xa5,0xb0,0x8b,0x8f,0x8d,0x96,0xbb,0x76,0x61,0x97,0xc2,0x65,0x83,0xd8,0xda,0xab,0x42,0xfa,0xe5 +.byte 0x1e,0x42,0x93,0xa7,0x66,0x03,0x06,0x3b,0xbe,0xb8,0xae,0x71,0xee,0xdb,0x5d,0xdf,0x40,0x64,0x17,0x17,0x2e,0x03,0xca,0x37,0x2a,0x71,0x92,0x0a,0x01,0xa3,0x0f,0x0b,0x09,0xf2,0x0e,0x4b,0x4d,0x18,0xf3,0xc4,0xf2,0x51,0x7b,0x53,0x30,0xab,0x24,0xa2,0x47,0x38,0xc9,0x2c,0xdf,0x0d,0x32,0x3e,0x3f,0x57,0x2d,0xfc,0x44,0x19,0x64,0x8b +.byte 0xe9,0x9a,0xc2,0xf2,0xf6,0x2d,0x30,0x0c,0x0f,0xc3,0xc3,0xfe,0xc2,0xd1,0xbc,0xe0,0xbf,0xaf,0xeb,0x40,0x64,0x28,0xe2,0xd9,0x3c,0x7e,0x24,0x94,0x8f,0xe8,0x54,0x8b,0x26,0x6b,0xe1,0x4e,0x44,0x5a,0x7d,0x7b,0x12,0x36,0x2c,0x12,0xad,0x26,0xbc,0xa7,0xa3,0x2b,0x25,0xb9,0xde,0xe6,0x64,0x2d,0xab,0x7f,0x15,0x22,0x51,0x26,0x1c,0x15 +.byte 0x5d,0x13,0x18,0x93,0xc1,0x19,0x65,0xca,0xf3,0x8b,0xe0,0xcf,0x8c,0x43,0xe9,0xfd,0xa1,0xbd,0xe9,0xde,0x78,0x26,0xcb,0x7c,0xdc,0x68,0x06,0x98,0xf6,0x90,0x44,0x40,0xf0,0x5e,0xe1,0x16,0xf5,0x5d,0x4d,0x9b,0x85,0xe6,0x26,0xbd,0xab,0xcc,0x46,0x62,0x18,0x51,0xd5,0x3c,0x9f,0x6e,0xfa,0xe7,0x94,0xfc,0xc2,0x1a,0x9d,0x63,0x2c,0xdc +.byte 0xc3,0x89,0x67,0x94,0x37,0x58,0x0d,0x13,0xb8,0xdf,0x41,0x3d,0x70,0x78,0x1e,0x61,0x75,0x77,0xcc,0xbf,0x5f,0xa8,0xd3,0x89,0xcc,0xd3,0x40,0x4e,0x65,0xbd,0xce,0x3c,0xf0,0x5a,0x8f,0xe2,0xe1,0x24,0xaa,0xed,0x0f,0xd1,0x03,0x0d,0xf5,0x36,0x98,0xcd,0xa5,0x77,0x40,0x24,0x0a,0x82,0x68,0x79,0x82,0x38,0x68,0x6f,0x2b,0x0b,0xce,0x0f +.byte 0xcd,0x0f,0xba,0xdb,0xb5,0x22,0x38,0xd2,0xb0,0x9f,0x0f,0x08,0x0d,0xd8,0x5e,0xa7,0xd0,0xa9,0x39,0x66,0x4c,0x46,0xce,0x2a,0xc3,0x67,0x8c,0x91,0xdc,0xf1,0xc0,0x3a,0x58,0x50,0x1f,0xb0,0xa4,0x4d,0xbf,0x99,0x57,0xcf,0xae,0xb2,0xaf,0x6a,0x42,0xd2,0x7f,0x85,0x8c,0x40,0xc6,0x9a,0x93,0x57,0x54,0xf5,0xb4,0x83,0x59,0xb5,0x19,0x52 +.byte 0x7c,0x8b,0x76,0xee,0x35,0x90,0xbf,0xbe,0x65,0x58,0x3b,0x25,0x52,0x18,0xd8,0x7f,0x1f,0xe6,0x70,0xce,0x56,0x1a,0x45,0xa0,0x81,0xee,0x95,0x6f,0x55,0x43,0xaa,0x6e,0x87,0xa9,0xab,0x7d,0xe9,0xa1,0xa3,0x63,0xe7,0x1b,0x6b,0xa6,0x2c,0xe5,0x4a,0xb2,0x1e,0x73,0x5e,0xb5,0xae,0x83,0xe6,0x54,0x0b,0xc5,0x6b,0xb6,0xc4,0x73,0x62,0x1a +.byte 0xbf,0x1a,0x65,0xa2,0x5e,0x3a,0x45,0xd9,0xba,0x5b,0xef,0xf7,0x13,0x0c,0x7c,0x68,0xa1,0x98,0x71,0xb7,0x39,0x7c,0xbc,0x69,0xdb,0xd4,0xac,0x3f,0x82,0x63,0x9b,0x71,0x25,0x3a,0x06,0x73,0x60,0x71,0xc3,0x30,0xd3,0x96,0x02,0x4b,0x46,0xbd,0xd4,0x6e,0xc6,0x29,0xcc,0xd0,0xe1,0x0b,0x66,0x62,0xea,0x29,0xc7,0xcf,0x35,0x9e,0x2f,0x1f +.byte 0xa0,0xfc,0x8c,0x4a,0x83,0x8e,0x3b,0xf5,0x7a,0x6f,0x52,0xaf,0x99,0x9c,0x86,0xab,0xe5,0x1b,0x82,0xb3,0x18,0x35,0x77,0x9b,0xa3,0x94,0xc8,0x39,0x30,0x3f,0xad,0xa9,0x0f,0x93,0xb8,0xc8,0xed,0x04,0xf2,0x0b,0x9a,0xb1,0xd1,0xc9,0x9e,0x40,0x4f,0x71,0x21,0x63,0x2a,0x05,0x26,0x53,0xa3,0x3f,0x43,0xe4,0xf8,0x7c,0x2f,0xa3,0x5a,0x6e +.byte 0xc1,0x40,0xa8,0x4d,0xbc,0x03,0xae,0xe9,0x36,0xb6,0x37,0xdc,0x5f,0xef,0xb0,0x35,0x33,0xdf,0x33,0x71,0xaf,0x80,0xf2,0x69,0xd9,0xb5,0xfc,0xff,0xd2,0x5b,0x6a,0xeb,0xdc,0xe0,0x26,0x43,0x38,0x7b,0x24,0xb2,0x79,0x53,0x52,0x57,0xc4,0x1f,0x6d,0xc9,0x50,0xf2,0x63,0x9d,0xc1,0x22,0x5f,0x11,0x82,0x38,0xdb,0xd3,0xb4,0x1d,0x10,0x72 +.byte 0x9e,0x4d,0x03,0x30,0xba,0x5e,0xe9,0x8c,0x21,0x12,0xe6,0x3a,0xd6,0x4c,0x18,0xa4,0x27,0xc9,0xf5,0x50,0xbd,0xbe,0xf0,0x86,0xd8,0x00,0x56,0xf0,0x10,0x81,0xec,0xeb,0xfc,0x5b,0x29,0x88,0xff,0x73,0x60,0x6b,0xf5,0x8c,0x0b,0x30,0x04,0x53,0x85,0x61,0x0c,0xfc,0xff,0x8f,0x21,0xd2,0xa1,0xcb,0xf7,0x90,0x53,0x3b,0xf4,0xf0,0x2c,0x7d +.byte 0xb6,0x84,0xe7,0x4c,0x88,0xea,0x4f,0xdf,0xff,0x0f,0x5d,0x0f,0xd3,0x2d,0x4f,0x7e,0xdc,0xd1,0x22,0x71,0x0d,0xae,0xa8,0xcf,0x05,0x7b,0xfc,0xfe,0x87,0x40,0xa5,0xe8,0xfd,0x3f,0xdb,0x2f,0x00,0x21,0xb9,0x70,0x02,0x2c,0x96,0x24,0xaf,0x35,0xe2,0x87,0xcb,0x50,0xcf,0x7e,0xfa,0xaf,0x39,0x82,0x0c,0xd5,0xa6,0x3f,0x9c,0x77,0x60,0x16 +.byte 0xbf,0x42,0xcc,0x97,0xd1,0x19,0x0d,0x8a,0x50,0x98,0x7d,0x19,0x7b,0x40,0x1c,0x22,0xde,0x50,0x90,0x32,0x9a,0x3d,0x07,0x35,0xc0,0x48,0x4c,0x0a,0xcd,0x91,0xab,0xf7,0xf3,0x06,0x77,0x80,0x96,0x7b,0x59,0x33,0xe6,0xbf,0x93,0xb8,0x59,0xd0,0x3a,0x1f,0xcc,0xe7,0x1d,0xd4,0xb5,0x58,0xee,0xe7,0x95,0xfa,0x75,0xdb,0x37,0x74,0xb0,0x7d +.byte 0x4d,0xee,0xef,0x20,0x13,0xe5,0x82,0x07,0x8e,0xdd,0x57,0x75,0x33,0x56,0xc4,0x80,0xb0,0x06,0x9f,0x6b,0x72,0x31,0xcf,0xac,0x5f,0x96,0x13,0xeb,0xf4,0x34,0xb6,0x6b,0x55,0xef,0x55,0x26,0x4e,0xdb,0x6c,0x2f,0x64,0x29,0x91,0x3c,0x6d,0x29,0xd2,0x94,0xbd,0x2c,0x99,0xb9,0x97,0x76,0xee,0x7d,0xfd,0xb2,0x8d,0x14,0x4f,0x09,0x81,0xb3 +.byte 0x68,0x3e,0x79,0x28,0x56,0x50,0x3f,0x86,0x4c,0x95,0x6c,0xad,0xf6,0xc5,0x43,0x25,0xea,0xbc,0xe2,0xba,0x77,0x18,0xc6,0x82,0x65,0x73,0x38,0x90,0x9d,0xc9,0x57,0xcd,0xa2,0x7c,0xd3,0x26,0x59,0x44,0xd9,0x79,0xae,0xdd,0x6f,0xe9,0xdc,0x16,0x73,0xba,0x05,0x8a,0x40,0x9f,0xe7,0xcf,0x29,0xa4,0xdf,0x49,0x7f,0x1d,0x73,0xc7,0x8b,0x8d +.byte 0xad,0xb5,0x3d,0x1b,0x64,0xb1,0x8f,0x78,0x06,0xbe,0xaa,0x2c,0x08,0x73,0xc7,0x2c,0xdc,0xd8,0x3f,0x9f,0x1b,0xd2,0xe1,0x4f,0x9d,0x87,0xb8,0xa9,0xdc,0xef,0xbc,0x31,0x9f,0xf7,0x84,0x09,0xe7,0xbc,0xec,0x2a,0xcb,0x3b,0x3a,0x30,0xe2,0x5b,0xbc,0xcd,0xa8,0xdb,0x46,0x80,0xec,0xaa,0x06,0x8e,0xd8,0x6c,0x35,0x65,0x52,0xb8,0xc3,0xf9 +.byte 0x97,0x68,0x06,0x2d,0x3e,0x91,0x71,0x44,0x6e,0x01,0x51,0x10,0x5b,0x74,0xb9,0x3f,0xd7,0xf9,0x5c,0x98,0xe6,0xf8,0x98,0x32,0x26,0x9b,0x5e,0x9c,0x88,0xfb,0xaa,0x70,0xd2,0x2e,0xc2,0xf6,0x02,0x92,0x33,0x55,0x92,0xba,0xfb,0x0e,0x0b,0x08,0xdf,0x5d,0xdd,0x47,0x28,0xae,0x32,0xb3,0x27,0x8d,0xd4,0x18,0x43,0x64,0xc4,0x7f,0x60,0x62 +.byte 0xd9,0x63,0xd1,0x28,0xc9,0x75,0x3b,0x44,0xb4,0x8e,0x2a,0x93,0xf9,0x4c,0x4f,0x7e,0x6b,0x98,0xc9,0x1a,0x82,0x51,0x9a,0xb2,0x80,0x70,0x2e,0xff,0x19,0x66,0x1b,0xb6,0xbc,0x15,0x8e,0xe6,0x0f,0x8e,0x04,0x10,0x94,0x44,0x6c,0x32,0x4b,0x61,0xbc,0x4a,0x16,0x7b,0x25,0x2a,0x27,0x96,0xa9,0xa9,0x61,0x10,0xc1,0x46,0xdd,0xf5,0xe3,0xe8 +.byte 0x1f,0x5b,0xa0,0x77,0xe1,0x42,0x9a,0xd4,0x04,0x33,0x68,0x72,0x1c,0x44,0x29,0xce,0x98,0xe0,0xc7,0x3a,0x9e,0x3c,0xb9,0xb4,0x29,0xef,0x57,0xee,0x8c,0x8f,0x7c,0xe6,0xe1,0x43,0x6e,0x45,0x0e,0xdd,0x4e,0x11,0x4b,0x28,0x69,0xde,0xb8,0xfa,0x32,0xbe,0xc6,0x4f,0x11,0x99,0xe5,0xe3,0xe2,0x1f,0x03,0xbe,0x4a,0xad,0x60,0x68,0xc8,0x13 +.byte 0x80,0x4e,0xb6,0xc0,0xc5,0xc7,0x97,0x5c,0x0b,0x0e,0x64,0x43,0x78,0x70,0x95,0x91,0x8e,0x36,0x6b,0xad,0x57,0xc7,0x1e,0x9c,0x54,0xc9,0x89,0xf0,0x13,0xde,0x0a,0xbe,0xc0,0xa9,0x35,0x77,0x0a,0x01,0x7f,0x98,0x51,0x82,0x92,0x14,0xe0,0x9a,0x08,0xa3,0x0c,0x6c,0x67,0xf2,0x05,0xaa,0xa9,0x4e,0xce,0x3b,0xb1,0xb6,0x8c,0x82,0x5d,0x11 +.byte 0xf2,0xe5,0xd7,0xda,0x3a,0x65,0xa0,0xe3,0xa4,0x09,0x01,0x1c,0xb2,0x08,0x90,0x94,0xb5,0x51,0x56,0x24,0x22,0xfd,0x12,0xad,0x7a,0x75,0xcf,0x0f,0x0f,0x23,0xc3,0xa6,0x1f,0xf8,0x39,0xbc,0x2f,0x18,0x53,0x14,0xef,0xdf,0x90,0x6a,0x50,0x2b,0x8c,0x8b,0xa8,0xd4,0x8c,0x59,0x8f,0xd8,0x81,0x86,0x57,0xc1,0xd1,0xfb,0xe7,0xa6,0x20,0x6e +.byte 0x7c,0xbf,0xce,0xe3,0xce,0x28,0x35,0x7c,0x8e,0x1a,0x66,0xea,0x7d,0x81,0x09,0xdb,0xa8,0x64,0xba,0x3c,0x07,0x3f,0x23,0xd3,0x05,0x97,0x4c,0x92,0xc2,0xa4,0xe8,0x6c,0xfb,0xa0,0x9d,0x8b,0x4d,0xcb,0x3a,0x96,0xe7,0x04,0x0f,0x48,0x87,0x2c,0xdd,0x51,0xf3,0x46,0x7e,0x61,0x89,0xbe,0xb8,0xb0,0x9e,0x9c,0xc4,0x37,0x55,0xe6,0x4f,0x78 +.byte 0x7e,0xb0,0x59,0x42,0xca,0xba,0x4a,0xb2,0x50,0xbd,0x16,0x68,0x99,0x42,0xb4,0x8b,0x60,0x3d,0x54,0x41,0x17,0x11,0x39,0x42,0x5d,0x41,0xec,0xc2,0x53,0x82,0x7c,0x32,0xc9,0xd1,0x34,0x49,0xd8,0x4f,0x29,0x21,0xeb,0x97,0x98,0x4c,0xeb,0x21,0xce,0x50,0xd6,0x53,0xd9,0xf1,0x6e,0x26,0xfa,0xe4,0x71,0x34,0xd8,0x38,0xac,0x39,0x4f,0x02 +.byte 0x36,0x93,0xf2,0x08,0x88,0xdc,0x24,0xdd,0x1f,0xf5,0xe9,0x7f,0x83,0xa0,0xa4,0x6b,0xc5,0xef,0x8e,0x82,0xf9,0x92,0xbc,0x82,0x3f,0xce,0x86,0xa6,0x34,0xf8,0x16,0xa7,0xdb,0x97,0xca,0x54,0x43,0xd8,0xfc,0x31,0xde,0x73,0xd0,0x79,0x1a,0xac,0x61,0x15,0xbd,0x38,0x64,0x3b,0xc6,0xb5,0x95,0xeb,0x2e,0x68,0xe4,0x1d,0x6b,0x18,0xab,0x88 +.byte 0xb0,0x96,0x51,0x8c,0xbe,0x41,0x63,0xd6,0x9a,0x21,0x60,0xe8,0x26,0x37,0xb3,0x10,0x76,0x46,0x31,0x90,0xb0,0x9f,0x17,0xab,0x0f,0x93,0xcc,0x12,0x78,0xee,0x17,0x1c,0xd8,0xc7,0x76,0x0a,0x5a,0xb4,0x8b,0xb1,0x67,0x11,0xde,0x48,0x14,0x8a,0x2a,0xc7,0x71,0x46,0x94,0x15,0x29,0x44,0x9e,0x35,0x03,0x10,0xf7,0x51,0x8a,0xaa,0x9c,0x4a +.byte 0x9a,0x44,0xd5,0xc7,0x37,0x9d,0xb4,0xad,0x41,0xd0,0xda,0xd2,0x1a,0xf9,0x93,0xee,0x28,0x32,0x65,0x0b,0x9c,0x12,0xe3,0xad,0x9f,0x82,0xeb,0x3f,0x03,0xe7,0x6a,0x58,0x83,0x3f,0xbe,0x9f,0x27,0xd3,0xd6,0xe2,0x45,0xbf,0x90,0xe2,0x12,0x61,0x0b,0x57,0xd7,0x06,0x72,0x39,0x2c,0x3e,0x65,0xb2,0xf4,0xf7,0x54,0xef,0x32,0x99,0x44,0x0d +.byte 0xf0,0x5c,0xde,0x4c,0x2e,0x22,0xcd,0x3c,0x25,0x02,0xa5,0x0d,0x79,0x16,0xb0,0x51,0x3f,0x3c,0x84,0x56,0xfa,0x00,0xae,0x7a,0x36,0x45,0x3a,0xcc,0x1d,0x66,0xff,0xf4,0x49,0xce,0xb5,0x5c,0x51,0xf4,0x3e,0x07,0xf2,0x83,0x84,0x4d,0x4e,0xb7,0xce,0x03,0x7b,0x23,0x63,0xdf,0x64,0xa2,0x55,0x92,0xf9,0x2e,0xa5,0x21,0x89,0x29,0x42,0x48 +.byte 0x36,0xc5,0xab,0xd6,0x82,0xe3,0xff,0x45,0xfc,0x61,0xa6,0x4f,0xb9,0x51,0xba,0xd5,0x03,0xa9,0x0b,0xe7,0x73,0x83,0x97,0x1d,0xb2,0xc6,0x75,0xa0,0x52,0x99,0xfc,0x1b,0x27,0x7a,0x10,0xc1,0xed,0x70,0x21,0x4b,0x93,0xa4,0x20,0xed,0x16,0x76,0x97,0x82,0xab,0x21,0xfe,0xa4,0x3f,0xd9,0xbd,0x9c,0x2f,0x19,0x42,0xbc,0xb3,0x4f,0x44,0xf3 +.byte 0x9e,0xd0,0xe7,0xc9,0x7e,0x31,0xaa,0xbc,0x4b,0xba,0x73,0xe1,0xc3,0xbf,0x5d,0xa2,0xd8,0xb7,0xb6,0xfc,0x0a,0x32,0xb9,0xff,0x80,0xb6,0x2a,0x8b,0xea,0x81,0xa0,0xeb,0x1e,0x9e,0x69,0xdd,0xbe,0xc1,0x8a,0x5d,0xfb,0x66,0x21,0x98,0x5c,0x6f,0xd8,0xb4,0xcf,0x8a,0x1a,0x4b,0xde,0xa2,0x20,0xe8,0x5a,0x5a,0xee,0x14,0x09,0xcb,0x63,0x1c +.byte 0x14,0x7d,0x9b,0x47,0xf8,0xfa,0xda,0xb7,0x0e,0xc6,0xbd,0xb2,0x13,0xb8,0x10,0xe2,0x71,0x04,0x36,0x78,0x6d,0x3a,0x8b,0x45,0xd3,0x05,0xec,0x8a,0x2d,0xfa,0x85,0x7c,0xdd,0x75,0xb3,0x2d,0xd1,0xae,0xfc,0xdd,0x02,0x2e,0xcc,0x43,0xc5,0xed,0xe4,0x3f,0xee,0x2c,0xd7,0x37,0x81,0x3a,0x44,0xe6,0xed,0x8c,0x9d,0x9d,0xfa,0xb5,0xdc,0xde +.byte 0xb2,0x7c,0x51,0x58,0xa4,0x21,0xac,0xe2,0x79,0x96,0x90,0xe2,0x0b,0xbf,0x51,0x66,0x77,0x02,0xff,0x67,0x0a,0x70,0x1f,0x04,0x6c,0xb0,0x5b,0x2d,0x26,0x23,0x5a,0x85,0x73,0x66,0x6e,0x7c,0xb3,0xeb,0x36,0x73,0x0f,0xcd,0xb2,0x07,0xee,0x78,0xd1,0xbd,0x5e,0xfa,0x31,0xf6,0x82,0x67,0x94,0xaa,0xff,0xef,0xd2,0x23,0xfc,0x82,0xaa,0xe2 +.byte 0xef,0xc3,0x74,0x79,0x6c,0xe9,0x3f,0x8d,0xe1,0x1b,0xc8,0xb4,0xff,0x15,0xf4,0x60,0xe8,0x84,0x3f,0xaa,0xc6,0x53,0x51,0x1a,0x9b,0x04,0x9b,0xab,0xc5,0xee,0x9a,0x98,0x80,0x89,0x8d,0x5b,0xef,0x0a,0x69,0x71,0xd2,0xf3,0x49,0xc1,0xc1,0x87,0xb3,0x18,0x4b,0x82,0x02,0x87,0xb0,0xf1,0x76,0x4b,0x3e,0xad,0x95,0x51,0xb1,0x64,0xb1,0x03 +.byte 0x5b,0xd2,0x10,0x7b,0x4e,0xd4,0x08,0xf8,0xfd,0xea,0xf0,0xc7,0x16,0x43,0x86,0xa6,0xdb,0xcd,0x75,0xce,0xa9,0xfd,0xa8,0x7c,0x51,0xf7,0xa5,0x29,0x6f,0x0d,0xee,0x66,0x8f,0xc6,0xcd,0x9e,0x3f,0x00,0x24,0x21,0xca,0x69,0x79,0x27,0x03,0x62,0xdf,0xad,0xb9,0x8c,0xd8,0x08,0x88,0x0d,0x0c,0xa1,0x29,0xf9,0xba,0x92,0xb5,0xdd,0xb8,0x1a +.byte 0xbb,0xab,0x44,0xb2,0xda,0x1b,0x8b,0xc1,0x3c,0x61,0x9f,0x7a,0x8b,0x89,0x99,0x09,0xc3,0xb4,0xe4,0x24,0xf5,0x3b,0x36,0xa6,0x61,0x0a,0xec,0x2a,0x1c,0x92,0x7c,0xb1,0x7c,0xd8,0x0b,0x98,0x48,0x8d,0x52,0xa2,0x57,0xc1,0x28,0x89,0xbb,0x60,0x5c,0x58,0x62,0x41,0x1c,0xd6,0xfb,0x69,0x09,0x93,0x90,0x31,0xc4,0x72,0x71,0xf0,0x4f,0xcf +.byte 0x10,0xbb,0xb7,0x6c,0x3b,0x53,0xa3,0x0b,0xff,0x44,0x4c,0x37,0xd5,0x26,0x83,0x7e,0x5c,0xb9,0xa5,0xe8,0x8b,0xc4,0x15,0xf6,0xc7,0xd1,0x39,0x67,0x01,0xb7,0xca,0xa7,0x71,0xa8,0x04,0x95,0x0f,0xfc,0x0a,0x9e,0x52,0xb2,0xfb,0x48,0x47,0xb6,0xa5,0x14,0xc2,0x4f,0xa8,0xd5,0x0f,0x10,0x76,0x39,0x23,0x74,0x2e,0xe5,0x17,0xcb,0xad,0x8a +.byte 0x4a,0x25,0xc8,0x9b,0x25,0x94,0x34,0xbc,0x4b,0x2f,0xdc,0x0a,0xcd,0xc1,0x02,0x72,0x7d,0xa0,0x10,0xa7,0x32,0x68,0xe8,0xd5,0x23,0xe8,0xc9,0xbc,0x05,0x05,0x1e,0xac,0x55,0x45,0xfb,0x42,0x2f,0x0f,0x51,0x8d,0x31,0xb1,0xbc,0x10,0xa1,0x03,0xc3,0x6f,0x35,0x08,0xa5,0x2f,0x91,0x4e,0x43,0x6b,0x62,0x3b,0x00,0x4c,0xd0,0xb8,0x33,0xbc +.byte 0xca,0x57,0xb8,0x1b,0xb4,0x52,0x1a,0xa7,0x03,0x78,0xa0,0x4f,0xda,0x86,0xb9,0xd8,0xc6,0x69,0xe6,0x61,0x2e,0x62,0x96,0x60,0x0d,0x76,0xdc,0x5d,0x0e,0xa8,0xf3,0x86,0xde,0xcf,0x39,0x34,0xc7,0x69,0xed,0xcb,0x9a,0xf5,0xc3,0xce,0x6d,0xa5,0x7f,0xae,0x73,0xb9,0xa6,0xbf,0x88,0x93,0x2b,0x0e,0x8b,0x4b,0xa5,0xeb,0x62,0xc6,0x1a,0xc7 +.byte 0x63,0x63,0x58,0x62,0x37,0xc6,0xbc,0x00,0x72,0xac,0x3d,0x7c,0x22,0xa5,0x59,0xf1,0x6e,0x60,0x45,0x3e,0x99,0x76,0x40,0x82,0xa7,0x52,0xf3,0x48,0x8e,0x4a,0xa3,0xe1,0x3b,0xea,0x77,0xa7,0x7d,0x13,0xe7,0xc4,0xc6,0xa6,0x6e,0xda,0xe8,0x50,0xc8,0x39,0x30,0xab,0x8a,0xe1,0x08,0xa9,0xe3,0xbd,0x8d,0xbd,0x83,0x3c,0xbc,0x6c,0x92,0xed +.byte 0xf1,0xa9,0xd3,0x50,0xf2,0x29,0x8b,0x39,0x46,0xaf,0x08,0x7e,0x00,0x64,0x2f,0xa8,0x18,0xab,0x7e,0x07,0xd3,0x63,0x2a,0xd3,0xd3,0xbb,0xf9,0xdd,0x2b,0xec,0x70,0x35,0x1a,0x94,0x6b,0x87,0xe4,0x1a,0x0a,0x44,0x46,0x08,0xa6,0xce,0x1b,0xf7,0xd7,0x20,0x87,0x1a,0x96,0x6c,0xbe,0xdf,0x73,0x3b,0xc9,0xaf,0x89,0x1c,0x2f,0x47,0xe9,0xd8 +.byte 0x03,0xa6,0x03,0x6c,0x73,0xa9,0x65,0x20,0x36,0xea,0x6f,0xe7,0x96,0x7c,0x01,0x87,0xb0,0x21,0xba,0xb4,0xed,0x1f,0x81,0x65,0x97,0x36,0xda,0x68,0x80,0x64,0x99,0xe6,0xda,0x95,0x04,0xdf,0x5d,0xfd,0x86,0xd1,0xfd,0xfa,0x1c,0xd7,0x89,0xbf,0xe6,0x99,0x6c,0xf5,0x01,0x56,0x20,0x88,0x79,0xa7,0x8d,0x88,0x82,0xe5,0x32,0x38,0xe0,0xf0 +.byte 0x98,0x63,0xa9,0xab,0xeb,0x09,0x8d,0xaf,0x3f,0xa8,0x57,0x98,0xde,0xc8,0x9c,0x8d,0x1d,0x18,0xc5,0xa8,0x82,0x51,0x9b,0x6f,0xc6,0xb8,0x09,0xd3,0xea,0xd4,0xe3,0xac,0xd1,0x0e,0x88,0xda,0xdf,0x38,0x53,0x14,0x87,0x28,0x6f,0x13,0x35,0xdb,0xfe,0xa1,0xe7,0x43,0xb5,0x02,0x46,0x08,0x1a,0x31,0x0d,0x9e,0x3d,0x3b,0xbf,0xbb,0x82,0x9c +.byte 0x09,0xf3,0xd9,0x22,0x0a,0x82,0x07,0xd3,0xe8,0x19,0x6e,0x21,0xd2,0xa2,0xa8,0x14,0xbc,0x42,0xb6,0xeb,0x8c,0x40,0x9b,0xb2,0xa9,0x17,0xad,0x2c,0x19,0xaa,0x4b,0x22,0xf9,0x4e,0xde,0x8f,0xbe,0x78,0x9b,0xab,0xb9,0xfa,0xb1,0x3e,0x68,0x86,0x1a,0x4a,0x61,0xba,0x63,0x51,0x25,0x11,0x59,0xd0,0xb7,0x0c,0xb7,0xcc,0x45,0x05,0x6d,0x5a +.byte 0xe2,0xd7,0x10,0x80,0x19,0xd3,0xa9,0xab,0xb6,0x9f,0x53,0x7a,0xaa,0x19,0x74,0x01,0xc9,0xd6,0x45,0x42,0x2c,0xe5,0xc0,0xcf,0x62,0xe6,0x95,0x6f,0x4c,0x90,0x50,0x97,0x61,0x83,0x73,0xd0,0xc2,0xd5,0xf0,0x05,0xca,0xe9,0x6f,0x67,0xa9,0x51,0xb8,0xb4,0x9d,0x30,0x8e,0xe3,0x29,0xf9,0x3b,0x3d,0x17,0x25,0xad,0xbb,0xb0,0x34,0x68,0x29 +.byte 0x06,0xad,0x0e,0xdf,0x41,0xa6,0xf1,0xa6,0x25,0xc4,0xf0,0x0d,0x57,0x84,0x34,0x2c,0x3b,0xb1,0x41,0xd6,0x83,0x00,0x3a,0x91,0x98,0x8e,0xd0,0x59,0x0b,0x2d,0xc9,0x65,0x03,0x91,0xcb,0x03,0x97,0x57,0xde,0x11,0x8b,0x4b,0x1b,0x85,0x0b,0xb6,0x68,0x25,0x3c,0x1a,0x04,0x7d,0xd5,0x2b,0x16,0x69,0x1f,0x64,0x8b,0x47,0x60,0x17,0xaa,0x68 +.byte 0x45,0xf2,0x0b,0xf8,0xa2,0x27,0xf8,0x47,0x86,0x41,0x94,0x3f,0x92,0xc3,0x02,0xab,0x80,0x2b,0x0e,0x3c,0xd0,0x13,0x59,0x08,0xfc,0x13,0x33,0x52,0xbb,0x2d,0x6b,0x22,0xa2,0x8b,0x9f,0x7c,0x8e,0x40,0x35,0xa4,0xc7,0x45,0xb7,0xf8,0x10,0x22,0x95,0xc5,0x48,0xc1,0x50,0x4d,0x4a,0x36,0xe1,0xec,0x1e,0x07,0xf7,0x68,0x63,0xcb,0x13,0x03 +.byte 0x70,0x63,0xb1,0x9b,0xf3,0x60,0x01,0x6e,0x63,0x5c,0x4d,0x2c,0x5c,0x5c,0x58,0x8b,0xbb,0x6e,0xd1,0x69,0xdd,0x19,0xfe,0xfb,0xd6,0xdc,0x68,0x97,0x9c,0x46,0x0d,0xdd,0x4d,0xbd,0x52,0xe4,0xd9,0xc2,0x03,0x4e,0x4c,0xe2,0x66,0x6b,0x4d,0xbe,0x6b,0xf3,0xd6,0xbe,0x2d,0xba,0xdd,0x1b,0x4f,0x60,0x02,0x74,0xa1,0xf0,0xd0,0xfa,0x23,0x33 +.byte 0x29,0x7e,0x00,0x09,0x47,0x15,0xa8,0xd8,0xdb,0xb8,0xe1,0x20,0xd5,0xe2,0x91,0xd0,0xe8,0xfa,0xa1,0x0d,0x80,0xbd,0x7d,0x62,0x9d,0xf2,0xbc,0x03,0xa1,0x44,0x9f,0x8d,0x3d,0xe3,0xb4,0xec,0x32,0xd9,0x66,0xb0,0xc7,0x75,0x11,0xaa,0xab,0xb7,0x84,0x1d,0x5b,0x4f,0x25,0x5c,0x53,0xed,0xbb,0x6d,0x06,0x1f,0x12,0x5f,0xc0,0xeb,0x55,0x3e +.byte 0xd0,0x5b,0x4d,0x07,0xf7,0x84,0x12,0xbc,0xc8,0xd4,0xf4,0x69,0xdb,0x71,0x8a,0x00,0x58,0xf5,0x84,0xff,0xc3,0xbc,0x13,0x6e,0x5f,0xac,0xd6,0x72,0x1b,0x2d,0xbb,0x27,0xfd,0x8d,0xcc,0x59,0x79,0xb9,0x63,0xe8,0x0a,0xf3,0x7f,0xa4,0x9f,0x4c,0x35,0x9a,0xdc,0xff,0x11,0x42,0xf3,0x1c,0x86,0xd0,0x22,0x7e,0x81,0x79,0x04,0x93,0x5c,0xf2 +.byte 0xab,0xdf,0xb7,0x1d,0x84,0xbd,0xde,0xfb,0xd2,0x75,0x43,0xb8,0x19,0x63,0x97,0xfe,0x0e,0x91,0x9d,0x38,0x50,0xc5,0x7a,0xd6,0x51,0xd4,0xfc,0x8d,0xec,0xd5,0xe2,0x07,0xce,0x21,0x03,0x02,0xa1,0x61,0x8d,0xf1,0xf5,0x1f,0xb3,0xaf,0x9f,0x13,0xd8,0x81,0xd2,0xf7,0xe9,0xe2,0x62,0x49,0xca,0x1c,0x15,0x07,0x39,0xe6,0x01,0xec,0x6c,0x7d +.byte 0x3b,0xf1,0x52,0xda,0xf2,0x97,0x55,0xef,0x6f,0x88,0x82,0x0e,0xe6,0xf4,0x3e,0x33,0xf6,0x61,0x6d,0xef,0xbf,0xa8,0x9a,0x91,0x2f,0xb3,0xd2,0x3d,0xaa,0x7a,0x4e,0x80,0xe1,0x04,0xbe,0xc7,0xf8,0xc3,0xc9,0xd8,0xa2,0x01,0x5d,0x30,0xae,0x6d,0x39,0x52,0x60,0x9d,0x07,0xd5,0xa2,0x86,0xf0,0x88,0x00,0xec,0x18,0x11,0x2d,0x69,0x86,0xa9 +.byte 0x5a,0x73,0xda,0x4e,0x4c,0xdb,0xb8,0x02,0xad,0x53,0xec,0x20,0x0f,0x35,0xe0,0x4f,0x6e,0xd5,0x04,0xcc,0xa0,0xf5,0x8c,0x7d,0x31,0x04,0xa4,0xcf,0xf0,0x27,0xd2,0xb6,0x7d,0x8c,0x26,0x5f,0x19,0xba,0x79,0x80,0xec,0x6d,0xfe,0xaf,0xc1,0x3a,0xc2,0x3d,0x14,0x3c,0xa0,0xc5,0x77,0xf4,0x96,0x56,0x51,0x8b,0x7c,0x7e,0xe5,0x23,0x5d,0x46 +.byte 0x1b,0x2e,0x28,0xc0,0x80,0x6b,0x6a,0x85,0x6c,0xcf,0xaa,0x28,0xf3,0x83,0x2d,0x42,0x6f,0xf3,0x5e,0x5d,0xa2,0x7b,0xba,0x5c,0x12,0xb0,0xda,0xa0,0xeb,0xdf,0xad,0x1d,0x4c,0x54,0xcf,0xad,0x02,0x68,0xcd,0xfe,0x5c,0x5b,0x65,0x6d,0xa5,0xcc,0xd3,0xed,0x32,0x74,0x6c,0x58,0x83,0x3a,0xc1,0x71,0xbf,0xb5,0xa2,0xbd,0x10,0xe5,0x46,0xc5 +.byte 0x00,0x82,0xb1,0xeb,0x6f,0x73,0xf9,0x12,0x23,0xe4,0xda,0xff,0xa3,0xc4,0x9c,0xf1,0xcc,0x0e,0x1a,0x7a,0x10,0x62,0x8f,0xa5,0xb2,0x35,0x51,0x67,0xb5,0x95,0xbe,0x4c,0x81,0x53,0xfc,0xdd,0x27,0x26,0x97,0x42,0x01,0xec,0x08,0x91,0xb8,0xf0,0xaf,0x57,0x54,0x73,0x52,0x8f,0xde,0xca,0xed,0x1b,0xca,0x8d,0x97,0x1e,0xdc,0xe7,0xfa,0x68 +.byte 0xaf,0x37,0xb0,0x62,0xa3,0x9f,0xbc,0xac,0x9f,0x28,0x1e,0xb7,0xaa,0xb0,0x91,0xe4,0x95,0xad,0xf9,0xe5,0xd4,0xcc,0x23,0x0f,0x4a,0x2d,0xdd,0xea,0x64,0xd1,0x04,0x3c,0xd0,0xca,0xfe,0xd3,0x19,0x9d,0x28,0xa5,0x1c,0xff,0x3e,0xae,0xe9,0xfb,0x12,0x03,0x6d,0xcf,0xbc,0x5f,0x27,0xce,0x1a,0xb9,0xc0,0x31,0x88,0x6e,0x2e,0xaf,0x35,0x5f +.byte 0xf0,0xce,0x92,0xf8,0x6f,0xd6,0x67,0x1c,0xc6,0x5c,0xee,0x59,0xaa,0xd6,0x8c,0xa8,0x13,0xe6,0xf7,0xe2,0x82,0x2f,0x82,0x1e,0x4c,0x0d,0xab,0x3e,0xdb,0x4d,0xc5,0x90,0x32,0xe4,0xf0,0x74,0xc1,0x92,0x1b,0xdd,0xf3,0xa7,0xf6,0x6b,0x01,0x9d,0x8d,0x78,0x3d,0x5a,0x46,0x74,0x16,0x93,0x44,0xca,0xbe,0x31,0xea,0xb4,0x65,0xcd,0xe6,0xdd +.byte 0x56,0x9d,0x63,0x48,0xf0,0xf3,0x15,0x91,0x6c,0x27,0xf9,0xf7,0x3b,0x9f,0x04,0x6d,0x4d,0x1d,0xf1,0x7c,0xd1,0x81,0x06,0xef,0x04,0x47,0x98,0x5d,0x21,0xf4,0xe0,0xa0,0x13,0xaf,0x1d,0xb0,0xd5,0x45,0x64,0x92,0x46,0x99,0xff,0xb4,0xbf,0x36,0x01,0x2d,0x23,0x6a,0xc4,0x6b,0x3f,0x91,0x10,0x03,0xaf,0x6e,0x79,0x86,0xdb,0x15,0xde,0xfa +.byte 0x0d,0x71,0x04,0x16,0x12,0x31,0x9b,0x69,0xb9,0xe0,0xe7,0x4e,0xfd,0x0e,0xd5,0x71,0xa0,0xc7,0xd7,0x46,0xdb,0xda,0xbd,0xcd,0xdc,0x77,0xe5,0x71,0x9d,0xa1,0xf4,0x02,0x10,0xc6,0x27,0x76,0x4e,0xa6,0x35,0xe6,0x9e,0xda,0xbe,0xd8,0xc0,0x21,0x15,0xd4,0xcc,0xd5,0x4b,0xdf,0x38,0xc5,0x15,0x4b,0xfa,0x4e,0x83,0xf4,0x27,0xdb,0x8a,0xb1 +.byte 0x0e,0x1f,0xc9,0x3c,0x1c,0x36,0x35,0x54,0x8b,0x54,0xf8,0x31,0x1e,0x0e,0x1c,0x4e,0x44,0x29,0x90,0xad,0x28,0x85,0xb4,0x72,0x2d,0x1b,0x8b,0x26,0x2f,0xb6,0xc2,0x14,0x0e,0x81,0xd0,0x37,0x29,0x5c,0x0f,0xdc,0x21,0x62,0x10,0x7a,0xeb,0xa3,0x6e,0xd4,0x5b,0xb4,0x13,0x2e,0xd6,0x8f,0xd9,0x57,0x0d,0x9b,0xfd,0x1e,0x66,0xb7,0x6e,0xac +.byte 0x88,0xb9,0x75,0x60,0x62,0x83,0x72,0x96,0xc6,0x2e,0xdc,0xfe,0x88,0xee,0x07,0x9a,0x62,0x19,0xde,0xf1,0xa5,0xfb,0xcc,0xdb,0x4a,0xeb,0x16,0x60,0x34,0x46,0xfc,0xf2,0x6d,0xee,0xfc,0xa0,0x3a,0xb1,0x11,0x03,0x8b,0xae,0x26,0xef,0x86,0x91,0x20,0x7a,0x19,0x35,0xd6,0x12,0xfc,0x73,0x5a,0xb3,0x13,0xf8,0x65,0x04,0xec,0x35,0xee,0xf8 +.byte 0x70,0xb2,0x0b,0xe1,0xfc,0x16,0x35,0xec,0x6b,0xdd,0x8b,0xdc,0x0d,0xe8,0x91,0xcf,0x18,0xff,0x44,0x1d,0xd9,0x29,0xae,0x33,0x83,0xfe,0x8d,0xe6,0x70,0xbb,0x77,0x48,0xaa,0xe6,0xbc,0x51,0xa7,0x25,0x01,0xcf,0x88,0xc4,0x8b,0xfc,0xb1,0x71,0x01,0xc7,0xfc,0xd6,0x96,0x63,0xee,0x2d,0x04,0x1d,0x80,0x24,0xd0,0x80,0x03,0xd9,0x18,0x96 +.byte 0xec,0x6a,0x98,0xed,0x6e,0x9a,0xe0,0x42,0x5a,0x9d,0xec,0xed,0x46,0x3c,0xb5,0xf0,0xd6,0x88,0x92,0x89,0x38,0x5f,0xd6,0xba,0xfd,0x32,0x31,0x81,0xe9,0xf1,0x56,0x89,0xa3,0x56,0xa6,0x03,0x00,0x60,0xe1,0xa8,0x59,0xdb,0xbe,0x72,0x39,0x6c,0x08,0x4d,0x26,0x57,0xa6,0xf6,0x13,0x7d,0x4a,0x2f,0x64,0xb8,0xa7,0x23,0x2c,0xa4,0x4a,0xad +.byte 0xcf,0xa1,0xa2,0x32,0xbb,0xd1,0x98,0x02,0xe4,0x1a,0x41,0x26,0x23,0xba,0xa2,0x17,0x62,0xaa,0xa6,0xc7,0x74,0x9d,0xea,0xc7,0xa0,0x08,0x0a,0x1a,0x4e,0x71,0xd9,0x45,0xf7,0xe8,0x57,0x79,0x12,0xd0,0x38,0x2f,0xdb,0xbd,0x5a,0x84,0xe1,0xb2,0x62,0x7e,0x56,0xb3,0x50,0x2a,0xa0,0x32,0x1f,0x86,0x71,0xc4,0xa5,0xba,0x93,0x5b,0x22,0x97 +.byte 0xf4,0xe5,0x44,0x27,0x6b,0x06,0x84,0x55,0x19,0x45,0x12,0x75,0x4b,0xf0,0x76,0x6d,0x3c,0x0a,0x17,0xc2,0x9d,0x96,0x72,0xe7,0x5e,0x79,0x84,0x0a,0x39,0x64,0x09,0x6e,0x7e,0xd7,0x77,0x40,0x75,0x2c,0xbd,0x98,0xae,0x3e,0x34,0x08,0x4d,0xda,0x2c,0xcf,0x0c,0xa2,0x8c,0x40,0xfa,0x34,0x43,0x15,0xed,0x4f,0x69,0xa6,0xef,0x2d,0x3c,0x55 +.byte 0x7a,0xe1,0x67,0xd1,0x0a,0x89,0xe0,0x2d,0x02,0x35,0x57,0xc8,0x9a,0x4b,0xc4,0x46,0xa7,0x57,0x03,0x89,0x7d,0x3f,0x70,0x47,0x03,0x06,0xd9,0x81,0x1f,0x8d,0x7e,0x36,0x9b,0xfd,0xad,0x20,0x9d,0x5a,0x29,0xe9,0x40,0x6a,0xb8,0x07,0x6b,0xc7,0x2b,0x58,0xd2,0x1d,0xef,0x88,0xa5,0xfb,0x3b,0xd6,0x9f,0xfd,0x89,0x0e,0x50,0xd4,0xbc,0x89 +.byte 0x3f,0x3c,0x6c,0x50,0xc6,0xe3,0x8b,0x7e,0x34,0x8b,0x26,0x99,0x2a,0xfa,0xa5,0x19,0x53,0xb5,0x5e,0xfd,0x94,0xe8,0x33,0xb2,0x6d,0x9c,0x3c,0x0c,0x14,0x90,0xc4,0xa2,0x4a,0x3a,0xca,0x07,0x72,0x46,0x37,0xfc,0x02,0x5d,0xf4,0x97,0xca,0x8e,0xc6,0xc4,0x63,0xda,0x5c,0x89,0xc3,0x6c,0xb1,0x1a,0xf5,0x2a,0xbc,0x2e,0xe3,0xcd,0x2f,0xe2 +.byte 0x91,0x16,0xf9,0x94,0x0e,0x1b,0xe6,0x01,0x73,0x61,0x1e,0xcf,0x5e,0x21,0x70,0xcb,0x5b,0x87,0xc1,0x46,0x39,0x59,0xa6,0x74,0x82,0x7f,0xa2,0x6c,0x4a,0x50,0x5f,0xbd,0x1c,0x1a,0x65,0x80,0x01,0x44,0x19,0xcf,0xcd,0xef,0x3d,0x5e,0x1b,0x71,0x82,0x4f,0x8b,0xc1,0xa0,0x9a,0x77,0xee,0xac,0x06,0xdc,0x6a,0xa0,0x34,0x50,0xa4,0xe0,0xda +.byte 0x3d,0xa0,0xf7,0x9a,0xb8,0xd5,0x59,0xe0,0x7f,0x05,0x04,0xd5,0x32,0x8c,0x49,0xf5,0x0a,0x0e,0x99,0x83,0xf5,0x47,0x2b,0x7c,0x7b,0x65,0x25,0x02,0xc4,0x88,0xbb,0x6a,0x4f,0x89,0x31,0x60,0xc2,0x47,0x8b,0x22,0xfc,0x4a,0xde,0xb3,0xb9,0xed,0xb8,0xdf,0xd7,0xd5,0x09,0x98,0xcc,0x5f,0xaf,0xbb,0x02,0xc3,0x62,0x62,0xee,0x99,0x42,0x1b +.byte 0xbe,0x5b,0xa8,0x5c,0x40,0x03,0x86,0x29,0x29,0x06,0x0b,0x53,0x46,0x29,0x03,0x3b,0x11,0x64,0xf1,0x09,0xca,0x69,0x69,0xfa,0xcc,0x85,0x23,0x14,0x1b,0xfd,0x65,0xb9,0xf5,0x6b,0xbb,0x2a,0x9d,0x6e,0x64,0x1a,0xe1,0x37,0x39,0xd4,0x85,0x40,0xa3,0xf9,0x04,0xec,0x9e,0x3b,0x74,0x97,0xa4,0x64,0x8a,0x48,0xb2,0x62,0xc1,0x1c,0xed,0x67 +.byte 0x6f,0x23,0xae,0x0f,0x64,0x2e,0xe5,0x92,0xb6,0xb5,0x71,0x24,0xc0,0x60,0x9a,0x10,0x23,0x6b,0x4a,0x22,0xe9,0x0a,0xaa,0x09,0x62,0x39,0xe0,0x40,0xee,0x13,0x27,0x14,0x73,0xeb,0x75,0x7b,0x4a,0xe1,0x42,0x65,0x37,0xae,0x80,0x08,0x26,0xf9,0x53,0x98,0x58,0xdd,0xf5,0xed,0x26,0x37,0x37,0x85,0xb5,0x88,0x91,0x05,0x2d,0x04,0xa6,0xd5 +.byte 0xa6,0x98,0xb0,0x0e,0x4b,0x4c,0x53,0x76,0x79,0xad,0x82,0xc5,0x16,0xba,0xd8,0x20,0x5f,0x4c,0x1d,0x69,0xa0,0xe0,0xe9,0xbc,0xb8,0x5c,0x10,0x4a,0x0a,0xd3,0x52,0x9c,0x2e,0x1b,0x6c,0xf7,0x43,0x83,0x6f,0xa9,0xcc,0x00,0xed,0x16,0x4c,0xc3,0x24,0x79,0x59,0x68,0xfb,0xf9,0xf6,0xb0,0xb4,0x01,0xc2,0xdd,0xf7,0xe5,0x3b,0x60,0x48,0x49 +.byte 0x32,0x48,0x05,0xa8,0x62,0xa3,0x03,0x9f,0x3d,0x91,0xdb,0x84,0x64,0x6f,0x1e,0x50,0x8e,0xdf,0x1a,0xa0,0xb1,0xf4,0x34,0x7c,0xe6,0xb7,0x7c,0x14,0xa1,0x65,0x1a,0xb4,0xdb,0x67,0x78,0xb1,0x88,0x3c,0xc2,0x5e,0x0e,0xea,0x32,0x15,0xc7,0xda,0xe4,0x9a,0x44,0xde,0x61,0x90,0x3b,0x97,0x11,0x5b,0x6d,0xa5,0x9a,0x2f,0x1b,0x8b,0xd7,0xdd +.byte 0x73,0xe4,0xc3,0x19,0x5d,0x68,0xcf,0x0e,0xe4,0x69,0xa5,0xeb,0x50,0x6f,0x79,0xff,0x91,0xc6,0x95,0x83,0xe8,0x72,0x6a,0x01,0x49,0x2b,0xcf,0x8f,0x93,0x1e,0xef,0x31,0x17,0x8f,0xa8,0x2b,0x5f,0x4b,0x79,0x8b,0xe5,0x6c,0xb7,0x61,0xd5,0x9e,0xe0,0xd4,0x25,0xc3,0x93,0x31,0x8f,0x66,0x6c,0x48,0x30,0x65,0xf4,0xd7,0xde,0x64,0xee,0xbd +.byte 0xbd,0xad,0x32,0xfc,0xf3,0xd8,0x7c,0x85,0x7c,0x24,0x40,0xb6,0xd4,0xe0,0x4b,0xc0,0xab,0xcc,0xeb,0x77,0x7c,0xb7,0x33,0x3c,0x90,0x04,0xaf,0x85,0xaa,0xb4,0xaa,0x90,0x67,0x29,0xd9,0x85,0x6a,0x34,0xf4,0xc4,0x6c,0xbc,0xb4,0x86,0x54,0x83,0xd5,0x5e,0xf3,0xdd,0x1a,0x56,0x5e,0xa5,0xd8,0x06,0xc0,0xa7,0x27,0xd4,0x0d,0x5b,0x08,0xf4 +.byte 0xb4,0x15,0xf9,0xb4,0x56,0x1c,0x80,0x98,0xc9,0xcd,0xf0,0x38,0x18,0xbe,0x99,0xec,0x7e,0x0c,0x3d,0xc1,0x98,0x26,0x9d,0x50,0xe4,0x00,0xcf,0x0f,0x0b,0x77,0x86,0x31,0x55,0x38,0xa4,0x31,0x50,0x51,0x64,0x88,0x81,0x05,0x32,0x99,0x38,0xd1,0x62,0x20,0x8e,0xf0,0x29,0x31,0xf5,0x79,0xbb,0x1e,0x0f,0xba,0x51,0x94,0xa9,0x54,0xcd,0x43 +.byte 0xce,0xe5,0x2c,0x29,0xa5,0x51,0x23,0x97,0x5d,0x36,0xff,0x51,0x5c,0x66,0xb7,0x62,0x1b,0x5f,0xd7,0x2f,0x19,0x07,0xff,0x0a,0xfc,0xf6,0x6e,0xb5,0xfd,0xa9,0x92,0x40,0xd3,0xe6,0x99,0x15,0x6f,0x1e,0x91,0xad,0x1f,0x4d,0x1c,0xe2,0xd9,0xcf,0x01,0x71,0xec,0x1a,0xa3,0xba,0x48,0x40,0xfd,0x18,0xb1,0x24,0x2b,0xd2,0x37,0xb5,0x74,0xdd +.byte 0x7e,0xf6,0x18,0xb4,0x7b,0x0e,0x7d,0x65,0x46,0x7b,0xe3,0x51,0x03,0xae,0xe1,0xd0,0x74,0xc6,0xc9,0xda,0x0e,0x79,0x6f,0xf5,0x62,0xc0,0x7e,0x76,0x3e,0x13,0x8b,0xe0,0x4c,0xfa,0x7e,0xe1,0xa2,0xee,0x9d,0x3f,0x91,0x9d,0x21,0xdd,0xc2,0xd0,0xa5,0x1d,0x17,0xd6,0xdc,0xeb,0xa3,0xc0,0x71,0xa0,0xfe,0xf0,0xaf,0x31,0xdc,0xa3,0xd4,0x21 +.byte 0x4a,0x32,0x1d,0x54,0x25,0x3b,0xc8,0x8f,0x68,0xcd,0x99,0xce,0x76,0x39,0x42,0xd8,0xca,0xf2,0x46,0x72,0xfe,0x52,0xc2,0x90,0x83,0xed,0xa0,0x6d,0x1b,0xf5,0xb1,0x09,0xae,0x2b,0x34,0x4f,0xd3,0x78,0x19,0x7f,0xad,0x8d,0x50,0x26,0x9c,0x36,0xa3,0xb5,0x3d,0x0b,0xa6,0x87,0x65,0xa0,0xdb,0x88,0x20,0xff,0xb6,0xfd,0xc5,0xbd,0x0a,0x28 +.byte 0xc8,0x9c,0x42,0x7f,0x24,0x58,0xe9,0x07,0x53,0x4b,0x9a,0x2a,0x1e,0x7b,0x90,0x97,0x78,0x74,0x80,0x5d,0xe5,0x6e,0xae,0x15,0x68,0xd4,0x2a,0x3a,0xd3,0x00,0x4f,0x4b,0xff,0x8f,0x1e,0x8f,0x9f,0x75,0xe5,0xea,0x9d,0xb9,0xed,0x8f,0xa9,0x2b,0x70,0xa8,0xcb,0x08,0x85,0xd3,0x8f,0x5d,0xc7,0x49,0x66,0xcc,0xa8,0x6d,0xbd,0x01,0x93,0xd5 +.byte 0xe6,0x75,0x2e,0x25,0x07,0x59,0x86,0x3f,0x44,0x8b,0x0b,0xb5,0x38,0xd5,0xbd,0xcf,0x48,0x8a,0xf7,0x71,0xd6,0x6b,0x2e,0x93,0x3d,0x0b,0xc0,0x75,0xee,0xa8,0x5d,0x9c,0x3d,0xa5,0xdb,0xc5,0x8d,0xac,0xda,0xf4,0xcd,0x5f,0x24,0xfe,0x86,0x14,0x44,0x65,0x3f,0x89,0x7f,0xd3,0x61,0x48,0xb0,0x43,0xf0,0x1e,0xde,0xbc,0xb7,0x51,0x0f,0xfc +.byte 0x32,0xf2,0x04,0xe2,0x4b,0xcb,0xbb,0x63,0x7d,0x5b,0x9a,0xb1,0x91,0x57,0x89,0xdc,0xed,0xde,0x91,0x2d,0xdd,0x42,0xc8,0x3c,0xb0,0xd7,0xa5,0xbc,0xa7,0x33,0x14,0x32,0xaf,0xf7,0xe9,0x25,0xd2,0x1a,0x64,0xf7,0x1b,0xab,0x0e,0xbc,0x50,0xbc,0x85,0x44,0xe0,0xa6,0xf1,0x4a,0x32,0x2f,0x30,0x27,0x48,0x4f,0xfc,0x8a,0x5a,0x78,0xe7,0x16 +.byte 0x55,0xcf,0xca,0x15,0xa8,0xa8,0xa2,0xef,0x9a,0x16,0x02,0xf4,0xb0,0x44,0xfd,0xc4,0x51,0x01,0x4f,0x1d,0x9d,0x09,0x62,0x42,0xe9,0x8b,0x18,0xa4,0x65,0xef,0x8b,0xfe,0x71,0x9f,0x4b,0x47,0x48,0x41,0x73,0x5c,0x0c,0x52,0x7d,0x79,0xbc,0x93,0x2a,0xaa,0x81,0x99,0x21,0xa5,0x9e,0xac,0xcd,0x57,0x51,0x50,0xbc,0xc9,0x96,0xaf,0xdf,0x1a +.byte 0x8f,0xee,0x36,0x05,0x20,0x32,0xe8,0x51,0x94,0x72,0x12,0xa3,0x17,0x25,0x7f,0x0a,0x3e,0xcc,0x22,0xcf,0x05,0xb2,0x2b,0xaa,0x36,0x01,0xdf,0xd4,0x4e,0xe1,0x02,0x43,0x4e,0xac,0x50,0x64,0xcd,0x2f,0xc2,0xa9,0xb0,0xf2,0xf2,0x4c,0xdf,0x16,0xa6,0x54,0xf7,0xbf,0x1a,0x69,0xeb,0xa1,0x5a,0xc7,0xcf,0x46,0x2d,0xc2,0x3a,0x7f,0x4a,0x14 +.byte 0x22,0x15,0x46,0x46,0x2d,0xc1,0x98,0xf7,0x0b,0xf3,0x27,0xfc,0x78,0x67,0x05,0xd8,0xe0,0xf6,0xb8,0xb6,0x0b,0xdb,0x4d,0x6b,0x7e,0x9b,0xbf,0x5c,0x15,0x97,0x49,0x9f,0x6f,0x11,0x6c,0x6e,0x1d,0x1e,0x65,0x5b,0xb9,0x60,0x8f,0xa3,0xa9,0x99,0x17,0x92,0xb8,0x65,0x25,0xc4,0xef,0xea,0xa6,0xc0,0x57,0xa9,0x4c,0x78,0xe3,0xd6,0xf2,0x19 +.byte 0x9c,0x86,0x9e,0x45,0x3e,0xfd,0x21,0x4c,0x2a,0x56,0x7c,0x23,0xf2,0x22,0xa1,0x81,0xdb,0xe6,0xfa,0x85,0x19,0x3b,0x1d,0x61,0xb3,0x21,0xb5,0x64,0x1d,0x07,0x66,0xd2,0xe5,0x9c,0xb0,0x76,0x9d,0xc9,0x02,0x6a,0x8d,0xd5,0x84,0xd5,0xa7,0x7c,0x70,0x64,0x46,0xd6,0xff,0xc7,0x9f,0x2f,0xed,0xc1,0x5a,0xcb,0x56,0x12,0x31,0x9d,0xff,0x66 +.byte 0x9a,0xf8,0x50,0xc6,0x54,0xfd,0x8d,0x49,0x32,0x8c,0xdd,0x8c,0xbe,0x30,0x79,0xaf,0x1a,0xd5,0x28,0x1d,0x03,0x87,0x12,0x60,0x7a,0xcc,0xe6,0xe8,0x4e,0x21,0x5d,0xa3,0x06,0xfb,0xdf,0xf6,0x31,0xd6,0x10,0x3e,0xec,0x23,0x69,0xc7,0x7b,0xf6,0x78,0xa6,0xd1,0x8a,0x48,0xd9,0xdc,0x35,0x1f,0xd4,0xd5,0xf2,0xe1,0xa2,0x13,0x8a,0xec,0x12 +.byte 0xa7,0xf1,0x5d,0xb2,0xc3,0x6b,0x72,0xd4,0xea,0x4f,0x21,0xff,0x68,0x51,0x51,0xd9,0xd7,0x2f,0x28,0xd7,0xdf,0xbc,0x35,0x4f,0x49,0x7e,0xe7,0x21,0x82,0xd7,0x0c,0x7c,0xf4,0x86,0x86,0x62,0xcd,0xf5,0x23,0x77,0xc1,0x14,0x8a,0xc4,0x2a,0x82,0x74,0x0e,0x90,0x93,0xd5,0x5a,0xc0,0x57,0x93,0x1a,0xe1,0x1c,0x13,0x17,0x72,0xc3,0xa6,0x54 +.byte 0xc4,0xe2,0xfc,0xd3,0xa0,0xce,0x08,0x87,0x9e,0x2a,0xaf,0xa7,0xbb,0x2d,0xaf,0xc0,0x38,0x97,0xc8,0x6d,0xb8,0x7b,0x75,0xc5,0xf2,0x79,0x62,0xdc,0x7c,0xa9,0xfd,0x19,0xa2,0xb1,0xee,0xdf,0x90,0x18,0x5a,0xdb,0x3c,0xba,0x0d,0x84,0xd6,0xaf,0x15,0xee,0xb6,0xa5,0x78,0x38,0x87,0xdf,0x42,0xd6,0xd1,0xa2,0xe9,0xe0,0xa6,0xf2,0x4e,0xa4 +.byte 0xed,0xa5,0xf6,0x66,0x7f,0x99,0xbc,0xfb,0x4b,0x37,0xca,0x5a,0xb3,0x29,0x8e,0x80,0x30,0x8b,0x74,0x7b,0xac,0x61,0xfb,0xca,0x62,0xfe,0x24,0xc4,0x6e,0xac,0x66,0x97,0xaa,0x9a,0x99,0xe6,0xa8,0xa4,0xd8,0x62,0x58,0x7c,0xd1,0xeb,0xee,0xc8,0x08,0xa0,0x54,0xde,0xb1,0xef,0x57,0x2c,0xb6,0x2c,0x78,0x22,0x10,0xbb,0xfe,0x4b,0x77,0xa5 +.byte 0x5a,0xed,0xbb,0xf8,0x97,0x96,0x20,0xa9,0x8c,0x78,0xb5,0xb9,0x55,0xc9,0xaf,0xb9,0xa1,0x1f,0x13,0x52,0xf9,0xbb,0xaa,0x98,0x01,0x57,0xa6,0x88,0xaa,0x5c,0xf0,0x62,0x5b,0x3e,0xe1,0x5f,0xf4,0x98,0x95,0x8b,0x8f,0x48,0xd6,0xd5,0x8b,0xc2,0x1d,0x45,0x7d,0xe2,0x03,0x66,0x84,0xfc,0xbd,0x8e,0x95,0x9f,0x58,0x99,0x7b,0x4c,0xb6,0xe5 +.byte 0xe2,0xf9,0x2e,0x92,0x58,0xca,0xa9,0x24,0x9c,0x7c,0x46,0xdf,0xea,0xb4,0x6e,0x0e,0xa5,0x9c,0x14,0xbf,0x25,0x5b,0x39,0x4a,0xaf,0x31,0xaa,0xd1,0x2c,0xe6,0x06,0x3d,0xc4,0x60,0xc7,0xcd,0x49,0x8d,0xe1,0x50,0x55,0xe4,0x72,0x68,0xed,0x43,0xb8,0x85,0xa3,0xc3,0xf1,0xf5,0xd1,0xcf,0xcb,0x57,0xac,0x04,0x16,0x22,0xe4,0xfc,0x4a,0x13 +.byte 0x60,0x3f,0x09,0xa4,0xf2,0x9b,0x34,0xeb,0x0c,0x10,0x57,0xc3,0x3f,0x15,0xb5,0x1b,0x6a,0xb3,0x7d,0x37,0x02,0x4c,0x0f,0x6f,0x8b,0x4d,0x5d,0x57,0x7d,0xbf,0x00,0x8a,0x74,0xb4,0x4c,0x5f,0x90,0x27,0x76,0x09,0x8c,0x18,0x3f,0x26,0x3a,0x09,0x06,0xdd,0x8b,0xff,0x0e,0xa4,0xae,0xef,0x0c,0x81,0xf2,0xf3,0x1f,0xe0,0x33,0x33,0x37,0xc6 +.byte 0xc3,0xfb,0x14,0xdd,0xa1,0x16,0x84,0x80,0xcb,0x37,0xe7,0x97,0x6d,0x21,0xa7,0x71,0x19,0x2b,0x2d,0x30,0xf5,0x89,0x2d,0x23,0x98,0xfc,0x60,0x64,0x4a,0x26,0x65,0x4a,0xef,0x12,0x59,0xa3,0x8c,0xd9,0xbd,0xdc,0xb7,0x67,0xc9,0x8d,0x51,0x72,0x56,0x6a,0xe5,0x59,0xa2,0x53,0x4f,0xb6,0x53,0xff,0xb0,0xd4,0x06,0x7f,0x79,0x23,0xf9,0xcb +.byte 0xbf,0x9a,0x93,0xde,0x88,0x33,0x58,0x70,0xa7,0xcc,0x07,0xb1,0x44,0xb9,0x99,0x1f,0x0d,0xb9,0xc9,0x18,0xdc,0x3e,0x50,0x22,0xfb,0x4e,0x86,0x0d,0xc0,0xe7,0x7f,0xc6,0xa1,0x52,0x0d,0x8d,0x37,0xe6,0xaf,0xe3,0x13,0xbe,0xa6,0xf9,0x59,0x39,0x0f,0x17,0x66,0xce,0xb1,0x7d,0x7f,0x19,0x1a,0xf8,0x30,0x3a,0xa5,0x72,0x33,0xa4,0x03,0xb6 +.byte 0xb6,0x9b,0xde,0x7a,0x7a,0x62,0x3d,0x85,0x98,0x8e,0x5d,0x8a,0xca,0x03,0xc8,0x2c,0xae,0xf0,0xf7,0x43,0x3f,0x53,0xb2,0xbb,0x1d,0xd0,0xd4,0xa7,0xa9,0x48,0xfa,0x46,0x5e,0x44,0x35,0x50,0x55,0xdc,0xd5,0x30,0xf9,0x94,0xe6,0x5f,0x4a,0x72,0xc2,0x77,0x59,0x68,0x93,0x49,0xb8,0xba,0xb4,0x67,0xd8,0x27,0xda,0x6a,0x97,0x8b,0x37,0x7e +.byte 0xe9,0x59,0x89,0xc7,0x5e,0xd9,0x32,0xe2,0xaa,0xd1,0xe9,0x2b,0x23,0xca,0x9d,0x89,0x7a,0xf5,0xe4,0xfb,0x29,0xcc,0x88,0xfb,0x82,0x0f,0xbf,0x47,0x54,0xca,0x2b,0x4b,0xd8,0x47,0x7f,0x65,0x38,0x5a,0xb3,0xe8,0x0b,0xd7,0xe1,0x8b,0x89,0x57,0x32,0xdb,0xa3,0x85,0xba,0xf9,0xbc,0x52,0x92,0x20,0x10,0x66,0x54,0x81,0xe1,0x49,0x3f,0xe1 +.byte 0x8c,0x2e,0x0b,0x3b,0xe7,0x49,0xb4,0x60,0x5a,0x20,0x33,0xc4,0x4e,0x81,0xef,0x96,0xda,0x73,0x90,0x2b,0xb4,0x86,0xa1,0x5c,0xcd,0xa0,0xc7,0xf3,0x06,0x0d,0x2a,0x5a,0x41,0x96,0xf5,0x40,0x1b,0x0a,0x3a,0xb7,0x38,0xe1,0xbb,0xe3,0x42,0xf9,0x52,0xe5,0x98,0xe2,0x17,0xd4,0xb0,0x09,0x73,0x75,0xc1,0x00,0x18,0x0f,0xa7,0x0b,0x58,0xc1 +.byte 0x78,0x5c,0x0c,0x05,0xd8,0xfb,0xc5,0xfd,0x5c,0x66,0xbe,0x54,0x68,0xd1,0x16,0x54,0xfb,0xc5,0x97,0xd7,0x03,0x82,0x47,0xbb,0x47,0xea,0x9e,0x8b,0x90,0x07,0xb2,0xd2,0x06,0x14,0x79,0xeb,0xb6,0xe1,0x10,0x55,0xa9,0x13,0xea,0x65,0x7a,0xd0,0xe5,0x66,0x5d,0xe7,0x7b,0x10,0x5f,0x7c,0x25,0x7d,0x4e,0x77,0xb3,0x19,0x02,0xb1,0x45,0x1c +.byte 0x1a,0x51,0x24,0x72,0xd4,0xaa,0x03,0x0c,0x37,0x2a,0x78,0x81,0x05,0xca,0x73,0xb9,0xb5,0xd8,0xf5,0x25,0x2b,0x30,0x59,0x00,0x66,0xbd,0x6c,0x38,0xa2,0xc3,0xfb,0x43,0x85,0x6d,0xab,0xca,0xd8,0x73,0xa8,0x76,0xda,0x6e,0x00,0x19,0xd0,0xb9,0x1e,0x9b,0x33,0xe4,0x57,0x68,0xf4,0xb8,0x35,0x44,0xe6,0x74,0xd2,0x33,0x64,0xa1,0x41,0xa6 +.byte 0x5a,0xf6,0x8e,0x29,0xb5,0xa6,0x21,0x8e,0xc4,0x0c,0x0c,0x16,0x81,0x08,0xef,0x0a,0x41,0x08,0x34,0xc7,0xe1,0xd8,0xa8,0x68,0xb1,0xf3,0x9a,0x7a,0xaa,0x90,0xc0,0x77,0x32,0x70,0x50,0x5c,0x92,0xfc,0x38,0x31,0xaf,0x3e,0xd8,0xd8,0x4b,0x90,0x99,0xc4,0x17,0xde,0xa6,0xb5,0x29,0xc0,0x82,0x45,0x20,0x08,0x0c,0x4f,0x76,0x36,0x56,0x7e +.byte 0x07,0x17,0x42,0x78,0xa1,0x2d,0x62,0x48,0x81,0x57,0xc4,0xcf,0xf4,0x89,0x34,0x78,0x10,0xe6,0x98,0x78,0xb0,0x69,0x15,0x06,0xdb,0x2b,0xbb,0x8b,0xa5,0x72,0x50,0x24,0xae,0x6b,0x33,0x49,0x7b,0x9d,0x69,0x74,0xc8,0x7c,0xca,0x7a,0x31,0x39,0x0d,0x72,0x78,0xc1,0x6b,0x97,0x50,0x97,0xea,0x90,0xab,0xe7,0xdf,0x29,0x2e,0xf7,0x6e,0x49 +.byte 0x95,0xab,0xbd,0xea,0x1f,0xd4,0x93,0x4d,0x30,0x6b,0x6d,0xb0,0x86,0x38,0x2c,0xc8,0x77,0x2c,0xb5,0xb5,0x5c,0xd9,0xbb,0xe9,0x7d,0xb2,0xb7,0x6b,0xd1,0x1c,0xd3,0xd0,0x66,0x51,0x63,0x8c,0xf3,0x13,0xad,0xcf,0xeb,0x82,0x12,0x1a,0x6d,0xf5,0x75,0x66,0xa2,0x55,0x30,0x64,0x1d,0x68,0x46,0x50,0x5a,0x93,0xf1,0xc2,0x13,0x68,0x95,0x55 +.byte 0x51,0xe0,0x56,0x3a,0x96,0x86,0x8e,0xfb,0x5f,0x3b,0x1f,0x49,0x9c,0x3d,0xe5,0xf2,0x8c,0x3f,0xd6,0x6d,0x17,0xc7,0x18,0x59,0x1a,0x8a,0x72,0xa8,0xb3,0x39,0xda,0xc4,0xfa,0xc5,0xca,0xdf,0x48,0x48,0xd1,0xd2,0xba,0x14,0x5d,0x28,0x3b,0x4c,0xb3,0xcb,0x8d,0x1b,0x91,0x46,0x6b,0x2d,0x21,0x21,0x99,0x98,0x6d,0xcc,0x6b,0x8e,0x91,0x1d +.byte 0x42,0xc2,0x72,0x1a,0xc6,0xd2,0xaf,0xed,0x10,0xff,0x1e,0xa5,0xae,0x16,0xc0,0x05,0xdf,0x37,0xe2,0x1e,0x2e,0x15,0x21,0x0c,0x33,0x6f,0xfd,0xed,0x3f,0x7e,0xd7,0x69,0xfb,0x76,0x79,0x65,0xe9,0xd9,0x8d,0xf6,0xc0,0x6c,0xf7,0x15,0x7f,0x04,0xd7,0x71,0xcc,0xaa,0x85,0x73,0x23,0xf1,0xc8,0x62,0xd0,0x8e,0x01,0x35,0xff,0x4f,0x4f,0x13 +.byte 0xe6,0x28,0xf1,0xc1,0x7a,0x04,0xc0,0x7b,0x75,0xac,0x1c,0x55,0xb4,0x7c,0x00,0xb9,0xe0,0x14,0x67,0xb6,0xc5,0x69,0x62,0x0b,0xe6,0xb5,0x46,0x86,0x6f,0x09,0xdf,0x84,0x2c,0xa8,0x30,0x89,0x5b,0x24,0x47,0xfa,0x43,0x24,0xd5,0x07,0xf7,0xba,0xab,0x1b,0xfd,0x60,0xad,0x89,0x5f,0x60,0x87,0x78,0x48,0xbb,0xc0,0x63,0xf4,0x27,0x86,0x33 +.byte 0xf4,0x49,0x64,0x4c,0x5c,0x94,0x9a,0xb8,0x0f,0x45,0xe2,0x92,0x7d,0x9a,0x86,0xdb,0xb7,0x05,0xe8,0xd7,0x64,0x44,0xfa,0x74,0x60,0x72,0x89,0x13,0x8f,0x2e,0x96,0x33,0xa9,0x12,0x4a,0x62,0x6b,0xc3,0xcb,0x55,0xd3,0xef,0x17,0x11,0x82,0x4a,0x51,0x77,0xbf,0x63,0xa0,0x21,0xfc,0xbc,0x0c,0x6f,0x9a,0xfd,0xde,0xbe,0x9f,0x2e,0x50,0xd5 +.byte 0x32,0xa4,0xf0,0x1b,0xed,0xfa,0xbf,0xcd,0xc9,0xd8,0xf8,0x06,0xf2,0x17,0x8a,0x92,0x18,0xb8,0xc3,0xe5,0xbf,0xc2,0xf4,0x77,0xb9,0x71,0xfb,0x60,0x6e,0xe7,0xad,0xe4,0x7d,0xd4,0x59,0xa9,0xbd,0x21,0xd5,0x03,0x69,0xb5,0xf1,0xce,0xb5,0x88,0xd9,0x1d,0xc7,0xb3,0x14,0xa6,0xb1,0x30,0x8d,0xaa,0xcd,0xe5,0x50,0xc5,0x0d,0x4b,0x6d,0xde +.byte 0x17,0x4d,0xd2,0x93,0xf3,0xc2,0x8d,0x59,0xf1,0xd0,0x2f,0xb5,0x62,0x18,0x81,0x07,0xb3,0xfb,0x08,0xb3,0xa8,0x15,0xe0,0x9a,0x4c,0xa5,0x24,0xcd,0x47,0x69,0xf9,0xf7,0xda,0xa9,0xff,0xe1,0xe2,0x43,0xe3,0x69,0xf1,0x26,0xac,0xc6,0x42,0xf2,0x32,0x42,0xfb,0x7c,0xa2,0x94,0xc6,0xaa,0xd9,0x05,0x29,0xc6,0x3d,0x45,0x44,0x1d,0x52,0x7e +.byte 0x48,0x47,0x93,0x34,0x08,0xa0,0x93,0xc2,0x5e,0x9b,0x22,0xc1,0x2a,0xaa,0xfe,0xa2,0x26,0x00,0xa8,0xbb,0xd0,0x58,0xfd,0x5a,0x09,0x4f,0xa1,0x0c,0xff,0x66,0xcc,0x88,0x3a,0x69,0x9a,0x12,0xb6,0x05,0x6e,0xdf,0x54,0x5d,0xe7,0x03,0x8e,0x95,0x86,0x68,0x83,0x83,0x6f,0x04,0x0b,0x9c,0x05,0x05,0x77,0x14,0x83,0x47,0x98,0x5f,0x22,0xaf +.byte 0xa8,0xfd,0xf3,0xe7,0x73,0xec,0xef,0xd7,0x57,0xd9,0xef,0xe7,0x1b,0x18,0x24,0x09,0xd9,0x14,0xf9,0x60,0xba,0x05,0x0f,0x8f,0x33,0x48,0xb1,0x06,0x41,0x2e,0x95,0x3d,0xf5,0xcf,0x14,0x50,0x5d,0xb6,0x93,0xeb,0xd5,0xf8,0x9f,0x7c,0x8f,0x23,0x35,0x39,0x30,0xc8,0xf6,0x74,0x07,0xc4,0x4c,0xcf,0xe1,0xdb,0x3e,0x9f,0x0a,0xfd,0x48,0x9e +.byte 0x56,0xe4,0xa7,0xa3,0x07,0x06,0x18,0xbb,0x50,0x75,0x33,0x48,0xb9,0xa1,0x4e,0x63,0x65,0xd3,0xf4,0x40,0xc3,0x2d,0x52,0x9a,0xad,0x56,0x7f,0xff,0xb0,0x46,0x24,0xa1,0x78,0x5f,0xb6,0xa8,0x72,0x28,0xb3,0x6c,0x61,0x6e,0xa0,0xfc,0xcb,0xe8,0xfe,0x07,0x28,0x97,0x1c,0xda,0x76,0xc7,0x98,0x2f,0x00,0x1d,0xf2,0x17,0xbe,0x48,0x3f,0xd3 +.byte 0xc7,0xbe,0x89,0x89,0xe1,0x96,0x75,0x1e,0xee,0xf9,0x78,0x67,0xbf,0x12,0x1e,0xe2,0x14,0xbf,0xd4,0xfd,0x49,0xaa,0xbf,0xc6,0xb8,0x4f,0x84,0xcd,0x5d,0x3c,0x45,0xb3,0xb0,0x14,0x6f,0x2d,0x6f,0x35,0xfa,0x60,0x7f,0x64,0x40,0xc8,0xde,0xa8,0x2b,0x56,0x75,0x74,0xc9,0xe1,0x2c,0xe2,0x2f,0xc2,0x3e,0xba,0xa3,0x20,0xd8,0xa3,0xbc,0x69 +.byte 0x9d,0x1c,0xcf,0x5e,0xe3,0xc0,0x66,0x72,0xce,0x22,0x96,0xad,0x47,0xc9,0x5b,0xac,0x45,0xdc,0x4f,0x8e,0xf6,0xa6,0x2e,0x4a,0x1e,0x01,0xe4,0xb7,0x83,0x68,0x92,0x2b,0x98,0xdf,0x22,0x0f,0xd9,0x4f,0x6f,0x72,0x37,0x56,0xfa,0x1b,0xbb,0x5a,0x4d,0xd8,0x5b,0xc6,0x65,0xf8,0xd4,0x4e,0xa5,0xc0,0x0f,0x2d,0xc2,0x38,0xa4,0x6c,0x33,0x2f +.byte 0x7a,0x52,0x14,0xbb,0xfb,0xb3,0xf2,0xa9,0xbf,0xa0,0xad,0xcb,0x8c,0x81,0x47,0x26,0xe9,0xfb,0xc1,0x8e,0xc6,0xe5,0x39,0x48,0xa5,0xb3,0xbc,0xb2,0xe4,0xac,0xf9,0x49,0xbb,0x34,0x2b,0xc4,0x4d,0x06,0xe4,0xd6,0x0b,0xdd,0x55,0x36,0xe6,0xaf,0x64,0xea,0x84,0xf2,0xa5,0x68,0xe3,0x4e,0x4c,0x77,0x46,0x6c,0x17,0x6e,0x08,0x99,0x96,0x1b +.byte 0xb5,0x44,0x3b,0x94,0x2d,0x0f,0xcd,0x90,0x17,0x8f,0x80,0xcb,0xc2,0x30,0xbe,0xe1,0x36,0xdc,0x1e,0x48,0xe3,0x2c,0xe5,0xc9,0xbc,0xbd,0xff,0x3f,0x95,0x59,0x35,0x58,0x2f,0x9c,0xa6,0x1c,0x45,0xa7,0x61,0xde,0xf2,0x9c,0xa3,0x04,0x0f,0xa0,0x93,0xaf,0x69,0x2b,0x0d,0x1c,0xfc,0xff,0x97,0x1c,0x69,0x7e,0x30,0x06,0x88,0x01,0xa4,0xf1 +.byte 0x32,0x36,0xed,0x56,0x89,0xff,0xa9,0x63,0x3a,0x17,0x91,0xc5,0xba,0x6e,0x38,0x84,0xb1,0xaf,0x28,0xac,0x8a,0xb2,0x60,0xbe,0x1b,0x0a,0xd8,0x05,0x22,0x25,0x56,0xbe,0x75,0x47,0x59,0xcf,0x8c,0x2e,0xb3,0xc3,0x5f,0x06,0x81,0x65,0x39,0x78,0xed,0xe3,0xc9,0x5a,0x99,0x01,0xae,0xfb,0xf6,0xed,0x55,0xf5,0xbd,0x2f,0x93,0xf1,0x62,0x6a +.byte 0x54,0x4f,0xe1,0x9f,0x0a,0x23,0x83,0xbc,0xc2,0xba,0xb4,0x6f,0xd9,0x88,0xc5,0x06,0x7a,0x83,0xd5,0xdb,0xeb,0x49,0x48,0xd6,0xc9,0x45,0xa2,0xd0,0xc4,0x06,0xd9,0x01,0xec,0x2d,0x6d,0xc1,0x95,0x69,0x22,0xd0,0xae,0x88,0x75,0x8b,0xd2,0x02,0x98,0x83,0xd9,0x10,0x27,0x8d,0x68,0x97,0x5e,0x6b,0xdd,0x51,0xbb,0x92,0x38,0xa8,0x12,0xde +.byte 0x0f,0xa4,0x1e,0x2e,0xec,0xd5,0x73,0x55,0x5f,0x46,0x6a,0x0f,0xc9,0x50,0x0d,0xb3,0x55,0x20,0xe0,0x01,0xef,0x92,0x29,0x04,0x38,0x60,0xbd,0xc7,0x0b,0x1e,0x94,0x10,0x37,0xb7,0x02,0x94,0xbc,0xde,0xdb,0xb3,0xe3,0x1e,0xd5,0xe2,0xa8,0xed,0x46,0xe8,0xd4,0x8a,0x6c,0x93,0x4e,0xb7,0x73,0xa6,0x20,0x86,0xd2,0x82,0x2f,0x78,0x80,0x34 +.byte 0x44,0x79,0x84,0x2e,0x54,0xd0,0x30,0xa8,0x06,0x0c,0xcf,0x78,0xb4,0xd7,0xe2,0xc9,0x6e,0xfb,0x37,0x47,0x8f,0xe5,0x9f,0xf8,0xca,0x58,0x9c,0xb6,0x8b,0xbe,0xf4,0x3a,0xfe,0x75,0xec,0x1b,0x22,0xfd,0x93,0x92,0x07,0x09,0xcd,0xe6,0x2f,0xe6,0x51,0x0f,0x19,0x43,0x9c,0x6a,0x32,0x38,0x7d,0xf0,0x0c,0x78,0x81,0xb7,0x5c,0xbe,0x3c,0xf4 +.byte 0xc0,0x12,0x57,0x51,0x8a,0x69,0x84,0x0d,0x1e,0x0a,0xed,0x75,0xde,0x9e,0x31,0x8a,0x9b,0x18,0x82,0x01,0x5a,0xee,0x0e,0x33,0x3c,0x8c,0x95,0xb1,0x0b,0x05,0x3b,0xb2,0x85,0xab,0xaf,0x47,0xa2,0x03,0xb6,0xbb,0xda,0xf5,0xc8,0xbe,0x0e,0x4d,0xf8,0x84,0xe4,0xfb,0xd4,0x54,0x44,0x72,0xe5,0x30,0x57,0xa3,0xb6,0x47,0x8f,0xd3,0x32,0xc2 +.byte 0x83,0x07,0x4f,0x17,0x20,0x88,0xa1,0x0b,0xb3,0xef,0x4b,0x27,0x60,0xe0,0x9d,0xec,0xc2,0xdf,0xaf,0x2e,0x74,0xae,0xa4,0x2b,0x59,0x94,0x75,0xbe,0x54,0xf5,0x18,0x62,0xd9,0xe2,0x35,0xee,0x37,0x2e,0xdf,0x48,0xf8,0x80,0x32,0xcb,0xf1,0x83,0x78,0x03,0x68,0x06,0xd7,0x82,0xc6,0x76,0x2a,0x10,0x2a,0xdb,0x73,0xe6,0x65,0x24,0x9f,0x73 +.byte 0x1f,0x55,0x55,0xb6,0x10,0x65,0x80,0x70,0x5a,0x8e,0x8a,0xc8,0x4c,0xca,0x74,0x47,0x63,0x3f,0xee,0x49,0xc3,0x86,0x0f,0x66,0x56,0x08,0xee,0x9f,0xf5,0x5a,0x89,0x4c,0xb4,0x97,0x6e,0x75,0x61,0xc0,0xa7,0x92,0xa8,0x38,0x99,0x08,0x01,0x12,0x82,0x77,0x80,0x20,0x9d,0x62,0x46,0x92,0xdd,0x39,0x4d,0xcf,0xc0,0x8a,0x3e,0x30,0x9a,0xfa +.byte 0x28,0xe8,0xd8,0xf8,0x07,0x0d,0xab,0x4c,0xd4,0x02,0x4c,0xd7,0xc3,0x16,0x89,0x24,0x84,0x52,0x7c,0xa4,0x1b,0x54,0x7f,0xc4,0x74,0x4f,0x88,0x0a,0x14,0x03,0xd9,0x1a,0x48,0xff,0x2c,0xfb,0xbf,0x33,0xf1,0xf8,0x0e,0xdd,0xc4,0x98,0xf2,0xbd,0x32,0x99,0x03,0x8e,0x56,0xc1,0x84,0x5d,0xa6,0xd7,0x21,0xf2,0x43,0xfb,0x3b,0xf5,0x6a,0x75 +.byte 0x20,0xfb,0x08,0x7b,0x66,0x15,0x47,0x31,0xb6,0xb6,0x7a,0xc9,0xe6,0xf5,0xd6,0x0a,0x14,0xb3,0x68,0x0a,0x32,0x13,0xb5,0xe6,0x56,0xbd,0xa5,0x24,0xe2,0xa3,0x7b,0x3d,0x01,0x23,0xed,0x08,0x09,0xb5,0xdb,0x7c,0xa9,0x4b,0x23,0xdb,0xa2,0x25,0x0c,0xc6,0xa4,0x0d,0xbb,0x1a,0x5d,0x1b,0x42,0x0b,0x86,0x72,0xc3,0xca,0x5b,0x14,0x04,0xa3 +.byte 0xd7,0x01,0xe7,0x17,0x78,0xd0,0x54,0xde,0xd4,0x76,0x3d,0xe1,0x7d,0x26,0x3e,0xb4,0x71,0x42,0x84,0x36,0x58,0x78,0x22,0x32,0x26,0x0e,0xc8,0x99,0x05,0xe3,0x4a,0xa6,0x5a,0x1a,0x06,0x0a,0x88,0x47,0x51,0x5c,0xa8,0x72,0x70,0x0c,0x62,0x5f,0xf3,0x1e,0x02,0x50,0x20,0xc6,0x5c,0x50,0x30,0x1f,0x4e,0x5a,0x3a,0x02,0xc9,0xca,0x3f,0xa4 +.byte 0xf1,0x66,0x05,0xf3,0x19,0xe5,0xaa,0xdb,0x75,0x51,0xc1,0xb8,0x94,0xfa,0x2d,0xb6,0x8b,0x42,0xdc,0x9a,0xa3,0x13,0xeb,0x95,0x8d,0xf0,0x65,0x87,0xc9,0xa1,0x43,0xb4,0xfe,0x76,0xf4,0xc8,0xbb,0x19,0x96,0x84,0x9d,0x2f,0x92,0xe8,0x22,0x9a,0xf0,0xd5,0xf4,0xc4,0x8d,0x19,0x59,0x21,0xbf,0x15,0xfd,0xa6,0xc4,0xde,0x77,0x58,0xae,0x93 +.byte 0xb3,0xff,0x44,0x49,0x6e,0x37,0x94,0x04,0xd2,0x96,0xe9,0x80,0xd8,0xe3,0x93,0xd8,0xb4,0x7f,0x5f,0xcf,0xe5,0x9d,0x51,0x92,0xac,0x5d,0x9f,0x23,0x3a,0x3e,0xdf,0x96,0x68,0x9a,0x46,0x9b,0x1a,0x06,0x44,0x54,0xc4,0x2e,0x19,0x0f,0x50,0xee,0x73,0xda,0x39,0x7e,0xec,0xcb,0x1d,0x39,0xf7,0x9f,0xbc,0xe0,0x6d,0x49,0x56,0xf8,0xa7,0x24 +.byte 0x70,0xab,0xe1,0xc3,0x82,0x99,0x0a,0x4d,0x64,0x41,0x37,0xab,0x92,0x76,0xeb,0x6a,0x2a,0xa5,0xab,0x75,0xd7,0xe3,0x6a,0x72,0x4a,0x2b,0x57,0x02,0xc7,0xbe,0xd5,0x35,0xce,0xdf,0xee,0xf1,0xc6,0xe6,0x69,0xb7,0x76,0x99,0x22,0xb0,0xb9,0xe1,0x18,0x91,0x9a,0x35,0xd9,0x3a,0x19,0xc7,0x77,0xf2,0x2d,0xae,0x04,0x2e,0xb7,0x35,0x97,0xa5 +.byte 0xc6,0x97,0x4e,0x5d,0xbe,0xa9,0x35,0x2b,0x53,0x1a,0x6b,0x4e,0xa8,0xa6,0x22,0x48,0x2c,0x81,0x25,0xac,0x30,0x89,0x7b,0xb3,0x38,0x34,0x42,0x0b,0xa5,0x5f,0x02,0xe8,0xee,0x12,0x9b,0xce,0xe7,0x10,0xf9,0x65,0xb6,0xc5,0x74,0x06,0xef,0xc8,0x95,0xb3,0x40,0x30,0xec,0x1f,0x8e,0xeb,0x93,0x31,0x91,0x5a,0x2f,0xc2,0x90,0x85,0xaa,0x4c +.byte 0x51,0xc4,0xd0,0x3e,0xc8,0xc9,0x61,0x46,0x96,0xd4,0x60,0x56,0x7d,0x91,0xc4,0x24,0x76,0xfb,0x09,0x08,0x48,0x2f,0x4a,0x73,0x90,0x8e,0x9d,0xb2,0x38,0xa8,0x95,0x3e,0x6d,0x10,0x57,0x91,0x8d,0x55,0x62,0x1f,0x21,0xc7,0x01,0x15,0xb0,0x71,0x0b,0x26,0xbc,0x10,0x33,0x3e,0x79,0x37,0x64,0x85,0x98,0x42,0x21,0xcc,0xff,0x51,0x9a,0xc2 +.byte 0xe0,0x51,0xc3,0xff,0xf2,0x14,0x3d,0xe8,0x89,0x12,0xe7,0xcd,0x58,0x2f,0x87,0xfb,0x4a,0x50,0x6c,0x4d,0xdf,0x6f,0x64,0x9c,0x64,0x93,0x49,0x89,0xb6,0x0d,0x10,0x3f,0x13,0x9d,0x9a,0x35,0xf1,0xc0,0xe7,0xf0,0x9b,0xe8,0x39,0xd3,0x32,0xb2,0x23,0x67,0x77,0xdb,0xbc,0x0d,0x19,0x77,0x7a,0xbe,0x54,0x56,0x64,0xec,0xb6,0x2e,0x03,0xc5 +.byte 0x35,0xda,0xf1,0xc7,0x7d,0x0c,0x5a,0x32,0xec,0x86,0xdf,0xdb,0x94,0x73,0x4e,0xe3,0x45,0xf6,0xb2,0x63,0xc4,0xb7,0x80,0x59,0x4b,0x82,0x0b,0x61,0xa0,0xd5,0x43,0x18,0x78,0x35,0x93,0xde,0x46,0xa3,0xa2,0xd5,0xa2,0x71,0xec,0x3e,0xee,0x7a,0x89,0x7f,0xe9,0x70,0xff,0xad,0xae,0xa3,0x64,0xde,0x61,0xea,0x71,0xc2,0x37,0x98,0x8a,0x33 +.byte 0xd1,0x5f,0x03,0x08,0x23,0x24,0xc7,0x6c,0x62,0x24,0x6d,0x3f,0x44,0x8e,0x7c,0x9f,0x64,0x87,0xa5,0x79,0x0b,0x16,0x7e,0x4e,0xc0,0x0e,0xb8,0x77,0x56,0x9c,0xa5,0x7d,0x2d,0x5d,0x7d,0x81,0x13,0x2c,0x08,0xd5,0x83,0x84,0x38,0xfe,0x50,0x6f,0xa7,0x30,0x1f,0x06,0xee,0xab,0x13,0xc2,0x19,0xe6,0xcf,0x7b,0x85,0xfc,0x31,0x5b,0xdf,0xb8 +.byte 0x0e,0xe8,0x72,0xba,0x97,0x03,0x25,0xbc,0xad,0x74,0x7c,0xe1,0x59,0xf7,0x08,0xc1,0xe3,0x2d,0xb1,0x05,0xe7,0x1f,0xb9,0x0f,0x09,0xcd,0xe6,0x4f,0x5a,0xf6,0xcc,0xea,0xc7,0x92,0x35,0xf5,0xbc,0x3f,0xef,0xc9,0x2b,0xb4,0xd7,0x66,0x50,0xaa,0x80,0xb9,0xaf,0x5d,0x02,0x9c,0x77,0xdf,0xc0,0xc7,0xe2,0xbf,0x7d,0xff,0x69,0x63,0x3e,0x7c +.byte 0x91,0x94,0xae,0xa4,0x0a,0x25,0xa3,0x1f,0xf3,0xc6,0x88,0xda,0x82,0xac,0xbc,0x1f,0x8d,0x53,0xd6,0xfd,0x2b,0x5c,0x33,0x6d,0x03,0x68,0x92,0x38,0x07,0xeb,0x85,0x7f,0x55,0x89,0x17,0x58,0x7f,0xc7,0xb4,0x7a,0xff,0x15,0xe5,0xe0,0xea,0xce,0xac,0x3f,0x0f,0x09,0x25,0xfa,0x80,0xe3,0x07,0x89,0x4e,0xbf,0x7e,0xc2,0x42,0xf1,0x18,0x78 +.byte 0x05,0xe3,0x6a,0x2e,0xf7,0x2e,0xe5,0xbf,0x63,0x9e,0x48,0x69,0xe6,0x3c,0x4b,0x12,0x73,0x58,0xde,0x0c,0x73,0x27,0x9a,0x95,0xfa,0x51,0x8c,0xbb,0x74,0x31,0x53,0x4e,0x9a,0x13,0xda,0x49,0xf0,0x8b,0xb4,0xcd,0xc1,0xe9,0xaf,0xd6,0x59,0x59,0xa8,0x24,0x94,0xd9,0x4b,0xf8,0x20,0x79,0xa0,0x79,0x01,0x08,0x84,0x9b,0x04,0xe7,0xda,0x06 +.byte 0x22,0x3e,0x85,0x23,0x0c,0xa9,0xe5,0xcd,0xd3,0xc4,0x27,0x8c,0x4e,0x75,0xe4,0x60,0xb5,0xe9,0xc5,0xb7,0xb1,0x3a,0x84,0x68,0x40,0x3e,0x36,0x1b,0x9a,0x64,0x50,0x45,0x6f,0xc6,0x58,0x70,0x46,0x1a,0xca,0xf6,0x81,0x02,0xa8,0x17,0x4d,0x92,0x0d,0xae,0x88,0x1a,0xbd,0x52,0xc0,0x32,0xb1,0x2d,0x2d,0x12,0x9c,0x29,0xfa,0xa6,0x70,0x5f +.byte 0xe7,0x0b,0xd5,0x5d,0xa5,0x49,0x9e,0x9e,0x5b,0x55,0xbc,0xce,0x5b,0xb4,0xef,0x3f,0xe4,0x7c,0x50,0xef,0x58,0xf5,0xfe,0xcc,0xf6,0xd0,0xf1,0x3a,0x0b,0xf2,0x3e,0x1c,0xce,0x22,0x7e,0x88,0x1c,0x8f,0x9a,0x69,0x76,0xa9,0xf0,0x18,0xa8,0x76,0x7f,0x0c,0xa6,0xfd,0x67,0x43,0xc7,0x43,0x67,0x98,0x6e,0x37,0xd4,0x82,0x29,0x62,0xa6,0xcf +.byte 0x2b,0x7c,0xee,0x14,0x4d,0x2d,0x1a,0xfc,0xc6,0xaf,0x5b,0xea,0x8a,0xa8,0x9a,0x3b,0xab,0x7d,0x76,0x15,0x50,0xe8,0x95,0x31,0xc8,0x5d,0x5d,0x19,0x68,0x07,0xf5,0xb0,0x29,0x5f,0x79,0x4f,0x0d,0x2b,0xba,0x1d,0xd2,0xf2,0x83,0x50,0x89,0x0b,0x96,0x16,0xde,0x7c,0x04,0xea,0x9c,0x75,0x97,0x7e,0xd7,0x2c,0xee,0x82,0x7c,0xbf,0x0b,0x71 +.byte 0x05,0x59,0xd7,0x11,0x70,0x8e,0x41,0x62,0x91,0x38,0x3a,0x69,0x3f,0x3d,0xde,0x8e,0x03,0x0a,0xea,0xfb,0xea,0x36,0xf0,0x5c,0xb6,0xdf,0x9a,0x66,0x9e,0x64,0x43,0xaf,0xb7,0x83,0xd1,0xef,0x7c,0xb6,0x9b,0x40,0xd8,0x0f,0x0e,0x0b,0xa7,0xd0,0x98,0xca,0x8e,0x3b,0xed,0xb7,0xa5,0x19,0xca,0x67,0x30,0x87,0x17,0x0e,0xc4,0xe1,0xaa,0x6e +.byte 0xdb,0x67,0xbd,0xf5,0xed,0x10,0x68,0xb1,0x43,0x73,0xaa,0x99,0x1a,0x83,0x0d,0x1a,0x5a,0x8b,0xc8,0xff,0xe9,0xe0,0x1c,0x15,0xda,0xb0,0x99,0x90,0xce,0x1f,0xfd,0x17,0xd2,0xfa,0x8f,0x3a,0xe8,0x1b,0xd3,0x96,0x2a,0x0d,0xa9,0x4d,0x6d,0x77,0x53,0xe8,0x8f,0xc7,0x6b,0xb4,0x3b,0x6d,0x0c,0x8e,0x35,0x67,0x09,0x6e,0x43,0x36,0x52,0x3e +.byte 0x0e,0xf6,0x4f,0x16,0x40,0x45,0x7f,0xab,0x39,0xf2,0x23,0xfb,0x4e,0xea,0x6e,0xcf,0xa0,0xb6,0xec,0x6d,0x93,0x1b,0x6f,0x9f,0xd6,0xce,0xcd,0x1e,0x90,0x5c,0x7d,0x61,0xc4,0xae,0x02,0xb2,0x7a,0xb2,0x25,0x59,0xac,0x0a,0xcb,0xc6,0x28,0xa2,0x9c,0x7b,0x4b,0x05,0x5a,0x23,0x55,0xc8,0x9a,0x72,0xe6,0x3b,0x91,0xa2,0x9b,0x12,0x1c,0x1f +.byte 0x4b,0x85,0x42,0x9d,0x73,0xf9,0x50,0x3e,0x12,0xc4,0x51,0xb4,0xe1,0x2a,0x08,0xfc,0xf9,0xc8,0x5a,0x53,0x79,0xcc,0xd1,0x24,0x4c,0xc1,0xf6,0xe7,0x10,0x9d,0xe6,0xce,0xcc,0xc7,0x04,0xf8,0x7a,0xd4,0x2f,0x0a,0x97,0x32,0xaf,0x38,0x77,0x97,0x78,0xc8,0xa9,0x9a,0xca,0x65,0xee,0x2b,0x07,0x0e,0xb1,0xaa,0x3c,0xee,0x03,0x85,0xf7,0x09 +.byte 0xd1,0x03,0xe5,0x4f,0x8a,0x6b,0xba,0x83,0xd2,0x6a,0x05,0xe6,0x4e,0x59,0x21,0x26,0xcc,0x8d,0x4a,0x91,0x21,0x6b,0xe5,0x7a,0x83,0xed,0x4e,0x95,0x4b,0x16,0x98,0x3f,0x2d,0x51,0xc5,0x67,0x56,0x58,0xc9,0xc3,0x32,0xff,0x91,0x9d,0x7f,0x6d,0xc7,0x8a,0x40,0x58,0x56,0x35,0xca,0xc1,0xa9,0x07,0xe2,0xc6,0xe1,0x8f,0x7b,0x7c,0x68,0x4e +.byte 0xde,0x19,0xc8,0x9c,0x41,0x65,0x74,0x33,0xb5,0x5b,0xf7,0x47,0x91,0x51,0x41,0x56,0x54,0xaa,0x8e,0xa5,0x1f,0xdb,0x50,0xa4,0x97,0x7a,0xea,0x86,0x2e,0xfd,0xdd,0x64,0x23,0x6e,0x44,0x28,0xfb,0xae,0xe8,0xc2,0x38,0x96,0x56,0x2e,0xd8,0x7e,0x3a,0xc8,0xc6,0x7f,0x20,0x15,0xad,0x9f,0xfa,0x5c,0x55,0xf5,0xe1,0x9a,0x07,0x84,0x5b,0x81 +.byte 0x39,0x4b,0x70,0xc3,0xfd,0x2b,0xc5,0xb7,0x47,0x36,0x74,0x5a,0x85,0xaa,0x45,0x94,0x8e,0xbe,0x7f,0x6c,0x45,0xf5,0x02,0x4e,0x5f,0x16,0x04,0x7e,0xfa,0xb8,0xa9,0x38,0xc4,0xd9,0xca,0x5f,0x7a,0xe3,0x96,0x78,0x82,0xa0,0xac,0xef,0xc4,0x2a,0xb5,0xf4,0x7d,0x28,0x8c,0x25,0xba,0x4e,0xd5,0xd5,0xd1,0x24,0xc6,0x05,0xb2,0x18,0x2d,0x66 +.byte 0xea,0xe3,0x42,0x79,0x33,0x9e,0x70,0x3a,0x1b,0x5a,0x8e,0xcb,0x03,0xa8,0x43,0xf3,0xd5,0x66,0x41,0x10,0xd7,0x09,0xf0,0x28,0xe5,0x25,0xe6,0xac,0x9a,0xe6,0x34,0x36,0xfb,0xc4,0xa6,0x9a,0xd0,0x24,0x4d,0x18,0xf9,0xd1,0x8e,0xca,0x92,0x83,0x0f,0x55,0x54,0x6d,0x72,0x81,0x81,0xdb,0x72,0x1f,0xd6,0x32,0xb9,0x32,0x45,0x84,0x9c,0x66 +.byte 0x68,0x7e,0xab,0xb3,0xca,0xf5,0x4f,0xdd,0xb4,0xee,0xbb,0x05,0x70,0xbe,0x4f,0xd1,0x27,0x01,0xcc,0x7c,0x4f,0x47,0x55,0xce,0x91,0x73,0x6f,0xff,0x8d,0xfc,0x0c,0x4c,0xaa,0xfc,0xce,0x9f,0xf3,0x4a,0x46,0x92,0x89,0x84,0x8f,0x4d,0x94,0x37,0xda,0xe3,0x11,0x0d,0x63,0x60,0xcb,0x40,0x8f,0xe8,0x0f,0xf9,0xa1,0x89,0x64,0x44,0x45,0x74 +.byte 0xc5,0xa2,0x73,0x33,0x08,0xa2,0x59,0xb0,0xeb,0x7b,0x7b,0xa7,0x28,0x4c,0x13,0x6a,0x04,0x15,0x14,0xd0,0x3e,0x5e,0xec,0xe1,0x3f,0xe5,0x93,0x06,0x6b,0x60,0x50,0x1c,0x90,0xc0,0x5c,0xea,0x7e,0x58,0xf1,0xed,0xba,0x43,0x0b,0x84,0xf7,0xa4,0xbd,0x4c,0xed,0x88,0x5b,0xae,0xa2,0x0a,0xf6,0x06,0xfd,0x43,0x63,0xfe,0x8a,0x03,0x21,0x8b +.byte 0x27,0xc6,0xef,0xa3,0xa9,0x3a,0xc1,0x8b,0x65,0x62,0x25,0x85,0xaa,0x2f,0xff,0x22,0x96,0xb7,0x5c,0x82,0xde,0x21,0x4e,0x0d,0x8d,0xd9,0x7f,0x97,0x79,0x95,0x6c,0xe6,0xfd,0xb1,0x7c,0x84,0xc8,0x73,0xbc,0x50,0x2f,0x87,0x03,0x56,0xcf,0xea,0x7f,0xed,0x17,0x7d,0xf7,0x61,0x6b,0x6f,0x5b,0xd3,0xe4,0x83,0xbd,0x8b,0xd3,0x8e,0x51,0x57 +.byte 0x3d,0xcc,0xe4,0x09,0xb9,0x73,0x1f,0xb4,0x47,0x5e,0xf2,0x10,0x3e,0xf4,0x9c,0x86,0x02,0xdf,0x3e,0x75,0x1c,0x9b,0xb5,0x0f,0x31,0xc6,0xbb,0x00,0xb4,0x8a,0x1a,0xe5,0x0d,0x9c,0x3e,0x93,0x61,0x5a,0x61,0x86,0x12,0x64,0xaa,0xfd,0xa2,0x6e,0x8f,0xcc,0xcd,0x60,0xa1,0xad,0x6d,0xdc,0xa2,0x7b,0x5a,0xe0,0xee,0x27,0x5d,0xc5,0xfe,0x1f +.byte 0x7b,0x9f,0x33,0xf1,0xee,0x2a,0x58,0x39,0x56,0x14,0x4f,0x2f,0x11,0x26,0x6b,0x56,0x7c,0x75,0xb7,0xc3,0xa7,0xf6,0x54,0xd8,0xa7,0xbb,0x73,0xb5,0xa5,0x83,0x1e,0x65,0x7e,0xa7,0x85,0x74,0xa4,0x04,0x0e,0x26,0x01,0x88,0xbc,0x8b,0x98,0x0c,0x9b,0x74,0x22,0x44,0x16,0x16,0xed,0x94,0x81,0x81,0x13,0x26,0xc9,0x27,0xa9,0xa7,0xe0,0x45 +.byte 0x69,0x6e,0x33,0xcc,0xa3,0x15,0x10,0x99,0x84,0x06,0x95,0x00,0xbb,0xc6,0x8e,0x4e,0x37,0x1b,0x23,0xb2,0xf7,0x4d,0xd7,0x24,0x68,0x6b,0xaa,0x2e,0x57,0x8d,0xd6,0x4e,0xa2,0x69,0xd8,0x8d,0x84,0xb2,0x85,0x91,0x30,0xbf,0x41,0xab,0xcf,0x5c,0xa6,0x51,0x1e,0xf5,0x79,0x5a,0x20,0xfa,0x3d,0x0a,0xc5,0xd7,0x3f,0xa6,0xcc,0xf6,0x9b,0x76 +.byte 0xe0,0xec,0x9e,0x0b,0x23,0xe4,0x74,0x36,0x14,0x6f,0x24,0x9d,0xe7,0xb2,0x41,0xd7,0x68,0x37,0x67,0xdc,0x01,0xb1,0x20,0xf9,0x8b,0x0b,0xf5,0xa7,0x95,0x78,0xa0,0x6c,0x4b,0xc0,0x44,0x92,0x4a,0x75,0x0f,0x61,0xde,0xc3,0xc2,0x3d,0x17,0xa0,0x4d,0x57,0x8b,0x11,0x35,0xbd,0x49,0x87,0x05,0xba,0x5d,0x1f,0x76,0xd4,0x0f,0xb0,0x5b,0x5f +.byte 0xb7,0xf8,0xcf,0x12,0x54,0x19,0x9a,0x49,0x6a,0x42,0xad,0x93,0x85,0x0b,0xe7,0x8c,0x30,0x59,0x82,0x82,0x2d,0xd9,0x89,0xf5,0x8c,0x39,0x9c,0xf5,0xcd,0x25,0x22,0x74,0xcf,0x56,0xa2,0x15,0x40,0xa6,0xa8,0xfc,0xdc,0x85,0x9e,0xab,0xd6,0x94,0x5d,0xd6,0x73,0x07,0xed,0x7b,0x76,0x11,0x67,0xf5,0x52,0xac,0x1a,0x69,0x1f,0x4a,0xa2,0xaa +.byte 0x4d,0x11,0xe0,0xc4,0x4c,0x6e,0x9e,0x8e,0x13,0x46,0x0b,0x95,0x40,0x53,0x35,0x53,0x58,0x7f,0x81,0x5f,0x17,0xd7,0x5e,0x53,0x86,0xf3,0x1b,0x70,0xf1,0x95,0x8f,0xf6,0xd4,0x6f,0x55,0x92,0xa2,0x38,0xd3,0x43,0x6c,0x7e,0xa2,0x21,0x5b,0x18,0x11,0xdd,0x03,0x52,0xe6,0xe5,0xc0,0xc5,0x4e,0x8e,0xda,0xdb,0x91,0xcf,0xf7,0x75,0xc2,0x33 +.byte 0x69,0xd1,0xd1,0x29,0x9d,0x51,0x79,0x91,0xe4,0x58,0x05,0xa5,0xf6,0x54,0x16,0x3e,0x42,0xf3,0xc4,0x1f,0x88,0x94,0xfc,0x6b,0x53,0xb1,0xd5,0x17,0xe6,0xab,0x77,0x33,0x8a,0xd0,0x93,0x74,0x02,0xe0,0x81,0x5e,0xbe,0x2f,0x4d,0xcd,0x25,0x0b,0xd0,0x06,0xd8,0xc9,0xf9,0xcf,0x8e,0xf8,0xc3,0xe2,0x33,0x60,0xe5,0xfa,0x89,0x68,0xf8,0xb7 +.byte 0xef,0x9d,0xfc,0x9d,0x76,0x13,0x2d,0x9d,0x18,0x7d,0x05,0xb4,0xa7,0xa3,0x8a,0x91,0xe0,0x73,0x65,0x89,0xb4,0xc1,0x53,0x7c,0xdc,0xf2,0xab,0x39,0x94,0xc7,0x3d,0xf8,0x1c,0x8f,0x49,0x37,0xee,0xc1,0x19,0x84,0x15,0x3b,0x36,0xb2,0xc2,0xe1,0x16,0xe2,0xfb,0xde,0x1f,0x0e,0xa4,0xea,0x59,0x67,0x2d,0xea,0x47,0xe5,0x2c,0xd1,0xb5,0xa9 +.byte 0xbd,0x5c,0x92,0x34,0x8b,0xc5,0xab,0x4f,0x2b,0x6b,0xc4,0x8b,0xdb,0xbb,0xcb,0x86,0x34,0x35,0xa0,0x5c,0x29,0x1a,0x8b,0xce,0xdc,0xd7,0x46,0x2b,0x20,0x9d,0xea,0xa8,0x97,0x68,0x37,0x56,0x03,0x7d,0x4f,0xb6,0xfc,0x30,0x82,0x68,0xb4,0x56,0xf3,0xbe,0x58,0xcc,0x20,0xc1,0x53,0x9f,0xbb,0x0b,0x2b,0x6e,0xa0,0x2d,0xc0,0x61,0x02,0x0b +.byte 0xf9,0x0e,0x55,0xb8,0xb8,0x23,0x6e,0x50,0xc0,0x36,0xb8,0xf6,0x5e,0xb3,0xa7,0x8f,0xf8,0x7f,0xd0,0x5d,0x0a,0xc4,0x2b,0xa9,0xd3,0x76,0xcf,0x4d,0x27,0xda,0xac,0xf3,0xb0,0xca,0x00,0xa0,0x94,0x12,0x20,0x89,0x22,0xa9,0x89,0xe4,0x23,0x71,0xe0,0xdb,0xec,0xb0,0xa9,0x2e,0x45,0xf6,0x8d,0x1e,0x4b,0x0e,0xc7,0xf8,0x40,0xd6,0xf4,0x2f +.byte 0x80,0x3e,0xf8,0xfb,0xcf,0x7b,0x54,0xb5,0xbd,0x55,0xf2,0x37,0x46,0x9f,0x32,0x45,0x87,0xa3,0x6a,0x51,0x25,0x43,0x54,0xa2,0x92,0xc6,0xbe,0xa4,0x33,0x54,0x82,0xc7,0xf1,0xe4,0x52,0xf9,0x09,0xac,0xc3,0xb1,0x25,0x86,0xc7,0x89,0x83,0x2c,0xf6,0x35,0x9e,0xd1,0xd8,0xb1,0x71,0xed,0xfa,0xae,0x09,0x83,0xb3,0xf0,0xde,0x24,0xed,0x3c +.byte 0xc6,0x60,0xe8,0x15,0x49,0x93,0x29,0x82,0xbf,0x1d,0x23,0x17,0x11,0xea,0xa7,0x53,0x83,0xa5,0xc1,0x9e,0x02,0x17,0x08,0x99,0xa6,0x72,0xaf,0x82,0x3f,0x0b,0x69,0xca,0xb8,0x72,0xa9,0x31,0x71,0x20,0x32,0x57,0x89,0x9b,0x16,0x92,0x54,0xc0,0x99,0x6d,0xa4,0xbf,0x5a,0xb5,0x53,0xa7,0x4c,0x69,0xd8,0xf7,0xe7,0x4c,0xc0,0x76,0xb6,0x35 +.byte 0xdd,0xe7,0xb2,0xd9,0x1c,0xd5,0xf7,0x39,0x32,0x44,0x48,0x02,0x85,0x69,0x02,0xad,0xe6,0xfc,0xbb,0x07,0x9e,0x7f,0xee,0x6d,0x07,0x12,0x21,0xeb,0x67,0x4d,0x74,0x90,0x8f,0x79,0x51,0x9d,0x8a,0x63,0x24,0xab,0x6f,0x8f,0x73,0xd3,0x91,0x68,0x15,0xa9,0x6a,0x84,0x92,0xc2,0xd4,0x4d,0xa8,0xe1,0x4f,0xa2,0x1e,0x34,0xa3,0x9a,0x04,0xf2 +.byte 0xfc,0xc4,0xe7,0xd0,0x52,0xc4,0x49,0x51,0x8e,0x7d,0xaa,0x74,0xaa,0x08,0xbe,0x08,0xf6,0xe4,0xc1,0x61,0xff,0x2e,0x9c,0x17,0x61,0xb6,0x01,0x44,0x18,0xe8,0x5e,0xa9,0xfb,0x02,0x21,0xbb,0x08,0x5c,0xe0,0xd3,0x0c,0x98,0xc5,0x93,0x2a,0x1c,0x69,0xf3,0xe8,0x8b,0x36,0xa0,0x9d,0x1e,0xda,0x18,0x14,0x06,0x7f,0x75,0x3d,0x42,0x92,0x5a +.byte 0xb9,0xb7,0xc0,0xc0,0xb0,0xc5,0xa9,0xb2,0x67,0x24,0xc2,0x28,0x29,0xcb,0x78,0x8e,0xf3,0xd1,0x37,0x63,0xca,0xc8,0x9a,0x1b,0x38,0xa5,0x9f,0x0e,0x0d,0x26,0x5b,0xfe,0x2f,0xdf,0x4f,0xb9,0x21,0x8c,0xc8,0xe0,0x9f,0x71,0xb9,0xc3,0x6c,0xd8,0xd3,0x2f,0xe4,0x3c,0x67,0x35,0x45,0x74,0x7f,0xcb,0x13,0xda,0x64,0x47,0xff,0x6f,0x05,0xf0 +.byte 0x87,0x8d,0x0d,0x1f,0x10,0x47,0x0e,0xf6,0x9d,0x89,0x6d,0x79,0x04,0x77,0x8a,0x6c,0xeb,0x7d,0x9b,0xd7,0x65,0x82,0xa8,0x95,0xa2,0x8c,0x02,0x91,0x0d,0xf2,0xe8,0x65,0x60,0x0d,0xb6,0x1d,0xf4,0xf3,0x41,0x75,0x33,0x21,0x13,0x22,0x93,0x01,0x2f,0x11,0xe7,0xed,0x45,0x56,0x90,0xec,0x0b,0x99,0x8e,0x84,0xc8,0x76,0x31,0x1d,0xb9,0xcb +.byte 0x87,0x3f,0x5f,0x39,0xeb,0xe8,0x9e,0x5e,0x96,0x9e,0x42,0x64,0xf3,0xef,0x00,0x1f,0x2a,0x6c,0x18,0x67,0xbd,0xdd,0xf9,0x65,0x11,0x1b,0x9c,0xd7,0xf3,0x3d,0xb2,0x6f,0x88,0xf7,0xd2,0x26,0x06,0xef,0xc8,0x23,0x3f,0x46,0x5d,0xf0,0x96,0x40,0xb1,0xdd,0xad,0xe4,0xee,0xb6,0xc2,0x67,0x18,0x46,0x67,0xc4,0xa5,0x7e,0x3e,0xce,0x72,0x47 +.byte 0xca,0xc3,0xa7,0x94,0x56,0xe2,0x23,0x03,0xcf,0xd0,0x18,0x55,0x30,0xe3,0x14,0x00,0xda,0x0f,0xaa,0x7f,0x20,0xaf,0x3b,0x24,0x43,0x7a,0xaa,0xd4,0x12,0x42,0x10,0xe4,0x44,0x8a,0x7f,0xf1,0x74,0x9d,0xe0,0x28,0x60,0xce,0xdd,0x04,0x96,0x03,0x80,0xcb,0xaa,0xa9,0xb5,0xc7,0xb4,0xbb,0xc7,0x9a,0x93,0xd8,0xff,0x3b,0x8f,0x1f,0xb7,0xce +.byte 0xed,0xbc,0xde,0x9f,0x9e,0x56,0x96,0x65,0xba,0xe7,0x89,0x03,0xb2,0xbd,0xfe,0xa7,0x02,0xeb,0x33,0x9a,0x8b,0x5b,0x36,0x64,0x17,0x9f,0xd2,0xe4,0x75,0xb5,0xfb,0x21,0x03,0xa4,0xe7,0xb4,0x49,0x72,0xfd,0xf3,0x1e,0x5f,0xdb,0xe5,0x6c,0x92,0x51,0xe7,0x91,0x55,0xb7,0x82,0x18,0x05,0xc3,0x2c,0xf1,0x23,0x61,0x36,0xad,0x80,0x1b,0xde +.byte 0xe1,0x51,0x4e,0x51,0xa1,0xf6,0x5a,0xb9,0x03,0x48,0xa7,0x12,0x88,0x63,0x30,0xff,0x48,0xfc,0x92,0x30,0x9a,0xca,0x08,0x1b,0x64,0xa9,0x74,0x2a,0x64,0x42,0x7d,0xa9,0xa4,0x9d,0xcb,0x59,0x71,0x53,0xc1,0xa8,0xa6,0xb5,0x47,0xf9,0x87,0xb5,0x41,0x58,0x92,0x14,0xf7,0xbd,0x10,0x45,0x37,0x20,0x1d,0x5b,0x42,0x04,0xed,0x69,0x4c,0xa5 +.byte 0xdc,0x2a,0x58,0xba,0x00,0x1e,0x05,0x9c,0x3c,0xbf,0x65,0x76,0xd1,0x11,0xe0,0x15,0x22,0xb0,0x2a,0x53,0x32,0x0f,0x6e,0x08,0x4e,0x27,0xc2,0x71,0x14,0x20,0xee,0xb0,0x0b,0x60,0xef,0x54,0xae,0x2c,0xe0,0x1d,0x30,0xac,0x0d,0x3a,0x93,0x15,0x0a,0xe7,0x14,0xf3,0x1a,0x67,0xb1,0x43,0x85,0xbd,0x06,0x53,0xab,0x6d,0x5d,0xe7,0xe3,0x82 +.byte 0xb8,0x39,0x35,0x10,0x87,0xe7,0x90,0x4d,0x9c,0x6f,0x83,0xad,0xa2,0x43,0x7a,0x5d,0xc1,0x8a,0x39,0xa3,0xa6,0xda,0x48,0x5c,0x9b,0xe1,0x0d,0x69,0xfc,0x87,0x18,0xdd,0x34,0x9a,0xb4,0x9c,0x04,0x0d,0x49,0x18,0x3e,0x38,0xd8,0x01,0x67,0xb1,0x7f,0x6b,0xb5,0xfe,0x58,0x1c,0x64,0x11,0x10,0x6b,0xc1,0xca,0x56,0xe3,0x12,0x8c,0xb4,0xac +.byte 0x03,0xbd,0xc1,0x54,0xbe,0x5c,0x70,0x6f,0xdd,0x73,0xa3,0x84,0xcd,0x0b,0x1b,0xbf,0x05,0xac,0x27,0x11,0xe8,0x5f,0xc3,0xb9,0x68,0xc2,0xe9,0x3f,0x5a,0x9b,0x28,0xca,0x65,0x5e,0x66,0x4e,0x50,0xa9,0x81,0xb1,0x10,0xc1,0x2c,0xa5,0x62,0xc8,0x52,0x07,0xa5,0xa1,0x99,0x16,0x7b,0x08,0xa4,0x1e,0xf4,0x50,0x8f,0xb2,0x42,0xa5,0x19,0xa2 +.byte 0x34,0x91,0xcf,0xa7,0x5e,0x73,0x6b,0xc2,0xa3,0x4d,0xdd,0x7c,0x26,0x46,0x34,0xe6,0x5d,0x54,0x52,0xe3,0x1e,0xc1,0x10,0x36,0x7c,0xc9,0xd2,0x1e,0xca,0xeb,0x80,0xc5,0x3c,0x04,0xf6,0xb7,0x09,0xd4,0x3e,0x67,0xc3,0xf6,0x6b,0xd4,0x60,0x00,0xc9,0x68,0x17,0x39,0xbc,0xcd,0x14,0x32,0xfc,0x33,0xa4,0xb0,0x6f,0x12,0x6b,0x5f,0xe2,0x15 +.byte 0x1c,0x9a,0x15,0x4f,0x0b,0x7d,0x4c,0xa0,0x89,0x40,0xb3,0x0e,0x84,0x90,0xb3,0xc6,0x3e,0xa5,0x0b,0x81,0x66,0x14,0x5f,0x8d,0xe0,0xbf,0xf7,0x9d,0xa4,0x4e,0x69,0xd5,0xac,0x0f,0x6c,0x29,0x94,0x8f,0x3b,0x4b,0xed,0x5b,0x6e,0xe1,0x58,0x5d,0x32,0x19,0xe6,0xbd,0xfb,0xd5,0xb7,0x0f,0x72,0x0e,0x5b,0x14,0xd3,0xf3,0x09,0xa8,0xea,0xf7 +.byte 0x98,0x2f,0x42,0x07,0x8e,0x72,0x27,0x53,0x8d,0x0b,0xea,0x74,0x38,0xbc,0xaf,0xb8,0x76,0x65,0x97,0xda,0xa7,0x06,0x37,0x29,0x09,0xbe,0xaa,0xe6,0xf7,0xb6,0xb1,0x5f,0x71,0x1f,0x5d,0x14,0x47,0xdf,0x20,0xa3,0x94,0x93,0x7d,0x21,0xe6,0x22,0x7e,0x38,0x1a,0x26,0x83,0xc7,0x32,0xdf,0x58,0xcd,0xab,0x67,0xae,0x94,0xa5,0x68,0xcb,0xe3 +.byte 0x51,0x70,0xc0,0xc4,0x41,0x9f,0xca,0x05,0xc9,0x51,0x2a,0x8e,0x53,0x89,0x3f,0x52,0x6b,0x29,0x64,0xa8,0xb8,0xdf,0x02,0xb1,0x41,0x4e,0x36,0x42,0x32,0xa8,0xc0,0x91,0xf0,0x69,0x69,0x55,0x99,0xb7,0x78,0x4f,0x79,0x5b,0xc5,0xab,0xc6,0xed,0x15,0x88,0x6b,0x94,0x0a,0xdd,0xea,0x47,0xf9,0x0e,0xb8,0x89,0x15,0x68,0x3e,0xc0,0x50,0xf8 +.byte 0xa1,0x2d,0x2a,0x11,0x8a,0xc5,0xb0,0x09,0x4f,0x7d,0x90,0x5f,0x49,0x35,0xe9,0xdd,0xfc,0xac,0xea,0x1b,0x20,0xad,0xd2,0xe6,0xb6,0xbf,0x3c,0x0e,0x7b,0xdf,0x2f,0x55,0x58,0x0e,0x25,0x53,0x62,0xd3,0x73,0xb8,0x3e,0x12,0x91,0xcb,0x23,0xf2,0xc0,0x5d,0x74,0x2b,0x51,0xcc,0xa2,0xb1,0x5a,0xd2,0xf4,0x9b,0xc9,0xa5,0x83,0x2b,0x5a,0x8a +.byte 0x0b,0xe9,0x09,0x59,0xb5,0x44,0xc9,0x55,0xcc,0xbd,0xb6,0x69,0x66,0x9a,0x0c,0x15,0xae,0x76,0x35,0xbe,0xe9,0x37,0x70,0x9e,0xdc,0x97,0x5a,0x82,0x97,0xf6,0x1a,0x45,0xd7,0x27,0xfe,0x1f,0xc3,0x7c,0x3a,0x52,0x85,0x12,0x73,0x8a,0x8e,0x07,0xec,0x1f,0x59,0x3f,0xb0,0x32,0x07,0x92,0x3e,0x81,0xe0,0x7a,0x9a,0xc9,0x91,0xca,0x84,0xf1 +.byte 0xe1,0x32,0x57,0x0a,0x3c,0x9a,0x20,0xa8,0xbe,0x84,0x91,0x44,0x66,0x81,0xdd,0x12,0xa8,0x46,0x15,0x18,0xfc,0xae,0x5e,0x9a,0xf3,0xd9,0xb9,0x6a,0xbb,0x90,0x1c,0x61,0x7f,0x61,0x2c,0xa7,0x12,0x1e,0x05,0xee,0x0c,0x66,0x9e,0xc2,0xc8,0xb9,0xe0,0xc9,0xc4,0xb9,0xee,0x3a,0x6f,0x97,0x2a,0x5e,0xcb,0xd9,0xff,0xd1,0x37,0x5e,0xa0,0x03 +.byte 0x70,0xc1,0x2f,0x15,0xf9,0xf7,0x90,0xbe,0x23,0xe7,0x7c,0x90,0x4b,0xe4,0x5a,0x01,0x65,0x27,0x2d,0x4b,0xd3,0xa8,0x8c,0x1d,0x2d,0x5d,0x48,0xac,0x6b,0x59,0xc9,0x78,0xb2,0xee,0xda,0x6e,0xa8,0x68,0x08,0x99,0x22,0x25,0xfe,0xc2,0xb8,0x83,0xa8,0x08,0xbb,0x6e,0x64,0xae,0x2e,0xbb,0x93,0xaf,0xdc,0xeb,0xa3,0x11,0xa7,0x5d,0x3f,0x22 +.byte 0xf1,0x95,0x27,0xf6,0xd6,0xa6,0xc3,0x56,0x0a,0xd0,0x17,0x43,0x35,0xd2,0xe7,0xa4,0x8f,0x6c,0x1c,0xc4,0x4d,0xa7,0x3b,0xb8,0x7f,0x0c,0xa0,0xd6,0x56,0x82,0xf4,0x16,0x96,0xcd,0xcf,0x6f,0x78,0xec,0xbb,0xb2,0xdb,0x67,0xcf,0x78,0x0c,0x22,0x1d,0x72,0x21,0x8e,0x40,0x85,0xa5,0x07,0x3b,0x0e,0xfa,0x44,0xb0,0xfe,0xbf,0x54,0x80,0x41 +.byte 0xdc,0xa7,0xc7,0xdb,0xaa,0x04,0x42,0x0d,0x42,0x03,0x17,0xc8,0x57,0xd7,0x08,0x34,0x37,0xf5,0x9a,0x90,0x30,0x43,0x54,0x5b,0x58,0x50,0x4e,0xc4,0x56,0x57,0xff,0xf0,0x05,0x82,0xca,0x2e,0x20,0xb0,0xbd,0xd0,0x00,0x7d,0x60,0x3f,0xdb,0x9c,0x08,0x7e,0x21,0x63,0xbc,0x89,0xbf,0xcb,0xcc,0x36,0xb5,0x36,0x41,0xb4,0x9c,0x5c,0x9d,0xa6 +.byte 0x74,0xa4,0x4f,0x6a,0xcb,0x63,0x51,0xb1,0x92,0xa0,0x03,0x9b,0x88,0x03,0xd5,0x82,0x30,0xfb,0x69,0x49,0x20,0xb0,0x37,0x50,0xe4,0x02,0x9e,0x11,0x09,0x20,0x1a,0x41,0x8d,0xdd,0xa0,0x18,0xb4,0x74,0x04,0x1e,0x3a,0xea,0xb4,0x28,0x01,0x7f,0x0b,0x73,0x27,0x5f,0x76,0x2e,0x71,0xfa,0x50,0x1b,0x43,0x8d,0x0d,0x6c,0x87,0xc3,0x10,0x7b +.byte 0x42,0x7d,0x17,0xa6,0x00,0x5b,0x83,0x6c,0x7b,0x7f,0x72,0xd8,0x90,0x4d,0x7f,0x54,0x72,0x17,0x21,0xe4,0x45,0x74,0x20,0x53,0x30,0x46,0x90,0xbf,0x2f,0xac,0x01,0xbd,0x40,0xa9,0xc5,0xbe,0xbd,0x9b,0x59,0x62,0x03,0x30,0x80,0xe3,0x8e,0x23,0x7b,0x2d,0x63,0x4f,0x30,0xe3,0xb8,0x56,0x87,0x57,0x43,0xdc,0x6a,0x3c,0x13,0xed,0x93,0xc9 +.byte 0x1a,0x1b,0xea,0x38,0x67,0x33,0x7f,0x11,0x5c,0x96,0x20,0x4d,0xf6,0x82,0x51,0x45,0xca,0x20,0xfd,0x59,0xef,0x4c,0xb4,0xb0,0xb2,0x0f,0xdb,0x4c,0x00,0x7a,0x18,0x58,0xb0,0xd3,0x65,0x73,0x42,0xe5,0x05,0x76,0xd7,0xa2,0x1e,0x9f,0x59,0xc0,0xd0,0x76,0x29,0x1b,0x12,0x29,0x9b,0xe4,0x7d,0x45,0x13,0xb4,0x57,0xf2,0x0b,0xd1,0xb5,0x60 +.byte 0x6d,0x15,0x0b,0xca,0x5e,0xe4,0x80,0xda,0x56,0x95,0x41,0x18,0x54,0xa7,0xad,0x40,0xe5,0xd7,0xa7,0x3e,0xf7,0x73,0x40,0x70,0xb3,0x23,0xdb,0x22,0x62,0xc7,0x44,0xfb,0x64,0x18,0x18,0x05,0x84,0x07,0x68,0x06,0x7f,0xb9,0xc3,0xf9,0x55,0xe2,0x0d,0x37,0x51,0x34,0xc3,0x55,0x3c,0x29,0x5d,0x1d,0x27,0x77,0xd3,0xe1,0x6a,0x60,0x9f,0x10 +.byte 0xef,0xb1,0x93,0xbf,0x2a,0xb7,0xe8,0x42,0x4d,0xfd,0xa9,0xa9,0x2f,0xb6,0x07,0x5b,0xe8,0xf7,0xd7,0x10,0x47,0x71,0x56,0xba,0x11,0x11,0x32,0xc4,0x22,0xf4,0x12,0x6f,0xc3,0xef,0x81,0xc5,0x82,0xb4,0x1b,0x99,0xbb,0x1a,0x63,0x6b,0x3a,0x70,0x4f,0xec,0x2c,0xf9,0xde,0x1a,0x2e,0x62,0x27,0x1c,0x81,0x21,0x30,0x08,0x30,0xf6,0xf5,0xc1 +.byte 0x6d,0x0b,0xeb,0x34,0xd9,0x3a,0xa2,0xa2,0xc6,0x17,0x60,0x85,0x65,0x43,0xd6,0x3d,0x71,0xac,0xc2,0xaf,0x2b,0x9e,0x62,0xf2,0x08,0x47,0x6f,0x42,0xa8,0x21,0xad,0x42,0x98,0xa0,0xef,0xdf,0xd8,0xda,0x10,0xad,0xf7,0xe5,0xf9,0x22,0x89,0x44,0xbf,0x86,0x86,0x2b,0x02,0xd1,0x9e,0x8f,0xb7,0x10,0x63,0xb1,0xcc,0x40,0x6b,0xa3,0x8e,0x09 +.byte 0xb8,0xe3,0x77,0x3c,0xde,0x36,0x7a,0xb7,0x78,0x4f,0x99,0x5d,0x9a,0x9e,0x19,0x2d,0xb5,0xd9,0x9c,0x95,0x1f,0xa1,0xcc,0x61,0x31,0x1c,0x96,0xe5,0xca,0xeb,0x26,0x34,0xa4,0x63,0x5c,0x7c,0x0f,0x23,0xd1,0xe1,0x09,0xf4,0xab,0xf6,0x73,0x2f,0x8a,0x62,0xf0,0xd3,0x8c,0x44,0xe5,0xe9,0x9d,0x58,0x71,0xfa,0xf5,0x39,0xa5,0x6f,0xf7,0x04 +.byte 0x43,0x0a,0x78,0x54,0xfb,0xa7,0x66,0x57,0x1f,0x61,0xd6,0xda,0xff,0x4f,0x32,0x9d,0x80,0x6b,0x77,0xed,0xda,0xaf,0xbc,0x9e,0xea,0x77,0x04,0xf3,0x47,0x96,0xd1,0x44,0x8e,0xca,0xfe,0xb0,0xa3,0xa6,0x1d,0x8d,0xa4,0xb5,0x8c,0x35,0x28,0xf3,0xaa,0xab,0x28,0x1e,0xc9,0x94,0x12,0x07,0xc6,0xea,0x23,0xf9,0x69,0xc3,0x14,0x27,0xcc,0x55 +.byte 0x27,0x0b,0x27,0x64,0x23,0x38,0x05,0xd9,0xb4,0xf7,0x00,0xf3,0x02,0xae,0xc8,0x5a,0xbd,0x2f,0x20,0xd5,0x45,0xa6,0x09,0x6f,0x1a,0x09,0xb7,0xe7,0x6f,0xf6,0xa6,0x6f,0xc7,0x03,0x4e,0xa3,0x72,0xb5,0xfc,0x17,0xcf,0x1e,0x64,0x8b,0xc4,0xa2,0xba,0x83,0x0e,0x2a,0x11,0xba,0x71,0xe0,0x1c,0x9f,0x70,0x6e,0xf4,0xd9,0x47,0x31,0xf7,0xaf +.byte 0xf7,0x1a,0xe7,0xc1,0xe9,0x66,0xa4,0x48,0xd4,0x25,0x8b,0xf7,0x6f,0x33,0x72,0xff,0x93,0x2e,0xcd,0xc7,0xae,0x3b,0x71,0x3f,0x84,0x7f,0xe6,0xb5,0x58,0x4f,0x95,0x34,0xe7,0x89,0x10,0xd3,0x2b,0x5c,0x30,0x9b,0xd3,0xef,0x98,0xf3,0x33,0x0e,0x6d,0x5f,0x7e,0xba,0x55,0x7a,0xb6,0xf3,0xb6,0xcd,0xa8,0x10,0x68,0x85,0x6f,0xea,0x54,0xc3 +.byte 0x66,0x51,0x5a,0xfc,0x11,0x83,0x9e,0x68,0x95,0xdb,0xec,0x74,0xf0,0x86,0x4a,0x90,0x24,0x66,0xf2,0x61,0x40,0x2e,0x3b,0x53,0xea,0xc1,0x3e,0x1c,0x69,0xaf,0x5f,0x04,0xb5,0xbd,0x3d,0x44,0x1c,0xc6,0x49,0x65,0xf6,0x78,0xfd,0x69,0x49,0x95,0x96,0xa1,0xa0,0xa9,0x78,0x1a,0xf6,0x0f,0xe9,0x52,0x93,0x9c,0x96,0x6c,0x5e,0x67,0x63,0x2d +.byte 0x18,0x22,0x2a,0xcc,0x7f,0x2f,0xd3,0x72,0x82,0x98,0xae,0xb0,0x2b,0xa6,0x96,0x41,0x25,0x47,0x3c,0x92,0xc5,0x0f,0x2c,0xd4,0x43,0x09,0x0b,0x94,0x73,0x73,0x29,0xc2,0x8a,0xa3,0xcc,0x8d,0xed,0x40,0x6d,0x40,0x18,0x7c,0x32,0x1e,0xe1,0x4e,0x26,0xa7,0xa4,0xd5,0xcb,0xfa,0x90,0xba,0xb2,0x04,0x1d,0x5d,0xbe,0x32,0x6c,0x71,0x09,0x51 +.byte 0xdb,0xe3,0xb0,0xe1,0x34,0x74,0xa3,0x2b,0xf2,0xcb,0x9e,0xc0,0xae,0x88,0x40,0x90,0xb6,0x22,0xc8,0xac,0xff,0x45,0xc6,0xfa,0xce,0x0f,0x03,0x9d,0xc0,0xb2,0x2e,0xdb,0x1e,0x6c,0xa5,0xbe,0xb5,0xb3,0xaa,0xd5,0x2d,0x06,0x4d,0x29,0xa3,0xbe,0x25,0x5f,0x21,0x42,0x8d,0x27,0xaa,0x6f,0x59,0x88,0x61,0x4d,0x72,0x9f,0x64,0xfc,0x07,0xaf +.byte 0xeb,0x02,0x5e,0xb9,0x1f,0xfe,0x1a,0x67,0x10,0x35,0xe9,0x9f,0x5f,0x9c,0x8d,0x4a,0xb3,0x10,0x99,0x8d,0x5b,0x9c,0x8b,0x8a,0x0c,0x02,0x8b,0x44,0x1a,0xaa,0xe7,0x14,0x05,0x3d,0x9e,0x62,0xfc,0x76,0x49,0x56,0x46,0xae,0xcc,0x0e,0x47,0x58,0x4d,0x94,0x33,0x4d,0x23,0x24,0x44,0x52,0x2e,0x18,0xf7,0x53,0x6b,0x24,0x67,0xb8,0x88,0x46 +.byte 0x70,0xc8,0xcb,0x60,0xac,0x70,0x85,0xdd,0x00,0xa1,0x5d,0xbb,0x94,0x07,0x0a,0xb6,0x1c,0x88,0x59,0xa7,0x88,0x7e,0x1e,0xc9,0x1d,0x7c,0xa0,0x1c,0xad,0xe4,0xa5,0x36,0xa5,0x35,0xe8,0xda,0x27,0x15,0xbc,0x7b,0x1e,0x8a,0x33,0x74,0x4b,0xc1,0xc7,0x9d,0xa9,0x21,0x98,0x02,0xe5,0xf4,0x8b,0x8e,0x2d,0x64,0x81,0xea,0xa6,0xbe,0xe2,0x05 +.byte 0x16,0xba,0xac,0x75,0x79,0xa4,0xc0,0xd3,0x9d,0xe0,0x25,0x63,0x22,0xb3,0x9c,0xee,0x04,0x8f,0x60,0xab,0x52,0x43,0x05,0x16,0xd4,0xb3,0x88,0xe8,0x68,0xc3,0x81,0x94,0xc4,0xee,0x13,0xaf,0xdd,0x36,0x23,0xe6,0x78,0xc9,0xf6,0x42,0xf0,0xf7,0x89,0x64,0x79,0x13,0xe8,0xed,0x50,0x03,0x16,0x78,0x6d,0xf4,0xdf,0x85,0x2e,0x4e,0x8f,0x2c +.byte 0x5b,0xfe,0x4c,0xf2,0x49,0xde,0xf2,0xa4,0x96,0xe0,0x8a,0x25,0xc8,0x6d,0x22,0xff,0xab,0xfc,0x18,0xe8,0x7f,0xd5,0xc1,0x7e,0x44,0x8e,0x21,0xb4,0xc8,0x79,0xc0,0x55,0xaa,0xb7,0x28,0xa1,0x3a,0xbd,0xc2,0x1d,0xf8,0x87,0xf9,0x35,0x30,0x25,0xb2,0xaa,0x8f,0x3c,0x0d,0x64,0xf2,0xd1,0xa0,0x51,0xbf,0x9b,0x9a,0x9a,0x9c,0x18,0x43,0xea +.byte 0xd2,0x54,0x50,0xe0,0xca,0x1a,0x29,0x16,0x9f,0x49,0x47,0x56,0x65,0x21,0x0f,0xb0,0x53,0x41,0xe3,0xec,0xe0,0x15,0xcb,0xd0,0x61,0x05,0x67,0xd6,0x02,0x1a,0x31,0x80,0xa4,0x9f,0xf5,0x9b,0x28,0xcd,0x43,0xd5,0x70,0x05,0x67,0xe8,0x76,0xb7,0x99,0x98,0x0a,0xd6,0x27,0xe9,0xfb,0x62,0xff,0x66,0x47,0xf7,0xbe,0x5e,0x35,0xa0,0x3b,0x56 +.byte 0x58,0x78,0x9b,0x9c,0x5b,0x9f,0xf5,0x6b,0x1a,0x6a,0xfd,0x8e,0xe3,0xd9,0xa2,0x8b,0x2e,0xef,0xc7,0xd3,0x74,0xb1,0xea,0x6a,0x03,0x8b,0xe2,0x78,0xbe,0xf1,0x75,0x7f,0x02,0x03,0xbc,0xd3,0x15,0x2c,0x87,0x01,0x95,0xa6,0x87,0x2d,0xf8,0x63,0xfe,0x33,0x8f,0xc5,0xc9,0x0a,0x06,0x79,0x93,0x46,0xd7,0x0b,0x61,0x06,0x68,0xae,0x9b,0x46 +.byte 0x6f,0x9e,0x1b,0x21,0x58,0xc1,0x72,0xa9,0x05,0xa7,0xaa,0x88,0xee,0xed,0x8d,0x7f,0x55,0x3b,0xb8,0xb8,0xf8,0x42,0x26,0x4a,0x78,0xe3,0x17,0xe8,0xac,0xb3,0xdb,0x9b,0x90,0x7d,0x8d,0x65,0x00,0x39,0x40,0xc2,0xe2,0x9c,0xc6,0x16,0x35,0x54,0x64,0x09,0xc8,0xc7,0x08,0x77,0x90,0x9d,0xb4,0xd4,0xe1,0x36,0xd4,0x5e,0x63,0xb0,0xba,0x81 +.byte 0x0c,0x4e,0x24,0x20,0xc0,0x7f,0xfc,0x02,0x3d,0x83,0x60,0x8a,0xf5,0xff,0x87,0x60,0x9c,0xd5,0xc0,0x94,0x64,0xe2,0x3f,0xeb,0x9a,0xe5,0xb6,0x50,0x13,0x36,0xf4,0x96,0x5d,0xf4,0xb5,0xab,0xa4,0x28,0x17,0x38,0x7f,0xca,0xf7,0x0c,0xcf,0xae,0xf8,0xef,0x41,0x6d,0x9c,0xa1,0x53,0x33,0xcb,0x8d,0x21,0xab,0x3a,0x8c,0x72,0x8d,0xf3,0xf2 +.byte 0x05,0x69,0xf5,0xe8,0x6b,0x5b,0x42,0x85,0xb1,0x2e,0x6f,0xf8,0x62,0x00,0x1c,0x48,0x6c,0x85,0x72,0x93,0x34,0x67,0x80,0xe7,0x2a,0xfe,0xcf,0x54,0xc6,0x94,0xf2,0x5a,0x48,0xab,0x40,0x52,0x66,0x7d,0x7a,0x75,0x68,0x77,0xfd,0xb2,0xdd,0xb1,0xdb,0x72,0x50,0x31,0x53,0x24,0xbd,0xb0,0x6e,0x1f,0xbd,0xa6,0x90,0x67,0x07,0x1d,0x31,0xf3 +.byte 0x8c,0x82,0xf7,0x53,0x85,0x54,0x64,0x7c,0x76,0x7b,0x5f,0xaa,0xe0,0xe0,0x36,0xa4,0x13,0xb3,0x0b,0x99,0x09,0xfe,0xed,0xbb,0x81,0x4b,0xb3,0x16,0x45,0x2e,0x3a,0xfe,0x60,0x9c,0xdc,0xcb,0x00,0x5a,0x41,0xc4,0x80,0x3c,0x9d,0x15,0x05,0xfa,0x5e,0x37,0x64,0x89,0x9c,0x2d,0xb8,0xf7,0xbc,0x35,0x8c,0x49,0xfe,0x0a,0x43,0x1a,0x59,0xaf +.byte 0x1e,0x50,0x08,0x0f,0x2d,0xb8,0x5d,0x63,0x7f,0x95,0x6a,0xe6,0xad,0x88,0xc3,0xac,0x05,0x14,0x44,0xb0,0x70,0x83,0x5f,0x94,0x45,0x3d,0xe5,0xbd,0xb8,0x92,0x28,0x20,0xd5,0xa0,0x83,0xd2,0xe2,0x41,0x71,0x27,0x29,0x1b,0x2a,0x3a,0x08,0xca,0x75,0xec,0x16,0x4a,0xcf,0x39,0xed,0xbe,0x2a,0x26,0x9b,0xa3,0x26,0xc6,0x89,0xf2,0xc6,0x8d +.byte 0x49,0x3a,0xfe,0xda,0x16,0x54,0x55,0x7e,0x7f,0x65,0x65,0xd2,0x16,0xdd,0xe2,0xa3,0x86,0x7a,0x69,0x82,0x99,0x58,0x45,0x16,0x4c,0x69,0xff,0x72,0xf2,0xbc,0xbb,0xdd,0xe1,0xb4,0x56,0xcf,0xc0,0x84,0xd6,0x2c,0xd8,0xce,0xf4,0x67,0xd8,0x1d,0xb7,0x77,0x6d,0x96,0xf4,0x28,0x7a,0x33,0x03,0x97,0x72,0x37,0xd9,0x35,0xcf,0x20,0x28,0xc2 +.byte 0xc4,0xea,0xf9,0x99,0x89,0xe0,0xcc,0x3d,0xec,0x2c,0xbf,0x06,0x78,0x91,0x1b,0x55,0x1b,0x51,0x9b,0xbe,0xf7,0x4a,0xf8,0x9f,0x46,0xab,0xee,0x5d,0x4e,0x29,0x36,0xf3,0xb9,0xa7,0x85,0x9b,0xf7,0xa1,0x9e,0x2a,0xbb,0xb3,0x0a,0x61,0xb5,0x0f,0x79,0xf4,0xe2,0xd2,0x2c,0x15,0xf7,0x4f,0xca,0xa9,0x46,0x25,0x1c,0xdc,0xfa,0x0f,0x9e,0xfa +.byte 0xf5,0xb8,0x54,0x7a,0xe3,0x98,0x3c,0x3b,0x85,0xf8,0xb3,0x7c,0x70,0x40,0x86,0x2a,0x66,0xd1,0x4d,0x83,0x38,0xc2,0x24,0x8e,0x30,0xc0,0x9e,0x54,0x4c,0x7a,0x62,0x9a,0x55,0x8e,0x11,0x02,0xef,0x30,0x08,0x5c,0xf3,0x57,0xa7,0xbe,0x32,0x04,0xab,0xb1,0x3a,0x51,0x6e,0xcd,0x6f,0xc1,0xd8,0xd0,0x7d,0x4f,0x1b,0xa9,0x1e,0x12,0x92,0x94 +.byte 0xd7,0x40,0xa9,0x99,0x70,0x06,0xcb,0x46,0xa5,0xe0,0x77,0xbe,0x6d,0x48,0xab,0x67,0x4e,0xa7,0x0e,0xfe,0x1f,0x53,0x24,0xbc,0x89,0xcb,0x70,0xac,0x05,0xa2,0xf4,0xa3,0x44,0xde,0xcb,0x18,0x95,0x78,0x70,0x0f,0x69,0xf0,0x5e,0xbd,0xe7,0xfc,0xd3,0x17,0x3e,0x18,0xb0,0x2f,0xa6,0xfe,0x82,0x81,0xe7,0x74,0x44,0xfb,0x43,0x5e,0xda,0xf4 +.byte 0xfb,0xfe,0x5c,0xb4,0x3c,0x1d,0xea,0x0d,0x2d,0xdb,0xee,0x1f,0xc5,0xbd,0xb2,0xa0,0x52,0x76,0x9e,0xad,0xfa,0x19,0x37,0xb0,0x15,0x53,0x82,0x25,0x86,0xd9,0xce,0x99,0x84,0x67,0x5f,0x57,0xb2,0x6f,0x99,0xa4,0x56,0xb5,0x01,0x4f,0xdf,0xa2,0xca,0x8c,0x23,0x51,0xd3,0xc7,0x72,0x9b,0x90,0x72,0x29,0x0c,0xca,0x86,0xff,0xc3,0xd9,0x9e +.byte 0x87,0xe4,0x8d,0xc6,0xac,0xba,0xfb,0x73,0xa9,0xcd,0x5d,0x16,0xfc,0x12,0xea,0x30,0xd5,0x7d,0x7b,0x16,0xa6,0x2c,0xeb,0x3c,0x3e,0x46,0x7c,0xee,0x03,0xd6,0x7a,0xe8,0x88,0x1c,0x17,0xa9,0x08,0xe9,0xd5,0x38,0x59,0x54,0x0b,0xb0,0x77,0x1b,0x76,0x09,0x53,0xca,0x38,0x12,0xd1,0xb5,0x2c,0xe3,0xd6,0xa0,0xca,0x9f,0x65,0x56,0xea,0x95 +.byte 0xab,0xc1,0xf4,0x98,0xaf,0x1a,0xe7,0x2b,0x1e,0x8d,0x75,0x43,0x43,0x9f,0x42,0x5c,0x2c,0xa5,0xd7,0x9a,0xcd,0xc2,0xab,0xd9,0x1f,0x1f,0xde,0x8a,0x3e,0xf8,0x0f,0x56,0x8a,0x01,0xde,0x47,0x41,0xd8,0xa0,0xc8,0x32,0x4d,0xa3,0x75,0x80,0x87,0xb1,0x1e,0x05,0x06,0x5e,0x2c,0x9a,0x7b,0xd3,0x22,0xe0,0x53,0x8f,0x4f,0x35,0x5f,0x46,0x3a +.byte 0xb2,0xfe,0x62,0x44,0x54,0x38,0xe0,0x03,0x5e,0xda,0xcb,0x86,0xdf,0xda,0x67,0x66,0x40,0x27,0x97,0xf0,0xc2,0xbd,0xce,0xce,0x37,0xeb,0x47,0xe2,0x56,0x7e,0x54,0xe9,0x51,0xda,0xec,0xd5,0xe6,0xc1,0x69,0x6e,0x4c,0x3d,0x92,0xdc,0xa0,0x51,0xe2,0x2b,0xb8,0x96,0xb6,0xce,0xdf,0x35,0xdb,0xd0,0xd4,0x42,0xe3,0x94,0x89,0x09,0x1b,0xb4 +.byte 0xe2,0x8f,0xfb,0x23,0x62,0x35,0x56,0xc7,0x94,0x40,0xd7,0x2d,0xdb,0x80,0xc9,0xbd,0x4d,0xe3,0x14,0x30,0x44,0x43,0xad,0xeb,0x3d,0x89,0xe9,0x61,0xd7,0x80,0x15,0x59,0xcd,0xda,0x38,0x11,0x3b,0x84,0x14,0x85,0xef,0x55,0xf2,0x01,0x2c,0xed,0x74,0xf5,0x71,0x75,0x0c,0x52,0x0c,0x41,0x86,0xbe,0x84,0xc5,0x89,0x8b,0xa5,0x6d,0xc3,0xfa +.byte 0x2b,0xe5,0xe7,0xe8,0xdd,0xf9,0xe8,0x27,0x08,0x5d,0xdf,0x61,0xdc,0xb2,0xe0,0x8c,0xe8,0xda,0xa8,0x68,0x22,0x51,0x6b,0xdf,0xd0,0x92,0x87,0x6a,0x43,0xff,0xd1,0x9d,0x9a,0x4c,0x03,0xdf,0x3e,0xc1,0x31,0x33,0x6e,0x2a,0x55,0xc1,0x58,0x59,0x69,0x66,0x05,0xd1,0xa7,0xa1,0x3b,0x98,0x1d,0x44,0x74,0xc7,0x7e,0xc0,0x07,0xd9,0x9c,0x87 +.byte 0x5f,0xc3,0x44,0x25,0x7b,0x96,0xbc,0x20,0x5d,0x14,0x08,0x34,0xe9,0xad,0x34,0xa3,0xc3,0x95,0x1a,0xc1,0xd1,0x37,0x43,0x49,0x66,0xff,0x39,0x70,0x27,0xa0,0x2b,0x39,0x9d,0x1b,0x78,0x52,0x55,0x77,0x30,0xe8,0x72,0x65,0x8a,0xc8,0xa4,0xe6,0xb7,0xd6,0x66,0x82,0xa7,0x1d,0xde,0x3e,0xc2,0x23,0x5a,0x8b,0x51,0xe4,0x44,0x03,0xf3,0x89 +.byte 0x10,0xb0,0x9a,0x09,0x5d,0xe3,0xe9,0x4a,0x0b,0xe3,0x86,0x58,0xf8,0xe3,0x1a,0x3f,0x7f,0x42,0xa5,0xd7,0xb0,0x24,0xb7,0xbc,0x1d,0x40,0xe7,0x2f,0x42,0x8c,0xa8,0x3c,0x33,0xee,0x9f,0xaf,0xd1,0x51,0x8e,0x34,0x82,0xc5,0x16,0xef,0xb1,0xa6,0xa8,0x0e,0xae,0xe6,0xc3,0x2f,0xb3,0x06,0xd4,0x4c,0xec,0xee,0x9e,0xff,0x88,0x82,0x4b,0xb8 +.byte 0xc5,0xef,0x94,0xe2,0x68,0x48,0x23,0xa2,0xc8,0xe4,0xdb,0x33,0xf9,0xee,0x73,0xc2,0xe6,0xa1,0x64,0xf9,0xf6,0xab,0x5a,0xdc,0xa5,0xb3,0xd8,0xae,0xf4,0x1f,0x47,0xfe,0xa0,0xee,0xf5,0xee,0x41,0x30,0xa6,0xbe,0x34,0x2c,0x1a,0x24,0x8a,0x80,0xb1,0x79,0x7e,0x2c,0xc0,0x65,0x68,0x46,0xae,0x0a,0x01,0x77,0xce,0xa2,0x5f,0xc3,0x00,0x8f +.byte 0xd4,0x0f,0xbe,0xbf,0x81,0x20,0x4e,0xb8,0x21,0x5f,0xfa,0xb2,0xf2,0x02,0x83,0x41,0xa8,0xf1,0xe8,0x2c,0x7e,0x0e,0xe6,0xf0,0x6e,0xd5,0x7b,0xcb,0x4e,0xed,0x06,0xc4,0x18,0xfb,0x0e,0x0d,0x8e,0x22,0x8a,0x40,0x4d,0x66,0xa5,0x0c,0x74,0xf3,0x9e,0xd9,0x90,0xf8,0x71,0xe4,0x92,0x05,0x3d,0x2d,0xa0,0xed,0x42,0x88,0x18,0x9a,0xc7,0xe4 +.byte 0x41,0x5d,0xde,0x44,0x2e,0x26,0x30,0xfe,0x51,0xa8,0x91,0xa3,0xa6,0xfd,0x3e,0x04,0x7f,0x3a,0xa9,0x1c,0x21,0x98,0xab,0xaa,0x39,0x9d,0xe4,0x51,0x75,0xeb,0x90,0x6b,0xab,0x11,0x89,0xa9,0x22,0xa8,0xc5,0x92,0x16,0x51,0xe1,0x77,0x09,0x53,0x7f,0xb6,0x80,0x4b,0xf5,0xf5,0xa2,0x0e,0x36,0x24,0x7f,0xe7,0xcc,0x67,0xfb,0x2c,0x6e,0xc2 +.byte 0x16,0x47,0x41,0xc2,0x77,0xf4,0xcf,0x49,0x37,0x17,0x67,0x34,0x14,0x92,0x7d,0x0f,0x14,0xe8,0x4b,0x4c,0xc3,0xbb,0x78,0xf7,0xa0,0x59,0xbe,0x06,0x10,0x38,0xe6,0x2c,0x08,0x15,0xba,0xc6,0x49,0x38,0x9a,0x91,0x2b,0x4d,0x82,0x42,0x0e,0xe4,0x02,0xef,0x2b,0xa2,0x06,0xcc,0x3a,0x3c,0xb9,0xc5,0xb5,0x71,0x1e,0x17,0x5d,0x65,0x35,0x91 +.byte 0x89,0x54,0x97,0xa8,0x7b,0x02,0x24,0xf9,0xdb,0xb5,0x52,0xf7,0xd0,0xa0,0x42,0x48,0x01,0xf4,0x47,0x7c,0x84,0x7c,0x8a,0xb4,0xf4,0x30,0xec,0xb9,0x21,0x44,0x87,0xb2,0x96,0xa4,0x3b,0x0d,0x93,0x26,0x09,0xc8,0xfa,0x28,0x6f,0x09,0xb7,0x03,0x85,0x66,0x21,0x2d,0xf1,0xaa,0x3f,0x0b,0x59,0x15,0xfe,0x8b,0x2b,0xe0,0x81,0x38,0x63,0x70 +.byte 0x09,0x37,0x38,0x62,0x04,0x8e,0x3f,0x23,0x65,0xf8,0xf7,0xc0,0x30,0xb8,0x04,0xb4,0x17,0xd7,0x21,0xcc,0x8b,0x31,0xd3,0x7b,0x11,0xea,0xc5,0x51,0x01,0x93,0x5f,0xe3,0xf3,0x1e,0x0d,0x41,0x52,0x2a,0xfd,0x27,0x02,0x00,0x58,0x0d,0x1f,0x16,0xd7,0x50,0x09,0xea,0x3f,0x9f,0x72,0xae,0x7a,0x79,0x4b,0x69,0x61,0xfc,0xac,0x5c,0x4d,0x6a +.byte 0x65,0x5d,0xa5,0x67,0x76,0xe4,0x24,0x3f,0xa0,0x6f,0xf6,0x60,0xd2,0x70,0x8e,0x2e,0xbe,0xf9,0x8b,0xab,0x22,0xc8,0x9c,0x5b,0x26,0xc5,0x75,0xeb,0x96,0xa2,0x4f,0xdf,0x6c,0x05,0x9a,0x15,0xef,0xbf,0x3e,0x35,0x6d,0x8d,0x48,0xa4,0x33,0xc2,0xe8,0x3b,0x89,0xe4,0x0c,0xb2,0x9a,0xc6,0x89,0x52,0xba,0xc7,0x2a,0xa5,0xfb,0xe5,0xde,0x06 +.byte 0xbd,0xc3,0x4f,0xe8,0xa9,0x9d,0x36,0xa5,0xcc,0x90,0xcd,0x68,0x49,0x52,0x6e,0x9a,0x85,0xd4,0x1b,0xe5,0x3f,0x54,0xc8,0xb4,0x7a,0x76,0xbf,0xa8,0xf4,0x25,0x05,0xeb,0x43,0x0c,0x2b,0x1c,0x59,0x5b,0x51,0x7f,0xd5,0x13,0x54,0x37,0x44,0x37,0x2f,0x79,0x1c,0x1f,0x18,0x57,0x60,0xab,0xf7,0xcc,0x5d,0xd5,0xdd,0x69,0xab,0x7f,0xc7,0x9d +.byte 0x7f,0xd7,0x6a,0xdc,0x34,0x3d,0x6e,0x2c,0x1e,0xb8,0x74,0xef,0xec,0x14,0x83,0x98,0x20,0x85,0x8a,0x95,0x93,0x26,0xed,0xbb,0x7d,0xfe,0x63,0xaa,0x20,0xbb,0x40,0x7b,0x35,0x1d,0xe5,0x64,0xc0,0x64,0x83,0x90,0x59,0xb4,0xae,0xf7,0xfe,0x14,0xb2,0xaa,0x72,0xf7,0x34,0x61,0xe0,0x61,0x06,0xb3,0xdc,0x09,0x5f,0xe1,0x57,0x65,0x83,0x8a +.byte 0x6d,0x46,0x54,0x8f,0xbf,0x38,0x12,0xf5,0xa3,0xfc,0x7b,0x90,0x4f,0x30,0xed,0xc1,0xab,0xb2,0x6e,0xee,0x7c,0x5e,0x35,0x70,0x80,0xb0,0xae,0x93,0xdc,0x4e,0x8f,0x6c,0x37,0xef,0xc9,0x4c,0x3a,0x41,0x14,0x91,0x99,0x0d,0x48,0xbe,0x5e,0x9b,0xc5,0xa6,0x4d,0x07,0x0d,0xd5,0xe6,0x5d,0x26,0x6b,0xa0,0xf3,0xb2,0x28,0x15,0x57,0xdb,0x7b +.byte 0x8e,0x6b,0x88,0xc3,0x81,0xb6,0x16,0xd1,0x3c,0xd0,0x2d,0x5a,0x23,0x35,0x8e,0xb0,0x8b,0x5c,0x99,0x6a,0x7a,0x55,0xb1,0xf9,0x45,0x97,0x94,0x05,0x6e,0x58,0xd4,0x53,0x8d,0x73,0x43,0x02,0x68,0xdf,0x7c,0x37,0x1a,0x6b,0x71,0x04,0xa0,0x31,0x77,0xbc,0xe0,0x16,0x5a,0x2a,0x9a,0xb2,0x40,0xe4,0xbb,0xd0,0xfd,0x35,0xcb,0x7f,0xf4,0x13 +.byte 0x0f,0xb5,0x93,0x9a,0x7d,0x50,0xf8,0xfe,0x56,0x34,0x83,0x20,0xce,0x3d,0x02,0x2e,0x0b,0x95,0x76,0x88,0x47,0x8c,0x75,0x51,0x14,0x52,0x49,0xbc,0xed,0x66,0x0e,0x81,0x65,0x5e,0x64,0xfb,0x45,0x59,0x3d,0x2b,0xd6,0x3a,0xc6,0xfd,0x50,0xe4,0xeb,0x0c,0x68,0x38,0x0f,0xdd,0xa2,0xdc,0xaa,0x26,0xf5,0x7b,0x40,0x6a,0x90,0xf8,0x08,0x2c +.byte 0xe8,0x8f,0x8e,0xc1,0xf2,0x6b,0x87,0xeb,0x7a,0x02,0x9e,0x26,0x3e,0x6b,0xb9,0x71,0x2e,0x6f,0x26,0x20,0xa9,0xc0,0x7c,0xe5,0x6c,0x6b,0xd4,0xc4,0x7b,0x54,0x8e,0x4a,0x7a,0xef,0xfc,0x03,0x02,0x1d,0x6a,0x16,0x99,0x35,0x12,0x49,0xba,0x86,0x37,0x7a,0xb0,0x8d,0x58,0x6f,0x1c,0xba,0xa9,0x5d,0x93,0xdf,0x98,0x50,0x7e,0xea,0x0a,0x88 +.byte 0x1a,0xd4,0x63,0x91,0x23,0x43,0x43,0x17,0x2e,0xe6,0x04,0x95,0x96,0xa8,0x2b,0xb4,0x9e,0x91,0x6c,0x13,0x52,0x8c,0xbf,0x7d,0x50,0xfc,0x79,0xef,0xa1,0x3e,0x90,0xba,0xac,0xd1,0x0d,0xb0,0x4d,0xd5,0x7a,0xc7,0xbd,0x82,0xb7,0x03,0x9c,0x0b,0xbc,0xa7,0x3c,0x05,0x8f,0xbd,0x0d,0x7f,0x80,0xeb,0xe9,0xbd,0x8f,0xdc,0xcd,0x86,0x23,0x26 +.byte 0xb0,0xa4,0xdc,0x63,0xef,0xad,0x61,0x53,0x7e,0x23,0x34,0x0d,0xd9,0x75,0x7c,0xa7,0x57,0xba,0x28,0x0c,0x82,0x7f,0x68,0xe5,0x24,0xdc,0x23,0x99,0xcd,0x6f,0x03,0x59,0x4f,0x35,0x47,0xc4,0x11,0xc0,0x0c,0x2b,0x16,0x94,0xb8,0x28,0xf2,0x0a,0x91,0x2e,0x1c,0xde,0x75,0x50,0x52,0x00,0x0a,0x92,0x80,0xca,0x39,0x3a,0xdf,0x16,0xb7,0xe2 +.byte 0xbd,0x98,0x7b,0x70,0x48,0x85,0x6d,0x48,0xa0,0x1b,0x0a,0xbb,0xa8,0xb6,0xca,0x9c,0x4e,0xda,0x0a,0x17,0x0b,0x30,0xf5,0xa2,0x9b,0x5a,0x89,0xf4,0x53,0x89,0x38,0x34,0x2b,0x7d,0x14,0x04,0x44,0xa3,0x8f,0x70,0x29,0xa5,0x3e,0xdd,0x5a,0x61,0xa1,0x04,0xac,0xd8,0xd3,0xec,0x42,0xc4,0xd9,0x2c,0x13,0x80,0xf8,0xc9,0xec,0x54,0xa7,0xa0 +.byte 0xe6,0x37,0x04,0x38,0x5f,0x1e,0x0b,0xfb,0x38,0x06,0xb9,0xe2,0x05,0x12,0x12,0xa2,0x28,0xff,0x12,0xae,0x44,0xd8,0x0d,0x2c,0x5a,0x8f,0xfb,0x1d,0x98,0x69,0x85,0x69,0x99,0xc0,0x63,0xc5,0x88,0xa7,0x2d,0x56,0x76,0x32,0x23,0x4c,0xf7,0x29,0xd6,0x3e,0x45,0xfa,0xd7,0x61,0xf4,0x9a,0xa6,0x9e,0x4a,0xe7,0xe7,0xf9,0xbf,0x1f,0x09,0x82 +.byte 0xbe,0x36,0xa0,0xdd,0x91,0x47,0x3b,0xbc,0x52,0xf2,0xc2,0x04,0x96,0x85,0xb6,0x93,0xac,0x99,0x94,0xbe,0xfd,0xe6,0x53,0x9f,0x75,0xab,0x38,0xdd,0x81,0xc0,0x79,0x25,0xcd,0x73,0x72,0x5b,0x4d,0xc0,0xba,0xa9,0x18,0xaa,0x76,0x51,0x15,0xef,0xb9,0x22,0xdd,0x5f,0x22,0x62,0x6c,0x36,0xf6,0xc0,0x72,0x34,0x01,0x7a,0xaf,0xe2,0x87,0x1b +.byte 0x5f,0x33,0x9c,0xd5,0xe2,0x81,0x03,0xbe,0x4e,0xac,0xcc,0x17,0xc5,0xc6,0xf8,0x0f,0x24,0xe0,0x26,0x56,0x8a,0x20,0x2e,0xe4,0x05,0xc8,0x0f,0x89,0x24,0x0e,0xd4,0xb7,0x07,0xd1,0x99,0x8c,0x55,0xfd,0x75,0xc1,0xdb,0xaa,0xd1,0xd2,0xa6,0xf2,0xf0,0x3c,0xae,0x62,0x0e,0x1f,0xaa,0xc9,0xa5,0x16,0x09,0x2c,0xc0,0x61,0x55,0x72,0x70,0x63 +.byte 0x22,0xb6,0x41,0xa5,0x08,0x34,0x6a,0x1b,0xfc,0x42,0x81,0xe7,0x25,0x98,0xcf,0xba,0x18,0xb0,0x36,0x90,0x72,0x65,0x75,0xf3,0x57,0x68,0xd0,0x86,0xe4,0xaf,0x33,0xb6,0x2b,0xef,0x96,0x97,0x17,0x42,0x6b,0x8e,0x19,0xaa,0x4b,0x9d,0xc7,0x73,0x34,0x5f,0x41,0x24,0x12,0xfb,0x66,0xa2,0x1e,0x91,0x41,0xc2,0x78,0x08,0x66,0xc4,0xb2,0x86 +.byte 0x67,0x70,0xe6,0x96,0x76,0x8d,0xa4,0x69,0x6f,0xe5,0x35,0x8b,0x20,0x3d,0x6a,0xcb,0x65,0x7b,0x82,0x7b,0xf6,0x2d,0xd8,0xd0,0xda,0x69,0x8b,0xcd,0xdf,0x15,0xf6,0x3a,0x2c,0xfe,0xc7,0x84,0x20,0x11,0xcc,0x18,0x4f,0xc7,0x2e,0x1c,0x46,0x41,0x6b,0x91,0x79,0xa0,0xbb,0xf4,0x48,0xd7,0x0c,0x9a,0x88,0x01,0xda,0xa1,0xd1,0x8f,0x27,0x49 +.byte 0x9d,0xa0,0x3f,0x5a,0xc2,0xf7,0x26,0x9b,0xe5,0xff,0xa4,0xcb,0x86,0x32,0xb3,0x3c,0xd5,0xe5,0x7c,0xbb,0x5e,0xfe,0x3d,0xcf,0x60,0x1c,0x16,0x8e,0x0c,0xc4,0xa9,0xf2,0xb2,0x42,0x1d,0x13,0xb0,0xa8,0xff,0x90,0xbc,0xd9,0x9a,0x6d,0x78,0x7a,0x46,0x1a,0xa8,0x35,0x4e,0xa4,0x79,0xd5,0xb4,0x36,0x47,0x62,0x3c,0x0e,0x23,0x56,0xca,0xa2 +.byte 0x60,0xe6,0xca,0xf6,0xc3,0xd6,0x7c,0x5d,0x54,0x9c,0x0c,0xfa,0x9a,0x0f,0x3a,0x8c,0x64,0x52,0xdb,0x62,0x5e,0x93,0x82,0xef,0x9e,0x8d,0x30,0xa5,0xe7,0x3d,0x52,0x11,0xd4,0x93,0xb1,0x77,0x8f,0xee,0x54,0x9c,0x80,0x47,0xa9,0x21,0xa8,0xf7,0x16,0x4b,0xbb,0xab,0x75,0x52,0xed,0x0c,0x85,0xf8,0x04,0xf4,0x80,0x08,0x4a,0xb5,0x2d,0x2d +.byte 0xd8,0x98,0x57,0x24,0xd5,0xc8,0x77,0xa0,0xd8,0xb5,0xb1,0x83,0x92,0xb4,0xc7,0x42,0x36,0xd1,0xa5,0xd6,0xbd,0x89,0xc6,0x76,0x31,0x92,0x31,0x67,0x2c,0xa4,0xb2,0x2b,0xcf,0x94,0x20,0x6a,0x17,0x63,0xb9,0x76,0xac,0x9c,0x1c,0x95,0x3e,0x57,0xf8,0x87,0x0d,0xef,0x36,0xcd,0x87,0xd1,0x58,0x2c,0x9a,0x5e,0x54,0x0e,0xac,0x97,0xbd,0x15 +.byte 0xc4,0xdb,0xea,0xd3,0x21,0x05,0x2d,0x78,0xce,0x4c,0x60,0xf3,0xf8,0xeb,0xd9,0x19,0x89,0xb0,0x83,0xc0,0xe4,0x42,0x08,0x5c,0x1a,0x1c,0x53,0xf3,0x1e,0x5a,0x28,0x92,0x0d,0x32,0xbe,0x4a,0x9a,0x70,0x78,0x93,0xc1,0x66,0x81,0xda,0xe7,0x3d,0x05,0xc5,0xaa,0xdc,0x51,0x6b,0xaf,0x67,0x4d,0x18,0xfe,0x29,0xe0,0xfa,0x5c,0xe5,0x9a,0x18 +.byte 0x7f,0x8f,0xaa,0x21,0xa5,0xd0,0x8b,0x62,0x32,0x6b,0x93,0x02,0x19,0x62,0xd3,0xd6,0x74,0xea,0x83,0xdb,0x6c,0x57,0xe3,0x1f,0x1f,0x90,0xd0,0x22,0xf7,0x9a,0x4a,0x14,0xf4,0x8a,0xb3,0x86,0xa5,0x4c,0x1e,0xdf,0x49,0xa5,0x78,0x30,0x5e,0xf0,0x9a,0x69,0x0d,0xaa,0xe9,0x47,0x01,0xae,0x51,0xcf,0x32,0x4c,0xec,0x03,0x08,0xe7,0xcb,0x35 +.byte 0x59,0xd2,0x48,0xd4,0xfa,0x6a,0x45,0x6b,0x66,0x1f,0xb8,0x1e,0x45,0x85,0xef,0x14,0x25,0x34,0x48,0x50,0x59,0xf3,0x76,0x09,0x32,0xf5,0xe4,0xa8,0x98,0xb0,0x9a,0x70,0xec,0x0a,0x17,0x87,0xcf,0x6d,0x96,0x7d,0x50,0x5e,0x3a,0xff,0x57,0xa7,0xaf,0x04,0x0d,0xdc,0xcc,0xad,0xe3,0x09,0xd3,0x92,0xab,0xd8,0x3a,0x61,0x1f,0x9c,0xc4,0x36 +.byte 0x3b,0xf3,0xf6,0x87,0x43,0xea,0xc8,0xff,0x29,0x19,0x9e,0x87,0x44,0xc7,0xe5,0x5c,0x43,0x30,0x9a,0xb2,0xd8,0x47,0x4a,0x87,0xcc,0xc7,0x8e,0x99,0x32,0xdd,0x3c,0x37,0xda,0xa0,0x39,0x04,0x55,0xca,0xcf,0x2f,0xce,0x8b,0x22,0x35,0x2c,0x29,0x89,0xef,0x5c,0x05,0x82,0x55,0xf3,0x8d,0x64,0x7f,0x69,0xf7,0x3d,0x43,0x27,0xf3,0x4c,0xd7 +.byte 0x43,0x89,0x47,0xd5,0x0b,0x01,0x1b,0x17,0x6c,0x7e,0x63,0x18,0x87,0x8b,0x8f,0x20,0x0d,0xa4,0x1e,0xa5,0x3b,0xf1,0x5c,0xe5,0xc8,0x23,0xd4,0xee,0x79,0x3e,0xd1,0xbc,0x83,0x30,0x03,0x64,0x80,0x7e,0xda,0x13,0x7c,0x52,0x88,0xc1,0x7c,0xa7,0x8a,0x5d,0x8d,0x7b,0x57,0x4e,0x59,0x97,0x83,0x52,0x03,0x04,0x6b,0xd2,0xf3,0xff,0x1c,0x4e +.byte 0x3b,0xae,0x70,0x61,0x3b,0x8b,0xaf,0x56,0x3d,0x28,0x73,0x24,0x39,0x4b,0xb8,0x6e,0x89,0x28,0xe6,0xc8,0x5c,0xe9,0xf8,0xec,0x8f,0xf7,0x75,0x1a,0x13,0xc1,0x8e,0x53,0x4e,0xe5,0xef,0x37,0xce,0xa1,0x54,0xca,0xcc,0xf5,0x01,0x29,0x2a,0x8f,0x00,0x1c,0xde,0xcd,0x5e,0x24,0x0b,0xa5,0x94,0x0c,0x8a,0xab,0x54,0x1e,0x80,0x2a,0x0d,0x84 +.byte 0x38,0x4c,0x17,0xea,0x84,0x07,0x9c,0xbd,0x85,0xd8,0x1b,0x57,0x6a,0xde,0xb3,0x86,0xa3,0xf8,0x6d,0x03,0x3e,0xf1,0x37,0xae,0x7d,0x02,0x33,0xc5,0x7b,0xf6,0x64,0xdb,0x3e,0xb0,0x48,0xda,0x49,0xec,0x89,0xb4,0x83,0xff,0xe1,0x6f,0x9a,0x7e,0x0a,0xda,0x6e,0xec,0x70,0x0b,0x51,0xac,0x82,0xac,0xb8,0xce,0x16,0xe7,0x47,0xab,0xe8,0xc7 +.byte 0x56,0xd1,0xab,0x73,0x72,0x5c,0xe7,0x9e,0xb8,0x77,0xa7,0xc1,0x47,0x9c,0x4e,0x16,0x68,0xce,0x21,0x23,0x2d,0x6c,0xcf,0x79,0xd6,0xd4,0xdf,0x74,0x30,0xb8,0x0f,0x60,0xea,0xbf,0x39,0x77,0x45,0xdc,0xaf,0x25,0xbd,0xc5,0x8d,0x0b,0x44,0x21,0xc1,0xc1,0x2e,0x54,0x2a,0x32,0x6c,0xea,0x51,0xe0,0x7d,0xa8,0x09,0x94,0x2f,0x4e,0xfe,0x27 +.byte 0xe8,0x63,0xfb,0x71,0xca,0x01,0x7d,0xc9,0x70,0xd8,0xe4,0x82,0xbf,0x3f,0xea,0x64,0x5e,0xa9,0x84,0x1d,0x2c,0xfd,0x8a,0x7d,0x33,0x73,0x5c,0x82,0xbe,0x9e,0x46,0xfc,0x39,0x5e,0x38,0x2a,0x20,0xd9,0xa9,0x20,0x46,0x23,0xc1,0x8b,0x0a,0x9c,0x42,0xb6,0x50,0x9f,0xc8,0x7d,0x4a,0x85,0x98,0xed,0x92,0x13,0xd3,0xd6,0xe6,0x6d,0x50,0x6e +.byte 0x93,0x63,0x41,0xa3,0x63,0x97,0x52,0xe3,0xaf,0x09,0xe1,0x40,0x12,0x41,0xed,0xb3,0xc5,0xb8,0x9f,0xc1,0xf2,0xd2,0xe6,0x16,0x94,0x97,0xdb,0xae,0xdb,0xd4,0x1f,0x5a,0x2f,0xf1,0xb1,0x22,0xf6,0x60,0xa4,0x0e,0xd8,0x2f,0xf7,0xf7,0x3f,0x6c,0x7d,0x73,0xe3,0x1d,0x99,0x04,0x7f,0x4f,0x70,0x2a,0x8c,0x43,0x80,0xa3,0xd0,0x25,0x75,0xd8 +.byte 0xb6,0xc8,0x90,0xa2,0x26,0xee,0xba,0xc5,0x1a,0xdc,0x1f,0x81,0x65,0x54,0xc6,0x57,0x6e,0xa2,0x03,0x32,0xf5,0x14,0xb2,0xdd,0x4d,0x21,0xaa,0xb9,0x78,0x4f,0x76,0xab,0xbe,0xfe,0x5d,0xc6,0xaf,0xed,0x6f,0xf9,0xaa,0x31,0x21,0x08,0xa4,0x6e,0xfb,0x78,0xdc,0xed,0x0c,0x05,0xff,0x1e,0x60,0x38,0x60,0x94,0xa9,0x92,0xa7,0x07,0x6e,0x6f +.byte 0x6d,0x89,0x8a,0x73,0xfb,0xaf,0x01,0x34,0x7d,0x7d,0x33,0x76,0xff,0x1f,0x6b,0x79,0x5e,0xff,0x50,0x14,0x80,0x7d,0x55,0x0e,0x2d,0xc3,0x77,0x85,0x30,0x20,0xf6,0xc8,0xc7,0xb7,0x73,0x1b,0xd1,0x87,0x69,0x44,0xeb,0x02,0x5e,0x45,0x66,0x6f,0x28,0x00,0x1f,0xf8,0x58,0x93,0xe5,0x21,0xbc,0x19,0x8d,0x72,0x19,0xaa,0x9a,0xbb,0xc6,0x47 +.byte 0xe6,0x0b,0xe4,0x76,0x13,0xc7,0xc4,0x1b,0x9d,0x85,0xba,0x17,0xb6,0x30,0x2a,0xdb,0x7c,0x36,0xd7,0xd8,0x8b,0x9c,0x99,0x92,0x64,0x03,0x4f,0xd4,0x1f,0x04,0x2e,0x45,0x34,0x55,0x92,0x99,0x77,0xb8,0x45,0xce,0x59,0x22,0x3c,0x6e,0xe5,0x18,0xb0,0x83,0x42,0x42,0x75,0x1c,0x34,0x0f,0x2e,0x59,0x06,0x94,0x17,0xea,0xc3,0xdb,0x0b,0x2f +.byte 0x44,0x97,0x54,0xe8,0x76,0xd3,0x25,0x24,0xe9,0x21,0x4f,0xd7,0x01,0x7d,0xbe,0x90,0x8a,0x0a,0x7d,0x4e,0x91,0x5f,0x4c,0x32,0x83,0x42,0x55,0x95,0x3c,0x7a,0x3e,0x46,0x8a,0x5d,0x0c,0x05,0xcd,0x0b,0xf6,0x3e,0x4d,0xf3,0x55,0xea,0x42,0x3e,0x19,0x0e,0xda,0xd4,0x22,0x88,0xe2,0x29,0x06,0x9e,0xea,0x1c,0x27,0x96,0x7f,0x3a,0x8a,0x28 +.byte 0x2f,0x7d,0xa2,0x65,0x37,0xae,0xb6,0x6a,0x59,0x41,0x19,0x73,0x91,0x64,0x77,0x4e,0x5a,0x1a,0x85,0x9f,0xc5,0xb0,0x85,0xc1,0x96,0x47,0x69,0x9c,0x36,0x70,0x36,0xa3,0x2e,0x1a,0x7d,0x11,0x59,0x55,0xec,0x4c,0x49,0xa1,0x86,0x3c,0x3d,0x24,0xb8,0x7a,0x84,0xca,0x4c,0x3f,0x7e,0x81,0x95,0x39,0x41,0xfe,0xc4,0x74,0xe5,0x89,0x7e,0xdc +.byte 0x86,0xd2,0xdb,0x8b,0xb8,0xa2,0xbb,0x15,0x64,0x89,0xf9,0x00,0x7d,0x56,0xec,0x8b,0xc8,0x05,0xcd,0x76,0x6c,0xcb,0xaf,0x7e,0xd2,0xdd,0x67,0xb3,0x99,0x16,0x63,0xf2,0x6d,0x49,0x7d,0xeb,0x67,0x24,0x98,0xf1,0x28,0xa3,0xb2,0x14,0xfc,0x95,0xf6,0x55,0xa0,0xb5,0x8c,0x26,0x2f,0xc6,0x08,0x49,0x57,0x4c,0x20,0xbc,0x48,0xab,0x24,0xef +.byte 0xe9,0xab,0x6b,0x77,0x4d,0x3b,0x61,0x84,0x68,0x67,0x72,0xc2,0xcf,0xab,0x8e,0xac,0x39,0xec,0x43,0x03,0xbb,0x4f,0x32,0x7d,0x7d,0x51,0x69,0x30,0xee,0x4f,0xd0,0xb9,0xa5,0x22,0xdd,0x47,0x06,0xad,0xac,0x62,0x20,0xff,0x7b,0x8c,0x90,0x91,0xb3,0xd8,0x89,0xd3,0xea,0x81,0xdc,0xca,0x31,0xc3,0x65,0xca,0x4c,0x50,0x0a,0x85,0xf7,0xaf +.byte 0xe3,0x67,0x57,0x53,0x1d,0x4e,0x42,0x17,0x2d,0x14,0x80,0x29,0x09,0x2b,0x48,0x45,0x43,0xb9,0xad,0x1f,0xb7,0x2d,0xab,0xfa,0x6a,0x1b,0x3c,0x7d,0x76,0xd7,0x36,0x20,0xb0,0xd3,0xc0,0x5e,0xc7,0x20,0x06,0x0c,0xa9,0x6a,0xb2,0x67,0xad,0x91,0x49,0xfc,0x4d,0xb2,0x15,0x61,0x61,0xfa,0x33,0x6c,0x94,0x92,0x58,0xef,0x46,0x82,0x9c,0x04 +.byte 0x52,0x21,0x28,0x08,0xb4,0xa9,0xd4,0x2e,0xd9,0x8c,0x93,0xd0,0xd8,0x4f,0x33,0x1d,0x0b,0x7e,0x07,0x12,0x40,0x64,0x3d,0xa2,0x8f,0xa3,0x96,0x45,0x0e,0xfc,0x9b,0x55,0x5f,0x3c,0xa2,0x57,0x3e,0x51,0x40,0x69,0xdc,0x7a,0x51,0xd2,0x3b,0x79,0x2f,0xd2,0x01,0x18,0xbf,0xd5,0xd2,0xd1,0x0e,0x08,0xcf,0xac,0x07,0x4d,0xd1,0x92,0xc7,0xca +.byte 0x92,0x75,0x0b,0x80,0x29,0xf1,0x46,0x24,0xba,0x47,0x6b,0x4a,0x64,0xfb,0x31,0x69,0xe9,0x40,0x0d,0x69,0x50,0xd0,0xdf,0xf8,0xcb,0x6a,0xe8,0xd4,0xc2,0xbd,0x0b,0x23,0x00,0xe0,0x29,0x0a,0x0a,0x8e,0x19,0xec,0xa9,0x14,0xe4,0x5d,0x4c,0x30,0xc9,0x85,0x42,0xd6,0x9f,0x83,0x8f,0x2a,0x5b,0x22,0x37,0xe4,0x71,0x3b,0x19,0x86,0xd4,0xda +.byte 0xb5,0x81,0x8e,0x84,0x57,0xcd,0x13,0x64,0xc3,0x23,0xfd,0x91,0x8a,0xe4,0xb9,0x32,0x12,0x17,0x02,0xa6,0x8d,0xec,0x44,0x9d,0xa5,0x7c,0x96,0x14,0xd1,0xd5,0x93,0x02,0x0c,0x9d,0xfc,0x26,0xa0,0xd2,0x41,0xaa,0x75,0xe8,0x82,0x6f,0x47,0x1d,0xe8,0xcf,0x94,0xe3,0x35,0xa9,0x76,0x1e,0xdb,0x92,0x5f,0x32,0x49,0xf4,0xd5,0x59,0x9c,0x4e +.byte 0xf7,0x89,0xda,0x23,0x7f,0x46,0x0e,0xfc,0xaf,0x1c,0x6f,0xcc,0x59,0xa5,0x43,0x04,0xbf,0x55,0xab,0x7d,0x36,0xa3,0xa5,0x03,0x7f,0xdf,0x33,0x6c,0x6d,0xd0,0x53,0xaa,0xef,0x54,0xc1,0x62,0xa0,0xd6,0x3a,0x67,0x87,0xe3,0x76,0x17,0x45,0xbe,0x7f,0x55,0xc8,0x8b,0xe8,0x1c,0xa8,0xe6,0xa6,0xb2,0xbf,0xe5,0x45,0xc0,0x88,0x22,0x36,0xa0 +.byte 0xec,0x21,0xdc,0x3e,0x6b,0xd2,0xc7,0xdf,0x5b,0xa4,0x32,0x28,0xca,0x23,0xe1,0x50,0x55,0x72,0x59,0x28,0x1c,0xf7,0x93,0x91,0x07,0x3c,0x4e,0x81,0x20,0x58,0x9b,0x07,0x38,0x37,0x68,0x2c,0x29,0xba,0x20,0x11,0xa9,0xa0,0x29,0x65,0x57,0xb1,0xe3,0xb1,0xfb,0xe2,0x70,0xee,0x1f,0xcd,0xf5,0x61,0xea,0x7a,0x08,0xb4,0x1e,0xfe,0xe7,0x4d +.byte 0x32,0xa0,0xfd,0xb4,0x52,0xa1,0x4b,0x67,0xba,0x5e,0x90,0xe7,0x56,0xec,0x06,0x03,0xb6,0xe6,0xc6,0x98,0xa1,0x41,0xf4,0xaf,0xde,0xe2,0x67,0xef,0xaa,0x05,0x97,0xc5,0x80,0x32,0xd0,0x43,0xc2,0x02,0x7a,0xcc,0x4c,0xdd,0xe9,0x1e,0xd0,0x4f,0xad,0xf3,0x4b,0x2c,0x5e,0xb8,0xd8,0x84,0xc2,0x43,0xc7,0xa9,0x86,0x4d,0x10,0xae,0xb7,0xe3 +.byte 0x5c,0xd5,0x2a,0xba,0x3b,0xd3,0x7b,0x5d,0xc8,0xe0,0x67,0x87,0xbe,0xbf,0x71,0x4e,0x22,0x68,0x12,0x53,0x95,0x73,0x5c,0x30,0x7b,0x2b,0xfd,0xc1,0x3c,0xfc,0xc4,0x0f,0xdd,0x5b,0x3e,0x1b,0x72,0x71,0xa6,0xe3,0x1f,0x2d,0x51,0xe2,0x61,0x3d,0xa0,0x60,0xc2,0x6b,0x41,0x8f,0x94,0x83,0x29,0xa3,0xb6,0xa7,0xc7,0x11,0x8f,0x1c,0xb5,0x19 +.byte 0x66,0x44,0xc7,0x05,0x58,0x83,0x28,0x69,0x0c,0xb6,0x65,0xe5,0x93,0x1c,0xb1,0xf6,0xf9,0xea,0xda,0x84,0x26,0x8e,0xa2,0xbb,0x9b,0x55,0xd3,0xbc,0x42,0x56,0x8f,0xce,0x6e,0x74,0x40,0xf2,0x02,0xa6,0x22,0x22,0x6e,0x20,0x0e,0x4b,0x8b,0x15,0xa5,0x04,0xf0,0xe0,0x7b,0x27,0x0a,0x38,0xe3,0x99,0x04,0xd0,0x5b,0x64,0xd2,0x04,0x92,0x61 +.byte 0x57,0x74,0xbc,0x1e,0x98,0x01,0x4b,0x2f,0x46,0x56,0x1c,0xeb,0x49,0x2d,0x66,0xac,0x85,0x96,0x48,0xfd,0xa1,0xf0,0xf5,0xc0,0xdb,0x7a,0xf2,0x0b,0x57,0x86,0xac,0x4c,0x6a,0x02,0x97,0x13,0xef,0x08,0xf6,0x18,0xe1,0x5c,0xb3,0x18,0x3d,0x70,0xc0,0x76,0x5e,0xd0,0xb8,0x44,0x32,0x25,0x75,0x62,0xa2,0x80,0x78,0x8c,0xc4,0x2a,0x84,0xbc +.byte 0x51,0xd4,0xee,0x44,0x48,0xe5,0xc4,0x48,0xbf,0xc0,0x27,0xc1,0x77,0x25,0xf5,0x59,0x6b,0x60,0xae,0xa5,0x42,0xfe,0xc3,0x06,0x91,0xe3,0xdb,0xa9,0x4b,0xe2,0x73,0x95,0x1f,0xf6,0xb6,0x66,0x71,0x63,0xb3,0x14,0x4a,0x3d,0x36,0x84,0xbe,0x2a,0x7c,0x7c,0xba,0x0e,0x8d,0x9a,0x73,0x52,0x21,0x89,0x02,0x8f,0x94,0xa5,0x9a,0x11,0x2e,0x6e +.byte 0x78,0xf7,0x07,0xf8,0xb1,0x42,0x96,0x06,0x78,0xf0,0x53,0x86,0xec,0x2b,0x1f,0xa7,0x84,0x79,0x37,0xc7,0x61,0x83,0x8e,0x62,0x65,0x49,0xdd,0xfe,0xee,0x97,0x70,0xa2,0x73,0xb5,0x85,0xaf,0x10,0xed,0xb8,0x74,0xec,0x42,0xd0,0x14,0x47,0xa6,0x90,0x7c,0x07,0x22,0xb4,0x4e,0xfc,0x12,0xa1,0x9d,0xd4,0x73,0x8f,0x6a,0x55,0xf8,0x56,0x25 +.byte 0xdb,0x9b,0xe8,0x10,0x87,0x7a,0x4b,0x42,0x9c,0xbb,0x6e,0xf1,0xd7,0x1d,0xf4,0x07,0x31,0x9c,0x94,0x3a,0xb6,0xad,0x4b,0xf4,0x57,0x3d,0x2f,0xba,0x23,0x36,0x34,0x52,0x62,0xf7,0x64,0xc7,0x47,0xeb,0x41,0xad,0x07,0xfb,0x3e,0x08,0x74,0x92,0x58,0x0f,0x73,0xe2,0x53,0x35,0xda,0xae,0x64,0x3c,0x47,0x89,0xaf,0xce,0x59,0x35,0x75,0x8b +.byte 0x50,0xee,0xbf,0xbe,0xd1,0xf4,0x2f,0x11,0xa3,0xfe,0xce,0xfd,0x15,0x0d,0x32,0x17,0x00,0xfb,0xad,0x02,0x70,0x5c,0xeb,0x59,0xfb,0x87,0xe5,0xed,0x0e,0xde,0x97,0xe7,0x75,0xb6,0xdc,0xe9,0xb0,0x08,0x26,0x0e,0x11,0xd4,0x4f,0xc4,0x92,0x71,0x7c,0x63,0xef,0xc0,0x14,0x64,0xe1,0x0f,0x7e,0xe6,0xcb,0x5b,0x4c,0xd4,0x16,0x8b,0x7b,0x8b +.byte 0x2f,0x2a,0x77,0xef,0xd3,0xdf,0x56,0xc0,0x5a,0x94,0x72,0xd5,0x36,0x12,0xfa,0x25,0xd7,0x77,0x52,0xdd,0xea,0x11,0x2f,0x6b,0x16,0x6e,0xe3,0xa2,0x84,0xba,0x55,0xc2,0xb0,0xe2,0x3b,0x53,0xb6,0xa4,0xc6,0xa5,0x3f,0x1b,0xb3,0x38,0xc0,0x2f,0x1a,0x80,0xe0,0xa4,0x60,0x49,0x8c,0xe3,0x23,0x5f,0x59,0xfd,0x2a,0x0f,0xe8,0x4c,0xaf,0xd7 +.byte 0x36,0xc7,0x25,0x21,0xad,0x41,0x54,0x27,0x95,0x15,0x42,0xbc,0xb3,0x77,0x4e,0x97,0xf4,0x3c,0x54,0xcc,0x19,0x63,0x62,0x67,0x97,0x5a,0xd0,0x59,0xfb,0xce,0xcd,0xe1,0x3c,0xb6,0xc9,0x49,0xc4,0xff,0xde,0xf9,0x89,0x87,0x9c,0xdf,0x4e,0x8c,0x9d,0xe5,0xbd,0x0d,0x0c,0x6e,0x93,0xfd,0xea,0x90,0xf2,0x80,0x7e,0x00,0x9a,0x06,0x02,0x87 +.byte 0xae,0xca,0xf4,0x46,0xbb,0xb5,0x52,0xee,0x18,0xb0,0xf1,0x61,0xcb,0xe1,0x65,0x9c,0x0b,0xfb,0xe6,0x3b,0xeb,0x3a,0x1a,0x22,0x41,0x0b,0x99,0xa4,0x8e,0x01,0x5e,0x7c,0x4e,0x1a,0xaa,0xab,0xd3,0x8b,0x99,0x7f,0xba,0x6b,0xec,0xe7,0x3a,0xd6,0x55,0x46,0x20,0x1b,0x10,0x39,0x06,0xcc,0x90,0xc1,0x6a,0xa5,0x27,0x7c,0xca,0xa5,0x58,0x07 +.byte 0xd7,0xaf,0x6d,0x12,0xa6,0x68,0xc7,0x0e,0x19,0x53,0x44,0x22,0x85,0xbb,0x72,0x9c,0x4d,0xfb,0xeb,0x94,0x3a,0xa0,0x64,0xf5,0x25,0xe8,0xee,0x7a,0x3b,0x71,0x0e,0xbb,0x40,0xa2,0xb3,0xc9,0x6b,0x14,0x0f,0xc3,0x75,0xac,0x1b,0x5c,0xf1,0x34,0x51,0xcb,0xeb,0x5f,0x40,0x0f,0x82,0xe9,0xd2,0x6d,0x95,0x88,0x84,0xea,0xe9,0xe3,0xa0,0xe9 +.byte 0xef,0x3b,0x33,0xfe,0x32,0x52,0x93,0xce,0x95,0x4b,0x64,0x3c,0x97,0x76,0x91,0xd8,0xce,0xb5,0xc2,0xda,0x58,0x23,0x27,0xe2,0x3d,0xbe,0xf6,0x31,0x79,0x73,0x0e,0x31,0xd7,0xa3,0xaa,0xac,0xcf,0x31,0x1e,0x75,0x58,0x14,0x21,0x52,0x1c,0x3e,0x4f,0x2a,0x2b,0x9a,0x22,0xbc,0x42,0x68,0x5b,0x83,0xc2,0x8c,0xd4,0xe8,0xd9,0x02,0x0d,0x13 +.byte 0x2f,0x08,0xd3,0x11,0xb7,0x4b,0x84,0x67,0x43,0xda,0x20,0xdb,0x89,0xd5,0x9e,0x14,0x54,0x3d,0x49,0xda,0xac,0x3f,0x8f,0xf5,0x17,0xfe,0xb8,0x5f,0xc3,0x20,0x38,0x27,0x21,0x32,0xbf,0xf3,0x9b,0x2c,0x0b,0x9b,0xeb,0x64,0x87,0xf7,0x9d,0xed,0x15,0x05,0x21,0x69,0xcf,0x2d,0xf8,0xfb,0xf2,0x81,0x51,0x08,0xc7,0x18,0x81,0xdf,0xed,0xa4 +.byte 0x70,0xb3,0x07,0xfa,0x00,0xd5,0x65,0xb9,0x5a,0x82,0x67,0x6f,0x10,0xfc,0x46,0x05,0x9a,0x85,0x64,0x14,0x60,0x64,0x4d,0x1f,0x13,0x57,0xbb,0x7c,0x4a,0x10,0x84,0x8c,0x57,0x36,0x13,0x22,0x00,0x04,0x2d,0xcf,0x27,0x3d,0xf4,0x27,0x3e,0x32,0xb3,0x87,0xda,0x82,0xaa,0xad,0xd7,0xa7,0xc5,0x3c,0x45,0xec,0x28,0x82,0x79,0x95,0x8f,0x56 +.byte 0x50,0x5f,0xc2,0x15,0xab,0x18,0x58,0x4f,0x69,0x46,0xce,0x29,0x33,0x42,0x53,0xe9,0xea,0xe5,0xa8,0x5b,0x90,0xc4,0xf4,0xbf,0x8a,0x20,0x62,0xad,0xa5,0xea,0x6a,0x4e,0xb4,0x20,0x2d,0xca,0x90,0xdf,0xbd,0xab,0x5b,0xc3,0x33,0x7c,0x53,0x1f,0xf5,0x2e,0xc0,0xbf,0x19,0xe1,0xa1,0x5a,0x63,0xf3,0x13,0x4d,0x6e,0xef,0x4f,0x3a,0x94,0x18 +.byte 0xbe,0x79,0xdb,0xbf,0xc2,0x2c,0xb3,0x36,0x59,0xab,0x21,0x1d,0x98,0x60,0x70,0xdd,0x95,0x51,0x19,0x07,0xd6,0x68,0x0e,0x2a,0xd4,0x4c,0x30,0x18,0x1c,0xe4,0xe1,0x89,0x15,0x25,0xea,0x27,0xcf,0x51,0x56,0xc9,0xa9,0xa7,0x31,0x08,0x17,0xfb,0xfc,0xf6,0x0c,0x5d,0xf1,0x7c,0x36,0xcb,0xad,0xef,0x29,0xf5,0x2e,0x23,0x09,0xcf,0x31,0x6f +.byte 0x74,0x12,0xd2,0xc2,0xc7,0x19,0xa5,0x6e,0x20,0x09,0x67,0xdc,0x41,0x69,0xbe,0x15,0xd6,0xeb,0x7b,0xba,0x63,0xae,0x65,0xd8,0x67,0xec,0x6e,0xcc,0x1d,0x04,0x08,0xfb,0x7c,0x34,0x1d,0x5f,0x1e,0x51,0x1c,0x30,0x72,0xd3,0x0c,0x48,0x60,0x3d,0x52,0xae,0xe6,0x78,0x44,0x6d,0xb8,0x40,0x08,0xb7,0x7a,0xa9,0xfc,0xa0,0x86,0xff,0x32,0xd6 +.byte 0x5a,0x31,0x4e,0xe2,0x65,0xab,0xb0,0x84,0xb6,0x74,0x3e,0xa6,0x67,0x7c,0xa2,0x0f,0x23,0x22,0xab,0x72,0x7e,0xeb,0x45,0xa9,0x2a,0xb4,0xd3,0xcc,0x27,0x5c,0x12,0xdb,0x14,0x68,0x73,0x0f,0x36,0xbf,0x9f,0x14,0x12,0xe9,0xef,0x04,0x2a,0x63,0x41,0x4b,0x04,0x9b,0x4c,0xc4,0xb2,0xb9,0x1c,0xc0,0xb8,0xcc,0x23,0x61,0xc4,0xed,0x27,0x1e +.byte 0x1d,0x97,0x3d,0x40,0x4c,0x1f,0xeb,0x6e,0xc4,0xfb,0x5c,0x2d,0xf5,0xf1,0xbb,0x05,0x47,0xa2,0x1a,0x9c,0x2b,0x8f,0xce,0x98,0x09,0x6b,0x86,0x22,0xf8,0x3a,0xae,0xf3,0xb4,0x66,0x2f,0xdb,0x20,0xa5,0xc6,0xb6,0x35,0xb5,0x5a,0x68,0xb5,0x37,0x2c,0xab,0x13,0x3d,0x2d,0xcb,0x38,0xed,0x3c,0x7a,0x1f,0x26,0x08,0x58,0x94,0x52,0x30,0xec +.byte 0x06,0x9f,0x90,0x97,0x4d,0x90,0x49,0x23,0xaf,0x00,0x90,0x6b,0x96,0x37,0x02,0x4c,0x35,0xc0,0x3e,0x66,0x2c,0x52,0xbc,0x75,0x28,0xd7,0x8f,0x25,0xbe,0x91,0x10,0x22,0x67,0xbf,0x4a,0x4d,0x62,0xc4,0xe9,0xda,0xe2,0x79,0xcc,0x76,0xeb,0x99,0x87,0xac,0x39,0x7d,0xf6,0x5a,0x37,0x85,0x30,0x33,0x65,0x3f,0xd9,0xd6,0x17,0xf8,0xf0,0x86 +.byte 0xee,0x5c,0x2f,0xb0,0xb3,0x4f,0x83,0x6c,0x4a,0x8f,0xfc,0x80,0x91,0xaf,0x4b,0x21,0x9c,0x9b,0x44,0x3c,0xed,0x67,0xfb,0xa3,0x31,0x7f,0xd4,0x73,0x72,0xb9,0xc1,0x31,0x96,0x47,0x8e,0x99,0x8e,0x62,0x1a,0xfd,0xc7,0x9d,0x2f,0x4c,0xda,0xe5,0xae,0x17,0xb6,0x40,0x5f,0x9e,0xa8,0xf2,0xcc,0xd7,0xd5,0x40,0x33,0x88,0x57,0x63,0x9b,0xde +.byte 0x82,0x71,0x68,0xfe,0xaf,0x29,0x6c,0xc1,0x2c,0x2f,0x02,0x42,0xd7,0xa5,0x28,0x05,0xca,0xa0,0xb6,0x8c,0x43,0x90,0x05,0xe2,0x1c,0xb7,0x76,0x79,0x39,0xd3,0x23,0xe1,0xe7,0xbb,0x19,0x65,0x1a,0xb4,0xbb,0x5a,0xcf,0x43,0x70,0x26,0x1a,0x2f,0x61,0x78,0x75,0x08,0xb0,0x88,0xe5,0x4a,0x46,0x0a,0xfc,0xcb,0x46,0x18,0xb0,0x8d,0x9b,0xeb +.byte 0xf5,0xe1,0x83,0x04,0x84,0x4f,0xd6,0xa0,0x4f,0xb2,0x4c,0x44,0x08,0xde,0xd6,0x82,0xb5,0x9a,0x45,0x15,0xb8,0x21,0xc7,0xf5,0xe2,0xfd,0x02,0x27,0x18,0x13,0x24,0x18,0x01,0xd1,0x2a,0xff,0x63,0xf2,0xa4,0x97,0xc8,0x4b,0x3b,0xae,0x49,0x47,0x54,0xe8,0x75,0xe7,0x16,0x77,0x22,0x10,0x7b,0x3c,0xf0,0xdb,0x49,0x6e,0xd6,0x55,0x9d,0x43 +.byte 0x6f,0x6e,0x2d,0x97,0xea,0x16,0x2e,0x0c,0x85,0x89,0x67,0xe1,0x7b,0x38,0xa6,0x2b,0x89,0xf0,0xcd,0x90,0xcd,0xba,0x9a,0x70,0xa9,0xe3,0xff,0xe0,0xbd,0x15,0x3e,0x4b,0x13,0x62,0x7b,0x59,0x64,0x18,0x96,0xe9,0x6a,0xf3,0x69,0x2d,0x2d,0x25,0xe7,0x91,0xd3,0xbc,0x74,0x58,0x66,0x2f,0x5e,0x8b,0x52,0xf6,0x91,0x24,0xa8,0x6f,0xa5,0xce +.byte 0xa1,0x4e,0x3b,0xe9,0xc5,0x30,0x7e,0xa5,0xc7,0xe2,0xb3,0x71,0x3b,0x25,0xb9,0x5f,0xe5,0x9c,0xf8,0x46,0x23,0xc5,0xa2,0xc1,0x1f,0x3f,0x43,0xa6,0xaa,0xf1,0x36,0x27,0xc6,0xa8,0xed,0x0d,0x50,0x71,0xf1,0x38,0x27,0xb7,0x16,0x43,0x7c,0x7f,0x77,0x5b,0x25,0x59,0xb7,0x08,0x0d,0xc8,0x84,0xe4,0xc2,0x03,0x95,0xe5,0xf3,0x0a,0x9c,0x1f +.byte 0xde,0x98,0x7c,0xa9,0xe2,0x70,0x9e,0xde,0xf6,0x80,0xd0,0xf8,0x86,0x4a,0x7a,0x0d,0x16,0xaa,0xde,0xba,0x02,0x30,0x8a,0xe6,0x03,0x0f,0xa1,0xf1,0xe8,0xd6,0xf8,0xce,0x7b,0xba,0x74,0xa8,0x25,0xb0,0x49,0x22,0xa6,0x81,0x7e,0x71,0xc5,0x97,0x9e,0xa8,0x46,0xa7,0xe9,0x8b,0x7c,0x7c,0x4c,0xc5,0x3c,0x93,0x08,0xb9,0x8b,0x3c,0x33,0xd6 +.byte 0xc4,0x37,0xc8,0x05,0xe7,0xfe,0xc2,0x7c,0x02,0xe6,0xda,0x09,0x52,0x2c,0xc6,0xa8,0x6e,0x44,0x7e,0x55,0xf0,0x32,0x10,0xcb,0x1e,0xa7,0x77,0x8d,0xc7,0xfe,0xb5,0xf6,0x3b,0x49,0xf2,0xfb,0xe0,0x41,0x98,0xd3,0x17,0xa6,0x5d,0x3f,0x4c,0x95,0xb0,0x02,0x8d,0xab,0x36,0xb7,0xa0,0x92,0x40,0x5e,0x15,0xfb,0xa9,0xb4,0xa3,0x04,0x8b,0x6b +.byte 0x81,0x44,0x59,0x22,0x10,0xcb,0xc5,0x52,0x3f,0x78,0x70,0x00,0xe2,0xa2,0xf7,0x76,0x62,0x72,0x06,0x8b,0xbb,0x56,0x0f,0x8c,0x67,0x2f,0x52,0x3f,0x3b,0xdc,0x15,0x79,0x55,0x89,0x6c,0x61,0x23,0xcc,0x6b,0x41,0x77,0xe5,0xc4,0x90,0x51,0xc3,0x87,0x22,0x1e,0x89,0xf5,0x5b,0x41,0xd7,0x34,0x22,0x3c,0xbd,0x29,0xaa,0x54,0xed,0x5a,0x90 +.byte 0x17,0x24,0xba,0x7a,0x46,0x5f,0x54,0x33,0x56,0x7e,0x2d,0x03,0x59,0xcb,0xbb,0x7a,0xce,0xbb,0x8d,0xf7,0xb6,0x38,0x00,0x18,0x6a,0xa1,0x6c,0xdf,0x42,0x49,0x4d,0x9b,0x4f,0xd6,0x85,0x54,0x1f,0xad,0x17,0xdd,0x66,0x0e,0x7c,0x30,0x86,0x82,0x1c,0x5a,0x81,0x08,0x55,0x51,0x5b,0x06,0x54,0x52,0x3e,0x8b,0x6e,0x72,0x92,0xd2,0x05,0x5d +.byte 0xe4,0xe8,0x0e,0x62,0x1d,0xec,0xb1,0x7f,0x42,0x05,0xd5,0xd3,0x60,0xd4,0xdc,0xa4,0x48,0xc0,0xf0,0x89,0xef,0x5b,0xae,0x5f,0xcd,0xf0,0x62,0xaa,0x3e,0xd5,0x1a,0xbe,0xe3,0x08,0xd5,0xe8,0x00,0x21,0x8c,0x0b,0x0c,0x8e,0x24,0xac,0xb2,0xea,0x44,0x9f,0xce,0x53,0x45,0x9a,0x85,0x67,0x99,0x85,0xea,0x92,0xa7,0x1d,0x86,0xb4,0x3b,0x22 +.byte 0xa2,0xcd,0x35,0x65,0xb5,0xa6,0xdb,0x6d,0x48,0xd1,0xa4,0x76,0x0c,0x00,0x30,0x62,0x86,0x06,0xda,0xa8,0xfe,0xec,0x70,0x87,0x4a,0xe8,0x2e,0x4d,0xe3,0x94,0x0b,0xdf,0x81,0xcd,0xfe,0x23,0x79,0x2c,0x2b,0xae,0xf7,0x75,0x49,0x47,0x24,0x46,0x09,0x10,0x62,0x39,0x3b,0x50,0xf1,0xfa,0xf7,0x5f,0xe4,0x7c,0xa5,0xc0,0x25,0x9e,0x20,0x4d +.byte 0xc8,0x6b,0x93,0xc5,0x4a,0x6b,0x62,0xb8,0x3b,0xe5,0x0d,0x92,0x70,0x26,0xa5,0x2b,0xd0,0x9f,0x03,0x8b,0xd3,0x1a,0xc4,0xb0,0xa3,0xc7,0xf4,0x35,0xe5,0x1d,0xe0,0xaa,0x43,0xab,0x64,0x10,0x2b,0xa4,0x09,0x42,0xee,0xba,0xb7,0xbf,0xfd,0xa6,0xff,0x76,0xe5,0x12,0xd6,0x50,0x9a,0x26,0x6b,0x3a,0xd3,0xe6,0x7d,0x3e,0x0e,0x9b,0x95,0xd7 +.byte 0xbf,0xb6,0x7e,0xfb,0x3c,0x24,0xa4,0x26,0x98,0x88,0x81,0xf4,0x56,0xa4,0xf7,0xe8,0x87,0x15,0x5e,0x9f,0x84,0xdd,0x04,0x66,0x43,0xd8,0x76,0xc2,0xa3,0xfd,0x4b,0x58,0x09,0x06,0xa6,0x60,0x5c,0x3f,0x75,0x80,0xd7,0xc4,0x29,0xf9,0x0b,0x1e,0x4d,0xe5,0x26,0xf6,0xae,0x7a,0xc1,0x05,0xf3,0xf1,0x6c,0xee,0xed,0x56,0x0b,0x51,0x66,0xbe +.byte 0x99,0xec,0x9c,0xc2,0x97,0xe2,0xed,0x09,0x1d,0xa8,0x18,0xaa,0x1c,0x9e,0x20,0x62,0xb1,0x80,0x68,0x3e,0x28,0x1f,0x4f,0x50,0x0e,0x41,0xaf,0x17,0x44,0x79,0x16,0xca,0x17,0xe9,0x13,0x66,0x0a,0x04,0x68,0x41,0xe2,0x1d,0xc7,0x00,0x1e,0x66,0xa3,0x6c,0x2d,0x52,0x8c,0x0b,0x7c,0x03,0x48,0x73,0x3b,0xa9,0x84,0xe5,0x31,0x12,0x0f,0xe8 +.byte 0x1e,0x58,0x4d,0xd0,0x1b,0xb7,0xcf,0x75,0xd5,0x2c,0xca,0x33,0x17,0x95,0x9c,0x30,0xc7,0x7f,0xe9,0xde,0xae,0x19,0x72,0x00,0x2a,0xf5,0xde,0x93,0x3f,0xf5,0x44,0xe5,0xf8,0xc7,0xeb,0x1a,0x5d,0x5b,0x11,0x30,0x09,0xf5,0x49,0x66,0x70,0x1a,0xd5,0xe6,0xfc,0xe6,0x59,0x3d,0x17,0x6c,0xb5,0x0c,0xdf,0x1e,0x9c,0x48,0xd1,0xde,0x12,0xd6 +.byte 0xc8,0x48,0xc8,0x73,0x6d,0xfc,0xec,0x07,0xce,0x02,0xe5,0xb3,0x18,0xb9,0x55,0x4d,0x64,0x07,0xf3,0xaa,0x3c,0xf1,0x71,0x22,0x31,0xbb,0x74,0x2c,0x9f,0x7b,0x68,0x9d,0x80,0x49,0x32,0x48,0x9b,0x54,0xf3,0x74,0x37,0xac,0x4e,0xb2,0x96,0xdf,0x9d,0xeb,0x43,0xe0,0xd0,0xa0,0xe3,0x77,0xbd,0x8b,0x92,0x95,0x9d,0x63,0x8d,0xa8,0x23,0x07 +.byte 0xb0,0xcb,0x9d,0x8d,0x3f,0xe2,0xd5,0x81,0x6a,0xe5,0xc2,0xfe,0xda,0x1c,0x25,0x25,0x5b,0xa8,0xad,0x06,0xec,0x0d,0x4b,0x68,0xc3,0x45,0x81,0x38,0xb0,0x22,0x71,0xa4,0x2b,0xf3,0xa6,0x05,0xae,0x0c,0x48,0x94,0x0d,0x3d,0x48,0x51,0x76,0xdf,0x79,0x66,0x0e,0x28,0xc0,0xc1,0x6f,0xc8,0x8f,0xf7,0x7d,0x37,0x06,0xa2,0x8a,0x3a,0x6b,0xab +.byte 0xe0,0x55,0x8e,0xec,0x89,0xe2,0xca,0xc4,0x01,0x03,0x5d,0xa1,0x84,0x21,0x44,0xbb,0x6b,0x36,0x63,0x57,0x4f,0x54,0x88,0x81,0xbe,0xf8,0x53,0xf7,0x57,0xee,0x30,0x85,0x03,0x11,0x86,0xff,0xe4,0xd6,0xc4,0xf0,0x3c,0xcf,0xfd,0x38,0xd8,0xcb,0xd0,0x96,0x03,0xf2,0xc7,0xfa,0x18,0xc8,0x1b,0xe6,0x77,0x3c,0x61,0xa9,0x14,0xdb,0xb4,0x5c +.byte 0x2d,0xee,0xd7,0xe8,0xc4,0x0c,0x69,0x0c,0x55,0xe2,0x99,0x4b,0xc4,0x89,0xc8,0xee,0x48,0x0e,0x16,0xd7,0xa4,0x78,0x25,0xda,0xd3,0xa8,0xac,0x89,0x66,0x67,0x0d,0x51,0x21,0x0e,0x91,0xfb,0xb5,0xab,0x33,0xcb,0x3e,0xc7,0x0f,0x03,0x22,0x51,0x71,0x03,0xa0,0x3c,0xa9,0x35,0xcb,0x40,0xa7,0xbe,0xe7,0xc3,0x51,0x43,0xd8,0x9a,0x24,0xb7 +.byte 0x7e,0xfb,0x26,0x8d,0xa5,0x1a,0x6b,0xe7,0x97,0xe4,0xdd,0xc0,0x3e,0x98,0x67,0x55,0x79,0x56,0xb9,0x7e,0x25,0x4c,0x5c,0x5a,0x47,0x0a,0xce,0xb6,0x4d,0x2c,0x69,0x73,0xaa,0xf0,0x12,0xbb,0x9d,0xe1,0x60,0xc4,0x5b,0x10,0x32,0x6d,0x89,0x54,0xb1,0xfe,0x36,0xbe,0xb2,0x60,0x9a,0x91,0x73,0x9c,0x32,0x61,0xad,0x9a,0xf7,0x56,0x5f,0x5a +.byte 0x54,0xaf,0xb2,0x0c,0x5b,0x1a,0xe6,0x98,0x94,0xed,0x69,0x0b,0x8d,0x06,0x87,0xc9,0x20,0xdc,0x92,0x2d,0x5e,0xba,0xbb,0x15,0xef,0xc1,0x07,0x18,0x44,0x3f,0xf4,0x48,0x3e,0x7b,0xa4,0x9e,0x14,0x6b,0x97,0xdd,0x68,0x33,0x18,0xdd,0x47,0x08,0xa6,0x3b,0x8d,0x79,0x58,0x92,0xd9,0xda,0x82,0x34,0xa7,0x99,0xbc,0x43,0xa3,0x0a,0x7e,0x85 +.byte 0x0b,0xab,0x0e,0xc2,0x94,0x22,0x2d,0x05,0x99,0x9d,0x5c,0xc7,0xb2,0x7b,0x18,0x3e,0xb2,0xdd,0x47,0xb3,0xd7,0xcf,0x19,0xc7,0x55,0x5e,0x64,0xd8,0x7b,0xb4,0xf6,0x11,0x72,0xed,0xbd,0xfc,0xd8,0xe9,0x9f,0xcd,0x9a,0xeb,0xb2,0x6c,0x04,0xb9,0x88,0xf7,0x60,0x68,0xc3,0xf2,0xfd,0xa0,0x8c,0x82,0xc5,0xf7,0x5d,0xc3,0x9a,0x1e,0x49,0x27 +.byte 0x69,0x35,0xb0,0x8f,0xe9,0xb3,0xe4,0x09,0xd8,0x1a,0x73,0x9e,0x56,0x41,0xfa,0xe0,0x94,0x9e,0x0e,0x65,0xe6,0x5b,0xe2,0x12,0x39,0xca,0x86,0x0c,0xae,0xee,0x24,0x58,0xfd,0x85,0x09,0x7a,0xad,0x54,0xde,0xda,0x06,0x73,0x7d,0x11,0x7e,0x91,0x44,0xf3,0x4b,0x61,0xce,0x8a,0xff,0x76,0x92,0x2e,0x43,0x52,0xcf,0x63,0x3f,0xc4,0x1f,0x7f +.byte 0x4d,0x67,0x21,0xed,0xd7,0x88,0xdb,0x36,0x56,0x11,0xb2,0x3b,0xee,0x5f,0x2d,0x5f,0x17,0x98,0xa1,0xd5,0xcc,0x82,0xfd,0xc2,0x56,0x69,0xaa,0x68,0x86,0xaf,0x48,0x77,0xba,0xe9,0xd9,0x42,0xcd,0xaa,0xe3,0xad,0x2b,0x17,0xef,0xd3,0x54,0xc5,0x4e,0x31,0x0b,0x14,0xb7,0x73,0xc1,0x6f,0xc3,0x06,0x41,0x1a,0x11,0x19,0x9f,0xe9,0x9f,0x61 +.byte 0x4f,0x13,0x9b,0x3e,0xcd,0x7c,0xd6,0x2a,0xb3,0x87,0x84,0x58,0x58,0x10,0x1f,0xa0,0x2e,0x5c,0x15,0x8b,0x5e,0x37,0xd4,0x22,0x93,0xd9,0x67,0xe1,0xa8,0x35,0xe2,0x95,0xd8,0x4c,0x2c,0x65,0xc9,0x21,0xaf,0xf9,0xdd,0x3d,0x2c,0x0e,0x0c,0xcc,0x6b,0xad,0xb3,0x6d,0xd2,0x3e,0x65,0x8e,0x82,0x70,0x41,0xd6,0xaa,0x97,0xab,0x38,0x78,0xe4 +.byte 0x62,0x7c,0x5f,0x22,0xa3,0x1e,0xf2,0x6c,0xfe,0x3c,0xa9,0xb5,0x57,0xcd,0x96,0x11,0xd0,0x8b,0xcf,0x6d,0x06,0xcf,0x7c,0xda,0x1d,0xe4,0x22,0x5c,0x5d,0x9f,0xa8,0x24,0x55,0x45,0x93,0xc6,0xeb,0xfc,0xb5,0x71,0x5a,0x1d,0x52,0x40,0x95,0xc7,0x76,0x32,0xfb,0x2b,0x0c,0x7d,0x64,0xfa,0x5b,0x5e,0x7a,0x3b,0x0b,0xa0,0x99,0x5d,0x19,0x16 +.byte 0xe4,0x8e,0xae,0x49,0xee,0xc5,0xb2,0x24,0xd7,0x0b,0xa4,0x20,0xa6,0x74,0xc4,0x36,0x1d,0x43,0x25,0xd6,0x71,0x54,0x69,0x79,0xea,0xa3,0xd5,0xe9,0x75,0x53,0xcf,0x99,0x4e,0x3b,0xc0,0x52,0x28,0x80,0xe5,0x07,0x65,0x83,0xb3,0x24,0xfe,0x13,0x92,0xd6,0x18,0xf7,0xa3,0xeb,0x9e,0xf0,0xd5,0x69,0x93,0x79,0xda,0xb7,0x2e,0xe2,0x01,0xdd +.byte 0x9a,0xc3,0x7b,0x3b,0x17,0x88,0xe5,0xe9,0x9b,0x46,0x5c,0x5f,0x0e,0x1e,0x80,0x9b,0x11,0x1f,0xa4,0x08,0x90,0x14,0x08,0xb4,0x73,0x32,0x72,0xbe,0x43,0x4f,0x70,0x90,0xe7,0x80,0xdd,0xfd,0xa7,0xea,0x13,0xd9,0x5d,0xae,0x93,0x24,0x2b,0x1e,0xc7,0xf4,0x81,0xbb,0x5f,0xb0,0xb9,0xe4,0x35,0x39,0xf4,0x9a,0x49,0xb5,0xc0,0x47,0x18,0xc3 +.byte 0xcc,0xbe,0x26,0x36,0x44,0x2d,0x65,0x24,0xa3,0x09,0xde,0x69,0x3b,0xb8,0xdc,0x52,0x98,0x2e,0x38,0x5f,0xf7,0xb1,0x84,0xdd,0xea,0xe2,0xe5,0xec,0x96,0x31,0xb1,0x93,0xc0,0x5b,0xc4,0x87,0x4a,0x51,0x58,0x2d,0xea,0x47,0xab,0xfd,0xd3,0x76,0xf1,0xbc,0x52,0xa7,0x94,0x6c,0x74,0x1e,0x84,0x07,0x1f,0x5c,0x18,0xb9,0x06,0x37,0xf0,0xfb +.byte 0xbd,0x5d,0xaf,0xa8,0x06,0xc9,0x86,0xf0,0xd1,0x78,0x84,0x95,0x01,0xdd,0x70,0x9d,0x71,0x51,0xb7,0x80,0x69,0xbe,0xe8,0xfb,0x8f,0x43,0x72,0xd9,0xa9,0xf1,0x90,0xbb,0xf1,0xb5,0xc0,0x75,0x93,0x4e,0x14,0xc5,0x14,0x77,0x59,0xf8,0xe5,0x81,0x11,0x25,0x48,0x51,0x46,0x2a,0x69,0x59,0x92,0xe7,0xa7,0x39,0x96,0xad,0x67,0x30,0xaa,0xb2 +.byte 0x5d,0x95,0x94,0x83,0x83,0x93,0xf3,0x52,0x81,0x1c,0x27,0x78,0x1d,0x19,0x35,0x6e,0x8f,0x16,0xe5,0x3b,0xce,0x80,0x2a,0x3a,0x89,0xb7,0x51,0xfc,0x34,0x24,0xa2,0x61,0x95,0x9e,0xd4,0x69,0xa1,0x2f,0x49,0x16,0x2d,0x12,0x05,0xfe,0x69,0x62,0x12,0xa4,0x2c,0x04,0x7b,0xce,0x3f,0x34,0xc4,0x48,0x1a,0xe6,0x64,0x4b,0x8a,0xbf,0x68,0xdd +.byte 0x54,0x15,0xd3,0x25,0x49,0xdd,0xed,0x5e,0x2c,0x0e,0x25,0xbe,0x77,0xcf,0x94,0xf4,0xe9,0xf3,0xcc,0xe6,0x94,0xf9,0xb2,0x5d,0x24,0x53,0x63,0xbb,0x66,0x8d,0x73,0xef,0x79,0x5c,0x95,0x1a,0x64,0xc3,0xfd,0xc0,0xd3,0x71,0xf4,0x79,0x19,0x79,0xa5,0x30,0xf8,0x2c,0x28,0xc2,0xc2,0x9d,0x12,0x50,0x95,0x38,0xec,0xd5,0xc6,0x28,0x94,0xaa +.byte 0x83,0x66,0x3b,0xe3,0x51,0xc7,0x6a,0x75,0x2a,0x9b,0xb9,0xb0,0xa2,0xe1,0xfd,0xaf,0x58,0xd2,0x4b,0xf4,0x22,0xef,0x77,0x1e,0xa0,0x00,0xd7,0x9e,0x20,0x63,0x87,0x1d,0x98,0xab,0x0e,0x57,0x31,0x4b,0xda,0x90,0x3a,0xe6,0x6e,0x5e,0xd4,0x17,0x06,0x83,0x4f,0x90,0x33,0x1c,0xe5,0xea,0xf7,0x8d,0x95,0xa2,0x1e,0x7d,0x27,0x15,0x49,0x68 +.byte 0x3a,0x54,0xe3,0x1e,0x60,0x72,0x42,0xa6,0x8c,0x5b,0x63,0x1d,0x7d,0xb1,0xe2,0x7e,0x8b,0x19,0xf4,0x25,0x6c,0x77,0x64,0x15,0x5e,0x4c,0xfa,0x35,0x68,0xd2,0x54,0x11,0x5a,0xac,0x85,0xb0,0xb3,0xe8,0xa8,0x70,0x36,0xa8,0xe5,0x04,0xd1,0x82,0xdc,0x62,0x63,0xe6,0x3f,0x86,0x46,0x77,0x08,0x6b,0xa8,0x09,0xd0,0x56,0x09,0x87,0x9c,0x65 +.byte 0x8e,0x53,0xae,0xa6,0x2b,0x59,0x23,0xca,0xe9,0xc7,0xc4,0xb5,0xb9,0xca,0x20,0xf6,0xcc,0x62,0xfd,0xb5,0x66,0x66,0x86,0x99,0xb2,0x5a,0xeb,0xac,0xff,0x22,0xf4,0x94,0x9c,0x6d,0xc9,0xce,0xf3,0x8d,0x26,0x7f,0x06,0x40,0x71,0x8b,0x3e,0x5c,0x3e,0xe6,0x11,0x64,0x91,0x79,0xbe,0x66,0x80,0xd2,0xf6,0x2d,0x28,0x4b,0x6c,0x8d,0x9c,0x5b +.byte 0x1e,0xd1,0x15,0xb0,0xdf,0xfb,0x57,0xaf,0x4a,0xab,0xde,0x12,0xe9,0xb8,0x41,0x3d,0xc3,0xff,0xb2,0xc1,0x86,0xb0,0x06,0x5b,0xaf,0xa4,0x30,0x62,0xd0,0xd8,0x91,0x36,0x28,0xc1,0xc2,0xef,0x60,0x5d,0x42,0x04,0xd5,0x6b,0x10,0xa9,0x6c,0x88,0x5c,0x56,0x59,0x4a,0x87,0xdc,0x7c,0x41,0x03,0xb3,0x7c,0x35,0x8c,0x52,0x0e,0xc1,0xd5,0xdf +.byte 0x9b,0x8a,0x2e,0xc2,0x6b,0x06,0x7f,0xb4,0x93,0xc9,0x52,0xd0,0xc5,0x57,0x78,0x9e,0xf9,0x08,0x36,0xbc,0x4b,0xc1,0xbd,0x71,0x35,0xf8,0x73,0xae,0x9c,0xbc,0xf1,0xd1,0xba,0xe3,0x7f,0x49,0x9b,0x9b,0xb3,0xe2,0x7d,0x7d,0x18,0x6d,0x0d,0x96,0xe3,0x50,0x28,0xf2,0x7c,0x7a,0x71,0x27,0x33,0x3c,0xd3,0xeb,0x3d,0x5a,0x79,0xb5,0x69,0xed +.byte 0x40,0x38,0xbe,0xc9,0xad,0x11,0x7b,0x9d,0xe6,0x71,0xc8,0x89,0x54,0x51,0xf0,0x8f,0xdc,0xad,0x96,0xc3,0x04,0x60,0x5f,0x6d,0xa0,0x37,0xba,0x1c,0x69,0xca,0x42,0x26,0xeb,0x31,0x34,0x8d,0xae,0x25,0xe2,0x29,0x8d,0x19,0x9f,0xfa,0x75,0x91,0x4b,0x51,0xcd,0x76,0xd6,0x8f,0xa2,0x40,0x79,0xc3,0xbb,0x61,0xaf,0xc4,0x69,0xf5,0x8b,0x8a +.byte 0xb6,0x2c,0x25,0xb9,0x3c,0x8e,0x13,0xa4,0x0f,0x52,0x72,0x11,0x4b,0x89,0x63,0x01,0x05,0x54,0xd5,0x0d,0x5f,0x91,0x59,0x84,0x64,0xac,0xf7,0x9c,0xa3,0x48,0x31,0x4a,0x2e,0xea,0xf8,0xf8,0x0e,0xf0,0xd9,0x4d,0x06,0x60,0x11,0x4a,0x72,0x6f,0x93,0x93,0x85,0xf0,0x20,0x55,0x8b,0x37,0xf1,0x29,0x92,0x2d,0x1f,0xa1,0x6c,0x7c,0x90,0x4f +.byte 0xdb,0x78,0xcc,0x6c,0xb2,0x14,0x85,0x07,0x34,0xc8,0x98,0x18,0x52,0x2d,0x6b,0x13,0x63,0xc5,0x31,0x20,0x8e,0xa9,0x88,0x6b,0xb3,0x3f,0x1a,0x68,0x2f,0xf9,0xf3,0x97,0x29,0x68,0x22,0x89,0xb0,0x45,0xc4,0xf4,0x1f,0x31,0xba,0x97,0x14,0x59,0xae,0x05,0xe0,0x99,0x5b,0x29,0xcf,0xe3,0xf0,0x2a,0x0c,0xca,0x5f,0xc1,0xe7,0xe7,0x11,0x48 +.byte 0x73,0xc0,0x86,0x0b,0x59,0xc2,0x8a,0xfa,0x44,0x51,0x1c,0x84,0xdf,0x2f,0x4d,0xab,0xca,0xea,0xe1,0x48,0x9a,0xa1,0x86,0x60,0x47,0x7a,0x86,0x30,0x6a,0xba,0xbe,0x6a,0x9b,0x34,0xf4,0x52,0x0e,0xae,0x7f,0xbd,0xe0,0xf4,0x5f,0xfd,0xbc,0x57,0x02,0x95,0x6f,0xad,0x78,0x2e,0xa7,0x46,0x1c,0x2d,0x98,0x40,0xb7,0xfa,0xb5,0x08,0xee,0xb5 +.byte 0x25,0x51,0xaa,0x1a,0x14,0x41,0x48,0xe0,0x8f,0xe7,0x2f,0xfc,0xfd,0x47,0x10,0x55,0x90,0x02,0xeb,0x7f,0x0d,0x40,0xa8,0x4b,0x82,0xdc,0xab,0x43,0x35,0x62,0xa1,0x1d,0x5a,0xb0,0xc0,0x93,0x75,0x3d,0x68,0xd9,0xf8,0x31,0x22,0xfd,0x30,0xda,0xea,0xea,0x7c,0x30,0xf8,0x6f,0x75,0x5f,0x07,0x39,0xfe,0x69,0x93,0x73,0x22,0xa2,0x72,0xed +.byte 0x39,0x2f,0x00,0x5c,0xc3,0x14,0x86,0x90,0xda,0xc9,0x09,0x43,0x80,0x85,0x22,0x98,0xb0,0x4e,0x05,0x47,0x8f,0xc7,0xba,0x2e,0x4c,0x8f,0x57,0x8a,0xe9,0xb0,0x97,0x3b,0x51,0x12,0xcb,0x88,0xfd,0x5e,0x7f,0xa6,0xc6,0x00,0xd0,0x3a,0x3a,0x70,0x9e,0x56,0x28,0xa0,0x08,0x76,0x58,0x57,0x4a,0x0f,0xff,0x31,0x44,0x08,0x6c,0x23,0x79,0xad +.byte 0x35,0x95,0xc5,0xc8,0x26,0x0f,0xb3,0x17,0x04,0x1d,0xde,0x16,0x5d,0xb8,0x71,0x76,0x89,0x0b,0xd6,0xd8,0x9d,0xa1,0xdf,0xcb,0xb5,0x1c,0x86,0xc3,0x15,0x8d,0xaa,0x25,0x82,0xbf,0x6b,0x06,0xfb,0x1b,0xf5,0x11,0xaa,0x14,0x0e,0x67,0x7f,0xbd,0x46,0x21,0x8f,0x6d,0xbd,0x63,0xe6,0x14,0x05,0xa2,0xee,0x56,0xee,0xe6,0x37,0xf9,0xc0,0x2f +.byte 0xc9,0xe0,0x8e,0xdb,0xf7,0xf6,0xcb,0x83,0x79,0xcc,0xe3,0xf6,0x30,0x9d,0x56,0x31,0x40,0xd2,0x50,0x25,0xb6,0x89,0x16,0x97,0x65,0xd8,0x8d,0x1a,0xa5,0xf4,0x47,0xfc,0x4c,0x73,0x07,0x42,0x9c,0x8f,0x7f,0x10,0xb4,0x96,0x33,0x1e,0xe2,0xff,0x0c,0x33,0x35,0xbc,0x37,0x01,0x2b,0x67,0xda,0xca,0xcf,0x87,0xa2,0x38,0x71,0x6b,0xf4,0xcf +.byte 0xa6,0xc6,0x6a,0x90,0x5c,0xa0,0x8b,0x66,0x44,0xc7,0xc2,0x05,0x24,0xee,0x53,0x99,0xf3,0x07,0x78,0xb0,0x17,0xf8,0x11,0xf9,0x52,0x20,0x41,0xc5,0xdb,0x4e,0x92,0xd3,0xeb,0xd2,0x86,0xea,0x9b,0xc3,0x4c,0x1b,0x75,0xcd,0x15,0x0c,0xe0,0x28,0xe9,0xe1,0x99,0x98,0x96,0x33,0x06,0xea,0xa8,0x4e,0xde,0xc1,0x1c,0xfe,0x6c,0xca,0xac,0x6d +.byte 0xc4,0x3a,0x7d,0xd2,0x41,0xf5,0xb3,0x7d,0x1c,0x28,0x93,0x72,0xf8,0x08,0xc1,0x71,0x72,0x4c,0x41,0x68,0x38,0x80,0x2e,0x4b,0xa6,0xc5,0xc7,0xb4,0x24,0x29,0xd0,0xce,0xb2,0x3d,0xc4,0x60,0x5b,0xeb,0x2d,0x80,0x13,0xee,0x95,0x41,0xfe,0x49,0x6d,0x89,0xc0,0x7a,0x61,0x51,0x3f,0xbb,0x24,0x7c,0x64,0x5e,0x9f,0xf7,0x60,0x88,0x95,0xe8 +.byte 0x60,0xc5,0xf6,0xc3,0xc3,0xd4,0x43,0xce,0xf9,0x4e,0x35,0xf2,0xfa,0xb0,0x2b,0xe3,0xfe,0xb8,0x88,0x19,0xf2,0x89,0xc0,0xb5,0x00,0x61,0xc8,0xe5,0xaa,0xde,0x18,0xb4,0xd4,0x21,0xbe,0xcc,0x61,0xc7,0xc9,0xfe,0x22,0xcc,0x65,0xf6,0x79,0xe8,0x4d,0x1c,0x30,0x31,0x7a,0xd4,0xbc,0x98,0x2d,0x72,0x5e,0x5c,0x4f,0x7e,0x52,0x9c,0x95,0x20 +.byte 0x29,0xa4,0x0b,0xf7,0xb2,0x7d,0xcc,0xc3,0x8c,0x94,0xb0,0x09,0xf4,0x6f,0x59,0x63,0x91,0x2a,0x06,0x80,0x09,0x01,0x3c,0x73,0x83,0x42,0xa1,0x5c,0x0f,0x42,0xf4,0x74,0x3c,0x24,0x8c,0xbe,0x91,0x73,0xdf,0xf1,0xea,0x21,0xbd,0xc9,0x36,0x17,0xca,0x81,0x28,0xd9,0x4a,0xc4,0x2e,0xdf,0x4c,0x4f,0xbd,0x1e,0xbc,0xe9,0x32,0x12,0xd3,0x8f +.byte 0x48,0x9b,0x4f,0x49,0x23,0x54,0x15,0x15,0x14,0x8b,0x18,0x64,0x7d,0x08,0x7f,0xc4,0x56,0x01,0x94,0x4e,0x50,0xe8,0xf2,0x4a,0xb5,0x3c,0xa0,0xb5,0xaf,0x55,0x70,0x44,0x41,0x5c,0xe6,0x61,0x5a,0xbb,0xf2,0xe6,0xc9,0x05,0x33,0x45,0x8f,0xbc,0xe5,0x59,0x7f,0x66,0xc5,0x61,0x4d,0x1b,0xc7,0xee,0x45,0x7d,0x57,0x8f,0x6c,0x9d,0x8b,0x87 +.byte 0x98,0xa8,0x58,0xac,0x4a,0x31,0x79,0xd6,0x26,0x08,0x2f,0x28,0x3f,0x31,0x77,0xad,0xff,0xe1,0x9d,0xa8,0xf7,0xe0,0x76,0x66,0x48,0x00,0x52,0xe8,0x9a,0xb2,0x47,0x5e,0x0a,0x87,0x86,0xaf,0xf6,0x7d,0x46,0x78,0x66,0x68,0xf7,0x68,0x0c,0x6f,0x5c,0xd7,0x09,0xc0,0xd7,0x90,0x98,0xe2,0x5c,0x07,0xe9,0xd1,0x58,0x48,0x57,0x9f,0x48,0x99 +.byte 0x87,0xdf,0x06,0xc1,0x35,0x0f,0xd8,0xb0,0xa9,0xfa,0xdc,0x31,0x76,0xd1,0xad,0x47,0x80,0xe4,0x74,0xe0,0xda,0x4b,0x77,0x8b,0x71,0xab,0x9a,0x8e,0xd7,0x6b,0x91,0xb1,0xdb,0x78,0xd2,0x86,0xf7,0x61,0x1b,0xdc,0x34,0x57,0x32,0x51,0xee,0xd3,0xff,0xb2,0x6c,0x6a,0x79,0x90,0x9c,0x1f,0x6b,0xe7,0x43,0x20,0x05,0x4f,0x66,0x83,0xd0,0x56 +.byte 0xe1,0x21,0x63,0xf4,0xd6,0x96,0x91,0xcb,0x51,0x3c,0x13,0x88,0x97,0x26,0x88,0xda,0x7c,0xd4,0x0d,0xcb,0xdf,0xc2,0x7d,0xcd,0x2c,0x0e,0x28,0x23,0x21,0x5f,0xbe,0x5d,0x62,0x58,0x6c,0xa7,0x45,0xae,0x1f,0xac,0x35,0x53,0xdb,0x2c,0xa6,0x71,0xe4,0x11,0x5e,0x59,0xbe,0xd5,0x20,0x2a,0xc4,0xcd,0x4c,0x1b,0xe0,0x38,0xef,0x02,0x0c,0x5f +.byte 0x5a,0x1b,0xf9,0x1e,0x32,0x63,0xd7,0xa6,0x0f,0x1d,0x98,0xd5,0x3a,0x0f,0xf6,0xcc,0xfc,0xd6,0xb4,0x87,0xc5,0x76,0xd8,0x3e,0x72,0xb0,0x20,0xfe,0xb3,0xfc,0x48,0x4c,0xd1,0x71,0xcd,0x13,0xef,0xe8,0x40,0xd9,0x0d,0xf6,0x1d,0x5b,0xa4,0x26,0x56,0x8c,0x66,0xcb,0x18,0x5a,0x5f,0x86,0x43,0x2c,0xa4,0x1e,0x00,0x3f,0x09,0xbf,0x8e,0x61 +.byte 0xad,0x2a,0x44,0x97,0x35,0xb2,0xf3,0x50,0x5f,0xfa,0x01,0x74,0xbf,0x70,0x46,0x38,0xf1,0x15,0xaa,0x04,0xfe,0xe9,0x3f,0x43,0x2f,0x53,0xcb,0xea,0x5c,0x04,0x8e,0xe6,0x43,0xeb,0xc0,0xd9,0xbf,0x4a,0xc1,0xbc,0xf9,0x11,0xd5,0x33,0xdc,0x41,0x8e,0xfe,0x5e,0xf3,0x8c,0x80,0x47,0x46,0x01,0x9e,0xa9,0x2c,0x2d,0xd2,0x90,0x7f,0xce,0x7c +.byte 0x59,0x78,0xaa,0xbb,0x96,0x52,0x0a,0xf3,0x18,0x1f,0x0b,0x41,0xc1,0xd5,0x12,0x14,0x1a,0xe1,0x4e,0xac,0xf8,0x2a,0x56,0xfe,0x66,0x34,0x21,0xdf,0x1f,0x6a,0x02,0x85,0xd2,0x38,0xc0,0x39,0x5c,0xa7,0x3f,0xcc,0x2b,0x6f,0x69,0xe7,0xa7,0x0a,0x36,0xf1,0xa9,0x77,0x59,0x2c,0x44,0x8b,0x72,0xc9,0xc2,0x74,0x32,0x48,0x76,0x19,0x1e,0x49 +.byte 0x10,0xe6,0x46,0xdf,0x82,0x9b,0xad,0x4e,0x40,0x20,0xd7,0xd3,0xf5,0x5c,0xbc,0x25,0x94,0xd1,0x68,0xaf,0x29,0xc5,0xcd,0x1b,0x86,0x4b,0x88,0x21,0x6e,0xeb,0x06,0x14,0xb5,0x15,0xe7,0x26,0x01,0x05,0x4e,0x3a,0x2a,0x24,0xbe,0xf2,0x64,0x6e,0xf4,0x9c,0x60,0xf8,0xd4,0xfd,0x4b,0xc0,0x0e,0x68,0x0d,0x19,0x26,0x87,0xa5,0xbf,0xe1,0x16 +.byte 0xf0,0x27,0x58,0xa8,0x3a,0xed,0x27,0x5b,0x73,0x4f,0x19,0x40,0x58,0x36,0xf6,0xfd,0x60,0x37,0x09,0x74,0x3c,0xb9,0x76,0x9a,0x32,0xfd,0x98,0x79,0x53,0xb3,0xea,0x3a,0x98,0x21,0xf9,0xb2,0x97,0xe4,0x00,0xb6,0xed,0x67,0xc4,0x76,0x8f,0x1e,0x4d,0xc8,0x2e,0xf4,0x54,0xd9,0x09,0xd7,0xcb,0xa0,0x91,0x1e,0x5a,0x60,0x53,0xbc,0x3e,0x35 +.byte 0x69,0xa6,0xca,0xf3,0xce,0x41,0x84,0x71,0xee,0xf3,0x75,0xd4,0x7a,0x71,0x36,0x62,0xe3,0x08,0xae,0x40,0x05,0xde,0x01,0x34,0x92,0x5f,0x71,0xa9,0x08,0xb3,0x43,0xcd,0xe7,0x2f,0x42,0x7e,0x9c,0x1e,0xfe,0x9a,0x40,0x99,0x58,0x31,0xd9,0x8d,0x5d,0xda,0x75,0x14,0x3f,0xae,0x45,0x27,0x85,0x47,0x7d,0x41,0x0e,0x94,0x20,0xee,0x11,0xd0 +.byte 0x1e,0xcd,0x00,0x56,0xb7,0x59,0xe6,0x58,0xab,0x2c,0xa6,0x44,0x14,0x8c,0xff,0x49,0x7b,0xe5,0xf7,0x93,0xd5,0x78,0x1a,0xe0,0x16,0xd8,0x24,0x08,0x1e,0x70,0xce,0x1a,0x84,0x87,0x6b,0xe5,0xf2,0x43,0x5f,0xb3,0x34,0xaa,0x85,0x3e,0x9e,0x2e,0x86,0x22,0x74,0xe2,0x1a,0x87,0xfb,0x1b,0x6c,0x08,0x8c,0x43,0xb4,0x85,0x75,0x2c,0x13,0xc2 +.byte 0x18,0x94,0xe8,0x0d,0x09,0xd5,0x8f,0xd4,0xca,0x50,0x93,0x9f,0xa3,0x9f,0x3b,0x3c,0x54,0x68,0xa9,0xb1,0xdd,0x0a,0x0b,0xe2,0x15,0x92,0x9c,0x6f,0xfa,0x45,0x6f,0x0a,0xb4,0x6b,0xcb,0xdc,0xa4,0xf3,0xf0,0xa6,0x1c,0x8a,0x60,0x42,0x35,0xa8,0xe3,0xdf,0xc8,0xdc,0xbb,0xbe,0x95,0xa7,0xac,0x08,0x08,0xbc,0x56,0x1a,0xa4,0xc2,0xd2,0x53 +.byte 0xfa,0xb2,0x89,0x4f,0xb8,0xe4,0xb9,0x90,0x95,0x91,0x2f,0x0f,0x93,0xa9,0x8c,0xc6,0xf8,0x01,0x34,0x08,0xe6,0x8c,0x58,0x43,0x57,0x40,0xf9,0x78,0x83,0xea,0x92,0x70,0xa8,0xa5,0xc8,0x9e,0xf8,0xc6,0x39,0x4c,0xb4,0xe9,0xbb,0xdf,0xd2,0x52,0x43,0x6b,0x6c,0x8b,0x2c,0x47,0xd7,0x11,0x42,0x3d,0xc7,0x3f,0xce,0xd1,0xd9,0x28,0x5b,0xce +.byte 0xec,0xb6,0x31,0x3a,0xc9,0xad,0x0c,0x93,0x82,0x2b,0xf6,0xdc,0xd4,0xcd,0x80,0xe1,0x75,0x45,0xeb,0x3b,0xbf,0x12,0x42,0xeb,0x71,0xc1,0x8b,0x27,0xd5,0xcb,0xd9,0xb6,0xe8,0xe9,0xc6,0x79,0xff,0x38,0x88,0x87,0x72,0xf2,0x71,0x4a,0x44,0x55,0x0f,0x9c,0x93,0xcf,0x15,0x18,0x44,0x62,0x2a,0xc5,0x0a,0x80,0x69,0x91,0x6e,0x4b,0x30,0x4e +.byte 0x3f,0x2f,0xb5,0x65,0x9e,0x65,0x07,0x36,0x9b,0xba,0x5f,0x81,0xd9,0x60,0xbe,0x1f,0xf5,0x98,0x20,0xf9,0x9e,0x53,0xf7,0x5d,0x57,0x7f,0x22,0xaf,0x8e,0x82,0x9e,0x0f,0x33,0x74,0x37,0x26,0x61,0x67,0xf6,0xfd,0x2c,0xab,0xd8,0x18,0x1d,0x10,0x48,0x7a,0x1d,0xed,0xbb,0x57,0x83,0xf9,0x82,0xf5,0xe3,0xf9,0x98,0x5c,0xc0,0x3e,0xee,0x38 +.byte 0x0a,0x57,0x10,0x22,0xc4,0xe8,0x1d,0xe3,0x46,0xa3,0x81,0x5e,0x92,0xba,0xcc,0x53,0x48,0x85,0x33,0x58,0xa2,0x3e,0xea,0x0a,0xfb,0x72,0x5c,0xcd,0xd9,0xa4,0x3f,0x56,0x99,0x35,0x92,0x6c,0xe8,0xf2,0x59,0x0f,0xc8,0x6a,0x21,0xb2,0x9f,0xa2,0xf6,0xf3,0x1b,0xec,0x38,0x95,0xed,0xef,0x00,0x09,0x16,0x6e,0xf7,0xf8,0x1a,0xef,0x0d,0x2b +.byte 0xef,0x83,0x8a,0xc2,0x22,0x3d,0x50,0xa3,0x70,0x52,0xe8,0xad,0x11,0x44,0x83,0x80,0xfe,0x88,0x7e,0x40,0x02,0x8f,0x4a,0x5d,0xd3,0x28,0x66,0x75,0x5a,0xf2,0x38,0xb5,0xdc,0x54,0xa8,0xb3,0xaa,0x76,0xdb,0x73,0xe0,0xd1,0xd7,0x51,0x20,0x8c,0x38,0x18,0x46,0x25,0x2e,0x0d,0x5b,0x61,0x9d,0x36,0x9a,0x14,0xfb,0xc8,0x4e,0x5a,0xba,0xa1 +.byte 0x98,0x34,0xfd,0x05,0x2c,0x87,0x58,0x8d,0xe3,0x5d,0x79,0x5a,0x45,0xff,0x75,0x25,0x98,0xbd,0xe4,0x9d,0x1a,0x70,0x79,0xaa,0x44,0x1a,0x10,0x7f,0xfb,0xe9,0x30,0x81,0xc7,0xa2,0x81,0x41,0x49,0x41,0x4e,0x42,0x5f,0x8a,0x9b,0x10,0xe2,0xdc,0xd9,0xdf,0xbd,0x61,0x29,0x72,0xa5,0x39,0xb7,0xf6,0x9f,0x4e,0x98,0xb8,0x04,0xae,0xd7,0xda +.byte 0x9a,0x9f,0x08,0xb8,0x2c,0x40,0x14,0x6d,0x01,0xb7,0x86,0x58,0x55,0x42,0xe5,0xdb,0x5f,0x4a,0xef,0xd8,0xed,0xdf,0x3b,0x24,0x1c,0xe4,0xb1,0x73,0xd1,0xce,0x29,0x96,0xde,0x8e,0xf3,0x1d,0x8d,0x75,0x57,0xd3,0x9a,0xf8,0xff,0x1a,0x4c,0x0c,0x47,0x82,0x83,0x73,0x34,0x43,0x55,0xfa,0xf2,0xd4,0x38,0xed,0xde,0x6d,0x24,0x55,0x90,0x06 +.byte 0xd6,0x03,0x52,0x28,0xc7,0x38,0x4a,0x16,0x95,0x4d,0xf4,0x46,0x56,0xf7,0x63,0x1f,0xe4,0xa9,0x51,0xc6,0x0b,0x85,0x42,0x40,0x8e,0x49,0x1e,0xc2,0xab,0xeb,0xda,0x99,0x26,0xf6,0x6e,0x00,0x8f,0x26,0x82,0xef,0x03,0xb0,0xd4,0xdb,0x54,0x46,0xdf,0xdc,0x23,0xaf,0xa8,0x6a,0x9f,0xb7,0xf9,0x41,0x07,0x5e,0x2d,0xcf,0x85,0xfd,0x9c,0x46 +.byte 0x30,0xb9,0x14,0xca,0xe2,0x30,0x12,0x06,0x88,0x08,0x05,0x2c,0x9a,0x4b,0x52,0x98,0xa9,0x99,0xd7,0xca,0xb5,0x1e,0x60,0x44,0xd9,0x5c,0x19,0x42,0xbe,0xa5,0x04,0xfd,0x7a,0xfc,0xb9,0xdf,0xd6,0xe3,0x6d,0x02,0xe3,0x96,0xf6,0xae,0xf3,0x78,0x1d,0x90,0x6d,0x86,0x17,0xf7,0xb7,0x6b,0x1d,0x52,0x32,0x5b,0xc0,0x31,0xaf,0x09,0x90,0x5e +.byte 0x81,0x75,0x17,0x47,0x6b,0x5e,0x9a,0x40,0xa5,0xa8,0x84,0x60,0xdc,0xdb,0xd2,0x89,0xcd,0xb2,0x72,0xf4,0x74,0xda,0x5d,0x34,0xf8,0xc6,0x1b,0x26,0x3e,0x8b,0xc7,0x73,0xf9,0x0c,0x93,0xf4,0x40,0x02,0xe0,0xed,0xe5,0xa0,0xae,0x91,0x03,0x85,0xa8,0x2f,0xe2,0x72,0xfe,0x17,0x7d,0x2b,0xa6,0x39,0x10,0x80,0x4c,0x58,0xaa,0xd8,0x22,0x7d +.byte 0x2f,0xbf,0x0c,0x40,0x48,0xfa,0xbe,0x40,0x4c,0x32,0x96,0x69,0xa5,0xab,0x0b,0x1e,0x33,0x9b,0xcf,0xe6,0x4e,0x2b,0x41,0x5a,0x21,0x23,0xa1,0xbb,0xd3,0xd6,0xd1,0xfd,0xbd,0x55,0xfc,0x92,0x92,0xcb,0x4b,0x72,0x39,0x8b,0xeb,0x72,0xdd,0xf7,0x77,0x43,0x52,0x2f,0x99,0x14,0x6e,0x41,0xce,0x1d,0x57,0x2c,0x09,0xd2,0x18,0xec,0x1b,0x89 +.byte 0xa0,0xe9,0xfe,0x1e,0x41,0xda,0x0f,0x76,0x02,0x38,0xec,0x9a,0x30,0xb7,0x5a,0x54,0x70,0xbc,0xe8,0xfa,0x06,0xd0,0x80,0xfb,0x27,0xd2,0xd8,0x00,0x80,0x65,0x9d,0x23,0xfd,0xad,0x26,0xb8,0xdc,0x09,0x4f,0xfb,0x52,0xcd,0xe4,0x41,0x68,0xca,0xdd,0xbc,0x2a,0x62,0xeb,0xa6,0x32,0x71,0xb0,0x08,0xb6,0x9f,0x3e,0x74,0xfe,0xb0,0xd4,0x9d +.byte 0x9e,0x6c,0x50,0x96,0x8a,0xde,0xd6,0xe9,0xde,0x2c,0xa6,0xf0,0x9f,0x67,0x00,0x50,0x0a,0x8c,0xe5,0xc2,0x37,0xcc,0xf0,0x53,0xeb,0x72,0xf2,0x87,0x77,0xee,0x80,0xe8,0xb2,0xa1,0x13,0x52,0x70,0xe6,0x8f,0x70,0x17,0x90,0x60,0xcb,0xac,0xb2,0x72,0xef,0xd9,0xb5,0xc3,0x68,0x57,0xdf,0x2d,0xcb,0x5a,0x35,0xf9,0x2e,0xfb,0xef,0x6e,0x77 +.byte 0x5d,0x21,0x37,0x4b,0x36,0x9b,0x3f,0x03,0x65,0xc9,0x84,0xb1,0x12,0x99,0xd1,0x6b,0x00,0x71,0x37,0xc7,0x57,0x82,0x44,0x7f,0xe1,0x81,0x24,0x70,0x96,0xd5,0x27,0xba,0x36,0xf7,0x25,0xc6,0x1c,0x7c,0x1b,0xdb,0xa3,0x6a,0x3e,0xb9,0x69,0x78,0xf7,0x51,0x46,0xe2,0x74,0xd3,0xfc,0xef,0x58,0x63,0x53,0x1d,0xd7,0xd0,0x8a,0x6a,0xd3,0xb0 +.byte 0xb9,0xbb,0xba,0x43,0xbf,0x8b,0x6b,0x04,0xd2,0xb1,0xe8,0xd1,0x72,0x3f,0xdc,0x2b,0x01,0xa6,0x2f,0x9c,0x7d,0x65,0xa1,0x9f,0x9b,0x4d,0x70,0x26,0x11,0x4c,0xb2,0xe1,0x01,0x0e,0x78,0xf2,0x32,0x87,0x2d,0x8e,0x95,0x02,0x76,0xca,0xe5,0x71,0x5f,0x36,0x35,0xb9,0xbb,0xc3,0xdf,0xf3,0x1e,0x1a,0x7a,0xe4,0x2c,0xdf,0x64,0x5d,0x96,0x12 +.byte 0xea,0x5c,0x14,0x73,0xa0,0xf1,0xbc,0xa9,0x6e,0x30,0x8a,0x47,0xf0,0x4b,0x9b,0x4c,0xc5,0xb0,0xbe,0x15,0x32,0x1b,0xde,0x0c,0x39,0x6a,0x6d,0x4e,0x3b,0x69,0x4c,0xb4,0x1f,0x56,0xf0,0xa1,0xb1,0x8c,0x29,0x5c,0x87,0x54,0xf2,0x5b,0x51,0x03,0x20,0x70,0x90,0x38,0x66,0x07,0xcc,0xd7,0xde,0x96,0x40,0x82,0xee,0xb5,0x87,0x2a,0x86,0xec +.byte 0x66,0x09,0xb7,0x4a,0xfe,0x4e,0x92,0x89,0x07,0xde,0x35,0xc4,0x6e,0x91,0x25,0xfd,0x18,0xfa,0xd9,0x8f,0xa7,0xa6,0xa7,0x6b,0x32,0xba,0xd3,0x1c,0x90,0xb9,0x8a,0x6c,0x9f,0x3f,0xb5,0x16,0x81,0x81,0xee,0xd7,0x55,0xc1,0x41,0x62,0xfd,0xe9,0x4c,0x5d,0xd7,0x70,0xdd,0xc6,0x4a,0x2b,0x42,0x77,0xe7,0x74,0xed,0x02,0x80,0x0d,0x7c,0x73 +.byte 0x8e,0xf0,0xd3,0xb0,0x20,0xbb,0xc8,0x82,0x06,0xdd,0x56,0x64,0xcb,0x9c,0xda,0xa1,0xa9,0x92,0xbc,0x8c,0x65,0x03,0xcd,0x68,0x87,0xa2,0x94,0x41,0x3c,0x36,0x96,0x1f,0xa4,0xd2,0x6d,0x5d,0x9f,0x2d,0x0c,0xf9,0x8a,0x82,0x19,0x93,0x47,0x62,0x71,0x8e,0x59,0xaa,0xf1,0x87,0xe0,0xb8,0xab,0x10,0x7f,0x4e,0xa8,0xa3,0xe2,0x32,0x58,0xb0 +.byte 0xcf,0x12,0xc0,0xf8,0x94,0x4a,0x61,0x36,0xdc,0x2d,0xb5,0x91,0xf9,0x0f,0x7d,0x91,0xd3,0xc7,0x03,0x8a,0xae,0x5c,0x22,0x8c,0x60,0x30,0xf4,0x71,0x51,0x00,0xf5,0x5d,0xe9,0x37,0x6c,0xae,0x64,0xff,0x45,0x35,0x4b,0x47,0x08,0xca,0xda,0x7b,0xe9,0xef,0xcb,0x27,0xcb,0x7e,0x3c,0xa6,0xd2,0x38,0x54,0x74,0xc3,0x7c,0xf8,0x71,0xb7,0x47 +.byte 0xe9,0xe0,0x43,0x03,0x3b,0x41,0x57,0xc3,0xda,0xa1,0xcb,0x64,0xb1,0x31,0x0d,0x12,0x45,0x3a,0xa0,0xad,0x6b,0xc7,0x26,0x62,0x50,0xcf,0x94,0x5a,0x30,0x8d,0xf6,0x91,0x49,0x9e,0xd5,0x84,0x0e,0x0c,0xe3,0x47,0x08,0x7f,0xa1,0x54,0x78,0x1b,0xa8,0x2c,0xbc,0x12,0x4f,0x7e,0x53,0x1b,0xca,0xfb,0x09,0x35,0xe0,0x9c,0x15,0xea,0xf6,0x3e +.byte 0xb2,0x20,0x9e,0x2c,0x81,0x6f,0xa4,0xb5,0x6b,0x04,0x6d,0xd1,0x90,0x66,0x46,0xdc,0x4b,0x71,0x7e,0x4b,0x3f,0xd6,0xe1,0xa8,0xc0,0xa7,0x45,0x85,0xe3,0x98,0x30,0xda,0x23,0x68,0x55,0xd8,0x96,0xb1,0xcc,0xeb,0xe1,0x95,0x0b,0x20,0xf3,0x4c,0xf2,0xc5,0xfa,0x0e,0xca,0xf5,0xc9,0xb3,0xd7,0xb4,0x1b,0x9f,0xef,0x82,0x56,0x4c,0xc5,0xa5 +.byte 0x21,0xda,0xcc,0x19,0x69,0x68,0xcb,0x37,0xb2,0x0c,0x73,0xb1,0x13,0x61,0x6b,0xca,0xda,0xfc,0xf7,0x1c,0xbc,0xd1,0x72,0x56,0xb8,0x7d,0xa1,0xef,0xc4,0x32,0x38,0xa3,0xdb,0x8b,0x2d,0x0a,0xce,0xcb,0x86,0x51,0x60,0xd2,0x47,0xf0,0x97,0x58,0xd8,0xa5,0x12,0x77,0xfc,0x32,0x04,0x29,0x61,0xfc,0xab,0xc2,0x42,0x86,0xd9,0x57,0x80,0xad +.byte 0x00,0xf0,0x9a,0x2a,0xac,0x52,0x27,0xd6,0xf8,0xd6,0x38,0xc8,0xfc,0xc1,0xab,0x4f,0x41,0xbf,0x8e,0x60,0x20,0xeb,0x24,0x36,0xd8,0xd8,0x25,0x6f,0xc8,0x5d,0x6b,0x00,0xdd,0x7a,0xe2,0x37,0xe4,0x13,0xd0,0xaa,0x5c,0x56,0x32,0x98,0x00,0x4b,0x8a,0x81,0xb1,0xfa,0xe8,0xf3,0xfa,0x0d,0xbb,0x66,0x6e,0x24,0xfd,0x3c,0x50,0x63,0x3a,0xf1 +.byte 0x72,0x63,0x18,0x71,0x6d,0xee,0x6f,0xf1,0x0e,0x1f,0x9e,0x9d,0x87,0x12,0x5c,0xdf,0x1d,0x9e,0xc0,0x0b,0x39,0x0e,0xd6,0x56,0x79,0x30,0xcb,0x07,0x7b,0x88,0xa5,0xbe,0xfd,0xd4,0x49,0xcc,0x92,0x6a,0xcc,0x78,0x1e,0xaf,0xee,0x89,0xc8,0x51,0x08,0x98,0x14,0x20,0xe5,0x52,0x93,0x18,0x6f,0xbb,0xdc,0xb2,0x68,0x14,0xd1,0xdb,0xe8,0x56 +.byte 0x24,0xd0,0x34,0xab,0xa6,0xfa,0xfe,0x72,0x5a,0xe3,0xe1,0x87,0x0d,0xf4,0xfa,0xa6,0xa6,0x6c,0xb6,0xcb,0xf8,0xfc,0x59,0xac,0xd9,0xb0,0xcd,0x15,0xa4,0x37,0x73,0x6e,0x70,0xc9,0x74,0xef,0x87,0x78,0x61,0xc2,0xd0,0x52,0x51,0xa9,0x2c,0xdb,0x9d,0xd9,0x3d,0xac,0xcd,0x52,0x39,0x69,0x2d,0x2a,0x4f,0xf3,0xb2,0x69,0xb9,0x01,0x3c,0x57 +.byte 0xeb,0x1b,0x0e,0x87,0xe9,0x42,0x58,0x83,0x6b,0xbc,0x72,0xc8,0x46,0x32,0x42,0x17,0x6a,0x19,0xa0,0xb3,0xf1,0x1c,0x96,0x9c,0x11,0x09,0x8b,0xc1,0x9e,0xe9,0x7f,0x18,0x8e,0xca,0xea,0x24,0x1b,0xce,0x12,0x57,0x1d,0x34,0xbe,0x60,0x60,0x2c,0xd8,0xa0,0x61,0x73,0xd6,0xf8,0xaf,0x15,0x26,0x84,0xd7,0xec,0xc0,0xbe,0x7e,0xa1,0xa8,0xba +.byte 0x2b,0xcc,0x20,0x67,0x6e,0xea,0x48,0x79,0x23,0xea,0x14,0x36,0x85,0x0a,0x56,0x3a,0xcd,0x5b,0x51,0xa4,0xf5,0x92,0x49,0xc2,0x55,0x62,0xed,0x88,0xde,0xd0,0x0c,0x01,0x36,0xb9,0x2e,0x94,0x80,0x75,0x8a,0x21,0x0a,0x07,0x45,0x68,0xd8,0x9d,0x49,0x7b,0xa7,0xb2,0x84,0xfa,0x3c,0xc4,0xd5,0x59,0xf9,0xc3,0xff,0xcf,0xe4,0x5f,0xea,0xbb +.byte 0x0f,0xae,0x7d,0x96,0xd3,0xe9,0x38,0xd1,0xb1,0x02,0xf6,0x4b,0x95,0x43,0x1c,0x69,0xa6,0x99,0xf5,0xdb,0x46,0x62,0xea,0x69,0x5a,0x08,0x2d,0x01,0x11,0xed,0x70,0x03,0x60,0x54,0xba,0x32,0x2c,0x0e,0x44,0x1f,0x8d,0xee,0x2e,0x39,0xab,0xc0,0xd4,0x88,0x11,0xef,0x07,0x3a,0x47,0xb9,0x6e,0x0c,0x22,0x9a,0xf3,0x89,0x01,0xfb,0xb8,0x2d +.byte 0x52,0xa0,0x42,0x4c,0xb3,0x9e,0xf5,0x4b,0x0c,0x78,0x0a,0x3b,0x29,0xae,0x4a,0xc0,0xb2,0xa3,0xc0,0x0d,0x38,0x07,0x49,0x9c,0xda,0x7c,0x48,0x81,0xba,0x53,0x0d,0x0d,0x78,0x8c,0xac,0x9b,0x3d,0x1f,0xaa,0xc1,0x32,0x54,0xca,0x54,0xe1,0xef,0x46,0x82,0x61,0xd0,0x88,0x04,0x53,0xb0,0x34,0xc2,0x23,0x9a,0x90,0xe3,0x73,0x9c,0x0d,0x46 +.byte 0x61,0xe5,0xc0,0x42,0x87,0x4a,0x3b,0x3a,0xf9,0xab,0xbe,0x4c,0xba,0x2f,0x88,0x03,0x6b,0x52,0x25,0x8c,0x9b,0xc0,0x13,0xb6,0x80,0x09,0x85,0x97,0x64,0x6d,0x65,0xcd,0x18,0x42,0x00,0xdf,0x76,0x4d,0x67,0xbf,0x04,0x7a,0x5f,0x7e,0x3a,0x5c,0x6f,0x1d,0x12,0x5b,0xbe,0xd2,0xc8,0xe5,0x09,0x45,0x4d,0xae,0xed,0xd8,0x77,0xc5,0x6f,0xb6 +.byte 0x43,0x09,0xe2,0xee,0xc9,0x5a,0x76,0xc5,0xeb,0xdd,0x96,0x23,0xb9,0xe5,0xfc,0xf2,0x3c,0xe1,0x67,0x5f,0x1b,0x10,0x39,0x47,0x67,0x8b,0x48,0x32,0xd0,0xbc,0xa0,0xa8,0x3e,0xc3,0x30,0x21,0x18,0x54,0x49,0xfe,0x8a,0x14,0x7a,0xe5,0x6e,0xbe,0x70,0xec,0xf6,0x97,0xa0,0xa4,0xf4,0xdd,0xaf,0xf2,0xde,0x50,0x1a,0x68,0xb9,0x1a,0x4b,0x37 +.byte 0xf8,0x29,0x16,0x4f,0x8c,0xa5,0x9e,0xd2,0x72,0x7f,0xf6,0x6b,0x7d,0xac,0xe4,0x17,0x93,0x39,0x8f,0xd9,0xdf,0x50,0x1f,0xce,0xf5,0x58,0xdd,0xcd,0xc2,0xb9,0x64,0xfc,0xad,0x8a,0x3c,0x2e,0x52,0x58,0x91,0x3b,0x78,0xb4,0xfd,0x4a,0x3b,0x13,0x5d,0x20,0xd5,0xdf,0xe7,0x52,0x3d,0x4c,0x2f,0x02,0x30,0xfc,0x24,0x17,0x99,0x6e,0x4b,0xfe +.byte 0x1d,0xf0,0xe6,0x86,0x32,0x37,0xb5,0xd5,0x09,0xa3,0xa5,0x3b,0xc1,0x88,0x9f,0x01,0x57,0x12,0x03,0x1d,0x60,0xd8,0x57,0xba,0xc6,0xfc,0xda,0xab,0x02,0xbe,0xab,0x89,0xf9,0x08,0x63,0xbd,0x42,0x11,0xf7,0xbf,0xd3,0x45,0x2b,0xa5,0x34,0x91,0x18,0xb9,0xb3,0x79,0xb4,0x15,0xa1,0x01,0x1a,0xf9,0x74,0x91,0x08,0x94,0xb2,0xf3,0xb2,0xca +.byte 0x0a,0x3a,0x4f,0x42,0x8a,0x16,0xf7,0x9e,0xbf,0x27,0x72,0x7b,0xff,0xd3,0xb9,0x4e,0xf5,0x8e,0x68,0xb5,0x91,0x23,0xef,0xeb,0x5d,0x7d,0xd8,0xc9,0xda,0x07,0x33,0xc9,0x1c,0x4a,0x7a,0xf2,0x72,0x64,0xb3,0x35,0x2e,0x54,0xec,0xc4,0xd9,0xee,0xea,0xda,0xfe,0x8b,0x1c,0x21,0x93,0x52,0x95,0x7c,0x2d,0xfe,0x56,0x05,0xdd,0x57,0x37,0xf2 +.byte 0x54,0x1c,0xe2,0x6c,0xc0,0xaa,0x71,0x67,0xdd,0x73,0x43,0x17,0x3e,0x76,0xdb,0x60,0xb4,0x66,0x62,0xc7,0x74,0x08,0x91,0x1f,0xd5,0x4c,0xa9,0xd0,0x34,0x33,0xea,0xb0,0x2c,0x0a,0x88,0xda,0xf7,0xca,0x91,0xf6,0x5f,0x9e,0x72,0xf6,0x18,0xf9,0x19,0x9d,0x84,0xf8,0x4c,0xe1,0xeb,0x45,0x29,0xaa,0xf2,0xa6,0xfd,0x64,0xf9,0x0b,0xfe,0x09 +.byte 0x1c,0xc2,0xde,0x19,0xdd,0x0f,0x02,0x16,0x65,0x70,0x33,0xd4,0x32,0x67,0x7b,0xc4,0xbb,0x11,0x60,0x4f,0xc3,0x4d,0x29,0x23,0x7e,0x84,0x58,0x51,0x43,0x7e,0x25,0x4f,0x3d,0xd4,0xe0,0x20,0x79,0xfd,0xce,0x59,0x49,0xf8,0xd1,0x53,0xca,0x2d,0x66,0xec,0xe5,0x7f,0xc8,0x14,0x06,0xc1,0x96,0x40,0xf2,0x61,0xa7,0x1b,0xf9,0x5e,0x97,0xfe +.byte 0x62,0x57,0x05,0xcc,0x6f,0x26,0x4b,0xa6,0x40,0x33,0x72,0x20,0xd3,0x1e,0x2b,0xb2,0x60,0xe7,0x56,0xda,0x87,0xd3,0xb4,0x5a,0x73,0x04,0xc9,0xc2,0x68,0xe3,0x18,0x74,0xd9,0x46,0x74,0x31,0xf4,0xf4,0xab,0xc4,0x0a,0xbc,0x66,0x4e,0x23,0x5f,0x92,0x7c,0x0a,0x81,0xdd,0xcc,0x79,0xee,0xb3,0x3d,0xc0,0x91,0x81,0xd0,0x79,0x39,0xd2,0x69 +.byte 0x5d,0xdc,0xc1,0x5c,0x61,0xb9,0x5e,0x87,0x32,0x73,0x70,0xd0,0xa8,0x7d,0xb5,0xd0,0xfc,0xf4,0xb6,0x55,0x9f,0x1f,0x8a,0xec,0xf4,0xb0,0x47,0xeb,0x3b,0x68,0x80,0x0b,0x79,0xd0,0x71,0x99,0xb1,0xd0,0xed,0x1f,0x9f,0x6c,0x2d,0x9d,0xae,0x1c,0x62,0x3b,0xec,0x3e,0x2f,0xb4,0x6f,0xbb,0x2e,0x1e,0xa9,0x7c,0xe8,0x5d,0x14,0x7d,0x0d,0x17 +.byte 0x6d,0x9c,0x54,0xce,0x64,0x93,0x8e,0x3b,0xa4,0xa9,0xfb,0xd9,0x44,0x06,0xbb,0xb8,0x7f,0xdf,0xd3,0xc2,0xa2,0xcf,0x5a,0xa2,0xa7,0xbb,0xb5,0x08,0xe2,0x67,0xdf,0x0e,0x4e,0xc6,0xcf,0x0a,0x79,0x1e,0xa5,0x60,0x1a,0x81,0xb1,0x8e,0x1b,0x27,0x7f,0x8d,0x28,0x50,0xa7,0x4a,0xe4,0x4b,0x61,0x6b,0xa9,0xfa,0xaf,0x82,0x83,0xfb,0x1f,0x2e +.byte 0xfa,0xce,0x18,0x0e,0x32,0x5f,0x5a,0xcf,0xac,0xaf,0x22,0x30,0x16,0xd7,0x97,0x99,0x0d,0xb8,0x92,0xa5,0x1d,0x44,0xb2,0xa5,0xc7,0x74,0xd2,0x81,0x8d,0x5c,0x38,0xda,0x9f,0x76,0xcb,0x47,0x6c,0xb7,0x08,0xd9,0xc1,0x52,0xd0,0x64,0x0a,0xf9,0xdd,0x3e,0xe8,0x99,0x15,0x4d,0xcb,0x7b,0x25,0x53,0x8c,0x13,0xb1,0xbf,0xb7,0xca,0x2d,0xce +.byte 0x71,0x48,0xee,0x5b,0x3a,0x01,0x5b,0xfd,0x22,0xfa,0x6f,0x17,0xcb,0x52,0xcc,0x0a,0x2b,0xbb,0x6d,0xce,0x2d,0x00,0xf5,0x9e,0x0d,0x58,0xf1,0xf4,0xa4,0x9f,0x13,0xf9,0x68,0x15,0xd7,0x02,0x41,0x6c,0x19,0x6b,0x66,0x9a,0x74,0xee,0xb4,0xb3,0xc7,0xec,0x60,0x19,0xbd,0xbb,0x97,0x22,0x7c,0x4e,0xe6,0xc6,0x00,0x03,0xa5,0x36,0x52,0xec +.byte 0x21,0xcf,0xc8,0xda,0x2c,0x14,0xa9,0xd8,0x75,0xab,0xea,0x05,0x8c,0x24,0x28,0x63,0xbd,0x58,0x35,0xd7,0x95,0xcb,0x14,0x89,0x04,0x99,0x7e,0x67,0x0d,0x07,0x35,0xdb,0x17,0x7c,0x72,0x2d,0xbc,0x89,0x9b,0xb4,0x16,0x21,0x2f,0x90,0xe8,0x8f,0xeb,0xc3,0x8d,0x86,0x0d,0x92,0xf6,0x4b,0x80,0x36,0x96,0x6b,0xd8,0x95,0x7b,0xad,0xe8,0xbf +.byte 0x77,0x9e,0xf4,0x93,0xcd,0xa5,0x06,0xbc,0x38,0xf2,0x57,0x25,0x54,0xfa,0x8e,0x19,0x8e,0x25,0x8e,0x3c,0x28,0xaa,0xf2,0x02,0x30,0xd4,0x47,0x89,0x36,0xb9,0xb7,0x01,0x5f,0x0c,0xd1,0x8d,0x93,0x7e,0xf0,0xf0,0xff,0x2f,0x8f,0xb5,0x97,0xa7,0x02,0xe8,0x9b,0xf2,0x51,0xe6,0x51,0x62,0xa5,0x27,0x26,0xc6,0x7a,0x39,0x7a,0xa9,0xaf,0x1e +.byte 0x03,0xd5,0x25,0xbe,0x3b,0x19,0x46,0xc4,0xdd,0xd6,0x5e,0x6a,0x18,0xc0,0x41,0x5f,0x53,0x89,0xd3,0x16,0xfb,0x3a,0x10,0xce,0x0d,0x8c,0x04,0x4c,0xcf,0xab,0xb9,0x0d,0x6c,0x45,0x6c,0x29,0xed,0x77,0x37,0x1f,0xd8,0x10,0x8a,0xfe,0x07,0xbd,0x7e,0xd7,0xa6,0x6b,0x80,0xde,0x3e,0x2c,0xa8,0xb1,0x38,0xcc,0xab,0x10,0x69,0x8f,0x58,0x3d +.byte 0x12,0xc7,0x9c,0xc1,0x0a,0xeb,0x3d,0x5e,0xf1,0x65,0xc6,0x09,0xcb,0x4b,0x09,0x24,0xa7,0x56,0x1d,0x1d,0x4c,0xd7,0x06,0xbd,0xe2,0x72,0x70,0xae,0x7e,0xe9,0xaa,0x97,0x6d,0xec,0xcb,0x55,0x0b,0x5d,0x45,0x3a,0x25,0x3d,0x52,0x0f,0x48,0x2f,0xe4,0xd0,0x5e,0x85,0x87,0xb6,0xa7,0x70,0x2f,0x9c,0x19,0x89,0x95,0x45,0x76,0x00,0xfe,0x27 +.byte 0xff,0xf8,0x73,0x59,0xba,0x98,0x92,0x4e,0x76,0x1a,0x90,0x1d,0xbc,0x1b,0xae,0x44,0xb6,0x63,0x86,0x4c,0x3c,0x8a,0x8f,0x3e,0x03,0x95,0x50,0x30,0xd8,0x0f,0x7f,0x6f,0xb6,0xe9,0xbe,0x2e,0xc9,0x55,0xe7,0x73,0xd6,0x77,0xdc,0xbc,0x67,0x54,0x31,0x47,0x30,0x46,0xe1,0xa4,0xf8,0xf3,0x90,0x4f,0x68,0x5a,0x52,0xe2,0xe7,0xdb,0xd9,0xfd +.byte 0xf6,0x36,0x2a,0xc1,0xdb,0x35,0x82,0x69,0xff,0xf9,0xea,0x53,0xff,0xcd,0x21,0x2c,0x26,0x79,0xd6,0x8c,0x74,0xe7,0x9e,0x85,0x1a,0x04,0xf5,0xed,0x89,0x16,0xf5,0xd7,0xf1,0x89,0xf1,0xb3,0x5b,0x47,0x42,0xcb,0x92,0x2e,0x70,0xf6,0x3e,0xfc,0x20,0x87,0x70,0xec,0x30,0x16,0xcc,0x88,0x64,0x13,0x58,0xf1,0x0d,0x17,0x90,0xc4,0xdb,0x07 +.byte 0xf5,0xe3,0x34,0x31,0x10,0x9c,0xa4,0x6a,0x4a,0xe6,0x6c,0x80,0x49,0x07,0x23,0x21,0xd6,0xf1,0xcb,0x4a,0xd1,0xb5,0xb7,0x63,0x94,0x4c,0x0a,0xce,0x90,0xf2,0x63,0x31,0x4f,0x96,0x6c,0x5d,0x3e,0xaa,0x10,0x20,0xd6,0xb6,0xbe,0xfa,0x3f,0x83,0xbc,0xa8,0x08,0x38,0xec,0x38,0xe4,0xe9,0xf5,0xb3,0x8e,0x32,0x31,0xcd,0x7c,0x08,0x98,0xf6 +.byte 0x0f,0x8a,0x8f,0xc1,0xd8,0x9e,0x05,0xb6,0x74,0x11,0x94,0xef,0x4f,0x8f,0xa1,0xc6,0x8c,0xdb,0xc3,0x27,0x4e,0xa3,0x30,0x94,0xf5,0xe8,0x2a,0x18,0x0a,0x51,0x9b,0x79,0xb2,0x1f,0xc3,0xa0,0x26,0xa9,0xf5,0xc4,0x9e,0x39,0xda,0x6a,0x53,0x8f,0x8c,0x4c,0x54,0x50,0x81,0xa0,0x0a,0xd3,0x7c,0x99,0x91,0xc7,0x3e,0x56,0x7d,0x53,0x8c,0x3c +.byte 0x51,0x44,0xa5,0x22,0x9d,0xd2,0x9b,0x13,0xcf,0xb8,0x0c,0xb8,0xd4,0xaa,0xb4,0xaa,0x8d,0xab,0x7c,0x06,0xca,0xbb,0x85,0xac,0x01,0xee,0xef,0xe7,0x74,0xd5,0x0d,0x64,0x91,0x1c,0xde,0x6c,0x05,0x37,0x1e,0x23,0x05,0x7e,0x38,0xdc,0x17,0xaf,0xa7,0x95,0x85,0x1f,0xaf,0xc8,0xe1,0xc2,0xda,0xda,0xf1,0x14,0x56,0x66,0x68,0x70,0x36,0x38 +.byte 0x7b,0xb8,0x22,0x9f,0xc4,0xeb,0x5d,0x76,0x97,0xc5,0xa3,0xb9,0x06,0x86,0x4f,0x20,0xab,0x7d,0xce,0x7d,0x78,0x59,0xc5,0x1f,0x73,0x81,0xf6,0x6d,0xb4,0xcc,0x10,0xc5,0x4d,0xe3,0x81,0xaf,0xbc,0x37,0x42,0x28,0x5f,0x51,0x1e,0xaa,0xc7,0x81,0x20,0xc3,0x89,0x35,0xf1,0x74,0x3a,0xe8,0x04,0x24,0xef,0x8b,0x70,0xe1,0x74,0xdf,0x87,0xd5 +.byte 0x3c,0x32,0x32,0x7d,0x03,0xd7,0xda,0x6d,0x8b,0x25,0x8d,0x11,0xa3,0xc2,0x27,0xdc,0xa3,0xfc,0xdf,0x70,0xa4,0x41,0xad,0xda,0xce,0x12,0x45,0x14,0xa1,0x96,0x16,0xd8,0x54,0x89,0x9e,0x78,0x7f,0x23,0x12,0xd1,0x15,0x08,0x7f,0xbd,0xf0,0x9a,0xf1,0x5b,0x07,0xd5,0xbc,0xab,0xab,0x15,0xae,0xda,0xf1,0x26,0x12,0x4e,0xd6,0x6c,0x35,0xc1 +.byte 0x6e,0x27,0x4d,0xa8,0x71,0x51,0x1e,0xae,0xa8,0x35,0x26,0x06,0x18,0x03,0xd8,0xae,0x9e,0x8b,0x07,0x30,0x10,0xfb,0x47,0x05,0x02,0xcc,0x0a,0xbd,0x57,0x43,0x15,0x0a,0x7a,0xb5,0x30,0x0b,0xa6,0x3c,0xa8,0xc9,0xf5,0x68,0xe1,0xfb,0xd1,0xe0,0xe7,0x44,0x6c,0xb4,0x44,0xb6,0xd1,0x2b,0x30,0x5e,0x17,0x89,0x40,0xcc,0x10,0x8f,0x97,0x8a +.byte 0xf3,0xf4,0x52,0x55,0xc4,0x8e,0x46,0xe5,0x24,0x0b,0x2a,0x5d,0x84,0xc1,0x4e,0xa8,0x5a,0x53,0xa8,0xce,0xc6,0x3f,0xa2,0xaa,0x3a,0x8f,0x51,0xed,0x4c,0xa6,0x34,0x6a,0x8c,0x18,0x9b,0x36,0x49,0x40,0x34,0xa3,0xe4,0xd8,0x3c,0x8a,0xfc,0x41,0xc9,0x35,0xfe,0x6e,0x3e,0x29,0xbc,0x04,0x61,0xaf,0x04,0x03,0x43,0x79,0xb5,0x77,0x27,0x25 +.byte 0xbe,0x85,0xc9,0x56,0xa4,0x17,0xc4,0x27,0x3d,0x53,0x1b,0x49,0x86,0xb2,0xb6,0x52,0x62,0x12,0x5d,0xe9,0x47,0x6f,0x65,0x78,0xf8,0x95,0x63,0xbc,0x73,0x6d,0xa6,0xb9,0xcd,0x17,0x39,0x56,0xb0,0xab,0x3a,0x15,0x5f,0x9a,0x98,0xfb,0xcd,0x51,0x4a,0x35,0x21,0xaf,0x07,0x4a,0x3d,0xfd,0x39,0x11,0x42,0xed,0xfc,0x7e,0x10,0x24,0xa5,0x0c +.byte 0xb2,0x4f,0x27,0xe4,0x78,0x32,0xfe,0xfc,0x8e,0x46,0x68,0xbb,0x2e,0x85,0x87,0x0f,0x01,0xde,0x1c,0x02,0xdd,0x82,0xa0,0x9e,0x30,0x31,0x8d,0x86,0x36,0x33,0xa6,0x59,0x16,0x78,0xae,0x1f,0x1d,0x27,0x0b,0x29,0x42,0x16,0x93,0x3b,0xe6,0xfb,0x8d,0xd5,0x48,0x42,0x61,0x39,0x5b,0xf7,0xea,0xd0,0x6f,0x67,0xd9,0x03,0x72,0xed,0x54,0xe1 +.byte 0xab,0x3f,0xa0,0xdc,0x4b,0x19,0xe6,0xe3,0xfe,0x5f,0x65,0x64,0x4c,0xa9,0x5c,0x52,0x36,0xb3,0x65,0x28,0x3e,0xe5,0x07,0x50,0xed,0xec,0x2f,0xc9,0xff,0x47,0x27,0xf6,0xfe,0xb8,0x60,0x60,0x52,0xe5,0xec,0x3c,0x4f,0x69,0x9f,0xaa,0x06,0x8a,0x99,0x9f,0xac,0xfc,0x0a,0x6f,0x8a,0xa4,0x0e,0x5c,0x58,0xb4,0x09,0xba,0x93,0x95,0x94,0x12 +.byte 0x9b,0x23,0x4f,0x93,0x28,0x6d,0xd0,0x76,0xfd,0xc9,0x87,0x3b,0xf1,0x8c,0x7d,0x56,0x84,0x5a,0x04,0x08,0x30,0xf7,0xf6,0x52,0x15,0xba,0xd6,0x7a,0x39,0x8c,0x5a,0xbf,0xeb,0x02,0x6d,0x31,0x30,0x92,0xbc,0xe2,0x07,0x21,0x16,0x96,0x70,0x66,0x00,0xe0,0x04,0xc5,0xa8,0xe4,0x08,0x6d,0x08,0x69,0x35,0xe2,0xb1,0x83,0x03,0x37,0xca,0xff +.byte 0x06,0x37,0x80,0xd5,0x1a,0xc5,0x31,0xfc,0x9a,0xb0,0x8a,0x4b,0x58,0xf3,0x00,0x4e,0xa4,0xfe,0x9e,0xe0,0x60,0xc7,0x3d,0x2c,0x52,0xb5,0x39,0xf0,0xa4,0x88,0x39,0x37,0xa5,0x26,0x8a,0xa3,0xe6,0x31,0xce,0xf3,0xa1,0x54,0x73,0xe7,0x69,0x38,0xef,0xa2,0xab,0x52,0x50,0x1a,0x45,0xcc,0x29,0x9c,0xb6,0xf4,0xde,0xc2,0xfe,0x7a,0x26,0xf7 +.byte 0x7a,0x6e,0x07,0xb6,0xd8,0x3f,0x77,0x60,0x35,0xae,0x6a,0x90,0xd6,0xb8,0x37,0xed,0x73,0x59,0x54,0xd9,0x0c,0x87,0x0e,0x81,0xef,0x69,0xc7,0xd4,0x8f,0x00,0x74,0x57,0x12,0xcf,0xa1,0x76,0xe8,0x45,0xf5,0x9a,0x4f,0xe2,0x5d,0x8a,0x89,0xb1,0x8b,0xea,0x9c,0x0a,0x1e,0x00,0x61,0x3b,0x66,0xbd,0xb5,0xd6,0xff,0xa3,0xff,0x52,0xc2,0x35 +.byte 0x81,0x05,0x08,0x2b,0xf9,0x52,0xda,0x74,0xd1,0x76,0x13,0xba,0x28,0x4c,0xb1,0xb1,0x82,0x5b,0x4e,0x79,0x39,0x22,0xf9,0x96,0x91,0x07,0x4f,0xf9,0xf2,0x25,0x25,0xb1,0x3e,0xda,0x07,0x5c,0x01,0x7b,0xfa,0x3e,0x95,0x92,0x1d,0xf8,0x44,0x06,0xc1,0xed,0x64,0x74,0x14,0x84,0x25,0xee,0x75,0xaf,0xe3,0x7c,0xd3,0xbe,0x7a,0x51,0x6b,0x80 +.byte 0x20,0x43,0x20,0x10,0x5f,0xf5,0xfc,0xd5,0xe8,0x06,0x43,0xad,0x10,0x6b,0x67,0x48,0xca,0xca,0x6e,0x3e,0x1c,0xdf,0x8f,0x7a,0x65,0xc8,0x5d,0xba,0x3b,0x67,0xeb,0x1f,0xc4,0x37,0xad,0xef,0x73,0x9e,0x18,0x8e,0xc1,0x99,0xaf,0x75,0xd3,0x91,0x73,0xc3,0x3a,0xb2,0xfe,0xff,0x30,0x81,0xc4,0x4f,0x37,0x37,0x23,0x96,0x17,0xf1,0xa2,0x9b +.byte 0x55,0x6e,0xd6,0xb3,0xc4,0x98,0xa3,0x32,0xb6,0xff,0x86,0x87,0x77,0xf4,0xad,0x16,0x3e,0xf0,0x24,0x01,0xb4,0x8e,0x1e,0x0f,0x10,0xa4,0x2e,0xe4,0x79,0xe6,0x88,0xe7,0x09,0x58,0x5e,0x97,0xad,0x0d,0x72,0x05,0xbf,0x2f,0x3f,0x99,0xee,0x8a,0x84,0xc3,0x62,0x43,0x52,0x6d,0xab,0x66,0xcf,0x9f,0x4e,0xf2,0x0d,0x13,0x15,0x49,0x84,0x5e +.byte 0x6c,0x8d,0x2d,0xef,0x53,0x16,0xa0,0x63,0xbe,0x05,0xb8,0x9b,0x23,0xca,0xca,0xb8,0xdd,0xbc,0x96,0x68,0x35,0x43,0x63,0x30,0x8e,0xaf,0x53,0x98,0xe2,0x76,0xe8,0x89,0x00,0x29,0x11,0x70,0xd5,0x94,0xbd,0x78,0xff,0xf6,0x88,0x4a,0x3d,0x99,0xd9,0x7e,0xdf,0xa8,0x33,0x92,0xa2,0xc0,0x32,0x42,0x73,0x08,0xd4,0x55,0x5d,0x18,0x93,0xca +.byte 0x7e,0x33,0xe3,0x51,0xc7,0xb7,0x24,0x62,0x69,0xf4,0xab,0x36,0xe3,0x22,0x10,0x9b,0xe0,0xbd,0x48,0x65,0x30,0x9c,0xfe,0xeb,0x3f,0x7f,0x22,0x67,0xcc,0x87,0x5a,0x71,0xb0,0xd1,0x19,0x82,0x1c,0xb2,0xf1,0x73,0xd2,0xd6,0x3f,0xef,0xe3,0x2f,0x25,0xf3,0x8b,0x21,0x4e,0xbf,0x0e,0xc1,0xd2,0x8a,0xbb,0x04,0xde,0xcf,0xd1,0x77,0xba,0xaa +.byte 0xc7,0x41,0x68,0xce,0xc4,0x64,0xf9,0x3a,0x2f,0x1c,0x0b,0x22,0xf8,0x60,0x09,0x76,0x31,0x88,0x62,0x3a,0xf3,0x49,0xe6,0xda,0x4b,0xd3,0xf3,0x35,0xaa,0x56,0x4c,0x2f,0x7f,0x03,0x3e,0xf8,0xcb,0x5e,0xed,0x37,0xa1,0x29,0xe8,0x20,0xf5,0x4a,0x32,0x73,0x30,0xfd,0xd1,0xf6,0xb4,0xa1,0x30,0x87,0xcb,0x21,0x63,0xf5,0x3a,0xad,0x05,0x1a +.byte 0x34,0xf5,0x32,0xf6,0x02,0xf3,0x10,0x52,0xfd,0x86,0x37,0x1f,0x5d,0xe4,0x2e,0x31,0xcb,0xb8,0x4c,0xeb,0xdd,0xea,0x01,0x0d,0x94,0x13,0xa8,0x8f,0xf0,0x52,0x4e,0x0d,0x4f,0xd1,0x24,0xeb,0x0f,0x2b,0xb1,0xaa,0xc5,0xc8,0x52,0xb9,0xbe,0x21,0x48,0x2a,0x53,0x98,0xe4,0x00,0x72,0x64,0xdb,0x44,0x48,0x36,0x60,0xe7,0x81,0xdc,0x25,0x85 +.byte 0x4d,0xaf,0xa8,0x0d,0xfb,0x07,0x76,0x4f,0x6a,0x30,0x3c,0x7c,0x3b,0x36,0xa9,0xf8,0xae,0x81,0x03,0xe9,0x19,0xdf,0xdb,0xd9,0x7f,0x59,0xe0,0xd7,0x50,0x14,0x9f,0x67,0x3d,0xc7,0xdf,0xa8,0x44,0x86,0x29,0x81,0x65,0x44,0x9e,0x37,0x27,0xdd,0x2f,0x33,0x59,0xf7,0xaa,0x17,0x34,0x8c,0x1c,0xa7,0x8e,0x06,0x46,0xf1,0x43,0x87,0xa9,0xb7 +.byte 0x85,0xec,0x92,0x0d,0xdd,0x78,0x55,0x99,0xfb,0x1c,0x66,0x85,0x0d,0x59,0x31,0x00,0xbc,0xd9,0x9b,0xbb,0xfb,0xfc,0xb2,0x36,0x3c,0x34,0x8f,0x4a,0xb6,0x74,0x9c,0x32,0x6f,0x69,0x6c,0x3e,0x68,0x7e,0xec,0xeb,0x58,0x6a,0xf5,0xa2,0xbb,0x04,0x68,0xdb,0x8c,0xf0,0x04,0xba,0xf7,0xf7,0x50,0xd0,0x60,0xba,0x45,0x73,0x0f,0x2c,0x2f,0x97 +.byte 0x58,0xcc,0xa2,0xbe,0xfe,0x5e,0xf9,0x44,0x03,0x8b,0x99,0x56,0xb0,0x4f,0xe1,0xd0,0xa5,0x9f,0xd1,0xfc,0x95,0x44,0x4b,0x01,0x24,0xc0,0x4c,0x91,0xc1,0xb5,0x99,0xe7,0x5f,0x2f,0xcf,0x5d,0x4f,0x64,0x6e,0x54,0x51,0x0c,0x35,0x5f,0xa8,0x7b,0x27,0xa0,0x7d,0xb1,0x90,0xc2,0xdd,0x50,0xef,0x09,0x6f,0xed,0x25,0x6b,0xf5,0x6f,0xc1,0x97 +.byte 0xea,0xd5,0x49,0xf5,0x40,0x60,0xc3,0xbb,0x0d,0x82,0x15,0xa5,0xf7,0xfe,0xa1,0x20,0x13,0x9e,0xbb,0x43,0x58,0xba,0xd2,0xe8,0x89,0xaa,0xfc,0xe0,0x47,0x6b,0xac,0x91,0x8b,0xeb,0x4f,0xf5,0xda,0xf5,0xc8,0x11,0x64,0x7c,0x8d,0x43,0x92,0xf2,0x84,0xeb,0xfb,0x5c,0x1b,0x6b,0x68,0x8e,0x3c,0x66,0xb2,0xd1,0x8e,0x67,0x44,0xbf,0x69,0x3b +.byte 0xb9,0x41,0x78,0x8d,0xc8,0x7b,0x81,0x61,0x70,0x6e,0xe2,0xfc,0xd2,0x96,0x31,0x31,0x2f,0x27,0x90,0xf2,0xc4,0xed,0xbd,0xb5,0x0e,0x91,0x7d,0xd0,0xec,0x3c,0xe9,0xcf,0xf2,0x07,0xac,0x54,0x44,0x9a,0x24,0x41,0xcb,0x2a,0x86,0x30,0x18,0xba,0x65,0x59,0x41,0x00,0x59,0xbf,0x3d,0x01,0x8a,0x51,0xe5,0xd2,0x90,0x8c,0x7d,0xd7,0xad,0x71 +.byte 0xdc,0x45,0x62,0x95,0xf9,0x9f,0xe8,0x55,0x6d,0x48,0x22,0x32,0xcb,0x9a,0x55,0x65,0xe5,0xdf,0xee,0x22,0x99,0x91,0xd7,0xed,0x33,0x04,0x72,0xc7,0xc5,0xb2,0x56,0x5e,0x8f,0x38,0x4b,0xd0,0x61,0x4b,0x4b,0x04,0x4c,0x4c,0x2b,0x23,0x00,0xd4,0x5c,0xdd,0x84,0x8d,0x73,0xf4,0xf7,0xef,0xd5,0xdb,0x2b,0xec,0x54,0x86,0x37,0x01,0x64,0x56 +.byte 0xef,0x73,0x9f,0xb4,0xb6,0xd2,0xf4,0x33,0x93,0xbd,0xd7,0xd9,0x6e,0x8f,0x60,0x85,0xbc,0xa6,0x16,0x3f,0x3f,0xc3,0xd7,0xfc,0xb6,0x82,0xf0,0xe5,0x1e,0x2c,0x51,0x48,0x27,0x50,0x3e,0xdb,0xe6,0x86,0x3b,0xa1,0xfa,0x09,0x39,0x04,0x6f,0xb1,0x85,0xbd,0xda,0x4d,0x2f,0xd1,0x40,0x6f,0x2e,0x2b,0xf2,0x9a,0x4d,0x8e,0xb2,0xc5,0x6e,0x21 +.byte 0xf9,0xdd,0xc9,0x2e,0x81,0x18,0x7b,0x88,0xb9,0x86,0x36,0xe5,0xb2,0xdd,0x19,0xb4,0x7f,0x5d,0xc0,0x20,0x34,0xdc,0x63,0x7d,0x8c,0x80,0x0f,0xe6,0x85,0x14,0xbb,0x87,0x6c,0x3e,0x39,0x53,0x60,0x3d,0xc5,0x46,0x11,0xa3,0x96,0x60,0x6f,0xe9,0xfe,0x59,0xcc,0xed,0x4d,0xdb,0xa3,0xa1,0xf1,0x71,0x0b,0xb0,0x1f,0x89,0x4c,0x32,0x59,0xa5 +.byte 0x7d,0xf7,0x3e,0x5b,0xca,0xa4,0xe1,0xc3,0x50,0xac,0xdf,0x00,0xad,0x45,0x59,0x9e,0x23,0x5f,0x52,0xbd,0x36,0x78,0x55,0xcf,0x90,0x91,0x41,0x14,0xdb,0x76,0x3a,0x43,0x39,0x89,0xe1,0x93,0xc8,0x66,0x91,0xc7,0x42,0x06,0x6f,0xbb,0x35,0x1e,0x07,0x52,0x5a,0xe4,0x41,0x9f,0x65,0xe0,0xdc,0x49,0x8c,0xd3,0x5f,0x16,0x21,0xc9,0xb8,0x8a +.byte 0xc2,0x56,0x91,0xcb,0x18,0x6b,0x38,0x7b,0x3a,0xeb,0x91,0x3c,0x0d,0x6a,0x1f,0xd6,0xc6,0xd7,0x56,0x8d,0xd3,0x76,0x1c,0x9d,0xed,0x3d,0xb6,0x92,0x71,0x6e,0x73,0xc6,0xb8,0xa2,0x1c,0x25,0xb9,0x3c,0xd4,0x41,0xf7,0x8f,0x39,0x60,0xe6,0x27,0xf2,0xc6,0x5f,0x56,0x08,0x7c,0xd3,0x16,0x9d,0x06,0xc0,0xca,0x3d,0xc6,0x61,0xb0,0x21,0x51 +.byte 0x6d,0xca,0x82,0x59,0xe6,0xbb,0x99,0xa2,0x4f,0xfc,0x71,0x66,0x2b,0x4e,0x40,0x62,0x97,0x34,0x73,0x4a,0xe5,0xf0,0x4f,0x4c,0x36,0x4c,0xdb,0x03,0xa9,0x87,0x29,0x21,0x5d,0x91,0x5b,0x89,0xb8,0x3d,0x65,0xc7,0x58,0x0a,0x81,0xb5,0x3e,0x22,0xa1,0x57,0x95,0xbe,0x60,0xf5,0xeb,0xb3,0x49,0xdf,0xd9,0xa2,0x31,0x36,0x5f,0xb2,0xa6,0xf6 +.byte 0x66,0x88,0x88,0x8e,0xa3,0x2c,0xac,0x5e,0xa1,0x33,0x16,0x64,0x08,0x47,0xc8,0xbc,0xc2,0xe9,0xdb,0x73,0x57,0x50,0xd4,0x24,0x01,0x26,0x26,0x04,0x4f,0x8a,0xc0,0x7a,0x97,0x14,0xf2,0xd0,0xbe,0x03,0xea,0x8a,0x25,0xcb,0x98,0xe7,0xbd,0x67,0xff,0x32,0xfd,0x8a,0x7d,0x11,0xe1,0xb2,0x91,0xb5,0xa0,0xb6,0x3c,0x2c,0xb3,0x6e,0x35,0x61 +.byte 0x86,0xbc,0x37,0x15,0xf8,0x3b,0x0d,0x84,0x83,0x69,0x76,0xb0,0xaa,0x8f,0x4f,0xca,0xba,0x54,0xfe,0x42,0xc8,0xba,0x9a,0xd5,0x53,0x69,0x67,0x29,0x23,0x3a,0x6a,0x75,0x97,0xb4,0x29,0x2e,0x62,0xe3,0x95,0x82,0xb3,0xa0,0xa1,0xb7,0xdf,0xc2,0x66,0x4d,0xdd,0x0d,0xda,0xda,0xc2,0x42,0xe0,0x69,0xb1,0xab,0x3c,0x44,0x39,0x11,0x3b,0x0a +.byte 0xd6,0x96,0x2c,0x36,0xb0,0xa0,0xed,0x3d,0x0c,0x63,0x8b,0x90,0xe4,0xb9,0x5f,0x4c,0x27,0x70,0x87,0xb3,0x54,0xe2,0x36,0x74,0x6f,0x3e,0x22,0xb1,0x3b,0x1b,0xba,0xdb,0x1c,0xbd,0x9c,0x6d,0x84,0xbd,0x33,0xfb,0xc0,0x98,0x4c,0xcf,0x7a,0xe8,0x41,0xdb,0x32,0x1f,0xb7,0x64,0x19,0xdb,0x87,0xe7,0xf9,0x52,0x40,0x8c,0xc6,0x89,0x98,0x15 +.byte 0x69,0xde,0xfa,0x29,0x9a,0x0f,0xaf,0xb0,0xad,0x71,0x35,0xab,0xab,0x34,0xe0,0xf4,0x03,0x24,0x6f,0x94,0x38,0x87,0xba,0x68,0xd5,0x1f,0x58,0x88,0x3e,0x12,0x20,0x57,0x43,0xde,0xd0,0xbc,0xaa,0x31,0x8f,0xbc,0x88,0xa0,0xdf,0x5a,0xcc,0xd1,0xba,0x9c,0x18,0x80,0x4e,0x8f,0x68,0x91,0x9c,0x57,0x3b,0x5a,0x62,0xc7,0x29,0x3e,0x49,0xc7 +.byte 0x23,0x26,0xfd,0x9e,0xd0,0xb0,0x4f,0xd4,0xb2,0xa9,0xa8,0x4c,0x66,0x54,0x52,0x75,0x6b,0xbf,0x63,0x76,0x49,0x3b,0xa3,0xb2,0x8f,0x87,0x9d,0xb4,0x8f,0x07,0x3c,0x8e,0xae,0xe1,0x0e,0x9a,0x86,0x90,0x58,0x73,0x8a,0xb3,0xa9,0xab,0xe6,0x27,0xd7,0x70,0x94,0x77,0x12,0xdc,0x71,0xdf,0xcf,0xba,0xdd,0x85,0xfe,0x28,0xaa,0xcd,0xcc,0xe8 +.byte 0x5f,0xd4,0xd8,0x45,0x6f,0x20,0xa8,0x5e,0x40,0x91,0x3b,0xd7,0x59,0x92,0xb8,0x7d,0x2b,0x8b,0x38,0xbd,0xfe,0x7b,0xae,0x5c,0xee,0x47,0x9b,0x20,0xb7,0xf3,0xad,0x75,0xa9,0xe1,0x96,0xc8,0xb2,0x30,0xfe,0x0c,0x36,0xa2,0x02,0xf4,0x3b,0x30,0xfd,0x91,0xfa,0x5f,0xd6,0x18,0x1a,0xcb,0xd2,0x26,0xbb,0x67,0xbe,0x1c,0x99,0xa5,0x4f,0x57 +.byte 0x40,0xb5,0xed,0xd6,0x84,0xfd,0x6b,0x00,0xc8,0xe7,0x18,0x1a,0x9f,0xf7,0x3b,0xd1,0xcc,0x12,0xeb,0x9d,0x61,0xf0,0x8d,0x64,0x08,0x93,0x61,0xc4,0x3e,0xdb,0xda,0x15,0xb1,0xd6,0x2c,0x84,0x2a,0xd8,0xd2,0xa1,0x66,0x4e,0xc9,0xd6,0xbf,0x7e,0xb6,0x22,0xfa,0x35,0x5e,0xdc,0xc0,0x31,0x02,0xb8,0x17,0x46,0x9e,0x67,0xd3,0x6a,0x8f,0x33 +.byte 0x85,0xc3,0xfe,0x36,0xbc,0x6f,0x18,0x8a,0xef,0x47,0xf1,0xf2,0x6e,0x15,0x6c,0xb1,0x4a,0x4b,0x13,0x84,0xd5,0x1b,0xf9,0xa2,0x69,0xcd,0xc7,0x49,0xce,0x36,0x8e,0xe5,0xd5,0x35,0x05,0x7c,0x7f,0xc6,0x15,0x29,0x2e,0x64,0xa6,0x91,0x9d,0xe5,0x9d,0x90,0xe7,0x26,0xec,0x75,0x19,0x58,0x57,0xf2,0x19,0x7b,0x24,0x7d,0x19,0xd3,0x72,0x69 +.byte 0xaa,0xa2,0x8c,0xe3,0x3d,0x38,0xb9,0xf0,0x5b,0xe9,0x3b,0xaa,0x96,0xef,0x2c,0xfc,0xf5,0x13,0xa6,0xa9,0x57,0x8c,0xa9,0x3a,0xc1,0xf0,0x2d,0x57,0x06,0x08,0xe3,0x9c,0xfe,0x82,0x8a,0x6a,0x79,0x5b,0xef,0x2b,0x81,0x83,0x01,0x53,0xac,0xdc,0x79,0x93,0x9b,0x23,0xd4,0xae,0x17,0x6f,0x62,0xaa,0x33,0x41,0xa6,0x31,0x1c,0x7b,0x46,0x2b +.byte 0x17,0xd3,0x6f,0x66,0x73,0x54,0xee,0xa1,0x08,0xee,0x8f,0x0f,0x0e,0x53,0xa7,0x49,0x17,0xdb,0x35,0xaf,0x4e,0x94,0x87,0x8e,0xff,0xf4,0x2b,0x29,0x01,0x45,0xa3,0x0a,0xd9,0x13,0x38,0x09,0x46,0x2c,0x56,0x97,0xd7,0xee,0x24,0x43,0xd1,0x20,0xed,0x38,0xde,0x52,0x13,0x38,0x06,0xd3,0x97,0xc7,0x48,0x8b,0x72,0x0a,0xc5,0xca,0x75,0x2c +.byte 0x04,0x9e,0xee,0x14,0xe7,0xda,0x59,0xc2,0x54,0x7a,0x72,0x55,0x35,0x00,0x93,0xb7,0xb9,0x81,0x01,0x46,0xae,0x43,0x81,0x34,0xd7,0xb4,0x7a,0xfc,0xfc,0x98,0x2b,0x29,0xe5,0x5e,0x9d,0x8e,0xef,0xd4,0x44,0x9d,0x9a,0xbe,0xdb,0x83,0x33,0x18,0x9e,0xbd,0x0f,0x34,0x4d,0xd9,0x34,0xe0,0x2c,0x1f,0x10,0xaa,0x06,0x5e,0x54,0x51,0x72,0xec +.byte 0xbf,0x6b,0x3e,0xb9,0xdd,0x37,0xc3,0xe1,0xbe,0xbe,0x1d,0x86,0xde,0x12,0xca,0x82,0xc5,0xe5,0x47,0xf8,0xbe,0xef,0xb6,0x79,0xd5,0x3c,0x69,0x0a,0x35,0x3e,0xd3,0xf8,0xaf,0x5b,0x8e,0x69,0xff,0xb2,0xf7,0x91,0xc2,0x70,0x22,0x97,0x1c,0x5c,0x56,0x25,0x5a,0xcf,0x31,0x7a,0x37,0xce,0xc7,0xf2,0x98,0xdc,0xb5,0x58,0x71,0x5a,0x60,0xe2 +.byte 0xfe,0x4f,0xf3,0xe2,0x2a,0xca,0x22,0x3e,0x07,0xc2,0xea,0x23,0xc8,0x04,0x97,0x7f,0xca,0xf6,0xf8,0x12,0x06,0x88,0x81,0xee,0xb7,0xdd,0x56,0x9e,0x0f,0x36,0xd3,0x09,0xa8,0x74,0x4d,0x8b,0x8f,0x31,0x64,0xbe,0x9d,0x7b,0x68,0x50,0xc8,0x64,0x40,0x3b,0x0c,0x04,0xb9,0x4b,0x9e,0xff,0x7e,0x5d,0xd8,0x57,0xa0,0xe5,0x6d,0xc2,0x37,0xe7 +.byte 0xd1,0xd9,0x96,0xaa,0x16,0x3e,0xa2,0x9d,0x32,0xe7,0x1e,0x11,0x6e,0x41,0xe2,0xa0,0xe1,0x6f,0x32,0x6d,0xd5,0x38,0x0c,0x27,0x27,0xa9,0xc2,0x04,0xc6,0xe7,0x8d,0x7d,0x7b,0x30,0xbe,0x54,0x6b,0x82,0x37,0x39,0x53,0x54,0xc9,0xac,0xcb,0xd1,0x31,0x79,0xd4,0x7b,0x85,0x07,0xf4,0xf4,0x5d,0x33,0xc7,0x91,0x4e,0xe5,0x13,0x78,0x09,0x42 +.byte 0x29,0x48,0xaf,0x82,0xb1,0x88,0xd4,0xd3,0x57,0x50,0x38,0xa7,0x66,0x41,0x63,0x34,0x2a,0x3c,0x5e,0x8f,0xc4,0xc1,0x00,0xa1,0x22,0xbe,0x5e,0x64,0xb0,0x60,0x9b,0x42,0x9d,0xc6,0x59,0x5c,0xcc,0x29,0x6f,0x64,0x5b,0x5c,0x0f,0xb2,0xae,0x21,0x0c,0x9a,0x6a,0x19,0xb9,0xa6,0x32,0xf8,0xdc,0x82,0xea,0xba,0x27,0xcf,0x42,0xd3,0xde,0x78 +.byte 0xfe,0x9c,0xa5,0x36,0xb6,0x24,0xb6,0x0d,0x5b,0x67,0x6c,0xf5,0x16,0xbf,0x67,0x54,0x4f,0xe4,0x83,0x29,0x75,0x42,0x9a,0xbb,0xd5,0xe7,0x01,0x1f,0xbd,0x80,0x1a,0x7a,0xb6,0xe1,0x2b,0x5d,0x71,0x93,0x00,0xad,0xf6,0x11,0x8d,0x67,0xdc,0x9c,0x8f,0xf0,0x09,0x3f,0xf9,0xa4,0xd6,0xe0,0xdd,0x95,0xea,0xfb,0x71,0x76,0x21,0x31,0x6d,0x48 +.byte 0x0a,0x27,0xa8,0xa6,0x3a,0x7f,0x42,0x6b,0x7e,0xd7,0x6e,0xd5,0x42,0x97,0xad,0x55,0xae,0x26,0x3c,0xde,0x3f,0xaf,0xfd,0x1d,0x6d,0xd3,0xeb,0x84,0xad,0x6d,0xd1,0x4a,0x85,0x1a,0xf7,0x99,0xa4,0xd0,0x48,0xfb,0xf6,0xfe,0xc6,0xea,0x61,0x77,0xe2,0x56,0x87,0xc1,0x36,0x44,0xb4,0xe3,0xd7,0xd9,0x6d,0x3e,0x1b,0xf4,0x72,0x3e,0xfe,0xa5 +.byte 0x47,0xf8,0x3f,0x1a,0x6e,0x43,0xf5,0x67,0xfe,0x90,0x96,0x9b,0x52,0xde,0xab,0xfb,0x45,0x7d,0x93,0xea,0xc3,0x40,0xe1,0x5f,0xcd,0xad,0x3b,0xe9,0x4e,0x36,0xc5,0x38,0xf4,0x66,0xde,0x4b,0xc8,0x2a,0xc3,0xa2,0x3a,0x2a,0xf1,0xd1,0xe8,0x01,0x07,0x37,0xca,0x42,0xbf,0x4f,0xd8,0xc5,0x50,0x93,0x1a,0x01,0x1d,0x51,0x41,0x6e,0xbf,0x68 +.byte 0x93,0x2e,0xdc,0x41,0x23,0xf3,0x13,0xe7,0x09,0xfa,0x39,0x6d,0xee,0x41,0x49,0xbb,0x78,0x04,0xcf,0xc9,0xbb,0x11,0xaa,0x57,0xb5,0x3e,0x4c,0x3a,0x77,0xb7,0x0b,0x38,0x34,0x48,0xd0,0x99,0x20,0x55,0xcd,0x43,0x2f,0x68,0x66,0xb0,0xe6,0x75,0x41,0xe4,0xae,0xfd,0x96,0xe8,0x01,0x4c,0x0b,0x5c,0xbc,0x4f,0x45,0x70,0x08,0x9e,0xf7,0x68 +.byte 0x9e,0xbb,0xe5,0x39,0x20,0x3f,0xbe,0xd3,0xe3,0x95,0xba,0x98,0xd5,0x12,0x2e,0x87,0xd4,0xf4,0x12,0xa2,0xcb,0xd4,0x51,0x53,0x93,0x67,0x06,0xf1,0x21,0x0e,0x92,0x8f,0x9f,0x9e,0x6c,0x16,0xa4,0x2c,0x6d,0xb0,0xd0,0xe1,0x87,0x2f,0x09,0x2c,0x8f,0x4b,0x89,0x1f,0xab,0x66,0xf1,0xcd,0x6e,0x67,0xaf,0x07,0x99,0x18,0x1b,0xda,0xc8,0x65 +.byte 0x81,0xa3,0x37,0x8a,0xad,0xe4,0x1d,0xfd,0x82,0xa0,0xf1,0xe1,0x1e,0x8d,0x0b,0xf7,0x07,0x7c,0xb3,0x10,0xc8,0x5a,0xa9,0xcc,0xc8,0xd0,0x2e,0x5a,0x71,0x45,0x4c,0x30,0xf0,0x10,0xe0,0xf6,0x0d,0x0d,0x11,0xb4,0x83,0x40,0x75,0xee,0xb9,0x24,0x04,0xe3,0xba,0xb3,0xd3,0x00,0x57,0x71,0x98,0xf0,0x4b,0x35,0x8d,0xd8,0x71,0xa0,0xcc,0xaf +.byte 0x46,0x54,0x67,0x65,0x70,0x0b,0x9c,0x61,0xf8,0xd4,0xb2,0x35,0xfd,0xcf,0x2b,0x3a,0x48,0x5b,0x03,0x86,0xd8,0x13,0x48,0x8a,0x55,0xa5,0x4d,0xef,0x42,0x41,0xbb,0x6a,0x8c,0x92,0x46,0x87,0x82,0x09,0x43,0xf3,0x94,0x1d,0x23,0x36,0xfe,0x6f,0xb8,0x9f,0xfa,0xf9,0x92,0x27,0x3c,0xcc,0x47,0x89,0x5c,0x7f,0x81,0x42,0x74,0x12,0x14,0xff +.byte 0x98,0x63,0xc0,0xfb,0x70,0xff,0xc7,0x65,0x5a,0xc3,0xb9,0x74,0x1b,0x71,0x3c,0x2c,0x47,0x79,0x07,0xb9,0x3c,0xc2,0x5f,0x48,0x4f,0xbd,0xaf,0x03,0x05,0x57,0xa9,0x84,0x33,0xc8,0x0d,0xd5,0xac,0x42,0xdb,0x4b,0x57,0x46,0x41,0xf0,0xe4,0x08,0x0d,0xf3,0x43,0x41,0xa5,0x14,0xb7,0xcd,0x64,0x23,0xc9,0xfe,0xff,0x12,0x97,0xc6,0x2f,0x8d +.byte 0x9e,0xf2,0x1d,0x33,0x26,0x3c,0x57,0x17,0xe1,0x7b,0x92,0x3f,0xb6,0xf4,0xd9,0xf8,0xe0,0x37,0xe6,0x18,0x7d,0xa7,0x8a,0x1e,0xe8,0xd8,0x56,0xa6,0x63,0xdf,0xa3,0x99,0x16,0x74,0x48,0x01,0xaf,0x95,0x55,0x40,0xce,0xa8,0x0d,0x30,0x01,0x09,0x40,0xc9,0x9d,0x3d,0xdf,0x4e,0x00,0xe0,0x2a,0xe6,0xdb,0xa2,0x79,0x42,0x57,0xd0,0x3d,0x81 +.byte 0x7f,0x67,0x3a,0xa9,0x63,0xb3,0xd4,0x60,0xa7,0xab,0x54,0x46,0xb0,0xbe,0xb0,0x83,0x72,0xec,0x47,0x0f,0xc7,0xd1,0xed,0x16,0x96,0xbc,0xa5,0x62,0x38,0xdb,0x88,0x2b,0x25,0x26,0x27,0x56,0x7f,0x46,0x39,0xe8,0x4e,0xc0,0x6c,0x62,0xf8,0x80,0x68,0x56,0x8a,0x93,0x51,0x95,0x77,0xe3,0x11,0x7b,0xaf,0xc4,0xcf,0x34,0x5a,0xd5,0x26,0xfc +.byte 0xa2,0x18,0xb0,0xc0,0xa5,0x8b,0x25,0x70,0x40,0x70,0x29,0xc3,0xda,0x80,0x3d,0xe2,0x59,0x49,0x7f,0xdd,0x62,0x6e,0x5a,0xe6,0x27,0x73,0xce,0xb6,0x32,0x37,0x5f,0x73,0x12,0x2b,0x34,0x84,0xff,0x85,0xe3,0xb5,0x93,0x41,0x47,0xc5,0xf5,0x0e,0x21,0xfb,0x24,0x0f,0xdf,0x7b,0xb4,0x29,0x7f,0x67,0x2a,0x38,0x79,0xf0,0x54,0x8a,0x94,0x68 +.byte 0xe2,0x0b,0xb0,0xd4,0xb2,0xa4,0xe4,0xfb,0x3b,0xe6,0xe7,0x59,0x41,0xbd,0xed,0x62,0xce,0x50,0x1a,0x47,0x92,0x92,0x8d,0x80,0xa6,0x05,0x7a,0xb0,0xce,0x48,0x9c,0xb0,0x64,0xea,0xe0,0xa5,0x77,0xff,0xc1,0x82,0x99,0x7b,0xfb,0x74,0x53,0xfa,0x41,0x9a,0x2c,0xb4,0xbb,0xd2,0x26,0xa1,0x80,0x68,0x17,0xaa,0x8f,0x14,0x52,0xb6,0x5d,0xe0 +.byte 0x69,0x5b,0x31,0xc5,0xf5,0x32,0x0d,0xff,0xa4,0x7b,0x28,0x38,0x9b,0x61,0xfc,0xd0,0x92,0xb8,0x6e,0x23,0x8a,0xf3,0xc7,0x85,0x11,0xb8,0xd0,0x19,0xaf,0xca,0xa7,0xb4,0xcc,0xeb,0x5d,0xf6,0xa1,0x1c,0x56,0xdf,0x78,0x7a,0xe3,0x6a,0xa4,0x07,0x71,0xce,0xf1,0xb2,0xd5,0x38,0x3c,0xfa,0xf7,0x7a,0xbf,0x4b,0x43,0xa6,0xb3,0x4d,0xff,0x82 +.byte 0x96,0x46,0xb5,0xec,0xda,0xb4,0x5e,0x35,0x78,0xeb,0x4a,0x7e,0xc5,0x7b,0x05,0xd4,0xdd,0xf7,0xb7,0xf3,0xf0,0x04,0x26,0x7e,0x5e,0xc1,0x23,0xca,0x7f,0x14,0x27,0xac,0xda,0xe7,0xdb,0x31,0x05,0x9d,0xd4,0xda,0x20,0xc7,0x6d,0x9a,0x47,0x14,0x38,0xbd,0x7c,0xfe,0xbe,0x8d,0x42,0x7c,0xba,0x36,0xe2,0x2c,0x26,0xd2,0x46,0xa5,0x6b,0xbd +.byte 0x6a,0x75,0x6b,0x52,0x8c,0x10,0xc6,0x0e,0x76,0x60,0x46,0xcc,0x93,0x54,0xc4,0x6e,0xc7,0x70,0x5b,0xb4,0x81,0x51,0x56,0x03,0x22,0x33,0x21,0xe4,0x36,0xee,0x01,0xc3,0x0d,0x17,0x23,0x15,0xae,0x79,0xbc,0xe6,0x13,0x0f,0xfc,0x77,0xa2,0x06,0xed,0x76,0x4a,0xf7,0x2d,0x99,0xc8,0x5c,0xfd,0xac,0xd0,0x11,0xe8,0xfa,0x55,0x17,0x56,0x63 +.byte 0x3e,0xd5,0x23,0x71,0xf8,0xe9,0x1f,0x62,0x95,0xae,0x7c,0x2d,0xcd,0xb8,0x6e,0xb0,0xfe,0xf3,0xd0,0xba,0x72,0x8e,0xe3,0x95,0x82,0x00,0x85,0xdb,0x25,0xe4,0xf2,0xaa,0xbc,0x8d,0xb9,0x4d,0x69,0xa4,0xcd,0x39,0x52,0x9e,0x10,0xae,0x90,0xf0,0x74,0x2f,0xc6,0x5e,0x01,0x99,0x03,0xd5,0x88,0x59,0xfd,0x1b,0x80,0x56,0x0a,0x04,0x27,0xd9 +.byte 0x04,0x51,0xb0,0xb7,0x7a,0x65,0x79,0xa8,0xe2,0x6d,0x7f,0xb2,0xba,0x37,0x40,0xa0,0xbb,0xaf,0x15,0x46,0x23,0x5f,0x22,0xd0,0x2c,0x6c,0x7a,0x58,0x76,0x6f,0xb8,0x19,0xfe,0xb5,0x3d,0xf0,0x77,0x00,0x6b,0x4c,0x83,0x36,0x90,0xe6,0x57,0x29,0x6e,0x27,0x76,0xd4,0x7d,0x9a,0x6a,0xf1,0xf6,0x1b,0x1a,0x45,0xf5,0xf6,0x2d,0xb8,0x30,0x33 +.byte 0x65,0x51,0x37,0x26,0xbc,0xf7,0xb7,0xf9,0x56,0x05,0x6b,0xd4,0xd6,0x00,0x1d,0x13,0x15,0x45,0x24,0x0d,0x28,0x69,0xc6,0x50,0xe1,0x48,0x48,0x34,0x69,0x31,0x3c,0x58,0x71,0xd6,0x4a,0xd9,0xda,0x0d,0x28,0xbd,0xe9,0x5d,0x5d,0x8a,0x6e,0x71,0xc0,0x8b,0x7a,0xba,0x17,0x8e,0x82,0xcb,0xe9,0x95,0xc4,0x43,0x37,0xd0,0x58,0xed,0xec,0x77 +.byte 0x1e,0x22,0xf0,0xf0,0x7c,0x9d,0xeb,0x64,0x30,0x7b,0xb2,0x7b,0x86,0xdb,0xef,0x92,0x79,0xd9,0x9c,0x1c,0x1a,0xf6,0x98,0x26,0x18,0xa2,0x83,0x45,0x08,0xd4,0x1d,0x84,0xd4,0x28,0x6d,0x1f,0xb5,0x1f,0xab,0x97,0xc9,0x0d,0x1f,0x83,0x34,0x18,0xa3,0x20,0x63,0x60,0x6c,0xf3,0xd8,0xb2,0x0a,0xd9,0x35,0xa6,0xce,0x44,0x50,0xc6,0xf3,0x91 +.byte 0xe3,0x95,0x89,0x49,0x99,0x32,0x1d,0xf2,0x54,0x39,0x09,0xca,0xd1,0xc4,0x7f,0xa1,0x1d,0xce,0x94,0x67,0xf1,0x88,0x04,0x29,0xcb,0x5d,0xf7,0xfa,0xcd,0x69,0x16,0x17,0x05,0xc3,0x93,0x45,0xbf,0xd3,0x74,0x63,0xdc,0xe2,0x84,0xab,0x27,0x60,0x56,0x61,0x72,0x5d,0xdf,0xb4,0xa4,0x0f,0xb0,0x21,0x82,0x9b,0x73,0x0a,0x11,0x22,0x2d,0x65 +.byte 0xa2,0xff,0x29,0x8a,0x19,0x28,0x4f,0x4f,0xdd,0x64,0x0a,0x48,0x35,0x70,0x30,0x9f,0x41,0x4d,0x0c,0x7b,0xa6,0xcb,0x63,0x83,0xd1,0x79,0xfa,0x5f,0xc9,0x9b,0x6e,0x09,0x12,0x87,0xcd,0x1e,0x39,0xd6,0x40,0x08,0x0f,0xfd,0x79,0xc8,0xcb,0x77,0x8f,0x7a,0x52,0x42,0xc0,0xb2,0xc8,0xa0,0x2a,0xff,0xbc,0x60,0x13,0xbc,0x41,0x4a,0xc6,0x8b +.byte 0x08,0xb0,0x9f,0x75,0x87,0xa1,0x75,0x42,0x4b,0x3a,0xf7,0xf7,0x84,0x39,0xa5,0x88,0x25,0x2d,0x4f,0x73,0x4e,0x30,0x27,0x92,0xea,0x93,0x70,0x5c,0xb5,0xeb,0xb0,0x10,0xda,0x0f,0xaa,0xb3,0x3f,0xb5,0x55,0x64,0x65,0xae,0xb5,0xf8,0x0a,0xe4,0x9f,0x86,0x02,0x6f,0x63,0x8a,0x0b,0x6b,0x82,0x85,0x3c,0x6a,0xdf,0x68,0x4c,0x1e,0xe9,0x5c +.byte 0xd0,0x99,0xe5,0x0c,0xfc,0x63,0xfb,0xce,0x2d,0x63,0xd5,0x7d,0x8a,0x7d,0x14,0x22,0xbd,0x71,0x5e,0x79,0x3f,0x44,0x95,0xe5,0x6c,0x58,0x94,0x84,0x41,0x65,0x52,0x94,0x50,0xec,0xd3,0x2a,0x16,0x88,0xdb,0x71,0xb9,0xe4,0xb6,0xbf,0xc5,0x3c,0x48,0x37,0x62,0x32,0x79,0xbe,0x1d,0xdb,0xc9,0x79,0x37,0x40,0x65,0x20,0x62,0x45,0xb4,0xda +.byte 0x24,0xef,0x33,0xf1,0x05,0x49,0xef,0x36,0x17,0x17,0x0f,0xdc,0x65,0xb4,0xdc,0x57,0xc3,0xc6,0x82,0x57,0x08,0xf2,0x20,0x57,0x5c,0x25,0x0e,0x46,0x75,0xa7,0x4f,0x9e,0xa4,0x00,0xf7,0x79,0xb9,0x0a,0xef,0x4f,0x50,0x79,0xf8,0x59,0x01,0xf2,0x74,0x9f,0x16,0x27,0xa5,0xc1,0x32,0xcc,0x58,0xa7,0x40,0xa1,0xa1,0x26,0x80,0x00,0xb5,0x64 +.byte 0x0a,0xd8,0x53,0x1f,0x72,0xf7,0x60,0xf7,0x0a,0xaa,0xdf,0x31,0x95,0xff,0xfc,0xb4,0xca,0xbc,0xf8,0x2a,0x33,0x20,0x04,0x16,0x1a,0xe7,0xeb,0x22,0xd1,0x25,0xa6,0x03,0xc9,0x9e,0x9e,0xca,0x7a,0x46,0x7c,0xcb,0x8a,0x63,0x4a,0xf0,0x1b,0xd0,0x34,0xc3,0xbb,0x89,0xcf,0x16,0x38,0xcb,0xe0,0xce,0xd5,0x0b,0xfd,0x4e,0xbc,0xce,0xba,0x28 +.byte 0x68,0x00,0x2a,0x31,0x52,0xe6,0xaf,0x81,0x3c,0x12,0x09,0x2f,0x11,0x0d,0x96,0xc7,0x07,0x42,0xd6,0xa4,0x2e,0xc1,0xa5,0x82,0xa5,0xbe,0xb3,0x67,0x7a,0x38,0xf0,0x5e,0xd8,0xff,0x09,0xf6,0xab,0x6b,0x5d,0xec,0x2b,0x9f,0xf4,0xe6,0xcc,0x9b,0x71,0x72,0xd1,0xcf,0x29,0x10,0xe6,0xe3,0x27,0x1c,0x41,0xc8,0x21,0xdf,0x55,0x27,0xa6,0x73 +.byte 0xb7,0x45,0xa1,0x09,0x66,0x2f,0x08,0x26,0xf1,0x50,0xe0,0xec,0x9d,0xf2,0x08,0xf3,0x49,0x56,0x50,0xe0,0xba,0x73,0x3a,0x93,0xf5,0xab,0x64,0xb6,0x50,0xf4,0xfa,0xce,0x8d,0x79,0x0b,0xad,0x73,0xf2,0x8c,0x1e,0xe4,0xdd,0x24,0x38,0x1a,0xde,0x77,0x99,0xb8,0x92,0xca,0xc0,0xc0,0xbc,0x3d,0x01,0x6f,0x93,0x3a,0x6e,0xc5,0x28,0x6e,0x24 +.byte 0x9c,0xf9,0xd9,0xcb,0x4b,0xbe,0x9e,0xda,0x0d,0x10,0xfb,0x9d,0x15,0xfe,0x28,0xdc,0xd9,0x09,0x72,0xd3,0x9f,0x6d,0x77,0x14,0x84,0x86,0x56,0x10,0xdc,0x8e,0x6a,0xa7,0x62,0xf0,0x0b,0x65,0x2c,0xa2,0xd1,0x7f,0xae,0x32,0xfa,0x9b,0x46,0x0f,0x12,0x08,0x22,0x8c,0x87,0x15,0x4b,0xc4,0x6d,0x85,0xfb,0x69,0xfe,0xce,0xfb,0xb4,0x3e,0x7b +.byte 0xcf,0x88,0xa7,0x97,0x52,0x56,0xd0,0x9f,0xb4,0x33,0xf9,0x08,0xd2,0x28,0x46,0x5e,0xc4,0xec,0x22,0xc6,0x1e,0x7b,0x34,0x99,0x0c,0x5b,0x04,0x19,0xe2,0xca,0x09,0x11,0x50,0x45,0xcc,0xb2,0x90,0x25,0x51,0x68,0xc9,0x20,0x6c,0x99,0x2e,0xdb,0x5b,0x07,0x91,0xb2,0x69,0xbf,0x3c,0x05,0x50,0xfb,0x21,0x33,0x4f,0x6e,0x18,0x19,0xd5,0xff +.byte 0xce,0x9d,0xb5,0x7f,0xd4,0xd5,0x8f,0x41,0x26,0x1f,0xa1,0x4c,0x34,0xd3,0x98,0x08,0x5d,0xb5,0x56,0xa7,0x04,0x63,0x76,0x7d,0xae,0xee,0xea,0xbf,0x69,0x8d,0xff,0xa1,0x62,0x86,0x19,0x7b,0xe5,0x08,0x7a,0xe5,0x9e,0xe5,0x44,0xca,0x24,0xde,0x00,0x43,0xc7,0xcd,0xc8,0x5b,0x21,0x00,0xb9,0x56,0x3f,0xba,0xef,0xcd,0xc4,0xe0,0xd7,0x90 +.byte 0xa7,0xe1,0xf9,0x83,0x2c,0x1d,0x8d,0xc3,0x1b,0xa2,0xab,0xcd,0x7d,0xbc,0xd1,0x2b,0xf8,0x30,0x9e,0xb6,0x95,0xe0,0xd1,0xe6,0x81,0x89,0xa7,0xda,0xf0,0x54,0xc1,0xcb,0x3a,0x85,0x85,0xb5,0x03,0xb4,0x8c,0x7d,0x98,0x16,0xa8,0x83,0x29,0xbb,0x1c,0x1d,0xe1,0x7e,0x0e,0xb5,0x04,0xba,0xbf,0x89,0x30,0x3c,0x44,0xa2,0xc5,0xbf,0xf1,0x70 +.byte 0xdb,0xf3,0x13,0xf4,0x44,0xac,0x63,0xc4,0x9c,0x93,0xa9,0x13,0x1b,0xf1,0xcc,0x16,0x66,0xdf,0x56,0x10,0x88,0x0c,0x76,0xab,0x43,0xcb,0x75,0xf8,0x4f,0x04,0x26,0x95,0x4c,0x6d,0x55,0xc8,0xbd,0xf8,0x94,0x0f,0xca,0x29,0x2b,0xcd,0xce,0x05,0x1e,0xea,0xae,0x02,0x01,0x8b,0x60,0x6a,0x6a,0x03,0x14,0xe5,0xa7,0xdf,0x9e,0x9f,0x94,0x92 +.byte 0x41,0x2c,0xf0,0x1a,0xa7,0xc2,0xc1,0xfc,0x11,0xf3,0x00,0xe1,0xfc,0x7a,0x97,0xc0,0xe1,0x81,0x90,0x3f,0xea,0x1e,0x7f,0xf8,0xb0,0xd8,0x4c,0x2d,0xdc,0x83,0xfa,0x27,0x8b,0xf2,0xef,0x3b,0x3a,0x44,0xdc,0xa5,0xa9,0xd5,0x24,0x5f,0xb1,0xdd,0x1d,0x3f,0x03,0x76,0x3b,0x92,0x0d,0xb4,0x84,0xa4,0x5b,0xef,0x9f,0x89,0x9d,0xef,0xff,0xcf +.byte 0xc2,0x28,0x3b,0x9d,0xd2,0x28,0x75,0x3e,0xdc,0x14,0x79,0x7c,0x0c,0xaa,0x6c,0xf2,0x05,0x9d,0x27,0x01,0x15,0x19,0x60,0x48,0x5a,0x7d,0x04,0x27,0x2d,0x82,0x92,0x3e,0x0b,0x62,0xd7,0x5a,0xfb,0x72,0xfb,0xdd,0x43,0xfa,0xf4,0x6f,0x16,0xd2,0x8f,0x8f,0x21,0xdc,0x81,0x48,0x7a,0xe8,0x39,0xd5,0xdf,0x54,0x0f,0xe1,0xbe,0x65,0xc9,0x49 +.byte 0x98,0xb1,0xff,0x8d,0x52,0x31,0x6a,0xcd,0x5e,0x83,0x17,0x41,0x93,0xcd,0x23,0x76,0x18,0xe9,0x82,0x71,0x15,0xb7,0xd8,0xde,0x0d,0x57,0x8b,0x90,0xe6,0xf4,0x57,0xc1,0xfd,0x3d,0x0d,0x6a,0xae,0xd1,0xd6,0x02,0x3e,0xb9,0x82,0xb2,0x82,0x80,0x48,0xa4,0x14,0x29,0x80,0x55,0x1d,0xaf,0x3e,0xf8,0x7e,0x36,0x5f,0x77,0x4c,0x73,0x6c,0x35 +.byte 0xd2,0x7c,0x36,0xca,0x2f,0xec,0x1e,0x3f,0x74,0xee,0xa5,0xe7,0x7d,0xce,0x81,0xf1,0xd5,0xc1,0xb3,0xaf,0x90,0x2c,0xc6,0x5b,0x81,0x37,0x85,0x98,0x78,0x3c,0x4f,0x2a,0x55,0xea,0x06,0x30,0x77,0x73,0x97,0x39,0x75,0xcf,0x4a,0x9b,0x55,0xb8,0x64,0x5c,0x86,0xfd,0x26,0x3e,0x8d,0x68,0xd2,0x70,0xe8,0xd7,0x99,0x57,0x6f,0x96,0x47,0x6d +.byte 0xa7,0x1a,0x0e,0x85,0xcd,0x00,0xa5,0x3e,0x11,0xec,0x76,0xd2,0x47,0x26,0x71,0xda,0x5c,0xf4,0xb1,0xd5,0x23,0xe1,0x62,0x71,0x43,0x30,0xa7,0x95,0xf6,0xc1,0xcf,0x8a,0x1b,0x75,0x53,0x39,0x6d,0x9d,0x18,0x7c,0xe3,0x48,0x27,0x33,0x1c,0x38,0x45,0xdf,0x75,0x22,0x05,0x6d,0x81,0x5d,0xfc,0xeb,0x0e,0x05,0x26,0x45,0x81,0x9f,0xce,0x0f +.byte 0xc9,0xdd,0x95,0x11,0x04,0x47,0x40,0xa4,0x07,0x3b,0x52,0x92,0xe0,0x91,0xdb,0xdd,0x3c,0x9f,0xd3,0xa1,0xb7,0xf9,0xeb,0xd6,0x6d,0x64,0x88,0xe9,0xf5,0x4e,0x98,0x8e,0x7b,0xd3,0xec,0xc0,0x22,0xe0,0xf2,0x14,0xf2,0x20,0xa2,0xa3,0xb3,0x0d,0x75,0x1a,0xbb,0xde,0x4a,0x41,0x04,0x43,0x0d,0xd9,0xd0,0x1d,0x73,0xc8,0x67,0x8e,0x58,0xe5 +.byte 0x4b,0x28,0x4d,0x8f,0x2f,0xab,0x1a,0x4a,0xfc,0x7c,0xd1,0x27,0x3e,0x4a,0x10,0x6a,0x5f,0x55,0x3a,0xf7,0x63,0x14,0xe9,0xad,0xb4,0x95,0xef,0x3d,0x5c,0xc3,0x7d,0xe4,0xb7,0x15,0xd7,0x0b,0x68,0xf0,0x23,0xa8,0xd4,0x8e,0x27,0xf6,0x55,0x11,0xbc,0xc0,0xff,0x3e,0x2c,0x24,0x59,0xb7,0xb7,0xb5,0x0b,0xd2,0x99,0xa5,0xd5,0xe2,0x24,0x33 +.byte 0x21,0xb8,0x96,0x48,0x18,0x94,0xb5,0xb2,0x50,0x5e,0x04,0x24,0x86,0x17,0x62,0x1e,0xc9,0xf8,0x22,0x6a,0xd0,0xec,0xc5,0xbc,0x90,0xf7,0x55,0xcf,0x3f,0x4c,0x7c,0xf7,0x51,0x19,0x95,0xa4,0x81,0x38,0x0c,0xa5,0x58,0x22,0xf3,0x10,0x05,0x05,0x44,0xbf,0x7e,0x2a,0xbd,0x5f,0x79,0x56,0x08,0xd5,0x68,0xea,0x85,0xa1,0xeb,0x0b,0xe1,0xd4 +.byte 0xfd,0x3a,0x38,0xd2,0x5a,0x49,0x17,0x9a,0x58,0x8f,0x52,0xf5,0xf4,0x7b,0x1f,0x58,0xa8,0xc0,0x1c,0x46,0x38,0xa6,0xe4,0x7d,0xcc,0x88,0x97,0x10,0x2b,0x5e,0x61,0xf5,0x73,0x7d,0x79,0x1b,0x53,0xf1,0xac,0xb4,0x3f,0xbd,0x9d,0xb6,0xc2,0x57,0xd5,0x84,0x4d,0x60,0xd6,0x45,0x56,0xa1,0x36,0x28,0xf5,0x74,0xc6,0x29,0xd7,0xc9,0x63,0x5e +.byte 0x7c,0x97,0x46,0xde,0x56,0x3f,0xd8,0x8e,0x75,0x29,0x87,0xe7,0xd1,0x24,0x78,0x26,0xdc,0x17,0x97,0xc9,0xf0,0x8e,0x95,0xbc,0xe5,0xfe,0xe3,0x3a,0x75,0x70,0x52,0xa9,0x31,0x97,0x79,0x3a,0xc2,0x53,0x6a,0x73,0xe2,0x76,0xf8,0x85,0xe6,0x0d,0x85,0x9b,0xfc,0x72,0x08,0x2a,0xa5,0x8e,0x42,0xb2,0x7c,0x8d,0x8b,0x28,0x4b,0xf5,0xcb,0x66 +.byte 0x80,0x46,0xb3,0x87,0xdf,0x38,0xa7,0x08,0xc8,0xea,0x85,0x0e,0x6f,0x13,0xe0,0x57,0x99,0xc6,0xb8,0xed,0x9c,0xb0,0xa9,0x89,0xd7,0xc5,0xa9,0x71,0xfd,0x8a,0x21,0xb1,0xec,0xc8,0x65,0x78,0x72,0xc6,0x77,0x69,0xd4,0x0b,0x47,0x4d,0x79,0x93,0xcf,0x2a,0x34,0xf1,0x1b,0x0e,0x6f,0x0d,0xd1,0xbb,0xe7,0xd7,0xb5,0x6f,0x57,0x01,0xd4,0xcd +.byte 0x56,0xbe,0xf0,0xd9,0xe2,0x8e,0x0e,0xb8,0x3d,0xdb,0xf6,0x97,0x39,0x0b,0x3e,0xe2,0xb2,0xa3,0x93,0x0b,0x74,0xe5,0x6a,0x21,0x04,0x29,0x5a,0x3e,0x07,0x9c,0x11,0x4e,0xfe,0x01,0x6e,0x96,0x1e,0x8f,0xe0,0xfe,0x24,0x24,0x7e,0x04,0x2f,0x65,0xf4,0xe2,0x1f,0x36,0x56,0x43,0x3a,0x6c,0xeb,0xd7,0x20,0x13,0x71,0x45,0x6a,0xe8,0xc6,0xfa +.byte 0xba,0x26,0x6f,0x7d,0x9a,0x62,0x76,0x34,0x7d,0xed,0x47,0x71,0xd1,0x0e,0x5b,0x04,0x39,0xd6,0xc0,0xe5,0xa5,0xd8,0xf5,0x73,0xf9,0xf4,0xc2,0x2a,0x54,0x25,0x67,0xdf,0x83,0xa3,0xcd,0xfd,0x1e,0x46,0x87,0x06,0x17,0x6d,0x78,0x8e,0x0c,0x7b,0x08,0x06,0x1b,0xd9,0x5d,0x3d,0x03,0x40,0xbc,0xe7,0x02,0xc4,0xe0,0xe0,0x49,0xb2,0x6c,0x6f +.byte 0x97,0x76,0x0f,0xc7,0x14,0xd8,0x7c,0xc0,0xad,0x8a,0xbb,0xbc,0x2a,0x7e,0x68,0x46,0xcd,0xa7,0x26,0x16,0x77,0x1b,0x89,0x38,0xd8,0x2a,0x69,0x43,0xc4,0xaa,0x0d,0xf6,0xd1,0x65,0xda,0x41,0x75,0x77,0xcd,0xf7,0xd2,0x38,0x9c,0xdb,0x81,0x17,0x27,0x2f,0xba,0x2e,0xa5,0xb5,0xbe,0x05,0xe8,0xdd,0x5f,0xa9,0xad,0xbe,0xb2,0x0e,0x0b,0x69 +.byte 0xb6,0x8d,0xd2,0xf2,0xde,0x76,0x32,0x26,0xd9,0x06,0x1d,0x42,0x26,0x8c,0xf7,0xca,0x4c,0xe1,0x59,0x82,0x6c,0xea,0x96,0x70,0x39,0xb8,0x0d,0xf3,0x67,0x9d,0x5e,0x94,0x99,0x77,0xf2,0x0a,0x9a,0xde,0xa5,0xd2,0xe1,0xaa,0x91,0x85,0xc7,0x0f,0x92,0x35,0x04,0xd3,0x7a,0x13,0xfa,0xf2,0x86,0x5a,0x38,0xd1,0x7f,0x10,0xd8,0x30,0x0e,0x33 +.byte 0xe3,0xa0,0x8a,0xad,0x4f,0x6c,0x24,0xdd,0x9d,0x1c,0x4e,0xff,0x4c,0xfc,0x74,0x01,0xab,0x08,0x6c,0xe6,0x4c,0x78,0x75,0xc9,0x67,0x83,0x1f,0x75,0x22,0xb0,0x7c,0x44,0xa0,0xa1,0xee,0x4e,0xf6,0x3e,0xd3,0x35,0x70,0xbe,0x36,0x1e,0x90,0xa6,0xaa,0x64,0x67,0x7f,0x52,0x84,0xd9,0x27,0xab,0x37,0x30,0x68,0x46,0xcc,0x0e,0x57,0x58,0x6f +.byte 0xdb,0xb2,0x5f,0x24,0xf7,0xeb,0x97,0xea,0x64,0xec,0x6c,0x1e,0xe1,0xc4,0x72,0xfb,0x00,0xa7,0x62,0xa0,0x59,0xb9,0x17,0x8a,0x33,0x32,0x59,0xb8,0xbe,0x84,0xd4,0x62,0xb7,0xf6,0x35,0xd4,0xf1,0x1c,0xdb,0x7e,0xa6,0xbc,0x2c,0x54,0x3c,0xf5,0x63,0x4a,0x22,0x26,0x58,0xa0,0x35,0x98,0xa7,0x32,0xb2,0xa0,0x2b,0xd5,0xfa,0x2f,0x9b,0xb4 +.byte 0xea,0xd6,0x58,0x61,0xb2,0x24,0x45,0x46,0x1e,0xac,0x79,0xa4,0xf7,0xc1,0x13,0x2f,0xf5,0x6b,0xfa,0x70,0x50,0x2b,0x83,0xee,0x7c,0xc1,0x55,0x27,0x7b,0x4f,0xa6,0x0a,0x72,0x26,0x82,0xcd,0x4d,0xe2,0xe8,0x45,0xe6,0xd7,0x39,0x7e,0xed,0x35,0xdf,0x9e,0xb1,0x41,0x55,0xa2,0x5d,0x68,0x4b,0x0b,0xd1,0x73,0x5a,0x2b,0x81,0x35,0x28,0xfc +.byte 0x64,0x08,0xd7,0xc4,0x9f,0x30,0x77,0x3d,0x9d,0x80,0x15,0x67,0x9a,0x84,0xe4,0x34,0xea,0x8c,0xf7,0x73,0x9e,0x33,0xb4,0x09,0x33,0xbd,0xd8,0x82,0x43,0x7d,0xc5,0x1f,0x0e,0x7b,0xa0,0x53,0x59,0x20,0x12,0x57,0xed,0xda,0xc7,0x19,0x8e,0x62,0xe4,0x09,0xc1,0x4b,0x20,0x32,0x9e,0x18,0x11,0x1c,0x42,0x49,0x62,0x76,0xa8,0x83,0x72,0x11 +.byte 0x45,0xe7,0xb5,0x60,0xa7,0xc0,0x07,0xbd,0xb4,0x7c,0xc6,0x5c,0x03,0x34,0xa3,0x85,0x47,0x24,0x75,0xd2,0xab,0x46,0xbb,0xc7,0x0d,0xcd,0x40,0xe2,0x5e,0x5b,0xa7,0x98,0x67,0xe4,0xe2,0x02,0xe9,0xdc,0xd7,0xc2,0xaf,0x90,0x43,0x94,0xfe,0xf3,0x53,0xc1,0x10,0x28,0xa7,0x90,0xba,0x73,0x57,0x0c,0x4d,0x6d,0xbd,0xda,0x81,0xd5,0x90,0xce +.byte 0x02,0x40,0xb3,0xf0,0xec,0x50,0x82,0xc9,0xfb,0xf1,0x22,0x6d,0xc8,0xd2,0x7b,0xed,0x0b,0x43,0x7e,0x0b,0x60,0x9b,0x69,0x9e,0x58,0x26,0xc3,0x9f,0x6b,0xd0,0x31,0xeb,0xb7,0x0a,0xf3,0x9a,0x9a,0xf5,0x72,0xcf,0x29,0xc8,0x19,0x08,0x4d,0x67,0xd5,0xa1,0x8f,0x68,0x0e,0xee,0x59,0x14,0xf8,0x86,0xc0,0x08,0x5a,0x56,0xfe,0x6a,0xb7,0xac +.byte 0x78,0x8d,0x77,0x39,0x5e,0xb1,0x01,0x4d,0x31,0x81,0x56,0xdc,0x5b,0x10,0xda,0x4d,0xd2,0xfd,0xfc,0xa3,0xe3,0xaa,0x46,0x29,0x1a,0xea,0x9c,0x47,0x1b,0xd0,0xa6,0x84,0x1f,0x71,0x1a,0xd3,0x35,0x59,0x7f,0xef,0xf7,0x81,0x39,0x7a,0x9f,0x4a,0x01,0x4d,0x46,0xcf,0xa4,0x6a,0x9c,0x7e,0x07,0x8b,0x98,0x17,0x49,0x5c,0x46,0xac,0xc8,0xfd +.byte 0x1c,0xaf,0x91,0x30,0x0c,0x36,0x63,0xef,0x69,0xd3,0x47,0xf4,0x76,0xc1,0xf7,0x40,0x03,0x98,0x9e,0xcb,0x61,0x65,0x46,0x45,0x1c,0x1b,0xfd,0x13,0x36,0xe9,0x19,0xbf,0x2b,0x59,0x51,0xe8,0x04,0x44,0xe3,0xc2,0x4b,0x66,0x78,0x69,0x66,0xa3,0x1a,0xe5,0x2a,0xad,0xf8,0xc5,0x0f,0xb7,0x3e,0xe8,0xab,0xe0,0xe4,0xd9,0xc2,0xb8,0x61,0x5b +.byte 0xef,0x6b,0x4d,0x5f,0xb8,0xdc,0x06,0xa5,0xce,0x08,0x5b,0x1f,0xf4,0x29,0x4d,0x0a,0x3e,0xb3,0x60,0xf4,0x63,0x3c,0x70,0x5d,0x02,0x9c,0x55,0x5e,0x5e,0xd1,0x9b,0xed,0x20,0x75,0x54,0xa1,0x8e,0xae,0xce,0x5a,0xb2,0x2d,0xe4,0xc3,0x9b,0x7d,0x72,0xce,0x7c,0x0c,0xa9,0x99,0xa4,0x12,0xaa,0x31,0xe9,0x61,0x47,0x8a,0x41,0x93,0xd5,0x69 +.byte 0xc5,0xf3,0x9f,0xf4,0x97,0x69,0x64,0x6f,0xf9,0x5b,0xbf,0x58,0xf6,0x3b,0x3e,0xd6,0x93,0x94,0x89,0xcc,0xc0,0x25,0x7d,0xf8,0x40,0x9e,0xb2,0xc8,0x75,0x9d,0x4d,0xf0,0x5f,0xa5,0x3d,0x38,0x67,0xea,0x8d,0x1b,0x60,0x5e,0xfe,0xa8,0x26,0xb9,0xed,0xc0,0xe9,0xc8,0xec,0xb1,0x77,0x0f,0xf2,0xaa,0x77,0x2a,0xcd,0xa8,0x70,0xb7,0xda,0x60 +.byte 0x49,0xb3,0x01,0x95,0xc8,0xac,0x71,0x6a,0xd0,0x49,0x67,0x2a,0x04,0xfc,0x55,0x38,0x08,0x37,0xd9,0x21,0x37,0xce,0x41,0xaf,0x7c,0x33,0xdd,0xcd,0xe0,0x92,0x27,0x38,0x63,0x77,0xea,0x86,0x04,0x99,0x4e,0x61,0x8b,0x8f,0xfe,0x4e,0xc1,0x16,0x6c,0x89,0xac,0x1f,0x0b,0x67,0x75,0x49,0xf4,0xdb,0x6d,0xd3,0xb8,0x1d,0x9c,0xb2,0xe6,0x98 +.byte 0x81,0xae,0x3f,0xe0,0xdd,0xda,0xfa,0x4c,0x8b,0x30,0x18,0x88,0xa1,0x1d,0xa1,0x18,0xb8,0x28,0xc2,0x04,0x6a,0x80,0x02,0x5a,0xe6,0x04,0x85,0xfa,0x54,0x38,0x45,0x64,0xe1,0x50,0x4a,0x38,0x4c,0x85,0xf7,0x00,0x0c,0xd3,0x16,0xcb,0xfa,0x38,0xb4,0x1b,0x6a,0x95,0x3d,0xc3,0x24,0x79,0x0e,0x3e,0x81,0xe6,0xc3,0xd9,0xdb,0x05,0x19,0x7c +.byte 0xb4,0x4d,0xef,0x71,0x22,0x53,0x97,0x8a,0xc9,0xe3,0x69,0x20,0x5b,0x83,0xb1,0x44,0xd7,0xd1,0x1e,0x87,0xa7,0xbf,0xe4,0x84,0x68,0x9c,0x77,0xfe,0x83,0xdb,0x7a,0x53,0xa8,0x53,0x1f,0xc7,0xd1,0x6a,0x26,0x87,0x71,0x06,0x23,0xa7,0xe0,0x18,0x5d,0xfa,0x8c,0xa7,0x24,0xee,0xf6,0x74,0xab,0x17,0xd3,0x46,0x33,0xe9,0xc3,0xcd,0xa6,0xaf +.byte 0xcf,0xa1,0x60,0x75,0x7b,0x77,0xc3,0x58,0xa2,0xe8,0x87,0x7b,0x4b,0x57,0xb1,0x96,0xc1,0x91,0x6d,0xbf,0x71,0xb3,0xbf,0xe2,0x62,0x86,0x72,0xa9,0x01,0x64,0x62,0x32,0x33,0xc8,0xa4,0x26,0x7d,0xfa,0x0d,0xd4,0xd8,0xc3,0xaa,0xc0,0xc8,0x7c,0x51,0xe8,0x10,0x08,0x6f,0xf6,0xc1,0x46,0x89,0xc4,0xd2,0x00,0x1d,0x14,0x05,0x89,0x64,0x52 +.byte 0xcd,0x1f,0x97,0x0b,0x1d,0x94,0xbe,0x9d,0xa0,0x6b,0x03,0x9b,0x83,0x87,0x38,0x0f,0x65,0xdd,0x6a,0xaf,0xf1,0x22,0x74,0x7e,0x11,0xa0,0xdf,0x1e,0x95,0xef,0x1a,0xdc,0x8b,0x29,0x4a,0xbe,0xfd,0x2f,0xc7,0x48,0x94,0x3f,0xb9,0x8c,0x8e,0xe1,0x0c,0x54,0xa6,0x2f,0xa5,0x2b,0x71,0xdd,0x16,0x68,0x91,0x35,0xd0,0x22,0x48,0x1f,0xf2,0xe2 +.byte 0xe8,0x57,0x83,0xd7,0x49,0x43,0xfd,0xf9,0x77,0xb5,0xfa,0x70,0x19,0xeb,0xae,0xf6,0x31,0xfe,0xd6,0x81,0x6c,0xcc,0x14,0x28,0xa6,0x9f,0x74,0x56,0xc5,0xf6,0x51,0xba,0xc8,0xbd,0x32,0x80,0x5f,0xdb,0x28,0x3f,0x4a,0x55,0x01,0xe1,0x39,0xf5,0x9c,0xda,0xb3,0x42,0xee,0x43,0x17,0xc3,0xc7,0xf5,0xd1,0xda,0xd2,0x2e,0x56,0xcf,0x77,0x0e +.byte 0xdd,0x72,0xcf,0xe5,0xab,0xfb,0xd6,0xa2,0x6c,0x03,0xa6,0x77,0x25,0xf8,0x2a,0x8c,0xfa,0x6f,0x45,0x79,0x59,0x84,0x92,0xd1,0x00,0x58,0xc7,0xb8,0x95,0x4d,0xc8,0x49,0xad,0xe0,0x1e,0x64,0x47,0x00,0xfb,0x93,0x7f,0x3e,0xf1,0x65,0x70,0x47,0x64,0xbb,0x36,0x63,0xe3,0x09,0xcb,0xdb,0x5a,0xd1,0x72,0x83,0xfd,0x15,0x91,0xa2,0x03,0x81 +.byte 0x04,0x98,0x45,0x0f,0x7f,0x23,0x48,0x6c,0xb1,0x2d,0xd0,0x2c,0x61,0x52,0x1b,0x4a,0x52,0x08,0x92,0xe1,0x7a,0xf1,0x8c,0x1f,0x1f,0xdf,0x1c,0xfd,0xd9,0x46,0x99,0x71,0x05,0x58,0x71,0x82,0x5c,0x05,0xa0,0xb2,0x6a,0x50,0xd2,0x6e,0x35,0xf4,0x6c,0xfb,0x50,0x99,0xb3,0xc1,0x2b,0x05,0xaf,0x02,0xe5,0x18,0xfa,0x74,0x09,0xcc,0xa5,0x2c +.byte 0x26,0xfd,0xc5,0xe7,0x2c,0x96,0x0f,0xa4,0x7c,0x88,0xc6,0x7f,0xf9,0x74,0x9d,0x1c,0xe5,0xd2,0x27,0xf0,0xae,0x5b,0x4c,0xbf,0x0a,0x99,0x2e,0xaa,0x54,0xba,0x0d,0x75,0xd9,0x48,0x76,0xf3,0xe9,0xd9,0x01,0xbe,0xaa,0x97,0x09,0xfe,0xb2,0x4a,0xcb,0x55,0xd0,0xe1,0x58,0xec,0x31,0x0c,0xd9,0xdf,0xd9,0x01,0xf9,0x3c,0x28,0x40,0x91,0xbb +.byte 0x4d,0x2d,0x88,0x60,0x31,0xc7,0xc9,0x1d,0xaf,0x22,0x44,0x21,0x05,0x06,0xdd,0x07,0x60,0x29,0x7d,0x49,0x30,0x9d,0x35,0x1d,0x9f,0x37,0xbd,0x32,0xb2,0x21,0xa6,0x4f,0x89,0xd8,0xe6,0x85,0x44,0xcf,0x13,0x12,0x4f,0x5f,0x50,0x71,0x01,0x39,0xff,0x6e,0xa0,0x07,0xff,0xf0,0xa6,0x3b,0x39,0x59,0x17,0xae,0x93,0xb2,0x86,0xcc,0xe5,0x59 +.byte 0x5a,0xf2,0x82,0x62,0xc6,0x8d,0x13,0x2f,0x6b,0x92,0x28,0xbe,0xd1,0xc0,0xf6,0xc9,0xe1,0xd6,0x98,0x94,0x65,0xd4,0x2a,0xdb,0x37,0xb1,0xd3,0x83,0xf2,0xaa,0xa5,0x00,0xf9,0x08,0xe6,0x22,0x38,0x30,0xb6,0x49,0x8d,0x9d,0x1c,0xa4,0xf7,0xdb,0x3c,0x6f,0x75,0x08,0xa0,0xda,0xe9,0xc0,0x01,0x54,0x09,0x68,0xc6,0x7c,0x5b,0x4d,0x88,0x71 +.byte 0xa7,0x2f,0xb3,0x50,0x18,0x4a,0xfb,0x55,0x29,0xf2,0x56,0x1d,0x4c,0x12,0x22,0x1c,0x54,0xd2,0x63,0x67,0xfa,0xe9,0x5b,0x74,0x3b,0x38,0xf6,0xa0,0x85,0x63,0x1c,0x41,0x6a,0x6d,0x71,0x1d,0xb1,0x39,0x28,0x88,0x96,0x9b,0x9c,0x50,0x9e,0x57,0x4e,0xf5,0xa7,0xf4,0x17,0xc6,0xca,0x42,0x84,0x83,0xca,0xa4,0x28,0x72,0x08,0x74,0x62,0xe1 +.byte 0xf0,0x73,0xc5,0x86,0x6c,0x76,0x9d,0xd3,0xa6,0xb8,0x5d,0x73,0x1b,0x02,0xe2,0x69,0x8b,0x59,0xd6,0x6a,0x53,0xe9,0x13,0x88,0x41,0x95,0xe9,0x97,0x5f,0x07,0x62,0xa5,0x21,0x97,0x7e,0x5e,0xc2,0x2c,0xc7,0xaf,0x0a,0xdb,0x9e,0x4f,0x44,0x4b,0xd6,0x3d,0xc0,0x24,0x38,0x50,0x47,0x98,0xa3,0xfc,0xda,0xfc,0xae,0x0e,0x2b,0x9b,0x53,0x0f +.byte 0x6b,0xb1,0x2f,0xd5,0xd7,0x68,0xc9,0xab,0xb9,0xff,0x7f,0x54,0xd6,0x2f,0x88,0xbc,0x5e,0x6a,0x22,0x49,0x0f,0x98,0xbe,0x1f,0xef,0x3e,0xcc,0xa2,0x72,0x6b,0x16,0xbe,0xe8,0x5f,0x0e,0x36,0xa2,0x68,0xe0,0x65,0xd9,0x7c,0xdc,0x8c,0x6a,0x66,0xf0,0x6a,0xfc,0x2b,0x85,0x28,0x2a,0x1a,0xfc,0x92,0x64,0x3d,0x38,0x5b,0xc1,0x0c,0x68,0x45 +.byte 0x94,0x85,0x58,0x82,0x99,0xfc,0x20,0xdd,0x62,0xae,0xed,0x35,0x7c,0x02,0x16,0x9b,0x00,0x8a,0x44,0x02,0x80,0x00,0xca,0x7d,0x95,0x03,0x5d,0xa6,0xec,0xe1,0x0c,0x50,0x34,0x61,0x55,0xee,0xb5,0x11,0xff,0xc3,0xaa,0xf2,0xbc,0xa3,0xa9,0xc7,0x6b,0x16,0xab,0x56,0x7b,0x55,0x54,0x95,0x88,0x15,0x15,0x6a,0x2c,0x97,0xd7,0x7c,0x26,0x65 +.byte 0xaf,0x8d,0xd1,0x05,0x57,0xb2,0x63,0xd1,0x22,0xf7,0x7d,0x77,0x54,0x6c,0x87,0x03,0x1f,0x0e,0x2b,0xae,0xa6,0xa4,0xb5,0xd6,0x95,0x34,0xd0,0x62,0x4e,0xfb,0xcb,0xee,0x01,0xc1,0xf7,0x36,0x94,0xa6,0x54,0x94,0x90,0x0e,0x45,0x9c,0x95,0x89,0x96,0x88,0x32,0x90,0x27,0x48,0xc5,0x96,0xf0,0x7e,0x7f,0x69,0x99,0xdf,0x7b,0xfb,0x2b,0x7b +.byte 0x38,0x10,0x6b,0xd1,0x1a,0xfb,0xf2,0xcd,0x2d,0x8b,0x47,0x21,0xca,0x92,0x64,0x28,0xd1,0x53,0x1d,0xed,0xa7,0x7d,0xa4,0x88,0xab,0xd0,0xfe,0x9b,0x2b,0xf8,0x48,0x94,0x8d,0xd5,0xfa,0x5c,0xef,0x12,0x43,0xdf,0xb6,0x5b,0x83,0x43,0xf3,0xf7,0x1d,0x6f,0x3e,0x44,0xe6,0x20,0xd8,0xbc,0x4a,0x9a,0xed,0xa0,0x79,0x66,0x8d,0x23,0xca,0x35 +.byte 0x15,0x87,0x11,0x50,0xa4,0x40,0x6e,0xfa,0xf7,0xaf,0xa2,0xb7,0x3b,0x9b,0x8b,0x44,0x19,0x90,0xb3,0x47,0x92,0x08,0x2f,0x0c,0xe2,0x95,0x5d,0x80,0xb5,0x93,0x5e,0x1c,0xb5,0xce,0x52,0x0b,0x12,0xc1,0x72,0x2e,0x66,0x8c,0xd1,0x13,0x94,0x36,0xf7,0x17,0xe3,0xad,0x69,0xc9,0x2d,0x21,0x64,0xcd,0x8f,0x2d,0x8f,0x0c,0x85,0xa5,0x23,0x8b +.byte 0x6c,0x00,0x13,0xf7,0x6a,0xb4,0x68,0x1a,0xcc,0xc4,0x03,0x5b,0xd6,0x7b,0x5b,0x34,0x90,0x34,0x3e,0x0a,0x07,0x19,0x81,0x99,0xe9,0xd2,0xa8,0x73,0x2c,0xa2,0xcf,0xdf,0x29,0x69,0xbf,0xec,0xdd,0xa5,0xd3,0x16,0xb0,0xd2,0x9c,0x2f,0xeb,0x70,0x50,0x20,0x3c,0x22,0x1a,0x5b,0x55,0x79,0x76,0x0f,0x1f,0xd0,0x34,0xa9,0x55,0xad,0x75,0x75 +.byte 0x7f,0xa7,0x9b,0xa7,0x3d,0x5d,0x73,0xce,0x91,0xf6,0x9b,0xcd,0xa5,0xee,0x48,0x44,0xba,0xd5,0xad,0xbe,0x1e,0xc6,0xd2,0x8b,0x05,0x21,0x20,0xb5,0x7d,0x78,0x88,0x10,0x20,0x85,0x90,0x8f,0x47,0x74,0x68,0xe6,0x32,0x2a,0x13,0x7a,0xb3,0x5d,0xfe,0x24,0x97,0xd1,0x65,0x55,0x60,0xb3,0x88,0xfb,0x59,0xc9,0x29,0x70,0xf1,0x45,0xbd,0xbe +.byte 0x4d,0x01,0x4e,0x5e,0x5f,0x99,0x52,0xf8,0x5f,0x38,0xcf,0xa8,0x5d,0x69,0x54,0x87,0x72,0x41,0xca,0xc4,0x63,0xc1,0x52,0x58,0x66,0x8b,0xda,0x8b,0x61,0xd1,0xab,0x7d,0x8d,0xfe,0x51,0x8d,0xf6,0xd0,0x21,0x4d,0x0b,0xc5,0xea,0x74,0xcd,0x21,0x93,0x4a,0x91,0xe5,0x3f,0xce,0x35,0x3b,0x3f,0xc0,0xab,0xa4,0x23,0x76,0xd1,0x8c,0xa7,0xbe +.byte 0x15,0xab,0x8e,0xd7,0x0d,0x86,0xac,0xc3,0x06,0xff,0x33,0xf2,0x41,0x6f,0x69,0x58,0x49,0xd1,0x73,0xcf,0x5e,0x4e,0x1e,0x46,0x12,0xfa,0x30,0x0d,0x4b,0xb1,0xfb,0xc6,0xe6,0x0d,0xcd,0x8d,0xca,0x34,0x28,0x5a,0xed,0x85,0x55,0x31,0xee,0xba,0xbf,0xa4,0x6f,0x9c,0x7d,0xeb,0x4b,0x1b,0x73,0xea,0x4e,0xb9,0x62,0x5d,0xac,0xe3,0x53,0xdf +.byte 0x27,0x87,0x2f,0x39,0xca,0x5b,0xd6,0x72,0xcf,0x95,0xc6,0x2a,0xa5,0x3f,0x57,0xfd,0xdc,0xa9,0x4a,0x86,0x0f,0xcd,0xd5,0xea,0xfe,0x85,0xeb,0x9b,0x84,0xc6,0xf7,0xba,0xc2,0x37,0xbc,0x18,0x85,0x49,0xa6,0x7f,0xd9,0x3e,0xfb,0xf0,0x0c,0x39,0xe3,0x1c,0x06,0xfe,0xb6,0x49,0xa3,0x8b,0x72,0x2b,0x39,0xa1,0x48,0xfd,0x1f,0xfe,0xa4,0xf7 +.byte 0xcc,0x7a,0xef,0x64,0xa0,0x0d,0xeb,0x78,0x71,0x8c,0xd6,0x59,0x7c,0xf4,0xaa,0x81,0x7a,0x89,0xe6,0x22,0xc9,0x57,0xe8,0x13,0x9c,0xca,0xc4,0x6f,0xb5,0xbf,0x08,0x31,0x93,0x56,0x2a,0x82,0x00,0x95,0xdc,0x4b,0xfd,0x9b,0xc7,0x8b,0x31,0x72,0xa0,0xff,0xbe,0xb4,0xd6,0x07,0x16,0x0a,0x4a,0x0a,0x96,0x02,0x83,0x53,0x2a,0x4d,0x33,0x72 +.byte 0x1f,0x20,0x20,0xc3,0x63,0xee,0x4e,0x05,0x90,0x7d,0x21,0xd0,0xf1,0xda,0xde,0x0d,0x4a,0x59,0xb9,0xca,0x81,0xe3,0x1f,0x83,0x19,0xdc,0x09,0x03,0x5f,0xaa,0xee,0xbc,0x5a,0xfa,0xc6,0x4d,0x3d,0xfe,0xfe,0xf3,0xdb,0xc3,0x77,0x31,0x74,0xb4,0x94,0xb5,0x09,0xb1,0xb5,0x13,0x47,0x2e,0x4f,0x3b,0x38,0x83,0xf5,0xfc,0xe9,0xcc,0x45,0xea +.byte 0x5b,0x88,0x21,0xba,0x53,0xc5,0xf6,0xd4,0x63,0xc5,0x37,0x1d,0xa1,0x42,0x2e,0x9c,0x9a,0x50,0x2c,0xfe,0xdb,0xf6,0x31,0x36,0x5f,0x9d,0xed,0x63,0x42,0x20,0xdd,0x27,0xe5,0x34,0x3c,0x0f,0x06,0x8b,0x8f,0x32,0xb6,0x47,0xce,0x07,0xcb,0x27,0xc1,0xb7,0xfe,0xb2,0x69,0x81,0x79,0x20,0xd7,0x47,0xbb,0xab,0x61,0x5f,0x09,0x99,0xdf,0x9f +.byte 0xde,0x59,0x33,0x75,0xd1,0xcc,0xfe,0x92,0x79,0x1f,0x2d,0x59,0x88,0xef,0x4b,0x80,0x0c,0x38,0xa3,0xb1,0xef,0xae,0x53,0x84,0x2f,0xbd,0xd3,0x0c,0xcf,0xd5,0xf7,0xb7,0x6f,0xa7,0x22,0x1f,0xf1,0x56,0x76,0x0c,0x78,0x52,0xa3,0xc0,0xd0,0x2f,0xbc,0xdf,0x29,0x0d,0xa8,0x54,0x0d,0x2b,0x65,0x1b,0x7f,0xeb,0x21,0x22,0xaf,0x10,0xc1,0xd6 +.byte 0x30,0xa8,0x2f,0xb1,0x25,0xbf,0xdc,0xee,0xe9,0x35,0x40,0x69,0xa0,0xa0,0x27,0x85,0x2e,0x18,0xc1,0x36,0x24,0xc5,0x96,0x9a,0x85,0x3f,0xbb,0xfd,0xf5,0x02,0xa2,0xa1,0x92,0x3c,0x16,0x48,0x9f,0xc5,0x00,0x7c,0x7b,0xaf,0x31,0xba,0x68,0x0e,0x58,0x88,0xf4,0x10,0xb9,0xa6,0xe0,0x46,0x2a,0xb8,0x8d,0xc7,0x8e,0xad,0x7c,0xec,0xd2,0x74 +.byte 0x92,0xfe,0x1b,0xd0,0x73,0x79,0x0b,0x4e,0xcc,0x2d,0x5c,0xe7,0x80,0x2d,0x21,0x1c,0x97,0xfc,0x2a,0xc9,0x9c,0x07,0x10,0x64,0x8b,0xf7,0xf5,0x1c,0x54,0xb6,0x6c,0x73,0x1c,0x50,0xd3,0x1a,0x2a,0x63,0xcb,0xba,0xd3,0x95,0xe2,0xa6,0xc3,0xca,0x45,0xfd,0x5e,0x1b,0xbb,0x6b,0x4d,0xb3,0xf7,0xfd,0xaa,0xf9,0x73,0xb8,0x74,0x4d,0x36,0x7e +.byte 0xcc,0xaa,0x1e,0xf3,0x20,0x68,0xa5,0x0c,0x03,0xe3,0xbe,0xee,0x82,0x03,0x8d,0x10,0xa6,0xf6,0x6c,0x73,0xc2,0x9d,0x74,0xba,0x57,0x17,0xd7,0xfa,0x85,0xf5,0x1e,0x3d,0xf8,0xc7,0x80,0xef,0xcd,0xf0,0xf4,0x46,0xfc,0x07,0xb5,0xc4,0x5f,0xd2,0x04,0x6a,0x90,0xf5,0x76,0xb6,0xf9,0x73,0x22,0xa6,0x09,0x2f,0xbf,0xb5,0x93,0x9a,0x95,0x05 +.byte 0x95,0xaa,0xf9,0x8c,0x71,0xd6,0xc6,0xd9,0x72,0x50,0xf6,0x58,0x77,0x09,0x47,0x97,0x21,0x42,0xf0,0x30,0x5c,0x3c,0xec,0x60,0x67,0xdf,0x5e,0xd2,0xed,0x0f,0xab,0x25,0x11,0xbb,0xf8,0x34,0x1e,0xbd,0x7f,0xc6,0x52,0x19,0xf5,0x53,0x28,0x46,0x75,0x93,0xce,0xc2,0x0b,0xdf,0xfd,0xa5,0xf1,0xb0,0xa2,0x0b,0x97,0xb5,0x76,0xb4,0x8a,0x2b +.byte 0x82,0x55,0x23,0x29,0xc2,0xd3,0x32,0x94,0x2f,0xf0,0xe6,0x77,0x2c,0xe4,0x6a,0x7f,0xd7,0xee,0x84,0xfb,0xba,0xb8,0x4b,0xae,0x13,0x34,0xbd,0xa8,0x12,0x7a,0x3c,0x28,0x40,0x74,0x5d,0x9a,0x11,0x1a,0xe9,0x74,0x31,0x28,0x3d,0x3d,0x64,0xb7,0x54,0xa0,0x51,0x0d,0xed,0x97,0x94,0x56,0x7a,0x48,0x8e,0x36,0xc9,0xae,0x5f,0xc6,0x79,0x45 +.byte 0x4f,0x07,0xdd,0x13,0x52,0x8b,0xfc,0x3b,0x73,0x44,0x68,0x64,0x51,0x0d,0x95,0x6f,0x0f,0x94,0xba,0xf8,0x40,0x64,0x51,0x43,0x49,0x63,0xc1,0xbd,0xf3,0x39,0x7f,0x6e,0x6f,0x45,0xeb,0xd2,0x33,0x44,0x2d,0x10,0xb4,0x68,0xcb,0xcb,0x8c,0x84,0xc5,0xd4,0x63,0x1d,0x23,0x85,0x30,0x4d,0x6c,0xfc,0xc9,0xa4,0x8c,0xd2,0x42,0x69,0x2f,0x17 +.byte 0x86,0xf0,0x17,0xd0,0xb2,0xaa,0xfd,0x62,0xcb,0xb4,0xfd,0xba,0x29,0xf8,0x85,0x45,0x84,0x9d,0xae,0xf8,0x9c,0x8f,0x64,0xd5,0xb8,0xb6,0xa9,0x64,0xf9,0x39,0x86,0x68,0x29,0xac,0x32,0x87,0x84,0x6c,0xb0,0x09,0xd2,0xdd,0xf2,0xec,0xa1,0x3a,0xfd,0x11,0x37,0x54,0x67,0x29,0x62,0x25,0x62,0xe8,0x6a,0x4b,0x5e,0xde,0x9a,0xf0,0x97,0x73 +.byte 0x66,0x69,0x2a,0x21,0xbe,0x95,0x86,0xca,0xf9,0x17,0xe9,0x4b,0x23,0x83,0x1e,0x8c,0x37,0x47,0x91,0x03,0x3f,0x9f,0xb8,0x60,0x2c,0xdd,0x82,0xbd,0x2a,0xc3,0xe7,0x30,0x8f,0x91,0x2b,0xa4,0x23,0x01,0x03,0xb2,0x8b,0xbd,0xd2,0x1d,0x16,0xf7,0x6a,0x86,0xa8,0xe4,0x54,0x6f,0x9c,0x47,0xa5,0x0f,0xbe,0x94,0x56,0xfa,0x18,0x69,0xbe,0x92 +.byte 0xe9,0xf8,0x24,0x4d,0x65,0x42,0x81,0x1f,0x85,0x52,0xb7,0xc9,0x49,0xde,0xa5,0x4c,0x8f,0x0d,0x5f,0x12,0x68,0x68,0x35,0xce,0x29,0x22,0x5c,0x55,0x3e,0xbd,0xce,0xf2,0x2a,0xec,0x7e,0xe1,0x29,0x0a,0x88,0xf3,0x5e,0xeb,0x27,0xe5,0x52,0xee,0x72,0x37,0xba,0xff,0x82,0x97,0xa9,0x5d,0x77,0x6f,0xb9,0xc3,0xa7,0x73,0xba,0x7f,0x2f,0x7a +.byte 0x19,0x32,0x87,0x56,0xa2,0x89,0xb2,0xb4,0x48,0xbe,0x2e,0x30,0x89,0x0a,0x8f,0x75,0x25,0x25,0x5c,0x46,0xe8,0x02,0x45,0xcb,0x03,0xd1,0xa3,0xeb,0x70,0x71,0x08,0x1c,0x46,0xf1,0x2c,0x43,0xe2,0x44,0x30,0x6a,0x61,0x31,0x45,0x3e,0xbb,0x47,0x33,0x24,0x25,0x13,0xeb,0xf7,0x24,0x66,0x15,0x4c,0xf3,0x07,0x2f,0xff,0xdc,0x37,0x0f,0x71 +.byte 0x85,0xc8,0x56,0xa7,0x2a,0x22,0x87,0x8b,0xae,0x35,0x31,0x29,0x96,0xf0,0x81,0xfb,0x2c,0xbf,0x44,0x69,0x69,0x9a,0x77,0xfd,0xc0,0x2b,0x42,0x16,0x67,0xd6,0xbd,0xd0,0xf1,0xb9,0x40,0x8f,0xd2,0x9a,0x1b,0x2c,0x64,0x78,0x6b,0xda,0x37,0x26,0xae,0x4c,0xee,0x36,0xaf,0x84,0x61,0xe4,0x93,0x22,0x64,0xaf,0xee,0x6d,0x69,0x5c,0xe5,0x85 +.byte 0xd8,0xcc,0xcf,0xf3,0xe8,0x05,0xcd,0xd2,0x09,0x66,0xaf,0xbb,0xc4,0x79,0xb2,0xa7,0xa5,0x09,0xd9,0xf5,0xa2,0x83,0x4f,0xd5,0xf5,0xf3,0x7d,0x7a,0xab,0x94,0x83,0xb3,0x15,0xfb,0x0d,0x1a,0x1d,0x77,0xc5,0x63,0x0b,0x54,0xde,0xa8,0x0d,0xc4,0x16,0xe3,0x89,0xeb,0xa3,0x1b,0xd4,0x77,0x13,0xe3,0x55,0x98,0x15,0xab,0x3b,0x32,0xc8,0xd4 +.byte 0x0c,0x91,0x80,0x57,0xf7,0x1e,0x24,0xd0,0x56,0x78,0x29,0xd2,0x03,0xe7,0xc4,0xd2,0x09,0xca,0xee,0x9b,0x60,0x5f,0xa1,0xfd,0xaa,0x85,0x4b,0x68,0x35,0xa4,0x3b,0xef,0x29,0xb8,0x49,0x85,0xee,0xbb,0x39,0xc0,0xc6,0x99,0x97,0xc6,0x86,0x6c,0x27,0xf9,0x1a,0x19,0x6e,0x7c,0xae,0x75,0x41,0x0d,0x08,0x1e,0xf0,0xb4,0xc3,0x9e,0xdb,0x40 +.byte 0x86,0x94,0x9d,0x90,0x09,0x3f,0xdc,0xb9,0xfc,0x59,0x41,0xc5,0x5b,0x89,0x97,0x49,0x4a,0x1a,0x06,0x68,0x83,0xd8,0x7e,0x09,0x51,0xe1,0x86,0xd8,0x88,0xbe,0x8a,0x36,0x48,0xb3,0x83,0x7b,0x57,0xdd,0x8f,0x18,0x67,0x4a,0x7d,0x68,0xab,0xb9,0x05,0xf0,0xe4,0x27,0x4e,0x33,0x44,0xa7,0x13,0x04,0x94,0xc5,0x57,0xaf,0x36,0x03,0xe8,0x09 +.byte 0x36,0x5b,0xe8,0x92,0xad,0x0a,0x79,0x02,0x24,0x43,0x62,0xc7,0xa5,0xce,0x7c,0xac,0x6d,0x0a,0xf2,0x83,0x33,0x05,0x3b,0x6f,0x9d,0xda,0x96,0x9f,0x8b,0x79,0x3e,0x6c,0xd6,0xba,0x7f,0xea,0x84,0xd8,0x23,0xb6,0x92,0xc3,0x9c,0x7f,0x0d,0xcb,0x7b,0x9f,0xbd,0xc2,0xf5,0x6f,0x71,0x67,0x5f,0x0b,0xd1,0x73,0xb5,0x8c,0x46,0x07,0xcd,0xd8 +.byte 0xee,0x28,0xcf,0x8f,0x8e,0x5c,0xde,0x14,0x78,0xc7,0x60,0xd5,0xf4,0x49,0x97,0x46,0x5f,0x49,0x4a,0xb4,0x8f,0xc9,0xd1,0x52,0x34,0x01,0x29,0xa1,0x46,0x55,0xf8,0x29,0x53,0xbb,0x32,0x1e,0x4b,0x89,0x96,0x53,0x0b,0xf2,0x16,0xf9,0xa7,0x70,0x93,0x59,0x78,0xc0,0x77,0x78,0x9f,0x6c,0xb3,0x0e,0x3f,0x6f,0x40,0x09,0x1d,0xd6,0x66,0x4e +.byte 0xe8,0xb0,0xa1,0x14,0x65,0xc8,0xc7,0x3f,0xd2,0xf0,0x1f,0xfd,0x51,0xe0,0x29,0xd6,0x39,0x26,0x60,0xfe,0x62,0xc2,0xe4,0x45,0x6d,0x01,0xdb,0xd3,0x7c,0xdf,0x48,0x10,0x2f,0xf2,0x8e,0x6c,0xc6,0x58,0xc3,0x7d,0x26,0xb1,0x9d,0x52,0x02,0x2a,0x5f,0x2b,0x57,0xca,0x84,0x9d,0x74,0x31,0x01,0x0f,0xda,0x3d,0x7c,0xbb,0xdc,0x71,0x82,0x8b +.byte 0x42,0xaf,0x49,0x9e,0x2c,0xe8,0xdc,0xa1,0xfb,0x23,0x6d,0xdb,0xdc,0x36,0x01,0xc9,0xb3,0x93,0xd4,0x2e,0x8b,0xd1,0xe4,0xed,0x1b,0xd0,0x4c,0xeb,0xaf,0x96,0x57,0xde,0xee,0x90,0xf4,0xa7,0x58,0x46,0x8a,0xd4,0xa9,0x44,0xe0,0xb3,0x13,0x96,0xb2,0x8a,0xb0,0xd3,0xbe,0x71,0x38,0xb7,0x35,0xa9,0xa8,0x48,0x37,0xa3,0x11,0x0e,0x61,0x36 +.byte 0x6c,0xaf,0x6c,0xf2,0x3f,0xd6,0x55,0xb3,0xa5,0xe0,0xaf,0x18,0x6a,0xf5,0x78,0xb5,0x7c,0xc7,0x48,0x24,0x6c,0xea,0x1e,0x7f,0x52,0xb4,0xe8,0x72,0x46,0xd2,0xbd,0x1c,0x9e,0xe6,0x5b,0x3e,0x9c,0x6c,0x6c,0x6b,0x45,0x0c,0x3a,0xb7,0x67,0x3c,0x8e,0x77,0x77,0xbf,0x50,0xb6,0x30,0x6e,0xe1,0x28,0x0d,0x2a,0x85,0x44,0xf8,0xbb,0xf1,0x14 +.byte 0x89,0xaa,0xc2,0x27,0xf5,0x8e,0xa1,0xd3,0x07,0xba,0xe8,0x03,0xcf,0x27,0x1c,0xa6,0xc4,0x63,0x70,0x40,0xe7,0xca,0x1e,0x05,0xb7,0xb7,0xdc,0xc0,0x07,0x4c,0x0d,0x21,0x12,0x60,0x02,0xe3,0x86,0x65,0xe7,0x1c,0x42,0x86,0xdd,0xdb,0x7f,0x26,0x60,0x01,0x3d,0xd8,0x18,0xcd,0x7a,0x9f,0xf8,0xb2,0xf6,0x6d,0xd3,0xe0,0x57,0x1f,0x80,0x30 +.byte 0x2d,0x5e,0x71,0xdf,0x4d,0x7f,0xcd,0x63,0x77,0x19,0x5e,0x2d,0xd5,0xb5,0xfa,0xa9,0x26,0x02,0xb9,0x62,0x2b,0x57,0x80,0x0a,0xe9,0xbc,0xa4,0x3b,0xa7,0xf1,0xf3,0x77,0x2b,0x6b,0x41,0x5e,0xf7,0xe8,0x66,0x23,0x63,0xac,0xcd,0x58,0xfc,0xa9,0x97,0x6b,0x5a,0x1e,0xe5,0x7d,0xfd,0xb1,0x42,0x7f,0x99,0xdd,0x60,0xaf,0x39,0x46,0x36,0xdd +.byte 0xc2,0x70,0x83,0x53,0xd1,0xc3,0x69,0xc8,0x90,0x0e,0x2b,0x34,0xb2,0x0c,0xb9,0x7a,0xb8,0x6b,0x7c,0xc2,0xf3,0xae,0x41,0x24,0xb8,0x94,0x5f,0xdd,0xce,0xda,0x95,0xda,0x49,0x81,0xb6,0xf8,0xa9,0x8e,0xb3,0x79,0xf8,0x55,0xf9,0xcf,0x8c,0x24,0x99,0xfc,0x6b,0x15,0x0f,0x39,0xac,0xd0,0x3e,0x89,0x9d,0xc2,0x46,0x8c,0x99,0x45,0xfd,0xce +.byte 0x13,0x4c,0x9c,0xc8,0x80,0x87,0x8f,0x7b,0x28,0xe3,0x5e,0x2b,0xe3,0x89,0x7e,0x13,0x52,0x52,0xe9,0x3a,0xed,0x33,0xe7,0x28,0xc7,0x7a,0x48,0x8d,0x0e,0xee,0x24,0xc4,0x61,0x04,0x3c,0xd4,0x7e,0xf3,0x30,0x22,0x07,0x58,0xae,0x02,0xc5,0xd1,0x7d,0x04,0x18,0xca,0xd6,0x04,0xd4,0xc5,0xa4,0xff,0x8d,0x0d,0x68,0xd4,0x1a,0x3a,0x72,0x6f +.byte 0x41,0x1e,0xda,0xc0,0x97,0x7c,0x55,0x2c,0x13,0x20,0x9a,0x07,0x35,0xcc,0xc5,0x83,0xee,0x41,0x77,0x51,0x28,0x07,0xe0,0x81,0xe3,0x9b,0x1f,0xdb,0x73,0x5c,0x8d,0x82,0xa2,0x8b,0xf4,0x92,0x4f,0x70,0xa8,0x6a,0xcf,0xbf,0xcf,0x0b,0x71,0xbc,0xeb,0x81,0xb4,0xc9,0x65,0xe7,0x43,0xef,0x25,0x45,0x27,0xea,0xcd,0x60,0x68,0xcd,0x2d,0x7a +.byte 0xfd,0x88,0x6d,0x06,0xd5,0x92,0x32,0xc3,0x18,0x88,0x64,0xa7,0xde,0x39,0xeb,0x0b,0x5c,0x9c,0xf6,0xf6,0x93,0x90,0x24,0x0c,0x9e,0x0b,0x89,0x1c,0xcb,0xc8,0x96,0x72,0x17,0xae,0x46,0x61,0x69,0x6e,0xbe,0x6c,0xf1,0xa4,0xa4,0x50,0xa9,0x2a,0x47,0xd7,0x80,0xe4,0x72,0xd2,0x3f,0x1a,0xdd,0x82,0xdc,0x12,0x66,0x10,0x26,0x15,0x80,0x56 +.byte 0x4d,0xbe,0x02,0xae,0xe1,0x24,0x8a,0x41,0x52,0xc8,0x5d,0x8d,0x62,0x85,0xbe,0x7c,0x35,0xdd,0x88,0xd3,0xf5,0xf7,0x9b,0xf1,0x5a,0x4e,0x70,0x48,0x31,0x5a,0xaa,0x96,0x1e,0xf8,0x73,0xb4,0x0f,0xb2,0x82,0xf4,0x13,0xac,0xba,0x3b,0x12,0x36,0x1e,0x23,0xbf,0x09,0x8a,0x1c,0x96,0x47,0x56,0x2d,0x16,0x24,0xc3,0x23,0x65,0xe2,0x99,0xd0 +.byte 0xf0,0xa0,0x2c,0x64,0x35,0xad,0x16,0x34,0x67,0x52,0xbc,0x8f,0x17,0x90,0xf9,0xc7,0x4f,0x64,0x6c,0x75,0x3f,0xd7,0x48,0xa4,0x6b,0x43,0xe6,0x2e,0x7a,0xe3,0x79,0xe8,0x47,0x51,0xe9,0x52,0x36,0x30,0xa4,0x24,0x89,0x00,0xd5,0x77,0xbd,0x34,0x2e,0xa9,0x74,0x02,0x25,0xc0,0x0c,0x10,0x31,0xf0,0xa7,0xcb,0x01,0xed,0x43,0x70,0x15,0xe6 +.byte 0xda,0x01,0xb4,0x7a,0x13,0xbc,0xf1,0x57,0x34,0xb1,0xb7,0xb3,0x26,0x18,0x5f,0x42,0x6b,0xcb,0x78,0x25,0x48,0xe9,0xe6,0xe8,0xf5,0x45,0xa2,0x61,0x97,0x10,0xa5,0x7e,0x7a,0x48,0xf3,0x23,0xa5,0x88,0xc0,0xc4,0xc7,0x3b,0x5c,0x0c,0xfc,0xe0,0xf4,0x68,0x64,0xc6,0x9f,0xd9,0x17,0xcb,0xe5,0xba,0x4a,0xa4,0xe0,0x27,0xf8,0x2b,0x4e,0x67 +.byte 0x13,0xab,0xd2,0xce,0xbc,0x8d,0xdf,0x6e,0x49,0xaf,0x72,0x8a,0x51,0xa1,0x78,0x38,0x0a,0x58,0x2e,0x72,0xec,0x94,0x70,0x8d,0xdf,0x0b,0x5a,0x52,0x81,0xb1,0x9b,0xda,0x2c,0xd2,0x85,0xbb,0x8f,0xb0,0x99,0x64,0x24,0xbe,0x03,0xd9,0x92,0x8d,0x29,0xf3,0x41,0x9c,0xd6,0xef,0xef,0xb2,0x5c,0x22,0x90,0xff,0x27,0x4d,0xb3,0x91,0x72,0x9f +.byte 0x42,0xca,0x66,0xc5,0x66,0xb7,0x50,0x3e,0x83,0x6f,0x2d,0xe3,0x7b,0x2a,0xc4,0x5a,0x93,0x92,0x80,0xdb,0x1a,0xdd,0xef,0xfd,0x96,0xcb,0x6a,0xd8,0x4a,0xc5,0x6e,0x36,0x4a,0xe4,0x10,0x15,0xb3,0x12,0xb4,0xd9,0x9e,0x37,0x48,0x96,0xcb,0xe5,0x3a,0x4f,0x57,0xa6,0x46,0x2f,0xd3,0x06,0xb8,0x61,0x1c,0x17,0x3a,0xb8,0xad,0x40,0x50,0x57 +.byte 0x10,0xd9,0xd0,0xe9,0x1b,0xe3,0x18,0x8c,0xc4,0xfa,0x08,0x8d,0x82,0x3c,0x22,0x22,0x1b,0x97,0x64,0xa6,0x8b,0x7c,0x70,0x2b,0xa0,0xd8,0x4c,0x64,0xcf,0xbc,0x49,0x78,0xcb,0x92,0x0f,0xe1,0x60,0x12,0x4e,0x92,0x0d,0xaf,0xa4,0x1f,0xe0,0x2a,0xa5,0x69,0xc6,0xa1,0x91,0x5c,0xdd,0xb8,0xae,0xfa,0xc5,0xb9,0x18,0x31,0x81,0x32,0x6e,0x97 +.byte 0x44,0x2a,0xda,0x58,0xcd,0x9e,0x0d,0x57,0xe0,0xe3,0x5f,0x7b,0x04,0xd8,0xc8,0x68,0xf5,0xa2,0xac,0x0c,0x29,0xf0,0x7e,0xff,0x32,0xfb,0x53,0x1a,0xc2,0xe3,0xae,0xa5,0xe4,0x9c,0x50,0xaf,0xf4,0xde,0x0b,0xdd,0x4d,0xfa,0x65,0x3c,0xbe,0x3c,0xb8,0xda,0x88,0xd9,0x6c,0x55,0x58,0xe1,0x4d,0x00,0xa8,0x1e,0xe2,0x3a,0x9c,0x53,0x9b,0xca +.byte 0xb7,0x5d,0x3a,0x83,0xe0,0xbb,0x95,0xc4,0xd5,0x45,0x48,0xdc,0x12,0xab,0x24,0xfc,0x5d,0x91,0xe1,0xc8,0x0a,0x5c,0x10,0xc4,0xc9,0xaf,0xb6,0x54,0x80,0xfd,0xa0,0x70,0xb9,0xab,0xdf,0x34,0x9f,0x5c,0xff,0xde,0x8e,0xa0,0x0b,0x21,0xcf,0x28,0xc4,0xdf,0x67,0xb5,0xc0,0x20,0x49,0x0c,0x7e,0xe6,0xf7,0x41,0x6b,0x75,0xd9,0x1d,0x3b,0x49 +.byte 0xb7,0x4f,0x01,0xd1,0x20,0x62,0x15,0x1e,0x9f,0x16,0xb0,0xbd,0x30,0x09,0x05,0x00,0x0f,0x25,0x5a,0x37,0xe9,0xa6,0xc6,0xef,0xe5,0x39,0x2b,0xd7,0x6b,0xc5,0x96,0xd2,0xad,0x46,0xaf,0xd3,0xc0,0xfd,0xea,0xff,0x4c,0xaa,0x44,0x48,0x9a,0xdb,0x99,0x44,0x3f,0x4a,0xf0,0x3f,0x81,0x75,0xf2,0x79,0x31,0x3c,0xed,0x56,0xc6,0xf0,0xf1,0x8c +.byte 0xdb,0x1d,0x6c,0x6c,0xcc,0xfb,0xc2,0x30,0xf6,0x24,0x14,0x69,0xc4,0x89,0x4d,0xd0,0x10,0x77,0x37,0x00,0xe8,0xc9,0xf2,0x32,0xf1,0x43,0x8b,0xe1,0x09,0xc4,0x59,0x17,0xf9,0x20,0x2b,0x01,0x76,0x20,0xb8,0x03,0x84,0xf6,0xd7,0x2e,0xef,0x20,0xa6,0xfa,0x8b,0x74,0x7f,0x4a,0x14,0x33,0xad,0xac,0x45,0x66,0x18,0x2b,0x6b,0xd2,0xb8,0x20 +.byte 0x1a,0xff,0xca,0x25,0x69,0xfd,0xba,0x4b,0x5b,0x9c,0x38,0x35,0x4c,0x30,0xa2,0x24,0x3d,0xbb,0xd4,0xf3,0x67,0x24,0xa5,0x93,0xc6,0xf5,0xb2,0xb4,0xa5,0x04,0x53,0xb6,0xe4,0xc7,0xdc,0xf1,0xe5,0x43,0xb7,0x73,0xaa,0xab,0x5c,0xea,0xcb,0xf1,0xeb,0x5b,0x04,0x7a,0xff,0x0f,0x5e,0xb4,0xd3,0x2a,0x39,0x50,0x1b,0x54,0x1f,0x32,0xd7,0x7c +.byte 0xea,0x3f,0xee,0xa5,0xc8,0x46,0x48,0x7e,0x75,0x60,0x7a,0x42,0x42,0xd3,0x15,0x07,0x69,0x46,0x1c,0xe2,0x21,0x31,0x94,0x31,0x24,0x9e,0x39,0xab,0x7a,0xf9,0xc2,0x0b,0x2d,0x6b,0x55,0xa3,0x36,0xb2,0x65,0xf2,0x17,0x08,0xde,0x15,0x83,0x07,0x36,0x12,0x54,0x8f,0x0b,0x23,0xa8,0x7e,0xb5,0x57,0x1c,0x9e,0x29,0xd7,0xd4,0x9b,0xc1,0xf6 +.byte 0x94,0x23,0xf3,0x92,0xbf,0xba,0xc8,0xf5,0x78,0x3e,0x67,0x48,0x14,0x3b,0xd4,0xe9,0x8f,0x78,0xc1,0x4b,0x9a,0x59,0x08,0xaa,0x50,0xf4,0x9d,0xc4,0xc3,0x2c,0xbc,0x56,0x2c,0x13,0x30,0x75,0xfb,0xed,0x48,0xab,0x90,0xec,0x64,0x18,0xb5,0xd5,0xb5,0x7f,0xc1,0x7f,0x83,0xf2,0xdb,0xae,0xde,0xf5,0xb5,0x29,0x03,0xbe,0x80,0xb1,0x5d,0x97 +.byte 0xd3,0x7a,0xa4,0xd0,0xe0,0xce,0x04,0xda,0xaa,0x82,0x19,0xc9,0x02,0xb7,0x1c,0xe1,0x66,0xd9,0x3e,0x86,0x6d,0xb5,0xd1,0x35,0x63,0x8e,0x4b,0xc6,0x58,0x41,0xf9,0xb7,0xba,0xf3,0x06,0x91,0xb7,0xa2,0xfb,0xb5,0x5f,0x53,0xf3,0xe0,0xc1,0xf6,0x91,0x66,0xc7,0x93,0x3a,0x0a,0x72,0xb1,0xed,0x36,0x9d,0xde,0x21,0xdd,0x7d,0x0a,0x7b,0x35 +.byte 0x1f,0xc3,0x56,0xde,0xbb,0xcb,0xb2,0x0a,0xb6,0x84,0xce,0xa1,0xc6,0x1a,0x46,0x2f,0x9f,0x48,0xd5,0x98,0x73,0xa4,0xbd,0xbd,0xa3,0xe9,0xc9,0xc4,0x64,0x89,0xb7,0x9c,0x97,0x7c,0x2f,0x88,0x22,0xe4,0x4b,0x71,0x3d,0x2a,0x47,0xee,0xf8,0xfe,0xe0,0xf7,0x03,0x14,0xe6,0x7c,0x9e,0x57,0xbb,0x8e,0xf5,0xea,0x63,0xfc,0x5b,0x18,0x3b,0xa2 +.byte 0xa1,0x4a,0x28,0x82,0x37,0x77,0x5b,0xc4,0xd3,0xc1,0xf2,0x87,0x13,0x2b,0x2a,0xc8,0xac,0x70,0xe1,0x82,0x38,0x9c,0x12,0xa0,0xc4,0x9e,0x6b,0xac,0x33,0x8a,0xe9,0x31,0x6f,0xa1,0x76,0x94,0x48,0xcf,0xbc,0x78,0x22,0x82,0x6a,0xb0,0xb9,0x49,0x71,0xdb,0xde,0x8b,0x90,0x09,0x82,0x4d,0x79,0x17,0xe8,0xcf,0xd8,0x50,0xc3,0x08,0x07,0x81 +.byte 0x5f,0x9a,0x72,0xce,0x0a,0xe4,0x29,0xc9,0xdd,0x95,0x67,0x58,0xa1,0x14,0xec,0xcf,0x2f,0x29,0xcf,0xce,0xb3,0x35,0x54,0x77,0x67,0x56,0xec,0x95,0x68,0xee,0xbf,0x9c,0x9f,0x74,0x78,0x12,0xd5,0x30,0x83,0x28,0xd5,0x36,0x96,0x57,0xa0,0x8d,0x1c,0x99,0x19,0x04,0xaf,0x25,0xe5,0x71,0x83,0x88,0xb0,0x74,0x38,0xdd,0x8a,0xff,0x39,0x7a +.byte 0xfd,0x34,0x8f,0x9c,0x67,0xa8,0xc8,0x6f,0x13,0x5d,0xf2,0x5b,0x22,0xd3,0x8e,0x63,0x51,0x58,0x9b,0xfc,0xaa,0x89,0x65,0x4e,0x36,0xc4,0xa7,0xef,0x98,0xf9,0xaf,0xcd,0x35,0x8c,0x16,0xbc,0x70,0x4f,0xcd,0x71,0x2a,0xf4,0x13,0xb3,0x3d,0xa3,0x92,0x71,0x45,0xe5,0x9a,0x45,0xbd,0xc5,0x1d,0x82,0x60,0x3a,0x97,0xf3,0x0f,0x96,0x21,0x3d +.byte 0xe5,0x6e,0xfb,0x9d,0x9b,0xeb,0x15,0xc2,0xa6,0x73,0x76,0xf2,0xcd,0xec,0xfd,0x0f,0xf4,0x3f,0x46,0xc9,0x9c,0x73,0xa1,0x21,0x08,0xdc,0x31,0x00,0xaa,0x95,0x07,0xf0,0x3d,0x51,0x57,0xfa,0x6b,0xc3,0x8e,0xe9,0xa4,0x65,0xdc,0xff,0x57,0xb9,0x1f,0x4f,0xc6,0x6d,0x03,0x00,0xa7,0x19,0xb8,0x24,0xb5,0x3d,0x87,0xcb,0x84,0xb7,0xf5,0xfe +.byte 0x51,0x16,0x5b,0xc7,0xed,0x4b,0xff,0xa3,0x66,0x17,0x93,0x60,0x69,0x84,0x8c,0x95,0x74,0xa7,0x30,0x2d,0x09,0xf7,0x4e,0x0e,0x2f,0x99,0xda,0x46,0x34,0x0f,0x93,0x90,0x97,0x4c,0xa6,0x25,0x15,0xb8,0x6f,0x1d,0xd5,0xe1,0xc1,0x39,0x50,0xfd,0xd5,0x79,0x4f,0x04,0x2f,0x76,0x50,0x3f,0x67,0x56,0xad,0x02,0x82,0x30,0x1a,0xaa,0x6e,0xe2 +.byte 0x05,0x6a,0x93,0xb7,0xbe,0xde,0x84,0xce,0xd8,0x53,0xed,0xad,0x95,0xab,0x45,0x1f,0x4c,0x3b,0x22,0x36,0x27,0x45,0x19,0xa4,0x7f,0x12,0x20,0x6c,0x9d,0xeb,0xd2,0xfe,0xd6,0x7d,0x25,0xf9,0xe3,0x64,0x77,0x56,0x89,0x12,0x57,0x80,0xd5,0x40,0xbb,0x2a,0xcc,0xac,0x34,0x8e,0x87,0xfd,0x58,0xc3,0xbd,0x92,0x48,0xd8,0x7f,0xc4,0x39,0x6a +.byte 0x4e,0x1c,0x50,0x93,0xef,0xae,0x81,0x93,0x50,0x95,0x6e,0x46,0x7c,0xf5,0x27,0x44,0x6c,0x21,0x06,0x49,0x89,0x7e,0xf4,0xfa,0x08,0xa5,0xbc,0x0a,0xbd,0xb6,0x7b,0x55,0xac,0x87,0x19,0x33,0xfa,0xab,0xf3,0x15,0xc9,0x1b,0x83,0xf2,0x41,0xf1,0x26,0x6f,0xdf,0x15,0x60,0xdb,0xa6,0x03,0x43,0x3e,0x34,0x7a,0xa9,0xb1,0x38,0x57,0xe4,0x09 +.byte 0x1a,0x4a,0xd8,0x6e,0x28,0xee,0x7d,0x74,0x54,0x03,0xb3,0x29,0x24,0xb3,0xf0,0xc6,0x20,0x7c,0x47,0x01,0x66,0x36,0x7a,0x14,0x18,0x09,0xd6,0xaa,0xa6,0x82,0x5b,0xe4,0x0a,0xf9,0x41,0x52,0x3b,0x56,0xa2,0xf8,0xa2,0xa1,0x2b,0xe0,0x0d,0x1f,0x5b,0xe4,0x0e,0xe1,0x94,0x84,0x6f,0xed,0x2e,0x11,0xfa,0x4a,0xbd,0x41,0xf4,0x3c,0x8c,0x7e +.byte 0x94,0x46,0xec,0x79,0x81,0xb0,0x36,0xfd,0x9c,0x73,0x0f,0x84,0x1a,0x59,0x4e,0x1b,0xd5,0xd1,0x0d,0xff,0xfd,0xb7,0xfb,0x73,0x35,0x8a,0x66,0xed,0xf3,0xee,0x6d,0xf7,0x86,0x0a,0xb9,0xc0,0xf1,0xa3,0xb7,0x32,0x49,0x01,0xe8,0xcd,0xfe,0x82,0x7b,0xf6,0x46,0xd8,0x73,0x47,0x8b,0x7b,0x6e,0x31,0x92,0x0f,0x4b,0x16,0x11,0x86,0x1d,0x02 +.byte 0x5d,0x12,0x79,0x59,0xdc,0x8c,0xaa,0x1b,0xc1,0x75,0x63,0xb2,0xd6,0xbf,0x19,0xb0,0x81,0x70,0x34,0x12,0xd2,0x09,0xbe,0x6d,0xa1,0x31,0x77,0xd2,0x9b,0x59,0xdc,0xcb,0x67,0xb5,0x14,0xcd,0x37,0x31,0x2c,0xa6,0x17,0x58,0x2b,0x24,0xfc,0x2a,0x9e,0x8f,0x38,0x38,0x7a,0x80,0xda,0x8b,0x54,0x1d,0xc9,0x99,0xc7,0x1f,0x98,0x7a,0x1f,0x32 +.byte 0x23,0x1c,0xb5,0x6e,0x53,0xd3,0x61,0xe7,0x78,0x19,0x6c,0xd5,0x2f,0x85,0xde,0xd1,0x67,0x6b,0x9b,0xa1,0x09,0x87,0x5e,0x89,0x5e,0x89,0x21,0x36,0xf2,0x94,0xc1,0xfd,0x6c,0x4e,0xd9,0x6b,0xd2,0xb1,0x1b,0x48,0x37,0x9a,0x7b,0xc9,0x52,0xfd,0xe2,0x6d,0x07,0x19,0xf2,0xa5,0x69,0xdc,0x0b,0x52,0x8f,0xb3,0x87,0x03,0x1a,0xd8,0x43,0x20 +.byte 0x68,0xcf,0x08,0xcc,0xce,0x37,0xf6,0x96,0x7f,0x03,0x62,0xb2,0xce,0x6a,0xfb,0x22,0x54,0xd6,0xfc,0x84,0x5c,0xf5,0x55,0x32,0x36,0x77,0x1d,0x15,0x6a,0x2c,0x3a,0x01,0x34,0xff,0x5b,0x7f,0x3f,0xab,0x97,0x8f,0xbd,0x1d,0x07,0xb9,0x47,0xb1,0xcc,0xc0,0xdf,0x17,0x38,0x54,0x07,0xc0,0x1b,0xb9,0xa2,0x29,0xa6,0x25,0x73,0x32,0x4d,0x5e +.byte 0x51,0x60,0xb3,0x27,0xe5,0xb6,0xdb,0x56,0x81,0x95,0x03,0x7e,0xca,0xc6,0x15,0x8f,0x48,0xd4,0xac,0x71,0x41,0xdc,0x9c,0x86,0x5d,0xd8,0x90,0x90,0x54,0xdd,0x3d,0xf3,0xa8,0xbb,0xe5,0x55,0x69,0x26,0xdf,0xd1,0x8e,0x75,0x2a,0xe4,0xfe,0xe0,0x80,0x1d,0x6b,0xd2,0x8a,0x06,0x49,0x4e,0x60,0xf8,0xbd,0x3d,0x99,0x27,0x80,0x27,0x42,0x66 +.byte 0x01,0x32,0xe1,0x9e,0xa6,0xde,0x7b,0x14,0xa4,0x49,0x68,0x70,0xbe,0xa4,0xe1,0x44,0x2e,0xce,0xa3,0xe9,0x1d,0x7a,0xbd,0xf1,0xe4,0x25,0x11,0x47,0xd8,0xaa,0x32,0x34,0xf8,0xca,0x3d,0xec,0xf3,0x5d,0x8a,0x55,0xe7,0xd4,0x7c,0xfb,0xcf,0xe7,0xa6,0x13,0xaa,0x16,0x5f,0xaa,0x02,0x19,0xdd,0xf1,0xf8,0x5c,0xb2,0x1e,0x68,0x9a,0x21,0x93 +.byte 0xd1,0x38,0x31,0xbb,0x26,0x76,0x44,0xf8,0x84,0x3b,0xf5,0xd1,0x52,0xbe,0x1b,0x8e,0x4d,0xa0,0xb4,0x4a,0x5a,0x7e,0x89,0xe5,0x36,0xb0,0x76,0x77,0xc5,0xc2,0x22,0x73,0xc2,0x19,0x12,0x7f,0xdf,0x9c,0xb8,0xc0,0xf5,0x0e,0xd5,0xa3,0x55,0xae,0x61,0xf8,0xf1,0x6b,0x79,0xc8,0x2e,0xbc,0xa5,0xef,0xd4,0xb1,0x84,0x0c,0x15,0xc4,0xed,0xb3 +.byte 0x18,0x29,0xd6,0x31,0x83,0x79,0x30,0x1a,0x8f,0xf0,0x3b,0xe9,0xd1,0xf2,0x1d,0xec,0xcb,0xe8,0xc5,0x1c,0xb5,0xcb,0x8e,0x01,0xd1,0xb2,0x86,0x43,0x33,0x95,0x70,0x7e,0x75,0xa9,0xa1,0xe7,0xcb,0xd9,0xf4,0xd3,0xe1,0xe2,0xe9,0x46,0x21,0x20,0x3b,0xe9,0x48,0x1c,0x3f,0x93,0x57,0x31,0xeb,0x15,0x9c,0xa7,0xa6,0xcb,0xb5,0xb7,0xa7,0x24 +.byte 0xbe,0x66,0x4c,0x92,0x7c,0xe8,0x8e,0x3f,0x9c,0xa9,0xd7,0xad,0x73,0x68,0x19,0x19,0xd4,0xb5,0x57,0x82,0xdc,0x67,0x3c,0xec,0xac,0x06,0xec,0x86,0x9b,0x65,0xff,0xbb,0xc3,0x90,0x48,0xdb,0x52,0xcc,0xa4,0xf5,0xdf,0x2c,0xc5,0x5a,0xe3,0x30,0xed,0xad,0x37,0x40,0x8c,0xaa,0x32,0x4f,0x94,0x1e,0x14,0x59,0x48,0x1d,0xd3,0xaf,0x80,0xe7 +.byte 0xcf,0x6b,0xa7,0x70,0xe7,0x98,0x22,0x4b,0x40,0x02,0x0c,0x29,0x09,0x0a,0x53,0xf7,0xd4,0xeb,0xbb,0x75,0xb4,0x30,0x1c,0x67,0xea,0xd2,0xb5,0x40,0xfe,0x57,0x2c,0x3c,0x44,0x8d,0x8d,0x02,0x78,0xf0,0x76,0x8f,0x92,0xab,0xb4,0xc9,0xc0,0x2f,0xf5,0xde,0xa7,0x09,0x14,0xf1,0xe5,0x34,0xeb,0x86,0xfa,0xcf,0xcc,0x85,0x1c,0x9c,0xa6,0xe1 +.byte 0x72,0x9e,0xc1,0xe4,0x74,0xc4,0x96,0x5d,0xf4,0x4b,0x23,0x4f,0xa5,0x32,0xff,0x38,0x21,0x8f,0x43,0xe5,0x96,0x20,0x3c,0x78,0xb8,0xb4,0xcd,0x29,0x62,0x84,0x59,0xb5,0xb4,0x57,0x07,0xa8,0x79,0x77,0x21,0xf4,0x82,0xa7,0xb1,0x36,0xee,0x16,0x8e,0xb5,0x9a,0xf7,0x03,0xac,0x64,0x03,0x20,0x48,0x24,0xbc,0xbb,0xec,0x50,0xed,0xa1,0xf3 +.byte 0x67,0xd9,0x34,0xe1,0x0c,0x0b,0xc3,0xd0,0x46,0x0b,0x55,0x85,0x59,0x3c,0xb4,0x7d,0xd0,0xc2,0xe7,0x95,0x24,0x1f,0x53,0x76,0xf1,0x81,0x4a,0x61,0x6a,0x2e,0x3b,0x3f,0x92,0x14,0x7c,0xe0,0x33,0x7f,0xb4,0x85,0x92,0x78,0x0c,0x0b,0xe7,0xbd,0x7a,0x08,0x31,0x7d,0x47,0x3b,0xfa,0xdd,0x90,0x9e,0xf0,0xa9,0xd1,0xa7,0x7c,0x2a,0x37,0xb1 +.byte 0x23,0x71,0x34,0xa0,0x63,0xfb,0x9e,0x8f,0x39,0x00,0xa0,0x09,0xd4,0x1f,0xf4,0xba,0x2d,0xc1,0xac,0x6c,0x94,0x18,0x56,0x3e,0x89,0x92,0x63,0x10,0x5e,0xfe,0x76,0xec,0x4e,0xb6,0x5d,0x59,0xf9,0x94,0x46,0x4f,0xda,0xd5,0x3e,0x6c,0x48,0x49,0x7e,0x7c,0x77,0xe7,0x7e,0x22,0x31,0xb5,0x9d,0x15,0xd3,0x08,0x24,0xdb,0x67,0x98,0x6b,0xfc +.byte 0x45,0x54,0x85,0x29,0x9a,0x47,0xa5,0x60,0xe2,0x46,0x36,0x45,0x16,0x54,0xd6,0xb1,0x5c,0x38,0x45,0xf8,0x43,0x28,0x58,0x81,0xc9,0x57,0x10,0xda,0x3b,0xfc,0x3e,0xe4,0xf4,0xb2,0x16,0xb6,0x16,0x1d,0xa4,0x68,0xa6,0xe0,0x36,0xdb,0xe2,0x19,0x1c,0xce,0x9f,0x94,0xa9,0x94,0xad,0x20,0xcb,0x17,0xd0,0x92,0x37,0x75,0x88,0x0d,0xaf,0xdf +.byte 0x98,0x6d,0x19,0x9e,0x8e,0x61,0xe4,0x8c,0xfc,0x27,0x27,0x6a,0xa7,0xa4,0x66,0x7f,0x08,0x03,0xef,0x5c,0x4a,0xb7,0x89,0xa1,0xae,0xe8,0x70,0x3f,0x13,0x27,0x0a,0x7d,0x5d,0x5e,0x2b,0x69,0xb5,0x98,0x1f,0x25,0x1e,0x41,0xff,0x46,0x5a,0x25,0x1f,0xb4,0x90,0x8e,0x81,0x91,0x19,0x63,0x10,0xd4,0xa9,0xdf,0x3b,0xae,0xe6,0x63,0x1a,0xdc +.byte 0x09,0x5f,0xac,0xaa,0xb8,0x6b,0xbd,0x6a,0x90,0x70,0xce,0x2c,0x63,0x6d,0x48,0x78,0xca,0xc1,0x59,0x94,0xe2,0xc7,0x89,0x17,0x73,0xfa,0x73,0x34,0xb7,0xd3,0x9c,0x4e,0xd8,0xac,0x18,0x80,0x25,0xbf,0xbe,0x75,0x0a,0x9a,0x05,0x5e,0x54,0xcb,0xba,0xab,0xca,0x7f,0x96,0xf7,0x26,0x8c,0x82,0xe0,0x23,0xa5,0x86,0xb5,0xdf,0x31,0xd0,0x2f +.byte 0xe3,0x66,0x96,0x83,0xd2,0x04,0x43,0x8a,0x28,0x59,0x49,0xdc,0x11,0x38,0xd9,0x5f,0xc2,0x31,0xaa,0xa8,0x1a,0xff,0x57,0xf1,0x84,0x18,0x28,0xe8,0x04,0xae,0x98,0xa4,0x17,0xc4,0x35,0x75,0xf5,0x37,0xf5,0x27,0x3e,0x7e,0x32,0xa4,0xcb,0xd4,0x43,0x59,0x02,0x63,0x7b,0x7c,0x9d,0xa7,0x61,0x12,0xf7,0xdc,0x12,0xe0,0x07,0xac,0x96,0xf3 +.byte 0x71,0x43,0xe5,0x30,0xe0,0x4c,0x51,0x2a,0x19,0xf5,0x79,0x59,0x5a,0xc5,0x74,0xfa,0x54,0x18,0xb4,0xb1,0xfb,0x4b,0x9b,0xf8,0xe4,0xa4,0x63,0x25,0xc3,0x84,0xeb,0x2e,0xa1,0xf8,0xf8,0x7b,0x25,0x6a,0x7d,0x14,0x38,0x06,0xeb,0xae,0x9f,0xa5,0x80,0x9a,0x8a,0xb6,0x46,0x95,0xdf,0x52,0x11,0xd4,0x30,0xcc,0x11,0x8f,0x4a,0x5e,0x56,0x26 +.byte 0x60,0x3d,0x5f,0x0b,0x04,0x94,0xcd,0xca,0x1d,0x6b,0x83,0x51,0x83,0x8d,0xf8,0x33,0x4a,0x91,0x00,0xa4,0xf5,0x44,0x5b,0xad,0xa0,0x4a,0x72,0xaf,0xe6,0x4a,0x0d,0x1e,0x9f,0x18,0x6b,0xb4,0xdf,0x85,0x61,0x2a,0x3b,0xe1,0x4c,0xaa,0xc3,0x17,0xef,0x51,0x9f,0xae,0xb5,0xca,0xaa,0x6c,0xd9,0xa1,0xf5,0xa3,0x6f,0x1c,0xca,0xb3,0x37,0xda +.byte 0x27,0xea,0xcb,0xb7,0x36,0xb2,0x11,0xda,0x9f,0x07,0x78,0xaa,0x6c,0xad,0x63,0x9b,0x49,0x6b,0xfe,0x1f,0x93,0x82,0x73,0xc9,0xc8,0xf6,0x68,0x54,0x50,0x77,0xba,0x78,0xc7,0x82,0xee,0xbd,0x97,0x66,0xb9,0x22,0x49,0x0d,0x7a,0x1f,0x0f,0x4e,0xe5,0x02,0x8b,0xa6,0x1b,0x11,0xfc,0xa6,0x37,0x2a,0x5c,0x66,0xaf,0xac,0xa5,0x9f,0xbf,0x26 +.byte 0x98,0x9b,0x25,0x44,0x48,0x09,0xe6,0x76,0xb9,0x08,0xf1,0x37,0xcf,0x86,0xc9,0xdf,0xa8,0xf3,0x88,0x2f,0xc1,0x33,0x15,0x95,0x59,0xf7,0x9b,0xf2,0x48,0x76,0xcb,0xd0,0x31,0xe4,0x27,0x74,0x2d,0x6e,0xd2,0xc3,0x29,0xea,0xef,0xff,0x4e,0x3d,0xda,0x3e,0xef,0x94,0x94,0x40,0xcd,0x93,0xcf,0xb8,0x56,0x29,0xf8,0x20,0x20,0xa3,0x66,0x83 +.byte 0xba,0xc8,0x4f,0xe6,0x22,0x96,0xb5,0xb2,0x44,0x75,0x55,0x98,0xed,0x11,0xd0,0x58,0x50,0x26,0xf1,0x4a,0xf6,0x80,0x5c,0x17,0x92,0xba,0xc2,0xd6,0x68,0xd4,0x7a,0x4f,0xdf,0x16,0x97,0xbd,0xad,0xd7,0x1b,0x0c,0xe5,0x23,0xa9,0xaa,0xf4,0x1c,0x8d,0xec,0xbf,0xf0,0xb5,0xaa,0x49,0xfd,0xf1,0x31,0x9b,0xf9,0xe9,0x21,0xa1,0x20,0xab,0xbe +.byte 0x56,0x8c,0xf2,0x85,0xdc,0x1f,0xea,0x25,0xce,0xf5,0x6c,0x18,0x7d,0xc4,0x1a,0x01,0x08,0x01,0xed,0x02,0xa8,0xac,0x7f,0x74,0x2c,0xd7,0x28,0x25,0x6e,0x68,0x19,0x38,0x8d,0x20,0x51,0x8f,0x38,0x8b,0x03,0x36,0xae,0x50,0x35,0x28,0x65,0x7e,0x15,0x2a,0x80,0x2c,0xae,0xcd,0xb3,0xb6,0x91,0xf1,0x8c,0xf2,0x8c,0xc5,0xce,0x3e,0x3a,0x97 +.byte 0x5a,0xff,0xe1,0x37,0x13,0xf7,0x6b,0x07,0xb2,0xaa,0xaa,0x57,0x18,0xb7,0xb2,0x19,0x52,0xbf,0x59,0x0b,0x6f,0xba,0x56,0x54,0x14,0xac,0x21,0xfd,0x7d,0x03,0x4b,0x0b,0x39,0x54,0xba,0xf9,0xba,0x73,0xcd,0x67,0x13,0x30,0xca,0x19,0x80,0x4f,0x18,0xb4,0x75,0x2a,0xec,0x78,0xa7,0xd0,0x5c,0x53,0xe2,0x43,0x2c,0x08,0x5f,0x5c,0xe6,0x60 +.byte 0xde,0x04,0xf6,0x75,0xca,0x35,0x3b,0xf6,0x68,0x53,0x60,0xc0,0xed,0xb0,0x15,0xa1,0xa4,0x89,0x23,0x34,0x49,0x35,0xd2,0x78,0x4b,0x8f,0x7c,0x8d,0x59,0x22,0x9f,0xad,0x72,0x47,0x5b,0xde,0xf2,0x09,0x08,0xa0,0x8d,0x5f,0x4d,0xc3,0xd1,0x83,0x17,0xbc,0x39,0x8e,0xa5,0x53,0xaa,0xe3,0x31,0x03,0x93,0x14,0xb4,0x57,0xf0,0xdf,0x54,0x1d +.byte 0x79,0x4d,0x21,0x1a,0x8f,0x3f,0x6e,0x07,0x41,0xcc,0x2d,0x94,0x55,0x4e,0x50,0xfd,0xac,0xe3,0xef,0xa7,0x50,0x3b,0x3c,0xda,0x32,0x25,0xee,0xd9,0x01,0x37,0x8e,0xb3,0x23,0xc5,0x5e,0x12,0x88,0x6d,0xd5,0x41,0xfd,0x3f,0xfa,0x75,0xb8,0xcb,0x82,0x10,0x81,0x38,0x1b,0x10,0x2d,0x2c,0x6b,0x62,0xa1,0x7c,0xd1,0x75,0xd8,0x8c,0x0c,0x2f +.byte 0xe8,0x97,0xff,0x18,0xb3,0x12,0xa2,0xef,0x6c,0xc5,0x79,0x9f,0x64,0xf3,0xc7,0xdc,0xdb,0x54,0xa4,0x25,0xc7,0x30,0xfb,0x6c,0x5a,0x50,0x24,0xf9,0xb6,0xc9,0xe7,0xda,0x78,0xcc,0x1b,0x5e,0xf3,0xe7,0x32,0xd8,0x36,0x47,0x10,0xe5,0x2c,0xeb,0xea,0xf7,0x25,0x30,0x93,0x64,0x88,0xc8,0x59,0xf8,0x5c,0x02,0x43,0x4c,0x23,0x8e,0x1c,0x42 +.byte 0xe4,0x36,0x39,0xbf,0xba,0x8b,0xe3,0x53,0x01,0x32,0x0d,0x89,0xc2,0xea,0x35,0x94,0xf1,0x0d,0x29,0x45,0x08,0x07,0x15,0xcb,0xd7,0x3e,0x4d,0x9f,0x04,0xd8,0x18,0x8a,0x56,0xa3,0xb1,0x1c,0x46,0x19,0x8b,0xd0,0x51,0x30,0xf3,0xca,0x52,0x2a,0x16,0xc4,0x90,0xc1,0x00,0x50,0x87,0x8b,0x4c,0x71,0x61,0x48,0x69,0xb2,0xf1,0x33,0xaa,0x79 +.byte 0x81,0x8b,0x36,0x33,0x19,0x41,0x6b,0xc1,0x91,0x40,0xf2,0xcc,0x1d,0x83,0x09,0xab,0xcc,0x6f,0x6c,0x54,0x91,0x62,0x80,0xac,0xe6,0x1f,0xcd,0x5d,0x05,0x2b,0xe5,0xac,0xbc,0xd6,0x1b,0x8b,0xef,0x95,0xa0,0xf3,0xfe,0x8e,0x4d,0x32,0x77,0xe8,0x02,0x8f,0x44,0xad,0xc4,0x40,0xc3,0x99,0x68,0x81,0x47,0x15,0xbd,0x3b,0x8f,0x0b,0x9b,0x3a +.byte 0xb3,0x9d,0x8f,0x3d,0x86,0xd1,0x89,0x5f,0x67,0x19,0x33,0x2d,0x18,0x64,0x0e,0x3a,0x13,0xa4,0xe9,0xb4,0xc9,0x90,0x09,0x6a,0xcb,0x5d,0x0d,0x83,0x13,0x04,0x29,0xe5,0xa5,0xf4,0x00,0x56,0xf4,0x80,0x96,0x33,0x93,0xe4,0x9b,0xc4,0x6e,0x38,0xbf,0x0a,0xe0,0xee,0x8c,0x89,0x5d,0x60,0x36,0x7e,0x69,0xc2,0xc7,0x28,0x6f,0x2b,0x97,0xfb +.byte 0xb3,0x5b,0x82,0xe8,0x9a,0x36,0x44,0xd7,0x1f,0x9b,0x1b,0xd0,0x14,0xe4,0xd4,0x0d,0x35,0xcd,0xee,0x88,0x50,0x37,0x5c,0x88,0x09,0xa5,0x16,0x4d,0xe1,0xbc,0xe8,0x79,0x8f,0xa9,0x18,0xb8,0x43,0xb4,0xd7,0x32,0xcd,0x26,0xdd,0x78,0x29,0x59,0xad,0x29,0xe3,0xe0,0xe7,0xcf,0x16,0x03,0xc6,0x8a,0xb6,0xa2,0x09,0x9a,0x6e,0x90,0x7b,0x0c +.byte 0x9d,0x20,0xb6,0xc4,0x28,0x3f,0x44,0x06,0xa9,0x45,0x72,0x27,0xa7,0x56,0x3f,0x07,0xff,0x13,0xd9,0x80,0xda,0xbd,0x25,0xad,0xd3,0x74,0x2c,0xd8,0xd2,0x93,0xa5,0xda,0xbc,0x5f,0xa5,0xde,0xb7,0x3a,0xf0,0xd2,0x17,0xb1,0xc3,0x70,0x2a,0x85,0xde,0xf0,0x97,0x7b,0x96,0xb2,0x0e,0x45,0x7f,0x63,0xd4,0x94,0xd8,0x78,0x05,0xcf,0xea,0xb3 +.byte 0xfb,0x7a,0x79,0xb5,0x91,0x53,0xb8,0x8c,0xa2,0x03,0xf4,0xc3,0xed,0xf0,0xab,0x33,0x5c,0x6e,0xcd,0xbd,0x73,0xe3,0xe9,0xd0,0x83,0x2a,0x2a,0x68,0x32,0xf1,0x69,0x4f,0xd0,0x8b,0xe8,0xa1,0x7d,0x5b,0x0f,0x69,0xc2,0x33,0xbf,0xc1,0x54,0x29,0x47,0xed,0x9f,0xdb,0x35,0x0a,0x3d,0x2b,0x9d,0x8b,0x91,0xb6,0xe0,0xbc,0x53,0xba,0xb7,0xcd +.byte 0x2c,0xd9,0xeb,0x81,0xa0,0x2e,0x14,0x6e,0xdc,0xe1,0x90,0x36,0x14,0x9d,0xa8,0x8b,0x6b,0x1b,0xac,0x4c,0x09,0x8b,0x1a,0x87,0xf4,0x66,0xf6,0xfb,0x62,0x92,0x13,0xcf,0xb2,0x96,0xf0,0xc9,0x8b,0x12,0x99,0xf1,0x16,0xae,0x5c,0x27,0x24,0xa8,0xfd,0xb3,0x4c,0xc2,0xe6,0x3f,0xd2,0xc6,0x0c,0xf2,0x65,0x4e,0xdf,0xf1,0x06,0xb8,0x99,0xc4 +.byte 0x3a,0x35,0xba,0xed,0x18,0x3e,0xfa,0x03,0x51,0x8d,0x45,0x68,0x12,0x7b,0xb6,0xac,0x63,0x99,0x47,0xee,0x6f,0x8b,0xcb,0xc1,0x0a,0xf9,0x23,0xf0,0x05,0xe1,0x03,0x4a,0xb5,0xe0,0x65,0x71,0xc8,0x64,0x7e,0x0d,0x39,0xe7,0x96,0xdb,0x34,0x63,0x2e,0x1a,0x27,0x85,0x52,0x63,0x8e,0x44,0xfb,0x61,0xca,0x79,0xe5,0x91,0x99,0x83,0x2d,0xe0 +.byte 0x26,0x04,0xad,0x43,0x26,0xf2,0x7e,0x56,0xae,0x35,0x6a,0xfb,0xec,0xc6,0x27,0xe4,0x3a,0xa3,0x6b,0x63,0x72,0xba,0x98,0x03,0x9f,0x2a,0x4c,0xb1,0x33,0x22,0x9d,0x53,0xf6,0x00,0xa3,0x1e,0x32,0xcb,0xbe,0xe0,0xc2,0xf8,0x71,0xcd,0x3f,0xe3,0x4d,0x83,0xf2,0x9f,0x1c,0x91,0x35,0x97,0x52,0x95,0xba,0x24,0x04,0x04,0xca,0x32,0x6d,0xd7 +.byte 0x4b,0xd4,0x9e,0x8b,0x73,0x42,0xfb,0x9f,0xfc,0x93,0xea,0xc2,0x41,0x56,0xa9,0xe5,0xdd,0xd0,0x37,0x8a,0xe2,0x92,0x9f,0x45,0x4f,0xd8,0xef,0xe6,0x6f,0x58,0x41,0x5f,0x7b,0xe7,0x0f,0x32,0xce,0x06,0x02,0x7f,0xe2,0x37,0x87,0xb7,0x35,0x72,0x68,0x87,0xc9,0x35,0xa8,0x51,0xce,0xd8,0xde,0xc3,0x8c,0xb4,0xab,0xf4,0xa7,0x3b,0xcd,0xc8 +.byte 0x0a,0x56,0x5b,0x48,0xb1,0xa4,0x27,0xa8,0x9e,0x3e,0x04,0xbc,0xb3,0x63,0x3e,0xd5,0xf7,0xae,0xec,0x0c,0x6e,0x4a,0x73,0xb6,0xed,0x66,0xea,0xc1,0x7a,0xc4,0xaa,0x21,0x27,0x62,0xef,0x3d,0x1d,0x51,0x8b,0x63,0xe6,0xe2,0x8a,0xed,0x7a,0x4b,0x90,0xc3,0x9f,0x91,0xb4,0x8f,0x78,0x65,0x9c,0xdd,0x0a,0x7a,0x50,0x36,0x33,0x30,0x3b,0xb4 +.byte 0xdf,0x67,0xbd,0xfd,0x71,0xfc,0x40,0x49,0xaa,0x01,0xdf,0x68,0x67,0x73,0x31,0x2c,0x98,0x2f,0x8c,0x9e,0x2d,0xce,0x4a,0x71,0xbc,0x6f,0x90,0x1d,0xc0,0x37,0x07,0x30,0x0c,0xa3,0x04,0xfb,0xd1,0xd0,0x0e,0xcb,0xdc,0x94,0x06,0x7f,0x83,0xe5,0x45,0x47,0xd0,0x71,0x06,0x94,0x23,0x7c,0x03,0x80,0x46,0xa5,0x10,0x08,0xd1,0xdb,0xfb,0x9d +.byte 0xd4,0x05,0x01,0x5e,0x66,0x4d,0xf9,0x32,0x9b,0x5b,0xfe,0x7a,0x60,0x63,0x77,0x9a,0x31,0x34,0xe5,0x9a,0x82,0x2d,0x2b,0xb7,0xe0,0x04,0x8f,0x86,0xf3,0xb2,0x16,0x86,0x50,0x37,0x9d,0x80,0xe7,0x62,0xdf,0x77,0xda,0xf4,0xfc,0xb7,0x42,0x9d,0xac,0xcb,0x11,0xff,0x0c,0x6f,0x4e,0x16,0x0c,0x59,0x04,0x05,0x8f,0x88,0x64,0x37,0xe6,0x6c +.byte 0xee,0x64,0x58,0x79,0x60,0xd4,0x2f,0xb7,0x90,0x59,0xfb,0x82,0x3b,0x20,0x2e,0x2b,0xba,0x15,0xfb,0xf7,0x5b,0x1d,0x81,0x8a,0x8a,0x8f,0xe3,0x39,0x92,0x34,0xfc,0x3a,0x67,0xce,0xb6,0xa0,0x9b,0x56,0x78,0x96,0x4d,0x32,0xbf,0x9c,0x83,0x9e,0x19,0x66,0x20,0x42,0xb2,0x78,0x62,0x42,0xdd,0xdf,0x98,0xab,0x0c,0x3d,0x41,0xb5,0x74,0xc1 +.byte 0x2d,0xf0,0x02,0x58,0x6e,0xb3,0x4d,0x7b,0x41,0x1c,0xf1,0x09,0xc1,0xbb,0x84,0x67,0xf8,0x24,0x77,0x32,0xcd,0x7a,0x63,0x87,0x0d,0xf2,0xc5,0xaf,0xe4,0xb5,0xc6,0x3b,0xad,0x66,0x5e,0xae,0x90,0xc2,0x24,0x27,0x7a,0x0b,0xed,0x1b,0x86,0x5d,0x02,0x19,0x85,0x78,0xc8,0xb1,0xce,0xe7,0xc9,0x5c,0xce,0x43,0x58,0xac,0x1c,0x4e,0xcd,0xb8 +.byte 0x3a,0xb8,0x7a,0xf3,0x79,0x4b,0x97,0xcf,0xbe,0x88,0x24,0xd0,0x9a,0x5a,0x55,0x43,0x0c,0x48,0xa2,0x7f,0xaf,0x4b,0xd8,0x16,0x02,0xfb,0xe6,0x0c,0x6b,0x85,0xb4,0xb8,0x5e,0x40,0x60,0x5d,0x93,0x51,0xc6,0x32,0xb9,0x4a,0x23,0x96,0x71,0xeb,0xe8,0xe8,0x01,0x1e,0x85,0xb0,0x47,0xde,0x86,0x15,0x52,0x3a,0xb2,0xd3,0x86,0x4b,0x78,0x09 +.byte 0x9c,0x6e,0x9d,0xd9,0xef,0xe8,0x64,0x2d,0x2a,0xec,0x21,0x5a,0x60,0xa5,0xe4,0x26,0xbb,0x79,0x0c,0xdb,0x48,0xd6,0x4b,0x5c,0x5b,0xe3,0x34,0xc9,0x96,0xf0,0xcb,0x68,0x8a,0x2d,0xee,0xa3,0x37,0x34,0x5f,0x3e,0x65,0x40,0xce,0xe1,0xc8,0x2e,0x11,0xca,0x42,0x51,0x53,0x72,0x3d,0xa9,0x68,0x54,0xb4,0xd8,0xd7,0x72,0x84,0x8d,0xcd,0x6d +.byte 0x1f,0x0e,0x0c,0x0f,0x32,0x3a,0x7d,0xdd,0xc1,0xd3,0xe7,0x2d,0x1f,0x52,0x8b,0x73,0x86,0x70,0x2a,0xcb,0x71,0x37,0xa1,0xab,0xe3,0x94,0x5a,0xd7,0x9d,0x68,0xc1,0x6e,0x5d,0x72,0x25,0x81,0xe8,0x45,0xad,0x6c,0xf8,0xdb,0x9b,0x70,0x31,0xb9,0xf0,0x4f,0x23,0xd7,0x03,0xc8,0x87,0x43,0x51,0x7a,0x55,0xfe,0x6f,0x2d,0x40,0xbc,0xfe,0xdf +.byte 0xe6,0x21,0x4b,0x4d,0xc6,0x02,0x48,0xe7,0x7a,0x2a,0xef,0x91,0xdf,0xbc,0x98,0x91,0x6f,0x59,0xc4,0x47,0x77,0x2e,0x45,0x45,0x23,0x47,0x5d,0xf8,0x50,0x41,0x84,0x75,0x8a,0xe7,0x4d,0xfb,0xeb,0x58,0x00,0xcf,0x42,0xca,0x02,0x05,0xc7,0xfa,0x11,0xfb,0x6e,0x90,0x7d,0x53,0xa0,0x19,0x23,0x24,0x8f,0x89,0x17,0x40,0xbe,0x11,0xfb,0xd9 +.byte 0x04,0xf8,0x84,0xeb,0x90,0x7c,0x84,0x45,0x9c,0x53,0x45,0x5e,0x45,0x51,0x55,0xfc,0xf1,0x6b,0x02,0x24,0xfd,0x95,0x4a,0x40,0x80,0xdc,0xa6,0x94,0x15,0x2c,0x1d,0x85,0xa0,0x07,0x8d,0xf8,0xf2,0x95,0x0c,0xa0,0x4e,0x5a,0x5b,0x29,0x09,0xcc,0xf3,0x4e,0x8e,0xea,0xe8,0x26,0xb8,0xbe,0xb2,0x6f,0x76,0x6f,0xa4,0xe5,0x6a,0x50,0xcf,0xc8 +.byte 0x7d,0xb6,0x1e,0x9d,0x90,0x6b,0xde,0xe2,0x55,0x49,0x97,0x00,0xa5,0xc5,0x1f,0x1c,0x41,0x66,0xe7,0x6b,0x20,0xb2,0x1e,0xc7,0xb3,0xd4,0xa9,0x75,0xbb,0x83,0x24,0xd0,0xdf,0xbd,0xba,0x2c,0x2f,0xa4,0x03,0x1d,0x17,0xc5,0x74,0xc2,0x6a,0x20,0x71,0x18,0xd1,0xc5,0xb0,0x78,0xfe,0xda,0x55,0xd2,0x43,0x2a,0xd8,0x88,0x74,0x75,0x86,0x07 +.byte 0xe9,0x8b,0x0d,0x0f,0xe5,0x8d,0xe8,0x3d,0xf4,0x93,0xde,0x4c,0x97,0x98,0xe2,0x9b,0x22,0xde,0x13,0x18,0x8b,0xc5,0xe1,0x6f,0x6d,0xb4,0x19,0x46,0xff,0xbd,0xa6,0x2e,0xe6,0x48,0xcd,0x66,0x22,0x7d,0xf4,0x0e,0xeb,0x74,0x25,0x5c,0x90,0x0e,0x26,0xce,0x17,0xe9,0xdb,0x30,0xb9,0x25,0x99,0x96,0x46,0x3a,0x78,0xa3,0x76,0x2d,0x9e,0x42 +.byte 0x06,0x8a,0x1e,0x62,0x46,0xa4,0xd0,0x1d,0xe2,0x4c,0x3c,0xb4,0x4c,0xc0,0xd1,0xf7,0x05,0x5b,0xe4,0xd4,0x71,0x73,0x31,0xfc,0x98,0x2a,0x55,0xb0,0x78,0x92,0x59,0x8b,0x25,0x97,0x15,0xf2,0xf9,0x57,0x8b,0x7c,0xd4,0xc4,0x47,0x2f,0x10,0x3b,0x76,0xde,0x5f,0xb1,0xdf,0xdc,0xb0,0x15,0xd5,0x4a,0xd2,0x54,0xad,0x5e,0x32,0xf4,0x5a,0x1a +.byte 0x8d,0xe8,0xa0,0x4a,0x4e,0x04,0xdc,0xdd,0xd2,0x57,0xe5,0x24,0x4b,0x93,0x51,0xef,0xd4,0xba,0x3f,0x77,0xfc,0x0a,0x5c,0x7d,0x6e,0xa7,0x86,0xe5,0x88,0xd1,0xac,0x74,0x46,0x9a,0x39,0xb6,0x98,0x3d,0xae,0x89,0x4e,0xea,0x8d,0xdc,0xc7,0xb9,0x0c,0xd7,0xa6,0x06,0x4d,0x28,0x2b,0x51,0x2b,0xdb,0x30,0x4a,0x91,0x1c,0x40,0x89,0xe4,0xba +.byte 0x72,0xd5,0xed,0x16,0x66,0xb8,0xef,0x81,0xd9,0x51,0xf8,0x1b,0xff,0xab,0x8b,0x52,0xb8,0xf3,0x11,0xb3,0xe5,0x04,0x5a,0xb0,0x60,0xa3,0x35,0x12,0x6a,0xa0,0x75,0x5c,0x21,0xa9,0x5a,0xe8,0xd3,0xd7,0x8a,0x1f,0xe0,0x9b,0xb7,0x1e,0x7d,0xbe,0x81,0xaa,0x56,0x5a,0xd8,0x2d,0x7e,0x0c,0x60,0xb2,0x68,0x26,0x6d,0xaa,0x8b,0xcc,0x11,0x40 +.byte 0x25,0xea,0xc9,0x94,0xfb,0x3b,0x9b,0xa7,0x3a,0xde,0xd9,0xfe,0x6b,0x4b,0xfc,0x3f,0xbf,0xdd,0x51,0x9b,0xa1,0xca,0x2f,0xed,0x33,0xd8,0x3d,0x92,0xa4,0x1d,0xee,0xb2,0x47,0xd0,0x72,0x6a,0x96,0x33,0x0f,0xdd,0x0a,0xd9,0xbd,0x86,0xdb,0x25,0x53,0x0e,0x3c,0x31,0xad,0x05,0xb9,0x24,0x13,0x00,0xdf,0xc2,0x7c,0x3d,0x03,0x9b,0xf6,0x6d +.byte 0x93,0xd9,0xdf,0x73,0xf8,0x1c,0x98,0xe2,0x77,0x46,0x46,0xdc,0x07,0xe6,0xbb,0xc1,0xa7,0xb6,0xbe,0x21,0x07,0xae,0xdb,0xca,0x69,0x2d,0x8a,0x2b,0x59,0x27,0xe0,0x7c,0xf0,0xf1,0x34,0x69,0x97,0x44,0xba,0xbb,0x48,0x9f,0xd9,0xd8,0x16,0x1a,0xef,0x11,0x68,0xb6,0xaf,0x3a,0x10,0xc6,0x7c,0xd1,0x12,0xc7,0x89,0x47,0xe3,0xd1,0x24,0xc6 +.byte 0x44,0x9f,0x7e,0x6a,0x66,0x43,0x48,0xd6,0x9f,0x7b,0xf0,0x1f,0xd2,0x5f,0x2b,0xa7,0x13,0x6a,0x7c,0x70,0x08,0x38,0xb0,0x00,0xbc,0x7c,0xd3,0x01,0x9b,0xf6,0x29,0xd3,0x9c,0xa4,0x11,0x90,0xe4,0x9f,0x04,0xd6,0x21,0xec,0xfd,0xcb,0xb8,0xe6,0xb6,0x49,0x2b,0xfa,0x4b,0x90,0x9e,0xc6,0x0c,0x87,0xff,0x5e,0x2e,0xcc,0xf8,0x09,0x70,0x52 +.byte 0x42,0xec,0x88,0xac,0x1e,0x76,0x2b,0xeb,0xfc,0xb3,0x65,0x81,0x34,0xb1,0x06,0x90,0xde,0xb2,0xc4,0xd3,0xfd,0xd4,0x9c,0x78,0x1a,0x5c,0x8f,0x65,0x0a,0xbd,0x88,0xe5,0x95,0x06,0xb5,0x94,0xe5,0xbf,0x90,0x31,0xbb,0xcb,0xce,0x19,0x51,0x25,0x4a,0x47,0x35,0x26,0x93,0xdb,0xe2,0x93,0x36,0x47,0x7d,0xdd,0x4e,0xd5,0xeb,0xdd,0x63,0x1c +.byte 0xbc,0x2d,0x75,0xdb,0xd4,0xfa,0x60,0x4b,0x51,0x45,0x32,0x0f,0x01,0xf9,0x73,0x9b,0xd8,0xbc,0xee,0xaa,0x7d,0x2e,0xfe,0xbf,0x9d,0x45,0xae,0xe2,0x01,0xe3,0xbf,0x58,0xdc,0xc0,0xb8,0xe8,0x44,0x16,0x3b,0xd8,0xaa,0x3b,0x13,0xca,0xfb,0x5f,0x8d,0xb3,0x2a,0x83,0x66,0x49,0xae,0x54,0x02,0x4e,0xd8,0x68,0xee,0x21,0x1a,0xbb,0xf4,0xf7 +.byte 0xdf,0xf1,0x51,0x7b,0x62,0xa8,0xb2,0xdc,0x4b,0xd4,0x04,0xd2,0x05,0x49,0xdd,0xa4,0x75,0xe6,0x64,0x82,0xe7,0x25,0x55,0x60,0x2c,0x9f,0x8a,0x7a,0x11,0xe9,0xf2,0x72,0xfe,0x89,0xe1,0xaf,0xca,0x0c,0xb9,0xf5,0xcc,0xcf,0x07,0xef,0x8f,0xbb,0xef,0x53,0x1e,0xe2,0xfb,0x98,0xe8,0x05,0xab,0x4e,0x7e,0x38,0x56,0x24,0xd5,0x74,0x1c,0x95 +.byte 0x1a,0x0e,0x62,0x92,0x80,0x16,0x45,0x78,0x2f,0xb1,0xe1,0x83,0x24,0x2b,0x16,0x5c,0x05,0x52,0x17,0xe9,0xe8,0x9e,0x5d,0x63,0x8f,0x77,0xc4,0x89,0x22,0x76,0x43,0x31,0xfd,0x09,0xc0,0x51,0x70,0x57,0x2d,0x51,0x91,0xe5,0x61,0x3f,0x77,0xff,0x17,0xfc,0xa6,0x19,0x9d,0x82,0x46,0x11,0x0c,0x77,0x19,0x2a,0xf5,0x19,0xb4,0x3d,0xa6,0xd4 +.byte 0x8b,0x07,0x4b,0xc6,0xa3,0x1e,0x8c,0xf5,0xe8,0x2d,0xe7,0xcc,0xa1,0x38,0x57,0x66,0x76,0x1d,0xdd,0xe3,0xb9,0x0a,0x1e,0x2c,0xad,0x09,0x07,0x26,0xff,0x7a,0xc0,0xb0,0x51,0x71,0x44,0x6d,0x2c,0x39,0x3d,0xa6,0x14,0x4e,0x74,0x2c,0x54,0x3d,0xfa,0xdc,0x2e,0x0c,0xc4,0x88,0x32,0xda,0xb0,0x9d,0xf4,0x2c,0x0a,0x1b,0xb7,0xb4,0x78,0x6f +.byte 0x1b,0x6a,0x21,0x03,0x4e,0xe0,0x87,0xa0,0x1c,0xd8,0xe6,0x0c,0x97,0x47,0xde,0x98,0x81,0x3d,0x39,0x93,0x3d,0xcb,0x29,0xa3,0x93,0x8d,0x27,0x5d,0x29,0xb5,0x85,0xc4,0x32,0xd8,0xdc,0x19,0xb1,0x63,0xdc,0x76,0x32,0xc3,0x52,0x9a,0xfd,0x3d,0xff,0xf9,0x94,0x55,0x72,0xbb,0x4d,0xe2,0x42,0xd2,0xf7,0xb2,0xac,0xac,0x5d,0x50,0x95,0xda +.byte 0x3a,0x87,0xb6,0x0f,0x27,0x72,0x34,0xe7,0xe8,0x9f,0xc7,0xba,0xca,0x8d,0xf3,0xb9,0xa1,0xdd,0xd7,0xa5,0x70,0x3b,0xcc,0x72,0x0e,0x9d,0x85,0x75,0x01,0x11,0xe1,0xc2,0xca,0xcb,0x40,0x3a,0x31,0xf2,0x5d,0x0c,0x63,0xc8,0xbf,0x38,0xde,0x09,0x3b,0x32,0xaa,0x6c,0x07,0xd2,0x2b,0x3b,0x94,0x37,0xd0,0xd9,0xe0,0x4c,0x25,0xa3,0x22,0x64 +.byte 0x05,0xcc,0x69,0x9e,0x73,0xd4,0x46,0x2c,0x73,0x23,0xd0,0x6f,0x09,0xff,0x8b,0xef,0x7a,0x08,0x3e,0xa2,0xa7,0x9d,0xf5,0xc9,0x40,0xd1,0x06,0xd6,0xe3,0x89,0xa5,0xcc,0x9f,0x40,0x67,0x80,0x11,0xec,0x5d,0x23,0x19,0xf3,0x66,0xaf,0x06,0xcc,0xe4,0xb6,0x5e,0x20,0xf7,0x19,0xce,0x1a,0xb6,0x86,0x0d,0x39,0x1d,0xc8,0x0a,0xdb,0x50,0x52 +.byte 0x7e,0x3b,0x96,0x9f,0x05,0xdd,0xd8,0xdf,0x40,0xdf,0xe4,0x66,0x14,0x4d,0x4e,0xb3,0x9f,0x86,0x7b,0xc2,0x99,0xc3,0x8f,0xb9,0xe7,0xc3,0x50,0xa4,0xab,0xb8,0x8e,0xc5,0x28,0xce,0x8b,0x51,0xcb,0xad,0xd8,0x1a,0x23,0x7d,0x12,0xc2,0xaf,0x1a,0x93,0x4c,0x57,0xe9,0x59,0x6a,0x03,0x65,0x81,0x07,0x40,0x84,0x92,0x9d,0x22,0x8a,0x3d,0x27 +.byte 0x39,0x05,0xdd,0xf7,0x20,0xad,0xc2,0x03,0x27,0x87,0x8e,0xc1,0x23,0xad,0xe5,0x59,0x16,0xe7,0xde,0xe4,0x44,0x6b,0x06,0xb5,0x1d,0xaf,0xda,0x08,0x4a,0xfa,0x75,0x1a,0x0b,0x35,0xe8,0x6e,0x29,0xd3,0x79,0x19,0x80,0xb9,0x5f,0x36,0xec,0x43,0x25,0x3c,0xbc,0xcf,0x70,0x0c,0xc7,0x2c,0xbc,0x2e,0x72,0x40,0x73,0x98,0x11,0xc9,0x72,0x9f +.byte 0xd9,0x95,0x9f,0x8d,0x4a,0x52,0xbb,0x89,0x30,0x5b,0xa2,0x7e,0x0c,0x21,0x11,0xda,0x4e,0xa1,0x7c,0xc1,0x0f,0x95,0x1b,0x5b,0x2e,0xbd,0xae,0x8a,0x56,0x82,0x8f,0x84,0x43,0xdf,0x24,0xac,0x99,0xaa,0x8a,0xaf,0x82,0x33,0xf7,0x0a,0xbf,0x5e,0xfd,0xf2,0x91,0xf0,0xe1,0x5d,0x4e,0xa5,0x16,0x6e,0xb4,0x39,0x8b,0x99,0x32,0x6b,0xc8,0x16 +.byte 0xc1,0x84,0x10,0xc2,0x74,0x54,0xfc,0x02,0x71,0x44,0xfc,0x52,0xfa,0xc2,0x3c,0x8d,0xf7,0x8b,0x1e,0xcc,0x5e,0x43,0x66,0x29,0x29,0x93,0xe7,0xf6,0x9f,0xa8,0xa3,0x35,0xc9,0xde,0xb0,0xbe,0x4d,0xdf,0x8c,0x61,0x5a,0x6b,0x16,0x88,0x33,0x65,0x47,0x98,0xd2,0xf8,0x71,0x09,0x9f,0x00,0xb6,0x9e,0x21,0x37,0x2a,0x0b,0xb4,0x74,0x6b,0x0e +.byte 0x6e,0x4d,0x14,0x45,0x6c,0x1b,0xa8,0x4c,0xa7,0xc6,0xc3,0x36,0x6e,0x9e,0x63,0x5a,0x36,0x76,0x04,0x06,0x7f,0xdd,0x74,0x24,0x19,0xd8,0xb7,0xbc,0x6c,0x52,0x82,0x67,0x6b,0xd5,0xcb,0x81,0xdf,0xd7,0xe4,0xdd,0x14,0x33,0x71,0xcf,0x6b,0x7f,0xaf,0x66,0x27,0x8a,0x70,0xb8,0x45,0xae,0x8c,0x1a,0x65,0xd3,0x16,0x5c,0x05,0x65,0xd0,0xfb +.byte 0x07,0xe3,0x98,0xa9,0x94,0x27,0x6c,0xac,0xfc,0xee,0x1b,0x35,0x43,0xd6,0x3b,0x41,0x1c,0x86,0xc0,0x4f,0xf3,0x63,0xf4,0xba,0x4d,0xdf,0x6a,0xda,0xcf,0xb5,0x9f,0x69,0x3f,0x3d,0x0c,0x80,0x79,0x02,0x34,0x4a,0x9a,0xfd,0xb6,0xea,0x0b,0x61,0x32,0x67,0x2d,0x6a,0x6b,0xcb,0xcf,0xa6,0xee,0x6a,0x93,0x11,0x00,0xb8,0x6e,0x27,0x88,0x62 +.byte 0xf7,0x4c,0x7b,0xe1,0x13,0xe1,0x47,0xaf,0x96,0x24,0x3b,0x46,0x8c,0xf4,0xbe,0x13,0xed,0x65,0xe1,0xf2,0x36,0x2d,0xa4,0x6d,0x5e,0xa6,0x93,0xfb,0x64,0x0e,0xbd,0x50,0xdc,0x29,0x4f,0x90,0x8e,0xe1,0x7f,0x5e,0x47,0x08,0x9b,0x1c,0xb7,0xce,0x06,0x80,0x52,0xc0,0xb5,0x82,0x77,0x49,0x3c,0xe0,0x70,0x1f,0x84,0x75,0x9e,0x19,0xb2,0x83 +.byte 0xda,0x40,0xf8,0xd7,0x27,0x1e,0xbc,0x39,0xb5,0x1d,0x25,0x75,0x63,0x7d,0x85,0x2f,0x09,0x07,0xe9,0x73,0x8e,0x2b,0xb8,0x9a,0xbe,0xd6,0x90,0x91,0x6e,0xdb,0x7c,0x9d,0x9b,0x43,0x1d,0x21,0x88,0x76,0xb0,0xaa,0x7b,0x68,0xe4,0xa7,0x92,0x64,0xe4,0x1f,0xff,0x53,0x1d,0xf7,0xc0,0x44,0x5c,0x0a,0x1e,0xcd,0xa7,0x6e,0x41,0x1c,0x8c,0x7d +.byte 0x66,0xa7,0xf6,0xfc,0xa9,0x0d,0x3f,0x9c,0xfb,0x15,0x87,0x14,0x20,0x43,0x1b,0x05,0xf5,0xea,0x5c,0x07,0x61,0xb3,0x0e,0x7c,0x52,0x57,0x1c,0x09,0x33,0xb4,0xd8,0x3d,0x9d,0x17,0xee,0x86,0x25,0xdc,0x6b,0xcd,0x58,0xb7,0x18,0xbd,0x85,0x39,0x0b,0xb9,0xb8,0x35,0x3a,0x86,0xbb,0x88,0xb5,0x5e,0x4b,0x0a,0x7e,0x9c,0x02,0xb5,0x45,0xe5 +.byte 0xc7,0x38,0x56,0x1e,0xe4,0xe7,0xf7,0x88,0xac,0x75,0x9a,0x97,0xa8,0x15,0xb6,0x2d,0xcf,0x2a,0x59,0x65,0x0e,0x00,0x9f,0x8e,0xa9,0x94,0x23,0x1c,0x40,0xe4,0xb9,0x6b,0xcf,0xf0,0x53,0x7f,0x98,0xd1,0xa7,0x72,0xd7,0xe3,0x22,0xfd,0x5f,0x3d,0x3f,0xd6,0x21,0xb4,0x84,0x0c,0x1b,0x1d,0x00,0x2d,0x8f,0x72,0x22,0x2d,0x2c,0x8c,0x54,0x46 +.byte 0xe5,0x53,0xca,0x66,0x67,0x5e,0xb3,0x62,0x6f,0xaf,0x33,0x81,0xc1,0xf6,0x77,0x92,0x3e,0xdb,0x74,0x68,0x93,0xca,0x38,0xf8,0x18,0x50,0xef,0xe4,0xc9,0x45,0x40,0xc9,0xf0,0xc5,0x7a,0x4b,0xf2,0xd8,0xca,0x72,0x62,0x5f,0x67,0x10,0x10,0xcc,0xff,0x1a,0xc7,0x9c,0x3a,0x7f,0xca,0x11,0x67,0x3e,0xca,0xa6,0x9c,0x48,0x15,0xaf,0x68,0xb7 +.byte 0x2b,0xa7,0xa2,0x68,0x7b,0x40,0xb2,0xe3,0x27,0x18,0x7e,0x94,0x4c,0xca,0x0e,0x5b,0x3a,0x30,0xcb,0xc3,0x72,0x31,0x6b,0xe6,0x3e,0xa7,0x09,0x3e,0xf2,0x53,0xda,0x7d,0x6f,0x55,0x08,0xd2,0x26,0xc3,0x07,0x52,0x38,0x90,0x04,0xc6,0x3c,0xb6,0xb5,0x2a,0x7b,0x38,0x07,0x9e,0xb4,0xa5,0x48,0x36,0xf5,0x5e,0xac,0xa8,0x97,0x4e,0x37,0xc2 +.byte 0xee,0x12,0x88,0x28,0xd0,0x7d,0xd1,0xae,0xc0,0xc7,0x84,0x69,0x25,0x79,0x9a,0x8a,0x16,0x49,0x50,0x72,0x69,0x1a,0x02,0xc9,0xfe,0xd5,0x2c,0x40,0xc6,0xc8,0x8b,0x7d,0xe3,0xab,0x89,0xe3,0x78,0xf1,0xe9,0xbd,0x3c,0xbd,0x02,0x96,0xfe,0x0c,0x5c,0xc4,0x9e,0x89,0x3a,0x4b,0xe9,0xcd,0x41,0x1c,0x59,0x71,0x52,0xb0,0xc9,0x36,0xf1,0x80 +.byte 0xab,0x5e,0xbc,0xf1,0x20,0x99,0xc0,0xab,0x0c,0x59,0x43,0xc2,0xcd,0x09,0xa6,0x30,0x91,0xfa,0x12,0x23,0xbe,0x18,0x24,0xa6,0xbf,0x55,0x4c,0xe8,0x22,0xff,0x01,0xbd,0xde,0x2c,0x72,0x3c,0x0a,0x36,0xd5,0x7e,0xed,0x6a,0xe3,0x63,0x14,0x60,0xa3,0x0a,0x6f,0x04,0x90,0x64,0xc1,0xd1,0x78,0x54,0xae,0x19,0x74,0xe2,0xea,0xec,0x86,0x22 +.byte 0xc7,0xdb,0xf6,0x48,0x0e,0x75,0x43,0x04,0xf7,0x62,0xe6,0xa9,0x46,0x65,0xcc,0xa5,0xa4,0x1a,0xb2,0x94,0x7b,0x7a,0x8c,0x9a,0x80,0x62,0x32,0x17,0x80,0xc3,0xc6,0x54,0x0e,0x4e,0xe3,0x46,0x74,0xa8,0xae,0xcd,0xd0,0xc1,0x19,0x84,0x61,0xb4,0x1d,0x18,0x4d,0x80,0xf1,0x70,0x40,0xbe,0xa2,0xa3,0x38,0xcc,0x21,0x1c,0x2f,0x72,0x85,0x72 +.byte 0x0a,0xa1,0x0d,0xa3,0xdc,0xa2,0xf4,0x64,0x84,0x3c,0x43,0x6d,0xfb,0x45,0x11,0xf9,0x40,0xdc,0x25,0x85,0x80,0x41,0x84,0xa7,0x06,0x2e,0x79,0xbf,0x0c,0xa7,0x8f,0x17,0xea,0xa2,0xc4,0x6f,0xd8,0xc6,0x9e,0xab,0xdc,0x45,0x6f,0xaa,0xda,0xe9,0xe6,0x84,0xf0,0x5f,0x8a,0x90,0x99,0x33,0x9b,0xcf,0x03,0xe6,0xce,0x19,0x0c,0xad,0x2f,0xad +.byte 0x81,0xb8,0x17,0xff,0x6b,0xff,0xc8,0x14,0xa6,0xf4,0x37,0x55,0xdc,0xbb,0x09,0x3c,0x3c,0xe7,0x29,0x95,0x23,0x5c,0x58,0x92,0x2e,0x95,0xe8,0x3b,0x8b,0x81,0x2d,0xfd,0x58,0x8a,0x1f,0xdf,0xf1,0x54,0xa3,0xd0,0x01,0xaa,0x3d,0x32,0x61,0xe5,0x8e,0x62,0xa7,0xf6,0x3b,0x2d,0x0e,0xff,0xf4,0xe9,0x08,0xe7,0xef,0x3a,0x63,0x10,0x34,0x49 +.byte 0x14,0xe1,0x88,0xd0,0xb2,0x1d,0xb7,0x31,0xc9,0xa4,0x48,0xa8,0xaf,0x64,0x29,0xab,0x1f,0x14,0x13,0xa7,0xb8,0xb8,0xa4,0x24,0x1d,0xf9,0xb6,0x3e,0x62,0xa6,0x5e,0x10,0xcb,0x44,0x5c,0x9d,0x2c,0x58,0x3a,0x36,0xa3,0x81,0x9f,0xa9,0xa4,0xa1,0x06,0x1d,0xbf,0x97,0x03,0x88,0xf2,0xf4,0x81,0x3e,0x1b,0x35,0xea,0xd0,0xb6,0x96,0xa1,0xf7 +.byte 0x1e,0x49,0xb7,0xe8,0x23,0x6f,0x05,0x7c,0x9f,0xc4,0x53,0xb1,0x63,0xdc,0x07,0xbb,0xd6,0x57,0x85,0x4d,0x77,0x33,0x21,0xbf,0x77,0xfe,0xfe,0x34,0x52,0x02,0xe7,0xe4,0x87,0x11,0xa0,0xfd,0x11,0x4a,0x34,0x36,0x88,0x69,0xdf,0x77,0xfd,0x83,0x71,0xa8,0x68,0xed,0x49,0x39,0xb4,0x06,0x32,0x48,0xf1,0xd2,0x4e,0x61,0x47,0x65,0x26,0x87 +.byte 0xba,0x2b,0x2e,0xf4,0x12,0xfc,0xd0,0x84,0x81,0xa1,0x59,0xdc,0xe3,0x13,0x51,0x9e,0xea,0x57,0x56,0x3b,0x7c,0x71,0x6b,0xff,0xe9,0xf8,0xec,0x3e,0xe7,0xbe,0x65,0x47,0xe1,0x6f,0x8f,0x7c,0x3a,0x77,0xdb,0x75,0x4a,0x43,0x43,0x39,0x37,0xb2,0x68,0x16,0x72,0xdb,0x49,0xf7,0x13,0x3c,0x09,0x93,0xef,0xc1,0x2a,0x99,0xff,0xc7,0xdb,0xd9 +.byte 0x80,0xd2,0xfe,0x7c,0x39,0x50,0x21,0xdc,0x1d,0xae,0x9b,0xfc,0xd4,0x5f,0x56,0xae,0x6a,0xd9,0x35,0xa1,0x2b,0xd6,0x53,0x90,0xe8,0x8c,0x31,0x73,0x0f,0xa3,0x9e,0xa1,0x2f,0x76,0xa8,0x72,0x4d,0x5e,0x58,0xca,0x9f,0x8f,0xdf,0xf0,0xf9,0x6a,0x54,0xb1,0x5f,0x39,0x03,0x7a,0x26,0x06,0x71,0x74,0x6f,0x42,0xee,0x63,0x76,0x13,0xb9,0xed +.byte 0x74,0xad,0xf9,0xe0,0xa7,0x35,0x9c,0x18,0xe0,0xf7,0xc5,0xb2,0x27,0x14,0x0f,0xd7,0xaa,0x17,0x1c,0x8f,0x50,0xc8,0xb0,0xc2,0x63,0xff,0x38,0x65,0x87,0x69,0xb3,0xd5,0x3f,0xb4,0xf2,0xe8,0x8b,0x7b,0x24,0xdc,0x1f,0x62,0x2f,0x0a,0xd7,0x2d,0x0f,0x6f,0x48,0x1d,0xf0,0x3c,0xb1,0xb4,0x10,0x8d,0xc6,0x5c,0x79,0x30,0xde,0x20,0x9e,0x7b +.byte 0xf1,0xa5,0x73,0x38,0x05,0x1b,0x13,0x78,0xb1,0x02,0x2f,0x32,0x2a,0x07,0x59,0xa4,0xfc,0x88,0x08,0x0c,0xff,0x42,0x72,0x6a,0xb0,0x8a,0xc9,0x3d,0xdb,0x04,0x90,0xdd,0x0b,0xbc,0x3a,0x4e,0xfa,0xd4,0x57,0xd8,0x2f,0x7b,0xcb,0xd9,0x6a,0xe7,0xfd,0x32,0x17,0x99,0x20,0x64,0x1e,0x76,0x07,0xb9,0xa3,0x58,0x7f,0x79,0xda,0x0c,0xe0,0xec +.byte 0x30,0xbf,0xa4,0x85,0x0a,0x39,0xc0,0xe9,0xf7,0xbe,0xd1,0xa7,0x94,0x1f,0xa6,0x6d,0xe8,0xc5,0x1b,0x04,0x27,0xf4,0xdc,0xc2,0x4d,0x9a,0x0e,0x9b,0xe8,0xec,0x56,0x99,0x90,0x5f,0x8b,0x28,0x0a,0x92,0xaf,0x0b,0xa1,0xd2,0x85,0x86,0x26,0xc7,0x8a,0x01,0xa4,0x08,0x29,0x32,0x7d,0x3d,0xa5,0x74,0x9c,0x90,0x63,0x83,0x1f,0xd4,0xee,0x98 +.byte 0xf5,0x14,0xff,0x39,0xeb,0xbf,0x40,0xa4,0xc9,0x70,0x4f,0x81,0x03,0x19,0xef,0xf5,0xdf,0xf7,0x00,0x75,0xcb,0x2e,0x81,0x41,0xc5,0xda,0xfb,0x67,0x6a,0xf0,0xa3,0xd3,0x5a,0x60,0xaf,0x72,0x27,0x3e,0xad,0x37,0x3e,0x3d,0xe6,0x85,0x4c,0xa1,0xb0,0xe9,0xab,0xc5,0xd3,0x8b,0x04,0x0d,0x64,0x7f,0xa2,0xb9,0x6d,0x6d,0x28,0xf8,0x4b,0x43 +.byte 0x78,0x51,0xf4,0x84,0xf1,0x3c,0x67,0xd8,0xdd,0xd7,0x0b,0x67,0xc3,0xd9,0x95,0x7b,0xfc,0x7d,0xc4,0x33,0x05,0x90,0xec,0x0a,0x98,0xfb,0x6b,0x0d,0xe9,0x8c,0x74,0x94,0x20,0xf8,0xcb,0xca,0xb6,0x72,0x07,0x7c,0xef,0xfa,0xd0,0x3f,0x51,0xc5,0x6e,0xf8,0x3f,0x37,0xe3,0xfe,0xb9,0x9a,0x9c,0xb3,0xf6,0x96,0x4e,0x65,0x77,0x21,0xcf,0xaf +.byte 0xe7,0x20,0x06,0xc2,0x93,0xc5,0x2e,0xc0,0x7f,0xe5,0x0a,0x42,0xad,0x89,0x64,0x6e,0x95,0xbf,0x95,0x1d,0x24,0x47,0xf8,0xd5,0xec,0x7c,0x1f,0x98,0x67,0x9c,0x5f,0x6e,0xaf,0x74,0x95,0x65,0x4c,0xb6,0xe0,0xd3,0xb7,0x5b,0xc7,0x76,0xe6,0x87,0x19,0xf5,0xc7,0xb0,0x2d,0xe0,0x8b,0xaf,0x6d,0x3c,0x31,0x6e,0x84,0xc8,0x86,0x51,0xff,0x29 +.byte 0x2a,0x1f,0xea,0xd4,0x2d,0x1a,0x8f,0x04,0xb4,0xc0,0x6a,0x93,0xc2,0xc5,0xe7,0x98,0x8c,0xc7,0xff,0xbf,0xb8,0x8e,0x5b,0x29,0x5b,0xa6,0x87,0xc7,0x02,0x88,0x51,0x29,0x66,0xd8,0xf3,0x68,0x38,0xd4,0xa6,0xbd,0xa2,0x5c,0x1b,0xb7,0x13,0xd7,0x64,0xed,0x68,0x21,0x88,0x2b,0x59,0xba,0x95,0x84,0xda,0xce,0x61,0x3b,0x51,0x04,0x3e,0xc2 +.byte 0xdd,0xec,0x0c,0x6b,0xbe,0x35,0x51,0x63,0x29,0x40,0xcb,0xa5,0x62,0xe4,0x27,0x35,0x15,0x1f,0x7c,0x8b,0xe5,0xd0,0x2e,0xde,0x8c,0x3d,0xa0,0xd2,0xbe,0x51,0x3d,0x65,0xed,0x94,0x8b,0x8c,0x00,0xda,0x0e,0x78,0x4d,0x25,0xef,0x8e,0x3c,0x55,0x77,0xeb,0x58,0x06,0x7d,0xd1,0xfc,0x73,0xad,0x76,0x0a,0x81,0xbe,0xda,0x50,0x30,0xf3,0xfd +.byte 0x58,0x25,0x0a,0x4b,0x1b,0x1e,0x0b,0xd0,0x9b,0xbc,0xb9,0x31,0x26,0xbc,0x4c,0x7b,0x05,0xd7,0x5c,0xe4,0x7a,0xdd,0xff,0x04,0xac,0x5d,0xcb,0xfd,0x91,0x34,0x68,0x26,0x1e,0xb4,0x86,0xcc,0xe3,0x90,0xaf,0x6a,0x65,0xda,0x6b,0x3e,0xec,0x44,0x90,0x72,0x7a,0x34,0xfc,0x7b,0x65,0x83,0x34,0x93,0xbc,0x85,0x50,0xdf,0x03,0x89,0x35,0xb8 +.byte 0x6a,0x39,0xd3,0xb6,0x38,0x66,0x5b,0xa7,0x9e,0x93,0xa2,0x3b,0xb6,0xe7,0xee,0x1e,0x5c,0xd6,0xa8,0xd9,0x1f,0xf7,0xd1,0x0a,0x2f,0x87,0x63,0xf4,0xf9,0x8c,0xd4,0x7c,0x02,0xaf,0x7e,0xb6,0xc7,0xfc,0xc9,0x4d,0x35,0x0c,0x8c,0x3c,0x13,0x9d,0xe6,0xd7,0x2e,0x4b,0x91,0xcc,0x88,0xdb,0xfc,0x68,0x3a,0xd1,0x15,0x07,0x16,0x66,0x11,0x9b +.byte 0x66,0x9f,0x3f,0x37,0xae,0x11,0xba,0x5f,0xc7,0x3a,0x1a,0x49,0xbc,0x14,0x21,0x75,0xdc,0xcc,0xbb,0x5c,0xed,0xdc,0x8b,0x21,0x9a,0x8f,0x5f,0x91,0x6a,0x9b,0x26,0x33,0x64,0x45,0xa0,0xdf,0xc4,0xa1,0x32,0xc4,0x4c,0xc2,0x42,0x1b,0x59,0x37,0x1f,0xdb,0x01,0x6d,0xed,0xd8,0x05,0x5b,0x90,0x59,0x32,0x45,0x50,0x5d,0xf1,0x34,0xc4,0xb7 +.byte 0x52,0x97,0xbb,0x42,0x12,0xf1,0xa5,0x76,0xe4,0x1a,0xbc,0x4a,0x64,0xd3,0x08,0xac,0xe1,0x49,0x70,0x61,0xc8,0xcf,0xb1,0xd3,0xc4,0x7f,0x38,0x31,0x6b,0xd3,0xe1,0xe1,0xe9,0x5b,0xaa,0x7a,0xec,0x26,0x81,0x44,0xd3,0xb9,0x63,0xea,0x37,0x98,0x15,0x41,0xf1,0xa1,0x72,0x87,0xcc,0x3b,0x6a,0x27,0x9b,0x85,0xa8,0x7b,0xb6,0x25,0xf9,0xd4 +.byte 0x84,0x3e,0x66,0x12,0xce,0x24,0xee,0x22,0x51,0x73,0x7e,0xba,0x1e,0x95,0x64,0xc5,0xbf,0x4e,0x4f,0x73,0xc1,0xc3,0x98,0xb9,0x6b,0x90,0x1f,0x39,0xfc,0x03,0x55,0x76,0x8c,0x57,0xea,0xe8,0xc1,0x25,0x09,0x69,0xc0,0xe8,0x54,0x91,0xc1,0x7c,0x52,0x8e,0x82,0x6d,0xf2,0x0e,0x3f,0xa9,0x98,0x04,0x40,0xda,0x1c,0xc0,0xbb,0x42,0xf0,0x7d +.byte 0xed,0x78,0xb0,0x4f,0x94,0xba,0x0d,0xbf,0x60,0xbe,0x09,0x67,0x42,0xc5,0x41,0x4c,0x80,0x8d,0x30,0x10,0xa9,0xd2,0x07,0x8c,0xa8,0x40,0xc6,0xe2,0x08,0x42,0x7f,0x99,0xad,0xc5,0x66,0x1f,0xfd,0xd2,0xc5,0x79,0x77,0x9b,0x60,0x7d,0x25,0x2d,0x69,0x14,0x94,0xa5,0xf0,0x0a,0x14,0xb6,0xf9,0xbe,0x3a,0x4a,0x3d,0xc6,0x45,0x2e,0x27,0x4a +.byte 0xd1,0x1d,0xcf,0x08,0xee,0x93,0x3c,0xb5,0x8a,0xee,0xdd,0xf3,0x33,0xa6,0x35,0x9d,0xd8,0xb4,0x68,0xc5,0x98,0x09,0x78,0xcc,0xb3,0xeb,0x0f,0xcd,0x25,0xf8,0x17,0x9c,0x45,0x77,0xc7,0x06,0x40,0x44,0x90,0xec,0x6a,0xd9,0xf5,0x05,0xd4,0x88,0x17,0x47,0xeb,0x29,0x85,0x32,0x76,0x7b,0xa4,0xe3,0x65,0x30,0x50,0x9a,0x99,0x26,0x91,0x60 +.byte 0xb0,0xb8,0xe5,0x8d,0x35,0x9e,0x9a,0x13,0x65,0x82,0xb2,0x4b,0xf1,0xed,0x1f,0xb7,0xb4,0xc0,0x03,0xe6,0x1d,0x2b,0xaa,0x1e,0x01,0x92,0x0b,0xcb,0x34,0x77,0x80,0x94,0xc2,0x4e,0x3b,0x73,0xd8,0x2e,0xd8,0x95,0x33,0x05,0x65,0xa2,0x99,0x29,0x7a,0xd1,0xb3,0xed,0x5a,0x8d,0x4d,0x6a,0x6d,0x69,0x2b,0x5a,0xa1,0x3a,0xc0,0x81,0x96,0xf1 +.byte 0xc2,0xa7,0x4e,0x07,0x90,0x04,0x99,0x70,0xea,0x1a,0x3a,0x26,0xb5,0xed,0x92,0xbd,0x57,0x80,0x11,0x06,0xf2,0xb4,0x05,0x69,0x7a,0xbf,0x27,0xa1,0xbd,0xdb,0x09,0xe5,0xb3,0x2d,0x86,0x41,0xcc,0x5d,0x68,0x37,0x9e,0x98,0xa5,0x4a,0x20,0x8a,0x5f,0x54,0xae,0x4f,0x73,0xd0,0x22,0x18,0x8d,0x2b,0x91,0xcb,0xbb,0x83,0x1e,0x04,0x93,0xc8 +.byte 0xc3,0x89,0x35,0xfd,0xda,0xeb,0x52,0x53,0x9f,0xdc,0x33,0xf0,0xe0,0x99,0x19,0x11,0xeb,0x55,0xd3,0x3c,0x5f,0xca,0x29,0x52,0xe7,0x6b,0xd1,0xad,0xeb,0xed,0x8e,0x68,0x82,0x91,0x85,0x81,0x68,0x70,0x78,0x61,0x1e,0x0c,0x09,0x3a,0x82,0xdc,0xdb,0x26,0x66,0x1c,0xa3,0x80,0x99,0x23,0x8a,0x45,0xd7,0xb8,0x10,0x97,0x80,0x70,0x49,0x78 +.byte 0xa9,0x4c,0xf0,0xec,0xcc,0x05,0xd0,0x6a,0x6a,0x1a,0xa0,0xf7,0xde,0x78,0xc6,0x42,0xbe,0xbd,0xa0,0x24,0x1d,0x3f,0xdd,0xfb,0x92,0xc2,0xbd,0xd6,0x5c,0x25,0x74,0x3d,0x2b,0xb8,0x60,0x67,0xdb,0x70,0x1e,0xe8,0x9f,0xcd,0xb4,0x82,0x90,0x9e,0x2a,0x94,0xa5,0xa2,0xd4,0xd2,0x24,0xa7,0xca,0xbf,0xe1,0x8b,0xab,0xf3,0xd2,0x7c,0xa6,0xc8 +.byte 0xe6,0xaf,0xef,0xe3,0x86,0xb1,0x42,0x1d,0xc6,0xa2,0x37,0x9b,0x26,0x46,0x0b,0xfd,0xee,0x88,0xa4,0xf1,0xa8,0x72,0xaf,0xda,0x30,0x56,0x22,0xd3,0x1b,0x31,0x76,0xd7,0x03,0xef,0xf3,0x98,0x16,0x4d,0x36,0x57,0x1b,0xd5,0x90,0xb8,0x67,0x50,0x7f,0x22,0xa8,0xdc,0x9c,0xf1,0x6e,0xa4,0x65,0x45,0xf0,0x73,0xd8,0x7e,0x41,0xb0,0x68,0x52 +.byte 0x00,0x0a,0xda,0x99,0x6c,0x84,0xce,0xf0,0x73,0x65,0x93,0x52,0xc8,0x4b,0xb4,0x72,0xda,0x2c,0xa1,0x47,0xb5,0xe3,0x00,0x63,0xc0,0x4e,0x84,0x16,0x00,0xe6,0x1f,0xbd,0xba,0x49,0xcb,0xd3,0x7d,0xd2,0xeb,0x4a,0xb2,0xd5,0xb2,0x53,0x96,0xfb,0x04,0x73,0xc0,0x09,0x31,0xf3,0xf2,0xc0,0xd3,0xa6,0xe1,0xea,0xe1,0x58,0xbe,0x90,0xc9,0xfb +.byte 0x6e,0x13,0x69,0xbe,0x17,0xd4,0x16,0x5b,0xcb,0xf4,0x93,0x0a,0x38,0x46,0xea,0x64,0xad,0xb0,0x0d,0xc0,0x3b,0xfc,0xe3,0xd4,0x20,0x75,0x0c,0x3e,0x71,0x1b,0x5f,0xde,0xff,0xd6,0xfa,0x6f,0xe4,0x10,0xb0,0x14,0x05,0xaa,0x05,0x70,0x5e,0xbd,0x58,0x9f,0x3c,0x9d,0x4f,0xa7,0x5a,0x65,0x57,0x02,0x05,0x44,0xe0,0x95,0x9d,0xa2,0x60,0x06 +.byte 0xcb,0xfd,0x91,0x8e,0x7f,0xce,0xa1,0x80,0x94,0xbb,0x88,0xf2,0xa6,0xe7,0x83,0xf9,0x38,0x8f,0x09,0x8e,0xe4,0xa9,0xc2,0xc7,0x84,0x9d,0x25,0x09,0x52,0x8b,0x32,0xaa,0x3b,0xde,0xb6,0x82,0x9f,0x6d,0xc4,0xdf,0x11,0xf7,0x72,0x1a,0xe4,0x00,0x51,0x41,0x01,0xba,0x21,0xea,0x0a,0xda,0xf2,0xbb,0x66,0xae,0x51,0x2b,0xb0,0x6d,0x1d,0xe8 +.byte 0x4b,0x1e,0x42,0x68,0x3a,0xed,0xe6,0x59,0x13,0x42,0x07,0x54,0xae,0x2e,0x15,0x93,0xd7,0xff,0xad,0x49,0x09,0x41,0x52,0x6b,0x3b,0x9c,0x41,0x43,0x0d,0xed,0xed,0x6f,0xb8,0xe9,0x0d,0xcc,0xde,0x0d,0xaa,0x91,0xef,0x89,0x2f,0x2d,0x94,0xd0,0x03,0x2b,0x51,0x7f,0x85,0x9b,0x7b,0x08,0xc8,0xb6,0xe2,0x82,0x22,0xa9,0x57,0x71,0xf2,0xae +.byte 0x08,0xfa,0x6c,0xd8,0xca,0x78,0x42,0x98,0x23,0xfd,0x38,0x4b,0x6c,0xd3,0x9f,0xc6,0xa3,0xb2,0xc1,0x8c,0x4a,0xa3,0xcd,0x9f,0x56,0xe7,0xc2,0x06,0xd7,0xc5,0xc2,0xd9,0x98,0x57,0xc8,0x5a,0xaa,0xf4,0xaa,0x44,0x02,0x83,0x11,0x1e,0xf6,0x64,0x8d,0xf7,0x3b,0x86,0x3c,0x04,0x53,0x5f,0x62,0xc8,0x7a,0x0e,0x1c,0x4f,0xa8,0xe3,0x5c,0xe8 +.byte 0x64,0xf7,0xe3,0x5d,0xea,0xb5,0x2d,0xdb,0x7b,0x0e,0xdb,0x91,0x34,0xd5,0x87,0x4f,0xe6,0x73,0xee,0x3d,0x79,0x7c,0x67,0x48,0xb5,0xbb,0x42,0x96,0x0d,0x9d,0xbd,0x68,0x98,0xe5,0x59,0x51,0x16,0x45,0x15,0xac,0x80,0x41,0xae,0x45,0xdb,0xe4,0x2a,0x44,0x0d,0xe4,0x25,0xc7,0xd3,0x06,0xf7,0x98,0x15,0xe1,0xc5,0x9b,0x34,0x0e,0x87,0xb8 +.byte 0x90,0x1b,0x24,0x84,0x06,0x24,0xb0,0x80,0xbe,0x03,0xa0,0x95,0x10,0x1e,0x72,0xde,0x0f,0xd4,0x15,0x7b,0xa0,0xf5,0x42,0xc3,0x6f,0x10,0xe9,0x76,0x44,0xe3,0xa9,0xb7,0xef,0xf6,0xc2,0x80,0xe2,0x0c,0x2d,0xad,0xe0,0xb9,0x45,0xca,0x67,0x6f,0xb6,0xc5,0xc0,0x8d,0x25,0xee,0x50,0xeb,0x51,0xc6,0x87,0x87,0x61,0x3a,0x75,0x95,0x41,0x47 +.byte 0x26,0xfd,0x35,0xf6,0x46,0xf4,0xe9,0x42,0xc6,0xef,0x37,0x97,0xb3,0x0a,0x1d,0xc8,0xdf,0x07,0x24,0xb1,0x0d,0x07,0x43,0x67,0x7d,0x81,0x09,0x58,0xdd,0xf6,0xcf,0xf1,0x47,0x42,0xbd,0x3c,0xa3,0xd7,0xe8,0x73,0xf9,0x5b,0xff,0x2c,0xcd,0xe6,0xd1,0xe9,0x47,0x6d,0x19,0x9b,0x6a,0x63,0x69,0xf4,0x4a,0xdf,0x69,0xab,0xa9,0xb7,0xe5,0x8d +.byte 0x1c,0x44,0x52,0x0c,0x7e,0xa1,0xfe,0x9d,0xd5,0xa4,0x71,0x62,0x0b,0x3c,0xf6,0xd2,0xd3,0xe9,0x70,0x09,0x68,0xf7,0xd6,0x0a,0x00,0x61,0xf1,0xf3,0xd0,0x41,0x4a,0x14,0xc6,0xf5,0x49,0xb1,0xde,0x10,0xd3,0x20,0x8b,0xfe,0x78,0x6a,0x87,0x79,0x15,0xd3,0x43,0x00,0xbe,0x71,0x40,0xaa,0xca,0x1a,0x64,0xe3,0x96,0x34,0x2f,0xea,0x0c,0x11 +.byte 0x41,0x21,0xf8,0xa7,0x65,0x9b,0x75,0xe2,0x1e,0x6f,0x5e,0xe0,0x68,0x42,0xca,0xd3,0x19,0x35,0xe8,0x88,0x0f,0x05,0xa3,0xb1,0x73,0xea,0x53,0x79,0x40,0x24,0x00,0x86,0x20,0xbb,0x25,0x58,0x89,0x6b,0xde,0xd6,0xd0,0x36,0xbb,0x33,0x30,0x59,0x4b,0x30,0x92,0xac,0xe5,0x95,0x94,0x22,0xab,0xc1,0x10,0x35,0x9c,0xa1,0x20,0x11,0x5d,0x4f +.byte 0x57,0x5c,0x9c,0xb8,0x3a,0xdc,0x97,0xa5,0xf3,0x0b,0xf5,0x96,0xe7,0xef,0x90,0x72,0x01,0x52,0x70,0x5a,0xf0,0xd9,0x7e,0x59,0x05,0x8c,0xd1,0x45,0x47,0xbf,0x16,0x15,0xa2,0xc9,0xdd,0xe7,0x5f,0x4b,0x94,0x5f,0xe6,0xf9,0x78,0xbb,0x8f,0xf9,0x79,0x9f,0x5e,0xd7,0x1f,0x0b,0xef,0x8d,0xfe,0x75,0xd4,0x8a,0x12,0x28,0xa5,0xf9,0x6e,0x14 +.byte 0x3c,0x52,0x80,0x57,0xc6,0x96,0xae,0x67,0x27,0xc1,0x1c,0xb6,0xd6,0x1c,0x74,0x8c,0x6f,0xc7,0x71,0x3e,0xd5,0x73,0xf2,0x3e,0x02,0x15,0x67,0x18,0xb8,0x5b,0x61,0x9e,0xfa,0x7e,0xba,0x00,0xe9,0xd9,0x51,0x91,0x63,0x7e,0xf7,0xab,0xc0,0xc6,0xee,0x66,0xdd,0x66,0x88,0x7a,0x8a,0xc5,0xc2,0x08,0x45,0x62,0xde,0xe1,0xfb,0x35,0x65,0x34 +.byte 0x00,0x9e,0x1d,0x25,0xdf,0x69,0xb6,0xe3,0xfe,0xbb,0x13,0xac,0xd3,0x13,0xb2,0x64,0x5a,0xf3,0x47,0xf1,0x36,0x55,0x5f,0x1b,0x87,0xea,0x5d,0x5c,0xfd,0x8a,0x68,0x69,0x8a,0x00,0x9f,0x83,0xbe,0x79,0x7d,0x01,0x9e,0xf2,0xb2,0x5d,0x56,0xe0,0xe6,0x49,0xe5,0xe1,0x76,0x57,0x7a,0x85,0xac,0x94,0x16,0xe3,0x68,0x05,0x14,0xb5,0x33,0x54 +.byte 0x64,0x5a,0xbe,0xa3,0x04,0x90,0x5c,0x1c,0xf8,0x97,0x16,0x36,0xce,0x76,0xe7,0xf0,0xaf,0x8a,0xea,0x65,0xa8,0x15,0x5b,0x1e,0x0a,0x91,0xad,0x62,0x62,0x67,0xb4,0xf0,0x94,0x1f,0x64,0x50,0xa8,0xc0,0x6b,0x38,0x80,0xd7,0x53,0xbb,0x70,0xbd,0x54,0x01,0xb0,0xa5,0xbc,0x00,0xe0,0xd6,0x23,0x37,0xe6,0x9f,0x0f,0x2f,0x96,0x21,0xc2,0x90 +.byte 0x55,0x26,0x55,0xa4,0xcd,0x3e,0x54,0x6b,0xa6,0xb0,0x2c,0xf2,0xd4,0xcc,0x6a,0x44,0xea,0x18,0x61,0xc5,0x1a,0x8e,0x60,0x64,0xf4,0x5f,0x21,0x36,0x01,0x5d,0x9f,0xc4,0x2c,0x67,0x1c,0x48,0x94,0x16,0xae,0xa8,0x13,0x5c,0xee,0x18,0x88,0x61,0xe4,0x54,0x6b,0xa2,0xe8,0x7f,0xf0,0x15,0xc3,0xce,0xbc,0x5b,0x91,0x25,0x7b,0x1d,0xd3,0x9f +.byte 0x13,0x1b,0x01,0x5d,0x43,0xe8,0xa1,0x77,0x5a,0x87,0x79,0x8b,0xd5,0x69,0xf7,0xdf,0x66,0xa2,0x84,0x0c,0x66,0xac,0x15,0x65,0xbf,0x74,0xc0,0xd2,0x78,0x6a,0x3a,0x9c,0x98,0x62,0x04,0x41,0x95,0xb2,0x23,0x59,0xc6,0xb0,0xc5,0x22,0xc0,0xfa,0xaa,0xc8,0x94,0x73,0x91,0x5b,0x64,0x1b,0x74,0xbe,0xcb,0xa1,0x81,0xb1,0xc1,0x26,0xa1,0x94 +.byte 0x55,0x04,0xb3,0x9c,0x80,0xb7,0x00,0x6f,0x36,0xc7,0x7f,0x6d,0x97,0xea,0xf3,0xf5,0x55,0xc5,0xfe,0x61,0xd9,0xb1,0x6d,0x8c,0xa1,0x02,0x08,0xb3,0x41,0xe6,0xe6,0x57,0xc6,0xff,0x6e,0x47,0xa4,0x22,0x2e,0x2d,0x21,0x53,0xbe,0xe3,0xbe,0x15,0xec,0x23,0x9d,0x87,0xe0,0x2e,0xcc,0x6c,0xd0,0xc7,0xb7,0x3d,0xa4,0x07,0x5f,0x69,0x4e,0x2b +.byte 0x07,0x69,0x4f,0xc5,0xa3,0x66,0x52,0x91,0x8f,0xa4,0x48,0xb9,0x40,0x76,0xd9,0xcb,0x6e,0x1a,0x35,0x9e,0x50,0x9f,0xd1,0x78,0xb2,0xb8,0x0d,0xa8,0xf8,0x6e,0x07,0xa5,0x3a,0xdf,0x3c,0x32,0xa6,0x10,0xbd,0x73,0x2f,0x07,0x45,0x66,0x0f,0x61,0xce,0xc2,0x08,0x19,0x98,0x33,0x4b,0x59,0x81,0xb5,0x78,0x4f,0x46,0x88,0xae,0x29,0xf8,0xf5 +.byte 0xc2,0x29,0x6f,0x8f,0xe5,0x8f,0xb0,0x53,0xc8,0x7a,0x48,0xda,0x6f,0x7e,0x8a,0x69,0x68,0xab,0xba,0xd9,0x20,0x0f,0x96,0x69,0x41,0xa6,0x92,0x94,0x8e,0x0f,0x86,0xdf,0x8d,0x70,0xaf,0xfe,0xf1,0x20,0x50,0x01,0xff,0xca,0x30,0x24,0x67,0x4a,0x04,0xa2,0xde,0x06,0xdc,0x26,0x1e,0x17,0xbc,0x52,0x9a,0x62,0x72,0xc1,0xd8,0xd7,0xe0,0xed +.byte 0xcf,0x4b,0x13,0x80,0x9a,0xbf,0x72,0x4f,0xf4,0x24,0x26,0xcd,0xe0,0x21,0x99,0x7b,0x5c,0x4f,0xbf,0x5c,0x41,0x08,0x8b,0x17,0x69,0x62,0x60,0x2c,0x74,0xb0,0x2d,0x22,0x7e,0x25,0x95,0x6a,0x84,0x0f,0x45,0x8f,0x9a,0x92,0xa1,0xcd,0xa5,0x50,0xf0,0x52,0x7f,0x60,0xd8,0x91,0xe1,0x17,0xe1,0x66,0x8f,0xd3,0x1f,0x41,0x7f,0x6f,0xf1,0x72 +.byte 0xa3,0xb6,0x12,0x62,0x46,0x16,0xea,0x26,0x9e,0xda,0x61,0x13,0x0b,0x17,0xf7,0xe1,0xec,0xc0,0x38,0xfe,0x40,0x31,0x6b,0x38,0x2a,0x4b,0xa5,0x8e,0xfb,0x99,0x60,0xd6,0x4a,0xbd,0xfb,0x75,0x2b,0x41,0xd4,0x33,0x5d,0x35,0xfe,0x2d,0xfc,0x1a,0xac,0x02,0xb3,0xf0,0xa2,0x6d,0xfa,0x8b,0x12,0x99,0xdd,0x54,0xf2,0x1c,0x35,0xd3,0x60,0x5a +.byte 0xdb,0x65,0xa7,0x58,0x1b,0x82,0xb4,0xf6,0x49,0x77,0xf2,0xea,0xa3,0xa9,0x57,0x94,0xb7,0x6e,0x19,0xda,0x7e,0xa5,0x70,0xb8,0xff,0x39,0x81,0x7d,0xfa,0xea,0xd6,0xc6,0x12,0x84,0x0a,0x8a,0x16,0xde,0x99,0xa6,0xe7,0xe0,0x77,0x76,0xb8,0xa3,0x6f,0xfb,0xb4,0x8f,0xc3,0xbd,0x90,0xd8,0x2a,0x04,0xed,0x42,0x91,0x9b,0x84,0x40,0x2d,0x01 +.byte 0x94,0xdb,0xbb,0x58,0x25,0xed,0xa3,0xdd,0xaa,0x0c,0xce,0x25,0x12,0xcd,0x11,0xbf,0xd0,0x57,0xe9,0x51,0x74,0xa7,0x45,0x6c,0x58,0xe7,0x4d,0x43,0xc6,0xd0,0x09,0x93,0x2d,0xe0,0xe3,0xae,0x7b,0x8f,0x53,0xa0,0x80,0xa1,0xef,0xcb,0xf5,0xfe,0x38,0x4d,0x31,0xa2,0x5c,0xd3,0x4a,0x66,0x1a,0x5c,0x07,0xbe,0x25,0xba,0x30,0xb6,0x00,0x27 +.byte 0x52,0xb9,0x1f,0xa3,0xed,0xd7,0x31,0x33,0x4a,0xf6,0x3f,0xed,0x75,0xe7,0xa4,0xf4,0xdf,0x97,0xc1,0x78,0x90,0x9b,0x4b,0xbd,0x06,0xc6,0x72,0x5c,0xdf,0x57,0x60,0xbe,0xbc,0x88,0x02,0xb6,0x5a,0x65,0xea,0x3a,0x3a,0x74,0x03,0xc8,0x66,0xef,0xf0,0x63,0xc7,0x9d,0x58,0x8e,0xa1,0xb2,0x25,0x4f,0xc4,0x14,0x5f,0x80,0x78,0x08,0x06,0x21 +.byte 0x50,0x34,0x01,0x2b,0x15,0xf4,0x7d,0x1f,0x1f,0x32,0x36,0x0a,0x52,0x1f,0x50,0xa2,0x50,0xbc,0x9a,0xdf,0x4e,0x84,0x49,0x2d,0x08,0xaa,0x46,0xc0,0x0e,0xcf,0x27,0x17,0x91,0x78,0x8c,0xb9,0x72,0xc5,0x8e,0x25,0x85,0x11,0xff,0x2f,0x4a,0x71,0x7c,0x14,0xfe,0x86,0xfe,0xb4,0x3a,0xd0,0x67,0xfd,0xaa,0x9b,0xee,0x89,0x66,0x03,0x59,0x4e +.byte 0x1c,0x96,0xaf,0x2b,0x8d,0x4d,0x6f,0xf6,0x72,0xc6,0x13,0xc7,0x14,0xce,0x19,0x0c,0x0b,0xa3,0x01,0x12,0x7c,0x8e,0x10,0xb8,0x63,0x41,0x57,0xb9,0xfe,0x6e,0x3e,0xda,0x20,0xfb,0x92,0x08,0x7d,0x66,0x31,0x9d,0x4f,0xdb,0x14,0xf4,0xb6,0xb8,0xea,0xee,0x54,0x0f,0xaf,0xc1,0x99,0xf0,0x8f,0x55,0x44,0x20,0x44,0xd0,0xa6,0x98,0xa3,0xa8 +.byte 0x8b,0x8e,0x26,0x03,0xec,0x2d,0x50,0x4f,0xb0,0x8d,0xd0,0xf2,0x96,0xcc,0x18,0xa9,0xb1,0x0f,0x79,0xe3,0x9f,0x08,0xb3,0x53,0x0b,0x9c,0x9f,0x22,0xdb,0x45,0x57,0xd6,0xaa,0x3b,0x6a,0xcb,0xdc,0xc9,0xda,0x57,0x75,0x65,0x0a,0xc1,0x17,0xb3,0x97,0xa9,0x07,0x40,0x20,0xfb,0x72,0x2d,0xc6,0x37,0x1e,0x44,0xb7,0x7e,0x0b,0x38,0xcc,0xfc +.byte 0xa0,0xed,0x48,0xa9,0x9b,0x87,0xbc,0x71,0x0f,0x8b,0xda,0x4f,0x09,0x27,0x1e,0x3d,0x9c,0x03,0x62,0x81,0xa8,0x7c,0x7b,0x8a,0x14,0xa7,0x22,0x69,0xa8,0xba,0x0e,0xcc,0x1f,0x2b,0xb3,0x0f,0x7d,0xce,0x3f,0xec,0xb5,0x9d,0xe0,0x3a,0x67,0x56,0x08,0x5d,0x03,0x8b,0x71,0x01,0x44,0x11,0x1b,0x7b,0xcf,0xcc,0x2e,0xfc,0xa5,0x52,0x9b,0xeb +.byte 0x1e,0x8a,0xa1,0x86,0x64,0xcf,0x32,0x03,0x6b,0x3e,0x29,0xe7,0x9a,0x16,0x7e,0xe2,0x21,0x2f,0x5f,0xe2,0x86,0x7f,0xf8,0x22,0x36,0x10,0x99,0xc8,0x27,0x43,0xa1,0xb9,0xf4,0xb4,0xb8,0xe1,0xa3,0x1d,0x80,0x9c,0x81,0x92,0xef,0x1f,0x28,0x54,0x51,0xf3,0x62,0x9c,0x7a,0x24,0xd4,0x5a,0xdc,0x38,0x4f,0xa5,0x57,0xdd,0x4d,0xa1,0x52,0xf3 +.byte 0xd3,0x9d,0xa1,0x93,0x5e,0xbe,0x9b,0xd1,0x2a,0x52,0xf1,0xbb,0xa5,0x3f,0x3a,0x94,0x7c,0x7d,0x41,0x61,0x36,0x14,0x25,0x5f,0xab,0xef,0x32,0xf3,0x0f,0x6c,0xc5,0xf5,0x5f,0xe5,0x88,0x51,0x17,0x60,0x8b,0xd5,0xa6,0xea,0x8b,0x21,0xec,0x1a,0xa7,0x69,0xa0,0x59,0xf9,0xeb,0x51,0x94,0x70,0x2b,0x96,0x2e,0x71,0xa9,0x8c,0x12,0x15,0xce +.byte 0x7d,0x59,0x6b,0xf2,0xca,0x2c,0xbd,0x85,0xfb,0x23,0xab,0xcb,0x89,0x89,0xda,0x28,0x49,0x7e,0xfc,0x90,0x2a,0x9a,0x3d,0x6d,0x24,0x57,0xba,0xd9,0x30,0xe0,0x10,0x04,0xb1,0x7f,0x8a,0xcf,0xc8,0x27,0x63,0xd6,0xbd,0xea,0xef,0x90,0x6f,0xc2,0xfc,0x78,0xfd,0xc4,0x5b,0x45,0x0c,0x41,0x8a,0x53,0x5b,0xbc,0x62,0x32,0x86,0x7f,0x19,0xb7 +.byte 0x8b,0x03,0x50,0xed,0xca,0x8e,0x8b,0xa0,0xe3,0xc2,0x0e,0x81,0xe5,0x8a,0xe8,0xf1,0x6a,0x0b,0x1a,0xa7,0xb6,0xed,0x74,0x23,0x34,0xad,0x5b,0xd8,0xf7,0x17,0x8d,0xa5,0x05,0xf3,0x00,0x4a,0xad,0x7e,0x91,0xc9,0x6b,0x13,0xff,0x76,0x78,0xf0,0xd1,0xf4,0x99,0x43,0x73,0xd9,0xba,0x59,0xbe,0xb5,0xa3,0xbd,0x5e,0xc5,0xd3,0x88,0x06,0x9c +.byte 0x86,0x32,0xb4,0xd5,0x30,0x77,0x78,0x8e,0xd5,0x6a,0x1d,0xeb,0xfd,0x6b,0xe6,0xf8,0x4b,0xe8,0xf3,0xba,0xbb,0x86,0x8e,0xe6,0x63,0x83,0x92,0x23,0x05,0x58,0x2e,0x61,0xdd,0x38,0xad,0x8d,0x19,0x7d,0xfa,0x7c,0x3e,0xc8,0x9f,0xae,0xea,0x6d,0x12,0xf0,0xa4,0x08,0xed,0x12,0x0c,0x97,0x87,0x58,0xd8,0xbc,0x3f,0xde,0x7c,0xee,0x0c,0xc0 +.byte 0xa2,0x2e,0xf0,0x25,0x6d,0xf3,0x30,0x23,0xa7,0xc2,0xc8,0x09,0x67,0x01,0xe1,0x25,0x26,0x46,0x38,0xf5,0x5e,0x55,0x8b,0xd6,0x43,0x6a,0xb8,0xe4,0xdf,0x0f,0x5d,0x6c,0xc3,0xb2,0x56,0x38,0xda,0xbc,0xbf,0x5e,0x85,0x8c,0xd5,0x2a,0x6a,0xe2,0xff,0x4f,0x36,0xf7,0x52,0x2c,0xe2,0xae,0x65,0x65,0xd1,0xfc,0xd3,0xc6,0xf7,0x26,0xa6,0xd0 +.byte 0x0b,0xc8,0xf0,0x68,0x5d,0x07,0x89,0x06,0xb3,0xfb,0x39,0x1d,0xd8,0xd8,0xd7,0x53,0xd0,0xc9,0x76,0x56,0xc0,0xd3,0xf5,0x66,0x80,0x5b,0xff,0x4a,0xdf,0xae,0x52,0x86,0x54,0x24,0x53,0xcf,0xcf,0xd2,0x89,0xde,0x71,0x62,0x9c,0x31,0xa5,0x3d,0x62,0x07,0xa1,0x33,0x49,0xbb,0x06,0x88,0xd8,0xa1,0xdd,0x0e,0x47,0x8d,0x72,0x00,0x2d,0x51 +.byte 0xa3,0x35,0x6e,0xb6,0x1f,0xbf,0xe5,0x42,0x68,0x6f,0x62,0xfa,0xf3,0x12,0xa9,0x1a,0xbd,0xe8,0xa4,0xf1,0x6d,0x07,0xe7,0x70,0x87,0x44,0xb7,0x3d,0xea,0xdc,0x3a,0x24,0xbd,0xa0,0x9b,0xb8,0xc5,0xa8,0xd9,0x06,0xde,0x02,0x68,0x7e,0xd5,0x2d,0x3b,0x5f,0x12,0x31,0x72,0x35,0x77,0xf6,0x10,0x6e,0x81,0x7d,0x3c,0xac,0x95,0x5b,0xbe,0x90 +.byte 0x74,0xf3,0x3e,0x9b,0x07,0x54,0x97,0xe3,0x1d,0xcf,0xe2,0xc5,0x80,0x6b,0x5f,0x0b,0x96,0x00,0x0f,0x0e,0x53,0x36,0x76,0x6e,0x99,0x0c,0x32,0xa2,0xc9,0xaa,0xa0,0xa1,0xb7,0xee,0x9d,0xd6,0x46,0xe7,0x2d,0x10,0x7a,0xf2,0x22,0x50,0x52,0xbf,0xec,0xcc,0xbc,0x0d,0x81,0x55,0x2d,0xac,0x2e,0xf7,0x99,0xbe,0x68,0x09,0xb0,0x11,0xc3,0xc8 +.byte 0xca,0x63,0xa7,0xc2,0x0f,0x37,0x2a,0x9e,0x85,0x79,0x6b,0x44,0xc1,0x4f,0xb9,0xd6,0x6c,0x56,0x0e,0x59,0x33,0xc3,0x00,0x53,0xe2,0xf4,0x30,0x90,0x4e,0x4b,0x09,0x4d,0x6f,0x9a,0x9e,0xb9,0x8d,0x0b,0xa1,0x80,0xfd,0xfb,0xde,0x74,0x49,0x53,0x04,0x3a,0x35,0xcb,0x45,0xe2,0x67,0x2c,0x4d,0x6e,0x39,0x7b,0xbd,0x68,0xaa,0x93,0x1e,0xee +.byte 0x1e,0x35,0xae,0x1e,0xf2,0xe7,0xb1,0x80,0x92,0x45,0x27,0x85,0xd0,0xc7,0x26,0x17,0x54,0x30,0xba,0x0c,0x8e,0x48,0xf3,0x08,0x51,0xa6,0x41,0x70,0xba,0x5b,0x90,0x69,0x7c,0x64,0x1d,0x61,0xb5,0x23,0x4a,0xef,0x97,0xe4,0x9a,0xd0,0xff,0x47,0x7a,0x93,0x1a,0x28,0xb3,0x8a,0x32,0x29,0xf8,0xe9,0x08,0xc3,0xf3,0x24,0xd7,0x2e,0x18,0x6d +.byte 0x99,0x40,0x77,0x43,0x9f,0x98,0xe4,0xe5,0x3a,0x34,0x9d,0x46,0x52,0x9f,0x84,0x79,0x8c,0x70,0xbc,0x88,0x30,0xaf,0x87,0x69,0x57,0x6e,0xde,0x2e,0xfe,0x0f,0x3b,0x8d,0xc8,0x95,0xcf,0x69,0x78,0xff,0xa1,0xb1,0x81,0x49,0x1e,0x45,0xc0,0x83,0x1b,0xa3,0x5a,0xee,0x3e,0x9a,0x15,0x7c,0xf0,0xa2,0xfd,0x04,0x22,0x55,0x2d,0x74,0x61,0x29 +.byte 0x0e,0x4f,0x31,0xdb,0x35,0x99,0x37,0xb7,0x7d,0x11,0xde,0x87,0x4f,0x84,0xeb,0x6c,0x14,0xcc,0xbb,0x71,0x47,0xab,0x5b,0x61,0x51,0xeb,0xa1,0xc1,0x5f,0xe4,0x5c,0x3c,0xab,0x04,0xf1,0x60,0x50,0xe1,0xd0,0x58,0xdf,0x42,0xed,0x73,0x5f,0x31,0xdf,0x8d,0xb8,0xb8,0xdc,0x4e,0x2f,0xe3,0x7f,0x89,0x9e,0x62,0xc9,0xef,0xfd,0x60,0xae,0x58 +.byte 0xa9,0xa5,0x8b,0xa8,0x3b,0xd8,0x5f,0xd4,0x09,0xff,0x61,0x8c,0x25,0xde,0x84,0x7f,0x35,0xc9,0x5c,0x2b,0xe8,0x46,0xe4,0x1c,0xbd,0x77,0x51,0x31,0x55,0x3d,0xb4,0x35,0xf3,0xdc,0xa5,0x55,0xd3,0xe3,0x24,0xf9,0x41,0xe2,0xf0,0xbd,0xf5,0xff,0x81,0x87,0x64,0xc9,0xe7,0x69,0x29,0x86,0xaf,0x98,0x33,0x33,0x62,0x9c,0x7b,0x16,0xbb,0xfe +.byte 0x0b,0xa7,0x92,0xa5,0x7b,0x81,0xbc,0x50,0x88,0xf6,0xe7,0xfc,0x73,0xd6,0x37,0x43,0x09,0xa5,0xc6,0xd6,0x4d,0x28,0xb5,0xaa,0x53,0x52,0x8c,0x2c,0x06,0x64,0x6c,0x21,0x6b,0xe7,0x67,0x4a,0xa5,0xcc,0xa1,0x32,0xf0,0xd9,0x78,0xb9,0xc3,0xdb,0x41,0xee,0x10,0x11,0x81,0x04,0x03,0x73,0x48,0xc6,0x3e,0x60,0x6d,0x82,0xef,0xe2,0xa8,0xe8 +.byte 0xd7,0xda,0xd9,0xb5,0x34,0x42,0xc8,0x1c,0xa7,0xa4,0x8e,0x88,0x2e,0xbc,0x96,0x0a,0xfc,0x40,0x36,0x80,0xdf,0x60,0xe9,0x03,0x02,0x0c,0x51,0xf7,0x7d,0x01,0xd2,0x21,0x38,0x44,0x4b,0x34,0x80,0xbf,0x5e,0xc1,0x86,0xf2,0x35,0xeb,0xa8,0x21,0x15,0x74,0x7c,0x99,0x55,0x64,0xf4,0x48,0xd6,0xd1,0x47,0x1f,0x4d,0xbf,0x0c,0x20,0x5d,0x86 +.byte 0xb9,0xab,0x4e,0xc8,0x86,0x08,0x71,0x1d,0x13,0xf6,0xd3,0x17,0xac,0x61,0x10,0x5d,0x2a,0xb4,0x48,0xa1,0xb9,0x79,0x5a,0x09,0x3a,0x65,0x4c,0xbd,0x97,0xbe,0x48,0xc6,0x66,0xd8,0xce,0x0c,0x19,0xb5,0x44,0x02,0xfa,0xb7,0xa8,0x3f,0x9b,0x86,0xec,0xd1,0xef,0x1d,0x7d,0xb3,0x82,0x5c,0x92,0x48,0x02,0x2c,0x56,0x0f,0xff,0xf7,0x19,0x74 +.byte 0xc2,0x38,0x24,0x8d,0xb2,0x87,0xb6,0xeb,0x49,0x50,0x6a,0x33,0x74,0x4e,0x2a,0xcb,0xf4,0x13,0x2c,0xfa,0x3b,0x0e,0x3d,0x98,0x3e,0x33,0xd9,0x55,0xfa,0xb9,0x74,0xb8,0x6f,0xc1,0xd8,0xfd,0x8f,0xff,0xb9,0x1a,0x17,0xf8,0xb6,0x21,0xc4,0x9d,0x47,0x5e,0x84,0xf6,0xe5,0xbf,0x93,0x98,0xac,0x8f,0x68,0x85,0xf8,0xe8,0x79,0x7f,0x6f,0x0d +.byte 0x62,0x2c,0xaa,0x1e,0xe4,0xab,0x73,0xf8,0x6f,0x02,0xda,0x6b,0x3c,0x14,0x2e,0xc9,0xdb,0xb0,0x4e,0x39,0xb5,0xcf,0x05,0xae,0x9c,0x63,0x2f,0x6a,0x25,0x61,0x9d,0x40,0xeb,0x7e,0xd8,0x97,0x97,0x33,0x67,0x5c,0x78,0x84,0x68,0xc2,0x7a,0x26,0x58,0xe3,0x6c,0x0a,0x2e,0x6a,0x82,0xd6,0x43,0xed,0x79,0xa5,0x8d,0x4e,0x7c,0xf7,0x80,0x01 +.byte 0xe7,0x02,0x5e,0x3a,0xf7,0x8a,0x4a,0x85,0xe9,0x98,0x1e,0x69,0x33,0xf3,0x54,0x96,0x79,0xc8,0x03,0x0a,0x9f,0x0c,0x5d,0x66,0x44,0x88,0x3c,0xd7,0x9e,0xd1,0xde,0x01,0xfd,0x5e,0xa5,0x6a,0x82,0x00,0x36,0xe6,0x12,0xe3,0x62,0x46,0x45,0x69,0xfb,0x4f,0x44,0x8e,0xe5,0x8d,0x21,0x57,0x6a,0x61,0x8e,0x56,0xcb,0x5b,0x2c,0x5f,0x65,0x41 +.byte 0x2c,0xad,0xf2,0x98,0x34,0xbb,0x06,0x0d,0x8a,0x3c,0x34,0x0d,0xa3,0xe2,0x6e,0x86,0xfa,0xa9,0xfb,0x6f,0xbb,0x32,0xd6,0x0d,0x76,0x6b,0x77,0xf3,0x83,0x41,0xc0,0x80,0x63,0x55,0x47,0xb8,0x13,0x6b,0x99,0x96,0x08,0x9b,0xc0,0x82,0xae,0x49,0x4a,0x51,0x63,0x74,0xf2,0xec,0xfa,0x0d,0xbc,0x3a,0xde,0xf5,0x4b,0x4f,0x08,0x41,0x23,0x88 +.byte 0x14,0x88,0x6a,0x3a,0xf0,0x5f,0x0c,0x45,0x7f,0x65,0x7a,0x67,0xd8,0x17,0xed,0x04,0x47,0x60,0x0e,0x74,0x8f,0xfd,0x48,0xda,0xcd,0xe9,0xfe,0xf5,0x6f,0x43,0xcd,0xa5,0x05,0xa2,0x2e,0x78,0x5b,0xff,0xb8,0x6f,0x2e,0xfd,0x3e,0x4b,0xef,0xcf,0xe0,0x06,0x57,0x28,0xf4,0x2e,0x3b,0xb5,0x9e,0x3c,0xbd,0x63,0xa6,0x78,0x8e,0xd5,0xb8,0x81 +.byte 0x4e,0xf0,0xbf,0x14,0x65,0xc8,0x00,0x9f,0x0e,0x25,0x6a,0x7a,0x63,0x58,0xe4,0xe7,0xa9,0x82,0x16,0xc9,0x86,0x20,0x94,0x71,0x5b,0x9f,0x9b,0xc3,0xc5,0x32,0xb0,0x6c,0x2b,0x8c,0x54,0x67,0x36,0x94,0xb1,0x47,0x33,0xfd,0x9f,0x7c,0x7f,0x7e,0x08,0x51,0x1f,0x7e,0xbf,0x09,0x57,0xf3,0xaa,0x77,0x94,0xf3,0x20,0x1b,0x95,0xf6,0x04,0xb2 +.byte 0x09,0x9d,0xe2,0xbb,0x4d,0xfe,0x6b,0x99,0x06,0x58,0x40,0x84,0x90,0xfa,0x0e,0x9b,0x58,0x6d,0x02,0xbe,0x53,0x73,0xd1,0xc9,0xc7,0x31,0x2a,0x4a,0x12,0x2c,0xb6,0x1c,0xfb,0x49,0xc6,0x1a,0x93,0x33,0x1f,0x29,0x8b,0x94,0xe9,0x20,0xa7,0xe6,0x20,0xe6,0xbf,0xcd,0x5c,0xb6,0x52,0x42,0xf0,0x9c,0x6c,0x21,0x61,0x10,0xe7,0x0e,0x9f,0x33 +.byte 0x5f,0xc8,0xd0,0x20,0xe0,0x3e,0xc5,0x7a,0x10,0xf1,0xe5,0x19,0x52,0xcd,0xe1,0xa8,0x62,0x43,0x20,0x79,0xc3,0xac,0x93,0x27,0x02,0x8e,0x21,0x06,0xb9,0x66,0xd9,0xc8,0x40,0xe0,0xd1,0xf0,0x64,0x81,0xa6,0xc4,0x87,0x85,0x2b,0x92,0x1c,0xd6,0x48,0x85,0xb1,0xbe,0x78,0xf3,0x89,0xa2,0xf0,0xe5,0x39,0xac,0xbf,0x59,0x5d,0xf8,0x4f,0x74 +.byte 0x44,0x85,0x98,0x03,0x81,0x4b,0x7e,0x6f,0x5c,0xa1,0x11,0xd2,0xfd,0x30,0x7f,0xcd,0xd0,0xe2,0xcc,0xd4,0x80,0x16,0x46,0xa6,0x64,0x8b,0x9e,0xfc,0x2a,0x1a,0x65,0x5c,0x90,0x82,0xf9,0x23,0x48,0x11,0xf6,0xf2,0x50,0x3f,0xed,0x44,0xf2,0x9a,0x5a,0xca,0x1c,0x9a,0xd2,0x71,0x1b,0xd6,0x4c,0x51,0xf6,0x89,0x6f,0x65,0xe4,0x97,0x41,0x47 +.byte 0x1b,0x86,0xbd,0x83,0xa0,0xfe,0xac,0x16,0xe8,0xab,0x28,0x96,0x2f,0xa2,0x12,0x5f,0x7c,0xb3,0x18,0x2b,0x05,0x51,0x49,0xba,0xb4,0x1f,0x1e,0xe6,0x8a,0x82,0xca,0x33,0x7d,0xe6,0x8c,0x95,0xba,0x08,0x60,0x47,0x6d,0x79,0xac,0x0f,0xba,0x46,0xff,0xed,0xe0,0x34,0x03,0xfe,0xa7,0x85,0xe5,0x61,0xe3,0xe4,0x6c,0x5c,0x1b,0x9d,0x8a,0x54 +.byte 0x17,0xaf,0x08,0x4c,0x44,0x7f,0xb7,0xb0,0x6a,0x3a,0xff,0xb7,0xf6,0x10,0xc4,0x8f,0x31,0xd6,0x1a,0x25,0x27,0x35,0xca,0x87,0xa9,0x61,0x0b,0x35,0x96,0x89,0x0f,0x1a,0xbd,0x1e,0xf6,0xee,0xaa,0x95,0x16,0xe4,0x38,0x7b,0xb2,0xbe,0xea,0xc9,0x5a,0xcd,0x3b,0xb8,0x9e,0xd7,0x20,0xcd,0x3f,0x90,0xaa,0x8b,0x2a,0x42,0xed,0xab,0xc1,0x53 +.byte 0x83,0xc7,0xb8,0x3f,0xa1,0xb9,0xf4,0xf4,0xb0,0xe0,0x1f,0xb0,0xeb,0xa9,0x81,0x9f,0x31,0x67,0x1e,0x6c,0x96,0x9f,0x09,0xea,0x04,0xfe,0x37,0x22,0x87,0x60,0xb9,0x91,0x8f,0xa9,0x11,0xa3,0x68,0x5e,0x29,0x21,0x41,0xa3,0x02,0x08,0x82,0xd0,0x2b,0x66,0x6d,0x3c,0x46,0xc7,0x23,0x09,0x86,0x7f,0x53,0x11,0x3e,0x83,0x52,0x0a,0x4a,0xe4 +.byte 0x93,0xc6,0xc1,0x96,0x17,0x94,0x51,0x17,0x69,0xea,0x72,0xb8,0x85,0xde,0x7e,0x13,0x4a,0x08,0x26,0xae,0x31,0x19,0x0f,0x6f,0x48,0xa1,0xf2,0x57,0xa2,0x01,0x8e,0x84,0xee,0x63,0x23,0xc0,0x97,0x84,0xa2,0xf5,0x3f,0xeb,0x30,0x9e,0xdd,0xd2,0x43,0x24,0xa2,0x57,0xb7,0x57,0x86,0x26,0xa3,0xe6,0x6e,0xf2,0xcd,0xfb,0x7b,0x34,0x74,0x53 +.byte 0x07,0x95,0x51,0xb7,0xfd,0xf3,0xd1,0x83,0xbd,0x25,0xd6,0x2c,0x69,0x73,0x02,0x8e,0x76,0x19,0xea,0xb0,0x83,0x60,0x8c,0x53,0x9d,0x77,0x86,0x1e,0x65,0xc7,0x57,0x31,0x29,0xd9,0xa9,0x3a,0xb2,0x0d,0xd8,0xf4,0xf9,0x48,0x49,0xfb,0x3c,0x40,0x3d,0x1b,0xc4,0x8b,0x94,0x0e,0x50,0x7f,0xd5,0x39,0x5e,0x57,0x86,0xd1,0xba,0x0c,0x38,0x10 +.byte 0x01,0x5f,0x44,0xf3,0xe5,0xb0,0xf8,0xae,0x17,0xdf,0xd2,0xb3,0x10,0xc5,0x3b,0xfd,0xd9,0x68,0x90,0x9c,0x6c,0x26,0xdf,0x12,0x50,0xfa,0xbf,0x8b,0xce,0x68,0x80,0x8c,0x04,0x60,0xbf,0x34,0x81,0xbd,0x29,0xa3,0xa2,0xe4,0xe0,0x2d,0x25,0xb2,0xff,0x9f,0xd1,0x20,0x07,0xd5,0x8c,0x19,0xfa,0x3f,0x47,0xec,0xc1,0x8d,0xc9,0x36,0xf8,0x51 +.byte 0x4c,0xaa,0x40,0xe3,0x6a,0x21,0xd5,0xe6,0xa6,0xcf,0x8c,0xd9,0x10,0x47,0x66,0xfd,0x32,0x48,0x36,0x8f,0x14,0xed,0x09,0x80,0x50,0x27,0xaa,0xd5,0x1f,0x69,0xb8,0xe4,0x96,0x27,0x56,0x78,0xd6,0xd5,0x2d,0xf0,0x4f,0x14,0x30,0x17,0x9e,0x5b,0x69,0x8c,0x7c,0x1c,0x97,0x38,0x65,0x77,0x75,0x49,0xac,0x4b,0x06,0xda,0x74,0x11,0x86,0xbc +.byte 0xad,0x01,0xf2,0x03,0x29,0x5d,0xa7,0x74,0xd3,0x44,0xae,0x1d,0xbf,0xf9,0xc5,0x5b,0x83,0x8c,0xd6,0x84,0x8a,0x8e,0xe9,0xa6,0x08,0xf4,0x88,0x13,0xcb,0x16,0x45,0x13,0x9c,0xc7,0x75,0xa9,0xa7,0x55,0x04,0x91,0xd6,0xe9,0xd4,0xe5,0x65,0xa0,0x3a,0x53,0xa0,0xfc,0x62,0xce,0x91,0x01,0xb4,0x06,0x8b,0x10,0x79,0x6f,0x2c,0xd6,0x0a,0xa2 +.byte 0x31,0x8f,0x75,0x32,0x0e,0xfa,0x0d,0xec,0xfd,0x71,0x7f,0x74,0x97,0x30,0xe9,0xee,0x9f,0x04,0x21,0xb5,0xc9,0xd1,0x52,0x2a,0x0f,0x18,0xbe,0x3e,0xbb,0x98,0xaf,0x59,0x9b,0x85,0x79,0x5e,0x52,0x93,0x1c,0x42,0x67,0x67,0x6b,0xd5,0x41,0xaf,0xba,0x09,0x3a,0xb4,0x0e,0x97,0x22,0xe6,0xbb,0xe1,0x27,0xa1,0xf9,0xf0,0xcd,0xa2,0x3d,0xdb +.byte 0x81,0x2f,0x65,0x90,0xb7,0xe5,0xe5,0xce,0x1d,0x3b,0xfe,0x34,0x57,0xcd,0x3a,0xbd,0x19,0x59,0x23,0x12,0xf1,0xb6,0xf2,0xf7,0xc1,0xf5,0x1d,0x0b,0x46,0x8f,0x16,0x6a,0x81,0xfe,0xc1,0x97,0x8d,0x69,0x55,0x60,0xdd,0xf0,0x61,0xe9,0x22,0x30,0x72,0x1a,0x24,0x30,0xd7,0xbc,0x1c,0xfa,0x02,0x55,0xfc,0xb9,0x4b,0x0a,0xe4,0x90,0x90,0x3a +.byte 0xe3,0xce,0xd4,0xa0,0x7d,0x21,0x5a,0xf7,0x79,0x6e,0x03,0x4f,0x4e,0x93,0xad,0xc4,0x8e,0x9d,0x9f,0x8a,0x39,0x59,0x20,0xc1,0x5d,0x6a,0x4d,0x8f,0x69,0x78,0xea,0xba,0xde,0xc0,0x87,0xb2,0xf2,0x20,0xd6,0x7a,0x9c,0xf9,0x09,0x03,0x2a,0x4d,0xb9,0x10,0xfc,0xe5,0x05,0x90,0xed,0x45,0x4f,0x5f,0x7c,0x5d,0xfa,0xe6,0x0d,0x07,0xae,0xcc +.byte 0x21,0xc8,0x1c,0x7a,0xfb,0x1d,0xb9,0xe3,0x69,0xa1,0xb7,0x5f,0xb5,0x6a,0xb9,0x58,0x9d,0xcd,0x99,0xf8,0x38,0xbb,0xa0,0xfe,0xf8,0x41,0x51,0x72,0xce,0x76,0x89,0x59,0xa2,0xab,0xef,0xea,0xab,0x79,0xbc,0xda,0x73,0xdb,0x18,0xda,0x60,0x1b,0xc4,0xb7,0x4f,0xb3,0x86,0x21,0x2a,0xc3,0xec,0x7f,0x0e,0x89,0x16,0x0e,0xd2,0xbd,0xea,0x0e +.byte 0xcf,0xc1,0x4b,0x2c,0x97,0x69,0xce,0xd3,0x94,0xad,0x81,0xe9,0x70,0xf4,0xf8,0xe5,0x77,0xe6,0x92,0xe0,0x23,0x38,0xd3,0xc1,0xdd,0x2e,0x58,0x77,0xc5,0xc3,0x29,0x34,0x66,0x48,0xf9,0x75,0x3c,0x8a,0x6a,0xb8,0xbf,0xf8,0xba,0xf0,0xb9,0xa1,0x81,0x0b,0xa1,0xaa,0x17,0x34,0x1a,0xbb,0xa3,0xa2,0xba,0x21,0x45,0xc0,0x1d,0x57,0x11,0x4d +.byte 0x9b,0xd4,0x64,0x84,0xd7,0x0b,0xd6,0xfb,0x72,0x2c,0xdb,0xc3,0xe6,0x24,0xa9,0xf3,0x30,0x9f,0x21,0x05,0x1e,0xcc,0x48,0x58,0xed,0xfd,0xb2,0x34,0xe3,0xf7,0x7e,0x56,0xee,0xdf,0xa4,0xbb,0xb1,0xcc,0x7f,0x81,0x40,0xe9,0xdf,0x3f,0x82,0xc4,0x0d,0x14,0x9b,0x3b,0x80,0x15,0x24,0x6e,0xa4,0xce,0xfa,0x28,0xa7,0x7f,0x89,0xfb,0xc6,0x83 +.byte 0xe8,0x2a,0x70,0xfb,0x9c,0x75,0xb8,0xfd,0xec,0xbc,0xbb,0xf5,0xef,0x0a,0xa5,0x77,0x0b,0x38,0xa0,0x63,0xa5,0x71,0x12,0xc9,0xaa,0xc3,0xf9,0x72,0x30,0x45,0x4e,0x19,0x44,0x2d,0x09,0xf4,0xf1,0xa8,0xe8,0xde,0x58,0x87,0x70,0xa8,0x91,0x86,0xef,0x5d,0x02,0x90,0x55,0x63,0x99,0xde,0xd7,0xb7,0x5f,0x07,0x01,0xdf,0xb1,0xe5,0x55,0xf5 +.byte 0x87,0x69,0xd2,0x7a,0x71,0xbc,0x0e,0x4b,0x8b,0x98,0xf7,0xf6,0x0a,0x01,0xbb,0x9f,0x1b,0x15,0xb6,0x76,0xe0,0xc0,0x4b,0x5d,0x08,0xba,0xba,0x73,0x3f,0x36,0x5a,0x29,0xd7,0x7c,0xc2,0x87,0x03,0x75,0xff,0x26,0x21,0xae,0xbe,0x66,0x70,0xa2,0x99,0x11,0x35,0x49,0x78,0x7b,0x3a,0xfe,0x94,0xf7,0x37,0xe0,0x69,0x56,0x39,0xf7,0x3f,0x71 +.byte 0x39,0x74,0x75,0x32,0x1f,0xfb,0x3a,0x87,0x07,0xab,0xf1,0xed,0xe3,0xe2,0xbf,0x3f,0xb1,0x73,0x11,0xc9,0x34,0x4b,0xb1,0x1e,0x62,0x4e,0xc1,0x8a,0xae,0xcc,0xc7,0xb3,0xa7,0x70,0x01,0x73,0xad,0xb3,0xc3,0x59,0x70,0x14,0x31,0x94,0x9f,0x6b,0x18,0x11,0x50,0x52,0xc9,0xf0,0xf8,0x12,0x9d,0x7c,0x90,0x64,0x9d,0xd9,0x41,0xa6,0x45,0xe3 +.byte 0xc9,0x25,0x73,0xe7,0x48,0x9d,0xdc,0xe0,0x2c,0x71,0xd3,0x68,0xc5,0xab,0xac,0xe3,0x16,0x95,0xe3,0xa5,0xae,0x2f,0x57,0x60,0x4b,0x11,0x90,0xaa,0xe7,0x48,0xca,0xc7,0xde,0x2e,0x56,0x10,0x8e,0xc3,0x0a,0x7d,0x66,0xf1,0xc3,0xf7,0x2d,0xdd,0xfa,0x5e,0xb2,0xcb,0x99,0x4d,0xaa,0x4e,0x91,0xc1,0x94,0x60,0x27,0x33,0x82,0xa6,0x2a,0xba +.byte 0x05,0x32,0x33,0x0a,0x30,0x47,0xb0,0xac,0x68,0x7d,0xef,0x25,0x09,0xcf,0x51,0xf4,0x06,0x28,0x14,0xb2,0xb4,0x1f,0xaf,0x37,0xdc,0x70,0x88,0x4d,0xb9,0xfc,0x2d,0x61,0x25,0x13,0x1f,0x32,0x48,0x6d,0xeb,0x46,0x05,0x66,0x44,0xa1,0xec,0xce,0xe9,0x51,0xa9,0xba,0xf8,0xde,0x95,0x1b,0x20,0xe1,0x21,0x75,0x4b,0x25,0x7f,0x3c,0x16,0xf7 +.byte 0xe2,0xbe,0xeb,0xca,0x2b,0x77,0x92,0x16,0x32,0xe2,0x74,0x21,0x52,0x3f,0x08,0xba,0x41,0xb0,0xd3,0xd2,0xf7,0xf3,0x29,0xb6,0x10,0xfa,0xa5,0x29,0x35,0x29,0x21,0x0d,0xec,0xba,0x5a,0xf3,0x63,0x0f,0x9d,0xbc,0x42,0x02,0x46,0xe9,0x07,0x4a,0x9a,0xe8,0xd3,0x78,0x92,0xa2,0xe5,0x03,0xec,0xd4,0xe2,0xc8,0x8f,0x92,0x4a,0xae,0xbc,0xd7 +.byte 0xdf,0x4b,0x07,0x22,0x47,0xbd,0xb4,0xb5,0xa0,0x7e,0xfb,0x21,0x40,0x62,0xb1,0x6c,0x07,0x00,0x64,0xf6,0xb2,0x75,0x5c,0x29,0x84,0xff,0x38,0x0c,0xc8,0x08,0x38,0x92,0xf9,0xad,0xd7,0xcc,0xc3,0x1c,0x03,0x80,0x49,0x39,0x1c,0xdb,0xae,0x60,0x87,0x8a,0x5c,0xe9,0x17,0xbd,0x2b,0x0f,0xa5,0xa1,0xf9,0x0d,0x4b,0x8c,0x4d,0x39,0xda,0x15 +.byte 0x8c,0xc4,0x69,0xaf,0x2b,0xb0,0xa1,0xfd,0xd9,0x65,0x3c,0x87,0x4b,0xf2,0x5a,0xd7,0xd8,0xb9,0xef,0x78,0x67,0x30,0x4c,0x6c,0x92,0xc5,0x1e,0x15,0xf8,0xd9,0x74,0x1b,0x54,0x0c,0x10,0x1b,0xb5,0x11,0x13,0xd6,0xb4,0xc0,0x53,0x03,0x2c,0x4b,0xee,0xac,0xf9,0x87,0x17,0x51,0x35,0xb8,0x1a,0xdc,0x16,0x61,0x5b,0xe9,0x5a,0x43,0x94,0x42 +.byte 0x8f,0x68,0xbd,0xb6,0x52,0x00,0x63,0xa3,0x52,0x6e,0x5d,0x8e,0xe9,0x4f,0xf5,0x69,0xd8,0x4f,0xf5,0x5c,0x89,0x7e,0x1c,0xb9,0xdc,0x7b,0x92,0x8a,0x2b,0xfc,0xb8,0xad,0xbb,0xff,0x61,0x2e,0xc0,0xdc,0xfb,0x2f,0x78,0x2a,0x50,0x32,0x9b,0x4c,0xfd,0x9e,0xab,0x80,0x5c,0x7d,0xc8,0x6b,0xb3,0x2d,0x0a,0xfe,0x43,0xa2,0x10,0x10,0x79,0xbc +.byte 0x8c,0xa0,0x86,0x09,0x8c,0x8b,0x28,0xf3,0x8a,0xc9,0xeb,0xcb,0xb5,0x0e,0x56,0x19,0xae,0xe0,0xa1,0x22,0x72,0xc5,0xad,0x01,0x12,0x69,0xb6,0x52,0xb8,0xdd,0x36,0x25,0x21,0xae,0x73,0x06,0xc1,0xe0,0x23,0x20,0xe1,0x8e,0xe4,0x99,0xcd,0x86,0xca,0xf5,0x93,0x0e,0x6b,0xb8,0xba,0x18,0x4a,0x36,0xed,0xd0,0x37,0xc8,0xc7,0x8a,0xb2,0x63 +.byte 0x2e,0xa4,0x22,0x76,0x6f,0xf7,0xdd,0x81,0xd6,0x6f,0xcd,0xb9,0x65,0xf0,0x95,0x77,0xae,0xca,0x54,0x62,0xce,0x5d,0x47,0x9e,0x10,0x89,0xb9,0xfa,0x72,0x0a,0xef,0x24,0x17,0x45,0xb0,0xb0,0xc7,0x51,0x85,0xa1,0xb1,0x6a,0xd2,0xea,0x48,0xe2,0x6a,0x03,0x2a,0xdf,0xa8,0x0e,0x62,0xa2,0x1e,0xe2,0xa7,0x20,0x57,0xbd,0x73,0xeb,0xef,0x86 +.byte 0xc9,0xd4,0xfa,0x96,0xfe,0xfa,0xb3,0xc6,0xbf,0x7a,0x16,0xa2,0x43,0x73,0x56,0x71,0x78,0x32,0x3b,0xc1,0xd8,0x26,0xbf,0xde,0x39,0x5d,0xbd,0x3b,0xff,0xd7,0x4f,0xa0,0x67,0xa6,0x09,0x9a,0x81,0xfd,0xec,0x34,0x73,0xcd,0x90,0x15,0x8b,0x3e,0x2d,0x6f,0x7d,0xcc,0xf5,0x20,0x15,0x07,0xa8,0x2f,0xa5,0x5b,0x2b,0x4f,0xb8,0x2f,0x14,0x6c +.byte 0x52,0x78,0xbd,0x92,0x98,0xda,0x69,0x19,0x58,0x4c,0x76,0xe4,0x20,0xb2,0x48,0xa4,0x9f,0x2f,0x4c,0x9b,0x45,0x7f,0x7d,0x1c,0x46,0xe9,0x1e,0x43,0x26,0x49,0x39,0xb6,0x42,0x3a,0x4c,0x59,0x95,0x6b,0x28,0xd5,0xbe,0xa7,0x2e,0xd0,0x0c,0x00,0xa0,0x67,0x06,0x4e,0xee,0xae,0x7f,0xc2,0xb5,0x12,0x46,0x3f,0xb4,0x35,0x16,0x2a,0xda,0xbf +.byte 0x41,0x34,0xbe,0x30,0x2a,0x0f,0x7b,0x60,0xa6,0x8b,0xcd,0xae,0x7a,0x8c,0xd6,0x97,0xab,0x06,0x1e,0x14,0x87,0x45,0xa3,0x3c,0x9c,0xc4,0xa0,0x1d,0xee,0xf0,0xca,0xb8,0xa6,0x8d,0x37,0x92,0xad,0xbc,0xe6,0x1f,0x65,0x75,0xd3,0xbc,0x72,0x66,0xe2,0xff,0xbc,0x19,0x93,0xae,0xee,0xd0,0x63,0x6d,0x97,0x6f,0x57,0xf3,0x77,0xcd,0xe3,0x57 +.byte 0x3f,0x00,0xc8,0xe1,0x63,0x83,0x15,0x84,0xc6,0x08,0xdb,0x03,0xc9,0x27,0x47,0x4c,0x17,0x12,0x40,0x6e,0xac,0x74,0x6f,0x3c,0x22,0x57,0x36,0x29,0xbb,0x6a,0xc7,0x5a,0xfe,0x60,0x1c,0x0f,0x32,0x95,0x1b,0xf2,0x3c,0xed,0x04,0x87,0x4c,0x48,0xc7,0x63,0x79,0x24,0xb3,0x12,0xbf,0x55,0x3b,0x32,0xbf,0x52,0x4e,0x1e,0xc1,0x1f,0xf2,0xfd +.byte 0xe6,0xb8,0x56,0x38,0x0e,0xd2,0x75,0x3d,0x41,0x99,0x0c,0x7a,0x12,0x3f,0xa7,0x3a,0x79,0xa0,0xd7,0x6f,0x47,0x97,0x7e,0x9e,0xf6,0xfe,0x29,0xc0,0x16,0x34,0x38,0x80,0x2f,0xde,0x65,0x79,0xc9,0xfd,0xa0,0x84,0xc3,0x39,0xbc,0x0b,0xbe,0x18,0xba,0x0d,0xe3,0x35,0x11,0xba,0x9f,0xde,0x5d,0x0c,0xae,0x8e,0x0c,0x0f,0x66,0x9c,0xe6,0xfc +.byte 0x3d,0xdb,0x46,0xf1,0x84,0x57,0x62,0xb0,0x00,0xd4,0x8c,0xaa,0x93,0xeb,0xf7,0xa7,0x8e,0x82,0xba,0x89,0x67,0xbb,0x38,0xb0,0xb6,0x13,0x0c,0x96,0x22,0x9c,0x6a,0x86,0xea,0x83,0xad,0x5f,0x7b,0x3a,0x28,0xd8,0x53,0x90,0x2d,0xab,0xc9,0xbe,0x99,0xfb,0x68,0x42,0x27,0xf6,0xe3,0x5a,0xaf,0xf3,0xd6,0xee,0xb6,0xa2,0xe0,0x32,0x3c,0x1d +.byte 0xd4,0x3c,0x2b,0x58,0xc2,0x4f,0x3d,0x20,0x39,0xdb,0x80,0x89,0x20,0x20,0x7b,0xe6,0x1d,0xd0,0xa2,0x1a,0xd4,0x88,0xc9,0xe0,0xb9,0xf6,0xb2,0xa1,0xcd,0xf2,0x67,0x60,0x44,0xd8,0xce,0x6a,0xe2,0x52,0xc3,0xf3,0x61,0xa3,0x14,0x58,0xd6,0xe5,0x43,0x4a,0x8d,0xcc,0x4f,0xf8,0x17,0xdd,0xd2,0x5d,0xd5,0x5a,0x86,0x8e,0xc4,0x74,0xdc,0x1b +.byte 0xad,0xca,0x63,0x75,0xf0,0x43,0x41,0x16,0x02,0x49,0x6a,0x3a,0xe3,0xb9,0xa9,0xdc,0xfb,0x99,0xbc,0x60,0x0d,0xdb,0xa0,0xcf,0x27,0xaa,0xd5,0xc5,0x42,0x0b,0x02,0x00,0x43,0xaf,0xb5,0x4f,0xe1,0x88,0xa1,0x9d,0xca,0xfb,0x9f,0x1f,0x08,0x9c,0x66,0x23,0xca,0x4b,0x88,0xb4,0x40,0xdc,0xd3,0xd3,0x1a,0x64,0xe3,0x9b,0x43,0xea,0x20,0x90 +.byte 0x30,0x2e,0xc4,0x75,0xc5,0x52,0xc5,0x7c,0x0e,0x35,0x56,0xf5,0x1f,0x50,0x2b,0xf6,0x28,0x93,0x6f,0xde,0x10,0xc6,0x49,0x2b,0x77,0xb1,0x6d,0xce,0xfd,0x37,0xd4,0x8d,0x11,0xed,0x88,0x1e,0xca,0x68,0x0c,0x4e,0x38,0x7f,0x0f,0xab,0x6f,0x8d,0x1c,0x7d,0xd4,0x7d,0xd8,0xa9,0x5c,0x24,0x5a,0x7d,0xf4,0x5b,0xb6,0xb7,0x28,0xc7,0x93,0xd6 +.byte 0xa9,0xe5,0xac,0x62,0x16,0x9c,0x4e,0x5c,0x24,0xa0,0x2a,0x76,0xce,0x7d,0x5c,0x4b,0xbe,0xbc,0x83,0x5c,0x9a,0xc8,0x06,0x7b,0x1e,0xac,0x98,0x67,0x17,0x32,0x94,0xda,0xd1,0x8b,0x58,0xad,0x8e,0x26,0x03,0x81,0x7c,0x48,0xd1,0x83,0x03,0xba,0x6c,0x51,0xe9,0x25,0x82,0xd2,0xb9,0x7f,0xd8,0x33,0x3f,0x77,0x29,0x45,0x41,0xa9,0x17,0x3d +.byte 0x62,0xc6,0xd2,0xfb,0xd1,0x24,0xc7,0xee,0x10,0xc0,0x64,0xc3,0x46,0xc6,0x2b,0xe8,0x9c,0xc8,0x99,0x23,0x77,0xa9,0xb5,0x12,0xc4,0x53,0xde,0xbc,0x20,0xb2,0xc4,0x12,0xdb,0xc2,0x0b,0x63,0x70,0x6a,0x41,0x31,0x65,0x48,0xa0,0xfc,0xbc,0xd6,0x3f,0x55,0x18,0x17,0x65,0x35,0x58,0xe3,0x33,0xac,0xaf,0xca,0xb2,0x51,0xc1,0xcc,0x60,0x38 +.byte 0x94,0x8f,0x13,0xb8,0xcc,0x8c,0xc4,0x12,0xea,0xd5,0x39,0xd3,0x46,0x55,0x17,0x27,0x7a,0x07,0x01,0x02,0x74,0xa6,0xe7,0xc8,0xa7,0xd0,0x76,0xc8,0x5e,0x57,0x50,0xc5,0x19,0xf1,0x95,0xa3,0x52,0x10,0xa3,0x1e,0xcd,0xb1,0x05,0x64,0xe5,0x69,0xd9,0x5e,0xfc,0x71,0xef,0xe1,0xf6,0xb3,0xa7,0xf7,0xf9,0x71,0xfd,0xbb,0x5b,0x2b,0x7a,0xd2 +.byte 0x72,0x7c,0xc7,0x73,0x89,0xf7,0xe2,0x0b,0xcd,0x05,0x4f,0x0c,0x10,0xed,0xcc,0xda,0xb6,0x81,0x19,0xe6,0x2b,0x06,0x66,0xef,0xc5,0xfd,0xd5,0xc6,0x66,0x20,0x86,0x2a,0x4f,0x05,0x49,0xf1,0x54,0x4a,0x6e,0x1d,0xcd,0xad,0x18,0xeb,0x6c,0x58,0xd6,0x75,0x3e,0x62,0x48,0xab,0xea,0x1f,0x7f,0x05,0x45,0x6e,0x75,0x2a,0x5e,0x97,0x5b,0xde +.byte 0x5a,0x99,0x42,0xc1,0x62,0xab,0xc7,0x01,0x4d,0xac,0xd6,0xdc,0xc9,0x71,0x24,0xd1,0x33,0xe2,0x4b,0x1f,0x09,0x04,0x1f,0x0d,0x42,0x45,0xcf,0x7c,0xa0,0xee,0x48,0xfd,0x8b,0x1f,0xaa,0x50,0x48,0x6d,0x8e,0x34,0x76,0x09,0x23,0x8a,0x40,0x0d,0x5d,0xc1,0x2a,0xba,0x5f,0x9c,0x86,0xfb,0x37,0xdf,0x24,0xff,0x27,0x88,0xbf,0xf6,0xa4,0xc3 +.byte 0xf0,0xd3,0x02,0xa8,0x7c,0x6d,0xc4,0xc5,0x14,0xc3,0x64,0x28,0xa8,0x05,0x33,0xc2,0xda,0x12,0xfc,0xbe,0x0d,0x8e,0xf4,0xf5,0x48,0x5a,0x8e,0x8a,0xd2,0x50,0x7c,0xc0,0xbc,0xde,0xdb,0x9a,0xf6,0xa0,0x92,0x8d,0x19,0xbc,0x5a,0xdc,0xbf,0xfb,0x13,0x8f,0x41,0x09,0xba,0xd9,0x0b,0x91,0x7a,0xdb,0x92,0x10,0xac,0xf2,0xb5,0x76,0xb5,0x7d +.byte 0x80,0x04,0xd6,0xec,0x98,0x09,0x5f,0x63,0x0d,0x58,0x00,0x8a,0x07,0x76,0xfa,0xe6,0x6e,0xdf,0xbf,0x73,0xe5,0xc9,0xe5,0x12,0x44,0x58,0xf9,0x2e,0xb1,0xe6,0x2c,0xf5,0x0d,0x94,0xa9,0x51,0x0d,0x01,0x03,0xab,0x79,0xf9,0xee,0x7e,0x10,0x4b,0xcb,0x20,0xbb,0x01,0x19,0xd6,0x12,0xd1,0xac,0x96,0xe9,0x0e,0xde,0xbf,0x7e,0x80,0xf6,0x58 +.byte 0xc9,0xec,0xaf,0xf7,0x2d,0x98,0xbc,0x2b,0xb1,0xf1,0x34,0x94,0x39,0x8e,0xbc,0x13,0x13,0x41,0x8f,0xf3,0x4e,0x4e,0x6b,0x2a,0xaa,0xea,0x70,0x5c,0xf8,0x42,0xf7,0xbc,0xfd,0xbd,0x6f,0x62,0x1b,0xcb,0xb9,0x39,0xdc,0x6a,0x47,0x81,0xaf,0xff,0x5b,0x7e,0x80,0xb9,0xbf,0xfa,0x15,0x7e,0xd1,0xc3,0xb2,0x80,0x99,0xbd,0xb9,0x30,0x8d,0xb5 +.byte 0x43,0x6b,0x7a,0x31,0xaf,0x45,0xf7,0xdd,0x21,0x8f,0x54,0xb1,0xf6,0x2d,0x7d,0x96,0x63,0x4a,0x93,0x98,0x37,0x7f,0x48,0x02,0x4b,0x0f,0x71,0xe4,0x70,0xce,0x66,0x6a,0x36,0xde,0x58,0x84,0x69,0xd6,0xbd,0x1a,0x9a,0x8b,0xc5,0xda,0x97,0xc5,0xe1,0x4e,0xec,0x9b,0x7a,0x65,0xe0,0xa5,0xdd,0x39,0x3c,0x9f,0xfd,0x45,0x17,0x4c,0x2f,0xb4 +.byte 0xb1,0xb1,0x42,0xe8,0x88,0x75,0x9f,0xb4,0xc1,0xdf,0x44,0xf9,0x4f,0x9a,0xf7,0x3d,0x35,0xc5,0x32,0xbe,0x43,0xd0,0x0d,0x71,0x4e,0x21,0xbf,0x31,0x99,0x73,0x5a,0x84,0x45,0x2e,0x00,0x8b,0x42,0x2b,0x14,0x86,0x51,0xcb,0xa0,0x98,0xa9,0x68,0x8d,0xdb,0x58,0x3d,0x73,0x9d,0xf9,0x2d,0x86,0x76,0x62,0xcb,0x93,0x29,0x48,0x92,0x38,0xfb +.byte 0xeb,0x1d,0xda,0xc3,0x10,0x1f,0x32,0x68,0xee,0xcb,0xb7,0x8a,0xcb,0xcb,0xe0,0x37,0x31,0xe8,0xad,0x7b,0x4a,0x29,0x2c,0x10,0x9e,0xdf,0x86,0xeb,0x13,0x0c,0xab,0xa4,0x30,0x36,0xf0,0xe0,0xac,0x14,0x41,0xa4,0xf4,0xf8,0x44,0x95,0xe8,0x8f,0x28,0xc2,0x35,0x0a,0x44,0x61,0xc7,0x60,0xc5,0x3b,0xc4,0x1d,0x67,0xfd,0xac,0x0b,0x2e,0x49 +.byte 0x62,0xea,0x17,0x3c,0xf5,0x4b,0xbe,0xba,0xba,0x42,0x02,0x0d,0x13,0xf1,0x15,0xff,0x2e,0x47,0x46,0xd1,0x27,0x64,0xb7,0x35,0x28,0x31,0xb5,0xde,0x1e,0xf9,0x26,0x6c,0x04,0x3c,0x0e,0x06,0x9d,0x4d,0xc7,0x1c,0x97,0x67,0x2c,0x6d,0x36,0x0d,0x4c,0x61,0x08,0xe9,0xbd,0x04,0x1d,0x8d,0xfb,0x0c,0x03,0x3d,0xb4,0x40,0xd5,0x1b,0x69,0x3b +.byte 0x68,0xcf,0x46,0x27,0xcf,0xb3,0xda,0x1e,0xdc,0x85,0x6f,0x4f,0x6b,0x09,0x9d,0xe9,0x6c,0x73,0x40,0x27,0xc9,0x8b,0x12,0x97,0xea,0x34,0xd7,0x51,0x32,0x90,0x4e,0xd7,0x91,0x41,0x3a,0xee,0xbc,0x97,0xb0,0x4a,0x39,0xdb,0xe3,0xe5,0x12,0x73,0xbf,0x5d,0x68,0xe0,0xc6,0x7c,0x6f,0x0d,0x14,0x1c,0xaa,0xde,0x29,0xb7,0xc7,0xa5,0x90,0x62 +.byte 0xe9,0xc5,0x75,0x16,0xe6,0xc0,0x9d,0xc5,0xb8,0xd6,0xfa,0xb0,0x72,0xb7,0x27,0xa6,0xa8,0x3f,0xbf,0x18,0x8b,0xaa,0x94,0xb3,0x47,0x50,0x2f,0x1c,0x49,0xab,0x46,0x38,0x7f,0x3e,0xf3,0xf1,0xb8,0xb3,0x44,0xaa,0x1f,0x76,0xb4,0x67,0xff,0xcf,0x7c,0x4b,0xa9,0xe1,0x62,0x93,0x4d,0x3e,0x96,0xdb,0x56,0xf6,0x26,0x5d,0x95,0x4c,0xfa,0x5f +.byte 0x06,0x2b,0x5c,0x33,0x2d,0xf8,0xfa,0x68,0x8a,0xed,0x28,0x2a,0x6e,0x95,0x86,0x59,0x71,0xef,0x86,0x47,0x60,0xec,0x35,0x79,0xa9,0x98,0x2d,0x6e,0x20,0x26,0x3a,0x21,0xec,0x59,0x15,0x65,0xcd,0xb9,0x91,0x19,0x6e,0x74,0x89,0x3b,0x10,0x00,0xab,0x8a,0x45,0x23,0x20,0x94,0x03,0x02,0x77,0xb7,0xcf,0x9c,0x71,0x18,0x0c,0x5b,0x40,0x62 +.byte 0x3b,0x8f,0xc9,0xf6,0x4c,0x8f,0x60,0x66,0x05,0x87,0x05,0x90,0xd4,0x08,0x76,0xd7,0xa3,0xb6,0x37,0xa8,0x83,0x05,0xb2,0x48,0xe9,0x24,0xc4,0xfb,0x79,0xa1,0xce,0xac,0x29,0x13,0x4e,0x72,0xdf,0xad,0x9e,0x5b,0xcd,0x9c,0x39,0x1d,0x3e,0x57,0x9d,0xf2,0x96,0x13,0xa4,0x79,0x4c,0x76,0x40,0x03,0xb3,0x18,0xcf,0xd7,0x45,0x2a,0x2d,0x07 +.byte 0xe5,0x2e,0xb7,0x74,0xda,0x94,0xea,0x32,0x74,0xb0,0xca,0xf4,0xd1,0x09,0x97,0x3c,0x69,0x17,0xf6,0x5b,0x13,0x7b,0xb8,0xb1,0xd9,0x0e,0x12,0x44,0x29,0xea,0x26,0xd8,0xaa,0x9d,0x26,0x87,0x0c,0x89,0x4e,0xec,0x29,0x48,0x43,0x66,0x21,0x0b,0xab,0xce,0x40,0x57,0x4c,0xa7,0xdd,0x56,0xde,0xac,0x5c,0x62,0xea,0xc4,0x54,0x4a,0xe0,0x8d +.byte 0x54,0xc8,0x65,0x44,0xcc,0x6f,0x2a,0xcd,0x0e,0xb3,0xad,0xa3,0x30,0xd1,0xb7,0x19,0x70,0x51,0xd3,0x9a,0xcf,0xe5,0x42,0x6c,0xa1,0xc1,0x0f,0xe2,0xda,0x86,0xb4,0x51,0x50,0x62,0xdc,0x51,0x3f,0xd2,0xff,0xde,0x7f,0x38,0x5a,0xff,0x2d,0x21,0x1d,0x59,0xb9,0xdd,0xde,0x83,0x13,0xb0,0x25,0xf5,0xbb,0x11,0x47,0x4a,0xaf,0x81,0x15,0xa0 +.byte 0x39,0x5b,0x30,0x17,0x2b,0xbf,0x5a,0x03,0x60,0xb6,0xbb,0x86,0x9f,0x50,0x45,0x15,0x0b,0xba,0x42,0xf4,0x3d,0x05,0x62,0xcd,0x9b,0x8c,0xcf,0x93,0x5c,0x33,0x6c,0xea,0x4b,0xd0,0x1d,0x91,0x3e,0xbf,0xa4,0x9d,0x7c,0x2c,0x87,0x9c,0x42,0x9f,0x03,0x98,0x03,0x1b,0x98,0x66,0x4f,0x8f,0x29,0x12,0xc5,0xb5,0xec,0x81,0xf8,0xb2,0x5e,0x44 +.byte 0x4f,0xb0,0x31,0xe4,0x2a,0x73,0x83,0xac,0x5a,0x3f,0xfa,0xcf,0x8b,0x7c,0xa3,0xf1,0x01,0x14,0xa1,0xca,0x60,0x8d,0x6a,0x6c,0x04,0x31,0xcc,0xba,0x12,0xe0,0x4e,0xaf,0x01,0x8d,0xf5,0x60,0x23,0x79,0x8a,0x80,0xcc,0x32,0x31,0x69,0x83,0xb6,0x83,0xaa,0xd9,0x3b,0x86,0x4a,0xd8,0x10,0x28,0x09,0x82,0x36,0xee,0x6a,0xc0,0x80,0x3f,0xfd +.byte 0xb1,0xd2,0xde,0x34,0xf9,0x4c,0x87,0x5b,0xdd,0xd0,0xb6,0x2d,0x99,0x69,0xd3,0x2c,0xb7,0x0b,0xfc,0x16,0x88,0x7b,0x80,0x21,0xbc,0x30,0x7b,0x56,0xe5,0x7b,0x41,0x43,0x4d,0xaf,0x40,0x5e,0x74,0x14,0x17,0x66,0x32,0xd6,0x81,0x53,0x94,0x35,0xf0,0x0f,0x4f,0x99,0x54,0x9a,0x38,0xc0,0x2a,0xa9,0xd3,0x53,0xdd,0x9a,0xc5,0x29,0x18,0x62 +.byte 0xf6,0x93,0xa3,0x02,0xf0,0x13,0xcb,0xcb,0xcc,0x64,0x0b,0x00,0xf4,0x43,0x03,0x26,0xe6,0x2f,0x39,0xa1,0x83,0xea,0x94,0x2f,0xde,0x61,0xbd,0xe1,0xbe,0x08,0xf8,0xd4,0x01,0x6e,0x61,0x98,0x01,0x39,0x4b,0x93,0x39,0x38,0x34,0x58,0x24,0xc1,0xf5,0x03,0x05,0x15,0x9c,0xf0,0x30,0x20,0x24,0xd4,0x7e,0x73,0xb2,0x60,0x06,0x3b,0xd3,0xb7 +.byte 0x2c,0x47,0x17,0xc4,0x79,0x4e,0x45,0x0b,0x89,0xf0,0xfc,0x42,0xa0,0x0d,0x80,0xd2,0x44,0x36,0x70,0xaa,0x9e,0x72,0x85,0xa8,0xc8,0x1d,0x35,0x28,0xc3,0x5a,0x72,0x4c,0x06,0x6d,0xf4,0xae,0x54,0x86,0x9a,0x32,0x3c,0xa5,0x06,0x63,0xc1,0x37,0xbb,0xaf,0xa6,0xae,0xce,0x94,0xea,0x9c,0x4a,0x9e,0x56,0xb1,0xc3,0x84,0x84,0xef,0x3d,0xe9 +.byte 0x24,0xf4,0xbf,0xc3,0xf6,0x45,0x74,0x4e,0xbb,0x86,0xd3,0x7f,0xab,0x19,0xe3,0x63,0x67,0x81,0xb6,0x18,0xc8,0x78,0x8e,0xf8,0x83,0x5f,0xfb,0x2e,0x49,0x97,0x2b,0x34,0xbb,0x76,0x2e,0x93,0xec,0xe9,0x7f,0x4d,0x7e,0x52,0x0c,0x92,0xbc,0x6d,0x3a,0x34,0x9b,0x5e,0x61,0x6f,0xea,0x45,0xe7,0x5c,0x34,0x6b,0xcb,0xc0,0x31,0x61,0x64,0x9d +.byte 0xad,0x7f,0x98,0xca,0xfe,0x3d,0xad,0xf7,0x21,0xf6,0x4c,0x2a,0x21,0x07,0x80,0x25,0xa2,0xea,0x26,0x85,0xc3,0xb1,0x74,0x04,0x7f,0xd1,0x1c,0x1b,0xa5,0x7e,0x96,0x45,0xfe,0x6f,0xa6,0x34,0xdf,0x94,0x1f,0x7e,0xfb,0xcf,0xfd,0x29,0xeb,0x3a,0xb0,0xfc,0xb6,0xd5,0x80,0x8b,0x37,0x71,0xfb,0x70,0x19,0x30,0xc4,0x6f,0xa0,0x5b,0xae,0x5b +.byte 0x75,0x51,0x98,0x89,0x9e,0xf0,0xf5,0x79,0xaf,0x1c,0x07,0xb6,0x5e,0xcf,0x34,0x70,0x0f,0x0b,0xbc,0x0a,0xa6,0x40,0xc7,0xf8,0xe4,0xef,0xe6,0xb7,0x94,0x6e,0x98,0x75,0x22,0x73,0x5c,0xca,0xcc,0xfb,0x09,0x2f,0x9c,0xfe,0x49,0x0f,0xd3,0x65,0xfe,0xd4,0xf0,0x9b,0xeb,0x8c,0xd7,0x8c,0xff,0x4b,0x18,0x3e,0xf3,0x9d,0x3f,0xf5,0x83,0xd6 +.byte 0x1d,0x3d,0x23,0x79,0x0f,0xae,0x17,0x62,0x33,0x07,0xc3,0xac,0x98,0x07,0x72,0x9b,0xd9,0x26,0x5c,0x1a,0x9d,0xf1,0x35,0x92,0xf9,0x38,0x17,0xf8,0xee,0x26,0xf9,0x64,0xfc,0x5e,0x8b,0x80,0xce,0xdb,0x64,0xf7,0xde,0x20,0x19,0x5c,0x26,0xf6,0x23,0xd6,0x99,0x8e,0x75,0x77,0x3d,0x17,0x0f,0xea,0x31,0x5a,0x65,0x32,0x1b,0x78,0x78,0xe4 +.byte 0xfe,0x76,0xf8,0xa7,0x81,0x34,0xf1,0x2a,0x13,0x22,0xe4,0x8a,0xe1,0x42,0x5a,0x3f,0x44,0x22,0xeb,0x7e,0xcd,0x20,0xcd,0xf7,0x44,0x1a,0x87,0xb9,0x7a,0x0e,0xf8,0xcb,0xb5,0x0a,0x1f,0x6a,0xe6,0x0b,0x70,0x59,0x38,0xa3,0x6b,0x64,0x7b,0x61,0xfe,0xbd,0xa4,0xb7,0x89,0x7a,0x28,0x70,0xfe,0x9d,0x64,0x2c,0xe9,0xc4,0xc9,0x2f,0xc8,0x3e +.byte 0xfa,0x70,0xce,0x21,0x9b,0xa8,0x10,0x6a,0x16,0xdd,0x28,0xce,0x4e,0xd4,0x6c,0x8c,0x47,0x83,0x13,0x8b,0xec,0x1c,0x76,0xdc,0x4d,0x81,0x25,0x08,0xd8,0xf9,0xde,0x66,0x1d,0xe2,0xf3,0xe7,0xdc,0x3e,0x3c,0x6b,0x98,0x25,0x55,0x88,0xe8,0xda,0x7f,0x16,0xe5,0x7d,0xad,0x8a,0x36,0x00,0xf0,0x68,0xc5,0xe4,0xfc,0xe9,0xe3,0x54,0xeb,0x4c +.byte 0xd1,0xff,0x07,0x1a,0x5c,0x5e,0xd4,0xb1,0xff,0x7d,0xfc,0x5b,0x34,0x42,0x95,0x89,0x01,0x24,0x8e,0x30,0xec,0xfe,0x67,0xf8,0xe2,0xaa,0xd5,0x6a,0x9f,0xe3,0xc3,0xa5,0x53,0x7f,0xd3,0xf4,0x98,0xa5,0x47,0x11,0xad,0xac,0xea,0xba,0x20,0x34,0x03,0x65,0x8c,0xec,0xb6,0xa3,0x2b,0xf6,0x93,0xe1,0xc8,0xad,0x34,0x30,0x8f,0x0e,0x3b,0xf6 +.byte 0x63,0xc6,0x58,0xc3,0xe8,0xa3,0x85,0xf8,0x24,0x8e,0x21,0xb9,0x36,0x7c,0xe0,0x11,0x64,0x31,0x6a,0x6a,0xa2,0xad,0xd3,0x94,0xbb,0x13,0x5b,0xb4,0xe9,0xee,0x09,0xdc,0xfe,0xb2,0xad,0xa8,0x43,0x02,0xba,0x85,0x1f,0x56,0xcb,0xb5,0x95,0x32,0xcc,0x7e,0xe0,0x00,0xde,0xfa,0x3f,0x91,0x71,0xde,0x21,0x19,0xff,0xc9,0x97,0x43,0x95,0xd8 +.byte 0x0d,0xc2,0x8a,0xde,0xcc,0x34,0x48,0xf4,0x35,0x41,0xb8,0x56,0x52,0xce,0x06,0xb3,0xcf,0xd4,0xae,0x7a,0xcb,0xe9,0xed,0x37,0xd6,0x76,0xa0,0x77,0x04,0xfb,0xb7,0x41,0x25,0x38,0xe1,0xd1,0xb5,0xde,0x21,0xe0,0x64,0xd8,0x83,0x13,0x7b,0x4b,0xb8,0xc9,0x12,0x02,0x51,0x56,0x52,0xe9,0x1c,0x49,0x48,0x83,0xd0,0x99,0x73,0x60,0x4a,0x4c +.byte 0x7d,0x8d,0x43,0xf9,0x06,0xa4,0xbb,0x0e,0xb6,0xdd,0x5f,0xc7,0x5e,0x35,0xcb,0xa0,0xc1,0x66,0x4a,0xe3,0x4a,0xa9,0xec,0xa4,0x5a,0xd7,0xd6,0xea,0xa5,0x20,0xa6,0xc3,0x1b,0xc0,0xa8,0xd1,0xf1,0x08,0x05,0xab,0x40,0x14,0x35,0xf2,0xdd,0x0f,0xc5,0xda,0xb3,0xa6,0xb1,0x07,0x36,0x17,0x5d,0xe9,0x96,0x23,0x96,0x46,0xd4,0xa7,0x71,0x64 +.byte 0x13,0x72,0x4e,0x83,0xe0,0x65,0x40,0x41,0xaf,0xb6,0x5b,0x00,0xa2,0xab,0x09,0x7f,0xa5,0xd5,0xc2,0xd9,0xc0,0x68,0x2a,0x44,0xdc,0x43,0x37,0x81,0xb8,0x88,0x4c,0x85,0x1b,0xb1,0x83,0xb2,0x56,0xa3,0x91,0x0f,0xa6,0x70,0x3f,0xbd,0xe9,0xda,0x40,0x9b,0xf5,0x9e,0x53,0xed,0x5f,0x84,0x70,0xd2,0x4c,0x1c,0xb6,0x87,0xd6,0xbb,0x3b,0xec +.byte 0xe5,0x35,0x1b,0x2c,0x9b,0xf1,0xe5,0xf8,0x0e,0x07,0x98,0xcc,0x58,0x38,0x57,0x74,0xdb,0x0e,0x08,0xd9,0x56,0xe8,0x08,0x63,0x3d,0x94,0x4a,0xdc,0x59,0xfc,0x3d,0xc1,0xa4,0x36,0xc3,0xe8,0xbe,0x4b,0xd7,0x47,0x69,0x33,0xb8,0x72,0x30,0x59,0x28,0x4e,0xf1,0xc1,0x25,0xa3,0xa4,0xe3,0x12,0xcf,0x31,0xf6,0xf8,0xae,0x31,0x06,0x76,0x92 +.byte 0x64,0x87,0x8e,0xb0,0x9f,0x1d,0xf4,0x56,0x73,0xc5,0x5d,0xbb,0x80,0x0d,0x19,0x3f,0x56,0x8c,0xe4,0xd6,0x8a,0x9a,0x62,0x26,0x4e,0x8a,0x21,0x7d,0x72,0x34,0x87,0xb6,0x7e,0x49,0xdc,0xfd,0x27,0x95,0xba,0x25,0xdd,0xf4,0x58,0x2b,0x11,0x3f,0xd1,0xd7,0x13,0x1d,0xb0,0xec,0xe2,0x55,0x5e,0x72,0xea,0x36,0xc9,0xd8,0x61,0xc0,0xee,0xc4 +.byte 0x9f,0x35,0x7e,0x73,0xd3,0xf6,0xd7,0x6a,0xce,0xd6,0xd2,0x80,0xe6,0x10,0x4b,0x65,0x18,0x6f,0xab,0xd3,0x41,0xbb,0x39,0x36,0x95,0x84,0x3c,0x99,0x9a,0xfd,0xf0,0xa3,0x46,0xdf,0x48,0x7c,0xd5,0x57,0x9d,0x10,0x59,0xca,0x70,0xc4,0xb5,0xbe,0x47,0x9e,0xca,0x2b,0x49,0x54,0xbb,0x34,0x8e,0x39,0xf4,0xf8,0x8c,0xa5,0xa1,0xab,0xf6,0x51 +.byte 0xd8,0x22,0x9a,0xd5,0xc2,0x12,0xf8,0x26,0xc6,0x19,0x2a,0xa6,0x6e,0xab,0xd3,0xac,0xd1,0x21,0x97,0x67,0x3e,0x39,0x90,0x5c,0x37,0x65,0x7b,0x06,0x54,0x1a,0xb8,0x2a,0x56,0x02,0xa3,0x92,0xee,0xf3,0x38,0x53,0x25,0x4d,0x5d,0x0a,0x37,0x9e,0xbb,0xf4,0xb2,0x13,0x77,0xbb,0x93,0xa9,0x85,0xf2,0x15,0xfd,0x71,0x17,0x00,0x89,0xe7,0x7b +.byte 0xa9,0xdc,0x10,0xd9,0xc7,0x44,0xa5,0x7b,0x3f,0x2f,0x1e,0x6d,0xa7,0xfe,0x0c,0x0e,0x83,0x3e,0x38,0x27,0xa7,0x4e,0x85,0x3c,0x84,0xfe,0x95,0x48,0x85,0x09,0x75,0x62,0x1d,0xa4,0x64,0x54,0xed,0x89,0xd5,0x28,0x62,0x52,0x18,0xef,0xf0,0x57,0x05,0x30,0xf0,0xce,0x87,0x05,0x0d,0x81,0xe8,0x2a,0x3c,0x8c,0x22,0xe1,0x4b,0x32,0x42,0x9d +.byte 0x02,0xc5,0xe4,0x6a,0xa4,0x4d,0x9b,0xc4,0x82,0x47,0xdc,0x61,0xbd,0x82,0x01,0xcd,0x5e,0x64,0x9f,0x4c,0xe3,0x31,0xe9,0x48,0x53,0x85,0x07,0xc7,0x47,0x49,0x35,0xd8,0x6a,0xab,0x4f,0x73,0x3f,0xd3,0xde,0x87,0x29,0xac,0xbc,0x35,0x0a,0xb4,0x74,0xc2,0xa7,0x0b,0xb1,0x93,0x92,0x29,0x3b,0x3e,0xa8,0xde,0x12,0x49,0x75,0xda,0x16,0x27 +.byte 0x52,0x2f,0x93,0x23,0xd6,0xf7,0x10,0xfe,0x1e,0x93,0x97,0x06,0x9d,0xef,0x4f,0xe4,0x3d,0x5d,0xde,0x30,0x70,0x3d,0x78,0x3a,0x30,0x00,0x9b,0x77,0x12,0x90,0x62,0xda,0x32,0x9b,0x6a,0x47,0xd7,0x0f,0xee,0x75,0x18,0xdd,0x4d,0x8a,0xe2,0x35,0x5b,0x60,0xb8,0xf9,0xa4,0x6c,0x93,0x3e,0x47,0x23,0xed,0x7a,0xe2,0x58,0x42,0xd6,0x3f,0x90 +.byte 0xc0,0x12,0x38,0x8b,0x70,0xe0,0xf8,0x1a,0xb5,0x8d,0xe1,0x39,0xdf,0x93,0x25,0x72,0x2e,0xa9,0x3f,0x58,0x12,0x40,0xc4,0x92,0x46,0x08,0xf0,0x64,0xdd,0x34,0x42,0xfe,0x74,0x35,0x0c,0xda,0xef,0x06,0x0b,0x33,0x59,0xd9,0xee,0x4c,0xf9,0x02,0x3a,0x93,0x40,0xa3,0x99,0x0e,0x64,0x11,0x2f,0x52,0x9d,0x28,0x4d,0xe8,0x45,0xd0,0x22,0xd7 +.byte 0x8f,0xd6,0x28,0x8c,0x0e,0x18,0x87,0x24,0xf9,0x88,0xd2,0xc0,0xe8,0xd4,0x9d,0xa2,0x5a,0x79,0x83,0x37,0x18,0x84,0x12,0xca,0xc7,0x10,0xd5,0x5a,0xa8,0xe5,0xa8,0xe7,0x79,0xb6,0x2c,0xb3,0x90,0x6c,0xc5,0xa4,0x99,0x1b,0x85,0x29,0x78,0x0b,0x09,0x77,0x05,0xf4,0x23,0x79,0x5c,0x91,0xf3,0xe0,0xe4,0x6f,0x82,0x33,0x4e,0xa2,0x2e,0xa2 +.byte 0x65,0x79,0xad,0x98,0x36,0x34,0x72,0x97,0xd7,0x39,0x89,0x5e,0x82,0x9f,0x4c,0xe2,0xea,0x51,0x85,0x62,0x0c,0x39,0xf6,0xdc,0xc6,0x80,0x48,0xcf,0x98,0x93,0x64,0x7d,0xf9,0x63,0xf4,0xf5,0x18,0x2a,0xb6,0x04,0xb7,0x44,0xc4,0x60,0xc0,0xcf,0x3d,0x88,0xa8,0xb6,0x81,0xa3,0x99,0x2a,0xf0,0x1a,0x8d,0x76,0x20,0x1d,0xcc,0x10,0x50,0x58 +.byte 0x09,0xf9,0xda,0x65,0x60,0xc3,0xb1,0xc1,0xc0,0x4d,0x62,0x52,0x22,0x45,0x32,0xbc,0x11,0x93,0x15,0xb6,0x25,0x8f,0x65,0xa0,0x4c,0x88,0xc9,0x83,0xe1,0x5c,0xbb,0xfb,0x1a,0xab,0xdb,0x35,0x40,0x66,0xc0,0x2f,0xdc,0xf5,0x92,0x08,0x4c,0xc7,0xb8,0x49,0x05,0xe0,0xe1,0x61,0x2b,0xde,0xc7,0x6a,0x04,0x05,0x4d,0x9f,0xe9,0x59,0x22,0x56 +.byte 0x63,0x77,0x9d,0xe3,0x1e,0x36,0xdf,0x87,0x4a,0xeb,0xba,0x42,0x3d,0x1b,0xa5,0xd0,0xc5,0x44,0x07,0xbe,0x37,0x37,0x70,0x10,0x2d,0x02,0x9b,0xf6,0x52,0xf3,0x54,0x6d,0x50,0xdb,0xdb,0x57,0x01,0x0b,0x9b,0xd5,0x99,0x99,0x69,0x9b,0x10,0x76,0x48,0xea,0x28,0x27,0x06,0x30,0x63,0x3b,0xdf,0x06,0x30,0x37,0x28,0x75,0xcf,0x9c,0xe7,0x52 +.byte 0x43,0xe2,0xd5,0x7b,0xfa,0x88,0x98,0x9c,0x3e,0x27,0x30,0x21,0xcc,0x11,0x71,0x14,0x24,0x04,0x1a,0x8c,0xe9,0xfe,0x2f,0x9d,0xec,0xb1,0x10,0x33,0x05,0x31,0x01,0x1b,0xde,0x6b,0x30,0x20,0x6d,0xf4,0x7c,0xbf,0x41,0x04,0x5f,0xb9,0x9c,0x24,0x63,0x74,0x98,0x3e,0x60,0xc7,0xf1,0xb1,0xc6,0x94,0xf3,0x6f,0x95,0x24,0xdf,0x97,0xd5,0xc7 +.byte 0x50,0x19,0xaf,0xa5,0xae,0x51,0xde,0x6d,0x44,0x0c,0x90,0x72,0x11,0x82,0x04,0xf9,0xda,0x17,0xd8,0xf3,0x03,0xf2,0x03,0x3f,0x65,0x7f,0xd7,0x66,0x84,0x9a,0x02,0x90,0x2b,0x65,0x00,0xd9,0x9c,0xfb,0xaa,0xe2,0xde,0x5f,0x1e,0x19,0x1e,0x6d,0x20,0x1e,0x01,0xf1,0xca,0x7b,0x90,0x06,0x96,0x1d,0x7a,0x34,0x0c,0x66,0x57,0xd7,0x61,0x1f +.byte 0x74,0x03,0xcb,0xae,0xea,0xaf,0x65,0x8e,0x32,0xbe,0xb8,0xe6,0xd8,0x6d,0xf7,0x51,0x6d,0xec,0x7e,0xc6,0x9d,0x20,0x01,0xbf,0xd7,0xbc,0xcb,0x34,0x7c,0xe5,0x1f,0x92,0x72,0x2f,0x6f,0xa3,0x1f,0xe8,0x4d,0x7e,0xa5,0x85,0x3b,0xed,0xc7,0x25,0x53,0xe3,0x77,0x90,0x1f,0xda,0xb7,0x48,0x7d,0xbe,0x20,0x48,0x9f,0xb4,0x05,0x5d,0x41,0xc5 +.byte 0x48,0xd0,0xc9,0x83,0xbe,0xf8,0xd8,0x6b,0x0d,0x26,0x66,0x2e,0xef,0x6b,0x13,0x58,0x6b,0x5f,0x0e,0x8b,0x4e,0x57,0xb2,0x6b,0x3d,0x4d,0xcd,0xcb,0x9a,0x9b,0xda,0x4d,0x7f,0xea,0x17,0x06,0x7f,0xcd,0xaf,0x18,0xda,0x3d,0xf0,0x30,0x2e,0xbb,0xc2,0x1d,0xcf,0xde,0xf7,0xee,0xda,0xd6,0x3d,0x75,0xcf,0x19,0xcf,0xfc,0xdf,0x7a,0xb6,0x1f +.byte 0x89,0xf5,0x0c,0xe9,0xd5,0xf1,0xd0,0x40,0xbd,0xae,0xb5,0x16,0xf6,0x05,0x1e,0xba,0xcd,0x18,0x80,0x4a,0xb3,0x87,0x93,0x6b,0x19,0xfc,0x47,0xa8,0x45,0x4b,0x75,0xe8,0x06,0xc0,0xbd,0x86,0xf7,0xcf,0x2c,0x39,0xc6,0x0b,0x3f,0x32,0xcd,0x1c,0x02,0xec,0x4b,0xd5,0x90,0x84,0xaf,0xc9,0x5c,0x9e,0x64,0x82,0x13,0x81,0x05,0x03,0xe4,0xed +.byte 0x48,0x23,0xc3,0x53,0x2c,0x5a,0x22,0x0a,0x27,0x7e,0x55,0x79,0xdc,0x46,0xf5,0x4b,0x04,0xcc,0x43,0x87,0x6c,0xb5,0xa4,0x2d,0x78,0x70,0x02,0x43,0x0e,0x76,0x62,0x99,0x86,0x40,0x2a,0xe4,0x62,0xe6,0xee,0x4e,0x03,0x64,0x83,0x9c,0x38,0x6d,0x62,0xa6,0x85,0xb8,0xce,0xd7,0xf8,0xcb,0x78,0x00,0x7a,0x48,0x72,0x75,0x4e,0x9c,0x6f,0x0c +.byte 0x61,0xc7,0x93,0x4e,0x6d,0x65,0xa3,0x1b,0x17,0x84,0xc6,0xd2,0x29,0xc3,0x4d,0xe3,0x14,0x21,0x5f,0x9e,0xa9,0x28,0x11,0xf3,0xb2,0xe8,0xe7,0x60,0x9e,0x24,0xab,0x88,0x9c,0x9c,0x5e,0x17,0xe4,0xe1,0xa7,0x74,0xb4,0x82,0xd5,0xaa,0x92,0x08,0xa7,0xa2,0x04,0x6f,0x77,0x14,0x54,0x44,0x5d,0x13,0x10,0xa2,0x40,0x1d,0xf0,0x44,0x16,0x17 +.byte 0xda,0x8c,0x80,0x83,0x2b,0x19,0xb8,0xab,0xf2,0xb8,0xb1,0x92,0xb5,0xc5,0x05,0x3e,0xd2,0x1a,0xfc,0xfd,0x21,0xa6,0xb2,0xbd,0x89,0xee,0x9c,0x3c,0x90,0xd9,0xf1,0xd2,0xe8,0xc3,0x21,0xb9,0x0e,0x0c,0x98,0xbc,0x5e,0xa1,0x0d,0x89,0xfe,0x0f,0x3c,0x45,0xea,0xe1,0x6e,0x06,0x59,0xff,0x79,0xf4,0x7e,0xf4,0x82,0xc0,0x6b,0xd9,0x53,0x30 +.byte 0x98,0xed,0x8d,0x6f,0x3d,0x0e,0xfb,0x42,0x66,0xab,0x41,0xa8,0x4a,0xef,0x73,0xa4,0x54,0x99,0x4f,0xb6,0x65,0x44,0xf9,0xd9,0x3c,0x6b,0x59,0x36,0xb0,0xe3,0x7c,0x4a,0x85,0x80,0x6c,0x77,0x6f,0x34,0x4e,0x9e,0x54,0xfd,0x0c,0x25,0x72,0xc3,0x5a,0xb6,0x3b,0xad,0x2b,0xd5,0x29,0x55,0x31,0xab,0x62,0xe4,0x15,0xed,0xef,0x16,0xef,0x43 +.byte 0xd5,0xdd,0x3d,0x64,0x8c,0x13,0xbc,0xcd,0x4d,0xfb,0x4f,0x86,0x3b,0x73,0x1e,0xc4,0xe8,0x54,0xb4,0xcc,0x49,0xba,0x4f,0x81,0xcd,0xe8,0x30,0x92,0x4b,0x57,0xd1,0x7c,0x0c,0x65,0x7d,0xe1,0x59,0xc6,0x8c,0x7d,0xad,0xd5,0xcf,0x6c,0xc4,0x9d,0xc5,0x3f,0x23,0x1f,0xb0,0x6d,0x1c,0x07,0xbf,0x38,0xc9,0x16,0xdc,0x5b,0x51,0xa1,0xdb,0x8f +.byte 0xf8,0x25,0xc6,0x4d,0xc0,0x4d,0xa1,0x02,0xd9,0xd3,0xb5,0x63,0xda,0xe1,0x91,0x60,0x71,0x39,0x46,0x1a,0x13,0xe0,0xf2,0xca,0xcc,0xd3,0xbb,0x6b,0xd0,0x64,0xaa,0x0e,0xc0,0x89,0xa3,0xc6,0x14,0x56,0xe4,0x44,0x97,0xa9,0xcc,0x17,0x68,0xe6,0xfc,0xe5,0xfd,0xf0,0xa6,0x69,0xcd,0xac,0x20,0xc7,0xeb,0x53,0x1b,0x4f,0xdd,0xd3,0xb0,0xed +.byte 0x30,0x4e,0x36,0x73,0x63,0xef,0x51,0x3e,0x9a,0x3e,0x41,0x2b,0x9c,0xda,0x67,0x96,0x46,0x33,0xe3,0x3f,0x87,0x01,0xd8,0xc5,0x26,0x80,0xe4,0x7e,0xf4,0x78,0x8c,0x2b,0x81,0x2a,0x01,0x7c,0xe3,0xfc,0x8d,0x6b,0xdc,0x84,0xb9,0xff,0x43,0x37,0x57,0xce,0x3f,0x5e,0x63,0xd3,0xbe,0xb6,0x4a,0x31,0xbf,0xb8,0x74,0x64,0x9c,0xf3,0xc5,0x8a +.byte 0xae,0xe8,0x5f,0x68,0xcf,0xce,0xff,0x3f,0xc5,0xb5,0xfd,0x13,0x08,0x11,0x9d,0x1a,0x0f,0x06,0x08,0x4d,0x7c,0xf9,0xd4,0x20,0xdf,0x82,0xf9,0x86,0xfc,0xf3,0x67,0xa0,0x14,0x99,0xe5,0x47,0xf0,0x02,0x7b,0x16,0xca,0xcf,0xb9,0x0f,0x68,0x08,0x5d,0x1d,0x65,0xee,0x23,0x56,0xeb,0x11,0x5b,0xca,0xf1,0xa7,0xad,0x50,0xb2,0xd1,0x37,0x65 +.byte 0xe9,0x7e,0xf6,0xe9,0x64,0x42,0x49,0x80,0x40,0x17,0xe3,0x43,0x00,0xda,0xe1,0x7a,0x1c,0xb3,0xde,0xd9,0xf7,0x33,0xeb,0xb3,0xb8,0xf5,0x40,0x1b,0xcd,0x71,0x97,0x30,0xf9,0x9c,0x4d,0xac,0x7e,0x8e,0xd9,0x36,0x92,0x39,0xb5,0x56,0x0f,0x4f,0xbf,0x58,0xb8,0xba,0xc3,0xbd,0x79,0xb0,0xd7,0x6c,0x45,0x49,0xe2,0xde,0x94,0x04,0x9d,0x3e +.byte 0x91,0x0a,0xb2,0x9b,0x90,0x57,0x2e,0x69,0xa4,0x4f,0x61,0xbf,0xdb,0xfb,0xe3,0xe9,0x81,0x26,0xe0,0x48,0x90,0x8c,0x32,0x95,0x8d,0x38,0xec,0x8e,0xa7,0x5e,0xc3,0x36,0xc6,0xd1,0xbc,0x9a,0xb3,0xba,0xdb,0x2c,0xe4,0xa0,0x50,0x74,0xef,0x98,0x48,0x14,0xc9,0x38,0x4d,0xa9,0x48,0x13,0xd4,0x08,0x60,0xfd,0xcf,0x5e,0xf2,0xcd,0xc7,0xeb +.byte 0xaf,0x88,0x32,0x30,0x6f,0x19,0x01,0xec,0x87,0xae,0x6d,0x63,0xa3,0xa7,0x7b,0xcd,0x53,0xa7,0xf2,0xf2,0x9f,0x43,0xcb,0x0a,0x3f,0x8c,0xd2,0x55,0x8d,0xa7,0x95,0xcf,0x5b,0xae,0x64,0x23,0xda,0xb4,0xbd,0x32,0x34,0x95,0x8a,0x03,0xe7,0x6e,0xef,0x3f,0xb4,0xcf,0xc6,0x8a,0x2f,0xc6,0x59,0x99,0xdf,0xad,0x3c,0x15,0xed,0x83,0x0b,0x59 +.byte 0x8b,0xcd,0x0d,0xa6,0xcf,0x3a,0xc3,0xdb,0xc3,0x01,0xa9,0x32,0x38,0x45,0x5c,0xc8,0x56,0x81,0xef,0x21,0x7f,0x52,0xc4,0xb5,0x48,0x97,0x6a,0x60,0x75,0x3a,0x1a,0xd3,0xb0,0x60,0x9a,0x83,0x61,0xad,0x3b,0x4b,0x65,0xaa,0x9e,0x77,0x47,0x6f,0x3b,0x48,0xb0,0xc6,0x36,0x9a,0x59,0x5e,0x26,0xc4,0xb9,0xed,0x04,0xf3,0xc7,0x09,0x33,0xda +.byte 0x81,0x63,0xa6,0x5d,0xe1,0x54,0x6b,0x04,0x17,0x2b,0xb9,0x2f,0xbd,0x55,0xdb,0xa1,0x69,0x00,0xcd,0xba,0xfa,0x36,0xaa,0x47,0x5a,0x7c,0xf4,0x1f,0x53,0x94,0x95,0x2f,0xf8,0x2a,0x4b,0xa8,0xcc,0x73,0xab,0xfd,0x25,0xb2,0x4e,0xd6,0x62,0x90,0x8c,0x8f,0x02,0xe4,0xdc,0x22,0x79,0x04,0x34,0x9b,0x54,0x5c,0x54,0xca,0x9b,0x8a,0xf8,0x05 +.byte 0xd1,0xb0,0x9e,0x8f,0xa3,0x0b,0x53,0xa8,0x6f,0x1b,0x2e,0xf2,0x71,0x78,0x28,0xce,0xa9,0xdb,0x4c,0x5b,0x83,0xfe,0xaa,0xff,0x99,0x2f,0x03,0x14,0xb2,0xe0,0x5f,0xaa,0x65,0x15,0x1f,0xd2,0x31,0x95,0x70,0x3c,0x8b,0x55,0x8e,0x87,0xed,0xbb,0x0c,0x91,0x87,0xaa,0xbe,0x49,0xdb,0x18,0x7b,0x1d,0x26,0xa7,0xdf,0x00,0xff,0x73,0x70,0x2e +.byte 0x10,0xaf,0x46,0xea,0x7f,0xca,0xfa,0x09,0x13,0x02,0xac,0x3f,0xa0,0x02,0xa6,0x67,0xb7,0xec,0x18,0x73,0x91,0x25,0xa0,0x28,0xe3,0xd8,0xfa,0x11,0x6d,0x34,0x79,0x1d,0xe4,0x8f,0x7c,0x73,0x66,0x77,0x3e,0x43,0x23,0xb0,0xee,0x84,0xb5,0x75,0xc9,0x23,0x87,0x6a,0x4f,0x59,0x3d,0xb5,0xf1,0xd6,0x06,0xf8,0xa6,0x5d,0x0c,0x24,0xed,0x94 +.byte 0xd7,0xa8,0x31,0x37,0x10,0x60,0xb6,0x03,0x33,0x27,0x38,0xdd,0xd3,0x74,0x02,0xa3,0xa6,0x01,0x94,0xa9,0x56,0x11,0x23,0x0e,0xdb,0xfd,0x25,0x92,0xa8,0xfb,0x79,0xc8,0x8e,0x0e,0x10,0x1f,0xca,0x95,0xf6,0xad,0x28,0xe7,0xaa,0x2b,0xf1,0x40,0xf6,0xef,0x7b,0x40,0x28,0x57,0xbb,0x4c,0xac,0x0b,0x8b,0xb3,0xe3,0xec,0x53,0xf2,0x15,0x61 +.byte 0x2e,0x91,0xdf,0x91,0xfb,0x55,0xb6,0x7f,0x6c,0xfc,0xb7,0x4b,0x91,0xdc,0xf7,0xe5,0x91,0xd8,0x70,0x92,0x94,0xea,0x3f,0x62,0x98,0x14,0xc3,0x43,0x34,0x02,0x87,0xc7,0xca,0x60,0x4a,0xfb,0x50,0xe4,0xa9,0x92,0x10,0x04,0x7c,0x55,0xd3,0x9a,0x89,0xba,0x8e,0x6f,0x02,0xd6,0xc7,0x6f,0x91,0xb5,0x87,0xb9,0x0e,0xbe,0xe4,0x9f,0x01,0x0b +.byte 0x20,0x60,0xc8,0x16,0xe6,0x23,0x1d,0x5f,0x4d,0x82,0xf4,0x42,0x25,0xe6,0x05,0xe3,0x5b,0xbb,0xd1,0xb0,0xad,0x0b,0x05,0x71,0x3a,0x7b,0xee,0x0e,0xe1,0xe4,0x08,0x9f,0xda,0xdf,0x59,0x57,0x4f,0x05,0x5a,0x51,0x9a,0x60,0xfd,0x85,0x21,0xd1,0x0a,0x3b,0x0a,0x15,0x61,0x28,0x98,0x0a,0x8f,0x1e,0x33,0x15,0xb3,0x5f,0xf3,0xbb,0x89,0x22 +.byte 0x0c,0xaf,0x91,0xce,0x44,0xb1,0x54,0xd0,0x80,0x86,0x43,0xa1,0xb9,0x07,0xde,0xab,0x1f,0x9b,0xae,0xef,0x07,0xf2,0x40,0x33,0x31,0x4d,0xf9,0x45,0x97,0xf6,0xcc,0xe5,0x3c,0x49,0xcd,0x83,0x6e,0x38,0x81,0xab,0x40,0x18,0xda,0xf6,0xfe,0xe7,0x96,0xd1,0x17,0x98,0xae,0xec,0xe9,0x93,0x37,0xbc,0x0b,0xa8,0x12,0xe7,0x65,0xca,0x27,0x37 +.byte 0x6a,0x74,0x81,0xf1,0xe0,0x6c,0x0d,0xba,0x86,0x48,0x94,0xd0,0x72,0xd5,0x4d,0x71,0xcf,0xa8,0x5e,0xd1,0x97,0xd1,0xed,0xf0,0xd3,0xe4,0xe3,0x41,0xc9,0x8f,0xfc,0x89,0xe8,0xbf,0x96,0x8b,0x86,0xb0,0x97,0x79,0x95,0xdf,0x69,0x56,0x6d,0x61,0x0a,0x37,0xcb,0x36,0xe1,0x95,0x88,0xf5,0xf0,0xe2,0x5c,0xb2,0x44,0x73,0xda,0x83,0xa7,0xdc +.byte 0x8b,0x35,0x3e,0xc1,0xd5,0x88,0x17,0x3b,0xeb,0xcf,0x36,0x9c,0xef,0x40,0xb2,0x72,0xde,0x4f,0x16,0x6c,0x8c,0x9d,0x15,0xce,0x7d,0x0d,0xc3,0x2f,0xea,0xab,0x50,0xdf,0x02,0xe0,0x24,0xcc,0xf4,0xa7,0x25,0xba,0x85,0x0d,0x62,0x9a,0x39,0xc7,0x5a,0xd1,0x9a,0xd1,0xa7,0x45,0x5f,0xc2,0x44,0xf5,0xa9,0x8d,0xd8,0xbc,0xd3,0xc8,0x75,0x0d +.byte 0x06,0xc6,0x4b,0x24,0xc6,0xe5,0x72,0xf7,0xd5,0x87,0xca,0x3c,0xc0,0x1c,0x18,0xa9,0x40,0xc6,0x7b,0xe5,0x4c,0xe6,0xb7,0x01,0x57,0xc1,0xcf,0x63,0x83,0x58,0x63,0x47,0xcf,0xa4,0xd3,0xf6,0x1d,0x2c,0xbf,0x17,0xe6,0x0a,0x7b,0x2d,0xa9,0x34,0x23,0xfc,0x1f,0x06,0x31,0x47,0x7b,0x31,0x34,0x8c,0x3c,0x15,0x9b,0xac,0xfd,0x38,0xe6,0xa3 +.byte 0x9e,0xa7,0xdf,0xa6,0x37,0x61,0xfd,0x85,0xb8,0x2e,0x67,0x73,0x7f,0x60,0x12,0x8b,0x62,0xb0,0x38,0xd0,0xaa,0xc4,0xad,0x3b,0xa9,0x04,0x66,0xdd,0xbb,0x9c,0xb1,0x95,0xe1,0x9c,0x0a,0x72,0x80,0x12,0xaa,0xa8,0x0c,0x3f,0x90,0x20,0x33,0xb4,0x76,0xdd,0x26,0xfe,0x1e,0x8f,0x6a,0x2d,0xea,0x4a,0xdc,0x28,0x47,0x66,0x36,0x5b,0x50,0x60 +.byte 0x7e,0x3e,0x93,0xf3,0xe9,0x37,0x31,0x3b,0x43,0x46,0x85,0xb3,0xa9,0xb2,0x14,0x95,0x96,0x49,0xf9,0x2a,0xe7,0x9e,0x3a,0x3e,0xd8,0x12,0xf7,0xbc,0x43,0x8c,0x35,0x31,0x44,0x08,0x7f,0x25,0x39,0x86,0x98,0x6a,0xe8,0xe3,0x2e,0x73,0x2d,0x3b,0xac,0x2d,0x75,0x4c,0xc8,0xca,0x21,0x2d,0x96,0x9b,0x4f,0x56,0xff,0x2d,0xc2,0xe2,0x98,0x3d +.byte 0xe2,0x3f,0xee,0x10,0xb7,0xc3,0x3d,0xa8,0x50,0x88,0x7f,0xd5,0x4e,0xbd,0xc7,0x9d,0xdc,0x01,0x49,0x27,0xf2,0xae,0xea,0x93,0x72,0xdf,0x00,0xcd,0xe6,0xa1,0xdd,0xd1,0x18,0xeb,0xa7,0xe1,0x4a,0x7b,0x38,0x72,0x73,0x29,0x46,0xa3,0xb3,0x25,0x23,0x6d,0x26,0xab,0x86,0xdc,0x67,0x52,0xe5,0x4a,0x5e,0x8f,0x16,0x67,0x8a,0x28,0x13,0xba +.byte 0x44,0x42,0xb5,0x21,0x9f,0x30,0x66,0x7f,0xc9,0x87,0x40,0xcb,0x75,0x58,0x2e,0xcd,0x09,0xb9,0x8a,0x84,0xa3,0xbd,0x63,0x53,0x75,0x2f,0x77,0x8b,0x7e,0x19,0x31,0x33,0x3b,0x9a,0xfb,0x86,0x39,0xa6,0xd9,0xeb,0x9b,0x43,0xc6,0xd9,0xc2,0x10,0xab,0x42,0xe5,0xc6,0x4a,0xe6,0x3e,0xde,0x9d,0xac,0x8e,0x95,0xf0,0xdb,0x48,0x95,0xc2,0x87 +.byte 0x6b,0x7f,0xde,0x09,0xdb,0xed,0x49,0x19,0x73,0x2d,0xa4,0x5c,0xdf,0xfa,0x2e,0x15,0xd0,0xb6,0x46,0x32,0xc9,0x7f,0x7e,0x01,0xd3,0x25,0x45,0x0e,0x5b,0x0d,0xf0,0x67,0xe3,0xd9,0xdf,0x4f,0x3b,0x6f,0xb3,0x15,0xc5,0x6b,0x91,0x75,0xa2,0xaf,0x42,0x3a,0x14,0x50,0xd9,0x4f,0x19,0x65,0x12,0x83,0x5d,0x8f,0x8a,0x01,0x0b,0x89,0xcc,0x7f +.byte 0x1a,0xde,0x5b,0x44,0x34,0x98,0x0f,0x8e,0x5a,0x5e,0x03,0x41,0x3e,0x66,0x9b,0x16,0xf5,0x91,0x7c,0xb0,0xc1,0xbf,0xa2,0x10,0x0b,0x60,0x3a,0x63,0x0c,0xcf,0xd8,0x49,0xdb,0x42,0x88,0x1f,0x36,0x8e,0x15,0xdb,0x5d,0x3f,0xe7,0xf1,0x9a,0x73,0x2b,0x74,0x0c,0xd5,0x09,0xab,0x01,0x2e,0x52,0x6f,0x03,0xf6,0xc9,0x0b,0xeb,0xa5,0xce,0x2e +.byte 0x1c,0x02,0x35,0xca,0xce,0xfe,0x4b,0xad,0x67,0x21,0xf8,0x44,0xea,0x70,0xf2,0x3d,0xfc,0x43,0x77,0x05,0x26,0xbe,0xaf,0x99,0xab,0x41,0xd4,0xcc,0x53,0x33,0x33,0xcd,0xb4,0x2d,0x76,0xfb,0xae,0x0c,0xac,0xc1,0xd0,0x42,0xfb,0x45,0x4a,0x6e,0x55,0xd2,0x93,0xef,0xb9,0x06,0xbc,0x38,0xce,0x94,0xc2,0x01,0xdf,0x27,0xc8,0x47,0xff,0x74 +.byte 0xfb,0x84,0xc5,0xa2,0x78,0x1f,0x4f,0x73,0x12,0xec,0x2d,0x82,0x5b,0xeb,0x3c,0xb6,0x1c,0x5a,0x29,0x9c,0xba,0x9e,0xa4,0x85,0x94,0x84,0x68,0x01,0xd7,0xb1,0x27,0x84,0x4a,0x7d,0x62,0x9c,0x32,0x12,0x89,0xd8,0x66,0xb5,0xe9,0x07,0xf4,0x5f,0x6b,0x0e,0x90,0x87,0xe5,0xc1,0x8b,0xaf,0x8f,0xf7,0xca,0x54,0xe0,0xc6,0x5f,0xa5,0xec,0xd1 +.byte 0xdc,0xdc,0x17,0x9e,0xca,0x4b,0x72,0x72,0x03,0x96,0x62,0xaa,0xc1,0xfe,0x23,0x7e,0xd2,0x06,0x61,0xb6,0xc9,0x0d,0x7e,0xbf,0x72,0x1c,0x66,0x46,0x0b,0x31,0x96,0x81,0x11,0x3d,0xac,0x5e,0xd0,0x35,0xaf,0xac,0x4c,0x74,0xce,0xf9,0x9c,0x64,0x3d,0xe5,0x9d,0xfe,0xc7,0x05,0x09,0xe1,0x70,0xc5,0x37,0xd5,0x4e,0xd8,0x7d,0xdb,0xfa,0x1c +.byte 0x28,0xfc,0x10,0x2a,0xe8,0x62,0x18,0x09,0x97,0xe0,0x98,0x2e,0x9f,0x1d,0x18,0xff,0x22,0xe9,0x5d,0x37,0xd2,0x74,0xf1,0x81,0x08,0x8a,0x55,0xc0,0x40,0x0f,0x70,0xbe,0x82,0x23,0x78,0x35,0xc8,0xf8,0x59,0x6e,0x0d,0x2e,0xd5,0xe7,0xf5,0x2e,0xbd,0xcd,0x1a,0xcf,0x76,0x43,0x1f,0xca,0x15,0x6c,0x4a,0xb7,0xc7,0xb9,0xaf,0x68,0xd7,0x31 +.byte 0x1e,0x0c,0x9c,0x78,0x74,0x66,0x80,0xc6,0x74,0xbe,0x86,0x59,0x0c,0x12,0xdc,0xf3,0x1b,0xaf,0x63,0x74,0xce,0x1e,0xac,0xf0,0x65,0xa0,0xab,0x7f,0x96,0x08,0x32,0xb2,0xca,0x9c,0xfb,0x9d,0x66,0x63,0x76,0xf9,0x69,0x08,0x6e,0xd3,0x46,0xde,0xdf,0x54,0x06,0x0d,0x25,0x81,0xd9,0x5a,0x45,0xeb,0xe5,0xc0,0xf6,0x86,0x0f,0xe9,0x27,0x7c +.byte 0xdc,0x52,0x28,0xb5,0xd0,0x7d,0x07,0xc1,0xb6,0x9b,0xdc,0xea,0xd3,0x2a,0xba,0xb0,0xd5,0xa3,0xd8,0x25,0x07,0x9c,0x6c,0xd6,0x16,0xa5,0x93,0x43,0x52,0xa7,0x5c,0x2b,0xe2,0xfa,0x8e,0x6e,0xaa,0x04,0x84,0x63,0x80,0x0f,0x90,0x10,0x41,0x1c,0xf6,0x67,0xea,0x39,0xb0,0x16,0xfc,0x6f,0x85,0x28,0x8c,0x8e,0xfb,0x79,0x39,0xdf,0xf6,0x6e +.byte 0x57,0xa1,0xaa,0xf1,0x0b,0x99,0xde,0xad,0x69,0xe2,0xf4,0x74,0x8e,0x8c,0x2d,0x20,0xdb,0xf3,0x2d,0xc2,0x75,0xe7,0xd6,0xc8,0x9d,0x46,0x3b,0x8b,0x8b,0x18,0xd8,0x41,0xfd,0xc2,0x7d,0xec,0x66,0x78,0xe7,0xbe,0xee,0x2b,0x07,0xd8,0x7e,0x13,0x61,0x7e,0xab,0x7d,0x2b,0x3f,0x83,0x96,0xf5,0xab,0x0b,0x20,0xd2,0x5b,0xb0,0xeb,0xf7,0x1b +.byte 0xac,0x1a,0x16,0x46,0x21,0x90,0xdb,0x67,0x66,0x42,0xe2,0x54,0x34,0xae,0x34,0xae,0x21,0x33,0x8c,0x48,0x19,0xdb,0x1f,0xa8,0x25,0x76,0xe0,0x03,0x1c,0x35,0x8d,0xd3,0xab,0x6b,0x93,0xf3,0xad,0x7d,0x3c,0x76,0x1d,0xaa,0x43,0x80,0x0f,0x5f,0x20,0xd9,0xf0,0xff,0x8b,0xf4,0xdb,0xbc,0xf2,0xff,0xf2,0x8a,0xfc,0xf5,0x0e,0x4e,0xd9,0xb0 +.byte 0xd6,0xb3,0x86,0x5b,0x3e,0x10,0x87,0x50,0xf1,0xd2,0x8f,0x8d,0xa4,0x39,0x85,0xf5,0x90,0xd6,0x53,0x69,0x40,0x42,0xc1,0xc3,0x7c,0xc1,0x3e,0x97,0xb4,0x08,0x49,0x93,0x4e,0x4c,0x67,0xd9,0x2e,0x05,0x70,0x04,0x98,0x0a,0xed,0xd0,0xff,0x0c,0x13,0xe4,0xde,0x75,0x81,0x24,0xb1,0x27,0x79,0xeb,0x80,0x68,0x52,0x50,0x66,0x77,0x4f,0xf6 +.byte 0x64,0x2f,0x85,0x9e,0xc1,0xbf,0x9f,0x0e,0x31,0x9a,0x36,0x24,0xcd,0xa8,0xe8,0xce,0x41,0x86,0xd1,0x02,0x96,0xdc,0x1a,0xa0,0x48,0xca,0x61,0xd5,0x87,0xdb,0x0a,0xeb,0x69,0x95,0xca,0xf8,0xe5,0xa0,0x5b,0x91,0x8f,0xb9,0x59,0x5f,0x68,0x60,0x58,0xc5,0xe0,0xc7,0x02,0x68,0xa5,0x67,0x1e,0xfc,0xa9,0x27,0x9f,0x83,0x4c,0x05,0x60,0xee +.byte 0xcb,0x79,0x31,0x73,0x36,0xf4,0x39,0x44,0xdb,0xea,0x62,0x89,0x97,0x69,0xd1,0x0d,0xf6,0x27,0xcf,0x47,0xfe,0x3d,0x5c,0xe9,0x92,0x54,0x0a,0x66,0xaf,0x82,0xb1,0x49,0x87,0x3f,0xa2,0x95,0x91,0x0e,0x72,0x1e,0x7b,0xde,0x32,0x31,0x51,0x40,0x24,0x4f,0x30,0x59,0x7d,0x97,0x28,0x30,0x7e,0x93,0xcd,0x1e,0x16,0xef,0xe1,0xb5,0xa8,0xff +.byte 0x3a,0xd0,0x62,0x94,0x8b,0x72,0xe7,0x97,0x8f,0x2f,0x58,0x3e,0x62,0x43,0x6b,0x28,0x05,0xc9,0x0d,0xf0,0x09,0xbd,0x12,0x3b,0xd8,0x15,0xd3,0x7c,0x97,0x96,0x5a,0xf4,0x9f,0x8d,0x25,0xb7,0xc5,0x66,0xf7,0xf7,0x5f,0x7e,0xca,0x2f,0xcd,0x9a,0xf2,0xa3,0x9b,0x4f,0x6f,0xc3,0xd9,0x64,0x38,0xda,0x87,0x97,0x8a,0x49,0x2d,0x80,0x16,0x73 +.byte 0x88,0x62,0xd2,0xdf,0x4f,0xf7,0x79,0xc0,0x83,0xeb,0x2b,0x66,0x5a,0x21,0x3a,0xa2,0x2a,0xed,0x8c,0xe7,0x91,0x6d,0x56,0x18,0xfc,0x59,0x68,0xea,0x9f,0x5c,0x3c,0xd5,0x0f,0x64,0x70,0x89,0x22,0x83,0xed,0xfa,0xc9,0x21,0x68,0x3c,0x69,0xb8,0x3e,0x89,0xb5,0x9d,0x8b,0xc8,0xf7,0x57,0x17,0x27,0x90,0x12,0xa7,0xd2,0x4d,0x2c,0x30,0x64 +.byte 0x42,0xbe,0xa6,0x49,0x4e,0xa3,0x3b,0xdb,0xdb,0x64,0x0e,0x89,0x66,0x87,0x72,0x90,0x86,0x1d,0x0b,0x61,0x32,0x47,0x3d,0x55,0x81,0xb2,0x50,0x5a,0x76,0x6c,0xa3,0x46,0x12,0x1b,0xaf,0x6e,0xbf,0xfd,0x98,0x2f,0xb7,0xd2,0x31,0x92,0xb5,0x26,0x1a,0x3d,0xfa,0x5d,0xc0,0x24,0x44,0xd2,0x6b,0x1c,0x81,0xf5,0x5d,0x50,0xb0,0x33,0x18,0xe0 +.byte 0xc5,0xb3,0x6b,0xf4,0xfd,0xde,0xf7,0x2f,0x69,0x1d,0x5a,0xfe,0x03,0x6d,0xca,0xad,0x29,0xe0,0x6e,0x70,0xcd,0xe3,0x6d,0x38,0xef,0xf1,0x3a,0x76,0x2b,0x2c,0xb6,0xcd,0xff,0xeb,0xbc,0xe7,0xd9,0x40,0xbe,0x23,0x61,0x20,0xd5,0xb8,0x66,0x77,0x65,0xc9,0x33,0xf5,0x75,0x8e,0x15,0x98,0x3f,0xb1,0x4a,0xb8,0x1c,0x47,0x73,0x45,0x0f,0x73 +.byte 0x2a,0xa1,0xb7,0x73,0x76,0x94,0x16,0x45,0xcf,0xd6,0x8f,0xe3,0x62,0x8a,0x42,0xfd,0xe3,0x1e,0xe0,0x7d,0xb5,0x99,0xbd,0x1c,0xf2,0x60,0xb2,0x72,0xa8,0x4b,0x19,0xd6,0xd0,0xdb,0x0b,0x1f,0xc9,0x68,0xc0,0xf3,0x65,0x04,0x50,0x41,0xf0,0xb3,0x0e,0x0a,0x9d,0x7f,0x0b,0x1f,0xeb,0x5b,0x4c,0x58,0x6a,0xf2,0x02,0x95,0xd2,0xf3,0xac,0xe5 +.byte 0x69,0x81,0xb1,0x3f,0x08,0xfc,0xba,0xcb,0x36,0xcd,0x54,0x28,0xac,0x65,0xd8,0x81,0xab,0xc1,0x6a,0x51,0x97,0x21,0xe4,0xc6,0xaf,0xd8,0x76,0x76,0xa4,0xc4,0xd0,0x58,0x63,0xdf,0x32,0xf5,0x04,0xfb,0x11,0xeb,0x76,0x39,0xda,0x55,0xf4,0x7e,0x1c,0x7b,0x04,0x07,0x4d,0x5a,0xeb,0x74,0x0a,0x57,0xcf,0x10,0xf6,0x0e,0x73,0x02,0x25,0x67 +.byte 0x4f,0x8f,0x37,0x75,0x8f,0x44,0x2a,0x1a,0x6d,0x05,0xda,0xe0,0xa0,0xaa,0xd2,0x78,0xaa,0x7e,0x76,0x0a,0xde,0x2a,0x54,0xae,0x1e,0x39,0xcc,0x3c,0x1c,0xa6,0xd5,0x8a,0xca,0xb4,0xcc,0x76,0xb9,0x30,0xd2,0xe2,0x46,0x31,0xb6,0x51,0xcf,0xe2,0x24,0x77,0xc9,0x9b,0x57,0x3c,0xa3,0x84,0x60,0x59,0x28,0x5f,0x23,0x74,0x17,0x79,0x42,0xbe +.byte 0x60,0x3f,0x09,0x6a,0x43,0x8e,0x40,0x25,0x79,0xb5,0xbb,0xbb,0x72,0x50,0xad,0x4f,0xaa,0xa2,0xd4,0xb2,0xc6,0x7d,0x50,0x7b,0x98,0x59,0x22,0x06,0x7d,0x2c,0x35,0xdd,0x44,0x34,0x9c,0x28,0x98,0xf3,0xe5,0xd0,0x7e,0x09,0xbe,0xc4,0x00,0x72,0xd5,0xa6,0x3b,0x0e,0xb1,0x18,0x91,0x0a,0x4d,0x5d,0xe2,0x0a,0x98,0x79,0x30,0x9b,0xaa,0x38 +.byte 0x03,0x2b,0x6c,0xb2,0x8e,0x0a,0x1d,0x30,0x59,0x8a,0xe8,0x6c,0x6d,0xb5,0xd4,0x91,0xc5,0x28,0x1d,0x5e,0x49,0xe0,0xfc,0x26,0x7f,0x40,0xc0,0x6a,0x81,0x0d,0xb9,0xc6,0x05,0xc6,0x18,0x82,0x70,0xf6,0xea,0x0e,0xb4,0x85,0xba,0x5d,0xfa,0xfd,0xe3,0xd6,0x08,0x7c,0x3d,0x99,0x03,0xd4,0xdc,0x9b,0x50,0x12,0xc8,0xbd,0x8c,0x47,0x67,0x28 +.byte 0x83,0x97,0xca,0xef,0xc3,0x1c,0x2b,0x6e,0x3b,0xf7,0xca,0x7a,0x68,0x6e,0x39,0x25,0x58,0xf7,0xa4,0x11,0x9d,0x8d,0x49,0x29,0xd6,0x6e,0x0b,0x0a,0xcf,0xa7,0x04,0x14,0x6f,0xc4,0x4c,0x36,0x1a,0x16,0x3e,0x8f,0x99,0x69,0x94,0x1d,0xa8,0x66,0x93,0xeb,0x1d,0x82,0xfd,0x3f,0x84,0xb0,0x9d,0xa4,0xe1,0xb0,0xd4,0x9d,0xb2,0x60,0x20,0xfb +.byte 0xd3,0xa0,0xdc,0x79,0x83,0xb0,0xfc,0x50,0x18,0x57,0xe1,0xeb,0x44,0x25,0x05,0xab,0x27,0xfb,0x5f,0x83,0xcd,0x51,0xd0,0x3b,0x80,0x4a,0xce,0xbf,0xe9,0xfe,0x46,0xd2,0x5f,0xea,0x8c,0x89,0x48,0xc8,0x65,0xdd,0x2a,0xa4,0xda,0x54,0xc2,0x37,0x7e,0xd7,0xff,0x80,0x5b,0xf0,0xc3,0x40,0x44,0x40,0x72,0x63,0x23,0xc6,0x9a,0x48,0xf3,0x4b +.byte 0x91,0x64,0x26,0xfc,0xf3,0xa0,0xb9,0x06,0x0c,0x88,0xbb,0xc0,0x93,0x73,0x63,0xf6,0x9c,0x0d,0xe2,0xf6,0xee,0xe0,0x51,0xfd,0xae,0x4d,0x21,0xb9,0x6b,0x7d,0x1e,0x34,0xa0,0x4d,0xe4,0x25,0x30,0xe6,0x81,0x2e,0x32,0xef,0xb9,0x9e,0xaf,0xa0,0x22,0xe0,0x67,0xe6,0x07,0x55,0x3a,0xed,0xef,0x4f,0x87,0x2f,0x44,0xd2,0xef,0xc1,0xfb,0xc4 +.byte 0x7b,0x27,0x20,0x44,0xd2,0xd6,0xf9,0xf3,0x67,0xc1,0xbf,0xaa,0xd5,0x9c,0xd9,0x2c,0xd5,0xf1,0x42,0x2d,0xec,0x39,0xb5,0xc1,0x18,0xed,0x6c,0x47,0x80,0xf8,0x6f,0x66,0x10,0xee,0x1d,0xd6,0x79,0x01,0x4e,0x2a,0xd0,0x83,0xa7,0x9d,0x1d,0x81,0xce,0xf5,0x6f,0x26,0x86,0xd2,0xd7,0x56,0x15,0x65,0x48,0x4c,0xf1,0xf9,0x21,0x77,0xd1,0x84 +.byte 0x22,0xce,0x4d,0x8d,0x83,0xda,0x8c,0x50,0x56,0xc8,0x3b,0xc5,0xb6,0xcf,0x3e,0x0d,0x50,0xe5,0x9d,0x6c,0xb5,0x2a,0x5a,0x58,0x28,0xf5,0x0a,0x05,0xf3,0x0e,0x40,0x8e,0xb6,0xb4,0xdf,0x11,0x1b,0x34,0x81,0xc5,0x0e,0x09,0xa6,0xfc,0x46,0x14,0x02,0x78,0x94,0xbb,0x63,0x9d,0x3e,0x25,0x2c,0xc8,0x1b,0x5c,0xef,0x64,0x77,0x0c,0x04,0x40 +.byte 0xe1,0x45,0x85,0xf8,0x07,0xbf,0x14,0x65,0xe9,0xfc,0xba,0xe4,0x9c,0xa7,0x91,0x56,0x2a,0x3a,0x8e,0x33,0xae,0x56,0x04,0x9d,0x35,0xbc,0xad,0x64,0x0e,0x99,0x8e,0xb5,0x84,0x72,0xcf,0xcc,0x81,0x14,0x11,0x9e,0xe6,0xac,0x0d,0x41,0x43,0x4e,0x2a,0x0d,0xda,0x98,0x42,0xfa,0x8c,0x21,0x79,0x93,0xa3,0xdf,0x84,0x88,0x76,0x14,0x5b,0xb9 +.byte 0xff,0xe1,0xab,0x94,0xc3,0xcd,0x10,0x69,0xee,0x53,0xea,0xfe,0xfb,0xaa,0x43,0x8f,0xdd,0x55,0x88,0x34,0x5d,0x55,0x0f,0x42,0x4d,0x1d,0x93,0xce,0x96,0x67,0xf8,0x33,0xc7,0xca,0x34,0x11,0x28,0xb2,0xed,0x0f,0x00,0x40,0x84,0xee,0x51,0x26,0x6e,0x7b,0x2d,0x77,0xeb,0x18,0xb8,0x9a,0xad,0x28,0xb6,0x6c,0x5e,0xde,0x10,0x4c,0x29,0x1d +.byte 0x79,0x3c,0x2e,0x1c,0xf0,0xc8,0xb3,0xee,0x19,0x7a,0x10,0xe1,0xe3,0x05,0x1e,0x63,0xe9,0x00,0xd7,0xfe,0x83,0xe7,0x54,0xff,0x65,0x9a,0x27,0xa3,0x86,0x72,0x5c,0xb6,0xef,0xf5,0x84,0x68,0x1e,0xae,0xe6,0xf8,0x66,0x9c,0x1b,0x86,0xab,0xfa,0x1a,0xe3,0xb8,0x97,0x16,0xb1,0xb7,0x42,0xfa,0x85,0xa3,0x3a,0x0d,0x21,0xd2,0x35,0xb1,0x89 +.byte 0xf0,0x4f,0x1a,0x1d,0x45,0x34,0x2f,0x31,0x12,0x8c,0x19,0xe7,0x4b,0x14,0xa7,0xcf,0x0f,0xf9,0xcd,0x77,0x40,0xbe,0x09,0xeb,0xc3,0x3e,0x4a,0x37,0x55,0xab,0xbb,0x9c,0xe5,0x22,0x56,0x8a,0x66,0xfa,0xb1,0xff,0x73,0x29,0x52,0xb1,0x89,0xf7,0xab,0xa6,0x58,0x53,0x97,0xfd,0x44,0xda,0xbd,0x0b,0x1f,0xc8,0x88,0x01,0xcc,0x5e,0xf7,0x05 +.byte 0xbd,0xf7,0x0a,0x4d,0xcb,0xef,0xbf,0xd9,0x8e,0x15,0xc3,0x40,0xb9,0xc9,0x14,0xe5,0x05,0x3c,0x20,0x67,0xfe,0xdc,0xa6,0xb8,0x92,0xbd,0xf5,0x33,0xb5,0x77,0x11,0x28,0x47,0x21,0x28,0x18,0x61,0xf8,0x1c,0xdb,0x65,0xad,0x89,0x0d,0x98,0x79,0xca,0x2b,0xa3,0x4f,0x16,0xa6,0xb3,0xb9,0xcc,0x47,0x5b,0x13,0x96,0x2e,0x39,0x78,0x24,0xc5 +.byte 0xf9,0xf5,0xae,0xdc,0x34,0x3c,0xf7,0x48,0x0d,0x75,0xaf,0x51,0x75,0x48,0xbe,0x4d,0x73,0x89,0x5a,0xfc,0xd7,0x51,0xd3,0x93,0xa8,0xbc,0xc3,0xa6,0x6b,0x63,0xc1,0xc3,0x7b,0x48,0xf1,0x57,0xe4,0xb4,0xce,0x5f,0x18,0xae,0xdc,0x61,0x99,0xaa,0x7e,0x49,0xd6,0xb5,0x2c,0x62,0xb8,0x8c,0x4a,0x94,0xc1,0xc2,0x13,0x23,0xdc,0x7c,0x48,0xc2 +.byte 0xaa,0xc4,0xd9,0xc0,0x09,0x11,0x6e,0x35,0x07,0x14,0x77,0x7e,0xeb,0x87,0x00,0x05,0x30,0xec,0xb2,0xc6,0xde,0x6e,0x42,0x0b,0x2a,0xb6,0xca,0xb1,0xdc,0x69,0x57,0x1b,0xad,0x52,0xa8,0x22,0x1e,0xb5,0x2b,0xb5,0x8e,0x39,0x4b,0xbf,0x38,0xf4,0xb2,0xf5,0xa1,0x9c,0x7b,0x7f,0x6c,0x14,0x48,0x37,0xa9,0xf9,0xcd,0x85,0x50,0x53,0xb0,0xc1 +.byte 0x15,0x28,0x19,0x3b,0xb1,0x04,0x44,0x93,0x7a,0x16,0x76,0x69,0xa1,0x5c,0x67,0xcc,0x8d,0x02,0x56,0xcd,0xd9,0x91,0x49,0x8c,0x1b,0xc9,0x89,0x98,0x09,0x2e,0x5b,0xf8,0x7c,0xe6,0x0f,0x46,0xb0,0xcc,0xe5,0x75,0x63,0xaf,0x40,0xd5,0xa3,0x45,0x4a,0x76,0x67,0x1d,0x81,0xc2,0x25,0x85,0x7f,0x52,0xc5,0xf8,0x6d,0xd9,0xb6,0xa8,0xa4,0x96 +.byte 0x63,0xcc,0x15,0xc5,0xec,0x40,0x0e,0x08,0xf7,0x6f,0x85,0xa5,0xe7,0x2e,0xbe,0x3f,0xf4,0xc8,0x74,0xc7,0xed,0x86,0x85,0xc0,0x44,0x9e,0x80,0xc8,0x89,0xdc,0x16,0x47,0xb1,0x68,0x0e,0x65,0x66,0x0f,0xbc,0x33,0xb1,0x78,0x1e,0x5e,0xd7,0xde,0x97,0x96,0xb8,0x74,0x5c,0x90,0x7a,0xed,0x36,0xf4,0x10,0x91,0x5a,0x42,0x92,0x81,0x11,0x73 +.byte 0x3e,0xf1,0x5e,0xfb,0xc2,0x38,0xe6,0xe5,0x41,0xce,0x96,0xed,0x44,0x14,0x9c,0xc0,0x1f,0x83,0x5f,0xdd,0x50,0x87,0x90,0x86,0x50,0x61,0x87,0x99,0x7c,0x64,0x2d,0x50,0x17,0xa3,0xb0,0x7e,0x69,0xd3,0x86,0xb4,0x7c,0xe7,0x15,0x34,0x9e,0x3b,0x17,0xc0,0x2d,0x08,0x60,0x8b,0xae,0xec,0xa2,0xf6,0xf1,0xa4,0xbc,0x7b,0xc2,0x75,0x91,0x13 +.byte 0xf6,0xd0,0x71,0xf0,0x3c,0x9c,0x51,0xb3,0x33,0x53,0x57,0x47,0x8b,0x47,0xb0,0x0b,0x95,0x9a,0x39,0x70,0x63,0x91,0xcc,0xd8,0xd0,0x23,0x32,0xc0,0xb6,0x0f,0x91,0x30,0x29,0x45,0xf1,0xfc,0xa1,0x83,0x10,0x9a,0xa4,0x05,0x05,0x9f,0x33,0xbd,0xaf,0x16,0x3e,0x53,0x39,0xb1,0x4b,0x76,0x55,0x3e,0x6f,0x47,0x23,0x59,0x4c,0xbb,0x82,0x31 +.byte 0x19,0xe2,0xb1,0x49,0x20,0x91,0x2d,0xb0,0xfe,0xa6,0xae,0x7f,0x6e,0xd1,0x5b,0xb9,0x84,0x18,0x0f,0x68,0xc6,0x56,0x8a,0x22,0x81,0x3f,0x38,0x42,0x7a,0x31,0xa1,0xc1,0xf7,0x10,0x6a,0xc3,0xb1,0xaf,0x19,0xad,0x06,0x3a,0x53,0x9d,0x44,0x9f,0xe7,0x25,0xac,0x59,0x06,0xb9,0xd2,0xf6,0xce,0xb6,0x1e,0x4d,0x65,0x2e,0x05,0xb4,0x14,0x91 +.byte 0xfb,0x5b,0x26,0xd0,0xee,0xfa,0x45,0x5b,0x0c,0xd5,0x5c,0x1f,0x0c,0xe0,0xf6,0x50,0x78,0x77,0x7e,0x83,0x04,0xec,0x3b,0x53,0x28,0x97,0x56,0x61,0xeb,0xa0,0x78,0xe5,0xc0,0xb2,0x3c,0xcd,0x6f,0x4b,0xda,0x11,0x00,0x93,0x49,0x9f,0x03,0x22,0x39,0x3a,0xc8,0xef,0x01,0x91,0x12,0x36,0x15,0x0c,0x47,0xd5,0x8b,0x77,0x5e,0x5f,0x91,0x4b +.byte 0x44,0x98,0xa0,0xa0,0x46,0x0f,0x17,0xef,0xf9,0x52,0x0b,0x92,0xc1,0xe0,0xfc,0x63,0x9b,0x6d,0xe2,0xde,0x88,0x89,0x32,0x89,0x93,0x44,0x6d,0x69,0xe7,0x26,0xfd,0x77,0xc0,0x18,0x58,0xdb,0x74,0xec,0x04,0x0c,0x60,0x51,0x74,0xca,0x49,0x3e,0x4f,0x5f,0xaa,0x53,0xf2,0xc1,0xcb,0x89,0x1f,0x69,0xaa,0xbb,0x97,0x17,0x04,0x49,0x5e,0x44 +.byte 0xf3,0xf3,0xc4,0x98,0x9d,0x49,0x1e,0xb0,0x27,0x7d,0xff,0x54,0xa5,0xed,0xbe,0xb0,0x52,0xf6,0x00,0x87,0x67,0x2d,0x28,0xdb,0x09,0x4e,0xa2,0xee,0x4f,0x81,0xeb,0xa1,0xca,0x2b,0x07,0x2f,0x54,0x6d,0x5a,0x2e,0x13,0xa4,0xd0,0xac,0x21,0x7c,0x44,0xc0,0x98,0xac,0xe4,0x6e,0x94,0xd1,0x5b,0x5e,0xd6,0xf1,0x3c,0x45,0x88,0xe1,0xbd,0x58 +.byte 0xf1,0xc7,0xba,0x36,0x2c,0x15,0xb9,0xf4,0xa3,0xea,0x73,0xb4,0x91,0x53,0xd8,0x18,0x86,0x23,0x87,0x0b,0x7a,0x4a,0x2d,0x2d,0x3d,0x73,0xcb,0x05,0x11,0x4c,0x19,0x26,0xf2,0x05,0x89,0xc8,0x29,0x26,0xa7,0xe4,0xcb,0x43,0xd0,0xf6,0xbc,0x76,0xbd,0x9a,0x17,0x4a,0xf1,0x39,0xe3,0xde,0x05,0x10,0x8a,0xd3,0x11,0x53,0x61,0xef,0x33,0xd9 +.byte 0x65,0x0d,0x99,0x0b,0x39,0xa4,0x1b,0x4f,0x0b,0xa5,0xf1,0x37,0xa3,0x4f,0x54,0xa7,0x29,0xc1,0xae,0x88,0x5c,0x13,0x2f,0xb2,0xbf,0xcf,0x1b,0x0d,0xa0,0x68,0x21,0xe2,0x20,0x3f,0x02,0x9f,0x08,0x39,0xc6,0x20,0x2d,0x08,0x01,0x5d,0xf1,0x47,0xde,0x88,0xad,0x49,0x09,0xf7,0x1a,0x0c,0xa7,0x29,0x91,0xe5,0xfc,0xc5,0xde,0xd7,0x92,0x3f +.byte 0xe5,0x0c,0x91,0xea,0x24,0xfb,0x02,0x9a,0x13,0x3a,0x61,0x01,0x9d,0x7e,0x9d,0x11,0xf8,0xbd,0xe0,0x05,0xbb,0x13,0xf0,0x00,0x67,0x90,0x6f,0x80,0xe7,0x2e,0xfc,0xe0,0xea,0x8a,0x9d,0x2c,0x13,0x57,0x4c,0x78,0x1c,0x44,0xe2,0xa6,0x62,0x01,0x46,0xf8,0xbe,0xf4,0x51,0x32,0x15,0xd4,0x3c,0x7d,0x3b,0xcc,0xfd,0xc3,0x46,0x43,0xf1,0xfa +.byte 0x9e,0xee,0xad,0x47,0x8f,0x32,0x31,0x94,0x70,0x92,0xea,0x45,0xe3,0x63,0xd6,0x28,0x23,0xa5,0xdf,0x61,0xee,0x19,0x1a,0x5e,0xb0,0xe7,0x17,0xab,0xac,0xb4,0x03,0xed,0xf6,0x9e,0xba,0xdf,0x52,0x88,0xb7,0xca,0x7c,0x27,0xcd,0x7b,0xf8,0x1e,0x54,0x4b,0xe6,0xa3,0x91,0xf7,0xeb,0x22,0x65,0x95,0x13,0xe1,0xac,0xb6,0x22,0x80,0xe3,0xeb +.byte 0xf9,0xde,0xf1,0xb7,0x6a,0xfd,0xc7,0xb8,0x9b,0x9c,0x49,0x4f,0x84,0x7f,0x68,0x93,0x6c,0x3c,0xea,0xb1,0x8a,0xeb,0x23,0xca,0x2d,0x5e,0x29,0xb5,0x52,0x49,0x98,0x12,0x3f,0xed,0xf0,0xb7,0xbc,0x22,0x14,0x73,0x92,0x84,0x1b,0x3e,0x2f,0xed,0x24,0x1e,0x62,0xcc,0x09,0xe8,0x7c,0x5a,0x08,0xd4,0xc6,0xd9,0xd1,0x55,0x66,0x18,0x2c,0x6a +.byte 0x99,0xc3,0x0e,0x1e,0x7b,0xb7,0xd4,0xbd,0x0e,0x1f,0x22,0x85,0x09,0x2c,0xcf,0xff,0x79,0x9f,0x93,0xbe,0xec,0xed,0x63,0xb7,0x97,0xbb,0xeb,0xd6,0x70,0x76,0xa9,0x4f,0xb7,0x9a,0x60,0x5b,0x50,0xdf,0x85,0x46,0x69,0xa0,0x9a,0x86,0xe3,0xe2,0x13,0x2b,0x8c,0x0f,0x3b,0xab,0xa8,0xce,0xa3,0xb0,0x78,0x72,0x40,0xfb,0xd1,0x26,0x72,0xc1 +.byte 0x91,0x25,0x7b,0x29,0xde,0xcf,0x99,0xf3,0x8e,0x87,0x39,0x81,0x04,0xad,0x3b,0x11,0x6a,0xda,0x00,0xdd,0xe9,0x41,0xc1,0xd8,0xcc,0xf9,0x59,0xac,0x9b,0xb1,0x64,0x6f,0xb8,0xf4,0x9f,0x20,0xde,0x67,0x09,0x1b,0xdf,0x11,0xa5,0x94,0x56,0xab,0x76,0xba,0xc5,0xda,0x6c,0x86,0xe6,0xa4,0x73,0x59,0xa9,0xe3,0x68,0xb9,0xc0,0x50,0x1b,0x55 +.byte 0x21,0x9e,0xea,0x8d,0xcc,0x5d,0xee,0x88,0xe1,0x18,0x7c,0xcd,0x8f,0xff,0x18,0xbd,0x13,0xea,0x95,0xc4,0x8e,0xd3,0x92,0xfe,0x3d,0xda,0x6f,0xa5,0xbc,0xa0,0x77,0x5a,0x1d,0x61,0xff,0x7b,0x77,0xc4,0x06,0x25,0xc5,0xa7,0x76,0x36,0x55,0xe7,0xc0,0xf0,0x46,0x7e,0xca,0xe7,0xc1,0xe8,0x88,0x65,0xff,0xa7,0xb6,0x9c,0x83,0x1d,0x2e,0x6e +.byte 0xd6,0xd3,0x07,0x22,0x65,0x79,0x4f,0x3c,0x0a,0x5c,0x4f,0x95,0xb3,0x14,0x37,0x9b,0x0b,0x97,0x69,0xd9,0x5b,0x37,0x09,0xc3,0x70,0x5b,0x4f,0x11,0xcb,0xce,0xc0,0x06,0xf2,0xb9,0x32,0xdd,0x24,0x7b,0x8c,0xe6,0x0c,0x91,0x3b,0xa8,0xb0,0x82,0x56,0x4d,0xde,0xa0,0x5c,0x0b,0x5b,0x70,0x53,0x64,0x9d,0xab,0xbb,0x51,0x6b,0x8c,0x8f,0xe5 +.byte 0x1f,0xc0,0xb8,0xfe,0x1b,0xf6,0x24,0x26,0x62,0xcb,0x78,0x84,0x90,0x76,0x67,0x30,0x18,0x37,0xa9,0xca,0xb7,0x0d,0xac,0x17,0x86,0xb1,0x87,0x59,0x18,0xc3,0x9e,0x62,0x1b,0xb1,0x04,0x52,0xfc,0x7c,0x86,0xa0,0x37,0xb9,0x8b,0x7a,0x85,0x79,0x21,0xe0,0x0f,0x87,0x28,0x91,0xd0,0xe5,0x24,0x63,0x5c,0x7c,0xe8,0x47,0xfa,0x42,0x55,0xe9 +.byte 0x66,0xad,0xdf,0xc3,0x43,0x90,0x47,0x83,0x24,0x09,0x54,0x5f,0x14,0x27,0x53,0xb3,0x22,0x15,0x52,0x84,0x2f,0x61,0x8c,0x01,0x9e,0x34,0x61,0x3f,0x76,0x44,0x1c,0xca,0x79,0x2c,0x40,0x4e,0xa0,0x36,0x11,0xe0,0x23,0x0f,0xa7,0x78,0xf9,0xf9,0x2a,0x2c,0x98,0x5c,0xa9,0x2d,0x66,0xb9,0x87,0x43,0xd5,0xbc,0x64,0xe5,0x52,0x2f,0x1d,0xdc +.byte 0x1d,0xf4,0xb3,0x18,0x6b,0xd1,0x3b,0x8b,0xa3,0x47,0x65,0x62,0xcc,0xca,0x5f,0x00,0xbb,0x78,0x9d,0x35,0xd4,0x79,0x45,0x33,0xc7,0xa8,0x29,0x96,0x98,0xa4,0x23,0x2c,0x23,0x7f,0x5a,0x1d,0x09,0xb4,0xcf,0xac,0x54,0xcd,0x27,0xda,0x88,0x21,0xe2,0xb4,0x85,0xdc,0xc9,0x4a,0x6b,0xc4,0xfa,0x48,0xc5,0x91,0xc1,0x53,0x4b,0xa1,0x7a,0x9c +.byte 0x8a,0x7d,0x35,0x52,0xf1,0x58,0x9d,0x20,0x36,0xc2,0x78,0xdb,0x37,0xf8,0xa4,0x2f,0x50,0x98,0xb0,0x34,0x51,0x66,0x93,0xcf,0xe7,0xf0,0x06,0xf1,0xcd,0x0e,0x4f,0x33,0xcc,0x9b,0x73,0x3b,0xc9,0x51,0x63,0x6d,0x29,0x6b,0xf4,0x9d,0x2c,0x76,0x59,0xcd,0xfc,0x11,0x35,0x52,0xbd,0x3b,0x2e,0x7d,0x8a,0x0d,0xb0,0xbb,0x90,0x9b,0x9c,0xac +.byte 0x1c,0x80,0x89,0xd6,0x6f,0xaf,0xea,0x89,0x38,0x74,0xef,0x83,0x82,0x91,0xf7,0x74,0x96,0x30,0x40,0xe2,0x18,0x2b,0xb4,0xf6,0x15,0xf0,0x8e,0x63,0xe1,0x82,0x55,0x7b,0x65,0x70,0x33,0x14,0xef,0x7a,0x7c,0x2d,0xa9,0x17,0x1b,0x53,0x1e,0xf8,0x98,0x1b,0xbe,0xc8,0x00,0xf5,0xbf,0x79,0xe7,0x8e,0xf2,0xdb,0x59,0x0d,0x46,0xab,0x43,0xd0 +.byte 0xe4,0xa0,0xeb,0x29,0x6a,0x8b,0xc1,0x99,0xa6,0xcc,0x8e,0xe5,0xde,0x67,0xdf,0x49,0x09,0x62,0x8d,0x4b,0xa1,0x1c,0x3b,0x01,0xe2,0x95,0x65,0x10,0xa5,0x91,0xd0,0x48,0x35,0x96,0xcf,0xe4,0x51,0xd2,0x7f,0x93,0x49,0xab,0x1a,0xba,0x08,0x33,0x54,0x34,0xd7,0x00,0xc9,0xa0,0x07,0x03,0xc7,0x8a,0x65,0xa2,0x84,0x60,0xcd,0xaa,0xa2,0x46 +.byte 0x8c,0x67,0xd9,0xc1,0xe7,0x58,0xc5,0x1d,0xc0,0xb3,0xc6,0xb2,0x2a,0xfb,0x70,0x04,0xa2,0x25,0x7f,0x75,0x3c,0xd5,0x8e,0x9c,0x33,0xa2,0xdc,0x20,0x4c,0x26,0x5b,0xbe,0xd9,0x00,0x5d,0xa2,0xbd,0x42,0xbd,0x0d,0xd6,0x52,0x79,0xb5,0x67,0xf6,0x27,0x62,0xc8,0x64,0x05,0xc5,0x0f,0xae,0xe1,0x78,0x39,0xd1,0xb5,0x28,0xe9,0xd4,0x2a,0xaa +.byte 0xd4,0xc4,0x3e,0x43,0x27,0x83,0xfa,0xdb,0x46,0x73,0x20,0xcd,0x2c,0xba,0x33,0xb4,0x77,0x10,0x32,0x3d,0x8e,0x56,0x88,0x81,0xe1,0x4c,0x8b,0x46,0x60,0xcb,0xb7,0x67,0xd7,0x7b,0xc2,0x47,0x7d,0xd8,0x2d,0x4c,0x09,0x9f,0x07,0x8e,0x34,0x45,0xf4,0x50,0x69,0xfd,0x35,0x0a,0x09,0x9e,0xac,0x49,0x5f,0xdf,0x72,0x84,0x97,0x93,0x30,0x2c +.byte 0xc6,0x20,0x6f,0xb5,0x18,0x03,0xb6,0x30,0x23,0xc8,0xcd,0xa1,0x43,0xbd,0xbb,0x6f,0xde,0xb3,0xcb,0x1c,0xdd,0x41,0x71,0xfa,0x37,0xa7,0xa9,0x57,0x5a,0xf7,0xee,0xcd,0xb1,0xc1,0xb6,0x78,0x1c,0xe3,0xde,0x5c,0x02,0xc8,0xce,0xb7,0x8e,0x72,0xce,0xfd,0x79,0xcf,0x1a,0xef,0xcb,0x5b,0x5d,0x3c,0x1d,0xc8,0x1e,0x9f,0x67,0x26,0x86,0xd3 +.byte 0x3b,0x98,0x49,0x04,0xcd,0x1b,0x48,0x7c,0xa6,0xbe,0x37,0x0b,0x19,0xb1,0xb7,0x8a,0x74,0x0a,0xd9,0x4f,0x7b,0xbb,0x8e,0xc6,0x9b,0xdd,0xbc,0x61,0xfd,0xdd,0x86,0x7e,0x70,0x2e,0xe4,0x94,0xb4,0x62,0x47,0x6b,0x7c,0x92,0x41,0xda,0x05,0xdc,0xaf,0x5c,0x93,0xbc,0x7d,0xad,0xce,0x44,0x9e,0x27,0x1c,0x74,0x30,0x01,0xf2,0x8a,0x22,0xce +.byte 0x88,0x61,0xf5,0xb8,0xe2,0xf0,0xca,0x14,0x21,0x53,0xd3,0xbe,0x95,0x8f,0x52,0x10,0x21,0xc5,0x25,0x16,0xa1,0x4f,0xef,0x9a,0x6f,0xce,0xe9,0xee,0x06,0xa8,0x32,0xa4,0xac,0xee,0xd8,0x95,0x0b,0x65,0x10,0xbc,0xb3,0x15,0x48,0xf9,0x96,0xee,0xde,0x5d,0xf6,0x38,0x5f,0x32,0x70,0xd1,0x29,0xa8,0x1d,0xdc,0xf4,0x34,0x2d,0x0c,0x93,0x48 +.byte 0x8c,0x40,0xed,0x35,0x41,0xfe,0x4b,0xab,0x20,0x7d,0x95,0x74,0x02,0xe5,0x71,0x76,0x7e,0x59,0x35,0xb3,0xd7,0x43,0x1f,0xd4,0xe6,0x02,0x86,0xba,0x4f,0x53,0xd9,0xc3,0x7d,0x7f,0x3d,0xb6,0xd8,0x92,0x07,0x89,0x99,0x46,0xf8,0x09,0xcd,0x19,0x43,0x93,0xa7,0xc1,0xb2,0x5d,0xec,0xbf,0x09,0xf4,0xba,0xfc,0xf7,0xf1,0xa7,0x2e,0xfe,0x71 +.byte 0x04,0x58,0xab,0x16,0xd7,0xc0,0xf7,0x03,0xd4,0xc4,0xb9,0xe4,0xd8,0xfc,0x5b,0x66,0xa6,0xb3,0x6a,0x94,0x0e,0xba,0x8c,0x54,0x5c,0x8c,0x02,0x0a,0x33,0xcb,0xde,0x1c,0xad,0x6d,0xef,0x48,0x05,0xa6,0xca,0x9a,0x27,0xd6,0x1c,0xc3,0xea,0x3a,0x46,0x20,0xec,0x72,0xc4,0x94,0x89,0x7e,0xba,0xa9,0x2f,0xe5,0xec,0x1a,0xe4,0x50,0x54,0xeb +.byte 0xd9,0x5a,0x08,0xc5,0x84,0xc1,0x9a,0xdf,0xb0,0xd4,0x9a,0x6d,0xa2,0x93,0x52,0xd2,0x4d,0x69,0x88,0xc8,0x40,0x2d,0x26,0xbd,0x7a,0x37,0x04,0x21,0xe1,0x9d,0xc9,0xed,0xda,0x7a,0x4c,0x11,0x49,0x14,0x42,0xa1,0xdb,0x6e,0xed,0x1b,0x37,0xbf,0x09,0xac,0x35,0xda,0x80,0xf6,0x75,0xd4,0x32,0x54,0xb5,0x18,0xe8,0x79,0x25,0xc4,0x95,0xe8 +.byte 0x74,0xcf,0x6d,0xac,0x34,0x1f,0xea,0xd4,0x2e,0xd1,0x77,0x5e,0x90,0x8f,0x12,0x51,0xbb,0x3c,0xdf,0xe6,0xf4,0x49,0x8c,0x0f,0x9a,0x8e,0xe3,0x96,0xbd,0xba,0xe6,0x47,0x4b,0x50,0xc7,0xa9,0x29,0xea,0x09,0x5d,0xef,0x3c,0x91,0x48,0xc6,0x37,0xfd,0xac,0x7b,0xe5,0x04,0x25,0x93,0x0b,0xe3,0xce,0x32,0x46,0x38,0x81,0x97,0x57,0xbe,0x1f +.byte 0x3c,0x61,0x2d,0xd1,0x4e,0xca,0xbb,0x44,0xc6,0xfd,0xdf,0xdd,0x11,0xbf,0xbf,0xa8,0xc0,0x32,0x67,0xc1,0x2e,0xd7,0xbe,0x3c,0xe3,0xcb,0x57,0xa5,0x6d,0xbb,0x8e,0x0f,0x69,0x22,0x42,0xef,0x53,0x0f,0xce,0x09,0x6a,0xda,0xbf,0xd6,0xed,0x61,0x67,0x82,0x83,0x13,0x63,0x97,0x7d,0x1a,0xad,0x34,0x77,0x37,0xa6,0xe0,0x89,0xaa,0xd4,0xb6 +.byte 0x8f,0x93,0xff,0xb8,0x8f,0x63,0x14,0xfd,0x17,0xff,0xe5,0x7c,0x83,0x23,0xaa,0xe0,0xb9,0xd9,0x94,0x3a,0x1a,0xe7,0xa5,0xbd,0xa6,0x2b,0xd3,0x49,0xca,0xeb,0x7d,0x87,0x1d,0x54,0x16,0x93,0xec,0x14,0x8b,0x77,0x3c,0xb4,0xbe,0x33,0x76,0x5e,0xcb,0x33,0x27,0xd3,0x20,0xd6,0xed,0x0c,0x66,0xb8,0xe0,0x00,0xa6,0x76,0xcd,0x8b,0xb4,0xef +.byte 0x11,0xbc,0xe5,0x59,0xcf,0x1d,0xf5,0x15,0x58,0x4a,0xe1,0xfd,0x87,0x8c,0x7b,0xb9,0xa4,0x42,0x5a,0xed,0x51,0x7e,0x8d,0xa6,0x19,0xaa,0xc4,0xa6,0x14,0x74,0x45,0xb1,0xda,0x87,0x0f,0xd7,0xe7,0x66,0x3b,0xcd,0x04,0x02,0x14,0x20,0x41,0x15,0x4c,0x33,0x79,0x80,0x7d,0xd4,0x44,0x2c,0xab,0x6c,0xf4,0xa8,0xd4,0x31,0x43,0x7b,0xa7,0xc7 +.byte 0x65,0x0e,0x32,0xc8,0xc8,0x6d,0xf5,0x65,0x1b,0x26,0xf1,0xe4,0x68,0x15,0x88,0x1b,0x00,0x60,0x23,0x31,0xd7,0x4b,0x57,0xda,0xf1,0x19,0xa9,0xd9,0xaf,0xe6,0xa9,0x1e,0x2c,0x0d,0x23,0xe4,0x5b,0xcb,0x43,0x38,0xf0,0x93,0xd3,0xfb,0x6a,0x9b,0x83,0x30,0x55,0x96,0x9f,0x53,0x06,0x3f,0xaf,0x40,0x69,0xef,0x9a,0x47,0x6b,0xba,0x7c,0x10 +.byte 0x10,0x44,0x89,0xfa,0xb9,0x9e,0x70,0xed,0x25,0x59,0x68,0xae,0x9b,0x17,0xcf,0x80,0x6f,0x34,0xb8,0x07,0x40,0xe5,0x27,0x6d,0xcd,0x46,0x2c,0x36,0x90,0xf3,0x83,0x74,0x68,0x35,0xf2,0x05,0xa8,0xdf,0x4e,0x34,0xc5,0xb4,0xeb,0x5a,0x7d,0xe6,0x10,0x8a,0x23,0x54,0xeb,0x9b,0x27,0xf2,0x07,0xee,0xf9,0x05,0xc2,0x5a,0x88,0xbd,0x49,0x2e +.byte 0x1b,0x00,0x31,0x68,0x4a,0xc9,0x3a,0xc5,0x93,0x82,0xa8,0x39,0xba,0x55,0xcd,0xc1,0xda,0x49,0xc2,0x4c,0xf4,0x93,0x00,0xcf,0x61,0xa4,0xbb,0x8c,0x64,0x33,0x90,0x14,0x6d,0x1d,0xad,0x75,0x97,0xd9,0x1d,0xfb,0x27,0x67,0x43,0x04,0xdc,0x4e,0xdf,0x0e,0x0c,0x7e,0x1c,0x89,0xfe,0x31,0xb7,0x9b,0x07,0x5e,0x99,0x08,0x22,0xef,0x6e,0x4d +.byte 0x8b,0xd6,0x27,0xe6,0x24,0x1a,0x28,0xb0,0x22,0xa5,0x69,0x17,0x82,0x46,0xe3,0x90,0xe8,0x04,0xae,0x90,0x66,0x14,0xec,0xa2,0x1b,0x7e,0x09,0x13,0x32,0x9d,0xec,0x8b,0x51,0x5f,0xa8,0x96,0x8f,0x4c,0xc6,0xbd,0x5c,0x70,0x29,0x21,0xac,0xe9,0x6e,0xb0,0x0c,0x61,0x50,0xba,0xcc,0x55,0x71,0xda,0x2a,0x92,0x86,0x0c,0xff,0xaf,0x7a,0xcf +.byte 0xaf,0x2a,0xbd,0xd6,0x15,0xa4,0x4c,0x2e,0x76,0x0d,0xcf,0x10,0x11,0x4a,0xd1,0x89,0xdd,0x46,0x5f,0x6b,0x5a,0x02,0x05,0x49,0x6f,0x98,0x6a,0xa7,0x8a,0x66,0x87,0x59,0x23,0xb5,0x3f,0x2e,0x95,0x73,0xfe,0x48,0xe9,0x0d,0x17,0xa6,0xa5,0x4e,0x40,0x98,0x79,0x40,0x1a,0x10,0x1d,0x84,0xdd,0x6f,0x17,0xa7,0xb7,0xfb,0x49,0xbd,0x54,0x97 +.byte 0x0f,0x42,0x25,0x95,0x83,0xf0,0x97,0xe7,0x4c,0x24,0xb5,0xe8,0x23,0x0a,0xd6,0xbf,0xef,0x2c,0x03,0x4f,0x87,0x59,0xe8,0x80,0x87,0xcc,0x51,0x1b,0x94,0xd8,0x60,0xe7,0x10,0x4d,0x01,0xfd,0x83,0xf2,0xd8,0x8d,0x1b,0x33,0xbf,0xaf,0x36,0x41,0x47,0x51,0xe0,0x45,0x2a,0x05,0x5f,0xe1,0x92,0xf8,0xa5,0x15,0x46,0x35,0xd8,0x9b,0xe0,0xff +.byte 0xee,0xa6,0x4e,0x7d,0xfd,0x96,0xa5,0x75,0xdf,0x7e,0xb0,0x7d,0x14,0x73,0xdd,0xbe,0x17,0x6d,0xdd,0xec,0xac,0x9a,0x92,0x68,0xe3,0x44,0x16,0x63,0x22,0xa8,0x15,0x58,0x8c,0x11,0x23,0x46,0x18,0xae,0x47,0x39,0x87,0xc7,0x4c,0x30,0x09,0xce,0xe5,0xc4,0xd8,0x82,0xc6,0xc6,0x3d,0x31,0xf6,0x0f,0xb5,0x69,0x61,0x63,0x88,0xd6,0xb8,0xda +.byte 0x89,0x29,0x87,0x69,0x6e,0x3f,0x55,0x2f,0xbc,0x91,0x91,0x43,0x7d,0xb3,0x7b,0x99,0x5a,0x5a,0xb0,0x7d,0x90,0xa7,0xe7,0x30,0x0d,0x32,0xb2,0x43,0x43,0x78,0x59,0x6e,0xbb,0xd7,0x76,0xd4,0x5b,0x4d,0xc4,0xa9,0x99,0xdd,0xd3,0xce,0x3d,0x13,0x41,0x38,0x33,0xed,0xb8,0x76,0x1a,0xbb,0xfd,0x26,0xcd,0x69,0x89,0x22,0x16,0x9a,0x21,0x35 +.byte 0x38,0x77,0x14,0x10,0x42,0x17,0x1f,0xa1,0xbf,0x55,0xb4,0x51,0x62,0x15,0xac,0xd0,0xa2,0x71,0xe4,0x32,0x89,0x33,0x8b,0x74,0xc6,0x61,0x38,0xd0,0xfe,0x28,0x69,0xe6,0x88,0x1b,0x11,0x7e,0x46,0x39,0xba,0x24,0xdd,0x1f,0x61,0xf4,0x74,0xad,0x58,0x94,0xa9,0x3e,0xc7,0x2a,0x9e,0xc0,0xe1,0x1c,0xee,0x21,0xab,0x3e,0x65,0x0c,0xe8,0xd8 +.byte 0x71,0x52,0xf3,0x6c,0x64,0x53,0x75,0x17,0x87,0x55,0x14,0x42,0x25,0x7f,0xe7,0x0d,0x89,0x1b,0x77,0x26,0xc4,0xaa,0xcc,0x91,0x47,0xe5,0x54,0xae,0x1a,0x0d,0x04,0x99,0xeb,0x56,0xd8,0xb4,0x6d,0xeb,0xec,0x2f,0x6c,0xc5,0x8e,0x76,0xe1,0xa0,0xa7,0x42,0x06,0xc9,0xc3,0x03,0xee,0xa9,0x9b,0x1e,0xfc,0x11,0xf5,0x2f,0x2b,0x14,0xb8,0x9f +.byte 0x87,0x61,0x9b,0xc7,0x38,0x0e,0x58,0xf1,0xd4,0x36,0xca,0x82,0x85,0x9c,0xde,0xec,0xd3,0x1e,0x29,0x4e,0x70,0x9e,0x9a,0xe0,0x8b,0x6f,0xfe,0xd0,0xe9,0x95,0x51,0xcf,0x36,0x31,0x9c,0xff,0x63,0xc6,0x04,0x8e,0x61,0xc2,0xcb,0x3a,0xfa,0xd0,0xd7,0x29,0xbd,0xe7,0x8a,0x2b,0x8e,0xa0,0xac,0x58,0x93,0xb3,0x52,0xca,0x80,0x17,0xd2,0x2d +.byte 0x93,0x5f,0xe0,0x8a,0x47,0x3c,0x67,0x95,0x64,0x91,0xa4,0x76,0xa4,0x5f,0xfa,0x93,0x4d,0xc7,0x6e,0x5d,0x23,0x9f,0xe1,0x4a,0x16,0xff,0xa5,0xf0,0x94,0xa8,0x02,0xcc,0x9a,0x84,0xd5,0x9d,0xb6,0xe5,0x7c,0x76,0x3f,0xc9,0xfd,0xdc,0x8e,0x59,0x9a,0x22,0x18,0x3c,0xe6,0x90,0x85,0x10,0x73,0x2d,0x65,0xa7,0xa7,0xe1,0xeb,0xc5,0x05,0x24 +.byte 0x1e,0x0b,0x31,0x19,0xb5,0xb0,0x8d,0xc0,0xb5,0x04,0xfe,0x9d,0xfa,0xf7,0xcd,0x71,0x29,0x40,0x19,0x23,0xed,0x2c,0xdb,0x89,0x89,0x8d,0x69,0x22,0x4c,0x9c,0xa7,0xf7,0xb1,0x56,0x87,0xa3,0x44,0xa9,0xa3,0x16,0x28,0xce,0x94,0x40,0x6f,0x71,0x77,0x0e,0x6d,0xe9,0x78,0xa2,0x2a,0x17,0x45,0x03,0xeb,0x1e,0xf1,0xfa,0x56,0x3e,0xa7,0x6b +.byte 0x08,0x06,0x6a,0xcb,0x8f,0x5e,0x0f,0xd3,0x6e,0x4b,0x21,0x31,0x73,0x50,0x94,0x56,0xf9,0xb9,0xc7,0x38,0x69,0xe8,0x09,0x3f,0x03,0xb3,0xb5,0xe8,0x2a,0x5e,0xf6,0xad,0xae,0x6f,0xab,0x6a,0x49,0xdd,0x93,0x6d,0xfb,0x8b,0xde,0xea,0x8b,0xb0,0xa1,0x44,0xf0,0xb3,0xf6,0xaa,0xe3,0xc8,0x04,0x87,0x9f,0x8b,0xee,0xab,0x13,0x1d,0x2d,0xeb +.byte 0x09,0x62,0x21,0x49,0x5f,0xb6,0x95,0xab,0xc4,0xee,0x69,0xfb,0x31,0xff,0xbf,0x1a,0xa6,0x4c,0x67,0x66,0x84,0xe6,0x0c,0xb7,0xb2,0x3e,0x3f,0xa4,0xb3,0x52,0xde,0x15,0xc9,0xa7,0xa9,0xb5,0x0d,0xe5,0x0b,0x99,0xa6,0xb6,0x8f,0x69,0xc5,0x6d,0x6c,0xbb,0x83,0x89,0x4e,0xfc,0x49,0x79,0x4d,0x46,0x31,0xa0,0x09,0x5f,0x5d,0xd0,0x5b,0x80 +.byte 0xa1,0xf4,0x36,0x48,0x97,0x6a,0xfd,0x34,0xcb,0x20,0xa8,0x01,0x25,0x04,0xe7,0x13,0x12,0x87,0x66,0x27,0x96,0x36,0xba,0x92,0xbd,0xda,0x94,0x11,0xef,0x90,0xbd,0xbc,0x9e,0xf9,0x63,0xb3,0xa6,0xc1,0xbb,0x46,0xe8,0x86,0x3f,0x2d,0xf9,0x11,0x3a,0x23,0xa8,0x7a,0x33,0x41,0x3e,0x2e,0x5d,0xde,0xc0,0xd2,0x23,0xca,0x41,0xa0,0xb9,0x70 +.byte 0x6d,0x31,0xf3,0x89,0x87,0x9b,0x72,0xd9,0x15,0x4d,0x8b,0x51,0xdd,0x56,0xa1,0xb4,0x68,0x52,0x65,0x81,0x12,0x46,0xea,0x24,0xb4,0x34,0xcc,0xa0,0xdb,0x7d,0x96,0xd9,0x8e,0x64,0x61,0x10,0x7c,0x2a,0x00,0x4d,0x82,0x61,0x54,0xa4,0x70,0x3d,0x9c,0xa5,0x0b,0xd2,0x08,0x71,0xa8,0x94,0xb1,0xb4,0x30,0x61,0x59,0x9f,0x72,0x61,0x56,0x2d +.byte 0xa3,0xf4,0x9d,0x1c,0xfc,0x49,0x9d,0x39,0x27,0xcb,0x54,0xb2,0xce,0x3c,0xb6,0x76,0xe5,0x8e,0xa5,0xe7,0x08,0xd4,0xc7,0x2c,0xa6,0x28,0xc8,0x3e,0x22,0x14,0x06,0x75,0x68,0x0d,0x6b,0xb5,0xa3,0x68,0x14,0x17,0xfe,0xb8,0xcc,0x26,0x5b,0x9d,0x0b,0xcc,0x3e,0xd7,0x6c,0xe0,0xec,0x5e,0x1e,0x1e,0xb8,0x9a,0xbe,0x91,0xb5,0xa6,0xb5,0x83 +.byte 0x28,0xc2,0x35,0x65,0xd3,0xde,0xdd,0x71,0x29,0x13,0xc1,0xee,0x78,0x22,0x34,0x0b,0x77,0x3a,0x48,0x98,0x26,0x43,0xc2,0xce,0x03,0xe8,0x75,0xf8,0x8a,0xdf,0x6a,0xb0,0xb4,0x8c,0x11,0x8c,0xe5,0x95,0x96,0x17,0xfb,0x06,0x5e,0x8f,0x36,0x10,0xc5,0x04,0x43,0x1b,0xed,0xd3,0xad,0xd4,0xa4,0xe0,0x17,0x85,0xed,0x9b,0xd8,0xae,0x98,0x46 +.byte 0x58,0x57,0x0e,0x46,0xea,0x3f,0x07,0x6d,0x0e,0x46,0xda,0x2f,0x68,0x2b,0xd6,0xe7,0x0d,0x4b,0xbe,0x32,0xee,0x10,0x73,0x18,0x7d,0x6b,0x2d,0x04,0x27,0x72,0xb1,0xe1,0xbf,0x89,0xaa,0x4d,0x1a,0xfc,0xbd,0xf2,0xc3,0x9f,0xf0,0x01,0x85,0x62,0x09,0x4d,0x08,0x2c,0x57,0x9a,0x7b,0xad,0x0b,0x79,0xff,0x14,0xa1,0x45,0xde,0x21,0x8f,0xe2 +.byte 0x93,0xd0,0x35,0x26,0xc3,0xbc,0x8c,0xb7,0x57,0x6a,0xdf,0x98,0xa7,0x75,0xc6,0xf6,0x4b,0x5f,0x91,0x6e,0x71,0x3a,0x5c,0x5f,0x57,0x63,0x34,0x87,0xf8,0x20,0x6a,0xa1,0xbf,0xf8,0xca,0x8e,0xf9,0xa9,0x10,0x8b,0xab,0x0b,0xc2,0xcc,0x71,0x89,0x7c,0xef,0x70,0x3a,0xb0,0xf6,0x90,0xcc,0x6b,0x2c,0xcc,0x8b,0x2a,0x21,0x78,0x23,0xa0,0x71 +.byte 0x8c,0x7b,0xc1,0x0f,0x27,0x72,0x40,0xe4,0x9e,0x35,0xf3,0x0a,0xc0,0x7e,0x7f,0xe5,0x9b,0xdb,0x93,0x49,0x08,0xc3,0x6b,0xb7,0xea,0xea,0xd4,0x5a,0x96,0x97,0x3c,0xdf,0xc7,0x02,0x39,0x9f,0xa3,0xca,0xdd,0x62,0xf3,0x68,0xc7,0xae,0x37,0xc1,0x35,0x73,0xb2,0x5d,0x99,0xe4,0xae,0x27,0x55,0x5e,0x6a,0xae,0x6f,0x1a,0x95,0x51,0xb1,0x3b +.byte 0xd7,0xb4,0x4d,0x3d,0x88,0x54,0x01,0xbe,0x2c,0x12,0x17,0x29,0x4f,0xf3,0xed,0x5a,0x1f,0xa9,0xf0,0x67,0xbd,0x7c,0xad,0xe5,0x58,0x52,0xd4,0xd1,0xfe,0x1e,0x1b,0xd6,0xce,0x7c,0xc3,0xa2,0xa9,0x72,0x9b,0x6a,0xe5,0xf9,0x39,0x22,0xaa,0x7f,0x2e,0xa2,0x53,0x75,0xf0,0x99,0x2e,0x36,0x86,0x83,0x10,0x63,0xd7,0xac,0xa3,0x52,0xa6,0x23 +.byte 0x80,0x46,0xe4,0xa9,0x07,0x79,0xe1,0x61,0x75,0xbf,0x08,0x31,0x6c,0xdd,0xe1,0x30,0xd0,0x35,0xc2,0xbd,0x30,0xb8,0x85,0xf3,0xd2,0x2c,0x90,0x7a,0xf0,0xd3,0x80,0xe5,0xf1,0xc2,0x58,0x3d,0xf7,0x3c,0xbc,0xff,0x03,0x4d,0xf7,0xad,0x2f,0xa6,0xfe,0x73,0xde,0xa8,0x60,0xd7,0x89,0x4a,0xcf,0x3d,0xf3,0xab,0x62,0xfa,0x9d,0x46,0xad,0xd0 +.byte 0x97,0x6f,0x89,0x84,0x16,0x9b,0x84,0xb2,0x6c,0x63,0x6d,0x29,0xee,0x8e,0x97,0x3c,0x48,0x19,0x92,0x62,0xdc,0x1d,0x35,0x9d,0xec,0x01,0x00,0x64,0xbf,0x4d,0x8b,0xa3,0x13,0x48,0x9f,0xb4,0x01,0x0d,0xb1,0xc4,0xf2,0xf2,0x6a,0x84,0x1a,0x07,0x3c,0x46,0xa6,0xb5,0x41,0x9a,0x32,0x7e,0xc3,0x4f,0x87,0x95,0x71,0x7a,0xbf,0x74,0xf8,0x0b +.byte 0xfb,0xa5,0xde,0xa8,0x35,0xf1,0xcb,0x04,0x8d,0x8b,0xd3,0xb0,0xc8,0x1d,0x6c,0xaf,0xb4,0x21,0x79,0x1c,0x34,0x71,0x2f,0xf5,0xc4,0xbe,0xad,0xbc,0xaf,0x2f,0x54,0x81,0xd9,0xf8,0xff,0x59,0xf9,0x4e,0x62,0x9f,0x7d,0x7c,0xe9,0xdc,0x67,0xae,0xa3,0x32,0x4b,0xf7,0x4e,0x53,0x4c,0x55,0x7d,0xc5,0xdd,0xd4,0x5d,0x93,0xb8,0x98,0x3e,0xd3 +.byte 0x15,0x65,0x52,0x78,0x5a,0xd2,0x21,0x84,0x5d,0x28,0xaf,0x44,0x7d,0x18,0xf8,0xdd,0x5c,0xc3,0x6e,0xc8,0x05,0x05,0x30,0xd0,0x82,0xf8,0x00,0x0f,0x3d,0x5c,0x62,0x7e,0xa6,0xd5,0x7b,0x9f,0xb1,0x44,0xb7,0x0d,0x22,0x81,0xe1,0x4a,0x2b,0x79,0x7e,0x39,0x4d,0x8a,0x9a,0xfd,0x94,0x0c,0xf7,0x23,0x10,0x99,0xd2,0xd2,0x8b,0x98,0xe5,0x9d +.byte 0xb0,0xbf,0xcf,0x06,0x08,0x80,0x32,0x69,0xfd,0x81,0x5f,0xb3,0x66,0x11,0x63,0xeb,0x30,0x1d,0xcd,0x5b,0x5b,0xec,0x0c,0xca,0x30,0x37,0xa0,0x82,0x79,0x75,0x87,0xc1,0xfa,0x5b,0x38,0x4b,0xe3,0xea,0x46,0x49,0x36,0x92,0x92,0xf0,0xc9,0x15,0xa5,0xec,0x9e,0x21,0xb6,0x9f,0xb4,0x6d,0xf6,0xef,0x5c,0x2f,0x7d,0xa4,0xb3,0x25,0xfb,0x13 +.byte 0x40,0xe1,0xa0,0x20,0x4a,0x3a,0xe2,0x3e,0xf5,0xe0,0x68,0x61,0x11,0x9a,0xfb,0x1e,0xe8,0x1b,0xe0,0x17,0x9c,0x8a,0xe5,0x53,0x74,0xdd,0xec,0xc6,0x03,0xc6,0xd0,0x9b,0xc2,0x0b,0x77,0x4c,0x36,0x2b,0xac,0x4e,0x4d,0xd2,0x26,0x70,0x39,0x96,0xb4,0x11,0x1a,0x5b,0xcc,0x3f,0xb9,0xcf,0x0d,0x04,0x55,0x05,0x00,0x66,0x8f,0xa9,0xec,0x31 +.byte 0xe5,0x47,0x4c,0x9b,0xb7,0x6e,0xa5,0xe7,0x9e,0x70,0xf4,0x02,0x2a,0x3c,0xa2,0x03,0x04,0x30,0x9e,0x3f,0x7c,0xaa,0x0a,0x8f,0x55,0x61,0xca,0x50,0x35,0xe6,0xa4,0x24,0x61,0x26,0x31,0x9e,0x9e,0x77,0x0d,0x15,0x3a,0xc0,0x88,0x32,0xb5,0xbb,0x3d,0x3e,0x59,0x25,0x52,0x81,0x2e,0x4b,0xc6,0x5d,0x9f,0x87,0x0f,0x1f,0x5e,0xec,0xdd,0xbe +.byte 0x32,0x6c,0x71,0xef,0xd2,0x9c,0xfd,0x70,0xc8,0xf6,0x1f,0xb9,0xc9,0xdd,0x4d,0x39,0x61,0x92,0xbd,0x0c,0x48,0x63,0x4b,0xd2,0x2b,0x8c,0x4b,0x35,0xb1,0x8e,0x04,0x44,0x3c,0xe1,0xde,0xfd,0x6e,0xde,0xeb,0x94,0x51,0xea,0x36,0x7b,0xc6,0x87,0x15,0x34,0x68,0xa0,0xb8,0x94,0xb6,0x56,0x33,0xf4,0xab,0x84,0xed,0x1c,0x36,0x91,0xa7,0x1b +.byte 0x03,0xca,0x48,0x64,0x16,0x5b,0x4b,0x69,0x47,0xae,0xd7,0xc9,0xcf,0x74,0xd2,0xbd,0x60,0x04,0x7c,0x66,0xe9,0x12,0x92,0x40,0x78,0x23,0x0b,0x5b,0xa0,0xda,0xf7,0xe4,0x9a,0xad,0x9c,0x31,0xe7,0xaa,0xad,0x5a,0xc3,0x45,0x00,0x6c,0xd3,0x4d,0x93,0xdf,0xb6,0x68,0x11,0x3f,0x2a,0xbc,0x9a,0x8d,0xeb,0x0f,0xb5,0xa9,0x8e,0xa5,0x2c,0x99 +.byte 0x94,0x8d,0x21,0xa9,0x41,0x6b,0x11,0x2e,0x02,0x21,0xd8,0xc1,0xbc,0xf0,0x2a,0x87,0xae,0x35,0xa9,0x78,0x5c,0x43,0xb8,0xb7,0x63,0x2d,0x09,0x31,0xae,0x6f,0xfc,0x39,0x7b,0x18,0xc3,0xce,0xe3,0xfa,0x51,0x70,0xc7,0x6b,0x5e,0xc3,0xce,0xc8,0xa2,0x3a,0x66,0x9e,0xfe,0x45,0xb4,0xa2,0xaf,0x81,0x03,0x74,0xbf,0x0c,0x65,0x4c,0x30,0x27 +.byte 0xd5,0x34,0x29,0x2d,0x83,0xa8,0xb9,0x1d,0xf8,0x12,0x09,0x51,0xdd,0x0e,0x66,0x95,0xf3,0x94,0xaa,0x83,0x3a,0x6f,0x8a,0x7c,0x3a,0x29,0x82,0xbb,0x80,0xa1,0x37,0x8c,0x79,0xf4,0x4a,0xa8,0xe4,0x17,0x72,0x77,0xee,0xc4,0xaa,0x25,0xd3,0x8f,0x2e,0xaf,0xb9,0xb2,0x3c,0xa6,0xd5,0x72,0x97,0x07,0x23,0x38,0xae,0x9e,0x22,0x08,0x85,0x70 +.byte 0xfa,0xff,0x38,0xe6,0x96,0x9f,0x2c,0x11,0x14,0x16,0x9a,0xfa,0x5a,0x7b,0x05,0x31,0x3e,0x20,0xbf,0x4d,0x87,0xaa,0xba,0x94,0xcd,0xdb,0xeb,0xec,0x29,0x58,0x4e,0x43,0x12,0xe8,0xf9,0x01,0x50,0xc8,0x51,0x7a,0x61,0x12,0xe9,0xed,0xc2,0xd6,0x2e,0xd3,0xed,0x54,0x72,0xf7,0x1b,0x0c,0x8c,0xb4,0x65,0xea,0x22,0x31,0x22,0xeb,0xcd,0x53 +.byte 0x66,0xf1,0xa5,0x34,0xe9,0x81,0x74,0xcb,0xb5,0x6b,0x45,0x71,0x69,0x6d,0x84,0xe8,0xc6,0x86,0xc9,0xdd,0x0c,0xa4,0x30,0x12,0x08,0x42,0x10,0x6b,0xcd,0x65,0x6c,0xfd,0x9c,0xde,0x77,0x3c,0x32,0x09,0xef,0x99,0x27,0x0e,0x4a,0x72,0x03,0x8d,0xb5,0x68,0xa0,0x67,0xf7,0xc2,0xae,0xb8,0xce,0x41,0x70,0x4e,0xdd,0x13,0xcb,0x3f,0x05,0x4e +.byte 0xf4,0xbc,0x88,0x98,0x2f,0x42,0x4e,0x5f,0x3e,0xcb,0x2c,0xd3,0x2f,0xb8,0x92,0xbb,0xd8,0x95,0xc8,0xaf,0xa9,0x44,0x8b,0xf0,0x2f,0x81,0xd4,0xe7,0x06,0x19,0xf7,0xa7,0x0a,0x73,0x3e,0x30,0xd9,0x00,0xe4,0x2d,0x76,0xb1,0x0d,0xfa,0x12,0x1f,0xbe,0x59,0x4f,0xf7,0xc8,0x5b,0xab,0xd7,0x16,0x3d,0x7e,0x97,0x9e,0xec,0xf8,0xcb,0x31,0x2e +.byte 0xe0,0x41,0x0b,0x00,0xa6,0x6d,0xe9,0x5e,0xd5,0x4a,0xc5,0xbf,0x1c,0xcc,0xa5,0x71,0x94,0x29,0x3d,0x17,0x43,0x27,0x63,0xc4,0xc7,0x8f,0x1b,0xb7,0x5f,0xcf,0xdf,0x8e,0x6a,0x69,0x87,0xc1,0x29,0xab,0x7b,0x8d,0xdf,0x07,0x95,0x50,0xa3,0x1c,0x8e,0xdc,0x7f,0x8a,0x21,0x37,0x1e,0x26,0xa7,0x67,0x28,0xb2,0xc8,0x23,0x5a,0x1d,0x94,0x46 +.byte 0x1b,0x3e,0x72,0x87,0x73,0x08,0xe2,0x3b,0x46,0x51,0xbe,0x5b,0xa9,0x72,0xb9,0xf8,0x45,0x6d,0x0c,0x89,0x80,0x0d,0x7a,0xfb,0x4c,0x3f,0x7f,0x3d,0x29,0xff,0xef,0xb2,0xec,0x23,0xc2,0x26,0xcf,0x8c,0x2e,0x28,0xbf,0xc5,0x68,0x47,0xd9,0x49,0x95,0xf1,0x67,0x7e,0x3a,0x48,0xe2,0x43,0x5c,0xc8,0x95,0x5b,0xb2,0xf3,0x22,0xc9,0x73,0x91 +.byte 0xb5,0x78,0x96,0x1b,0x9a,0x75,0x5f,0xb2,0x6b,0x8c,0x66,0x8c,0x8e,0xc1,0xe1,0xde,0xd6,0x64,0x31,0xe1,0x7b,0x12,0xd2,0x85,0x8f,0x52,0x68,0xec,0x80,0x26,0x3d,0xcc,0x9b,0xe3,0x57,0xbe,0x19,0x42,0xb9,0xdd,0x7d,0x2b,0x5b,0x6d,0x1b,0x9e,0x96,0xd7,0x75,0x83,0x82,0x3c,0x3e,0x5f,0xf8,0xa9,0x36,0xbe,0x14,0xc7,0xce,0x9d,0x05,0x7e +.byte 0xd7,0x38,0x37,0x35,0xc9,0x37,0x8b,0x9f,0xc6,0x2d,0xff,0x00,0x41,0xff,0x1b,0x09,0xea,0xd2,0xb0,0x04,0x48,0xff,0xfc,0xb5,0x67,0x54,0x39,0x3d,0x23,0x68,0x0b,0x7d,0x97,0xf3,0x65,0x20,0xa2,0xf8,0x33,0x96,0xd1,0xf4,0xc7,0xba,0x6f,0x00,0x95,0x36,0xf6,0x33,0xd1,0x8d,0xde,0xee,0x1e,0xfa,0x60,0x8e,0x5e,0x4c,0x70,0xbb,0x53,0x79 +.byte 0xc9,0x9a,0xdf,0x3c,0x53,0xe4,0x35,0x87,0xc3,0xe6,0x8e,0x0e,0x1a,0xd0,0xf8,0x57,0x2b,0x33,0x51,0x4d,0x7d,0x43,0x17,0x3e,0x6f,0x0e,0xca,0x86,0xb2,0xc6,0x09,0xf3,0x2f,0xc1,0x5f,0x0e,0x9a,0x5e,0x7d,0x9d,0xf7,0xff,0x09,0x46,0xe5,0x30,0x91,0x61,0x93,0xb5,0x2f,0xc5,0x7f,0x09,0x0b,0x55,0x94,0x17,0x25,0x19,0x9b,0xa9,0x0e,0x68 +.byte 0x71,0x18,0x1b,0x4b,0x1b,0xa3,0x75,0x90,0x56,0x96,0x5e,0x33,0x71,0xf2,0x06,0x69,0x07,0x04,0xcb,0x8c,0x79,0x9b,0xa5,0x17,0xd8,0xd8,0x77,0xc7,0xca,0x95,0x58,0x12,0xec,0xdd,0x41,0xc9,0x12,0x16,0x9a,0xc4,0xf0,0x27,0x7a,0x8e,0xeb,0x19,0x79,0x27,0x7b,0x2e,0x55,0x96,0x57,0x19,0xbe,0x55,0x8c,0x7f,0x97,0x90,0x80,0x40,0x5d,0x5a +.byte 0xf6,0x07,0xd6,0xb4,0xc5,0xe8,0x0e,0x54,0xde,0x78,0x23,0xca,0x39,0x90,0x42,0xb6,0x8b,0x14,0x22,0x06,0x71,0x77,0xd5,0xf7,0x8d,0x05,0x9d,0xbf,0xfe,0x38,0x91,0xba,0x79,0x85,0x30,0x47,0x25,0xf0,0xa2,0x72,0x55,0x94,0x2a,0x8a,0xc8,0x28,0xc8,0xa9,0x23,0xab,0xf0,0x4e,0x49,0x2f,0x58,0x53,0x35,0xd1,0xb6,0x16,0x81,0xc2,0x25,0x18 +.byte 0xd9,0x71,0x91,0xc4,0x81,0x3e,0xf4,0xd7,0x87,0x9e,0x57,0x78,0xf7,0x7d,0x4b,0xb2,0xfd,0x91,0x9f,0xa8,0x0e,0x77,0xb3,0xc7,0xe5,0x6a,0x95,0x17,0xc3,0xf4,0xcb,0x7f,0x96,0xc1,0xa8,0xee,0x6a,0x0f,0x1f,0x5d,0x20,0x28,0x93,0xe5,0xf3,0x13,0x46,0x53,0x47,0x9f,0x98,0xc6,0xf5,0x29,0x69,0xb9,0x83,0x36,0x03,0xa1,0x9a,0xb4,0xa9,0x4e +.byte 0xd6,0xda,0x25,0xe2,0x5b,0xbb,0x95,0xdf,0x0f,0x37,0x0b,0x02,0x51,0x03,0xd1,0x0e,0x84,0xef,0xdd,0x85,0xdd,0xae,0x10,0x32,0x65,0x03,0x65,0xf0,0x8e,0x0c,0x69,0x90,0x35,0x26,0x36,0xe8,0x05,0x46,0xe6,0xce,0x52,0x4d,0xb5,0x93,0x9f,0xe3,0xe5,0xb0,0x43,0x57,0x32,0x5d,0xca,0xd4,0xc9,0x89,0x2e,0x5b,0x03,0x8a,0x82,0x78,0x21,0x6b +.byte 0x41,0xa9,0x0a,0x9f,0xe0,0x50,0xec,0x72,0x01,0x67,0xe7,0x1c,0x92,0xe3,0xe4,0x83,0x4d,0x4b,0xcf,0x01,0x37,0x2f,0x34,0x86,0xcf,0x36,0xf7,0x3a,0x57,0xa3,0x89,0x73,0x0f,0x9c,0x06,0x82,0x75,0x7a,0x4b,0xd8,0x44,0x40,0xf2,0xc5,0xc4,0x22,0xa6,0x99,0x1b,0x73,0x2f,0xad,0x09,0xe9,0x84,0x6f,0xc3,0xca,0x72,0x3a,0x8a,0x55,0x55,0x0a +.byte 0xcd,0x33,0x51,0xef,0x5b,0x36,0x77,0x6c,0xb4,0x4a,0xae,0xdd,0xbd,0xec,0x65,0x99,0x43,0xd6,0x8a,0x16,0xba,0x89,0x4d,0x0c,0x11,0xb4,0x0d,0x5d,0x3e,0x76,0xcb,0x48,0x9d,0x31,0x40,0x71,0xe2,0xe4,0xa9,0xd9,0x6e,0x3c,0x3d,0xd1,0x6e,0xaf,0xb9,0x28,0x71,0x5a,0x07,0x6f,0xab,0xdb,0xf8,0x4f,0x11,0xbc,0xe0,0x14,0x01,0x43,0x4d,0xe2 +.byte 0xad,0x5d,0x2a,0xb2,0x58,0x66,0x05,0x50,0x66,0xf6,0x2f,0x66,0x11,0xd1,0xd7,0x05,0x85,0xb0,0x7f,0xa8,0x89,0xbd,0x41,0xda,0x35,0x1e,0xbb,0xff,0x70,0x1a,0xe8,0x65,0x96,0xe9,0x50,0x18,0x7f,0x4c,0xb2,0xe2,0x95,0x26,0xf6,0x37,0x09,0x8c,0x8d,0x7b,0x02,0xb0,0x7f,0x32,0xb5,0x70,0x22,0xd6,0x83,0x0b,0x85,0x25,0x00,0xc5,0x55,0x3f +.byte 0xfa,0x7a,0xc9,0xaf,0x87,0xc1,0x1c,0x11,0x96,0x71,0x18,0xd8,0xdb,0xab,0x86,0x57,0x0a,0x16,0x23,0x32,0x40,0xd3,0xaf,0x17,0x55,0xe3,0xe7,0x01,0x65,0x1f,0x87,0xda,0xb5,0x46,0x67,0x18,0x34,0xcc,0x28,0x77,0xc3,0x12,0x62,0x6c,0x8b,0x8a,0x11,0x7a,0x5a,0xd1,0xdf,0xb3,0x13,0x6b,0x29,0xce,0xf8,0x03,0xba,0xad,0x7c,0x14,0x60,0x42 +.byte 0x17,0xf6,0x7b,0x0c,0xb7,0x5f,0xd6,0xc1,0xb5,0xa5,0x2b,0xb1,0x9f,0x6c,0x65,0x29,0xe5,0xf4,0x84,0x85,0x11,0x82,0xf1,0x4c,0xcd,0xff,0x99,0x29,0x53,0x7b,0x43,0x04,0x60,0xc4,0x6c,0x01,0x5c,0xcb,0x33,0x4f,0xdb,0xc4,0xad,0x8c,0xea,0xff,0xd6,0xcd,0x8e,0x85,0x6e,0x54,0xd5,0x18,0x63,0x84,0x78,0xea,0xff,0x08,0x95,0xdc,0x2a,0x07 +.byte 0xac,0xea,0x44,0x79,0x52,0x07,0xf3,0xf1,0x03,0x7f,0x71,0x53,0xd8,0x85,0xdb,0x70,0xde,0x5e,0xd5,0x9a,0x18,0x9f,0xcc,0x3f,0xc0,0xc0,0x49,0x82,0x70,0x09,0xce,0x29,0x04,0x0a,0x19,0x81,0xd9,0x81,0x22,0x71,0x48,0x8e,0x79,0x08,0x1c,0xb4,0xc8,0x7e,0x60,0x43,0x4a,0xe3,0xd5,0x6b,0x09,0x5c,0x01,0x6e,0x20,0x9e,0xd2,0xaf,0x80,0xb7 +.byte 0xa2,0x0a,0x5b,0x26,0x08,0x32,0x73,0xbc,0xc6,0xfd,0x06,0xaa,0x2e,0x55,0xa0,0x5b,0xa9,0x3c,0x85,0xb2,0x04,0xdc,0x9a,0x94,0x02,0x93,0x96,0x6b,0x3e,0xc3,0x5e,0x37,0x9b,0x6f,0xef,0xb9,0x65,0x52,0x42,0x1c,0xa7,0x84,0x09,0x0c,0x49,0x3a,0x95,0x06,0x94,0xd7,0xc7,0x40,0xf5,0xf1,0x69,0x41,0xfb,0xf8,0x57,0xb5,0x1e,0x0c,0xf3,0xd9 +.byte 0xb1,0x2e,0x58,0x33,0xbe,0xb1,0x3d,0x61,0xc6,0xca,0x01,0xe5,0xda,0x60,0x8f,0x87,0xf7,0x9a,0xb5,0x92,0xb4,0x8c,0x2a,0xaf,0xd4,0x1e,0x9c,0x97,0x39,0x83,0x99,0x4a,0x07,0x54,0x75,0x7d,0xde,0x72,0x06,0xc1,0x8f,0xb4,0xde,0x12,0x43,0xf2,0x62,0xae,0xe7,0xec,0xfe,0xb2,0xe5,0x63,0x35,0xb7,0xee,0xaa,0xf0,0x09,0xb8,0x61,0xf2,0x42 +.byte 0x28,0x87,0xd7,0x47,0xa8,0xfc,0x51,0x85,0x6f,0xa2,0xb1,0xa6,0x82,0xd6,0x0e,0x1b,0x3f,0xea,0xa1,0xe1,0x91,0xc9,0xd2,0x5b,0x3e,0xff,0x18,0x39,0x14,0xe0,0x44,0xda,0x3d,0xd8,0xca,0xdb,0xd9,0xbf,0x3f,0xa4,0xdb,0x99,0x2e,0x31,0x32,0x7c,0xf4,0x61,0x2f,0xa1,0xf9,0xa9,0xbe,0x26,0x94,0xea,0xb4,0xe3,0x25,0x8d,0x93,0x3b,0xa1,0x7e +.byte 0x1e,0x99,0x87,0x6c,0xaf,0x14,0x54,0xd0,0xc0,0x37,0x39,0x76,0x3c,0x07,0x2e,0xce,0x98,0x25,0x81,0xe4,0x01,0x0c,0x07,0x79,0x4e,0xcd,0x82,0x44,0x83,0x04,0x07,0xa6,0x52,0xb7,0x96,0x7c,0x43,0x12,0xe1,0xc5,0x12,0x18,0x25,0x47,0xe4,0x19,0x6d,0x26,0x1e,0x55,0x66,0xca,0x28,0x4c,0xfa,0xd2,0xd9,0xcc,0x7e,0xad,0x9f,0x2a,0x2f,0xc6 +.byte 0x6c,0x77,0xaa,0x0f,0x5b,0xeb,0x15,0x97,0x62,0x52,0x3c,0x6f,0x4b,0xf3,0xcc,0x80,0x7b,0x1f,0x1d,0x58,0xf8,0xfe,0xc1,0x8c,0x3b,0xe3,0xd7,0x05,0xc3,0xd6,0xa9,0xda,0xcf,0x85,0x1c,0x68,0xd6,0x6d,0x2b,0x06,0x30,0x5f,0x58,0x39,0xea,0xfa,0x99,0xaa,0x04,0x10,0x05,0xaf,0xb0,0xf7,0x32,0x60,0x8d,0xe4,0xd1,0x40,0x32,0xd6,0xa3,0xf2 +.byte 0xba,0x5a,0x79,0x58,0x92,0x75,0xf0,0x3a,0xce,0xb2,0xee,0x66,0x3e,0xe3,0xbe,0x4d,0x53,0x9d,0xbb,0xdb,0x45,0xf0,0x09,0xeb,0xd5,0x83,0x39,0x20,0x06,0xa9,0x44,0x35,0xeb,0x6d,0x9b,0xd9,0xa4,0xda,0x4b,0x9d,0xde,0x3d,0x26,0xa2,0x2d,0xcf,0x8e,0x3e,0xbc,0xb4,0x8c,0x3a,0xbf,0x56,0x7c,0x48,0x50,0xb5,0xc5,0xbe,0x84,0x5e,0x63,0x82 +.byte 0x5f,0x87,0x77,0x4a,0xa7,0xf6,0x66,0x07,0x42,0x6a,0xb0,0xcf,0x19,0xaf,0x6c,0x16,0x85,0x78,0x88,0x3b,0xa5,0xbc,0x42,0xd2,0x4c,0xdf,0x51,0x3b,0xc4,0x0e,0xf5,0xc5,0x70,0x57,0x40,0xf6,0xed,0xd2,0x37,0x3e,0x14,0x0c,0x31,0xda,0x94,0x87,0x6b,0xd9,0x8c,0x15,0x41,0xa9,0xc0,0x2a,0x61,0xd3,0x52,0xe0,0xb6,0x0a,0x83,0x6b,0x75,0x1b +.byte 0x1e,0xd1,0x7f,0x26,0x19,0x34,0x9b,0x70,0xc9,0xba,0xdc,0xa2,0x03,0x6d,0xc7,0xac,0xbd,0x2c,0x63,0x8a,0x7b,0xb1,0x62,0x51,0xc1,0x1d,0x54,0x0d,0x34,0x0e,0xfb,0xa6,0xb8,0x9d,0x79,0x4f,0xc3,0xaa,0x8d,0xa0,0xcc,0x80,0x96,0x86,0x37,0xd6,0x80,0x9c,0x3d,0x91,0xd0,0xe7,0xe2,0xb4,0x00,0xba,0x86,0xe9,0xeb,0x86,0xea,0x84,0x78,0x81 +.byte 0x20,0x29,0x28,0x02,0x4d,0xd8,0x1b,0x5e,0x4f,0x41,0xfc,0x13,0x3e,0x4c,0x7f,0x64,0x55,0x35,0x41,0x0d,0x74,0xc5,0x6a,0x7c,0x37,0x82,0x41,0xbd,0x67,0x39,0xd9,0x83,0xfa,0x7f,0x8c,0xe1,0x9f,0x23,0x0d,0xe4,0x1d,0x40,0xe6,0x6e,0x94,0x5d,0xec,0x77,0xf7,0x5e,0xb4,0xa1,0x03,0xfb,0xa0,0x0e,0xba,0xf8,0x28,0x50,0x3c,0x38,0x47,0xf7 +.byte 0xed,0x2d,0xe5,0x0b,0xa8,0x7a,0xbd,0xbf,0x7e,0x38,0xc0,0x60,0xe7,0x7e,0xb1,0x03,0xef,0x4a,0x8c,0xc7,0x98,0xf1,0x94,0xf6,0xa0,0x50,0xb2,0x0b,0x7c,0x66,0x0a,0x62,0x10,0x24,0xb0,0xa1,0x69,0x02,0x33,0x79,0xbf,0xd0,0xb5,0xcb,0x17,0x20,0x55,0x02,0x70,0x44,0x5b,0xac,0x20,0x35,0xea,0x05,0x2d,0x68,0x51,0xe7,0x5f,0x1b,0xcd,0x4c +.byte 0x33,0x4d,0x04,0x21,0xfd,0x06,0x67,0x82,0x60,0x98,0x1f,0x79,0xf4,0x28,0xe0,0xa8,0x18,0xeb,0xf5,0x86,0x58,0xe6,0x9f,0xb5,0x29,0x0f,0xe8,0x37,0xeb,0x09,0xf4,0xc6,0x08,0xf2,0xde,0x4d,0x96,0x48,0x62,0x36,0x63,0x10,0x3f,0x63,0xeb,0x44,0x84,0xc8,0xf5,0x74,0x19,0x03,0x50,0xf7,0x7c,0xd2,0x06,0x20,0x6e,0x9b,0xa2,0x37,0xb0,0x68 +.byte 0x78,0x31,0xb6,0x05,0xfa,0xc9,0xcd,0x1d,0x4c,0xbd,0x33,0xb7,0xf3,0x93,0x38,0x7d,0x5f,0x00,0x85,0x5b,0x10,0x7f,0xc4,0x3f,0x3e,0xfe,0x62,0xca,0x51,0x83,0x95,0xcf,0x00,0x65,0x83,0x0e,0xd3,0x78,0xd0,0x51,0xcb,0x70,0x34,0x42,0xc6,0x3a,0x04,0xb9,0x10,0x92,0xe0,0x09,0x06,0xb0,0x66,0x9b,0x37,0x02,0x8d,0x0d,0x3e,0x2f,0xc5,0x17 +.byte 0x6a,0x87,0x7d,0x48,0xa4,0xcc,0x55,0x20,0x7b,0x77,0x07,0xcf,0x44,0x2f,0x88,0x8a,0xcc,0xf2,0x5d,0xa6,0x3e,0x5f,0xda,0xe2,0xde,0xd2,0x7f,0x7f,0xb7,0x90,0x53,0x64,0x6b,0x79,0x42,0x52,0x69,0xc6,0xd6,0xaa,0x9f,0xf9,0x19,0xbe,0x65,0x10,0x99,0x49,0xaf,0x36,0x49,0x1b,0x8a,0x3d,0x7f,0xdb,0xa2,0x1a,0xb5,0xd6,0x34,0x51,0xc8,0xc8 +.byte 0x06,0xca,0xf6,0xb8,0x76,0xa8,0x9d,0x43,0xae,0xf0,0x51,0xe5,0x9a,0x42,0xa2,0x83,0xed,0x20,0x8d,0xe8,0x1c,0xca,0x15,0x4e,0x37,0x3f,0xd8,0x06,0xa0,0xe1,0xf8,0x05,0xfd,0x42,0xf3,0x7a,0x96,0x44,0x36,0x02,0xca,0x11,0x2a,0xc3,0x24,0x58,0xdd,0x85,0x55,0xb2,0xe5,0x1d,0x92,0xc2,0x2d,0x5f,0x7c,0xb5,0x02,0x37,0x7c,0x07,0x35,0x25 +.byte 0x2b,0x33,0x80,0xe2,0xd4,0xfd,0xc7,0xa7,0x19,0x7e,0xba,0x36,0xaf,0xa0,0x4e,0xab,0x8b,0x28,0x4f,0x3b,0x92,0x72,0x42,0x49,0xaa,0x3b,0x08,0x0f,0x1e,0xff,0x2d,0xbf,0x9c,0x48,0x16,0x72,0xbe,0x28,0x05,0x8b,0x3a,0x20,0x6b,0x38,0x43,0xa2,0x35,0xea,0xf7,0x4e,0x50,0xa0,0x43,0x40,0x5c,0xbf,0xe5,0x75,0x13,0x4c,0x36,0x61,0xa1,0x5d +.byte 0x46,0xd7,0x7a,0x94,0x06,0x2f,0x63,0x32,0x9c,0x6e,0x54,0x18,0x31,0x79,0xf2,0x83,0xcf,0xb4,0x47,0x40,0xe5,0x9a,0xd6,0x99,0x12,0xb3,0x61,0x3d,0x0f,0x5e,0xc8,0x95,0xa3,0x5f,0xc3,0xd5,0x6b,0x6e,0xa0,0xf2,0x2f,0xeb,0x66,0xd0,0x68,0x67,0x10,0x85,0x64,0x27,0xd8,0xb8,0x68,0x00,0x36,0xa5,0xab,0x3e,0xe1,0x43,0x65,0x81,0x2d,0xb9 +.byte 0x0f,0x87,0xfe,0xa1,0x52,0xe9,0x8d,0x82,0x3a,0xd1,0x10,0x52,0x34,0x48,0x7c,0x1c,0xc6,0xd0,0xfe,0xa0,0x1a,0x92,0x07,0x88,0x57,0x9e,0xd7,0x5e,0x9f,0xc8,0xb0,0x93,0x73,0x03,0x28,0x36,0x8c,0x25,0x8c,0x0f,0x4e,0x0f,0x5b,0x26,0x58,0xed,0x5c,0x33,0x75,0x20,0x08,0x11,0x47,0xe1,0x47,0x85,0x47,0xeb,0x54,0xbf,0x58,0xe3,0xd4,0x5b +.byte 0xf9,0xc6,0x5e,0x42,0x58,0xe6,0xaf,0x79,0x66,0x3c,0xa5,0xa3,0x30,0x33,0xe3,0xbe,0x21,0x4b,0x42,0x98,0x6e,0x44,0xd7,0x68,0xc0,0xff,0xbe,0x7f,0xc5,0xb3,0x4f,0x4a,0x93,0xb0,0x11,0x88,0xcf,0x36,0xb2,0x03,0xbe,0x30,0x52,0x71,0x20,0x0d,0x16,0xc5,0xbb,0xf5,0x92,0x12,0x67,0x6a,0x35,0x66,0x00,0x09,0xd7,0xc6,0x67,0xb0,0x6a,0x04 +.byte 0x19,0x3e,0xbf,0xe2,0x82,0x74,0x78,0x2f,0x77,0x44,0xdc,0xad,0x0f,0x66,0x2a,0x23,0x62,0x2c,0x5a,0x4e,0x3a,0x82,0x2a,0x75,0x16,0x0d,0x74,0x64,0x35,0x53,0xc5,0xf6,0xda,0x36,0x44,0xba,0xe2,0xfa,0x1e,0xc2,0xcf,0x29,0x01,0x36,0x66,0xc3,0xca,0x40,0xf7,0xc4,0xba,0x67,0xac,0xf6,0x17,0xcc,0xa3,0x96,0x2d,0x08,0x5f,0x0a,0xea,0x5e +.byte 0x97,0xdc,0xc8,0xf9,0x59,0x24,0x6e,0xc5,0x0b,0x02,0xb9,0x1a,0xde,0xac,0x60,0x1d,0xaf,0x9f,0x5a,0x6f,0xe1,0xa6,0xdf,0x75,0xc5,0x9b,0xb7,0xde,0xa4,0xf7,0xf6,0xa4,0xdc,0xb6,0x96,0x08,0xde,0x2a,0x0e,0xb3,0x9d,0xf5,0x75,0x7d,0x7e,0x96,0x91,0x79,0xd4,0xa7,0x30,0x97,0x3a,0xbd,0x7c,0xe0,0xc5,0x87,0x24,0xb0,0x65,0xb7,0x58,0x00 +.byte 0xd9,0x0e,0x97,0xa6,0xa4,0x6a,0xe8,0x0a,0xac,0xac,0x9f,0x3a,0xe3,0x2a,0x9a,0x43,0x41,0x92,0x6e,0x0e,0xc4,0x63,0xc3,0x18,0xb6,0xe1,0xef,0x3d,0xe8,0x0b,0xb0,0x9f,0x2e,0x19,0xa0,0x98,0x98,0x34,0xf8,0x86,0x6d,0xc5,0x8c,0x41,0x26,0xb7,0xf2,0x1d,0xd4,0x72,0x39,0xeb,0x79,0x06,0xaf,0x53,0xaa,0x34,0x80,0x53,0xf8,0x1b,0xf4,0x53 +.byte 0x19,0xfa,0x16,0x8b,0x39,0xea,0x63,0x7f,0x38,0xc4,0x66,0x1d,0xd1,0x90,0xe4,0x2f,0x20,0x43,0x0d,0x5f,0x98,0xcc,0xae,0xef,0x86,0xc8,0xe5,0xf6,0xd2,0xa5,0x49,0xd0,0x3f,0xb5,0x7e,0x42,0xb5,0x6e,0x5e,0x13,0xa5,0xb4,0x71,0x2c,0x5d,0x57,0x24,0x06,0xd2,0x29,0x7c,0x4c,0x90,0xb6,0xea,0xdb,0x62,0xa4,0x2c,0x6c,0x38,0x57,0x97,0xbd +.byte 0xfd,0x41,0x6e,0x26,0xc1,0xe1,0x6b,0xbb,0xf0,0xe7,0x71,0xf1,0xcf,0x6a,0x7f,0xfa,0xe7,0xfb,0x17,0xe7,0x81,0x19,0x9a,0xf2,0xf6,0x86,0x22,0x4f,0x62,0x59,0xd6,0xc2,0x33,0xbd,0x11,0xe7,0x07,0x3a,0xfe,0x74,0x0d,0xf8,0xd9,0xdb,0xbd,0x05,0xf4,0xf4,0xb1,0x41,0xc9,0xb3,0xf8,0x6a,0x7b,0x98,0x08,0x6c,0xce,0x4c,0x28,0xbf,0x8c,0x77 +.byte 0x68,0xdc,0xee,0xf7,0x11,0xde,0xfc,0x5a,0x58,0x4f,0xf4,0x74,0x9d,0x5b,0x78,0xc3,0x78,0xe5,0x5e,0x26,0x83,0x40,0x17,0x80,0x2a,0x02,0xa4,0xf1,0x0f,0xa0,0xc8,0x22,0xe6,0x09,0x3a,0x52,0x74,0xf0,0xb9,0xb9,0x60,0xaf,0x20,0xa6,0x7e,0x88,0xf4,0xc2,0x38,0xa2,0x21,0x73,0xa9,0x18,0x3f,0x7a,0x04,0x7b,0xc4,0xcd,0x68,0xd9,0x83,0xa4 +.byte 0x8e,0x54,0x0d,0xbc,0xee,0x8b,0x39,0x93,0x66,0xa2,0xd6,0x76,0x4a,0xb2,0x33,0x4f,0x61,0x53,0xde,0x3b,0xff,0x47,0xcb,0x87,0xd9,0x21,0xd0,0x82,0x64,0x54,0xdf,0xf2,0x67,0x62,0x40,0x33,0xc7,0x0d,0xea,0x98,0xaa,0x95,0xfb,0xa9,0x0e,0x90,0xa5,0xd9,0x54,0x81,0x86,0xad,0x9e,0xa4,0x4d,0x36,0xe1,0x77,0xf2,0xe3,0x0a,0x54,0x1a,0x57 +.byte 0x9d,0x62,0x5e,0x0e,0x00,0xc8,0xa6,0x1e,0xf3,0x43,0xe6,0x20,0x0d,0x6a,0x8e,0x90,0x1d,0x4d,0xac,0x2f,0x9f,0x1c,0xb7,0x30,0xec,0x5c,0x99,0x78,0x6f,0x3b,0xe7,0xe0,0x28,0xb9,0x97,0xc5,0x6a,0xf2,0x17,0xc2,0x11,0xac,0x1a,0xe2,0xca,0x57,0x49,0x64,0xc8,0xc7,0x66,0x43,0x8d,0xc8,0xa7,0x0e,0xfc,0xcf,0x05,0x2f,0xae,0x4b,0xfe,0xe4 +.byte 0xbe,0x9c,0xe7,0xe6,0xa8,0x36,0x49,0x0d,0x9c,0x60,0x39,0x0c,0xfd,0x41,0x5b,0xc7,0xa4,0xa5,0x30,0x89,0xe5,0x10,0xf6,0xea,0xf8,0x2c,0xf2,0x3e,0xb1,0x96,0x81,0xa7,0x32,0x8b,0x39,0x14,0x15,0x36,0xfc,0x55,0x3c,0x22,0xcf,0xa3,0x98,0x90,0x68,0x13,0xd8,0x3f,0xf2,0x53,0x19,0x3e,0x9a,0x0c,0x1f,0xc6,0x29,0x43,0x46,0x23,0x58,0xea +.byte 0x49,0x49,0x15,0x46,0x8e,0x63,0x30,0x1f,0x3e,0x2a,0xa0,0x18,0xfd,0x28,0xc5,0x32,0x77,0x75,0xac,0x6e,0x5d,0x39,0xa9,0x44,0xce,0xfe,0x39,0xa6,0xec,0xde,0x69,0xde,0xfa,0xc8,0x40,0x44,0x34,0x29,0x15,0x19,0xa7,0xbe,0xd6,0x5b,0xfd,0x1f,0x7b,0xb9,0x88,0xf1,0x14,0xcf,0x42,0xc5,0xa7,0xa7,0x0e,0x6b,0x6e,0x86,0xb2,0x7c,0x23,0x8e +.byte 0xf6,0xae,0xde,0x3c,0xd7,0x26,0x5e,0xde,0x31,0x94,0xc1,0x19,0x65,0x55,0x03,0x73,0xba,0xdc,0x69,0x95,0x9c,0x9d,0x8e,0x59,0xd8,0x51,0x61,0x9f,0x8f,0xf4,0x29,0x43,0x4b,0x6a,0x75,0xb3,0x4b,0x9d,0xcc,0x46,0xd2,0x6e,0x00,0x49,0x4f,0xf0,0xac,0x80,0x55,0xc0,0x0c,0xbf,0x18,0x52,0x75,0x76,0x3b,0xac,0x92,0x83,0x69,0x1b,0xb4,0x15 +.byte 0xe5,0x9e,0xde,0x10,0x30,0x30,0x0e,0x85,0xc7,0xf9,0xae,0xbc,0x9e,0xaf,0x4b,0xee,0x27,0x6b,0xa5,0x6d,0xe4,0x8e,0xed,0xdd,0x95,0xaa,0x85,0xe2,0xf5,0x38,0x15,0x50,0xd3,0xcd,0x2c,0x88,0x6c,0x2b,0x14,0x37,0x74,0x2d,0x6d,0x30,0xec,0x96,0x78,0xae,0x80,0xb3,0xd9,0x84,0xc1,0xd6,0x71,0x90,0xe4,0x8d,0x3a,0x7c,0x9c,0xc4,0xf5,0xa0 +.byte 0x20,0x7e,0xa2,0x0e,0x75,0x7c,0x25,0x7a,0x7e,0x2b,0x2e,0xdb,0x12,0x23,0x73,0x6a,0x8e,0xe3,0xd7,0x47,0x94,0xfb,0xcc,0xe4,0x5a,0x8c,0xfb,0xdc,0x46,0xb3,0x4a,0x42,0x15,0xe0,0xaf,0x6e,0x81,0x72,0x72,0x04,0x52,0x09,0xc5,0x8b,0x6e,0xdd,0x7d,0xff,0x27,0xa8,0xc1,0x94,0xb5,0x33,0x59,0xc2,0x7d,0x59,0x6c,0x3c,0xaa,0xd9,0xd8,0x05 +.byte 0x43,0x7e,0x8a,0x47,0xdd,0x76,0x36,0xe3,0x05,0x49,0xd1,0x8f,0xdf,0x45,0x46,0x63,0xff,0x17,0xb4,0x52,0xc8,0xee,0x4d,0xf5,0x74,0x65,0xc6,0xca,0x19,0xfd,0xb9,0x51,0xc8,0xc9,0x96,0xd4,0x06,0xd4,0x09,0x1e,0xab,0x6d,0x1b,0x26,0x61,0x80,0x5b,0xa8,0xcb,0x62,0x92,0x5a,0x1a,0x8e,0xa4,0xb7,0x25,0x19,0x96,0x63,0xd5,0xc3,0xc9,0xdc +.byte 0x04,0x83,0x62,0x31,0xe3,0x76,0x00,0x4d,0xf8,0xb3,0x98,0xae,0x4d,0x1a,0x38,0xe3,0xa1,0x27,0x52,0x87,0xbe,0x2c,0x93,0x45,0xd1,0xab,0x56,0xc6,0xf5,0xbc,0xb5,0xe6,0x9c,0xe1,0x1b,0x37,0x42,0x08,0xe7,0x71,0xb5,0xa4,0x67,0xf9,0x48,0xd4,0xc4,0x10,0x25,0x53,0x9c,0x03,0xfc,0x6d,0x5e,0x62,0x5e,0x6d,0x56,0xbc,0x78,0x11,0x0a,0x6d +.byte 0x1b,0x7a,0xdc,0x62,0xb5,0x58,0x86,0x15,0x71,0xff,0x11,0x33,0x94,0x2b,0xa6,0xc7,0x68,0xd5,0x68,0xda,0x5b,0xd5,0xb7,0x38,0x6c,0x1c,0xf4,0x07,0x39,0xef,0x1f,0x72,0x0a,0xb3,0x12,0x13,0x25,0x86,0xd3,0xf8,0x9f,0xb5,0x40,0x58,0xe7,0x5e,0x9f,0xa0,0xbc,0xd7,0xab,0x4f,0xf3,0x94,0xcf,0x0f,0x5a,0x4c,0x98,0xb4,0x70,0x35,0x62,0xee +.byte 0x33,0x24,0x72,0x31,0xd4,0x06,0xd9,0xb4,0x1c,0x1e,0x0f,0xa7,0x48,0xc7,0x75,0x45,0x40,0x02,0xd0,0x60,0x32,0x29,0x4d,0x61,0x7a,0xee,0x65,0x35,0x2b,0xe5,0x50,0xac,0x82,0xdb,0xf7,0x9c,0x8f,0x82,0xe4,0xf0,0xbd,0xdb,0x00,0x3d,0x3a,0x3d,0xa2,0xc3,0x2d,0x0e,0x51,0x20,0xdb,0xdb,0x8d,0x15,0x03,0xbd,0xcb,0xcb,0x24,0x81,0xc5,0xdb +.byte 0x05,0x39,0x48,0xb8,0x3c,0x93,0x35,0x10,0xef,0x19,0xba,0x09,0x9e,0xff,0xf9,0x3f,0x0c,0xdc,0x96,0x98,0x32,0x26,0x76,0xe7,0xfa,0xaa,0xdf,0xdc,0xb9,0x15,0x44,0x42,0x9a,0x8c,0x6c,0x88,0xea,0x43,0x63,0xb5,0x79,0xb6,0x50,0x30,0x78,0xea,0x70,0xba,0x33,0x36,0x8f,0x8c,0xe5,0x78,0xfd,0xbc,0xc0,0xbd,0xde,0x3a,0x3d,0xe6,0xe6,0x57 +.byte 0x0f,0x29,0xf2,0x82,0x05,0xf2,0x5c,0xfd,0x33,0xc1,0xb2,0x2e,0xc2,0xc0,0x42,0xa2,0xc8,0xa5,0xf9,0x70,0x05,0xff,0x7b,0x8d,0xb9,0x68,0xc3,0xf6,0x74,0x00,0xcd,0x9d,0x70,0xfa,0x62,0x34,0xe5,0x05,0xe8,0x5f,0x53,0x9b,0x69,0x01,0x86,0xb9,0x1d,0x68,0x80,0x89,0x51,0x52,0x0d,0xe8,0x28,0xa1,0xdd,0x62,0x2b,0xf3,0x53,0x74,0xaa,0x98 +.byte 0xdb,0x7e,0x74,0x44,0xeb,0x25,0xe7,0xde,0xc4,0x29,0x14,0x11,0x7b,0xc6,0xef,0x14,0xe4,0x04,0xd0,0xf4,0x11,0xca,0xdc,0xdc,0xe6,0x3f,0x9a,0xc9,0xe2,0x0e,0x67,0x30,0x78,0x65,0x94,0x5a,0xa1,0x24,0xd6,0x90,0x2f,0x1c,0x13,0x46,0xf5,0xb5,0xf9,0x74,0x56,0x3e,0xd5,0x1b,0x09,0xb3,0x04,0xbe,0x89,0x00,0xbd,0xe0,0xba,0x13,0x05,0xd1 +.byte 0x98,0xa7,0x93,0x09,0xc5,0x96,0x46,0xb5,0x5a,0x05,0xac,0x1e,0x66,0x03,0xf0,0xaa,0x3d,0xc2,0x54,0xa3,0xc4,0x2b,0x0d,0xa3,0xe4,0x92,0xd6,0xd0,0x44,0xa6,0x37,0x30,0xa5,0xac,0xc2,0xc8,0x58,0x2a,0x2c,0x18,0x68,0x8d,0x9b,0x4f,0x99,0xd0,0x55,0x41,0xf4,0x84,0x3c,0x69,0xda,0x3c,0x6d,0x43,0xb3,0x85,0x15,0x1f,0xdb,0x58,0x0b,0x71 +.byte 0x33,0x24,0xbb,0x21,0x43,0x19,0x16,0xeb,0x83,0xde,0xe5,0xb7,0x68,0x9e,0xb9,0xd9,0xf6,0x2e,0xae,0xdd,0x88,0x2c,0x18,0xd7,0xc3,0x72,0x8b,0xbe,0xaf,0x8d,0xfd,0xcd,0x2f,0x8e,0x3e,0x2b,0xa4,0x20,0x11,0x9d,0x00,0x4f,0xea,0xf0,0xaa,0x2d,0xf3,0x9d,0xfd,0x11,0x7b,0xac,0x2c,0x66,0x74,0x03,0xe5,0xcc,0x70,0x9f,0xfb,0xb7,0x5a,0x16 +.byte 0xc3,0x05,0x61,0x7c,0x8c,0x73,0xcc,0x9c,0x6a,0x2f,0xee,0xae,0x85,0xc9,0x51,0x91,0x13,0xa4,0x09,0x82,0x4d,0x62,0x09,0x24,0x25,0x35,0x1f,0x82,0x88,0xbb,0xdd,0x16,0x5e,0x8d,0x98,0x5f,0x07,0x49,0x32,0x96,0xb7,0xee,0x85,0xb0,0x7b,0xfd,0xf5,0x35,0x4b,0xa9,0xd4,0xee,0xf2,0x37,0xd1,0xfe,0x62,0xf5,0x52,0x13,0xb4,0xb2,0xce,0xc4 +.byte 0xe0,0x09,0x78,0x48,0xd5,0xc6,0x5d,0x36,0x1b,0x90,0x3a,0x6a,0x3c,0x21,0x50,0xf0,0x0a,0xe9,0x46,0x24,0x45,0xc1,0x5e,0x76,0xa3,0xf9,0x70,0xb8,0x62,0x4d,0x0e,0x92,0x87,0x4a,0x6a,0xf9,0x46,0x91,0x64,0xfe,0x7f,0x53,0x24,0x7e,0xc7,0x3e,0xb0,0x37,0x1a,0xc8,0xd6,0x33,0x0b,0x5f,0xa5,0x30,0x03,0x0e,0x85,0x3d,0x7b,0xc1,0xa1,0x18 +.byte 0xb3,0x8c,0xfe,0xca,0x3e,0x71,0xd8,0x92,0x46,0x49,0x60,0x54,0xd9,0x7b,0xf7,0xc3,0x99,0x2f,0xb5,0x79,0xcc,0x32,0x40,0x7d,0x3d,0x0b,0xc6,0x6f,0x04,0xd9,0xf1,0xdd,0x64,0xf5,0xc4,0x60,0x14,0x04,0x5c,0x3a,0xa4,0xda,0xdc,0xad,0x8f,0xc2,0x44,0x37,0x96,0x63,0x00,0xf7,0xb1,0xc0,0x7c,0x8c,0x12,0xb5,0x3a,0xec,0xc0,0x16,0xd8,0x24 +.byte 0xe9,0xc0,0xc4,0xfa,0xb1,0x85,0x5b,0xe3,0x62,0x24,0xa1,0x75,0x92,0x82,0x04,0x59,0x10,0x50,0x4b,0x51,0x51,0x3e,0x39,0xba,0x6d,0xa0,0x65,0x2d,0xfc,0x23,0x1c,0x9d,0x69,0x22,0xe7,0x15,0xfa,0xba,0x76,0xbf,0x53,0x62,0xb0,0x0d,0x0d,0x5d,0x55,0x00,0xbc,0x58,0x01,0xed,0x37,0x53,0xb9,0xa6,0x0d,0x71,0xab,0xec,0x42,0xbf,0x3b,0x52 +.byte 0xfd,0xae,0xe9,0x6d,0x65,0x07,0xf3,0xd9,0x32,0x66,0xc1,0x66,0x1a,0x18,0x73,0x86,0x01,0xaf,0x1d,0xd1,0xd0,0xcf,0xb1,0xea,0x54,0x23,0xdf,0xf2,0x4d,0x7d,0xc7,0xfe,0xfe,0x7d,0x1d,0x2c,0x1b,0xb6,0xa7,0x7a,0x9e,0x90,0x3a,0x3b,0xb0,0x6c,0xb0,0xd2,0xd1,0xd0,0x6a,0x94,0x4c,0x84,0x1c,0x45,0xae,0xda,0x16,0xa9,0x2e,0x63,0x19,0x26 +.byte 0xf6,0x74,0xd3,0x6f,0x9b,0x9c,0x0c,0xb8,0x85,0x9f,0xeb,0x99,0xbc,0xab,0xff,0xc3,0x75,0x86,0xe5,0x3a,0xa0,0xf9,0xfc,0x6b,0x3d,0x5a,0xad,0x46,0x7f,0x17,0x0e,0x94,0xb7,0xa4,0x43,0x61,0x54,0x76,0x29,0x78,0xe4,0x41,0x91,0xbe,0xa5,0x36,0x39,0xdf,0xdc,0xcc,0x8e,0x42,0x40,0x08,0x51,0x26,0xb0,0x53,0x5d,0xb4,0x7a,0x18,0x8e,0xb3 +.byte 0xae,0xf2,0xe0,0xef,0x63,0x51,0x3a,0xbe,0x4c,0x2d,0xce,0xc7,0xe2,0x1b,0xc2,0x40,0xf3,0x82,0x61,0xf0,0x1b,0x05,0xdd,0x1e,0xae,0xed,0x87,0x2c,0xe5,0xad,0xc7,0xec,0xb5,0x63,0xf7,0x3a,0xf9,0xb7,0xd8,0x4e,0xa7,0xef,0xac,0x6d,0x9c,0x27,0xd9,0xcc,0x66,0xf4,0x75,0x40,0x94,0x8b,0x78,0x4f,0x61,0x4f,0x31,0x49,0x5c,0x96,0x72,0x58 +.byte 0xcf,0x55,0xb2,0x66,0x16,0x29,0x27,0x24,0x39,0xc3,0x64,0xb1,0xdf,0x69,0x87,0x85,0x46,0xe3,0xd0,0x82,0x53,0x1a,0xc2,0xf1,0x3a,0xab,0xdf,0xe5,0x29,0x17,0xdd,0xfe,0xbf,0xf9,0x3d,0x7a,0xfb,0xe7,0x74,0x49,0xa9,0xef,0x61,0x93,0x4c,0xfa,0x30,0xea,0x65,0xa7,0x61,0x32,0x88,0x74,0x12,0xc1,0x91,0xf1,0xc2,0x1f,0x38,0x6a,0xfd,0x0d +.byte 0xc8,0x6f,0x87,0xe6,0x15,0x55,0x26,0x13,0x86,0x13,0xb9,0x01,0x98,0x34,0x1c,0x2d,0x1d,0x30,0xae,0x7d,0x8e,0x07,0x7d,0x4d,0xe9,0xfd,0x58,0x18,0xc3,0xa6,0x8e,0x87,0x98,0x33,0xcc,0x80,0xd7,0x70,0x07,0x6a,0x4a,0x97,0xef,0x56,0xf3,0x9d,0xf9,0xef,0x6f,0xa8,0x71,0x7f,0x61,0x07,0x1d,0x9d,0x51,0x06,0x86,0x4a,0x35,0x9e,0xab,0x2c +.byte 0x66,0x8d,0x61,0x62,0xbd,0xed,0x6c,0x76,0x7c,0x67,0xe0,0xe1,0x6e,0x90,0x74,0xb1,0xa6,0x26,0x0d,0x01,0x1f,0xe9,0xb4,0x30,0x9a,0x7e,0x37,0xd1,0xea,0x97,0x9a,0x0f,0x9e,0x8d,0x52,0xd4,0x96,0x36,0x5b,0x6f,0x40,0xbb,0x9e,0x44,0xb4,0x6e,0xee,0x15,0x70,0xef,0x66,0x81,0xf5,0xb4,0xe7,0x69,0xb0,0x40,0x44,0xdc,0x70,0x1e,0x4d,0x3c +.byte 0x9b,0x19,0x2a,0x97,0xbd,0xb2,0xd2,0x9b,0x98,0xac,0x36,0xf1,0x05,0x48,0xdc,0x5d,0x21,0xfb,0x17,0xe3,0x9c,0x3c,0xbf,0xfd,0x1d,0x39,0x1e,0x5b,0x2a,0xa2,0xb3,0x7d,0x4f,0xdf,0x3a,0x41,0x7a,0x31,0x01,0xc2,0xe5,0xd0,0x06,0x50,0x29,0x05,0xce,0xb8,0x28,0xb7,0xdd,0x83,0xc8,0xaa,0x39,0x78,0xc7,0x7d,0x9e,0xcd,0x9a,0x07,0x71,0x7e +.byte 0x20,0x92,0x82,0xce,0x49,0x90,0xce,0xef,0x53,0xa7,0x48,0x2a,0x69,0x86,0xa1,0x5e,0x35,0xe8,0x7d,0x10,0xb8,0x5e,0xa6,0x9a,0x69,0x6f,0x32,0x75,0xf3,0x4a,0xee,0x9c,0x06,0x5c,0xdd,0x84,0x7e,0x38,0x00,0x67,0x39,0x42,0xed,0x72,0xda,0xe3,0x6b,0x5a,0xf4,0xc9,0x80,0x3e,0x0e,0xda,0x39,0xfa,0x83,0x2c,0x60,0x69,0x87,0x85,0x05,0xfc +.byte 0xf4,0x2b,0xd4,0x0a,0xad,0x86,0xca,0xd5,0xf0,0x92,0x1f,0x43,0x3c,0x0e,0xac,0x99,0xf3,0x67,0xa3,0x41,0x6d,0xb9,0x29,0x70,0x57,0x62,0x9f,0x45,0x91,0x72,0xe5,0x53,0xcc,0x89,0x80,0x3f,0xbc,0x1c,0x66,0x21,0xdd,0x90,0x2b,0xa4,0xca,0x2f,0xf0,0x0f,0x9f,0xd0,0xe9,0x28,0xe2,0xd9,0x36,0xaf,0xf9,0x01,0x81,0xce,0xb4,0xe7,0x71,0xfd +.byte 0x92,0xf8,0x56,0x2e,0xc3,0xc8,0x8b,0x54,0xc8,0xc7,0x40,0x79,0x27,0x06,0x18,0x4a,0x7b,0x88,0x3f,0xd6,0x4f,0xd4,0x66,0x1e,0x1f,0x9a,0x14,0x1a,0x0a,0x98,0xc7,0xd6,0x25,0x83,0x37,0x8a,0x5d,0xb2,0x88,0x39,0x68,0x7b,0x1f,0x4e,0x0a,0xed,0x11,0x1a,0x77,0x9b,0xcb,0xb6,0x7d,0x5c,0x36,0xac,0x07,0x07,0x9f,0x05,0xcf,0x90,0x8f,0x3f +.byte 0x4b,0xc5,0xf9,0x42,0x90,0xb4,0x42,0x26,0xa1,0x2c,0x66,0xc6,0xb8,0x98,0x80,0x8a,0xbb,0x9b,0x41,0xe4,0x44,0x8c,0x5e,0x56,0x33,0xe3,0xba,0xcf,0x31,0x8e,0x28,0xd7,0xc5,0xd1,0x3b,0x68,0x47,0x10,0xae,0xda,0xc3,0xbd,0x20,0xe7,0xac,0xe2,0xe1,0xe0,0x7a,0x4b,0x83,0xb1,0xab,0x72,0xf4,0xc4,0xe7,0x0d,0x02,0xaf,0x5b,0x74,0xac,0xda +.byte 0x9d,0xce,0x26,0x1f,0x79,0x05,0x67,0x7e,0xc4,0x98,0x3f,0xde,0xa6,0xf3,0xfe,0x59,0x65,0x88,0xfb,0x14,0x3a,0x43,0x91,0x04,0x1a,0x78,0x7e,0x08,0xba,0x55,0x50,0xc7,0x65,0xd3,0x8e,0xda,0x0a,0xee,0x8e,0x11,0xa9,0xf6,0x9e,0xd3,0x23,0x97,0x05,0x0c,0x98,0x2a,0x36,0x25,0xec,0x5e,0x0b,0xf9,0x31,0x80,0x00,0x8a,0x70,0xf1,0xaa,0x7c +.byte 0x73,0x02,0x98,0x8d,0x42,0x27,0x53,0xf1,0x83,0x37,0xd0,0x2d,0xfa,0xc7,0x4b,0xa5,0xb3,0xc9,0xb8,0xd4,0x56,0x94,0x5a,0x17,0x2e,0x9d,0x1b,0x46,0xaa,0xb6,0xd9,0x2a,0x3a,0x6c,0xaf,0x24,0x59,0xfd,0x08,0xc5,0xca,0x0c,0x79,0x3f,0xe7,0x91,0x8d,0x9d,0x59,0x91,0xd8,0x5f,0xda,0x6d,0x35,0x7b,0x52,0x47,0x35,0xf9,0x81,0x86,0x2c,0xee +.byte 0x1a,0x14,0xc5,0x1f,0xb6,0x85,0xb5,0x74,0xe9,0xb7,0x4f,0xde,0xcd,0x93,0x2d,0xf3,0x10,0xbe,0x34,0xfa,0xca,0x15,0x9f,0x02,0x9d,0x19,0x72,0x7c,0xd6,0xfd,0x81,0x43,0x49,0xb5,0x2b,0x52,0x31,0xd6,0x2c,0x28,0x2e,0x83,0x6d,0xd3,0x0f,0x6e,0x03,0x65,0xf0,0x8a,0xdd,0x0a,0xec,0x58,0x10,0x45,0x5d,0xac,0xda,0xf5,0x32,0x5d,0x18,0x26 +.byte 0xcc,0x2e,0xcf,0xd3,0x41,0x2d,0x1d,0xba,0xdf,0xd8,0x96,0x8f,0x18,0x0f,0xa7,0xec,0x8e,0x6e,0x84,0x2c,0xd6,0x1f,0x4e,0x76,0xfe,0xf3,0x14,0x27,0x4b,0x5b,0x3d,0x7c,0x1c,0x59,0x46,0x97,0x1b,0x59,0x5a,0x2d,0x57,0x80,0x17,0x98,0x7d,0x92,0x5d,0x2f,0x98,0x53,0x10,0x59,0x8e,0x7f,0x55,0x64,0x15,0x62,0x2c,0x16,0x0b,0x8d,0x48,0x54 +.byte 0xaf,0x96,0x17,0xa9,0x8e,0x2c,0xcf,0x41,0x8c,0x8a,0x37,0x55,0xe4,0xf9,0x20,0x3b,0x21,0x5c,0x86,0x8d,0x3f,0xa6,0x5e,0x43,0xf3,0x3b,0xf7,0x7c,0x27,0x88,0x8e,0xa5,0x15,0xca,0x0e,0x9e,0x85,0x30,0x17,0x0d,0xcf,0xf0,0x82,0x87,0xd6,0xe8,0xd2,0xad,0xe9,0x4d,0x3f,0xc9,0x58,0x19,0xf9,0x99,0x4d,0xf9,0x6b,0x1b,0xd3,0xf9,0xdd,0x52 +.byte 0xd1,0x3c,0x64,0x46,0xfd,0x4f,0x2e,0x63,0x39,0xd8,0xe4,0xeb,0xfc,0x07,0xf1,0xa5,0xff,0x84,0xa8,0x92,0xfe,0xbc,0xc5,0x36,0x91,0x2b,0xec,0x2c,0xad,0xf0,0xac,0xc5,0xb0,0xad,0x8a,0x0d,0x6a,0xd9,0x29,0x7a,0xb0,0x87,0x0c,0xaf,0xda,0x75,0x84,0x25,0xbe,0xee,0x0d,0xfd,0x4c,0xf5,0x2d,0x46,0xe9,0x17,0xb9,0x9d,0x3d,0x4b,0x8f,0x3a +.byte 0xe9,0x49,0xb6,0x32,0x99,0x27,0xe2,0x4d,0xff,0x2f,0x2e,0xd5,0x69,0x52,0x56,0x20,0x0a,0xbf,0x62,0x14,0x34,0xfb,0xbf,0x95,0xe8,0xfe,0xb1,0x9f,0x43,0x30,0x02,0x03,0x9e,0xa8,0xe2,0x68,0x64,0xdd,0x37,0xfc,0xb9,0x0f,0x85,0x8c,0x36,0x45,0xdb,0x7c,0x8b,0x97,0x50,0xc3,0x75,0xa1,0xcf,0xf4,0xc2,0x46,0xd8,0xa1,0x8c,0xab,0x8d,0x3a +.byte 0xde,0xe7,0x9e,0xd2,0x1e,0x2d,0x8b,0xe4,0x31,0xe3,0x12,0x3f,0x9f,0x0b,0x2c,0x95,0x75,0x8d,0xf1,0x24,0xb9,0xdf,0x1e,0x64,0x35,0x45,0x2a,0xc2,0xf9,0x96,0x5d,0x10,0x64,0x32,0xae,0xe9,0xf8,0x71,0xd4,0x2d,0x6b,0xc6,0xde,0x08,0x1e,0x5d,0x51,0xf1,0xe7,0xfd,0x3c,0x22,0x43,0x59,0x82,0x83,0x13,0x75,0x36,0xef,0x81,0xe4,0xcf,0xa8 +.byte 0xb8,0x30,0x16,0x44,0xae,0x55,0x06,0xdd,0xb9,0x60,0x3f,0x75,0xc6,0xd1,0x73,0xa9,0xea,0xc9,0x64,0x2b,0x8a,0xde,0x44,0x4b,0x3d,0xc3,0x31,0x12,0x84,0x9a,0xe3,0xda,0x24,0x82,0x99,0x00,0x6d,0x8e,0xb8,0x26,0x82,0xa6,0xc2,0x37,0x6c,0x2a,0x1d,0xcf,0x6d,0x18,0xc7,0xee,0x27,0xca,0xe7,0xad,0x95,0xed,0x7d,0xe0,0xe0,0x6f,0x45,0xc3 +.byte 0x8a,0x2f,0x08,0x49,0x7e,0x09,0x9e,0xc1,0xb7,0x1e,0x8f,0x57,0x61,0xf8,0x3e,0xea,0xd7,0x47,0xfb,0xd0,0xda,0xaa,0x04,0xf9,0x06,0xbb,0xa3,0x80,0x68,0x89,0xb0,0x7f,0x18,0xf3,0xd2,0xeb,0xee,0x48,0x30,0x6a,0x24,0xc8,0x71,0x43,0xc3,0x50,0xcc,0x85,0x68,0xf5,0xca,0x44,0x34,0x43,0xaa,0x2e,0x4f,0x02,0x1b,0x23,0x4f,0xe9,0x07,0x02 +.byte 0xa2,0xfa,0x24,0x57,0x70,0x4e,0x1a,0x78,0x03,0xa2,0xdd,0x53,0x50,0x82,0x05,0xb1,0x0f,0xcb,0x9e,0x2e,0x58,0x04,0x62,0xc8,0xac,0x71,0x31,0x56,0x0f,0xc7,0x70,0x32,0x53,0xda,0x51,0xc3,0x15,0x78,0x82,0xb6,0xe8,0x6e,0x32,0xeb,0x39,0xab,0xba,0x67,0xcc,0xbc,0x99,0x58,0x88,0xc4,0x60,0x0d,0x0b,0xc1,0xfa,0x6f,0x40,0x85,0x04,0xdf +.byte 0x5f,0x17,0x69,0xf1,0xbd,0x44,0x97,0xc8,0x62,0x19,0x49,0x1f,0x23,0xcb,0x3d,0x17,0x04,0xf2,0xbd,0x58,0x15,0xa6,0x37,0x3a,0x3f,0x77,0x98,0x32,0x40,0x8a,0x72,0xf0,0x41,0x0b,0xad,0x88,0xba,0xd3,0xae,0xdc,0x3b,0x9a,0x37,0x89,0xa5,0x09,0xe5,0xbb,0xf2,0xf8,0x5d,0xa5,0xed,0xe8,0x39,0x7b,0xed,0x2b,0x90,0xd6,0x6c,0xd3,0xfa,0x69 +.byte 0xa7,0xca,0x09,0x83,0x15,0x8d,0xd8,0xe3,0x81,0x03,0x4e,0x2d,0xd8,0x96,0x3b,0x4b,0x18,0x91,0xac,0x5f,0x22,0xe6,0x9d,0x4b,0x09,0xaf,0xf0,0xdf,0x16,0xa2,0xf1,0x2c,0xd9,0x35,0x8a,0x6e,0x85,0x7a,0xbc,0xc7,0x10,0xd1,0x5f,0x8a,0x53,0x9c,0x8e,0xbc,0x8c,0x15,0xb3,0x8a,0xb0,0x0b,0x74,0x40,0x2a,0x5f,0x46,0x71,0x1c,0x0b,0xee,0x08 +.byte 0xae,0x17,0x26,0x1e,0xcf,0xbf,0x3d,0xa0,0x5e,0x3a,0xdb,0x39,0x6b,0x4a,0x82,0x53,0x02,0xf4,0xa2,0x15,0x5c,0xb6,0xdb,0x20,0x30,0xa2,0x7d,0xcb,0x9a,0xf7,0x88,0x69,0xb5,0xc8,0xe6,0xcd,0x9e,0xa4,0xaf,0x27,0x0e,0x61,0x41,0xcd,0x8e,0x71,0x83,0x11,0xce,0x5e,0x6c,0xaf,0xa4,0x50,0x81,0xb6,0xf2,0x36,0x05,0xbb,0x36,0x4e,0x4a,0x1b +.byte 0x09,0x9f,0xca,0x1b,0x12,0xb0,0x01,0xc0,0xbf,0x7e,0x3f,0x81,0x60,0x9f,0xfd,0x56,0x81,0x54,0x99,0x2b,0x7f,0x1e,0xb1,0xbf,0xd4,0xb7,0xe1,0x7c,0x71,0xf9,0x00,0x72,0x5f,0x10,0xab,0x60,0x03,0x9d,0x13,0xf1,0xba,0x48,0x93,0x1c,0x1d,0x11,0x04,0x40,0xf6,0xde,0x3b,0xef,0x6c,0x47,0xb3,0x0d,0xcf,0x53,0xbd,0x45,0x7e,0xd7,0x8c,0x34 +.byte 0xd0,0xcb,0x85,0x4b,0x1e,0xd1,0xc5,0xfd,0x5b,0x1a,0x18,0x8a,0x27,0xe3,0x16,0x3c,0x25,0x12,0xf2,0xf1,0xa1,0x40,0x53,0x68,0x27,0x2c,0x81,0x0e,0x20,0x12,0xe3,0xde,0xe2,0x9f,0x08,0x75,0xc0,0x25,0x79,0xf0,0xc4,0xaa,0x10,0xad,0x41,0x3f,0x0b,0xc7,0xb2,0xe0,0x50,0xde,0xec,0x24,0x09,0xeb,0xb5,0xd3,0xbc,0xd3,0xdf,0x44,0x6d,0xc8 +.byte 0xf1,0x79,0xf8,0x33,0xb7,0x75,0x09,0x18,0x04,0x59,0x0f,0x15,0x5e,0xf9,0xca,0xe0,0xa9,0x2a,0xe1,0x1b,0xf0,0x49,0x5f,0xca,0xa3,0x80,0xd5,0x9b,0x1e,0xc1,0x1f,0x98,0x18,0x0a,0x24,0xc3,0x3f,0xfb,0x43,0xfd,0xa3,0x01,0x59,0x50,0xea,0x21,0xe0,0x92,0xfd,0xe1,0xd5,0xe4,0x38,0x24,0x88,0xf3,0xb0,0xc9,0x79,0xfd,0x4e,0xd3,0x3e,0xbf +.byte 0xc6,0xb8,0x9e,0x7f,0xab,0x65,0x79,0xd9,0xb9,0x83,0x38,0xe1,0xf7,0xd0,0x37,0x04,0xb3,0x0c,0x48,0x82,0x74,0xe1,0x0c,0x80,0x13,0x59,0xc4,0x72,0xf9,0x2d,0x88,0x06,0x46,0x08,0x7a,0x6b,0xb4,0xfc,0x5f,0x63,0x31,0x2f,0x4f,0xfd,0x4b,0x1f,0x8e,0x21,0x3c,0x67,0x83,0xdd,0xa9,0x65,0x68,0xc6,0xd0,0xb8,0x1d,0xcd,0x60,0xc5,0xb9,0x3b +.byte 0xea,0xe9,0xc7,0xa5,0x1a,0x98,0x8a,0x87,0xb7,0x73,0x29,0x3a,0x6a,0x3a,0x75,0xbf,0xa4,0x79,0x64,0xcb,0x94,0x68,0x93,0x56,0x55,0x1e,0xd5,0x61,0xda,0x87,0xe1,0x28,0xf0,0xa5,0x64,0x9a,0xd7,0xa0,0x91,0xfd,0x46,0x20,0x6c,0x87,0x1f,0xe8,0x9e,0x7e,0x95,0xc4,0x60,0xdb,0xf4,0xe2,0x3e,0xb2,0x6a,0x4a,0xe7,0x46,0x3f,0xca,0xf3,0x72 +.byte 0xb5,0xe8,0x06,0x3a,0x1b,0xeb,0xcb,0x81,0x46,0x44,0xf6,0x97,0xa0,0x79,0xe4,0xa4,0x8a,0xba,0x5e,0x1b,0x6d,0xf4,0xcf,0x7c,0x12,0x7a,0xec,0xdd,0xf6,0xc8,0xab,0x5f,0x30,0xb3,0xf9,0x8e,0x31,0xfd,0x51,0x95,0x8b,0xa1,0xe9,0xe8,0x2d,0xec,0x86,0x12,0x4a,0xf8,0x8b,0xa5,0xdd,0xb2,0xe4,0xad,0xdd,0xcb,0xf5,0xcd,0x9c,0x9f,0x0a,0x42 +.byte 0x5f,0x83,0x9d,0xa6,0x4f,0xbe,0x11,0x75,0x3c,0xde,0x67,0x6b,0x95,0xcd,0xcf,0xdc,0xfd,0x1f,0x1a,0x14,0x01,0x27,0x68,0xaf,0x9b,0x82,0xd6,0xae,0x29,0x8a,0x1f,0xc8,0xf1,0x1f,0xb8,0xa9,0xa2,0x1d,0x81,0xbb,0x19,0xda,0x06,0xe3,0x34,0x7b,0xce,0x99,0x3c,0x5b,0x0c,0x9b,0x8b,0x35,0xc0,0x6c,0x88,0xef,0xeb,0x9f,0x64,0xe3,0xc3,0xbf +.byte 0x37,0xd7,0xf6,0xdf,0xad,0x28,0xf4,0xd7,0x19,0xb0,0xf2,0xa7,0xd4,0x71,0xbc,0xd3,0xa3,0x09,0x5c,0x1a,0x45,0x30,0x2d,0x53,0xa5,0x19,0x2f,0xb0,0x5d,0xae,0x04,0x28,0xe6,0x16,0x3e,0x75,0x9f,0xcc,0x76,0xc4,0xc2,0xa0,0xfb,0xff,0xdd,0x4c,0xa3,0x8b,0xad,0x05,0x73,0x26,0xf0,0xef,0x48,0xd5,0x25,0x22,0x90,0x78,0x21,0xfd,0xc6,0x23 +.byte 0x14,0xbc,0xed,0x13,0x29,0x76,0x17,0xa6,0x93,0x09,0x6e,0xa7,0x42,0xdd,0x11,0x9e,0x05,0xa3,0xb7,0x48,0x84,0x85,0xf8,0x4e,0xed,0x3d,0xdb,0xfc,0x68,0xd2,0xec,0xec,0x69,0x2b,0x60,0x38,0xd1,0x99,0x44,0xf9,0x60,0xd3,0x5a,0x9e,0xe4,0x26,0x9d,0x12,0xf8,0x6a,0x53,0xde,0x76,0x78,0xa7,0x68,0xb0,0xb4,0xdc,0x33,0x7b,0x8a,0x73,0xa0 +.byte 0xa5,0x5f,0x8f,0x81,0x0e,0x51,0x06,0x13,0x6b,0x56,0x16,0x91,0x1f,0xf5,0x6b,0x68,0xe6,0x8b,0x69,0xda,0x0a,0x9c,0xb1,0x74,0x8f,0x1c,0xb3,0xbf,0x52,0x59,0xaa,0xb1,0xb6,0x3a,0x81,0xc2,0x04,0x54,0x12,0x46,0xa2,0xd5,0x21,0xdf,0xe0,0x57,0x1f,0xe8,0x36,0x56,0x87,0xbf,0xcb,0x7d,0x06,0x6c,0xd5,0xc9,0x4e,0xca,0x47,0x47,0x11,0x91 +.byte 0x7a,0x14,0x13,0x5d,0x5d,0x46,0xd5,0x3a,0xe4,0xa4,0x4d,0x99,0x3a,0x54,0x99,0x62,0xb4,0x70,0xa0,0xf5,0x8a,0xda,0x05,0x75,0xf1,0xa5,0xa1,0x5d,0x9d,0xc4,0x7f,0x83,0x8a,0x5b,0x09,0x54,0x0e,0x69,0x28,0xef,0x66,0xfb,0xe4,0xc4,0xe4,0xc4,0xda,0xb0,0xda,0xe2,0x19,0x33,0x3c,0x76,0xa0,0x35,0xdc,0x31,0x4e,0x40,0xfe,0xb8,0x20,0x26 +.byte 0x8f,0x6f,0x7d,0x02,0x54,0x86,0x1d,0xca,0xa6,0x10,0xa6,0x89,0x87,0x3a,0x5a,0xd5,0x3d,0x0f,0xb5,0x81,0x7d,0xab,0xb6,0xc6,0x36,0x87,0xce,0xd7,0xe4,0xc3,0x9e,0xc2,0x9c,0xf6,0x75,0xd5,0x9a,0x69,0xd2,0x13,0x89,0x5a,0xe9,0x29,0xc9,0xf5,0x6e,0xcc,0x05,0x87,0x0a,0x61,0x49,0xd7,0xa5,0x76,0xd0,0xaf,0x96,0xe0,0x2f,0x91,0xf4,0x45 +.byte 0x70,0x5a,0xdc,0x9f,0x07,0x7f,0x86,0x02,0xa4,0x83,0x8d,0x4a,0x6d,0xfc,0x1b,0xd8,0x9b,0xc2,0x42,0x4f,0xcb,0xdf,0xcb,0xe0,0x55,0xb4,0x8f,0xf7,0x27,0x73,0xd9,0x7e,0xf8,0x3a,0x5c,0x4f,0x29,0x64,0xd8,0x39,0xfa,0xf2,0xc4,0x6b,0xeb,0x55,0xc3,0x13,0x22,0x15,0xdf,0xc5,0x91,0x6d,0xd7,0xf3,0x11,0x34,0x08,0xce,0xe5,0xbd,0x16,0x14 +.byte 0x60,0x14,0x8a,0xed,0x4d,0x38,0x98,0x15,0x5d,0xee,0x70,0xff,0x05,0xd2,0x74,0x3a,0x5f,0x78,0x1a,0x70,0x61,0x2a,0x42,0x4a,0xf3,0x15,0x6f,0x9e,0x33,0xca,0xb8,0x46,0x22,0x64,0xd6,0x24,0xe8,0x10,0x1a,0x89,0xab,0x74,0xdf,0x56,0x35,0x41,0x57,0xe1,0xd9,0x4b,0x67,0x60,0x89,0x6f,0xbf,0x73,0xac,0x6b,0xf9,0x78,0x3f,0xbc,0xf3,0x2a +.byte 0xb5,0x8c,0x1f,0xda,0xe7,0xe2,0xac,0x60,0xbf,0x41,0x96,0xbb,0xd5,0x35,0x9c,0x56,0xe7,0xfd,0x95,0xc7,0x4d,0x32,0xa1,0x07,0x34,0xbc,0x99,0xca,0xcc,0x42,0x71,0xfb,0xec,0x5c,0x1e,0xf9,0x8b,0xde,0x43,0x65,0x84,0x16,0x52,0x0a,0x5e,0x92,0x20,0xd8,0x26,0x4b,0x97,0x71,0xde,0xd2,0x1f,0x2e,0xd1,0xb2,0xb6,0x29,0x6a,0x6d,0x41,0x00 +.byte 0x20,0x3d,0x03,0xf8,0x43,0x7b,0x57,0x87,0x4e,0xf1,0x8e,0x6f,0xd3,0xf4,0x6c,0x6c,0x29,0xf6,0x99,0xe3,0xd3,0x1d,0xd3,0x26,0x21,0x3b,0x02,0xa2,0xc1,0x06,0xcf,0x31,0xec,0x7f,0xc6,0x80,0xbc,0xab,0x86,0x01,0xff,0x11,0x8a,0x24,0xfd,0x1b,0x41,0x49,0xd4,0xbe,0x15,0x34,0x82,0xc5,0x02,0x51,0x67,0x5c,0x41,0x8e,0xbf,0x94,0x12,0x15 +.byte 0x64,0xea,0x00,0x0c,0x51,0x40,0x57,0x66,0x1e,0x6d,0x3e,0x41,0x8e,0x84,0xdf,0x71,0xb8,0xd7,0xfa,0x12,0x17,0x22,0x17,0x05,0xdc,0x82,0xfd,0x7c,0x5e,0xfa,0x62,0x23,0xa8,0xbe,0x14,0xdc,0x84,0x42,0xf0,0x90,0xc5,0xb0,0x68,0xbe,0x64,0x74,0xc3,0xa5,0xd1,0x10,0xcf,0xe3,0xd1,0x09,0x98,0x3b,0xb9,0x19,0xf2,0x9b,0x5d,0x90,0x99,0x3d +.byte 0x30,0x67,0x55,0x34,0x50,0x78,0x3b,0xd2,0x70,0xb1,0xd2,0x91,0x4e,0xfa,0x98,0x7d,0x93,0xad,0x7f,0xb1,0x89,0xb0,0x61,0x4c,0x95,0x3f,0x51,0x95,0xd7,0xc6,0x87,0x7a,0xc5,0x53,0xb6,0x6d,0x61,0xec,0xbe,0x40,0x1f,0xa5,0x7f,0x73,0x4a,0x78,0xd2,0x58,0x1e,0x41,0x8e,0x9a,0x08,0x49,0xce,0x39,0x52,0xf9,0xd1,0xcd,0x41,0xb6,0x39,0x99 +.byte 0xfa,0xfb,0x1c,0x38,0xe1,0xe5,0xe1,0xd6,0x16,0x0f,0xc8,0x12,0x0b,0x88,0xdc,0x00,0xd4,0x7b,0x24,0x69,0x16,0x27,0x37,0xa3,0xd5,0x39,0x27,0x34,0xda,0x23,0x24,0x50,0x13,0xd8,0x02,0x48,0x14,0xd7,0xc9,0x28,0x1b,0xba,0x66,0xa8,0xc8,0x9a,0x7b,0xed,0x92,0x5b,0x78,0x46,0x79,0x5a,0xd1,0xf2,0x75,0xf0,0x98,0xd3,0x9f,0x4c,0x72,0x51 +.byte 0xed,0xe5,0xce,0x83,0xac,0xe1,0xc8,0x2b,0x7f,0x77,0x6a,0x70,0xdd,0x80,0x88,0x62,0x58,0x94,0x15,0x72,0x53,0x34,0x48,0x17,0xb2,0xe8,0x4a,0xab,0x2d,0x4e,0xef,0x93,0xb7,0xba,0xd1,0x1c,0x53,0x69,0xd5,0xac,0xa1,0x61,0x7c,0x44,0xec,0x81,0x72,0xcc,0xe8,0x6f,0x5d,0x67,0x1f,0x65,0x9a,0x34,0xf5,0x95,0x89,0x1c,0x2e,0x54,0x42,0xc0 +.byte 0x85,0x79,0xb0,0xfa,0x44,0x0d,0x28,0xc4,0x20,0x2f,0x2e,0x85,0x73,0xfb,0xf6,0x44,0x0e,0xbc,0xab,0x4f,0x42,0x5c,0xdb,0x1f,0x11,0x6f,0x9a,0x23,0x75,0x70,0x78,0x1a,0xd2,0xb8,0x83,0x72,0xf5,0xf6,0x40,0x48,0x3f,0xc8,0xd5,0xe3,0x2c,0x08,0x5c,0x0c,0x2a,0xb0,0x8e,0x69,0xe6,0xdf,0x4b,0x4a,0x95,0x9c,0x4c,0x5e,0x09,0x24,0xc3,0xd0 +.byte 0x4c,0x20,0x0c,0x9a,0xce,0x95,0x53,0x6a,0x7b,0x54,0x0a,0x7e,0x73,0xa7,0x95,0xe7,0x7c,0x67,0x9d,0x05,0xbc,0x26,0x3a,0xa1,0x43,0x99,0x7a,0xee,0x04,0xcf,0x94,0x02,0x36,0x26,0xb3,0x81,0x74,0x22,0xee,0x1e,0x9e,0xe2,0x82,0xd4,0xe0,0xca,0xf2,0xec,0xd2,0x9e,0xf8,0x3f,0x9f,0xc4,0x5b,0xe8,0xfc,0xbd,0x93,0xaa,0xc3,0x2f,0xce,0xf2 +.byte 0x32,0xa9,0x23,0xf3,0xe1,0x06,0xae,0x7d,0x87,0xe9,0xe7,0xe0,0xc1,0x7c,0x74,0x9c,0xdf,0x86,0x6d,0x5c,0x8a,0x51,0x45,0x9d,0x43,0x49,0x87,0x45,0x75,0xfb,0x40,0x55,0xab,0x9a,0x52,0xf1,0x32,0x5e,0xde,0x8b,0x52,0x50,0x9f,0xb8,0x7a,0xe5,0x1c,0x40,0x4f,0xc7,0xb1,0x29,0x90,0xcc,0x98,0x99,0xa0,0x4e,0x1c,0x43,0x6e,0x91,0x61,0x9c +.byte 0xf7,0xa7,0xf7,0x43,0x89,0x15,0x8c,0x56,0x22,0x9d,0x66,0xac,0x71,0x19,0xdc,0xb9,0xf8,0xd3,0xaf,0x2e,0xd7,0x7b,0xc3,0xe4,0x25,0x0d,0x2c,0xaf,0x15,0x8c,0xea,0x2b,0xdb,0x8c,0x71,0xff,0x55,0x29,0x11,0x35,0x11,0xef,0xb0,0x97,0xb2,0x95,0xab,0xeb,0x4a,0x40,0x1c,0x92,0xc4,0x13,0x36,0x74,0x53,0x78,0x51,0x6c,0xca,0x37,0xcb,0xda +.byte 0x5e,0x6b,0x8c,0x69,0xc5,0xd0,0xf9,0xdb,0xbe,0xd9,0x30,0x42,0x16,0xcf,0x40,0x63,0x87,0x10,0x28,0x7d,0xae,0xa9,0x8c,0x14,0x99,0xe1,0x4f,0x11,0x98,0x7e,0xe9,0x14,0x9c,0x2e,0xe2,0xed,0x20,0x15,0x7c,0xb5,0xf4,0xc9,0x16,0x30,0x8d,0x7c,0x61,0x45,0xf4,0x23,0xf5,0xdb,0x81,0x8f,0x6b,0x41,0xaf,0xa9,0xf8,0x51,0xbe,0xc4,0x5d,0x8c +.byte 0xda,0x5e,0x07,0x62,0x7c,0xc6,0xd1,0xae,0x91,0x5e,0x05,0xa8,0xc6,0xc5,0xfc,0xb7,0x12,0x2e,0x7f,0x85,0xef,0xbd,0x2b,0x56,0x57,0x32,0xad,0x3d,0x97,0x5b,0x26,0xcf,0xd3,0xe7,0x48,0x4e,0x9b,0x15,0x98,0x77,0xb4,0x3e,0xf1,0x3e,0x1c,0x21,0xb0,0x98,0xe2,0x69,0xee,0xd8,0x29,0x10,0x93,0xd5,0xc9,0x71,0x8f,0x28,0xbd,0xe3,0xd9,0x54 +.byte 0xf3,0x72,0xb6,0x85,0xe9,0x2b,0xdc,0x96,0x52,0x53,0x5c,0x61,0x54,0x96,0x4a,0xf5,0x3f,0xee,0x53,0xc3,0x63,0xc9,0x67,0x14,0xdf,0x3a,0xfe,0x46,0x8a,0xa6,0xec,0x06,0x0c,0xea,0xb8,0x82,0x49,0xb5,0xed,0x94,0xf2,0xac,0x76,0xd5,0x87,0x79,0x15,0x4f,0xa1,0x34,0x90,0x8e,0x7b,0x02,0xf7,0x02,0xb0,0x07,0xa5,0x7c,0x6b,0xc2,0x34,0x84 +.byte 0xd4,0xaa,0xbf,0x32,0x81,0xf7,0xed,0x1f,0x61,0xd7,0x6e,0x40,0xa0,0xdc,0x4c,0xb5,0xb7,0x36,0x3a,0x87,0x09,0x82,0xd5,0x5a,0xc8,0x1f,0xe6,0x77,0xa6,0xaa,0xcf,0x3c,0x7b,0x23,0x46,0x58,0x95,0x7f,0x84,0xba,0x4a,0x05,0x0b,0x36,0xdb,0x58,0xf9,0xa4,0x2b,0x24,0xd4,0x8a,0xbc,0xb2,0xb7,0x04,0xac,0x64,0x0e,0x88,0x25,0x9a,0x69,0xe7 +.byte 0x87,0x70,0x0b,0xa6,0x43,0xe9,0xb2,0xbb,0x4e,0x4c,0x10,0x19,0x44,0x4d,0x12,0x4c,0x58,0x2a,0x49,0xe2,0x01,0xd2,0x65,0x23,0xee,0xe9,0xca,0x0b,0xa1,0x28,0x02,0x8d,0xcf,0x37,0x06,0xbc,0x5d,0x35,0xba,0xec,0x97,0x95,0xcc,0xfe,0x7b,0xc9,0x1c,0x0d,0x89,0x4e,0xe1,0x8d,0x9b,0x5e,0x5b,0xb9,0x6c,0x24,0x73,0x9a,0x62,0xd7,0xc5,0xfa +.byte 0x54,0xeb,0x05,0x22,0xd9,0xe7,0xc4,0x68,0x88,0x20,0x43,0xd9,0x14,0x47,0xd7,0xa5,0xd0,0xce,0x10,0x77,0xe8,0x5c,0x85,0x39,0x99,0x3f,0x72,0x88,0x4f,0x22,0x15,0x87,0xa0,0xa3,0x47,0x10,0x81,0x64,0xff,0x94,0x77,0x5d,0xce,0x6d,0xd8,0x29,0xb1,0x9c,0x8e,0xce,0xa8,0x39,0x4f,0xfc,0x36,0x3c,0x50,0xb2,0xf1,0x08,0x66,0x1a,0xf0,0x22 +.byte 0x65,0x1f,0x4d,0x17,0xd3,0x63,0x10,0x64,0xd1,0xc6,0x5a,0x3e,0x82,0x72,0x0c,0x48,0x5e,0x07,0x9c,0x07,0xa0,0x40,0x60,0xab,0x74,0x9a,0x00,0xdf,0xd7,0x7d,0xd4,0x11,0x4e,0xce,0x5a,0xaf,0x12,0x4f,0xe7,0x12,0x36,0x1a,0x12,0x11,0x16,0xb7,0xad,0x4b,0x28,0x84,0x7b,0xd8,0x30,0x0d,0x85,0xb8,0x76,0xde,0xa3,0x78,0x8c,0xb7,0x7c,0xbc +.byte 0x97,0x33,0x53,0x95,0xf8,0x14,0x5f,0xf8,0x0d,0xc1,0x6b,0x79,0xa2,0x42,0x49,0xab,0xae,0x8e,0x78,0xf3,0x51,0x01,0xcc,0x20,0x36,0x80,0xbd,0x32,0x0b,0x1b,0xd2,0xcd,0x27,0x52,0x69,0x1b,0x4a,0x37,0xba,0x31,0xe4,0xc2,0x03,0x8d,0x00,0x48,0x4b,0xcd,0x39,0x2e,0xec,0x94,0x2e,0xe0,0x81,0xfd,0x94,0xd9,0x86,0x39,0x23,0x87,0x3c,0x2f +.byte 0x25,0xe1,0x5b,0x22,0xe0,0x2e,0x37,0x6d,0x9b,0x97,0x9c,0x94,0x37,0x01,0x26,0xb8,0xb1,0x73,0x7c,0xfc,0x0a,0x64,0xe7,0x54,0xf1,0x0f,0x71,0xa1,0xd6,0xc7,0xc8,0xb4,0x86,0x2d,0xfe,0x30,0x8b,0xca,0xb2,0x18,0x21,0xc0,0xc7,0x7d,0x60,0xcf,0x2e,0x25,0xb0,0xa4,0x1a,0x28,0x19,0xa9,0xa9,0x15,0x32,0x5e,0x21,0x89,0x3a,0x99,0x5f,0x50 +.byte 0x86,0x37,0x3b,0x10,0xb8,0xa5,0xad,0x8e,0xbf,0xfc,0x8c,0x85,0xf1,0x76,0x5c,0xe7,0x4d,0xac,0xe7,0x21,0xb3,0x45,0x87,0x3b,0x05,0xc8,0x41,0xf4,0x99,0x83,0x28,0x40,0x6b,0x30,0x37,0x31,0xd2,0xb3,0xdd,0x43,0x3b,0x3f,0xec,0x50,0x58,0x7d,0x20,0xc6,0xb2,0xa9,0x3c,0x22,0x38,0xea,0x16,0x32,0x01,0xc4,0xb0,0x9f,0x7d,0x12,0x91,0x82 +.byte 0x0c,0xd8,0x36,0xfc,0xa4,0xec,0x06,0xb2,0xc2,0xce,0x9b,0xa4,0x53,0x71,0x77,0xdd,0xc3,0xfc,0x34,0x6f,0xd9,0x5c,0xfc,0x36,0xdd,0x63,0x19,0x06,0xfb,0x3c,0xf3,0x3f,0x82,0x28,0x6d,0x00,0xf9,0xfd,0x8d,0x6b,0x79,0x06,0x8a,0xe7,0x6f,0xcc,0x39,0x12,0x80,0x71,0xcb,0x71,0xb3,0xb6,0xa4,0xa8,0xbe,0x61,0x9d,0x1f,0x48,0xa2,0x15,0xa1 +.byte 0xb5,0xf5,0x16,0x70,0xc5,0x39,0xce,0x43,0xa3,0x09,0xe5,0xf4,0x8b,0x77,0x18,0x5e,0xa0,0x77,0xa3,0xa4,0x17,0x2c,0x3e,0x50,0x73,0x2f,0xaa,0x5d,0x58,0x5e,0xdc,0xec,0xaf,0xca,0x6e,0x57,0x80,0xa3,0xd5,0x94,0x30,0x7c,0x11,0x75,0xc4,0xbb,0x9d,0x18,0xc1,0x5a,0x58,0xc7,0x04,0x56,0xb1,0x3a,0x21,0x55,0x02,0xea,0xad,0x58,0x19,0x72 +.byte 0xdc,0x7d,0x0e,0x41,0x62,0x1b,0x5c,0x48,0x97,0x3f,0xed,0xd7,0x4e,0x30,0x1f,0xf5,0xde,0xc5,0x23,0xf2,0xd7,0x22,0xde,0x2f,0x3e,0x80,0x06,0x81,0xf6,0x24,0xb7,0x91,0x09,0x56,0x91,0x00,0x1a,0xea,0xaa,0xa6,0xc2,0x8b,0xc9,0x78,0xd7,0xde,0xf6,0x87,0xb1,0x04,0xcc,0xbb,0xc1,0xc6,0x48,0x43,0xc8,0x03,0xb2,0xdd,0x70,0xc0,0xe3,0xf5 +.byte 0xc0,0xf5,0x13,0xd5,0x11,0x41,0x7f,0x1a,0xdc,0x48,0xf5,0xd6,0x1b,0x0a,0x84,0xd2,0x84,0xcd,0x10,0x4f,0x0a,0xd7,0xcb,0x41,0x61,0x1c,0xcc,0x5c,0xa9,0xbd,0x6e,0x6a,0xf3,0x81,0xd8,0xaa,0x3a,0xff,0x39,0x90,0x8e,0x33,0xe6,0x58,0x13,0x5f,0xec,0x58,0x74,0x35,0xe0,0x06,0x38,0x0f,0xd0,0xbf,0x8d,0xf7,0x26,0x99,0xea,0xdd,0xfb,0xdf +.byte 0x5b,0xcc,0xf1,0x3d,0x9b,0x84,0x8b,0x5b,0xe8,0xc4,0xc6,0x3e,0x0a,0x55,0xec,0x73,0xf7,0x70,0xb1,0xc8,0xfa,0xf8,0xd6,0x72,0x2c,0x6d,0x8d,0xc1,0xa3,0xb2,0x9a,0xe7,0x80,0x6d,0x09,0xa6,0x76,0x06,0x71,0xf9,0x95,0x9a,0xa9,0x2f,0x4b,0x7c,0xad,0x64,0x01,0x01,0x91,0xe4,0x87,0x1d,0xe1,0x46,0xf5,0x4a,0x96,0xc6,0x58,0xd9,0xe0,0xa9 +.byte 0x2f,0x80,0x1e,0xd6,0xe9,0xa6,0xeb,0xfe,0x5a,0xb6,0xd3,0xe8,0x76,0xd2,0x51,0xc6,0x68,0x34,0xc9,0xed,0x76,0x29,0x7e,0x63,0xb1,0x09,0xdf,0x23,0x47,0x41,0x2f,0x70,0x46,0x4d,0xbb,0x36,0xc8,0x84,0xe9,0x58,0x20,0x6b,0x04,0xb2,0xa4,0x1c,0x4d,0xe0,0xa5,0xa2,0x59,0xc9,0xed,0x63,0x25,0x5f,0x3f,0x24,0x18,0x59,0x29,0xe3,0x79,0xbd +.byte 0x35,0x50,0xee,0x81,0x59,0xff,0xd4,0x0e,0x62,0xd3,0x52,0x30,0x81,0xa2,0xe6,0x9e,0xc3,0xc9,0x7a,0x10,0x57,0x36,0x27,0xb7,0x3c,0x61,0x38,0x89,0x70,0xa0,0xc5,0xdf,0x78,0x05,0xa5,0x81,0xe2,0x8a,0x93,0xda,0x7c,0xaf,0xbf,0x6d,0x42,0x09,0x1b,0x43,0x9d,0xf9,0x26,0x87,0xc3,0x84,0x6c,0xb7,0x25,0x31,0x50,0x00,0xd8,0x13,0xc0,0xc0 +.byte 0x6c,0x21,0x82,0x6d,0xf9,0x2f,0xef,0x40,0xe8,0xf8,0xae,0x4d,0x9e,0x1d,0x4a,0xda,0xa0,0x0d,0x77,0x36,0x8b,0xed,0xaf,0x6e,0x2a,0x3d,0xa8,0x36,0xe4,0xff,0x37,0xc2,0xa3,0x11,0x5e,0x68,0x58,0xa8,0xa3,0x19,0xf3,0xc1,0x33,0xea,0x39,0x49,0xfe,0x51,0x87,0xb6,0x31,0x6a,0x61,0x47,0xe7,0xb1,0x46,0xde,0x5a,0xf7,0x93,0x06,0xa7,0x72 +.byte 0xa9,0x2e,0x9e,0x2e,0xc9,0x7f,0xe1,0xb2,0x86,0xb4,0xc9,0xff,0x3b,0xf7,0xaf,0xef,0x91,0x47,0xc2,0xfa,0x42,0x0a,0x4e,0xbb,0x10,0x0d,0xea,0xa4,0x11,0x54,0xa9,0x53,0xde,0xc4,0x01,0xde,0xc7,0x2d,0x1f,0x18,0x40,0x79,0xd1,0x44,0x7d,0x51,0x1d,0xf6,0xdc,0x6f,0xad,0xa2,0x5d,0xd9,0xbe,0x5d,0x11,0x57,0xb7,0x68,0x0d,0x96,0xad,0xb3 +.byte 0x32,0xf7,0x99,0xcc,0x0e,0x03,0xa2,0x79,0x9b,0x63,0xce,0xee,0xf9,0x0c,0xfd,0xfa,0x9a,0x82,0xc9,0x43,0xd3,0xd5,0x23,0xfa,0xac,0x75,0xbe,0x61,0x85,0x18,0xb6,0x75,0x72,0x8d,0x17,0xdd,0xde,0x3f,0x6d,0xb4,0xe8,0x47,0x09,0xe1,0xa7,0xe0,0x4c,0xce,0x93,0x7b,0xc3,0xa3,0x3f,0xc0,0x81,0x21,0x6f,0xe8,0xce,0x68,0x61,0xde,0x1a,0x58 +.byte 0x48,0x7f,0xb4,0xae,0xfd,0x7c,0x80,0x63,0x43,0x5a,0xfc,0xf9,0xf9,0x4d,0xb4,0x8c,0x85,0x27,0x12,0x4f,0x7d,0xe8,0x69,0xc3,0x7d,0x57,0x63,0x0d,0x5f,0xd2,0x85,0x4e,0x0c,0x9a,0x0d,0x1c,0x4d,0xdf,0x3f,0x9a,0x16,0x2f,0x34,0x43,0xc3,0xf0,0xf1,0x16,0x16,0xd2,0x9f,0x2e,0x78,0xd8,0x3c,0x63,0xa0,0x7e,0x02,0x8e,0x65,0xd2,0xb0,0x61 +.byte 0xb0,0x1d,0x7a,0x8f,0xf7,0x30,0x45,0x05,0xf7,0x15,0xc3,0x69,0x24,0x98,0xc3,0x74,0x20,0x16,0x09,0x57,0x39,0x16,0x68,0x23,0x33,0x62,0x4c,0xf5,0xd6,0x34,0xe3,0xad,0x7a,0x14,0x64,0x8c,0x2b,0x48,0x96,0xf9,0x85,0x39,0x19,0x73,0x27,0x04,0xa6,0x55,0x66,0x15,0x8c,0xf1,0x47,0xcd,0x53,0xaf,0x31,0x3a,0xd9,0xfa,0xf9,0xac,0xbd,0xb8 +.byte 0x27,0xe0,0xaa,0xa5,0x62,0x85,0x9f,0xbb,0x4e,0xaf,0xa5,0x72,0x42,0x98,0xa6,0x7f,0xa1,0xb6,0xac,0x17,0xc2,0x2c,0xf3,0xd6,0xc0,0x14,0x4b,0xb3,0x86,0x88,0x89,0x81,0x83,0x7d,0x9d,0xf7,0xe3,0xe4,0x27,0xba,0xa8,0x03,0xb4,0xe3,0x97,0x74,0x1c,0x0d,0xab,0xb4,0x6e,0xc6,0x9e,0x58,0xdd,0x15,0x95,0x2f,0xa6,0xd6,0xaa,0x5a,0x96,0x71 +.byte 0x69,0xca,0xe0,0x5f,0xd2,0x3c,0x66,0x1b,0x58,0x25,0xd6,0xec,0xc0,0x46,0x3e,0x56,0xd0,0xe1,0x36,0x44,0x56,0xc0,0xf2,0x15,0x48,0x9e,0x07,0xce,0x5d,0xb9,0xd4,0x4e,0xcc,0x31,0x26,0xaa,0xdb,0x6a,0x87,0x98,0x0e,0x37,0xfc,0xc5,0x91,0x28,0x1b,0xf8,0x70,0xbf,0x30,0x71,0xbe,0xa0,0x81,0x1e,0x30,0x33,0x37,0x37,0xc8,0x07,0x08,0x9b +.byte 0x8f,0xe4,0x27,0x9f,0x90,0x67,0xb4,0x96,0x08,0xd7,0x30,0x9e,0xa6,0x53,0x39,0xd1,0x9b,0xde,0x02,0x35,0xf3,0xb1,0x19,0x7b,0xd2,0x28,0x5a,0xc3,0x1f,0x69,0x0e,0x48,0xbf,0xa3,0xb4,0x55,0xd1,0x10,0x3d,0x30,0x71,0xc6,0x82,0x2d,0xb8,0x6f,0xe6,0x99,0x6b,0xef,0x9f,0x86,0xed,0x93,0x13,0xb6,0xb0,0x87,0x91,0x77,0x4a,0x00,0xe4,0x5f +.byte 0x4c,0x7d,0x41,0x3b,0xc9,0xda,0x99,0x6b,0xff,0xec,0xef,0x05,0x3c,0xc6,0x0d,0xec,0x68,0x12,0x44,0x31,0xac,0xc9,0x0b,0x9c,0xf5,0xea,0xed,0xda,0x88,0xec,0x6e,0x6e,0x73,0xda,0x85,0x52,0x69,0xa1,0x13,0x52,0xcf,0xc3,0x4d,0x95,0x88,0xec,0x1f,0x53,0x81,0x6f,0xac,0x53,0x60,0x48,0x20,0x9a,0x4d,0x88,0x2c,0x4b,0xb0,0x69,0x5f,0x07 +.byte 0xf9,0xa7,0x2c,0x9a,0x13,0x91,0x86,0xa2,0x98,0x20,0xa9,0x80,0x1e,0xaa,0x8e,0xbc,0x3c,0x3d,0x51,0x34,0x3d,0x5b,0x80,0xe4,0x39,0xfe,0xc8,0xb1,0x6d,0xfe,0x36,0x9d,0x9b,0xde,0x22,0x39,0x41,0xe9,0xff,0xda,0x67,0x67,0xd4,0xeb,0x60,0x44,0xd5,0xc1,0x74,0xcd,0xa0,0x98,0x06,0x34,0x76,0xf8,0xe5,0x0d,0xc8,0x52,0xca,0x83,0xd2,0xdd +.byte 0xf2,0x12,0x36,0x7d,0x3e,0x7f,0xbd,0xa6,0xd8,0x1e,0xc0,0x9d,0x67,0x2a,0x33,0x87,0x86,0x79,0x7a,0x70,0x3a,0x63,0x0b,0x74,0x77,0x89,0xce,0x8f,0x5a,0x3b,0xf3,0x2e,0x52,0x4d,0x1d,0xc6,0xc3,0xc8,0x69,0x98,0xdc,0x81,0x45,0x99,0xfd,0xcd,0x6b,0x6d,0x05,0x33,0x40,0xde,0xb3,0xbd,0x4a,0x27,0xc2,0x9e,0x8b,0xf1,0x4c,0xac,0x92,0x82 +.byte 0x55,0x04,0x79,0xe7,0x28,0x74,0x5b,0x70,0xdc,0xc0,0x4f,0x0c,0xcf,0x3a,0x7f,0x08,0xcc,0x2e,0x1d,0xfd,0x8d,0xd9,0x5c,0xe2,0xa7,0x98,0xc1,0xe8,0x4b,0x96,0xbe,0x27,0xd6,0xfd,0x0a,0x59,0x30,0x33,0x85,0x41,0xc5,0x63,0xab,0xe7,0xda,0x26,0xbd,0xce,0xe7,0x9d,0x50,0xd7,0x2d,0x67,0x7a,0xa1,0x05,0x2b,0x74,0x60,0x5e,0x6c,0x04,0x2b +.byte 0xba,0xe6,0x2d,0x25,0xc9,0x00,0xd0,0xf0,0xa5,0x4f,0x22,0x59,0x34,0xb8,0x43,0x6b,0xb7,0x67,0x25,0x99,0xff,0x75,0x17,0xb1,0x13,0x7e,0x34,0x1d,0x42,0xa3,0x6b,0xb5,0x9d,0xfe,0xa1,0x71,0x0d,0x90,0x81,0x58,0xfc,0xc7,0x85,0xe6,0xbd,0xc2,0xcc,0xc9,0xc9,0x23,0x6e,0xd6,0xbe,0x4a,0x61,0xd4,0xf5,0x9e,0x37,0x6a,0xb1,0x8b,0x91,0x59 +.byte 0xe1,0x3e,0xac,0x87,0x54,0xa6,0xf9,0xf5,0x90,0xd2,0x7c,0xba,0x4b,0x37,0x33,0x1b,0x88,0x5e,0xbd,0x78,0x3f,0xed,0x43,0x40,0x4f,0x16,0x59,0x29,0xbc,0x27,0x98,0x87,0xfe,0x62,0x56,0x93,0x21,0x0a,0xca,0xc1,0x21,0x99,0xb3,0x32,0xbb,0x5a,0x79,0x40,0xab,0xea,0x00,0xf8,0xe9,0x90,0x0d,0x59,0xbd,0x6e,0x7f,0x74,0x01,0x50,0x67,0x3a +.byte 0x8e,0x24,0x1d,0x6c,0xc8,0xd6,0x93,0xca,0x71,0x95,0xec,0xac,0x78,0xe9,0x1f,0x38,0x0d,0xa2,0xe5,0x32,0x90,0xa2,0xaf,0xef,0x15,0x06,0xd6,0x52,0xa4,0xd2,0x94,0x0f,0xbd,0x86,0x81,0x82,0x12,0x9b,0x3a,0xc4,0x0b,0xdf,0x8a,0x5f,0xc6,0x3b,0xb4,0x13,0x9b,0xeb,0xed,0x2d,0x06,0x46,0xa3,0xbe,0xbb,0xe1,0xe1,0x93,0xa1,0xab,0x46,0xf3 +.byte 0xd0,0xd9,0xce,0xb6,0xfb,0xd0,0xd5,0xb6,0xde,0x0c,0xed,0x90,0x18,0x6c,0x1e,0x46,0xb0,0x36,0xa7,0xf1,0x29,0xbe,0x9a,0xa0,0xcf,0xed,0xd6,0xaf,0xb8,0x89,0x9b,0x83,0xa8,0xa0,0x8d,0x26,0xaf,0x8f,0x48,0x66,0xfc,0x22,0x1a,0xc0,0xcf,0xf8,0x90,0x57,0x7e,0x25,0x5f,0xe4,0x0c,0x68,0xd2,0xaa,0x59,0x09,0x2f,0x6d,0x3f,0x80,0x8d,0xe0 +.byte 0xfa,0x25,0xb0,0xe0,0x85,0xe9,0x13,0x39,0x3d,0x1f,0xed,0xd1,0x94,0x9b,0xb5,0xc2,0x65,0xda,0xec,0x7a,0x1f,0x2f,0xe2,0x0a,0x42,0x09,0xbd,0x79,0x7d,0xcb,0xb8,0x4a,0x02,0x2b,0x72,0xaf,0x33,0x85,0x72,0x1b,0x18,0x0c,0xa3,0xec,0x39,0x0e,0x30,0x21,0x41,0xf8,0x2e,0xc7,0x8e,0x5c,0x4c,0xda,0x22,0x49,0x8c,0xa7,0xfb,0x89,0x76,0x2e +.byte 0x45,0x90,0x6c,0xeb,0x70,0x78,0x6d,0x6e,0xee,0x12,0x6c,0xb9,0xb9,0x8d,0xe7,0xf3,0x4d,0x86,0xc4,0x58,0x49,0x55,0xa6,0x86,0xaf,0x39,0x03,0x21,0xfa,0xa7,0xdd,0x51,0x80,0x79,0x6d,0x5b,0xa5,0x58,0x0f,0xfd,0x57,0xb3,0x83,0xe6,0x0d,0x25,0xec,0x55,0xdc,0x0a,0x6f,0xbc,0x7d,0xfd,0x94,0x16,0xdd,0x60,0x9f,0x2a,0x4b,0x6c,0x82,0x03 +.byte 0x4b,0x44,0xbb,0x84,0xdc,0xcb,0x97,0x8e,0x58,0xe7,0xc1,0x79,0xa9,0xf3,0x53,0x78,0x1f,0xf1,0x3e,0xdd,0x94,0x24,0x6d,0xb1,0xd2,0x99,0xbc,0xa1,0xbe,0x7d,0xdd,0xff,0xa8,0x5d,0xd2,0xc2,0xba,0xad,0x60,0x6b,0x40,0x5d,0x7b,0x99,0xd2,0xea,0x45,0x66,0x80,0x6c,0x47,0xf2,0xeb,0x94,0xb8,0xe8,0xe8,0xa0,0x46,0x05,0xe1,0x4f,0x40,0x23 +.byte 0x34,0xdf,0x91,0x63,0xae,0xc9,0xe7,0x32,0x20,0x9a,0x95,0x1e,0xcd,0x5a,0x60,0xe1,0x3d,0xe0,0xf1,0x16,0x3d,0x6e,0x8b,0x96,0x23,0xe0,0xaa,0x1d,0x1a,0xde,0xed,0xc6,0x63,0xb5,0x46,0x8b,0x78,0x71,0x9a,0x14,0x88,0x79,0x61,0x68,0x6b,0xcf,0x80,0xd8,0x9c,0xaa,0xfb,0xb1,0xc0,0xf3,0x39,0x07,0x26,0x56,0x80,0xba,0x9d,0xf5,0xe7,0x95 +.byte 0x99,0xac,0x90,0xea,0xe7,0xe1,0xc9,0x0d,0x40,0x94,0x83,0x58,0xd2,0xc3,0x2b,0xce,0x1e,0xae,0x2a,0xa6,0xfa,0xc7,0x89,0x44,0xcb,0xe2,0x9e,0x74,0x33,0xaa,0x70,0xe5,0x28,0x3a,0x51,0x74,0x53,0xe2,0xfb,0x7c,0x47,0x76,0x22,0xdf,0x46,0xa6,0x01,0x17,0xef,0x88,0x43,0x46,0x3f,0x1a,0x26,0x0c,0xad,0xf4,0x31,0x55,0xf2,0xe7,0xc9,0x35 +.byte 0x6f,0x7c,0x0c,0x5c,0xfd,0x43,0xa4,0x6c,0x6c,0x74,0xf0,0xa4,0xec,0x1d,0x83,0x97,0xc1,0x6c,0x9c,0xd7,0x97,0x90,0x7c,0x07,0x88,0xc0,0xb4,0x79,0x2c,0x7a,0x9c,0x93,0xa2,0x15,0x6c,0xd2,0xa9,0x45,0xa5,0xc1,0x16,0xfe,0x72,0xf4,0x01,0x32,0xe4,0x51,0xdd,0xdb,0x50,0xe3,0x61,0x4e,0x29,0x1e,0x27,0x10,0xe9,0x5e,0x30,0x2b,0x30,0x27 +.byte 0x99,0xff,0x92,0x23,0x04,0x8d,0x28,0x68,0x28,0xd3,0x0f,0xec,0xbb,0xf9,0xfb,0x44,0x1c,0xaa,0x8b,0x38,0x95,0x67,0x1e,0xf5,0x42,0xc9,0xec,0x05,0xeb,0x94,0xe5,0x1c,0x8a,0x2a,0xef,0x3b,0x74,0x46,0x89,0x4f,0xd5,0x6f,0xa0,0xe5,0x74,0xae,0x24,0x8d,0x81,0xae,0x9d,0x3c,0x3e,0x3d,0x41,0x54,0x8f,0xd9,0xc2,0x98,0xf4,0x84,0xeb,0x30 +.byte 0x6a,0x06,0x67,0x11,0x2d,0xb0,0x55,0x70,0x26,0xdf,0x19,0x5f,0x81,0xe9,0x39,0x69,0x3a,0xd6,0x09,0xa4,0x40,0x22,0x1f,0x5c,0xbf,0xd5,0xa6,0xea,0x69,0x99,0x0d,0xea,0x70,0xed,0xfe,0x3a,0xba,0x23,0x8b,0xab,0x08,0xfe,0xfb,0xe9,0x1a,0x88,0x80,0x13,0x45,0x9c,0xca,0x2e,0xda,0x4a,0xc8,0x5d,0x15,0x52,0x87,0x36,0x9b,0x87,0x8a,0x76 +.byte 0x5d,0x31,0x24,0x4a,0xcb,0xf5,0xd3,0xd3,0xc1,0xec,0xde,0x1e,0x48,0x99,0xd5,0xcb,0x93,0xf7,0xca,0x2d,0xa4,0x66,0x5e,0xa4,0xcf,0xc6,0x15,0x20,0x10,0xb1,0xe2,0x8e,0xb9,0x44,0xa7,0xc3,0x54,0x14,0x86,0x08,0xb7,0x89,0x52,0xd5,0x72,0xc5,0x62,0x4d,0x82,0x96,0x23,0xcf,0x6e,0x52,0x3a,0x92,0x53,0x48,0xa2,0xa5,0x9d,0xa4,0xcc,0x32 +.byte 0x45,0x5a,0xdf,0xe2,0xbe,0xce,0x28,0xc8,0xb1,0xb7,0x0f,0x6a,0x38,0x28,0x14,0x66,0x55,0x7a,0xab,0x35,0x56,0xd0,0xc7,0xe5,0xa1,0x8a,0x84,0xf7,0xc5,0xa9,0xdb,0x2a,0x45,0xe9,0x34,0x2d,0xf2,0xed,0x2b,0xa9,0x9e,0x49,0x1b,0x23,0x10,0xeb,0x0e,0x01,0x46,0x6f,0x7a,0x50,0x09,0x5f,0xc3,0xb6,0x1e,0x2f,0x1a,0x3e,0x89,0x32,0xaa,0x5a +.byte 0xaa,0xef,0x23,0x45,0xdc,0xb5,0x7e,0x5f,0x87,0x77,0xde,0x50,0xab,0xbf,0x9e,0x62,0xa8,0xe0,0xf0,0xc8,0x4a,0xf1,0x4e,0xaf,0xe4,0x50,0x8a,0xfe,0xc9,0x68,0xdd,0x19,0x1d,0xc6,0x54,0xe5,0x38,0x0a,0x6f,0x36,0xe4,0x85,0xe8,0xab,0xc4,0x06,0xef,0x07,0x29,0xce,0xea,0x9d,0x2e,0x22,0x97,0x18,0x7e,0x59,0x89,0x92,0x31,0xc5,0x87,0x50 +.byte 0xa8,0x23,0x22,0x58,0x47,0x27,0x1c,0x89,0x5f,0xec,0x94,0x1d,0xb2,0xc8,0x61,0x1e,0x0a,0x80,0xd3,0xe9,0xbf,0x65,0xb9,0x66,0x32,0x56,0xde,0xd2,0x13,0xee,0xea,0xc4,0xc9,0xbf,0x4c,0xb7,0xa4,0x1c,0xc0,0xbf,0xcf,0xa4,0x58,0x1f,0x98,0x1d,0x25,0x4e,0x51,0xd9,0xbe,0x89,0x32,0xdb,0x7a,0xa6,0x39,0xa9,0xbf,0xed,0x65,0x6b,0x92,0xc4 +.byte 0x8d,0xcd,0x63,0x18,0x65,0x44,0x95,0xcf,0x17,0x72,0x8f,0x27,0x79,0x83,0xda,0xe3,0xe7,0xd9,0xca,0x57,0xff,0xa3,0x15,0xbf,0xb6,0xd8,0xc2,0x8c,0xe8,0xdb,0x8c,0xdc,0x54,0x6a,0xc8,0x57,0x6e,0x24,0xc3,0x3c,0x1f,0x33,0xdd,0x68,0xbd,0x7a,0xa3,0xbc,0xa9,0x9a,0xe8,0xfc,0x97,0xa5,0xbe,0x59,0xfb,0x77,0xcd,0x22,0xc6,0x3d,0x95,0x21 +.byte 0xcb,0xf7,0x8d,0xc1,0x77,0xc6,0xe0,0x06,0xb2,0xdb,0xec,0x54,0x19,0xad,0x02,0x25,0xe0,0x0f,0xda,0x4c,0xa5,0xf2,0x47,0x3f,0xc9,0xa0,0x91,0x21,0x39,0xe9,0x74,0x2a,0x9a,0xc1,0x57,0x86,0x3c,0x32,0x27,0x4c,0xc2,0x2d,0x50,0xbd,0x7a,0x04,0x9c,0x45,0x0d,0x7e,0x06,0x1d,0x3e,0xc1,0x6f,0x06,0x7f,0xd4,0x71,0xd3,0x5c,0x66,0x74,0xa7 +.byte 0x33,0x75,0x64,0xa8,0x7d,0xc0,0x23,0xda,0xb0,0x6d,0x12,0xbe,0x83,0x98,0xe7,0x65,0x38,0x4d,0x39,0xc3,0xd7,0x33,0xfb,0x58,0x64,0xfc,0xde,0xd7,0xbf,0x9e,0xdb,0xcc,0x7a,0x35,0xac,0xdf,0x13,0x08,0xbc,0x0a,0x55,0x82,0x5f,0xc3,0x74,0xc5,0xb2,0xdb,0x89,0xdc,0x9c,0x60,0xfa,0x02,0x1c,0xba,0x5b,0x7e,0x0f,0xb1,0x0f,0xad,0x43,0xe1 +.byte 0xe1,0xbe,0x1e,0x06,0x05,0x0f,0x39,0x80,0x3d,0x7d,0xbe,0x8f,0x38,0x25,0x46,0x5e,0xea,0x47,0x36,0x65,0x4c,0x3c,0x6c,0xd6,0xaa,0x46,0xaa,0xb0,0x95,0x1d,0xff,0x67,0x6c,0x70,0x9d,0xec,0x3d,0x3d,0x4c,0x2f,0xd9,0x2b,0xb0,0xbd,0x8c,0x6a,0xca,0xac,0x0c,0x53,0xa1,0xda,0xd8,0xc1,0x3c,0xaa,0xcc,0x50,0x85,0x41,0xa1,0xa7,0xe9,0x7f +.byte 0xf7,0xa8,0x28,0xb1,0x5f,0xd6,0x77,0xc9,0xb5,0xae,0x33,0xa7,0x2d,0x16,0xe0,0x13,0xe8,0xd4,0xf9,0x4e,0x62,0x2e,0xc2,0x9a,0xf3,0x83,0xe0,0x45,0x43,0x68,0x40,0x5a,0x56,0xf3,0x31,0xc8,0x5b,0x46,0x0b,0x38,0x1f,0xa5,0xff,0xe6,0xa1,0x81,0xc0,0x91,0xe5,0x5a,0x63,0x8f,0x47,0x9a,0xe7,0x26,0x0d,0x78,0x8d,0x11,0x7d,0xc8,0xd4,0x9f +.byte 0xc1,0xf7,0x8f,0x93,0xfa,0x2f,0xb5,0xfd,0x6d,0xa4,0x34,0xcf,0x3c,0x6c,0xf6,0x64,0xae,0x5c,0x60,0xa2,0xb4,0xcc,0x18,0x3e,0x08,0x8e,0x36,0x88,0xab,0xc3,0xea,0x53,0x4f,0x1c,0x9e,0xe6,0xef,0x2d,0x9c,0x78,0x4a,0x3a,0x5a,0x60,0x8e,0xf7,0xeb,0x0b,0x36,0xb1,0xbb,0x59,0xe2,0x5e,0x64,0x60,0xe5,0xd6,0x3d,0x2a,0xe1,0x1b,0x03,0x40 +.byte 0x8d,0xde,0x2e,0xd0,0x76,0x0a,0x6b,0x63,0x2a,0x53,0x2d,0x39,0xe0,0x53,0xee,0x7d,0xc4,0x8a,0x39,0xc5,0xda,0xfc,0x31,0x7e,0xa2,0x1b,0x11,0x1d,0x8a,0x8e,0x66,0xf4,0x00,0x17,0xd3,0x78,0x1b,0x94,0xad,0xcf,0xdd,0x56,0xce,0xaf,0xf6,0x34,0xe4,0xb6,0x47,0xe0,0xda,0x1b,0x36,0x4f,0x86,0x26,0xc1,0x65,0xec,0x85,0x8c,0xa9,0xfe,0x96 +.byte 0x75,0x0d,0xe3,0xeb,0x9a,0xa6,0x3f,0xb3,0x10,0x03,0x85,0x24,0xf2,0xb5,0xcd,0x69,0x7d,0xba,0xa2,0x5c,0x8a,0x6d,0x45,0xf4,0xc8,0x4f,0x69,0x8e,0xd4,0x69,0x82,0x42,0xfd,0x00,0x59,0xfd,0x20,0x7a,0x63,0x58,0x56,0x30,0x21,0x73,0xbd,0xd4,0x49,0x84,0x3f,0x51,0x0e,0xfb,0xd3,0xfc,0x93,0x17,0x7f,0x23,0x75,0x25,0xea,0x78,0x79,0xf7 +.byte 0xec,0x22,0xef,0x86,0x91,0x0a,0x90,0x10,0x71,0x3b,0xb8,0x8e,0xb7,0xc9,0xd1,0x26,0x98,0x7d,0x1a,0xab,0x74,0x3e,0x5f,0x10,0xa8,0x47,0xdf,0xc9,0x0a,0x03,0xbb,0xe2,0xbb,0x34,0xbe,0x87,0x1a,0x3e,0x13,0x4b,0xd5,0xdd,0x53,0xb7,0x65,0xb4,0x16,0x38,0xd3,0xfd,0x01,0xde,0xe8,0xba,0x1d,0x33,0x5b,0x7b,0x9b,0x9f,0xfb,0xe7,0x8d,0x82 +.byte 0x21,0x78,0x9e,0xb2,0xf5,0x16,0x37,0x88,0x47,0x9d,0x1a,0x2c,0xfe,0x6a,0xac,0xde,0x3e,0xc4,0xa8,0xed,0x64,0x46,0xdd,0x05,0x07,0x60,0xef,0x99,0x96,0xf0,0x84,0x27,0x38,0x58,0xe5,0xc0,0x53,0x7d,0x07,0xe3,0xa5,0x31,0xb5,0x8a,0xe7,0x50,0x94,0xbb,0x29,0xf9,0x58,0x13,0x91,0x5b,0x54,0x77,0xf6,0x91,0xb8,0x75,0x05,0x3d,0x70,0x3e +.byte 0x07,0x95,0x7d,0x37,0xbd,0x1d,0x29,0x4d,0x33,0x07,0x13,0x2b,0x54,0x70,0x9c,0x31,0xf1,0xcd,0x2d,0x28,0x09,0x43,0x90,0x24,0x8c,0x82,0xb0,0x08,0x71,0x08,0x97,0x7e,0x1a,0xbc,0x82,0xd8,0x31,0x0a,0x13,0xe9,0x22,0xf0,0x8d,0x2b,0x91,0xe5,0x2e,0x34,0x56,0x97,0x86,0xc9,0xbd,0x45,0x1e,0x32,0x03,0xcb,0xa1,0x29,0x00,0x81,0xd4,0x6e +.byte 0x5d,0xbc,0x0f,0x01,0x8d,0x5c,0xb9,0x80,0xcc,0xfe,0x0d,0xa3,0xef,0x8e,0x85,0x59,0x37,0xf7,0x64,0xa7,0xe5,0x2a,0xd5,0x44,0xee,0x91,0xcf,0x6c,0xf5,0x0a,0x9b,0xc7,0xdf,0xb6,0x02,0x2d,0xa4,0xf1,0x22,0x2a,0x97,0xfe,0x1d,0xb7,0x4c,0xc7,0x4f,0x2f,0x0b,0x38,0xd2,0xbf,0xfe,0xe3,0x94,0x55,0xae,0x85,0x0c,0x34,0x59,0x67,0x23,0x7b +.byte 0x4a,0x87,0xd9,0xd2,0xca,0xd5,0x38,0xd2,0x9d,0x05,0x2e,0xd8,0xe3,0x26,0x51,0xa4,0x14,0x66,0xfb,0x38,0x40,0x18,0x3b,0xda,0x43,0x85,0xc9,0xf5,0xf4,0xe7,0x22,0x82,0x45,0xa1,0xdf,0x98,0xa0,0xab,0x5f,0x7a,0x50,0x84,0x75,0x7a,0x70,0xa6,0x3b,0x04,0x20,0xed,0xa8,0x68,0x6d,0x3f,0x43,0xf8,0xb8,0xac,0xc7,0x32,0xa0,0xff,0x47,0xd5 +.byte 0xb3,0x92,0x6a,0x15,0x5a,0xf1,0x7c,0x32,0x30,0xda,0x1e,0x5d,0xab,0xcc,0xd0,0x3a,0xdc,0xcf,0x70,0xd8,0x4d,0xa3,0x50,0xac,0x50,0x42,0x53,0xc6,0xe0,0x3a,0x26,0xdc,0x77,0x30,0x31,0x59,0xa1,0xfc,0x4d,0x48,0x00,0x0d,0xe0,0x66,0xb3,0x9b,0xd3,0x38,0x45,0xbb,0x0c,0x57,0xc5,0x78,0xee,0x8c,0x96,0xea,0xa2,0x16,0xa3,0x12,0xb1,0x06 +.byte 0xd0,0x2a,0x70,0xf7,0xce,0x42,0xae,0x17,0x64,0xbf,0x13,0xa0,0xe9,0x62,0x57,0x1d,0x55,0x78,0xfa,0x72,0x19,0x58,0x15,0xea,0xe5,0xdf,0x72,0x0e,0xc6,0xd3,0xb4,0x3d,0x60,0xee,0x32,0x2a,0xce,0xdc,0xad,0xd0,0x34,0xe6,0xb4,0xcf,0xce,0x5a,0x4a,0x9f,0xaf,0x01,0xb3,0x2a,0xed,0x46,0xa0,0xad,0xaa,0x62,0x8b,0xa4,0xf7,0x4b,0xce,0x32 +.byte 0x35,0x29,0x1e,0x7a,0xda,0x74,0xf8,0xe5,0xda,0x52,0x66,0xaf,0x3d,0x1a,0xff,0x42,0xc0,0xcc,0xb1,0x32,0x36,0x10,0x44,0x34,0x6a,0x16,0xc2,0x5b,0x9a,0x35,0x3f,0xd2,0x29,0xc5,0x76,0x3c,0x24,0xc7,0x2b,0x92,0xae,0xe0,0xe2,0x04,0x6c,0x3b,0x97,0xda,0xfd,0x49,0x43,0x6d,0x35,0xf5,0xc3,0xc1,0x93,0xf8,0x2f,0x25,0xef,0x3e,0xd8,0xf2 +.byte 0xc0,0xb3,0xb5,0x71,0x01,0xe0,0x07,0x11,0xd5,0xf1,0xd3,0x54,0x59,0x93,0x77,0x2e,0x77,0xdc,0x57,0xd7,0x9b,0x0a,0xe2,0xde,0x29,0x04,0x81,0xa1,0x81,0x6f,0x94,0x86,0x39,0xd7,0x29,0x69,0x3f,0xfa,0xe4,0x02,0x01,0x85,0x04,0x21,0xd3,0x17,0xf5,0x68,0x85,0x6e,0x74,0x15,0x56,0xe6,0x5e,0x12,0x1c,0x0d,0x2f,0x7a,0x8d,0xe1,0xc8,0x47 +.byte 0x7b,0xdc,0x35,0x64,0xf1,0x00,0xc0,0x7b,0xd8,0x2c,0x8c,0x60,0x10,0x53,0x11,0x2c,0x5c,0xa2,0xb6,0x05,0xa3,0xcd,0x14,0xb6,0xd0,0x36,0xe9,0x74,0x78,0xc3,0x84,0x6b,0x51,0xa9,0xf9,0xf1,0x05,0xe2,0xd4,0xa3,0x57,0xec,0xb1,0x5e,0xd5,0x75,0x64,0xe3,0xb0,0xf9,0x8f,0x88,0x60,0xdf,0x8e,0x75,0xf9,0x32,0xfc,0x58,0x5b,0x4b,0x17,0xdb +.byte 0x41,0x04,0x6f,0x17,0x7a,0xf8,0xd0,0x47,0x8e,0xeb,0xd1,0xf9,0xa6,0xa8,0x52,0x7e,0x07,0x6b,0x5b,0x4d,0xb9,0xda,0x91,0x40,0x51,0x25,0x67,0x4b,0xf1,0x95,0x12,0x07,0xa9,0xa5,0x33,0x96,0x92,0x5e,0xb4,0x0e,0xf0,0x85,0x2e,0x70,0xd8,0xaf,0xae,0x9a,0x3d,0x0c,0xb0,0xee,0xe1,0x80,0x5a,0xb9,0x17,0xe6,0x00,0xa8,0x82,0xd0,0x9b,0xf5 +.byte 0xe3,0xa0,0x12,0xc4,0x15,0xd6,0x5e,0x57,0x5c,0xd2,0xb9,0xa7,0x8e,0xfd,0x09,0xc3,0xd2,0x66,0xfd,0x86,0xb4,0xdc,0xa3,0xc2,0xfe,0x16,0x86,0xc4,0x98,0xa3,0x2e,0x4c,0xc9,0x2c,0xd6,0x87,0x83,0x1b,0x6f,0xe2,0x44,0xd6,0x72,0x94,0x1d,0xba,0xaf,0x34,0x1f,0xf2,0x40,0x40,0x33,0x24,0x63,0xc1,0x26,0xef,0xbc,0x0f,0x3b,0x3c,0x65,0x2b +.byte 0xa7,0xc7,0xdf,0x96,0x67,0xab,0x92,0x0e,0x04,0x8c,0x82,0x9e,0xbe,0x52,0x61,0x40,0xdf,0x77,0x00,0xc5,0x01,0x9a,0xe9,0xde,0xe1,0xe2,0x45,0xb8,0xed,0x94,0xd5,0xf0,0x28,0x29,0xef,0x0d,0x91,0x07,0x9b,0xfe,0x69,0x78,0x26,0xd7,0xf9,0x51,0xf1,0x9c,0xf2,0xbb,0x83,0x2d,0x79,0x1e,0xff,0x97,0x13,0xdc,0x28,0x93,0x26,0x7c,0x54,0x52 +.byte 0xc0,0x92,0xeb,0x4a,0xa2,0xe3,0x01,0xfc,0x07,0xb9,0x26,0x11,0x03,0xe0,0x19,0xa8,0x9c,0xff,0x3a,0x95,0x26,0x3a,0x17,0xf1,0x7d,0x6a,0x6a,0xb2,0xb5,0x5a,0x07,0x43,0x2b,0xb7,0xdd,0x19,0x14,0xe0,0x05,0x91,0xc5,0xee,0x49,0x35,0x7b,0x1a,0x2d,0x34,0xda,0xa2,0x45,0x7e,0x0d,0x64,0x98,0xb6,0x2e,0x47,0xaa,0x6c,0x73,0x66,0x55,0x01 +.byte 0x27,0xb0,0xa9,0x13,0xa6,0xe0,0x74,0x38,0xb3,0x97,0xfe,0xaf,0xdc,0xc0,0x6a,0x4f,0xd8,0xdb,0x07,0x62,0x61,0x05,0xbb,0xa0,0xa8,0xc5,0xb3,0x89,0x13,0xbb,0x09,0x01,0x6f,0x09,0xcb,0x47,0x62,0x46,0xf0,0x4b,0xf0,0xb7,0x7c,0x39,0x8d,0xe5,0x7b,0x64,0x49,0x32,0x93,0x1e,0x94,0x0a,0x98,0xe0,0xca,0xc6,0x67,0x5b,0xdf,0x88,0x0a,0x26 +.byte 0x83,0x77,0xc3,0xd0,0x11,0x66,0x3d,0x25,0x91,0x61,0x80,0xfc,0x9c,0x50,0xfb,0xe8,0x81,0x6f,0xd8,0xfa,0x77,0x78,0x4c,0x2b,0x44,0xd0,0x92,0x52,0xa4,0x50,0x50,0x7e,0xa2,0xb9,0xe7,0x79,0x33,0x95,0xfe,0x29,0x1c,0x1d,0x43,0x9d,0xa7,0x12,0xfe,0xa1,0x45,0xf4,0xd9,0x1c,0x7e,0x5a,0x67,0x99,0x7f,0x22,0x7c,0xa3,0xb1,0x2d,0xb7,0x1d +.byte 0x6b,0xf6,0xb4,0x94,0xf2,0xd1,0x5c,0x28,0x56,0xe9,0x4f,0x21,0x81,0x96,0x37,0x7c,0x25,0x74,0x0f,0xf9,0xc5,0xf5,0xc6,0xe8,0x8f,0xbb,0xfb,0xe4,0xaf,0x23,0xac,0x4c,0x20,0x35,0x7d,0xb4,0x4a,0xde,0x90,0xec,0x16,0x30,0x95,0x1b,0x79,0xf6,0x77,0xfe,0x80,0x10,0xba,0xd2,0x49,0xda,0xca,0x9e,0x6b,0x63,0x2f,0x24,0x38,0xf9,0xee,0x20 +.byte 0x38,0x5c,0xeb,0xf5,0xbc,0x07,0x7a,0xeb,0xde,0xc4,0x97,0xcf,0x48,0x9b,0x80,0x40,0xfa,0x81,0xf5,0x24,0xa7,0xf3,0xf7,0x16,0xe9,0xba,0xae,0x9f,0xde,0xa1,0x00,0x34,0x74,0x36,0x9f,0x47,0xce,0xcf,0x35,0xdb,0x30,0x7e,0x72,0x81,0xc5,0xe1,0x59,0x07,0x3e,0xc7,0x5b,0x7b,0xd3,0xc6,0xeb,0x4e,0x71,0x9c,0xeb,0x41,0x37,0xd9,0x9e,0x34 +.byte 0x0b,0xc1,0x9c,0xf7,0xfd,0x56,0xb0,0xd6,0xa6,0xe4,0x1d,0xdf,0x43,0xc6,0xf3,0x26,0x0f,0x01,0x07,0x29,0x57,0x9c,0x8f,0xe1,0x31,0xc9,0xa6,0x98,0x0f,0x0e,0x27,0xfd,0xa0,0x59,0xdf,0x92,0x7b,0x0a,0x4c,0x42,0x4b,0x03,0x98,0x2a,0xea,0xcb,0xd8,0x0f,0x6d,0x19,0x0b,0x22,0x69,0x8b,0xaa,0x3b,0xc8,0x41,0x66,0x81,0xc3,0xaa,0x64,0x6d +.byte 0x44,0xdd,0xb9,0xe2,0xc4,0x47,0x6d,0xdf,0x61,0xe0,0xf3,0x26,0x40,0x23,0x2f,0xf9,0x2a,0xb3,0xfa,0xe2,0xe8,0x36,0xc0,0xd9,0x89,0xb0,0x05,0x47,0x36,0x20,0x3b,0x03,0x0c,0xd1,0x46,0x9b,0xc9,0x65,0xfa,0x14,0xba,0x68,0x49,0xfc,0x2a,0xb9,0x04,0x47,0xbb,0x64,0xe1,0x7f,0x5a,0xd3,0x70,0x19,0x0f,0x14,0x09,0xc0,0xbe,0xc3,0x9b,0x2f +.byte 0xd1,0x05,0x90,0x56,0x09,0x47,0xb3,0xc5,0x08,0x6f,0x89,0x59,0x8c,0xf3,0xd4,0x1c,0xaf,0x68,0x00,0x32,0x58,0xe2,0x66,0x55,0xe2,0xc3,0x46,0x73,0xfd,0x4b,0x63,0xc5,0xdd,0x48,0xa8,0x14,0xe9,0x07,0x94,0x8f,0x51,0x6e,0x2d,0x7c,0x62,0x97,0x73,0xa5,0x42,0x7d,0xad,0x43,0xcb,0x65,0x56,0xf0,0x23,0x28,0x72,0xdb,0x1f,0xcf,0x34,0x9a +.byte 0x62,0x06,0x8d,0xc9,0x86,0x40,0x6d,0xee,0x58,0x72,0x02,0xbb,0xce,0x33,0x6a,0xe4,0xcb,0x46,0x25,0xda,0x2f,0x8d,0xc9,0x8e,0xfe,0xcf,0xbb,0xfc,0xb0,0xe8,0xec,0xf2,0xf9,0xff,0x5d,0x70,0x9e,0x2e,0x22,0x0e,0x9a,0x4d,0xb8,0x26,0x7a,0x48,0x3f,0xba,0x5c,0xcd,0x10,0xf4,0x6d,0x89,0x3d,0x5d,0x87,0xd4,0x69,0xb8,0x4a,0x20,0xc6,0xf8 +.byte 0x03,0x6c,0x60,0x1e,0x9c,0xc6,0xe3,0x39,0x9b,0xa1,0x16,0x64,0xed,0xc6,0xd7,0x54,0xfd,0x8d,0xa0,0x2f,0xcf,0xc6,0xde,0x43,0xe4,0xc5,0xb7,0xd6,0x00,0xaf,0x95,0x7a,0xc6,0xde,0x26,0x59,0x39,0xb0,0x12,0x6b,0xe1,0x3c,0xa9,0x09,0xb6,0x15,0xb0,0x62,0xad,0xa9,0x11,0x4f,0x86,0xde,0xc6,0xe8,0x32,0x46,0x78,0xeb,0x60,0x81,0x6b,0x8f +.byte 0xac,0x80,0xbf,0xa4,0xc4,0xb7,0x5f,0x3b,0x2f,0xf8,0xe4,0x05,0xcf,0xbf,0xa3,0x14,0x6f,0x16,0xbc,0x6c,0x4e,0x31,0xd7,0x79,0x09,0xcf,0x9c,0x58,0xa3,0x0b,0x1a,0x31,0x4b,0xda,0xcb,0x11,0x35,0xb1,0xf5,0xbb,0xfb,0x00,0x46,0x6d,0x70,0x5e,0x4a,0x85,0x19,0xdf,0xb5,0xd0,0x03,0x2e,0x5d,0x01,0x95,0x4e,0x5a,0x59,0x99,0x24,0xac,0x3f +.byte 0x2d,0x64,0xaf,0xef,0x40,0x16,0x2a,0xcc,0x6a,0x6c,0x0f,0xe3,0x45,0x15,0x74,0x3d,0xea,0xdb,0xa7,0x3f,0xd2,0x50,0x4d,0xc7,0xc6,0x19,0x36,0x84,0xf4,0xbd,0x09,0xff,0xe7,0xf3,0xc0,0xa5,0x34,0x49,0x8a,0xfe,0x83,0xcd,0xe4,0x80,0x7d,0xe3,0xff,0xc9,0x8a,0xb9,0xd6,0x34,0x01,0xd1,0x47,0x16,0x5e,0x7c,0x16,0xf5,0x7c,0xf8,0xb5,0x53 +.byte 0x26,0x84,0x89,0x73,0xf3,0x7f,0x9c,0xb0,0x2f,0x07,0x9e,0xf2,0x12,0xdf,0xba,0xc0,0x15,0xd0,0x3a,0x59,0x9d,0xde,0x67,0x5e,0x1c,0x2b,0x4b,0x84,0xb8,0x89,0xfb,0x62,0x90,0xe9,0x89,0xd9,0xdb,0xb7,0x21,0x4a,0x9f,0xbd,0xc0,0x02,0x01,0xda,0xb3,0x4c,0x9d,0xfb,0x46,0xa1,0xd0,0x3c,0xf5,0x27,0x6f,0x70,0xb5,0xa9,0x74,0xdc,0xa0,0x76 +.byte 0xb7,0x3a,0x53,0x18,0xdd,0x80,0x5e,0x43,0xb5,0x35,0xe4,0x0e,0x26,0x27,0x0a,0xab,0xe8,0x4d,0x2e,0x89,0x20,0xc3,0xff,0xe4,0x7f,0x03,0x2c,0x5f,0x25,0xc7,0x70,0x53,0x27,0x4c,0xc8,0xb9,0xb1,0x81,0x10,0x7a,0xa2,0x65,0xe4,0x0b,0x65,0x8e,0x3d,0x2f,0x96,0xa0,0xa5,0x7b,0x4f,0x09,0xe9,0x9d,0x10,0x06,0xf7,0x18,0xad,0x2d,0x7f,0xb8 +.byte 0x8f,0x08,0xa7,0x2c,0xda,0x82,0xbe,0x5c,0xd6,0x1d,0xb6,0xe2,0x9b,0xa2,0xfc,0x18,0x8c,0x8d,0xf7,0x81,0xf4,0xc6,0x1e,0xcb,0xe5,0x73,0xa6,0x74,0x06,0x20,0xf3,0xa9,0xcb,0x80,0x01,0x55,0x7e,0xc0,0x6a,0x1f,0x5a,0x5b,0xb1,0x56,0x5d,0xd8,0x2a,0xd5,0xf5,0x57,0xe8,0x48,0x6c,0xfb,0x9e,0x93,0xa7,0x0e,0x13,0x2b,0x68,0xc5,0x6b,0x17 +.byte 0x43,0xb0,0x58,0x04,0x65,0x3d,0x46,0x57,0xa7,0x3d,0x99,0xb8,0xa1,0x48,0x17,0x44,0x67,0x2a,0x0d,0x44,0x87,0x9f,0x63,0xd7,0x92,0x56,0x7b,0xab,0xd3,0x6a,0xbd,0x4f,0xc0,0xc3,0xd2,0xee,0xd1,0x3d,0xd1,0x18,0x2e,0x6a,0xf5,0x3b,0x67,0xa0,0x0a,0xf3,0x11,0x49,0xc5,0x4b,0xef,0xcf,0x00,0xfd,0x22,0x8f,0xa0,0x9c,0x99,0x32,0x2f,0x58 +.byte 0xf9,0x97,0x98,0x13,0x4a,0x88,0x50,0xcc,0x58,0x1e,0x27,0x02,0x34,0x7d,0xec,0xf6,0x88,0x3a,0x74,0xb5,0x34,0x6d,0x6f,0x52,0x2d,0x20,0x02,0x70,0x22,0x27,0xdf,0x7a,0xff,0x30,0x36,0x66,0x1a,0xa0,0x51,0xc3,0x75,0x9a,0x06,0xe5,0x3f,0x6c,0x74,0x0d,0x15,0xa2,0xb6,0xe5,0xcd,0x55,0x4d,0xea,0x65,0x8f,0xbb,0xb2,0xd4,0x95,0x73,0xa4 +.byte 0xcd,0xb9,0xc8,0x82,0x60,0x49,0xe9,0x36,0xc9,0xb1,0xe9,0xcb,0x52,0xae,0xa7,0x7a,0x64,0xab,0x75,0x84,0x03,0x4b,0x37,0xf7,0x07,0x75,0xf7,0x1c,0x32,0x19,0xb6,0x8b,0xca,0x7c,0x43,0x15,0xe8,0xec,0x57,0x89,0x1d,0xe2,0xa0,0x80,0xc5,0xb6,0x02,0x29,0xfd,0xda,0xe0,0x14,0x93,0xb4,0xb3,0x44,0x2e,0x17,0x2f,0xed,0x3b,0x38,0x6e,0x8f +.byte 0xe0,0x3d,0xc6,0x77,0xe9,0xa7,0x76,0xcb,0x98,0x2d,0x08,0x61,0xcf,0x1b,0x25,0x3f,0xfb,0x1d,0x99,0xb1,0x5a,0x3c,0x53,0x96,0x4e,0x09,0x11,0xf6,0x5b,0x09,0x31,0xe1,0xad,0xb0,0xaf,0x7b,0xec,0xf9,0xa8,0x68,0xb7,0x93,0x57,0xf7,0x17,0x77,0x87,0x2b,0xdb,0x00,0x28,0xc6,0x48,0xac,0xff,0xcd,0x26,0x4a,0x8a,0x76,0x9a,0x2a,0x1d,0x37 +.byte 0x4c,0x70,0x4f,0xf6,0x52,0xe3,0x7a,0x78,0x94,0x5b,0x0b,0x50,0xb4,0x48,0x03,0xcd,0x78,0xd0,0x5d,0x89,0x6d,0x76,0xaf,0x9d,0x67,0xc3,0x75,0x6f,0x6a,0x2d,0xe2,0xb7,0x58,0x51,0x10,0x0d,0xef,0xa0,0x1a,0x74,0x28,0x3a,0x97,0x19,0x4f,0x3c,0x8a,0x86,0x3d,0xe4,0x66,0x3d,0x57,0xb4,0x66,0xb3,0x0b,0x4f,0x57,0x57,0x34,0x2e,0xc7,0x0c +.byte 0x11,0xdf,0x3c,0xb4,0x9f,0xe1,0xd5,0x27,0x41,0x08,0xec,0xca,0x18,0x88,0x48,0x5e,0x88,0x55,0x89,0x71,0xe6,0xa5,0x90,0x7c,0x3b,0xe5,0xf3,0x2a,0xd7,0xf5,0x0b,0x3d,0xbb,0x47,0xad,0xd7,0x78,0x41,0xa8,0xef,0xd4,0x36,0x31,0xd1,0xe4,0x9c,0x87,0x9e,0xb1,0x11,0x0e,0xff,0x8f,0x4d,0x79,0x65,0xc4,0x83,0x75,0x33,0xc9,0x89,0xe2,0xc3 +.byte 0x41,0x68,0x11,0xe7,0xe4,0x58,0xb9,0xf1,0xee,0x06,0x48,0x4d,0xc3,0xc7,0x76,0x60,0x42,0x94,0x8f,0x0d,0xb9,0x53,0x46,0x78,0x06,0x97,0x94,0x36,0xf4,0x3e,0xf3,0xdd,0x5b,0x46,0xe1,0x9d,0x3f,0x9e,0x78,0x00,0x9e,0xe7,0xcb,0x9e,0xc8,0x30,0x87,0x4a,0x52,0x91,0xd5,0xe2,0xa3,0x65,0x98,0xb2,0xc9,0x6c,0xfb,0x4e,0x54,0x5a,0x9f,0x57 +.byte 0x2c,0x4a,0x76,0xe4,0x97,0x88,0xd5,0x6a,0x0e,0x6c,0x7c,0xef,0x78,0x2a,0x7c,0x26,0xa3,0x25,0xf6,0x33,0x82,0x46,0x6d,0x91,0x0d,0xe4,0x83,0xec,0xf1,0x24,0xf8,0x0a,0x34,0xec,0xfc,0x7e,0x47,0xda,0x9a,0x17,0x1b,0x33,0xd0,0xf1,0x70,0xe4,0x0b,0xc7,0x70,0x58,0x1d,0x76,0x20,0x89,0xce,0x4f,0xd1,0xcb,0x3b,0x26,0xd1,0x98,0xd9,0x51 +.byte 0xb1,0xd0,0xaa,0x4a,0xd5,0x10,0xf2,0xae,0xaa,0x14,0xa7,0x72,0x99,0x3d,0xc8,0xbf,0xfb,0xec,0x6a,0x14,0xdd,0x97,0x7b,0x2f,0x16,0x96,0x0f,0x41,0xb8,0x33,0x15,0x1b,0xa2,0x6a,0x7e,0x64,0x0d,0xab,0xe7,0x62,0xf5,0x6c,0x56,0x69,0x09,0x46,0x32,0x24,0x60,0x4e,0x21,0xc7,0x5b,0xee,0x0a,0xe2,0x94,0x7c,0x20,0xe2,0x06,0xa0,0xa2,0x36 +.byte 0xa0,0x7d,0xb5,0x37,0x2a,0xee,0x20,0x25,0x4c,0xba,0x9a,0x06,0x4c,0x07,0x9b,0xea,0x55,0xac,0x2a,0xf7,0xb9,0x5c,0x23,0xac,0x43,0xda,0x9d,0xad,0x76,0xe2,0x5f,0xe0,0x27,0xaf,0x0a,0x5e,0x3d,0x54,0x84,0xfc,0x19,0x75,0x8c,0x62,0x4d,0x37,0x17,0x1a,0x90,0x55,0xb8,0x7e,0xa1,0xad,0x31,0x1a,0xc0,0x91,0x96,0x51,0xa9,0x5f,0xbb,0xb9 +.byte 0x95,0xbf,0xe2,0xd5,0x7e,0x31,0xba,0xc4,0x1e,0x63,0x98,0xd3,0xe2,0x7d,0x87,0xa5,0x46,0xe3,0xae,0xe1,0xe8,0x4e,0x74,0x29,0x0e,0x4b,0x10,0xa8,0x7f,0x3a,0xe5,0x60,0x0f,0x49,0x6a,0xcd,0x3d,0x5a,0x8e,0xf1,0x48,0xd0,0x80,0x7b,0xa3,0x7f,0x06,0x47,0x2b,0x60,0xf2,0x17,0xc3,0xe1,0x26,0x1e,0xb7,0x0f,0x2b,0x7c,0xc7,0xb8,0x3a,0x4f +.byte 0xad,0x05,0x97,0x88,0x93,0x82,0x8e,0x06,0x77,0x44,0xd1,0x65,0xfd,0x18,0x48,0xd6,0x88,0xcd,0x5c,0xbd,0xe4,0xaa,0xea,0xf1,0xed,0x16,0x5f,0xb3,0x58,0xe2,0x69,0x82,0xbe,0x9e,0xfc,0xcb,0xf6,0x17,0xa9,0x70,0xeb,0x08,0xd7,0x06,0x86,0xf6,0x5a,0x43,0x68,0x7b,0xcf,0xa3,0xfa,0x26,0x5e,0xe5,0x42,0xd3,0x5a,0xc8,0x1c,0x3b,0x8d,0x2d +.byte 0xf1,0x45,0xb0,0x97,0x90,0x0b,0xe7,0x2d,0xab,0xd7,0xd8,0x8a,0x16,0xf9,0x5f,0xa6,0xcf,0xc5,0x60,0x2c,0x34,0x5a,0x2e,0x2b,0xb9,0xb4,0x9c,0xa7,0x09,0x77,0xd2,0x3f,0x8c,0xf3,0xf6,0xf7,0xe0,0x27,0x79,0xc3,0x4e,0x61,0x7d,0x09,0x50,0x05,0x01,0x35,0x1b,0x33,0x54,0x6f,0x90,0x9a,0x19,0xcd,0x86,0x45,0x23,0xcd,0x6f,0x1b,0x62,0xc5 +.byte 0xce,0x4e,0x8e,0xff,0xe7,0x12,0x32,0x85,0x9a,0xc4,0x11,0x83,0xcf,0x78,0xd7,0x41,0x99,0x64,0x20,0xa6,0x69,0xdd,0xe3,0x53,0x98,0x6b,0xc7,0x98,0x51,0xc5,0xf8,0x3e,0xa3,0x5f,0x0d,0x78,0x2f,0xa7,0x05,0xff,0xe5,0x3a,0x0f,0x7c,0x09,0x58,0x3f,0xaa,0x0d,0x9a,0x9d,0x8d,0xe7,0xbf,0x6b,0x7d,0xfe,0x3a,0x4f,0x5c,0x50,0xb2,0xe7,0xc5 +.byte 0xa5,0x13,0xde,0xc8,0xe8,0x59,0xac,0xb0,0xdd,0xc0,0x81,0xa7,0x0b,0x78,0x32,0x23,0x76,0x85,0x11,0xef,0xe3,0x88,0x6f,0x7f,0xa9,0x09,0x7b,0x0c,0x6f,0x34,0xb2,0x67,0x5e,0xd6,0x11,0xad,0xd7,0x3b,0xf2,0xbb,0x66,0x5b,0xde,0x22,0xfc,0x55,0x26,0xa1,0x89,0x80,0x2e,0xb8,0xf3,0x3c,0xf8,0x1e,0xba,0x99,0x1c,0x24,0x33,0xb4,0xe6,0x17 +.byte 0x2b,0x9c,0x80,0xe5,0x9b,0x58,0x54,0x70,0xcd,0x15,0x81,0xcd,0x51,0x48,0x75,0x24,0x27,0xf5,0x30,0x79,0xc1,0x16,0xff,0x89,0x70,0x12,0x74,0x07,0x9d,0x39,0xf2,0x9c,0xc6,0x89,0x8d,0x94,0x41,0x01,0x04,0xf5,0x16,0x99,0xf3,0xf0,0xd1,0xf5,0x6d,0xd3,0x11,0x19,0x29,0x36,0xfb,0x41,0xf9,0x32,0xb9,0x0f,0x13,0xaf,0xac,0xfb,0x30,0x75 +.byte 0x62,0x8c,0x04,0x5b,0xf1,0xce,0x52,0x9b,0xbe,0x8c,0xf9,0x86,0x5d,0x7d,0xc1,0x8e,0x41,0x76,0x42,0x63,0xd7,0x74,0x8e,0x2c,0x46,0xa1,0x0a,0x51,0xb5,0xec,0xe9,0x91,0x56,0xbc,0xdc,0x32,0xfc,0x10,0xb5,0xca,0x5b,0x4b,0x72,0x99,0x07,0xff,0x01,0x11,0x2c,0xa4,0x60,0xf5,0x6b,0xd4,0xa8,0x96,0x21,0xee,0xbe,0x14,0x8f,0x69,0x99,0xdc +.byte 0x43,0x7f,0x13,0x3d,0x17,0x1e,0xa3,0x1b,0x21,0x23,0x26,0x7e,0xff,0x80,0x6b,0x66,0x3e,0xb2,0x48,0x1a,0x77,0x3c,0x50,0xe2,0xca,0x4d,0xc6,0xdb,0xfd,0xd1,0x23,0xcc,0xcb,0x01,0x25,0xc0,0x62,0x8d,0xe5,0x9c,0xb7,0x13,0x97,0xf5,0x49,0x01,0x19,0x45,0x45,0x83,0x17,0xff,0x8e,0x94,0x8c,0xb0,0xc0,0xaf,0x46,0x62,0x0e,0x62,0xb7,0x8c +.byte 0xd5,0xcf,0xb9,0x82,0x6e,0x8a,0xb9,0x22,0xbc,0x30,0xf9,0x65,0xc2,0x7f,0xce,0x6b,0x4d,0xad,0x87,0xcb,0x23,0xab,0x57,0x36,0x6a,0xb7,0x8c,0x63,0x17,0x60,0x13,0xa1,0x1f,0x3d,0xa4,0xd4,0xab,0x5d,0x97,0xc7,0x18,0xaf,0xf8,0xae,0x13,0x64,0x2a,0x19,0x34,0xe2,0x28,0x28,0x4f,0x32,0x2a,0xd8,0x43,0x79,0xaf,0x1e,0x56,0xfc,0x97,0x51 +.byte 0x67,0x8c,0x63,0x80,0x32,0x63,0x71,0x5c,0x78,0x00,0xeb,0xfd,0xa2,0x96,0x58,0x21,0x36,0x13,0x02,0xe5,0xa4,0xb7,0xcd,0x5a,0x30,0xa0,0x5b,0x7b,0x23,0xa4,0xcc,0x54,0x64,0x6f,0x6d,0x9b,0xaf,0xea,0x49,0x69,0x9e,0x2f,0x51,0x5c,0xe7,0xa3,0xa3,0xb8,0xac,0xed,0x47,0x23,0x7a,0x37,0x38,0xe3,0x15,0x98,0x6f,0x50,0x6c,0x8d,0xa7,0xe6 +.byte 0xa8,0x39,0xcc,0x63,0x08,0xeb,0x8f,0x8c,0xfd,0x83,0xaa,0x34,0x75,0x19,0xc0,0xf4,0xd6,0x25,0x18,0x94,0x9d,0xa1,0x7e,0xc8,0x6b,0x19,0x76,0xc0,0x8d,0xaf,0x51,0xe5,0x7c,0x8a,0x98,0x17,0x80,0x90,0xc0,0xb6,0xed,0x5c,0x8f,0x33,0x56,0xba,0xce,0xbe,0x83,0x87,0x5d,0x51,0x2e,0x64,0x84,0xa6,0x9d,0x49,0x27,0x5b,0x92,0xe0,0xe7,0xac +.byte 0x37,0x3d,0x22,0x5e,0x25,0xe7,0xca,0x2f,0x5d,0x2f,0xa0,0xd5,0xcb,0xe9,0xac,0x84,0x5b,0x19,0x72,0x1c,0x2c,0x0a,0xd1,0xb7,0x73,0x24,0x8a,0x0f,0xe0,0x07,0xd8,0x49,0x4d,0x23,0x1b,0xac,0xb8,0xd1,0x42,0xd4,0xdf,0xf8,0x4d,0x85,0xa2,0x37,0x30,0x46,0x38,0x88,0x55,0x1d,0xea,0x37,0x54,0x8c,0x43,0xb0,0xed,0x01,0x53,0x75,0xe6,0xf7 +.byte 0x9b,0xe6,0x10,0x91,0x6e,0x80,0x11,0xf9,0x96,0x29,0x4f,0x08,0x77,0x2b,0x7e,0xdb,0x5b,0x14,0xbd,0x77,0x37,0xe8,0x36,0x07,0x4a,0xe4,0xd8,0xa2,0x4e,0x38,0xea,0xeb,0xc2,0xd6,0x43,0x59,0x20,0x0c,0x12,0x31,0x6c,0x27,0xc5,0x7b,0xfc,0xfc,0x54,0x94,0x1d,0x5f,0x82,0x73,0xd7,0x1f,0x43,0x3a,0x73,0xc4,0xf3,0xb3,0xbb,0x53,0xfe,0x22 +.byte 0xc0,0xa4,0x7e,0x2b,0x84,0x1b,0xef,0x6d,0x83,0x9d,0xb3,0x8b,0x2a,0x6c,0xea,0x1e,0xfa,0x77,0x01,0x35,0xd2,0x5b,0xc4,0xd3,0xe7,0x1e,0xca,0x73,0x8b,0xb9,0x1f,0xfb,0x67,0xf2,0xdd,0x03,0xe6,0xca,0xfe,0x3b,0x61,0xd7,0xb5,0x96,0xe0,0x85,0xc2,0x23,0xa7,0xea,0x38,0xbf,0x6e,0x29,0x9e,0x8e,0x18,0xd4,0xbf,0x16,0x73,0xf9,0x18,0xef +.byte 0xc9,0xaf,0x6c,0xe2,0xdc,0xa4,0x58,0x9c,0xf5,0x6d,0x4a,0xc8,0xb4,0x8f,0x16,0x02,0xb7,0x65,0xd3,0x32,0x3b,0x83,0xfe,0xf3,0xc7,0xba,0x68,0xf4,0x95,0xa4,0xf6,0x33,0x57,0x43,0xbe,0xae,0x83,0xa9,0xe4,0x0d,0x0b,0x23,0xaa,0xbc,0x15,0x53,0x18,0x4d,0xb4,0x35,0xe3,0x8e,0x86,0xfe,0xe4,0x98,0x5d,0x63,0x23,0xce,0x44,0xea,0x4d,0x64 +.byte 0x86,0xf8,0x06,0x8f,0xc0,0x73,0xa6,0x6d,0x04,0x53,0x47,0x95,0x0f,0x6d,0x6c,0x01,0x1c,0x3f,0x7b,0x83,0xe4,0xc2,0x40,0xb8,0x97,0x26,0x9e,0x35,0xb0,0x76,0xee,0xe4,0xc7,0xd8,0xaa,0x22,0x83,0x96,0xe1,0x34,0x7b,0x78,0x31,0xee,0xd3,0x9a,0x50,0xd4,0x05,0xfd,0xd6,0x15,0xca,0x83,0x2f,0x49,0xfd,0x00,0x23,0x82,0x39,0xac,0x46,0x7a +.byte 0xe4,0xb5,0xcc,0xee,0xbb,0xaa,0x98,0x82,0xb5,0x27,0x45,0xd5,0x96,0x6e,0x89,0x01,0x1e,0x30,0xe4,0x1c,0x3a,0x65,0xcc,0x9f,0xda,0x38,0xf0,0x4c,0x68,0xfa,0xe5,0xf2,0xe2,0xce,0x34,0xc2,0x15,0xfd,0x21,0xf6,0xe2,0x33,0xbd,0xef,0xfd,0x49,0x15,0xdc,0x38,0x3b,0x24,0xba,0x3a,0x80,0x35,0x60,0xbe,0x50,0x17,0x38,0x3e,0xe2,0x96,0x84 +.byte 0x01,0x41,0x6c,0xb2,0x0b,0xc6,0xff,0xce,0xb3,0x37,0xa2,0x46,0x27,0x33,0x8e,0x04,0x44,0x8a,0x7c,0x64,0x0e,0xbc,0xed,0x74,0x4f,0x40,0x58,0xf4,0x8c,0xf8,0xd9,0x92,0xa9,0x0b,0x18,0x7c,0x93,0x95,0xca,0xa7,0x3e,0x1d,0xad,0x68,0x80,0xd9,0xdb,0x81,0x78,0x50,0x37,0x49,0xbc,0x64,0xc2,0x52,0x5c,0x70,0x7e,0x0a,0x26,0x7e,0xc6,0xbf +.byte 0xd2,0x7f,0x05,0x55,0x7a,0x5a,0x3e,0x9e,0xe3,0x8b,0xf5,0x95,0x2b,0xd8,0xb4,0xb8,0xc6,0x5d,0x91,0xb8,0xc7,0x7c,0xe1,0x75,0xf2,0x43,0x6b,0x73,0xb7,0xb1,0x10,0xf2,0xa7,0x1e,0xab,0xaf,0xc9,0xc0,0x3b,0xab,0xbe,0xf7,0x4a,0x43,0x9c,0xca,0x3d,0x00,0x5b,0x02,0xf8,0xa2,0x4f,0x57,0x81,0xb0,0xde,0x1e,0xd1,0x60,0xbe,0x6c,0x0d,0xe6 +.byte 0xcd,0x51,0xb6,0xc7,0x00,0x52,0x37,0x4f,0xfc,0xee,0xe2,0x43,0x5c,0x61,0x76,0xed,0x80,0x72,0x38,0x26,0x94,0xfe,0x28,0x06,0xfb,0x62,0xa6,0x21,0x9b,0x53,0x60,0x1b,0xf0,0x56,0xae,0xba,0x6b,0x52,0x27,0x2a,0xd5,0xed,0x11,0x92,0xa2,0xe2,0xab,0xdd,0x05,0x38,0x38,0xae,0xeb,0x72,0xcb,0x6c,0xa5,0x2a,0x73,0xc5,0xfc,0xb0,0x36,0x83 +.byte 0xd6,0xe6,0xda,0x6b,0x38,0x72,0x5e,0x8d,0xaf,0x11,0x5f,0x5b,0x89,0x58,0x21,0x36,0xf6,0x7d,0x42,0x48,0xdc,0xce,0xaa,0x94,0xf0,0xc3,0xc5,0x2c,0x08,0x2a,0x36,0x35,0x25,0x95,0xc4,0x11,0x09,0xea,0x7a,0xbc,0x2e,0xc6,0x0a,0x5b,0x4f,0x86,0xeb,0xc2,0x38,0x71,0x48,0x8c,0x63,0x79,0x3b,0xe4,0xba,0x14,0x44,0x31,0x28,0x4f,0x9d,0xb4 +.byte 0x26,0xa6,0x3b,0xea,0x3f,0xcb,0x30,0x6c,0x02,0x13,0xdb,0x4c,0x9c,0x76,0xc8,0xd8,0x01,0x52,0x3d,0x2f,0x51,0x70,0x15,0x91,0xec,0x8f,0x80,0xed,0x88,0xb7,0xfa,0x91,0x2c,0x10,0xcd,0x3b,0x92,0x85,0xe7,0xe8,0x11,0xfa,0x50,0x15,0xe2,0xdf,0xf7,0xbe,0xa4,0x2d,0x13,0x75,0xa6,0x00,0x25,0x8d,0xe1,0xb6,0x9b,0xbb,0x64,0xfb,0x5c,0xde +.byte 0x97,0xcc,0x00,0x51,0xd6,0xac,0x67,0xc3,0x91,0x1e,0x56,0x36,0x2b,0x43,0xed,0x8c,0x67,0x7b,0xf6,0x54,0x6f,0x91,0x44,0x28,0x93,0x60,0xac,0xca,0xb9,0x91,0x7e,0xeb,0x49,0xd8,0xfc,0x12,0x6c,0x40,0x9d,0x0a,0x4d,0xb4,0xab,0xe6,0xad,0x5b,0x8e,0x2d,0x3e,0x53,0xa1,0x88,0xf7,0x41,0x71,0xa7,0xff,0x05,0x46,0x04,0x34,0x1f,0x12,0x89 +.byte 0x92,0xc1,0xf9,0x26,0x16,0x23,0xb6,0x59,0x82,0xdc,0xa7,0xb8,0xa4,0x8a,0x0f,0x1d,0x7d,0x8f,0x44,0xe8,0x4f,0x70,0xbb,0xdb,0x8d,0xe6,0x7e,0x9d,0xd9,0x44,0x10,0x41,0x6c,0x3f,0xb7,0xe8,0x6f,0x39,0x93,0xe1,0xde,0xb8,0x6c,0xba,0x99,0x95,0xb7,0xc8,0xb2,0x2a,0xcd,0x81,0x53,0xc3,0xb5,0x2a,0x8a,0xd6,0x62,0x1e,0x74,0x4d,0xde,0xfa +.byte 0xff,0x7b,0xed,0x11,0x1e,0x44,0x3e,0x93,0x1c,0xae,0x7c,0x5c,0xed,0x52,0x75,0x5e,0x0a,0xf3,0x95,0xce,0x47,0x86,0x1b,0x7f,0x17,0x09,0x12,0xcc,0x08,0xca,0x16,0x11,0xf1,0xa1,0x39,0x78,0x89,0x5c,0x11,0x25,0xc7,0x39,0x5f,0x97,0x74,0xbc,0xa9,0x2a,0x25,0x5d,0xdd,0x93,0x0d,0x8c,0x74,0x07,0x1e,0xd9,0x9f,0xc1,0x38,0x9c,0xbf,0xe0 +.byte 0x42,0xad,0xb2,0xe7,0xb1,0x84,0x82,0xb4,0x56,0xbe,0x3c,0x42,0xb0,0xce,0x2c,0x94,0xb7,0xe6,0x78,0xc8,0x04,0x06,0x58,0x15,0x3e,0xdc,0xf6,0x9a,0x58,0xc3,0xe3,0x85,0x16,0xc8,0x84,0xba,0x8f,0xbc,0x94,0xa7,0x44,0x04,0x29,0xc4,0xd8,0xec,0x63,0xc4,0x47,0x58,0x22,0x02,0x08,0x20,0x44,0x39,0x52,0xa5,0x33,0xfe,0x1c,0x30,0x27,0x92 +.byte 0xbf,0x42,0x44,0x4c,0x3f,0x3d,0x00,0x7b,0x21,0xef,0xbb,0x25,0x75,0x4c,0xb2,0xe7,0x66,0xc9,0xc1,0xfb,0x1e,0x13,0x04,0xd0,0xcb,0x69,0x51,0x9d,0x9a,0xb0,0xb0,0xec,0xb0,0x12,0x24,0x84,0x57,0x9f,0xef,0xb4,0x19,0x50,0xa6,0xf5,0x03,0xa3,0x93,0x0f,0x77,0xaf,0xe0,0x4c,0xa5,0xd3,0xb0,0xd8,0x5e,0xc3,0x78,0x94,0xd5,0x6e,0x48,0x58 +.byte 0x7a,0x93,0xb1,0x62,0x60,0xea,0xa1,0xba,0x7a,0x86,0x6e,0x87,0xe9,0x97,0xe0,0x7c,0x1e,0xb6,0x63,0x94,0x76,0x5f,0x9c,0x95,0x65,0x00,0xd4,0x14,0x0e,0x4c,0x87,0xe7,0xcd,0x9e,0xb1,0xe2,0x13,0x1b,0xb1,0x8a,0x83,0xaa,0xaa,0x34,0xcd,0xb2,0xf6,0x7f,0x12,0xb0,0x79,0xff,0x1e,0x04,0xc8,0x9a,0xfc,0x41,0x88,0xbb,0x28,0x42,0xeb,0x45 +.byte 0x47,0x8b,0xcb,0x57,0x03,0xcd,0xe5,0x9a,0x84,0xea,0x0a,0xb5,0x0c,0xb8,0x30,0x33,0xd6,0xde,0x66,0xa8,0x57,0xf9,0x76,0x4f,0x0f,0x8f,0x53,0x56,0x57,0x91,0xd4,0x55,0xf5,0x78,0xde,0xa6,0xa2,0x59,0xc8,0xb0,0xf2,0xb9,0xfa,0x6d,0x4a,0x70,0x86,0x3d,0x24,0x1b,0xc6,0xb8,0x06,0xf5,0xea,0x09,0x63,0x9b,0x1e,0x61,0x18,0x85,0xba,0x08 +.byte 0x20,0xaa,0x33,0x66,0xcf,0xa7,0xff,0xf5,0x30,0xfe,0xf8,0x39,0xd3,0x88,0x9a,0x5b,0x3f,0x55,0xa6,0x00,0x4c,0x57,0x0d,0xd1,0xa4,0x0c,0xe7,0x8a,0x95,0xd8,0x64,0xc7,0x93,0x51,0x84,0xa6,0x41,0x2c,0xfc,0xb0,0xfb,0x99,0x9a,0xcd,0x2c,0x62,0x3a,0xca,0x43,0x15,0xf2,0x5a,0x22,0x25,0xa4,0x91,0xa3,0x7c,0x42,0x69,0xc1,0x67,0xe3,0xf5 +.byte 0xd4,0x92,0x54,0xbd,0xb3,0x57,0xe5,0x19,0xca,0x1b,0x9c,0x19,0x79,0x9d,0xbf,0x89,0xfc,0xaa,0x72,0xcd,0xcb,0xc5,0xbc,0xdd,0x0c,0x7c,0x31,0x42,0xb0,0xc2,0x76,0xe5,0x8b,0x9b,0x7c,0x92,0x13,0x20,0x5c,0xdc,0x94,0xfc,0xa1,0x90,0x34,0x27,0x88,0x9f,0xe5,0x97,0x5f,0xc3,0xa3,0x83,0xca,0x8b,0xf8,0xac,0x36,0x33,0x47,0xc6,0x20,0x2f +.byte 0x04,0x2d,0x13,0xc1,0x3c,0x07,0x6e,0xf0,0xe2,0x3d,0x32,0x5c,0x50,0x41,0xf2,0x92,0x3f,0x25,0x2c,0x80,0x34,0xa5,0x90,0x2b,0x97,0x6e,0xd1,0xa2,0xa6,0xf4,0x4a,0xe0,0x20,0xd9,0xb9,0x2b,0x66,0xe5,0x06,0x73,0x97,0xfe,0x80,0x70,0x28,0xf9,0xb6,0xae,0x93,0x27,0x7a,0x65,0xff,0x23,0xc1,0x78,0x18,0x92,0xc9,0x0b,0x05,0x82,0x93,0xbc +.byte 0x73,0x3f,0x98,0xe9,0xa0,0x6d,0x20,0x8d,0x13,0xb1,0xf0,0x7e,0xe4,0x07,0x21,0x7d,0x6d,0xea,0x03,0x59,0xf8,0x29,0xc0,0xc8,0x7d,0xce,0xd1,0xf8,0x67,0x82,0x7f,0x84,0xe8,0x77,0xa9,0x9c,0xa2,0x34,0xdf,0xa9,0xac,0xec,0x6d,0x54,0xe5,0x0f,0xcb,0xdb,0x86,0xbc,0x01,0x44,0x91,0x3b,0xc8,0x85,0x4e,0x1d,0xe4,0x74,0x19,0xc6,0x39,0x2e +.byte 0xdf,0xf2,0x8f,0x3a,0x7f,0xe3,0x1e,0x55,0x45,0xcb,0x7e,0xde,0xcd,0xa6,0x1c,0xef,0x20,0xf7,0x07,0x31,0x94,0x9a,0x3d,0x04,0xd7,0x5e,0x65,0x20,0x6a,0x4d,0x31,0x1e,0x6f,0x89,0x40,0x45,0x1f,0x37,0xc1,0x7e,0x07,0xd5,0xa6,0x38,0x4a,0xf1,0x39,0xae,0x72,0x26,0x60,0xb0,0xb5,0xc7,0xd3,0x9a,0xaf,0x57,0x12,0xe9,0x34,0x28,0x8b,0xaf +.byte 0xd8,0x62,0x24,0x58,0xe2,0xcd,0xa2,0x9e,0x74,0x23,0x2d,0x52,0xc7,0x09,0xe5,0xb5,0xf5,0xc1,0xd3,0xa3,0x19,0xe5,0x1d,0x8d,0x0c,0xdf,0x13,0x8d,0xa4,0xa7,0xc1,0x41,0xea,0x9e,0x6d,0x61,0xd4,0xa4,0x74,0xe5,0xf8,0x5f,0x9e,0xfd,0x6d,0xf6,0x6e,0x87,0x0f,0xb5,0xa3,0x82,0xac,0x64,0xb4,0xda,0x07,0x49,0x51,0xc2,0xfd,0xcb,0x55,0xa3 +.byte 0x59,0x34,0xdf,0xa1,0xd6,0x90,0x62,0x43,0x1a,0xf9,0xae,0x85,0x5c,0x11,0x40,0xb2,0xbe,0xa5,0x03,0x04,0x4f,0xec,0x2c,0x58,0x2d,0xe9,0xda,0xcf,0xaa,0x2f,0xcf,0x60,0xc3,0x2c,0x6c,0x81,0x4d,0xf2,0x71,0x41,0xe4,0xae,0x4c,0xfa,0x8e,0x05,0x10,0xff,0x40,0xfa,0xea,0x96,0x78,0x6e,0xfc,0x35,0x35,0xec,0x84,0xf6,0x1d,0x24,0x60,0xcd +.byte 0x96,0x21,0x21,0xa7,0x32,0x90,0x3d,0x51,0x72,0x13,0xa4,0x9b,0x7e,0x94,0x3a,0x9d,0x97,0xf6,0x68,0xd8,0x08,0x42,0x54,0x7a,0xbb,0x9a,0x95,0x83,0xac,0xb8,0xb4,0x68,0xe3,0x31,0xdb,0xe2,0x32,0x8b,0x7d,0x57,0x62,0x1d,0x61,0x81,0xa1,0x36,0x7a,0x25,0x00,0x72,0x24,0x4c,0xa7,0x96,0x3b,0xa5,0x82,0xba,0x8e,0x89,0x1e,0x1b,0x8e,0xf4 +.byte 0xab,0x91,0x85,0x7a,0x32,0x4a,0x47,0x9f,0xce,0xd2,0x51,0x77,0xcd,0xc9,0x02,0x54,0xf2,0x7b,0xcb,0xb8,0x83,0xe0,0xe0,0x1b,0x4a,0xa2,0xe0,0xd9,0x15,0xb6,0x02,0x19,0x75,0xa6,0xba,0xa6,0x98,0xd9,0x61,0x74,0xc6,0x48,0xa5,0x59,0x3d,0xc8,0x47,0xc9,0xe8,0x6b,0xbb,0x6d,0xcf,0x0e,0x8d,0x6b,0x58,0x8b,0x7d,0x4e,0x0b,0x3d,0x67,0xc4 +.byte 0x8e,0x78,0x59,0x40,0x88,0x82,0x33,0x27,0x2c,0xfe,0x2a,0x6c,0xe4,0x80,0xee,0x5a,0xd4,0x5f,0xc8,0xf7,0x82,0x02,0x67,0xfd,0xcb,0x55,0x3e,0xd8,0x41,0xb3,0xce,0x93,0xfe,0xe7,0x56,0xf5,0x63,0xba,0xfa,0x2e,0x79,0xfc,0x11,0x5d,0xb0,0xc6,0x32,0x54,0xed,0x71,0x9b,0x15,0xce,0x62,0x09,0xd4,0x28,0x7f,0x7b,0xa1,0x50,0x5b,0x46,0x24 +.byte 0x0e,0x40,0xa2,0xe2,0x7d,0x93,0xa6,0x2b,0x0b,0x9b,0x40,0x25,0xc9,0xca,0x7a,0x01,0x8b,0x7d,0x68,0xeb,0xd7,0x84,0xc1,0x9d,0xf9,0xfb,0xd0,0x1a,0xec,0xef,0x6b,0x4c,0x78,0x31,0x62,0x8e,0x9d,0xdc,0x78,0x8f,0xcb,0xf8,0xf9,0x41,0xdc,0x9f,0x6d,0x0a,0x27,0x67,0xce,0xbd,0xeb,0x87,0xb3,0x26,0xf3,0x51,0xe1,0xd6,0xd1,0x57,0x46,0xfe +.byte 0x21,0xb9,0x88,0x7c,0xdd,0xa2,0x49,0x71,0x24,0xfb,0xc4,0xc0,0x6a,0x6b,0x05,0x7f,0x80,0xb0,0x09,0x3b,0x9e,0x6c,0x59,0x31,0x3e,0xac,0x7a,0x2e,0x5c,0x04,0x03,0xa3,0x6e,0xf5,0x66,0xee,0xc2,0x9b,0x65,0x88,0x06,0xbf,0xf5,0xe3,0x23,0x73,0x38,0x88,0x99,0xf1,0x64,0x68,0xdf,0x7d,0x04,0x06,0x72,0x92,0x0b,0x62,0x5d,0x12,0x1e,0x4e +.byte 0xff,0x60,0x35,0xe3,0x0f,0xd9,0x8c,0xac,0x38,0x5b,0x91,0xc1,0x51,0xbb,0xa5,0x19,0x7d,0xfb,0x79,0xfa,0x42,0x3b,0xaa,0xf8,0xd3,0x0f,0xc3,0xf2,0xb2,0x68,0x91,0xae,0x28,0x83,0x4f,0x75,0xbd,0x20,0x5f,0x20,0xba,0xc2,0x75,0x85,0x74,0x23,0xf3,0x36,0x33,0x99,0x9c,0x64,0x4c,0xd1,0x5d,0xbd,0x06,0x46,0xbd,0x49,0xf0,0x86,0xc0,0xcb +.byte 0x1b,0xbd,0xec,0x98,0x5b,0xb1,0x80,0xba,0x12,0x42,0x22,0x09,0x9a,0x62,0x3c,0xa8,0x33,0xbf,0xce,0x92,0xd4,0x07,0xef,0x34,0x33,0x8f,0x67,0x1d,0x25,0x60,0xeb,0xd3,0xe4,0x31,0x63,0xa8,0xab,0xe3,0xab,0x70,0x50,0xd8,0x44,0x9f,0x39,0x51,0xd2,0xb9,0x4b,0x16,0xe4,0xfa,0xc5,0x47,0xf3,0xae,0xb5,0xfe,0x7d,0x5d,0x43,0x28,0xa6,0x3d +.byte 0xcf,0x71,0x23,0x6d,0x8e,0xd7,0x74,0xa4,0x86,0x9f,0x92,0x86,0x3c,0x1e,0x51,0xd4,0xe0,0xe6,0xd5,0xc4,0x53,0x3c,0x96,0x55,0xb9,0xac,0x63,0x5b,0xee,0x5a,0x03,0x84,0xb9,0x43,0x2c,0x0f,0x6d,0xbb,0xb5,0xca,0xf0,0x4f,0x3e,0x8b,0x3b,0x14,0x01,0x0e,0x81,0x0d,0xe6,0x62,0xa9,0x34,0x4e,0x03,0xc9,0x85,0x9f,0xc8,0x4f,0x52,0x3f,0x84 +.byte 0x1b,0xab,0x7e,0xaf,0x93,0x22,0xe2,0x0d,0x41,0x79,0x50,0xb2,0x17,0xa7,0x9a,0x80,0xd5,0x65,0x40,0x3b,0x56,0x9b,0xc9,0x00,0xcf,0x03,0xf1,0xff,0xcd,0x72,0x27,0xdb,0x74,0x94,0x70,0x02,0xdc,0x3a,0xee,0x00,0xcc,0x08,0x0a,0xab,0x40,0x87,0x24,0xaf,0x7d,0x67,0x18,0xd0,0x7c,0xeb,0x91,0x1f,0x7e,0x9e,0x41,0x7b,0x39,0xf2,0xfe,0xaf +.byte 0xb7,0x6c,0x58,0xe0,0xdb,0xf7,0xf1,0x23,0x0b,0x98,0x08,0xfa,0xde,0xfa,0xf9,0x24,0x23,0xd1,0x7f,0x69,0xd3,0xb1,0x82,0x68,0x03,0x06,0x86,0x7a,0xf4,0x90,0x8d,0xa5,0xbd,0xbe,0x14,0x2f,0xa2,0x5e,0xaf,0x5c,0x1e,0x07,0x68,0x19,0x5a,0xd3,0x53,0x7d,0xe8,0x13,0x6b,0xe3,0x02,0x49,0x0d,0xd2,0x96,0x56,0xae,0x67,0x8a,0x27,0x61,0xa0 +.byte 0x60,0x20,0x2c,0xb4,0x5d,0xdf,0xc3,0x24,0x50,0xa9,0xbc,0x3d,0x5c,0xf3,0x2e,0xb6,0xba,0x71,0xf0,0x04,0x43,0x84,0x4d,0x80,0xe9,0xa5,0xdd,0xb3,0x1e,0x5e,0x56,0x32,0x1a,0xd4,0xe3,0x10,0x57,0x35,0xa8,0xf1,0xe5,0x96,0xc1,0x27,0xef,0xcc,0x21,0x71,0x10,0xd1,0x07,0x7e,0xb3,0xab,0x95,0x64,0x86,0xaf,0xc9,0x15,0xe6,0x98,0x5e,0xb1 +.byte 0xbd,0xde,0x99,0x38,0xfc,0x8d,0xb2,0x5a,0xa4,0x44,0x5b,0x74,0x31,0x31,0x07,0x93,0xf5,0x86,0x78,0xc5,0x82,0x26,0xfc,0x95,0x1f,0x33,0xd8,0xfe,0x70,0x42,0x2a,0xa7,0x3a,0xb1,0xb2,0x63,0xd6,0x5b,0x54,0x9c,0x54,0x45,0x4f,0x1b,0x4a,0xc2,0xb4,0x0e,0x99,0x48,0xde,0x8d,0xa6,0x5d,0xd3,0xdc,0x31,0xa4,0x2b,0x0d,0x44,0x6e,0x1a,0x10 +.byte 0x3f,0x6c,0xa0,0xab,0xcb,0xb4,0xf6,0x18,0xba,0x11,0xd4,0xd4,0x70,0xc4,0xab,0x04,0x4c,0xe7,0xe9,0x53,0xe5,0xd9,0xe7,0xeb,0x21,0xa2,0x2c,0xc4,0xc6,0xc3,0xe7,0x73,0xd9,0xd3,0x84,0xb0,0x12,0x94,0x3b,0xfd,0xd9,0x32,0xba,0xe3,0x37,0xc1,0xb9,0x4d,0xea,0x3e,0x3d,0x31,0x4e,0xa0,0xe7,0x73,0x9d,0x4e,0x26,0xd1,0xdf,0xe6,0x26,0xcd +.byte 0xd7,0x17,0xd7,0x28,0x2c,0x04,0xe9,0x55,0xd5,0x70,0xaf,0xab,0xc1,0x07,0xbc,0xc4,0xd2,0x89,0xdc,0x22,0x59,0x19,0x0e,0xd8,0x8b,0xdd,0x46,0x7f,0xe4,0xad,0xa5,0x70,0xd7,0x18,0x51,0x30,0xd7,0xbc,0x26,0x45,0xe7,0xea,0xce,0xc7,0xf2,0xca,0xb1,0x9c,0x57,0x1e,0x10,0x5f,0x44,0x8d,0x3d,0xe8,0x55,0xa1,0x22,0x68,0x97,0xe8,0x03,0x9c +.byte 0x8b,0x63,0x81,0xd9,0xcd,0x4c,0x6c,0xe3,0x68,0xc9,0x35,0xee,0x94,0x13,0x25,0x0b,0x12,0x61,0xbd,0xee,0x6f,0xc7,0xe8,0xb5,0x01,0x7a,0x9e,0xd0,0x5a,0x46,0xc6,0x19,0x1b,0xc2,0xf1,0x2d,0xaa,0x53,0x29,0xcf,0x23,0x1a,0x4d,0x94,0x0a,0x50,0x64,0xf5,0x3b,0x52,0x55,0xac,0xa5,0x21,0x15,0x47,0xd9,0x14,0x8c,0x7f,0x4d,0x79,0x6b,0xc1 +.byte 0x43,0x0a,0xf2,0x42,0xd2,0xb0,0x95,0x19,0x99,0xdd,0x1d,0x8e,0x84,0x8c,0x7e,0x59,0x69,0x93,0x86,0xae,0xf1,0x67,0x35,0x55,0x7c,0x5b,0x38,0x11,0x56,0xec,0x6c,0xbb,0xe8,0xc0,0x54,0xec,0x5f,0x65,0x13,0xe3,0x86,0xa0,0xb1,0xc1,0x5e,0x34,0x4f,0xdd,0x4d,0x00,0xc6,0x29,0x05,0x78,0x64,0x8c,0x19,0xb0,0xfc,0x8a,0xb2,0xc7,0x86,0x57 +.byte 0xa2,0xdd,0xed,0x43,0xc1,0x7f,0xab,0x89,0x19,0xe8,0xa6,0xf5,0x7a,0x15,0xfe,0xd5,0x4f,0x53,0xde,0x78,0x42,0x76,0xf7,0x8a,0x54,0xe8,0x37,0xfd,0xee,0x82,0x20,0xd5,0xe2,0x32,0xb9,0x32,0x67,0xc7,0xff,0xdc,0xf0,0x40,0x07,0x28,0x55,0x16,0x56,0x84,0xe9,0x17,0x25,0x17,0x8e,0x10,0xef,0x9f,0xed,0x33,0x83,0x6d,0x9e,0x87,0x82,0xb8 +.byte 0xa9,0x6b,0xcb,0xe5,0x04,0xfb,0x87,0x51,0x05,0x1a,0x64,0x64,0x51,0x34,0xa3,0x61,0x4a,0xe3,0xa6,0x35,0xa5,0xc9,0xe3,0xde,0xb0,0xcf,0x5f,0x68,0x49,0xbc,0x98,0xf9,0x0b,0x82,0xde,0xb1,0xf9,0x77,0x16,0x7c,0x1f,0x80,0x0c,0xfc,0xbb,0x6d,0x8e,0x92,0x93,0x00,0xc2,0xa5,0xbe,0xde,0x55,0x09,0x9d,0x83,0xa5,0x6c,0x0a,0xb5,0xc4,0x53 +.byte 0xde,0xbc,0x07,0xca,0x0f,0x43,0xea,0x50,0x25,0xee,0x51,0x3b,0xfb,0x7a,0xcf,0x31,0x8a,0x19,0x1c,0xa2,0x2d,0x72,0x79,0x81,0xc6,0xb8,0xe6,0xe1,0xd8,0x3e,0x0f,0xc0,0xae,0x73,0x40,0x30,0x15,0xaa,0xe3,0x72,0xc3,0x36,0xc1,0x42,0x11,0xc5,0x3f,0xf5,0x69,0x78,0xea,0x95,0x54,0x36,0xe8,0x7e,0x9c,0xad,0xbd,0xcd,0x19,0xfe,0x4a,0x04 +.byte 0xb4,0x54,0x14,0x98,0x58,0x6f,0x06,0x8f,0x8c,0x95,0xa8,0xc9,0xe8,0xc4,0x2b,0x03,0xaa,0x42,0x75,0x74,0xa2,0x63,0xdb,0xca,0xd1,0xf0,0x60,0xc3,0x63,0x84,0xfb,0xd7,0x5a,0x7b,0xca,0x45,0x8d,0x14,0xdc,0xf8,0x71,0x40,0x71,0xbb,0xa1,0x1a,0xd3,0x8c,0xfb,0xf6,0xf7,0xfc,0x82,0x72,0x50,0xc9,0xe3,0xc5,0xe2,0xb1,0x57,0xb1,0x24,0x3e +.byte 0x11,0x4d,0x96,0x1c,0x3a,0xe1,0xb6,0xb7,0x0e,0x55,0x35,0x6c,0xd8,0x2b,0xe3,0x78,0xcd,0xac,0x8f,0x24,0x70,0xc6,0x35,0x5b,0x6e,0x75,0x7a,0xf1,0x7d,0x87,0x53,0xcf,0x0a,0x24,0xb6,0x6a,0xfd,0xef,0x90,0x07,0xcf,0xde,0x30,0xbc,0x8c,0xec,0xda,0x6f,0x45,0xad,0x92,0xb6,0x8d,0x6b,0xb8,0x8e,0xdc,0xe5,0xbf,0x57,0x67,0x5e,0x2f,0x4d +.byte 0x5d,0xee,0x38,0x0a,0xaf,0xeb,0x62,0x84,0x2b,0x4c,0x30,0x7b,0x91,0x99,0x40,0x6f,0x09,0x2b,0x36,0xcd,0x04,0xeb,0x7c,0x8d,0xa5,0xbd,0xd6,0xb0,0xfc,0x27,0xcf,0x6b,0xdd,0xe1,0x94,0xbc,0x21,0xc6,0xc9,0x55,0x24,0xd4,0xa1,0x6f,0x1e,0xa2,0x81,0x31,0x22,0xb7,0x75,0x9e,0xa7,0x01,0x26,0x01,0x6c,0x12,0x91,0x02,0x87,0x40,0x5c,0x91 +.byte 0x1f,0x0c,0x55,0x07,0x12,0xa7,0x48,0xdd,0xed,0xb6,0xfe,0x38,0x05,0xbc,0xe1,0x2e,0x3b,0x89,0x4f,0x98,0x65,0x22,0x93,0xda,0x09,0x9f,0x04,0x90,0x66,0x81,0xd1,0x56,0x27,0x8b,0x26,0x99,0xbe,0x93,0x08,0xf1,0xfb,0x80,0x5b,0xaa,0xc4,0x96,0x88,0x93,0xb6,0x01,0xae,0xf6,0x69,0xaa,0x6f,0x4d,0xde,0x2f,0xc7,0x24,0xbf,0xe9,0xb8,0xeb +.byte 0xcd,0xb2,0x0a,0x50,0x5c,0xd2,0x0b,0xfc,0x57,0x3b,0x96,0xf8,0xd9,0xbe,0xd2,0xb5,0x16,0xac,0x7c,0xe4,0x2f,0x46,0x93,0x86,0x48,0x91,0xfa,0xae,0xca,0x05,0x9e,0xfe,0x6e,0xae,0xa5,0x58,0x94,0xc0,0x58,0x1e,0xc5,0x69,0x28,0xe0,0x99,0x12,0x83,0xcf,0x35,0xe4,0x72,0x7d,0x4e,0x8b,0x66,0x56,0xb3,0xa6,0x2a,0x72,0x06,0x03,0x45,0xd1 +.byte 0x95,0xc9,0x93,0xb7,0xf4,0x8a,0x83,0xce,0x17,0x8b,0xf0,0x8e,0x8f,0x4a,0x68,0x55,0xd8,0xfc,0x54,0x8d,0xb5,0x62,0x17,0xa8,0xe6,0x18,0x03,0x53,0x04,0xb8,0xbe,0xd2,0xd0,0x7a,0x84,0xe1,0x39,0x31,0xc5,0x74,0xf2,0x64,0x1c,0x3b,0xd5,0x52,0x9b,0x81,0x8a,0x8f,0x36,0xc8,0xab,0x3d,0xe1,0xa8,0x2a,0xf2,0x84,0x9a,0xca,0x0c,0xcf,0xc9 +.byte 0x45,0x54,0x06,0xe8,0xd2,0x62,0x61,0x4d,0xeb,0x0b,0x38,0x4e,0x43,0x59,0x85,0x3a,0xe4,0xa3,0x25,0x15,0xc2,0xb5,0x7b,0x5e,0x2f,0xe6,0xc1,0x5d,0x2a,0xb7,0x57,0xb8,0x7e,0x61,0x51,0xc3,0x81,0x53,0x45,0x8a,0x6e,0x4c,0x89,0x84,0x2a,0x6b,0xca,0x15,0xff,0x97,0xfc,0x1f,0x8a,0x44,0xbd,0xcd,0x5e,0x32,0x6b,0x5f,0x78,0x7b,0xdf,0xdd +.byte 0x9d,0x2f,0x21,0xf2,0x14,0x40,0x5f,0x5a,0xd5,0x21,0x27,0x3d,0x0b,0x9f,0x9f,0xb0,0x8e,0xab,0x9e,0x68,0x96,0x02,0xfd,0x4d,0xcc,0x03,0xf0,0x03,0xfb,0x4c,0xac,0xfa,0x00,0x3b,0xea,0x1a,0x53,0x80,0x77,0xec,0x53,0xc3,0x3c,0x6c,0xf8,0xa5,0x3e,0x52,0x34,0xd4,0xa1,0x52,0xb8,0xd6,0x19,0x8c,0xdf,0x85,0x27,0x61,0x22,0xe7,0x43,0xeb +.byte 0x85,0xc0,0xbe,0x58,0xe6,0x60,0x81,0x4c,0xc6,0xbb,0xc0,0xbf,0x63,0x39,0x9d,0xad,0x2e,0xa8,0x2a,0x83,0x3d,0xfa,0xdb,0x0b,0x98,0x16,0x78,0x18,0x43,0xc7,0x17,0x82,0xb8,0xec,0x32,0x45,0x75,0x0c,0xc1,0x4c,0x84,0xbf,0xce,0x83,0x3b,0xb4,0x91,0xf4,0x0d,0x5d,0x83,0xf6,0xd6,0x10,0xab,0xc6,0x26,0x9b,0x68,0x59,0xec,0x48,0x4b,0x1d +.byte 0x35,0x2a,0x5b,0x23,0x83,0x22,0x8e,0x7d,0xfa,0xce,0xde,0xb1,0xd9,0x78,0xf6,0x9e,0x08,0xba,0xfb,0xda,0xf2,0x04,0xc5,0x2a,0xac,0xbf,0xb4,0x04,0x05,0x1f,0x0b,0xeb,0xe8,0x2a,0x3c,0x3f,0x4f,0xb6,0xc8,0x6b,0x97,0x5a,0x9e,0xdb,0x4b,0x3c,0x93,0xc1,0x20,0x1c,0x62,0x91,0x74,0x76,0x49,0x92,0xc2,0xd8,0x0d,0xd8,0xfe,0xb5,0x68,0x77 +.byte 0x48,0x9f,0xbe,0xe0,0x78,0x20,0xe7,0xa4,0x3d,0x3e,0xa1,0x4c,0xc7,0xeb,0xd3,0x30,0xd3,0xf0,0x65,0xcf,0x18,0x3c,0xf8,0x25,0xc2,0x99,0xf4,0xec,0xef,0xdd,0xef,0xf3,0x6b,0x28,0x00,0xaa,0xfd,0x76,0xec,0x19,0x67,0xd6,0x79,0xa6,0x01,0x6e,0x20,0x3a,0x7f,0xd4,0xd0,0x05,0xb4,0xea,0xd4,0xde,0x11,0x06,0x44,0x4a,0x6f,0x15,0x2f,0x62 +.byte 0x9a,0xaa,0xeb,0xaf,0xb5,0xb5,0x46,0xb2,0x28,0x2e,0x74,0x26,0x06,0x91,0xeb,0x15,0xef,0xd4,0xfd,0xc7,0x1b,0x65,0x25,0x01,0x24,0xd2,0x44,0x05,0x18,0x1c,0x71,0x36,0x58,0xc4,0x37,0xfe,0x22,0x29,0xc0,0x2f,0xd2,0x4e,0xeb,0x43,0xb9,0xf9,0x4e,0x87,0xd7,0x92,0x77,0xa8,0x4f,0xa5,0x6e,0x5c,0x4d,0x3a,0xe9,0x16,0x62,0x30,0x51,0xbb +.byte 0x32,0xd8,0x0d,0x86,0x20,0xbf,0x68,0x0f,0x3e,0xef,0x8b,0x0d,0xc5,0xa6,0x94,0x81,0xe9,0x6f,0x85,0xf5,0x22,0x6e,0x9e,0x0a,0x56,0xa3,0x43,0x79,0x50,0xd9,0x45,0x5f,0x5a,0x3f,0x53,0x53,0xb7,0xfe,0xb6,0x1c,0x63,0xab,0x7c,0xed,0x2f,0xc4,0x2b,0xa8,0x53,0xfb,0xad,0x46,0xf0,0x63,0xca,0x7a,0x6e,0xce,0xf4,0xb9,0x34,0xd0,0x9a,0xc8 +.byte 0x0d,0xd2,0x32,0xce,0x26,0x3f,0xcd,0xd9,0xbc,0xa9,0x46,0x65,0x45,0xfe,0x45,0xeb,0x0d,0xab,0xe6,0x31,0xb6,0xb9,0x41,0x53,0x7d,0x55,0xc3,0xfb,0x10,0x46,0x37,0x77,0x1f,0x15,0xf0,0x5f,0xcb,0x8f,0xea,0xc5,0xc0,0xb8,0xc6,0xb1,0x3a,0x06,0x42,0xec,0x38,0xec,0x06,0xd1,0x37,0x3b,0xe1,0x8d,0xad,0xc2,0xce,0x96,0x0b,0xf0,0xab,0xde +.byte 0x9c,0x3c,0x09,0xef,0x59,0xcd,0x67,0xa7,0x6e,0x0e,0xc7,0xee,0x51,0x6d,0x90,0x40,0x0e,0xdf,0xb1,0x13,0xe3,0x0c,0xb6,0xe8,0xcb,0xf5,0x57,0x50,0xeb,0xdf,0x09,0x45,0x72,0x40,0xff,0xdc,0x5c,0x51,0x42,0x47,0xb2,0x9e,0xca,0xf3,0x1b,0x06,0xb1,0x3e,0x04,0x55,0x96,0x63,0x24,0x16,0xdb,0x3e,0xab,0x98,0x33,0x70,0x6f,0xfd,0x8f,0x7b +.byte 0x56,0xb0,0x7f,0x28,0x26,0xc4,0x2a,0x9e,0xf5,0xa7,0xba,0x61,0x75,0xa4,0xb1,0x25,0x60,0xe5,0x9c,0x7e,0xb4,0xaa,0x04,0xa1,0x33,0x5a,0x8d,0x88,0x1d,0xc4,0x38,0x58,0x28,0x23,0xc7,0xac,0x20,0xf8,0xaa,0x18,0xf8,0xc7,0x27,0x05,0x07,0xf7,0x12,0xfe,0xe1,0xa5,0x99,0xaa,0x55,0x79,0x72,0xc4,0x14,0x08,0x14,0x4a,0xfb,0xf7,0x66,0x81 +.byte 0x6e,0xed,0x81,0x12,0x5f,0xb6,0x08,0x00,0x37,0xf9,0xdc,0xdf,0x4d,0xcb,0xfa,0xc6,0xf3,0xc2,0x17,0x17,0x52,0x39,0x7b,0xa0,0x3e,0x25,0xc9,0x48,0xd8,0xa6,0x1b,0x8b,0xdb,0xf8,0x74,0xac,0x6b,0x16,0xec,0xa6,0x4a,0x1e,0x7e,0x5c,0x50,0xbf,0x81,0xef,0x3c,0x7d,0x9d,0x21,0x38,0xa9,0x26,0x3c,0x30,0x7a,0xfb,0xab,0xd8,0x6a,0x0a,0xaa +.byte 0xbb,0x6e,0x91,0x92,0x7c,0x04,0x02,0x0e,0xa2,0x71,0xc7,0xde,0x7d,0x42,0xaf,0xe5,0x92,0xc1,0xb9,0xd7,0x52,0xaa,0x32,0xea,0x39,0x84,0x17,0x40,0xb0,0x83,0x18,0xff,0x46,0xb8,0x59,0xd9,0xa3,0xce,0x82,0x7e,0x65,0x54,0xe0,0xa4,0x6d,0x8a,0xbc,0x6a,0x65,0xb2,0xd5,0x96,0x5b,0x1c,0x9a,0x32,0x72,0xf7,0x81,0x57,0xcd,0xb3,0x22,0xc5 +.byte 0x7d,0x20,0x24,0xea,0xbe,0x51,0x4c,0xb3,0x48,0x36,0x4f,0x73,0xf4,0x3f,0x07,0x92,0x01,0xe2,0x1e,0x78,0x3f,0x8e,0x1f,0x35,0x1a,0xf1,0xe1,0x14,0xd1,0xe7,0xd9,0xfd,0xd8,0xf7,0x20,0xc2,0xf3,0x7a,0x59,0xc9,0x1d,0x13,0x41,0x01,0xf6,0x77,0x69,0xfb,0x0f,0xc7,0xe4,0x58,0x04,0xce,0xe8,0x73,0x87,0x2f,0xef,0xe6,0x36,0x38,0xc7,0x91 +.byte 0x2d,0x17,0xb5,0x56,0x68,0xb1,0x9f,0xbf,0x2e,0x4b,0xe7,0x09,0x7b,0x35,0x33,0x5a,0x6c,0xc1,0x6f,0xb3,0xac,0x6c,0x1e,0xfe,0xc0,0xc9,0xd8,0x77,0xf5,0xcb,0x5e,0xcc,0xd1,0x2f,0xdd,0x23,0x8b,0x3b,0xb5,0x43,0x96,0x1f,0xa9,0xe4,0x84,0x41,0x92,0xe9,0x68,0x47,0x50,0xf7,0xd4,0x85,0x22,0xa1,0x43,0xaa,0xde,0xf7,0xea,0xe0,0x54,0xaa +.byte 0x0d,0xe6,0xa5,0xb8,0x7e,0xec,0x13,0x9a,0x1e,0x6c,0x10,0x9d,0xa8,0xfb,0x97,0xde,0x24,0xda,0x33,0xbb,0xab,0x17,0x7a,0xb4,0x72,0xaf,0xed,0xc9,0xa4,0x62,0x65,0x0c,0x99,0x3d,0x74,0x7f,0xff,0x59,0xa9,0x8e,0x37,0xb9,0x10,0x30,0x26,0x3f,0x2f,0xfc,0x1e,0xe2,0xc6,0xb8,0xff,0x41,0xb3,0x35,0x3f,0x41,0xf4,0x47,0xbc,0x76,0xc6,0x77 +.byte 0x0f,0xf8,0xff,0xb8,0xd2,0x34,0x40,0xac,0x43,0xcb,0xcf,0x1f,0x57,0xaa,0x1a,0xa7,0xe1,0x4a,0x69,0xd7,0x05,0xa7,0x9d,0xff,0x13,0x43,0x91,0xe3,0x09,0x1c,0xb2,0xb2,0x82,0x06,0xa3,0x3c,0x35,0x85,0x9e,0xd0,0xcf,0x1c,0xb9,0x13,0x09,0x7d,0x3d,0x17,0x0f,0xf8,0x2f,0x61,0x97,0x7e,0x02,0xe0,0x78,0x07,0x69,0x8c,0x91,0xbe,0x96,0x92 +.byte 0x4a,0x03,0xa7,0x31,0x5f,0x6c,0xfe,0x55,0xb2,0x17,0xe8,0x4c,0x64,0x48,0x18,0xde,0x4f,0x5a,0xce,0xd2,0xcb,0x83,0x4d,0x1b,0x2a,0x1f,0xce,0x85,0xf7,0xdc,0x74,0x8c,0x42,0xc6,0x5a,0x3a,0x51,0x22,0x79,0x70,0xa0,0xe0,0x29,0x2a,0x73,0xe4,0x53,0xb4,0x47,0x5f,0x54,0xa8,0x65,0xe4,0x89,0x78,0xf9,0xb9,0x5f,0x5f,0x9d,0xa8,0xf7,0x82 +.byte 0x4e,0x34,0x60,0xfc,0xe3,0x88,0x65,0x73,0x99,0x1f,0x53,0xed,0xe8,0xf0,0xf4,0x5a,0x0a,0x49,0x42,0x6e,0x02,0x3f,0xa8,0x63,0x21,0x02,0x2e,0x8f,0x33,0xba,0x0e,0x10,0xd3,0x4c,0x1a,0x8b,0xf5,0x84,0x8e,0x2b,0x37,0x12,0x23,0x77,0x02,0x45,0xc7,0xc3,0x79,0x06,0xc2,0x8c,0xaa,0x32,0x53,0x7c,0x19,0xa2,0x92,0x7e,0x47,0x40,0x8f,0xae +.byte 0x8a,0x64,0x51,0x67,0xe1,0xc1,0xc3,0xd2,0x14,0x1d,0x63,0x0c,0x80,0x04,0x30,0x3d,0xee,0x58,0x44,0xe4,0x14,0x63,0xfc,0x95,0x05,0x3e,0xc1,0x8d,0xd3,0xcb,0x5d,0xc1,0x8e,0xf9,0xd7,0xe5,0x9d,0x97,0xef,0x8a,0xaa,0x50,0x31,0xa3,0x01,0x3a,0xb2,0x8d,0x63,0xb6,0xe7,0x34,0xec,0xa1,0x7a,0xff,0x57,0x95,0xbb,0x1d,0xbe,0x0c,0xa5,0x91 +.byte 0x92,0x08,0x06,0x1c,0x67,0x03,0x2e,0xee,0xf6,0x6f,0xa0,0xb7,0x9a,0x7c,0xe3,0x6a,0x8e,0xd8,0x50,0xc1,0xd6,0xa1,0x8d,0xe9,0x66,0x9a,0x1f,0x62,0x15,0x04,0x93,0x74,0xe8,0x04,0x0d,0x27,0x55,0x2b,0x07,0xb1,0xbd,0x69,0xe4,0xc1,0x34,0x8e,0xe7,0xfb,0xa0,0x3f,0x40,0x31,0x47,0xba,0xcb,0x80,0x88,0xf7,0x4f,0x46,0x05,0x31,0xaf,0x23 +.byte 0xdf,0x93,0x09,0x0a,0x15,0xc9,0x95,0x74,0x52,0x72,0xf4,0xbf,0x0d,0x07,0xb6,0xcc,0x4b,0x40,0x12,0xf3,0x87,0xea,0x29,0xd8,0x29,0x31,0x23,0xac,0x29,0x1a,0x89,0x83,0x5b,0x33,0x4b,0x6b,0x69,0xbe,0xb6,0x15,0x7e,0xfd,0xf2,0x95,0xc4,0xbe,0xeb,0xee,0x59,0x01,0x2a,0xce,0xca,0x80,0xda,0xf8,0x1a,0x01,0x23,0xf7,0xa1,0x4f,0xf5,0x83 +.byte 0x5e,0x16,0xd9,0x12,0xa9,0x4e,0xcb,0x59,0x23,0x4f,0x40,0xd7,0xbf,0xaf,0x76,0xf0,0x50,0x31,0x27,0x3a,0x8b,0x1d,0x9b,0xb1,0x1c,0x41,0xb0,0xed,0xe6,0xf3,0xa8,0x5f,0x6b,0x58,0x54,0x92,0xaf,0xcc,0x44,0x5c,0xea,0xdb,0x09,0xc5,0x26,0x5e,0xbe,0x46,0xbd,0x72,0x49,0x5a,0x4e,0x65,0x7e,0x75,0xcf,0xfc,0xf6,0xd0,0x3c,0x4a,0x7e,0xd6 +.byte 0x8e,0x8e,0xb4,0x19,0x45,0x75,0xbf,0xc3,0x5e,0x46,0xff,0xc9,0x46,0x65,0x8d,0x31,0x01,0x5e,0x1c,0x13,0x93,0x56,0x6f,0x28,0xec,0xf3,0x77,0xfa,0x6e,0xb9,0x0e,0xb6,0x8e,0x0e,0x38,0xf8,0x28,0x64,0xa2,0xa1,0x42,0x9a,0xb4,0xf3,0x14,0x8d,0x17,0x80,0x05,0x82,0x7c,0xf1,0xea,0x8b,0x4b,0x62,0xa0,0xde,0xf6,0xd7,0x36,0xb0,0x70,0x8d +.byte 0x03,0xf6,0xc8,0x2a,0x9e,0xc0,0xbb,0x2f,0xcb,0xef,0x35,0xf7,0x16,0xcd,0xd6,0xd6,0x90,0xd7,0x5d,0x61,0x00,0x33,0x9f,0xd8,0xd1,0xda,0x17,0x67,0x90,0xd1,0xf8,0x59,0xcb,0xf1,0x76,0xc2,0xbe,0x1f,0x5d,0x0d,0xb2,0x02,0xbd,0x19,0x9f,0x5a,0xa0,0x91,0xac,0x51,0xb5,0xf5,0x0a,0x64,0x67,0xf2,0x49,0x30,0x6c,0x57,0x83,0xda,0x90,0xf1 +.byte 0xc6,0xc7,0xe6,0x05,0x13,0x30,0x52,0xfd,0x2a,0x47,0xea,0xae,0xd3,0xed,0xe4,0x64,0x1f,0x6c,0xb1,0xdf,0xca,0x20,0x97,0x2a,0xc8,0xdc,0x00,0x0e,0x5b,0x59,0xc8,0x16,0x95,0x68,0x9a,0x2e,0x44,0xab,0xf6,0x93,0x7c,0x8f,0x66,0x4f,0x07,0x42,0x3f,0xa5,0x81,0xe7,0xab,0x59,0xbb,0xae,0xb1,0x3e,0x9a,0x25,0xf1,0xde,0xac,0x4c,0x1d,0x7a +.byte 0x54,0xb9,0xa9,0x59,0xaf,0xb0,0xab,0xaf,0x6b,0x76,0x66,0x1e,0xbe,0x1a,0xc1,0x61,0x1b,0x81,0x6b,0xe8,0xe4,0x73,0x6a,0x87,0xe9,0x39,0xcb,0x2c,0xab,0x64,0x36,0x9a,0x11,0x46,0xec,0x9f,0x30,0xb6,0x2c,0x14,0xe0,0xec,0xbe,0x33,0xde,0x60,0xc6,0x00,0x29,0x3c,0x55,0xda,0xfc,0x64,0xff,0xaa,0xbf,0x99,0x58,0xe2,0xe3,0xec,0xde,0xca +.byte 0xd1,0x3d,0xd2,0xad,0xaa,0xca,0x36,0x8f,0x93,0xa2,0xdd,0xde,0xaa,0x49,0x7f,0xdd,0x39,0x91,0xa0,0x7b,0x33,0xdf,0x36,0xcd,0xc3,0x3a,0xbc,0x53,0xf0,0x07,0x99,0x78,0x4e,0x63,0x47,0x79,0xbf,0x21,0xfc,0x05,0x47,0x69,0xec,0xee,0xf4,0x21,0x97,0x94,0x0c,0x7a,0x9f,0xa6,0xeb,0x5b,0x23,0xed,0x9d,0xc1,0xe1,0x5e,0x10,0xca,0xe0,0x84 +.byte 0x5a,0xdd,0xf6,0xae,0xd8,0x23,0x98,0xea,0x6c,0x43,0x77,0x41,0xf3,0x84,0x5a,0xe8,0xda,0xb3,0x11,0x0e,0x19,0x33,0xe9,0xf9,0x7a,0x90,0x07,0x68,0xf1,0xe4,0x52,0x0c,0x03,0x67,0xb9,0x42,0x41,0x24,0xa3,0x61,0x67,0x75,0xc9,0xb5,0xdd,0x10,0xf1,0x20,0x93,0x54,0xdb,0x0d,0xc7,0x0d,0x25,0x3e,0xda,0xb3,0xe7,0xce,0x97,0x7e,0xdb,0x1a +.byte 0x8f,0x92,0xff,0xe3,0x44,0x2d,0x6b,0xdb,0xe0,0x69,0x8b,0x16,0xce,0xe8,0xc7,0x93,0xf1,0x19,0xb9,0xd3,0x41,0x45,0x8d,0x95,0xb3,0x03,0xb2,0x66,0x96,0x95,0x91,0x33,0x1c,0xee,0xde,0xd7,0x9d,0xab,0x32,0x2f,0xb8,0x3c,0x7a,0x44,0x8f,0xa6,0xca,0x02,0x03,0x2f,0xa8,0x44,0x85,0x0e,0xf5,0x27,0x90,0x84,0xd9,0x80,0x06,0xf4,0x4f,0xc7 +.byte 0x21,0xc5,0x92,0xa4,0x2d,0x08,0x42,0x4c,0xa7,0x84,0xfa,0x7e,0x2b,0x66,0xfb,0x7c,0x81,0xea,0x5c,0x7d,0xdd,0x86,0xf1,0xf5,0x04,0xef,0xf2,0x50,0x12,0x72,0x42,0x22,0x23,0x74,0x7f,0xe7,0xed,0xd9,0xce,0x78,0x10,0x83,0x37,0xd0,0x81,0x97,0x4a,0xac,0xc2,0xe5,0x13,0x91,0x83,0xe2,0x6e,0xff,0x5a,0x0b,0xc3,0x4d,0xc1,0x3e,0x97,0x16 +.byte 0x96,0x69,0x39,0x9e,0x1d,0x6b,0x16,0x82,0xa2,0x94,0x0d,0x50,0xdd,0xa3,0xda,0x9d,0xda,0x3f,0x46,0xce,0x6c,0xd0,0xdf,0x6e,0x1b,0x17,0x47,0x51,0x74,0x6f,0xe9,0xa4,0x6b,0xae,0xd2,0x6e,0x5b,0xc0,0x26,0xc6,0x0b,0x84,0xb1,0x39,0xcf,0x9e,0x7c,0x18,0x52,0xd7,0x8f,0x33,0xae,0x3d,0xaf,0x3d,0x1a,0xba,0x3f,0x09,0x76,0x22,0x1d,0xf3 +.byte 0x42,0x14,0x4f,0x06,0xc7,0x33,0xc1,0x2d,0x58,0x1b,0x4c,0xc0,0x3a,0x29,0xa6,0x5e,0x19,0x26,0xdf,0x36,0x18,0xa9,0xc5,0xe9,0xd3,0xb1,0xae,0x86,0xa8,0x7f,0xd9,0xb4,0x18,0xef,0x9c,0x46,0xb6,0xf2,0xb2,0xb6,0x6e,0xe2,0xf8,0x5f,0x27,0xea,0x76,0xd3,0x40,0x68,0x94,0x66,0x8a,0xf5,0x9f,0xee,0x0c,0xe5,0xae,0xb6,0xba,0x87,0x42,0x40 +.byte 0xc9,0x83,0xac,0xb4,0x2c,0xec,0x74,0xb7,0x55,0x17,0x0b,0x1e,0x45,0x1a,0x87,0x9d,0x52,0xce,0xb7,0x58,0x2f,0x45,0xc7,0x7d,0xf3,0xd3,0x11,0x2e,0xf4,0xd8,0xc0,0xb8,0xc3,0x31,0x45,0x68,0x40,0xe8,0x8a,0x33,0x20,0x9a,0x06,0xa8,0x18,0x53,0xb2,0x73,0xa1,0x57,0xac,0x8f,0x56,0xeb,0x8e,0xa4,0xfc,0xd6,0x76,0x7e,0x81,0x62,0x2c,0x17 +.byte 0x49,0xb4,0xcc,0x15,0x66,0xcb,0xa2,0x3c,0x29,0xf0,0x73,0x0e,0x9a,0x34,0x16,0x6d,0x43,0x62,0x20,0x89,0x14,0xae,0x8b,0x5d,0x61,0x54,0xa1,0x82,0x49,0x73,0xb9,0x2b,0x48,0xd4,0xe3,0x21,0x37,0x5e,0x4d,0xbf,0xd0,0x72,0xa4,0x23,0xdb,0x7c,0xd9,0x45,0x77,0x8a,0x24,0x23,0x56,0xcd,0x84,0x80,0x44,0x12,0xce,0x99,0x39,0xbd,0x77,0xff +.byte 0x8c,0x62,0x8d,0x56,0x77,0x24,0x40,0x11,0x22,0xab,0x28,0xd6,0x75,0x2b,0xbb,0xc1,0x51,0xd6,0x5e,0x61,0x1c,0xe9,0xac,0x36,0x99,0x52,0x44,0xa5,0x20,0xdb,0xe0,0x12,0x9a,0x45,0x8f,0x7f,0x47,0xf9,0xa3,0x91,0x18,0x2b,0x51,0x9a,0x9f,0x3f,0x7d,0x36,0xde,0x71,0xae,0xca,0x62,0x62,0x16,0xda,0x19,0x9c,0x84,0xce,0xde,0x93,0x22,0xde +.byte 0xaf,0xe7,0x91,0x09,0xe8,0xf0,0x0e,0x07,0x71,0xdf,0x48,0xcd,0x8a,0x77,0x19,0x3c,0xd6,0xef,0x8e,0xe0,0x49,0xdf,0xcb,0xd6,0x34,0x78,0x7f,0x42,0xc2,0x6e,0x7a,0x50,0x53,0xee,0xbf,0x73,0x4b,0xd4,0x4f,0x06,0x18,0x26,0x67,0x51,0x54,0xa3,0x40,0xe6,0xb3,0x61,0x4b,0xfd,0xee,0x62,0x00,0x44,0x6c,0x0d,0x8b,0x2f,0x4d,0x06,0x17,0x41 +.byte 0xee,0x8b,0xde,0x1f,0x80,0x36,0x58,0x3e,0x0a,0x53,0x0a,0x83,0xf9,0xba,0xbd,0x91,0x6a,0x20,0x32,0x42,0x6c,0x85,0xdc,0x84,0xfd,0xce,0x57,0xbe,0xf8,0xa5,0x2c,0x7e,0xf9,0x1b,0x07,0xf4,0x32,0x13,0x32,0x79,0xdc,0x91,0xfc,0xc0,0x18,0xe6,0x1e,0xb2,0x67,0x9d,0x08,0xd2,0x89,0xa2,0xb1,0xbf,0x37,0xe1,0x3f,0x9e,0xb5,0x17,0xf7,0x2f +.byte 0x9a,0x4f,0x3c,0xea,0x5d,0x48,0x56,0x48,0x35,0x17,0xe9,0x5a,0x99,0xa7,0x2e,0x25,0x4f,0x96,0xa6,0x3d,0x3c,0xf8,0xdc,0xe7,0xe5,0x98,0x46,0xf7,0x10,0x16,0x4f,0xb0,0x7b,0x48,0x06,0xbb,0x9a,0x5a,0xad,0x32,0x49,0x92,0x39,0xb2,0xfe,0x01,0x1a,0x5e,0xcc,0xf7,0x0d,0x65,0x1c,0xf5,0x3d,0xb3,0x40,0x28,0x06,0x6e,0xbb,0x74,0x2a,0x95 +.byte 0xe9,0x62,0x2a,0xe2,0x19,0x38,0xc6,0x0d,0x46,0x30,0x6d,0x90,0xa5,0x68,0x4d,0x89,0xf0,0xf4,0xaf,0x52,0x11,0x8a,0x47,0x65,0xc0,0x6d,0xee,0xde,0xbc,0xed,0xf2,0x94,0xf3,0xfb,0xfd,0x2f,0xea,0xd5,0x36,0x89,0x8a,0x22,0xb8,0x75,0x3c,0xda,0x8d,0x3f,0x71,0xe5,0x50,0xb8,0xef,0xfc,0xa1,0x34,0x4a,0xb0,0x56,0x64,0xaf,0x28,0x0c,0x7a +.byte 0x28,0x3e,0xc8,0x83,0xc2,0xbb,0x89,0xc4,0x29,0x7f,0xc9,0xe7,0x4e,0xcb,0xdc,0x8f,0xe8,0xa4,0xdc,0x0d,0xcc,0xa0,0x16,0xda,0xa9,0x34,0x61,0xec,0x64,0xa7,0xf4,0x47,0xe9,0xee,0xbf,0xc6,0x4b,0xc5,0x01,0x65,0xe4,0xe0,0x12,0xd6,0x27,0xda,0x30,0xb5,0x60,0x72,0xe1,0xee,0x38,0x23,0x6c,0x9d,0xbb,0x83,0x01,0x4b,0x26,0x9a,0x68,0xb3 +.byte 0x89,0xb3,0xe0,0x10,0x22,0x58,0xef,0x2d,0xd4,0x86,0xab,0xab,0xc4,0xd8,0x9c,0x56,0xe8,0x54,0x40,0x86,0x11,0xd2,0x6b,0xc0,0xaf,0xfc,0x4a,0xef,0x24,0x38,0x79,0x32,0x54,0x26,0x8b,0x7e,0x02,0xad,0x86,0x9d,0x40,0x65,0x28,0x28,0xa3,0xa6,0xe4,0x07,0x29,0x3a,0xbb,0x81,0xed,0x17,0x54,0x51,0x35,0xc6,0x88,0x9c,0x63,0x7e,0x73,0x02 +.byte 0x28,0x13,0x4b,0x33,0xc0,0x68,0xbc,0xae,0x8c,0x59,0xd4,0x84,0x1d,0x41,0x86,0x5a,0xf6,0x14,0x50,0x13,0x88,0xca,0xc8,0xb8,0xfc,0x61,0xeb,0xe6,0x69,0x70,0x4a,0xa5,0xa5,0x36,0x4b,0xac,0xca,0x00,0x28,0xae,0xb0,0x03,0xef,0xe3,0x92,0xad,0x97,0x32,0x05,0x8c,0x93,0x95,0x45,0xd5,0x75,0x66,0x11,0xd3,0x6f,0x7f,0x5f,0x35,0x44,0xb7 +.byte 0xd7,0x34,0xcf,0x8c,0x4a,0x61,0x68,0x63,0x3f,0x92,0x54,0x01,0x3c,0x25,0x2d,0x6f,0x4a,0x2d,0x55,0xff,0x3f,0x86,0x85,0x9f,0xc2,0xa1,0xde,0x6b,0xbf,0x7e,0xb4,0x7c,0xc1,0x80,0x73,0xf5,0x3b,0x85,0xae,0x36,0x1a,0xdf,0x00,0x52,0xb7,0x70,0xa9,0x42,0x79,0xd2,0x26,0xf8,0x3b,0xeb,0x9f,0x2e,0x15,0x33,0xc8,0x85,0x2d,0x63,0xb2,0x89 +.byte 0x24,0x8e,0xfd,0xe6,0xdf,0x01,0x80,0x8b,0x27,0xe3,0x7e,0x17,0xc2,0x4e,0x26,0xa2,0xe1,0x95,0x81,0x3a,0xdd,0x2a,0xf4,0x75,0x21,0x64,0x11,0x04,0x5e,0x00,0x39,0xf0,0x08,0x68,0x67,0x09,0xa8,0x9b,0xbe,0xb7,0x62,0x0e,0xa8,0x69,0xcd,0x4e,0xaf,0xc8,0x4f,0x92,0x3d,0x8e,0x35,0x60,0x70,0xb3,0xda,0x2f,0x38,0x80,0x6f,0x5e,0xcc,0x3b +.byte 0x6e,0x05,0x26,0x14,0x9d,0x36,0x72,0x7d,0x09,0xb8,0xb7,0xa1,0xf7,0x5f,0xb3,0xe1,0xd6,0xc5,0x54,0x4e,0x80,0x4d,0x06,0x8f,0x84,0xbb,0xb6,0x65,0x87,0x2c,0x19,0x4a,0x74,0x3c,0x34,0x62,0x32,0xad,0x4c,0x06,0xa3,0xbb,0xfb,0x4f,0x4f,0x9d,0x91,0x84,0x63,0x75,0x34,0xcc,0x6b,0x00,0xa1,0x5a,0x63,0x03,0x8d,0x1e,0xdb,0xa4,0x0c,0xe6 +.byte 0x3d,0xd1,0x94,0x77,0xd8,0x77,0x8c,0x39,0x48,0x78,0xb1,0xb5,0xa2,0x41,0xd0,0x6d,0x27,0x20,0x4a,0x41,0x88,0xa5,0x78,0x3f,0x51,0x72,0x8c,0x80,0xe7,0x37,0x81,0x8b,0x06,0x46,0x58,0xab,0x23,0x85,0x47,0x89,0x39,0xf9,0x14,0xfe,0xbf,0x07,0x7c,0x47,0x8e,0xcc,0xd7,0x08,0xfe,0x5d,0xee,0xf9,0x94,0xa2,0x83,0x81,0x8a,0xfd,0x0f,0x9a +.byte 0xa7,0xe4,0x59,0xad,0xe6,0x1f,0xed,0x5d,0xe4,0x20,0xd6,0x2f,0xa7,0xd3,0xcf,0x5b,0x18,0x6d,0x24,0x79,0x66,0xd9,0xaa,0x44,0xfa,0x8d,0x74,0x60,0xcc,0x7e,0xbf,0x4f,0x0e,0xe3,0x9c,0xa5,0xe4,0xff,0x14,0x05,0xff,0x24,0x62,0x94,0x00,0x7a,0x58,0xe5,0x0b,0x3b,0xe8,0xee,0xe1,0x4d,0x4e,0x34,0x26,0xba,0x70,0x10,0x5e,0x14,0x4f,0xa5 +.byte 0x7a,0x9e,0x7b,0x28,0x99,0xbe,0x94,0x4a,0xcb,0x8d,0x65,0x60,0xa0,0x6e,0xc7,0xbc,0x51,0xba,0xb5,0x07,0x97,0x25,0x42,0xb7,0x2c,0x0e,0x9b,0xfc,0xfb,0x35,0x6f,0x74,0x10,0xce,0x25,0xdb,0xa9,0x7c,0x11,0x61,0x43,0xf9,0x19,0xbf,0xe2,0x21,0xa3,0x57,0x3c,0x41,0x0a,0x15,0x4e,0x7f,0x6b,0x38,0xb6,0x73,0x41,0xa2,0x4e,0x8e,0xb9,0x44 +.byte 0xee,0x2a,0x2e,0x0a,0x9e,0x85,0xf1,0x6e,0x93,0x72,0x42,0x50,0x55,0xe1,0xc6,0x18,0x11,0x92,0xf7,0xbf,0x05,0xd8,0xb6,0xbc,0x2b,0xd5,0xe0,0xd3,0x9b,0x64,0xc4,0xdd,0xb0,0xb3,0x46,0xd8,0xfb,0x73,0xea,0xed,0x06,0x96,0x16,0x9e,0xf6,0xc6,0xe8,0xbe,0xae,0x00,0x2f,0x5a,0xf4,0x1f,0xb5,0x28,0x7c,0x75,0x76,0x68,0x74,0xa2,0x57,0x0e +.byte 0x6c,0xfa,0x2d,0xbe,0x34,0xf1,0xc9,0x2b,0x83,0x58,0xe7,0x2a,0x87,0xdb,0x47,0xae,0xc7,0xc2,0x78,0x50,0xed,0x20,0xdf,0x30,0x38,0xdd,0x84,0xa9,0x6b,0x00,0xb1,0x7b,0xbb,0x69,0xd3,0xbe,0xed,0x3d,0x99,0x6e,0x39,0x42,0x75,0x8a,0x6c,0x7c,0xa5,0xcf,0xc9,0xcf,0x11,0x14,0xb3,0xaf,0x72,0x00,0x3b,0x58,0xdd,0x2a,0xe1,0x44,0xa7,0x51 +.byte 0x15,0x05,0x1b,0x18,0x49,0x07,0x90,0x4c,0xbc,0x99,0x88,0x64,0xf6,0x14,0x0b,0x99,0xc0,0x84,0xc9,0x06,0x32,0xf0,0xec,0x19,0x8d,0x4a,0xb8,0xdb,0x32,0xb4,0x5e,0xc9,0x0c,0x24,0xf0,0xad,0xdc,0xf4,0x32,0x3b,0xf6,0x68,0x28,0x4a,0xa5,0x5b,0xb7,0xd5,0x00,0x35,0xf8,0x56,0x03,0xa3,0x86,0xa0,0x8a,0x1b,0x53,0xb5,0x58,0x73,0x8c,0xf9 +.byte 0x2b,0xd8,0xcb,0x88,0xe7,0x7e,0x79,0x68,0x13,0x5d,0x7d,0x23,0xc4,0xec,0x9c,0xf4,0x95,0x97,0xbf,0xb2,0xd9,0xdf,0x38,0xe8,0xa2,0x79,0xf7,0xe8,0x36,0x80,0x59,0x3f,0x58,0x2f,0xf7,0xf9,0x32,0x73,0xdd,0xd6,0x9e,0x20,0x1a,0x29,0xab,0xc1,0x77,0x14,0x71,0x3c,0xde,0x90,0xe9,0xea,0xdb,0x78,0x14,0xa3,0x89,0x43,0xf1,0x42,0x43,0x3f +.byte 0xe7,0x67,0x32,0x3d,0x65,0xdc,0xa4,0x79,0x8f,0x81,0xa5,0xb0,0x94,0x0f,0x96,0xf5,0x82,0xcc,0x47,0xc1,0x29,0x39,0x70,0x7a,0xf3,0x49,0xf5,0x09,0x43,0x50,0x56,0xd6,0xea,0xc4,0x35,0xa5,0xa2,0x8a,0xbe,0xc0,0xe3,0xfe,0x4c,0xa2,0x83,0x09,0xab,0x72,0x8a,0x96,0x7c,0x01,0x70,0xb2,0xd5,0x62,0xb7,0x67,0x59,0x36,0xcf,0x56,0x2d,0x14 +.byte 0xc2,0x69,0x49,0x52,0x4e,0x7c,0x45,0x4b,0xef,0xcd,0x79,0xcd,0xe6,0xa6,0xd0,0xbe,0x10,0x1e,0x18,0xca,0xe7,0x8d,0x65,0xb1,0x17,0xc7,0x2c,0xc8,0x2a,0x5b,0xe8,0x08,0x11,0x15,0xea,0xa9,0x43,0x7b,0x70,0x04,0x0c,0xc8,0xca,0x67,0x18,0x18,0x12,0x16,0xc2,0xd3,0xf2,0x0a,0xc7,0x01,0xa9,0x97,0x61,0xf6,0xa7,0x44,0x9a,0xb3,0x67,0xdc +.byte 0x07,0x63,0x02,0x02,0x2e,0x58,0x80,0xa9,0x95,0xa0,0x8e,0x86,0xb6,0xf6,0x14,0x13,0x0a,0xea,0xf1,0x6d,0xd9,0x98,0x37,0x12,0xdb,0x67,0x1b,0x13,0x8e,0xd1,0xfa,0x2f,0x98,0x53,0x3c,0xd7,0x56,0x55,0x42,0x2f,0x64,0x59,0xd5,0xb7,0x6e,0xa8,0x6c,0xc2,0x40,0x11,0xb5,0xa1,0xc0,0x5c,0x45,0x87,0x91,0xb1,0x1c,0x4e,0xa9,0xf6,0x72,0x57 +.byte 0x50,0x8e,0xc5,0xfc,0x64,0x59,0x52,0x82,0xb0,0x75,0xc3,0x98,0xff,0x32,0xce,0xa4,0x39,0xb8,0xa4,0x61,0xb4,0x53,0x3f,0xc7,0x80,0x35,0x48,0xaf,0xa8,0x67,0xfe,0xa1,0x1d,0x3c,0x95,0xb5,0x63,0x1c,0x3a,0x2c,0x68,0xfa,0x98,0x8b,0xa7,0x19,0x29,0x79,0xe4,0x9b,0xff,0x8f,0x15,0x9c,0x65,0x60,0xd2,0xa9,0x4f,0xd5,0xb2,0x57,0xff,0x32 +.byte 0x4c,0x96,0x82,0x6b,0x09,0x6c,0x74,0x55,0x00,0x5c,0x68,0x68,0xd5,0x9b,0xd4,0xdf,0x3d,0x2d,0xb9,0x0b,0xf5,0x2c,0x87,0x35,0x2a,0xc0,0xc0,0xc9,0xd7,0xa1,0x76,0x30,0x82,0x46,0xd8,0x24,0x6e,0x27,0x02,0x71,0x57,0x5c,0x43,0xf2,0x54,0xd6,0xea,0xd7,0x67,0x7d,0xac,0x76,0x91,0xf1,0x26,0x6e,0xaf,0x87,0x05,0x06,0x48,0x57,0xbd,0x67 +.byte 0x1d,0xd7,0x07,0xcd,0x41,0x02,0x49,0x6c,0x8c,0xe1,0xe3,0x00,0x78,0xbe,0x28,0x84,0x16,0x44,0xb1,0x0d,0x6d,0x40,0xfe,0xab,0x7e,0xf6,0x6b,0xff,0xfa,0xe1,0xc7,0x9d,0x56,0x62,0xf1,0x68,0xba,0x76,0x34,0x8f,0x54,0x20,0x49,0xf5,0xa2,0x54,0x52,0xca,0x42,0xed,0x4f,0x9b,0xdf,0xcf,0xfb,0xf6,0xee,0x12,0x29,0x43,0x8f,0xf9,0xfd,0xf4 +.byte 0x8a,0xbf,0xae,0x50,0xf2,0x8f,0x46,0xa2,0x97,0x3b,0x2d,0xfb,0x84,0x98,0x61,0xae,0xba,0x36,0x25,0x30,0x8b,0xdc,0xd3,0x08,0x8e,0x7e,0xfa,0x91,0xac,0x4b,0x29,0x6d,0x0c,0x81,0x0f,0xc7,0xc8,0xc4,0x5c,0x48,0x68,0xa7,0x83,0xf3,0x6a,0xc8,0x0d,0x3a,0x9b,0x46,0xb9,0xe1,0x31,0xac,0x3c,0x12,0xa2,0xae,0x74,0xb8,0x91,0xed,0x63,0xba +.byte 0x40,0xb8,0x57,0x58,0x1f,0x1d,0x1a,0x2d,0x98,0x60,0xe8,0xe1,0x84,0x16,0xe5,0xf0,0x1e,0x35,0x58,0x31,0xc3,0x0c,0x49,0x6e,0x13,0x2c,0xac,0x14,0xc2,0xde,0x5f,0x62,0xe5,0x37,0x5b,0x1d,0x71,0x8b,0xc3,0x3d,0xd8,0xaf,0x3d,0x0a,0xef,0x80,0x3c,0x9a,0x4b,0x0a,0x3f,0x0e,0x8f,0x90,0x8f,0x73,0x2e,0xff,0x8e,0x8e,0x87,0xf8,0x46,0x52 +.byte 0xed,0x7d,0x76,0xf3,0xff,0xaf,0x5e,0x62,0x87,0x16,0x9c,0xa6,0x12,0x39,0x13,0xc3,0x62,0x4b,0xd2,0x21,0xa2,0x43,0xfa,0x4c,0x5d,0x75,0x61,0x64,0x5b,0x23,0xcd,0x76,0x86,0x81,0xd6,0xa6,0x25,0xe1,0xc1,0xc6,0x04,0x5e,0x65,0xfe,0x89,0x0e,0x67,0x02,0xeb,0xb9,0x26,0x88,0x81,0x97,0x1e,0x62,0x4e,0xf4,0x4e,0x0d,0xef,0xac,0xcf,0xd7 +.byte 0xc5,0x9b,0x9d,0x3a,0xa2,0x71,0xd7,0xd4,0x72,0xa6,0x66,0x90,0xe2,0xf7,0xb7,0xec,0xe4,0xca,0x9f,0xd1,0xd8,0x5a,0x65,0xff,0x39,0x65,0x78,0x47,0x1c,0x64,0xab,0x1a,0x35,0x2e,0xe2,0xf7,0x67,0xa4,0x7f,0xd5,0xea,0x04,0xee,0x4d,0xf6,0x29,0xe4,0xcd,0x1b,0xcf,0x0a,0xef,0xa1,0x14,0x90,0x0e,0xed,0x1a,0x10,0x63,0xa0,0x56,0x11,0x05 +.byte 0x57,0x94,0x3a,0x11,0xff,0xe0,0xc7,0x33,0x19,0x67,0xd7,0xd0,0xcc,0x76,0x52,0x5d,0x9e,0x10,0xe7,0xd6,0xaa,0x13,0xe8,0x8d,0xa5,0x60,0x66,0x98,0x26,0x11,0x66,0x0f,0x2d,0x4d,0xec,0x28,0x93,0x17,0x3a,0x6f,0x99,0x70,0x00,0x2b,0x66,0xb3,0x49,0x69,0x3c,0x3b,0x03,0xb8,0xc0,0x9b,0x1c,0x96,0xd9,0xd1,0xe1,0x6d,0x8f,0x45,0xce,0x22 +.byte 0xcf,0x48,0x61,0x85,0x10,0x1b,0x3f,0x2b,0x74,0x48,0x61,0x68,0x63,0xe3,0xa3,0x83,0xe2,0xcc,0xa0,0x6d,0x82,0x8b,0xe5,0x42,0xab,0xa7,0x62,0x6c,0x05,0xb4,0x7b,0x65,0xf5,0xd8,0x0b,0x7d,0x61,0xd6,0x5c,0xf0,0xc0,0x03,0x0c,0x51,0xec,0x06,0xad,0x79,0x8c,0x62,0x0c,0xf5,0x8e,0xcb,0x97,0x62,0xf9,0x3e,0x39,0x8d,0x3c,0x2e,0xd1,0xc0 +.byte 0x5f,0x98,0xea,0xb5,0x26,0x19,0xf5,0x93,0xbb,0xf8,0xd4,0xd5,0x35,0xee,0x1f,0xf8,0x71,0x81,0x0e,0xe6,0xe9,0xf3,0x2c,0x80,0xa8,0x15,0x35,0x1e,0xda,0x07,0x41,0x39,0x8a,0x19,0x1f,0x70,0x99,0xbe,0x3d,0x5c,0x1f,0xf6,0x72,0x85,0x73,0xea,0xb5,0x61,0xbb,0x77,0xaa,0xef,0xc7,0x2c,0xed,0x1e,0xa6,0xfd,0xc9,0xde,0xa9,0x82,0xba,0x19 +.byte 0x04,0x17,0xf7,0xa1,0x59,0x5c,0x7d,0x8d,0xe7,0x1c,0x89,0x7f,0xe1,0x02,0xd3,0xb0,0x46,0x6c,0xcf,0xde,0xf0,0x0b,0x00,0x43,0x8d,0xd6,0xe6,0xf7,0xc8,0x83,0x20,0x77,0x8b,0x9f,0x14,0xea,0x2b,0xb2,0xd2,0x41,0xfd,0x96,0x7c,0x0d,0x05,0xb9,0x5a,0xa0,0x83,0x50,0xde,0x0e,0xc6,0xa6,0x29,0x55,0x12,0x8e,0x2f,0x0a,0x5c,0xcd,0xae,0x92 +.byte 0x76,0x84,0xc9,0x8a,0x81,0xe5,0x3e,0xf0,0xe6,0x5b,0xe4,0x21,0xfb,0x4c,0xb6,0x0a,0x7b,0x7f,0x7e,0xab,0xdc,0x15,0x44,0xf8,0xeb,0x23,0x21,0x31,0xef,0x98,0xec,0x84,0x69,0x34,0x29,0x99,0x03,0x8a,0x12,0x8e,0x28,0xdd,0x00,0x6a,0xa3,0xe7,0x08,0x17,0x35,0x2a,0x42,0x8a,0xcb,0x4a,0x7b,0x1c,0xd2,0x74,0x4f,0x6a,0x8c,0x85,0x1c,0xd6 +.byte 0x05,0x3a,0xfd,0xdf,0x1c,0xa5,0x59,0xbb,0xdb,0xe3,0xa7,0x59,0xb1,0x67,0x3d,0xa4,0x71,0x4d,0x6c,0x99,0xe0,0xa7,0x8c,0xfa,0x96,0x1f,0x8d,0x0c,0xa7,0xc8,0xce,0xa3,0xbf,0x4d,0xc7,0xa9,0xb7,0xfd,0x04,0x58,0xcd,0xd7,0x20,0xb1,0xb9,0xf5,0x06,0x70,0x1b,0xdd,0xf4,0x1c,0xdc,0x32,0xa0,0x90,0x0d,0xb2,0x91,0x14,0x05,0xa2,0xf7,0xb7 +.byte 0xb6,0xd2,0xf1,0x30,0x75,0xcc,0x78,0x0d,0x56,0x70,0x64,0x02,0xe7,0x83,0x97,0x65,0x63,0x4b,0x64,0xff,0x8b,0x62,0xc9,0xa4,0x6e,0x96,0xbf,0xd3,0xeb,0x74,0xc5,0x1f,0xdb,0x1c,0xf3,0xca,0x54,0x7d,0x8d,0xd9,0xec,0x18,0xd8,0x99,0xd1,0xa5,0x70,0x8a,0xc5,0xdc,0xa0,0xcb,0xb7,0x52,0xe3,0xe6,0x88,0x0c,0x5a,0x42,0xde,0xe6,0xd8,0xc4 +.byte 0x39,0xe5,0x6c,0x0b,0xd4,0xa5,0x9b,0x51,0xa2,0x3d,0xc5,0xc7,0x17,0x17,0xb8,0xd8,0x09,0xad,0xeb,0x67,0x47,0xe0,0x88,0xef,0x1d,0x22,0x18,0x25,0xdc,0x32,0xb2,0xf7,0x47,0xc5,0xb3,0x0b,0x57,0x01,0x67,0xac,0xc3,0x9e,0xb0,0xa8,0xd7,0xce,0xb2,0xcd,0xea,0x3b,0x61,0xbb,0x24,0xad,0x91,0x7b,0xa2,0x9a,0xb3,0x63,0x56,0xe2,0x9d,0x69 +.byte 0x9e,0xd7,0x5f,0x5f,0x47,0x9f,0xae,0xf6,0x09,0xb1,0x9e,0x22,0x35,0xaa,0x55,0x0b,0xfc,0x70,0x96,0xfd,0x53,0x8a,0x37,0xaf,0x2d,0xa2,0xc5,0x49,0x5b,0x1e,0x32,0x47,0x9d,0xc3,0xb4,0x46,0xf3,0x54,0xdb,0x3f,0xb9,0x69,0x9e,0x8b,0xad,0x11,0xb2,0x68,0xe8,0x27,0x0d,0xca,0x33,0x1c,0x86,0xb2,0x2c,0xaa,0xc2,0x15,0xf9,0x6e,0xed,0x30 +.byte 0x71,0x08,0xeb,0x93,0x1d,0x16,0xc5,0x34,0x73,0x65,0x7a,0x19,0x2b,0xa7,0x3d,0xe6,0x88,0xb5,0x0f,0xa0,0x92,0x91,0x22,0x9d,0x01,0xf3,0xf4,0x57,0x9f,0xd9,0x23,0x1b,0xbd,0xd7,0xd5,0x11,0xc9,0x24,0xf6,0x36,0x30,0x30,0x69,0x95,0x17,0x48,0xf9,0x76,0x71,0xef,0xef,0xc0,0x00,0x9c,0x7d,0x87,0xdc,0xdc,0x1a,0x32,0x82,0x7a,0x13,0xc2 +.byte 0x9f,0x53,0xc2,0x7d,0x4d,0xbf,0xbe,0xf5,0x9d,0xc8,0x81,0x5b,0x81,0xe9,0x38,0xb6,0xa5,0x40,0xa5,0xd4,0x6f,0x0c,0xea,0xf1,0x52,0x59,0x37,0x3b,0xc2,0xb2,0x5f,0x10,0xdf,0x22,0xf7,0x77,0xe8,0x66,0xb0,0x97,0x91,0x5f,0xc2,0x18,0x8d,0x17,0x40,0xd1,0x6d,0xde,0x6e,0xf0,0x6c,0x1f,0x4e,0x9b,0x15,0x83,0x9b,0x70,0x21,0x2b,0x98,0x46 +.byte 0xbf,0xa5,0x82,0xac,0x63,0xac,0xd7,0x52,0xec,0x2c,0xf2,0xe4,0xe0,0x2a,0xbf,0x7e,0xa2,0xd2,0x9d,0x0d,0xf2,0x9b,0x79,0x5f,0x22,0xb0,0x6d,0x22,0x2e,0xed,0xe2,0x4f,0x73,0xc5,0x89,0xcc,0x4a,0xaa,0x9a,0x7e,0xab,0x95,0x25,0xa7,0x9d,0xf4,0xc2,0xe8,0x42,0x6e,0xd3,0xf9,0x25,0x54,0xb9,0x1f,0xa9,0x16,0x9c,0x22,0x7a,0xf0,0xa6,0xac +.byte 0x8b,0x9d,0xe6,0xe3,0x93,0x4e,0x65,0x3a,0x39,0x3e,0xf5,0x41,0x38,0x02,0xb7,0x37,0xd4,0xdc,0xea,0xc5,0x53,0x0e,0x52,0x85,0x96,0xc0,0xa7,0x21,0xbf,0xe7,0xca,0x12,0x1c,0x59,0x33,0xe4,0xd5,0x70,0x6b,0x25,0x54,0x24,0x58,0x48,0x1b,0x65,0x6e,0x7e,0xe6,0x84,0x39,0x38,0xbc,0xdf,0x96,0xbc,0x39,0xdf,0x8f,0x36,0x9e,0x3a,0xda,0x02 +.byte 0x86,0xe2,0x9f,0xb7,0x3a,0xd0,0xdb,0xc2,0x5d,0xb0,0xde,0x31,0x73,0x43,0xe5,0x4b,0x6a,0xa1,0x6d,0xaa,0xca,0x34,0xfa,0xa9,0xaf,0xec,0x05,0x2a,0xdb,0x82,0xa1,0xdc,0xdc,0x3d,0xb5,0x92,0x42,0x28,0xdc,0x93,0xec,0xab,0x9b,0x75,0xae,0x7c,0xbf,0x9b,0x25,0x01,0xb1,0xc8,0x3b,0x47,0xb6,0xfd,0x11,0x6f,0x4b,0xaa,0x6f,0xdf,0x1f,0x15 +.byte 0xc2,0xf3,0x87,0x4a,0xaf,0xf7,0x41,0x64,0x5a,0x19,0xa0,0xc4,0x4f,0x58,0xe8,0x19,0xe0,0x84,0x44,0xc7,0x65,0x0c,0xf1,0xff,0xcb,0x73,0xb2,0xac,0x25,0x28,0xe1,0xd4,0x03,0x16,0x3c,0x1c,0x24,0x3a,0xfc,0x2b,0x7e,0xcb,0xa3,0xba,0xb7,0x78,0x87,0xbe,0x95,0x06,0x27,0xb8,0x16,0x72,0xe4,0x24,0xa6,0x5d,0xe7,0x5e,0x93,0xa9,0x96,0xfd +.byte 0x01,0x1d,0xb8,0x7c,0x85,0x3c,0xe3,0xc9,0x56,0x68,0xcd,0xd9,0x79,0x97,0x50,0x39,0xfe,0x96,0x93,0x50,0xae,0xde,0xcd,0x8d,0xa0,0x38,0x31,0xba,0xca,0x21,0xff,0x19,0xea,0x44,0x95,0x4d,0xba,0xae,0xe2,0x62,0xd2,0x82,0x60,0x0c,0xb9,0x10,0x40,0x9a,0xaf,0x9b,0x17,0xcd,0xf3,0x26,0xec,0x38,0x13,0x18,0xd3,0xf2,0xd2,0x11,0xa6,0xc3 +.byte 0x3c,0x3b,0xe8,0xa0,0x49,0xba,0x4e,0x07,0xec,0x44,0x75,0x1c,0xc9,0x2f,0x68,0x64,0x02,0x1d,0x14,0x35,0x80,0xd8,0xa8,0x53,0xde,0x44,0x65,0x72,0x37,0x28,0x61,0x5f,0xa1,0x58,0xea,0x17,0xb3,0x89,0x25,0xf7,0xcb,0x87,0xe6,0x43,0xc5,0xc3,0xf3,0xd1,0xf5,0x1f,0x18,0xe9,0xd1,0x05,0xd9,0x85,0x38,0xf0,0x5e,0x26,0x35,0xf2,0x72,0x92 +.byte 0x34,0x2f,0xea,0xdd,0x7b,0x64,0xac,0x1d,0x78,0x41,0x56,0x83,0x7d,0x83,0x83,0x59,0xbe,0x9f,0x81,0x90,0x00,0x1f,0x04,0xd8,0xd8,0x8e,0xd9,0xeb,0x12,0x16,0x96,0x81,0x61,0x96,0xe8,0x7b,0x36,0x7b,0x26,0x9b,0x43,0x1e,0x0e,0xc2,0x59,0xdf,0x8f,0xb4,0x91,0x74,0x2e,0x1e,0x6d,0x20,0x70,0xe7,0x3c,0x39,0xe3,0xa8,0x62,0x66,0x32,0x63 +.byte 0x7d,0x89,0xb6,0xad,0x69,0x38,0x2c,0x21,0xe5,0x02,0xcc,0x93,0x8a,0x65,0x71,0x65,0x02,0x5c,0xeb,0xc9,0x70,0xf3,0x81,0xce,0x65,0x37,0x22,0xb7,0x47,0x3c,0xd6,0x3d,0x29,0x65,0x29,0xba,0xf9,0xae,0xd9,0x1f,0xd7,0x38,0x88,0x95,0xa9,0x66,0xa8,0x77,0x75,0x4a,0xf9,0x2e,0xd9,0x63,0x75,0x80,0x90,0x82,0x39,0x8b,0x21,0x58,0xf4,0x2e +.byte 0x2d,0x1f,0x7f,0xcb,0x33,0xdb,0x9b,0x9b,0x31,0x21,0x4e,0x6e,0xdb,0x0f,0x1f,0x69,0x22,0x97,0x69,0xd7,0x7f,0x2e,0xd7,0xce,0x6c,0xe4,0xc0,0xe7,0x27,0x82,0xe6,0x8a,0xf8,0xae,0x46,0x2d,0x5a,0x45,0x82,0xce,0xb6,0x49,0x84,0x15,0x4a,0x54,0xa6,0x76,0xf3,0x29,0x28,0xc0,0x05,0x82,0xae,0x7d,0x85,0x41,0xb0,0x87,0x67,0x44,0x37,0x46 +.byte 0x3e,0x47,0xbc,0x00,0x7c,0x05,0xd3,0xdc,0x9a,0x31,0x49,0xf8,0x48,0x99,0x57,0x4a,0x2b,0xe7,0xcf,0xb2,0xa7,0xf0,0xcf,0xc7,0xf5,0xfd,0x73,0x59,0xf1,0xe4,0x86,0xb5,0x5d,0xce,0x6d,0xbf,0xc6,0xe5,0xa9,0xca,0x75,0xe9,0x69,0xe6,0x09,0xab,0x66,0x17,0x09,0xe9,0xbc,0x14,0xd8,0x6f,0xe9,0xc2,0x87,0x39,0x2f,0x87,0x1e,0xb8,0x16,0x08 +.byte 0x10,0xee,0x1c,0x2f,0x47,0x7d,0xa3,0x5b,0x1f,0x1f,0x5d,0x95,0xd0,0xa4,0xbb,0x08,0xc2,0x47,0xab,0x46,0x3c,0xbb,0xbe,0x3a,0x64,0x82,0x40,0x08,0x75,0x03,0x02,0x6e,0x6a,0xab,0x6b,0xd4,0x90,0xa7,0x28,0x7a,0xb4,0x8b,0x1f,0x6b,0xcc,0x16,0x30,0x16,0xf5,0xc6,0xd8,0x4a,0xed,0xc9,0xc7,0xac,0x0f,0x75,0x1b,0x13,0xe3,0x45,0x6d,0x22 +.byte 0x7e,0x3d,0x59,0x55,0x87,0x8d,0x04,0xee,0x85,0xac,0x98,0x0c,0x52,0x5b,0xe6,0x92,0x04,0x31,0xdf,0x7c,0x44,0x4d,0x06,0xbe,0xb2,0x5a,0x95,0xef,0x29,0x75,0x9b,0xb2,0xe7,0xb8,0x83,0x18,0x82,0x23,0x4e,0x66,0xe5,0xdd,0x47,0xa1,0x6b,0x33,0x4e,0x9c,0x13,0x0e,0x0a,0x8a,0x5c,0xba,0x7b,0x2f,0x6c,0x72,0x78,0x86,0xd2,0xf8,0xbd,0x1b +.byte 0x4b,0x9e,0xe0,0x99,0x46,0x7f,0x24,0x0f,0x1b,0xda,0x85,0x87,0xe9,0xda,0x96,0x25,0xc6,0x81,0x77,0x8b,0x56,0xae,0x7a,0x9c,0x47,0x34,0xe1,0xac,0xf2,0xba,0x52,0x95,0xf8,0x56,0x26,0x66,0xf0,0x53,0xcc,0xc4,0x6f,0x46,0x94,0x10,0x22,0x69,0xb1,0x93,0x7b,0x51,0xb7,0xb8,0xdd,0x42,0x67,0x51,0x6d,0x9c,0xb2,0xbd,0xdb,0xdd,0x19,0xa2 +.byte 0x25,0x13,0xfe,0x42,0xca,0x36,0xeb,0xce,0x15,0x41,0xe7,0x35,0xce,0xa8,0x45,0x56,0x58,0x9f,0x46,0xcf,0x11,0xe7,0xcc,0x40,0x54,0xe4,0x85,0x0d,0x73,0x36,0x7e,0xae,0x38,0x8c,0x56,0xab,0xf0,0x5f,0x5c,0xff,0x14,0x9b,0x46,0x1b,0x35,0xbd,0x03,0x0e,0x2f,0x9e,0xde,0xd8,0x82,0xfe,0xa0,0x09,0xb4,0xb4,0xbd,0x58,0xc0,0xe2,0x01,0xb1 +.byte 0xca,0x5c,0x3d,0xc3,0x18,0x5e,0xc1,0xee,0x61,0x60,0x00,0xca,0x1e,0xf3,0x71,0xd8,0x15,0x37,0xf0,0x2e,0x13,0xa0,0xf7,0xac,0x73,0x4b,0xfb,0x6a,0x27,0x6b,0xde,0x69,0x3d,0x19,0x36,0x4b,0x63,0x55,0xae,0xd1,0x2b,0x66,0x69,0x0d,0x64,0xa7,0x86,0xfd,0x3a,0xb8,0xe6,0x87,0xaa,0x32,0x5f,0xbc,0xa7,0x67,0xde,0x7a,0xe0,0xdd,0xff,0x57 +.byte 0x2c,0xc9,0x25,0x92,0x03,0x91,0xa8,0x0e,0x39,0xe4,0x9a,0xdf,0x21,0x29,0xc7,0xbc,0x93,0x01,0x2a,0x02,0xd8,0xaf,0xbc,0x20,0x57,0xc7,0x37,0x77,0xa7,0xad,0x5e,0x15,0x20,0xcf,0x4a,0x3c,0x22,0x1b,0x92,0xa9,0x05,0x91,0x70,0xb3,0x88,0x4e,0x97,0x58,0xf7,0x33,0x1a,0x05,0x33,0x57,0xdc,0xbb,0x2a,0xba,0xd0,0x22,0xac,0x40,0xbe,0x60 +.byte 0xa2,0x89,0xe6,0x6c,0xf3,0x5d,0xef,0x58,0xb4,0x7c,0x4a,0x28,0xb8,0x16,0xd2,0xe0,0x49,0xf5,0xe8,0xaf,0x84,0x39,0xae,0x1e,0xa2,0x34,0x67,0x42,0x26,0x31,0x93,0x87,0x7a,0xd5,0xde,0x79,0xdb,0x4c,0x7e,0xcf,0x1f,0xef,0x9a,0x4c,0xb9,0x70,0xe2,0x72,0x9b,0xcd,0x30,0xe5,0xf1,0x84,0x44,0x5a,0xff,0x36,0xa2,0x37,0xe7,0x49,0x78,0x63 +.byte 0xbe,0xe0,0x90,0xdf,0xef,0x9e,0xf3,0x55,0x9e,0x8a,0x51,0xe8,0xa3,0x32,0x2d,0xed,0xc8,0x99,0xf6,0x92,0xf9,0x62,0x74,0xa7,0x8d,0xcf,0xa5,0x09,0xb3,0x43,0xb9,0x18,0x70,0x59,0x4f,0xd2,0x7f,0x7e,0xce,0x1e,0x7d,0xe8,0xa9,0xb7,0x29,0x0f,0x86,0x8a,0xac,0x22,0x41,0x98,0xb2,0xc3,0x48,0x3b,0x60,0xcb,0x7b,0x1d,0xc3,0x5e,0x19,0x5b +.byte 0x31,0x57,0x12,0x09,0x41,0x54,0xf8,0x01,0x70,0x02,0x03,0x8a,0x6e,0x8e,0x5b,0x23,0xf3,0xd4,0x13,0xbf,0x51,0xba,0xf9,0x2d,0x6c,0xb9,0xb3,0x90,0xd0,0xa3,0x76,0xfb,0xef,0x85,0x17,0x8b,0x2c,0x05,0xa3,0x06,0x0a,0xaa,0xdd,0xbf,0xd4,0xcc,0xe4,0x96,0x19,0x7f,0x51,0xf6,0x7e,0xa1,0x2c,0x14,0x1c,0x21,0x99,0x28,0x3a,0x0e,0x36,0x1b +.byte 0xf1,0xd7,0x3e,0x29,0x94,0xa6,0x03,0xf7,0xe5,0x6f,0x1b,0x56,0xc8,0xfb,0x2d,0x4f,0x12,0x2b,0xc7,0x3a,0xec,0x5e,0xc8,0x88,0x1b,0xd8,0x65,0x21,0x04,0x0e,0xe2,0x95,0x6d,0x62,0xea,0xeb,0xee,0xbe,0x47,0x0a,0x90,0x26,0xe3,0x85,0xd7,0x1d,0xb5,0xd5,0x56,0x8b,0xc0,0x2f,0x7f,0x01,0xc8,0xac,0x90,0xc3,0x2d,0x10,0xf2,0x11,0x30,0x0c +.byte 0xa9,0x4d,0x13,0xde,0x65,0x6d,0x34,0x68,0x5d,0xad,0x3f,0x7a,0x56,0x3a,0x1f,0xb9,0xd6,0x7b,0x8f,0xe8,0x42,0x2a,0x16,0xb6,0x3f,0xf2,0x4f,0x14,0x8e,0x8e,0x29,0x88,0x68,0x1b,0x10,0x80,0x80,0x47,0x36,0xaa,0x82,0xf5,0xa8,0x97,0xc4,0xcb,0xc2,0xef,0xaa,0x9f,0xdc,0x96,0x4f,0x1f,0xaf,0x39,0x71,0x55,0x8f,0x3c,0xbf,0x26,0x91,0x46 +.byte 0x38,0x59,0xa7,0xd1,0xb5,0x87,0xd6,0x81,0x71,0x17,0x83,0x05,0x40,0x9c,0xf3,0x33,0x4b,0x09,0x06,0xb1,0x69,0xfb,0x43,0x1f,0xef,0x9a,0xfe,0xc3,0x4e,0x4e,0x25,0xe1,0x3a,0xfb,0xf9,0xc9,0x97,0xe2,0x1c,0xa1,0x9a,0x06,0x6e,0xbb,0x16,0x4a,0x9f,0xf4,0x87,0x31,0x38,0x78,0xae,0x77,0x4c,0x42,0x28,0xc4,0x63,0xc0,0x49,0x37,0x4f,0xf9 +.byte 0xeb,0x31,0x0d,0x3e,0x0c,0x8a,0xb7,0x17,0xa7,0x90,0x26,0xc2,0xea,0xa5,0x9d,0xe4,0x4d,0xc6,0x3a,0x33,0x2d,0x47,0x42,0x8c,0xeb,0x50,0xea,0xfe,0x74,0x43,0x06,0xcd,0xa5,0xb1,0x49,0xf0,0x98,0x91,0x25,0xf4,0x8d,0x06,0xd1,0xeb,0x56,0x2c,0xf9,0xc4,0x84,0x02,0x9e,0xf2,0x3a,0xfe,0xb4,0x39,0xce,0xee,0x85,0xb6,0x64,0x6c,0xbc,0x1f +.byte 0xe6,0x86,0x00,0xc3,0xa9,0xb4,0x53,0xdf,0x2d,0x7c,0xc6,0xde,0x2e,0x79,0x25,0x5c,0xbb,0xe5,0xbe,0x33,0xe9,0x58,0x49,0x35,0xbe,0xae,0xbc,0x06,0xdc,0x48,0x9d,0xc3,0x08,0x6f,0xe8,0xb8,0x48,0x67,0xea,0x1c,0x05,0xb4,0xf7,0xe3,0xcc,0xc1,0xb3,0xa8,0x61,0xcb,0xa8,0xf6,0x12,0x52,0x68,0x06,0x36,0x2b,0x15,0x43,0xc9,0x98,0xfe,0xe5 +.byte 0x43,0x11,0x0d,0xc3,0x37,0x38,0x7a,0xcb,0x98,0x14,0xc1,0xaf,0x29,0x36,0x35,0x63,0x74,0x98,0xcf,0x0f,0x44,0xe4,0x6e,0xf7,0x3f,0x6e,0x15,0xe8,0xe9,0x93,0x7b,0x96,0x1b,0x84,0xe7,0x8b,0x83,0x30,0xa1,0xdc,0xc3,0xb8,0x18,0x2f,0xc5,0x34,0xd1,0xa5,0xb9,0xee,0x4a,0x04,0xbf,0x26,0x63,0x29,0xba,0x90,0xb5,0x7c,0x83,0x2b,0x1f,0xe8 +.byte 0x5c,0x9f,0x23,0x40,0x7f,0x9c,0x2f,0x76,0x96,0xd6,0xd5,0x13,0xda,0x5c,0x81,0xa4,0x60,0x60,0xbd,0x5e,0xb3,0xd2,0x2c,0xaa,0x48,0x04,0x74,0x31,0x5d,0xbd,0x46,0xd8,0x8d,0x3f,0x62,0x2d,0x1e,0x17,0x97,0x08,0x71,0x06,0x1b,0x96,0x1b,0xd5,0x80,0xa6,0x41,0x06,0x10,0x6e,0x36,0xd4,0xfb,0x36,0x6d,0x96,0xb8,0x86,0x22,0x34,0xda,0x7e +.byte 0x6c,0x5f,0x3b,0x95,0x35,0x1b,0x42,0x3c,0xf2,0x9d,0xe3,0xe9,0x3f,0x44,0xd5,0x4c,0x60,0x55,0xae,0xbe,0x4f,0xf2,0xb3,0x84,0xa1,0x79,0xdf,0x86,0xf0,0x8f,0xad,0xa5,0xa3,0x4a,0xea,0x5d,0x68,0x34,0x17,0x4c,0xb7,0xd8,0x6f,0x67,0x22,0x85,0xe2,0x16,0xcf,0xba,0xee,0x92,0xeb,0x95,0x8e,0x67,0xb1,0xf0,0xbb,0xb0,0x34,0x2f,0x58,0x49 +.byte 0x56,0x3e,0x81,0x31,0xb6,0xc3,0x2c,0xee,0x2b,0x85,0x72,0xbc,0xe9,0x20,0xaa,0x4e,0x34,0xb9,0x8b,0x32,0x2f,0x9e,0xd7,0x98,0x63,0x9d,0xfd,0x3a,0xe9,0x30,0x49,0x23,0x4a,0xb4,0xcb,0xc5,0xe5,0x78,0xcd,0x22,0x90,0xce,0x9f,0x35,0x13,0xda,0x8f,0x14,0xdb,0x36,0x0f,0x66,0x87,0x62,0x50,0xde,0x52,0x15,0x10,0x67,0x8a,0x5c,0xdb,0x76 +.byte 0x51,0x7f,0x72,0x9b,0x8e,0x91,0x39,0xc8,0x3c,0x34,0x0f,0x3d,0x92,0x07,0xb8,0xef,0x2a,0x8b,0x59,0xbd,0x82,0xc1,0x5c,0x95,0x93,0x0d,0x3d,0x9b,0x51,0x53,0x38,0x6b,0xd0,0xe3,0x5b,0xbb,0xe5,0x6c,0xc0,0xb5,0x71,0xa8,0xd8,0x7d,0x5d,0xbd,0xfc,0x69,0xcf,0xcc,0xa1,0xcd,0x83,0x9d,0x8f,0x46,0x47,0xe7,0x36,0x19,0x9f,0x4d,0xda,0x9c +.byte 0xcb,0x2a,0x47,0x58,0x93,0xbb,0x64,0xa3,0x89,0x53,0xbf,0xc7,0xc2,0xe2,0x65,0x0f,0x4f,0x17,0xc6,0x4c,0x15,0xfe,0x4b,0x95,0xb2,0x79,0x4a,0xb8,0xf6,0xae,0xcc,0xba,0xc3,0x5d,0x18,0xb2,0x8e,0xd8,0x6b,0x43,0x1b,0x2f,0xe1,0x36,0xb2,0xa5,0x22,0xa0,0xc7,0xc0,0x26,0x8e,0x48,0x77,0x0c,0x14,0xdd,0xdc,0xde,0x71,0x98,0xce,0xdd,0x61 +.byte 0x85,0xd9,0x23,0x42,0x7f,0x85,0xc8,0x06,0x81,0x3e,0xa2,0x0f,0x1e,0x3e,0xcf,0x33,0xef,0x43,0x6a,0xc7,0xee,0x3f,0x91,0x68,0x32,0x89,0xd9,0xed,0xdf,0x45,0x33,0x10,0xbb,0xd5,0xef,0x1d,0x3c,0x1e,0x26,0x21,0x4d,0x1a,0x06,0x98,0x60,0x71,0x7f,0xce,0x45,0x4e,0xe3,0x3f,0xfa,0xff,0xcd,0xe2,0x92,0x82,0x2e,0x83,0x69,0x9c,0xc6,0x5c +.byte 0x6e,0xb6,0xec,0x28,0xdc,0x7b,0xdb,0xf3,0x02,0x3a,0xf7,0xad,0x9b,0x7a,0x73,0xb2,0x07,0x70,0x76,0x9d,0xa2,0x11,0xcf,0x89,0xea,0xaf,0x6a,0xd2,0x15,0xeb,0x5a,0x99,0x1a,0x17,0x1d,0xce,0xc0,0x7f,0x50,0x26,0x84,0x07,0xd7,0x7e,0x33,0x27,0x74,0x84,0x18,0x32,0x86,0x32,0x34,0x28,0xe8,0x45,0x21,0xb7,0x26,0x3b,0x11,0xbb,0x9a,0x8b +.byte 0x46,0x8e,0x27,0xf8,0x62,0xb5,0x98,0x6e,0x03,0xee,0x9e,0xcb,0xbc,0x74,0xbe,0x63,0x7a,0x86,0xe5,0x75,0xeb,0x7f,0x14,0xa6,0x96,0x76,0x5a,0x46,0xa9,0xda,0xf1,0x4e,0x0e,0x90,0x59,0x56,0x4a,0x48,0x2d,0x91,0xbe,0x78,0x5b,0xfb,0xf7,0xea,0xab,0x1c,0xc0,0x0c,0x5d,0xba,0xb4,0x7b,0xc7,0x21,0xb1,0xc9,0xa3,0x20,0xe6,0xae,0xee,0x0e +.byte 0xf0,0x3b,0x44,0xd6,0xaa,0x57,0x88,0x1f,0x76,0xc8,0x43,0x07,0x91,0x71,0xa5,0xcc,0x04,0x38,0x01,0x13,0xa6,0xea,0x18,0x48,0x8f,0x09,0x8d,0x37,0x8b,0x6f,0x35,0x36,0x51,0xc6,0x30,0xca,0x9e,0xe2,0xaf,0x0c,0x26,0x14,0xe3,0xbf,0xea,0x0e,0x14,0x88,0x97,0xcc,0xf6,0xc1,0x8f,0xad,0xef,0x2d,0xc1,0x0f,0xad,0x45,0x12,0x7a,0xe6,0x37 +.byte 0x97,0xcb,0x34,0x83,0xd8,0xef,0x34,0x2a,0xce,0xd0,0x21,0x8a,0x7d,0x87,0x7a,0x66,0xf7,0x1c,0xdf,0xa0,0x3f,0xa0,0xf6,0xb3,0x24,0xee,0x6e,0x21,0xe9,0xc3,0x73,0xe4,0xd9,0xc6,0xf6,0xf6,0xac,0x25,0xb7,0xb5,0x64,0x7f,0xcc,0x88,0x3e,0x98,0xe1,0xef,0xa9,0xd2,0x03,0x10,0x4b,0xa3,0xbc,0x3c,0x24,0xfc,0x41,0x36,0x30,0x2d,0xca,0x17 +.byte 0x35,0xd6,0x17,0xa2,0x2b,0x48,0xed,0xd3,0xd7,0x18,0x4f,0x45,0xe9,0x59,0x03,0x35,0xa0,0x80,0x75,0x17,0x48,0xd5,0xea,0x07,0x7a,0x6c,0x3f,0x7a,0x2c,0x02,0x0a,0x7f,0xb5,0x17,0xea,0xf4,0xf6,0xb5,0xf4,0x81,0xba,0x69,0x44,0x81,0x6b,0xff,0xb2,0x43,0xae,0x3d,0x37,0x81,0x91,0x3f,0x6a,0x70,0x35,0x2d,0x06,0x9d,0xa8,0xb5,0xb8,0xc7 +.byte 0x19,0x3a,0x5f,0x59,0x79,0x0b,0x62,0x23,0xa4,0x5b,0x46,0x7b,0x17,0x82,0x19,0x87,0xe8,0xdf,0x09,0xb7,0x50,0x7e,0x40,0xe3,0x71,0x2d,0x09,0xde,0x69,0x2e,0x6c,0x35,0x5c,0x44,0xae,0xb7,0x05,0xb8,0x7e,0xb4,0xe4,0x34,0x05,0x1f,0xd2,0x1f,0xe5,0x79,0x2a,0x15,0xf8,0x8f,0x02,0xc7,0xc8,0x1e,0xe6,0x12,0x83,0x08,0x9c,0x7a,0x2f,0xc6 +.byte 0xc9,0x15,0x0f,0x0f,0x0f,0xa9,0x53,0x16,0x19,0x5b,0x74,0x58,0x6c,0xac,0x21,0x72,0x7f,0xa1,0xae,0xbc,0x34,0x76,0xa6,0x9b,0xbe,0x0f,0x13,0x55,0x50,0x5a,0x8b,0x9e,0xb3,0xf3,0x9e,0x8b,0x61,0xbe,0xb4,0x09,0x71,0x61,0xf0,0xd6,0xaa,0x8c,0x0d,0x0c,0x66,0x31,0x88,0xe3,0x71,0x6a,0xb5,0xaa,0xc0,0x9b,0xce,0x0d,0x79,0x90,0xc1,0x0a +.byte 0xf9,0xfe,0x4d,0x49,0xd0,0x5a,0x63,0xf1,0xfc,0x47,0x71,0x9e,0xbb,0xd1,0x2c,0xef,0xfe,0x90,0x28,0x75,0x82,0xf6,0xa5,0x95,0xea,0x65,0xfa,0xe8,0x04,0xcd,0xb4,0xe1,0x0d,0xb2,0xac,0xd5,0x12,0xf5,0x17,0xbb,0x3b,0x2e,0x52,0x9e,0x7b,0xe7,0x8e,0x86,0x03,0xce,0x77,0x01,0xf0,0x4f,0xb5,0xf7,0xef,0x8b,0x37,0x5e,0x97,0x80,0xbb,0x2b +.byte 0xcf,0x9a,0x63,0x18,0xc5,0x0c,0xfb,0x3c,0x91,0x9c,0x37,0x90,0x76,0x71,0x62,0xbc,0x80,0x40,0x1a,0x74,0xb8,0x1b,0x61,0xb1,0x89,0x4d,0xf7,0x8d,0xd4,0x46,0xef,0x1f,0x3b,0xac,0xe8,0x41,0x62,0x8e,0xea,0x2b,0x56,0x22,0x25,0x37,0x70,0x53,0xcd,0x8f,0x57,0xfa,0xad,0x00,0xc5,0x0c,0x9e,0x57,0xde,0x50,0x07,0x8d,0x80,0xbf,0x22,0x5d +.byte 0x4a,0xbd,0x6a,0xcb,0xfc,0x6f,0xd1,0x56,0x8f,0xd5,0x34,0x8a,0xe6,0xe9,0xa0,0x00,0x06,0x12,0xd8,0xb1,0x49,0x0a,0xbb,0x87,0xe5,0xca,0x75,0x11,0x4c,0x85,0x60,0x77,0xc0,0x90,0x1c,0x14,0x38,0x38,0x3e,0x4f,0xff,0xbf,0xfc,0xa1,0xa1,0xe7,0xb0,0x5d,0xd8,0x1f,0x33,0x07,0x5f,0x04,0x4f,0xc7,0x93,0xc6,0xcc,0xe3,0x01,0xd0,0x43,0xe1 +.byte 0xd9,0x00,0xc5,0x9f,0x79,0xab,0xfc,0xe9,0x55,0x51,0x03,0x0c,0xe1,0x73,0xd6,0x09,0xe3,0xb9,0x76,0x72,0x77,0x4c,0x1b,0x7c,0x57,0x1e,0x7f,0x5f,0x02,0x83,0xa3,0xc6,0xde,0x23,0x85,0x76,0x1a,0xbf,0x48,0xc8,0x02,0xdb,0x31,0x30,0x95,0x85,0x68,0x8a,0xf6,0xe9,0x48,0x7f,0xc9,0x26,0xab,0x68,0x36,0x9f,0x1c,0xf0,0x90,0xbc,0x4a,0x68 +.byte 0x94,0xf8,0x7f,0xae,0xa9,0x3b,0x5b,0x63,0x9a,0xcd,0xe3,0xf0,0xac,0x9f,0x6f,0x78,0xa0,0x67,0x58,0xd8,0x2c,0x71,0x8a,0x14,0x31,0x07,0x95,0x0c,0x38,0xa4,0x53,0x33,0x60,0x23,0x21,0x87,0x6b,0x4f,0xf9,0xa8,0xb8,0xfc,0x8e,0xf1,0x3a,0x03,0x0b,0x03,0x02,0x33,0xbc,0x6a,0xb9,0x8e,0x41,0xc8,0x38,0xd8,0x83,0x30,0x6a,0x61,0x5c,0xcf +.byte 0x49,0xdd,0xd7,0xda,0x2c,0xaf,0xc4,0x68,0xad,0x07,0x9c,0xd4,0xaf,0x94,0x64,0xcf,0xe1,0x9b,0x37,0x50,0x65,0x03,0x20,0x3c,0x34,0x43,0xe9,0xb0,0x9b,0xba,0xb1,0x9a,0x3e,0x10,0x99,0x8f,0x93,0xb7,0x3d,0xac,0xbd,0xab,0xa8,0xfa,0x74,0x90,0xe1,0x38,0xe4,0xf3,0x47,0xfc,0xad,0x8b,0xb4,0x98,0xe4,0x65,0xe9,0xd9,0x8a,0x21,0x81,0x4f +.byte 0x0c,0xd7,0xb1,0x84,0xb9,0x69,0x68,0x64,0xa3,0x1f,0x25,0x84,0x5f,0xf7,0x3f,0xca,0x52,0xff,0xda,0xc9,0x3d,0x5e,0x8b,0x57,0xd3,0x9a,0x1d,0xb7,0xae,0x90,0xa4,0xc3,0x78,0x68,0xfd,0x80,0x3f,0xfd,0x5c,0x09,0x83,0x5d,0xc2,0x48,0xd8,0x84,0xeb,0x8a,0xfe,0xbe,0x30,0x12,0x79,0x54,0x5f,0x7f,0x6e,0x4b,0x8a,0x1e,0xcb,0xcd,0xed,0xb6 +.byte 0xe9,0x6d,0x8a,0x1f,0xdc,0xb1,0x46,0xab,0xdc,0x0d,0xbf,0xda,0xd9,0x39,0x3b,0xd2,0x81,0x00,0x83,0x77,0x32,0xf7,0xdf,0x0e,0x31,0x5d,0x1d,0x6c,0xa7,0x4e,0x54,0xa8,0xac,0x81,0x8c,0xb6,0xa5,0x89,0x02,0xd7,0x2e,0xfd,0x26,0xa3,0x9e,0xcf,0xdb,0x1f,0x5a,0xf3,0x54,0xac,0xe5,0xd0,0x1f,0x9b,0xa7,0xab,0x28,0xcc,0x66,0xd3,0xbc,0x4c +.byte 0x54,0x1a,0x54,0x73,0x78,0xde,0x08,0xd5,0xa5,0x08,0xdc,0x00,0x09,0xc5,0x37,0x61,0x1a,0x98,0x12,0x84,0x2d,0xff,0xc3,0x25,0x62,0x93,0x83,0x05,0x66,0x3d,0xfb,0x1d,0x54,0x08,0x8a,0x50,0x03,0xc4,0xc4,0x6e,0xfa,0x16,0x83,0xbb,0x27,0xf1,0xb7,0x31,0x92,0x64,0x76,0xbc,0xf0,0x44,0x62,0xe9,0x5e,0x15,0x94,0xdc,0xe9,0xf3,0xf8,0x20 +.byte 0x93,0x4d,0x11,0xa2,0xc8,0xde,0x83,0xe6,0x75,0x63,0xfe,0x13,0x75,0x0f,0x79,0xd1,0x3d,0x75,0xb7,0x43,0x62,0x57,0x8d,0x96,0x9c,0xa3,0xc4,0xb2,0x84,0x6a,0x14,0x6e,0x17,0x32,0x09,0x76,0x95,0xbb,0xd6,0xc1,0x2e,0xdc,0x8c,0x73,0xd7,0xad,0x5a,0x41,0x8b,0xb3,0x7e,0x8d,0x90,0xec,0xf5,0xa0,0x46,0x90,0x4c,0x52,0xec,0x97,0xc6,0x98 +.byte 0x7d,0x19,0x77,0xa0,0x99,0x85,0x11,0x26,0x77,0x26,0xf9,0xac,0xe3,0x81,0xcf,0x7d,0x22,0xc8,0x00,0x3d,0x5b,0xee,0xa5,0xf8,0x6d,0xfe,0x47,0xe4,0xef,0x60,0xcc,0xd0,0x33,0xf7,0x5b,0xed,0xbd,0x82,0xc9,0xa8,0x41,0xb8,0x47,0x34,0x9f,0x62,0xb2,0x67,0x62,0xb0,0x3a,0x27,0x95,0xe1,0x22,0x76,0x98,0x0f,0x35,0xaf,0xfc,0x4d,0xc7,0x92 +.byte 0x92,0x7e,0xaf,0x3b,0x3a,0x36,0x5e,0x5c,0xbf,0x43,0x02,0x66,0x5a,0x30,0x78,0x82,0x52,0x20,0x98,0xd6,0xa1,0xe9,0x9a,0x61,0x54,0x0b,0x74,0x85,0xb5,0x99,0x69,0x9f,0x9b,0x3b,0x2f,0x49,0xec,0xb3,0x18,0x0c,0x4a,0x53,0x20,0xd7,0x80,0x7b,0xd4,0x20,0x21,0x32,0x89,0x08,0x81,0x50,0x2b,0x16,0x8d,0xbb,0xe6,0xbb,0xc7,0x74,0x80,0x67 +.byte 0x47,0xf1,0x06,0x68,0x02,0x37,0x31,0x00,0x50,0x8b,0xe2,0x44,0x85,0x2e,0x39,0x54,0xda,0x26,0x7b,0xe1,0xb0,0x23,0xd7,0x0c,0x3c,0x3b,0x81,0x9b,0xa6,0xbe,0x24,0xfd,0x09,0x73,0xbe,0xc3,0x2f,0xa0,0x7b,0x85,0x5b,0x1b,0x55,0x4e,0x9e,0x38,0x80,0x61,0xd7,0xe8,0x9b,0xec,0x88,0x00,0x6a,0x64,0x1b,0xd5,0x65,0x20,0x2a,0x62,0x64,0xbc +.byte 0x21,0xca,0xce,0xc3,0xeb,0x2d,0x2b,0x5c,0x4d,0xb8,0x7c,0xb5,0xbe,0x98,0x0d,0x5b,0x88,0x23,0x60,0xff,0xbe,0x0a,0xb6,0xdd,0xdf,0x28,0xd5,0x2c,0xe5,0x9d,0xb5,0x29,0xea,0x6c,0x3a,0xf4,0x78,0x91,0xa3,0xb2,0xab,0x12,0xf9,0x90,0x96,0xc9,0xa4,0xfc,0x4d,0x28,0x2b,0x0c,0x28,0x8b,0xb7,0x8b,0x36,0xd6,0x80,0xbf,0x07,0x09,0xf9,0x62 +.byte 0x32,0xc0,0x50,0x60,0xd9,0x73,0xe3,0xbe,0xfa,0xa6,0x78,0x48,0x47,0xd7,0xb5,0x39,0xd8,0x04,0x6d,0x79,0x98,0x2e,0xd6,0x3a,0xe5,0xc9,0x01,0xd0,0x00,0x2e,0xd2,0x8b,0xd7,0x1f,0xf1,0xba,0xd4,0x0e,0x9f,0x9d,0xab,0xbf,0x2c,0xe1,0x75,0xf6,0x9c,0xc0,0xae,0x73,0x2b,0x58,0xcb,0x6d,0x46,0x6d,0x11,0xb7,0xce,0xc7,0xef,0x34,0x2c,0x11 +.byte 0x93,0x3c,0x17,0xd9,0x3e,0xad,0xc9,0x4c,0xb3,0xd0,0x0a,0xd0,0xfe,0xf3,0x9d,0xc5,0x43,0x03,0xa9,0x78,0x4a,0x42,0x7f,0xfb,0x75,0xd2,0x85,0xfb,0xe7,0xe6,0xa9,0x48,0x2f,0xa6,0xc3,0x16,0xe2,0x2a,0x9d,0x0d,0xcb,0x2e,0x8b,0x75,0xa8,0x14,0x3a,0x2e,0xb1,0xff,0x58,0x1d,0xa8,0xa6,0xc0,0xf6,0x17,0xda,0xc1,0xce,0xaf,0x08,0xa9,0xc2 +.byte 0xa3,0xc1,0xab,0xb6,0xe8,0x10,0x57,0x8a,0xce,0xc0,0x03,0x5c,0x53,0x5c,0x02,0x5d,0xcf,0x5c,0x65,0xc6,0x47,0x3c,0x62,0x0e,0xa3,0xfc,0xe2,0xae,0x10,0x55,0x4a,0xb4,0x27,0xe8,0x59,0x5e,0x45,0xa9,0xbb,0x21,0x10,0x91,0x46,0x1f,0x50,0x3b,0xc6,0x8c,0xa1,0x8a,0xee,0x5e,0x6e,0x32,0xe6,0x42,0x40,0x79,0x7f,0xbb,0xb3,0x5b,0x05,0xde +.byte 0xe0,0xf6,0x7f,0x3d,0x37,0xe6,0xc3,0x3b,0x40,0xc9,0xe0,0x42,0x36,0xd0,0x0e,0x13,0x32,0x3e,0x48,0xce,0xd8,0xa2,0xef,0xae,0x93,0x66,0x7d,0xde,0xb9,0xdd,0x60,0x15,0x53,0xf2,0xd9,0x90,0x3d,0x38,0x8c,0xa6,0x34,0x44,0xb5,0x6c,0x74,0x7d,0x9d,0xe7,0xd0,0xef,0x6c,0xd6,0xfe,0x9b,0x79,0x4e,0x79,0x5e,0x48,0xef,0x93,0xb2,0x81,0x0b +.byte 0x2b,0xee,0x83,0x69,0x3d,0x15,0x8c,0x27,0x69,0x6f,0xca,0xbf,0x75,0x29,0x37,0xc6,0xe6,0xca,0xb2,0x70,0xd0,0xaf,0xc8,0x5e,0x69,0xf1,0x6b,0x2d,0x0d,0xe7,0xe9,0xbf,0x07,0x52,0xe5,0xac,0x98,0xcf,0xcf,0xd6,0xdd,0x7c,0x2b,0xfc,0x8f,0xd2,0x5f,0x81,0x4b,0x1b,0x7b,0x2d,0x84,0xe2,0x69,0x96,0xcb,0xa2,0x59,0x10,0xba,0xda,0x51,0x11 +.byte 0xeb,0xc3,0x4f,0x10,0xbf,0x8e,0x5b,0xbb,0xa3,0x29,0xe9,0xd8,0x0e,0x71,0xa0,0x1b,0xff,0xee,0x36,0x8c,0x00,0x83,0x6b,0x32,0xfe,0x05,0xeb,0x89,0x8f,0xed,0x48,0x22,0xe1,0x76,0x0a,0xac,0xae,0x3c,0x24,0x54,0x84,0xc2,0x0f,0x79,0x33,0x2b,0x49,0x35,0x1c,0x84,0x5a,0xca,0x92,0x6c,0x1f,0x78,0x15,0x5a,0x36,0xad,0xd5,0x1d,0x9d,0x10 +.byte 0xc1,0x5f,0x7c,0x61,0x60,0xba,0x2e,0xe6,0x9b,0x34,0x02,0xe9,0x68,0x1c,0xfb,0xbf,0x02,0xdc,0x79,0x57,0x1c,0x0f,0xc8,0x8c,0x2a,0x66,0x2a,0x50,0xaa,0x81,0x4e,0x1f,0xa8,0x2d,0xe4,0x61,0xe8,0x43,0x84,0xcb,0xda,0x96,0xf9,0x4a,0xd0,0x8f,0xe1,0xd7,0xc4,0x05,0xf5,0x76,0xfa,0x47,0x7a,0x07,0x1a,0x77,0xbb,0x63,0xb3,0x3a,0x85,0x3b +.byte 0x0d,0x32,0x4f,0x14,0x15,0x02,0x5b,0x9c,0xbc,0xc2,0x12,0x90,0x0f,0x7b,0x94,0x27,0x5f,0x70,0x23,0xd8,0x5d,0x54,0xc4,0xca,0x6a,0x69,0x9e,0xd1,0xb3,0x2a,0x75,0x1a,0x07,0x9c,0x20,0xf6,0x76,0x22,0x4d,0x09,0x30,0x24,0x3f,0x3b,0xe5,0xcb,0x4b,0x5a,0x03,0x2d,0xe8,0xbe,0xed,0xf0,0xe3,0x91,0xf2,0x6c,0xb8,0x02,0x2d,0x6c,0x7a,0xa6 +.byte 0xc1,0x8e,0xa7,0xbb,0x73,0xdf,0x40,0xa5,0x60,0x91,0xbf,0xbe,0x28,0x0b,0x37,0x2e,0x5f,0x4b,0xcd,0x14,0x4d,0x2d,0xfc,0x5e,0x43,0xb5,0x78,0x8d,0xea,0xa0,0x86,0x54,0x4f,0xb6,0x25,0x40,0x39,0x3f,0x9c,0x7a,0x26,0x74,0x88,0x42,0x53,0xb0,0x3b,0x81,0x75,0x04,0x67,0x41,0x65,0x66,0x2c,0xdc,0xe9,0xf0,0xb3,0xab,0x2a,0xa5,0xf3,0xef +.byte 0xfa,0xc5,0x10,0x63,0xe2,0x70,0xb5,0x29,0x60,0x86,0x9e,0xb9,0x0b,0xe2,0xc4,0x05,0xa9,0x3c,0x1b,0x60,0x15,0x6b,0x2f,0x74,0x93,0x5e,0x70,0x9a,0x56,0x6a,0xc4,0x92,0x49,0xaa,0x95,0x51,0xc4,0xba,0xfd,0xf6,0x2d,0x36,0x3e,0x66,0xbd,0x74,0xbc,0x2e,0xb3,0xad,0xa1,0x41,0x50,0x33,0x79,0x84,0xac,0x21,0x7a,0xfc,0x3a,0x8e,0xdb,0xcc +.byte 0x27,0xf6,0x2c,0x5c,0x23,0x38,0x73,0xd5,0xaf,0xc9,0x2d,0x9c,0x18,0x58,0xdf,0x8f,0x89,0x9d,0xdd,0x00,0x3c,0x5f,0x23,0x00,0x6e,0x66,0x1d,0xf3,0x1c,0x40,0x9d,0x43,0xb0,0x74,0xf1,0x41,0xa5,0x77,0xcb,0x8d,0x5b,0x94,0x68,0x95,0xb6,0x0e,0xd4,0x4d,0x47,0x9b,0xd2,0xcd,0x9b,0x94,0xa4,0x28,0xf9,0xf0,0x3d,0xcf,0x89,0xb1,0xc3,0x73 +.byte 0x84,0x15,0xb6,0xc8,0x6b,0xf1,0xb1,0xdc,0x1b,0x1a,0x6f,0xb5,0x73,0x87,0x8b,0x63,0xbf,0x4b,0x25,0x9b,0xe4,0xdd,0x44,0xed,0xe7,0x0e,0x6f,0x03,0xae,0xa1,0x5e,0x1f,0x5f,0xa7,0xa4,0xed,0x69,0x7a,0x91,0x6d,0x55,0xac,0xce,0x18,0x32,0x17,0x78,0x49,0x9f,0x1e,0x9c,0xd2,0x7b,0x1f,0x74,0x60,0xa5,0x64,0xb1,0x99,0xe6,0xc5,0x0d,0x69 +.byte 0xfa,0xb2,0xd9,0x05,0x61,0x71,0xa4,0x6f,0xc2,0xb6,0x91,0x0e,0x6c,0xf2,0xa6,0x6c,0xea,0x8e,0x94,0x8b,0xac,0xa7,0xfe,0x70,0x8e,0x8d,0xc2,0x85,0xa6,0xa7,0x8e,0xe8,0xfa,0xbc,0xa1,0xaf,0x0e,0xa9,0x06,0xa4,0x9a,0xb0,0x23,0x93,0xbc,0x93,0x2d,0x97,0x42,0xe2,0x0d,0x3a,0x65,0xb4,0x60,0x5b,0xeb,0xa1,0x20,0x8a,0xdc,0x17,0x6b,0xc5 +.byte 0x19,0xc3,0x67,0xbf,0xae,0xf7,0xb9,0xb1,0x88,0x7f,0xe5,0x1b,0xc2,0x61,0x97,0xa0,0xd3,0x64,0x74,0x6b,0x7a,0x46,0x39,0x3f,0xc8,0xd3,0x53,0x79,0x74,0x4e,0x1e,0x63,0x91,0xc5,0x4a,0x70,0xb0,0x05,0x35,0x19,0xc2,0x26,0x54,0x44,0x3b,0xa9,0x12,0x40,0xd0,0x21,0x19,0xf3,0x8d,0xc7,0x2b,0x88,0x9a,0xec,0x41,0x8f,0x4f,0x23,0x19,0x1a +.byte 0xf3,0x1d,0x0a,0x88,0x0f,0xa7,0x02,0xd4,0x78,0x88,0xe6,0x43,0xb6,0x9e,0x07,0xdf,0x6a,0x1f,0x41,0xbb,0x3e,0xea,0x15,0xff,0x66,0x4c,0x7a,0x8b,0xee,0x27,0x47,0x81,0x81,0x95,0xa2,0x22,0xb4,0x9f,0x1c,0x09,0x1c,0xfc,0x0a,0xef,0x88,0x7f,0x59,0x60,0x91,0x6a,0xe4,0x92,0x8c,0x02,0x54,0xc9,0xee,0xc7,0x5e,0xd1,0xbf,0xc9,0x41,0xde +.byte 0x2f,0xa3,0x22,0x07,0x1d,0x8c,0xe1,0x04,0x59,0x94,0x75,0x3e,0xee,0x56,0x62,0x07,0x80,0x18,0x60,0x78,0x0e,0x55,0x06,0xec,0xe1,0xa5,0xf6,0x21,0x7e,0xf9,0x37,0xab,0x6a,0xed,0x07,0xcb,0xbf,0xa2,0xab,0x50,0xee,0x1f,0x2f,0x54,0x2b,0x82,0x93,0x59,0x03,0x35,0xd9,0xe8,0x2b,0xa6,0x03,0xc2,0xef,0x37,0x85,0xfc,0x89,0x06,0x30,0xe0 +.byte 0xc2,0x00,0xc4,0xaf,0x59,0xb6,0x31,0x52,0x37,0xa4,0x6c,0xdb,0x1b,0x20,0x87,0xf0,0xa4,0x15,0x4b,0xa8,0xd9,0x7e,0x1b,0x96,0x00,0x07,0xf4,0x86,0x07,0x14,0x55,0x70,0x37,0xe3,0xe3,0xf0,0xeb,0xd6,0xf1,0xe0,0xe9,0x6c,0xdf,0x3d,0xaf,0x86,0xb8,0x00,0x9b,0xdf,0xc6,0x5c,0xd2,0x53,0xcb,0xcf,0x63,0xcc,0x3e,0x6d,0x62,0xeb,0xe6,0x97 +.byte 0xd8,0x54,0xed,0x36,0xe4,0xed,0x69,0xaa,0x10,0x83,0xde,0x16,0xfd,0xcc,0xd6,0x24,0xb9,0x3c,0x4f,0x99,0x81,0xc2,0x23,0x16,0x91,0x5d,0x9f,0x46,0xa5,0xdd,0xb4,0x8a,0xe1,0x07,0x89,0x84,0x2e,0x62,0x48,0xf6,0x1a,0x17,0x7b,0xc8,0xf7,0xb4,0x3d,0x9e,0x82,0xe3,0xe3,0xcf,0x0b,0xd9,0x52,0x90,0x61,0xd8,0xdf,0x9e,0xc4,0xc7,0x7c,0xfa +.byte 0xcf,0x09,0xd2,0x94,0x86,0x37,0x94,0xaf,0x7e,0x0a,0x9d,0x16,0xee,0xad,0xfb,0xa2,0x9e,0x2d,0x2f,0xad,0xd5,0xc2,0xf9,0x91,0xf8,0x7e,0x2b,0xb8,0xb2,0x60,0x3c,0x0a,0x89,0x53,0x07,0x87,0x3b,0x83,0x70,0xee,0x71,0xa3,0x94,0x0b,0x77,0x50,0xeb,0xcc,0x23,0xf0,0xbe,0x95,0x51,0x54,0xd2,0xd6,0xd2,0x09,0xa5,0x19,0x3d,0x4e,0xec,0xe3 +.byte 0x88,0x71,0xa7,0xb1,0x10,0x03,0x7e,0xc4,0x92,0x2a,0xe7,0x99,0x75,0xff,0xae,0x10,0x3d,0xbb,0x33,0xc9,0x7f,0xc2,0xe6,0x3c,0xc4,0xe7,0xba,0x37,0xba,0x68,0x69,0x92,0x4a,0xfb,0x32,0x3b,0xb5,0xde,0xdb,0x91,0xd0,0x8e,0x77,0xf2,0x1e,0x2d,0x25,0xb4,0xa0,0x42,0xef,0x78,0x6c,0x75,0xcb,0xa0,0x73,0xdf,0xde,0xd8,0x26,0xfe,0xe3,0xf9 +.byte 0x74,0xe7,0xa0,0xd2,0xbd,0x6c,0x99,0x8d,0x07,0xf2,0xf8,0xff,0x36,0x2d,0x8e,0xda,0x5e,0x5c,0x47,0x06,0xf8,0x08,0x33,0x1d,0x93,0xcf,0xc3,0x1a,0x20,0x86,0xb6,0x8e,0x44,0x10,0xbc,0xba,0x89,0xfc,0xa3,0x57,0x92,0x2c,0x28,0xa1,0xd0,0xab,0xdc,0xba,0x0a,0x7e,0x9d,0xd2,0xfd,0x09,0xd3,0x87,0x6c,0x06,0x44,0x17,0x73,0xfe,0xc9,0x8b +.byte 0x52,0xd3,0x09,0x60,0x14,0x03,0xb1,0x79,0x4c,0x9c,0xc4,0xec,0x42,0x4c,0xd3,0x21,0xe5,0x34,0x21,0x38,0xdd,0x12,0x95,0xd4,0x20,0x50,0xef,0x5f,0x46,0x4f,0x37,0x65,0xd5,0xf1,0xb2,0x2c,0x6c,0x9a,0x06,0x28,0x77,0xbf,0xe3,0xec,0xec,0x2b,0xcb,0x2c,0x8b,0x62,0x2e,0x39,0xaa,0x28,0x0b,0x51,0x01,0xa5,0x02,0x06,0x66,0x4a,0x67,0x0c +.byte 0x96,0xa3,0x12,0x74,0x94,0x2c,0x0f,0x23,0xa3,0xea,0xda,0x1a,0x6d,0x54,0x30,0x33,0xc8,0x33,0x0a,0xfb,0x25,0x2a,0x8b,0x9a,0x87,0xd9,0x9d,0x37,0x4c,0x41,0x3b,0xe5,0x4a,0x81,0x92,0x40,0x38,0x18,0x82,0x13,0x54,0xde,0x56,0x11,0x63,0xf3,0x09,0x61,0x3b,0xdd,0x0c,0x71,0xe8,0x4f,0xc2,0x9a,0x77,0x2f,0xeb,0xf1,0x39,0x1c,0x10,0x0e +.byte 0x01,0xaf,0x92,0x34,0x9a,0xb6,0x7b,0x79,0x86,0x0c,0xf1,0x53,0xb6,0x59,0xbd,0x6d,0x79,0x6e,0x37,0x11,0x25,0x67,0x95,0x31,0x4f,0x43,0xdf,0xb7,0x4b,0x80,0x8d,0x07,0x3c,0x49,0x73,0x8a,0x72,0x61,0x02,0x0f,0x2f,0x13,0xed,0x91,0x10,0xf6,0x08,0xf3,0x50,0x4a,0xd4,0x36,0xcb,0x52,0xb3,0x3b,0xe6,0xef,0x85,0xe9,0xe0,0xad,0x0d,0x3d +.byte 0x84,0x07,0x70,0xdf,0x16,0x47,0xeb,0x26,0x19,0x27,0xaf,0x7a,0x9f,0x2f,0x2b,0x6d,0xbb,0x37,0x68,0x8e,0x19,0x46,0x5a,0x65,0x0d,0x0a,0x67,0xd8,0xe2,0xc2,0xcd,0x49,0xf6,0xc2,0x27,0xac,0x12,0xea,0x1f,0x81,0x60,0xac,0x8b,0x5d,0xcc,0x9a,0x5b,0xec,0xc3,0xcb,0x85,0x0d,0xef,0xa6,0xd5,0x33,0xb3,0x67,0x73,0x3f,0xc9,0x90,0x25,0x3e +.byte 0xe6,0x7c,0x41,0x59,0x83,0xf7,0x90,0x4a,0xbf,0x14,0x72,0x11,0xf2,0x3a,0x38,0x58,0x17,0xd8,0x3d,0x00,0xc6,0x42,0xf2,0xbc,0xfd,0x05,0x37,0x6d,0x11,0xb0,0xd7,0xb2,0xb7,0x73,0x69,0x80,0x47,0x30,0x64,0x13,0x8c,0x24,0xb2,0x42,0x12,0x8c,0xc0,0x8a,0x45,0x0b,0x71,0x23,0xeb,0xac,0x65,0xda,0x44,0x13,0x85,0x77,0xdf,0xb8,0x4b,0x69 +.byte 0xd4,0x8e,0x40,0x54,0x24,0xac,0xc8,0x62,0x36,0x51,0x20,0xaa,0xcd,0x5d,0xa5,0x73,0x2c,0x81,0x92,0x99,0x44,0x6b,0x04,0xac,0x8e,0xee,0x96,0x29,0xca,0xdc,0x2f,0xd1,0x13,0x5c,0x9e,0xc2,0x67,0x6a,0xaf,0xf6,0x3e,0xe2,0xa1,0x6d,0xda,0xbe,0x8a,0x55,0x50,0x27,0xee,0x6d,0xb8,0x35,0x5f,0xb4,0xa8,0x76,0xa1,0xe2,0x52,0x87,0xf6,0xfb +.byte 0xe2,0x16,0x1c,0x90,0x78,0xe4,0x17,0xb0,0xd9,0x56,0xf5,0xd3,0xa4,0xb0,0x3f,0xe9,0x01,0xf9,0xd0,0x67,0x2b,0xeb,0x1d,0x73,0x24,0x90,0x36,0x36,0x0d,0xcf,0xfb,0x3f,0xa1,0xa0,0x25,0x3b,0xf1,0x7f,0x9e,0x90,0xcf,0xb6,0xd0,0x83,0x90,0xcd,0x3f,0xff,0x5f,0xa3,0x33,0x95,0xd7,0xbe,0x78,0xfe,0xcc,0x9a,0xb9,0x64,0x88,0xb7,0xd9,0x5e +.byte 0x46,0x2d,0xf0,0xb1,0xa1,0x81,0x2b,0xab,0x80,0xf5,0x4d,0x3b,0xd8,0x53,0x64,0x8f,0xac,0x7a,0x03,0xb3,0x39,0x7a,0x85,0xef,0x61,0xb5,0x2c,0x8e,0xf4,0x27,0x07,0x9b,0x7b,0xc9,0x8b,0x1a,0xe4,0x4f,0xce,0x8b,0x35,0x32,0xac,0xcf,0x47,0xb8,0x2f,0x9e,0xe5,0x11,0x48,0xc1,0x07,0xea,0x0c,0xee,0x06,0xc6,0xa3,0x48,0xb6,0x1a,0xd8,0xb4 +.byte 0xa7,0xae,0x59,0x7d,0x9e,0x4e,0x66,0x7f,0xe9,0x02,0x40,0xdc,0x21,0x5e,0x74,0x2c,0x1d,0x29,0x22,0xca,0x97,0x4f,0xc8,0xc7,0xea,0x69,0x02,0x89,0xd1,0x43,0xff,0x83,0x89,0x58,0x66,0x92,0xbc,0x11,0xf6,0x02,0x8b,0xa8,0x34,0x8d,0xbe,0x3a,0x70,0xc3,0x10,0xe7,0xb5,0xc4,0xda,0xdb,0xc6,0x87,0xee,0xee,0xe0,0x48,0x62,0x80,0x8d,0xfc +.byte 0xaa,0xc7,0xce,0x1a,0xea,0xb9,0x1b,0x30,0x4a,0x48,0x9b,0xf4,0x58,0xff,0x5d,0x15,0xc8,0xf2,0x84,0x44,0xae,0x63,0xe8,0xb1,0xe0,0x2e,0x38,0x8e,0x47,0xf9,0x09,0xec,0xb9,0x94,0x18,0x37,0x68,0xef,0xbd,0xd5,0x67,0x72,0x01,0x9a,0x15,0xb9,0x7c,0x36,0xc0,0x22,0x80,0x12,0xb1,0x4e,0xab,0x3c,0xea,0x81,0xcf,0x70,0xf3,0xde,0x1f,0xd4 +.byte 0x67,0x94,0xfa,0xe1,0xf0,0xb6,0xd6,0x6b,0xc3,0xa2,0xbb,0x59,0x6b,0x9f,0x58,0x26,0x99,0x0c,0xdc,0xcd,0xb8,0xae,0x49,0xf0,0x8f,0xd3,0x0d,0xb7,0x4c,0x22,0xcf,0xb6,0x6c,0xa3,0x19,0x09,0x42,0x59,0x25,0xf8,0xdc,0xf3,0xc2,0x00,0xc3,0xc3,0xd3,0x9e,0x98,0xd3,0xa3,0xd0,0x96,0xfd,0x4f,0x15,0x57,0x5b,0xa7,0x08,0x3a,0x0e,0x3d,0xd2 +.byte 0x7d,0xa1,0xa0,0x94,0xc0,0x76,0x83,0xf6,0xc1,0xe8,0x7e,0xd3,0x97,0xc1,0xbf,0x38,0x74,0x9b,0xfb,0x35,0xeb,0xf7,0x34,0x20,0xea,0xda,0xd3,0xb1,0x2e,0x10,0x16,0x9c,0x09,0x1c,0x67,0x46,0xa2,0x05,0xf9,0x47,0xde,0x35,0x53,0x18,0x58,0xb0,0xbb,0x7a,0x88,0x58,0xc5,0x3e,0x98,0x29,0x43,0x98,0x07,0x76,0xa3,0xe1,0x95,0x92,0x21,0xe9 +.byte 0x06,0x17,0x15,0xe0,0x6b,0xd5,0x5a,0x6d,0x10,0xa6,0x08,0x92,0xa9,0xf5,0xcf,0x57,0x1a,0x28,0x5d,0x14,0x33,0x99,0xf9,0xa0,0xb3,0xeb,0xee,0xd4,0x6e,0x0b,0x5e,0xf7,0xe9,0xe3,0xc6,0x71,0x34,0x55,0xf3,0xde,0xd5,0xc2,0x52,0xc3,0x7b,0x06,0x87,0xef,0x26,0x81,0xc9,0xbd,0xaf,0x12,0x61,0x95,0x2b,0xa4,0x8e,0xe8,0x08,0x9a,0x13,0x48 +.byte 0x2e,0x84,0x98,0xf6,0x95,0x21,0x22,0xe5,0xcf,0x30,0x8d,0xaf,0x70,0x16,0x27,0x0c,0xcd,0x26,0x7f,0xe8,0xa0,0x35,0x0c,0x01,0x0e,0xdd,0x9d,0x2c,0x89,0x41,0x34,0xc4,0xa2,0xaa,0xf6,0x3f,0xca,0x3b,0x86,0xce,0xd7,0x4c,0xe3,0xb5,0x69,0xe9,0x41,0xbe,0x3c,0x9a,0x4c,0x1a,0xb3,0x88,0xea,0x78,0x12,0x4c,0x1b,0x79,0xc7,0xcd,0x32,0x72 +.byte 0xfa,0x3f,0x0b,0x73,0x1b,0xd9,0xec,0x85,0xd4,0x52,0x6c,0x91,0x2d,0xbe,0x76,0x8b,0xfd,0xb6,0x49,0xcf,0x67,0xd1,0x18,0x7b,0xae,0x86,0x47,0x47,0xfd,0xff,0x63,0xf2,0x88,0x1b,0x58,0xd5,0x30,0x69,0xf9,0x9a,0x03,0x52,0xae,0xe5,0xe2,0x55,0xbf,0x35,0x12,0xb0,0x84,0xa9,0xed,0xb6,0x8d,0x5f,0x6c,0xed,0x1a,0x00,0x7a,0xdc,0xf2,0x03 +.byte 0x9e,0xef,0x59,0x27,0x4c,0xf4,0x83,0xa2,0x36,0x3d,0x3d,0x8c,0x75,0x8c,0x37,0x68,0x93,0x0b,0x30,0x48,0xea,0x91,0x14,0x37,0x88,0x87,0x7f,0xe6,0xd8,0xbd,0x04,0x34,0x1e,0xe8,0x2a,0x41,0x48,0x5c,0x66,0xf9,0xc2,0xd1,0x56,0x25,0x29,0x45,0xfa,0x71,0xe1,0x59,0xa8,0x52,0x99,0x0b,0x92,0xe0,0x33,0x52,0x91,0xd6,0x5f,0x0a,0x70,0x83 +.byte 0x4f,0xa3,0x47,0x6e,0xfa,0x85,0x5e,0xb1,0x0a,0x1d,0xe7,0x35,0xc9,0x88,0x27,0xc9,0x8c,0x3e,0x7f,0x6d,0x34,0x1e,0x11,0x7b,0xcd,0xe7,0x09,0x82,0x3a,0xa1,0x46,0xc6,0x15,0xde,0x0b,0xde,0x35,0x71,0x92,0x5c,0x72,0x50,0x08,0x6b,0x62,0xa7,0xec,0xa2,0xca,0x53,0x6e,0x47,0x7d,0x50,0x32,0xa7,0x32,0x7b,0x49,0x0c,0x97,0xcc,0x98,0x8d +.byte 0xc3,0x29,0x72,0x1e,0x85,0x47,0x1b,0xa7,0x89,0x19,0x85,0xaa,0x3f,0x11,0x6a,0xea,0x61,0x84,0x07,0x9a,0xc8,0xb3,0x25,0xfe,0x72,0xca,0x83,0xa9,0xf0,0x9e,0x01,0xe4,0x9a,0xd6,0x1b,0x87,0xfc,0xd4,0x3a,0x04,0x34,0x8c,0x0b,0x46,0xbc,0xe9,0x3c,0x3f,0xd9,0x93,0xf1,0xca,0x41,0x0b,0xdb,0x28,0xe8,0x28,0x1b,0x84,0x36,0x16,0x84,0x22 +.byte 0x1e,0x1e,0x2b,0xb0,0xfb,0xa6,0xcc,0x95,0x31,0x46,0xd7,0xca,0xc2,0x8b,0xa3,0x3a,0xa5,0xb0,0xaf,0x52,0x66,0x53,0x39,0x5f,0x58,0xb5,0xdf,0x01,0x52,0x07,0xb4,0x82,0xdc,0xb7,0xf9,0x88,0xd8,0x77,0xf8,0x12,0x9d,0xe8,0x21,0xd7,0x0b,0x0f,0x57,0x90,0x40,0xb2,0x64,0x3f,0xce,0xa0,0xa3,0xfa,0x12,0x16,0xec,0x6d,0xcc,0xc7,0x2a,0x43 +.byte 0xc9,0xe7,0xb7,0x90,0x52,0x35,0x22,0x6d,0x46,0x99,0x1e,0x44,0x12,0xd6,0x0f,0xaf,0x5c,0x16,0xd3,0x7a,0xd6,0xb4,0xfe,0x20,0x26,0x11,0xe1,0xc6,0xa5,0x10,0xfd,0x9f,0x0c,0x47,0xae,0x32,0x08,0x15,0x8f,0xef,0xef,0x4c,0x83,0xbc,0xbf,0x6a,0xe5,0xf5,0x69,0x11,0x4d,0x7d,0x47,0x1f,0x10,0x58,0x61,0xb0,0x0d,0x98,0x67,0xc0,0x99,0x3a +.byte 0x2d,0x9a,0x5b,0xd5,0x37,0xe7,0xe5,0xd4,0x56,0x96,0x69,0xf8,0x53,0x7e,0x24,0x70,0x51,0x01,0x83,0x8d,0x49,0x01,0x32,0x7d,0x4f,0x41,0x92,0x54,0x9c,0x15,0xf1,0x3c,0x05,0x32,0x28,0x0d,0x0f,0x67,0xbe,0x65,0xfa,0x1b,0xa3,0xd0,0x28,0x18,0xb8,0x84,0xfe,0x6a,0x30,0xea,0xb9,0x00,0xb1,0x10,0x7c,0xa2,0x94,0x4f,0x86,0x18,0xdd,0xb4 +.byte 0x80,0x18,0x48,0x18,0xe1,0x56,0x70,0x7d,0x5c,0x3b,0xe5,0xd7,0x88,0x66,0x57,0xe3,0xe1,0x04,0x4c,0x68,0x5b,0x64,0x4d,0x0d,0x30,0x76,0x26,0xaa,0x84,0x0e,0xe0,0xed,0x53,0x62,0x20,0x33,0xaf,0x45,0x42,0x40,0x47,0x01,0x15,0xc9,0x0b,0x27,0x7c,0x68,0x4d,0x55,0xc4,0x6a,0x5f,0x96,0x9f,0x96,0x67,0xae,0x13,0x1c,0x84,0x52,0x33,0x41 +.byte 0x80,0xfc,0xae,0xb6,0xb1,0x8c,0xc3,0x19,0x80,0xa8,0x5f,0xe5,0x8c,0xd0,0xa8,0xb4,0x58,0xc9,0x48,0x29,0xab,0x11,0xd1,0x09,0xc6,0x20,0x98,0x4c,0xdb,0xa4,0x83,0x5c,0x26,0x51,0xce,0x80,0xe5,0xc4,0x9b,0xae,0xba,0x8e,0x99,0x4e,0xa4,0xff,0xdc,0x99,0x4c,0x02,0xa0,0x42,0x80,0xca,0xd7,0xea,0x6a,0x58,0x31,0xdb,0x16,0xd8,0x4d,0xab +.byte 0x03,0x2e,0x3a,0xdc,0xe9,0x07,0xfb,0xfb,0x5b,0x57,0x67,0x2a,0x7b,0xdc,0xc1,0x66,0xd1,0x31,0x3a,0x03,0x87,0xd8,0x66,0xda,0xa1,0x24,0x00,0x26,0xc0,0x26,0x78,0xf8,0x59,0x13,0x3f,0x34,0x08,0x35,0x45,0xbd,0x45,0x4f,0x89,0x65,0x97,0xdb,0xe6,0x1e,0x09,0x6e,0x23,0x2a,0xc4,0xf5,0x6a,0x74,0x28,0xb0,0xae,0x8c,0xfb,0x49,0x35,0x99 +.byte 0x06,0x30,0xc6,0xb2,0x8c,0xcd,0x8b,0x41,0xea,0xf2,0x04,0x18,0x29,0x25,0x1b,0x32,0x42,0x45,0xb5,0x92,0x42,0xb4,0x33,0xd2,0x90,0x31,0x08,0xcd,0x35,0x5d,0x50,0x64,0xa8,0x93,0xfd,0xa5,0xfd,0x32,0xbd,0xe8,0x13,0x1c,0x48,0x5c,0x14,0x70,0x03,0x92,0x0f,0x12,0x86,0xf6,0x6c,0xcd,0xc6,0xec,0xbf,0x8e,0x85,0x28,0x1d,0x1c,0x63,0x3f +.byte 0x81,0x93,0xd4,0x80,0x3c,0x29,0x0b,0x63,0xfe,0x87,0xa6,0x24,0xd6,0x3e,0x62,0xb6,0xd9,0xb0,0x58,0xf1,0x41,0x36,0xc7,0x47,0x8b,0xfd,0x4b,0x91,0x4e,0x5d,0x41,0x44,0xb0,0x65,0x3d,0x9e,0x3b,0x70,0x01,0xcc,0x7d,0x77,0xf0,0x23,0xd9,0xca,0x5f,0xda,0xa1,0x8c,0x71,0x11,0x91,0x7d,0x36,0xf5,0xc9,0xcd,0xf4,0x34,0x5f,0x69,0x57,0xd6 +.byte 0x33,0x4c,0xb2,0xe1,0x38,0x5f,0x86,0x3c,0x57,0x7b,0x2e,0x99,0x05,0x80,0x63,0xc4,0x77,0x69,0x06,0xc2,0x47,0x44,0xca,0x17,0x27,0x1d,0x55,0x34,0x02,0xd0,0x89,0x3a,0x3b,0x79,0xf0,0x86,0xd7,0x6b,0x01,0x9c,0xc7,0xa8,0xde,0xdb,0xdf,0x49,0xd1,0xb9,0x11,0xaf,0x7e,0x22,0x8b,0x5d,0xb5,0x0b,0xdc,0xd0,0x36,0xe6,0x9d,0x85,0x41,0x4a +.byte 0x35,0xf0,0xe1,0xcd,0xce,0x7b,0xd1,0xd6,0x00,0xdd,0xb6,0xe4,0x06,0x3e,0x66,0xe9,0x2b,0xa8,0x44,0x0d,0x18,0xd4,0xbc,0xfb,0x3c,0x58,0x6c,0x11,0xe9,0xdc,0x19,0x14,0x08,0x27,0x23,0x0c,0xd0,0xf9,0x97,0xaf,0x97,0x07,0x02,0x1a,0x5e,0xcd,0xae,0xd2,0x80,0x96,0x16,0x49,0xc3,0xfc,0xda,0x25,0x12,0x20,0xe1,0xc0,0x68,0x90,0x4b,0x30 +.byte 0x2d,0x06,0x53,0x2c,0x57,0x63,0x4a,0x7a,0xf6,0xc8,0x5a,0xb7,0x58,0x8c,0x13,0xfe,0x43,0xb3,0xf8,0x25,0x3e,0x7a,0x25,0x3e,0x1d,0x7f,0x8f,0x5e,0xdb,0xad,0x99,0x83,0xfc,0xd9,0x0a,0xdf,0xb5,0x19,0x1c,0x2c,0xf6,0xe8,0x06,0xbe,0xc0,0x9f,0x7e,0x0f,0x95,0xaa,0xac,0x09,0xdc,0x8c,0x37,0xcf,0x35,0x35,0x95,0x62,0xf1,0xff,0x96,0x1c +.byte 0x77,0xe9,0x53,0x7e,0x12,0x56,0x2d,0x4e,0x3e,0x1f,0xdb,0x1d,0x71,0x0e,0xdc,0xf7,0x65,0xb1,0x78,0x7f,0xe4,0xba,0xbf,0x7f,0x6c,0xcb,0x73,0xd3,0xe8,0xd9,0xce,0xfb,0xdb,0x48,0x87,0xe0,0x10,0x00,0x74,0xcb,0xdf,0x32,0xa8,0xdd,0x83,0x24,0x49,0xda,0x86,0x38,0x1c,0x2c,0x93,0x09,0x8a,0x26,0xbb,0x34,0x21,0x1d,0xac,0xb5,0x16,0xae +.byte 0xd8,0xcb,0x94,0x04,0xd6,0xbc,0xde,0x9c,0x70,0x28,0xa5,0x1a,0x15,0x5e,0x35,0xe4,0xe6,0x53,0xea,0x9c,0x3b,0x0c,0x36,0x3b,0x80,0x13,0x28,0x1d,0xc7,0x1a,0xa8,0x8e,0x9e,0x09,0xce,0x5d,0x50,0xd3,0xc7,0x6f,0x3a,0x75,0xa5,0x84,0x1c,0x08,0x66,0xe6,0x05,0xda,0x8b,0xf1,0x4b,0x5c,0xe2,0xc7,0x0f,0xa1,0xf1,0x47,0x02,0xf4,0xa7,0x24 +.byte 0xf3,0x0e,0x2c,0xa9,0xae,0x67,0xdf,0xce,0x30,0x88,0x4a,0x9a,0x39,0x4a,0x97,0x64,0xa8,0x30,0x53,0xf9,0x47,0x66,0x5c,0x19,0x1c,0xfb,0x2f,0x05,0x89,0x4f,0xfe,0x25,0xe7,0xed,0xed,0x17,0x5a,0x86,0xeb,0x25,0xee,0xe4,0x09,0x88,0x05,0x49,0x20,0x54,0x4b,0x7f,0x3e,0xb5,0x23,0x85,0xa9,0x66,0x61,0x73,0xe0,0x61,0x94,0xc6,0xe5,0x29 +.byte 0xb4,0xe1,0x6f,0xa4,0x4d,0x50,0x56,0x2e,0x30,0x75,0x51,0x5d,0xdd,0xa2,0x68,0x56,0x67,0xd8,0xec,0x2d,0x2a,0xfd,0x49,0xc5,0xbc,0xae,0x2f,0x6b,0xc7,0x8d,0x2e,0xca,0x91,0x35,0xe8,0xea,0x65,0xe9,0x9c,0x65,0xaf,0x8e,0xd5,0x16,0xdf,0xac,0x44,0x1e,0xb6,0x16,0xf0,0xb6,0x33,0x6a,0xe6,0x96,0x0f,0x85,0x2e,0xa1,0xaa,0x6a,0xe0,0x12 +.byte 0x0c,0xaa,0x7d,0xae,0xf7,0xe3,0xb2,0x4c,0x3c,0x10,0xc6,0x87,0x8e,0x87,0xfb,0xac,0xf7,0xd7,0x7a,0x2e,0x9a,0x7a,0xa7,0x4f,0xf0,0x75,0xce,0xbd,0xc3,0xe6,0x79,0x1d,0x56,0xab,0xff,0x56,0xfe,0x69,0xbd,0xcf,0x15,0x27,0x64,0x3c,0x83,0x1c,0x08,0xb0,0x91,0x60,0x67,0xe7,0x27,0x44,0x49,0x22,0x78,0xd5,0x1a,0xc8,0x3b,0x35,0x9b,0xa5 +.byte 0x53,0xce,0xde,0x04,0xd2,0x3e,0x67,0x48,0xaf,0x54,0xdf,0x9c,0xf7,0xb9,0xd4,0xe3,0xb6,0x85,0x02,0x68,0x21,0x10,0xdb,0xb5,0xca,0x11,0xa2,0x7c,0xcf,0x13,0x41,0x7a,0xfd,0xe9,0x0a,0x3c,0x53,0xd6,0x07,0xf2,0xdd,0xe2,0x7c,0x16,0xf0,0x44,0x3f,0x5d,0x34,0x09,0x7c,0x7b,0x21,0x8c,0x8e,0xdb,0x0d,0xc5,0x73,0xce,0x61,0xce,0x17,0x46 +.byte 0x6c,0x14,0x07,0xb5,0x70,0x80,0xf0,0x29,0x7c,0x13,0x41,0x2d,0x8e,0xdc,0x53,0xc2,0xbf,0xf0,0xc2,0xfb,0x59,0xa0,0x66,0x5f,0x25,0xda,0x17,0x5f,0xac,0xab,0x75,0x1b,0xc7,0x61,0x87,0x53,0x80,0x2e,0x11,0x4e,0x04,0x48,0xf9,0xee,0x54,0xe6,0x69,0x69,0x57,0xc2,0x46,0xd8,0xb3,0x2e,0x7b,0xc8,0xa5,0xd0,0xb2,0x5e,0xd4,0x6b,0x9b,0x1a +.byte 0xd6,0x79,0x9d,0x99,0xa6,0xbb,0x4d,0xca,0x74,0x2c,0x3d,0xd4,0x86,0xd0,0x64,0xd4,0x81,0x49,0x76,0x42,0xb8,0xf9,0x2c,0x52,0xe7,0x77,0x37,0x31,0xbb,0x2e,0x5b,0x38,0x81,0x01,0x2c,0x27,0x28,0xcb,0x0c,0xba,0xfa,0x8a,0x9a,0x45,0x51,0xa2,0xde,0xf2,0x7b,0xe6,0x65,0xec,0x5b,0x2d,0xe8,0x55,0x8e,0xb4,0x7f,0xf8,0x1a,0x66,0x3a,0x5f +.byte 0x06,0x10,0x15,0xb2,0x3d,0xb2,0x36,0x6e,0x9f,0x8e,0xe2,0x4c,0x78,0xe5,0x3a,0xac,0x21,0x16,0x20,0x30,0x0f,0x51,0x56,0xcb,0x53,0xca,0x70,0x3c,0xa2,0x3f,0x37,0x06,0x6c,0x70,0xec,0xf4,0x3d,0x7c,0x77,0xa0,0x61,0xc7,0x0e,0x26,0x9f,0x25,0xc0,0xf2,0x28,0xdb,0x57,0xbe,0xe6,0x4e,0x9c,0x4d,0x2e,0x48,0x50,0xc2,0xd4,0xfd,0x5e,0x52 +.byte 0x3f,0xd0,0x82,0xd1,0xd4,0x53,0xad,0x42,0x38,0xb1,0x02,0xd6,0xa0,0x34,0x7a,0xb4,0xb3,0xdd,0x91,0x12,0xf4,0x91,0xc9,0xa2,0x35,0x2d,0xdc,0x97,0xa1,0xdb,0x82,0xe7,0x92,0x99,0x66,0x13,0x99,0x20,0x95,0x1f,0x47,0x64,0x80,0x5e,0x5f,0x74,0x6b,0xa6,0xca,0x47,0x0b,0x24,0x72,0xa6,0x27,0xe7,0x56,0x61,0xa7,0x8e,0x62,0xa4,0xff,0x8e +.byte 0x29,0xf8,0x09,0xa4,0xbb,0x70,0x97,0x8a,0x39,0xe8,0x65,0xc8,0x52,0x23,0x9d,0xbf,0x10,0xe8,0x7d,0xbc,0x3c,0xc4,0x8b,0x1e,0x5c,0x75,0x94,0x24,0x62,0x3f,0x5b,0x2b,0x9a,0x08,0x00,0x78,0xfd,0x28,0x44,0x12,0x62,0x2a,0x6f,0x47,0x9d,0x57,0xb0,0x4e,0x3b,0xcd,0x01,0x7d,0x6e,0x62,0xe3,0x99,0x9c,0xae,0x6e,0xe2,0x70,0x7a,0x32,0xb4 +.byte 0xc1,0x19,0xb1,0x03,0x6b,0x92,0x89,0x4f,0x37,0xaf,0x36,0xee,0x5e,0x03,0x31,0x8c,0x41,0x27,0x17,0x21,0xdf,0xe4,0x34,0x97,0x8d,0xe7,0x41,0x47,0xf2,0x80,0x51,0x41,0x01,0xe4,0x0c,0x1a,0x09,0xfc,0x07,0xc3,0x94,0x07,0x6f,0xa7,0x6c,0xff,0x32,0x21,0xa5,0x01,0x8c,0xa2,0x88,0x3c,0xc8,0x57,0xe8,0x68,0x19,0x4a,0x46,0x7a,0x36,0xd2 +.byte 0x75,0x8e,0xc5,0xa4,0x84,0x91,0x13,0x7f,0xdd,0x2b,0x3c,0x2e,0xc4,0x92,0x29,0xb3,0x60,0x74,0xc8,0x81,0x58,0x0e,0xad,0x6a,0x9d,0xaa,0x81,0x49,0x26,0x0f,0xd4,0x2a,0x39,0xdd,0x4d,0x2b,0x13,0xdb,0x2e,0x72,0xe6,0x45,0x99,0xeb,0xe6,0xe5,0xd5,0x76,0xd4,0x19,0xd8,0xd7,0xa9,0x1f,0xce,0x7f,0xc4,0x1c,0x9e,0x6f,0x68,0x32,0xb1,0x26 +.byte 0xc4,0xb6,0x4e,0x9f,0xbf,0xdc,0xe0,0xde,0x54,0x9b,0xe0,0x04,0x03,0xae,0xc9,0xce,0x3a,0xcb,0x93,0xad,0xcc,0x1f,0x46,0xf6,0xbb,0xff,0x40,0x52,0x9c,0x64,0x97,0x5a,0x6f,0x8d,0x28,0x45,0x1c,0xf6,0x8b,0xcb,0xb9,0x38,0xb8,0x00,0xee,0xec,0xac,0x68,0x3f,0x50,0xcb,0x36,0x6e,0x97,0xfd,0xa5,0x1d,0x29,0x6e,0xfa,0x9f,0x4b,0x83,0xcd +.byte 0x0d,0x34,0xf3,0x1e,0x3f,0x0f,0x2e,0x89,0xeb,0xf7,0x8e,0x5f,0xe0,0x3b,0x39,0xd2,0xe8,0x87,0xe3,0xe7,0xe9,0xd0,0x1b,0x32,0x03,0x6b,0x3c,0x75,0x7d,0xe2,0x5c,0x3c,0x42,0xb4,0x46,0x69,0x0b,0xaf,0x0a,0x5d,0x1a,0x83,0x0b,0x0e,0x3c,0x5a,0x36,0xbd,0x5d,0xb6,0xad,0x4c,0xdd,0xf1,0x8d,0xbf,0x2b,0x70,0x8e,0xbc,0x92,0x95,0x1b,0x0f +.byte 0xed,0x3f,0xae,0x9e,0xa2,0x5a,0x50,0xe4,0xda,0xde,0x04,0x51,0x31,0xac,0xa4,0x0b,0x94,0xcc,0x14,0x87,0x59,0xa8,0x30,0x09,0xe6,0x46,0xb9,0x07,0x3e,0x1a,0xbf,0x5a,0x23,0x32,0xfb,0x60,0x63,0x24,0x25,0x12,0xf6,0x3e,0x2d,0xd0,0x8b,0x88,0x9b,0xe9,0x2d,0xab,0xf5,0xaf,0xba,0xbc,0xfe,0xab,0xb2,0x61,0x7a,0x7c,0xbb,0x28,0x6b,0x86 +.byte 0xe5,0xa2,0x9c,0x2c,0x5a,0x23,0x12,0x11,0xe5,0x72,0xe8,0x7b,0x6b,0x40,0xf1,0x91,0x37,0x3b,0x47,0x75,0x65,0xac,0x4d,0x22,0x59,0x75,0x13,0xb0,0x73,0xff,0x59,0xd1,0x1b,0xcc,0x05,0x1f,0xf2,0xc8,0x50,0x83,0xf1,0x28,0x38,0x0b,0xc3,0xa0,0x3b,0xe3,0x86,0xbb,0x9c,0x7e,0xc1,0xe9,0xcc,0xd9,0xb8,0x2b,0x05,0xf3,0x6f,0xc7,0x9d,0xaf +.byte 0x7b,0xb7,0x38,0x41,0xa3,0x50,0x8f,0x92,0xe0,0x63,0x35,0xb3,0x95,0x9f,0x80,0xf8,0x75,0xbb,0xf3,0x2b,0x0e,0xaf,0x32,0x6e,0xff,0xeb,0x79,0xca,0xbf,0x1c,0x4f,0x6c,0x9c,0x06,0xb2,0xeb,0x99,0x57,0x1f,0xf6,0x64,0x0b,0x81,0x57,0xba,0xf4,0x32,0x1e,0x77,0x37,0x55,0xb7,0xbc,0xba,0x70,0x0b,0x0d,0xdd,0x95,0x41,0xb5,0x17,0x5b,0x14 +.byte 0x10,0x9d,0x14,0x52,0x83,0x65,0x0a,0xf4,0x55,0xca,0xf8,0xbe,0xa6,0x3a,0xa0,0x6e,0xcc,0x83,0x84,0x65,0xb4,0x1c,0x7e,0x40,0xdd,0x32,0x36,0x5a,0x23,0x17,0x7d,0xb5,0xb9,0x38,0x48,0x5c,0x6f,0x23,0x54,0x0e,0x93,0x74,0x27,0x0f,0xfd,0x58,0xc1,0x97,0x26,0x78,0x9a,0xd3,0x85,0xc5,0xb2,0xb3,0x44,0xb7,0x36,0x85,0x69,0xde,0x3b,0xa1 +.byte 0x2b,0x11,0xef,0x75,0xfc,0xaa,0x92,0xf1,0xf1,0x72,0xa0,0x5f,0x33,0xf6,0x0b,0x72,0xdb,0xce,0x6c,0x2a,0x15,0x76,0x40,0xd4,0x85,0xff,0x96,0xe1,0x48,0xe1,0x27,0x8f,0x74,0xf3,0xfa,0xa1,0xb7,0x2a,0xb6,0x41,0x90,0x92,0x7e,0xfa,0xfc,0xad,0xa3,0x94,0x91,0x77,0xf1,0x8f,0xee,0xa2,0x64,0x47,0x01,0xb3,0x01,0x99,0x05,0xe7,0x31,0x4a +.byte 0xe8,0xd2,0x65,0x40,0x21,0xc4,0x83,0x8e,0xc9,0x89,0xda,0x16,0x7b,0xe0,0xcb,0xc0,0xc0,0x3d,0x37,0x18,0x66,0xe9,0x70,0x86,0x0b,0x6c,0xe8,0x65,0x44,0xce,0x3a,0xcd,0x84,0x1e,0xce,0x0e,0xe3,0xf9,0x77,0x12,0xfb,0xe6,0x92,0x8b,0x0d,0x7e,0x15,0x7a,0x34,0x94,0x2a,0xa7,0xc5,0x35,0xa4,0xfc,0xbe,0xa3,0x13,0x70,0xe4,0x6b,0x2f,0x71 +.byte 0x31,0xef,0xdb,0x79,0x44,0xf2,0x77,0xc7,0xc9,0x0d,0x1a,0x7b,0xff,0x34,0xf8,0xc9,0xe8,0xc9,0xc2,0xe0,0x0c,0x9e,0xd6,0xb4,0x7a,0xdb,0x1f,0x65,0xb8,0xd4,0x92,0xbf,0x7f,0x06,0x44,0xe3,0xb4,0xd8,0x14,0xe3,0x9b,0x49,0x81,0x12,0xec,0x7d,0x01,0xe2,0x50,0x2c,0x0e,0xfd,0x4b,0x84,0x3b,0x4d,0x89,0x1d,0x2e,0x4b,0xe9,0xda,0xa5,0x3f +.byte 0x19,0xc2,0x53,0x36,0x5d,0xd8,0xdc,0x6e,0xc3,0x48,0x8f,0x09,0xd5,0x95,0x4b,0x0c,0x7c,0x00,0x15,0x33,0x8e,0x1d,0x0c,0xdf,0x32,0x3b,0x93,0x1f,0xf5,0x49,0x4f,0xfd,0x8b,0x64,0xe7,0x96,0xaf,0x2f,0xc8,0xea,0xab,0x91,0x53,0x29,0xe3,0x31,0x0a,0x1c,0x6e,0xe0,0xbb,0x81,0x11,0x83,0xe0,0x07,0xfb,0x29,0x11,0x0f,0x0d,0x85,0xd4,0x61 +.byte 0x3c,0x75,0xbb,0x8a,0x23,0xb6,0xa0,0x7f,0xa4,0xbb,0x11,0xd4,0x75,0xde,0x27,0xe5,0xeb,0x11,0x5d,0x02,0xfe,0x5c,0x62,0x60,0x0f,0x6f,0x45,0x9b,0xfb,0xb7,0x32,0xa8,0x1c,0xd6,0xff,0x43,0x7b,0x53,0xee,0xa4,0x1f,0xf2,0xba,0xb6,0xb7,0xb7,0x39,0x18,0x85,0x79,0x77,0x27,0x30,0x26,0xe4,0xef,0xd1,0x39,0xc9,0xa2,0x0d,0x50,0xd7,0xef +.byte 0x9e,0xd8,0x8e,0xd2,0x74,0x1a,0x3f,0x99,0x24,0xf4,0x8b,0x4d,0x02,0x63,0x18,0x3a,0xaf,0x26,0xef,0xfc,0x1d,0xfe,0x46,0xc1,0x55,0xd7,0x92,0x65,0x2f,0xe7,0x4f,0x47,0xa8,0x2f,0x5d,0x47,0x67,0xeb,0x62,0x1d,0x69,0xa6,0x0e,0x51,0x1d,0x2c,0xed,0x6e,0x94,0xe9,0x48,0x4c,0x22,0xc2,0x93,0x79,0x6f,0x1b,0xc2,0x93,0x61,0x3d,0x8b,0xba +.byte 0xcb,0xe9,0x4a,0x88,0x5e,0x19,0x50,0x14,0xfe,0xda,0x3f,0x4d,0x47,0x54,0xfc,0x1c,0x09,0x77,0x37,0x30,0xfe,0x75,0x9f,0xdd,0xa4,0x74,0x04,0x04,0x88,0xe0,0xac,0x93,0x64,0x6f,0xbf,0x50,0xd8,0xf0,0xf7,0xa0,0xfa,0x98,0x49,0xfa,0xf7,0x6e,0xcf,0xa2,0xbf,0xb6,0x07,0x15,0x0e,0x4e,0x21,0x74,0x0a,0xa6,0xa3,0x67,0xce,0xf9,0x3b,0xd6 +.byte 0x4c,0xc8,0x43,0xe3,0x3b,0x3b,0x6a,0x86,0x62,0x3f,0x5a,0xf3,0x3f,0xf9,0xeb,0xbf,0xa3,0x2a,0x83,0x8a,0x70,0x8f,0x01,0x65,0x17,0x9a,0xa6,0x26,0x3b,0x09,0x06,0x22,0x19,0xed,0xd7,0x25,0x4b,0xd2,0x9a,0x30,0xfe,0x1c,0x82,0x68,0x16,0x04,0x0e,0x04,0x8f,0xc6,0x92,0xbe,0xe4,0x43,0x98,0x1d,0x3b,0x10,0x15,0x5b,0xef,0x4e,0x60,0x5e +.byte 0x6b,0xc9,0xde,0xb8,0x47,0x02,0x86,0x45,0x39,0x7a,0x1a,0xef,0x67,0x28,0xc5,0x40,0x73,0x2a,0xa7,0x12,0x9d,0x58,0x3a,0x34,0xc2,0xda,0x34,0xb0,0x48,0xd9,0x34,0xcd,0x18,0xe9,0x76,0x41,0x78,0x8f,0xe5,0xe8,0x3d,0xb2,0x01,0x3b,0x84,0xd1,0xca,0x5e,0x26,0x1d,0x8c,0xea,0xe1,0x46,0xa3,0xf9,0x11,0xac,0x0d,0x98,0x9f,0xd3,0x46,0x79 +.byte 0xff,0xad,0x99,0x32,0x63,0x96,0xbc,0x57,0x39,0x16,0xce,0x06,0x7e,0x63,0x78,0x7b,0x86,0x92,0x1a,0xe1,0x45,0xc0,0x73,0xe1,0xec,0xfc,0x88,0x8f,0xf8,0x36,0x0f,0x54,0x76,0x02,0x98,0x49,0x40,0xb9,0xef,0xd8,0x13,0x68,0xf5,0x1d,0x0a,0x98,0x65,0x21,0xc5,0x1a,0x22,0x4e,0x8e,0xad,0xa9,0x52,0x57,0xc4,0xc6,0xa8,0x48,0x01,0x7a,0x78 +.byte 0xc9,0xfc,0xdd,0xf3,0xc3,0x83,0xc0,0x06,0xb5,0x56,0x84,0xe2,0x0c,0x6b,0x80,0xd9,0x59,0xa1,0x3d,0xe3,0x56,0xf0,0xe3,0x3f,0x93,0x61,0xf7,0x8c,0x6b,0x40,0x65,0x6e,0x01,0xc2,0xa1,0xc1,0xb8,0x9b,0x15,0x6c,0xa1,0x18,0x4a,0x6c,0x8b,0x18,0x2d,0x8e,0x71,0x7a,0xa1,0x26,0xc1,0x4b,0xac,0x0c,0xca,0x08,0x33,0xef,0x35,0x33,0x63,0xeb +.byte 0x57,0x6e,0x7e,0x36,0xe0,0x31,0xad,0x10,0x76,0xb7,0x45,0xd9,0x3a,0x92,0x66,0x69,0x13,0x61,0x59,0x87,0xfd,0x6b,0xf1,0x46,0x0a,0x7a,0x3f,0x29,0x88,0x5b,0x7d,0xef,0x07,0x02,0xa8,0xa1,0xdc,0xd4,0x0e,0x77,0x8f,0x68,0x32,0xbd,0x8e,0xd6,0x0b,0xe4,0xd1,0x75,0xc1,0xb0,0x74,0x6c,0x0e,0xc3,0x46,0x79,0x36,0x3b,0x5f,0x0e,0xa0,0xad +.byte 0x28,0x8c,0xcb,0x01,0x8e,0x58,0x14,0x09,0xf1,0xd4,0x3b,0x2e,0xdc,0xbf,0x37,0x95,0x26,0xda,0xb6,0xcf,0xc8,0xa1,0xd4,0xec,0x72,0xf3,0x44,0xf5,0x4e,0x27,0x9b,0x2e,0x7c,0xfa,0x37,0x16,0x1d,0x7f,0x90,0x86,0xae,0x96,0x3b,0xe1,0xda,0xf7,0xc4,0x54,0x0b,0x51,0x7e,0x83,0xbe,0xed,0xd6,0x5f,0xd2,0x6d,0xbb,0xd3,0xc6,0x53,0x95,0x65 +.byte 0x3d,0x19,0xc2,0xc5,0xdf,0x47,0x00,0x2c,0x4b,0x2d,0xec,0x32,0xd5,0x28,0xb5,0x30,0xe0,0x79,0x15,0x2e,0xab,0x97,0xa8,0xcf,0xc5,0x40,0x98,0x30,0x22,0x9f,0xbc,0xdb,0x65,0x06,0xfc,0x58,0xe5,0x55,0x5b,0xe2,0xf8,0x6e,0xc6,0xfc,0xec,0x6c,0x14,0xd2,0xe3,0x9a,0x71,0x8a,0x61,0xea,0x39,0xc6,0x77,0x94,0xdf,0x7b,0x99,0x71,0xdd,0x18 +.byte 0xc6,0x03,0x2d,0x49,0xf6,0xc3,0xe8,0x2b,0x7e,0x3f,0x28,0xfc,0xc8,0xa1,0xb0,0x15,0x31,0x7e,0x83,0xb8,0x14,0x34,0x0e,0x7f,0xde,0x74,0x7b,0xbf,0xb7,0x8e,0xd9,0x31,0x90,0x16,0xb6,0x57,0x14,0x4a,0xc6,0x67,0x3d,0xb9,0x46,0x92,0xf2,0xf9,0x94,0x36,0x2b,0xd6,0x1f,0x84,0xa5,0x8c,0x0f,0xd9,0x8c,0x5f,0x97,0x7a,0x7b,0xff,0xc9,0xf5 +.byte 0x5e,0x13,0x5f,0x19,0x58,0xba,0xa6,0xe8,0x29,0xf4,0xb8,0x7e,0x98,0xb7,0xef,0x1b,0x00,0xe8,0x90,0x8f,0x86,0x4c,0xe0,0x51,0x13,0x8b,0xa1,0x37,0x40,0x38,0x51,0x2f,0x5a,0x9b,0x63,0x8f,0xce,0x9a,0x97,0x07,0x0d,0x8e,0xce,0xb1,0x66,0x89,0x78,0xca,0xa6,0x0c,0x20,0xc4,0xf1,0xe3,0xab,0xe2,0x1c,0x83,0x2b,0x46,0x97,0xe8,0x8f,0x94 +.byte 0xb4,0x71,0x40,0xde,0xa1,0x05,0x4b,0xed,0xbf,0x0c,0x46,0xe1,0x25,0xf1,0xd0,0x5a,0xdb,0x9c,0x2a,0x09,0x03,0x80,0x24,0xc1,0x22,0x02,0xa5,0xde,0xf6,0x4c,0xbc,0x93,0x37,0xa9,0x28,0xb3,0x92,0x19,0xa8,0x3f,0x71,0x90,0x62,0x78,0xaa,0x9a,0x0c,0xab,0x50,0xaf,0x89,0x2b,0xf1,0xf4,0x12,0xbd,0xc9,0xd5,0xee,0x64,0x8b,0x48,0x21,0xd6 +.byte 0xa1,0xa1,0xf2,0x68,0x4a,0xf8,0x06,0x3e,0x20,0x31,0x66,0xb7,0x2f,0x64,0x01,0x5a,0x46,0x14,0x85,0xfb,0xde,0x04,0xc3,0xe4,0xd6,0x25,0x14,0xa0,0xbe,0x4d,0x39,0xd8,0xe0,0x9b,0xb7,0x6b,0x00,0xe6,0x46,0xfb,0xcc,0xa8,0xad,0x67,0x12,0x2c,0x53,0x2c,0xb6,0x9f,0x6e,0xfe,0xbc,0xcc,0x2c,0xa8,0x09,0x17,0x00,0x8e,0xf1,0xf4,0x3e,0xa9 +.byte 0x92,0x4d,0x83,0xe6,0x3c,0xf0,0xd3,0x1c,0xaf,0x84,0x2c,0x59,0x7e,0xda,0x1e,0xfd,0x7d,0xf3,0xef,0x93,0x05,0x03,0xb0,0x76,0x69,0xb5,0x51,0xa8,0x65,0x8f,0x8a,0xf8,0x55,0x92,0x08,0xfe,0xbf,0xc1,0x95,0x98,0x58,0xb1,0xd3,0xb6,0x78,0x4f,0x2f,0x25,0xcb,0x9d,0x32,0x4f,0xa6,0xcc,0xf8,0x36,0xff,0x72,0xb3,0x93,0x3d,0xd8,0x0b,0xe6 +.byte 0xc6,0xf6,0xed,0xcc,0x2a,0xa5,0x44,0x6e,0xe2,0x2d,0x6e,0x02,0xb4,0x7c,0x24,0x7f,0x57,0x02,0x84,0x61,0x8e,0xbd,0x32,0x4e,0x41,0x92,0x01,0x1b,0x8b,0x1d,0xd1,0x1e,0x31,0xc1,0x4c,0x5b,0x0c,0xa7,0x48,0x52,0x67,0xc2,0xd9,0xdc,0x86,0x9d,0xbd,0x6c,0x19,0x95,0x00,0xf0,0xd4,0x47,0xaf,0xfe,0x5d,0xa5,0x81,0xbd,0x1b,0x42,0x62,0xce +.byte 0x18,0x1b,0xa3,0x6f,0xf5,0x0b,0xb7,0x6a,0x3d,0xe3,0xcc,0x41,0x27,0xcd,0x49,0x4b,0xe5,0x2b,0xc4,0x28,0xfa,0xbe,0xd5,0x7e,0xb7,0xac,0xab,0x64,0x3b,0xe3,0x87,0xb1,0x33,0x8b,0xa8,0xe5,0x75,0xce,0x61,0x57,0x89,0xad,0x5f,0x61,0xdd,0x7c,0x06,0x2a,0x3f,0x50,0xb8,0x7e,0xd2,0xfb,0x32,0x83,0x07,0xd4,0xc5,0x3f,0xad,0x64,0x59,0x1f +.byte 0x21,0x59,0x6f,0x1b,0xd7,0x40,0x89,0x28,0x18,0xac,0xca,0xee,0x92,0x1c,0x0d,0x88,0x98,0x7a,0x75,0x68,0xe0,0xe2,0x96,0xda,0x88,0xb3,0xc6,0x21,0x02,0x34,0xfa,0xae,0x0b,0x38,0xcf,0x1c,0x6c,0x7a,0xc9,0xd9,0x5f,0xf0,0x4c,0x73,0xfd,0xe6,0x14,0xf3,0x39,0xed,0xbc,0x28,0x2f,0xf8,0x79,0x02,0x39,0x05,0xf3,0x6a,0x88,0xd9,0x03,0xe2 +.byte 0xb9,0x65,0x81,0x3a,0x34,0x80,0x3f,0x17,0x37,0x1e,0xe8,0x7d,0x41,0x49,0xfb,0x70,0x5d,0x58,0x3a,0x71,0x7b,0x3e,0xd3,0x83,0x0b,0x1b,0x11,0xfc,0x53,0xce,0xc6,0xc4,0x39,0x55,0xbe,0xbe,0x32,0xa5,0x88,0xab,0xcd,0x38,0x78,0x3e,0x52,0xaf,0x64,0x42,0x10,0xc3,0x70,0x81,0x76,0xe9,0x7d,0x8e,0x46,0x41,0xca,0x2c,0x0c,0x4c,0x30,0xd3 +.byte 0xca,0x38,0xa3,0x97,0x2e,0x0f,0xa5,0x18,0x3b,0xaa,0x0f,0x00,0x75,0x35,0x9c,0xcd,0x28,0x83,0xd4,0xa7,0x7c,0xb9,0xcd,0xb5,0x55,0x29,0x4c,0x14,0xcd,0xfc,0x8f,0xaf,0x7d,0x69,0x4f,0xf7,0x0f,0xed,0x7c,0xa5,0x79,0x9d,0x36,0xbb,0x72,0xbc,0xf2,0x14,0xfd,0xf0,0x04,0x2a,0x89,0x1e,0xf7,0x80,0x4c,0x5e,0xb8,0xc1,0xdb,0xfa,0x3c,0x27 +.byte 0xbb,0x30,0x08,0x2b,0xd2,0xf8,0xdb,0xe0,0x8c,0x00,0xe4,0xca,0xa9,0xde,0xb0,0x14,0x5b,0xec,0x6b,0xe6,0x5c,0x90,0x17,0x02,0x59,0x5f,0x5f,0x51,0xf8,0x30,0x10,0x11,0xc4,0xdf,0x37,0x30,0x32,0xb1,0x4d,0x49,0xfe,0x82,0x87,0xd2,0x42,0xf5,0x38,0x76,0xf9,0xa5,0x28,0xfc,0x14,0xb2,0xe0,0x72,0x82,0xde,0xc8,0x47,0x9e,0x8f,0x8a,0xb5 +.byte 0x85,0x44,0x42,0x12,0xc6,0xc0,0xa5,0x60,0x5a,0x27,0xd0,0x36,0x14,0x7b,0x2a,0x83,0x98,0x92,0x08,0xe9,0x03,0xc9,0xc3,0xd3,0x36,0x97,0xba,0x5e,0xd5,0x51,0xcc,0x44,0xeb,0x81,0x76,0xae,0x28,0x94,0x0b,0xf6,0xc7,0xeb,0xae,0x61,0x6f,0x7b,0x34,0xb5,0x8c,0x5f,0x31,0xb6,0x23,0xe3,0xe7,0x4b,0x60,0xe6,0xba,0x8d,0x0e,0xd1,0xb2,0x37 +.byte 0x72,0x3d,0xc1,0x75,0x9b,0x5e,0xcb,0x0f,0xf9,0xe4,0xdb,0x82,0x4c,0xc4,0x37,0xef,0x9d,0xde,0x16,0x85,0xe9,0xc2,0x03,0xd8,0x5b,0xa1,0xff,0xfa,0xd4,0xd7,0x5c,0x34,0xb6,0x1e,0x25,0x96,0xf5,0x8b,0xc3,0xee,0x16,0x1f,0xf8,0x55,0x4e,0x1c,0x83,0x80,0x77,0x1d,0x4f,0xb6,0x95,0x1c,0x91,0x7d,0x50,0x25,0xf4,0x2a,0x5d,0x2e,0xc7,0x8a +.byte 0x14,0xf8,0xb9,0xbc,0xab,0x5b,0xcd,0x47,0xb5,0xaf,0x85,0xc0,0x34,0x27,0x7d,0x6a,0x8c,0x84,0x8a,0xae,0x68,0x60,0x0e,0xa1,0x45,0xf7,0x83,0x66,0x91,0x69,0x30,0xed,0x26,0x5e,0xf5,0x48,0x6b,0x20,0xb3,0x11,0x50,0xf7,0x70,0x9d,0x10,0x50,0x44,0x87,0xfe,0x96,0x5c,0xc6,0xa4,0xa4,0xed,0x5e,0x7f,0x3d,0x90,0x19,0xbe,0x31,0xa3,0xdd +.byte 0x44,0xbb,0x9b,0x51,0x5a,0x06,0x1d,0x2e,0xd7,0xef,0xd1,0x81,0xb6,0xec,0xc6,0x89,0xfb,0x13,0xc5,0x21,0xef,0x9a,0x1a,0x48,0xf2,0xf8,0xb3,0xa3,0xec,0x7f,0x85,0xc1,0xc6,0x8c,0x5f,0xa9,0x30,0x38,0x25,0x1e,0x8d,0xcf,0x18,0x24,0xef,0x5a,0x9a,0x14,0x31,0xc0,0x2c,0x88,0xa5,0x3f,0x50,0x8b,0xb1,0xda,0x5d,0x26,0xd9,0xd3,0x81,0xb1 +.byte 0xec,0xf0,0x42,0x88,0xd0,0x81,0x51,0xf9,0x1b,0xbc,0x43,0xa4,0x37,0xf1,0xd7,0x90,0x21,0x7e,0xa0,0x3e,0x63,0xfb,0x21,0xfa,0x12,0xfb,0xde,0xc7,0xbf,0xb3,0x58,0xe7,0x76,0x42,0x20,0x01,0x3d,0x66,0x80,0xf1,0xb8,0xaf,0xfa,0x7d,0x96,0x89,0x36,0x48,0x95,0xd9,0x6e,0x6d,0xe6,0x4f,0xff,0x2a,0x47,0x61,0xf2,0x04,0xb7,0x83,0x14,0xce +.byte 0x0a,0x3c,0x73,0x17,0x50,0x88,0x03,0x25,0x4a,0xe3,0x13,0x55,0x8b,0x7e,0x50,0x38,0xfc,0x14,0x0b,0x04,0x8e,0xa8,0x5b,0xd6,0x72,0x20,0x60,0xe9,0xaa,0x22,0x82,0x11,0xc6,0xc4,0xd7,0xb9,0xc8,0x0c,0x7e,0x05,0xfb,0x90,0xe4,0x9c,0x28,0x89,0x29,0x99,0x63,0x4d,0xec,0x7b,0x50,0xbd,0xd8,0xa3,0x5b,0x50,0x77,0x19,0x81,0x92,0xce,0x82 +.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed +.align 5 +.Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +.LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +.Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +.Lone: +.quad 1,0,0,0 +.Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 + +// void ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_to_mont +.type ecp_nistz256_to_mont,%function +.align 6 +ecp_nistz256_to_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,.LRR // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + adr x2,.LRR // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont + +// void ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_from_mont +.type ecp_nistz256_from_mont,%function +.align 4 +ecp_nistz256_from_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + mov x3,#1 // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + adr x2,.Lone // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,%function +.align 4 +ecp_nistz256_mul_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,%function +.align 4 +ecp_nistz256_sqr_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +// void ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_add +.type ecp_nistz256_add,%function +.align 4 +ecp_nistz256_add: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x8,x9,[x2] + ldp x16,x17,[x1,#16] + ldp x10,x11,[x2,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_add + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_add,.-ecp_nistz256_add + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,%function +.align 4 +ecp_nistz256_div_by_2: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,%function +.align 4 +ecp_nistz256_mul_by_2: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,%function +.align 4 +ecp_nistz256_mul_by_3: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_sub +.type ecp_nistz256_sub,%function +.align 4 +ecp_nistz256_sub: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_sub,.-ecp_nistz256_sub + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_neg +.type ecp_nistz256_neg,%function +.align 4 +ecp_nistz256_neg: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_neg,.-ecp_nistz256_neg + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 +.type __ecp_nistz256_mul_mont,%function +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 +.type __ecp_nistz256_sqr_mont,%function +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont + +// Note that __ecp_nistz256_add expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... +.type __ecp_nistz256_add,%function +.align 4 +__ecp_nistz256_add: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_add,.-__ecp_nistz256_add + +.type __ecp_nistz256_sub_from,%function +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from + +.type __ecp_nistz256_sub_morf,%function +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf + +.type __ecp_nistz256_div_by_2,%function +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2 +.globl ecp_nistz256_point_double +.type ecp_nistz256_point_double,%function +.align 5 +ecp_nistz256_point_double: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +.Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + ldr x12,.Lpoly+8 + mov x8,x14 + ldr x13,.Lpoly+24 + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +.globl ecp_nistz256_point_add +.type ecp_nistz256_point_add,%function +.align 5 +ecp_nistz256_point_add: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +.Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#32*(12-4) // difference in stack frames + b .Ldouble_shortcut + +.align 4 +.Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +.Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +.globl ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,%function +.align 5 +ecp_nistz256_point_add_affine: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adr x23,.Lone_mont-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,%function +.align 4 +ecp_nistz256_ord_mul_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,.Lord + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// uint64_t rep); +.globl ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,%function +.align 4 +ecp_nistz256_ord_sqr_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,.Lord + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b .Loop_ord_sqr + +.align 4 +.Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,.Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont +// void ecp_nistz256_scatter_w5(void *x0,const P256_POINT *x1, +// int x2); +.globl ecp_nistz256_scatter_w5 +.type ecp_nistz256_scatter_w5,%function +.align 4 +ecp_nistz256_scatter_w5: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + add x0,x0,x2,lsl#2 + + ldp x4,x5,[x1] // X + ldp x6,x7,[x1,#16] + stur w4,[x0,#64*0-4] + lsr x4,x4,#32 + str w5,[x0,#64*1-4] + lsr x5,x5,#32 + str w6,[x0,#64*2-4] + lsr x6,x6,#32 + str w7,[x0,#64*3-4] + lsr x7,x7,#32 + str w4,[x0,#64*4-4] + str w5,[x0,#64*5-4] + str w6,[x0,#64*6-4] + str w7,[x0,#64*7-4] + add x0,x0,#64*8 + + ldp x4,x5,[x1,#32] // Y + ldp x6,x7,[x1,#48] + stur w4,[x0,#64*0-4] + lsr x4,x4,#32 + str w5,[x0,#64*1-4] + lsr x5,x5,#32 + str w6,[x0,#64*2-4] + lsr x6,x6,#32 + str w7,[x0,#64*3-4] + lsr x7,x7,#32 + str w4,[x0,#64*4-4] + str w5,[x0,#64*5-4] + str w6,[x0,#64*6-4] + str w7,[x0,#64*7-4] + add x0,x0,#64*8 + + ldp x4,x5,[x1,#64] // Z + ldp x6,x7,[x1,#80] + stur w4,[x0,#64*0-4] + lsr x4,x4,#32 + str w5,[x0,#64*1-4] + lsr x5,x5,#32 + str w6,[x0,#64*2-4] + lsr x6,x6,#32 + str w7,[x0,#64*3-4] + lsr x7,x7,#32 + str w4,[x0,#64*4-4] + str w5,[x0,#64*5-4] + str w6,[x0,#64*6-4] + str w7,[x0,#64*7-4] + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5 + +// void ecp_nistz256_gather_w5(P256_POINT *x0,const void *x1, +// int x2); +.globl ecp_nistz256_gather_w5 +.type ecp_nistz256_gather_w5,%function +.align 4 +ecp_nistz256_gather_w5: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + cmp x2,xzr + csetm x3,ne + add x2,x2,x3 + add x1,x1,x2,lsl#2 + + ldr w4,[x1,#64*0] + ldr w5,[x1,#64*1] + ldr w6,[x1,#64*2] + ldr w7,[x1,#64*3] + ldr w8,[x1,#64*4] + ldr w9,[x1,#64*5] + ldr w10,[x1,#64*6] + ldr w11,[x1,#64*7] + add x1,x1,#64*8 + orr x4,x4,x8,lsl#32 + orr x5,x5,x9,lsl#32 + orr x6,x6,x10,lsl#32 + orr x7,x7,x11,lsl#32 + csel x4,x4,xzr,ne + csel x5,x5,xzr,ne + csel x6,x6,xzr,ne + csel x7,x7,xzr,ne + stp x4,x5,[x0] // X + stp x6,x7,[x0,#16] + + ldr w4,[x1,#64*0] + ldr w5,[x1,#64*1] + ldr w6,[x1,#64*2] + ldr w7,[x1,#64*3] + ldr w8,[x1,#64*4] + ldr w9,[x1,#64*5] + ldr w10,[x1,#64*6] + ldr w11,[x1,#64*7] + add x1,x1,#64*8 + orr x4,x4,x8,lsl#32 + orr x5,x5,x9,lsl#32 + orr x6,x6,x10,lsl#32 + orr x7,x7,x11,lsl#32 + csel x4,x4,xzr,ne + csel x5,x5,xzr,ne + csel x6,x6,xzr,ne + csel x7,x7,xzr,ne + stp x4,x5,[x0,#32] // Y + stp x6,x7,[x0,#48] + + ldr w4,[x1,#64*0] + ldr w5,[x1,#64*1] + ldr w6,[x1,#64*2] + ldr w7,[x1,#64*3] + ldr w8,[x1,#64*4] + ldr w9,[x1,#64*5] + ldr w10,[x1,#64*6] + ldr w11,[x1,#64*7] + orr x4,x4,x8,lsl#32 + orr x5,x5,x9,lsl#32 + orr x6,x6,x10,lsl#32 + orr x7,x7,x11,lsl#32 + csel x4,x4,xzr,ne + csel x5,x5,xzr,ne + csel x6,x6,xzr,ne + csel x7,x7,xzr,ne + stp x4,x5,[x0,#64] // Z + stp x6,x7,[x0,#80] + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5 + +// void ecp_nistz256_scatter_w7(void *x0,const P256_POINT_AFFINE *x1, +// int x2); +.globl ecp_nistz256_scatter_w7 +.type ecp_nistz256_scatter_w7,%function +.align 4 +ecp_nistz256_scatter_w7: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + add x0,x0,x2 + mov x2,#64/8 +.Loop_scatter_w7: + ldr x3,[x1],#8 + subs x2,x2,#1 + prfm pstl1strm,[x0,#4096+64*0] + prfm pstl1strm,[x0,#4096+64*1] + prfm pstl1strm,[x0,#4096+64*2] + prfm pstl1strm,[x0,#4096+64*3] + prfm pstl1strm,[x0,#4096+64*4] + prfm pstl1strm,[x0,#4096+64*5] + prfm pstl1strm,[x0,#4096+64*6] + prfm pstl1strm,[x0,#4096+64*7] + strb w3,[x0,#64*0] + lsr x3,x3,#8 + strb w3,[x0,#64*1] + lsr x3,x3,#8 + strb w3,[x0,#64*2] + lsr x3,x3,#8 + strb w3,[x0,#64*3] + lsr x3,x3,#8 + strb w3,[x0,#64*4] + lsr x3,x3,#8 + strb w3,[x0,#64*5] + lsr x3,x3,#8 + strb w3,[x0,#64*6] + lsr x3,x3,#8 + strb w3,[x0,#64*7] + add x0,x0,#64*8 + b.ne .Loop_scatter_w7 + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7 + +// void ecp_nistz256_gather_w7(P256_POINT_AFFINE *x0,const void *x1, +// int x2); +.globl ecp_nistz256_gather_w7 +.type ecp_nistz256_gather_w7,%function +.align 4 +ecp_nistz256_gather_w7: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + cmp x2,xzr + csetm x3,ne + add x2,x2,x3 + add x1,x1,x2 + mov x2,#64/8 + nop +.Loop_gather_w7: + ldrb w4,[x1,#64*0] + prfm pldl1strm,[x1,#4096+64*0] + subs x2,x2,#1 + ldrb w5,[x1,#64*1] + prfm pldl1strm,[x1,#4096+64*1] + ldrb w6,[x1,#64*2] + prfm pldl1strm,[x1,#4096+64*2] + ldrb w7,[x1,#64*3] + prfm pldl1strm,[x1,#4096+64*3] + ldrb w8,[x1,#64*4] + prfm pldl1strm,[x1,#4096+64*4] + ldrb w9,[x1,#64*5] + prfm pldl1strm,[x1,#4096+64*5] + ldrb w10,[x1,#64*6] + prfm pldl1strm,[x1,#4096+64*6] + ldrb w11,[x1,#64*7] + prfm pldl1strm,[x1,#4096+64*7] + add x1,x1,#64*8 + orr x4,x4,x5,lsl#8 + orr x6,x6,x7,lsl#8 + orr x8,x8,x9,lsl#8 + orr x4,x4,x6,lsl#16 + orr x10,x10,x11,lsl#8 + orr x4,x4,x8,lsl#32 + orr x4,x4,x10,lsl#48 + and x4,x4,x3 + str x4,[x0],#8 + b.ne .Loop_gather_w7 + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7 diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S new file mode 100644 index 0000000000..6b0bda3ad8 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S @@ -0,0 +1,6389 @@ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=8 +.arch armv8-a+crypto +.text +.globl aes_gcm_enc_128_kernel +.type aes_gcm_enc_128_kernel,%function +.align 4 +aes_gcm_enc_128_kernel: + cbz x1, .L128_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 +#ifdef __AARCH64EB__ + rev x10, x10 + rev x11, x11 +#endif + ldp x13, x14, [x8, #160] //load rk10 +#ifdef __AARCH64EB__ + ror x13, x13, #32 + ror x14, x14, #32 +#endif + ld1 {v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + lsr x5, x1, #3 //byte_len + mov x15, x5 + + ld1 {v18.4s}, [x8], #16 //load rk0 + add x4, x0, x1, lsr #3 //end_input_ptr + sub x5, x5, #1 //byte_len - 1 + + lsr x12, x11, #32 + ldr q15, [x3, #112] //load h4l | h4h +#ifndef __AARCH64EB__ + ext v15.16b, v15.16b, v15.16b, #8 +#endif + fmov d1, x10 //CTR block 1 + rev w12, w12 //rev_ctr32 + + add w12, w12, #1 //increment rev_ctr32 + orr w11, w11, w11 + ld1 {v19.4s}, [x8], #16 //load rk1 + + rev w9, w12 //CTR block 1 + add w12, w12, #1 //CTR block 1 + fmov d3, x10 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 3 + ld1 {v20.4s}, [x8], #16 //load rk2 + + add w12, w12, #1 //CTR block 3 + fmov v3.d[1], x9 //CTR block 3 + + ldr q14, [x3, #80] //load h3l | h3h +#ifndef __AARCH64EB__ + ext v14.16b, v14.16b, v14.16b, #8 +#endif + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ld1 {v21.4s}, [x8], #16 //load rk3 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q12, [x3, #32] //load h1l | h1h +#ifndef __AARCH64EB__ + ext v12.16b, v12.16b, v12.16b, #8 +#endif + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + ld1 {v22.4s}, [x8], #16 //load rk4 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ld1 {v23.4s}, [x8], #16 //load rk5 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + ld1 {v24.4s}, [x8], #16 //load rk6 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ld1 {v25.4s}, [x8], #16 //load rk7 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ld1 {v26.4s}, [x8], #16 //load rk8 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ldr q13, [x3, #64] //load h2l | h2h +#ifndef __AARCH64EB__ + ext v13.16b, v13.16b, v13.16b, #8 +#endif + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + ld1 {v27.4s}, [x8], #16 //load rk9 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + add x5, x5, x0 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + cmp x0, x5 //check if we have <= 4 blocks + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v2.16b, v27.16b //AES block 2 - round 9 + + aese v0.16b, v27.16b //AES block 0 - round 9 + + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v1.16b, v27.16b //AES block 1 - round 9 + + aese v3.16b, v27.16b //AES block 3 - round 9 + b.ge .L128_enc_tail //handle tail + + ldp x6, x7, [x0, #0] //AES block 0 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + ldp x21, x22, [x0, #32] //AES block 2 - load plaintext +#ifdef __AARCH64EB__ + rev x21, x21 + rev x22, x22 +#endif + ldp x19, x20, [x0, #16] //AES block 1 - load plaintext +#ifdef __AARCH64EB__ + rev x19, x19 + rev x20, x20 +#endif + ldp x23, x24, [x0, #48] //AES block 3 - load plaintext +#ifdef __AARCH64EB__ + rev x23, x23 + rev x24, x24 +#endif + eor x6, x6, x13 //AES block 0 - round 10 low + eor x7, x7, x14 //AES block 0 - round 10 high + + eor x21, x21, x13 //AES block 2 - round 10 low + fmov d4, x6 //AES block 0 - mov low + + eor x19, x19, x13 //AES block 1 - round 10 low + eor x22, x22, x14 //AES block 2 - round 10 high + fmov v4.d[1], x7 //AES block 0 - mov high + + fmov d5, x19 //AES block 1 - mov low + eor x20, x20, x14 //AES block 1 - round 10 high + + eor x23, x23, x13 //AES block 3 - round 10 low + fmov v5.d[1], x20 //AES block 1 - mov high + + fmov d6, x21 //AES block 2 - mov low + eor x24, x24, x14 //AES block 3 - round 10 high + rev w9, w12 //CTR block 4 + + fmov v6.d[1], x22 //AES block 2 - mov high + orr x9, x11, x9, lsl #32 //CTR block 4 + + eor v4.16b, v4.16b, v0.16b //AES block 0 - result + fmov d0, x10 //CTR block 4 + add w12, w12, #1 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + + eor v5.16b, v5.16b, v1.16b //AES block 1 - result + fmov d1, x10 //CTR block 5 + orr x9, x11, x9, lsl #32 //CTR block 5 + + add w12, w12, #1 //CTR block 5 + add x0, x0, #64 //AES input_ptr update + fmov v1.d[1], x9 //CTR block 5 + + fmov d7, x23 //AES block 3 - mov low + rev w9, w12 //CTR block 6 + st1 { v4.16b}, [x2], #16 //AES block 0 - store result + + fmov v7.d[1], x24 //AES block 3 - mov high + orr x9, x11, x9, lsl #32 //CTR block 6 + + add w12, w12, #1 //CTR block 6 + eor v6.16b, v6.16b, v2.16b //AES block 2 - result + st1 { v5.16b}, [x2], #16 //AES block 1 - store result + + fmov d2, x10 //CTR block 6 + cmp x0, x5 //check if we have <= 8 blocks + + fmov v2.d[1], x9 //CTR block 6 + rev w9, w12 //CTR block 7 + st1 { v6.16b}, [x2], #16 //AES block 2 - store result + + orr x9, x11, x9, lsl #32 //CTR block 7 + + eor v7.16b, v7.16b, v3.16b //AES block 3 - result + st1 { v7.16b}, [x2], #16 //AES block 3 - store result + b.ge .L128_enc_prepretail //do prepretail + +.L128_enc_main_loop: //main loop start + ldp x23, x24, [x0, #48] //AES block 4k+3 - load plaintext +#ifdef __AARCH64EB__ + rev x23, x23 + rev x24, x24 +#endif + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov d3, x10 //CTR block 4k+3 + + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + add w12, w12, #1 //CTR block 4k+3 + fmov v3.d[1], x9 //CTR block 4k+3 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x24, x24, x14 //AES block 4k+3 - round 10 high + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + rev w9, w12 //CTR block 4k+8 + + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + mov d8, v4.d[1] //GHASH block 4k - mid + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + add w12, w12, #1 //CTR block 4k+8 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor x7, x7, x14 //AES block 4k+4 - round 10 high + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor x6, x6, x13 //AES block 4k+4 - round 10 low + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + movi v8.8b, #0xc2 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + shl d8, d8, #56 //mod_constant + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext +#ifdef __AARCH64EB__ + rev x19, x19 + rev x20, x20 +#endif + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext +#ifdef __AARCH64EB__ + rev x21, x21 + rev x22, x22 +#endif + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor x19, x19, x13 //AES block 4k+5 - round 10 low + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + eor x23, x23, x13 //AES block 4k+3 - round 10 low + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + fmov d4, x6 //AES block 4k+4 - mov low + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + add x0, x0, #64 //AES input_ptr update + fmov d7, x23 //AES block 4k+3 - mov low + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + fmov d5, x19 //AES block 4k+5 - mov low + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor x20, x20, x14 //AES block 4k+5 - round 10 high + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + fmov v5.d[1], x20 //AES block 4k+5 - mov high + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + fmov v7.d[1], x24 //AES block 4k+3 - mov high + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + cmp x0, x5 //.LOOP CONTROL + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + eor x21, x21, x13 //AES block 4k+6 - round 10 low + eor x22, x22, x14 //AES block 4k+6 - round 10 high + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + fmov d6, x21 //AES block 4k+6 - mov low + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + fmov v6.d[1], x22 //AES block 4k+6 - mov high + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result + + fmov d0, x10 //CTR block 4k+8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result + + add w12, w12, #1 //CTR block 4k+9 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + fmov d1, x10 //CTR block 4k+9 + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 + st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result + eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + add w12, w12, #1 //CTR block 4k+10 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + fmov d2, x10 //CTR block 4k+10 + + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result + + fmov v2.d[1], x9 //CTR block 4k+10 + st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result + rev w9, w12 //CTR block 4k+11 + + orr x9, x11, x9, lsl #32 //CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b //AES block 4k+3 - result + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + st1 { v7.16b}, [x2], #16 //AES block 4k+3 - store result + b.lt .L128_enc_main_loop + +.L128_enc_prepretail: //PREPRETAIL + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + fmov d3, x10 //CTR block 4k+3 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + add w12, w12, #1 //CTR block 4k+3 + fmov v3.d[1], x9 //CTR block 4k+3 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + eor v4.16b, v4.16b, v11.16b //PRE 1 + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + mov d31, v6.d[1] //GHASH block 4k+2 - mid + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + movi v8.8b, #0xc2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + shl d8, d8, #56 //mod_constant + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull v28.1q, v9.1d, v8.1d + eor v10.16b, v10.16b, v9.16b //karatsuba tidy up + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + ext v9.16b, v9.16b, v9.16b, #8 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v11.16b + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v10.16b, v10.16b, v28.16b + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v9.16b + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + pmull v28.1q, v10.1d, v8.1d + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + ext v10.16b, v10.16b, v10.16b, #8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v28.16b + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + eor v11.16b, v11.16b, v10.16b + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 +.L128_enc_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + cmp x5, #48 + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + eor x6, x6, x13 //AES block 4k+4 - round 10 low + eor x7, x7, x14 //AES block 4k+4 - round 10 high + + fmov d4, x6 //AES block 4k+4 - mov low + + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result + + b.gt .L128_enc_blocks_more_than_3 + + sub w12, w12, #1 + movi v11.8b, #0 + mov v3.16b, v2.16b + + cmp x5, #32 + mov v2.16b, v1.16b + movi v9.8b, #0 + + movi v10.8b, #0 + b.gt .L128_enc_blocks_more_than_2 + + mov v3.16b, v1.16b + cmp x5, #16 + + sub w12, w12, #1 + b.gt .L128_enc_blocks_more_than_1 + + sub w12, w12, #1 + b .L128_enc_blocks_less_than_1 +.L128_enc_blocks_more_than_3: //blocks left > 3 + st1 { v5.16b}, [x2], #16 //AES final-3 block - store result + + ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + rev64 v4.16b, v5.16b //GHASH final-3 block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + eor x7, x7, x14 //AES final-2 block - round 10 high + eor x6, x6, x13 //AES final-2 block - round 10 low + + fmov d5, x6 //AES final-2 block - mov low + + movi v8.8b, #0 //suppress further partial tag feed in + fmov v5.d[1], x7 //AES final-2 block - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + mov d22, v4.d[1] //GHASH final-3 block - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + mov d10, v17.d[1] //GHASH final-3 block - mid + + eor v5.16b, v5.16b, v1.16b //AES final-2 block - result + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid +.L128_enc_blocks_more_than_2: //blocks left > 2 + + st1 { v5.16b}, [x2], #16 //AES final-2 block - store result + + rev64 v4.16b, v5.16b //GHASH final-2 block + ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x6, x6, x13 //AES final-1 block - round 10 low + + fmov d5, x6 //AES final-1 block - mov low + eor x7, x7, x14 //AES final-1 block - round 10 high + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + fmov v5.d[1], x7 //AES final-1 block - mov high + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + eor v5.16b, v5.16b, v2.16b //AES final-1 block - result + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L128_enc_blocks_more_than_1: //blocks left > 1 + + st1 { v5.16b}, [x2], #16 //AES final-1 block - store result + + rev64 v4.16b, v5.16b //GHASH final-1 block + ldp x6, x7, [x0], #16 //AES final block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final block - round 10 high + eor x6, x6, x13 //AES final block - round 10 low + + fmov d5, x6 //AES final block - mov low + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + fmov v5.d[1], x7 //AES final block - mov high + + mov d22, v4.d[1] //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + eor v5.16b, v5.16b, v3.16b //AES final block - result + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid + movi v8.8b, #0 //suppress further partial tag feed in +.L128_enc_blocks_less_than_1: //blocks left <= 1 + + and x1, x1, #127 //bit_length %= 128 + mvn x13, xzr //rk10_l = 0xffffffffffffffff + + mvn x14, xzr //rk10_h = 0xffffffffffffffff + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk10_h is mask for top 64b of last block + cmp x1, #64 + + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + + fmov d0, x6 //ctr0b is mask for last block + + fmov v0.d[1], x7 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d8, v4.d[1] //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid +#ifndef __AARCH64EB__ + rev w9, w12 +#else + mov w9, w12 +#endif + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing + + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + st1 { v5.16b}, [x2] //store all 16B + + str w9, [x16, #12] //store the updated counter + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L128_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_128_kernel,.-aes_gcm_enc_128_kernel +.globl aes_gcm_dec_128_kernel +.type aes_gcm_dec_128_kernel,%function +.align 4 +aes_gcm_dec_128_kernel: + cbz x1, .L128_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 +#ifdef __AARCH64EB__ + rev x10, x10 + rev x11, x11 +#endif + ldp x13, x14, [x8, #160] //load rk10 +#ifdef __AARCH64EB__ + ror x14, x14, 32 + ror x13, x13, 32 +#endif + sub x5, x5, #1 //byte_len - 1 + ld1 {v18.4s}, [x8], #16 //load rk0 + + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + ldr q13, [x3, #64] //load h2l | h2h +#ifndef __AARCH64EB__ + ext v13.16b, v13.16b, v13.16b, #8 +#endif + lsr x12, x11, #32 + fmov d2, x10 //CTR block 2 + + ld1 {v19.4s}, [x8], #16 //load rk1 + orr w11, w11, w11 + rev w12, w12 //rev_ctr32 + + fmov d1, x10 //CTR block 1 + add w12, w12, #1 //increment rev_ctr32 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + rev w9, w12 //CTR block 1 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 {v20.4s}, [x8], #16 //load rk2 + add w12, w12, #1 //CTR block 1 + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + fmov d3, x10 //CTR block 3 + orr x9, x11, x9, lsl #32 //CTR block 3 + add w12, w12, #1 //CTR block 3 + + fmov v3.d[1], x9 //CTR block 3 + add x4, x0, x1, lsr #3 //end_input_ptr + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ld1 {v21.4s}, [x8], #16 //load rk3 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ld1 {v22.4s}, [x8], #16 //load rk4 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ld1 {v23.4s}, [x8], #16 //load rk5 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ld1 {v24.4s}, [x8], #16 //load rk6 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + ld1 {v25.4s}, [x8], #16 //load rk7 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ld1 {v26.4s}, [x8], #16 //load rk8 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + ldr q14, [x3, #80] //load h3l | h3h +#ifndef __AARCH64EB__ + ext v14.16b, v14.16b, v14.16b, #8 +#endif + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + ld1 {v27.4s}, [x8], #16 //load rk9 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + ldr q12, [x3, #32] //load h1l | h1h +#ifndef __AARCH64EB__ + ext v12.16b, v12.16b, v12.16b, #8 +#endif + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + ldr q15, [x3, #112] //load h4l | h4h +#ifndef __AARCH64EB__ + ext v15.16b, v15.16b, v15.16b, #8 +#endif + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + add x5, x5, x0 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v2.16b, v27.16b //AES block 2 - round 9 + + aese v3.16b, v27.16b //AES block 3 - round 9 + + aese v0.16b, v27.16b //AES block 0 - round 9 + cmp x0, x5 //check if we have <= 4 blocks + + aese v1.16b, v27.16b //AES block 1 - round 9 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + b.ge .L128_dec_tail //handle tail + + ld1 {v4.16b, v5.16b}, [x0], #32 //AES block 0 - load ciphertext; AES block 1 - load ciphertext + + eor v1.16b, v5.16b, v1.16b //AES block 1 - result + ld1 {v6.16b}, [x0], #16 //AES block 2 - load ciphertext + + eor v0.16b, v4.16b, v0.16b //AES block 0 - result + rev64 v4.16b, v4.16b //GHASH block 0 + rev w9, w12 //CTR block 4 + + orr x9, x11, x9, lsl #32 //CTR block 4 + add w12, w12, #1 //CTR block 4 + ld1 {v7.16b}, [x0], #16 //AES block 3 - load ciphertext + + rev64 v5.16b, v5.16b //GHASH block 1 + mov x19, v1.d[0] //AES block 1 - mov low + + mov x20, v1.d[1] //AES block 1 - mov high + + mov x6, v0.d[0] //AES block 0 - mov low + cmp x0, x5 //check if we have <= 8 blocks + + mov x7, v0.d[1] //AES block 0 - mov high + + fmov d0, x10 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + eor x19, x19, x13 //AES block 1 - round 10 low +#ifdef __AARCH64EB__ + rev x19, x19 +#endif + fmov d1, x10 //CTR block 5 + add w12, w12, #1 //CTR block 5 + orr x9, x11, x9, lsl #32 //CTR block 5 + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + add w12, w12, #1 //CTR block 6 + + orr x9, x11, x9, lsl #32 //CTR block 6 + + eor x20, x20, x14 //AES block 1 - round 10 high +#ifdef __AARCH64EB__ + rev x20, x20 +#endif + eor x6, x6, x13 //AES block 0 - round 10 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v2.16b, v6.16b, v2.16b //AES block 2 - result + + eor x7, x7, x14 //AES block 0 - round 10 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + stp x6, x7, [x2], #16 //AES block 0 - store result + + stp x19, x20, [x2], #16 //AES block 1 - store result + b.ge .L128_dec_prepretail //do prepretail + +.L128_dec_main_loop: //main loop start + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + mov x22, v2.d[1] //AES block 4k+2 - mov high + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d2, x10 //CTR block 4k+6 + + rev64 v6.16b, v6.16b //GHASH block 4k+2 + fmov v2.d[1], x9 //CTR block 4k+6 + rev w9, w12 //CTR block 4k+7 + + mov x23, v3.d[0] //AES block 4k+3 - mov low + eor v4.16b, v4.16b, v11.16b //PRE 1 + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + mov x24, v3.d[1] //AES block 4k+3 - mov high + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + fmov d3, x10 //CTR block 4k+7 + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + mov d8, v4.d[1] //GHASH block 4k - mid + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor x23, x23, x13 //AES block 4k+3 - round 10 low +#ifdef __AARCH64EB__ + rev x23, x23 +#endif + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + eor x22, x22, x14 //AES block 4k+2 - round 10 high +#ifdef __AARCH64EB__ + rev x22, x22 +#endif + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor x24, x24, x14 //AES block 4k+3 - round 10 high +#ifdef __AARCH64EB__ + rev x24, x24 +#endif + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + eor x21, x21, x13 //AES block 4k+2 - round 10 low +#ifdef __AARCH64EB__ + rev x21, x21 +#endif + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + movi v8.8b, #0xc2 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + ld1 {v4.16b}, [x0], #16 //AES block 4k+3 - load ciphertext + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + add w12, w12, #1 //CTR block 4k+7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + shl d8, d8, #56 //mod_constant + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + rev w9, w12 //CTR block 4k+8 + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + ld1 {v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + ld1 {v6.16b}, [x0], #16 //AES block 4k+5 - load ciphertext + + add w12, w12, #1 //CTR block 4k+8 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + ld1 {v7.16b}, [x0], #16 //AES block 4k+6 - load ciphertext + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + rev64 v5.16b, v5.16b //GHASH block 4k+5 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + mov x7, v0.d[1] //AES block 4k+4 - mov high + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + mov x6, v0.d[0] //AES block 4k+4 - mov low + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + fmov d0, x10 //CTR block 4k+8 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor x7, x7, x14 //AES block 4k+4 - round 10 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + mov x20, v1.d[1] //AES block 4k+5 - mov high + eor x6, x6, x13 //AES block 4k+4 - round 10 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result + mov x19, v1.d[0] //AES block 4k+5 - mov low + add w12, w12, #1 //CTR block 4k+9 + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + fmov d1, x10 //CTR block 4k+9 + cmp x0, x5 //.LOOP CONTROL + + rev64 v4.16b, v4.16b //GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + fmov v1.d[1], x9 //CTR block 4k+9 + + rev w9, w12 //CTR block 4k+10 + add w12, w12, #1 //CTR block 4k+10 + + eor x20, x20, x14 //AES block 4k+5 - round 10 high +#ifdef __AARCH64EB__ + rev x20, x20 +#endif + stp x6, x7, [x2], #16 //AES block 4k+4 - store result + + eor x19, x19, x13 //AES block 4k+5 - round 10 low +#ifdef __AARCH64EB__ + rev x19, x19 +#endif + stp x19, x20, [x2], #16 //AES block 4k+5 - store result + + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + b.lt .L128_dec_main_loop + +.L128_dec_prepretail: //PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + mov x22, v2.d[1] //AES block 4k+2 - mov high + + eor v4.16b, v4.16b, v11.16b //PRE 1 + fmov d2, x10 //CTR block 4k+6 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + fmov v2.d[1], x9 //CTR block 4k+6 + + rev w9, w12 //CTR block 4k+7 + mov x23, v3.d[0] //AES block 4k+3 - mov low + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d10, v17.d[1] //GHASH block 4k - mid + mov x24, v3.d[1] //AES block 4k+3 - mov high + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov v3.d[1], x9 //CTR block 4k+7 + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + movi v8.8b, #0xc2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor x23, x23, x13 //AES block 4k+3 - round 10 low +#ifdef __AARCH64EB__ + rev x23, x23 +#endif + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor x21, x21, x13 //AES block 4k+2 - round 10 low +#ifdef __AARCH64EB__ + rev x21, x21 +#endif + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + shl d8, d8, #56 //mod_constant + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor x24, x24, x14 //AES block 4k+3 - round 10 high +#ifdef __AARCH64EB__ + rev x24, x24 +#endif + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor x22, x22, x14 //AES block 4k+2 - round 10 high +#ifdef __AARCH64EB__ + rev x22, x22 +#endif + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 + add w12, w12, #1 //CTR block 4k+7 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low +.L128_dec_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result + + mov x7, v0.d[1] //AES block 4k+4 - mov high + + mov x6, v0.d[0] //AES block 4k+4 - mov low + + cmp x5, #48 + + eor x7, x7, x14 //AES block 4k+4 - round 10 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + eor x6, x6, x13 //AES block 4k+4 - round 10 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + b.gt .L128_dec_blocks_more_than_3 + + mov v3.16b, v2.16b + sub w12, w12, #1 + movi v11.8b, #0 + + movi v9.8b, #0 + mov v2.16b, v1.16b + + movi v10.8b, #0 + cmp x5, #32 + b.gt .L128_dec_blocks_more_than_2 + + cmp x5, #16 + + mov v3.16b, v1.16b + sub w12, w12, #1 + b.gt .L128_dec_blocks_more_than_1 + + sub w12, w12, #1 + b .L128_dec_blocks_less_than_1 +.L128_dec_blocks_more_than_3: //blocks left > 3 + rev64 v4.16b, v5.16b //GHASH final-3 block + ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d10, v17.d[1] //GHASH final-3 block - mid + stp x6, x7, [x2], #16 //AES final-3 block - store result + eor v0.16b, v5.16b, v1.16b //AES final-2 block - result + + mov d22, v4.d[1] //GHASH final-3 block - mid + mov x7, v0.d[1] //AES final-2 block - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + mov x6, v0.d[0] //AES final-2 block - mov low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + eor x7, x7, x14 //AES final-2 block - round 10 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor x6, x6, x13 //AES final-2 block - round 10 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif +.L128_dec_blocks_more_than_2: //blocks left > 2 + + rev64 v4.16b, v5.16b //GHASH final-2 block + ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor v0.16b, v5.16b, v2.16b //AES final-1 block - result + stp x6, x7, [x2], #16 //AES final-2 block - store result + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + mov x6, v0.d[0] //AES final-1 block - mov low + + mov x7, v0.d[1] //AES final-1 block - mov high + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor x6, x6, x13 //AES final-1 block - round 10 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid + eor x7, x7, x14 //AES final-1 block - round 10 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif +.L128_dec_blocks_more_than_1: //blocks left > 1 + + rev64 v4.16b, v5.16b //GHASH final-1 block + + ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d22, v4.d[1] //GHASH final-1 block - mid + + eor v0.16b, v5.16b, v3.16b //AES final block - result + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + stp x6, x7, [x2], #16 //AES final-1 block - store result + mov x6, v0.d[0] //AES final block - mov low + + mov x7, v0.d[1] //AES final block - mov high + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + movi v8.8b, #0 //suppress further partial tag feed in + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + eor x7, x7, x14 //AES final block - round 10 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + eor x6, x6, x13 //AES final block - round 10 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid +.L128_dec_blocks_less_than_1: //blocks left <= 1 + + mvn x14, xzr //rk10_h = 0xffffffffffffffff + and x1, x1, #127 //bit_length %= 128 + + mvn x13, xzr //rk10_l = 0xffffffffffffffff + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk10_h is mask for top 64b of last block + cmp x1, #64 + + csel x10, x14, xzr, lt + csel x9, x13, x14, lt + + fmov d0, x9 //ctr0b is mask for last block + + mov v0.d[1], x10 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + ldp x4, x5, [x2] //load existing bytes we need to not overwrite + + and x7, x7, x10 + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + mov d8, v4.d[1] //GHASH final block - mid + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + bic x4, x4, x9 //mask out low existing bytes + and x6, x6, x9 + +#ifndef __AARCH64EB__ + rev w9, w12 +#else + mov w9, w12 +#endif + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + bic x5, x5, x10 //mask out high existing bytes + shl d8, d8, #56 //mod_constant + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + orr x6, x6, x4 + str w9, [x16, #12] //store the updated counter + + orr x7, x7, x5 + stp x6, x7, [x2] + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L128_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_128_kernel,.-aes_gcm_dec_128_kernel +.globl aes_gcm_enc_192_kernel +.type aes_gcm_enc_192_kernel,%function +.align 4 +aes_gcm_enc_192_kernel: + cbz x1, .L192_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 +#ifdef __AARCH64EB__ + rev x10, x10 + rev x11, x11 +#endif + ldp x13, x14, [x8, #192] //load rk12 +#ifdef __AARCH64EB__ + ror x13, x13, #32 + ror x14, x14, #32 +#endif + ld1 {v18.4s}, [x8], #16 //load rk0 + + ld1 {v19.4s}, [x8], #16 //load rk1 + + ld1 {v20.4s}, [x8], #16 //load rk2 + + lsr x12, x11, #32 + ld1 {v21.4s}, [x8], #16 //load rk3 + orr w11, w11, w11 + + ld1 {v22.4s}, [x8], #16 //load rk4 + rev w12, w12 //rev_ctr32 + + add w12, w12, #1 //increment rev_ctr32 + fmov d3, x10 //CTR block 3 + + rev w9, w12 //CTR block 1 + add w12, w12, #1 //CTR block 1 + fmov d1, x10 //CTR block 1 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 3 + ld1 {v23.4s}, [x8], #16 //load rk5 + + fmov v3.d[1], x9 //CTR block 3 + + ld1 {v24.4s}, [x8], #16 //load rk6 + + ld1 {v25.4s}, [x8], #16 //load rk7 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ld1 {v26.4s}, [x8], #16 //load rk8 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q15, [x3, #112] //load h4l | h4h +#ifndef __AARCH64EB__ + ext v15.16b, v15.16b, v15.16b, #8 +#endif + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ld1 {v27.4s}, [x8], #16 //load rk9 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + ld1 {v28.4s}, [x8], #16 //load rk10 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldr q12, [x3, #32] //load h1l | h1h +#ifndef __AARCH64EB__ + ext v12.16b, v12.16b, v12.16b, #8 +#endif + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ld1 {v29.4s}, [x8], #16 //load rk11 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ldr q14, [x3, #80] //load h3l | h3h +#ifndef __AARCH64EB__ + ext v14.16b, v14.16b, v14.16b, #8 +#endif + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + ldr q13, [x3, #64] //load h2l | h2h +#ifndef __AARCH64EB__ + ext v13.16b, v13.16b, v13.16b, #8 +#endif + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + lsr x5, x1, #3 //byte_len + mov x15, x5 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + sub x5, x5, #1 //byte_len - 1 + + eor v16.16b, v16.16b, v8.16b //h2k | h1k + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v2.16b, v29.16b //AES block 2 - round 11 + add x4, x0, x1, lsr #3 //end_input_ptr + add x5, x5, x0 + + aese v1.16b, v29.16b //AES block 1 - round 11 + cmp x0, x5 //check if we have <= 4 blocks + + aese v0.16b, v29.16b //AES block 0 - round 11 + add w12, w12, #1 //CTR block 3 + + aese v3.16b, v29.16b //AES block 3 - round 11 + b.ge .L192_enc_tail //handle tail + + rev w9, w12 //CTR block 4 + ldp x6, x7, [x0, #0] //AES block 0 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + orr x9, x11, x9, lsl #32 //CTR block 4 + ldp x21, x22, [x0, #32] //AES block 2 - load plaintext +#ifdef __AARCH64EB__ + rev x21, x21 + rev x22, x22 +#endif + ldp x23, x24, [x0, #48] //AES block 3 - load plaintext +#ifdef __AARCH64EB__ + rev x23, x23 + rev x24, x24 +#endif + ldp x19, x20, [x0, #16] //AES block 1 - load plaintext +#ifdef __AARCH64EB__ + rev x19, x19 + rev x20, x20 +#endif + add x0, x0, #64 //AES input_ptr update + cmp x0, x5 //check if we have <= 8 blocks + + eor x6, x6, x13 //AES block 0 - round 12 low + + eor x7, x7, x14 //AES block 0 - round 12 high + eor x22, x22, x14 //AES block 2 - round 12 high + fmov d4, x6 //AES block 0 - mov low + + eor x24, x24, x14 //AES block 3 - round 12 high + fmov v4.d[1], x7 //AES block 0 - mov high + + eor x21, x21, x13 //AES block 2 - round 12 low + eor x19, x19, x13 //AES block 1 - round 12 low + + fmov d5, x19 //AES block 1 - mov low + eor x20, x20, x14 //AES block 1 - round 12 high + + fmov v5.d[1], x20 //AES block 1 - mov high + + eor x23, x23, x13 //AES block 3 - round 12 low + fmov d6, x21 //AES block 2 - mov low + + add w12, w12, #1 //CTR block 4 + eor v4.16b, v4.16b, v0.16b //AES block 0 - result + fmov d0, x10 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + + orr x9, x11, x9, lsl #32 //CTR block 5 + add w12, w12, #1 //CTR block 5 + + fmov d7, x23 //AES block 3 - mov low + st1 { v4.16b}, [x2], #16 //AES block 0 - store result + + fmov v6.d[1], x22 //AES block 2 - mov high + + eor v5.16b, v5.16b, v1.16b //AES block 1 - result + fmov d1, x10 //CTR block 5 + st1 { v5.16b}, [x2], #16 //AES block 1 - store result + + fmov v7.d[1], x24 //AES block 3 - mov high + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + + orr x9, x11, x9, lsl #32 //CTR block 6 + + add w12, w12, #1 //CTR block 6 + eor v6.16b, v6.16b, v2.16b //AES block 2 - result + fmov d2, x10 //CTR block 6 + + fmov v2.d[1], x9 //CTR block 6 + rev w9, w12 //CTR block 7 + + orr x9, x11, x9, lsl #32 //CTR block 7 + st1 { v6.16b}, [x2], #16 //AES block 2 - store result + + eor v7.16b, v7.16b, v3.16b //AES block 3 - result + st1 { v7.16b}, [x2], #16 //AES block 3 - store result + b.ge .L192_enc_prepretail //do prepretail + +.L192_enc_main_loop: //main loop start + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext +#ifdef __AARCH64EB__ + rev x19, x19 + rev x20, x20 +#endif + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + fmov d3, x10 //CTR block 4k+3 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + fmov v3.d[1], x9 //CTR block 4k+3 + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext +#ifdef __AARCH64EB__ + rev x21, x21 + rev x22, x22 +#endif + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + ldp x23, x24, [x0, #48] //AES block 4k+3 - load plaintext +#ifdef __AARCH64EB__ + rev x23, x23 + rev x24, x24 +#endif + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + eor v4.16b, v4.16b, v11.16b //PRE 1 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x24, x24, x14 //AES block 4k+3 - round 12 high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor x21, x21, x13 //AES block 4k+6 - round 12 low + + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor x19, x19, x13 //AES block 4k+5 - round 12 low + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + mov d10, v17.d[1] //GHASH block 4k - mid + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + eor x20, x20, x14 //AES block 4k+5 - round 12 high + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + add w12, w12, #1 //CTR block 4k+3 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + eor x22, x22, x14 //AES block 4k+6 - round 12 high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor x23, x23, x13 //AES block 4k+3 - round 12 low + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + rev w9, w12 //CTR block 4k+8 + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + add x0, x0, #64 //AES input_ptr update + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + movi v8.8b, #0xc2 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + eor x7, x7, x14 //AES block 4k+4 - round 12 high + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor x6, x6, x13 //AES block 4k+4 - round 12 low + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + shl d8, d8, #56 //mod_constant + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + fmov d5, x19 //AES block 4k+5 - mov low + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + fmov v5.d[1], x20 //AES block 4k+5 - mov high + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + cmp x0, x5 //.LOOP CONTROL + fmov d4, x6 //AES block 4k+4 - mov low + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + fmov d7, x23 //AES block 4k+3 - mov low + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + add w12, w12, #1 //CTR block 4k+8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + fmov v7.d[1], x24 //AES block 4k+3 - mov high + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + fmov d6, x21 //AES block 4k+6 - mov low + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v0.16b, v29.16b //AES block 4k+4 - round 11 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result + fmov d0, x10 //CTR block 4k+8 + + aese v1.16b, v29.16b //AES block 4k+5 - round 11 + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + fmov v6.d[1], x22 //AES block 4k+6 - mov high + st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + + eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result + add w12, w12, #1 //CTR block 4k+9 + fmov d1, x10 //CTR block 4k+9 + + aese v2.16b, v29.16b //AES block 4k+6 - round 11 + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + + add w12, w12, #1 //CTR block 4k+10 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + + aese v3.16b, v29.16b //AES block 4k+7 - round 11 + eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result + fmov d2, x10 //CTR block 4k+10 + + st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result + fmov v2.d[1], x9 //CTR block 4k+10 + rev w9, w12 //CTR block 4k+11 + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + orr x9, x11, x9, lsl #32 //CTR block 4k+11 + + eor v7.16b, v7.16b, v3.16b //AES block 4k+3 - result + st1 { v7.16b}, [x2], #16 //AES block 4k+3 - store result + b.lt .L192_enc_main_loop + +.L192_enc_prepretail: //PREPRETAIL + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + fmov d3, x10 //CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + add w12, w12, #1 //CTR block 4k+3 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + + fmov v3.d[1], x9 //CTR block 4k+3 + eor v4.16b, v4.16b, v11.16b //PRE 1 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + movi v8.8b, #0xc2 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v9.16b //karatsuba tidy up + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + shl d8, d8, #56 //mod_constant + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v11.16b + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + pmull v30.1q, v9.1d, v8.1d + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + ext v9.16b, v9.16b, v9.16b, #8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v30.16b + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v9.16b + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + pmull v30.1q, v10.1d, v8.1d + + ext v10.16b, v10.16b, v10.16b, #8 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v11.16b, v11.16b, v30.16b + + aese v0.16b, v29.16b //AES block 4k+4 - round 11 + + aese v3.16b, v29.16b //AES block 4k+7 - round 11 + + aese v2.16b, v29.16b //AES block 4k+6 - round 11 + + aese v1.16b, v29.16b //AES block 4k+5 - round 11 + eor v11.16b, v11.16b, v10.16b +.L192_enc_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + eor x6, x6, x13 //AES block 4k+4 - round 12 low + eor x7, x7, x14 //AES block 4k+4 - round 12 high + + fmov d4, x6 //AES block 4k+4 - mov low + + fmov v4.d[1], x7 //AES block 4k+4 - mov high + cmp x5, #48 + + eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + b.gt .L192_enc_blocks_more_than_3 + + sub w12, w12, #1 + movi v10.8b, #0 + + mov v3.16b, v2.16b + movi v9.8b, #0 + cmp x5, #32 + + mov v2.16b, v1.16b + movi v11.8b, #0 + b.gt .L192_enc_blocks_more_than_2 + + sub w12, w12, #1 + + mov v3.16b, v1.16b + cmp x5, #16 + b.gt .L192_enc_blocks_more_than_1 + + sub w12, w12, #1 + b .L192_enc_blocks_less_than_1 +.L192_enc_blocks_more_than_3: //blocks left > 3 + st1 { v5.16b}, [x2], #16 //AES final-3 block - store result + + ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + rev64 v4.16b, v5.16b //GHASH final-3 block + + eor x6, x6, x13 //AES final-2 block - round 12 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final-2 block - round 12 high + fmov d5, x6 //AES final-2 block - mov low + + fmov v5.d[1], x7 //AES final-2 block - mov high + + mov d22, v4.d[1] //GHASH final-3 block - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + + mov d10, v17.d[1] //GHASH final-3 block - mid + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b //AES final-2 block - result +.L192_enc_blocks_more_than_2: //blocks left > 2 + + st1 { v5.16b}, [x2], #16 //AES final-2 block - store result + + rev64 v4.16b, v5.16b //GHASH final-2 block + ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final-1 block - round 12 high + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + eor x6, x6, x13 //AES final-1 block - round 12 low + + fmov d5, x6 //AES final-1 block - mov low + + fmov v5.d[1], x7 //AES final-1 block - mov high + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + eor v5.16b, v5.16b, v2.16b //AES final-1 block - result + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L192_enc_blocks_more_than_1: //blocks left > 1 + + st1 { v5.16b}, [x2], #16 //AES final-1 block - store result + + ldp x6, x7, [x0], #16 //AES final block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + rev64 v4.16b, v5.16b //GHASH final-1 block + + eor x6, x6, x13 //AES final block - round 12 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + movi v8.8b, #0 //suppress further partial tag feed in + + mov d22, v4.d[1] //GHASH final-1 block - mid + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + eor x7, x7, x14 //AES final block - round 12 high + fmov d5, x6 //AES final block - mov low + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + fmov v5.d[1], x7 //AES final block - mov high + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + eor v5.16b, v5.16b, v3.16b //AES final block - result + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid +.L192_enc_blocks_less_than_1: //blocks left <= 1 + + ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored +#ifndef __AARCH64EB__ + rev w9, w12 +#else + mov w9, w12 +#endif + and x1, x1, #127 //bit_length %= 128 + + sub x1, x1, #128 //bit_length -= 128 + mvn x14, xzr //rk12_h = 0xffffffffffffffff + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + mvn x13, xzr //rk12_l = 0xffffffffffffffff + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk12_h is mask for top 64b of last block + cmp x1, #64 + + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + + fmov d0, x6 //ctr0b is mask for last block + + fmov v0.d[1], x7 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d8, v4.d[1] //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + str w9, [x16, #12] //store the updated counter + + st1 { v5.16b}, [x2] //store all 16B + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_192_kernel,.-aes_gcm_enc_192_kernel +.globl aes_gcm_dec_192_kernel +.type aes_gcm_dec_192_kernel,%function +.align 4 +aes_gcm_dec_192_kernel: + cbz x1, .L192_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add x4, x0, x1, lsr #3 //end_input_ptr + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 +#ifdef __AARCH64EB__ + rev x10, x10 + rev x11, x11 +#endif + ldp x13, x14, [x8, #192] //load rk12 +#ifdef __AARCH64EB__ + ror x13, x13, #32 + ror x14, x14, #32 +#endif + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + ld1 {v18.4s}, [x8], #16 //load rk0 + + lsr x5, x1, #3 //byte_len + mov x15, x5 + ld1 {v19.4s}, [x8], #16 //load rk1 + + lsr x12, x11, #32 + orr w11, w11, w11 + fmov d3, x10 //CTR block 3 + + rev w12, w12 //rev_ctr32 + fmov d1, x10 //CTR block 1 + + add w12, w12, #1 //increment rev_ctr32 + ld1 {v20.4s}, [x8], #16 //load rk2 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + rev w9, w12 //CTR block 1 + + add w12, w12, #1 //CTR block 1 + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 {v21.4s}, [x8], #16 //load rk3 + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + orr x9, x11, x9, lsl #32 //CTR block 3 + + fmov v3.d[1], x9 //CTR block 3 + + ld1 {v22.4s}, [x8], #16 //load rk4 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ld1 {v23.4s}, [x8], #16 //load rk5 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q15, [x3, #112] //load h4l | h4h +#ifndef __AARCH64EB__ + ext v15.16b, v15.16b, v15.16b, #8 +#endif + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q13, [x3, #64] //load h2l | h2h +#ifndef __AARCH64EB__ + ext v13.16b, v13.16b, v13.16b, #8 +#endif + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ldr q14, [x3, #80] //load h3l | h3h +#ifndef __AARCH64EB__ + ext v14.16b, v14.16b, v14.16b, #8 +#endif + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ldr q12, [x3, #32] //load h1l | h1h +#ifndef __AARCH64EB__ + ext v12.16b, v12.16b, v12.16b, #8 +#endif + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ld1 {v24.4s}, [x8], #16 //load rk6 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + ld1 {v25.4s}, [x8], #16 //load rk7 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ld1 {v26.4s}, [x8], #16 //load rk8 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + ld1 {v27.4s}, [x8], #16 //load rk9 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + add w12, w12, #1 //CTR block 3 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + ld1 {v28.4s}, [x8], #16 //load rk10 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + ld1 {v29.4s}, [x8], #16 //load rk11 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + sub x5, x5, #1 //byte_len - 1 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + add x5, x5, x0 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + cmp x0, x5 //check if we have <= 4 blocks + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v3.16b, v29.16b //AES block 3 - round 11 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v2.16b, v29.16b //AES block 2 - round 11 + + aese v1.16b, v29.16b //AES block 1 - round 11 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v0.16b, v29.16b //AES block 0 - round 11 + b.ge .L192_dec_tail //handle tail + + ld1 {v4.16b, v5.16b}, [x0], #32 //AES block 0,1 - load ciphertext + + eor v1.16b, v5.16b, v1.16b //AES block 1 - result + + eor v0.16b, v4.16b, v0.16b //AES block 0 - result + rev w9, w12 //CTR block 4 + ld1 {v6.16b, v7.16b}, [x0], #32 //AES block 2,3 - load ciphertext + + mov x19, v1.d[0] //AES block 1 - mov low + + mov x20, v1.d[1] //AES block 1 - mov high + + mov x6, v0.d[0] //AES block 0 - mov low + orr x9, x11, x9, lsl #32 //CTR block 4 + add w12, w12, #1 //CTR block 4 + + mov x7, v0.d[1] //AES block 0 - mov high + rev64 v4.16b, v4.16b //GHASH block 0 + + fmov d0, x10 //CTR block 4 + rev64 v5.16b, v5.16b //GHASH block 1 + cmp x0, x5 //check if we have <= 8 blocks + + eor x19, x19, x13 //AES block 1 - round 12 low +#ifdef __AARCH64EB__ + rev x19, x19 +#endif + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + + orr x9, x11, x9, lsl #32 //CTR block 5 + fmov d1, x10 //CTR block 5 + eor x20, x20, x14 //AES block 1 - round 12 high +#ifdef __AARCH64EB__ + rev x20, x20 +#endif + add w12, w12, #1 //CTR block 5 + fmov v1.d[1], x9 //CTR block 5 + eor x6, x6, x13 //AES block 0 - round 12 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + rev w9, w12 //CTR block 6 + eor x7, x7, x14 //AES block 0 - round 12 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + stp x6, x7, [x2], #16 //AES block 0 - store result + orr x9, x11, x9, lsl #32 //CTR block 6 + + stp x19, x20, [x2], #16 //AES block 1 - store result + + add w12, w12, #1 //CTR block 6 + eor v2.16b, v6.16b, v2.16b //AES block 2 - result + b.ge .L192_dec_prepretail //do prepretail + +.L192_dec_main_loop: //main loop start + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + mov x21, v2.d[0] //AES block 4k+2 - mov low + + mov x22, v2.d[1] //AES block 4k+2 - mov high + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + fmov d2, x10 //CTR block 4k+6 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + fmov v2.d[1], x9 //CTR block 4k+6 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + fmov d3, x10 //CTR block 4k+7 + mov d8, v4.d[1] //GHASH block 4k - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d10, v17.d[1] //GHASH block 4k - mid + rev w9, w12 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + fmov v3.d[1], x9 //CTR block 4k+7 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + eor x22, x22, x14 //AES block 4k+2 - round 12 high +#ifdef __AARCH64EB__ + rev x22, x22 +#endif + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + eor x21, x21, x13 //AES block 4k+2 - round 12 low +#ifdef __AARCH64EB__ + rev x21, x21 +#endif + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + movi v8.8b, #0xc2 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + shl d8, d8, #56 //mod_constant + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + ld1 {v4.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + ld1 {v5.16b}, [x0], #16 //AES block 4k+5 - load ciphertext + eor x23, x23, x13 //AES block 4k+3 - round 12 low +#ifdef __AARCH64EB__ + rev x23, x23 +#endif + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v0.16b, v29.16b //AES block 4k+4 - round 11 + add w12, w12, #1 //CTR block 4k+7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + ld1 {v6.16b}, [x0], #16 //AES block 4k+6 - load ciphertext + + aese v1.16b, v29.16b //AES block 4k+5 - round 11 + ld1 {v7.16b}, [x0], #16 //AES block 4k+7 - load ciphertext + rev w9, w12 //CTR block 4k+8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + cmp x0, x5 //.LOOP CONTROL + + eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result + eor x24, x24, x14 //AES block 4k+3 - round 12 high +#ifdef __AARCH64EB__ + rev x24, x24 +#endif + eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + mov x19, v1.d[0] //AES block 4k+5 - mov low + + mov x6, v0.d[0] //AES block 4k+4 - mov low + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + rev64 v5.16b, v5.16b //GHASH block 4k+5 + + aese v2.16b, v29.16b //AES block 4k+6 - round 11 + mov x7, v0.d[1] //AES block 4k+4 - mov high + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + mov x20, v1.d[1] //AES block 4k+5 - mov high + + fmov d0, x10 //CTR block 4k+8 + add w12, w12, #1 //CTR block 4k+8 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + + eor x6, x6, x13 //AES block 4k+4 - round 12 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + fmov d1, x10 //CTR block 4k+9 + add w12, w12, #1 //CTR block 4k+9 + eor x19, x19, x13 //AES block 4k+5 - round 12 low +#ifdef __AARCH64EB__ + rev x19, x19 +#endif + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + eor x20, x20, x14 //AES block 4k+5 - round 12 high +#ifdef __AARCH64EB__ + rev x20, x20 +#endif + eor x7, x7, x14 //AES block 4k+4 - round 12 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + stp x6, x7, [x2], #16 //AES block 4k+4 - store result + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + + add w12, w12, #1 //CTR block 4k+10 + rev64 v4.16b, v4.16b //GHASH block 4k+4 + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + aese v3.16b, v29.16b //AES block 4k+7 - round 11 + stp x19, x20, [x2], #16 //AES block 4k+5 - store result + b.lt .L192_dec_main_loop + +.L192_dec_prepretail: //PREPRETAIL + mov x22, v2.d[1] //AES block 4k+2 - mov high + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + eor v4.16b, v4.16b, v11.16b //PRE 1 + fmov d2, x10 //CTR block 4k+6 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + fmov v2.d[1], x9 //CTR block 4k+6 + rev w9, w12 //CTR block 4k+7 + + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + eor x24, x24, x14 //AES block 4k+3 - round 12 high +#ifdef __AARCH64EB__ + rev x24, x24 +#endif + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + eor x21, x21, x13 //AES block 4k+2 - round 12 low +#ifdef __AARCH64EB__ + rev x21, x21 +#endif + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + eor x22, x22, x14 //AES block 4k+2 - round 12 high +#ifdef __AARCH64EB__ + rev x22, x22 +#endif + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor x23, x23, x13 //AES block 4k+3 - round 12 low +#ifdef __AARCH64EB__ + rev x23, x23 +#endif + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + rev64 v7.16b, v7.16b //GHASH block 4k+3 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + add w12, w12, #1 //CTR block 4k+7 + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + movi v8.8b, #0xc2 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + shl d8, d8, #56 //mod_constant + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + + aese v0.16b, v29.16b + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v2.16b, v29.16b + + aese v1.16b, v29.16b + + aese v3.16b, v29.16b + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low +.L192_dec_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result + + mov x7, v0.d[1] //AES block 4k+4 - mov high + + mov x6, v0.d[0] //AES block 4k+4 - mov low + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + + cmp x5, #48 + + eor x7, x7, x14 //AES block 4k+4 - round 12 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + eor x6, x6, x13 //AES block 4k+4 - round 12 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + b.gt .L192_dec_blocks_more_than_3 + + movi v11.8b, #0 + movi v9.8b, #0 + + mov v3.16b, v2.16b + mov v2.16b, v1.16b + sub w12, w12, #1 + + movi v10.8b, #0 + cmp x5, #32 + b.gt .L192_dec_blocks_more_than_2 + + mov v3.16b, v1.16b + cmp x5, #16 + sub w12, w12, #1 + + b.gt .L192_dec_blocks_more_than_1 + + sub w12, w12, #1 + b .L192_dec_blocks_less_than_1 +.L192_dec_blocks_more_than_3: //blocks left > 3 + rev64 v4.16b, v5.16b //GHASH final-3 block + ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext + + stp x6, x7, [x2], #16 //AES final-3 block - store result + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor v0.16b, v5.16b, v1.16b //AES final-2 block - result + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + mov x6, v0.d[0] //AES final-2 block - mov low + mov d22, v4.d[1] //GHASH final-3 block - mid + + mov x7, v0.d[1] //AES final-2 block - mov high + + mov d10, v17.d[1] //GHASH final-3 block - mid + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + eor x6, x6, x13 //AES final-2 block - round 12 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + movi v8.8b, #0 //suppress further partial tag feed in + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor x7, x7, x14 //AES final-2 block - round 12 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif +.L192_dec_blocks_more_than_2: //blocks left > 2 + + rev64 v4.16b, v5.16b //GHASH final-2 block + ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + movi v8.8b, #0 //suppress further partial tag feed in + + eor v0.16b, v5.16b, v2.16b //AES final-1 block - result + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + stp x6, x7, [x2], #16 //AES final-2 block - store result + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + mov x7, v0.d[1] //AES final-1 block - mov high + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + mov x6, v0.d[0] //AES final-1 block - mov low + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + eor x7, x7, x14 //AES final-1 block - round 12 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + eor x6, x6, x13 //AES final-1 block - round 12 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L192_dec_blocks_more_than_1: //blocks left > 1 + + rev64 v4.16b, v5.16b //GHASH final-1 block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext + + mov d22, v4.d[1] //GHASH final-1 block - mid + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + + eor v0.16b, v5.16b, v3.16b //AES final block - result + stp x6, x7, [x2], #16 //AES final-1 block - store result + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + mov x7, v0.d[1] //AES final block - mov high + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + mov x6, v0.d[0] //AES final block - mov low + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + eor x7, x7, x14 //AES final block - round 12 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + eor x6, x6, x13 //AES final block - round 12 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid +.L192_dec_blocks_less_than_1: //blocks left <= 1 + + mvn x13, xzr //rk12_l = 0xffffffffffffffff + ldp x4, x5, [x2] //load existing bytes we need to not overwrite + and x1, x1, #127 //bit_length %= 128 + + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + mvn x14, xzr //rk12_h = 0xffffffffffffffff + + lsr x14, x14, x1 //rk12_h is mask for top 64b of last block + cmp x1, #64 + + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + + fmov d0, x9 //ctr0b is mask for last block + and x6, x6, x9 + bic x4, x4, x9 //mask out low existing bytes + + orr x6, x6, x4 + mov v0.d[1], x10 +#ifndef __AARCH64EB__ + rev w9, w12 +#else + mov w9, w12 +#endif + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + str w9, [x16, #12] //store the updated counter + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + bic x5, x5, x10 //mask out high existing bytes + + and x7, x7, x10 + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + mov d8, v4.d[1] //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + orr x7, x7, x5 + stp x6, x7, [x2] + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_192_kernel,.-aes_gcm_dec_192_kernel +.globl aes_gcm_enc_256_kernel +.type aes_gcm_enc_256_kernel,%function +.align 4 +aes_gcm_enc_256_kernel: + cbz x1, .L256_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add x4, x0, x1, lsr #3 //end_input_ptr + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 +#ifdef __AARCH64EB__ + rev x10, x10 + rev x11, x11 +#endif + ldp x13, x14, [x8, #224] //load rk14 +#ifdef __AARCH64EB__ + ror x13, x13, #32 + ror x14, x14, #32 +#endif + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 //byte_len - 1 + + ld1 {v18.4s}, [x8], #16 //load rk0 + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + ld1 {v19.4s}, [x8], #16 //load rk1 + add x5, x5, x0 + + lsr x12, x11, #32 + fmov d2, x10 //CTR block 2 + orr w11, w11, w11 + + rev w12, w12 //rev_ctr32 + cmp x0, x5 //check if we have <= 4 blocks + fmov d1, x10 //CTR block 1 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + add w12, w12, #1 //increment rev_ctr32 + + rev w9, w12 //CTR block 1 + fmov d3, x10 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 1 + add w12, w12, #1 //CTR block 1 + ld1 {v20.4s}, [x8], #16 //load rk2 + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + orr x9, x11, x9, lsl #32 //CTR block 2 + ld1 {v21.4s}, [x8], #16 //load rk3 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + orr x9, x11, x9, lsl #32 //CTR block 3 + + fmov v3.d[1], x9 //CTR block 3 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ld1 {v22.4s}, [x8], #16 //load rk4 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ld1 {v23.4s}, [x8], #16 //load rk5 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ld1 {v24.4s}, [x8], #16 //load rk6 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldr q14, [x3, #80] //load h3l | h3h +#ifndef __AARCH64EB__ + ext v14.16b, v14.16b, v14.16b, #8 +#endif + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ld1 {v25.4s}, [x8], #16 //load rk7 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ld1 {v26.4s}, [x8], #16 //load rk8 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ldr q13, [x3, #64] //load h2l | h2h +#ifndef __AARCH64EB__ + ext v13.16b, v13.16b, v13.16b, #8 +#endif + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ld1 {v27.4s}, [x8], #16 //load rk9 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ldr q15, [x3, #112] //load h4l | h4h +#ifndef __AARCH64EB__ + ext v15.16b, v15.16b, v15.16b, #8 +#endif + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + ld1 {v28.4s}, [x8], #16 //load rk10 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + ld1 {v29.4s}, [x8], #16 //load rk11 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + add w12, w12, #1 //CTR block 3 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + ld1 {v30.4s}, [x8], #16 //load rk12 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + ldr q12, [x3, #32] //load h1l | h1h +#ifndef __AARCH64EB__ + ext v12.16b, v12.16b, v12.16b, #8 +#endif + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + ld1 {v31.4s}, [x8], #16 //load rk13 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 1 - round 11 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 2 - round 11 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 1 - round 12 + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 2 - round 12 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 0 - round 11 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 3 - round 11 + + aese v2.16b, v31.16b //AES block 2 - round 13 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 0 - round 12 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 3 - round 12 + + aese v1.16b, v31.16b //AES block 1 - round 13 + + aese v0.16b, v31.16b //AES block 0 - round 13 + + aese v3.16b, v31.16b //AES block 3 - round 13 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + b.ge .L256_enc_tail //handle tail + + ldp x19, x20, [x0, #16] //AES block 1 - load plaintext +#ifdef __AARCH64EB__ + rev x19, x19 + rev x20, x20 +#endif + rev w9, w12 //CTR block 4 + ldp x6, x7, [x0, #0] //AES block 0 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + ldp x23, x24, [x0, #48] //AES block 3 - load plaintext +#ifdef __AARCH64EB__ + rev x23, x23 + rev x24, x24 +#endif + ldp x21, x22, [x0, #32] //AES block 2 - load plaintext +#ifdef __AARCH64EB__ + rev x21, x21 + rev x22, x22 +#endif + add x0, x0, #64 //AES input_ptr update + + eor x19, x19, x13 //AES block 1 - round 14 low + eor x20, x20, x14 //AES block 1 - round 14 high + + fmov d5, x19 //AES block 1 - mov low + eor x6, x6, x13 //AES block 0 - round 14 low + + eor x7, x7, x14 //AES block 0 - round 14 high + eor x24, x24, x14 //AES block 3 - round 14 high + fmov d4, x6 //AES block 0 - mov low + + cmp x0, x5 //check if we have <= 8 blocks + fmov v4.d[1], x7 //AES block 0 - mov high + eor x23, x23, x13 //AES block 3 - round 14 low + + eor x21, x21, x13 //AES block 2 - round 14 low + fmov v5.d[1], x20 //AES block 1 - mov high + + fmov d6, x21 //AES block 2 - mov low + add w12, w12, #1 //CTR block 4 + + orr x9, x11, x9, lsl #32 //CTR block 4 + fmov d7, x23 //AES block 3 - mov low + eor x22, x22, x14 //AES block 2 - round 14 high + + fmov v6.d[1], x22 //AES block 2 - mov high + + eor v4.16b, v4.16b, v0.16b //AES block 0 - result + fmov d0, x10 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + add w12, w12, #1 //CTR block 5 + + eor v5.16b, v5.16b, v1.16b //AES block 1 - result + fmov d1, x10 //CTR block 5 + orr x9, x11, x9, lsl #32 //CTR block 5 + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + st1 { v4.16b}, [x2], #16 //AES block 0 - store result + + fmov v7.d[1], x24 //AES block 3 - mov high + orr x9, x11, x9, lsl #32 //CTR block 6 + eor v6.16b, v6.16b, v2.16b //AES block 2 - result + + st1 { v5.16b}, [x2], #16 //AES block 1 - store result + + add w12, w12, #1 //CTR block 6 + fmov d2, x10 //CTR block 6 + + fmov v2.d[1], x9 //CTR block 6 + st1 { v6.16b}, [x2], #16 //AES block 2 - store result + rev w9, w12 //CTR block 7 + + orr x9, x11, x9, lsl #32 //CTR block 7 + + eor v7.16b, v7.16b, v3.16b //AES block 3 - result + st1 { v7.16b}, [x2], #16 //AES block 3 - store result + b.ge .L256_enc_prepretail //do prepretail + +.L256_enc_main_loop: //main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d3, x10 //CTR block 4k+3 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + fmov v3.d[1], x9 //CTR block 4k+3 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] //AES block 4k+7 - load plaintext +#ifdef __AARCH64EB__ + rev x23, x23 + rev x24, x24 +#endif + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext +#ifdef __AARCH64EB__ + rev x21, x21 + rev x22, x22 +#endif + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x23, x23, x13 //AES block 4k+7 - round 14 low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + mov d10, v17.d[1] //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + eor x22, x22, x14 //AES block 4k+6 - round 14 high + mov d8, v4.d[1] //GHASH block 4k - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext +#ifdef __AARCH64EB__ + rev x19, x19 + rev x20, x20 +#endif + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + mov d4, v7.d[1] //GHASH block 4k+3 - mid + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b //GHASH block 4k+3 - mid + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor x19, x19, x13 //AES block 4k+5 - round 14 low + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + eor x21, x21, x13 //AES block 4k+6 - round 14 low + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + movi v8.8b, #0xc2 + + pmull v4.1q, v4.1d, v16.1d //GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + fmov d5, x19 //AES block 4k+5 - mov low + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + shl d8, d8, #56 //mod_constant + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+3 - mid + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + add w12, w12, #1 //CTR block 4k+3 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + eor v4.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + add x0, x0, #64 //AES input_ptr update + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + rev w9, w12 //CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + eor x6, x6, x13 //AES block 4k+4 - round 14 low + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + eor v10.16b, v10.16b, v4.16b //MODULO - karatsuba tidy up + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + eor x7, x7, x14 //AES block 4k+4 - round 14 high + + fmov d4, x6 //AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b //MODULO - fold into mid + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + eor x20, x20, x14 //AES block 4k+5 - round 14 high + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + eor x24, x24, x14 //AES block 4k+7 - round 14 high + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + add w12, w12, #1 //CTR block 4k+8 + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + fmov v4.d[1], x7 //AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + fmov d7, x23 //AES block 4k+7 - mov low + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + fmov v5.d[1], x20 //AES block 4k+5 - mov high + + fmov d6, x21 //AES block 4k+6 - mov low + cmp x0, x5 //.LOOP CONTROL + + fmov v6.d[1], x22 //AES block 4k+6 - mov high + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result + fmov d0, x10 //CTR block 4k+8 + + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + add w12, w12, #1 //CTR block 4k+9 + + eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result + fmov d1, x10 //CTR block 4k+9 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + fmov v1.d[1], x9 //CTR block 4k+9 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + rev w9, w12 //CTR block 4k+10 + st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result + + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + fmov v7.d[1], x24 //AES block 4k+7 - mov high + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result + add w12, w12, #1 //CTR block 4k+10 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result + fmov d2, x10 //CTR block 4k+10 + + st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result + fmov v2.d[1], x9 //CTR block 4k+10 + rev w9, w12 //CTR block 4k+11 + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + orr x9, x11, x9, lsl #32 //CTR block 4k+11 + + eor v7.16b, v7.16b, v3.16b //AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 //AES block 4k+7 - store result + b.lt .L256_enc_main_loop + +.L256_enc_prepretail: //PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov d3, x10 //CTR block 4k+3 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + fmov v3.d[1], x9 //CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + + eor v4.16b, v4.16b, v11.16b //PRE 1 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + add w12, w12, #1 //CTR block 4k+3 + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + mov d4, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + eor v4.8b, v4.8b, v7.8b //GHASH block 4k+3 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + pmull v4.1q, v4.1d, v16.1d //GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + shl d8, d8, #56 //mod_constant + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+3 - mid + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + eor v10.16b, v10.16b, v9.16b //karatsuba tidy up + + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v11.16b + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + eor v10.16b, v10.16b, v4.16b + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + eor v10.16b, v10.16b, v9.16b + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + + pmull v4.1q, v10.1d, v8.1d + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + ext v10.16b, v10.16b, v10.16b, #8 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + eor v11.16b, v11.16b, v4.16b + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + eor v11.16b, v11.16b, v10.16b +.L256_enc_tail: //TAIL + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + eor x6, x6, x13 //AES block 4k+4 - round 14 low + eor x7, x7, x14 //AES block 4k+4 - round 14 high + + cmp x5, #48 + fmov d4, x6 //AES block 4k+4 - mov low + + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result + b.gt .L256_enc_blocks_more_than_3 + + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + + movi v9.8b, #0 + sub w12, w12, #1 + + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt .L256_enc_blocks_more_than_2 + + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + + b.gt .L256_enc_blocks_more_than_1 + + sub w12, w12, #1 + b .L256_enc_blocks_less_than_1 +.L256_enc_blocks_more_than_3: //blocks left > 3 + st1 { v5.16b}, [x2], #16 //AES final-3 block - store result + + ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + rev64 v4.16b, v5.16b //GHASH final-3 block + + eor x6, x6, x13 //AES final-2 block - round 14 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final-2 block - round 14 high + + mov d22, v4.d[1] //GHASH final-3 block - mid + fmov d5, x6 //AES final-2 block - mov low + + fmov v5.d[1], x7 //AES final-2 block - mov high + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + movi v8.8b, #0 //suppress further partial tag feed in + + mov d10, v17.d[1] //GHASH final-3 block - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b //AES final-2 block - result +.L256_enc_blocks_more_than_2: //blocks left > 2 + + st1 { v5.16b}, [x2], #16 //AES final-2 block - store result + + ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + rev64 v4.16b, v5.16b //GHASH final-2 block + + eor x6, x6, x13 //AES final-1 block - round 14 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + fmov d5, x6 //AES final-1 block - mov low + eor x7, x7, x14 //AES final-1 block - round 14 high + + fmov v5.d[1], x7 //AES final-1 block - mov high + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + eor v5.16b, v5.16b, v2.16b //AES final-1 block - result + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L256_enc_blocks_more_than_1: //blocks left > 1 + + st1 { v5.16b}, [x2], #16 //AES final-1 block - store result + + rev64 v4.16b, v5.16b //GHASH final-1 block + + ldp x6, x7, [x0], #16 //AES final block - load input low & high +#ifdef __AARCH64EB__ + rev x6, x6 + rev x7, x7 +#endif + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + movi v8.8b, #0 //suppress further partial tag feed in + + eor x6, x6, x13 //AES final block - round 14 low + mov d22, v4.d[1] //GHASH final-1 block - mid + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + eor x7, x7, x14 //AES final block - round 14 high + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + fmov d5, x6 //AES final block - mov low + + fmov v5.d[1], x7 //AES final block - mov high + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + eor v5.16b, v5.16b, v3.16b //AES final block - result + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low +.L256_enc_blocks_less_than_1: //blocks left <= 1 + + and x1, x1, #127 //bit_length %= 128 + + mvn x13, xzr //rk14_l = 0xffffffffffffffff + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored + + mvn x14, xzr //rk14_h = 0xffffffffffffffff + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk14_h is mask for top 64b of last block + cmp x1, #64 + + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + + fmov d0, x6 //ctr0b is mask for last block + + fmov v0.d[1], x7 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + mov d8, v4.d[1] //GHASH final block - mid +#ifndef __AARCH64EB__ + rev w9, w12 +#else + mov w9, w12 +#endif + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v4.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v4.16b //MODULO - karatsuba tidy up + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + str w9, [x16, #12] //store the updated counter + + st1 { v5.16b}, [x2] //store all 16B + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_256_kernel,.-aes_gcm_enc_256_kernel +.globl aes_gcm_dec_256_kernel +.type aes_gcm_dec_256_kernel,%function +.align 4 +aes_gcm_dec_256_kernel: + cbz x1, .L256_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 +#ifdef __AARCH64EB__ + rev x10, x10 + rev x11, x11 +#endif + ldp x13, x14, [x8, #224] //load rk14 +#ifdef __AARCH64EB__ + ror x14, x14, #32 + ror x13, x13, #32 +#endif + ld1 {v18.4s}, [x8], #16 //load rk0 + sub x5, x5, #1 //byte_len - 1 + + ld1 {v19.4s}, [x8], #16 //load rk1 + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + add x4, x0, x1, lsr #3 //end_input_ptr + ld1 {v20.4s}, [x8], #16 //load rk2 + + lsr x12, x11, #32 + ld1 {v21.4s}, [x8], #16 //load rk3 + orr w11, w11, w11 + + ld1 {v22.4s}, [x8], #16 //load rk4 + add x5, x5, x0 + rev w12, w12 //rev_ctr32 + + add w12, w12, #1 //increment rev_ctr32 + fmov d3, x10 //CTR block 3 + + rev w9, w12 //CTR block 1 + add w12, w12, #1 //CTR block 1 + fmov d1, x10 //CTR block 1 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 3 + ld1 {v23.4s}, [x8], #16 //load rk5 + + fmov v3.d[1], x9 //CTR block 3 + add w12, w12, #1 //CTR block 3 + + ld1 {v24.4s}, [x8], #16 //load rk6 + + ld1 {v25.4s}, [x8], #16 //load rk7 + + ld1 {v26.4s}, [x8], #16 //load rk8 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + ldr q14, [x3, #80] //load h3l | h3h +#ifndef __AARCH64EB__ + ext v14.16b, v14.16b, v14.16b, #8 +#endif + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q15, [x3, #112] //load h4l | h4h +#ifndef __AARCH64EB__ + ext v15.16b, v15.16b, v15.16b, #8 +#endif + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q13, [x3, #64] //load h2l | h2h +#ifndef __AARCH64EB__ + ext v13.16b, v13.16b, v13.16b, #8 +#endif + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ld1 {v27.4s}, [x8], #16 //load rk9 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ld1 {v28.4s}, [x8], #16 //load rk10 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ld1 {v29.4s}, [x8], #16 //load rk11 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ldr q12, [x3, #32] //load h1l | h1h +#ifndef __AARCH64EB__ + ext v12.16b, v12.16b, v12.16b, #8 +#endif + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ld1 {v30.4s}, [x8], #16 //load rk12 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + cmp x0, x5 //check if we have <= 4 blocks + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + ld1 {v31.4s}, [x8], #16 //load rk13 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 0 - round 11 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 3 - round 11 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 1 - round 11 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 2 - round 11 + + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 1 - round 12 + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 0 - round 12 + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 2 - round 12 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 3 - round 12 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v1.16b, v31.16b //AES block 1 - round 13 + + aese v2.16b, v31.16b //AES block 2 - round 13 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v3.16b, v31.16b //AES block 3 - round 13 + + aese v0.16b, v31.16b //AES block 0 - round 13 + b.ge .L256_dec_tail //handle tail + + ld1 {v4.16b, v5.16b}, [x0], #32 //AES block 0,1 - load ciphertext + + rev w9, w12 //CTR block 4 + + eor v0.16b, v4.16b, v0.16b //AES block 0 - result + + eor v1.16b, v5.16b, v1.16b //AES block 1 - result + rev64 v5.16b, v5.16b //GHASH block 1 + ld1 {v6.16b}, [x0], #16 //AES block 2 - load ciphertext + + mov x7, v0.d[1] //AES block 0 - mov high + + mov x6, v0.d[0] //AES block 0 - mov low + rev64 v4.16b, v4.16b //GHASH block 0 + add w12, w12, #1 //CTR block 4 + + fmov d0, x10 //CTR block 4 + orr x9, x11, x9, lsl #32 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + add w12, w12, #1 //CTR block 5 + + mov x19, v1.d[0] //AES block 1 - mov low + + orr x9, x11, x9, lsl #32 //CTR block 5 + mov x20, v1.d[1] //AES block 1 - mov high + eor x7, x7, x14 //AES block 0 - round 14 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + eor x6, x6, x13 //AES block 0 - round 14 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + stp x6, x7, [x2], #16 //AES block 0 - store result + fmov d1, x10 //CTR block 5 + + ld1 {v7.16b}, [x0], #16 //AES block 3 - load ciphertext + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + add w12, w12, #1 //CTR block 6 + + eor x19, x19, x13 //AES block 1 - round 14 low +#ifdef __AARCH64EB__ + rev x19, x19 +#endif + orr x9, x11, x9, lsl #32 //CTR block 6 + + eor x20, x20, x14 //AES block 1 - round 14 high +#ifdef __AARCH64EB__ + rev x20, x20 +#endif + stp x19, x20, [x2], #16 //AES block 1 - store result + + eor v2.16b, v6.16b, v2.16b //AES block 2 - result + cmp x0, x5 //check if we have <= 8 blocks + b.ge .L256_dec_prepretail //do prepretail + +.L256_dec_main_loop: //main loop start + mov x21, v2.d[0] //AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov x22, v2.d[1] //AES block 4k+2 - mov high + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d2, x10 //CTR block 4k+6 + + fmov v2.d[1], x9 //CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b //PRE 1 + rev w9, w12 //CTR block 4k+7 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor x22, x22, x14 //AES block 4k+2 - round 14 high +#ifdef __AARCH64EB__ + rev x22, x22 +#endif + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x21, x21, x13 //AES block 4k+2 - round 14 low +#ifdef __AARCH64EB__ + rev x21, x21 +#endif + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor x23, x23, x13 //AES block 4k+3 - round 14 low +#ifdef __AARCH64EB__ + rev x23, x23 +#endif + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + eor x24, x24, x14 //AES block 4k+3 - round 14 high +#ifdef __AARCH64EB__ + rev x24, x24 +#endif + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + add w12, w12, #1 //CTR block 4k+7 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + rev w9, w12 //CTR block 4k+8 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + add w12, w12, #1 //CTR block 4k+8 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + mov d6, v7.d[1] //GHASH block 4k+3 - mid + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + pmull v4.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v6.8b, v6.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + pmull v6.1q, v6.1d, v16.1d //GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b //GHASH block 4k+3 - low + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + shl d8, d8, #56 //mod_constant + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b //GHASH block 4k+3 - mid + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + ld1 {v4.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + ld1 {v5.16b}, [x0], #16 //AES block 4k+5 - load ciphertext + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + ld1 {v6.16b}, [x0], #16 //AES block 4k+6 - load ciphertext + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + ld1 {v7.16b}, [x0], #16 //AES block 4k+7 - load ciphertext + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + mov x7, v0.d[1] //AES block 4k+4 - mov high + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + mov x6, v0.d[0] //AES block 4k+4 - mov low + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + fmov d0, x10 //CTR block 4k+8 + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + fmov v0.d[1], x9 //CTR block 4k+8 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result + rev w9, w12 //CTR block 4k+9 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + cmp x0, x5 //.LOOP CONTROL + + add w12, w12, #1 //CTR block 4k+9 + + eor x6, x6, x13 //AES block 4k+4 - round 14 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor x7, x7, x14 //AES block 4k+4 - round 14 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + mov x20, v1.d[1] //AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + mov x19, v1.d[0] //AES block 4k+5 - mov low + + fmov d1, x10 //CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + add w12, w12, #1 //CTR block 4k+10 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + rev64 v5.16b, v5.16b //GHASH block 4k+5 + eor x20, x20, x14 //AES block 4k+5 - round 14 high +#ifdef __AARCH64EB__ + rev x20, x20 +#endif + stp x6, x7, [x2], #16 //AES block 4k+4 - store result + + eor x19, x19, x13 //AES block 4k+5 - round 14 low +#ifdef __AARCH64EB__ + rev x19, x19 +#endif + stp x19, x20, [x2], #16 //AES block 4k+5 - store result + + rev64 v4.16b, v4.16b //GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + b.lt .L256_dec_main_loop + + +.L256_dec_prepretail: //PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov x22, v2.d[1] //AES block 4k+2 - mov high + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d2, x10 //CTR block 4k+6 + + fmov v2.d[1], x9 //CTR block 4k+6 + rev w9, w12 //CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + rev64 v6.16b, v6.16b //GHASH block 4k+2 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + + pmull v4.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + mov d6, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b //GHASH block 4k+3 - low + + pmull v6.1q, v6.1d, v16.1d //GHASH block 4k+3 - mid + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b //GHASH block 4k+3 - mid + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + shl d8, d8, #56 //mod_constant + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + eor x22, x22, x14 //AES block 4k+2 - round 14 high +#ifdef __AARCH64EB__ + rev x22, x22 +#endif + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor x23, x23, x13 //AES block 4k+3 - round 14 low +#ifdef __AARCH64EB__ + rev x23, x23 +#endif + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + add w12, w12, #1 //CTR block 4k+7 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + eor x21, x21, x13 //AES block 4k+2 - round 14 low +#ifdef __AARCH64EB__ + rev x21, x21 +#endif + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor x24, x24, x14 //AES block 4k+3 - round 14 high +#ifdef __AARCH64EB__ + rev x24, x24 +#endif + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low +.L256_dec_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result + + mov x6, v0.d[0] //AES block 4k+4 - mov low + + mov x7, v0.d[1] //AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + + cmp x5, #48 + + eor x6, x6, x13 //AES block 4k+4 - round 14 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + + eor x7, x7, x14 //AES block 4k+4 - round 14 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif + b.gt .L256_dec_blocks_more_than_3 + + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + + movi v11.8b, #0 + cmp x5, #32 + + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt .L256_dec_blocks_more_than_2 + + sub w12, w12, #1 + + mov v3.16b, v1.16b + cmp x5, #16 + b.gt .L256_dec_blocks_more_than_1 + + sub w12, w12, #1 + b .L256_dec_blocks_less_than_1 +.L256_dec_blocks_more_than_3: //blocks left > 3 + rev64 v4.16b, v5.16b //GHASH final-3 block + ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext + + stp x6, x7, [x2], #16 //AES final-3 block - store result + + mov d10, v17.d[1] //GHASH final-3 block - mid + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor v0.16b, v5.16b, v1.16b //AES final-2 block - result + + mov d22, v4.d[1] //GHASH final-3 block - mid + + mov x6, v0.d[0] //AES final-2 block - mov low + + mov x7, v0.d[1] //AES final-2 block - mov high + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor x6, x6, x13 //AES final-2 block - round 14 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + eor x7, x7, x14 //AES final-2 block - round 14 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif +.L256_dec_blocks_more_than_2: //blocks left > 2 + + rev64 v4.16b, v5.16b //GHASH final-2 block + ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + stp x6, x7, [x2], #16 //AES final-2 block - store result + + eor v0.16b, v5.16b, v2.16b //AES final-1 block - result + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + mov x6, v0.d[0] //AES final-1 block - mov low + + mov x7, v0.d[1] //AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + movi v8.8b, #0 //suppress further partial tag feed in + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + eor x6, x6, x13 //AES final-1 block - round 14 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid + eor x7, x7, x14 //AES final-1 block - round 14 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif +.L256_dec_blocks_more_than_1: //blocks left > 1 + + stp x6, x7, [x2], #16 //AES final-1 block - store result + rev64 v4.16b, v5.16b //GHASH final-1 block + + ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + movi v8.8b, #0 //suppress further partial tag feed in + + mov d22, v4.d[1] //GHASH final-1 block - mid + + eor v0.16b, v5.16b, v3.16b //AES final block - result + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + mov x6, v0.d[0] //AES final block - mov low + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + mov x7, v0.d[1] //AES final block - mov high + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + eor x6, x6, x13 //AES final block - round 14 low +#ifdef __AARCH64EB__ + rev x6, x6 +#endif + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid + eor x7, x7, x14 //AES final block - round 14 high +#ifdef __AARCH64EB__ + rev x7, x7 +#endif +.L256_dec_blocks_less_than_1: //blocks left <= 1 + + and x1, x1, #127 //bit_length %= 128 + mvn x14, xzr //rk14_h = 0xffffffffffffffff + + sub x1, x1, #128 //bit_length -= 128 + mvn x13, xzr //rk14_l = 0xffffffffffffffff + + ldp x4, x5, [x2] //load existing bytes we need to not overwrite + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk14_h is mask for top 64b of last block + cmp x1, #64 + + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + + fmov d0, x9 //ctr0b is mask for last block + and x6, x6, x9 + + mov v0.d[1], x10 + bic x4, x4, x9 //mask out low existing bytes + +#ifndef __AARCH64EB__ + rev w9, w12 +#else + mov w9, w12 +#endif + + bic x5, x5, x10 //mask out high existing bytes + + orr x6, x6, x4 + + and x7, x7, x10 + + orr x7, x7, x5 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + mov d8, v4.d[1] //GHASH final block - mid + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + stp x6, x7, [x2] + + str w9, [x16, #12] //store the updated counter + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_256_kernel,.-aes_gcm_dec_256_kernel +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S new file mode 100644 index 0000000000..ae1afff441 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S @@ -0,0 +1,552 @@ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=7 +.arch armv8-a+crypto +.text +.globl gcm_init_v8 +.type gcm_init_v8,%function +.align 4 +gcm_init_v8: + ld1 {v17.2d},[x1] //load input H + movi v19.16b,#0xe1 + shl v19.2d,v19.2d,#57 //0xc2.0 + ext v3.16b,v17.16b,v17.16b,#8 + ushr v18.2d,v19.2d,#63 + dup v17.4s,v17.s[1] + ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01 + ushr v18.2d,v3.2d,#63 + sshr v17.4s,v17.4s,#31 //broadcast carry bit + and v18.16b,v18.16b,v16.16b + shl v3.2d,v3.2d,#1 + ext v18.16b,v18.16b,v18.16b,#8 + and v16.16b,v16.16b,v17.16b + orr v3.16b,v3.16b,v18.16b //H<<<=1 + eor v20.16b,v3.16b,v16.16b //twisted H + st1 {v20.2d},[x0],#16 //store Htable[0] + + //calculate H^2 + ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing + pmull v0.1q,v20.1d,v20.1d + eor v16.16b,v16.16b,v20.16b + pmull2 v2.1q,v20.2d,v20.2d + pmull v1.1q,v16.1d,v16.1d + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v22.16b,v0.16b,v18.16b + + ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v21.2d,v22.2d},[x0],#32 //store Htable[1..2] + //calculate H^3 and H^4 + pmull v0.1q,v20.1d, v22.1d + pmull v5.1q,v22.1d,v22.1d + pmull2 v2.1q,v20.2d, v22.2d + pmull2 v7.1q,v22.2d,v22.2d + pmull v1.1q,v16.1d,v17.1d + pmull v6.1q,v17.1d,v17.1d + + ext v16.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + ext v17.16b,v5.16b,v7.16b,#8 + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v16.16b + eor v4.16b,v5.16b,v7.16b + eor v6.16b,v6.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + eor v6.16b,v6.16b,v4.16b + pmull v4.1q,v5.1d,v19.1d + + ins v2.d[0],v1.d[1] + ins v7.d[0],v6.d[1] + ins v1.d[1],v0.d[0] + ins v6.d[1],v5.d[0] + eor v0.16b,v1.16b,v18.16b + eor v5.16b,v6.16b,v4.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + ext v4.16b,v5.16b,v5.16b,#8 + pmull v0.1q,v0.1d,v19.1d + pmull v5.1q,v5.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v4.16b,v4.16b,v7.16b + eor v20.16b, v0.16b,v18.16b //H^3 + eor v22.16b,v5.16b,v4.16b //H^4 + + ext v16.16b,v20.16b, v20.16b,#8 //Karatsuba pre-processing + ext v17.16b,v22.16b,v22.16b,#8 + eor v16.16b,v16.16b,v20.16b + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v20.2d,v21.2d,v22.2d},[x0] //store Htable[3..5] + ret +.size gcm_init_v8,.-gcm_init_v8 +.globl gcm_gmult_v8 +.type gcm_gmult_v8,%function +.align 4 +gcm_gmult_v8: + ld1 {v17.2d},[x0] //load Xi + movi v19.16b,#0xe1 + ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... + shl v19.2d,v19.2d,#57 +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ext v3.16b,v17.16b,v17.16b,#8 + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_gmult_v8,.-gcm_gmult_v8 +.globl gcm_ghash_v8 +.type gcm_ghash_v8,%function +.align 4 +gcm_ghash_v8: + cmp x3,#64 + b.hs .Lgcm_ghash_v8_4x + ld1 {v0.2d},[x0] //load [rotated] Xi + //"[rotated]" means that + //loaded value would have + //to be rotated in order to + //make it appear as in + //algorithm specification + subs x3,x3,#32 //see if x3 is 32 or larger + mov x12,#16 //x12 is used as post- + //increment for input pointer; + //as loop is modulo-scheduled + //x12 is zeroed just in time + //to preclude overstepping + //inp[len], which means that + //last block[s] are actually + //loaded twice, but last + //copy is not processed + ld1 {v20.2d,v21.2d},[x1],#32 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v22.2d},[x1] + csel x12,xzr,x12,eq //is it time to zero x12? + ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi + ld1 {v16.2d},[x2],#16 //load [rotated] I[0] + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant +#ifndef __ARMEB__ + rev64 v16.16b,v16.16b + rev64 v0.16b,v0.16b +#endif + ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] + b.lo .Lodd_tail_v8 //x3 was less than 32 + ld1 {v17.2d},[x2],x12 //load [rotated] I[1] +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ext v7.16b,v17.16b,v17.16b,#8 + eor v3.16b,v3.16b,v0.16b //I[i]^=Xi + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + pmull2 v6.1q,v20.2d,v7.2d + b .Loop_mod2x_v8 + +.align 4 +.Loop_mod2x_v8: + ext v18.16b,v3.16b,v3.16b,#8 + subs x3,x3,#32 //is there more data? + pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo + csel x12,xzr,x12,lo //is it time to zero x12? + + pmull v5.1q,v21.1d,v17.1d + eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi + eor v0.16b,v0.16b,v4.16b //accumulate + pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2] + + eor v2.16b,v2.16b,v6.16b + csel x12,xzr,x12,eq //is it time to zero x12? + eor v1.16b,v1.16b,v5.16b + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] +#ifndef __ARMEB__ + rev64 v16.16b,v16.16b +#endif + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v7.16b,v17.16b,v17.16b,#8 + ext v3.16b,v16.16b,v16.16b,#8 + eor v0.16b,v1.16b,v18.16b + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v3.16b,v3.16b,v18.16b + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + eor v3.16b,v3.16b,v0.16b + pmull2 v6.1q,v20.2d,v7.2d + b.hs .Loop_mod2x_v8 //there was at least 32 more bytes + + eor v2.16b,v2.16b,v18.16b + ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b + adds x3,x3,#32 //re-construct x3 + eor v0.16b,v0.16b,v2.16b //re-construct v0.16b + b.eq .Ldone_v8 //is x3 zero? +.Lodd_tail_v8: + ext v18.16b,v0.16b,v0.16b,#8 + eor v3.16b,v3.16b,v0.16b //inp^=Xi + eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +.Ldone_v8: +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8,.-gcm_ghash_v8 +.type gcm_ghash_v8_4x,%function +.align 4 +gcm_ghash_v8_4x: +.Lgcm_ghash_v8_4x: + ld1 {v0.2d},[x0] //load [rotated] Xi + ld1 {v20.2d,v21.2d,v22.2d},[x1],#48 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v26.2d,v27.2d,v28.2d},[x1] //load twisted H^3, ..., H^4 + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant + + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + ext v25.16b,v7.16b,v7.16b,#8 + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + pmull2 v31.1q,v20.2d,v25.2d + pmull v30.1q,v21.1d,v7.1d + + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#128 + b.lo .Ltail4x + + b .Loop4x + +.align 4 +.Loop4x: + eor v16.16b,v4.16b,v0.16b + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 + ext v3.16b,v16.16b,v16.16b,#8 +#ifndef __ARMEB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + ext v25.16b,v7.16b,v7.16b,#8 + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + ext v24.16b,v6.16b,v6.16b,#8 + eor v1.16b,v1.16b,v30.16b + ext v23.16b,v5.16b,v5.16b,#8 + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + eor v1.16b,v1.16b,v17.16b + pmull2 v31.1q,v20.2d,v25.2d + eor v1.16b,v1.16b,v18.16b + pmull v30.1q,v21.1d,v7.1d + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + eor v0.16b,v1.16b,v18.16b + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + eor v18.16b,v18.16b,v2.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v0.16b,v0.16b,v18.16b + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#64 + b.hs .Loop4x + +.Ltail4x: + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + + adds x3,x3,#64 + b.eq .Ldone4x + + cmp x3,#32 + b.lo .Lone + b.eq .Ltwo +.Lthree: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d,v6.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __ARMEB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + pmull v29.1q,v20.1d,v24.1d //H·Ii+2 + eor v6.16b,v6.16b,v24.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + pmull2 v31.1q,v20.2d,v24.2d + pmull v30.1q,v21.1d,v6.1d + eor v0.16b,v0.16b,v18.16b + pmull v7.1q,v22.1d,v23.1d //H^2·Ii+1 + eor v5.16b,v5.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull2 v23.1q,v22.2d,v23.2d + eor v16.16b,v4.16b,v0.16b + pmull2 v5.1q,v21.2d,v5.2d + ext v3.16b,v16.16b,v16.16b,#8 + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + pmull v0.1q,v26.1d,v3.1d //H^3·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v26.2d,v3.2d + pmull v1.1q,v27.1d,v16.1d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b .Ldone4x + +.align 4 +.Ltwo: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __ARMEB__ + rev64 v5.16b,v5.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull v29.1q,v20.1d,v23.1d //H·Ii+1 + eor v5.16b,v5.16b,v23.16b + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull2 v31.1q,v20.2d,v23.2d + pmull v30.1q,v21.1d,v5.1d + + pmull v0.1q,v22.1d,v3.1d //H^2·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v22.2d,v3.2d + pmull2 v1.1q,v21.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b .Ldone4x + +.align 4 +.Lone: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __ARMEB__ + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v20.1d,v3.1d + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v20.2d,v3.2d + pmull v1.1q,v21.1d,v16.1d + +.Ldone4x: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8_4x,.-gcm_ghash_v8_4x +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S new file mode 100644 index 0000000000..67e553f976 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S @@ -0,0 +1,1009 @@ +.text + +.align 8 // strategic alignment and padding that allows to use + // address value as loop termination condition... +.quad 0,0,0,0,0,0,0,0 +.type iotas,%object +iotas: +.quad 0x0000000000000001 +.quad 0x0000000000008082 +.quad 0x800000000000808a +.quad 0x8000000080008000 +.quad 0x000000000000808b +.quad 0x0000000080000001 +.quad 0x8000000080008081 +.quad 0x8000000000008009 +.quad 0x000000000000008a +.quad 0x0000000000000088 +.quad 0x0000000080008009 +.quad 0x000000008000000a +.quad 0x000000008000808b +.quad 0x800000000000008b +.quad 0x8000000000008089 +.quad 0x8000000000008003 +.quad 0x8000000000008002 +.quad 0x8000000000000080 +.quad 0x000000000000800a +.quad 0x800000008000000a +.quad 0x8000000080008081 +.quad 0x8000000000008080 +.quad 0x0000000080000001 +.quad 0x8000000080008008 +.size iotas,.-iotas +.type KeccakF1600_int,%function +.align 5 +KeccakF1600_int: + adr x28,iotas +.inst 0xd503233f // paciasp + stp x28,x30,[sp,#16] // 32 bytes on top are mine + b .Loop +.align 4 +.Loop: + ////////////////////////////////////////// Theta + eor x26,x0,x5 + stp x4,x9,[sp,#0] // offload pair... + eor x27,x1,x6 + eor x28,x2,x7 + eor x30,x3,x8 + eor x4,x4,x9 + eor x26,x26,x10 + eor x27,x27,x11 + eor x28,x28,x12 + eor x30,x30,x13 + eor x4,x4,x14 + eor x26,x26,x15 + eor x27,x27,x16 + eor x28,x28,x17 + eor x30,x30,x25 + eor x4,x4,x19 + eor x26,x26,x20 + eor x28,x28,x22 + eor x27,x27,x21 + eor x30,x30,x23 + eor x4,x4,x24 + + eor x9,x26,x28,ror#63 + + eor x1,x1,x9 + eor x6,x6,x9 + eor x11,x11,x9 + eor x16,x16,x9 + eor x21,x21,x9 + + eor x9,x27,x30,ror#63 + eor x28,x28,x4,ror#63 + eor x30,x30,x26,ror#63 + eor x4,x4,x27,ror#63 + + eor x27, x2,x9 // mov x27,x2 + eor x7,x7,x9 + eor x12,x12,x9 + eor x17,x17,x9 + eor x22,x22,x9 + + eor x0,x0,x4 + eor x5,x5,x4 + eor x10,x10,x4 + eor x15,x15,x4 + eor x20,x20,x4 + ldp x4,x9,[sp,#0] // re-load offloaded data + eor x26, x3,x28 // mov x26,x3 + eor x8,x8,x28 + eor x13,x13,x28 + eor x25,x25,x28 + eor x23,x23,x28 + + eor x28, x4,x30 // mov x28,x4 + eor x9,x9,x30 + eor x14,x14,x30 + eor x19,x19,x30 + eor x24,x24,x30 + + ////////////////////////////////////////// Rho+Pi + mov x30,x1 + ror x1,x6,#64-44 + //mov x27,x2 + ror x2,x12,#64-43 + //mov x26,x3 + ror x3,x25,#64-21 + //mov x28,x4 + ror x4,x24,#64-14 + + ror x6,x9,#64-20 + ror x12,x13,#64-25 + ror x25,x17,#64-15 + ror x24,x21,#64-2 + + ror x9,x22,#64-61 + ror x13,x19,#64-8 + ror x17,x11,#64-10 + ror x21,x8,#64-55 + + ror x22,x14,#64-39 + ror x19,x23,#64-56 + ror x11,x7,#64-6 + ror x8,x16,#64-45 + + ror x14,x20,#64-18 + ror x23,x15,#64-41 + ror x7,x10,#64-3 + ror x16,x5,#64-36 + + ror x5,x26,#64-28 + ror x10,x30,#64-1 + ror x15,x28,#64-27 + ror x20,x27,#64-62 + + ////////////////////////////////////////// Chi+Iota + bic x26,x2,x1 + bic x27,x3,x2 + bic x28,x0,x4 + bic x30,x1,x0 + eor x0,x0,x26 + bic x26,x4,x3 + eor x1,x1,x27 + ldr x27,[sp,#16] + eor x3,x3,x28 + eor x4,x4,x30 + eor x2,x2,x26 + ldr x30,[x27],#8 // Iota[i++] + + bic x26,x7,x6 + tst x27,#255 // are we done? + str x27,[sp,#16] + bic x27,x8,x7 + bic x28,x5,x9 + eor x0,x0,x30 // A[0][0] ^= Iota + bic x30,x6,x5 + eor x5,x5,x26 + bic x26,x9,x8 + eor x6,x6,x27 + eor x8,x8,x28 + eor x9,x9,x30 + eor x7,x7,x26 + + bic x26,x12,x11 + bic x27,x13,x12 + bic x28,x10,x14 + bic x30,x11,x10 + eor x10,x10,x26 + bic x26,x14,x13 + eor x11,x11,x27 + eor x13,x13,x28 + eor x14,x14,x30 + eor x12,x12,x26 + + bic x26,x17,x16 + bic x27,x25,x17 + bic x28,x15,x19 + bic x30,x16,x15 + eor x15,x15,x26 + bic x26,x19,x25 + eor x16,x16,x27 + eor x25,x25,x28 + eor x19,x19,x30 + eor x17,x17,x26 + + bic x26,x22,x21 + bic x27,x23,x22 + bic x28,x20,x24 + bic x30,x21,x20 + eor x20,x20,x26 + bic x26,x24,x23 + eor x21,x21,x27 + eor x23,x23,x28 + eor x24,x24,x30 + eor x22,x22,x26 + + bne .Loop + + ldr x30,[sp,#24] +.inst 0xd50323bf // autiasp + ret +.size KeccakF1600_int,.-KeccakF1600_int + +.type KeccakF1600,%function +.align 5 +KeccakF1600: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#48 + + str x0,[sp,#32] // offload argument + mov x26,x0 + ldp x0,x1,[x0,#16*0] + ldp x2,x3,[x26,#16*1] + ldp x4,x5,[x26,#16*2] + ldp x6,x7,[x26,#16*3] + ldp x8,x9,[x26,#16*4] + ldp x10,x11,[x26,#16*5] + ldp x12,x13,[x26,#16*6] + ldp x14,x15,[x26,#16*7] + ldp x16,x17,[x26,#16*8] + ldp x25,x19,[x26,#16*9] + ldp x20,x21,[x26,#16*10] + ldp x22,x23,[x26,#16*11] + ldr x24,[x26,#16*12] + + bl KeccakF1600_int + + ldr x26,[sp,#32] + stp x0,x1,[x26,#16*0] + stp x2,x3,[x26,#16*1] + stp x4,x5,[x26,#16*2] + stp x6,x7,[x26,#16*3] + stp x8,x9,[x26,#16*4] + stp x10,x11,[x26,#16*5] + stp x12,x13,[x26,#16*6] + stp x14,x15,[x26,#16*7] + stp x16,x17,[x26,#16*8] + stp x25,x19,[x26,#16*9] + stp x20,x21,[x26,#16*10] + stp x22,x23,[x26,#16*11] + str x24,[x26,#16*12] + + ldp x19,x20,[x29,#16] + add sp,sp,#48 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size KeccakF1600,.-KeccakF1600 + +.globl SHA3_absorb +.type SHA3_absorb,%function +.align 5 +SHA3_absorb: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#64 + + stp x0,x1,[sp,#32] // offload arguments + stp x2,x3,[sp,#48] + + mov x26,x0 // uint64_t A[5][5] + mov x27,x1 // const void *inp + mov x28,x2 // size_t len + mov x30,x3 // size_t bsz + ldp x0,x1,[x26,#16*0] + ldp x2,x3,[x26,#16*1] + ldp x4,x5,[x26,#16*2] + ldp x6,x7,[x26,#16*3] + ldp x8,x9,[x26,#16*4] + ldp x10,x11,[x26,#16*5] + ldp x12,x13,[x26,#16*6] + ldp x14,x15,[x26,#16*7] + ldp x16,x17,[x26,#16*8] + ldp x25,x19,[x26,#16*9] + ldp x20,x21,[x26,#16*10] + ldp x22,x23,[x26,#16*11] + ldr x24,[x26,#16*12] + b .Loop_absorb + +.align 4 +.Loop_absorb: + subs x26,x28,x30 // len - bsz + blo .Labsorbed + + str x26,[sp,#48] // save len - bsz + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x0,x0,x26 + cmp x30,#8*(0+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x1,x1,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x2,x2,x26 + cmp x30,#8*(2+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x3,x3,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x4,x4,x26 + cmp x30,#8*(4+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x5,x5,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x6,x6,x26 + cmp x30,#8*(6+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x7,x7,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x8,x8,x26 + cmp x30,#8*(8+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x9,x9,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x10,x10,x26 + cmp x30,#8*(10+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x11,x11,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x12,x12,x26 + cmp x30,#8*(12+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x13,x13,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x14,x14,x26 + cmp x30,#8*(14+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x15,x15,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x16,x16,x26 + cmp x30,#8*(16+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x17,x17,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x25,x25,x26 + cmp x30,#8*(18+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x19,x19,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x20,x20,x26 + cmp x30,#8*(20+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x21,x21,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x22,x22,x26 + cmp x30,#8*(22+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x23,x23,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x24,x24,x26 + +.Lprocess_block: + str x27,[sp,#40] // save inp + + bl KeccakF1600_int + + ldr x27,[sp,#40] // restore arguments + ldp x28,x30,[sp,#48] + b .Loop_absorb + +.align 4 +.Labsorbed: + ldr x27,[sp,#32] + stp x0,x1,[x27,#16*0] + stp x2,x3,[x27,#16*1] + stp x4,x5,[x27,#16*2] + stp x6,x7,[x27,#16*3] + stp x8,x9,[x27,#16*4] + stp x10,x11,[x27,#16*5] + stp x12,x13,[x27,#16*6] + stp x14,x15,[x27,#16*7] + stp x16,x17,[x27,#16*8] + stp x25,x19,[x27,#16*9] + stp x20,x21,[x27,#16*10] + stp x22,x23,[x27,#16*11] + str x24,[x27,#16*12] + + mov x0,x28 // return value + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size SHA3_absorb,.-SHA3_absorb +.globl SHA3_squeeze +.type SHA3_squeeze,%function +.align 5 +SHA3_squeeze: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-48]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + + mov x19,x0 // put aside arguments + mov x20,x1 + mov x21,x2 + mov x22,x3 + +.Loop_squeeze: + ldr x4,[x0],#8 + cmp x21,#8 + blo .Lsqueeze_tail +#ifdef __AARCH64EB__ + rev x4,x4 +#endif + str x4,[x20],#8 + subs x21,x21,#8 + beq .Lsqueeze_done + + subs x3,x3,#8 + bhi .Loop_squeeze + + mov x0,x19 + bl KeccakF1600 + mov x0,x19 + mov x3,x22 + b .Loop_squeeze + +.align 4 +.Lsqueeze_tail: + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + +.Lsqueeze_done: + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x29,x30,[sp],#48 +.inst 0xd50323bf // autiasp + ret +.size SHA3_squeeze,.-SHA3_squeeze +.type KeccakF1600_ce,%function +.align 5 +KeccakF1600_ce: + mov x9,#24 + adr x10,iotas + b .Loop_ce +.align 4 +.Loop_ce: + ////////////////////////////////////////////////// Theta +.inst 0xce0f2a99 //eor3 v25.16b,v20.16b,v15.16b,v10.16b +.inst 0xce102eba //eor3 v26.16b,v21.16b,v16.16b,v11.16b +.inst 0xce1132db //eor3 v27.16b,v22.16b,v17.16b,v12.16b +.inst 0xce1236fc //eor3 v28.16b,v23.16b,v18.16b,v13.16b +.inst 0xce133b1d //eor3 v29.16b,v24.16b,v19.16b,v14.16b +.inst 0xce050339 //eor3 v25.16b,v25.16b, v5.16b,v0.16b +.inst 0xce06075a //eor3 v26.16b,v26.16b, v6.16b,v1.16b +.inst 0xce070b7b //eor3 v27.16b,v27.16b, v7.16b,v2.16b +.inst 0xce080f9c //eor3 v28.16b,v28.16b, v8.16b,v3.16b +.inst 0xce0913bd //eor3 v29.16b,v29.16b, v9.16b,v4.16b + +.inst 0xce7b8f3e //rax1 v30.16b,v25.16b,v27.16b // D[1] +.inst 0xce7c8f5f //rax1 v31.16b,v26.16b,v28.16b // D[2] +.inst 0xce7d8f7b //rax1 v27.16b,v27.16b,v29.16b // D[3] +.inst 0xce798f9c //rax1 v28.16b,v28.16b,v25.16b // D[4] +.inst 0xce7a8fbd //rax1 v29.16b,v29.16b,v26.16b // D[0] + + ////////////////////////////////////////////////// Theta+Rho+Pi +.inst 0xce9efc39 //xar v25.16b, v1.16b,v30.16b,#64-1 // C[0]=A[2][0] + +.inst 0xce9e50c1 //xar v1.16b,v6.16b,v30.16b,#64-44 +.inst 0xce9cb126 //xar v6.16b,v9.16b,v28.16b,#64-20 +.inst 0xce9f0ec9 //xar v9.16b,v22.16b,v31.16b,#64-61 +.inst 0xce9c65d6 //xar v22.16b,v14.16b,v28.16b,#64-39 +.inst 0xce9dba8e //xar v14.16b,v20.16b,v29.16b,#64-18 + +.inst 0xce9f085a //xar v26.16b, v2.16b,v31.16b,#64-62 // C[1]=A[4][0] + +.inst 0xce9f5582 //xar v2.16b,v12.16b,v31.16b,#64-43 +.inst 0xce9b9dac //xar v12.16b,v13.16b,v27.16b,#64-25 +.inst 0xce9ce26d //xar v13.16b,v19.16b,v28.16b,#64-8 +.inst 0xce9b22f3 //xar v19.16b,v23.16b,v27.16b,#64-56 +.inst 0xce9d5df7 //xar v23.16b,v15.16b,v29.16b,#64-41 + +.inst 0xce9c948f //xar v15.16b,v4.16b,v28.16b,#64-27 + +.inst 0xce9ccb1c //xar v28.16b, v24.16b,v28.16b,#64-14 // D[4]=A[0][4] +.inst 0xce9efab8 //xar v24.16b,v21.16b,v30.16b,#64-2 +.inst 0xce9b2508 //xar v8.16b,v8.16b,v27.16b,#64-55 // A[1][3]=A[4][1] +.inst 0xce9e4e04 //xar v4.16b,v16.16b,v30.16b,#64-45 // A[0][4]=A[1][3] +.inst 0xce9d70b0 //xar v16.16b,v5.16b,v29.16b,#64-36 + +.inst 0xce9b9065 //xar v5.16b,v3.16b,v27.16b,#64-28 + + eor v0.16b,v0.16b,v29.16b + +.inst 0xce9bae5b //xar v27.16b, v18.16b,v27.16b,#64-21 // D[3]=A[0][3] +.inst 0xce9fc623 //xar v3.16b,v17.16b,v31.16b,#64-15 // A[0][3]=A[3][3] +.inst 0xce9ed97e //xar v30.16b, v11.16b,v30.16b,#64-10 // D[1]=A[3][2] +.inst 0xce9fe8ff //xar v31.16b, v7.16b,v31.16b,#64-6 // D[2]=A[2][1] +.inst 0xce9df55d //xar v29.16b, v10.16b,v29.16b,#64-3 // D[0]=A[1][2] + + ////////////////////////////////////////////////// Chi+Iota +.inst 0xce362354 //bcax v20.16b,v26.16b, v22.16b,v8.16b // A[1][3]=A[4][1] +.inst 0xce375915 //bcax v21.16b,v8.16b,v23.16b,v22.16b // A[1][3]=A[4][1] +.inst 0xce385ed6 //bcax v22.16b,v22.16b,v24.16b,v23.16b +.inst 0xce3a62f7 //bcax v23.16b,v23.16b,v26.16b, v24.16b +.inst 0xce286b18 //bcax v24.16b,v24.16b,v8.16b,v26.16b // A[1][3]=A[4][1] + + ld1r {v26.2d},[x10],#8 + +.inst 0xce330fd1 //bcax v17.16b,v30.16b, v19.16b,v3.16b // A[0][3]=A[3][3] +.inst 0xce2f4c72 //bcax v18.16b,v3.16b,v15.16b,v19.16b // A[0][3]=A[3][3] +.inst 0xce303e73 //bcax v19.16b,v19.16b,v16.16b,v15.16b +.inst 0xce3e41ef //bcax v15.16b,v15.16b,v30.16b, v16.16b +.inst 0xce237a10 //bcax v16.16b,v16.16b,v3.16b,v30.16b // A[0][3]=A[3][3] + +.inst 0xce2c7f2a //bcax v10.16b,v25.16b, v12.16b,v31.16b +.inst 0xce2d33eb //bcax v11.16b,v31.16b, v13.16b,v12.16b +.inst 0xce2e358c //bcax v12.16b,v12.16b,v14.16b,v13.16b +.inst 0xce3939ad //bcax v13.16b,v13.16b,v25.16b, v14.16b +.inst 0xce3f65ce //bcax v14.16b,v14.16b,v31.16b, v25.16b + +.inst 0xce2913a7 //bcax v7.16b,v29.16b, v9.16b,v4.16b // A[0][4]=A[1][3] +.inst 0xce252488 //bcax v8.16b,v4.16b,v5.16b,v9.16b // A[0][4]=A[1][3] +.inst 0xce261529 //bcax v9.16b,v9.16b,v6.16b,v5.16b +.inst 0xce3d18a5 //bcax v5.16b,v5.16b,v29.16b, v6.16b +.inst 0xce2474c6 //bcax v6.16b,v6.16b,v4.16b,v29.16b // A[0][4]=A[1][3] + +.inst 0xce207363 //bcax v3.16b,v27.16b, v0.16b,v28.16b +.inst 0xce210384 //bcax v4.16b,v28.16b, v1.16b,v0.16b +.inst 0xce220400 //bcax v0.16b,v0.16b,v2.16b,v1.16b +.inst 0xce3b0821 //bcax v1.16b,v1.16b,v27.16b, v2.16b +.inst 0xce3c6c42 //bcax v2.16b,v2.16b,v28.16b, v27.16b + + eor v0.16b,v0.16b,v26.16b + + subs x9,x9,#1 + bne .Loop_ce + + ret +.size KeccakF1600_ce,.-KeccakF1600_ce + +.type KeccakF1600_cext,%function +.align 5 +KeccakF1600_cext: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp d8,d9,[sp,#16] // per ABI requirement + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + ldp d0,d1,[x0,#8*0] + ldp d2,d3,[x0,#8*2] + ldp d4,d5,[x0,#8*4] + ldp d6,d7,[x0,#8*6] + ldp d8,d9,[x0,#8*8] + ldp d10,d11,[x0,#8*10] + ldp d12,d13,[x0,#8*12] + ldp d14,d15,[x0,#8*14] + ldp d16,d17,[x0,#8*16] + ldp d18,d19,[x0,#8*18] + ldp d20,d21,[x0,#8*20] + ldp d22,d23,[x0,#8*22] + ldr d24,[x0,#8*24] + bl KeccakF1600_ce + ldr x30,[sp,#8] + stp d0,d1,[x0,#8*0] + stp d2,d3,[x0,#8*2] + stp d4,d5,[x0,#8*4] + stp d6,d7,[x0,#8*6] + stp d8,d9,[x0,#8*8] + stp d10,d11,[x0,#8*10] + stp d12,d13,[x0,#8*12] + stp d14,d15,[x0,#8*14] + stp d16,d17,[x0,#8*16] + stp d18,d19,[x0,#8*18] + stp d20,d21,[x0,#8*20] + stp d22,d23,[x0,#8*22] + str d24,[x0,#8*24] + + ldp d8,d9,[sp,#16] + ldp d10,d11,[sp,#32] + ldp d12,d13,[sp,#48] + ldp d14,d15,[sp,#64] + ldr x29,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size KeccakF1600_cext,.-KeccakF1600_cext +.globl SHA3_absorb_cext +.type SHA3_absorb_cext,%function +.align 5 +SHA3_absorb_cext: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp d8,d9,[sp,#16] // per ABI requirement + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + ldp d0,d1,[x0,#8*0] + ldp d2,d3,[x0,#8*2] + ldp d4,d5,[x0,#8*4] + ldp d6,d7,[x0,#8*6] + ldp d8,d9,[x0,#8*8] + ldp d10,d11,[x0,#8*10] + ldp d12,d13,[x0,#8*12] + ldp d14,d15,[x0,#8*14] + ldp d16,d17,[x0,#8*16] + ldp d18,d19,[x0,#8*18] + ldp d20,d21,[x0,#8*20] + ldp d22,d23,[x0,#8*22] + ldr d24,[x0,#8*24] + b .Loop_absorb_ce + +.align 4 +.Loop_absorb_ce: + subs x2,x2,x3 // len - bsz + blo .Labsorbed_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v0.16b,v0.16b,v31.16b + cmp x3,#8*(0+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v1.16b,v1.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v2.16b,v2.16b,v31.16b + cmp x3,#8*(2+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v3.16b,v3.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v4.16b,v4.16b,v31.16b + cmp x3,#8*(4+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v5.16b,v5.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v6.16b,v6.16b,v31.16b + cmp x3,#8*(6+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v7.16b,v7.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v8.16b,v8.16b,v31.16b + cmp x3,#8*(8+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v9.16b,v9.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v10.16b,v10.16b,v31.16b + cmp x3,#8*(10+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v11.16b,v11.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v12.16b,v12.16b,v31.16b + cmp x3,#8*(12+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v13.16b,v13.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v14.16b,v14.16b,v31.16b + cmp x3,#8*(14+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v15.16b,v15.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v16.16b,v16.16b,v31.16b + cmp x3,#8*(16+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v17.16b,v17.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v18.16b,v18.16b,v31.16b + cmp x3,#8*(18+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v19.16b,v19.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v20.16b,v20.16b,v31.16b + cmp x3,#8*(20+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v21.16b,v21.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v22.16b,v22.16b,v31.16b + cmp x3,#8*(22+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v23.16b,v23.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v24.16b,v24.16b,v31.16b + +.Lprocess_block_ce: + + bl KeccakF1600_ce + + b .Loop_absorb_ce + +.align 4 +.Labsorbed_ce: + stp d0,d1,[x0,#8*0] + stp d2,d3,[x0,#8*2] + stp d4,d5,[x0,#8*4] + stp d6,d7,[x0,#8*6] + stp d8,d9,[x0,#8*8] + stp d10,d11,[x0,#8*10] + stp d12,d13,[x0,#8*12] + stp d14,d15,[x0,#8*14] + stp d16,d17,[x0,#8*16] + stp d18,d19,[x0,#8*18] + stp d20,d21,[x0,#8*20] + stp d22,d23,[x0,#8*22] + str d24,[x0,#8*24] + add x0,x2,x3 // return value + + ldp d8,d9,[sp,#16] + ldp d10,d11,[sp,#32] + ldp d12,d13,[sp,#48] + ldp d14,d15,[sp,#64] + ldp x29,x30,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size SHA3_absorb_cext,.-SHA3_absorb_cext +.globl SHA3_squeeze_cext +.type SHA3_squeeze_cext,%function +.align 5 +SHA3_squeeze_cext: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x9,x0 + mov x10,x3 + +.Loop_squeeze_ce: + ldr x4,[x9],#8 + cmp x2,#8 + blo .Lsqueeze_tail_ce +#ifdef __AARCH64EB__ + rev x4,x4 +#endif + str x4,[x1],#8 + beq .Lsqueeze_done_ce + + sub x2,x2,#8 + subs x10,x10,#8 + bhi .Loop_squeeze_ce + + bl KeccakF1600_cext + ldr x30,[sp,#8] + mov x9,x0 + mov x10,x3 + b .Loop_squeeze_ce + +.align 4 +.Lsqueeze_tail_ce: + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + +.Lsqueeze_done_ce: + ldr x29,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size SHA3_squeeze_cext,.-SHA3_squeeze_cext +.byte 75,101,99,99,97,107,45,49,54,48,48,32,97,98,115,111,114,98,32,97,110,100,32,115,113,117,101,101,122,101,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S new file mode 100644 index 0000000000..7f6d5be953 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S @@ -0,0 +1,1211 @@ +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.globl sha1_block_data_order +.type sha1_block_data_order,%function +.align 6 +sha1_block_data_order: + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA1 + b.ne .Lv8_entry + + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + ldp w20,w21,[x0] + ldp w22,w23,[x0,#8] + ldr w24,[x0,#16] + +.Loop: + ldr x3,[x1],#64 + movz w28,#0x7999 + sub x2,x2,#1 + movk w28,#0x5a82,lsl#16 +#ifdef __AARCH64EB__ + ror x3,x3,#32 +#else + rev32 x3,x3 +#endif + add w24,w24,w28 // warm it up + add w24,w24,w3 + lsr x4,x3,#32 + ldur x5,[x1,#-56] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w4 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x5,x5,#32 +#else + rev32 x5,x5 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w5 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x6,x5,#32 + ldur x7,[x1,#-48] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w6 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x7,x7,#32 +#else + rev32 x7,x7 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w7 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x8,x7,#32 + ldur x9,[x1,#-40] + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w8 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x9,x9,#32 +#else + rev32 x9,x9 +#endif + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w9 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + lsr x10,x9,#32 + ldur x11,[x1,#-32] + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w10 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x11,x11,#32 +#else + rev32 x11,x11 +#endif + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w11 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + lsr x12,x11,#32 + ldur x13,[x1,#-24] + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w12 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x13,x13,#32 +#else + rev32 x13,x13 +#endif + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w13 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + lsr x14,x13,#32 + ldur x15,[x1,#-16] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w14 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x15,x15,#32 +#else + rev32 x15,x15 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w15 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x16,x15,#32 + ldur x17,[x1,#-8] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w16 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x17,x17,#32 +#else + rev32 x17,x17 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w17 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x19,x17,#32 + eor w3,w3,w5 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w3,w3,w11 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w3,w3,w16 + ror w22,w22,#2 + add w24,w24,w19 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + eor w4,w4,w12 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + eor w4,w4,w17 + ror w21,w21,#2 + add w23,w23,w3 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + eor w5,w5,w13 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + eor w5,w5,w19 + ror w20,w20,#2 + add w22,w22,w4 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + eor w6,w6,w14 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + eor w6,w6,w3 + ror w24,w24,#2 + add w21,w21,w5 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + eor w7,w7,w15 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + eor w7,w7,w4 + ror w23,w23,#2 + add w20,w20,w6 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w7,w7,#31 + movz w28,#0xeba1 + movk w28,#0x6ed9,lsl#16 + eor w8,w8,w10 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w8,w8,w16 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w8,w8,w5 + ror w22,w22,#2 + add w24,w24,w7 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w9,w9,w6 + add w23,w23,w8 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w10,w10,w7 + add w22,w22,w9 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w11,w11,w8 + add w21,w21,w10 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w12,w12,w9 + add w20,w20,w11 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w13,w13,w10 + add w24,w24,w12 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w14,w14,w11 + add w23,w23,w13 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w15,w15,w12 + add w22,w22,w14 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w16,w16,w13 + add w21,w21,w15 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w17,w17,w14 + add w20,w20,w16 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w19,w19,w15 + add w24,w24,w17 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w3,w3,w16 + add w23,w23,w19 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w4,w4,w17 + add w22,w22,w3 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w5,w5,w19 + add w21,w21,w4 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w6,w6,w3 + add w20,w20,w5 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w7,w7,w4 + add w24,w24,w6 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w8,w8,w5 + add w23,w23,w7 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w9,w9,w6 + add w22,w22,w8 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w10,w10,w7 + add w21,w21,w9 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w11,w11,w8 + add w20,w20,w10 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w11,w11,#31 + movz w28,#0xbcdc + movk w28,#0x8f1b,lsl#16 + eor w12,w12,w14 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w12,w12,w9 + add w24,w24,w11 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w13,w13,w15 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w13,w13,w5 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w13,w13,w10 + add w23,w23,w12 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w14,w14,w16 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w14,w14,w6 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w14,w14,w11 + add w22,w22,w13 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w15,w15,w17 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w15,w15,w7 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w15,w15,w12 + add w21,w21,w14 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w15,w15,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w16,w16,w19 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w16,w16,w8 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w16,w16,w13 + add w20,w20,w15 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w16,w16,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w17,w17,w3 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w17,w17,w9 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w17,w17,w14 + add w24,w24,w16 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w17,w17,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w19,w19,w4 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w19,w19,w10 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w19,w19,w15 + add w23,w23,w17 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w19,w19,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w3,w3,w5 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w3,w3,w11 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w3,w3,w16 + add w22,w22,w19 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w3,w3,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w4,w4,w6 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w4,w4,w12 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w4,w4,w17 + add w21,w21,w3 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w4,w4,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w5,w5,w7 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w5,w5,w13 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w5,w5,w19 + add w20,w20,w4 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w5,w5,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w6,w6,w8 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w6,w6,w14 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w6,w6,w3 + add w24,w24,w5 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w6,w6,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w7,w7,w9 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w7,w7,w15 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w7,w7,w4 + add w23,w23,w6 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w7,w7,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w8,w8,w10 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w8,w8,w16 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w8,w8,w5 + add w22,w22,w7 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w8,w8,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w9,w9,w11 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w9,w9,w17 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w9,w9,w6 + add w21,w21,w8 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w9,w9,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w10,w10,w12 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w10,w10,w19 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w10,w10,w7 + add w20,w20,w9 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w10,w10,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w11,w11,w13 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w11,w11,w3 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w11,w11,w8 + add w24,w24,w10 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w11,w11,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w12,w12,w14 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w12,w12,w4 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w12,w12,w9 + add w23,w23,w11 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w13,w13,w15 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w13,w13,w5 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w13,w13,w10 + add w22,w22,w12 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w14,w14,w16 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w14,w14,w6 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w14,w14,w11 + add w21,w21,w13 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w15,w15,w17 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w15,w15,w7 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w15,w15,w12 + add w20,w20,w14 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w15,w15,#31 + movz w28,#0xc1d6 + movk w28,#0xca62,lsl#16 + orr w25,w22,w23 + and w26,w22,w23 + eor w16,w16,w19 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w16,w16,w8 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w16,w16,w13 + add w24,w24,w15 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w17,w17,w14 + add w23,w23,w16 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w19,w19,w15 + add w22,w22,w17 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w3,w3,w16 + add w21,w21,w19 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w4,w4,w17 + add w20,w20,w3 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w5,w5,w19 + add w24,w24,w4 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w6,w6,w3 + add w23,w23,w5 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w7,w7,w4 + add w22,w22,w6 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w8,w8,w5 + add w21,w21,w7 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w9,w9,w6 + add w20,w20,w8 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w10,w10,w7 + add w24,w24,w9 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w11,w11,w8 + add w23,w23,w10 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w12,w12,w9 + add w22,w22,w11 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w13,w13,w10 + add w21,w21,w12 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w14,w14,w11 + add w20,w20,w13 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w15,w15,w12 + add w24,w24,w14 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w16,w16,w13 + add w23,w23,w15 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w17,w17,w14 + add w22,w22,w16 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w19,w19,w15 + add w21,w21,w17 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w19,w19,#31 + ldp w4,w5,[x0] + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w19 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ldp w6,w7,[x0,#8] + eor w25,w24,w22 + ror w27,w21,#27 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + ldr w8,[x0,#16] + add w20,w20,w25 // e+=F(b,c,d) + add w21,w21,w5 + add w22,w22,w6 + add w20,w20,w4 + add w23,w23,w7 + add w24,w24,w8 + stp w20,w21,[x0] + stp w22,w23,[x0,#8] + str w24,[x0,#16] + cbnz x2,.Loop + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldr x29,[sp],#96 + ret +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_armv8,%function +.align 6 +sha1_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + adr x4,.Lconst + eor v1.16b,v1.16b,v1.16b + ld1 {v0.4s},[x0],#16 + ld1 {v1.s}[0],[x0] + sub x0,x0,#16 + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[x4] + +.Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + + add v20.4s,v16.4s,v4.4s + rev32 v6.16b,v6.16b + orr v22.16b,v0.16b,v0.16b // offload + + add v21.4s,v16.4s,v5.4s + rev32 v7.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b +.inst 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0 + add v20.4s,v16.4s,v6.4s +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 1 +.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v16.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 2 +.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v16.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 3 +.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 4 +.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 5 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 6 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 7 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 8 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 9 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 10 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 11 +.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 12 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 13 +.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 14 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 15 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 16 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 17 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s + +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 18 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 19 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + + add v1.4s,v1.4s,v2.4s + add v0.4s,v0.4s,v22.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s},[x0],#16 + st1 {v1.s}[0],[x0] + + ldr x29,[sp],#16 + ret +.size sha1_block_armv8,.-sha1_block_armv8 +.align 6 +.Lconst: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S new file mode 100644 index 0000000000..f762580f09 --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S @@ -0,0 +1,2051 @@ +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. The module is, however, dual licensed under OpenSSL and +// CRYPTOGAMS licenses depending on where you obtain it. For further +// details see http://www.openssl.org/~appro/cryptogams/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// ThunderX2 2.54 13.2 (+40%) 8.40 (+18%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. +// +// October 2016. +// +// Originally it was reckoned that it makes no sense to implement NEON +// version of SHA256 for 64-bit processors. This is because performance +// improvement on most wide-spread Cortex-A5x processors was observed +// to be marginal, same on Cortex-A53 and ~10% on A57. But then it was +// observed that 32-bit NEON SHA256 performs significantly better than +// 64-bit scalar version on *some* of the more recent processors. As +// result 64-bit NEON version of SHA256 was added to provide best +// all-round performance. For example it executes ~30% faster on X-Gene +// and Mongoose. [For reference, NEON version of SHA512 is bound to +// deliver much less improvement, likely *negative* on Cortex-A5x. +// Which is why NEON support is limited to SHA256.] + +// $output is the last argument if it looks like a file (it has an extension) +// $flavour is the first argument if it doesn't look like a file +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.globl sha256_block_data_order +.type sha256_block_data_order,%function +.align 6 +sha256_block_data_order: +#ifndef __KERNEL__ + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA256 + b.ne .Lv8_entry + tst w16,#ARMV7_NEON + b.ne .Lneon_entry +#endif +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*4 + + ldp w20,w21,[x0] // load context + ldp w22,w23,[x0,#2*4] + ldp w24,w25,[x0,#4*4] + add x2,x1,x2,lsl#6 // end of input + ldp w26,w27,[x0,#6*4] + adr x30,.LK256 + stp x0,x2,[x29,#96] + +.Loop: + ldp w3,w4,[x1],#2*4 + ldr w19,[x30],#4 // *K++ + eor w28,w21,w22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev w3,w3 // 0 +#endif + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w6,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w3 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w4,w4 // 1 +#endif + ldp w5,w6,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w7,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w4 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w5,w5 // 2 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w8,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w5 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w6,w6 // 3 +#endif + ldp w7,w8,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w9,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w6 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w7,w7 // 4 +#endif + add w24,w24,w17 // h+=Sigma0(a) + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w10,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w7 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w10,ror#11 // Sigma1(e) + ror w10,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w10,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w8,w8 // 5 +#endif + ldp w9,w10,[x1],#2*4 + add w23,w23,w17 // h+=Sigma0(a) + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w11,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w8 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w11,ror#11 // Sigma1(e) + ror w11,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w11,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w9,w9 // 6 +#endif + add w22,w22,w17 // h+=Sigma0(a) + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w12,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w9 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w12,ror#11 // Sigma1(e) + ror w12,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w12,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w10,w10 // 7 +#endif + ldp w11,w12,[x1],#2*4 + add w21,w21,w17 // h+=Sigma0(a) + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + eor w13,w25,w25,ror#14 + and w17,w26,w25 + bic w28,w27,w25 + add w20,w20,w10 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w13,ror#11 // Sigma1(e) + ror w13,w21,#2 + add w20,w20,w17 // h+=Ch(e,f,g) + eor w17,w21,w21,ror#9 + add w20,w20,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w24,w24,w20 // d+=h + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w13,w17,ror#13 // Sigma0(a) + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w20,w20,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w11,w11 // 8 +#endif + add w20,w20,w17 // h+=Sigma0(a) + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w14,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w11 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w14,ror#11 // Sigma1(e) + ror w14,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w14,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w12,w12 // 9 +#endif + ldp w13,w14,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w15,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w12 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w15,ror#11 // Sigma1(e) + ror w15,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w15,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w13,w13 // 10 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w0,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w13 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w0,ror#11 // Sigma1(e) + ror w0,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w0,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w14,w14 // 11 +#endif + ldp w15,w0,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w6,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w14 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w15,w15 // 12 +#endif + add w24,w24,w17 // h+=Sigma0(a) + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w7,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w15 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w0,w0 // 13 +#endif + ldp w1,w2,[x1] + add w23,w23,w17 // h+=Sigma0(a) + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w8,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w0 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w1,w1 // 14 +#endif + ldr w6,[sp,#12] + add w22,w22,w17 // h+=Sigma0(a) + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w9,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w1 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w2,w2 // 15 +#endif + ldr w7,[sp,#0] + add w21,w21,w17 // h+=Sigma0(a) + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 +.Loop_16_xx: + ldr w8,[sp,#4] + str w11,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w10,w5,#7 + and w17,w25,w24 + ror w9,w2,#17 + bic w19,w26,w24 + ror w11,w20,#2 + add w27,w27,w3 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w10,w10,w5,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w11,w11,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w9,w9,w2,ror#19 + eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w11,w20,ror#22 // Sigma0(a) + eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) + add w4,w4,w13 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w4,w4,w10 + add w27,w27,w17 // h+=Sigma0(a) + add w4,w4,w9 + ldr w9,[sp,#8] + str w12,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w11,w6,#7 + and w17,w24,w23 + ror w10,w3,#17 + bic w28,w25,w23 + ror w12,w27,#2 + add w26,w26,w4 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w11,w11,w6,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w12,w12,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w10,w10,w3,ror#19 + eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w12,w27,ror#22 // Sigma0(a) + eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) + add w5,w5,w14 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w5,w5,w11 + add w26,w26,w17 // h+=Sigma0(a) + add w5,w5,w10 + ldr w10,[sp,#12] + str w13,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w12,w7,#7 + and w17,w23,w22 + ror w11,w4,#17 + bic w19,w24,w22 + ror w13,w26,#2 + add w25,w25,w5 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w12,w12,w7,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w13,w13,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w11,w11,w4,ror#19 + eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w13,w26,ror#22 // Sigma0(a) + eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) + add w6,w6,w15 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w6,w6,w12 + add w25,w25,w17 // h+=Sigma0(a) + add w6,w6,w11 + ldr w11,[sp,#0] + str w14,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w13,w8,#7 + and w17,w22,w21 + ror w12,w5,#17 + bic w28,w23,w21 + ror w14,w25,#2 + add w24,w24,w6 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w13,w13,w8,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w14,w14,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w12,w12,w5,ror#19 + eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w14,w25,ror#22 // Sigma0(a) + eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) + add w7,w7,w0 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w7,w7,w13 + add w24,w24,w17 // h+=Sigma0(a) + add w7,w7,w12 + ldr w12,[sp,#4] + str w15,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w14,w9,#7 + and w17,w21,w20 + ror w13,w6,#17 + bic w19,w22,w20 + ror w15,w24,#2 + add w23,w23,w7 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w14,w14,w9,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w15,w15,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w13,w13,w6,ror#19 + eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w15,w24,ror#22 // Sigma0(a) + eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) + add w8,w8,w1 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w8,w8,w14 + add w23,w23,w17 // h+=Sigma0(a) + add w8,w8,w13 + ldr w13,[sp,#8] + str w0,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w15,w10,#7 + and w17,w20,w27 + ror w14,w7,#17 + bic w28,w21,w27 + ror w0,w23,#2 + add w22,w22,w8 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w15,w15,w10,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w0,w0,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w14,w14,w7,ror#19 + eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w0,w23,ror#22 // Sigma0(a) + eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) + add w9,w9,w2 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w9,w9,w15 + add w22,w22,w17 // h+=Sigma0(a) + add w9,w9,w14 + ldr w14,[sp,#12] + str w1,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w0,w11,#7 + and w17,w27,w26 + ror w15,w8,#17 + bic w19,w20,w26 + ror w1,w22,#2 + add w21,w21,w9 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w0,w0,w11,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w1,w1,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w15,w15,w8,ror#19 + eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w1,w22,ror#22 // Sigma0(a) + eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) + add w10,w10,w3 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w10,w10,w0 + add w21,w21,w17 // h+=Sigma0(a) + add w10,w10,w15 + ldr w15,[sp,#0] + str w2,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w1,w12,#7 + and w17,w26,w25 + ror w0,w9,#17 + bic w28,w27,w25 + ror w2,w21,#2 + add w20,w20,w10 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w1,w1,w12,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w2,w2,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w0,w0,w9,ror#19 + eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w2,w21,ror#22 // Sigma0(a) + eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) + add w11,w11,w4 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w11,w11,w1 + add w20,w20,w17 // h+=Sigma0(a) + add w11,w11,w0 + ldr w0,[sp,#4] + str w3,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w2,w13,#7 + and w17,w25,w24 + ror w1,w10,#17 + bic w19,w26,w24 + ror w3,w20,#2 + add w27,w27,w11 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w2,w2,w13,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w3,w3,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w1,w1,w10,ror#19 + eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w3,w20,ror#22 // Sigma0(a) + eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) + add w12,w12,w5 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w12,w12,w2 + add w27,w27,w17 // h+=Sigma0(a) + add w12,w12,w1 + ldr w1,[sp,#8] + str w4,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w3,w14,#7 + and w17,w24,w23 + ror w2,w11,#17 + bic w28,w25,w23 + ror w4,w27,#2 + add w26,w26,w12 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w3,w3,w14,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w4,w4,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w2,w2,w11,ror#19 + eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w4,w27,ror#22 // Sigma0(a) + eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) + add w13,w13,w6 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w13,w13,w3 + add w26,w26,w17 // h+=Sigma0(a) + add w13,w13,w2 + ldr w2,[sp,#12] + str w5,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w4,w15,#7 + and w17,w23,w22 + ror w3,w12,#17 + bic w19,w24,w22 + ror w5,w26,#2 + add w25,w25,w13 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w4,w4,w15,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w5,w5,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w3,w3,w12,ror#19 + eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w5,w26,ror#22 // Sigma0(a) + eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) + add w14,w14,w7 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w14,w14,w4 + add w25,w25,w17 // h+=Sigma0(a) + add w14,w14,w3 + ldr w3,[sp,#0] + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w5,w0,#7 + and w17,w22,w21 + ror w4,w13,#17 + bic w28,w23,w21 + ror w6,w25,#2 + add w24,w24,w14 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w5,w5,w0,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w6,w6,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w4,w4,w13,ror#19 + eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w25,ror#22 // Sigma0(a) + eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) + add w15,w15,w8 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w15,w15,w5 + add w24,w24,w17 // h+=Sigma0(a) + add w15,w15,w4 + ldr w4,[sp,#4] + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w6,w1,#7 + and w17,w21,w20 + ror w5,w14,#17 + bic w19,w22,w20 + ror w7,w24,#2 + add w23,w23,w15 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w6,w6,w1,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w7,w7,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w5,w5,w14,ror#19 + eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w24,ror#22 // Sigma0(a) + eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) + add w0,w0,w9 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w0,w0,w6 + add w23,w23,w17 // h+=Sigma0(a) + add w0,w0,w5 + ldr w5,[sp,#8] + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w7,w2,#7 + and w17,w20,w27 + ror w6,w15,#17 + bic w28,w21,w27 + ror w8,w23,#2 + add w22,w22,w0 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w7,w7,w2,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w8,w8,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w6,w6,w15,ror#19 + eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w23,ror#22 // Sigma0(a) + eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) + add w1,w1,w10 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w1,w1,w7 + add w22,w22,w17 // h+=Sigma0(a) + add w1,w1,w6 + ldr w6,[sp,#12] + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w8,w3,#7 + and w17,w27,w26 + ror w7,w0,#17 + bic w19,w20,w26 + ror w9,w22,#2 + add w21,w21,w1 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w8,w8,w3,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w9,w9,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w7,w7,w0,ror#19 + eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w22,ror#22 // Sigma0(a) + eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) + add w2,w2,w11 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w2,w2,w8 + add w21,w21,w17 // h+=Sigma0(a) + add w2,w2,w7 + ldr w7,[sp,#0] + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 + cbnz w19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#260 // rewind + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#2*4] + add x1,x1,#14*4 // advance input pointer + ldp w7,w8,[x0,#4*4] + add w20,w20,w3 + ldp w9,w10,[x0,#6*4] + add w21,w21,w4 + add w22,w22,w5 + add w23,w23,w6 + stp w20,w21,[x0] + add w24,w24,w7 + add w25,w25,w8 + stp w22,w23,[x0,#2*4] + add w26,w26,w9 + add w27,w27,w10 + cmp x1,x2 + stp w24,w25,[x0,#4*4] + stp w26,w27,[x0,#6*4] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*4 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size sha256_block_data_order,.-sha256_block_data_order + +.align 6 +.type .LK256,%object +.LK256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0 //terminator +.size .LK256,.-.LK256 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#ifndef __KERNEL__ +.type sha256_block_armv8,%function +.align 6 +sha256_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v0.4s,v1.4s},[x0] + adr x3,.LK256 + +.Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + ld1 {v16.4s},[x3],#16 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + orr v18.16b,v0.16b,v0.16b // offload + orr v19.16b,v1.16b,v1.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + ld1 {v17.4s},[x3] + add v16.4s,v16.4s,v6.4s + sub x3,x3,#64*4-16 // rewind + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + add v17.4s,v17.4s,v7.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + add v0.4s,v0.4s,v18.4s + add v1.4s,v1.4s,v19.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s,v1.4s},[x0] + + ldr x29,[sp],#16 + ret +.size sha256_block_armv8,.-sha256_block_armv8 +#endif +#ifdef __KERNEL__ +.globl sha256_block_neon +#endif +.type sha256_block_neon,%function +.align 4 +sha256_block_neon: +.Lneon_entry: + stp x29, x30, [sp, #-16]! + mov x29, sp + sub sp,sp,#16*4 + + adr x16,.LK256 + add x2,x1,x2,lsl#6 // len to point at the end of inp + + ld1 {v0.16b},[x1], #16 + ld1 {v1.16b},[x1], #16 + ld1 {v2.16b},[x1], #16 + ld1 {v3.16b},[x1], #16 + ld1 {v4.4s},[x16], #16 + ld1 {v5.4s},[x16], #16 + ld1 {v6.4s},[x16], #16 + ld1 {v7.4s},[x16], #16 + rev32 v0.16b,v0.16b // yes, even on + rev32 v1.16b,v1.16b // big-endian + rev32 v2.16b,v2.16b + rev32 v3.16b,v3.16b + mov x17,sp + add v4.4s,v4.4s,v0.4s + add v5.4s,v5.4s,v1.4s + add v6.4s,v6.4s,v2.4s + st1 {v4.4s,v5.4s},[x17], #32 + add v7.4s,v7.4s,v3.4s + st1 {v6.4s,v7.4s},[x17] + sub x17,x17,#32 + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#8] + ldp w7,w8,[x0,#16] + ldp w9,w10,[x0,#24] + ldr w12,[sp,#0] + mov w13,wzr + eor w14,w4,w5 + mov w15,wzr + b .L_00_48 + +.align 4 +.L_00_48: + ext v4.16b,v0.16b,v1.16b,#4 + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + bic w15,w9,w7 + ext v7.16b,v2.16b,v3.16b,#4 + eor w11,w7,w7,ror#5 + add w3,w3,w13 + mov d19,v3.d[1] + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w3,w3,ror#11 + ushr v5.4s,v4.4s,#3 + add w10,w10,w12 + add v0.4s,v0.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + ushr v7.4s,v4.4s,#18 + add w10,w10,w11 + ldr w12,[sp,#4] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w6,w6,w10 + sli v7.4s,v4.4s,#14 + eor w14,w14,w4 + ushr v16.4s,v19.4s,#17 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + eor v5.16b,v5.16b,v7.16b + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + sli v16.4s,v19.4s,#15 + add w10,w10,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + ushr v7.4s,v19.4s,#19 + add w9,w9,w12 + ror w11,w11,#6 + add v0.4s,v0.4s,v5.4s + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + sli v7.4s,v19.4s,#13 + add w9,w9,w11 + ldr w12,[sp,#8] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + eor v17.16b,v17.16b,v7.16b + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + add v0.4s,v0.4s,v17.4s + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + ushr v18.4s,v0.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v0.4s,#10 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + sli v18.4s,v0.4s,#15 + add w8,w8,w12 + ushr v17.4s,v0.4s,#19 + ror w11,w11,#6 + eor w13,w9,w10 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w9,ror#20 + add w8,w8,w11 + sli v17.4s,v0.4s,#13 + ldr w12,[sp,#12] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w4,w4,w8 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w10 + eor v17.16b,v17.16b,v17.16b + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + mov v17.d[1],v19.d[0] + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + add v0.4s,v0.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add v4.4s,v4.4s,v0.4s + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#16] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + ext v4.16b,v1.16b,v2.16b,#4 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + bic w15,w5,w3 + ext v7.16b,v3.16b,v0.16b,#4 + eor w11,w3,w3,ror#5 + add w7,w7,w13 + mov d19,v0.d[1] + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w7,w7,ror#11 + ushr v5.4s,v4.4s,#3 + add w6,w6,w12 + add v1.4s,v1.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + ushr v7.4s,v4.4s,#18 + add w6,w6,w11 + ldr w12,[sp,#20] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w10,w10,w6 + sli v7.4s,v4.4s,#14 + eor w14,w14,w8 + ushr v16.4s,v19.4s,#17 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + eor v5.16b,v5.16b,v7.16b + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + sli v16.4s,v19.4s,#15 + add w6,w6,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + ushr v7.4s,v19.4s,#19 + add w5,w5,w12 + ror w11,w11,#6 + add v1.4s,v1.4s,v5.4s + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + sli v7.4s,v19.4s,#13 + add w5,w5,w11 + ldr w12,[sp,#24] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + eor v17.16b,v17.16b,v7.16b + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + add v1.4s,v1.4s,v17.4s + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + ushr v18.4s,v1.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v1.4s,#10 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + sli v18.4s,v1.4s,#15 + add w4,w4,w12 + ushr v17.4s,v1.4s,#19 + ror w11,w11,#6 + eor w13,w5,w6 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w5,ror#20 + add w4,w4,w11 + sli v17.4s,v1.4s,#13 + ldr w12,[sp,#28] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w8,w8,w4 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w6 + eor v17.16b,v17.16b,v17.16b + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + mov v17.d[1],v19.d[0] + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + add v1.4s,v1.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add v4.4s,v4.4s,v1.4s + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + ldr w12,[sp,#32] + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + ext v4.16b,v2.16b,v3.16b,#4 + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + bic w15,w9,w7 + ext v7.16b,v0.16b,v1.16b,#4 + eor w11,w7,w7,ror#5 + add w3,w3,w13 + mov d19,v1.d[1] + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w3,w3,ror#11 + ushr v5.4s,v4.4s,#3 + add w10,w10,w12 + add v2.4s,v2.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + ushr v7.4s,v4.4s,#18 + add w10,w10,w11 + ldr w12,[sp,#36] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w6,w6,w10 + sli v7.4s,v4.4s,#14 + eor w14,w14,w4 + ushr v16.4s,v19.4s,#17 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + eor v5.16b,v5.16b,v7.16b + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + sli v16.4s,v19.4s,#15 + add w10,w10,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + ushr v7.4s,v19.4s,#19 + add w9,w9,w12 + ror w11,w11,#6 + add v2.4s,v2.4s,v5.4s + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + sli v7.4s,v19.4s,#13 + add w9,w9,w11 + ldr w12,[sp,#40] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + eor v17.16b,v17.16b,v7.16b + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + add v2.4s,v2.4s,v17.4s + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + ushr v18.4s,v2.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v2.4s,#10 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + sli v18.4s,v2.4s,#15 + add w8,w8,w12 + ushr v17.4s,v2.4s,#19 + ror w11,w11,#6 + eor w13,w9,w10 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w9,ror#20 + add w8,w8,w11 + sli v17.4s,v2.4s,#13 + ldr w12,[sp,#44] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w4,w4,w8 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w10 + eor v17.16b,v17.16b,v17.16b + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + mov v17.d[1],v19.d[0] + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + add v2.4s,v2.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add v4.4s,v4.4s,v2.4s + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#48] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + ext v4.16b,v3.16b,v0.16b,#4 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + bic w15,w5,w3 + ext v7.16b,v1.16b,v2.16b,#4 + eor w11,w3,w3,ror#5 + add w7,w7,w13 + mov d19,v2.d[1] + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w7,w7,ror#11 + ushr v5.4s,v4.4s,#3 + add w6,w6,w12 + add v3.4s,v3.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + ushr v7.4s,v4.4s,#18 + add w6,w6,w11 + ldr w12,[sp,#52] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w10,w10,w6 + sli v7.4s,v4.4s,#14 + eor w14,w14,w8 + ushr v16.4s,v19.4s,#17 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + eor v5.16b,v5.16b,v7.16b + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + sli v16.4s,v19.4s,#15 + add w6,w6,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + ushr v7.4s,v19.4s,#19 + add w5,w5,w12 + ror w11,w11,#6 + add v3.4s,v3.4s,v5.4s + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + sli v7.4s,v19.4s,#13 + add w5,w5,w11 + ldr w12,[sp,#56] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + eor v17.16b,v17.16b,v7.16b + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + add v3.4s,v3.4s,v17.4s + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + ushr v18.4s,v3.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v3.4s,#10 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + sli v18.4s,v3.4s,#15 + add w4,w4,w12 + ushr v17.4s,v3.4s,#19 + ror w11,w11,#6 + eor w13,w5,w6 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w5,ror#20 + add w4,w4,w11 + sli v17.4s,v3.4s,#13 + ldr w12,[sp,#60] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w8,w8,w4 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w6 + eor v17.16b,v17.16b,v17.16b + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + mov v17.d[1],v19.d[0] + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + add v3.4s,v3.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add v4.4s,v4.4s,v3.4s + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + ldr w12,[x16] + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + cmp w12,#0 // check for K256 terminator + ldr w12,[sp,#0] + sub x17,x17,#64 + bne .L_00_48 + + sub x16,x16,#256 // rewind x16 + cmp x1,x2 + mov x17, #64 + csel x17, x17, xzr, eq + sub x1,x1,x17 // avoid SEGV + mov x17,sp + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + ld1 {v0.16b},[x1],#16 + bic w15,w9,w7 + eor w11,w7,w7,ror#5 + ld1 {v4.4s},[x16],#16 + add w3,w3,w13 + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + eor w15,w3,w3,ror#11 + rev32 v0.16b,v0.16b + add w10,w10,w12 + ror w11,w11,#6 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + add v4.4s,v4.4s,v0.4s + add w10,w10,w11 + ldr w12,[sp,#4] + and w14,w14,w13 + ror w15,w15,#2 + add w6,w6,w10 + eor w14,w14,w4 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + add w10,w10,w14 + orr w12,w12,w15 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + add w9,w9,w12 + ror w11,w11,#6 + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + add w9,w9,w11 + ldr w12,[sp,#8] + and w13,w13,w14 + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + orr w12,w12,w15 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + add w8,w8,w12 + ror w11,w11,#6 + eor w13,w9,w10 + eor w15,w15,w9,ror#20 + add w8,w8,w11 + ldr w12,[sp,#12] + and w14,w14,w13 + ror w15,w15,#2 + add w4,w4,w8 + eor w14,w14,w10 + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#16] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + ld1 {v1.16b},[x1],#16 + bic w15,w5,w3 + eor w11,w3,w3,ror#5 + ld1 {v4.4s},[x16],#16 + add w7,w7,w13 + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + eor w15,w7,w7,ror#11 + rev32 v1.16b,v1.16b + add w6,w6,w12 + ror w11,w11,#6 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + add v4.4s,v4.4s,v1.4s + add w6,w6,w11 + ldr w12,[sp,#20] + and w14,w14,w13 + ror w15,w15,#2 + add w10,w10,w6 + eor w14,w14,w8 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + add w6,w6,w14 + orr w12,w12,w15 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + add w5,w5,w12 + ror w11,w11,#6 + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + add w5,w5,w11 + ldr w12,[sp,#24] + and w13,w13,w14 + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + orr w12,w12,w15 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + add w4,w4,w12 + ror w11,w11,#6 + eor w13,w5,w6 + eor w15,w15,w5,ror#20 + add w4,w4,w11 + ldr w12,[sp,#28] + and w14,w14,w13 + ror w15,w15,#2 + add w8,w8,w4 + eor w14,w14,w6 + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + ldr w12,[sp,#32] + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + ld1 {v2.16b},[x1],#16 + bic w15,w9,w7 + eor w11,w7,w7,ror#5 + ld1 {v4.4s},[x16],#16 + add w3,w3,w13 + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + eor w15,w3,w3,ror#11 + rev32 v2.16b,v2.16b + add w10,w10,w12 + ror w11,w11,#6 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + add v4.4s,v4.4s,v2.4s + add w10,w10,w11 + ldr w12,[sp,#36] + and w14,w14,w13 + ror w15,w15,#2 + add w6,w6,w10 + eor w14,w14,w4 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + add w10,w10,w14 + orr w12,w12,w15 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + add w9,w9,w12 + ror w11,w11,#6 + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + add w9,w9,w11 + ldr w12,[sp,#40] + and w13,w13,w14 + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + orr w12,w12,w15 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + add w8,w8,w12 + ror w11,w11,#6 + eor w13,w9,w10 + eor w15,w15,w9,ror#20 + add w8,w8,w11 + ldr w12,[sp,#44] + and w14,w14,w13 + ror w15,w15,#2 + add w4,w4,w8 + eor w14,w14,w10 + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#48] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + ld1 {v3.16b},[x1],#16 + bic w15,w5,w3 + eor w11,w3,w3,ror#5 + ld1 {v4.4s},[x16],#16 + add w7,w7,w13 + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + eor w15,w7,w7,ror#11 + rev32 v3.16b,v3.16b + add w6,w6,w12 + ror w11,w11,#6 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + add v4.4s,v4.4s,v3.4s + add w6,w6,w11 + ldr w12,[sp,#52] + and w14,w14,w13 + ror w15,w15,#2 + add w10,w10,w6 + eor w14,w14,w8 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + add w6,w6,w14 + orr w12,w12,w15 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + add w5,w5,w12 + ror w11,w11,#6 + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + add w5,w5,w11 + ldr w12,[sp,#56] + and w13,w13,w14 + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + orr w12,w12,w15 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + add w4,w4,w12 + ror w11,w11,#6 + eor w13,w5,w6 + eor w15,w15,w5,ror#20 + add w4,w4,w11 + ldr w12,[sp,#60] + and w14,w14,w13 + ror w15,w15,#2 + add w8,w8,w4 + eor w14,w14,w6 + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + add w3,w3,w15 // h+=Sigma0(a) from the past + ldp w11,w12,[x0,#0] + add w3,w3,w13 // h+=Maj(a,b,c) from the past + ldp w13,w14,[x0,#8] + add w3,w3,w11 // accumulate + add w4,w4,w12 + ldp w11,w12,[x0,#16] + add w5,w5,w13 + add w6,w6,w14 + ldp w13,w14,[x0,#24] + add w7,w7,w11 + add w8,w8,w12 + ldr w12,[sp,#0] + stp w3,w4,[x0,#0] + add w9,w9,w13 + mov w13,wzr + stp w5,w6,[x0,#8] + add w10,w10,w14 + stp w7,w8,[x0,#16] + eor w14,w4,w5 + stp w9,w10,[x0,#24] + mov w15,wzr + mov x17,sp + b.ne .L_00_48 + + ldr x29,[x29] + add sp,sp,#16*4+16 + ret +.size sha256_block_neon,.-sha256_block_neon diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S new file mode 100644 index 0000000000..00269c027b --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S @@ -0,0 +1,1606 @@ +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. The module is, however, dual licensed under OpenSSL and +// CRYPTOGAMS licenses depending on where you obtain it. For further +// details see http://www.openssl.org/~appro/cryptogams/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// ThunderX2 2.54 13.2 (+40%) 8.40 (+18%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. +// +// October 2016. +// +// Originally it was reckoned that it makes no sense to implement NEON +// version of SHA256 for 64-bit processors. This is because performance +// improvement on most wide-spread Cortex-A5x processors was observed +// to be marginal, same on Cortex-A53 and ~10% on A57. But then it was +// observed that 32-bit NEON SHA256 performs significantly better than +// 64-bit scalar version on *some* of the more recent processors. As +// result 64-bit NEON version of SHA256 was added to provide best +// all-round performance. For example it executes ~30% faster on X-Gene +// and Mongoose. [For reference, NEON version of SHA512 is bound to +// deliver much less improvement, likely *negative* on Cortex-A5x. +// Which is why NEON support is limited to SHA256.] + +// $output is the last argument if it looks like a file (it has an extension) +// $flavour is the first argument if it doesn't look like a file +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.globl sha512_block_data_order +.type sha512_block_data_order,%function +.align 6 +sha512_block_data_order: +#ifndef __KERNEL__ + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA512 + b.ne .Lv8_entry +#endif +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*8 + + ldp x20,x21,[x0] // load context + ldp x22,x23,[x0,#2*8] + ldp x24,x25,[x0,#4*8] + add x2,x1,x2,lsl#7 // end of input + ldp x26,x27,[x0,#6*8] + adr x30,.LK512 + stp x0,x2,[x29,#96] + +.Loop: + ldp x3,x4,[x1],#2*8 + ldr x19,[x30],#8 // *K++ + eor x28,x21,x22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev x3,x3 // 0 +#endif + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x6,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x3 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x4,x4 // 1 +#endif + ldp x5,x6,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x7,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x4 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x5,x5 // 2 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x8,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x5 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x6,x6 // 3 +#endif + ldp x7,x8,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x9,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x6 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x7,x7 // 4 +#endif + add x24,x24,x17 // h+=Sigma0(a) + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x10,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x7 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x10,ror#18 // Sigma1(e) + ror x10,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x10,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x8,x8 // 5 +#endif + ldp x9,x10,[x1],#2*8 + add x23,x23,x17 // h+=Sigma0(a) + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x11,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x8 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x11,ror#18 // Sigma1(e) + ror x11,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x11,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x9,x9 // 6 +#endif + add x22,x22,x17 // h+=Sigma0(a) + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x12,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x9 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x12,ror#18 // Sigma1(e) + ror x12,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x12,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x10,x10 // 7 +#endif + ldp x11,x12,[x1],#2*8 + add x21,x21,x17 // h+=Sigma0(a) + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + eor x13,x25,x25,ror#23 + and x17,x26,x25 + bic x28,x27,x25 + add x20,x20,x10 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x13,ror#18 // Sigma1(e) + ror x13,x21,#28 + add x20,x20,x17 // h+=Ch(e,f,g) + eor x17,x21,x21,ror#5 + add x20,x20,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x24,x24,x20 // d+=h + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x13,x17,ror#34 // Sigma0(a) + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x20,x20,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x11,x11 // 8 +#endif + add x20,x20,x17 // h+=Sigma0(a) + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x14,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x11 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x14,ror#18 // Sigma1(e) + ror x14,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x14,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x12,x12 // 9 +#endif + ldp x13,x14,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x15,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x12 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x15,ror#18 // Sigma1(e) + ror x15,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x15,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x13,x13 // 10 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x0,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x13 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x0,ror#18 // Sigma1(e) + ror x0,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x0,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x14,x14 // 11 +#endif + ldp x15,x0,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x6,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x14 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x15,x15 // 12 +#endif + add x24,x24,x17 // h+=Sigma0(a) + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x7,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x15 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x0,x0 // 13 +#endif + ldp x1,x2,[x1] + add x23,x23,x17 // h+=Sigma0(a) + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x8,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x0 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x1,x1 // 14 +#endif + ldr x6,[sp,#24] + add x22,x22,x17 // h+=Sigma0(a) + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x9,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x1 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x2,x2 // 15 +#endif + ldr x7,[sp,#0] + add x21,x21,x17 // h+=Sigma0(a) + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 +.Loop_16_xx: + ldr x8,[sp,#8] + str x11,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x10,x5,#1 + and x17,x25,x24 + ror x9,x2,#19 + bic x19,x26,x24 + ror x11,x20,#28 + add x27,x27,x3 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x10,x10,x5,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x11,x11,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x9,x9,x2,ror#61 + eor x10,x10,x5,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x11,x20,ror#39 // Sigma0(a) + eor x9,x9,x2,lsr#6 // sigma1(X[i+14]) + add x4,x4,x13 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x4,x4,x10 + add x27,x27,x17 // h+=Sigma0(a) + add x4,x4,x9 + ldr x9,[sp,#16] + str x12,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x11,x6,#1 + and x17,x24,x23 + ror x10,x3,#19 + bic x28,x25,x23 + ror x12,x27,#28 + add x26,x26,x4 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x11,x11,x6,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x12,x12,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x10,x10,x3,ror#61 + eor x11,x11,x6,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x12,x27,ror#39 // Sigma0(a) + eor x10,x10,x3,lsr#6 // sigma1(X[i+14]) + add x5,x5,x14 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x5,x5,x11 + add x26,x26,x17 // h+=Sigma0(a) + add x5,x5,x10 + ldr x10,[sp,#24] + str x13,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x12,x7,#1 + and x17,x23,x22 + ror x11,x4,#19 + bic x19,x24,x22 + ror x13,x26,#28 + add x25,x25,x5 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x12,x12,x7,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x13,x13,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x11,x11,x4,ror#61 + eor x12,x12,x7,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x13,x26,ror#39 // Sigma0(a) + eor x11,x11,x4,lsr#6 // sigma1(X[i+14]) + add x6,x6,x15 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x6,x6,x12 + add x25,x25,x17 // h+=Sigma0(a) + add x6,x6,x11 + ldr x11,[sp,#0] + str x14,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x13,x8,#1 + and x17,x22,x21 + ror x12,x5,#19 + bic x28,x23,x21 + ror x14,x25,#28 + add x24,x24,x6 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x13,x13,x8,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x14,x14,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x12,x12,x5,ror#61 + eor x13,x13,x8,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x14,x25,ror#39 // Sigma0(a) + eor x12,x12,x5,lsr#6 // sigma1(X[i+14]) + add x7,x7,x0 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x7,x7,x13 + add x24,x24,x17 // h+=Sigma0(a) + add x7,x7,x12 + ldr x12,[sp,#8] + str x15,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x14,x9,#1 + and x17,x21,x20 + ror x13,x6,#19 + bic x19,x22,x20 + ror x15,x24,#28 + add x23,x23,x7 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x14,x14,x9,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x15,x15,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x13,x13,x6,ror#61 + eor x14,x14,x9,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x15,x24,ror#39 // Sigma0(a) + eor x13,x13,x6,lsr#6 // sigma1(X[i+14]) + add x8,x8,x1 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x8,x8,x14 + add x23,x23,x17 // h+=Sigma0(a) + add x8,x8,x13 + ldr x13,[sp,#16] + str x0,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x15,x10,#1 + and x17,x20,x27 + ror x14,x7,#19 + bic x28,x21,x27 + ror x0,x23,#28 + add x22,x22,x8 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x15,x15,x10,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x0,x0,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x14,x14,x7,ror#61 + eor x15,x15,x10,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x0,x23,ror#39 // Sigma0(a) + eor x14,x14,x7,lsr#6 // sigma1(X[i+14]) + add x9,x9,x2 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x9,x9,x15 + add x22,x22,x17 // h+=Sigma0(a) + add x9,x9,x14 + ldr x14,[sp,#24] + str x1,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x0,x11,#1 + and x17,x27,x26 + ror x15,x8,#19 + bic x19,x20,x26 + ror x1,x22,#28 + add x21,x21,x9 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x0,x0,x11,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x1,x1,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x15,x15,x8,ror#61 + eor x0,x0,x11,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x1,x22,ror#39 // Sigma0(a) + eor x15,x15,x8,lsr#6 // sigma1(X[i+14]) + add x10,x10,x3 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x10,x10,x0 + add x21,x21,x17 // h+=Sigma0(a) + add x10,x10,x15 + ldr x15,[sp,#0] + str x2,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x1,x12,#1 + and x17,x26,x25 + ror x0,x9,#19 + bic x28,x27,x25 + ror x2,x21,#28 + add x20,x20,x10 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x1,x1,x12,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x2,x2,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x0,x0,x9,ror#61 + eor x1,x1,x12,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x2,x21,ror#39 // Sigma0(a) + eor x0,x0,x9,lsr#6 // sigma1(X[i+14]) + add x11,x11,x4 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x11,x11,x1 + add x20,x20,x17 // h+=Sigma0(a) + add x11,x11,x0 + ldr x0,[sp,#8] + str x3,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x2,x13,#1 + and x17,x25,x24 + ror x1,x10,#19 + bic x19,x26,x24 + ror x3,x20,#28 + add x27,x27,x11 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x2,x2,x13,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x3,x3,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x1,x1,x10,ror#61 + eor x2,x2,x13,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x3,x20,ror#39 // Sigma0(a) + eor x1,x1,x10,lsr#6 // sigma1(X[i+14]) + add x12,x12,x5 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x12,x12,x2 + add x27,x27,x17 // h+=Sigma0(a) + add x12,x12,x1 + ldr x1,[sp,#16] + str x4,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x3,x14,#1 + and x17,x24,x23 + ror x2,x11,#19 + bic x28,x25,x23 + ror x4,x27,#28 + add x26,x26,x12 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x3,x3,x14,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x4,x4,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x2,x2,x11,ror#61 + eor x3,x3,x14,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x4,x27,ror#39 // Sigma0(a) + eor x2,x2,x11,lsr#6 // sigma1(X[i+14]) + add x13,x13,x6 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x13,x13,x3 + add x26,x26,x17 // h+=Sigma0(a) + add x13,x13,x2 + ldr x2,[sp,#24] + str x5,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x4,x15,#1 + and x17,x23,x22 + ror x3,x12,#19 + bic x19,x24,x22 + ror x5,x26,#28 + add x25,x25,x13 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x4,x4,x15,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x5,x5,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x3,x3,x12,ror#61 + eor x4,x4,x15,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x5,x26,ror#39 // Sigma0(a) + eor x3,x3,x12,lsr#6 // sigma1(X[i+14]) + add x14,x14,x7 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x14,x14,x4 + add x25,x25,x17 // h+=Sigma0(a) + add x14,x14,x3 + ldr x3,[sp,#0] + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x5,x0,#1 + and x17,x22,x21 + ror x4,x13,#19 + bic x28,x23,x21 + ror x6,x25,#28 + add x24,x24,x14 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x5,x5,x0,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x6,x6,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x4,x4,x13,ror#61 + eor x5,x5,x0,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x25,ror#39 // Sigma0(a) + eor x4,x4,x13,lsr#6 // sigma1(X[i+14]) + add x15,x15,x8 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x15,x15,x5 + add x24,x24,x17 // h+=Sigma0(a) + add x15,x15,x4 + ldr x4,[sp,#8] + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x6,x1,#1 + and x17,x21,x20 + ror x5,x14,#19 + bic x19,x22,x20 + ror x7,x24,#28 + add x23,x23,x15 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x6,x6,x1,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x7,x7,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x5,x5,x14,ror#61 + eor x6,x6,x1,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x24,ror#39 // Sigma0(a) + eor x5,x5,x14,lsr#6 // sigma1(X[i+14]) + add x0,x0,x9 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x0,x0,x6 + add x23,x23,x17 // h+=Sigma0(a) + add x0,x0,x5 + ldr x5,[sp,#16] + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x7,x2,#1 + and x17,x20,x27 + ror x6,x15,#19 + bic x28,x21,x27 + ror x8,x23,#28 + add x22,x22,x0 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x7,x7,x2,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x8,x8,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x6,x6,x15,ror#61 + eor x7,x7,x2,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x23,ror#39 // Sigma0(a) + eor x6,x6,x15,lsr#6 // sigma1(X[i+14]) + add x1,x1,x10 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x1,x1,x7 + add x22,x22,x17 // h+=Sigma0(a) + add x1,x1,x6 + ldr x6,[sp,#24] + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x8,x3,#1 + and x17,x27,x26 + ror x7,x0,#19 + bic x19,x20,x26 + ror x9,x22,#28 + add x21,x21,x1 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x8,x8,x3,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x9,x9,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x7,x7,x0,ror#61 + eor x8,x8,x3,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x22,ror#39 // Sigma0(a) + eor x7,x7,x0,lsr#6 // sigma1(X[i+14]) + add x2,x2,x11 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x2,x2,x8 + add x21,x21,x17 // h+=Sigma0(a) + add x2,x2,x7 + ldr x7,[sp,#0] + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 + cbnz x19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#648 // rewind + + ldp x3,x4,[x0] + ldp x5,x6,[x0,#2*8] + add x1,x1,#14*8 // advance input pointer + ldp x7,x8,[x0,#4*8] + add x20,x20,x3 + ldp x9,x10,[x0,#6*8] + add x21,x21,x4 + add x22,x22,x5 + add x23,x23,x6 + stp x20,x21,[x0] + add x24,x24,x7 + add x25,x25,x8 + stp x22,x23,[x0,#2*8] + add x26,x26,x9 + add x27,x27,x10 + cmp x1,x2 + stp x24,x25,[x0,#4*8] + stp x26,x27,[x0,#6*8] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*8 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size sha512_block_data_order,.-sha512_block_data_order + +.align 6 +.type .LK512,%object +.LK512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0 // terminator +.size .LK512,.-.LK512 +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#ifndef __KERNEL__ +.type sha512_block_armv8,%function +.align 6 +sha512_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adr x3,.LK512 + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b .Loop_hw + +.align 4 +.Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,.Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret +.size sha512_block_armv8,.-sha512_block_armv8 +#endif diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf index 6d328dddb1..3d4917b29f 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf @@ -25,7 +25,7 @@ DEFINE OPENSSL_FLAGS = -DL_ENDIAN -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DEDK2_OPENSSL_NOEC=1 DEFINE OPENSSL_FLAGS_IA32 = -DAES_ASM -DGHASH_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM DEFINE OPENSSL_FLAGS_X64 = -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DKECCAK1600_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM - DEFINE OPENSSL_FLAGS_AARCH64 = + DEFINE OPENSSL_FLAGS_AARCH64 = -DKECCAK1600_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM # # VALID_ARCHITECTURES = IA32 X64 AARCH64 @@ -1330,6 +1330,625 @@ [Sources.AARCH64] # Autogenerated files list starts here + $(OPENSSL_PATH)/crypto/aes/aes_cbc.c + $(OPENSSL_PATH)/crypto/aes/aes_cfb.c + $(OPENSSL_PATH)/crypto/aes/aes_core.c + $(OPENSSL_PATH)/crypto/aes/aes_ecb.c + $(OPENSSL_PATH)/crypto/aes/aes_ige.c + $(OPENSSL_PATH)/crypto/aes/aes_misc.c + $(OPENSSL_PATH)/crypto/aes/aes_ofb.c + $(OPENSSL_PATH)/crypto/aes/aes_wrap.c + $(OPENSSL_PATH)/crypto/asn1/a_bitstr.c + $(OPENSSL_PATH)/crypto/asn1/a_d2i_fp.c + $(OPENSSL_PATH)/crypto/asn1/a_digest.c + $(OPENSSL_PATH)/crypto/asn1/a_dup.c + $(OPENSSL_PATH)/crypto/asn1/a_gentm.c + $(OPENSSL_PATH)/crypto/asn1/a_i2d_fp.c + $(OPENSSL_PATH)/crypto/asn1/a_int.c + $(OPENSSL_PATH)/crypto/asn1/a_mbstr.c + $(OPENSSL_PATH)/crypto/asn1/a_object.c + $(OPENSSL_PATH)/crypto/asn1/a_octet.c + $(OPENSSL_PATH)/crypto/asn1/a_print.c + $(OPENSSL_PATH)/crypto/asn1/a_sign.c + $(OPENSSL_PATH)/crypto/asn1/a_strex.c + $(OPENSSL_PATH)/crypto/asn1/a_strnid.c + $(OPENSSL_PATH)/crypto/asn1/a_time.c + $(OPENSSL_PATH)/crypto/asn1/a_type.c + $(OPENSSL_PATH)/crypto/asn1/a_utctm.c + $(OPENSSL_PATH)/crypto/asn1/a_utf8.c + $(OPENSSL_PATH)/crypto/asn1/a_verify.c + $(OPENSSL_PATH)/crypto/asn1/ameth_lib.c + $(OPENSSL_PATH)/crypto/asn1/asn1_err.c + $(OPENSSL_PATH)/crypto/asn1/asn1_gen.c + $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.c + $(OPENSSL_PATH)/crypto/asn1/asn1_lib.c + $(OPENSSL_PATH)/crypto/asn1/asn1_parse.c + $(OPENSSL_PATH)/crypto/asn1/asn_mime.c + $(OPENSSL_PATH)/crypto/asn1/asn_moid.c + $(OPENSSL_PATH)/crypto/asn1/asn_mstbl.c + $(OPENSSL_PATH)/crypto/asn1/asn_pack.c + $(OPENSSL_PATH)/crypto/asn1/bio_asn1.c + $(OPENSSL_PATH)/crypto/asn1/bio_ndef.c + $(OPENSSL_PATH)/crypto/asn1/d2i_param.c + $(OPENSSL_PATH)/crypto/asn1/d2i_pr.c + $(OPENSSL_PATH)/crypto/asn1/d2i_pu.c + $(OPENSSL_PATH)/crypto/asn1/evp_asn1.c + $(OPENSSL_PATH)/crypto/asn1/f_int.c + $(OPENSSL_PATH)/crypto/asn1/f_string.c + $(OPENSSL_PATH)/crypto/asn1/i2d_evp.c + $(OPENSSL_PATH)/crypto/asn1/nsseq.c + $(OPENSSL_PATH)/crypto/asn1/p5_pbe.c + $(OPENSSL_PATH)/crypto/asn1/p5_pbev2.c + $(OPENSSL_PATH)/crypto/asn1/p5_scrypt.c + $(OPENSSL_PATH)/crypto/asn1/p8_pkey.c + $(OPENSSL_PATH)/crypto/asn1/t_bitst.c + $(OPENSSL_PATH)/crypto/asn1/t_pkey.c + $(OPENSSL_PATH)/crypto/asn1/t_spki.c + $(OPENSSL_PATH)/crypto/asn1/tasn_dec.c + $(OPENSSL_PATH)/crypto/asn1/tasn_enc.c + $(OPENSSL_PATH)/crypto/asn1/tasn_fre.c + $(OPENSSL_PATH)/crypto/asn1/tasn_new.c + $(OPENSSL_PATH)/crypto/asn1/tasn_prn.c + $(OPENSSL_PATH)/crypto/asn1/tasn_scn.c + $(OPENSSL_PATH)/crypto/asn1/tasn_typ.c + $(OPENSSL_PATH)/crypto/asn1/tasn_utl.c + $(OPENSSL_PATH)/crypto/asn1/x_algor.c + $(OPENSSL_PATH)/crypto/asn1/x_bignum.c + $(OPENSSL_PATH)/crypto/asn1/x_info.c + $(OPENSSL_PATH)/crypto/asn1/x_int64.c + $(OPENSSL_PATH)/crypto/asn1/x_long.c + $(OPENSSL_PATH)/crypto/asn1/x_pkey.c + $(OPENSSL_PATH)/crypto/asn1/x_sig.c + $(OPENSSL_PATH)/crypto/asn1/x_spki.c + $(OPENSSL_PATH)/crypto/asn1/x_val.c + $(OPENSSL_PATH)/crypto/async/arch/async_null.c + $(OPENSSL_PATH)/crypto/async/arch/async_posix.c + $(OPENSSL_PATH)/crypto/async/arch/async_win.c + $(OPENSSL_PATH)/crypto/async/async.c + $(OPENSSL_PATH)/crypto/async/async_err.c + $(OPENSSL_PATH)/crypto/async/async_wait.c + $(OPENSSL_PATH)/crypto/bio/bf_buff.c + $(OPENSSL_PATH)/crypto/bio/bf_lbuf.c + $(OPENSSL_PATH)/crypto/bio/bf_nbio.c + $(OPENSSL_PATH)/crypto/bio/bf_null.c + $(OPENSSL_PATH)/crypto/bio/bf_prefix.c + $(OPENSSL_PATH)/crypto/bio/bf_readbuff.c + $(OPENSSL_PATH)/crypto/bio/bio_addr.c + $(OPENSSL_PATH)/crypto/bio/bio_cb.c + $(OPENSSL_PATH)/crypto/bio/bio_dump.c + $(OPENSSL_PATH)/crypto/bio/bio_err.c + $(OPENSSL_PATH)/crypto/bio/bio_lib.c + $(OPENSSL_PATH)/crypto/bio/bio_meth.c + $(OPENSSL_PATH)/crypto/bio/bio_print.c + $(OPENSSL_PATH)/crypto/bio/bio_sock.c + $(OPENSSL_PATH)/crypto/bio/bio_sock2.c + $(OPENSSL_PATH)/crypto/bio/bss_acpt.c + $(OPENSSL_PATH)/crypto/bio/bss_bio.c + $(OPENSSL_PATH)/crypto/bio/bss_conn.c + $(OPENSSL_PATH)/crypto/bio/bss_core.c + $(OPENSSL_PATH)/crypto/bio/bss_dgram.c + $(OPENSSL_PATH)/crypto/bio/bss_fd.c + $(OPENSSL_PATH)/crypto/bio/bss_file.c + $(OPENSSL_PATH)/crypto/bio/bss_log.c + $(OPENSSL_PATH)/crypto/bio/bss_mem.c + $(OPENSSL_PATH)/crypto/bio/bss_null.c + $(OPENSSL_PATH)/crypto/bio/bss_sock.c + $(OPENSSL_PATH)/crypto/bio/ossl_core_bio.c + $(OPENSSL_PATH)/crypto/bn/bn_add.c + $(OPENSSL_PATH)/crypto/bn/bn_asm.c + $(OPENSSL_PATH)/crypto/bn/bn_blind.c + $(OPENSSL_PATH)/crypto/bn/bn_const.c + $(OPENSSL_PATH)/crypto/bn/bn_conv.c + $(OPENSSL_PATH)/crypto/bn/bn_ctx.c + $(OPENSSL_PATH)/crypto/bn/bn_dh.c + $(OPENSSL_PATH)/crypto/bn/bn_div.c + $(OPENSSL_PATH)/crypto/bn/bn_err.c + $(OPENSSL_PATH)/crypto/bn/bn_exp.c + $(OPENSSL_PATH)/crypto/bn/bn_exp2.c + $(OPENSSL_PATH)/crypto/bn/bn_gcd.c + $(OPENSSL_PATH)/crypto/bn/bn_gf2m.c + $(OPENSSL_PATH)/crypto/bn/bn_intern.c + $(OPENSSL_PATH)/crypto/bn/bn_kron.c + $(OPENSSL_PATH)/crypto/bn/bn_lib.c + $(OPENSSL_PATH)/crypto/bn/bn_mod.c + $(OPENSSL_PATH)/crypto/bn/bn_mont.c + $(OPENSSL_PATH)/crypto/bn/bn_mpi.c + $(OPENSSL_PATH)/crypto/bn/bn_mul.c + $(OPENSSL_PATH)/crypto/bn/bn_nist.c + $(OPENSSL_PATH)/crypto/bn/bn_prime.c + $(OPENSSL_PATH)/crypto/bn/bn_print.c + $(OPENSSL_PATH)/crypto/bn/bn_rand.c + $(OPENSSL_PATH)/crypto/bn/bn_recp.c + $(OPENSSL_PATH)/crypto/bn/bn_rsa_fips186_4.c + $(OPENSSL_PATH)/crypto/bn/bn_shift.c + $(OPENSSL_PATH)/crypto/bn/bn_sqr.c + $(OPENSSL_PATH)/crypto/bn/bn_sqrt.c + $(OPENSSL_PATH)/crypto/bn/bn_srp.c + $(OPENSSL_PATH)/crypto/bn/bn_word.c + $(OPENSSL_PATH)/crypto/bn/bn_x931p.c + $(OPENSSL_PATH)/crypto/buffer/buf_err.c + $(OPENSSL_PATH)/crypto/buffer/buffer.c + $(OPENSSL_PATH)/crypto/comp/c_zlib.c + $(OPENSSL_PATH)/crypto/comp/comp_err.c + $(OPENSSL_PATH)/crypto/comp/comp_lib.c + $(OPENSSL_PATH)/crypto/conf/conf_api.c + $(OPENSSL_PATH)/crypto/conf/conf_def.c + $(OPENSSL_PATH)/crypto/conf/conf_err.c + $(OPENSSL_PATH)/crypto/conf/conf_lib.c + $(OPENSSL_PATH)/crypto/conf/conf_mall.c + $(OPENSSL_PATH)/crypto/conf/conf_mod.c + $(OPENSSL_PATH)/crypto/conf/conf_sap.c + $(OPENSSL_PATH)/crypto/conf/conf_ssl.c + $(OPENSSL_PATH)/crypto/dh/dh_ameth.c + $(OPENSSL_PATH)/crypto/dh/dh_asn1.c + $(OPENSSL_PATH)/crypto/dh/dh_backend.c + $(OPENSSL_PATH)/crypto/dh/dh_check.c + $(OPENSSL_PATH)/crypto/dh/dh_err.c + $(OPENSSL_PATH)/crypto/dh/dh_gen.c + $(OPENSSL_PATH)/crypto/dh/dh_group_params.c + $(OPENSSL_PATH)/crypto/dh/dh_kdf.c + $(OPENSSL_PATH)/crypto/dh/dh_key.c + $(OPENSSL_PATH)/crypto/dh/dh_lib.c + $(OPENSSL_PATH)/crypto/dh/dh_meth.c + $(OPENSSL_PATH)/crypto/dh/dh_pmeth.c + $(OPENSSL_PATH)/crypto/dh/dh_prn.c + $(OPENSSL_PATH)/crypto/dh/dh_rfc5114.c + $(OPENSSL_PATH)/crypto/dso/dso_dl.c + $(OPENSSL_PATH)/crypto/dso/dso_dlfcn.c + $(OPENSSL_PATH)/crypto/dso/dso_err.c + $(OPENSSL_PATH)/crypto/dso/dso_lib.c + $(OPENSSL_PATH)/crypto/dso/dso_openssl.c + $(OPENSSL_PATH)/crypto/dso/dso_vms.c + $(OPENSSL_PATH)/crypto/dso/dso_win32.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_err.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_lib.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_meth.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_pkey.c + $(OPENSSL_PATH)/crypto/err/err.c + $(OPENSSL_PATH)/crypto/err/err_all.c + $(OPENSSL_PATH)/crypto/err/err_all_legacy.c + $(OPENSSL_PATH)/crypto/err/err_blocks.c + $(OPENSSL_PATH)/crypto/err/err_prn.c + $(OPENSSL_PATH)/crypto/ess/ess_asn1.c + $(OPENSSL_PATH)/crypto/ess/ess_err.c + $(OPENSSL_PATH)/crypto/ess/ess_lib.c + $(OPENSSL_PATH)/crypto/evp/asymcipher.c + $(OPENSSL_PATH)/crypto/evp/bio_b64.c + $(OPENSSL_PATH)/crypto/evp/bio_enc.c + $(OPENSSL_PATH)/crypto/evp/bio_md.c + $(OPENSSL_PATH)/crypto/evp/bio_ok.c + $(OPENSSL_PATH)/crypto/evp/c_allc.c + $(OPENSSL_PATH)/crypto/evp/c_alld.c + $(OPENSSL_PATH)/crypto/evp/cmeth_lib.c + $(OPENSSL_PATH)/crypto/evp/ctrl_params_translate.c + $(OPENSSL_PATH)/crypto/evp/dh_ctrl.c + $(OPENSSL_PATH)/crypto/evp/dh_support.c + $(OPENSSL_PATH)/crypto/evp/digest.c + $(OPENSSL_PATH)/crypto/evp/dsa_ctrl.c + $(OPENSSL_PATH)/crypto/evp/e_aes.c + $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha1.c + $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha256.c + $(OPENSSL_PATH)/crypto/evp/e_aria.c + $(OPENSSL_PATH)/crypto/evp/e_bf.c + $(OPENSSL_PATH)/crypto/evp/e_cast.c + $(OPENSSL_PATH)/crypto/evp/e_chacha20_poly1305.c + $(OPENSSL_PATH)/crypto/evp/e_des.c + $(OPENSSL_PATH)/crypto/evp/e_des3.c + $(OPENSSL_PATH)/crypto/evp/e_idea.c + $(OPENSSL_PATH)/crypto/evp/e_null.c + $(OPENSSL_PATH)/crypto/evp/e_rc2.c + $(OPENSSL_PATH)/crypto/evp/e_rc4.c + $(OPENSSL_PATH)/crypto/evp/e_rc4_hmac_md5.c + $(OPENSSL_PATH)/crypto/evp/e_rc5.c + $(OPENSSL_PATH)/crypto/evp/e_sm4.c + $(OPENSSL_PATH)/crypto/evp/e_xcbc_d.c + $(OPENSSL_PATH)/crypto/evp/ec_ctrl.c + $(OPENSSL_PATH)/crypto/evp/ec_support.c + $(OPENSSL_PATH)/crypto/evp/encode.c + $(OPENSSL_PATH)/crypto/evp/evp_cnf.c + $(OPENSSL_PATH)/crypto/evp/evp_enc.c + $(OPENSSL_PATH)/crypto/evp/evp_err.c + $(OPENSSL_PATH)/crypto/evp/evp_fetch.c + $(OPENSSL_PATH)/crypto/evp/evp_key.c + $(OPENSSL_PATH)/crypto/evp/evp_lib.c + $(OPENSSL_PATH)/crypto/evp/evp_pbe.c + $(OPENSSL_PATH)/crypto/evp/evp_pkey.c + $(OPENSSL_PATH)/crypto/evp/evp_rand.c + $(OPENSSL_PATH)/crypto/evp/evp_utils.c + $(OPENSSL_PATH)/crypto/evp/exchange.c + $(OPENSSL_PATH)/crypto/evp/kdf_lib.c + $(OPENSSL_PATH)/crypto/evp/kdf_meth.c + $(OPENSSL_PATH)/crypto/evp/kem.c + $(OPENSSL_PATH)/crypto/evp/keymgmt_lib.c + $(OPENSSL_PATH)/crypto/evp/keymgmt_meth.c + $(OPENSSL_PATH)/crypto/evp/legacy_md5.c + $(OPENSSL_PATH)/crypto/evp/legacy_md5_sha1.c + $(OPENSSL_PATH)/crypto/evp/legacy_sha.c + $(OPENSSL_PATH)/crypto/evp/m_null.c + $(OPENSSL_PATH)/crypto/evp/m_sigver.c + $(OPENSSL_PATH)/crypto/evp/mac_lib.c + $(OPENSSL_PATH)/crypto/evp/mac_meth.c + $(OPENSSL_PATH)/crypto/evp/names.c + $(OPENSSL_PATH)/crypto/evp/p5_crpt.c + $(OPENSSL_PATH)/crypto/evp/p5_crpt2.c + $(OPENSSL_PATH)/crypto/evp/p_dec.c + $(OPENSSL_PATH)/crypto/evp/p_enc.c + $(OPENSSL_PATH)/crypto/evp/p_legacy.c + $(OPENSSL_PATH)/crypto/evp/p_lib.c + $(OPENSSL_PATH)/crypto/evp/p_open.c + $(OPENSSL_PATH)/crypto/evp/p_seal.c + $(OPENSSL_PATH)/crypto/evp/p_sign.c + $(OPENSSL_PATH)/crypto/evp/p_verify.c + $(OPENSSL_PATH)/crypto/evp/pbe_scrypt.c + $(OPENSSL_PATH)/crypto/evp/pmeth_check.c + $(OPENSSL_PATH)/crypto/evp/pmeth_gn.c + $(OPENSSL_PATH)/crypto/evp/pmeth_lib.c + $(OPENSSL_PATH)/crypto/evp/signature.c + $(OPENSSL_PATH)/crypto/ffc/ffc_backend.c + $(OPENSSL_PATH)/crypto/ffc/ffc_dh.c + $(OPENSSL_PATH)/crypto/ffc/ffc_key_generate.c + $(OPENSSL_PATH)/crypto/ffc/ffc_key_validate.c + $(OPENSSL_PATH)/crypto/ffc/ffc_params.c + $(OPENSSL_PATH)/crypto/ffc/ffc_params_generate.c + $(OPENSSL_PATH)/crypto/ffc/ffc_params_validate.c + $(OPENSSL_PATH)/crypto/hmac/hmac.c + $(OPENSSL_PATH)/crypto/http/http_client.c + $(OPENSSL_PATH)/crypto/http/http_err.c + $(OPENSSL_PATH)/crypto/http/http_lib.c + $(OPENSSL_PATH)/crypto/kdf/kdf_err.c + $(OPENSSL_PATH)/crypto/lhash/lh_stats.c + $(OPENSSL_PATH)/crypto/lhash/lhash.c + $(OPENSSL_PATH)/crypto/asn1_dsa.c + $(OPENSSL_PATH)/crypto/bsearch.c + $(OPENSSL_PATH)/crypto/context.c + $(OPENSSL_PATH)/crypto/core_algorithm.c + $(OPENSSL_PATH)/crypto/core_fetch.c + $(OPENSSL_PATH)/crypto/core_namemap.c + $(OPENSSL_PATH)/crypto/cpt_err.c + $(OPENSSL_PATH)/crypto/cpuid.c + $(OPENSSL_PATH)/crypto/cryptlib.c + $(OPENSSL_PATH)/crypto/ctype.c + $(OPENSSL_PATH)/crypto/cversion.c + $(OPENSSL_PATH)/crypto/der_writer.c + $(OPENSSL_PATH)/crypto/ebcdic.c + $(OPENSSL_PATH)/crypto/ex_data.c + $(OPENSSL_PATH)/crypto/getenv.c + $(OPENSSL_PATH)/crypto/info.c + $(OPENSSL_PATH)/crypto/init.c + $(OPENSSL_PATH)/crypto/initthread.c + $(OPENSSL_PATH)/crypto/mem.c + $(OPENSSL_PATH)/crypto/mem_sec.c + $(OPENSSL_PATH)/crypto/o_dir.c + $(OPENSSL_PATH)/crypto/o_fopen.c + $(OPENSSL_PATH)/crypto/o_init.c + $(OPENSSL_PATH)/crypto/o_str.c + $(OPENSSL_PATH)/crypto/o_time.c + $(OPENSSL_PATH)/crypto/packet.c + $(OPENSSL_PATH)/crypto/param_build.c + $(OPENSSL_PATH)/crypto/param_build_set.c + $(OPENSSL_PATH)/crypto/params.c + $(OPENSSL_PATH)/crypto/params_dup.c + $(OPENSSL_PATH)/crypto/params_from_text.c + $(OPENSSL_PATH)/crypto/passphrase.c + $(OPENSSL_PATH)/crypto/provider.c + $(OPENSSL_PATH)/crypto/provider_child.c + $(OPENSSL_PATH)/crypto/provider_conf.c + $(OPENSSL_PATH)/crypto/provider_core.c + $(OPENSSL_PATH)/crypto/punycode.c + $(OPENSSL_PATH)/crypto/self_test_core.c + $(OPENSSL_PATH)/crypto/sparse_array.c + $(OPENSSL_PATH)/crypto/threads_lib.c + $(OPENSSL_PATH)/crypto/threads_none.c + $(OPENSSL_PATH)/crypto/threads_pthread.c + $(OPENSSL_PATH)/crypto/threads_win.c + $(OPENSSL_PATH)/crypto/trace.c + $(OPENSSL_PATH)/crypto/uid.c + $(OPENSSL_PATH)/crypto/md5/md5_dgst.c + $(OPENSSL_PATH)/crypto/md5/md5_one.c + $(OPENSSL_PATH)/crypto/md5/md5_sha1.c + $(OPENSSL_PATH)/crypto/modes/cbc128.c + $(OPENSSL_PATH)/crypto/modes/ccm128.c + $(OPENSSL_PATH)/crypto/modes/cfb128.c + $(OPENSSL_PATH)/crypto/modes/ctr128.c + $(OPENSSL_PATH)/crypto/modes/cts128.c + $(OPENSSL_PATH)/crypto/modes/gcm128.c + $(OPENSSL_PATH)/crypto/modes/ocb128.c + $(OPENSSL_PATH)/crypto/modes/ofb128.c + $(OPENSSL_PATH)/crypto/modes/siv128.c + $(OPENSSL_PATH)/crypto/modes/wrap128.c + $(OPENSSL_PATH)/crypto/modes/xts128.c + $(OPENSSL_PATH)/crypto/objects/o_names.c + $(OPENSSL_PATH)/crypto/objects/obj_dat.c + $(OPENSSL_PATH)/crypto/objects/obj_err.c + $(OPENSSL_PATH)/crypto/objects/obj_lib.c + $(OPENSSL_PATH)/crypto/objects/obj_xref.c + $(OPENSSL_PATH)/crypto/pem/pem_all.c + $(OPENSSL_PATH)/crypto/pem/pem_err.c + $(OPENSSL_PATH)/crypto/pem/pem_info.c + $(OPENSSL_PATH)/crypto/pem/pem_lib.c + $(OPENSSL_PATH)/crypto/pem/pem_oth.c + $(OPENSSL_PATH)/crypto/pem/pem_pk8.c + $(OPENSSL_PATH)/crypto/pem/pem_pkey.c + $(OPENSSL_PATH)/crypto/pem/pem_sign.c + $(OPENSSL_PATH)/crypto/pem/pem_x509.c + $(OPENSSL_PATH)/crypto/pem/pem_xaux.c + $(OPENSSL_PATH)/crypto/pem/pvkfmt.c + $(OPENSSL_PATH)/crypto/pkcs7/bio_pk7.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_asn1.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_attr.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_doit.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_lib.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_mime.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_smime.c + $(OPENSSL_PATH)/crypto/pkcs7/pkcs7err.c + $(OPENSSL_PATH)/crypto/property/defn_cache.c + $(OPENSSL_PATH)/crypto/property/property.c + $(OPENSSL_PATH)/crypto/property/property_err.c + $(OPENSSL_PATH)/crypto/property/property_parse.c + $(OPENSSL_PATH)/crypto/property/property_query.c + $(OPENSSL_PATH)/crypto/property/property_string.c + $(OPENSSL_PATH)/crypto/rand/prov_seed.c + $(OPENSSL_PATH)/crypto/rand/rand_deprecated.c + $(OPENSSL_PATH)/crypto/rand/rand_err.c + $(OPENSSL_PATH)/crypto/rand/rand_lib.c + $(OPENSSL_PATH)/crypto/rand/rand_meth.c + $(OPENSSL_PATH)/crypto/rand/rand_pool.c + $(OPENSSL_PATH)/crypto/rsa/rsa_ameth.c + $(OPENSSL_PATH)/crypto/rsa/rsa_asn1.c + $(OPENSSL_PATH)/crypto/rsa/rsa_backend.c + $(OPENSSL_PATH)/crypto/rsa/rsa_chk.c + $(OPENSSL_PATH)/crypto/rsa/rsa_crpt.c + $(OPENSSL_PATH)/crypto/rsa/rsa_err.c + $(OPENSSL_PATH)/crypto/rsa/rsa_gen.c + $(OPENSSL_PATH)/crypto/rsa/rsa_lib.c + $(OPENSSL_PATH)/crypto/rsa/rsa_meth.c + $(OPENSSL_PATH)/crypto/rsa/rsa_mp.c + $(OPENSSL_PATH)/crypto/rsa/rsa_mp_names.c + $(OPENSSL_PATH)/crypto/rsa/rsa_none.c + $(OPENSSL_PATH)/crypto/rsa/rsa_oaep.c + $(OPENSSL_PATH)/crypto/rsa/rsa_ossl.c + $(OPENSSL_PATH)/crypto/rsa/rsa_pk1.c + $(OPENSSL_PATH)/crypto/rsa/rsa_pmeth.c + $(OPENSSL_PATH)/crypto/rsa/rsa_prn.c + $(OPENSSL_PATH)/crypto/rsa/rsa_pss.c + $(OPENSSL_PATH)/crypto/rsa/rsa_saos.c + $(OPENSSL_PATH)/crypto/rsa/rsa_schemes.c + $(OPENSSL_PATH)/crypto/rsa/rsa_sign.c + $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_check.c + $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_gen.c + $(OPENSSL_PATH)/crypto/rsa/rsa_x931.c + $(OPENSSL_PATH)/crypto/rsa/rsa_x931g.c + $(OPENSSL_PATH)/crypto/sha/sha1_one.c + $(OPENSSL_PATH)/crypto/sha/sha1dgst.c + $(OPENSSL_PATH)/crypto/sha/sha256.c + $(OPENSSL_PATH)/crypto/sha/sha3.c + $(OPENSSL_PATH)/crypto/sha/sha512.c + $(OPENSSL_PATH)/crypto/sm3/legacy_sm3.c + $(OPENSSL_PATH)/crypto/sm3/sm3.c + $(OPENSSL_PATH)/crypto/stack/stack.c + $(OPENSSL_PATH)/crypto/txt_db/txt_db.c + $(OPENSSL_PATH)/crypto/ui/ui_err.c + $(OPENSSL_PATH)/crypto/ui/ui_lib.c + $(OPENSSL_PATH)/crypto/ui/ui_null.c + $(OPENSSL_PATH)/crypto/ui/ui_openssl.c + $(OPENSSL_PATH)/crypto/ui/ui_util.c + $(OPENSSL_PATH)/crypto/x509/by_dir.c + $(OPENSSL_PATH)/crypto/x509/by_file.c + $(OPENSSL_PATH)/crypto/x509/by_store.c + $(OPENSSL_PATH)/crypto/x509/pcy_cache.c + $(OPENSSL_PATH)/crypto/x509/pcy_data.c + $(OPENSSL_PATH)/crypto/x509/pcy_lib.c + $(OPENSSL_PATH)/crypto/x509/pcy_map.c + $(OPENSSL_PATH)/crypto/x509/pcy_node.c + $(OPENSSL_PATH)/crypto/x509/pcy_tree.c + $(OPENSSL_PATH)/crypto/x509/t_crl.c + $(OPENSSL_PATH)/crypto/x509/t_req.c + $(OPENSSL_PATH)/crypto/x509/t_x509.c + $(OPENSSL_PATH)/crypto/x509/v3_addr.c + $(OPENSSL_PATH)/crypto/x509/v3_admis.c + $(OPENSSL_PATH)/crypto/x509/v3_akeya.c + $(OPENSSL_PATH)/crypto/x509/v3_akid.c + $(OPENSSL_PATH)/crypto/x509/v3_asid.c + $(OPENSSL_PATH)/crypto/x509/v3_bcons.c + $(OPENSSL_PATH)/crypto/x509/v3_bitst.c + $(OPENSSL_PATH)/crypto/x509/v3_conf.c + $(OPENSSL_PATH)/crypto/x509/v3_cpols.c + $(OPENSSL_PATH)/crypto/x509/v3_crld.c + $(OPENSSL_PATH)/crypto/x509/v3_enum.c + $(OPENSSL_PATH)/crypto/x509/v3_extku.c + $(OPENSSL_PATH)/crypto/x509/v3_genn.c + $(OPENSSL_PATH)/crypto/x509/v3_ia5.c + $(OPENSSL_PATH)/crypto/x509/v3_info.c + $(OPENSSL_PATH)/crypto/x509/v3_int.c + $(OPENSSL_PATH)/crypto/x509/v3_ist.c + $(OPENSSL_PATH)/crypto/x509/v3_lib.c + $(OPENSSL_PATH)/crypto/x509/v3_ncons.c + $(OPENSSL_PATH)/crypto/x509/v3_pci.c + $(OPENSSL_PATH)/crypto/x509/v3_pcia.c + $(OPENSSL_PATH)/crypto/x509/v3_pcons.c + $(OPENSSL_PATH)/crypto/x509/v3_pku.c + $(OPENSSL_PATH)/crypto/x509/v3_pmaps.c + $(OPENSSL_PATH)/crypto/x509/v3_prn.c + $(OPENSSL_PATH)/crypto/x509/v3_purp.c + $(OPENSSL_PATH)/crypto/x509/v3_san.c + $(OPENSSL_PATH)/crypto/x509/v3_skid.c + $(OPENSSL_PATH)/crypto/x509/v3_sxnet.c + $(OPENSSL_PATH)/crypto/x509/v3_tlsf.c + $(OPENSSL_PATH)/crypto/x509/v3_utf8.c + $(OPENSSL_PATH)/crypto/x509/v3_utl.c + $(OPENSSL_PATH)/crypto/x509/v3err.c + $(OPENSSL_PATH)/crypto/x509/x509_att.c + $(OPENSSL_PATH)/crypto/x509/x509_cmp.c + $(OPENSSL_PATH)/crypto/x509/x509_d2.c + $(OPENSSL_PATH)/crypto/x509/x509_def.c + $(OPENSSL_PATH)/crypto/x509/x509_err.c + $(OPENSSL_PATH)/crypto/x509/x509_ext.c + $(OPENSSL_PATH)/crypto/x509/x509_lu.c + $(OPENSSL_PATH)/crypto/x509/x509_meth.c + $(OPENSSL_PATH)/crypto/x509/x509_obj.c + $(OPENSSL_PATH)/crypto/x509/x509_r2x.c + $(OPENSSL_PATH)/crypto/x509/x509_req.c + $(OPENSSL_PATH)/crypto/x509/x509_set.c + $(OPENSSL_PATH)/crypto/x509/x509_trust.c + $(OPENSSL_PATH)/crypto/x509/x509_txt.c + $(OPENSSL_PATH)/crypto/x509/x509_v3.c + $(OPENSSL_PATH)/crypto/x509/x509_vfy.c + $(OPENSSL_PATH)/crypto/x509/x509_vpm.c + $(OPENSSL_PATH)/crypto/x509/x509cset.c + $(OPENSSL_PATH)/crypto/x509/x509name.c + $(OPENSSL_PATH)/crypto/x509/x509rset.c + $(OPENSSL_PATH)/crypto/x509/x509spki.c + $(OPENSSL_PATH)/crypto/x509/x509type.c + $(OPENSSL_PATH)/crypto/x509/x_all.c + $(OPENSSL_PATH)/crypto/x509/x_attrib.c + $(OPENSSL_PATH)/crypto/x509/x_crl.c + $(OPENSSL_PATH)/crypto/x509/x_exten.c + $(OPENSSL_PATH)/crypto/x509/x_name.c + $(OPENSSL_PATH)/crypto/x509/x_pubkey.c + $(OPENSSL_PATH)/crypto/x509/x_req.c + $(OPENSSL_PATH)/crypto/x509/x_x509.c + $(OPENSSL_PATH)/crypto/x509/x_x509a.c + $(OPENSSL_PATH)/providers/nullprov.c + $(OPENSSL_PATH)/providers/prov_running.c + $(OPENSSL_PATH)/providers/common/der/der_rsa_sig.c + $(OPENSSL_PATH)/providers/common/bio_prov.c + $(OPENSSL_PATH)/providers/common/capabilities.c + $(OPENSSL_PATH)/providers/common/digest_to_nid.c + $(OPENSSL_PATH)/providers/common/provider_seeding.c + $(OPENSSL_PATH)/providers/common/provider_util.c + $(OPENSSL_PATH)/providers/common/securitycheck.c + $(OPENSSL_PATH)/providers/common/securitycheck_default.c + $(OPENSSL_PATH)/providers/implementations/asymciphers/rsa_enc.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_wrp.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_fips.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_cts.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_null.c + $(OPENSSL_PATH)/providers/implementations/digests/md5_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/md5_sha1_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/null_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/sha2_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/sha3_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/sm3_prov.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_der2key.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_epki2pki.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_msblob2key.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pem2der.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pvk2key.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_spki2typespki.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/endecoder_common.c + $(OPENSSL_PATH)/providers/implementations/exchange/dh_exch.c + $(OPENSSL_PATH)/providers/implementations/exchange/kdf_exch.c + $(OPENSSL_PATH)/providers/implementations/kdfs/hkdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/kbkdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/krb5kdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2.c + $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2_fips.c + $(OPENSSL_PATH)/providers/implementations/kdfs/pkcs12kdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/scrypt.c + $(OPENSSL_PATH)/providers/implementations/kdfs/sshkdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/sskdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/tls1_prf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/x942kdf.c + $(OPENSSL_PATH)/providers/implementations/kem/rsa_kem.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/dh_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/kdf_legacy_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/mac_legacy_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/rsa_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/macs/gmac_prov.c + $(OPENSSL_PATH)/providers/implementations/macs/hmac_prov.c + $(OPENSSL_PATH)/providers/implementations/macs/kmac_prov.c + $(OPENSSL_PATH)/providers/implementations/rands/crngt.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg_ctr.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg_hash.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg_hmac.c + $(OPENSSL_PATH)/providers/implementations/rands/seed_src.c + $(OPENSSL_PATH)/providers/implementations/rands/test_rng.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_cpu_x86.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_tsc.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_unix.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_win.c + $(OPENSSL_PATH)/providers/implementations/signature/mac_legacy_sig.c + $(OPENSSL_PATH)/providers/implementations/signature/rsa_sig.c + $(OPENSSL_PATH)/ssl/s3_cbc.c + $(OPENSSL_PATH)/providers/common/der/der_rsa_key.c + $(OPENSSL_PATH)/providers/common/provider_ctx.c + $(OPENSSL_PATH)/providers/common/provider_err.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_block.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_hw.c + $(OPENSSL_PATH)/providers/implementations/digests/digestcommon.c + $(OPENSSL_PATH)/ssl/record/tls_pad.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_digests_gen.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_rsa_gen.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_wrap_gen.c + $(OPENSSL_PATH)/ssl/bio_ssl.c + $(OPENSSL_PATH)/ssl/d1_lib.c + $(OPENSSL_PATH)/ssl/d1_msg.c + $(OPENSSL_PATH)/ssl/d1_srtp.c + $(OPENSSL_PATH)/ssl/methods.c + $(OPENSSL_PATH)/ssl/pqueue.c + $(OPENSSL_PATH)/ssl/s3_enc.c + $(OPENSSL_PATH)/ssl/s3_lib.c + $(OPENSSL_PATH)/ssl/s3_msg.c + $(OPENSSL_PATH)/ssl/ssl_asn1.c + $(OPENSSL_PATH)/ssl/ssl_cert.c + $(OPENSSL_PATH)/ssl/ssl_ciph.c + $(OPENSSL_PATH)/ssl/ssl_conf.c + $(OPENSSL_PATH)/ssl/ssl_err.c + $(OPENSSL_PATH)/ssl/ssl_err_legacy.c + $(OPENSSL_PATH)/ssl/ssl_init.c + $(OPENSSL_PATH)/ssl/ssl_lib.c + $(OPENSSL_PATH)/ssl/ssl_mcnf.c + $(OPENSSL_PATH)/ssl/ssl_rsa.c + $(OPENSSL_PATH)/ssl/ssl_rsa_legacy.c + $(OPENSSL_PATH)/ssl/ssl_sess.c + $(OPENSSL_PATH)/ssl/ssl_stat.c + $(OPENSSL_PATH)/ssl/ssl_txt.c + $(OPENSSL_PATH)/ssl/ssl_utst.c + $(OPENSSL_PATH)/ssl/t1_enc.c + $(OPENSSL_PATH)/ssl/t1_lib.c + $(OPENSSL_PATH)/ssl/t1_trce.c + $(OPENSSL_PATH)/ssl/tls13_enc.c + $(OPENSSL_PATH)/ssl/tls_depr.c + $(OPENSSL_PATH)/ssl/tls_srp.c + $(OPENSSL_PATH)/ssl/record/dtls1_bitmap.c + $(OPENSSL_PATH)/ssl/record/rec_layer_d1.c + $(OPENSSL_PATH)/ssl/record/rec_layer_s3.c + $(OPENSSL_PATH)/ssl/record/ssl3_buffer.c + $(OPENSSL_PATH)/ssl/record/ssl3_record.c + $(OPENSSL_PATH)/ssl/record/ssl3_record_tls13.c + $(OPENSSL_PATH)/ssl/statem/extensions.c + $(OPENSSL_PATH)/ssl/statem/extensions_clnt.c + $(OPENSSL_PATH)/ssl/statem/extensions_cust.c + $(OPENSSL_PATH)/ssl/statem/statem.c + $(OPENSSL_PATH)/ssl/statem/statem_clnt.c + $(OPENSSL_PATH)/ssl/statem/statem_dtls.c + $(OPENSSL_PATH)/ssl/statem/statem_lib.c + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/aesv8-armx.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/vpaes-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/arm64cpuid.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/ghashv8-armx.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/keccak1600-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha1-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha256-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha512-armv8.S | GCC # Autogenerated files list ends here [Packages] diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf index e9f0fa94bf..715c483536 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf @@ -30,7 +30,7 @@ DEFINE OPENSSL_FLAGS = -DL_ENDIAN -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE DEFINE OPENSSL_FLAGS_IA32 = -DAES_ASM -DGHASH_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM DEFINE OPENSSL_FLAGS_X64 = -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DKECCAK1600_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM - DEFINE OPENSSL_FLAGS_AARCH64 = + DEFINE OPENSSL_FLAGS_AARCH64 = -DKECCAK1600_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM # # VALID_ARCHITECTURES = IA32 X64 AARCH64 @@ -1433,6 +1433,674 @@ [Sources.AARCH64] # Autogenerated files list starts here + $(OPENSSL_PATH)/crypto/aes/aes_cbc.c + $(OPENSSL_PATH)/crypto/aes/aes_cfb.c + $(OPENSSL_PATH)/crypto/aes/aes_core.c + $(OPENSSL_PATH)/crypto/aes/aes_ecb.c + $(OPENSSL_PATH)/crypto/aes/aes_ige.c + $(OPENSSL_PATH)/crypto/aes/aes_misc.c + $(OPENSSL_PATH)/crypto/aes/aes_ofb.c + $(OPENSSL_PATH)/crypto/aes/aes_wrap.c + $(OPENSSL_PATH)/crypto/asn1/a_bitstr.c + $(OPENSSL_PATH)/crypto/asn1/a_d2i_fp.c + $(OPENSSL_PATH)/crypto/asn1/a_digest.c + $(OPENSSL_PATH)/crypto/asn1/a_dup.c + $(OPENSSL_PATH)/crypto/asn1/a_gentm.c + $(OPENSSL_PATH)/crypto/asn1/a_i2d_fp.c + $(OPENSSL_PATH)/crypto/asn1/a_int.c + $(OPENSSL_PATH)/crypto/asn1/a_mbstr.c + $(OPENSSL_PATH)/crypto/asn1/a_object.c + $(OPENSSL_PATH)/crypto/asn1/a_octet.c + $(OPENSSL_PATH)/crypto/asn1/a_print.c + $(OPENSSL_PATH)/crypto/asn1/a_sign.c + $(OPENSSL_PATH)/crypto/asn1/a_strex.c + $(OPENSSL_PATH)/crypto/asn1/a_strnid.c + $(OPENSSL_PATH)/crypto/asn1/a_time.c + $(OPENSSL_PATH)/crypto/asn1/a_type.c + $(OPENSSL_PATH)/crypto/asn1/a_utctm.c + $(OPENSSL_PATH)/crypto/asn1/a_utf8.c + $(OPENSSL_PATH)/crypto/asn1/a_verify.c + $(OPENSSL_PATH)/crypto/asn1/ameth_lib.c + $(OPENSSL_PATH)/crypto/asn1/asn1_err.c + $(OPENSSL_PATH)/crypto/asn1/asn1_gen.c + $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.c + $(OPENSSL_PATH)/crypto/asn1/asn1_lib.c + $(OPENSSL_PATH)/crypto/asn1/asn1_parse.c + $(OPENSSL_PATH)/crypto/asn1/asn_mime.c + $(OPENSSL_PATH)/crypto/asn1/asn_moid.c + $(OPENSSL_PATH)/crypto/asn1/asn_mstbl.c + $(OPENSSL_PATH)/crypto/asn1/asn_pack.c + $(OPENSSL_PATH)/crypto/asn1/bio_asn1.c + $(OPENSSL_PATH)/crypto/asn1/bio_ndef.c + $(OPENSSL_PATH)/crypto/asn1/d2i_param.c + $(OPENSSL_PATH)/crypto/asn1/d2i_pr.c + $(OPENSSL_PATH)/crypto/asn1/d2i_pu.c + $(OPENSSL_PATH)/crypto/asn1/evp_asn1.c + $(OPENSSL_PATH)/crypto/asn1/f_int.c + $(OPENSSL_PATH)/crypto/asn1/f_string.c + $(OPENSSL_PATH)/crypto/asn1/i2d_evp.c + $(OPENSSL_PATH)/crypto/asn1/nsseq.c + $(OPENSSL_PATH)/crypto/asn1/p5_pbe.c + $(OPENSSL_PATH)/crypto/asn1/p5_pbev2.c + $(OPENSSL_PATH)/crypto/asn1/p5_scrypt.c + $(OPENSSL_PATH)/crypto/asn1/p8_pkey.c + $(OPENSSL_PATH)/crypto/asn1/t_bitst.c + $(OPENSSL_PATH)/crypto/asn1/t_pkey.c + $(OPENSSL_PATH)/crypto/asn1/t_spki.c + $(OPENSSL_PATH)/crypto/asn1/tasn_dec.c + $(OPENSSL_PATH)/crypto/asn1/tasn_enc.c + $(OPENSSL_PATH)/crypto/asn1/tasn_fre.c + $(OPENSSL_PATH)/crypto/asn1/tasn_new.c + $(OPENSSL_PATH)/crypto/asn1/tasn_prn.c + $(OPENSSL_PATH)/crypto/asn1/tasn_scn.c + $(OPENSSL_PATH)/crypto/asn1/tasn_typ.c + $(OPENSSL_PATH)/crypto/asn1/tasn_utl.c + $(OPENSSL_PATH)/crypto/asn1/x_algor.c + $(OPENSSL_PATH)/crypto/asn1/x_bignum.c + $(OPENSSL_PATH)/crypto/asn1/x_info.c + $(OPENSSL_PATH)/crypto/asn1/x_int64.c + $(OPENSSL_PATH)/crypto/asn1/x_long.c + $(OPENSSL_PATH)/crypto/asn1/x_pkey.c + $(OPENSSL_PATH)/crypto/asn1/x_sig.c + $(OPENSSL_PATH)/crypto/asn1/x_spki.c + $(OPENSSL_PATH)/crypto/asn1/x_val.c + $(OPENSSL_PATH)/crypto/async/arch/async_null.c + $(OPENSSL_PATH)/crypto/async/arch/async_posix.c + $(OPENSSL_PATH)/crypto/async/arch/async_win.c + $(OPENSSL_PATH)/crypto/async/async.c + $(OPENSSL_PATH)/crypto/async/async_err.c + $(OPENSSL_PATH)/crypto/async/async_wait.c + $(OPENSSL_PATH)/crypto/bio/bf_buff.c + $(OPENSSL_PATH)/crypto/bio/bf_lbuf.c + $(OPENSSL_PATH)/crypto/bio/bf_nbio.c + $(OPENSSL_PATH)/crypto/bio/bf_null.c + $(OPENSSL_PATH)/crypto/bio/bf_prefix.c + $(OPENSSL_PATH)/crypto/bio/bf_readbuff.c + $(OPENSSL_PATH)/crypto/bio/bio_addr.c + $(OPENSSL_PATH)/crypto/bio/bio_cb.c + $(OPENSSL_PATH)/crypto/bio/bio_dump.c + $(OPENSSL_PATH)/crypto/bio/bio_err.c + $(OPENSSL_PATH)/crypto/bio/bio_lib.c + $(OPENSSL_PATH)/crypto/bio/bio_meth.c + $(OPENSSL_PATH)/crypto/bio/bio_print.c + $(OPENSSL_PATH)/crypto/bio/bio_sock.c + $(OPENSSL_PATH)/crypto/bio/bio_sock2.c + $(OPENSSL_PATH)/crypto/bio/bss_acpt.c + $(OPENSSL_PATH)/crypto/bio/bss_bio.c + $(OPENSSL_PATH)/crypto/bio/bss_conn.c + $(OPENSSL_PATH)/crypto/bio/bss_core.c + $(OPENSSL_PATH)/crypto/bio/bss_dgram.c + $(OPENSSL_PATH)/crypto/bio/bss_fd.c + $(OPENSSL_PATH)/crypto/bio/bss_file.c + $(OPENSSL_PATH)/crypto/bio/bss_log.c + $(OPENSSL_PATH)/crypto/bio/bss_mem.c + $(OPENSSL_PATH)/crypto/bio/bss_null.c + $(OPENSSL_PATH)/crypto/bio/bss_sock.c + $(OPENSSL_PATH)/crypto/bio/ossl_core_bio.c + $(OPENSSL_PATH)/crypto/bn/bn_add.c + $(OPENSSL_PATH)/crypto/bn/bn_asm.c + $(OPENSSL_PATH)/crypto/bn/bn_blind.c + $(OPENSSL_PATH)/crypto/bn/bn_const.c + $(OPENSSL_PATH)/crypto/bn/bn_conv.c + $(OPENSSL_PATH)/crypto/bn/bn_ctx.c + $(OPENSSL_PATH)/crypto/bn/bn_dh.c + $(OPENSSL_PATH)/crypto/bn/bn_div.c + $(OPENSSL_PATH)/crypto/bn/bn_err.c + $(OPENSSL_PATH)/crypto/bn/bn_exp.c + $(OPENSSL_PATH)/crypto/bn/bn_exp2.c + $(OPENSSL_PATH)/crypto/bn/bn_gcd.c + $(OPENSSL_PATH)/crypto/bn/bn_gf2m.c + $(OPENSSL_PATH)/crypto/bn/bn_intern.c + $(OPENSSL_PATH)/crypto/bn/bn_kron.c + $(OPENSSL_PATH)/crypto/bn/bn_lib.c + $(OPENSSL_PATH)/crypto/bn/bn_mod.c + $(OPENSSL_PATH)/crypto/bn/bn_mont.c + $(OPENSSL_PATH)/crypto/bn/bn_mpi.c + $(OPENSSL_PATH)/crypto/bn/bn_mul.c + $(OPENSSL_PATH)/crypto/bn/bn_nist.c + $(OPENSSL_PATH)/crypto/bn/bn_prime.c + $(OPENSSL_PATH)/crypto/bn/bn_print.c + $(OPENSSL_PATH)/crypto/bn/bn_rand.c + $(OPENSSL_PATH)/crypto/bn/bn_recp.c + $(OPENSSL_PATH)/crypto/bn/bn_rsa_fips186_4.c + $(OPENSSL_PATH)/crypto/bn/bn_shift.c + $(OPENSSL_PATH)/crypto/bn/bn_sqr.c + $(OPENSSL_PATH)/crypto/bn/bn_sqrt.c + $(OPENSSL_PATH)/crypto/bn/bn_srp.c + $(OPENSSL_PATH)/crypto/bn/bn_word.c + $(OPENSSL_PATH)/crypto/bn/bn_x931p.c + $(OPENSSL_PATH)/crypto/buffer/buf_err.c + $(OPENSSL_PATH)/crypto/buffer/buffer.c + $(OPENSSL_PATH)/crypto/comp/c_zlib.c + $(OPENSSL_PATH)/crypto/comp/comp_err.c + $(OPENSSL_PATH)/crypto/comp/comp_lib.c + $(OPENSSL_PATH)/crypto/conf/conf_api.c + $(OPENSSL_PATH)/crypto/conf/conf_def.c + $(OPENSSL_PATH)/crypto/conf/conf_err.c + $(OPENSSL_PATH)/crypto/conf/conf_lib.c + $(OPENSSL_PATH)/crypto/conf/conf_mall.c + $(OPENSSL_PATH)/crypto/conf/conf_mod.c + $(OPENSSL_PATH)/crypto/conf/conf_sap.c + $(OPENSSL_PATH)/crypto/conf/conf_ssl.c + $(OPENSSL_PATH)/crypto/dh/dh_ameth.c + $(OPENSSL_PATH)/crypto/dh/dh_asn1.c + $(OPENSSL_PATH)/crypto/dh/dh_backend.c + $(OPENSSL_PATH)/crypto/dh/dh_check.c + $(OPENSSL_PATH)/crypto/dh/dh_err.c + $(OPENSSL_PATH)/crypto/dh/dh_gen.c + $(OPENSSL_PATH)/crypto/dh/dh_group_params.c + $(OPENSSL_PATH)/crypto/dh/dh_kdf.c + $(OPENSSL_PATH)/crypto/dh/dh_key.c + $(OPENSSL_PATH)/crypto/dh/dh_lib.c + $(OPENSSL_PATH)/crypto/dh/dh_meth.c + $(OPENSSL_PATH)/crypto/dh/dh_pmeth.c + $(OPENSSL_PATH)/crypto/dh/dh_prn.c + $(OPENSSL_PATH)/crypto/dh/dh_rfc5114.c + $(OPENSSL_PATH)/crypto/dso/dso_dl.c + $(OPENSSL_PATH)/crypto/dso/dso_dlfcn.c + $(OPENSSL_PATH)/crypto/dso/dso_err.c + $(OPENSSL_PATH)/crypto/dso/dso_lib.c + $(OPENSSL_PATH)/crypto/dso/dso_openssl.c + $(OPENSSL_PATH)/crypto/dso/dso_vms.c + $(OPENSSL_PATH)/crypto/dso/dso_win32.c + $(OPENSSL_PATH)/crypto/ec/curve448/arch_32/f_impl32.c + $(OPENSSL_PATH)/crypto/ec/curve448/arch_64/f_impl64.c + $(OPENSSL_PATH)/crypto/ec/curve448/curve448.c + $(OPENSSL_PATH)/crypto/ec/curve448/curve448_tables.c + $(OPENSSL_PATH)/crypto/ec/curve448/eddsa.c + $(OPENSSL_PATH)/crypto/ec/curve448/f_generic.c + $(OPENSSL_PATH)/crypto/ec/curve448/scalar.c + $(OPENSSL_PATH)/crypto/ec/curve25519.c + $(OPENSSL_PATH)/crypto/ec/ec2_oct.c + $(OPENSSL_PATH)/crypto/ec/ec2_smpl.c + $(OPENSSL_PATH)/crypto/ec/ec_ameth.c + $(OPENSSL_PATH)/crypto/ec/ec_asn1.c + $(OPENSSL_PATH)/crypto/ec/ec_backend.c + $(OPENSSL_PATH)/crypto/ec/ec_check.c + $(OPENSSL_PATH)/crypto/ec/ec_curve.c + $(OPENSSL_PATH)/crypto/ec/ec_cvt.c + $(OPENSSL_PATH)/crypto/ec/ec_deprecated.c + $(OPENSSL_PATH)/crypto/ec/ec_err.c + $(OPENSSL_PATH)/crypto/ec/ec_key.c + $(OPENSSL_PATH)/crypto/ec/ec_kmeth.c + $(OPENSSL_PATH)/crypto/ec/ec_lib.c + $(OPENSSL_PATH)/crypto/ec/ec_mult.c + $(OPENSSL_PATH)/crypto/ec/ec_oct.c + $(OPENSSL_PATH)/crypto/ec/ec_pmeth.c + $(OPENSSL_PATH)/crypto/ec/ec_print.c + $(OPENSSL_PATH)/crypto/ec/ecdh_kdf.c + $(OPENSSL_PATH)/crypto/ec/ecdh_ossl.c + $(OPENSSL_PATH)/crypto/ec/ecdsa_ossl.c + $(OPENSSL_PATH)/crypto/ec/ecdsa_sign.c + $(OPENSSL_PATH)/crypto/ec/ecdsa_vrf.c + $(OPENSSL_PATH)/crypto/ec/eck_prn.c + $(OPENSSL_PATH)/crypto/ec/ecp_mont.c + $(OPENSSL_PATH)/crypto/ec/ecp_nist.c + $(OPENSSL_PATH)/crypto/ec/ecp_oct.c + $(OPENSSL_PATH)/crypto/ec/ecp_smpl.c + $(OPENSSL_PATH)/crypto/ec/ecx_backend.c + $(OPENSSL_PATH)/crypto/ec/ecx_key.c + $(OPENSSL_PATH)/crypto/ec/ecx_meth.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_err.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_lib.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_meth.c + $(OPENSSL_PATH)/crypto/encode_decode/decoder_pkey.c + $(OPENSSL_PATH)/crypto/err/err.c + $(OPENSSL_PATH)/crypto/err/err_all.c + $(OPENSSL_PATH)/crypto/err/err_all_legacy.c + $(OPENSSL_PATH)/crypto/err/err_blocks.c + $(OPENSSL_PATH)/crypto/err/err_prn.c + $(OPENSSL_PATH)/crypto/ess/ess_asn1.c + $(OPENSSL_PATH)/crypto/ess/ess_err.c + $(OPENSSL_PATH)/crypto/ess/ess_lib.c + $(OPENSSL_PATH)/crypto/evp/asymcipher.c + $(OPENSSL_PATH)/crypto/evp/bio_b64.c + $(OPENSSL_PATH)/crypto/evp/bio_enc.c + $(OPENSSL_PATH)/crypto/evp/bio_md.c + $(OPENSSL_PATH)/crypto/evp/bio_ok.c + $(OPENSSL_PATH)/crypto/evp/c_allc.c + $(OPENSSL_PATH)/crypto/evp/c_alld.c + $(OPENSSL_PATH)/crypto/evp/cmeth_lib.c + $(OPENSSL_PATH)/crypto/evp/ctrl_params_translate.c + $(OPENSSL_PATH)/crypto/evp/dh_ctrl.c + $(OPENSSL_PATH)/crypto/evp/dh_support.c + $(OPENSSL_PATH)/crypto/evp/digest.c + $(OPENSSL_PATH)/crypto/evp/dsa_ctrl.c + $(OPENSSL_PATH)/crypto/evp/e_aes.c + $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha1.c + $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha256.c + $(OPENSSL_PATH)/crypto/evp/e_aria.c + $(OPENSSL_PATH)/crypto/evp/e_bf.c + $(OPENSSL_PATH)/crypto/evp/e_cast.c + $(OPENSSL_PATH)/crypto/evp/e_chacha20_poly1305.c + $(OPENSSL_PATH)/crypto/evp/e_des.c + $(OPENSSL_PATH)/crypto/evp/e_des3.c + $(OPENSSL_PATH)/crypto/evp/e_idea.c + $(OPENSSL_PATH)/crypto/evp/e_null.c + $(OPENSSL_PATH)/crypto/evp/e_rc2.c + $(OPENSSL_PATH)/crypto/evp/e_rc4.c + $(OPENSSL_PATH)/crypto/evp/e_rc4_hmac_md5.c + $(OPENSSL_PATH)/crypto/evp/e_rc5.c + $(OPENSSL_PATH)/crypto/evp/e_sm4.c + $(OPENSSL_PATH)/crypto/evp/e_xcbc_d.c + $(OPENSSL_PATH)/crypto/evp/ec_ctrl.c + $(OPENSSL_PATH)/crypto/evp/ec_support.c + $(OPENSSL_PATH)/crypto/evp/encode.c + $(OPENSSL_PATH)/crypto/evp/evp_cnf.c + $(OPENSSL_PATH)/crypto/evp/evp_enc.c + $(OPENSSL_PATH)/crypto/evp/evp_err.c + $(OPENSSL_PATH)/crypto/evp/evp_fetch.c + $(OPENSSL_PATH)/crypto/evp/evp_key.c + $(OPENSSL_PATH)/crypto/evp/evp_lib.c + $(OPENSSL_PATH)/crypto/evp/evp_pbe.c + $(OPENSSL_PATH)/crypto/evp/evp_pkey.c + $(OPENSSL_PATH)/crypto/evp/evp_rand.c + $(OPENSSL_PATH)/crypto/evp/evp_utils.c + $(OPENSSL_PATH)/crypto/evp/exchange.c + $(OPENSSL_PATH)/crypto/evp/kdf_lib.c + $(OPENSSL_PATH)/crypto/evp/kdf_meth.c + $(OPENSSL_PATH)/crypto/evp/kem.c + $(OPENSSL_PATH)/crypto/evp/keymgmt_lib.c + $(OPENSSL_PATH)/crypto/evp/keymgmt_meth.c + $(OPENSSL_PATH)/crypto/evp/legacy_md5.c + $(OPENSSL_PATH)/crypto/evp/legacy_md5_sha1.c + $(OPENSSL_PATH)/crypto/evp/legacy_sha.c + $(OPENSSL_PATH)/crypto/evp/m_null.c + $(OPENSSL_PATH)/crypto/evp/m_sigver.c + $(OPENSSL_PATH)/crypto/evp/mac_lib.c + $(OPENSSL_PATH)/crypto/evp/mac_meth.c + $(OPENSSL_PATH)/crypto/evp/names.c + $(OPENSSL_PATH)/crypto/evp/p5_crpt.c + $(OPENSSL_PATH)/crypto/evp/p5_crpt2.c + $(OPENSSL_PATH)/crypto/evp/p_dec.c + $(OPENSSL_PATH)/crypto/evp/p_enc.c + $(OPENSSL_PATH)/crypto/evp/p_legacy.c + $(OPENSSL_PATH)/crypto/evp/p_lib.c + $(OPENSSL_PATH)/crypto/evp/p_open.c + $(OPENSSL_PATH)/crypto/evp/p_seal.c + $(OPENSSL_PATH)/crypto/evp/p_sign.c + $(OPENSSL_PATH)/crypto/evp/p_verify.c + $(OPENSSL_PATH)/crypto/evp/pbe_scrypt.c + $(OPENSSL_PATH)/crypto/evp/pmeth_check.c + $(OPENSSL_PATH)/crypto/evp/pmeth_gn.c + $(OPENSSL_PATH)/crypto/evp/pmeth_lib.c + $(OPENSSL_PATH)/crypto/evp/signature.c + $(OPENSSL_PATH)/crypto/ffc/ffc_backend.c + $(OPENSSL_PATH)/crypto/ffc/ffc_dh.c + $(OPENSSL_PATH)/crypto/ffc/ffc_key_generate.c + $(OPENSSL_PATH)/crypto/ffc/ffc_key_validate.c + $(OPENSSL_PATH)/crypto/ffc/ffc_params.c + $(OPENSSL_PATH)/crypto/ffc/ffc_params_generate.c + $(OPENSSL_PATH)/crypto/ffc/ffc_params_validate.c + $(OPENSSL_PATH)/crypto/hmac/hmac.c + $(OPENSSL_PATH)/crypto/http/http_client.c + $(OPENSSL_PATH)/crypto/http/http_err.c + $(OPENSSL_PATH)/crypto/http/http_lib.c + $(OPENSSL_PATH)/crypto/kdf/kdf_err.c + $(OPENSSL_PATH)/crypto/lhash/lh_stats.c + $(OPENSSL_PATH)/crypto/lhash/lhash.c + $(OPENSSL_PATH)/crypto/asn1_dsa.c + $(OPENSSL_PATH)/crypto/bsearch.c + $(OPENSSL_PATH)/crypto/context.c + $(OPENSSL_PATH)/crypto/core_algorithm.c + $(OPENSSL_PATH)/crypto/core_fetch.c + $(OPENSSL_PATH)/crypto/core_namemap.c + $(OPENSSL_PATH)/crypto/cpt_err.c + $(OPENSSL_PATH)/crypto/cpuid.c + $(OPENSSL_PATH)/crypto/cryptlib.c + $(OPENSSL_PATH)/crypto/ctype.c + $(OPENSSL_PATH)/crypto/cversion.c + $(OPENSSL_PATH)/crypto/der_writer.c + $(OPENSSL_PATH)/crypto/ebcdic.c + $(OPENSSL_PATH)/crypto/ex_data.c + $(OPENSSL_PATH)/crypto/getenv.c + $(OPENSSL_PATH)/crypto/info.c + $(OPENSSL_PATH)/crypto/init.c + $(OPENSSL_PATH)/crypto/initthread.c + $(OPENSSL_PATH)/crypto/mem.c + $(OPENSSL_PATH)/crypto/mem_sec.c + $(OPENSSL_PATH)/crypto/o_dir.c + $(OPENSSL_PATH)/crypto/o_fopen.c + $(OPENSSL_PATH)/crypto/o_init.c + $(OPENSSL_PATH)/crypto/o_str.c + $(OPENSSL_PATH)/crypto/o_time.c + $(OPENSSL_PATH)/crypto/packet.c + $(OPENSSL_PATH)/crypto/param_build.c + $(OPENSSL_PATH)/crypto/param_build_set.c + $(OPENSSL_PATH)/crypto/params.c + $(OPENSSL_PATH)/crypto/params_dup.c + $(OPENSSL_PATH)/crypto/params_from_text.c + $(OPENSSL_PATH)/crypto/passphrase.c + $(OPENSSL_PATH)/crypto/provider.c + $(OPENSSL_PATH)/crypto/provider_child.c + $(OPENSSL_PATH)/crypto/provider_conf.c + $(OPENSSL_PATH)/crypto/provider_core.c + $(OPENSSL_PATH)/crypto/punycode.c + $(OPENSSL_PATH)/crypto/self_test_core.c + $(OPENSSL_PATH)/crypto/sparse_array.c + $(OPENSSL_PATH)/crypto/threads_lib.c + $(OPENSSL_PATH)/crypto/threads_none.c + $(OPENSSL_PATH)/crypto/threads_pthread.c + $(OPENSSL_PATH)/crypto/threads_win.c + $(OPENSSL_PATH)/crypto/trace.c + $(OPENSSL_PATH)/crypto/uid.c + $(OPENSSL_PATH)/crypto/md5/md5_dgst.c + $(OPENSSL_PATH)/crypto/md5/md5_one.c + $(OPENSSL_PATH)/crypto/md5/md5_sha1.c + $(OPENSSL_PATH)/crypto/modes/cbc128.c + $(OPENSSL_PATH)/crypto/modes/ccm128.c + $(OPENSSL_PATH)/crypto/modes/cfb128.c + $(OPENSSL_PATH)/crypto/modes/ctr128.c + $(OPENSSL_PATH)/crypto/modes/cts128.c + $(OPENSSL_PATH)/crypto/modes/gcm128.c + $(OPENSSL_PATH)/crypto/modes/ocb128.c + $(OPENSSL_PATH)/crypto/modes/ofb128.c + $(OPENSSL_PATH)/crypto/modes/siv128.c + $(OPENSSL_PATH)/crypto/modes/wrap128.c + $(OPENSSL_PATH)/crypto/modes/xts128.c + $(OPENSSL_PATH)/crypto/objects/o_names.c + $(OPENSSL_PATH)/crypto/objects/obj_dat.c + $(OPENSSL_PATH)/crypto/objects/obj_err.c + $(OPENSSL_PATH)/crypto/objects/obj_lib.c + $(OPENSSL_PATH)/crypto/objects/obj_xref.c + $(OPENSSL_PATH)/crypto/pem/pem_all.c + $(OPENSSL_PATH)/crypto/pem/pem_err.c + $(OPENSSL_PATH)/crypto/pem/pem_info.c + $(OPENSSL_PATH)/crypto/pem/pem_lib.c + $(OPENSSL_PATH)/crypto/pem/pem_oth.c + $(OPENSSL_PATH)/crypto/pem/pem_pk8.c + $(OPENSSL_PATH)/crypto/pem/pem_pkey.c + $(OPENSSL_PATH)/crypto/pem/pem_sign.c + $(OPENSSL_PATH)/crypto/pem/pem_x509.c + $(OPENSSL_PATH)/crypto/pem/pem_xaux.c + $(OPENSSL_PATH)/crypto/pem/pvkfmt.c + $(OPENSSL_PATH)/crypto/pkcs7/bio_pk7.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_asn1.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_attr.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_doit.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_lib.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_mime.c + $(OPENSSL_PATH)/crypto/pkcs7/pk7_smime.c + $(OPENSSL_PATH)/crypto/pkcs7/pkcs7err.c + $(OPENSSL_PATH)/crypto/property/defn_cache.c + $(OPENSSL_PATH)/crypto/property/property.c + $(OPENSSL_PATH)/crypto/property/property_err.c + $(OPENSSL_PATH)/crypto/property/property_parse.c + $(OPENSSL_PATH)/crypto/property/property_query.c + $(OPENSSL_PATH)/crypto/property/property_string.c + $(OPENSSL_PATH)/crypto/rand/prov_seed.c + $(OPENSSL_PATH)/crypto/rand/rand_deprecated.c + $(OPENSSL_PATH)/crypto/rand/rand_err.c + $(OPENSSL_PATH)/crypto/rand/rand_lib.c + $(OPENSSL_PATH)/crypto/rand/rand_meth.c + $(OPENSSL_PATH)/crypto/rand/rand_pool.c + $(OPENSSL_PATH)/crypto/rsa/rsa_ameth.c + $(OPENSSL_PATH)/crypto/rsa/rsa_asn1.c + $(OPENSSL_PATH)/crypto/rsa/rsa_backend.c + $(OPENSSL_PATH)/crypto/rsa/rsa_chk.c + $(OPENSSL_PATH)/crypto/rsa/rsa_crpt.c + $(OPENSSL_PATH)/crypto/rsa/rsa_err.c + $(OPENSSL_PATH)/crypto/rsa/rsa_gen.c + $(OPENSSL_PATH)/crypto/rsa/rsa_lib.c + $(OPENSSL_PATH)/crypto/rsa/rsa_meth.c + $(OPENSSL_PATH)/crypto/rsa/rsa_mp.c + $(OPENSSL_PATH)/crypto/rsa/rsa_mp_names.c + $(OPENSSL_PATH)/crypto/rsa/rsa_none.c + $(OPENSSL_PATH)/crypto/rsa/rsa_oaep.c + $(OPENSSL_PATH)/crypto/rsa/rsa_ossl.c + $(OPENSSL_PATH)/crypto/rsa/rsa_pk1.c + $(OPENSSL_PATH)/crypto/rsa/rsa_pmeth.c + $(OPENSSL_PATH)/crypto/rsa/rsa_prn.c + $(OPENSSL_PATH)/crypto/rsa/rsa_pss.c + $(OPENSSL_PATH)/crypto/rsa/rsa_saos.c + $(OPENSSL_PATH)/crypto/rsa/rsa_schemes.c + $(OPENSSL_PATH)/crypto/rsa/rsa_sign.c + $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_check.c + $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_gen.c + $(OPENSSL_PATH)/crypto/rsa/rsa_x931.c + $(OPENSSL_PATH)/crypto/rsa/rsa_x931g.c + $(OPENSSL_PATH)/crypto/sha/sha1_one.c + $(OPENSSL_PATH)/crypto/sha/sha1dgst.c + $(OPENSSL_PATH)/crypto/sha/sha256.c + $(OPENSSL_PATH)/crypto/sha/sha3.c + $(OPENSSL_PATH)/crypto/sha/sha512.c + $(OPENSSL_PATH)/crypto/sm3/legacy_sm3.c + $(OPENSSL_PATH)/crypto/sm3/sm3.c + $(OPENSSL_PATH)/crypto/stack/stack.c + $(OPENSSL_PATH)/crypto/txt_db/txt_db.c + $(OPENSSL_PATH)/crypto/ui/ui_err.c + $(OPENSSL_PATH)/crypto/ui/ui_lib.c + $(OPENSSL_PATH)/crypto/ui/ui_null.c + $(OPENSSL_PATH)/crypto/ui/ui_openssl.c + $(OPENSSL_PATH)/crypto/ui/ui_util.c + $(OPENSSL_PATH)/crypto/x509/by_dir.c + $(OPENSSL_PATH)/crypto/x509/by_file.c + $(OPENSSL_PATH)/crypto/x509/by_store.c + $(OPENSSL_PATH)/crypto/x509/pcy_cache.c + $(OPENSSL_PATH)/crypto/x509/pcy_data.c + $(OPENSSL_PATH)/crypto/x509/pcy_lib.c + $(OPENSSL_PATH)/crypto/x509/pcy_map.c + $(OPENSSL_PATH)/crypto/x509/pcy_node.c + $(OPENSSL_PATH)/crypto/x509/pcy_tree.c + $(OPENSSL_PATH)/crypto/x509/t_crl.c + $(OPENSSL_PATH)/crypto/x509/t_req.c + $(OPENSSL_PATH)/crypto/x509/t_x509.c + $(OPENSSL_PATH)/crypto/x509/v3_addr.c + $(OPENSSL_PATH)/crypto/x509/v3_admis.c + $(OPENSSL_PATH)/crypto/x509/v3_akeya.c + $(OPENSSL_PATH)/crypto/x509/v3_akid.c + $(OPENSSL_PATH)/crypto/x509/v3_asid.c + $(OPENSSL_PATH)/crypto/x509/v3_bcons.c + $(OPENSSL_PATH)/crypto/x509/v3_bitst.c + $(OPENSSL_PATH)/crypto/x509/v3_conf.c + $(OPENSSL_PATH)/crypto/x509/v3_cpols.c + $(OPENSSL_PATH)/crypto/x509/v3_crld.c + $(OPENSSL_PATH)/crypto/x509/v3_enum.c + $(OPENSSL_PATH)/crypto/x509/v3_extku.c + $(OPENSSL_PATH)/crypto/x509/v3_genn.c + $(OPENSSL_PATH)/crypto/x509/v3_ia5.c + $(OPENSSL_PATH)/crypto/x509/v3_info.c + $(OPENSSL_PATH)/crypto/x509/v3_int.c + $(OPENSSL_PATH)/crypto/x509/v3_ist.c + $(OPENSSL_PATH)/crypto/x509/v3_lib.c + $(OPENSSL_PATH)/crypto/x509/v3_ncons.c + $(OPENSSL_PATH)/crypto/x509/v3_pci.c + $(OPENSSL_PATH)/crypto/x509/v3_pcia.c + $(OPENSSL_PATH)/crypto/x509/v3_pcons.c + $(OPENSSL_PATH)/crypto/x509/v3_pku.c + $(OPENSSL_PATH)/crypto/x509/v3_pmaps.c + $(OPENSSL_PATH)/crypto/x509/v3_prn.c + $(OPENSSL_PATH)/crypto/x509/v3_purp.c + $(OPENSSL_PATH)/crypto/x509/v3_san.c + $(OPENSSL_PATH)/crypto/x509/v3_skid.c + $(OPENSSL_PATH)/crypto/x509/v3_sxnet.c + $(OPENSSL_PATH)/crypto/x509/v3_tlsf.c + $(OPENSSL_PATH)/crypto/x509/v3_utf8.c + $(OPENSSL_PATH)/crypto/x509/v3_utl.c + $(OPENSSL_PATH)/crypto/x509/v3err.c + $(OPENSSL_PATH)/crypto/x509/x509_att.c + $(OPENSSL_PATH)/crypto/x509/x509_cmp.c + $(OPENSSL_PATH)/crypto/x509/x509_d2.c + $(OPENSSL_PATH)/crypto/x509/x509_def.c + $(OPENSSL_PATH)/crypto/x509/x509_err.c + $(OPENSSL_PATH)/crypto/x509/x509_ext.c + $(OPENSSL_PATH)/crypto/x509/x509_lu.c + $(OPENSSL_PATH)/crypto/x509/x509_meth.c + $(OPENSSL_PATH)/crypto/x509/x509_obj.c + $(OPENSSL_PATH)/crypto/x509/x509_r2x.c + $(OPENSSL_PATH)/crypto/x509/x509_req.c + $(OPENSSL_PATH)/crypto/x509/x509_set.c + $(OPENSSL_PATH)/crypto/x509/x509_trust.c + $(OPENSSL_PATH)/crypto/x509/x509_txt.c + $(OPENSSL_PATH)/crypto/x509/x509_v3.c + $(OPENSSL_PATH)/crypto/x509/x509_vfy.c + $(OPENSSL_PATH)/crypto/x509/x509_vpm.c + $(OPENSSL_PATH)/crypto/x509/x509cset.c + $(OPENSSL_PATH)/crypto/x509/x509name.c + $(OPENSSL_PATH)/crypto/x509/x509rset.c + $(OPENSSL_PATH)/crypto/x509/x509spki.c + $(OPENSSL_PATH)/crypto/x509/x509type.c + $(OPENSSL_PATH)/crypto/x509/x_all.c + $(OPENSSL_PATH)/crypto/x509/x_attrib.c + $(OPENSSL_PATH)/crypto/x509/x_crl.c + $(OPENSSL_PATH)/crypto/x509/x_exten.c + $(OPENSSL_PATH)/crypto/x509/x_name.c + $(OPENSSL_PATH)/crypto/x509/x_pubkey.c + $(OPENSSL_PATH)/crypto/x509/x_req.c + $(OPENSSL_PATH)/crypto/x509/x_x509.c + $(OPENSSL_PATH)/crypto/x509/x_x509a.c + $(OPENSSL_PATH)/providers/nullprov.c + $(OPENSSL_PATH)/providers/prov_running.c + $(OPENSSL_PATH)/providers/common/der/der_rsa_sig.c + $(OPENSSL_PATH)/providers/common/bio_prov.c + $(OPENSSL_PATH)/providers/common/capabilities.c + $(OPENSSL_PATH)/providers/common/digest_to_nid.c + $(OPENSSL_PATH)/providers/common/provider_seeding.c + $(OPENSSL_PATH)/providers/common/provider_util.c + $(OPENSSL_PATH)/providers/common/securitycheck.c + $(OPENSSL_PATH)/providers/common/securitycheck_default.c + $(OPENSSL_PATH)/providers/implementations/asymciphers/rsa_enc.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_wrp.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_fips.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_cts.c + $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_null.c + $(OPENSSL_PATH)/providers/implementations/digests/md5_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/md5_sha1_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/null_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/sha2_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/sha3_prov.c + $(OPENSSL_PATH)/providers/implementations/digests/sm3_prov.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_der2key.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_epki2pki.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_msblob2key.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pem2der.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pvk2key.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_spki2typespki.c + $(OPENSSL_PATH)/providers/implementations/encode_decode/endecoder_common.c + $(OPENSSL_PATH)/providers/implementations/exchange/dh_exch.c + $(OPENSSL_PATH)/providers/implementations/exchange/ecdh_exch.c + $(OPENSSL_PATH)/providers/implementations/exchange/ecx_exch.c + $(OPENSSL_PATH)/providers/implementations/exchange/kdf_exch.c + $(OPENSSL_PATH)/providers/implementations/kdfs/hkdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/kbkdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/krb5kdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2.c + $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2_fips.c + $(OPENSSL_PATH)/providers/implementations/kdfs/pkcs12kdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/scrypt.c + $(OPENSSL_PATH)/providers/implementations/kdfs/sshkdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/sskdf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/tls1_prf.c + $(OPENSSL_PATH)/providers/implementations/kdfs/x942kdf.c + $(OPENSSL_PATH)/providers/implementations/kem/rsa_kem.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/dh_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/ec_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/ecx_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/kdf_legacy_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/mac_legacy_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/keymgmt/rsa_kmgmt.c + $(OPENSSL_PATH)/providers/implementations/macs/gmac_prov.c + $(OPENSSL_PATH)/providers/implementations/macs/hmac_prov.c + $(OPENSSL_PATH)/providers/implementations/macs/kmac_prov.c + $(OPENSSL_PATH)/providers/implementations/rands/crngt.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg_ctr.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg_hash.c + $(OPENSSL_PATH)/providers/implementations/rands/drbg_hmac.c + $(OPENSSL_PATH)/providers/implementations/rands/seed_src.c + $(OPENSSL_PATH)/providers/implementations/rands/test_rng.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_cpu_x86.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_tsc.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_unix.c + $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_win.c + $(OPENSSL_PATH)/providers/implementations/signature/ecdsa_sig.c + $(OPENSSL_PATH)/providers/implementations/signature/eddsa_sig.c + $(OPENSSL_PATH)/providers/implementations/signature/mac_legacy_sig.c + $(OPENSSL_PATH)/providers/implementations/signature/rsa_sig.c + $(OPENSSL_PATH)/ssl/s3_cbc.c + $(OPENSSL_PATH)/providers/common/der/der_ec_key.c + $(OPENSSL_PATH)/providers/common/der/der_ec_sig.c + $(OPENSSL_PATH)/providers/common/der/der_ecx_key.c + $(OPENSSL_PATH)/providers/common/der/der_rsa_key.c + $(OPENSSL_PATH)/providers/common/provider_ctx.c + $(OPENSSL_PATH)/providers/common/provider_err.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_block.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm_hw.c + $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_hw.c + $(OPENSSL_PATH)/providers/implementations/digests/digestcommon.c + $(OPENSSL_PATH)/ssl/record/tls_pad.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_digests_gen.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_ec_gen.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_ecx_gen.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_rsa_gen.c + $(OPENSSL_GEN_PATH)/providers/common/der/der_wrap_gen.c + $(OPENSSL_PATH)/ssl/bio_ssl.c + $(OPENSSL_PATH)/ssl/d1_lib.c + $(OPENSSL_PATH)/ssl/d1_msg.c + $(OPENSSL_PATH)/ssl/d1_srtp.c + $(OPENSSL_PATH)/ssl/methods.c + $(OPENSSL_PATH)/ssl/pqueue.c + $(OPENSSL_PATH)/ssl/s3_enc.c + $(OPENSSL_PATH)/ssl/s3_lib.c + $(OPENSSL_PATH)/ssl/s3_msg.c + $(OPENSSL_PATH)/ssl/ssl_asn1.c + $(OPENSSL_PATH)/ssl/ssl_cert.c + $(OPENSSL_PATH)/ssl/ssl_ciph.c + $(OPENSSL_PATH)/ssl/ssl_conf.c + $(OPENSSL_PATH)/ssl/ssl_err.c + $(OPENSSL_PATH)/ssl/ssl_err_legacy.c + $(OPENSSL_PATH)/ssl/ssl_init.c + $(OPENSSL_PATH)/ssl/ssl_lib.c + $(OPENSSL_PATH)/ssl/ssl_mcnf.c + $(OPENSSL_PATH)/ssl/ssl_rsa.c + $(OPENSSL_PATH)/ssl/ssl_rsa_legacy.c + $(OPENSSL_PATH)/ssl/ssl_sess.c + $(OPENSSL_PATH)/ssl/ssl_stat.c + $(OPENSSL_PATH)/ssl/ssl_txt.c + $(OPENSSL_PATH)/ssl/ssl_utst.c + $(OPENSSL_PATH)/ssl/t1_enc.c + $(OPENSSL_PATH)/ssl/t1_lib.c + $(OPENSSL_PATH)/ssl/t1_trce.c + $(OPENSSL_PATH)/ssl/tls13_enc.c + $(OPENSSL_PATH)/ssl/tls_depr.c + $(OPENSSL_PATH)/ssl/tls_srp.c + $(OPENSSL_PATH)/ssl/record/dtls1_bitmap.c + $(OPENSSL_PATH)/ssl/record/rec_layer_d1.c + $(OPENSSL_PATH)/ssl/record/rec_layer_s3.c + $(OPENSSL_PATH)/ssl/record/ssl3_buffer.c + $(OPENSSL_PATH)/ssl/record/ssl3_record.c + $(OPENSSL_PATH)/ssl/record/ssl3_record_tls13.c + $(OPENSSL_PATH)/ssl/statem/extensions.c + $(OPENSSL_PATH)/ssl/statem/extensions_clnt.c + $(OPENSSL_PATH)/ssl/statem/extensions_cust.c + $(OPENSSL_PATH)/ssl/statem/statem.c + $(OPENSSL_PATH)/ssl/statem/statem_clnt.c + $(OPENSSL_PATH)/ssl/statem/statem_dtls.c + $(OPENSSL_PATH)/ssl/statem/statem_lib.c + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/aesv8-armx.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/vpaes-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/arm64cpuid.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/ghashv8-armx.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/keccak1600-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha1-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha256-armv8.S | GCC + $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha512-armv8.S | GCC # Autogenerated files list ends here [Packages] -- cgit From 368f9b62a2f284b95b90e5083fcc3f434c3a35c2 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 4 Oct 2023 15:53:55 +0200 Subject: CryptoPkg/OpensslLib: Add AArch64Cap for arch specific hooks Add AARCH64 specific implementations of: - OPENSSL_cpuid_setup(), probing hardware capabilitie (presence of FEAT_AES, etc.) - OPENSSL_rdtsc(), returning non-trusted entropy by accessing system counter. Signed-off-by: Pierre Gondois --- CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf | 1 + .../Library/OpensslLib/OpensslLibFullAccel.inf | 1 + .../Library/OpensslLib/OpensslStub/AArch64Cap.c | 107 +++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf index 3d4917b29f..912fd07f09 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf @@ -1329,6 +1329,7 @@ # Autogenerated files list ends here [Sources.AARCH64] + OpensslStub/AArch64Cap.c # Autogenerated files list starts here $(OPENSSL_PATH)/crypto/aes/aes_cbc.c $(OPENSSL_PATH)/crypto/aes/aes_cfb.c diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf index 715c483536..8f8b94c3ac 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf @@ -1432,6 +1432,7 @@ # Autogenerated files list ends here [Sources.AARCH64] + OpensslStub/AArch64Cap.c # Autogenerated files list starts here $(OPENSSL_PATH)/crypto/aes/aes_cbc.c $(OPENSSL_PATH)/crypto/aes/aes_cfb.c diff --git a/CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c b/CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c new file mode 100644 index 0000000000..e45961a87b --- /dev/null +++ b/CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c @@ -0,0 +1,107 @@ +/** @file + Arm capabilities probing. + + Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include "crypto/arm_arch.h" + +#include + +/** Get bits from a value. + + Shift the input value from 'shift' bits and apply 'mask'. + + @param value The value to get the bits from. + @param shift Index of the bits to read. + @param mask Mask to apply to the value once shifted. + + @return The desired bitfield from the value. +**/ +#define GET_BITFIELD(value, shift, mask) \ + ((value >> shift) & mask) + +UINT32 OPENSSL_armcap_P = 0; + +void +OPENSSL_cpuid_setup ( + void + ) +{ + UINT64 Isar0; + + OPENSSL_armcap_P = 0; + Isar0 = ArmReadIdAA64Isar0Reg (); + + /* Access to EL0 registers is possible from higher ELx. */ + OPENSSL_armcap_P |= ARMV8_CPUID; + /* Access to Physical timer is possible. */ + OPENSSL_armcap_P |= ARMV7_TICK; + + /* Neon support is not guaranteed, but it is assumed to be present. + Arm ARM for Armv8, sA1.5 Advanced SIMD and floating-point support + */ + OPENSSL_armcap_P |= ARMV7_NEON; + + if (GET_BITFIELD ( + Isar0, + ARM_ID_AA64ISAR0_EL1_AES_SHIFT, + ARM_ID_AA64ISAR0_EL1_AES_MASK + ) != 0) + { + OPENSSL_armcap_P |= ARMV8_AES; + } + + if (GET_BITFIELD ( + Isar0, + ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA1_MASK + ) != 0) + { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + + if (GET_BITFIELD ( + Isar0, + ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA2_MASK + ) != 0) + { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + + if (GET_BITFIELD ( + Isar0, + ARM_ID_AA64ISAR0_EL1_AES_SHIFT, + ARM_ID_AA64ISAR0_EL1_AES_MASK + ) >= ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK) + { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + + if (GET_BITFIELD ( + Isar0, + ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA2_MASK + ) >= ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK) + { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +/** Read system counter value. + + Used to get some non-trusted entropy. + + @return Lower bits of the physical counter. +**/ +uint32_t +OPENSSL_rdtsc ( + void + ) +{ + return (UINT32)ArmReadCntPctReg (); +} -- cgit From a679ceca974e94a659f9b6b9e7a7900644220ef9 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 4 Oct 2023 15:16:58 +0200 Subject: CryptoPkg: Enable Openssl Accel builds for AARCH64 Enable the following modules builds for AARCH64: - OpensslLibAccel.inf - OpensslLibFullAccel.inf Signed-off-by: Pierre Gondois --- CryptoPkg/CryptoPkg.dsc | 23 ++++++++++++----------- CryptoPkg/Readme.md | 14 +++++++------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 6a0104a3bb..f08808d5d1 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -5,6 +5,7 @@ # Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
+# Copyright (c) 2023, Arm Limited. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -327,7 +328,7 @@ MSFT:NOOPT_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000 } -[Components.IA32, Components.X64] +[Components.IA32, Components.X64, Components.AARCH64] CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf { FILE_GUID = B91B9A95-4D52-4501-A98F-A1711C14ED93 @@ -396,9 +397,9 @@ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf } -[Components.IA32, Components.X64] +[Components.IA32, Components.X64, Components.AARCH64] # - # Build verification of IA32/X64 specific libraries + # Build verification of IA32/X64/AARCH64 specific libraries # CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf @@ -439,9 +440,9 @@ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf } -[Components.IA32, Components.X64] +[Components.IA32, Components.X64, Components.AARCH64] # - # CryptoPei with IA32/X64 performance optimized OpensslLib instance without EC services + # CryptoPei with IA32/X64/AARCH64 performance optimized OpensslLib instance without EC services # IA32/X64 assembly optimizations required larger alignments # CryptoPkg/Driver/CryptoPei.inf { @@ -455,7 +456,7 @@ } # - # CryptoPei with IA32/X64 performance optimized OpensslLib instance all services + # CryptoPei with IA32/X64/AARCH64 performance optimized OpensslLib instance all services # IA32/X64 assembly optimizations required larger alignments # CryptoPkg/Driver/CryptoPei.inf { @@ -505,9 +506,9 @@ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf } -[Components.IA32, Components.X64] +[Components.IA32, Components.X64, Components.AARCH64] # - # CryptoDxe with IA32/X64 performance optimized OpensslLib instance with no EC services + # CryptoDxe with IA32/X64/AARCH64 performance optimized OpensslLib instance with no EC services # with TLS feature enabled. # IA32/X64 assembly optimizations required larger alignments # @@ -521,7 +522,7 @@ MSFT:*_*_X64_DLINK_FLAGS = /ALIGN:256 } # - # CryptoDxe with IA32/X64 performance optimized OpensslLib instance with all services. + # CryptoDxe with IA32/X64/AARCH64 performance optimized OpensslLib instance with all services. # IA32/X64 assembly optimizations required larger alignments # CryptoPkg/Driver/CryptoDxe.inf { @@ -561,7 +562,7 @@ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf } # - # CryptoSmm with IA32/X64 performance optimized OpensslLib instance with no EC services + # CryptoSmm with IA32/X64/AARCH64 performance optimized OpensslLib instance with no EC services # IA32/X64 assembly optimizations required larger alignments # CryptoPkg/Driver/CryptoSmm.inf { @@ -574,7 +575,7 @@ MSFT:*_*_X64_DLINK_FLAGS = /ALIGN:256 } # - # CryptoSmm with IA32/X64 performance optimized OpensslLib instance with all services + # CryptoSmm with IA32/X64/AARCH64 performance optimized OpensslLib instance with all services # IA32/X64 assembly optimizations required larger alignments # CryptoPkg/Driver/CryptoSmm.inf { diff --git a/CryptoPkg/Readme.md b/CryptoPkg/Readme.md index 5a68dfb6ab..cb2228b6b8 100644 --- a/CryptoPkg/Readme.md +++ b/CryptoPkg/Readme.md @@ -246,13 +246,13 @@ specific set of enabled cryptographic services. If ECC services are not required, then the size can be reduced by using OpensslLib.inf instead of `OpensslLibFull.inf`. Performance optimization requires a size increase. -| OpensslLib Instance | SSL | ECC | Perf Opt | CPU Arch | Size | -|:------------------------|:---:|:---:|:--------:|:--------:|:-----:| -| OpensslLibCrypto.inf | N | N | N | All | +0K | -| OpensslLib.inf | Y | N | N | All | +0K | -| OpensslLibAccel.inf | Y | N | Y | IA32/X64 | +20K | -| OpensslLibFull.inf | Y | Y | N | All | +115K | -| OpensslLibFullAccel.inf | Y | Y | Y | IA32/X64 | +135K | +| OpensslLib Instance | SSL | ECC | Perf Opt | CPU Arch | Size | +|:------------------------|:---:|:---:|:--------:|:----------------:|:-----:| +| OpensslLibCrypto.inf | N | N | N | All | +0K | +| OpensslLib.inf | Y | N | N | All | +0K | +| OpensslLibAccel.inf | Y | N | Y | IA32/X64/AARCH64 | +20K | +| OpensslLibFull.inf | Y | Y | N | All | +115K | +| OpensslLibFullAccel.inf | Y | Y | Y | IA32/X64/AARCH64 | +135K | ### SEC Phase Library Mappings -- cgit From caac25e22e608736ee02c2f943f6698e02585092 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 29 Jul 2024 14:40:01 +0200 Subject: ArmVirtPkg: Drop bogus reference to MPCore related PCD Bringing up secondaries is out of scope for ArmVirtPkg, and the declared PCD reference is never actually made from the code. So drop it. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf index 578ee37e74..6ac210760f 100755 --- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf +++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf @@ -56,15 +56,11 @@ MemoryInitPeiLib CacheMaintenanceLib -[Ppis] - gArmMpCoreInfoPpiGuid - [Guids] gArmMpCoreInfoGuid [FeaturePcd] gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob - gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores [FixedPcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString @@ -75,7 +71,6 @@ gArmTokenSpaceGuid.PcdFvSize gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize -- cgit From 4fc1c513f8b4368f6fab3e5787e9ceb640028f6b Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 29 Jul 2024 14:40:58 +0200 Subject: ArmPlatformPkg: Drop bogus reference to MPCore related PCD The UniCore SEC implementations never bring up secondaries, so the PCD reference is bogus. Drop it. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf | 3 --- ArmPlatformPkg/PrePi/PeiUniCore.inf | 1 - 2 files changed, 4 deletions(-) diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf index 1d50b4d0b5..7bcc5a383a 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf @@ -55,9 +55,6 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString -[FeaturePcd] - gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores - [FixedPcd] gArmTokenSpaceGuid.PcdFvBaseAddress gArmTokenSpaceGuid.PcdFvSize diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf index 2e237172d5..e0eef40ba7 100644 --- a/ArmPlatformPkg/PrePi/PeiUniCore.inf +++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf @@ -65,7 +65,6 @@ [FeaturePcd] gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob - gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString -- cgit From cee49c82d5e2775bd6cf3554621b7a85bf4532c0 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 29 Jul 2024 14:55:28 +0200 Subject: ArmPlatformPkg/PrePi: Drop MPCore variant The PrePi SEC driver can be built in unicore and MPcore versions from [mostly] the same source. The latter is obsolete, so remove it and simplyify the remaining code accordingly. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 - ArmPlatformPkg/PrePi/MainMPCore.c | 104 ----------------------------------- ArmPlatformPkg/PrePi/MainUniCore.c | 31 ----------- ArmPlatformPkg/PrePi/PeiMPCore.inf | 106 ------------------------------------ ArmPlatformPkg/PrePi/PeiUniCore.inf | 1 - ArmPlatformPkg/PrePi/PrePi.c | 41 +++----------- ArmPlatformPkg/PrePi/PrePi.h | 19 ------- 7 files changed, 8 insertions(+), 295 deletions(-) delete mode 100644 ArmPlatformPkg/PrePi/MainMPCore.c delete mode 100644 ArmPlatformPkg/PrePi/MainUniCore.c delete mode 100644 ArmPlatformPkg/PrePi/PeiMPCore.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index ddd128f9e6..72d4eb4b2c 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -123,7 +123,6 @@ ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf - ArmPlatformPkg/PrePi/PeiMPCore.inf ArmPlatformPkg/PrePi/PeiUniCore.inf ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.inf diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c deleted file mode 100644 index 68a7c13298..0000000000 --- a/ArmPlatformPkg/PrePi/MainMPCore.c +++ /dev/null @@ -1,104 +0,0 @@ -/** @file - - Copyright (c) 2011-2014, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "PrePi.h" - -#include - -#include - -VOID -PrimaryMain ( - IN UINTN UefiMemoryBase, - IN UINTN StacksBase, - IN UINT64 StartTimeStamp - ) -{ - // Enable the GIC Distributor - ArmGicEnableDistributor (PcdGet64 (PcdGicDistributorBase)); - - // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader to resume their initialization - if (!FixedPcdGet32 (PcdSendSgiToBringUpSecondaryCores)) { - // Sending SGI to all the Secondary CPU interfaces - ArmGicSendSgiTo (PcdGet64 (PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId)); - } - - PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp); - - // We must never return - ASSERT (FALSE); -} - -VOID -SecondaryMain ( - IN UINTN MpId - ) -{ - EFI_STATUS Status; - ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; - UINTN Index; - UINTN ArmCoreCount; - ARM_CORE_INFO *ArmCoreInfoTable; - UINT32 ClusterId; - UINT32 CoreId; - - VOID (*SecondaryStart)( - VOID - ); - UINTN SecondaryEntryAddr; - UINTN AcknowledgeInterrupt; - UINTN InterruptId; - - ClusterId = GET_CLUSTER_ID (MpId); - CoreId = GET_CORE_ID (MpId); - - // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid) - Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi); - ASSERT_EFI_ERROR (Status); - - ArmCoreCount = 0; - Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); - ASSERT_EFI_ERROR (Status); - - // Find the core in the ArmCoreTable - for (Index = 0; Index < ArmCoreCount; Index++) { - if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) && - (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId)) - { - break; - } - } - - // The ARM Core Info Table must define every core - ASSERT (Index != ArmCoreCount); - - // Clear Secondary cores MailBox - MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue); - - do { - ArmCallWFI (); - - // Read the Mailbox - SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress); - - // Acknowledge the interrupt and send End of Interrupt signal. - AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId); - // Check if it is a valid interrupt ID - if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) { - // Got a valid SGI number hence signal End of Interrupt - ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt); - } - } while (SecondaryEntryAddr == 0); - - // Jump to secondary core entry point. - SecondaryStart = (VOID (*)()) SecondaryEntryAddr; - SecondaryStart (); - - // The secondaries shouldn't reach here - ASSERT (FALSE); -} diff --git a/ArmPlatformPkg/PrePi/MainUniCore.c b/ArmPlatformPkg/PrePi/MainUniCore.c deleted file mode 100644 index 6162d1241f..0000000000 --- a/ArmPlatformPkg/PrePi/MainUniCore.c +++ /dev/null @@ -1,31 +0,0 @@ -/** @file - - Copyright (c) 2011, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "PrePi.h" - -VOID -PrimaryMain ( - IN UINTN UefiMemoryBase, - IN UINTN StacksBase, - IN UINT64 StartTimeStamp - ) -{ - PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp); - - // We must never return - ASSERT (FALSE); -} - -VOID -SecondaryMain ( - IN UINTN MpId - ) -{ - // We must never get into this function on UniCore system - ASSERT (FALSE); -} diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf deleted file mode 100644 index 0b13b72353..0000000000 --- a/ArmPlatformPkg/PrePi/PeiMPCore.inf +++ /dev/null @@ -1,106 +0,0 @@ -#/** @file -# -# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
-# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 1.30 - BASE_NAME = ArmPlatformPrePiMPCore - FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8 - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - -[Sources] - PrePi.h - PrePi.c - MainMPCore.c - -[Sources.ARM] - Arm/ArchPrePi.c - Arm/ModuleEntryPoint.S | GCC - -[Sources.AArch64] - AArch64/ArchPrePi.c - AArch64/ModuleEntryPoint.S - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - ArmPkg/ArmPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - -[LibraryClasses] - BaseLib - CacheMaintenanceLib - DebugLib - DebugAgentLib - ArmLib - ArmGicLib - IoLib - TimerLib - SerialPortLib - ExtractGuidedSectionLib - LzmaDecompressLib - DebugAgentLib - PrePiLib - ArmPlatformLib - ArmPlatformStackLib - MemoryAllocationLib - HobLib - PrePiHobListPointerLib - PlatformPeiLib - MemoryInitPeiLib - -[Ppis] - gArmMpCoreInfoPpiGuid - -[Guids] - gArmMpCoreInfoGuid - gEfiFirmwarePerformanceGuid - -[FeaturePcd] - gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob - gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString - -[FixedPcd] - gArmTokenSpaceGuid.PcdVFPEnabled - - gArmTokenSpaceGuid.PcdFdBaseAddress - gArmTokenSpaceGuid.PcdFdSize - - gArmTokenSpaceGuid.PcdFvBaseAddress - gArmTokenSpaceGuid.PcdFvSize - - gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize - - gArmTokenSpaceGuid.PcdGicDistributorBase - gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase - gArmTokenSpaceGuid.PcdGicSgiIntId - - gArmTokenSpaceGuid.PcdSystemMemoryBase - gArmTokenSpaceGuid.PcdSystemMemorySize - gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize - - gArmPlatformTokenSpaceGuid.PcdCoreCount - - gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize - - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData - diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf index e0eef40ba7..5c32fcbee4 100644 --- a/ArmPlatformPkg/PrePi/PeiUniCore.inf +++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf @@ -18,7 +18,6 @@ [Sources] PrePi.h PrePi.c - MainUniCore.c [Sources.ARM] Arm/ArchPrePi.c diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c index 9b127b94a6..8cc43093b9 100644 --- a/ArmPlatformPkg/PrePi/PrePi.c +++ b/ArmPlatformPkg/PrePi/PrePi.c @@ -108,14 +108,8 @@ PrePiMain ( Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); ASSERT_EFI_ERROR (Status); - // Create the Stacks HOB (reserve the memory for all stacks) - if (ArmIsMpCore ()) { - StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) + - ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize)); - } else { - StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); - } - + // Create the Stacks HOB + StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); BuildStackHob (StacksBase, StacksSize); // TODO: Call CpuPei as a library @@ -177,7 +171,7 @@ CEntryPoint ( // Initialize the platform specific controllers ArmPlatformInitialize (MpId); - if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) { + if (PerformanceMeasurementEnabled ()) { // Initialize the Timer Library to setup the Timer HW controller TimerConstructor (); // We cannot call yet the PerformanceLib because the HOB List has not been initialized @@ -193,31 +187,12 @@ CEntryPoint ( // Enable Instruction Caches on all cores. ArmEnableInstructionCache (); - // Define the Global Variable region when we are not running in XIP - if (!IS_XIP ()) { - if (ArmPlatformIsPrimaryCore (MpId)) { - if (ArmIsMpCore ()) { - // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT) - ArmCallSEV (); - } - } else { - // Wait the Primary core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT) - ArmCallWFE (); - } - } - - // If not primary Jump to Secondary Main - if (ArmPlatformIsPrimaryCore (MpId)) { - InvalidateDataCacheRange ( - (VOID *)UefiMemoryBase, - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) - ); + InvalidateDataCacheRange ( + (VOID *)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) + ); - // Goto primary Main. - PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp); - } else { - SecondaryMain (MpId); - } + PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp); // DXE Core should always load and never return ASSERT (FALSE); diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h index 1d47ba26be..b4ba292c32 100644 --- a/ArmPlatformPkg/PrePi/PrePi.h +++ b/ArmPlatformPkg/PrePi/PrePi.h @@ -29,13 +29,6 @@ TimerConstructor ( VOID ); -VOID -PrePiMain ( - IN UINTN UefiMemoryBase, - IN UINTN StacksBase, - IN UINT64 StartTimeStamp - ); - EFI_STATUS EFIAPI MemoryPeim ( @@ -49,18 +42,6 @@ PlatformPeim ( VOID ); -VOID -PrimaryMain ( - IN UINTN UefiMemoryBase, - IN UINTN StacksBase, - IN UINT64 StartTimeStamp - ); - -VOID -SecondaryMain ( - IN UINTN MpId - ); - // Either implemented by PrePiLib or by MemoryInitPei VOID BuildMemoryTypeInformationHob ( -- cgit From 96c8e756819de09d14770aedbd63916c3004e657 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 29 Jul 2024 15:22:02 +0200 Subject: ArmPlatformPkg/PrePeiCore: Drop MPCore variant The PrePeiCore SEC driver can be built in unicore and MPcore versions from [mostly] the same source. The latter is obsolete, so remove it and simplify the remaining code accordingly. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dec | 2 - ArmPlatformPkg/ArmPlatformPkg.dsc | 1 - ArmPlatformPkg/PrePeiCore/MainMPCore.c | 153 ------------------------- ArmPlatformPkg/PrePeiCore/MainUniCore.c | 9 -- ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 27 ++--- ArmPlatformPkg/PrePeiCore/PrePeiCore.h | 15 --- ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf | 76 ------------ 7 files changed, 11 insertions(+), 272 deletions(-) delete mode 100644 ArmPlatformPkg/PrePeiCore/MainMPCore.c delete mode 100644 ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec index 7b5d7e6cb5..be384524bd 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dec +++ b/ArmPlatformPkg/ArmPlatformPkg.dec @@ -50,8 +50,6 @@ gArmPlatformTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } } [PcdsFeatureFlag.common] - gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|FALSE|BOOLEAN|0x00000004 - # Disable the GOP controller on ExitBootServices(). By default the value is FALSE, # we assume the OS will handle the FrameBuffer from the UEFI GOP information. gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices|FALSE|BOOLEAN|0x0000003D diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index 72d4eb4b2c..bc4160d931 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -120,7 +120,6 @@ ArmPlatformPkg/PlatformPei/PlatformPeim.inf ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf - ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf ArmPlatformPkg/PrePi/PeiUniCore.inf diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c deleted file mode 100644 index b5d0d3a644..0000000000 --- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c +++ /dev/null @@ -1,153 +0,0 @@ -/** @file - - Copyright (c) 2011-2014, ARM Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include - -#include "PrePeiCore.h" - -/* - * This is the main function for secondary cores. They loop around until a non Null value is written to - * SYS_FLAGS register.The SYS_FLAGS register is platform specific. - * Note:The secondary cores, while executing secondary_main, assumes that: - * : SGI 0 is configured as Non-secure interrupt - * : Priority Mask is configured to allow SGI 0 - * : Interrupt Distributor and CPU interfaces are enabled - * - */ -VOID -EFIAPI -SecondaryMain ( - IN UINTN MpId - ) -{ - EFI_STATUS Status; - UINTN PpiListSize; - UINTN PpiListCount; - EFI_PEI_PPI_DESCRIPTOR *PpiList; - ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; - UINTN Index; - UINTN ArmCoreCount; - ARM_CORE_INFO *ArmCoreInfoTable; - UINT32 ClusterId; - UINT32 CoreId; - - VOID (*SecondaryStart)( - VOID - ); - UINTN SecondaryEntryAddr; - UINTN AcknowledgeInterrupt; - UINTN InterruptId; - - ClusterId = GET_CLUSTER_ID (MpId); - CoreId = GET_CORE_ID (MpId); - - // Get the gArmMpCoreInfoPpiGuid - PpiListSize = 0; - ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList); - PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR); - for (Index = 0; Index < PpiListCount; Index++, PpiList++) { - if (CompareGuid (PpiList->Guid, &gArmMpCoreInfoPpiGuid) == TRUE) { - break; - } - } - - // On MP Core Platform we must implement the ARM MP Core Info PPI - ASSERT (Index != PpiListCount); - - ArmMpCoreInfoPpi = PpiList->Ppi; - ArmCoreCount = 0; - Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); - ASSERT_EFI_ERROR (Status); - - // Find the core in the ArmCoreTable - for (Index = 0; Index < ArmCoreCount; Index++) { - if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) && - (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId)) - { - break; - } - } - - // The ARM Core Info Table must define every core - ASSERT (Index != ArmCoreCount); - - // Clear Secondary cores MailBox - MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue); - - do { - ArmCallWFI (); - - // Read the Mailbox - SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress); - - // Acknowledge the interrupt and send End of Interrupt signal. - AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId); - // Check if it is a valid interrupt ID - if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) { - // Got a valid SGI number hence signal End of Interrupt - ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt); - } - } while (SecondaryEntryAddr == 0); - - // Jump to secondary core entry point. - SecondaryStart = (VOID (*)()) SecondaryEntryAddr; - SecondaryStart (); - - // The secondaries shouldn't reach here - ASSERT (FALSE); -} - -VOID -EFIAPI -PrimaryMain ( - IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint - ) -{ - EFI_SEC_PEI_HAND_OFF SecCoreData; - UINTN PpiListSize; - EFI_PEI_PPI_DESCRIPTOR *PpiList; - UINTN TemporaryRamBase; - UINTN TemporaryRamSize; - - CreatePpiList (&PpiListSize, &PpiList); - - // Enable the GIC Distributor - ArmGicEnableDistributor (PcdGet64 (PcdGicDistributorBase)); - - // If ArmVe has not been built as Standalone then we need to wake up the secondary cores - if (FeaturePcdGet (PcdSendSgiToBringUpSecondaryCores)) { - // Sending SGI to all the Secondary CPU interfaces - ArmGicSendSgiTo (PcdGet64 (PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId)); - } - - // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at - // the base of the primary core stack - PpiListSize = ALIGN_VALUE (PpiListSize, CPU_STACK_ALIGNMENT); - TemporaryRamBase = (UINTN)PcdGet64 (PcdCPUCoresStackBase) + PpiListSize; - TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize; - - // - // Bind this information into the SEC hand-off state - // Note: this must be in sync with the stuff in the asm file - // Note also: HOBs (pei temp ram) MUST be above stack - // - SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); - SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet64 (PcdFvBaseAddress); - SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize); - SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack) - SecCoreData.TemporaryRamSize = TemporaryRamSize; - SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; - SecCoreData.PeiTemporaryRamSize = ALIGN_VALUE (SecCoreData.TemporaryRamSize / 2, CPU_STACK_ALIGNMENT); - SecCoreData.StackBase = (VOID *)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize); - SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase; - - // Jump to PEI core entry point - PeiCoreEntryPoint (&SecCoreData, PpiList); -} diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c index 1c2580eb92..3d3c6caaa3 100644 --- a/ArmPlatformPkg/PrePeiCore/MainUniCore.c +++ b/ArmPlatformPkg/PrePeiCore/MainUniCore.c @@ -8,15 +8,6 @@ #include "PrePeiCore.h" -VOID -EFIAPI -SecondaryMain ( - IN UINTN MpId - ) -{ - ASSERT (FALSE); -} - VOID EFIAPI PrimaryMain ( diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c index 42a7ccc9c6..b4d40e7156 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c @@ -117,26 +117,21 @@ CEntryPoint ( // Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on. - // If not primary Jump to Secondary Main - if (ArmPlatformIsPrimaryCore (MpId)) { - // Invoke "ProcessLibraryConstructorList" to have all library constructors - // called. - ProcessLibraryConstructorList (); + // Invoke "ProcessLibraryConstructorList" to have all library constructors + // called. + ProcessLibraryConstructorList (); - PrintFirmwareVersion (); + PrintFirmwareVersion (); - // Initialize the Debug Agent for Source Level Debugging - InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); - SaveAndSetDebugTimerInterrupt (TRUE); + // Initialize the Debug Agent for Source Level Debugging + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); + SaveAndSetDebugTimerInterrupt (TRUE); - // Initialize the platform specific controllers - ArmPlatformInitialize (MpId); + // Initialize the platform specific controllers + ArmPlatformInitialize (MpId); - // Goto primary Main. - PrimaryMain (PeiCoreEntryPoint); - } else { - SecondaryMain (MpId); - } + // Goto primary Main. + PrimaryMain (PeiCoreEntryPoint); // PEI Core should always load and never return ASSERT (FALSE); diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h index fbf6207db8..966b0e7eee 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h @@ -52,21 +52,6 @@ PrimaryMain ( IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint ); -/* - * This is the main function for secondary cores. They loop around until a non Null value is written to - * SYS_FLAGS register.The SYS_FLAGS register is platform specific. - * Note:The secondary cores, while executing secondary_main, assumes that: - * : SGI 0 is configured as Non-secure interrupt - * : Priority Mask is configured to allow SGI 0 - * : Interrupt Distributor and CPU interfaces are enabled - * - */ -VOID -EFIAPI -SecondaryMain ( - IN UINTN MpId - ); - VOID PeiCommonExceptionEntry ( IN UINT32 Entry, diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf deleted file mode 100644 index c5cad7e37f..0000000000 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf +++ /dev/null @@ -1,76 +0,0 @@ -#/** @file -# Pre PeiCore - Hand-off to PEI Core in Normal World -# -# Copyright (c) 2011-2014, ARM Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 1.30 - BASE_NAME = ArmPlatformPrePeiCore - FILE_GUID = b78d02bb-d0b5-4389-bc7f-b39ee846c784 - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - -[Sources.common] - MainMPCore.c - PrePeiCore.h - PrePeiCore.c - -[Sources.ARM] - Arm/ArchPrePeiCore.c - Arm/PrePeiCoreEntryPoint.S | GCC - Arm/SwitchStack.S | GCC - Arm/Exception.S | GCC - -[Sources.AARCH64] - AArch64/ArchPrePeiCore.c - AArch64/PrePeiCoreEntryPoint.S - AArch64/SwitchStack.S - AArch64/Exception.S - AArch64/Helper.S - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ArmPkg/ArmPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - -[LibraryClasses] - ArmLib - ArmPlatformLib - CacheMaintenanceLib - BaseLib - DebugLib - DebugAgentLib - IoLib - ArmGicLib - PrintLib - SerialPortLib - -[Ppis] - gEfiTemporaryRamSupportPpiGuid - gArmMpCoreInfoPpiGuid - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString - -[FeaturePcd] - gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores - -[FixedPcd] - gArmTokenSpaceGuid.PcdFvBaseAddress - gArmTokenSpaceGuid.PcdFvSize - gArmTokenSpaceGuid.PcdVFPEnabled - - gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase - gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize - - gArmTokenSpaceGuid.PcdGicDistributorBase - gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase - gArmTokenSpaceGuid.PcdGicSgiIntId - - gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack -- cgit From 9c1bc36ad19dc91ad03f4e2e3fc1fc5033d158d5 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 19:25:55 +0200 Subject: ArmPlatformPkg/PrePeiCore: Drop secondary stack handling This SEC driver is single CPU only now, so all of the secondary stack handling is dead code, and can be removed. Signed-off-by: Ard Biesheuvel --- .../PrePeiCore/AArch64/PrePeiCoreEntryPoint.S | 51 ++++--------------- .../PrePeiCore/Arm/PrePeiCoreEntryPoint.S | 59 +++++----------------- ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 3 +- ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf | 1 - 4 files changed, 25 insertions(+), 89 deletions(-) diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S index 8ecec234bf..1c1054304a 100644 --- a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S +++ b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S @@ -30,41 +30,23 @@ ASM_FUNC(_ModuleEntryPoint) b ASM_PFX(MainEntryPoint) ASM_PFX(MainEntryPoint): - // Identify CPU ID - bl ASM_PFX(ArmReadMpidr) - // Keep a copy of the MpId register value - mov x5, x0 - - // Is it the Primary Core ? - bl ASM_PFX(ArmPlatformIsPrimaryCore) - // Get the top of the primary stacks (and the base of the secondary stacks) MOV64 (x1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - // x0 is equal to 1 if I am the primary core - cmp x0, #1 - b.eq _SetupPrimaryCoreStack - -_SetupSecondaryCoreStack: - // x1 contains the base of the secondary stacks - - // Get the Core Position - mov x6, x1 // Save base of the secondary stacks - mov x0, x5 - bl ASM_PFX(ArmPlatformGetCorePosition) - // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack - add x0, x0, #1 + // Set up the stack pointer + mov sp, x1 - // StackOffset = CorePos * StackSize - MOV32 (x2, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) - mul x0, x0, x2 - // SP = StackBase + StackOffset - add sp, x6, x0 + // Apply the init value to the entire stack + MOV64 (x8, FixedPcdGet64 (PcdCPUCoresStackBase)) + MOV64 (x9, FixedPcdGet32 (PcdInitValueInTempStack) |\ + FixedPcdGet32 (PcdInitValueInTempStack) << 32) +0:stp x9, x9, [x8], #16 + cmp x8, x1 + b.lt 0b -_PrepareArguments: // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector MOV64 (x2, FixedPcdGet64(PcdFvBaseAddress)) - ldr x1, [x2, #8] + ldr x0, [x2, #8] // Move sec startup address into a data register // Ensure we're jumping to FV version of the code (not boot remapped alias) @@ -74,17 +56,6 @@ _PrepareArguments: mov x29, xzr // Jump to PrePeiCore C code - // x0 = mp_id - // x1 = pei_core_address + // x0 = pei_core_address mov x0, x5 blr x3 - -_SetupPrimaryCoreStack: - mov sp, x1 - MOV64 (x8, FixedPcdGet64 (PcdCPUCoresStackBase)) - MOV64 (x9, FixedPcdGet32 (PcdInitValueInTempStack) |\ - FixedPcdGet32 (PcdInitValueInTempStack) << 32) -0:stp x9, x9, [x8], #16 - cmp x8, x1 - b.lt 0b - b _PrepareArguments diff --git a/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S index 1c9d1b5193..b3c67234e9 100644 --- a/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S +++ b/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S @@ -11,63 +11,30 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions bl ASM_PFX(ArmPlatformPeiBootAction) - // Identify CPU ID - bl ASM_PFX(ArmReadMpidr) - // Keep a copy of the MpId register value - mov r5, r0 - - // Is it the Primary Core ? - bl ASM_PFX(ArmPlatformIsPrimaryCore) - // Get the top of the primary stacks (and the base of the secondary stacks) MOV32 (r1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - // r0 is equal to 1 if I am the primary core - cmp r0, #1 - beq _SetupPrimaryCoreStack - -_SetupSecondaryCoreStack: - // r1 contains the base of the secondary stacks - - // Get the Core Position - mov r6, r1 // Save base of the secondary stacks - mov r0, r5 - bl ASM_PFX(ArmPlatformGetCorePosition) - // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack - add r0, r0, #1 + // Set up the stack pointer + mov sp, r1 - // StackOffset = CorePos * StackSize - MOV32 (r2, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) - mul r0, r0, r2 - // SP = StackBase + StackOffset - add sp, r6, r0 + // Apply the init value to the entire stack + MOV32 (r8, FixedPcdGet64 (PcdCPUCoresStackBase)) + MOV32 (r9, FixedPcdGet32 (PcdInitValueInTempStack)) + mov r10, r9 + mov r11, r9 + mov r12, r9 +0:stm r8!, {r9-r12} + cmp r8, r1 + blt 0b -_PrepareArguments: // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector MOV32 (r2, FixedPcdGet32(PcdFvBaseAddress)) - ldr r1, [r2, #4] + ldr r0, [r2, #4] // Move sec startup address into a data register // Ensure we're jumping to FV version of the code (not boot remapped alias) ldr r3, =ASM_PFX(CEntryPoint) // Jump to PrePeiCore C code - // r0 = mp_id - // r1 = pei_core_address - mov r0, r5 + // r0 = pei_core_address blx r3 - -_SetupPrimaryCoreStack: - mov sp, r1 - MOV32 (r8, FixedPcdGet64 (PcdCPUCoresStackBase)) - MOV32 (r9, FixedPcdGet32 (PcdInitValueInTempStack)) - mov r10, r9 - mov r11, r9 - mov r12, r9 -0:stm r8!, {r9-r12} - cmp r8, r1 - blt 0b - b _PrepareArguments - -_NeverReturn: - b _NeverReturn diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c index b4d40e7156..cbaccbbad9 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c @@ -81,7 +81,6 @@ PrintFirmwareVersion ( VOID CEntryPoint ( - IN UINTN MpId, IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint ) { @@ -128,7 +127,7 @@ CEntryPoint ( SaveAndSetDebugTimerInterrupt (TRUE); // Initialize the platform specific controllers - ArmPlatformInitialize (MpId); + ArmPlatformInitialize (ArmReadMpidr ()); // Goto primary Main. PrimaryMain (PeiCoreEntryPoint); diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf index 7bcc5a383a..772bd14db0 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf @@ -62,6 +62,5 @@ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack -- cgit From 1941a901f08893dfc2f2cb8a44c6172a9f7ae8e4 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 19:27:03 +0200 Subject: ArmPlatformPkg/PrePi: Drop secondary stack handling This SEC driver is single CPU only now, so all of the secondary stack handling is dead code, and can be removed. This removes the last remaining user of the associated PCD, so drop that as well. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dec | 1 - ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S | 30 ++++-------------------- ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S | 31 ++++--------------------- ArmPlatformPkg/PrePi/PeiUniCore.inf | 2 -- 4 files changed, 10 insertions(+), 54 deletions(-) diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec index be384524bd..e8be550a8a 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dec +++ b/ArmPlatformPkg/ArmPlatformPkg.dec @@ -61,7 +61,6 @@ # Stack for CPU Cores in Non Secure Mode gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0|UINT64|0x00000009 gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x10000|UINT32|0x00000037 - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000|UINT32|0x0000000A # Size of the region used by UEFI in permanent memory (Reserved 128MB by default) gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000|UINT32|0x00000015 diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S index e3aa546897..c45fc5f400 100644 --- a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -11,11 +11,6 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions bl ASM_PFX(ArmPlatformPeiBootAction) - // Get ID of this CPU in multi-core system - bl ASM_PFX(ArmReadMpidr) - // Keep a copy of the MpId register value - mov x10, x0 - _SetSVCMode: // Check if we can install the stack at the top of the System Memory or if we need // to install the stacks at the bottom of the Firmware Device (case the FD is located @@ -71,31 +66,16 @@ _GetBaseUefiMemory: sub x11, x1, x4 _GetStackBase: - // r1 = The top of the Mpcore Stacks + // r1 = The top of the stack + mov sp, x1 + // Stack for the primary core = PrimaryCoreStack MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) sub x12, x1, x2 - // Stack for the secondary core = Number of Cores - 1 - MOV32 (x1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) - sub x12, x12, x1 - - // x12 = The base of the MpCore Stacks (primary stack & secondary stacks) - mov x0, x12 - mov x1, x10 - //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) - MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - MOV32 (x3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) - bl ASM_PFX(ArmPlatformStackSet) - - // Is it the Primary Core ? - mov x0, x10 - bl ASM_PFX(ArmPlatformIsPrimaryCore) - cmp x0, #1 - bne _PrepareArguments + // Get ID of this CPU in multi-core system + bl ASM_PFX(ArmReadMpidr) -_PrepareArguments: - mov x0, x10 mov x1, x11 mov x2, x12 diff --git a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S index 60e530e4f1..c87f94689c 100644 --- a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S @@ -13,11 +13,6 @@ ASM_FUNC(_ModuleEntryPoint) // Do early platform specific actions bl ASM_PFX(ArmPlatformPeiBootAction) - // Get ID of this CPU in multi-core system - bl ASM_PFX(ArmReadMpidr) - // Keep a copy of the MpId register value - mov r8, r0 - _SetSVCMode: // Enter SVC mode, Disable FIQ and IRQ mov r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ) @@ -81,34 +76,18 @@ _GetBaseUefiMemory: sub r9, r1, r4 _GetStackBase: - // r1 = The top of the Mpcore Stacks + // r1 = The top of the stack + mov sp, r1 + // Stack for the primary core = PrimaryCoreStack MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) sub r10, r1, r2 - // Stack for the secondary core = Number of Cores - 1 - MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) - sub r10, r10, r1 - - // r10 = The base of the MpCore Stacks (primary stack & secondary stacks) - mov r0, r10 - mov r1, r8 - //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) - MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) - MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) - bl ASM_PFX(ArmPlatformStackSet) - - // Is it the Primary Core ? - mov r0, r8 - bl ASM_PFX(ArmPlatformIsPrimaryCore) - cmp r0, #1 - bne _PrepareArguments + // Get ID of this CPU in multi-core system + bl ASM_PFX(ArmReadMpidr) -_PrepareArguments: - mov r0, r8 mov r1, r9 mov r2, r10 - mov r3, sp // Move sec startup address into a data register // Ensure we're jumping to FV version of the code (not boot remapped alias) diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf index 5c32fcbee4..9aa97d0a30 100644 --- a/ArmPlatformPkg/PrePi/PeiUniCore.inf +++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf @@ -48,7 +48,6 @@ DebugAgentLib PrePiLib ArmPlatformLib - ArmPlatformStackLib MemoryAllocationLib HobLib PrePiHobListPointerLib @@ -78,7 +77,6 @@ gArmTokenSpaceGuid.PcdFvSize gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize -- cgit From 8c10017aa7eeb4f58da1fc353d7af3ecb69e4bf7 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 19:48:03 +0200 Subject: ArmVirtPkg/PrePi: Drop call to TimerConstructor() Drop the call to the TimerConstructor, which should not be called explicitly, and does nothing useful to begin with. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/PrePi/PrePi.c | 2 -- ArmVirtPkg/PrePi/PrePi.h | 6 ------ 2 files changed, 8 deletions(-) diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c index f27e0ad3d2..9dbb5af942 100755 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -109,8 +109,6 @@ CEntryPoint ( UINT64 StartTimeStamp; if (PerformanceMeasurementEnabled ()) { - // Initialize the Timer Library to setup the Timer HW controller - TimerConstructor (); // We cannot call yet the PerformanceLib because the HOB List has not been initialized StartTimeStamp = GetPerformanceCounter (); } else { diff --git a/ArmVirtPkg/PrePi/PrePi.h b/ArmVirtPkg/PrePi/PrePi.h index 4bb9791e40..c00899b338 100644 --- a/ArmVirtPkg/PrePi/PrePi.h +++ b/ArmVirtPkg/PrePi/PrePi.h @@ -22,12 +22,6 @@ #define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1); -RETURN_STATUS -EFIAPI -TimerConstructor ( - VOID - ); - VOID PrePiMain ( IN UINTN UefiMemoryBase, -- cgit From e76b248d8fc37832a880121551b0780501f14308 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 19:49:35 +0200 Subject: ArmPlatformPkg/PrePi: Drop call to TimerConstructor() Drop the call to the TimerConstructor, which should not be called explicitly, and does nothing useful to begin with. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/PrePi/PrePi.c | 2 -- ArmPlatformPkg/PrePi/PrePi.h | 6 ------ 2 files changed, 8 deletions(-) diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c index 8cc43093b9..f16084673e 100644 --- a/ArmPlatformPkg/PrePi/PrePi.c +++ b/ArmPlatformPkg/PrePi/PrePi.c @@ -172,8 +172,6 @@ CEntryPoint ( ArmPlatformInitialize (MpId); if (PerformanceMeasurementEnabled ()) { - // Initialize the Timer Library to setup the Timer HW controller - TimerConstructor (); // We cannot call yet the PerformanceLib because the HOB List has not been initialized StartTimeStamp = GetPerformanceCounter (); } else { diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h index b4ba292c32..4d6e3251d7 100644 --- a/ArmPlatformPkg/PrePi/PrePi.h +++ b/ArmPlatformPkg/PrePi/PrePi.h @@ -23,12 +23,6 @@ extern UINT64 mSystemMemoryEnd; -RETURN_STATUS -EFIAPI -TimerConstructor ( - VOID - ); - EFI_STATUS EFIAPI MemoryPeim ( -- cgit From 12dc8d420bc98ceb3dbeb7be433b7dfc465a24b8 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 19:52:21 +0200 Subject: ArmPkg/ArmArchTimerLib: Drop pointless constructor Drop the pointless constructor in ArmArchTimerLib, which does nothing useful, especially because AArch64 mandates the presence of the generic timer, and 32-bit ARM is mostly obsolete these days. To preserve the existing behavior in DEBUG builds when actually using the timer, move the ASSERT () on a non-zero frequency to the associated accessor helper function. Signed-off-by: Ard Biesheuvel --- ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c | 26 ++-------------------- ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf | 1 - 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c index ccb4f6474b..76f94c9161 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c @@ -24,30 +24,6 @@ #define MULT_U64_X_N MultU64x64 #endif -RETURN_STATUS -EFIAPI -TimerConstructor ( - VOID - ) -{ - // - // Check if the ARM Generic Timer Extension is implemented. - // - if (ArmIsArchTimerImplemented ()) { - // - // Architectural Timer Frequency must be set in Secure privileged - // mode (if secure extension is supported). - // If the reset value (0) is returned, just ASSERT. - // - ASSERT (ArmGenericTimerGetTimerFreq () != 0); - } else { - DEBUG ((DEBUG_ERROR, "ARM Architectural Timer is not available in the CPU, hence this library cannot be used.\n")); - ASSERT (0); - } - - return RETURN_SUCCESS; -} - /** A local utility function that returns the PCD value, if specified. Otherwise it defaults to ArmGenericTimerGetTimerFreq. @@ -65,6 +41,8 @@ GetPlatformTimerFreq ( TimerFreq = ArmGenericTimerGetTimerFreq (); + ASSERT (TimerFreq != 0); + return TimerFreq; } diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf index 273b1e9555..76bad81531 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf @@ -12,7 +12,6 @@ MODULE_TYPE = BASE VERSION_STRING = 1.0 LIBRARY_CLASS = TimerLib - CONSTRUCTOR = TimerConstructor [Sources.common] ArmArchTimerLib.c -- cgit From bbe26ca2cc1c192ea6946567718621cb1ef16fe3 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 20:12:01 +0200 Subject: ArmPlatformPkg/PrePi: Make some functions STATIC Make some functions STATIC that are only called locally, and add some function headers to placate the tools. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/PrePi/PrePi.c | 17 +++++++++++++++++ ArmPlatformPkg/PrePi/PrePi.h | 6 ------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c index f16084673e..f98a0e56c1 100644 --- a/ArmPlatformPkg/PrePi/PrePi.c +++ b/ArmPlatformPkg/PrePi/PrePi.c @@ -28,6 +28,15 @@ UINT64 mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) + FixedPcdGet64 (PcdSystemMemorySize) - 1; +/** + Obtain a PPI from the list of PPIs provided by the platform code. + + @param[in] PpiGuid GUID of the PPI to obtain + @param[out] Ppi Address of GUID pointer to return the PPI + + @return Whether the PPI was obtained successfully +**/ +STATIC EFI_STATUS GetPlatformPpi ( IN EFI_GUID *PpiGuid, @@ -52,6 +61,14 @@ GetPlatformPpi ( return EFI_NOT_FOUND; } +/** + SEC main routine. + + @param[in] UefiMemoryBase Start of the PI/UEFI memory region + @param[in] StacksBase Start of the stack + @param[in] StartTimeStamp Timer value at start of execution +**/ +STATIC VOID PrePiMain ( IN UINTN UefiMemoryBase, diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h index 4d6e3251d7..9d3e7feaa0 100644 --- a/ArmPlatformPkg/PrePi/PrePi.h +++ b/ArmPlatformPkg/PrePi/PrePi.h @@ -42,12 +42,6 @@ BuildMemoryTypeInformationHob ( VOID ); -EFI_STATUS -GetPlatformPpi ( - IN EFI_GUID *PpiGuid, - OUT VOID **Ppi - ); - // Initialize the Architecture specific controllers VOID ArchInitialize ( -- cgit From 91117d70d89fbef4d7cac2d57854fa613716ca4d Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 30 Jul 2024 20:33:21 +0200 Subject: ArmPlatformPkg: Clone PrePiUniCore into PeilessSec PrePiUniCore was already spectacularly mis-named but now that the UniCore bit has become redundant too, let's rename it in a way that conveys its purpose a bit better: PeilessSec. A straight rename would break all out-of-tree users, so clone it into a new module with a fresh GUID, giving users some time to update. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 + ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c | 37 ++++ .../PeilessSec/AArch64/ModuleEntryPoint.S | 89 +++++++++ ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c | 25 +++ ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S | 96 ++++++++++ ArmPlatformPkg/PeilessSec/PeilessSec.c | 205 +++++++++++++++++++++ ArmPlatformPkg/PeilessSec/PeilessSec.h | 76 ++++++++ ArmPlatformPkg/PeilessSec/PeilessSec.inf | 78 ++++++++ 8 files changed, 607 insertions(+) create mode 100644 ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c create mode 100644 ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S create mode 100644 ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c create mode 100644 ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S create mode 100644 ArmPlatformPkg/PeilessSec/PeilessSec.c create mode 100644 ArmPlatformPkg/PeilessSec/PeilessSec.h create mode 100644 ArmPlatformPkg/PeilessSec/PeilessSec.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index bc4160d931..d73c5741f6 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -123,5 +123,6 @@ ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf ArmPlatformPkg/PrePi/PeiUniCore.inf + ArmPlatformPkg/PeilessSec/PeilessSec.inf ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.inf diff --git a/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c b/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c new file mode 100644 index 0000000000..ccc9cde6d1 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c @@ -0,0 +1,37 @@ +/** @file + + Copyright (c) 2011-2017, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PeilessSec.h" + +#include + +/** + Architecture specific initialization routine. +**/ +VOID +ArchInitialize ( + VOID + ) +{ + // Enable Floating Point + if (FixedPcdGet32 (PcdVFPEnabled)) { + ArmEnableVFP (); + } + + if (ArmReadCurrentEL () == AARCH64_EL2) { + // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2 + ArmWriteHcr (ARM_HCR_TGE); + + /* Enable Timer access for non-secure EL1 and EL0 + The cnthctl_el2 register bits are architecturally + UNKNOWN on reset. + Disable event stream as it is not in use at this stage + */ + ArmWriteCntHctl (CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN); + } +} diff --git a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S new file mode 100644 index 0000000000..efb6c5ade9 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S @@ -0,0 +1,89 @@ +// +// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include + +ASM_FUNC(_ModuleEntryPoint) + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + +_SetSVCMode: +// Check if we can install the stack at the top of the System Memory or if we need +// to install the stacks at the bottom of the Firmware Device (case the FD is located +// at the top of the DRAM) +_SystemMemoryEndInit: + ldr x1, mSystemMemoryEnd + +_SetupStackPosition: + // r1 = SystemMemoryTop + + // Calculate Top of the Firmware Device + MOV64 (x2, FixedPcdGet64(PcdFdBaseAddress)) + MOV32 (x3, FixedPcdGet32(PcdFdSize) - 1) + sub x3, x3, #1 + add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize + + // UEFI Memory Size (stacks are allocated in this region) + MOV32 (x4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) + + // + // Reserve the memory for the UEFI region (contain stacks on its top) + // + + // Calculate how much space there is between the top of the Firmware and the Top of the System Memory + subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop + b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when SEC is in XIP memory outside of the DRAM + cmp x0, x4 + b.ge _SetupStack + + // Case the top of stacks is the FdBaseAddress + mov x1, x2 + +_SetupStack: + // x1 contains the top of the stack (and the UEFI Memory) + + // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment + // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the + // top of the memory space) + adds x11, x1, #1 + b.cs _SetupOverflowStack + +_SetupAlignedStack: + mov x1, x11 + b _GetBaseUefiMemory + +_SetupOverflowStack: + // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE + // aligned (4KB) + and x1, x1, ~EFI_PAGE_MASK + +_GetBaseUefiMemory: + // Calculate the Base of the UEFI Memory + sub x0, x1, x4 + +_GetStackBase: + // r1 = The top of the stack + mov sp, x1 + + // Stack for the primary core = PrimaryCoreStack + MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + sub x1, x1, x2 + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr x4, =ASM_PFX(CEntryPoint) + + // Set the frame pointer to NULL so any backtraces terminate here + mov x29, xzr + + // Jump to SEC C code + // x0 = UefiMemoryBase + // x1 = StacksBase + blr x4 + +_NeverReturn: + b _NeverReturn diff --git a/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c b/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c new file mode 100644 index 0000000000..3c3cef6925 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c @@ -0,0 +1,25 @@ +/** @file + + Copyright (c) 2011 - 2013, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PeilessSec.h" + +/** + Architecture specific initialization routine. +**/ +VOID +ArchInitialize ( + VOID + ) +{ + // Enable program flow prediction, if supported. + ArmEnableBranchPrediction (); + + if (FixedPcdGet32 (PcdVFPEnabled)) { + ArmEnableVFP (); + } +} diff --git a/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S new file mode 100644 index 0000000000..ab5b023fa9 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S @@ -0,0 +1,96 @@ +// +// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include + +#include + +ASM_FUNC(_ModuleEntryPoint) + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + +_SetSVCMode: + // Enter SVC mode, Disable FIQ and IRQ + mov r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ) + msr CPSR_c, r1 + +// Check if we can install the stack at the top of the System Memory or if we need +// to install the stacks at the bottom of the Firmware Device (case the FD is located +// at the top of the DRAM) +_SystemMemoryEndInit: + ADRL (r1, mSystemMemoryEnd) + ldrd r2, r3, [r1] + teq r3, #0 + moveq r1, r2 + mvnne r1, #0 + +_SetupStackPosition: + // r1 = SystemMemoryTop + + // Calculate Top of the Firmware Device + MOV32 (r2, FixedPcdGet32(PcdFdBaseAddress)) + MOV32 (r3, FixedPcdGet32(PcdFdSize) - 1) + add r3, r3, r2 // r3 = FdTop = PcdFdBaseAddress + PcdFdSize + + // UEFI Memory Size (stacks are allocated in this region) + MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) + + // + // Reserve the memory for the UEFI region (contain stacks on its top) + // + + // Calculate how much space there is between the top of the Firmware and the Top of the System Memory + subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop + bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when SEC is in XIP memory outside of the DRAM + cmp r0, r4 + bge _SetupStack + + // Case the top of stacks is the FdBaseAddress + mov r1, r2 + +_SetupStack: + // r1 contains the top of the stack (and the UEFI Memory) + + // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment + // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the + // top of the memory space) + adds r9, r1, #1 + bcs _SetupOverflowStack + +_SetupAlignedStack: + mov r1, r9 + b _GetBaseUefiMemory + +_SetupOverflowStack: + // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE + // aligned (4KB) + MOV32 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF) + and r1, r1, r9 + +_GetBaseUefiMemory: + // Calculate the Base of the UEFI Memory + sub r0, r1, r4 + +_GetStackBase: + // r1 = The top of the stack + mov sp, r1 + + // Stack for the primary core = PrimaryCoreStack + MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + sub r1, r1, r2 + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr r4, =ASM_PFX(CEntryPoint) + + // Jump to SEC C code + // r0 = UefiMemoryBase + // r1 = StacksBase + blx r4 + +_NeverReturn: + b _NeverReturn diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.c b/ArmPlatformPkg/PeilessSec/PeilessSec.c new file mode 100644 index 0000000000..639c3744c9 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.c @@ -0,0 +1,205 @@ +/** @file + + Copyright (c) 2011-2017, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PeilessSec.h" + +#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\ + ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase))) + +UINT64 mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) + + FixedPcdGet64 (PcdSystemMemorySize) - 1; + +/** + Obtain a PPI from the list of PPIs provided by the platform code. + + @param[in] PpiGuid GUID of the PPI to obtain + @param[out] Ppi Address of GUID pointer to return the PPI + + @return Whether the PPI was obtained successfully +**/ +STATIC +EFI_STATUS +GetPlatformPpi ( + IN EFI_GUID *PpiGuid, + OUT VOID **Ppi + ) +{ + UINTN PpiListSize; + UINTN PpiListCount; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINTN Index; + + PpiListSize = 0; + ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList); + PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR); + for (Index = 0; Index < PpiListCount; Index++, PpiList++) { + if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) { + *Ppi = PpiList->Ppi; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + SEC main routine. + + @param[in] UefiMemoryBase Start of the PI/UEFI memory region + @param[in] StackBase Start of the stack + @param[in] StartTimeStamp Timer value at start of execution +**/ +STATIC +VOID +SecMain ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase, + IN UINT64 StartTimeStamp + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE *HobList; + ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; + UINTN ArmCoreCount; + ARM_CORE_INFO *ArmCoreInfoTable; + EFI_STATUS Status; + CHAR8 Buffer[100]; + UINTN CharCount; + UINTN StacksSize; + FIRMWARE_SEC_PERFORMANCE Performance; + + // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP) + ASSERT ( + IS_XIP () || + ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) && + ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)) + ); + + // Initialize the architecture specific bits + ArchInitialize (); + + // Initialize the Serial Port + SerialPortInitialize (); + CharCount = AsciiSPrint ( + Buffer, + sizeof (Buffer), + "UEFI firmware (version %s built at %a on %a)\n\r", + (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString), + __TIME__, + __DATE__ + ); + SerialPortWrite ((UINT8 *)Buffer, CharCount); + + // Initialize the Debug Agent for Source Level Debugging + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); + SaveAndSetDebugTimerInterrupt (TRUE); + + // Declare the PI/UEFI memory region + HobList = HobConstructor ( + (VOID *)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), + (VOID *)UefiMemoryBase, + (VOID *)StackBase // The top of the UEFI Memory is reserved for the stack + ); + PrePeiSetHobList (HobList); + + // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) + Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); + ASSERT_EFI_ERROR (Status); + + // Create the Stacks HOB + StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); + BuildStackHob (StackBase, StacksSize); + + // TODO: Call CpuPei as a library + BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize)); + + if (ArmIsMpCore ()) { + // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid + Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi); + + // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid) + ASSERT_EFI_ERROR (Status); + + // Build the MP Core Info Table + ArmCoreCount = 0; + Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); + if (!EFI_ERROR (Status) && (ArmCoreCount > 0)) { + // Build MPCore Info HOB + BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount); + } + } + + // Store timer value logged at the beginning of firmware image execution + Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp); + + // Build SEC Performance Data Hob + BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance)); + + // Set the Boot Mode + SetBootMode (ArmPlatformGetBootMode ()); + + // Initialize Platform HOBs (CpuHob and FvHob) + Status = PlatformPeim (); + ASSERT_EFI_ERROR (Status); + + // Now, the HOB List has been initialized, we can register performance information + PERF_START (NULL, "PEI", NULL, StartTimeStamp); + + // SEC phase needs to run library constructors by hand. + ProcessLibraryConstructorList (); + + // Assume the FV that contains the SEC (our code) also contains a compressed FV. + Status = DecompressFirstFv (); + ASSERT_EFI_ERROR (Status); + + // Load the DXE Core and transfer control to it + Status = LoadDxeCoreFromFv (NULL, 0); + ASSERT_EFI_ERROR (Status); +} + +/** + C entrypoint into the SEC driver. + + @param[in] UefiMemoryBase Start of the PI/UEFI memory region + @param[in] StackBase Start of the stack +**/ +VOID +CEntryPoint ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase + ) +{ + UINT64 StartTimeStamp; + + // Initialize the platform specific controllers + ArmPlatformInitialize (ArmReadMpidr ()); + + if (PerformanceMeasurementEnabled ()) { + // We cannot call yet the PerformanceLib because the HOB List has not been initialized + StartTimeStamp = GetPerformanceCounter (); + } else { + StartTimeStamp = 0; + } + + // Data Cache enabled on Primary core when MMU is enabled. + ArmDisableDataCache (); + // Invalidate instruction cache + ArmInvalidateInstructionCache (); + // Enable Instruction Caches on all cores. + ArmEnableInstructionCache (); + + InvalidateDataCacheRange ( + (VOID *)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) + ); + + SecMain (UefiMemoryBase, StackBase, StartTimeStamp); + + // DXE Core should always load and never return + ASSERT (FALSE); +} diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.h b/ArmPlatformPkg/PeilessSec/PeilessSec.h new file mode 100644 index 0000000000..70d78cafb0 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.h @@ -0,0 +1,76 @@ +/** @file + + Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PEILESSSEC_H_ +#define PEILESSSEC_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern UINT64 mSystemMemoryEnd; + +/** + Entrypoint of the memory PEIM driver. + + @param[in] UefiMemoryBase The base of the PI/UEFI memory region + @param[in[ UefiMemorySize The size of the PI/UEFI memory region + + @return Whether the memory PEIM driver executed successfully +**/ +EFI_STATUS +EFIAPI +MemoryPeim ( + IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, + IN UINT64 UefiMemorySize + ); + +/** + Entrypoint of platform PEIM driver. + + @return Whether the platform PEIM driver executed successfully +**/ +EFI_STATUS +EFIAPI +PlatformPeim ( + VOID + ); + +/** + Populate and install the memory type information HOB. +**/ +VOID +BuildMemoryTypeInformationHob ( + VOID + ); + +/** + Architecture specific initialization routine. +**/ +VOID +ArchInitialize ( + VOID + ); + +#endif /* PEILESSSEC_H_ */ diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.inf b/ArmPlatformPkg/PeilessSec/PeilessSec.inf new file mode 100644 index 0000000000..7ceeb74f69 --- /dev/null +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.inf @@ -0,0 +1,78 @@ +## @file +# SEC driver for PEI-less ARM platforms. +# +# Copyright (C) 2015 Hewlett-Packard Development Company, L.P.
+# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = PeilessSec + FILE_GUID = d90b03a8-2df5-4174-9ec1-c6e5b12b334b + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +[Sources] + PeilessSec.h + PeilessSec.c + +[Sources.ARM] + Arm/ArchPeilessSec.c + Arm/ModuleEntryPoint.S + +[Sources.AArch64] + AArch64/ArchPeilessSec.c + AArch64/ModuleEntryPoint.S + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmLib + ArmPlatformLib + BaseMemoryLib + CacheMaintenanceLib + DebugAgentLib + DebugLib + HobLib + MemoryInitPeiLib + PerformanceLib + PlatformPeiLib + PrePiHobListPointerLib + PrePiLib + PrintLib + SerialPortLib + TimerLib + +[Ppis] + gArmMpCoreInfoPpiGuid + +[Guids] + gArmMpCoreInfoGuid + gEfiFirmwarePerformanceGuid + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFdSize + gArmTokenSpaceGuid.PcdFvBaseAddress + gArmTokenSpaceGuid.PcdFvSize + gArmTokenSpaceGuid.PcdVFPEnabled + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + +[Pcd] + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString -- cgit From e85e29309e602a4e61870829ba965bad8f5da30f Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 31 Jul 2024 12:05:49 +0200 Subject: ArmPlatformPkg: Clone PrePeiUniCore into Sec PrePeiUniCore was already named rather awkwardly, but now that the UniCore bit has become redundant too, let's rename it in a way that conveys its purpose a bit better: Sec. This also matches what other architectures and platforms tend to provide. A straight rename would break all out-of-tree users, so clone it into a new module with a fresh GUID, giving users some time to update. Signed-off-by: Ard Biesheuvel --- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 + ArmPlatformPkg/Sec/AArch64/ArchSec.c | 49 ++++++ ArmPlatformPkg/Sec/AArch64/Exception.S | 116 ++++++++++++ ArmPlatformPkg/Sec/AArch64/Helper.S | 42 +++++ ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S | 60 +++++++ ArmPlatformPkg/Sec/AArch64/SwitchStack.S | 32 ++++ ArmPlatformPkg/Sec/Arm/ArchSec.c | 60 +++++++ ArmPlatformPkg/Sec/Arm/Exception.S | 96 ++++++++++ ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S | 40 +++++ ArmPlatformPkg/Sec/Arm/SwitchStack.S | 32 ++++ ArmPlatformPkg/Sec/Sec.c | 245 ++++++++++++++++++++++++++ ArmPlatformPkg/Sec/Sec.h | 54 ++++++ ArmPlatformPkg/Sec/Sec.inf | 65 +++++++ 13 files changed, 892 insertions(+) create mode 100644 ArmPlatformPkg/Sec/AArch64/ArchSec.c create mode 100644 ArmPlatformPkg/Sec/AArch64/Exception.S create mode 100644 ArmPlatformPkg/Sec/AArch64/Helper.S create mode 100644 ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S create mode 100644 ArmPlatformPkg/Sec/AArch64/SwitchStack.S create mode 100644 ArmPlatformPkg/Sec/Arm/ArchSec.c create mode 100644 ArmPlatformPkg/Sec/Arm/Exception.S create mode 100644 ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S create mode 100644 ArmPlatformPkg/Sec/Arm/SwitchStack.S create mode 100644 ArmPlatformPkg/Sec/Sec.c create mode 100644 ArmPlatformPkg/Sec/Sec.h create mode 100644 ArmPlatformPkg/Sec/Sec.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index d73c5741f6..bc6f2b5ede 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -121,6 +121,7 @@ ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf + ArmPlatformPkg/Sec/Sec.inf ArmPlatformPkg/PrePi/PeiUniCore.inf ArmPlatformPkg/PeilessSec/PeilessSec.inf diff --git a/ArmPlatformPkg/Sec/AArch64/ArchSec.c b/ArmPlatformPkg/Sec/AArch64/ArchSec.c new file mode 100644 index 0000000000..371f2b9e3c --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/ArchSec.c @@ -0,0 +1,49 @@ +/** @file + Architecture specific handling of CPU exceptions taken while running in PEI. + + Copyright (c) 2012-2013, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Sec.h" + +/** + Minimal high level handling of exceptions occurring in PEI. + + @param[in] Entry Type of exception + @param[in] LR Address of instruction where the exception was taken +**/ +VOID +PeiCommonExceptionEntry ( + IN UINT32 Entry, + IN UINTN LR + ) +{ + CHAR8 Buffer[100]; + UINTN CharCount; + + switch (Entry) { + case EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Synchronous Exception at 0x%X\n\r", LR); + break; + case EXCEPT_AARCH64_IRQ: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "IRQ Exception at 0x%X\n\r", LR); + break; + case EXCEPT_AARCH64_FIQ: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "FIQ Exception at 0x%X\n\r", LR); + break; + case EXCEPT_AARCH64_SERROR: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "SError/Abort Exception at 0x%X\n\r", LR); + break; + default: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Unknown Exception at 0x%X\n\r", LR); + break; + } + + SerialPortWrite ((UINT8 *)Buffer, CharCount); + + while (1) { + } +} diff --git a/ArmPlatformPkg/Sec/AArch64/Exception.S b/ArmPlatformPkg/Sec/AArch64/Exception.S new file mode 100644 index 0000000000..d0d6bc44f7 --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/Exception.S @@ -0,0 +1,116 @@ +# +# Copyright (c) 2011-2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# + +#include +#include +#include +#include + +.text + +//============================================================ +//Default Exception Handlers +//============================================================ + +#define TO_HANDLER \ + EL1_OR_EL2(x1) \ +1: mrs x1, elr_el1 /* EL1 Exception Link Register */ ;\ + b 3f ;\ +2: mrs x1, elr_el2 /* EL2 Exception Link Register */ ;\ +3: bl ASM_PFX(PeiCommonExceptionEntry) ; + + +// +// Default Exception handlers: There is no plan to return from any of these exceptions. +// No context saving at all. +// + +VECTOR_BASE(PeiVectorTable) + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_SYNC) +_DefaultSyncExceptHandler_t: + mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_IRQ) +_DefaultIrq_t: + mov x0, #EXCEPT_AARCH64_IRQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_FIQ) +_DefaultFiq_t: + mov x0, #EXCEPT_AARCH64_FIQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SP0_SERR) +_DefaultSError_t: + mov x0, #EXCEPT_AARCH64_SERROR + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_SYNC) +_DefaultSyncExceptHandler_h: + mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_IRQ) +_DefaultIrq_h: + mov x0, #EXCEPT_AARCH64_IRQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_FIQ) +_DefaultFiq_h: + mov x0, #EXCEPT_AARCH64_FIQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_CUR_SPX_SERR) +_DefaultSError_h: + mov x0, #EXCEPT_AARCH64_SERROR + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_SYNC) +_DefaultSyncExceptHandler_LowerA64: + mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_IRQ) +_DefaultIrq_LowerA64: + mov x0, #EXCEPT_AARCH64_IRQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_FIQ) +_DefaultFiq_LowerA64: + mov x0, #EXCEPT_AARCH64_FIQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A64_SERR) +_DefaultSError_LowerA64: + mov x0, #EXCEPT_AARCH64_SERROR + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_SYNC) +_DefaultSyncExceptHandler_LowerA32: + mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_IRQ) +_DefaultIrq_LowerA32: + mov x0, #EXCEPT_AARCH64_IRQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_FIQ) +_DefaultFiq_LowerA32: + mov x0, #EXCEPT_AARCH64_FIQ + TO_HANDLER + +VECTOR_ENTRY(PeiVectorTable, ARM_VECTOR_LOW_A32_SERR) +_DefaultSError_LowerA32: + mov x0, #EXCEPT_AARCH64_SERROR + TO_HANDLER + +VECTOR_END(PeiVectorTable) + +AARCH64_BTI_NOTE() diff --git a/ArmPlatformPkg/Sec/AArch64/Helper.S b/ArmPlatformPkg/Sec/AArch64/Helper.S new file mode 100644 index 0000000000..9b81b96a49 --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/Helper.S @@ -0,0 +1,42 @@ +#======================================================================================== +# Copyright (c) 2011-2017, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#======================================================================================= + +#include +#include + +// Setup EL1 while in EL1 +ASM_FUNC(SetupExceptionLevel1) + mov x5, x30 // Save LR + + mov x0, #CPACR_CP_FULL_ACCESS + bl ASM_PFX(ArmWriteCpacr) // Disable copro traps to EL1 + + ret x5 + +// Setup EL2 while in EL2 +ASM_FUNC(SetupExceptionLevel2) + msr sctlr_el2, xzr + mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register + + // Send all interrupts to their respective Exception levels for EL2 + orr x0, x0, #(1 << 3) // Enable EL2 FIQ + orr x0, x0, #(1 << 4) // Enable EL2 IRQ + orr x0, x0, #(1 << 5) // Enable EL2 SError and Abort + msr hcr_el2, x0 // Write back our settings + + msr cptr_el2, xzr // Disable copro traps to EL2 + + // Enable Timer access for non-secure EL1 and EL0 + // The cnthctl_el2 register bits are architecturally + // UNKNOWN on reset. + // Disable event stream as it is not in use at this stage + mov x0, #(CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN) + msr cnthctl_el2, x0 + + ret + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S new file mode 100644 index 0000000000..7addae6cff --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S @@ -0,0 +1,60 @@ +// +// Copyright (c) 2011-2014, ARM Limited. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include + +ASM_FUNC(_ModuleEntryPoint) + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + +// NOTE: We could be booting from EL3, EL2 or EL1. Need to correctly detect +// and configure the system accordingly. EL2 is default if possible. +// If we started in EL3 we need to switch and run at EL2. +// If we are running at EL2 stay in EL2 +// If we are starting at EL1 stay in EL1. + +// If started at EL3 Sec is run and switches to EL2 before jumping to PEI. +// If started at EL1 or EL2 Sec jumps directly to PEI without making any +// changes. + +// Which EL are we running at? Every EL needs some level of setup... +// We should not run this code in EL3 + EL1_OR_EL2(x0) +1:bl ASM_PFX(SetupExceptionLevel1) + b ASM_PFX(MainEntryPoint) +2:bl ASM_PFX(SetupExceptionLevel2) + b ASM_PFX(MainEntryPoint) + +ASM_PFX(MainEntryPoint): + // Get the top of the primary stacks (and the base of the secondary stacks) + MOV64 (x1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + + // Set up the stack pointer + mov sp, x1 + + // Apply the init value to the entire stack + MOV64 (x8, FixedPcdGet64 (PcdCPUCoresStackBase)) + MOV64 (x9, FixedPcdGet32 (PcdInitValueInTempStack) |\ + FixedPcdGet32 (PcdInitValueInTempStack) << 32) +0:stp x9, x9, [x8], #16 + cmp x8, x1 + b.lt 0b + + // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector + MOV64 (x2, FixedPcdGet64(PcdFvBaseAddress)) + ldr x0, [x2, #8] + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr x3, =ASM_PFX(CEntryPoint) + + // Set the frame pointer to NULL so any backtraces terminate here + mov x29, xzr + + // Jump to PrePeiCore C code + // x0 = pei_core_address + blr x3 diff --git a/ArmPlatformPkg/Sec/AArch64/SwitchStack.S b/ArmPlatformPkg/Sec/AArch64/SwitchStack.S new file mode 100644 index 0000000000..308b8764fc --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/SwitchStack.S @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +#include + +#/** +# This allows the caller to switch the stack and return +# +# @param StackDelta Signed amount by which to modify the stack pointer +# +# @return Nothing. Goes to the Entry Point passing in the new parameters +# +#**/ +#VOID +#EFIAPI +#SecSwitchStack ( +# VOID *StackDelta +# )# +# +ASM_FUNC(SecSwitchStack) + mov x1, sp + add x1, x0, x1 + mov sp, x1 + ret + diff --git a/ArmPlatformPkg/Sec/Arm/ArchSec.c b/ArmPlatformPkg/Sec/Arm/ArchSec.c new file mode 100644 index 0000000000..0c1e4998d7 --- /dev/null +++ b/ArmPlatformPkg/Sec/Arm/ArchSec.c @@ -0,0 +1,60 @@ +/** @file + Architecture specific handling of CPU exceptions taken while running in PEI. + + Copyright (c) 2012, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Sec.h" + +/** + Minimal high level handling of exceptions occurring in PEI. + + @param[in] Entry Type of exception + @param[in] LR Address of instruction where the exception was taken +**/ +VOID +PeiCommonExceptionEntry ( + IN UINT32 Entry, + IN UINTN LR + ) +{ + CHAR8 Buffer[100]; + UINTN CharCount; + + switch (Entry) { + case 0: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Reset Exception at 0x%X\n\r", LR); + break; + case 1: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Undefined Exception at 0x%X\n\r", LR); + break; + case 2: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "SWI Exception at 0x%X\n\r", LR); + break; + case 3: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "PrefetchAbort Exception at 0x%X\n\r", LR); + break; + case 4: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "DataAbort Exception at 0x%X\n\r", LR); + break; + case 5: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Reserved Exception at 0x%X\n\r", LR); + break; + case 6: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "IRQ Exception at 0x%X\n\r", LR); + break; + case 7: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "FIQ Exception at 0x%X\n\r", LR); + break; + default: + CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Unknown Exception at 0x%X\n\r", LR); + break; + } + + SerialPortWrite ((UINT8 *)Buffer, CharCount); + while (1) { + } +} diff --git a/ArmPlatformPkg/Sec/Arm/Exception.S b/ArmPlatformPkg/Sec/Arm/Exception.S new file mode 100644 index 0000000000..956ae84714 --- /dev/null +++ b/ArmPlatformPkg/Sec/Arm/Exception.S @@ -0,0 +1,96 @@ +// +// Copyright (c) 2011, ARM Limited. All rights reserved. +// +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# + +#include +#include +#include + +#start of the code section +.text +.align 5 + +# IMPORT +GCC_ASM_IMPORT(PeiCommonExceptionEntry) + +# EXPORT +GCC_ASM_EXPORT(PeiVectorTable) + +//============================================================ +//Default Exception Handlers +//============================================================ + + +ASM_PFX(PeiVectorTable): + b _DefaultResetHandler + b _DefaultUndefined + b _DefaultSWI + b _DefaultPrefetchAbort + b _DefaultDataAbort + b _DefaultReserved + b _DefaultIrq + b _DefaultFiq + +// +// Default Exception handlers: There is no plan to return from any of these exceptions. +// No context saving at all. +// +_DefaultResetHandler: + mov r1, lr + # Switch to SVC for common stack + cps #0x13 + mov r0, #0 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultUndefined: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #1 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultSWI: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #2 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultPrefetchAbort: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #3 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultDataAbort: + sub r1, LR, #8 + # Switch to SVC for common stack + cps #0x13 + mov r0, #4 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultReserved: + mov r1, lr + # Switch to SVC for common stack + cps #0x13 + mov r0, #5 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultIrq: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #6 + blx ASM_PFX(PeiCommonExceptionEntry) + +_DefaultFiq: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #7 + blx ASM_PFX(PeiCommonExceptionEntry) + diff --git a/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S new file mode 100644 index 0000000000..b3c67234e9 --- /dev/null +++ b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S @@ -0,0 +1,40 @@ +// +// Copyright (c) 2011-2013, ARM Limited. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// + +#include + +ASM_FUNC(_ModuleEntryPoint) + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + + // Get the top of the primary stacks (and the base of the secondary stacks) + MOV32 (r1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + + // Set up the stack pointer + mov sp, r1 + + // Apply the init value to the entire stack + MOV32 (r8, FixedPcdGet64 (PcdCPUCoresStackBase)) + MOV32 (r9, FixedPcdGet32 (PcdInitValueInTempStack)) + mov r10, r9 + mov r11, r9 + mov r12, r9 +0:stm r8!, {r9-r12} + cmp r8, r1 + blt 0b + + // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector + MOV32 (r2, FixedPcdGet32(PcdFvBaseAddress)) + ldr r0, [r2, #4] + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr r3, =ASM_PFX(CEntryPoint) + + // Jump to PrePeiCore C code + // r0 = pei_core_address + blx r3 diff --git a/ArmPlatformPkg/Sec/Arm/SwitchStack.S b/ArmPlatformPkg/Sec/Arm/SwitchStack.S new file mode 100644 index 0000000000..d64772b8ed --- /dev/null +++ b/ArmPlatformPkg/Sec/Arm/SwitchStack.S @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +#include + +#/** +# This allows the caller to switch the stack and return +# +# @param StackDelta Signed amount by which to modify the stack pointer +# +# @return Nothing. Goes to the Entry Point passing in the new parameters +# +#**/ +#VOID +#EFIAPI +#SecSwitchStack ( +# VOID *StackDelta +# )# +# +ASM_FUNC(SecSwitchStack) + mov R1, R13 + add R1, R0, R1 + mov R13, R1 + bx LR + + + diff --git a/ArmPlatformPkg/Sec/Sec.c b/ArmPlatformPkg/Sec/Sec.c new file mode 100644 index 0000000000..482e68ad42 --- /dev/null +++ b/ArmPlatformPkg/Sec/Sec.c @@ -0,0 +1,245 @@ +/** @file + Generic SEC driver for ARM platforms + + Copyright (c) 2011 - 2022, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Sec.h" + +/** + This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary + RAM into permanent memory. + + @param PeiServices Pointer to the PEI Services Table. + @param TemporaryMemoryBase Source Address in temporary memory from which + the SEC or PEIM will copy the Temporary RAM + contents. + @param PermanentMemoryBase Destination Address in permanent memory into + which the SEC or PEIM will copy the Temporary + RAM contents. + @param CopySize Amount of memory to migrate from temporary to + permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > + TemporaryMemoryBase when TemporaryMemoryBase > + PermanentMemoryBase. + +**/ +STATIC +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + VOID *OldHeap; + VOID *NewHeap; + VOID *OldStack; + VOID *NewStack; + UINTN HeapSize; + + HeapSize = ALIGN_VALUE (CopySize / 2, CPU_STACK_ALIGNMENT); + + OldHeap = (VOID *)(UINTN)TemporaryMemoryBase; + NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize - HeapSize)); + + OldStack = (VOID *)((UINTN)TemporaryMemoryBase + HeapSize); + NewStack = (VOID *)(UINTN)PermanentMemoryBase; + + // + // Migrate the temporary memory stack to permanent memory stack. + // + CopyMem (NewStack, OldStack, CopySize - HeapSize); + + // + // Migrate the temporary memory heap to permanent memory heap. + // + CopyMem (NewHeap, OldHeap, HeapSize); + + SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack); + + return EFI_SUCCESS; +} + +STATIC CONST EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + +STATIC CONST EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiTemporaryRamSupportPpiGuid, + (VOID *)&mTemporaryRamSupportPpi + } +}; + +/** + Construct a PPI list from the PPIs provided in this file and the ones + provided by the platform code. + + @param[out] PpiListSize Size of the PPI list in bytes + @param[out] PpiList Pointer to the constructed PPI list +**/ +STATIC +VOID +CreatePpiList ( + OUT UINTN *PpiListSize, + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList + ) +{ + EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList; + UINTN PlatformPpiListSize; + UINTN ListBase; + EFI_PEI_PPI_DESCRIPTOR *LastPpi; + + // Get the Platform PPIs + PlatformPpiListSize = 0; + ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList); + + // Copy the Common and Platform PPis in Temporary Memory + ListBase = PcdGet64 (PcdCPUCoresStackBase); + CopyMem ((VOID *)ListBase, gCommonPpiTable, sizeof (gCommonPpiTable)); + CopyMem ((VOID *)(ListBase + sizeof (gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize); + + // Set the Terminate flag on the last PPI entry + LastPpi = (EFI_PEI_PPI_DESCRIPTOR *)ListBase + + ((sizeof (gCommonPpiTable) + PlatformPpiListSize) / sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1; + LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + + *PpiList = (EFI_PEI_PPI_DESCRIPTOR *)ListBase; + *PpiListSize = sizeof (gCommonPpiTable) + PlatformPpiListSize; +} + +/** + + Prints firmware version and build time to serial console. + +**/ +STATIC +VOID +PrintFirmwareVersion ( + VOID + ) +{ + CHAR8 Buffer[100]; + UINTN CharCount; + + CharCount = AsciiSPrint ( + Buffer, + sizeof (Buffer), + "UEFI firmware (version %s built at %a on %a)\n\r", + (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString), + __TIME__, + __DATE__ + ); + SerialPortWrite ((UINT8 *)Buffer, CharCount); +} + +/** + SEC main routine. + + @param[in] PeiCoreEntryPoint Address in ram of the entrypoint of the PEI + core +**/ +STATIC +VOID +EFIAPI +SecMain ( + IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + UINTN PpiListSize; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINTN TemporaryRamBase; + UINTN TemporaryRamSize; + + CreatePpiList (&PpiListSize, &PpiList); + + // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at + // the base of the primary core stack + PpiListSize = ALIGN_VALUE (PpiListSize, CPU_STACK_ALIGNMENT); + TemporaryRamBase = (UINTN)PcdGet64 (PcdCPUCoresStackBase) + PpiListSize; + TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize; + + // + // Bind this information into the SEC hand-off state + // Note: this must be in sync with the stuff in the asm file + // Note also: HOBs (pei temp ram) MUST be above stack + // + SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet64 (PcdFvBaseAddress); + SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize); + SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack) + SecCoreData.TemporaryRamSize = TemporaryRamSize; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = ALIGN_VALUE (SecCoreData.TemporaryRamSize / 2, CPU_STACK_ALIGNMENT); + SecCoreData.StackBase = (VOID *)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize); + SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase; + + // Jump to PEI core entry point + (PeiCoreEntryPoint)(&SecCoreData, PpiList); +} + +/** + Module C entrypoint. + + @param[in] PeiCoreEntryPoint Address in ram of the entrypoint of the PEI + core +**/ +VOID +CEntryPoint ( + IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint + ) +{ + if (!ArmMmuEnabled ()) { + // Data Cache enabled on Primary core when MMU is enabled. + ArmDisableDataCache (); + // Invalidate instruction cache + ArmInvalidateInstructionCache (); + // Enable Instruction Caches on all cores. + ArmEnableInstructionCache (); + + InvalidateDataCacheRange ( + (VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase), + PcdGet32 (PcdCPUCorePrimaryStackSize) + ); + } + + // Write VBAR - The Exception Vector table must be aligned to its requirement + // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure + // 'Align=4K' is defined into your FDF for this module. + ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0); + ArmWriteVBar ((UINTN)PeiVectorTable); + + // Enable Floating Point + if (FixedPcdGet32 (PcdVFPEnabled)) { + ArmEnableVFP (); + } + + // Invoke "ProcessLibraryConstructorList" to have all library constructors + // called. + ProcessLibraryConstructorList (); + + PrintFirmwareVersion (); + + // Initialize the Debug Agent for Source Level Debugging + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); + SaveAndSetDebugTimerInterrupt (TRUE); + + // Initialize the platform specific controllers + ArmPlatformInitialize (ArmReadMpidr ()); + + // Goto primary Main. + SecMain (PeiCoreEntryPoint); + + // PEI Core should always load and never return + ASSERT (FALSE); +} diff --git a/ArmPlatformPkg/Sec/Sec.h b/ArmPlatformPkg/Sec/Sec.h new file mode 100644 index 0000000000..56d9f352bd --- /dev/null +++ b/ArmPlatformPkg/Sec/Sec.h @@ -0,0 +1,54 @@ +/** @file + Generic SEC driver for ARM platforms + + Copyright (c) 2011 - 2022, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SEC_H_ +#define SEC_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + Helper function to switch to a different stack. Implemented in assembler as + this cannot be done from C code. +**/ +VOID +SecSwitchStack ( + INTN StackDelta + ); + +/** + Vector Table for the PEI Phase. This is executable code but not a callable + function. Implemented in assembler. +**/ +VOID +PeiVectorTable ( + VOID + ); + +/** + Minimal high level handling of exceptions occurring in PEI. +**/ +VOID +PeiCommonExceptionEntry ( + IN UINT32 Entry, + IN UINTN LR + ); + +#endif diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf new file mode 100644 index 0000000000..58a566f5f0 --- /dev/null +++ b/ArmPlatformPkg/Sec/Sec.inf @@ -0,0 +1,65 @@ +## @file +# Generic SEC driver for ARM platforms +# +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = Sec + FILE_GUID = 4c97830a-8e18-4aa6-9fd0-837b089910e2 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +[Sources.common] + Sec.h + Sec.c + +[Sources.ARM] + Arm/ArchSec.c + Arm/Exception.S + Arm/ModuleEntryPoint.S + Arm/SwitchStack.S + +[Sources.AARCH64] + AArch64/ArchSec.c + AArch64/Exception.S + AArch64/Helper.S + AArch64/ModuleEntryPoint.S + AArch64/SwitchStack.S + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmLib + ArmPlatformLib + BaseLib + BaseMemoryLib + CacheMaintenanceLib + DebugAgentLib + DebugLib + PrintLib + SerialPortLib + +[Ppis] + gEfiTemporaryRamSupportPpiGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString + +[FixedPcd] + gArmTokenSpaceGuid.PcdFvBaseAddress + gArmTokenSpaceGuid.PcdFvSize + gArmTokenSpaceGuid.PcdVFPEnabled + + gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + + gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack -- cgit From 2d5390053ff934ec1e94b84f5bb67400b3b75841 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 31 Jul 2024 12:08:35 +0200 Subject: ArmVirtPkg: Switch all PrePeiCore users to new Sec.inf Switch to the new SEC driver based on PrePeiCore, but with a sane name. The old one will be retired once all users have migrated, including many in edk2-platforms. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/ArmVirtCloudHv.dsc | 2 +- ArmVirtPkg/ArmVirtCloudHv.fdf | 2 +- ArmVirtPkg/ArmVirtQemu.dsc | 2 +- ArmVirtPkg/ArmVirtQemu.fdf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc index 5cb2a609b1..234a2b5cf0 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.dsc +++ b/ArmVirtPkg/ArmVirtCloudHv.dsc @@ -210,7 +210,7 @@ # # PEI Phase modules # - ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf + ArmPlatformPkg/Sec/Sec.inf MdeModulePkg/Core/Pei/PeiMain.inf MdeModulePkg/Universal/PCD/Pei/Pcd.inf { diff --git a/ArmVirtPkg/ArmVirtCloudHv.fdf b/ArmVirtPkg/ArmVirtCloudHv.fdf index 8554efc294..555604056c 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.fdf +++ b/ArmVirtPkg/ArmVirtCloudHv.fdf @@ -236,7 +236,7 @@ READ_STATUS = TRUE READ_LOCK_CAP = TRUE READ_LOCK_STATUS = TRUE - INF ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf + INF ArmPlatformPkg/Sec/Sec.inf INF MdeModulePkg/Core/Pei/PeiMain.inf INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 942a602706..713710c499 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -345,7 +345,7 @@ # # PEI Phase modules # - ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf + ArmPlatformPkg/Sec/Sec.inf MdeModulePkg/Core/Pei/PeiMain.inf ArmPlatformPkg/PlatformPei/PlatformPeim.inf ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf index 764f652afd..ac2040acff 100644 --- a/ArmVirtPkg/ArmVirtQemu.fdf +++ b/ArmVirtPkg/ArmVirtQemu.fdf @@ -104,7 +104,7 @@ READ_STATUS = TRUE READ_LOCK_CAP = TRUE READ_LOCK_STATUS = TRUE - INF ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf + INF ArmPlatformPkg/Sec/Sec.inf INF MdeModulePkg/Core/Pei/PeiMain.inf INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf INF ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf -- cgit From 5c9b889b81f9ad22c7442887be72abef054998b9 Mon Sep 17 00:00:00 2001 From: Zhihao Li Date: Mon, 29 Apr 2024 09:43:25 +0800 Subject: IntelFsp2WrapperPkg/FspmWrapperPeim: Fix FspT/M address for measurement REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4716 Tcg module should use permanent address of FSP-T/M for measurement. TCG notification checks MigatedFvInfoHob and transmits DRAM address for measurement. Cc: Chasel Chiu Cc: Nate DeSimone Cc: Duggapu Chinni B Cc: Chen Gang C Signed-off-by: Zhihao Li --- .../FspmWrapperPeim/FspmWrapperPeim.c | 38 ++++++++++++++++++---- .../FspmWrapperPeim/FspmWrapperPeim.inf | 3 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c index 7f1deb9542..d9fbb21417 100644 --- a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c +++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c @@ -3,7 +3,7 @@ register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi notify to call FspSiliconInit API. - Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -38,6 +38,7 @@ #include #include #include +#include extern EFI_GUID gFspHobGuid; @@ -278,18 +279,41 @@ TcgPpiNotify ( IN VOID *Ppi ) { - UINT32 FspMeasureMask; + UINT32 FspMeasureMask; + EFI_PHYSICAL_ADDRESS FsptBaseAddress; + EFI_PHYSICAL_ADDRESS FspmBaseAddress; + EDKII_MIGRATED_FV_INFO *MigratedFvInfo; + EFI_PEI_HOB_POINTERS Hob; DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPM\n")); - FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig); + FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig); + FsptBaseAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFsptBaseAddress); + FspmBaseAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFspmBaseAddress); + Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid); + while (Hob.Raw != NULL) { + MigratedFvInfo = GET_GUID_HOB_DATA (Hob); + if ((MigratedFvInfo->FvOrgBase == PcdGet32 (PcdFsptBaseAddress)) && (MigratedFvInfo->FvDataBase != 0)) { + // + // Found the migrated FspT raw data + // + FsptBaseAddress = MigratedFvInfo->FvDataBase; + } + + if ((MigratedFvInfo->FvOrgBase == PcdGet32 (PcdFspmBaseAddress)) && (MigratedFvInfo->FvDataBase != 0)) { + FspmBaseAddress = MigratedFvInfo->FvDataBase; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw); + } if ((FspMeasureMask & FSP_MEASURE_FSPT) != 0) { MeasureFspFirmwareBlob ( 0, "FSPT", - PcdGet32 (PcdFsptBaseAddress), - (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFsptBaseAddress))->FvLength + FsptBaseAddress, + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FsptBaseAddress)->FvLength ); } @@ -297,8 +321,8 @@ TcgPpiNotify ( MeasureFspFirmwareBlob ( 0, "FSPM", - PcdGet32 (PcdFspmBaseAddress), - (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspmBaseAddress))->FvLength + FspmBaseAddress, + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FspmBaseAddress)->FvLength ); } diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf index 0307ce0acc..a0f384f992 100644 --- a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf @@ -6,7 +6,7 @@ # register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi # notify to call FspSiliconInit API. # -# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -69,6 +69,7 @@ [Guids] gFspHobGuid ## PRODUCES ## HOB gFspApiPerformanceGuid ## SOMETIMES_CONSUMES ## GUID + gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB [Ppis] gEdkiiTcgPpiGuid ## NOTIFY -- cgit From 29619603d213faebb8a3a78020b7d59dd1621b0a Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Mon, 25 Jul 2022 23:01:58 +0100 Subject: MdePkg/IndustryStandard: Add definitions for MPAM ACPI specification Add definitions, macros and types for elements associated with MPAM ACPI 2.0 specification. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Liming Gao Cc: Michael D Kinney Cc: Sami Mujawar Cc: Thomas Abraham Cc: Zhiguang Liu Acked-by: Liming Gao Reviewed-by: Pierre Gondois Reviewed-by: Sami Mujawar --- MdePkg/Include/IndustryStandard/Acpi65.h | 7 +- MdePkg/Include/IndustryStandard/Mpam.h | 246 +++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 MdePkg/Include/IndustryStandard/Mpam.h diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h index 218f909160..1f2af6ad2a 100644 --- a/MdePkg/Include/IndustryStandard/Acpi65.h +++ b/MdePkg/Include/IndustryStandard/Acpi65.h @@ -2,7 +2,7 @@ ACPI 6.5 definitions from the ACPI Specification Revision 6.5 Aug, 2022. Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.
- Copyright (c) 2019 - 2023, ARM Ltd. All rights reserved.
+ Copyright (c) 2019 - 2024, ARM Ltd. All rights reserved.
Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -3268,6 +3268,11 @@ typedef struct { /// #define EFI_ACPI_6_5_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') +/// +/// "MPAM" Memory System Resource Partitioning and Monitoring Table +/// +#define EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'A', 'M') + #pragma pack() #endif diff --git a/MdePkg/Include/IndustryStandard/Mpam.h b/MdePkg/Include/IndustryStandard/Mpam.h new file mode 100644 index 0000000000..8358b35d81 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/Mpam.h @@ -0,0 +1,246 @@ +/** @file + ACPI for Memory System Resource Partitioning and Monitoring 2.0 (MPAM) as + specified in ARM spec DEN0065 + + Copyright (c) 2024, Arm Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - [1] ACPI for Memory System Resource Partitioning and Monitoring 2.0 + (https://developer.arm.com/documentation/den0065/latest) + + @par Glossary: + - MPAM - Memory System Resource Partitioning And Monitoring + - MSC - Memory System Component + - PCC - Platform Communication Channel + - RIS - Resource Instance Selection + - SMMU - Arm System Memory Management Unit + **/ + +#ifndef MPAM_H_ +#define MPAM_H_ + +#include + +/// +/// MPAM Revision +/// +#define EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_REVISION (0x01) + +/// +/// MPAM Interrupt mode +/// +#define EFI_ACPI_MPAM_INTERRUPT_LEVEL_TRIGGERED (0x0) +#define EFI_ACPI_MPAM_INTERRUPT_EDGE_TRIGGERED (0x1) + +/// +/// MPAM Interrupt type +/// +#define EFI_ACPI_MPAM_INTERRUPT_WIRED (0x0) + +/// +/// MPAM Interrupt affinity type +/// +#define EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_AFFINITY (0x0) +#define EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_CONTAINER_AFFINITY (0x1) + +/// +/// MPAM MSC affinity valid +/// +#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_NOT_VALID (0x0) +#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID (0x1) + +/// +/// MPAM Interrupt flag - bit positions +/// +#define EFI_ACPI_MPAM_INTERRUPT_MODE_SHIFT (0) +#define EFI_ACPI_MPAM_INTERRUPT_TYPE_SHIFT (1) +#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_TYPE_SHIFT (3) +#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID_SHIFT (4) +#define EFI_ACPI_MPAM_INTERRUPT_RESERVED_SHIFT (5) + +/// +/// MPAM Interrupt flag - bit masks +/// +#define EFI_ACPI_MPAM_INTERRUPT_MODE_MASK (0x1) +#define EFI_ACPI_MPAM_INTERRUPT_TYPE_MASK (0x3) +#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_TYPE_MASK (0x8) +#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID_MASK (0x10) +#define EFI_ACPI_MPAM_INTERRUPT_RESERVED_MASK (0xFFFFFFE0) + +/// +/// MPAM Location types +/// as described in document [1], table 11. +/// +#define EFI_ACPI_MPAM_LOCATION_PROCESSOR_CACHE (0x0) +#define EFI_ACPI_MPAM_LOCATION_MEMORY (0x1) +#define EFI_ACPI_MPAM_LOCATION_SMMU (0x2) +#define EFI_ACPI_MPAM_LOCATION_MEMORY_CACHE (0x3) +#define EFI_ACPI_MPAM_LOCATION_ACPI_DEVICE (0x4) +#define EFI_ACPI_MPAM_LOCATION_INTERCONNECT (0x5) +#define EFI_ACPI_MPAM_LOCATION_UNKNOWN (0xFF) + +/// +/// MPAM Interface types +/// as desscribed in document[1], table 4. +/// +#define EFI_ACPI_MPAM_INTERFACE_MMIO (0x00) +#define EFI_ACPI_MPAM_INTERFACE_PCC (0x0A) + +/// +/// MPAM Link types +/// as described in document [1], table 19. +/// +#define EFI_ACPI_MPAM_LINK_TYPE_NUMA (0x00) +#define EFI_ACPI_MPAM_LINK_TYPE_PROC (0x01) + +#pragma pack(1) + +/// +/// MPAM MSC generic locator descriptor +/// as described in document [1], table 12. +/// +typedef struct { + UINT64 Descriptor1; + UINT32 Descriptor2; +} EFI_ACPI_MPAM_GENERIC_LOCATOR; + +/// +/// MPAM processor cache locator descriptor +/// as described in document [1], table 13. +/// +typedef struct { + UINT64 CacheReference; + UINT32 Reserved; +} EFI_ACPI_MPAM_CACHE_LOCATOR; + +/// +/// MPAM memory locator descriptor +/// as described in document [1], table 14. +/// +typedef struct { + UINT64 ProximityDomain; + UINT32 Reserved; +} EFI_ACPI_MPAM_MEMORY_LOCATOR; + +/// +/// MPAM SMMU locator descriptor +/// as described in document [1], table 15. +/// +typedef struct { + UINT64 SmmuInterface; + UINT32 Reserved; +} EFI_ACPI_MPAM_SMMU_LOCATOR; + +/// +/// MPAM memory-side cache locator descriptor +/// as described in Document [1], table 16. +/// +typedef struct { + UINT8 Reserved[7]; + UINT8 Level; + UINT32 Reference; +} EFI_ACPI_MPAM_MEMORY_CACHE_LOCATOR; + +/// +/// MPAM ACPI device locator descriptor +/// as described in document [1], table 17. +/// +typedef struct { + UINT64 AcpiHardwareId; + UINT32 AcpiUniqueId; +} EFI_ACPI_MPAM_ACPI_LOCATOR; + +/// +/// MPAM interconnect locator descriptor +/// as described in document [1], table 18. +/// +typedef struct { + UINT64 InterconnectDescTblOff; + UINT32 Reserved; +} EFI_ACPI_MPAM_INTERCONNECT_LOCATOR; + +/// +/// MPAM interconnect descriptor +/// as described in document [1], table 19. +/// +typedef struct { + UINT32 SourceId; + UINT32 DestinationId; + UINT8 LinkType; + UINT8 Reserved[3]; +} EFI_ACPI_MPAM_INTERCONNECT_DESCRIPTOR; + +/// +/// MPAM interconnect descriptor table +/// as described in document [1], table 20. +/// +typedef struct { + UINT8 Signature[16]; + UINT32 NumDescriptors; +} EFI_ACPI_MPAM_INTERCONNECT_DESCRIPTOR_TABLE; + +/// +/// MPAM resource locator +/// +typedef union { + EFI_ACPI_MPAM_CACHE_LOCATOR CacheLocator; + EFI_ACPI_MPAM_MEMORY_LOCATOR MemoryLocator; + EFI_ACPI_MPAM_SMMU_LOCATOR SmmuLocator; + EFI_ACPI_MPAM_MEMORY_CACHE_LOCATOR MemCacheLocator; + EFI_ACPI_MPAM_ACPI_LOCATOR AcpiLocator; + EFI_ACPI_MPAM_INTERCONNECT_LOCATOR InterconnectIfcLocator; + EFI_ACPI_MPAM_GENERIC_LOCATOR GenericLocator; +} EFI_ACPI_MPAM_LOCATOR; + +/// +/// MPAM MSC node body +/// as described document [1], table 4. +/// +typedef struct { + UINT16 Length; + UINT8 InterfaceType; + UINT8 Reserved; + UINT32 Identifier; + UINT64 BaseAddress; + UINT32 MmioSize; + UINT32 OverflowInterrupt; + UINT32 OverflowInterruptFlags; + UINT32 Reserved1; + UINT32 OverflowInterruptAffinity; + UINT32 ErrorInterrupt; + UINT32 ErrorInterruptFlags; + UINT32 Reserved2; + UINT32 ErrorInterruptAffinity; + UINT32 MaxNrdyUsec; + UINT64 HardwareIdLinkedDevice; + UINT32 InstanceIdLinkedDevice; + UINT32 NumResources; +} EFI_ACPI_MPAM_MSC_NODE; + +/// +/// MPAM MSC resource +/// as described in document [1], table 9. +/// +typedef struct { + UINT32 Identifier; + UINT8 RisIndex; + UINT16 Reserved1; + UINT8 LocatorType; + EFI_ACPI_MPAM_LOCATOR Locator; + UINT32 NumFunctionalDependencies; +} EFI_ACPI_MPAM_MSC_RESOURCE; + +/// +/// MPAM Function dependency descriptor +/// as described in document [1], table 10. +/// +typedef struct { + UINT32 Producer; + UINT32 Reserved; +} EFI_ACPI_MPAM_FUNCTIONAL_DEPENDENCY_DESCRIPTOR; + +#pragma pack() + +#endif -- cgit From 107d0c380009ad3b17a1730fce264eefdd027616 Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Tue, 22 Aug 2023 12:20:58 +0100 Subject: ShellPkg/AcpiView: Update field-validator prototype As of now, the field-validator implemented by FNPTR_FIELD_VALIDATOR function pointer takes two parameters, the pointer to the field and a context pointer. For cases where the validator has to have access to the length of the field, there is no clean way to currently do it. In order to resolve this, this commit updates the field-validator's prototype to take the length of the field as an additional parameter. This enhancement allows field validators to perform more comprehensive validation, especially when the length of the field is critical to the validation logic. This change should improve the overall robustness and flexibility of AcpiView. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Sami Mujawar Cc: Thomas Abraham Cc: Zhichao Gao Reviewed-by: Sami Mujawar --- .../UefiShellAcpiViewCommandLib/AcpiParser.c | 14 ++++-- .../UefiShellAcpiViewCommandLib/AcpiParser.h | 9 +++- .../Parsers/Aest/AestParser.c | 32 ++++++++----- .../Parsers/Dbg2/Dbg2Parser.c | 8 ++-- .../Parsers/Einj/EinjParser.c | 24 ++++++---- .../Parsers/Erst/ErstParser.c | 20 +++++--- .../Parsers/Fadt/FadtParser.c | 20 +++++--- .../Parsers/Gtdt/GtdtParser.c | 14 ++++-- .../Parsers/Hest/HestParser.c | 42 ++++++++++------ .../Parsers/Hmat/HmatParser.c | 8 ++-- .../Parsers/Hpet/HpetParser.c | 7 ++- .../Parsers/Iort/IortParser.c | 32 ++++++++----- .../Parsers/Madt/MadtParser.c | 20 +++++--- .../Parsers/Pcct/PcctParser.c | 56 ++++++++++++++-------- .../Parsers/Pptt/PpttParser.c | 38 ++++++++++----- .../Parsers/Rsdp/RsdpParser.c | 14 ++++-- .../Parsers/Spcr/SpcrParser.c | 14 ++++-- .../Parsers/Srat/SratParser.c | 14 ++++-- .../Parsers/Wsmt/WsmtParser.c | 17 ++++--- 19 files changed, 266 insertions(+), 137 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c index eac9286176..2e3afbac9d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c @@ -1,7 +1,7 @@ /** @file ACPI parser - Copyright (c) 2016 - 2021, Arm Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. Copyright (c) 2022, AMD Incorporated. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -616,7 +616,11 @@ ParseAcpi ( if (GetConsistencyChecking () && (Parser[Index].FieldValidator != NULL)) { - Parser[Index].FieldValidator (Ptr, Parser[Index].Context); + Parser[Index].FieldValidator ( + Ptr, + Parser[Index].Length, + Parser[Index].Context + ); } Print (L"\n"); @@ -927,7 +931,11 @@ ParseAcpiBitFields ( if (GetConsistencyChecking () && (Parser[Index].FieldValidator != NULL)) { - Parser[Index].FieldValidator ((UINT8 *)&Data, Parser[Index].Context); + Parser[Index].FieldValidator ( + (UINT8 *)&Data, + Parser[Index].Length, + Parser[Index].Context + ); } Print (L"\n"); diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index b449ded0d1..b759a916f5 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -2,7 +2,7 @@ Header file for ACPI parser Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - Copyright (c) 2016 - 2020, Arm Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. Copyright (c) 2022, AMD Incorporated. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -234,11 +234,16 @@ typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR16 *Format, UINT8 *Ptr); This function pointer is the template for validating an ACPI table field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information as specified by the 'Context' member of the ACPI_PARSER. e.g. this could be a pointer to the ACPI table header. **/ -typedef VOID (EFIAPI *FNPTR_FIELD_VALIDATOR)(UINT8 *Ptr, VOID *Context); +typedef VOID (EFIAPI *FNPTR_FIELD_VALIDATOR)( + UINT8 *Ptr, + UINT32 Length, + VOID *Context + ); /** The ACPI_PARSER structure describes the fields of an ACPI table and diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c index 48f71484fb..83f9b292b0 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c @@ -1,7 +1,7 @@ /** @file AEST table parser - Copyright (c) 2020, Arm Limited. + Copyright (c) 2020 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -33,6 +33,7 @@ STATIC UINT8 *ProcessorResourceType; Validate Processor Flags. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -40,8 +41,9 @@ STATIC VOID EFIAPI ValidateProcessorFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { // If the global or shared node flag is set then the ACPI Processor ID @@ -59,6 +61,7 @@ ValidateProcessorFlags ( Validate GIC Interface Type. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -66,8 +69,9 @@ STATIC VOID EFIAPI ValidateGicInterfaceType ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT32 GicInterfaceType; @@ -83,6 +87,7 @@ ValidateGicInterfaceType ( Validate Interface Type. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -90,8 +95,9 @@ STATIC VOID EFIAPI ValidateInterfaceType ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*Ptr > 1) { @@ -104,6 +110,7 @@ ValidateInterfaceType ( Validate Interrupt Type. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -111,8 +118,9 @@ STATIC VOID EFIAPI ValidateInterruptType ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*Ptr > 1) { @@ -125,6 +133,7 @@ ValidateInterruptType ( Validate interrupt flags. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -132,8 +141,9 @@ STATIC VOID EFIAPI ValidateInterruptFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if ((*Ptr & 0xfe) != 0) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c index d25d4d84f8..3d43d5cb8c 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c @@ -1,7 +1,7 @@ /** @file DBG2 table parser - Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -30,6 +30,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; This function validates the NameSpace string length. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -37,8 +38,9 @@ STATIC VOID EFIAPI ValidateNameSpaceStrLen ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT16 NameSpaceStrLen; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c index de867fb34a..3e3c1b0df8 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c @@ -31,6 +31,7 @@ STATIC CONST CHAR16 *InstNameTable[] = { This function validates the flags field in the EINJ injection header. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -38,8 +39,9 @@ STATIC VOID EFIAPI ValidateInjectionFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 Flags; @@ -72,6 +74,7 @@ STATIC CONST ACPI_PARSER EinjParser[] = { the EINJ injection instruction entry. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -79,8 +82,9 @@ STATIC VOID EFIAPI ValidateInjectionAction ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 InjectionAction; @@ -113,6 +117,7 @@ ValidateInjectionAction ( the EINJ injection instruction entry. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -120,8 +125,9 @@ STATIC VOID EFIAPI ValidateInstruction ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 Inst; @@ -141,6 +147,7 @@ ValidateInstruction ( the EINJ injection instruction entry. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -148,8 +155,9 @@ STATIC VOID EFIAPI ValidateRegisterRegion ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *RegisterRegion; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c index f3ae09309c..2b19e3e1c0 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c @@ -2,7 +2,7 @@ ERST table parser Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -70,6 +70,7 @@ STATIC CONST CHAR16 *ErstInstructionTable[] = { Validate Erst action. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -77,8 +78,9 @@ STATIC VOID EFIAPI ValidateErstAction ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*Ptr > EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS) { @@ -91,6 +93,7 @@ ValidateErstAction ( Validate Erst instruction. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -98,8 +101,9 @@ STATIC VOID EFIAPI ValidateErstInstruction ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*Ptr > EFI_ACPI_6_4_ERST_MOVE_DATA) { @@ -112,6 +116,7 @@ ValidateErstInstruction ( Validate Erst flags. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -119,8 +124,9 @@ STATIC VOID EFIAPI ValidateErstFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if ((*Ptr & 0xfe) != 0) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c index abc58d6552..c9eac9c18e 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c @@ -1,7 +1,7 @@ /** @file FADT table parser - Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. Copyright (c) 2022, AMD Incorporated. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -57,6 +57,7 @@ GetAcpiXsdtHeaderInfo ( This function validates the Firmware Control Field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -64,8 +65,9 @@ STATIC VOID EFIAPI ValidateFirmwareCtrl ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) @@ -83,6 +85,7 @@ ValidateFirmwareCtrl ( This function validates the X_Firmware Control Field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -90,8 +93,9 @@ STATIC VOID EFIAPI ValidateXFirmwareCtrl ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) @@ -109,6 +113,7 @@ ValidateXFirmwareCtrl ( This function validates the flags. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -116,8 +121,9 @@ STATIC VOID EFIAPI ValidateFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c index e62927098a..c8681e8424 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c @@ -1,7 +1,7 @@ /** @file GTDT table parser - Copyright (c) 2016 - 2021, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -30,6 +30,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; This function validates the GT Block timer count. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -37,8 +38,9 @@ STATIC VOID EFIAPI ValidateGtBlockTimerCount ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT32 BlockTimerCount; @@ -59,6 +61,7 @@ ValidateGtBlockTimerCount ( This function validates the GT Frame Number. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -66,8 +69,9 @@ STATIC VOID EFIAPI ValidateGtFrameNumber ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 FrameNumber; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c index 963163448f..1e9991dba2 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c @@ -113,6 +113,7 @@ STATIC CONST ACPI_PARSER HestErrorNotificationCweParser[] = { This function validates the Type field of Hardware Error Notification Structure @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -120,8 +121,9 @@ STATIC VOID EFIAPI ValidateErrorNotificationType ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 Type; @@ -246,6 +248,7 @@ STATIC CONST ACPI_PARSER HestErrorNotificationParser[] = { pci related Error source structure's bus field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -253,8 +256,9 @@ STATIC VOID EFIAPI ValidatePciBusReservedBits ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*Ptr != 0x00) { @@ -277,6 +281,7 @@ STATIC CONST ACPI_PARSER HestErrorSourcePciCommonBusParser[] = { error source descriptor structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -284,8 +289,9 @@ STATIC VOID EFIAPI ValidateIA32ErrorSourceFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 SourceFlags; @@ -313,6 +319,7 @@ ValidateIA32ErrorSourceFlags ( error source descriptor structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -320,8 +327,9 @@ STATIC VOID EFIAPI ValidatePciErrorSourceFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 SourceFlags; @@ -342,6 +350,7 @@ ValidatePciErrorSourceFlags ( error source descriptor structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -349,8 +358,9 @@ STATIC VOID EFIAPI ValidateGhesSourceFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 SourceFlags; @@ -368,6 +378,7 @@ ValidateGhesSourceFlags ( structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -375,8 +386,9 @@ STATIC VOID EFIAPI ValidateEnabledField ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT8 *)Ptr > 1) { @@ -391,6 +403,7 @@ ValidateEnabledField ( structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -398,8 +411,9 @@ STATIC VOID EFIAPI ValidateRecordCount ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 RecordCount; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c index 2a1357c853..ce69a600e7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c @@ -1,7 +1,7 @@ /** @file HMAT table parser - Copyright (c) 2020, Arm Limited. + Copyright (c) 2020 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -54,6 +54,7 @@ STATIC CONST CHAR16 *SllbiNames[] = { This function validates the Cache Attributes field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -61,8 +62,9 @@ STATIC VOID EFIAPI ValidateCacheAttributes ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES * diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c index 1b4c38f2af..9975af53fd 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c @@ -1,6 +1,7 @@ /** @file HPET table parser + Copyright (c) 2024, Arm Limited. All rights reserved. Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -121,6 +122,7 @@ DumpCounterSize ( This function validates the flags. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -128,8 +130,9 @@ STATIC VOID EFIAPI ValidateHpetRevId ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if ((*(UINT8 *)Ptr) == 0) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c index 599cf0ee8f..299ea4fd45 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c @@ -1,7 +1,7 @@ /** @file IORT table parser - Copyright (c) 2016 - 2022, Arm Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -46,6 +46,7 @@ STATIC CONST UINT32 *RmrMemDescOffset; This function validates the ID Mapping array count for the ITS node. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -53,8 +54,9 @@ STATIC VOID EFIAPI ValidateItsIdMappingCount ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr != 0) { @@ -68,6 +70,7 @@ ValidateItsIdMappingCount ( Monitoring Counter Group (PMCG) node. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -75,8 +78,9 @@ STATIC VOID EFIAPI ValidatePmcgIdMappingCount ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr > 1) { @@ -89,6 +93,7 @@ ValidatePmcgIdMappingCount ( This function validates the ID Mapping array offset for the ITS node. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -96,8 +101,9 @@ STATIC VOID EFIAPI ValidateItsIdArrayReference ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr != 0) { @@ -111,6 +117,7 @@ ValidateItsIdArrayReference ( and is 64K aligned. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -118,8 +125,9 @@ STATIC VOID EFIAPI ValidatePhysicalRange ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT64 Value; @@ -135,6 +143,7 @@ ValidatePhysicalRange ( This function validates that the RMR memory range descriptor count. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -142,8 +151,9 @@ STATIC VOID EFIAPI ValidateRmrMemDescCount ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr == 0) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c index 42f45d5a94..614fa4c2f9 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c @@ -1,7 +1,7 @@ /** @file MADT table parser - Copyright (c) 2016 - 2023, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. Copyright (c) 2022, AMD Incorporated. All rights reserved. Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -29,6 +29,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; This function validates the System Vector Base in the GICD. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -36,8 +37,9 @@ STATIC VOID EFIAPI ValidateGICDSystemVectorBase ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr != 0) { @@ -52,6 +54,7 @@ ValidateGICDSystemVectorBase ( This function validates the SPE Overflow Interrupt in the GICC. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -59,8 +62,9 @@ STATIC VOID EFIAPI ValidateSpeOverflowInterrupt ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT16 SpeOverflowInterrupt; @@ -102,6 +106,7 @@ ValidateSpeOverflowInterrupt ( This function validates the TRBE Interrupt in the GICC. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -109,8 +114,9 @@ STATIC VOID EFIAPI ValidateTrbeInterrupt ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT16 TrbeInterrupt; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c index 8ad39090af..43c6a9fb6f 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c @@ -1,7 +1,7 @@ /** @file PCCT table parser - Copyright (c) 2021, Arm Limited. + Copyright (c) 2021 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -28,6 +28,7 @@ STATIC UINT8 *ExtendedPccSubspaceInterruptFlags; This function validates the length coded on 4 bytes of a shared memory range @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -35,8 +36,9 @@ STATIC VOID EFIAPI ValidateRangeLength4 ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) { @@ -54,6 +56,7 @@ ValidateRangeLength4 ( This function validates the length coded on 8 bytes of a shared memory range @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -61,8 +64,9 @@ STATIC VOID EFIAPI ValidateRangeLength8 ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT64 *)Ptr <= MIN_MEMORY_RANGE_LENGTH) { @@ -80,6 +84,7 @@ ValidateRangeLength8 ( This function validates address space for Memory/IO GAS. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -87,8 +92,9 @@ STATIC VOID EFIAPI ValidatePccMemoryIoGas ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { switch (*(UINT8 *)Ptr) { @@ -107,6 +113,7 @@ ValidatePccMemoryIoGas ( This function validates address space for structures of types other than 0. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -114,8 +121,9 @@ STATIC VOID EFIAPI ValidatePccGas ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { switch (*(UINT8 *)Ptr) { @@ -135,6 +143,7 @@ ValidatePccGas ( This function validates doorbell address space for type 4 structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -142,8 +151,9 @@ STATIC VOID EFIAPI ValidatePccDoorbellGas ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { // For responder subspaces this field is optional, if not present the field @@ -158,7 +168,7 @@ ValidatePccDoorbellGas ( } } - ValidatePccGas (Ptr, Context); + ValidatePccGas (Ptr, Length, Context); } /** @@ -166,6 +176,7 @@ ValidatePccDoorbellGas ( type 4 structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -173,8 +184,9 @@ STATIC VOID EFIAPI ValidatePccIntAckGas ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { // If the subspace does not support interrupts or the interrupt is @@ -196,13 +208,14 @@ ValidatePccIntAckGas ( } } - ValidatePccGas (Ptr, Context); + ValidatePccGas (Ptr, Length, Context); } /** This function validates error status address space for type 4 structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -210,8 +223,9 @@ STATIC VOID EFIAPI ValidatePccErrStatusGas ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { // This field is ignored by the OSPM on responder channels. @@ -219,13 +233,14 @@ ValidatePccErrStatusGas ( return; } - ValidatePccGas (Ptr, Context); + ValidatePccGas (Ptr, Length, Context); } /** This function validates platform interrupt flags for type 4 structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -233,8 +248,9 @@ STATIC VOID EFIAPI ValidatePlatInterrupt ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { // If a responder subspace is present in the PCCT, then the global Platform diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c index 5377764458..fabe057d05 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c @@ -1,7 +1,7 @@ /** @file PPTT table parser - Copyright (c) 2019 - 2021, ARM Limited. All rights reserved. + Copyright (c) 2019 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -52,6 +52,7 @@ LogCacheFlagError ( This function validates the Cache Type Structure (Type 1) Cache Flags field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -59,8 +60,9 @@ STATIC VOID EFIAPI ValidateCacheFlags ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) @@ -115,6 +117,7 @@ ValidateCacheFlags ( field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -122,8 +125,9 @@ STATIC VOID EFIAPI ValidateCacheNumberOfSets ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT32 NumberOfSets; @@ -166,6 +170,7 @@ ValidateCacheNumberOfSets ( field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -173,8 +178,9 @@ STATIC VOID EFIAPI ValidateCacheAssociativity ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 Associativity; @@ -192,6 +198,7 @@ ValidateCacheAssociativity ( This function validates the Cache Type Structure (Type 1) Line size field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -199,8 +206,9 @@ STATIC VOID EFIAPI ValidateCacheLineSize ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) @@ -237,6 +245,7 @@ ValidateCacheLineSize ( This function validates the Cache Type Structure (Type 1) Cache ID field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -244,8 +253,9 @@ STATIC VOID EFIAPI ValidateCacheId ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT32 CacheId; @@ -276,6 +286,7 @@ ValidateCacheId ( This function validates the Cache Type Structure (Type 1) Attributes field. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -283,8 +294,9 @@ STATIC VOID EFIAPI ValidateCacheAttributes ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { // Reference: Advanced Configuration and Power Interface (ACPI) Specification diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c index bddf276356..895258bc1d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c @@ -1,7 +1,7 @@ /** @file RSDP table parser - Copyright (c) 2016 - 2019, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -19,6 +19,7 @@ STATIC CONST UINT64 *XsdtAddress; This function validates the RSDT Address. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -26,8 +27,9 @@ STATIC VOID EFIAPI ValidateRsdtAddress ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) @@ -55,6 +57,7 @@ ValidateRsdtAddress ( This function validates the XSDT Address. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -62,8 +65,9 @@ STATIC VOID EFIAPI ValidateXsdtAddress ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c index e5267b1d04..d172a555da 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c @@ -1,7 +1,7 @@ /** @file SPCR table parser - Copyright (c) 2016 - 2019, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -22,6 +22,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; This function validates the Interrupt Type. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -29,8 +30,9 @@ STATIC VOID EFIAPI ValidateInterruptType ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) @@ -55,6 +57,7 @@ ValidateInterruptType ( This function validates the Irq. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -62,8 +65,9 @@ STATIC VOID EFIAPI ValidateIrq ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c index 2980704479..d9831023ce 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c @@ -1,7 +1,7 @@ /** @file SRAT table parser - Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2024, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): @@ -25,6 +25,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; This function validates the Reserved field in the SRAT table header. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -32,8 +33,9 @@ STATIC VOID EFIAPI ValidateSratReserved ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { if (*(UINT32 *)Ptr != 1) { @@ -47,6 +49,7 @@ ValidateSratReserved ( Affinity Structure. @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -54,8 +57,9 @@ STATIC VOID EFIAPI ValidateSratDeviceHandleType ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT8 DeviceHandleType; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c index 3c7252b0bf..96c2706c73 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c @@ -1,6 +1,7 @@ /** @file WSMT table parser + Copyright (c) 2024, Arm Limited. All rights reserved. Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -17,7 +18,8 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; /** This function validates the WSMT Protection flag. - @param [in] Ptr Pointer to the start of the buffer. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. @@ -26,8 +28,9 @@ STATIC VOID EFIAPI ValidateWsmtProtectionFlag ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT32 ProtectionFlag; @@ -49,7 +52,8 @@ ValidateWsmtProtectionFlag ( /** This function validates the reserved bits in the WSMT Protection flag. - @param [in] Ptr Pointer to the start of the buffer. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. @param [in] Context Pointer to context specific information e.g. this could be a pointer to the ACPI table header. **/ @@ -57,8 +61,9 @@ STATIC VOID EFIAPI ValidateReserved ( - IN UINT8 *Ptr, - IN VOID *Context + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context ) { UINT32 ProtectionFlag; -- cgit From 9e865f9579004b772e36f85ae4e76484bb93b484 Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Tue, 22 Aug 2023 14:32:52 +0100 Subject: ShellPkg/AcpiView: Update print-formatter prototype As of now, the print-formatter implemented by the FNPTR_PRINT_FORMATTER function pointer takes two parameters, the format string and the pointer to the field. For cases where the print-formatter has to have access to the length of the field, there is no clean way to currently do it. In order to resolve this, update the print-formatter's prototype to take the length of the field as a third parameter. This change should improve the overall robustness and flexibility of AcpiView. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Sami Mujawar Cc: Thomas Abraham Cc: Zhichao Gao Reviewed-by: Sami Mujawar --- .../UefiShellAcpiViewCommandLib/AcpiParser.c | 28 +++++++++++++++------- .../UefiShellAcpiViewCommandLib/AcpiParser.h | 27 +++++++++++++++------ .../Parsers/Aest/AestParser.c | 4 +++- .../Parsers/Einj/EinjParser.c | 8 +++++-- .../Parsers/Erst/ErstParser.c | 8 +++++-- .../Parsers/Fadt/FadtParser.c | 4 +++- .../Parsers/Hest/HestParser.c | 20 ++++++++++++---- .../Parsers/Hmat/HmatParser.c | 4 +++- .../Parsers/Hpet/HpetParser.c | 12 ++++++---- .../Parsers/Madt/MadtParser.c | 4 +++- .../Parsers/Srat/SratParser.c | 12 +++++++--- .../Parsers/Wsmt/WsmtParser.c | 3 ++- 12 files changed, 98 insertions(+), 36 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c index 2e3afbac9d..beb58c72a9 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c @@ -319,12 +319,14 @@ DumpUint64 ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump3Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { Print ( @@ -343,12 +345,14 @@ Dump3Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump4Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { Print ( @@ -368,12 +372,14 @@ Dump4Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump6Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { Print ( @@ -395,12 +401,14 @@ Dump6Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump8Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { Print ( @@ -424,12 +432,14 @@ Dump8Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump12Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { Print ( @@ -587,7 +597,7 @@ ParseAcpi ( // the Format for printing PrintFieldName (2, Parser[Index].NameStr); if (Parser[Index].PrintFormatter != NULL) { - Parser[Index].PrintFormatter (Parser[Index].Format, Ptr); + Parser[Index].PrintFormatter (Parser[Index].Format, Ptr, Parser[Index].Length); } else if (Parser[Index].Format != NULL) { switch (Parser[Index].Length) { case 1: @@ -685,12 +695,14 @@ DumpGasStruct ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI DumpGas ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { DumpGasStruct (Ptr, 2, sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE)); @@ -896,7 +908,7 @@ ParseAcpiBitFields ( // the Format for printing PrintFieldName (2, Parser[Index].NameStr); if (Parser[Index].PrintFormatter != NULL) { - Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data); + Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data, Parser[Index].Length); } else if (Parser[Index].Format != NULL) { // convert bit length to byte length switch ((Parser[Index].Length + 7) >> 3) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index b759a916f5..df63741b1c 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -130,12 +130,14 @@ DumpUint64 ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump3Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ); /** @@ -146,12 +148,14 @@ Dump3Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump4Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ); /** @@ -162,12 +166,14 @@ Dump4Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump6Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ); /** @@ -178,12 +184,14 @@ Dump6Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump8Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ); /** @@ -194,12 +202,14 @@ Dump8Chars ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI Dump12Chars ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ); /** @@ -227,8 +237,9 @@ PrintFieldName ( @param [in] Format Format string for tracing the data as specified by the 'Format' member of ACPI_PARSER. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ -typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR16 *Format, UINT8 *Ptr); +typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR16 *Format, UINT8 *Ptr, UINT32 Length); /** This function pointer is the template for validating an ACPI table field. @@ -473,12 +484,14 @@ DumpGasStruct ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI DumpGas ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ); /** diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c index 83f9b292b0..af70c41826 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c @@ -157,12 +157,14 @@ ValidateInterruptFlags ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI DumpVendorSpecificData ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { Print ( diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c index 3e3c1b0df8..d01b15ff5f 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c @@ -177,13 +177,15 @@ ValidateRegisterRegion ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpInjectionInstAction ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { UINT8 InjectionAction; @@ -244,13 +246,15 @@ DumpInjectionInstAction ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpInstruction ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { UINT8 Inst; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c index 2b19e3e1c0..e237e0e04e 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c @@ -171,13 +171,15 @@ FormatByte ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the Action byte. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpErstAction ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { FormatByte (ErstActionTable, *Ptr, ARRAY_SIZE (ErstActionTable)); @@ -188,13 +190,15 @@ DumpErstAction ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the Instruction byte. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpErstInstruction ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { FormatByte (ErstInstructionTable, *Ptr, ARRAY_SIZE (ErstInstructionTable)); diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c index c9eac9c18e..d89fcb13a4 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c @@ -169,12 +169,14 @@ STATIC CONST ACPI_PARSER FadtFlagParser[] = { @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI DumpFadtFlags ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c index 1e9991dba2..75fc40b0ba 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c @@ -146,13 +146,15 @@ ValidateErrorNotificationType ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpSourceFlags ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { @@ -176,13 +178,15 @@ DumpSourceFlags ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpErrorNotificationType ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { @@ -202,13 +206,15 @@ DumpErrorNotificationType ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpErrorNotificationCwe ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { @@ -433,13 +439,15 @@ ValidateRecordCount ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpNotificationStructure ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { UINT32 Offset; @@ -466,13 +474,15 @@ DumpNotificationStructure ( from HestTable. @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpPciBus ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c index ce69a600e7..8f48927da7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c @@ -111,13 +111,15 @@ ValidateCacheAttributes ( @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpCacheAttributes ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES * diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c index 9975af53fd..c8ccdd4785 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c @@ -25,7 +25,8 @@ VOID EFIAPI DumpHpetPageProtectionFlag ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { @@ -72,7 +73,8 @@ VOID EFIAPI DumpHpetFlag ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { @@ -102,7 +104,8 @@ VOID EFIAPI DumpCounterSize ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { @@ -166,7 +169,8 @@ VOID EFIAPI DumpHpetEventTimerBlockId ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c index 614fa4c2f9..56ab507ef1 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c @@ -270,12 +270,14 @@ STATIC CONST ACPI_PARSER LocalApicFlags[] = { @param [in] Format Optional format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ VOID EFIAPI DumpLocalApicBitFlags ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c index d9831023ce..7bae94c076 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c @@ -81,13 +81,15 @@ ValidateSratDeviceHandleType ( @param [in] Format Format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpSratPciBdfNumber ( IN CONST CHAR16 *Format, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH]; @@ -169,13 +171,15 @@ STATIC CONST ACPI_PARSER SratDeviceHandlePciParser[] = { @param [in] Format Format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpSratDeviceHandle ( IN CONST CHAR16 *Format, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (SratDeviceHandleType == NULL) { @@ -212,13 +216,15 @@ DumpSratDeviceHandle ( @param [in] Format Format string for tracing the data. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. **/ STATIC VOID EFIAPI DumpSratApicProximity ( IN CONST CHAR16 *Format, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { UINT32 ProximityDomain; diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c index 96c2706c73..4433c047a4 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c @@ -97,7 +97,8 @@ VOID EFIAPI DumpWsmtProtectionFlag ( IN CONST CHAR16 *Format OPTIONAL, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Format != NULL) { -- cgit From 8a036c89132e124ebb6852d3468e575ac289e26b Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Thu, 27 Apr 2023 16:07:18 +0100 Subject: ShellPkg: acpiview: Add routine to print 16 chars Certain ACPI tables like MPAM has fields which are 16 bytes long. Routines similar to Dump12Chars but for 16 characters are required to print such fields. Add Dump16Chars routine to satisfy this requirement. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Sami Mujawar Cc: Thomas Abraham Cc: Zhichao Gao Reviewed-by: Pierre Gondois Reviewed-by: Zhichao Gao Reviewed-by: Sami Mujawar --- .../UefiShellAcpiViewCommandLib/AcpiParser.c | 39 ++++++++++++++++++++++ .../UefiShellAcpiViewCommandLib/AcpiParser.h | 18 ++++++++++ 2 files changed, 57 insertions(+) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c index beb58c72a9..5fd7fd7a3d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c @@ -459,6 +459,45 @@ Dump12Chars ( ); } +/** + This function traces 16 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +VOID +EFIAPI +Dump16Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + Print ( + (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7], + Ptr[8], + Ptr[9], + Ptr[10], + Ptr[11], + Ptr[12], + Ptr[13], + Ptr[14], + Ptr[15] + ); +} + /** This function indents and prints the ACPI table Field Name. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index df63741b1c..4c616cc6ed 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -212,6 +212,24 @@ Dump12Chars ( IN UINT32 Length ); +/** + This function traces 16 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +VOID +EFIAPI +Dump16Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ); + /** This function indents and prints the ACPI table Field Name. -- cgit From 3c8133ba870b89f2b8d1cee05942e954a4fbb866 Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Thu, 28 Sep 2023 16:48:28 +0100 Subject: ShellPkg: acpiview: Add routines to print reserved fields Most of the ACPI tables have fields that are marked reserved. Implement functions "DumpReserved" and "DumpReservedBits" aligning with the print-formatter prototype to print out reserved fields. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Sami Mujawar Cc: Thomas Abraham Cc: Zhichao Gao Reviewed-by: Sami Mujawar --- .../UefiShellAcpiViewCommandLib/AcpiParser.c | 126 +++++++++++++++++++++ .../UefiShellAcpiViewCommandLib/AcpiParser.h | 38 +++++++ 2 files changed, 164 insertions(+) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c index 5fd7fd7a3d..728d8b523a 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c @@ -498,6 +498,132 @@ Dump16Chars ( ); } +/** + This function traces reserved fields up to 8 bytes in length. + + Format string is ignored by this function as the reserved field is printed + byte by byte with intermittent spacing . Use DumpxChars for any + other use case. + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +VOID +EFIAPI +DumpReserved ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + switch (Length) { + case 8: + Print ( + L"%u %u %u %u %u %u %u %u", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7] + ); + break; + case 7: + Print ( + L"%u %u %u %u %u %u %u", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6] + ); + break; + case 6: + Print ( + L"%u %u %u %u %u %u", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5] + ); + break; + case 5: + Print ( + L"%u %u %u %u %u", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4] + ); + break; + case 4: + Print ( + L"%u %u %u %u", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3] + ); + break; + case 3: + Print ( + L"%u %u %u", + Ptr[0], + Ptr[1], + Ptr[2] + ); + break; + case 2: + Print ( + L"%u %u", + Ptr[0], + Ptr[1] + ); + break; + case 1: + Print ( + L"%u", + Ptr[0] + ); + break; + default: + return; + } +} + +/** + This function traces reserved fields up to 64 bits in length. + + Format string is ignored by this function as the reserved field is printed + byte by byte with intermittent spacing. eg: <0 0 0 0>. When the field length + isn't a multiple of 8, the number of bytes are "ceil"-ed by one. eg for 27 + bits <0 0 0 0> + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field as number of bits. +**/ +VOID +EFIAPI +DumpReservedBits ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + UINT32 ByteLength; + + ByteLength = (Length + 7) >> 3; + DumpReserved (Format, Ptr, ByteLength); +} + /** This function indents and prints the ACPI table Field Name. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 4c616cc6ed..1baf615415 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -230,6 +230,44 @@ Dump16Chars ( IN UINT32 Length ); +/** + This function traces reserved fields up to 8 bytes in length. + + Format string is ignored by this function as the reserved field is printed + byte by byte with intermittent spacing . Use DumpxChars for any + other use case. + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +VOID +EFIAPI +DumpReserved ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ); + +/** + This function traces reserved fields up to 64 bits in length. + + Format string is ignored by this function as the reserved field is printed + byte by byte with intermittent spacing. eg: <0 0 0 0>. When the field length + isn't a multiple of 8, the number of bytes are "ceil"-ed by one. eg for 27 + bits <0 0 0 0> + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field as number of bits. +**/ +VOID +EFIAPI +DumpReservedBits ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ); + /** This function indents and prints the ACPI table Field Name. -- cgit From b0e7a75a4959a481cc6b857d6e6a9607d14523bf Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Wed, 26 Apr 2023 15:24:39 +0100 Subject: ShellPkg/AcpiView: Add MPAM Parser Add a parser for the MPAM (Memory system resource partitioning and monitoring) ACPI table. This parser would parse all MPAM related structures embedded as part of the ACPI table. Necessary validations are also performed where and when required. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Sami Mujawar Cc: Thomas Abraham Cc: Yeo Reum Yun Cc: Zhichao Gao Reviewed-by: Zhichao Gao --- .../UefiShellAcpiViewCommandLib/AcpiParser.h | 21 + .../Parsers/Mpam/MpamParser.c | 1241 ++++++++++++++++++++ .../UefiShellAcpiViewCommandLib.c | 3 +- .../UefiShellAcpiViewCommandLib.inf | 1 + .../UefiShellAcpiViewCommandLib.uni | 3 +- 5 files changed, 1267 insertions(+), 2 deletions(-) create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 1baf615415..6427ea7d8a 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -942,6 +942,27 @@ ParseAcpiMcfg ( IN UINT8 AcpiTableRevision ); +/** + This function parses the ACPI MPAM table. + When trace is enabled this function parses the MPAM table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiMpam ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + /** This function parses the ACPI PCCT table including its sub-structures of type 0 through 4. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c new file mode 100644 index 0000000000..acbb859fc3 --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c @@ -0,0 +1,1241 @@ +/** @file + MPAM table parser + + Copyright (c) 2024, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - [1] ACPI for Memory System Resource Partitioning and Monitoring 2.0 + (https://developer.arm.com/documentation/den0065/latest) + + @par Glossary: + - MPAM - Memory System Resource Partitioning And Monitoring + - MSC - Memory System Component + - PCC - Platform Communication Channel + - RIS - Resource Instance Selection + - SMMU - Arm System Memory Management Unit + **/ + +#include +#include +#include +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +// Local variables +STATIC CONST UINT8 *MscInterfaceType; +STATIC CONST UINT8 *ResourceLocatorType; +STATIC UINT32 MpamMscNodeStart; +STATIC CONST UINT16 *MpamMscNodeLength; +STATIC CONST UINT32 *NumberOfMscResources; +STATIC CONST UINT32 *NumberOfFunctionalDependencies; +STATIC CONST UINT32 *NumberOfInterconnectDescriptors; +STATIC CONST UINT64 *InterconnectTableOffset; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +// Array of locator type names. New types should be added keeping the order +// preserved as locator type is used to index into the array while parsing. +STATIC CONST CHAR16 *MpamMscLocatorTitles[] = { + L"Processor cache", + L"Memory", + L"SMMU", + L"Memory cache", + L"ACPI device", + L"Interconnect" +}; + +/** + When the length of the table is insufficient to be parsed, this function could + be used to display an appropriate error message. + + @param [in] ErrorMsg Error message string that has to be appended to the + main error log. This string could explain the reason + why a insufficient length error was encountered in + the first place. +**/ +STATIC +VOID +EFIAPI +MpamLengthError ( + IN CONST CHAR16 *ErrorMsg + ) +{ + IncrementErrorCount (); + Print (L"\nERROR : "); + Print (ErrorMsg); + Print ( + L"\nError : Insufficient MPAM MSC Node length. Table length : %u.\n", + *(AcpiHdrInfo.Length) + ); +} + +/** + This function validates reserved fields. Any reserved field within the MPAM + specification must be 0. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + particular function, context holds the size of the + reserved field that needs to be validated. +**/ +STATIC +VOID +EFIAPI +ValidateReserved ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + while (Length > 0) { + if (Ptr[Length-1] != 0) { + IncrementErrorCount (); + Print (L"\nERROR : Reserved field must be 0\n"); + break; + } + + Length--; + } +} + +/** + This function validates bit-length reserved fields. Any reserved field within + the MPAM specification must be 0. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + particular function, context holds the size of the + reserved field that needs to be validated. +**/ +STATIC +VOID +EFIAPI +ValidateReservedBits ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT32 ByteLength; + + ByteLength = (Length + 7) >> 3; + ValidateReserved (Ptr, ByteLength, Context); +} + +/** + This function validates the MMIO size within the MSC node body for MPAM ACPI + table. MPAM ACPI specification states that the MMIO size for an MSC having PCC + type interface should be zero. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context holds the parent/double pointer to a + variable holding the interface type. Make sure to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +ValidateMmioSize ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterfaceType; + UINT32 MmioSize; + + InterfaceType = *MscInterfaceType; + + if (InterfaceType == EFI_ACPI_MPAM_INTERFACE_PCC) { + MmioSize = *((UINT32 *)Ptr); + + if (MmioSize != 0) { + IncrementErrorCount (); + Print ( + L"\nERROR: MMIO size must be 0 for PCC interface type. Size - %u\n", + MmioSize + ); + } + } +} + +/** + This function decodes and validates the link type for MPAM's interconnect + descriptor. Valid links are of NUMA and PROC type. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context is ignored. +**/ +STATIC +VOID +EFIAPI +DecodeLinkType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 LinkType; + + LinkType = *Ptr; + + if (LinkType == EFI_ACPI_MPAM_LINK_TYPE_NUMA) { + Print ( + L" (NUMA)" + ); + } else if (LinkType == EFI_ACPI_MPAM_LINK_TYPE_PROC) { + Print ( + L" (PROC)" + ); + } else { + IncrementErrorCount (); + Print ( + L"\nERROR: Invalid link type - %u\n", + (UINT32)LinkType + ); + } +} + +/** + This function decodes the hardware ID field present within MPAM ACPI table. + The specification states that the hardware ID has to be set to zero if not + being used. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context is ignored. +**/ +STATIC +VOID +EFIAPI +DecodeHardwareId ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT64 HardwareId; + + HardwareId = *((UINT64 *)Ptr); + + if (HardwareId != 0) { + Print (L" ("); + Dump8Chars (NULL, Ptr, Length); + Print (L")"); + } +} + +/** + This function decodes and validates the interface type for MPAM. Valid + interfaces are of MMIO and PCC type. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context is ignored. +**/ +STATIC +VOID +EFIAPI +DecodeInterfaceType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterfaceType; + + InterfaceType = *Ptr; + + if (InterfaceType == EFI_ACPI_MPAM_INTERFACE_MMIO) { + Print (L" (MMIO)"); + } else if (InterfaceType == EFI_ACPI_MPAM_INTERFACE_PCC) { + Print (L" (PCC)"); + } else { + IncrementErrorCount (); + Print ( + L"\nERROR: Invalid interface type - %u\n", + (UINT32)InterfaceType + ); + } +} + +/** + This function decodes the interrupt mode flag for MPAM. Interrupt mode could + either be "edge triggered" or "level triggered". + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context holds the parent/double pointer to a + variable holding the interrupt gsiv. Make sure to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptMode ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptMode; + + InterruptMode = *Ptr; + + if (InterruptMode == EFI_ACPI_MPAM_INTERRUPT_LEVEL_TRIGGERED) { + Print (L" (Level triggered)"); + } else { + Print (L" (Edge triggered)"); + } +} + +/** + This function decodes the interrupt type flag for MPAM. Interrupt type could + be "wired interrupt". Other values are reserved at this point. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context holds the parent/double pointer to a + variable holding the interrupt gsiv. Make sure to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptType; + + InterruptType = *Ptr; + + if (InterruptType == EFI_ACPI_MPAM_INTERRUPT_WIRED) { + Print (L" (Wired interrupt)"); + } else { + IncrementWarningCount (); + Print (L" (Reserved value!)"); + } +} + +/** + This function decodes the interrupt affinity valid flag for MPAM. Interrupt + affinity could be either be valid or not. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context holds the parent/double pointer to a + variable holding the interrupt gsiv. Make sure to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptAffinityValid ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptAffinityValid; + + InterruptAffinityValid = *Ptr; + + if (InterruptAffinityValid != EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID) { + Print (L" (Affinity not valid)"); + } else { + Print (L" (Affinity valid)"); + } +} + +/** + This function decodes the interrupt affinity type flag for MPAM. Interrupt + affinity type could either be "Processor affinity" or "Processor container + affinity" + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context holds the parent/double pointer to a + variable holding the interrupt gsiv. Make sure to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptAffinityType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptAffinityType; + + InterruptAffinityType = *Ptr; + + if (InterruptAffinityType == EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_AFFINITY) { + Print (L" (Processor affinity)"); + } else { + Print (L" (Processor container affinity)"); + } +} + +/** + This function decodes the locator type for a particular MPAM MSC resource. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Length Length of the field. + @param [in] Context Pointer to context specific information. For this + function, context holds the parent/double pointer to a + variable holding the interrupt gsiv. Make sure to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeLocatorType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 LocatorType; + + LocatorType = *Ptr; + + if (LocatorType <= EFI_ACPI_MPAM_LOCATION_INTERCONNECT) { + Print (L" (%s)", MpamMscLocatorTitles[LocatorType]); + } else if (LocatorType == EFI_ACPI_MPAM_LOCATION_UNKNOWN) { + Print (L" (Unknown)"); + } else { + Print (L" (Reserved)"); + } +} + +/** + ACPI_PARSER array describing MPAM MSC interrupt flags. +**/ +STATIC CONST ACPI_PARSER MpamMscInterruptFlagParser[] = { + { L"Interrupt Mode", 1, 0, L"%u", NULL, NULL, + DecodeInterruptMode, NULL }, + { L"Interrupt Type", 2, 1, L"%u", NULL, NULL, + DecodeInterruptType, NULL }, + { L"Affinity Type", 1, 3, L"%u", NULL, NULL, + DecodeInterruptAffinityType, NULL }, + { L"Affinity Valid", 1, 4, L"%u", NULL, NULL, + DecodeInterruptAffinityValid, NULL }, + { L"Reserved", 27, 5, NULL, DumpReservedBits, NULL, + ValidateReservedBits, NULL } +}; + +/** + This function traces MPAM MSC Interrupt Flags. + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +STATIC +VOID +EFIAPI +DumpMpamMscInterruptFlags ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + Print (L"%u\n", *(UINT32 *)Ptr); + + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (MpamMscInterruptFlagParser) + ); +} + +/** + ACPI_PARSER array describing the MPAM MSC processor cache locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscProcessorCacheLocatorParser[] = { + { L"Cache reference", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC memory locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscMemoryLocatorParser[] = { + { L"Proximity domain", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC SMMU locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscSMMULocatorParser[] = { + { L"SMMU interface", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC memory cache locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscMemoryCacheLocatorParser[] = { + { L"Reserved", 7, 0, NULL, DumpReserved, NULL, + ValidateReserved, NULL }, + { L"Level", 1, 7, L"%u", NULL, NULL,NULL, NULL }, + { L"Reference", 4, 8, L"%u", NULL, NULL,NULL, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC ACPI device locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscAcpiDeviceLocatorParser[] = { + { L"ACPI hardware ID", 8, 0, L"0x%lx", NULL, NULL, + DecodeHardwareId, NULL }, + { L"ACPI unique ID", 4, 8, L"%u", NULL, NULL,NULL,NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC interconnect locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscInterconnectLocatorParser[] = { + { L"Interconnect desc tbl offset", 8, 0, L"%lu", NULL, + (VOID **)&InterconnectTableOffset, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, + NULL, ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC generic resource locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscGenericLocatorParser[] = { + { L"Descriptor1", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Descriptor2", 4, 8, L"%u", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the locator field within the resource node for ACPI MPAM + table. The parsing is based on the locator type field. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field. +**/ +STATIC +VOID +EFIAPI +ParseLocator ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + Print (L"\n"); + switch (*ResourceLocatorType) { + case EFI_ACPI_MPAM_LOCATION_PROCESSOR_CACHE: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscProcessorCacheLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_MEMORY: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscMemoryLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_SMMU: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscSMMULocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_MEMORY_CACHE: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscMemoryCacheLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_ACPI_DEVICE: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscAcpiDeviceLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_INTERCONNECT: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscInterconnectLocatorParser) + ); + break; + // For both UNKNOWN and RESERVED locator types, the locator is parsed using + // the generic locator parser as the spec does not define any format. + case EFI_ACPI_MPAM_LOCATION_UNKNOWN: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscGenericLocatorParser) + ); + break; + default: + Print (L"\nWARNING : Reserved locator type\n"); + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscGenericLocatorParser) + ); + IncrementWarningCount (); + break; + } // switch +} + +/** + ACPI_PARSER array describing the Generic ACPI MPAM table header. +**/ +STATIC CONST ACPI_PARSER MpamParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + ACPI_PARSER array describing the MPAM MSC node object. +**/ +STATIC CONST ACPI_PARSER MpamMscNodeParser[] = { + { L"Length", 2, 0, L"%u", NULL, + (VOID **)&MpamMscNodeLength, NULL, NULL }, + // Once Interface type is decoded, the address of interface type field is + // captured into InterfaceType pointer so that it could be used to check if + // MMIO Size field is set as per the specification. + { L"Interface type", 1, 2, L"0x%x", NULL, + (VOID **)&MscInterfaceType, DecodeInterfaceType, NULL }, + { L"Reserved", 1, 3, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Identifier", 4, 4, L"%u", NULL, + NULL, NULL, NULL }, + { L"Base address", 8, 8, L"0x%lx", NULL, + NULL, NULL, NULL }, + { L"MMIO Size", 4, 16, L"0x%x", NULL, + NULL, ValidateMmioSize, (VOID **)&MscInterfaceType }, + { L"Overflow interrupt", 4, 20, L"%u", NULL, + NULL, NULL, NULL }, + { L"Overflow interrupt flags", 4, 24, NULL, DumpMpamMscInterruptFlags, + NULL, NULL, NULL }, + { L"Reserved1", 4, 28, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Overflow interrupt affinity", 4, 32, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"Error interrupt", 4, 36, L"%u", NULL, + NULL, NULL, NULL }, + { L"Error interrupt flags", 4, 40, NULL, DumpMpamMscInterruptFlags, + NULL, NULL, NULL }, + { L"Reserved2", 4, 44, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Error interrupt affinity", 4, 48, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"MAX_NRDY_USEC", 4, 52, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"Hardware ID of linked device", 8, 56, L"0x%lx", NULL, + NULL, DecodeHardwareId, NULL }, + { L"Instance ID of linked device", 4, 64, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"Number of resource nodes", 4, 68, L"%u", NULL, + (VOID **)&NumberOfMscResources, NULL, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC resource. +**/ +STATIC CONST ACPI_PARSER MpamMscResourceParser[] = { + { L"Identifier", 4, 0, L"%u", NULL, + NULL, NULL, NULL }, + { L"RIS index", 1, 4, L"%u", NULL, + NULL, NULL, NULL }, + { L"Reserved1", 2, 5, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Locator type", 1, 7, L"0x%x", NULL, + (VOID **)&ResourceLocatorType, + DecodeLocatorType, NULL }, + { L"Locator", 12, 8, NULL, ParseLocator, + NULL, NULL, NULL }, + { L"Number of func dependencies", 4, 20, L"%u", NULL, + (VOID **)&NumberOfFunctionalDependencies, NULL, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC resource's functional dependencies. +**/ +STATIC CONST ACPI_PARSER MpamMscFunctionalDependencyParser[] = { + { L"Producer", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 4, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, +}; + +/** + ACPI_PARSER array describing the interconnect descriptor table associated with + the interconnect locator type. +**/ +STATIC CONST ACPI_PARSER MpamInterconnectDescriptorTableParser[] = { + { L"Signature", 16, 0, + L"%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x", Dump16Chars, NULL, NULL, NULL }, + { L"Number of Interconnect desc", 4, 16,L"0x%x", NULL, + (VOID **)&NumberOfInterconnectDescriptors, NULL, NULL } +}; + +/** + ACPI_PARSER array describing the interconnect descriptor associated with the + interconnect locator type. +**/ +STATIC CONST ACPI_PARSER MpamInterconnectDescriptorParser[] = { + { L"Source ID", 4, 0, L"%u", NULL, NULL, NULL, NULL }, + { L"Destination ID", 4, 4, L"%u", NULL, NULL, NULL, NULL }, + { L"Link type", 1, 8, L"0x%x", NULL, + NULL, DecodeLinkType, NULL }, + { L"Reserved", 3, 9, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + PrintBlockTitle could be used to print the title of blocks that + appear more than once in the MPAM ACPI table. + + @param [in] Indent Number of spaces to add to the global table + indent. The global table indent is 0 by + default; however this value is updated on + entry to the ParseAcpi() by adding the indent + value provided to ParseAcpi() and restored + back on exit. Therefore the total indent in + the output is dependent on from where this + function is called. + @param [in] Title Title string to be used for the block. + @param [in] Index Index of the block. +**/ +STATIC +VOID +EFIAPI +PrintBlockTitle ( + IN UINT32 Indent, + IN CONST CHAR16 *Title, + IN CONST UINT32 Index + ) +{ + Print (L"\n"); + PrintFieldName (Indent, Title); + Print (L"%u\n\n", Index); +} + +/** + This function parses the interconnect descriptor(s) associated with + an interconnect type locator object. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in, out] Offset Pointer to current offset within Ptr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseInterconnectDescriptors ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN OUT UINT32 *CONST Offset + ) +{ + UINT32 InterconnectDescriptorIndex; + + InterconnectDescriptorIndex = 0; + + if (NumberOfInterconnectDescriptors == NULL) { + MpamLengthError (L"Number of interconnect descriptors not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + while (InterconnectDescriptorIndex < *NumberOfInterconnectDescriptors) { + PrintBlockTitle ( + 6, + L"* Interconnect descriptor *", + InterconnectDescriptorIndex + ); + + // Parse interconnect descriptor + *Offset += ParseAcpi ( + TRUE, + 4, + NULL, + Ptr + *Offset, + AcpiTableLength - *Offset, + PARSER_PARAMS (MpamInterconnectDescriptorParser) + ); + + InterconnectDescriptorIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses the interconnect descriptor table associated with an + interconnect type locator object. It also performs necessary validation to + make sure the interconnect descriptor is at a valid location. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] Offset Pointer to current offset within Ptr. + @param [in] InterconnectOffset Offset to the interconnect descriptor table. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not + long enough to be parsed correctly. + EFI_INVALID_PARAMETER The Offset parameter encoded within the Ptr + buffer is not valid. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseInterconnectDescriptorTable ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN UINT32 Offset, + IN CONST UINT64 InterconnectOffset + ) +{ + EFI_STATUS Status; + + // Lower bound check + if (Offset > (MpamMscNodeStart + InterconnectOffset)) { + IncrementErrorCount (); + Print (L"\nERROR : Parsing Interconnect descriptor table failed!\n"); + Print ( + L"ERROR : Offset overlaps with other objects within the MSC. Offset %u.\n", + InterconnectOffset + ); + + return EFI_INVALID_PARAMETER; + } + + // Upper bound check + if (InterconnectOffset > (*MpamMscNodeLength)) { + IncrementErrorCount (); + Print (L"\nERROR : Parsing Interconnect descriptor table failed!\n"); + Print ( + L"ERROR : Offset falls outside MSC's space. Offset %u.\n", + InterconnectOffset + ); + + return EFI_INVALID_PARAMETER; + } + + // It is safe to cast InterconnectOffset to UINT32 as IntercconnectOffset can + // never exceed the MPAM table length which is at max 2 bytes. + Offset = MpamMscNodeStart + (UINT32)InterconnectOffset; + + Print (L"\n"); + PrintFieldName (6, L"* Interconnect desc table *"); + Print (L"\n\n"); + + // Parse interconnect descriptor table + Offset += ParseAcpi ( + TRUE, + 4, + NULL, + Ptr + Offset, + AcpiTableLength - Offset, + PARSER_PARAMS (MpamInterconnectDescriptorTableParser) + ); + + Status = ParseInterconnectDescriptors ( + Ptr, + AcpiTableLength, + &Offset + ); + + return Status; +} + +/** + This function parses all the MPAM functional dependency nodes within a + single resource node. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in, out] Offset Pointer to current offset within Ptr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMpamMscFunctionalDependencies ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN OUT UINT32 *CONST Offset + ) +{ + UINT32 FunctionalDependencyIndex; + + FunctionalDependencyIndex = 0; + + if (NumberOfFunctionalDependencies == NULL) { + MpamLengthError (L"Number of functional dependencies not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + while (FunctionalDependencyIndex < *NumberOfFunctionalDependencies) { + PrintBlockTitle ( + 6, + L"* Functional dependency *", + FunctionalDependencyIndex + ); + + // Parse functional dependency + *Offset += ParseAcpi ( + TRUE, + 4, + NULL, + Ptr + *Offset, + AcpiTableLength - *Offset, + PARSER_PARAMS (MpamMscFunctionalDependencyParser) + ); + + FunctionalDependencyIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses all the MPAM resource nodes within a single MSC + node within the MPAM ACPI table. It also invokes helper functions to + validate and parse locators and functional dependency descriptors. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] Offset Pointer to current offset within Ptr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMpamMscResources ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN UINT32 Offset + ) +{ + EFI_STATUS Status; + UINT32 ResourceIndex; + + ResourceIndex = 0; + + if (NumberOfMscResources == NULL) { + MpamLengthError (L"Number of MSC resource not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + while (ResourceIndex < *NumberOfMscResources) { + PrintBlockTitle ( + 4, + L"* Resource *", + ResourceIndex + ); + + // Parse MPAM MSC resources within the MSC body. + Offset += ParseAcpi ( + TRUE, + 2, + NULL, + Ptr + Offset, + AcpiTableLength - Offset, + PARSER_PARAMS (MpamMscResourceParser) + ); + + Status = ParseMpamMscFunctionalDependencies (Ptr, AcpiTableLength, &Offset); + if (Status != EFI_SUCCESS) { + return Status; + } + + // If the InterconnectTableOffset field has been set, proceed to parse the + // interconnect descriptor table. Please note that the interconnect + // descriptors are placed within the MSC node body in the resource specific + // region. However since its easier to map an interconnect descriptor to + // its corresponding resource, proceed to parse it along with its parent + // resource. This design choice is made to keep the trace view as intuitive + // as possible. + // + // +---------------------+ + // | MPAM ACPI Header | + // +---------------------+------- + // | MSC Node 0 Hdr | ^ + // | +-----------------+ | | + // | | Res Node 0 | | | + // | | +-------------+ | | | + // | | | Res Node Hdr| | | | + // | | +-------------+ | | | + // | | | Res Data | | | | + // | | | | | | | + // | | | +---------+ | | | | +---------------------------+ + // | | | | Locator | | | | ..|..| Interconnect locator desc | + // | | | | | | | | | | Descriptor Table Offset |--points-to->+ + // | | | | | | | | | | Reserved [4] | | + // | | | +---------+ | | | | +---------------------------+ | + // | | | |FnDep Cnt| | | | | | + // | | | +---------+ | | | | | + // | | | |FnDep 1 | | | | | | + // | | | +---------+ | | | Interconnect | + // | | | |FnDep 2 | | | | descriptor | + // | | | +---------+ | | | table | + // | | | |FnDep n | | | | offset | + // | | | +---------+ | | | value | + // | | +-------------+ | | | | + // | +-----------------+ | | | + // | ... | | | + // | +-----------------+ | | | + // | | Res Node N | | | | + // | | +-------------+ | | | | + // | | | Res Node Hdr| | | | | + // | | +-------------+ | | | | + // | | | Res Data | | | | | + // | | | | | | | | + // | | | +---------+ | | | | | + // | | | | Locator | | | | | | + // | | | | | | | | | | + // | | | | | | | | | | + // | | | +---------+ | | | | | + // | | | |FnDep Cnt| | | | | | + // | | | +---------+ | | | | | + // | | | |FnDep 1 | | | | | | + // | | | +---------+ | | | | | + // | | | |FnDep 2 | | | | | | + // | | | +---------+ | | | | | + // | | | |FnDep n | | | | | | + // | | | +---------+ | | | | | + // | | +-------------+ | | | | + // | +-----------------+ | | | + // \ Resource-specific / v | + // / data region. \<-----------------------------------------------+ + // \ / + // +---------------------+ + // | MSC Node 1 Hdr | + // | ... | + // +---------------------+ + if ( (*ResourceLocatorType == EFI_ACPI_MPAM_LOCATION_INTERCONNECT) + && (InterconnectTableOffset != NULL)) + { + Status = ParseInterconnectDescriptorTable ( + Ptr, + AcpiTableLength, + Offset, + *InterconnectTableOffset + ); + if (Status != EFI_SUCCESS) { + return Status; + } + } + + ResourceIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses all the MPAM MSC nodes within the MPAM ACPI table. It + also invokes a helper function to detect and parse resource nodes that maybe + present. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in, out] Offset Pointer to the current offset within Ptr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMpamMscNodes ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN OUT UINT32 *CONST Offset + ) +{ + EFI_STATUS Status; + UINT32 MscIndex; + + MscIndex = 0; + + while (*Offset < AcpiTableLength) { + MpamMscNodeStart = *Offset; + + PrintBlockTitle (2, L"* MSC *", MscIndex); + // Parse MPAM MSC node + *Offset += ParseAcpi ( + TRUE, + 0, + NULL, + Ptr + *Offset, + AcpiTableLength - *Offset, + PARSER_PARAMS (MpamMscNodeParser) + ); + + if (MpamMscNodeLength == NULL) { + MpamLengthError (L"MPAM MSC node length not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + if (*MpamMscNodeLength < sizeof (EFI_ACPI_MPAM_MSC_NODE)) { + IncrementErrorCount (); + Print (L"\nERROR: MSC length should be at least the size of node body! "); + Print (L"MSC Length %u\n", *MpamMscNodeLength); + return EFI_BAD_BUFFER_SIZE; + } + + // Parse MPAM MSC resources within the MSC body + Status = ParseMpamMscResources (Ptr, AcpiTableLength, *Offset); + if (Status != EFI_SUCCESS) { + return Status; + } + + *Offset = MpamMscNodeStart + *MpamMscNodeLength; + MscIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses the MPAM ACPI table's generic header. It also invokes a + sub routine that would help with parsing rest of the table. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiMpam ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + EFI_STATUS Status; + UINT32 Offset; + + if (!Trace) { + return; + } + + // Parse generic table header + Offset = ParseAcpi ( + TRUE, + 0, + "MPAM", + Ptr, + AcpiTableLength, + PARSER_PARAMS (MpamParser) + ); + + Status = ParseMpamMscNodes ( + Ptr, + AcpiTableLength, + &Offset + ); + + if (Status == EFI_SUCCESS) { + // Check if the length of all MPAM MSCs with the header, matches with the + // ACPI table's length field. + if (*(AcpiHdrInfo.Length) != Offset) { + IncrementErrorCount (); + Print (L"\nERROR: Length mismatch! : "); + Print (L"MSC Length total != MPAM table length."); + Print ( + L"Table length : %u MSC total : %u\n", + *(AcpiHdrInfo.Length), + Offset + ); + } + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c index 81c58da45e..4f4254ac40 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -2,7 +2,7 @@ Main file for 'acpiview' Shell command function. Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -66,6 +66,7 @@ ACPI_TABLE_PARSER ParserList[] = { { EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt }, { EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMcfg }, + { EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_SIGNATURE, ParseAcpiMpam }, { EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE, ParseAcpiPcct }, { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index 87998b210d..54dddd0ee2 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -45,6 +45,7 @@ Parsers/Madt/MadtParser.c Parsers/Madt/MadtParser.h Parsers/Mcfg/McfgParser.c + Parsers/Mpam/MpamParser.c Parsers/Pcct/PcctParser.c Parsers/Pcct/PcctParser.h Parsers/Pptt/PpttParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni index e4a9dd5b40..4079a8e51e 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni @@ -1,6 +1,6 @@ // /** // -// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+// Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause-Patent // // Module Name: @@ -89,6 +89,7 @@ " HMAT - Heterogeneous Memory Attributes Table\r\n" " IORT - IO Remapping Table\r\n" " MCFG - Memory Mapped Config Space Base Address Description Table\r\n" +" MPAM - Memory System Resource Partitioning and Monitoring Table\r\n" " PPTT - Processor Properties Topology Table\r\n" " RSDP - Root System Description Pointer\r\n" " SLIT - System Locality Information Table\r\n" -- cgit From bd23183ac91566754077869b720cf542c11d68b1 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 04:51:55 -0600 Subject: .pytool: Add "MPIDR" to the list of known words in cspell.base.yaml "MPIDR" is the Multiprocessor Affinity Register on Arm systems. Add it the list of known words so that cspell doesn't flag it as a misspelling. Signed-off-by: Rebecca Cran --- .pytool/Plugin/SpellCheck/cspell.base.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml index 92e65ec6f6..915fd17f40 100644 --- a/.pytool/Plugin/SpellCheck/cspell.base.yaml +++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml @@ -291,6 +291,7 @@ "unenrolling", "unconfigure", "Loongson", - "LOONGARCH" + "LOONGARCH", + "MPIDR" ] } -- cgit From cf60ca43664c45477a65214ba398d58b63474ac1 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 10:39:46 -0600 Subject: .pytool: Sort the list of words in cspell.base.yaml Sort the list of words to add to cspell's dictionary by running the list through `sort`. Signed-off-by: Rebecca Cran --- .pytool/Plugin/SpellCheck/cspell.base.yaml | 468 ++++++++++++++--------------- 1 file changed, 234 insertions(+), 234 deletions(-) diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml index 915fd17f40..d701c0650e 100644 --- a/.pytool/Plugin/SpellCheck/cspell.base.yaml +++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml @@ -28,270 +28,270 @@ "muchange" ], "words": [ - "MTRRs", - "Microarchitecture", - "Goldmont", - "cpuid", - "mwait", - "cstate", - "smram", - "scrtm", - "smbus", - "selftest", - "socket", - "MMRAM", - "qword", - "ENDBR", - "SMBASE", - "FXSAVE", - "FXRSTOR", - "RDRAND", - "IOAPIC", - "ATAPI", - "movsb", - "iretw", - "XENSTORE", - "cdrom", - "oprom", - "oproms", - "varstore", - "EKU", + "ACPICA", + "ACPINVS", + "armltd", "ascii", - "nmake", - "NVDIMM", - "nasmb", - "Mtftp", - "Hypercall", - "hypercalls", - "IOMMU", - "QEMU", - "qemus", - "OVMF", - "tiano", - "tianocore", - "edkii", - "coreboot", - "uefipayload", + "ASMLINK", + "ATAPI", + "autodetect", + "autogen", + "autoreload", + "basetools", + "blockio", + "bootability", + "bootable", + "bootflow", "bootloader", "bootloaders", - "mdepkg", - "skuid", - "dxefv", - "toolchain", - "libraryclass", - "preboot", - "pythonpath", - "cygpath", - "nuget", - "basetools", - "prepi", - "OPTEE", - "stringid", - "peims", - "memmap", - "guids", - "uuids", - "smbios", + "bootup", + "bringup", + "brotli", + "bugbug", + "bytecodes", + "bytelist", + "bytestream", + "cacheability", + "cachetype", + "cdrom", "certdb", "certdbv", - "EfiSigList", - "depex", - "IHANDLE", - "Virtio", - "Mbytes", "Citrix", - "initrd", - "semihost", - "Semihosting", - "Trustzone", - "Fastboot", - "framebuffer", - "genfw", - "TTYTERM", - "miniport", - "LFENCE", - "PCANSI", - "submodule", - "submodules", - "brotli", - "PCCTS", - "softfloat", - "whitepaper", - "ACPICA", - "plugfest", - "bringup", - "formset", #VFR - "ideqvallist", - "numberof", - "oneof", - "endformset", - "endnumeric", - "endoneof", - "disableif", - "guidid", + "CLANGPDB", "classguid", + "cmocka", + "conout", + "Consplitter", # common module in UEFI + "coreboot", + "countof", + "cpuid", + "creatorid", + "cstate", + "cygpath", + "datacache", + "deadloop", + "depex", + "depexes", + "deregistering", + "devicepath", + "devicetree", + "devpath", + "disableif", + "Disasm", + "drhds", + "dxefv", + "dxeipl", + "dynamicex", + "edkii", + "edksetup", + "EfiSigList", "efivarstore", - "formsetguid", - "formid", - "suppressif", - "grayoutif", - "ideqval", - "endform", + "EKU", + "ENDBR", "endcheckbox", - "questionid", - "questionref", "enddate", - "endstring", - "guidop", + "endform", + "endformset", "endguidop", - "langdef", - "dynamicex", - "tokenspace", - "tokenguid", - "pcd's", #seems like cspell bug - "peim's", - "autogen", - "Disasm", - "Torito", - "SRIOV", - "MRIOV", - "UARTs", - "Consplitter", # common module in UEFI - "FIFOs", - "ACPINVS", + "endiannness", + "endnumeric", "Endof", # due to of not being uppercase - "bootability", - "Sdhci", + "endoneof", + "endstring", + "Fastboot", + "FIFOs", + "formid", + "formsetguid", + "formset", #VFR + "framebuffer", + "fvmain", + "fwvol", + "FXRSTOR", + "FXSAVE", + "genfw", + "Goldmont", + "grayoutif", + "guidid", + "guidop", + "guids", + "harddisk", + "hisilicon", + "hoblist", + "hwerrrec", + "Hypercall", + "hypercalls", + "ideqval", + "ideqvallist", + "IHANDLE", + "imagehandle", + "initrd", "inmodule", - "RISCV", - "edksetup", + "IOAPIC", + "IOMMU", + "iretw", "iscsi", - "nvdata", - "pytools", - "NTDDI", - "Wnonportable", - "CLANGPDB", - "nologo", + "langcode", + "langcodes", + "langdef", + "lastattemptstatus", + "lastattemptversion", + "LFENCE", + "libraryclass", + "littleendian", "lldmap", - "ASMLINK", - "NODEFAULTLIB", - "vcruntimed", - "ucrtd", + "lockv", + "LOONGARCH", + "Loongson", + "lowestsupportedversion", + "mainpage", + "Mbytes", + "mdepkg", + "memmap", + "Microarchitecture", + "miniport", + "mismanipulation", + "MMRAM", + "movsb", + "MPIDR", + "MRIOV", "msvcrtd", - "XIPFLAGS", - "bootflow", - "bootup", - "cacheability", - "cachetype", - "conout", - "deadloop", - "devicepath", - "hisilicon", - "littleendian", + "Mtftp", + "mtrrcap", + "MTRRs", + "multiboot", + "mwait", + "nasmb", + "nmake", + "NODEFAULTLIB", + "nofailure", + "nologo", "nonsecure", + "NTDDI", + "ntxml", + "ntxmlcomparestrings", + "ntxmlfetchcharacterdecoder", + "ntxmlrawnextcharacter", + "ntxmlspecialstringcompare", + "ntxmltransformcharacter", + "nuget", + "numberof", + "nvdata", + "NVDIMM", + "okcancel", + "oneof", + "oprom", + "oproms", + "OPTEE", + "osruntime", + "OVMF", "pagetable", + "PCANSI", + "PCCTS", + "pcd's", #seems like cspell bug + "pcencoder", + "pclutf", + "pcunicode", + "pcvoid", + "pcxml", + "pcxmldoc", + "pcxmlstructure", + "pecoff", + "peim's", + "peims", + "plugfest", "postmem", + "preboot", + "prefetchable", "premem", + "prepi", + "pxmldoc", + "pxmlstructure", + "pythonpath", + "pytool", + "pytools", + "QEMU", + "qemus", + "qrencoder", + "qrencoding", + "qrlevel", + "questionid", + "questionref", + "qword", + "ramdisk", + "RDRAND", + "readytoboot", "reglist", + "reprompt", + "RISCV", + "rmrrs", + "rtlxmlcallback", + "schedulable", + "scrtm", + "Sdhci", + "selawik", + "selftest", "semihalf", - "subvendor", + "semihost", + "Semihosting", + "setjump", + "shiftn", + "skuid", + "SMBASE", + "smbios", + "smbus", + "smram", + "socket", + "softfloat", + "SRIOV", + "StandaloneMMCore", + "stringid", "subhierarchy", + "submodule", + "submodules", + "subvendor", + "suppressif", + "swmdialogs", + "systemtable", "targetlist", + "testcase", + "testsuites", + "tiano", + "tianocore", "tmpname", - "watchdogtimer", - "writeback", - "langcode", - "langcodes", - "autoreload", - "bootable", - "endiannness", - "fvmain", - "prefetchable", - "multiboot", - "ramdisk", - "unbootable", - "setjump", - "bytecodes", - "bytelist", - "bytestream", - "countof", - "deregistering", - "devicetree", - "mainpage", - "mismanipulation", - "pytool", - "wbinvd", - "armltd", - "datacache", - "lastattemptstatus", - "lastattemptversion", - "lowestsupportedversion", - "updateable", - "pecoff", - "autodetect", - "harddisk", "toctou", - "bugbug", - "depexes", - "fwvol", - "hoblist", - "imagehandle", - "schedulable", - "StandaloneMMCore", - "systemtable", + "tokenguid", + "tokenspace", + "toolchain", + "Torito", + "Trustzone", + "TTYTERM", + "UARTs", + "ucrtd", + "uefipayload", + "uefishelldebug", + "unbootable", "uncacheable", - "devpath", - "testsuites", - "testcase", - "pxmldoc", - "pcxml", - "pclutf", - "pcunicode", - "ntxmltransformcharacter", - "ntxmlcomparestrings", - "pcxmldoc", - "ntxmlfetchcharacterdecoder", - "ntxml", - "ntxmlspecialstringcompare", - "rtlxmlcallback", - "xmlef", - "osruntime", - "readytoboot", - "hwerrrec", - "xformed", - "xform", + "unconfigure", "undock", - "qrencoder", - "selawik", - "ntxmlrawnextcharacter", "undocked", - "reprompt", - "yesno", - "okcancel", - "qrencoding", - "qrlevel", - "shiftn", "unenroll", - "pcxmlstructure", - "pxmlstructure", - "pcencoder", - "pcvoid", - "nofailure", - "blockio", - "lockv", - "uefishelldebug", - "mtrrcap", - "drhds", - "rmrrs", - "creatorid", - "dxeipl", - "swmdialogs", - "unrecovered", - "cmocka", "unenrolling", - "unconfigure", - "Loongson", - "LOONGARCH", - "MPIDR" + "unrecovered", + "updateable", + "uuids", + "varstore", + "vcruntimed", + "Virtio", + "watchdogtimer", + "wbinvd", + "whitepaper", + "Wnonportable", + "writeback", + "XENSTORE", + "xform", + "xformed", + "XIPFLAGS", + "xmlef", + "yesno" ] } -- cgit From 7b1646d4542e58058b02163a31a7228f4dba1611 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 09:56:41 -0600 Subject: ArmPlatformPkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in ArmPlatformPkg. Signed-off-by: Rebecca Cran --- ArmPlatformPkg/Include/Library/LcdPlatformLib.h | 2 +- ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c | 2 +- ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ArmPlatformPkg/Include/Library/LcdPlatformLib.h b/ArmPlatformPkg/Include/Library/LcdPlatformLib.h index b5628ece56..2049e5ef60 100644 --- a/ArmPlatformPkg/Include/Library/LcdPlatformLib.h +++ b/ArmPlatformPkg/Include/Library/LcdPlatformLib.h @@ -220,7 +220,7 @@ typedef struct { @param[in] Handle Handle to the LCD device instance. - @retval EFI_SUCCESS Plaform library initialized successfully. + @retval EFI_SUCCESS Platform library initialized successfully. @retval !(EFI_SUCCESS) Other errors. **/ EFI_STATUS diff --git a/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c b/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c index d01c910f6e..cea7ce2cc7 100644 --- a/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c +++ b/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c @@ -287,7 +287,7 @@ LcdInitialize ( return EFI_SUCCESS; } -/** Set ARM Mali DP in cofiguration mode. +/** Set ARM Mali DP in configuration mode. The ARM Mali DP must be in the configuration mode for configuration of the H_INTERVALS, V_INTERVALS, SYNC_CONTROL diff --git a/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c b/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c index 07f9b0f6be..b0b0cd8a85 100644 --- a/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c +++ b/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c @@ -19,7 +19,7 @@ @retval EFI_SUCCESS Returns success if platform implements a PL111 controller. - @retval EFI_NOT_FOUND PL111 display controller not found the plaform. + @retval EFI_NOT_FOUND PL111 display controller not found the platform. **/ EFI_STATUS LcdIdentify ( @@ -71,9 +71,9 @@ LcdInitialize ( /** Set requested mode of the display. - @param[in] ModeNumbe Display mode number. + @param[in] ModeNumber Display mode number. - @retval EFI_SUCCESS Display mode set successfuly. + @retval EFI_SUCCESS Display mode set successfully. @retval !(EFI_SUCCESS) Other errors. **/ EFI_STATUS -- cgit From 394cbc4ab28f825cdcdc25f4e9f0b8523ebf187c Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 09:59:11 -0600 Subject: ArmVirtPkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in ArmVirtPkg. Signed-off-by: Rebecca Cran --- ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c | 28 +++++++++++----------- .../QemuVirtMemInfoLib/QemuVirtMemInfoLib.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c index 0da84ba8d2..83d52e98f5 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c @@ -182,8 +182,8 @@ DebugBPrint ( Print a message of the form "ASSERT (): \n" to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of - PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if - DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then CpuDeadLoop() is called. If neither of these bits are set, then this function returns immediately after the message is printed to the debug output device. DebugAssert() must actively prevent recursion. If DebugAssert() is called while @@ -264,10 +264,10 @@ DebugClearMemory ( Returns TRUE if ASSERT() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -283,10 +283,10 @@ DebugAssertEnabled ( Returns TRUE if DEBUG() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -302,10 +302,10 @@ DebugPrintEnabled ( Returns TRUE if DEBUG_CODE() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -321,10 +321,10 @@ DebugCodeEnabled ( Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN diff --git a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c index 62fa62e5f0..d435d72598 100644 --- a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c +++ b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c @@ -27,7 +27,7 @@ #define MACH_VIRT_PERIPH_SIZE SIZE_128MB /** - Default library constructur that obtains the memory size from a PCD. + Default library constructor that obtains the memory size from a PCD. @return Always returns RETURN_SUCCESS -- cgit From ecb0d1e2cb513baf03586158899349d67b3f7c8f Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 10:00:09 -0600 Subject: MdePkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in MdePkg. Signed-off-by: Rebecca Cran --- .../UefiDebugLibDebugPortProtocol/DebugLib.c | 28 +++++++++++----------- .../DebugLibConstructor.c | 2 +- MdePkg/Library/UefiDebugLibStdErr/DebugLib.c | 28 +++++++++++----------- .../Library/UefiDevicePathLib/DevicePathFromText.c | 4 ++-- .../Test/UnitTest/Library/BaseLib/Base64UnitTest.c | 2 +- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c index c25199b53f..3314d3f69a 100644 --- a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c +++ b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c @@ -233,8 +233,8 @@ DebugBPrint ( Print a message of the form "ASSERT (): \n" to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of - PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if - DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then CpuDeadLoop() is called. If neither of these bits are set, then this function returns immediately after the message is printed to the debug output device. DebugAssert() must actively prevent recursion. If DebugAssert() is called while @@ -327,10 +327,10 @@ DebugClearMemory ( Returns TRUE if ASSERT() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -346,10 +346,10 @@ DebugAssertEnabled ( Returns TRUE if DEBUG() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -365,10 +365,10 @@ DebugPrintEnabled ( Returns TRUE if DEBUG_CODE() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -384,10 +384,10 @@ DebugCodeEnabled ( Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN diff --git a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c index 7ddecd0b62..0215c27139 100644 --- a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c +++ b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c @@ -13,7 +13,7 @@ #include // -// BOOLEAN value to indicate if it is at the post ExitBootServices pahse +// BOOLEAN value to indicate if it is at the post ExitBootServices phase // BOOLEAN mPostEBS = FALSE; diff --git a/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c b/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c index 5b28cd10ae..dc9c5254db 100644 --- a/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c +++ b/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c @@ -177,8 +177,8 @@ DebugBPrint ( Print a message of the form "ASSERT (): \n" to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of - PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if - DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then CpuDeadLoop() is called. If neither of these bits are set, then this function returns immediately after the message is printed to the debug output device. DebugAssert() must actively prevent recursion. If DebugAssert() is called while @@ -273,10 +273,10 @@ DebugClearMemory ( Returns TRUE if ASSERT() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -292,10 +292,10 @@ DebugAssertEnabled ( Returns TRUE if DEBUG() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -311,10 +311,10 @@ DebugPrintEnabled ( Returns TRUE if DEBUG_CODE() macros are enabled. This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN @@ -330,10 +330,10 @@ DebugCodeEnabled ( Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of - PcdDebugProperyMask is set. Otherwise FALSE is returned. + PcdDebugPropertyMask is set. Otherwise FALSE is returned. - @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. - @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear. **/ BOOLEAN diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c index 1aaa968d6f..86ecb66ba3 100644 --- a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c +++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c @@ -922,8 +922,8 @@ DevPathFromTextAcpiExp ( AcpiEx->HID = EisaIdFromText (HIDStr); // - // According to UEFI spec, the CID parametr is optional and has a default value of 0. - // So when the CID parametr is not specified or specified as 0 in the text device node. + // According to UEFI spec, the CID parameter is optional and has a default value of 0. + // So when the CID parameter is not specified or specified as 0 in the text device node. // Set the CID to 0 in the ACPI extension device path structure. // if ((*CIDStr == L'\0') || (*CIDStr == L'0')) { diff --git a/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c b/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c index 9f2d2bd9e6..80d2c9cd4e 100644 --- a/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c +++ b/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c @@ -390,7 +390,7 @@ SafeStringContraintCheckTest ( } /** - Initialze the unit test framework, suite, and unit tests for the + Initialize the unit test framework, suite, and unit tests for the Base64 conversion APIs of BaseLib and run the unit tests. @retval EFI_SUCCESS All test cases were dispatched. -- cgit From 1f6dbab8d9d3b364cf873a5a04531ee4c2cbd637 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 10:00:30 -0600 Subject: RedfishPkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in RedfishPkg. Signed-off-by: Rebecca Cran --- RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c | 8 ++++---- RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c | 2 +- RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c index 741a8c1e93..e601bb633d 100644 --- a/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c @@ -660,7 +660,7 @@ RestExHttpCallback ( then a new handle is created. If it is a pointer to an existing UEFI handle, then the protocol is added to the existing UEFI handle. - @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_SUCCESS The protocol was added to ChildHandle. @retval EFI_INVALID_PARAMETER ChildHandle is NULL. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create the child @@ -762,7 +762,7 @@ RedfishRestExServiceBindingCreateChild ( goto ON_ERROR; } - // Initial HTTP callback funciton on this REST EX instance + // Initial HTTP callback function on this REST EX instance Instance->HttpCallbakFunction.Callback = RestExHttpCallback; Status = gBS->InstallProtocolInterface ( &Instance->HttpIo.Handle, @@ -771,7 +771,7 @@ RedfishRestExServiceBindingCreateChild ( &Instance->HttpCallbakFunction ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: Fail to install HttpCallbakFunction.\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a: Fail to install HttpCallbackFunction.\n", __func__)); goto ON_ERROR; } @@ -803,7 +803,7 @@ ON_ERROR: @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. @param[in] ChildHandle Handle of the child to destroy - @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_SUCCESS The protocol was removed from ChildHandle. @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. @retval EFI_INVALID_PARAMETER Child handle is NULL. @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c index b2961424de..0b38c1f0a6 100644 --- a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c @@ -110,7 +110,7 @@ RedfishCheckHttpReceiveStatus ( if the write to URL is permitted by Redfish service. This function checks if the HTTP request has Content-length in HTTP header. If yes, set HTTP body to NULL and then send to service. Check the HTTP status - for the firther actions. + for the further actions. @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular REST service. diff --git a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c index 0da5132e5a..fba634f687 100644 --- a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c +++ b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c @@ -373,7 +373,7 @@ InterpreterInstanceDestoryJsonStruct ( Status = EFI_UNSUPPORTED; // - // Check if the namesapce and version is supported by this interpreter. + // Check if the namespace and version is supported by this interpreter. // ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { -- cgit From 669c5aa240f6675c93a275dd45a1b8fccd351519 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 10:00:54 -0600 Subject: UefiPayloadPkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in UefiPayloadPkg. Signed-off-by: Rebecca Cran --- UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c | 2 +- UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c | 2 +- UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c | 6 +++--- UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c | 2 +- UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c index de33d49bd1..8566618511 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c @@ -132,7 +132,7 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { Install Pei Load File PPI. @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. - @retval EFI_SUCESS The entry point executes successfully. + @retval EFI_SUCCESS The entry point executes successfully. @retval Others Some error occurs during the execution of this function. **/ EFI_STATUS diff --git a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c index 9f9d3c13e1..219a86cfbc 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c +++ b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c @@ -173,7 +173,7 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. - @retval EFI_SUCESS The entry point executes successfully. + @retval EFI_SUCCESS The entry point executes successfully. @retval Others Some error occurs during the execution of this function. **/ diff --git a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c index 7fc589303e..8a076e16e6 100644 --- a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c +++ b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c @@ -25,7 +25,7 @@ LIST_ENTRY mSmmSwDispatch2Queue = INITIALIZE_LIST_HEAD_VARIABLE (mSmm /** Find SmmSwDispatch2Context by SwSmiInputValue. - @param[in] SwSmiInputValue The value to indentify the SmmSwDispatch2 context + @param[in] SwSmiInputValue The value to identify the SmmSwDispatch2 context @return Pointer to EFI_SMM_SW_DISPATCH2_CONTEXT context **/ @@ -51,7 +51,7 @@ FindContextBySwSmiInputValue ( /** Find SmmSwDispatch2Context by DispatchHandle. - @param DispatchHandle The handle to indentify the SmmSwDispatch2 context + @param DispatchHandle The handle to identify the SmmSwDispatch2 context @return Pointer to EFI_SMM_SW_DISPATCH2_CONTEXT context **/ @@ -178,7 +178,7 @@ End: /** Check the SwSmiInputValue is already used -@param[in] SwSmiInputValue To indentify the SmmSwDispatch2 context +@param[in] SwSmiInputValue To identify the SmmSwDispatch2 context @retval EFI_SUCCESS SwSmiInputValue could be used. @retval EFI_INVALID_PARAMETER SwSmiInputValue is already be used. diff --git a/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c b/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c index 748728981a..24ee43aeec 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c +++ b/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c @@ -13,7 +13,7 @@ Find the board related info from ACPI table @param AcpiTableBase ACPI table start address in memory - @param AcpiBoardInfo Pointer to the acpi board info strucutre + @param AcpiBoardInfo Pointer to the acpi board info structure @retval RETURN_SUCCESS Successfully find out all the required information. @retval RETURN_NOT_FOUND Failed to find the required info. diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c index 83936ae26e..9a65b7dbfe 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c +++ b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c @@ -39,7 +39,7 @@ AllocatePages ( return NULL; } - // Make sure allocation address is page alligned. + // Make sure allocation address is page aligned. Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK; if (Offset != 0) { HobTable->EfiFreeMemoryTop -= Offset; -- cgit From c26490ea29f47ca059183d9447ac23b3b463d9d4 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 10:01:32 -0600 Subject: EmbeddedPkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in EmbeddedPkg. Signed-off-by: Rebecca Cran --- EmbeddedPkg/EmbeddedPkg.dsc | 2 +- EmbeddedPkg/GdbStub/SerialIo.c | 2 +- EmbeddedPkg/Include/libfdt.h | 2 +- EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index e89bfae72c..67034dd7dc 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -171,7 +171,7 @@ gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0 # -# Optinal feature to help prevent EFI memory map fragments +# Optional feature to help prevent EFI memory map fragments # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob # Values are in EFI Pages (4K). DXE Core will make sure that # at least this much of each type of memory can be allocated diff --git a/EmbeddedPkg/GdbStub/SerialIo.c b/EmbeddedPkg/GdbStub/SerialIo.c index 98ea611e8b..fdc9e2d75f 100644 --- a/EmbeddedPkg/GdbStub/SerialIo.c +++ b/EmbeddedPkg/GdbStub/SerialIo.c @@ -457,7 +457,7 @@ GDB_SERIAL_DEV gdbSerialDevTemplate = { 0, // ControlMask 0, // Timeout 0, // BaudRate - 1, // RceiveFifoDepth + 1, // ReceiveFifoDepth 0, // DataBits 0, // Parity 0 // StopBits diff --git a/EmbeddedPkg/Include/libfdt.h b/EmbeddedPkg/Include/libfdt.h index 6105b9c075..a2db686629 100644 --- a/EmbeddedPkg/Include/libfdt.h +++ b/EmbeddedPkg/Include/libfdt.h @@ -2311,7 +2311,7 @@ fdt_del_node ( * returns: * 0, on success * -FDT_ERR_NOSPACE, there's not enough space in the base device tree - * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or + * -FDT_ERR_NOTFOUND, the overlay points to some nonexistant nodes or * properties in the base DT * -FDT_ERR_BADPHANDLE, * -FDT_ERR_BADOVERLAY, diff --git a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c index ce288d719f..f066b1f7e1 100644 --- a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c +++ b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c @@ -2,7 +2,7 @@ * * Implement virtual EFI RealTimeClock runtime services. * - * Coypright (c) 2019, Pete Batard + * Copyright (c) 2019, Pete Batard * Copyright (c) 2018, Andrei Warkentin * Copyright (c) 2011-2021, ARM Ltd. All rights reserved. * Copyright (c) 2008-2010, Apple Inc. All rights reserved. -- cgit From bbee1cc852fa8676ed0b530b1c67c92f32f4f740 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 30 Jul 2024 10:02:01 -0600 Subject: DynamicTablesPkg: Fix some spelling mistakes found by cspell When cspell is installed (via `npm install cspell`), CI checks for spelling mistakes. There are currently a very large number of them: some are genuine mistakes while others are words or acryonyms that cspell doesn't know. Fix a few of the misspellings in DynamicTablesPkg. Signed-off-by: Rebecca Cran --- DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c | 2 +- DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c index d3a51a94c7..3762441c7a 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c @@ -330,7 +330,7 @@ AmlParseString ( StrSize = 0; // AML String is NULL terminated. do { - // Reading the stream moves the stream forward aswell. + // Reading the stream moves the stream forward as well. Status = AmlStreamReadByte (FStream, &Byte); if (EFI_ERROR (Status)) { ASSERT (0); diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c index 1404a2182b..0a744f1ff3 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c @@ -573,7 +573,7 @@ AmlIsMethodDefinitionNode ( { AML_DATA_NODE *ObjectType; - // Node is checked to be an object node aswell. + // Node is checked to be an object node as well. if (AmlNodeCompareOpCode (Node, AML_METHOD_OP, 0)) { return TRUE; } else if (AmlNodeCompareOpCode (Node, AML_EXTERNAL_OP, 0)) { -- cgit From 9d8a5fbd0ca7ed563544e71d2dbdd23b0a3f53e3 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Fri, 12 Jul 2024 16:05:02 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Enable single step after SmmProfile start There is a bug in the existing code: the single step is always enabled once the Page Fault (#PF) occurs, but it is only disabled when the SMM Profile feature actually starts (see DebugExceptionHandler). If the SMM Profile feature has not been started, this will result in the single-step mode remaining enabled if a Page Fault occurs. This patch is to enable the single-step debugging mode by setting the Trap Flag only after SmmProfile feature starts. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 10 +++++----- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 5c0f9b4a3f..d54c4c180a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -759,6 +759,11 @@ SmmProfileStart ( // The flag indicates SMM profile starts to work. // mSmmProfileStart = TRUE; + + // + // Tell #PF handler to prepare a #DB subsequently. + // + mSetupDebugTrap = TRUE; } /** @@ -1146,11 +1151,6 @@ InitSmmProfile ( // Initialize profile IDT. // InitIdtr (); - - // - // Tell #PF handler to prepare a #DB subsequently. - // - mSetupDebugTrap = TRUE; } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm index f329a988f8..cddc55fca5 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm @@ -13,6 +13,7 @@ ;------------------------------------------------------------------------------- extern ASM_PFX(SmiPFHandler) +extern ASM_PFX(mSetupDebugTrap) global ASM_PFX(gcSmiIdtr) global ASM_PFX(gcSmiGdtr) @@ -369,9 +370,14 @@ ASM_PFX(PageFaultIdtHandlerSmmProfile): mov rsp, rbp +; Check if mSetupDebugTrap is TRUE (non-zero) + cmp byte [dword ASM_PFX(mSetupDebugTrap)], 0 + jz SkipSettingTF + ; Enable TF bit after page fault handler runs bts dword [rsp + 40], 8 ;RFLAGS +SkipSettingTF: pop rbp add rsp, 16 ; skip INT# & ErrCode iretq -- cgit From f73b97fe7f3ff12f021ea786235ec25d69d8c23c Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 15 Jul 2024 10:16:12 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Check PDE entry exist or not before use Before the commit 701b5797 & 4ceefd6d, 2MB-page will be created to cover [0: 4G] by default if SmmProfile enabled, and it will be go through to change 2MB-page into 4KB-page during page table update (InitPaging). If so, there was no problem to assert PDE entry exist in the RestorePageTableBelow4G. But after above commits, PageTableMap API is used to create/update the page table, 1G-page will be the default page table mode, and only covers the limited address range. Those not covered ranges will be marked as non-present in 1g-page level address. If so, 2M-page address might not exist, it's incorrect to assert PDE entry exist in the RestorePageTableBelow4G. The correct behavior should check PDE entry exist or not, if not, PDE should be allocated and assigned to PDPTE. Note: RestorePageTableBelow4G () does not use 1G page size entries for the creation of new pages, maintaining consistency with the behavior of the original code. The purpose of this patch is to ensure that a Page Directory Entry (PDE) exists prior to its usage. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 18 +++++++++++++++++- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 22 +++++++++++++++++++--- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h | 13 ++++++++++++- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index b11264ce4a..5c00c0fa8c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -1,7 +1,7 @@ /** @file Page table manipulation functions for IA-32 processors -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -66,6 +66,22 @@ SmmInitPageTable ( return GenSmmPageTable (PagingPae, mPhysicalAddressBits); } +/** + Allocate free Page for PageFault handler use. + + @return Page address. + +**/ +UINT64 +AllocPage ( + VOID + ) +{ + CpuDeadLoop (); + + return 0; +} + /** Page Fault handler for SMM use. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index d54c4c180a..9d8a9dc575 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1202,6 +1202,21 @@ RestorePageTableBelow4G ( // PDPTE // PTIndex = (UINTN)BitFieldRead64 (PFAddress, 30, 38); + + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + // + // For 32-bit case, because a full map page table for 0-4G is created by default, + // and since the PDPTE must be one non-leaf entry, the PDPTE must always be present. + // So, ASSERT it must be the 64-bit case running here. + // + ASSERT (sizeof (UINT64) == sizeof (UINTN)); + + // + // If the entry is not present, allocate one page from page pool for it + // + PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + ASSERT (PageTable[PTIndex] != 0); PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); @@ -1209,9 +1224,9 @@ RestorePageTableBelow4G ( // PD // PTIndex = (UINTN)BitFieldRead64 (PFAddress, 21, 29); - if ((PageTable[PTIndex] & IA32_PG_PS) != 0) { + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { // - // Large page + // A 2M page size will be used directly when the 2M entry is marked as non-present. // // @@ -1238,7 +1253,8 @@ RestorePageTableBelow4G ( } } else { // - // Small page + // If the 2M entry is marked as present, a 4K page size will be utilized. + // In this scenario, the 2M entry must be a non-leaf entry. // ASSERT (PageTable[PTIndex] != 0); PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index 964dd52817..760d76a48d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -1,7 +1,7 @@ /** @file SMM profile internal header file. -Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2020, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -142,6 +142,17 @@ IsAddressValid ( IN BOOLEAN *Nx ); +/** + Allocate free Page for PageFault handler use. + + @return Page address. + +**/ +UINT64 +AllocPage ( + VOID + ); + /** Page Fault handler for SMM use. -- cgit From 24f8b97a9d5b5189dd0e2acf96b4920f54ddcb7d Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 15 Jul 2024 11:56:43 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Remove assert check for PDE entry not exist If 2MB-page is selected, PDE entry might exist, it's incorrect to assert it's not exist. Detailed see blow case analysis (it's similar case if address exceeds 4G): Assume the Default Page table has covered below 6M size range: [0000000000001000, 0000000000601000) Then, with PageTableMap API, below Page table entry will be created if 1G-page or 2M-page mode is selected: [0000000000001000, 0000000000002000) --> 4K [0000000000002000, 0000000000003000) --> 4K ... [00000000001FF000, 0000000000200000) --> 4k [0000000000200000, 0000000000400000) --> 2M [0000000000400000, 0000000000600000) --> 2M [0000000000600000, 0000000000601000) --> 4K Above will cover 2M aligned address (0000000000600000) in page table. If Page Fault happen by accessing 0000000000602000, need create the page entry: [0000000000602000, 0000000000603000) --> 4K But PDE entry has been created/existed in page table with 0 PS bit. So, this patch removes the assert check. The page table entry created will be the platform-specified PageSize granularity. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 5964884762..556e9f320e 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -823,15 +823,6 @@ SmiDefaultPFHandler ( } PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); - if ((PageTable[PTIndex] & IA32_PG_P) != 0) { - // - // Check if the entry has already existed, this issue may occur when the different - // size page entries created under the same entry - // - DEBUG ((DEBUG_ERROR, "PageTable = %lx, PTIndex = %x, PageTable[PTIndex] = %lx\n", PageTable, PTIndex, PageTable[PTIndex])); - DEBUG ((DEBUG_ERROR, "New page table overlapped with old page table!\n")); - ASSERT (FALSE); - } // // Fill the new entry -- cgit From 87d3a6272ca8637787813256c1a2435e89e326e2 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Mon, 15 Jul 2024 11:39:48 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Iterate page table to find proper entry Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met: 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity. 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 45 +++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 556e9f320e..9052ea8e84 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -799,27 +799,40 @@ SmiDefaultPFHandler ( for (Index = 0; Index < NumOfPages; Index++) { PageTable = PageTableTop; UpperEntry = NULL; - for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > EndBit; StartBit -= 9) { + for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) { PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); - if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + + // + // Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met: + // 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity. + // 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry. + // + if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) { + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + // + // If the entry is not present, allocate one page from page pool for it + // + PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } else { + // + // Save the upper entry address + // + UpperEntry = PageTable + PTIndex; + } + // - // If the entry is not present, allocate one page from page pool for it + // BIT9 to BIT11 of entry is used to save access record, + // initialize value is 7 // - PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + PageTable[PTIndex] |= (UINT64)IA32_PG_A; + SetAccNum (PageTable + PTIndex, 7); + PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask); } else { // - // Save the upper entry address + // Found the appropriate entry. // - UpperEntry = PageTable + PTIndex; + break; } - - // - // BIT9 to BIT11 of entry is used to save access record, - // initialize value is 7 - // - PageTable[PTIndex] |= (UINT64)IA32_PG_A; - SetAccNum (PageTable + PTIndex, 7); - PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask); } PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); @@ -827,7 +840,7 @@ SmiDefaultPFHandler ( // // Fill the new entry // - PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << EndBit) - 1)) | + PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) | PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS; if (UpperEntry != NULL) { SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF); @@ -836,7 +849,7 @@ SmiDefaultPFHandler ( // // Get the next page address if we need to create more page tables // - PFAddress += (1ull << EndBit); + PFAddress += (1ull << StartBit); } } -- cgit From 967cbd87b7a1ebf01c12627f6099e785099bf85c Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Wed, 31 Jul 2024 10:51:52 +0000 Subject: DynamicTablesPkg: Adds X64 namespace object REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4781 Adds empty X64 namespace object for future use. Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: Abdul Lateef Attar --- .../Include/ConfigurationManagerObject.h | 15 +++++++++++++ DynamicTablesPkg/Include/X64NameSpaceObjects.h | 26 ++++++++++++++++++++++ .../ConfigurationManagerObjectParser.c | 24 ++++++++++++++++++++ DynamicTablesPkg/Readme.md | 7 ++++++ 4 files changed, 72 insertions(+) create mode 100644 DynamicTablesPkg/Include/X64NameSpaceObjects.h diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h index dd730ca677..26605229d3 100644 --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h @@ -1,12 +1,14 @@ /** @file Copyright (c) 2017 - 2024, Arm Limited. All rights reserved. + Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Glossary: - Cm or CM - Configuration Manager - Obj or OBJ - Object + - X64 or x64 - X64 Architecture **/ #ifndef CONFIGURATION_MANAGER_OBJECT_H_ @@ -15,6 +17,7 @@ #include #include #include +#include #pragma pack(1) @@ -32,6 +35,7 @@ Bits: [31:28] - Name Space ID 0000 - Standard 0001 - Arch Common 0010 - ARM + 0011 - X64 1111 - Custom/OEM All other values are reserved. @@ -83,6 +87,7 @@ typedef enum ObjectNameSpaceID { EObjNameSpaceStandard, ///< Standard Objects Namespace EObjNameSpaceArchCommon, ///< Arch Common Objects Namespace EObjNameSpaceArm, ///< ARM Objects Namespace + EObjNameSpaceX64, ///< X64 Objects Namespace EObjNameSpaceOem = 0xF, ///< OEM Objects Namespace EObjNameSpaceMax, } EOBJECT_NAMESPACE_ID; @@ -178,4 +183,14 @@ typedef struct CmObjDescriptor { #define CREATE_CM_OEM_OBJECT_ID(ObjectId) \ (CREATE_CM_OBJECT_ID (EObjNameSpaceOem, ObjectId)) +/** This macro returns a Configuration Manager Object ID + in the X64 Object Namespace. + + @param [in] ObjectId The Object ID. + + @retval Returns X64 Configuration Manager Object ID. +**/ +#define CREATE_CM_X64_OBJECT_ID(ObjectId) \ + (CREATE_CM_OBJECT_ID (EObjNameSpaceX64, ObjectId)) + #endif // CONFIGURATION_MANAGER_OBJECT_H_ diff --git a/DynamicTablesPkg/Include/X64NameSpaceObjects.h b/DynamicTablesPkg/Include/X64NameSpaceObjects.h new file mode 100644 index 0000000000..f9f131e822 --- /dev/null +++ b/DynamicTablesPkg/Include/X64NameSpaceObjects.h @@ -0,0 +1,26 @@ +/** @file + + Defines the X64 Namespace Object. + + Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object + - X64 or x64 - X64 Architecture +**/ + +#ifndef X64_NAMESPACE_OBJECTS_H_ +#define X64_NAMESPACE_OBJECTS_H_ + +/** The EX64_OBJECT_ID enum describes the Object IDs + in the X64 Namespace +*/ +typedef enum X64ObjectID { + EX64ObjReserved, ///< 0 - Reserved + EX64ObjMax +} EX64_OBJECT_ID; + +#endif // X64_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index e726b2c616..ccd681fb91 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -2,6 +2,7 @@ Configuration Manager Object parser. Copyright (c) 2021 - 2023, ARM Limited. All rights reserved.
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -729,6 +730,13 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax) }; +/** A parser for X64 namespace objects. +*/ +STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { + CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjReserved), + CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjMax) +}; + /** A parser for EStdObjCfgMgrInfo. */ STATIC CONST CM_OBJ_PARSER StdObjCfgMgrInfoParser[] = { @@ -1070,6 +1078,22 @@ ParseCmObjDesc ( ParserArray = &ArchCommonNamespaceObjectParser[ObjId]; break; + + case EObjNameSpaceX64: + if (ObjId >= EX64ObjMax) { + ASSERT (0); + return; + } + + if (ObjId >= ARRAY_SIZE (X64NamespaceObjectParser)) { + DEBUG ((DEBUG_ERROR, "ObjId 0x%x is missing from the X64NamespaceObjectParser array\n", ObjId)); + ASSERT (0); + return; + } + + ParserArray = &X64NamespaceObjectParser[ObjId]; + break; + default: // Not supported DEBUG ((DEBUG_ERROR, "NameSpaceId 0x%x, ObjId 0x%x is not supported by the parser\n", NameSpaceId, ObjId)); diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 7790b14636..eebde70046 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -421,6 +421,7 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 0000b | Standard | | | 0001b | Arch Common | | | 0010b | ARM | | +| 0011b | X64 | | | 1111b | Custom/OEM | | | `*` | All other values are reserved. | | @@ -498,3 +499,9 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 25 | P-State Dependency (PSD) Info | | | `*` | All other values are reserved. | | +#### Object ID's in the X64 Namespace: + +| ID | Description | Comments | +| ---: | :-------------------------- | :--- | +| 0 | Reserved | | +| `*` | All other values are reserved. | | -- cgit From bc0fc7563780191622146593998b355f383041a2 Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Thu, 1 Aug 2024 10:49:20 +0000 Subject: DynamicTablesPkg/AcpiFadtLib: Adds FADT X64 generator REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4781 Updates FADT X64 generator to collect below configuration information and update the table accordingly. - SCI interrupt - SCI command - PM Block - GPE Block - PM Block 64-bit - GPE Block 64-bit - Sleep block - Reset block - Miscellaneous legacy information Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: Abdul Lateef Attar --- DynamicTablesPkg/DynamicTables.dsc.inc | 7 +- DynamicTablesPkg/Include/X64NameSpaceObjects.h | 146 +++++++- .../Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf | 2 +- .../Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c | 47 --- .../Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c | 382 +++++++++++++++++++++ .../ConfigurationManagerObjectParser.c | 119 +++++++ DynamicTablesPkg/Readme.md | 9 + 7 files changed, 662 insertions(+), 50 deletions(-) delete mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index fa68b63ab1..3fdb3e66b2 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -53,7 +53,12 @@ # # Dynamic Table Factory Dxe # - DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf + DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf { + + # Generators + # Common + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf + } [Components.ARM, Components.AARCH64] # diff --git a/DynamicTablesPkg/Include/X64NameSpaceObjects.h b/DynamicTablesPkg/Include/X64NameSpaceObjects.h index f9f131e822..2fa696b4c3 100644 --- a/DynamicTablesPkg/Include/X64NameSpaceObjects.h +++ b/DynamicTablesPkg/Include/X64NameSpaceObjects.h @@ -15,12 +15,156 @@ #ifndef X64_NAMESPACE_OBJECTS_H_ #define X64_NAMESPACE_OBJECTS_H_ +#include + /** The EX64_OBJECT_ID enum describes the Object IDs in the X64 Namespace */ typedef enum X64ObjectID { EX64ObjReserved, ///< 0 - Reserved - EX64ObjMax + EX64ObjFadtSciInterrupt, ///< 1 - FADT SCI Interrupt information + EX64ObjFadtSciCmdInfo, ///< 2 - FADT SCI CMD information + EX64ObjFadtPmBlockInfo, ///< 3 - FADT Power management block info + EX64ObjFadtGpeBlockInfo, ///< 4 - FADT GPE block info + EX64ObjFadtXpmBlockInfo, ///< 5 - FADT 64-bit Power Management block info + EX64ObjFadtXgpeBlockInfo, ///< 6 - FADT 64-bit GPE block info + EX64ObjFadtSleepBlockInfo, ///< 7 - FADT Sleep block info + EX64ObjFadtResetBlockInfo, ///< 8 - FADT Reset block info + EX64ObjFadtMiscInfo, ///< 0 - FADT Legacy fields info + EX64ObjMax ///< 10 - Maximum Object ID } EX64_OBJECT_ID; +/** A structure that describes the + SCI interrupt Information for the Platform. + + ID: EX64ObjFadtSciInterrupt +*/ +typedef struct CmX64FadtSciInterrupt { + /** This is the SCI interrupt field of the FADT Table + described in the ACPI Specification + */ + UINT16 SciInterrupt; +} CM_X64_FADT_SCI_INTERRUPT; + +/** A structure that describes the + SCI CMD Information for the Platform. + + ID: EX64ObjFadtSciCmdInfo +*/ +typedef struct CmX64FadtSciCmdInfo { + /** This is the System control interrupt command information of the FADT Table + described in the ACPI Specification + */ + UINT32 SciCmd; + UINT8 AcpiEnable; + UINT8 AcpiDisable; + UINT8 S4BiosReq; + UINT8 PstateCnt; + UINT8 CstCnt; +} CM_X64_FADT_SCI_CMD_INFO; + +/** A structure that describes the + power management block information. + + ID: EX64ObjFadtPmBlockInfo +*/ +typedef struct CmX64FadtPmBlockInfo { + /** This is the PM event block information of the FADT Table + described in the ACPI Specification + */ + UINT32 Pm1aEvtBlk; + UINT32 Pm1bEvtBlk; + UINT32 Pm1aCntBlk; + UINT32 Pm1bCntBlk; + UINT32 Pm2CntBlk; + UINT32 PmTmrBlk; + UINT8 Pm1EvtLen; + UINT8 Pm1CntLen; + UINT8 Pm2CntLen; + UINT8 PmTmrLen; +} CM_X64_FADT_PM_BLOCK_INFO; + +/** A structure that describes the + GPE block information. + + ID: EX64ObjFadtGpeBlockInfo +*/ +typedef struct CmX64FadtGpeBlockInfo { + /** This is the GPE Block information of the FADT Table + described in the ACPI Specification + */ + UINT32 Gpe0Blk; + UINT32 Gpe1Blk; + UINT8 Gpe0BlkLen; + UINT8 Gpe1BlkLen; + UINT8 Gpe1Base; +} CM_X64_FADT_GPE_BLOCK_INFO; + +/** A structure that describes the + 64bit power management block information. + + ID: EX64ObjFadtXpmBlockInfo +*/ +typedef struct CmX64FadtXpmBlockInfo { + /** This is the System control interrupt command information of the FADT Table + described in the ACPI Specification + */ + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; +} CM_X64_FADT_X_PM_BLOCK_INFO; + +/** A structure that describes the + 64-bit GPE block information. + + ID: EX64ObjFadtXgpeBlockInfo +*/ +typedef struct CmX64FadtXgpeBlockInfo { + /** This is the GPE Block information of the FADT Table + described in the ACPI Specification + */ + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; +} CM_X64_FADT_X_GPE_BLOCK_INFO; + +/** A structure that describes the + sleep control block information. + + ID: EX64ObjFadtSleepBlockInfo +*/ +typedef struct CmX64FadtSleepBlockInfo { + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepControlReg; + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; +} CM_X64_FADT_SLEEP_BLOCK_INFO; + +/** A structure that describes the + Reset control block information. + + ID: EX64ObjFadtResetBlockInfo +*/ +typedef struct CmX64FadtResetBlockInfo { + EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg; + UINT8 ResetValue; +} CM_X64_FADT_RESET_BLOCK_INFO; + +/** A structure that describes the + miscellaneous FADT fields information. + + ID: EX64ObjFadtMiscInfo +*/ +typedef struct CmX64FadtFadtMiscInfo { + UINT16 PLvl2Lat; + UINT16 PLvl3Lat; + UINT16 FlushSize; + UINT16 FlushStride; + UINT8 DutyOffset; + UINT8 DutyWidth; + UINT8 DayAlrm; + UINT8 MonAlrm; + UINT8 Century; +} CM_X64_FADT_MISC_INFO; + #endif // X64_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf index 67c7fdbd23..b4b899ca17 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf @@ -24,7 +24,7 @@ Arm/ArmFadtGenerator.c [Sources.IA32, Sources.X64] - FadtGeneratorNull.c + X64/X64FadtGenerator.c [Packages] MdePkg/MdePkg.dec diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c deleted file mode 100644 index 7868aae742..0000000000 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGeneratorNull.c +++ /dev/null @@ -1,47 +0,0 @@ -/** @file - Common FADT Table Helpers - - Copyright (c) 2017 - 2023, Arm Limited. All rights reserved. - SPDX-License-Identifier: BSD-2-Clause-Patent - - @par Reference(s): - - ACPI 6.5 Specification, Aug 29, 2022 - -**/ - -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include "FadtGenerator.h" - -/** Updates the Architecture specific information in the FADT Table. - - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in, out] Fadt Pointer to the constructed ACPI Table. - - @retval EFI_SUCCESS Success. - @retval EFI_UNSUPPORTED Unsupported. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND The required object was not found. - @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration - Manager is less than the Object size for the - requested object. -**/ -EFI_STATUS -EFIAPI -FadtArchUpdate ( - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt - ) -{ - // Not implemented. - return EFI_UNSUPPORTED; -} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c new file mode 100644 index 0000000000..113894183d --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c @@ -0,0 +1,382 @@ +/** @file + X64 FADT Table Helpers + + Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification, Aug 29, 2022 + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include "FadtGenerator.h" + +/** This macro expands to a function that retrieves the + SCI interrupt information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtSciInterrupt, + CM_X64_FADT_SCI_INTERRUPT + ); + +/** This macro expands to a function that retrieves the + SCI command information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtSciCmdInfo, + CM_X64_FADT_SCI_CMD_INFO + ); + +/** This macro expands to a function that retrieves the + legacy power management information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtPmBlockInfo, + CM_X64_FADT_PM_BLOCK_INFO + ); + +/** This macro expands to a function that retrieves the + legacy GPE block information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtGpeBlockInfo, + CM_X64_FADT_GPE_BLOCK_INFO + ); + +/** This macro expands to a function that retrieves the + legacy level2 latency, level 3 latency, RTC information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtMiscInfo, + CM_X64_FADT_MISC_INFO + ); + +/** This macro expands to a function that retrieves the + 64-bit power management information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtXpmBlockInfo, + CM_X64_FADT_X_PM_BLOCK_INFO + ); + +/** This macro expands to a function that retrieves the + 64-bit GPE block information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtXgpeBlockInfo, + CM_X64_FADT_X_GPE_BLOCK_INFO + ); + +/** This macro expands to a function that retrieves the + sleep block information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtSleepBlockInfo, + CM_X64_FADT_SLEEP_BLOCK_INFO + ); + +/** This macro expands to a function that retrieves the + reset block information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceX64, + EX64ObjFadtResetBlockInfo, + CM_X64_FADT_RESET_BLOCK_INFO + ); + +/** Updates the Architecture specific information in the FADT Table. + + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Fadt Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +FadtArchUpdate ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt + ) +{ + EFI_STATUS Status; + CM_X64_FADT_SCI_INTERRUPT *SciInterrupt; + CM_X64_FADT_SCI_CMD_INFO *SciCmdinfo; + CM_X64_FADT_PM_BLOCK_INFO *PmBlockInfo; + CM_X64_FADT_GPE_BLOCK_INFO *GpeBlockInfo; + CM_X64_FADT_X_PM_BLOCK_INFO *XpmBlockInfo; + CM_X64_FADT_X_GPE_BLOCK_INFO *XgpeBlockInfo; + CM_X64_FADT_SLEEP_BLOCK_INFO *SleepBlockInfo; + CM_X64_FADT_RESET_BLOCK_INFO *ResetBlockInfo; + CM_X64_FADT_MISC_INFO *FadtMiscInfo; + + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Fadt != NULL); + + // Get the SCI interrupt from the Platform Configuration Manager + Status = GetEX64ObjFadtSciInterrupt ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SciInterrupt, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get SCI Interrupt information." \ + " Status = %r\n", + Status + )); + } else { + Fadt->SciInt = SciInterrupt->SciInterrupt; + } + + // Get the SCI CMD information from the Platform Configuration Manager + Status = GetEX64ObjFadtSciCmdInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SciCmdinfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get SCI CMD information." \ + " Status = %r\n", + Status + )); + } else { + Fadt->SmiCmd = SciCmdinfo->SciCmd; + Fadt->AcpiEnable = SciCmdinfo->AcpiEnable; + Fadt->AcpiDisable = SciCmdinfo->AcpiDisable; + Fadt->S4BiosReq = SciCmdinfo->S4BiosReq; + Fadt->PstateCnt = SciCmdinfo->PstateCnt; + Fadt->CstCnt = SciCmdinfo->CstCnt; + } + + // Get the SCI PM Block information from the Platform Configuration Manager + Status = GetEX64ObjFadtPmBlockInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &PmBlockInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get PM Block information." \ + " Status = %r\n", + Status + )); + } else { + Fadt->Pm1aEvtBlk = PmBlockInfo->Pm1aEvtBlk; + Fadt->Pm1bEvtBlk = PmBlockInfo->Pm1bEvtBlk; + Fadt->Pm1aCntBlk = PmBlockInfo->Pm1aCntBlk; + Fadt->Pm1bCntBlk = PmBlockInfo->Pm1bCntBlk; + Fadt->Pm2CntBlk = PmBlockInfo->Pm2CntBlk; + Fadt->PmTmrBlk = PmBlockInfo->PmTmrBlk; + Fadt->Pm1EvtLen = PmBlockInfo->Pm1EvtLen; + Fadt->Pm1CntLen = PmBlockInfo->Pm1CntLen; + Fadt->Pm2CntLen = PmBlockInfo->Pm2CntLen; + Fadt->PmTmrLen = PmBlockInfo->PmTmrLen; + } + + // Get the SCI PM Block information from the Platform Configuration Manager + Status = GetEX64ObjFadtGpeBlockInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &GpeBlockInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get PM Block information." \ + " Status = %r\n", + Status + )); + } else { + Fadt->Gpe0Blk = GpeBlockInfo->Gpe0Blk; + Fadt->Gpe1Blk = GpeBlockInfo->Gpe1Blk; + Fadt->Gpe0BlkLen = GpeBlockInfo->Gpe0BlkLen; + Fadt->Gpe1BlkLen = GpeBlockInfo->Gpe1BlkLen; + Fadt->Gpe1Base = GpeBlockInfo->Gpe1Base; + } + + // Get the 64-bit PM Block information from the Platform Configuration Manager + Status = GetEX64ObjFadtXpmBlockInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &XpmBlockInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get 64-bit PM Block information." \ + " Status = %r\n", + Status + )); + } else { + CopyMem ( + &Fadt->XPm1aCntBlk, + &XpmBlockInfo->XPm1aCntBlk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->XPm1bEvtBlk, + &XpmBlockInfo->XPm1bEvtBlk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->XPm1aCntBlk, + &XpmBlockInfo->XPm1aCntBlk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->XPm1bCntBlk, + &XpmBlockInfo->XPm1bCntBlk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->XPm2CntBlk, + &XpmBlockInfo->XPm2CntBlk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->XPmTmrBlk, + &XpmBlockInfo->XPmTmrBlk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + } + + // Get the various platform information from the Platform Configuration manager + Status = GetEX64ObjFadtMiscInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &FadtMiscInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get various platform information." \ + " Status = %r\n", + Status + )); + } else { + Fadt->PLvl2Lat = FadtMiscInfo->PLvl2Lat; + Fadt->PLvl3Lat = FadtMiscInfo->PLvl3Lat; + Fadt->FlushSize = FadtMiscInfo->FlushSize; + Fadt->FlushStride = FadtMiscInfo->FlushStride; + Fadt->DutyOffset = FadtMiscInfo->DutyOffset; + Fadt->DutyWidth = FadtMiscInfo->DutyWidth; + Fadt->DayAlrm = FadtMiscInfo->DayAlrm; + Fadt->MonAlrm = FadtMiscInfo->MonAlrm; + Fadt->Century = FadtMiscInfo->Century; + } + + // Get the 64-bit GPE Block information from the Platform Configuration Manager + Status = GetEX64ObjFadtXgpeBlockInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &XgpeBlockInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get 64-bit GPE Block information." \ + " Status = %r\n", + Status + )); + } else { + CopyMem ( + &Fadt->XGpe0Blk, + &XgpeBlockInfo->XGpe0Blk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->XGpe1Blk, + &XgpeBlockInfo->XGpe1Blk, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + } + + // Get the sleep Block information from the Platform Configuration Manager + Status = GetEX64ObjFadtSleepBlockInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SleepBlockInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Sleep Block information." \ + " Status = %r\n", + Status + )); + } else { + CopyMem ( + &Fadt->SleepControlReg, + &SleepBlockInfo->SleepControlReg, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + CopyMem ( + &Fadt->SleepStatusReg, + &SleepBlockInfo->SleepStatusReg, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + } + + // Get the sleep Block information from the Platform Configuration Manager + Status = GetEX64ObjFadtResetBlockInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &ResetBlockInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: FADT: Failed to get Reset Block information." \ + " Status = %r\n", + Status + )); + } else { + CopyMem ( + &Fadt->ResetReg, + &ResetBlockInfo->ResetReg, + sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE) + ); + Fadt->ResetValue = ResetBlockInfo->ResetValue; + } + + return Status; +} diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index ccd681fb91..96d02821e3 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -730,10 +730,129 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax) }; +/** A parser for EX64ObjFadtSciInterrupt. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtSciInterruptParser[] = { + { "SciInterrupt", 2, "0x%x", NULL } +}; + +/** A parser for EX64ObjFadtSciCmdInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtSciCmdInfoParser[] = { + { "SciCmd", 4, "0x%x", NULL }, + { "AcpiEnable", 1, "0x%x", NULL }, + { "AcpiDisable", 1, "0x%x", NULL }, + { "S4BiosReq", 1, "0x%x", NULL }, + { "PstateCnt", 1, "0x%x", NULL }, + { "CstCnt", 1, "0x%x", NULL } +}; + +/** A parser for EX64ObjFadtPmBlockInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtPmBlockInfoParser[] = { + { "Pm1aEvtBlk", 4, "0x%x", NULL }, + { "Pm1bEvtBlk", 4, "0x%x", NULL }, + { "Pm1aCntBlk", 4, "0x%x", NULL }, + { "Pm1bCntBlk", 4, "0x%x", NULL }, + { "Pm2CntBlk", 4, "0x%x", NULL }, + { "PmTmrBlk", 4, "0x%x", NULL }, + { "Pm1EvtLen", 1, "0x%x", NULL }, + { "Pm1CntLen", 1, "0x%x", NULL }, + { "Pm2CntLen", 1, "0x%x", NULL }, + { "PmTmrLen", 1, "0x%x", NULL } +}; + +/** A parser for EX64ObjFadtGpeBlockInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtGpeBlockInfoParser[] = { + { "Gpe0Blk", 4, "0x%x", NULL }, + { "Gpe1Blk", 4, "0x%x", NULL }, + { "Gpe0BlkLen", 1, "0x%x", NULL }, + { "Gpe1BlkLen", 1, "0x%x", NULL }, + { "Gpe1Base", 1, "0x%x", NULL } +}; + +/** A parser for EX64ObjFadtXpmBlockInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtXpmBlockInfoParser[] = { + { "XPm1aEvtBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "XPm1bEvtBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "XPm1aCntBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "XPm1bCntBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "XPm2CntBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "XPmTmrBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) } +}; + +/** A parser for EX64ObjFadtXgpeBlockInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtXgpeBlockInfoParser[] = { + { "XGpe0Blk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "XGpe1Blk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) } +}; + +/** A parser for EX64ObjFadtSleepBlockInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtSleepBlockInfoParser[] = { + { "SleepControlReg", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "SleepStatusReg", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) } +}; + +/** A parser for EX64ObjFadtResetBlockInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtResetBlockInfoParser[] = { + { "ResetReg", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE), + NULL, NULL, AcpiGenericAddressParser, + ARRAY_SIZE (AcpiGenericAddressParser) }, + { "ResetValue", 1, "0x%x",NULL } +}; + +/** A parser for EX64ObjFadtMiscInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmX64ObjFadtMiscInfoParser[] = { + { "PLvl2Lat", 2, "0x%x", NULL }, + { "PLvl3Lat", 2, "0x%x", NULL }, + { "FlushSize", 2, "0x%x", NULL }, + { "FlushStride", 2, "0x%x", NULL }, + { "DutyOffset", 1, "0x%x", NULL }, + { "DutyWidth", 1, "0x%x", NULL }, + { "DayAlrm", 1, "0x%x", NULL }, + { "MonAlrm", 1, "0x%x", NULL }, + { "Century", 1, "0x%x", NULL } +}; + /** A parser for X64 namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjReserved), + CM_PARSER_ADD_OBJECT (EX64ObjFadtSciInterrupt, CmX64ObjFadtSciInterruptParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtSciCmdInfo, CmX64ObjFadtSciCmdInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtPmBlockInfo, CmX64ObjFadtPmBlockInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtGpeBlockInfo, CmX64ObjFadtGpeBlockInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtXpmBlockInfo, CmX64ObjFadtXpmBlockInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtXgpeBlockInfo, CmX64ObjFadtXgpeBlockInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtSleepBlockInfo,CmX64ObjFadtSleepBlockInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtResetBlockInfo,CmX64ObjFadtResetBlockInfoParser), + CM_PARSER_ADD_OBJECT (EX64ObjFadtMiscInfo, CmX64ObjFadtMiscInfoParser), CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjMax) }; diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index eebde70046..3b64bc857b 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -504,4 +504,13 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | ID | Description | Comments | | ---: | :-------------------------- | :--- | | 0 | Reserved | | +| 1 | SCI Interrupt Info | | +| 2 | SCI Command Info | | +| 3 | Legacy Power Management Block Info | | +| 4 | Legacy GPE Block Info | | +| 5 | Power Management Block Info | | +| 6 | GPE Block Info | | +| 7 | Sleep Block Info | | +| 8 | Reset Block Info | | +| 9 | Miscellaneous Block Info | | | `*` | All other values are reserved. | | -- cgit From 4f5de749cb2247a4ead21523f2d9deb389291636 Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Fri, 2 Aug 2024 04:01:16 +0000 Subject: DynamicTablesPkg/DynamicTableManagerDxe: Adds X64 GetAcpiTablePresenceInfo Adds X64 specific GetAcpiTablePresenceInfo() function, which checks for mandatory ACPI tables. Cc: Sami Mujawar Cc: Pierre Gondois Signed-off-by: Abdul Lateef Attar --- .../DynamicTableManagerDxe.inf | 3 +- .../DynamicTableManagerNull.c | 59 ---------------------- .../X64/X64DynamicTableManager.c | 56 ++++++++++++++++++++ 3 files changed, 58 insertions(+), 60 deletions(-) delete mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c create mode 100755 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf index 00d03e75be..c982b24c2a 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf @@ -2,6 +2,7 @@ # Module that drives the table generation and installation process. # # Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. +# Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -28,7 +29,7 @@ Arm/ArmDynamicTableManager.c [Sources.IA32, Sources.X64] - DynamicTableManagerNull.c + X64/X64DynamicTableManager.c [Packages] MdePkg/MdePkg.dec diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c deleted file mode 100644 index d9b727468a..0000000000 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerNull.c +++ /dev/null @@ -1,59 +0,0 @@ -/** @file - Common Dynamic Table Manager Dxe - - Copyright (c) 2024, Arm Limited. All rights reserved. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include - -// Module specific include files. -#include -#include -#include -#include -#include -#include -#include -#include "DynamicTableManagerDxe.h" - -/// -/// Array containing the ACPI tables to check. -/// This is a dummy list only existing for build purpose. -/// The FADT table must be placed at index 0. -/// -ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[] = { - { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }, -}; - -/** Get the arch specific ACPI table presence information. - - @param [out] PresenceArray Array containing the ACPI tables to check. - @param [out] PresenceArrayCount Count of elements in the PresenceArray. - @param [out] FadtIndex Index of the FADT table in the PresenceArray. - -1 if absent. - - @retval EFI_SUCCESS Success. - @retval EFI_UNSUPPORTED Unsupported. -**/ -EFI_STATUS -EFIAPI -GetAcpiTablePresenceInfo ( - OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray, - OUT UINT32 *PresenceArrayCount, - OUT INT32 *FadtIndex - ) -{ - // Dummy function - Not Implemented. - *PresenceArray = mAcpiVerifyTables; - *PresenceArrayCount = ARRAY_SIZE (mAcpiVerifyTables); - *FadtIndex = ACPI_TABLE_VERIFY_FADT; - - return EFI_UNSUPPORTED; -} diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c new file mode 100755 index 0000000000..a5457f383d --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c @@ -0,0 +1,56 @@ +/** @file + X64 Dynamic Table Manager Dxe + + Copyright (c) 2024, Arm Limited. All rights reserved. + Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include +#include "DynamicTableManagerDxe.h" + +/// +/// Array containing the ACPI tables to check. +/// +STATIC ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[] = { + { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 } +}; + +/** Get the arch specific ACPI table presence information. + + @param [out] PresenceArray Array containing the ACPI tables to check. + @param [out] PresenceArrayCount Count of elements in the PresenceArray. + @param [out] FadtIndex Index of the FADT table in the PresenceArray. + -1 if absent. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +EFIAPI +GetAcpiTablePresenceInfo ( + OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray, + OUT UINT32 *PresenceArrayCount, + OUT INT32 *FadtIndex + ) +{ + *PresenceArray = mAcpiVerifyTables; + *PresenceArrayCount = ARRAY_SIZE (mAcpiVerifyTables); + *FadtIndex = ACPI_TABLE_VERIFY_FADT; + + return EFI_SUCCESS; +} -- cgit From 66b4a2f91de2206b06a911712cfbbcf793d0f6f9 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 18 Jul 2024 11:18:22 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: clean unused PCD for S3 This patch is to clean the PcdCpuFeaturesInitOnS3Resume since it's unused after commit 077760fe Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 1 - 1 file changed, 1 deletion(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index c64d37e498..2412f4caeb 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -139,7 +139,6 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmShadowStackSize ## SOMETIMES_CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES -- cgit From 8f3e132512b478389c201fa44b41dec0f51ab4bf Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 18 Jul 2024 11:37:09 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Clean redundant SmmS3Cr3 Init The SmmS3Cr3 is only used by S3Resume PEIM to switch CPU from 32bit to 64bit, it should be the CR3 for Non-SMM environment and init by InitSmmS3Cr3 function. No need set to SMM CR3. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 5 +---- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 4 +--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index c37a2d4d1b..37d36daf66 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -187,12 +187,10 @@ SmmRestoreCpu ( /** Initialize SMM S3 resume state structure used during S3 Resume. - @param[in] Cr3 The base address of the page tables to use in SMM. - **/ VOID InitSmmS3ResumeState ( - IN UINT32 Cr3 + VOID ) { VOID *GuidHob; @@ -233,7 +231,6 @@ InitSmmS3ResumeState ( } SmmS3ResumeState->SmmS3Cr0 = (UINT32)AsmReadCr0 (); - SmmS3ResumeState->SmmS3Cr3 = Cr3; SmmS3ResumeState->SmmS3Cr4 = (UINT32)AsmReadCr4 (); if (sizeof (UINTN) == sizeof (UINT64)) { diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 20a1a9cdbc..e7149ff7fd 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -1359,7 +1359,7 @@ PiCpuSmmEntry ( InitSmmProfile (Cr3); GetAcpiS3EnableFlag (); - InitSmmS3ResumeState (Cr3); + InitSmmS3ResumeState (); DEBUG ((DEBUG_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n")); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 8409891b1d..abbdd79f05 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -1045,12 +1045,10 @@ extern BOOLEAN mSmmS3Flag; /** Initialize SMM S3 resume state structure used during S3 Resume. - @param[in] Cr3 The base address of the page tables to use in SMM. - **/ VOID InitSmmS3ResumeState ( - IN UINT32 Cr3 + VOID ); /** -- cgit From 24a375fcdd26ce5a36bde69b92f638420fddf9c8 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 1 Aug 2024 16:59:28 +0800 Subject: UefiCpuPkg/PiSmmCpuDxeSmm: Avoid use global variable in InitSmmS3Cr3 This patch is to avoid use global variable in InitSmmS3Cr3. No function impact. Signed-off-by: Jiaxin Wu --- UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 3 ++- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c | 10 +++++++--- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h | 6 ++++-- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h | 11 +++++------ UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c | 13 +++++++------ UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h | 6 ++++-- 6 files changed, 29 insertions(+), 20 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c index 37d36daf66..caad70ac84 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -243,8 +243,9 @@ InitSmmS3ResumeState ( // // Patch SmmS3ResumeState->SmmS3Cr3 + // The SmmS3Cr3 is only used by S3Resume PEIM to switch CPU from 32bit to 64bit // - InitSmmS3Cr3 (); + InitSmmS3Cr3 ((UINTN *)&SmmS3ResumeState->SmmS3Cr3); } } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c index 650090e534..9021f9cf5d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c @@ -1,7 +1,7 @@ /** @file IA-32 processor specific functions to enable SMM profile. -Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -12,13 +12,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent /** Create SMM page table for S3 path. + @param[out] Cr3 The base address of the page tables. + **/ VOID InitSmmS3Cr3 ( - VOID + OUT UINTN *Cr3 ) { - mSmmS3ResumeState->SmmS3Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits); + ASSERT (Cr3 != NULL); + + *Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits); return; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h index 6c95f2bb19..de4a3a3a25 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h @@ -1,7 +1,7 @@ /** @file IA-32 processor specific header file to enable SMM profile. -Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -73,10 +73,12 @@ RestorePageTableAbove4G ( /** Create SMM page table for S3 path. + @param[out] Cr3 The base address of the page tables. + **/ VOID InitSmmS3Cr3 ( - VOID + OUT UINTN *Cr3 ); /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index 760d76a48d..9b00ea41b3 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -96,12 +96,11 @@ typedef struct { UINT64 SmiCmd; } SMM_PROFILE_ENTRY; -extern SMM_S3_RESUME_STATE *mSmmS3ResumeState; -extern UINTN gSmiExceptionHandlers[]; -extern BOOLEAN mXdSupported; -X86_ASSEMBLY_PATCH_LABEL gPatchXdSupported; -X86_ASSEMBLY_PATCH_LABEL gPatchMsrIa32MiscEnableSupported; -extern UINTN *mPFEntryCount; +extern UINTN gSmiExceptionHandlers[]; +extern BOOLEAN mXdSupported; +X86_ASSEMBLY_PATCH_LABEL gPatchXdSupported; +X86_ASSEMBLY_PATCH_LABEL gPatchMsrIa32MiscEnableSupported; +extern UINTN *mPFEntryCount; extern UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT]; extern UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT]; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c index 01432d466c..8e15c42d99 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c @@ -1,7 +1,7 @@ /** @file X64 processor specific functions to enable SMM profile. -Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -29,20 +29,21 @@ UINT64 *mPFPageUplink[MAX_PF_PAGE_COUNT]; /** Create SMM page table for S3 path. + @param[out] Cr3 The base address of the page tables. + **/ VOID InitSmmS3Cr3 ( - VOID + OUT UINTN *Cr3 ) { + ASSERT (Cr3 != NULL); + // // Generate level4 page table for the first 4GB memory space // Return the address of PML4 (to set CR3) // - // - // The SmmS3Cr3 is only used by S3Resume PEIM to switch CPU from 32bit to 64bit - // - mSmmS3ResumeState->SmmS3Cr3 = (UINT32)GenSmmPageTable (Paging4Level, 32); + *Cr3 = GenSmmPageTable (Paging4Level, 32); return; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h index 80205c9b3e..993e1dd63a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h @@ -1,7 +1,7 @@ /** @file X64 processor specific header file to enable SMM profile. -Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -81,10 +81,12 @@ RestorePageTableAbove4G ( /** Create SMM page table for S3 path. + @param[out] Cr3 The base address of the page tables. + **/ VOID InitSmmS3Cr3 ( - VOID + OUT UINTN *Cr3 ); /** -- cgit From f203a6db92eedf03ac544ed270404cb29d3dea7f Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 2 Aug 2024 03:44:30 +0100 Subject: OvmfPkg: Pass correct virtio-scsi request size The patch at "1fc55a3933b0 OvmfPkg: Use heap memory for virtio-scsi request" modified the virtio-scsi request header memory to be allocated from the heap. In doing so the request structure header which was a local variable on the stack was converted to be a pointer. This required adjusting the size computation for the request header to reflect that the structure was changed to a pointer. Unfortunately, this was missed out in the call to VirtioAppendDesc() for enqueuing the request due to which only 8 bytes were being shared with the host instead of the size of the VIRTIO_SCSI_REQ structure which is 51 bytes. This resulted in the following error message to be printed by qemu: "qemu-system-: wrong size for virtio-scsi headers" and the virtio-scsi functionality degraded. Therefore, pass the correct size of the virtio-scsi request header when enqueuing the request. Reported-by: Aithal Srikanth Tested-by: Aithal Srikanth Signed-off-by: Sami Mujawar --- OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c index 11e4d8703d..ac8c57660e 100644 --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c @@ -610,7 +610,7 @@ VirtioScsiPassThru ( VirtioAppendDesc ( &Dev->Ring, RequestDeviceAddress, - sizeof Request, + sizeof (*Request), VRING_DESC_F_NEXT, &Indices ); -- cgit From 159f1aee56d270d2575e50eb2af077abe182fc9b Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Thu, 1 Aug 2024 16:08:52 -0700 Subject: BaseTools/WinRcPath: Improve Performance. WinRcPath generally takes about 2 seconds to run, due to calling multiple .bat files behind the scenes. This change reduces this time to ~0 seconds due to the following changes: 1. It will attempt to load the path from the cache, which is located a $(WORKSPACE)/Conf/.rc_path. If the loading is a success and the rc_path still exists, it will use it. 2. If the cache did not exist, or the path provided by the cache does not exist, it will find the rc path via the .bat files. If that succeeds, it will write the path to the cache. Signed-off-by: Aaron Pop --- .../Plugin/WindowsResourceCompiler/WinRcPath.py | 36 ++++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py b/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py index ec2f2d1298..348e847fa7 100644 --- a/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py +++ b/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py @@ -6,24 +6,40 @@ # Copyright (c) Microsoft Corporation # SPDX-License-Identifier: BSD-2-Clause-Patent ## -import os +import logging from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin import edk2toollib.windows.locate_tools as locate_tools from edk2toolext.environment import shell_environment from edk2toolext.environment import version_aggregator +from pathlib import Path -class WinRcPath(IUefiBuildPlugin): - def do_post_build(self, thebuilder): - return 0 +class WinRcPath(IUefiBuildPlugin): def do_pre_build(self, thebuilder): - #get the locate tools module + # Check if the rc.exe path is already cached and still exists + cache_path = Path(thebuilder.ws, "Conf", ".rc_path") + if cache_path.exists(): + with open(cache_path, "r") as f: + rc_path = Path(f.readline().strip()).absolute() + if (rc_path / "rc.exe").exists(): + logging.debug(f"Found rc.exe folder in cache: {rc_path}") + self._set_path(rc_path) + return 0 + + # If it does not exist, try to find it with FindToolInWinSdk path = locate_tools.FindToolInWinSdk("rc.exe") if path is None: - thebuilder.logging.warning("Failed to find rc.exe") - else: - p = os.path.abspath(os.path.dirname(path)) - shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", p) - version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", p, version_aggregator.VersionTypes.INFO) + logging.critical("Failed to find rc.exe") + return 1 + + path = Path(path).absolute().parent + self._set_path(path) + cache_path.unlink(missing_ok=True) + with cache_path.open("w") as f: + f.write(str(path)) return 0 + + def _set_path(self, path: Path): + shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", str(path)) + version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", str(path), version_aggregator.VersionTypes.INFO) -- cgit From 5ff99e0dabefea14b04e190c1659f4817fcb7bc0 Mon Sep 17 00:00:00 2001 From: joe <37425738+JoeLopez333@users.noreply.github.com> Date: Mon, 24 Jul 2023 10:19:22 -0700 Subject: MdePkg /IoRemappingTable: Define additional IORT SMMUv3 node flags. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The flag for HTTU override in an SMMUv3 node in the IORT table is defined in MdePkg/Include/IndustryStandard/IoRemappingTable.h as a single bit. BIT0 or BIT1. The implementation of this field is actually two bits, with the following mapings: 0b0000: Hardware update of the Access flag and dirty state are not supported. 0b0001: Support for hardware update of the Access flag for Block and Page descriptors. 0b0010: As 0b0001, and adds support for hardware update of the Access flag for Block and Page descriptors. Hardware update of dirty state is supported. Referenced in Arm® System Memory Management Unit Architecture Specification SMMU architecture version 3: https://documentation-service.arm.com/static/63d7a2d5e4378a55c5e045b9 Signed-off-by: Aaron Pop --- MdePkg/Include/IndustryStandard/IoRemappingTable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/IndustryStandard/IoRemappingTable.h b/MdePkg/Include/IndustryStandard/IoRemappingTable.h index 7900bb5bbd..851ce00cb8 100644 --- a/MdePkg/Include/IndustryStandard/IoRemappingTable.h +++ b/MdePkg/Include/IndustryStandard/IoRemappingTable.h @@ -61,7 +61,8 @@ #define EFI_ACPI_IORT_SMMUv1v2_INT_FLAG_EDGE 0x1 #define EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE BIT0 -#define EFI_ACPI_IORT_SMMUv3_FLAG_HTTU_OVERRIDE BIT1 +#define EFI_ACPI_IORT_SMMUv3_FLAG_HTTU_OVERRIDE BIT1 // HW update of Access Flag supported +#define EFI_ACPI_IORT_SMMUv3_FLAG_HTTU_OVERRIDE_DS BIT2 // HW update of Access Flag + Dirty Flag supported #define EFI_ACPI_IORT_SMMUv3_FLAG_PROXIMITY_DOMAIN BIT3 #define EFI_ACPI_IORT_SMMUv3_FLAG_DEVICEID_VALID BIT4 -- cgit From 68b4c4b481f3129132cd90c45d241990445f4a3a Mon Sep 17 00:00:00 2001 From: Jason1 Lin Date: Wed, 31 Jul 2024 17:05:48 +0800 Subject: BaseTools/Capsule: Support Different Hash Algorithm for Payload Digest REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4821 - The capsule payload digest got hardcoded inside the GenerateCapsule script as "sha256". - It would be hard for the caller to change the supported hash algorithm which supported on OpenSSL or Windows signtool program and platform. - Capsule payload digest signed data is followed by the PKCS#7 standard, in EDK-II CryptoPkg "Pkcs7Verify ()" is supported to validate with several hash algorithms naturally. (md5, sha1, sha256, sha384, and sha512) - Deliver below changes within this patch, (1) Introduce an optional argument "--hash-algorithm" to assign the caller expected one and leave the default value "sha256" to support the backward compatibility. (2) Add the double quotes to put the string of certificate's subject name inside it. (3) Set "Open" argument of "SignToolSubjectName" into "False". (4) Set "Convert" argument of "SignToolSubjectName: into "str". (5) Correct the actual name of the "--subject-name" flag. (6) Add back correct number of arguments for PayloadDescriptor class object initializing. Note: - Platform needs to support the correspond hash algorithm to validate the digital signature or the failure would be observed. - Set the md5 and sha1 algorithm as EOL based on the CryptoPkg supported table and reject the capsule creation. Signed-off-by: Jason1 Lin --- BaseTools/Source/Python/Capsule/GenerateCapsule.py | 117 ++++++++++++++++++--- 1 file changed, 103 insertions(+), 14 deletions(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py index a773cfb2b3..fd3ee4a614 100644 --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py @@ -10,7 +10,7 @@ # keep the tool as simple as possible, it has the following limitations: # * Do not support vendor code bytes in a capsule. # -# Copyright (c) 2018 - 2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2018 - 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -38,11 +38,68 @@ from Common.Edk2.Capsule.FmpPayloadHeader import FmpPayloadHeaderClass # Globals for help information # __prog__ = 'GenerateCapsule' -__version__ = '0.10' -__copyright__ = 'Copyright (c) 2022, Intel Corporation. All rights reserved.' +__version__ = '0.11' +__copyright__ = 'Copyright (c) 2024, Intel Corporation. All rights reserved.' __description__ = 'Generate a capsule.\n' -def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose = False): +# +# Globals definitions +# +HASH_ALG_MD5 = 'md5' +HASH_ALG_SHA1 = 'sha1' +HASH_ALG_SHA256 = 'sha256' +HASH_ALG_SHA384 = 'sha384' +HASH_ALG_SHA512 = 'sha512' +DEFAULT_HASH_ALGORITHM = HASH_ALG_SHA256 + +TOOL_SIGN_TOOL = 0x0 +TOOL_OPENSSL = 0x1 + +SIGN_TOOL_HASH_ALG_EOL_LIST = [ + HASH_ALG_MD5, + HASH_ALG_SHA1, + ] + +SIGN_TOOL_HASH_ALG_SUPPORT_LIST = [ + HASH_ALG_SHA256, + HASH_ALG_SHA384, + HASH_ALG_SHA512, + ] + +OPENSSL_HASH_ALG_EOL_LIST = [ + HASH_ALG_MD5, + HASH_ALG_SHA1, + ] + +OPENSSL_HASH_ALG_SUPPORT_LIST = [ + HASH_ALG_SHA256, + HASH_ALG_SHA384, + HASH_ALG_SHA512, + ] + +def CheckHashAlgorithmSupported (ToolType, HashAlgorithm): + if ToolType == TOOL_SIGN_TOOL: + EolList = SIGN_TOOL_HASH_ALG_EOL_LIST + SupportList = SIGN_TOOL_HASH_ALG_SUPPORT_LIST + elif ToolType == TOOL_OPENSSL: + EolList = OPENSSL_HASH_ALG_EOL_LIST + SupportList = OPENSSL_HASH_ALG_SUPPORT_LIST + else: + raise ValueError ('GenerateCapsule: error: unsupported type of tool.') + + if HashAlgorithm.lower () in EolList: + raise ValueError ('GenerateCapsule: error: hash algorithm [{HashAlgorithm}] had been EOL.'.format (HashAlgorithm = HashAlgorithm)) + elif HashAlgorithm.lower () not in SupportList: + raise ValueError ('GenerateCapsule: error: hash algorithm [{HashAlgorithm}] is not supported.'.format (HashAlgorithm = HashAlgorithm)) + + return + +def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False): + # + # Check the hash algorithm is supported + # + CheckHashAlgorithmSupported (TOOL_SIGN_TOOL, HashAlgorithm) + # # Create a temporary directory # @@ -70,12 +127,12 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose = Fals ToolPath = '' Command = '' Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'signtool.exe')) - Command = Command + 'sign /fd sha256 /p7ce DetachedSignedData /p7co 1.2.840.113549.1.7.2 ' + Command = Command + 'sign /fd {HashAlgorithm} /p7ce DetachedSignedData /p7co 1.2.840.113549.1.7.2 '.format (HashAlgorithm = HashAlgorithm) Command = Command + '/p7 {TempDir} '.format (TempDir = TempDirectoryName) if PfxFile is not None: Command = Command + '/f {PfxFile} '.format (PfxFile = PfxFile) if SubjectName is not None: - Command = Command + '/n {SubjectName} '.format (SubjectName = SubjectName) + Command = Command + '/n "{SubjectName}" '.format (SubjectName = SubjectName) Command = Command + TempFileName if Verbose: print (Command) @@ -108,11 +165,16 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose = Fals shutil.rmtree (TempDirectoryName) return Signature -def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, SubjectName, Verbose = False): +def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, SubjectName, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False): print ('signtool verify is not supported.') raise ValueError ('GenerateCapsule: error: signtool verify is not supported.') -def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, Verbose = False): +def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False): + # + # Check the hash algorithm is supported + # + CheckHashAlgorithmSupported (TOOL_OPENSSL, HashAlgorithm) + # # Build openssl command # @@ -120,7 +182,7 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer ToolPath = '' Command = '' Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'openssl')) - Command = Command + 'smime -sign -binary -outform DER -md sha256 ' + Command = Command + 'smime -sign -binary -outform DER -md {HashAlgorithm} '.format (HashAlgorithm = HashAlgorithm) Command = Command + '-signer "{Private}" -certfile "{Public}"'.format (Private = SignerPrivateCertFile, Public = OtherPublicCertFile) if Verbose: print (Command) @@ -141,7 +203,7 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer return Signature -def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, Verbose = False): +def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False): # # Create a temporary directory # @@ -251,8 +313,9 @@ if __name__ == '__main__': LowestSupportedVersion = ConvertJsonValue (Config, 'LowestSupportedVersion', ValidateUnsignedInteger, Required = False) HardwareInstance = ConvertJsonValue (Config, 'HardwareInstance', ValidateUnsignedInteger, Required = False, Default = 0) MonotonicCount = ConvertJsonValue (Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False, Default = 0) + HashAlgorithm = ConvertJsonValue (Config, 'HashAlgorithm', str, Required = False, Default = DEFAULT_HASH_ALGORITHM) SignToolPfxFile = ConvertJsonValue (Config, 'SignToolPfxFile', os.path.expandvars, Required = False, Default = None, Open = True) - SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', os.path.expandvars, Required = False, Default = None, Open = True) + SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', str, Required = False, Default = None, Open = False) OpenSslSignerPrivateCertFile = ConvertJsonValue (Config, 'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False, Default = None, Open = True) OpenSslOtherPublicCertFile = ConvertJsonValue (Config, 'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True) OpenSslTrustedPublicCertFile = ConvertJsonValue (Config, 'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True) @@ -267,6 +330,7 @@ if __name__ == '__main__': MonotonicCount, HardwareInstance, UpdateImageIndex, + HashAlgorithm, SignToolPfxFile, SignToolSubjectName, OpenSslSignerPrivateCertFile, @@ -307,8 +371,9 @@ if __name__ == '__main__': HardwareInstance = ConvertJsonValue (Config, 'HardwareInstance', ValidateUnsignedInteger, Required = False, Default = 0) UpdateImageIndex = ConvertJsonValue (Config, 'UpdateImageIndex', ValidateUnsignedInteger, Required = False, Default = 1) MonotonicCount = ConvertJsonValue (Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False, Default = 0) + HashAlgorithm = ConvertJsonValue (Config, 'HashAlgorithm', str, Required = False, Default = DEFAULT_HASH_ALGORITHM) SignToolPfxFile = ConvertJsonValue (Config, 'SignToolPfxFile', os.path.expandvars, Required = False, Default = None, Open = True) - SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', os.path.expandvars, Required = False, Default = None, Open = True) + SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', str, Required = False, Default = None, Open = False) OpenSslSignerPrivateCertFile = ConvertJsonValue (Config, 'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False, Default = None, Open = True) OpenSslOtherPublicCertFile = ConvertJsonValue (Config, 'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True) OpenSslTrustedPublicCertFile = ConvertJsonValue (Config, 'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True) @@ -334,6 +399,7 @@ if __name__ == '__main__': MonotonicCount, HardwareInstance, UpdateImageIndex, + HashAlgorithm, SignToolPfxFile, SignToolSubjectName, OpenSslSignerPrivateCertFile, @@ -354,6 +420,7 @@ if __name__ == '__main__': "Payload": PayloadDescriptor.Payload, "HardwareInstance": str(PayloadDescriptor.HardwareInstance), "UpdateImageIndex": str(PayloadDescriptor.UpdateImageIndex), + "HashAlgorithm": str(PayloadDescriptor.HashAlgorithm), "SignToolPfxFile": str(PayloadDescriptor.SignToolPfxFile), "SignToolSubjectName": str(PayloadDescriptor.SignToolSubjectName), "OpenSslSignerPrivateCertFile": str(PayloadDescriptor.OpenSslSignerPrivateCertFile), @@ -409,11 +476,14 @@ if __name__ == '__main__': if args.HardwareInstance: print ('GenerateCapsule: error: Argument --hardware-instance conflicts with Argument -j') sys.exit (1) + if args.HashAlgorithm: + print ('GenerateCapsule: error: Argument --hash-algorithm conflicts with Argument -j') + sys.exit (1) if args.SignToolPfxFile: print ('GenerateCapsule: error: Argument --pfx-file conflicts with Argument -j') sys.exit (1) if args.SignToolSubjectName: - print ('GenerateCapsule: error: Argument --SubjectName conflicts with Argument -j') + print ('GenerateCapsule: error: Argument --subject-name conflicts with Argument -j') sys.exit (1) if args.OpenSslSignerPrivateCertFile: print ('GenerateCapsule: error: Argument --signer-private-cert conflicts with Argument -j') @@ -437,6 +507,7 @@ if __name__ == '__main__': MonotonicCount = 0, HardwareInstance = 0, UpdateImageIndex = 1, + HashAlgorithm = None, SignToolPfxFile = None, SignToolSubjectName = None, OpenSslSignerPrivateCertFile = None, @@ -452,6 +523,7 @@ if __name__ == '__main__': self.MonotonicCount = MonotonicCount self.HardwareInstance = HardwareInstance self.UpdateImageIndex = UpdateImageIndex + self.HashAlgorithm = HashAlgorithm self.SignToolPfxFile = SignToolPfxFile self.SignToolSubjectName = SignToolSubjectName self.OpenSslSignerPrivateCertFile = OpenSslSignerPrivateCertFile @@ -523,6 +595,9 @@ if __name__ == '__main__': if args.OutputFile is None: raise argparse.ArgumentTypeError ('--decode requires --output') + if self.HashAlgorithm is None: + self.HashAlgorithm = DEFAULT_HASH_ALGORITHM + if self.UseSignTool: if self.SignToolPfxFile is not None: self.SignToolPfxFile.close() @@ -568,6 +643,7 @@ if __name__ == '__main__': args.MonotonicCount, args.HardwareInstance, args.UpdateImageIndex, + args.HashAlgorithm, args.SignToolPfxFile, args.SignToolSubjectName, args.OpenSslSignerPrivateCertFile, @@ -613,6 +689,7 @@ if __name__ == '__main__': SinglePayloadDescriptor.SigningToolPath, SinglePayloadDescriptor.SignToolPfxFile, SinglePayloadDescriptor.SignToolSubjectName, + HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm, Verbose = args.Verbose ) else: @@ -622,6 +699,7 @@ if __name__ == '__main__': SinglePayloadDescriptor.OpenSslSignerPrivateCertFile, SinglePayloadDescriptor.OpenSslOtherPublicCertFile, SinglePayloadDescriptor.OpenSslTrustedPublicCertFile, + HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm, Verbose = args.Verbose ) except Exception as Msg: @@ -693,6 +771,7 @@ if __name__ == '__main__': args.MonotonicCount, args.HardwareInstance, args.UpdateImageIndex, + args.HashAlgorithm, args.SignToolPfxFile, args.SignToolSubjectName, args.OpenSslSignerPrivateCertFile, @@ -738,6 +817,7 @@ if __name__ == '__main__': None, HardwareInstance, UpdateImageIndex, + PayloadDescriptorList[Index].HashAlgorithm, PayloadDescriptorList[Index].SignToolPfxFile, PayloadDescriptorList[Index].SignToolSubjectName, PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile, @@ -751,7 +831,10 @@ if __name__ == '__main__': for Index in range (0, FmpCapsuleHeader.PayloadItemCount): if Index > 0: PayloadDecodeFile = FmpCapsuleHeader.GetFmpCapsuleImageHeader (Index).Payload - PayloadDescriptorList.append (PayloadDescriptor (PayloadDecodeFile, + PayloadDescriptorList.append (PayloadDescriptor ( + PayloadDecodeFile, + None, + None, None, None, None, @@ -777,6 +860,7 @@ if __name__ == '__main__': None, HardwareInstance, UpdateImageIndex, + PayloadDescriptorList[Index].HashAlgorithm, PayloadDescriptorList[Index].SignToolPfxFile, PayloadDescriptorList[Index].SignToolSubjectName, PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile, @@ -812,6 +896,7 @@ if __name__ == '__main__': SinglePayloadDescriptor.SigningToolPath, SinglePayloadDescriptor.SignToolPfxFile, SinglePayloadDescriptor.SignToolSubjectName, + HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm, Verbose = args.Verbose ) else: @@ -822,6 +907,7 @@ if __name__ == '__main__': SinglePayloadDescriptor.OpenSslSignerPrivateCertFile, SinglePayloadDescriptor.OpenSslOtherPublicCertFile, SinglePayloadDescriptor.OpenSslTrustedPublicCertFile, + HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm, Verbose = args.Verbose ) except Exception as Msg: @@ -993,6 +1079,9 @@ if __name__ == '__main__': parser.add_argument ("--lsv", dest = 'LowestSupportedVersion', type = ValidateUnsignedInteger, help = "The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678). Required for encode operations.") + parser.add_argument ("--hash-algorithm", dest = 'HashAlgorithm', type = str, + help = "Hash algorithm for the payload digest.") + parser.add_argument ("--pfx-file", dest='SignToolPfxFile', type=argparse.FileType('rb'), help="signtool PFX certificate filename.") parser.add_argument ("--subject-name", dest='SignToolSubjectName', -- cgit From 47bb9f9a97726d11a11a5658a3917045bd9b0787 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Tue, 30 Jul 2024 11:31:59 +0800 Subject: UefiCpuPkg: Revert "UefiCpuPkg/PiSmmCpuDxeSmm: Fix system..." This reverts commit bef0d333dc "UefiCpuPkg/PiSmmCpuDxeSmm: Fix system hang when SmmProfile enable". The commit bef0d333dc was added to modify the code logic in InitPaging() to fix a code assert issue. Previously, the root cause of this issue is that we try to only set NX attribute for not-present MMIO range above 4G when SMM profile feature is enabled, which is not allowed by CpuPageTableLib. But after we always create full mapping initial SMM page table in the next commit, this code assert issue won't happen anymore since MMIO range above 4g will also be present in SMM page table before InitPaging(). Meanwhile another issue was introduced by commit bef0d333dc: In the entrypoint of PiSmmCpuDxe driver, we will set some pages in stack range as not-present in SMM page table if PcdCpuSmmStackGuard or PcdControlFlowEnforcementPropertyMask is TRUE. But in commit bef0d333dc, all SMRAM range are set to present in InitPaging() if SMM profile is enabled. Then the stack guard and shadow stack features do not work anymore. So let's revert the commit "UefiCpuPkg/PiSmmCpuDxeSmm: Fix system hang when SmmProfile enable" Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 40 +++++++++------------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 9d8a9dc575..d18084b71f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1,7 +1,7 @@ /** @file Enable SMM profile. -Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2023, Intel Corporation. All rights reserved.
Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -610,7 +610,6 @@ InitPaging ( UINT64 Limit; UINT64 PreviousAddress; UINT64 MemoryAttrMask; - BOOLEAN IsSet; BOOLEAN WriteProtect; BOOLEAN CetEnabled; @@ -633,38 +632,19 @@ InitPaging ( DEBUG ((DEBUG_INFO, "Patch page table start ...\n")); if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { for (Index = 0; Index < mProtectionMemRangeCount; Index++) { - Base = mProtectionMemRange[Index].Range.Base; - Length = mProtectionMemRange[Index].Range.Top - Base; - - MemoryAttrMask = EFI_MEMORY_RP; - if (!mProtectionMemRange[Index].Present) { - // - // Config the EFI_MEMORY_RP attribute to make it non-present. - // - IsSet = TRUE; - } else { - // - // Clear the EFI_MEMORY_RP attribute to make it present. - // - IsSet = FALSE; - - // - // Config the range as writable and executable when mapping a range as present. - // - MemoryAttrMask |= EFI_MEMORY_RO; + MemoryAttrMask = 0; + if (mProtectionMemRange[Index].Nx == TRUE) { MemoryAttrMask |= EFI_MEMORY_XP; } - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, IsSet, NULL); - ASSERT_RETURN_ERROR (Status); + if (mProtectionMemRange[Index].Present == FALSE) { + MemoryAttrMask = EFI_MEMORY_RP; + } - if (mProtectionMemRange[Index].Present && mProtectionMemRange[Index].Nx) { - // - // Since EFI_MEMORY_XP has already been cleared above, only handle the case to disable execution. - // Config the EFI_MEMORY_XP attribute to disable execution. - // - MemoryAttrMask = EFI_MEMORY_XP; - Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL); + Base = mProtectionMemRange[Index].Range.Base; + Length = mProtectionMemRange[Index].Range.Top - Base; + if (MemoryAttrMask != 0) { + Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL); ASSERT_RETURN_ERROR (Status); } -- cgit From 9f29fbd33b73dafb7fca430d08e68b6b8f4bbb9d Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 25 Jul 2024 13:54:23 +0800 Subject: UefiCpuPkg: always create full mapping SMM page table In this commit, we always create full mapping SMM page table in SmmInitPageTable regardless the value of the PcdCpuSmmRestrictedMemoryAccess. Previously, when PcdCpuSmmRestrictedMemoryAccess is false, only [0, 4G] is mapped in smm page table in SmmInitPageTable. If the range above 4G is accessed in SMM, SmiPFHandler will create new paging entry for the accessed range. To simplify the code logic, we also create full mapping SMM page table in SmmInitPageTable when PcdCpuSmmRestrictedMemoryAccess is false. Then we don't need to dynamic create paging entry for range above 4G except SMM profile is enabled. The comparison of SMM page table before and after the change under different configuration are listed here: 1.PcdCpuSmmRestrictedMemoryAccess is TRUE No change 2.PcdCpuSmmRestrictedMemoryAccess is FALSE and PcdCpuSmmProfileEnable is TRUE Before: the SMM page table when ReadyToLock covers 1. SMRAM range 2.SMM profile range 3. MMIO range below 4G After: the SMM page table when ReadyToLock covers 1. SMRAM range 2.SMM profile range 3. MMIO range below 4G and above 4G 3.PcdCpuSmmRestrictedMemoryAccess is FALSE and PcdCpuSmmProfileEnable is FALSE Before: the SMM page table when ReadyToLock covers [0, 4G] After: the SMM page table when ReadyToLock covers [0, MaxSupportPhysicalAddress] Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 8 ++------ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 5 +---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index d18084b71f..6172c7df34 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1,7 +1,7 @@ /** @file Enable SMM profile. -Copyright (c) 2012 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -616,11 +616,7 @@ InitPaging ( PERF_FUNCTION_BEGIN (); PageTable = AsmReadCr3 (); - if (sizeof (UINTN) == sizeof (UINT32)) { - Limit = BASE_4GB; - } else { - Limit = (IsRestrictedMemoryAccess ()) ? LShiftU64 (1, mPhysicalAddressBits) : BASE_4GB; - } + Limit = LShiftU64 (1, mPhysicalAddressBits); WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 9052ea8e84..14b0b1981b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -201,7 +201,6 @@ SmmInitPageTable ( UINT64 *PdptEntry; UINT64 *Pml4Entry; UINT64 *Pml5Entry; - UINT8 PhysicalAddressBits; // // Initialize spin lock @@ -226,10 +225,8 @@ SmmInitPageTable ( // // Generate initial SMM page table. - // Only map [0, 4G] when PcdCpuSmmRestrictedMemoryAccess is FALSE. // - PhysicalAddressBits = mCpuSmmRestrictedMemoryAccess ? mPhysicalAddressBits : 32; - PageTable = GenSmmPageTable (mPagingMode, PhysicalAddressBits); + PageTable = GenSmmPageTable (mPagingMode, mPhysicalAddressBits); if (m5LevelPagingNeeded) { Pml5Entry = (UINT64 *)PageTable; -- cgit From b3631ca944bda812f51db3f833f18d82d8e0e761 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 25 Jul 2024 13:58:38 +0800 Subject: UefiCpuPkg: remove unnecessary manipulation for smm page table In this commit, we only set some special bits in paging entry content when SMM profile is enabled. Previously, we set Pml4Entry sub-entries number and set the IA32_PG_PMNT bit for first 4 PdptEntry. It's to make sure that the paging structures cover [0, 4G] won't be reclaimed during dynamic page table creation. In last commit, we always create full mapping SMM page table regardless PcdCpuSmmRestrictedMemoryAccess. With this change, we only need to dynamic create SMM page table in smm PF handler when PcdCpuSmmProfileEnable is TRUE. So the sub-entries number and IA32_PG_PMNT bit in paging entry is only needed to set when PcdCpuSmmProfileEnable is TRUE. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 14b0b1981b..a7b02981dc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -228,26 +228,26 @@ SmmInitPageTable ( // PageTable = GenSmmPageTable (mPagingMode, mPhysicalAddressBits); - if (m5LevelPagingNeeded) { - Pml5Entry = (UINT64 *)PageTable; + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + if (m5LevelPagingNeeded) { + Pml5Entry = (UINT64 *)PageTable; + // + // Set Pml5Entry sub-entries number for smm PF handler usage. + // + SetSubEntriesNum (Pml5Entry, 1); + Pml4Entry = (UINT64 *)((*Pml5Entry) & ~mAddressEncMask & gPhyMask); + } else { + Pml4Entry = (UINT64 *)PageTable; + } + // - // Set Pml5Entry sub-entries number for smm PF handler usage. + // Set IA32_PG_PMNT bit to mask first 4 PdptEntry. // - SetSubEntriesNum (Pml5Entry, 1); - Pml4Entry = (UINT64 *)((*Pml5Entry) & ~mAddressEncMask & gPhyMask); - } else { - Pml4Entry = (UINT64 *)PageTable; - } - - // - // Set IA32_PG_PMNT bit to mask first 4 PdptEntry. - // - PdptEntry = (UINT64 *)((*Pml4Entry) & ~mAddressEncMask & gPhyMask); - for (Index = 0; Index < 4; Index++) { - PdptEntry[Index] |= IA32_PG_PMNT; - } + PdptEntry = (UINT64 *)((*Pml4Entry) & ~mAddressEncMask & gPhyMask); + for (Index = 0; Index < 4; Index++) { + PdptEntry[Index] |= IA32_PG_PMNT; + } - if (!mCpuSmmRestrictedMemoryAccess) { // // Set Pml4Entry sub-entries number for smm PF handler usage. // -- cgit From b5c9bbff8e9c2613dc72ab4dde6d4ddc1e1217bd Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 25 Jul 2024 13:56:37 +0800 Subject: UefiCpuPkg:CpuDeadLoop in SmiPFHandler if SMM profile is disabled Always call CpuDeadLoop() in SmiPFHandler if SMM profile is disabled. Previously, when PcdCpuSmmRestrictedMemoryAccess is FALSE, SMM page table only covers [0, 4g]. When code access to range above 4g happens, SmiPFHandler will map the accessed not-present range to present. After we always create full mapping page table, the dynamic page table creation logic is only needed when SMM profile is enabled. So we use CpuDeadLoop() in SmiPFHandler to cover the all the PF exception when SMM profile is disabled Considering that [0, 4g] is always mapped in SMM page table, we also modify the IA32 SmiPFHandler code to be aligned with X64 code. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index 5c00c0fa8c..5170be342f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -212,7 +212,7 @@ SmiPFHandler ( ); } else { DumpCpuContext (InterruptType, SystemContext); - SmiDefaultPFHandler (); + CpuDeadLoop (); } Exit: diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index a7b02981dc..09a9c1c49f 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -1,7 +1,7 @@ /** @file Page Fault (#PF) handler for X64 processors -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -982,7 +982,8 @@ SmiPFHandler ( SystemContext.SystemContextX64->ExceptionData ); } else { - SmiDefaultPFHandler (); + DumpCpuContext (InterruptType, SystemContext); + CpuDeadLoop (); } Exit: -- cgit From cae90a83907d5f9e10c45cd2985bab1fafc47f56 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 31 Jul 2024 13:48:47 +0800 Subject: UefiCpuPkg: Remove duplicate code in SmiPfHandler In this commit, we remove duplicate CpuDeadLoop in SmiPfHandler where mCpuSmmRestrictedMemoryAccess is TRUE. With last commit, we always call CpuDeadLoop if SMM profile is disabled. Then the CpuDeadLoop calling for the condition (mCpuSmmRestrictedMemoryAccess && IsSmmCommBufferForbiddenAddress (PFAddress)) is not needed anymore. We also modify the IA32 related code to be aligned with X64. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 9 +++------ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index 5170be342f..a8f0b503c0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -195,13 +195,7 @@ SmiPFHandler ( } if (IsSmmCommBufferForbiddenAddress (PFAddress)) { - DumpCpuContext (InterruptType, SystemContext); DEBUG ((DEBUG_ERROR, "Access SMM communication forbidden address (0x%x)!\n", PFAddress)); - DEBUG_CODE ( - DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip); - ); - CpuDeadLoop (); - goto Exit; } } @@ -212,6 +206,9 @@ SmiPFHandler ( ); } else { DumpCpuContext (InterruptType, SystemContext); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip); + ); CpuDeadLoop (); } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index 09a9c1c49f..a29bec55ea 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -966,13 +966,7 @@ SmiPFHandler ( } if (mCpuSmmRestrictedMemoryAccess && IsSmmCommBufferForbiddenAddress (PFAddress)) { - DumpCpuContext (InterruptType, SystemContext); DEBUG ((DEBUG_ERROR, "Access SMM communication forbidden address (0x%lx)!\n", PFAddress)); - DEBUG_CODE ( - DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip); - ); - CpuDeadLoop (); - goto Exit; } } @@ -983,6 +977,9 @@ SmiPFHandler ( ); } else { DumpCpuContext (InterruptType, SystemContext); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip); + ); CpuDeadLoop (); } -- cgit From 8b8ac5d986dd78ee729a3fd32c833ff2235feeb9 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 31 Jul 2024 15:20:14 +0800 Subject: UefiCpuPkg: rename the SmiDefaultPFHandler function Rename SmiDefaultPFHandler to SmiProfileMapPFAddress and move the implementation to SmmProfileArch.c since it only will be used when SMM profile is enabled. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 12 -- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c | 12 ++ UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h | 4 +- UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 150 ----------------------- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c | 152 +++++++++++++++++++++++- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h | 55 +++++++++ 7 files changed, 221 insertions(+), 166 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index a8f0b503c0..dfc9668dbc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -82,18 +82,6 @@ AllocPage ( return 0; } -/** - Page Fault handler for SMM use. - -**/ -VOID -SmiDefaultPFHandler ( - VOID - ) -{ - CpuDeadLoop (); -} - /** ThePage Fault handler wrapper for SMM use. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c index 9021f9cf5d..b279c8a09c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c @@ -76,3 +76,15 @@ ClearTrapFlag ( { SystemContext.SystemContextIa32->Eflags &= (UINTN) ~BIT8; } + +/** + Create new entry in page table for page fault address in SmmProfilePFHandler. + +**/ +VOID +SmmProfileMapPFAddress ( + VOID + ) +{ + CpuDeadLoop (); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 6172c7df34..351afc9638 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1337,7 +1337,7 @@ SmmProfilePFHandler ( // // If SMM profile does not start, call original page fault handler. // - SmiDefaultPFHandler (); + SmmProfileMapPFAddress (); return; } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index 9b00ea41b3..df6bdae0cc 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -153,11 +153,11 @@ AllocPage ( ); /** - Page Fault handler for SMM use. + Create new entry in page table for page fault address in SmmProfilePFHandler. **/ VOID -SmiDefaultPFHandler ( +SmmProfileMapPFAddress ( VOID ); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c index a29bec55ea..abaa3349f4 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -700,156 +700,6 @@ AllocPage ( return RetVal; } -/** - Page Fault handler for SMM use. - -**/ -VOID -SmiDefaultPFHandler ( - VOID - ) -{ - UINT64 *PageTable; - UINT64 *PageTableTop; - UINT64 PFAddress; - UINTN StartBit; - UINTN EndBit; - UINT64 PTIndex; - UINTN Index; - SMM_PAGE_SIZE_TYPE PageSize; - UINTN NumOfPages; - UINTN PageAttribute; - EFI_STATUS Status; - UINT64 *UpperEntry; - BOOLEAN Enable5LevelPaging; - IA32_CR4 Cr4; - - // - // Set default SMM page attribute - // - PageSize = SmmPageSize2M; - NumOfPages = 1; - PageAttribute = 0; - - EndBit = 0; - PageTableTop = (UINT64 *)(AsmReadCr3 () & gPhyMask); - PFAddress = AsmReadCr2 (); - - Cr4.UintN = AsmReadCr4 (); - Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0); - - Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute); - // - // If platform not support page table attribute, set default SMM page attribute - // - if (Status != EFI_SUCCESS) { - PageSize = SmmPageSize2M; - NumOfPages = 1; - PageAttribute = 0; - } - - if (PageSize >= MaxSmmPageSizeType) { - PageSize = SmmPageSize2M; - } - - if (NumOfPages > 512) { - NumOfPages = 512; - } - - switch (PageSize) { - case SmmPageSize4K: - // - // BIT12 to BIT20 is Page Table index - // - EndBit = 12; - break; - case SmmPageSize2M: - // - // BIT21 to BIT29 is Page Directory index - // - EndBit = 21; - PageAttribute |= (UINTN)IA32_PG_PS; - break; - case SmmPageSize1G: - if (!m1GPageTableSupport) { - DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!")); - ASSERT (FALSE); - } - - // - // BIT30 to BIT38 is Page Directory Pointer Table index - // - EndBit = 30; - PageAttribute |= (UINTN)IA32_PG_PS; - break; - default: - ASSERT (FALSE); - } - - // - // If execute-disable is enabled, set NX bit - // - if (mXdEnabled) { - PageAttribute |= IA32_PG_NX; - } - - for (Index = 0; Index < NumOfPages; Index++) { - PageTable = PageTableTop; - UpperEntry = NULL; - for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) { - PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); - - // - // Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met: - // 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity. - // 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry. - // - if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) { - if ((PageTable[PTIndex] & IA32_PG_P) == 0) { - // - // If the entry is not present, allocate one page from page pool for it - // - PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS; - } else { - // - // Save the upper entry address - // - UpperEntry = PageTable + PTIndex; - } - - // - // BIT9 to BIT11 of entry is used to save access record, - // initialize value is 7 - // - PageTable[PTIndex] |= (UINT64)IA32_PG_A; - SetAccNum (PageTable + PTIndex, 7); - PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask); - } else { - // - // Found the appropriate entry. - // - break; - } - } - - PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); - - // - // Fill the new entry - // - PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) | - PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS; - if (UpperEntry != NULL) { - SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF); - } - - // - // Get the next page address if we need to create more page tables - // - PFAddress += (1ull << StartBit); - } -} - /** ThePage Fault handler wrapper for SMM use. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c index 8e15c42d99..39dd2c8029 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c @@ -109,6 +109,156 @@ AcquirePage ( mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT; } +/** + Create new entry in page table for page fault address in SmmProfilePFHandler. + +**/ +VOID +SmmProfileMapPFAddress ( + VOID + ) +{ + UINT64 *PageTable; + UINT64 *PageTableTop; + UINT64 PFAddress; + UINTN StartBit; + UINTN EndBit; + UINT64 PTIndex; + UINTN Index; + SMM_PAGE_SIZE_TYPE PageSize; + UINTN NumOfPages; + UINTN PageAttribute; + EFI_STATUS Status; + UINT64 *UpperEntry; + BOOLEAN Enable5LevelPaging; + IA32_CR4 Cr4; + + // + // Set default SMM page attribute + // + PageSize = SmmPageSize2M; + NumOfPages = 1; + PageAttribute = 0; + + EndBit = 0; + PageTableTop = (UINT64 *)(AsmReadCr3 () & gPhyMask); + PFAddress = AsmReadCr2 (); + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0); + + Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute); + // + // If platform not support page table attribute, set default SMM page attribute + // + if (Status != EFI_SUCCESS) { + PageSize = SmmPageSize2M; + NumOfPages = 1; + PageAttribute = 0; + } + + if (PageSize >= MaxSmmPageSizeType) { + PageSize = SmmPageSize2M; + } + + if (NumOfPages > 512) { + NumOfPages = 512; + } + + switch (PageSize) { + case SmmPageSize4K: + // + // BIT12 to BIT20 is Page Table index + // + EndBit = 12; + break; + case SmmPageSize2M: + // + // BIT21 to BIT29 is Page Directory index + // + EndBit = 21; + PageAttribute |= (UINTN)IA32_PG_PS; + break; + case SmmPageSize1G: + if (!m1GPageTableSupport) { + DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!")); + ASSERT (FALSE); + } + + // + // BIT30 to BIT38 is Page Directory Pointer Table index + // + EndBit = 30; + PageAttribute |= (UINTN)IA32_PG_PS; + break; + default: + ASSERT (FALSE); + } + + // + // If execute-disable is enabled, set NX bit + // + if (mXdEnabled) { + PageAttribute |= IA32_PG_NX; + } + + for (Index = 0; Index < NumOfPages; Index++) { + PageTable = PageTableTop; + UpperEntry = NULL; + for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) { + PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); + + // + // Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met: + // 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity. + // 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry. + // + if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) { + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + // + // If the entry is not present, allocate one page from page pool for it + // + PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } else { + // + // Save the upper entry address + // + UpperEntry = PageTable + PTIndex; + } + + // + // BIT9 to BIT11 of entry is used to save access record, + // initialize value is 7 + // + PageTable[PTIndex] |= (UINT64)IA32_PG_A; + SetAccNum (PageTable + PTIndex, 7); + PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask); + } else { + // + // Found the appropriate entry. + // + break; + } + } + + PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); + + // + // Fill the new entry + // + PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) | + PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS; + if (UpperEntry != NULL) { + SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF); + } + + // + // Get the next page address if we need to create more page tables + // + PFAddress += (1ull << StartBit); + } +} + /** Update page table to map the memory correctly in order to make the instruction which caused page fault execute successfully. And it also save the original page @@ -220,7 +370,7 @@ RestorePageTableAbove4G ( // // Create one entry in page table for page fault address. // - SmiDefaultPFHandler (); + SmmProfileMapPFAddress (); // // Find the page table entry created just now. // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h index 993e1dd63a..5249360a1a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h @@ -55,6 +55,8 @@ typedef struct _PEBS_RECORD { #pragma pack () +extern BOOLEAN m1GPageTableSupport; + #define PHYSICAL_ADDRESS_MASK ((1ull << 52) - SIZE_4KB) /** @@ -98,4 +100,57 @@ InitPagesForPFHandler ( VOID ); +/** + Set sub-entries number in entry. + + @param[in, out] Entry Pointer to entry + @param[in] SubEntryNum Sub-entries number based on 0: + 0 means there is 1 sub-entry under this entry + 0x1ff means there is 512 sub-entries under this entry + +**/ +VOID +SetSubEntriesNum ( + IN OUT UINT64 *Entry, + IN UINT64 SubEntryNum + ); + +/** + Return sub-entries number in entry. + + @param[in] Entry Pointer to entry + + @return Sub-entries number based on 0: + 0 means there is 1 sub-entry under this entry + 0x1ff means there is 512 sub-entries under this entry +**/ +UINT64 +GetSubEntriesNum ( + IN UINT64 *Entry + ); + +/** + Allocate free Page for PageFault handler use. + + @return Page address. + +**/ +UINT64 +AllocPage ( + VOID + ); + +/** + Set access record in entry. + + @param[in, out] Entry Pointer to entry + @param[in] Acc Access record value + +**/ +VOID +SetAccNum ( + IN OUT UINT64 *Entry, + IN UINT64 Acc + ); + #endif // _SMM_PROFILE_ARCH_H_ -- cgit From cff06413604a980bd3f04782c4a745f7c02ccd7b Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Thu, 1 Aug 2024 09:53:20 +0800 Subject: UefiCpuPkg: remove unneeded code in SmmProfilePFHandler Remove unneeded calling of SmmProfileMapPFAddress () in SmmProfileMapPFAddress if SMM profile is not started. Previously, before SMM profile is started at ReadyToLock, SMM page table only covers [0, 4G]. The access to the range above 4G will cause PF. SmmProfileMapPFAddress is needed here to map the PF address before SMM profile is started. Now we always create full mapping SMM page table in the SmmInitPageTable(). When SMM profile is enabled, before SMM profile is started at ReadyToLock, SMM page table covers [0, MaxSupportedPhysicalAddress]. So the case that access to the range above 4G causes PF won't happen anymore. Then we can remove the calling of SmmProfileMapPFAddress before SMM profile is started. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 351afc9638..2dd166d39c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1333,14 +1333,6 @@ SmmProfilePFHandler ( UINT8 SoftSmiValue; EFI_SMM_SAVE_STATE_IO_INFO IoInfo; - if (!mSmmProfileStart) { - // - // If SMM profile does not start, call original page fault handler. - // - SmmProfileMapPFAddress (); - return; - } - if (mBtsSupported) { DisableBTS (); } -- cgit From 5d43165ff8596c2fa07b7d4de3c482d64338ca99 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Fri, 2 Aug 2024 11:45:49 +0800 Subject: UefiCpuPkg: rename and simplify IsAddressValid function In this commit, we rename IsAddressValid function to IsSmmProfilePFAddressAbove4GValid and remove unneeded code logic in it. Currently, IsAddressValid is only used in the function RestorePageTableAbove4G. It's used to identify if a SMM profile PF address above 4G is inside mProtectionMemRange or not. So we can remove the PcdCpuSmmProfileEnable FALSE condition related code logic in it. Also the function name is change to be more detailed and specific. Signed-off-by: Dun Tan --- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 44 +++++++++++--------------- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h | 15 +++++---- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c | 6 ++-- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 2dd166d39c..115d477fd0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -298,41 +298,35 @@ IsInSmmRanges ( } /** - Check if the memory address will be mapped by 4KB-page. + Check if the SMM profile page fault address above 4GB is in protected range or not. - @param Address The address of Memory. - @param Nx The flag indicates if the memory is execute-disable. + @param[in] Address The address of Memory. + @param[out] Nx The flag indicates if the memory is execute-disable. + + @retval TRUE The input address is in protected range. + @retval FALSE The input address is not in protected range. **/ BOOLEAN -IsAddressValid ( - IN EFI_PHYSICAL_ADDRESS Address, - IN BOOLEAN *Nx +IsSmmProfilePFAddressAbove4GValid ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT BOOLEAN *Nx ) { UINTN Index; - if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { - // - // Check configuration - // - for (Index = 0; Index < mProtectionMemRangeCount; Index++) { - if ((Address >= mProtectionMemRange[Index].Range.Base) && (Address < mProtectionMemRange[Index].Range.Top)) { - *Nx = mProtectionMemRange[Index].Nx; - return mProtectionMemRange[Index].Present; - } - } - - *Nx = TRUE; - return FALSE; - } else { - *Nx = TRUE; - if (IsInSmmRanges (Address)) { - *Nx = FALSE; + // + // Check configuration + // + for (Index = 0; Index < mProtectionMemRangeCount; Index++) { + if ((Address >= mProtectionMemRange[Index].Range.Base) && (Address < mProtectionMemRange[Index].Range.Top)) { + *Nx = mProtectionMemRange[Index].Nx; + return mProtectionMemRange[Index].Present; } - - return TRUE; } + + *Nx = TRUE; + return FALSE; } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index df6bdae0cc..42a6effe52 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -129,16 +129,19 @@ IsAddressSplit ( ); /** - Check if the memory address will be mapped by 4KB-page. + Check if the SMM profile page fault address above 4GB is in protected range or not. - @param Address The address of Memory. - @param Nx The flag indicates if the memory is execute-disable. + @param[in] Address The address of Memory. + @param[out] Nx The flag indicates if the memory is execute-disable. + + @retval TRUE The input address is in protected range. + @retval FALSE The input address is not in protected range. **/ BOOLEAN -IsAddressValid ( - IN EFI_PHYSICAL_ADDRESS Address, - IN BOOLEAN *Nx +IsSmmProfilePFAddressAbove4GValid ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT BOOLEAN *Nx ); /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c index 39dd2c8029..a95653ddbf 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c @@ -358,7 +358,7 @@ RestorePageTableAbove4G ( // If page entry does not existed in page table at all, create a new entry. // if (!Existed) { - if (IsAddressValid (PFAddress, &Nx)) { + if (IsSmmProfilePFAddressAbove4GValid (PFAddress, &Nx)) { // // If page fault address above 4GB is in protected range but it causes a page fault exception, // Will create a page entry for this page fault address, make page table entry as present/rw and execution-disable. @@ -401,7 +401,7 @@ RestorePageTableAbove4G ( PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); for (Index = 0; Index < 512; Index++) { PageTable[Index] = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS; - if (!IsAddressValid (Address, &Nx)) { + if (!IsSmmProfilePFAddressAbove4GValid (Address, &Nx)) { PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } @@ -419,7 +419,7 @@ RestorePageTableAbove4G ( // // Update 2MB page entry. // - if (!IsAddressValid (Address, &Nx)) { + if (!IsSmmProfilePFAddressAbove4GValid (Address, &Nx)) { // // Patch to remove present flag and rw flag. // -- cgit From 38c4cd4e88adf6d5d5c4bf753dafba7f24f019d0 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:18:23 -0400 Subject: .github/request-reviews.yml: Use sparse checkout Optimizes the repository checkout step from an average time of 21 to 1 second by performing a sparse checkout of only the file paths needed for the workflow run at a fetch depth of 1. Signed-off-by: Michael Kubacki --- .github/workflows/request-reviews.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index 3311e1165d..a9b81c37d2 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -32,10 +32,18 @@ jobs: pull-requests: write steps: + # Reduce checkout time with sparse-checkout + # - .github: Contains the scripts to interact with Github and add reviewers + # - BaseTools/Scripts: Contains the GetMaintainer.py script + # - Maintainers.txt: Contains the list of maintainers for the repository - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 1 + sparse-checkout: | + .github + BaseTools/Scripts + Maintainers.txt - name: Set up Python uses: actions/setup-python@v5 -- cgit From 057c26710a1f1daf68c00a72180963191d49953d Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:21:30 -0400 Subject: .github/request-reviews.yml: Cache PIP modules - Optimizes and makes the PIP module installation process for the workflow more robust by caching the pip modules used so the only time the workflow needs to reach to PyPi is when new PIP modules are published. - Improves long term stability by locking the major versions for PIP modules in the workflow. This is to reduce overall maintenance over time to automatically pick up new versions while also not being broken in the process. - Removes edk2-pytool-extensions as it is not used. The new "requirements.txt" file is used to lock versions and support the caching step which depends on a requirements file. Signed-off-by: Michael Kubacki --- .github/scripts/requirements.txt | 12 ++++++++++++ .github/workflows/request-reviews.yml | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 .github/scripts/requirements.txt diff --git a/.github/scripts/requirements.txt b/.github/scripts/requirements.txt new file mode 100644 index 0000000000..4b4988cc2f --- /dev/null +++ b/.github/scripts/requirements.txt @@ -0,0 +1,12 @@ +## @file +# GitHub Helpers Python PIP requirements file +# +# This file provides the list of python components used in GitHub scripts in this repository. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +edk2-pytool-library==0.* +requests==2.* diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index a9b81c37d2..f80bb591d5 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -45,13 +45,15 @@ jobs: BaseTools/Scripts Maintainers.txt - - name: Set up Python + - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.x' + cache: 'pip' + cache-dependency-path: '.github/scripts/requirements.txt' - name: Install PIP Modules - run: pip install edk2-pytool-library edk2-pytool-extensions requests + run: pip install -r .github/scripts/requirements.txt --upgrade - name: Add Reviewers to Pull Request shell: python -- cgit From 98f17cdcf41df331ac3cdd4be0686219fa812b7f Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:28:27 -0400 Subject: .github/request-reviews.yml: Switch to GitPython Uses `GitPython` instead of invoking the git executable directly. This has the benefit of improving code readability and less support code for binary interaction. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 22 +++++++--------------- .github/scripts/requirements.txt | 1 + .github/workflows/request-reviews.yml | 18 ++---------------- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index 95865dea41..ad3ee3ef06 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -5,12 +5,13 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent # +import git import logging import re import requests from collections import OrderedDict -from edk2toollib.utility_functions import RunCmd, RunPythonScript +from edk2toollib.utility_functions import RunPythonScript from io import StringIO from typing import List @@ -59,24 +60,15 @@ def get_reviewers_for_range( Returns: List[str]: A list of GitHub usernames. """ - if range_start == range_end: commits = [range_start] else: - commit_stream_buffer = StringIO() - cmd_ret = RunCmd( - "git", - f"log --format=format:%H {range_start}..{range_end}", - workingdir=workspace_path, - outstream=commit_stream_buffer, - logging_level=logging.INFO, - ) - if cmd_ret != 0: - print( - f"::error title=Commit Lookup Error!::Error getting branch commits: [{cmd_ret}]: {commit_stream_buffer.getvalue()}" + commits = [ + c.hexsha + for c in git.Repo(workspace_path).iter_commits( + f"{range_start}..{range_end}" ) - return [] - commits = commit_stream_buffer.getvalue().splitlines() + ] raw_reviewers = [] for commit_sha in commits: diff --git a/.github/scripts/requirements.txt b/.github/scripts/requirements.txt index 4b4988cc2f..a1c2a3c672 100644 --- a/.github/scripts/requirements.txt +++ b/.github/scripts/requirements.txt @@ -9,4 +9,5 @@ ## edk2-pytool-library==0.* +GitPython==3.* requests==2.* diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index f80bb591d5..e176a979e9 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -65,12 +65,10 @@ jobs: TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} WORKSPACE_PATH: ${{ github.workspace }} run: | - import logging + import git import os import sys sys.path.append(os.path.join(os.environ['WORKSPACE_PATH'], ".github")) - from edk2toollib.utility_functions import RunCmd - from io import StringIO from scripts import GitHub WORKSPACE_PATH = os.environ['WORKSPACE_PATH'] @@ -82,19 +80,7 @@ jobs: print(f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}") - out_stream_buffer = StringIO() - cmd_ret = RunCmd( - "git", - f"fetch origin {pr_commit_sha}", - workingdir=WORKSPACE_PATH, - outstream=out_stream_buffer, - logging_level=logging.INFO, - ) - if cmd_ret != 0: - print( - f"::error title=Commit Fetch Error!::Error fetching PR commit: [{cmd_ret}]: {out_stream_buffer.getvalue()}" - ) - sys.exit(1) + git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) reviewers = GitHub.get_reviewers_for_range(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha) if not reviewers: -- cgit From d3e9e1077059e8f565daae31811fe3f0d245fb17 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:42:44 -0400 Subject: .github/request-reviews.yml: Switch to PyGithub Uses PyGithub for GitHub interactions instead of the GitHub REST API directly. This simplifies the code, improves error handling and robustness, and lets the PyGithub project abstract GitHub REST API changes that may occur over time. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 176 ++++++++++++++++++++-------------- .github/scripts/requirements.txt | 1 + .github/workflows/request-reviews.yml | 4 +- 3 files changed, 106 insertions(+), 75 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index ad3ee3ef06..da9e94a84d 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -12,14 +12,56 @@ import requests from collections import OrderedDict from edk2toollib.utility_functions import RunPythonScript +from github import Auth, Github, GithubException from io import StringIO from typing import List + """GitHub API helper functions.""" +def _authenticate(token: str): + """Authenticate to GitHub using a token. + + Returns a GitHub instance that is authenticated using the provided + token. + + Args: + token (str): The GitHub token to use for authentication. + + Returns: + Github: A GitHub instance. + """ + auth = Auth.Token(token) + return Github(auth=auth) + + +def _get_pr(token: str, owner: str, repo: str, pr_number: int): + """Get the PR object from GitHub. + + Args: + token (str): The GitHub token to use for authentication. + owner (str): The GitHub owner (organization) name. + repo (str): The GitHub repository name (e.g. 'edk2'). + pr_number (int): The pull request number. + + Returns: + PullRequest: A PyGithub PullRequest object for the given pull request + or None if the attempt to get the PR fails. + """ + try: + g = _authenticate(token) + return g.get_repo(f"{owner}/{repo}").get_pull(pr_number) + except GithubException as ge: + print( + f"::error title=Error Getting PR {pr_number} Info!::" + f"{ge.data['message']}" + ) + return None + + def leave_pr_comment( - token: str, owner: str, repo: str, pr_number: str, comment_body: str + token: str, owner: str, repo: str, pr_number: int, comment_body: str ): """Leaves a comment on a PR. @@ -27,17 +69,17 @@ def leave_pr_comment( token (str): The GitHub token to use for authentication. owner (str): The GitHub owner (organization) name. repo (str): The GitHub repository name (e.g. 'edk2'). - pr_number (str): The pull request number. + pr_number (int): The pull request number. comment_body (str): The comment text. Markdown is supported. """ - url = f"https://api.github.com/repos/{owner}/{repo}/issues/{pr_number}/comments" - headers = { - "Authorization": f"Bearer {token}", - "Accept": "application/vnd.github.v3+json", - } - data = {"body": comment_body} - response = requests.post(url, json=data, headers=headers) - response.raise_for_status() + if pr := _get_pr(token, owner, repo, pr_number): + try: + pr.create_issue_comment(comment_body) + except GithubException as ge: + print( + f"::error title=Error Commenting on PR {pr_number}!::" + f"{ge.data['message']}" + ) def get_reviewers_for_range( @@ -106,7 +148,7 @@ def get_reviewers_for_range( return reviewers -def get_pr_sha(token: str, owner: str, repo: str, pr_number: str) -> str: +def get_pr_sha(token: str, owner: str, repo: str, pr_number: int) -> str: """Returns the commit SHA of given PR branch. This returns the SHA of the merge commit that GitHub creates from a @@ -117,31 +159,18 @@ def get_pr_sha(token: str, owner: str, repo: str, pr_number: str) -> str: token (str): The GitHub token to use for authentication. owner (str): The GitHub owner (organization) name. repo (str): The GitHub repository name (e.g. 'edk2'). - pr_number (str): The pull request number. + pr_number (int): The pull request number. Returns: str: The commit SHA of the PR branch. An empty string is returned if the request fails. """ - url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" - headers = { - "Authorization": f"Bearer {token}", - "Accept": "application/vnd.github.v3+json", - } - response = requests.get(url, headers=headers) - try: - response.raise_for_status() - except requests.exceptions.HTTPError: - print( - f"::error title=HTTP Error!::Error getting PR Commit Info: {response.reason}" - ) - return "" - - commit_sha = response.json()["merge_commit_sha"] - - print(f"::debug title=PR {pr_number} Commit SHA::{commit_sha}") + if pr := _get_pr(token, owner, repo, pr_number): + merge_commit_sha = pr.merge_commit_sha + print(f"::debug title=PR {pr_number} Merge Commit SHA::{merge_commit_sha}") + return merge_commit_sha - return commit_sha + return "" def download_gh_file(github_url: str, local_path: str, token=None): @@ -171,57 +200,58 @@ def download_gh_file(github_url: str, local_path: str, token=None): def add_reviewers_to_pr( - token: str, owner: str, repo: str, pr_number: str, user_names: List[str] -): + token: str, owner: str, repo: str, pr_number: int, user_names: List[str] +) -> List[str]: """Adds the set of GitHub usernames as reviewers to the PR. Args: token (str): The GitHub token to use for authentication. owner (str): The GitHub owner (organization) name. repo (str): The GitHub repository name (e.g. 'edk2'). - pr_number (str): The pull request number. + pr_number (int): The pull request number. user_names (List[str]): List of GitHub usernames to add as reviewers. + + Returns: + List[str]: A list of GitHub usernames that were successfully added as + reviewers to the PR. This list will exclude any reviewers + from the list provided if they are not relevant to the PR. """ - headers = { - "Authorization": f"Bearer {token}", - "Accept": "application/vnd.github.v3+json", - } - pr_author_url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" - url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/requested_reviewers" - - response = requests.get(pr_author_url, headers=headers) - if response.status_code != 200: - print(f"::error title=HTTP Error!::Error getting PR author: {response.reason}") - return - pr_author = response.json().get("user").get("login").strip() + try: + g = _authenticate(token) + repo_gh = g.get_repo(f"{owner}/{repo}") + pr = repo_gh.get_pull(pr_number) + except GithubException as ge: + print( + f"::error title=Error Getting PR {pr_number} Info!::" + f"{ge.data['message']}" + ) + return None + + pr_author = pr.user.login.strip() + while pr_author in user_names: user_names.remove(pr_author) - data = {"reviewers": user_names} - response = requests.post(url, json=data, headers=headers) - try: - response.raise_for_status() - except requests.exceptions.HTTPError: - if ( - response.status_code == 422 - and "Reviews may only be requested from collaborators" - in response.json().get("message") - ): - print( - f"::error title=User is not a Collaborator!::{response.json().get('message')}" - ) - leave_pr_comment( - token, - owner, - repo, - pr_number, - f"⚠ **WARNING: Cannot add reviewers**: A user specified as a " - f"reviewer for this PR is not a collaborator " - f"of the edk2 repository. Please add them as a collaborator to the " - f"repository and re-request the review.\n\n" - f"Users requested:\n{', '.join(user_names)}", - ) - elif response.status_code == 422: - print( - "::error title=Invalid Request!::The request is invalid. " - "Verify the API request string." + + repo_collaborators = [c.login.strip() for c in repo_gh.get_collaborators()] + non_collaborators = [u for u in user_names if u not in repo_collaborators] + + if non_collaborators: + print( + f"::error title=User is not a Collaborator!::{', '.join(non_collaborators)}" ) + + leave_pr_comment( + token, + owner, + repo, + pr_number, + f"⚠ **WARNING: Cannot add reviewers**: A user specified as a " + f"reviewer for this PR is not a collaborator " + f"of the edk2 repository. Please add them as a collaborator to the " + f"repository and re-request the review.\n\n" + f"Users requested:\n{', '.join(user_names)}", + ) + + pr.create_review_request(reviewers=user_names) + + return user_names diff --git a/.github/scripts/requirements.txt b/.github/scripts/requirements.txt index a1c2a3c672..44f0bdd335 100644 --- a/.github/scripts/requirements.txt +++ b/.github/scripts/requirements.txt @@ -10,4 +10,5 @@ edk2-pytool-library==0.* GitPython==3.* +PyGithub==2.* requests==2.* diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index e176a979e9..b358ae089f 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -74,7 +74,7 @@ jobs: WORKSPACE_PATH = os.environ['WORKSPACE_PATH'] GET_MAINTAINER_LOCAL_PATH = os.path.join(WORKSPACE_PATH, os.environ['GET_MAINTAINER_REL_PATH']) - pr_commit_sha = GitHub.get_pr_sha(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], os.environ['PR_NUMBER']) + pr_commit_sha = GitHub.get_pr_sha(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], int(os.environ['PR_NUMBER'])) if not pr_commit_sha: sys.exit(1) @@ -89,4 +89,4 @@ jobs: print(f"::notice title=Reviewer List::Reviewers found for PR {os.environ['PR_NUMBER']}:\n{', '.join(reviewers)}") - GitHub.add_reviewers_to_pr(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], os.environ['PR_NUMBER'], reviewers) + GitHub.add_reviewers_to_pr(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], int(os.environ['PR_NUMBER']), reviewers) -- cgit From eaf2b82eda199260022504a1a0f7966b0dd56944 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:44:04 -0400 Subject: .github/request-reviews.yml: Removed unused functionality Removed the `download_gh_file()` function which is no longer needed with sparse checkout. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 27 --------------------------- .github/scripts/requirements.txt | 1 - 2 files changed, 28 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index da9e94a84d..43eb5c7e4f 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -8,7 +8,6 @@ import git import logging import re -import requests from collections import OrderedDict from edk2toollib.utility_functions import RunPythonScript @@ -173,32 +172,6 @@ def get_pr_sha(token: str, owner: str, repo: str, pr_number: int) -> str: return "" -def download_gh_file(github_url: str, local_path: str, token=None): - """Downloads a file from GitHub. - - Args: - github_url (str): The GitHub raw file URL. - local_path (str): A local path to write the file contents to. - token (_type_, optional): A GitHub authentication token. - Only needed for a private repo. Defaults to None. - """ - headers = {} - if token: - headers["Authorization"] = f"Bearer {token}" - - try: - response = requests.get(github_url, headers=headers) - response.raise_for_status() - except requests.exceptions.HTTPError: - print( - f"::error title=HTTP Error!::Error downloading {github_url}: {response.reason}" - ) - return - - with open(local_path, "w", encoding="utf-8") as file: - file.write(response.text) - - def add_reviewers_to_pr( token: str, owner: str, repo: str, pr_number: int, user_names: List[str] ) -> List[str]: diff --git a/.github/scripts/requirements.txt b/.github/scripts/requirements.txt index 44f0bdd335..c589084ab0 100644 --- a/.github/scripts/requirements.txt +++ b/.github/scripts/requirements.txt @@ -11,4 +11,3 @@ edk2-pytool-library==0.* GitPython==3.* PyGithub==2.* -requests==2.* -- cgit From e86647decda974aff8a4356f67adc730eddea111 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:51:12 -0400 Subject: .github/request-reviews.yml: Update PR reviewer exclusion Updates logic to: - Not request reviews from reviewers that have already left a review on the PR. Previously, the reviewers review (e.g. approval) would remain on the PR, but they would be notified on each change to the PR. This approach follows the expected notification process for requesting reviews which is one time. Maintainers and reviewers can set up their own notifications for more granular updates on PR activity separately. - Add the collaborator reviewers if a reviewer(s) is found to not be a collaborator. This is an improvement to today's behavior which is to not add any reviewers if a single reviewer is not a collaborator of the repo. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 22 ++++++++++++++++++---- .github/workflows/request-reviews.yml | 31 +++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index 43eb5c7e4f..bc0f355206 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -202,12 +202,20 @@ def add_reviewers_to_pr( pr_author = pr.user.login.strip() - while pr_author in user_names: - user_names.remove(pr_author) + current_pr_requested_reviewers = [ + r.login.strip() for r in pr.get_review_requests()[0] + ] + current_pr_reviewed_reviewers = [r.user.login.strip() for r in pr.get_reviews()] + current_pr_reviewers = list( + set(current_pr_requested_reviewers + current_pr_reviewed_reviewers) + ) repo_collaborators = [c.login.strip() for c in repo_gh.get_collaborators()] non_collaborators = [u for u in user_names if u not in repo_collaborators] + excluded_pr_reviewers = [pr_author] + current_pr_reviewers + non_collaborators + new_pr_reviewers = [u for u in user_names if u not in excluded_pr_reviewers] + if non_collaborators: print( f"::error title=User is not a Collaborator!::{', '.join(non_collaborators)}" @@ -225,6 +233,12 @@ def add_reviewers_to_pr( f"Users requested:\n{', '.join(user_names)}", ) - pr.create_review_request(reviewers=user_names) + # Add any new reviewers to the PR if needed. + if new_pr_reviewers: + print( + f"::debug title=Adding New PR Reviewers::" f"{', '.join(new_pr_reviewers)}" + ) + + pr.create_review_request(reviewers=new_pr_reviewers) - return user_names + return new_pr_reviewers diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index b358ae089f..9b0d126649 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -84,9 +84,28 @@ jobs: reviewers = GitHub.get_reviewers_for_range(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha) if not reviewers: - print("::notice title=No Reviewers Found!::No reviewers found for this PR.") - sys.exit(1) - - print(f"::notice title=Reviewer List::Reviewers found for PR {os.environ['PR_NUMBER']}:\n{', '.join(reviewers)}") - - GitHub.add_reviewers_to_pr(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], int(os.environ['PR_NUMBER']), reviewers) + print("::notice title=No New Reviewers Found!::No reviewers found for this PR.") + sys.exit(0) + + print( + f"::notice title=Preliminary Reviewer List::Total reviewer candidates for " + f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}" + ) + + new_reviewers = GitHub.add_reviewers_to_pr( + os.environ["GH_TOKEN"], + os.environ["ORG_NAME"], + os.environ["REPO_NAME"], + int(os.environ["PR_NUMBER"]), + reviewers, + ) + if new_reviewers: + print( + f"::notice title=New Reviewers Added::New reviewers requested for PR " + f"{os.environ['PR_NUMBER']}: {', '.join(new_reviewers)}" + ) + else: + print( + "::notice title=No New Reviewers Added::No reviewers were found that " + "should be newly requested." + ) -- cgit From 09ad1a00729d53ba06e7f441eefc6fa364b10059 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:54:02 -0400 Subject: .github/request-reviews.yml: Add non-collab admin notification If a non-collaborator is part of the reviewer list, an admin needs to be notified so they can be removed. This change finds the list of admins for the repo and notifies them in the comment left on the PR describing the list of non-collaborator users. The message itself is cleaned up to show only the non-collaborator users for ease of identification. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index bc0f355206..5db2060ca9 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -221,16 +221,29 @@ def add_reviewers_to_pr( f"::error title=User is not a Collaborator!::{', '.join(non_collaborators)}" ) + repo_admins = [ + a.login for a in repo_gh.get_collaborators(permission="admin") + ] + leave_pr_comment( token, owner, repo, pr_number, - f"⚠ **WARNING: Cannot add reviewers**: A user specified as a " - f"reviewer for this PR is not a collaborator " - f"of the edk2 repository. Please add them as a collaborator to the " - f"repository and re-request the review.\n\n" - f"Users requested:\n{', '.join(user_names)}", + f"⚠ **WARNING: Cannot add some reviewers**: A user " + f"specified as a reviewer for this PR is not a collaborator " + f"of the repository. Please add them as a collaborator to " + f"the repository so they can be requested in the future.\n\n" + f"Non-collaborators requested:\n" + f"{'\n'.join([f'- @{c}' for c in non_collaborators])}" + f"\n\nAttn Admins:\n" + f"{'\n'.join([f'- @{a}' for a in repo_admins])}\n---\n" + f"**Admin Instructions:**\n" + f"- Add the non-collaborators as collaborators to the " + f"appropriate team(s) listed in " + f"[teams](https://github.com/orgs/tianocore/teams)\n" + f"- If they are no longer needed as reviewers, remove them " + f"from [`Maintainers.txt`](https://github.com/tianocore/edk2/blob/HEAD/Maintainers.txt)", ) # Add any new reviewers to the PR if needed. -- cgit From f617b6ee0eb81853b50fd50ea71dd1b2ceb9b9a5 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 18:54:55 -0400 Subject: .github/request-reviews.yml: Only post non-collab message once Enhances the flow that adds a comment on a PR if a non-collaborator is in the reviewer list by checking if a comment was previously left on the PR. If it was for the same set of non-collaborators, another comment is not created. If a new non-collaborator is discovered, the message will be left identifying that new user account. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 58 +++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index 5db2060ca9..6c755c2415 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -221,30 +221,40 @@ def add_reviewers_to_pr( f"::error title=User is not a Collaborator!::{', '.join(non_collaborators)}" ) - repo_admins = [ - a.login for a in repo_gh.get_collaborators(permission="admin") - ] - - leave_pr_comment( - token, - owner, - repo, - pr_number, - f"⚠ **WARNING: Cannot add some reviewers**: A user " - f"specified as a reviewer for this PR is not a collaborator " - f"of the repository. Please add them as a collaborator to " - f"the repository so they can be requested in the future.\n\n" - f"Non-collaborators requested:\n" - f"{'\n'.join([f'- @{c}' for c in non_collaborators])}" - f"\n\nAttn Admins:\n" - f"{'\n'.join([f'- @{a}' for a in repo_admins])}\n---\n" - f"**Admin Instructions:**\n" - f"- Add the non-collaborators as collaborators to the " - f"appropriate team(s) listed in " - f"[teams](https://github.com/orgs/tianocore/teams)\n" - f"- If they are no longer needed as reviewers, remove them " - f"from [`Maintainers.txt`](https://github.com/tianocore/edk2/blob/HEAD/Maintainers.txt)", - ) + for comment in pr.get_issue_comments(): + # If a comment has already been made for these non-collaborators, + # do not make another comment. + if ( + comment.user.login == "github-actions[bot]" + and "WARNING: Cannot add some reviewers" in comment.body + and all(u in comment.body for u in non_collaborators) + ): + break + else: + repo_admins = [ + a.login for a in repo_gh.get_collaborators(permission="admin") + ] + + leave_pr_comment( + token, + owner, + repo, + pr_number, + f"⚠ **WARNING: Cannot add some reviewers**: A user " + f"specified as a reviewer for this PR is not a collaborator " + f"of the repository. Please add them as a collaborator to " + f"the repository so they can be requested in the future.\n\n" + f"Non-collaborators requested:\n" + f"{'\n'.join([f'- @{c}' for c in non_collaborators])}" + f"\n\nAttn Admins:\n" + f"{'\n'.join([f'- @{a}' for a in repo_admins])}\n---\n" + f"**Admin Instructions:**\n" + f"- Add the non-collaborators as collaborators to the " + f"appropriate team(s) listed in " + f"[teams](https://github.com/orgs/tianocore/teams)\n" + f"- If they are no longer needed as reviewers, remove them " + f"from [`Maintainers.txt`](https://github.com/tianocore/edk2/blob/HEAD/Maintainers.txt)", + ) # Add any new reviewers to the PR if needed. if new_pr_reviewers: -- cgit From 32a099c358b3d4b093f76b2d060bcb3154ac5c56 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 19:04:06 -0400 Subject: .github/request-reviews.yml: Improve doc and dbg messages Adds additional documentation and cleans up debug messages printed to GitHub workflow output (available in the GitHub Actions pane). Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 26 ++++++++++++++++++++------ .github/workflows/request-reviews.yml | 5 +++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index 6c755c2415..ed39474064 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -89,8 +89,11 @@ def get_reviewers_for_range( ) -> List[str]: """Get the reviewers for the current branch. - To get the reviewers for a single commit, set `range_start` and - `range_end` to the commit SHA. + !!! note + This function accepts a range of commits and returns the reviewers + for that set of commits as a single list of GitHub usernames. To get + the reviewers for a single commit, set `range_start` and `range_end` + to the commit SHA. Args: workspace_path (str): The workspace path. @@ -150,9 +153,9 @@ def get_reviewers_for_range( def get_pr_sha(token: str, owner: str, repo: str, pr_number: int) -> str: """Returns the commit SHA of given PR branch. - This returns the SHA of the merge commit that GitHub creates from a - PR branch. This commit contains all of the files in the PR branch in - a single commit. + This returns the SHA of the merge commit that GitHub creates from a + PR branch. This commit contains all of the files in the PR branch in + a single commit. Args: token (str): The GitHub token to use for authentication. @@ -189,6 +192,13 @@ def add_reviewers_to_pr( reviewers to the PR. This list will exclude any reviewers from the list provided if they are not relevant to the PR. """ + if not user_names: + print( + "::debug title=No PR Reviewers Requested!::" + "The list of PR reviewers is empty so not adding any reviewers." + ) + return [] + try: g = _authenticate(token) repo_gh = g.get_repo(f"{owner}/{repo}") @@ -200,8 +210,10 @@ def add_reviewers_to_pr( ) return None + # The pull request author cannot be a reviewer. pr_author = pr.user.login.strip() + # The current PR reviewers do not need to be requested again. current_pr_requested_reviewers = [ r.login.strip() for r in pr.get_review_requests()[0] ] @@ -210,15 +222,17 @@ def add_reviewers_to_pr( set(current_pr_requested_reviewers + current_pr_reviewed_reviewers) ) + # A user can only be added if they are a collaborator of the repository. repo_collaborators = [c.login.strip() for c in repo_gh.get_collaborators()] non_collaborators = [u for u in user_names if u not in repo_collaborators] excluded_pr_reviewers = [pr_author] + current_pr_reviewers + non_collaborators new_pr_reviewers = [u for u in user_names if u not in excluded_pr_reviewers] + # Notify the admins of the repository if non-collaborators are requested. if non_collaborators: print( - f"::error title=User is not a Collaborator!::{', '.join(non_collaborators)}" + f"::warning title=Non-Collaborator Reviewers Found!::{', '.join(non_collaborators)}" ) for comment in pr.get_issue_comments(): diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index 9b0d126649..bd00dd4516 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -74,14 +74,17 @@ jobs: WORKSPACE_PATH = os.environ['WORKSPACE_PATH'] GET_MAINTAINER_LOCAL_PATH = os.path.join(WORKSPACE_PATH, os.environ['GET_MAINTAINER_REL_PATH']) + # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit) pr_commit_sha = GitHub.get_pr_sha(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], int(os.environ['PR_NUMBER'])) if not pr_commit_sha: sys.exit(1) print(f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}") + # Step 2: Fetch only the PR commit to get the files changed in the PR git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) + # Step 3: Get the list of reviewers for the PR reviewers = GitHub.get_reviewers_for_range(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha) if not reviewers: print("::notice title=No New Reviewers Found!::No reviewers found for this PR.") @@ -92,6 +95,8 @@ jobs: f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}" ) + # Step 4: Add the reviewers to the PR + # Note the final requested reviewer list in the workflow run for reference new_reviewers = GitHub.add_reviewers_to_pr( os.environ["GH_TOKEN"], os.environ["ORG_NAME"], -- cgit From 59ad8aeda6352e5da12aaab08ede719ac3a832e5 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Wed, 31 Jul 2024 19:06:24 -0400 Subject: .github/request-reviews.yml: Formatting (non-functional) Updates code for PEP8 formatting by using the Black code formatter. Signed-off-by: Michael Kubacki --- .github/scripts/GitHub.py | 12 ++++++++---- .github/workflows/request-reviews.yml | 24 ++++++++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py index ed39474064..628cd8412a 100644 --- a/.github/scripts/GitHub.py +++ b/.github/scripts/GitHub.py @@ -126,7 +126,9 @@ def get_reviewers_for_range( ) if cmd_ret != 0: print( - f"::error title=Reviewer Lookup Error!::Error calling GetMaintainer.py: [{cmd_ret}]: {reviewer_stream_buffer.getvalue()}" + f"::error title=Reviewer Lookup Error!::Error calling " + f"GetMaintainer.py: [{cmd_ret}]: " + f"{reviewer_stream_buffer.getvalue()}" ) return [] @@ -138,7 +140,8 @@ def get_reviewers_for_range( return [] print( - f"::debug title=Commit {commit_sha[:7]} Reviewer(s)::{', '.join(matches)}" + f"::debug title=Commit {commit_sha[:7]} " + f"Reviewer(s)::{', '.join(matches)}" ) raw_reviewers.extend(matches) @@ -232,8 +235,9 @@ def add_reviewers_to_pr( # Notify the admins of the repository if non-collaborators are requested. if non_collaborators: print( - f"::warning title=Non-Collaborator Reviewers Found!::{', '.join(non_collaborators)}" - ) + f"::warning title=Non-Collaborator Reviewers Found!::" + f"{', '.join(non_collaborators)}" + ) for comment in pr.get_issue_comments(): # If a comment has already been made for these non-collaborators, diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index bd00dd4516..15de2cb0e5 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -68,24 +68,36 @@ jobs: import git import os import sys - sys.path.append(os.path.join(os.environ['WORKSPACE_PATH'], ".github")) + + sys.path.append(os.path.join(os.environ["WORKSPACE_PATH"], ".github")) from scripts import GitHub - WORKSPACE_PATH = os.environ['WORKSPACE_PATH'] - GET_MAINTAINER_LOCAL_PATH = os.path.join(WORKSPACE_PATH, os.environ['GET_MAINTAINER_REL_PATH']) + WORKSPACE_PATH = os.environ["WORKSPACE_PATH"] + GET_MAINTAINER_LOCAL_PATH = os.path.join( + WORKSPACE_PATH, os.environ["GET_MAINTAINER_REL_PATH"] + ) # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit) - pr_commit_sha = GitHub.get_pr_sha(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], int(os.environ['PR_NUMBER'])) + pr_commit_sha = GitHub.get_pr_sha( + os.environ["GH_TOKEN"], + os.environ["ORG_NAME"], + os.environ["REPO_NAME"], + int(os.environ["PR_NUMBER"]), + ) if not pr_commit_sha: sys.exit(1) - print(f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}") + print( + f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}" + ) # Step 2: Fetch only the PR commit to get the files changed in the PR git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) # Step 3: Get the list of reviewers for the PR - reviewers = GitHub.get_reviewers_for_range(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha) + reviewers = GitHub.get_reviewers_for_range( + WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha + ) if not reviewers: print("::notice title=No New Reviewers Found!::No reviewers found for this PR.") sys.exit(0) -- cgit From 51ada84cd57c5ef6c75a72aeb002226cf9180b21 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 2 Aug 2024 15:35:08 -0400 Subject: .github/request-reviews.yml: Move workflow Py code to file To make the Python code used within the action more mantainable over time, it is moved to a standalone script in .github/scripts. No functional changes are made to the workflow itself. Signed-off-by: Michael Kubacki --- .github/scripts/RequestPrReviewers.py | 98 +++++++++++++++++++++++++++++++++++ .github/workflows/request-reviews.yml | 64 +---------------------- 2 files changed, 99 insertions(+), 63 deletions(-) create mode 100644 .github/scripts/RequestPrReviewers.py diff --git a/.github/scripts/RequestPrReviewers.py b/.github/scripts/RequestPrReviewers.py new file mode 100644 index 0000000000..fdff657617 --- /dev/null +++ b/.github/scripts/RequestPrReviewers.py @@ -0,0 +1,98 @@ +## @file +# Used in a CI workflow to request reviewers for a pull request. +# +# Refer to the following link for a list of pre-defined GitHub workflow +# environment variables: +# https://docs.github.com/actions/reference/environment-variables +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import git +import GitHub +import os +import sys + + +"""Request Pull Request Reviewers Helpers""" + + +def request_pr_reviewers(): + """Request pull request reviewers for a GitHub PR. + + This function is intended to be used in a GitHub Actions workflow to + request reviewers for a pull request triggered by a GitHub event. The + function makes assumptions about GitHub workflow environment variables and + the pull request context in which it is run. + + The function will exit with a non-zero status indicating an error if a + critical error occurs during execution so the workflow fails. + + The following environment variables are expected to be set before calling + this function. The recommend GitHub context values are show for reference: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG_NAME: ${{ github.repository_owner }} + PR_NUMBER: ${{ github.event.number}} + REPO_NAME: ${{ github.event.pull_request.base.repo.name }} + TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} + WORKSPACE_PATH: ${{ github.workspace }} + """ + WORKSPACE_PATH = os.environ["WORKSPACE_PATH"] + GET_MAINTAINER_LOCAL_PATH = os.path.join( + WORKSPACE_PATH, os.environ["GET_MAINTAINER_REL_PATH"] + ) + + # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit) + pr_commit_sha = GitHub.get_pr_sha( + os.environ["GH_TOKEN"], + os.environ["ORG_NAME"], + os.environ["REPO_NAME"], + int(os.environ["PR_NUMBER"]), + ) + if not pr_commit_sha: + sys.exit(1) + + print( + f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}" + ) + + # Step 2: Fetch only the PR commit to get the files changed in the PR + git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) + + # Step 3: Get the list of reviewers for the PR + reviewers = GitHub.get_reviewers_for_range( + WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha + ) + if not reviewers: + print("::notice title=No New Reviewers Found!::No reviewers found for this PR.") + sys.exit(0) + + print( + f"::notice title=Preliminary Reviewer List::Total reviewer candidates for " + f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}" + ) + + # Step 4: Add the reviewers to the PR + # Note the final requested reviewer list in the workflow run for reference + new_reviewers = GitHub.add_reviewers_to_pr( + os.environ["GH_TOKEN"], + os.environ["ORG_NAME"], + os.environ["REPO_NAME"], + int(os.environ["PR_NUMBER"]), + reviewers, + ) + if new_reviewers: + print( + f"::notice title=New Reviewers Added::New reviewers requested for PR " + f"{os.environ['PR_NUMBER']}: {', '.join(new_reviewers)}" + ) + else: + print( + "::notice title=No New Reviewers Added::No reviewers were found that " + "should be newly requested." + ) + + +if __name__ == '__main__': + request_pr_reviewers() diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index 15de2cb0e5..13330561f2 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -56,7 +56,6 @@ jobs: run: pip install -r .github/scripts/requirements.txt --upgrade - name: Add Reviewers to Pull Request - shell: python env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} ORG_NAME: ${{ github.repository_owner }} @@ -64,65 +63,4 @@ jobs: REPO_NAME: ${{ github.event.pull_request.base.repo.name }} TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} WORKSPACE_PATH: ${{ github.workspace }} - run: | - import git - import os - import sys - - sys.path.append(os.path.join(os.environ["WORKSPACE_PATH"], ".github")) - from scripts import GitHub - - WORKSPACE_PATH = os.environ["WORKSPACE_PATH"] - GET_MAINTAINER_LOCAL_PATH = os.path.join( - WORKSPACE_PATH, os.environ["GET_MAINTAINER_REL_PATH"] - ) - - # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit) - pr_commit_sha = GitHub.get_pr_sha( - os.environ["GH_TOKEN"], - os.environ["ORG_NAME"], - os.environ["REPO_NAME"], - int(os.environ["PR_NUMBER"]), - ) - if not pr_commit_sha: - sys.exit(1) - - print( - f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}" - ) - - # Step 2: Fetch only the PR commit to get the files changed in the PR - git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) - - # Step 3: Get the list of reviewers for the PR - reviewers = GitHub.get_reviewers_for_range( - WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha - ) - if not reviewers: - print("::notice title=No New Reviewers Found!::No reviewers found for this PR.") - sys.exit(0) - - print( - f"::notice title=Preliminary Reviewer List::Total reviewer candidates for " - f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}" - ) - - # Step 4: Add the reviewers to the PR - # Note the final requested reviewer list in the workflow run for reference - new_reviewers = GitHub.add_reviewers_to_pr( - os.environ["GH_TOKEN"], - os.environ["ORG_NAME"], - os.environ["REPO_NAME"], - int(os.environ["PR_NUMBER"]), - reviewers, - ) - if new_reviewers: - print( - f"::notice title=New Reviewers Added::New reviewers requested for PR " - f"{os.environ['PR_NUMBER']}: {', '.join(new_reviewers)}" - ) - else: - print( - "::notice title=No New Reviewers Added::No reviewers were found that " - "should be newly requested." - ) + run: python .github/scripts/RequestPrReviewers.py -- cgit From 1b37b3659b5098f764dee5b893e4eb174949f40a Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 5 Aug 2024 19:21:17 -0400 Subject: .github/request-reviews.yml: Use GitHub App authentication Since the edk2 repository is owned by an organization, the default GitHub token will not be able to access the collaborator list. Therefore, a GitHub App with `metadata:read` permission will be used to grant access to that REST API. This is used in GitHub.py when it makes the `repo_gh.get_collaborators()` call that resolves to the `/repos/{owner}/{repo}/collaborators` GitHub REST API. Signed-off-by: Michael Kubacki --- .github/workflows/request-reviews.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index 13330561f2..e5db19ca08 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -32,6 +32,13 @@ jobs: pull-requests: write steps: + - name: Generate Token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.TIANOCORE_ASSIGN_REVIEWERS_APPLICATION_ID }} + private-key: ${{ secrets.TIANOCORE_ASSIGN_REVIEWERS_APPLICATION_PRIVATE_KEY }} + # Reduce checkout time with sparse-checkout # - .github: Contains the scripts to interact with Github and add reviewers # - BaseTools/Scripts: Contains the GetMaintainer.py script @@ -57,7 +64,7 @@ jobs: - name: Add Reviewers to Pull Request env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.generate-token.outputs.token }} ORG_NAME: ${{ github.repository_owner }} PR_NUMBER: ${{ github.event.number}} REPO_NAME: ${{ github.event.pull_request.base.repo.name }} -- cgit From 472be4d139b26c50949cf30eeb47640810e5ef2c Mon Sep 17 00:00:00 2001 From: John Schock Date: Fri, 26 May 2023 16:50:41 -0700 Subject: MdeModulePkg ConPlatform: Support IAD-style USB input devices. Some multi-function input devices (e.g. combo keyboard and mouse) present as IAD-style devices (https://www.usb.org/defined-class-codes, https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-interface-association-descriptor). Historically, multi-function devices would report a DeviceClass of 0, indicating that interface matching should be done on the interface descriptor rather than the global device descriptor. IAD-style devices us DeviceClass of 0xEF, so they don't match MatchUsbClass() for keyboard (DeviceClass=3, SubClass=1, Proto=1). If they are treated as if they had a DeviceClass of zero, which is more traditional for legacy multi-function devices, then the interface descriptors are used instead and these types of devices will "just work" without needing to add a custom USB device path to ConIn. Signed-off-by: Aaron Pop --- .../Universal/Console/ConPlatformDxe/ConPlatform.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c b/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c index 700ea9d5c0..a7f0225f30 100644 --- a/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c +++ b/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c @@ -27,6 +27,15 @@ EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = { NULL }; +// +// Values from Usb Inteface Association Descriptor Device +// Class Code and Usage Model specification (iadclasscode_r10.pdf) +// from Usb.org +// +#define USB_BASE_CLASS_MISCELLANEOUS 0xEF +#define USB_MISCELLANEOUS_SUBCLASS_COMMON 0x02 +#define USB_MISCELLANEOUS_PROTOCOL_IAD 0x01 + /** Entrypoint of this module. @@ -808,10 +817,16 @@ MatchUsbClass ( DeviceClass = DevDesc.DeviceClass; DeviceSubClass = DevDesc.DeviceSubClass; DeviceProtocol = DevDesc.DeviceProtocol; - if (DeviceClass == 0) { + + if ((DeviceClass == 0) || + ((DeviceClass == USB_BASE_CLASS_MISCELLANEOUS) && + (DeviceSubClass == USB_MISCELLANEOUS_SUBCLASS_COMMON) && + (DeviceProtocol == USB_MISCELLANEOUS_PROTOCOL_IAD))) + { // - // If Class in Device Descriptor is set to 0, use the Class, SubClass and - // Protocol in Interface Descriptor instead. + // If Class in Device Descriptor is set to 0 (Device), or + // Class/SubClass/Protocol is 0xEF/0x02/0x01 (IAD), use the Class, SubClass + // and Protocol in Interface Descriptor instead. // Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); if (EFI_ERROR (Status)) { -- cgit From a29a9cce5f9afa32560d966e501247246ec96ef6 Mon Sep 17 00:00:00 2001 From: kuqin12 <42554914+kuqin12@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:20:02 -0700 Subject: MdePkg/BaseLib: Add CRC16 CCITT False Implementation. This change is added to incorporate basic implementation for CRC16-CCITT-FALSE algorithm. This function is useful for providing CRC16 value used in other data structures that requires CRC16 value that complies with JEDEC SPD requirements, i.e. BDAT table. The lookup table is inherited from `https://crccalc.com/` and the result values are also compared against this site. Signed-off-by: Aaron Pop --- MdePkg/Include/Library/BaseLib.h | 17 ++++++++++ MdePkg/Library/BaseLib/CheckSum.c | 69 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index aec84c0184..eb817f131f 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -4987,6 +4987,23 @@ CalculateCrc32c ( IN UINT32 InitialValue ); +/** + Calculates the CRC16-CCITT-FALSE checksum of the given buffer. + + @param[in] Buffer Pointer to the buffer. + @param[in] Length Length of the buffer, in bytes. + @param[in] InitialValue Initial value of the CRC. + + @return The CRC16-CCITT-FALSE checksum. +**/ +UINT16 +EFIAPI +CalculateCrc16CcittF ( + IN CONST VOID *Buffer, + IN UINTN Length, + IN UINT16 InitialValue + ); + // // Base Library CPU Functions // diff --git a/MdePkg/Library/BaseLib/CheckSum.c b/MdePkg/Library/BaseLib/CheckSum.c index 57d324c82b..1c82a534d0 100644 --- a/MdePkg/Library/BaseLib/CheckSum.c +++ b/MdePkg/Library/BaseLib/CheckSum.c @@ -762,3 +762,72 @@ CalculateCrc32c ( return ~Crc; } + +// The lookup table is inherited from [https://crccalc.com/](https://crccalc.com/%60) +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT16 mCrc16CcittFLookupTable[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +}; + +/** + Calculates the CRC16-CCITT-FALSE checksum of the given buffer. + + @param[in] Buffer Pointer to the buffer. + @param[in] Length Length of the buffer, in bytes. + @param[in] InitialValue Initial value of the CRC. + + @return The CRC16-CCITT-FALSE checksum. +**/ +UINT16 +EFIAPI +CalculateCrc16CcittF ( + IN CONST VOID *Buffer, + IN UINTN Length, + IN UINT16 InitialValue + ) +{ + CONST UINT8 *Buf; + UINT16 Crc; + + ASSERT (Buffer != NULL); + ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1)); + + Buf = Buffer; + Crc = InitialValue; + + while (Length-- != 0) { + Crc = mCrc16CcittFLookupTable[((Crc >> 8) ^ *(Buf++)) & 0xFF] ^ (Crc << 8); + } + + return Crc; +} -- cgit From 976113774320e5f18bb5bd6f21dd062c1d74f3d4 Mon Sep 17 00:00:00 2001 From: Igor Kulchytskyy <116655144+igorkulchytskyy@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:50:45 -0400 Subject: RedfishPkg: Allow deletion of the bootstrap account Extending the Redfish Credential protocol to allow Redfish Clients to be registered/unregistered for tracking their end of work and delete a bootstrap account when all registered Redfish clients finish their communication with Redfish service. Redfish Http module also was updated to register/unregister clients on Redfish Service creation/stop event. Cc: Abner Chang Cc: Nickle Wang Signed-off-by: Igor Kulchytskyy --- .../Include/Protocol/EdkIIRedfishCredential2.h | 128 ++++ .../RedfishCredentialDxe/RedfishCredentialDxe.c | 798 ++++++++++++++++++++- .../RedfishCredentialDxe/RedfishCredentialDxe.h | 87 +-- .../RedfishCredentialDxe/RedfishCredentialDxe.inf | 9 + RedfishPkg/RedfishHttpDxe/RedfishHttpData.h | 16 +- RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c | 38 +- RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h | 2 +- RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf | 2 +- RedfishPkg/RedfishPkg.dec | 7 + 9 files changed, 999 insertions(+), 88 deletions(-) create mode 100644 RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h b/RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h new file mode 100644 index 0000000000..b2b3799bd1 --- /dev/null +++ b/RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h @@ -0,0 +1,128 @@ +/** @file + This file defines the EDKII_REDFISH_CREDENTIAL2_PROTOCOL interface. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ (C) Copyright 2024 American Megatrends International LLC
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDKII_REDFISH_CREDENTIAL2_H_ +#define EDKII_REDFISH_CREDENTIAL2_H_ + +#include +#include + +typedef struct _EDKII_REDFISH_CREDENTIAL2_PROTOCOL EDKII_REDFISH_CREDENTIAL2_PROTOCOL; + +#define REDFISH_CREDENTIAL_PROTOCOL_REVISION 0x00010000 + +#define EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GUID \ + { \ + 0x936b81dc, 0x348c, 0x42e3, { 0x9e, 0x82, 0x2, 0x91, 0x4f, 0xd3, 0x48, 0x86 } \ + } + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GET_AUTH_INFO)( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ); + +/** + Notifies the Redfish service provider to stop providing configuration service to this platform. + Deletes the bootstrap account on BMC side, so it will not be used by any other driver. + + This function should be called when the platfrom is about to leave the safe environment. + It will delete the bootstrap account sending DELETE request to BMC. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stopped successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_STOP_SERVICE)( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType + ); + +/** + Register Redfish service instance so protocol knows that some module uses bootstrap account . + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance. + @param[in] RedfishService Redfish service instance to register. + + @retval EFI_SUCCESS This Redfish service instance has been registered successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_REGISTER_REDFISH_SERVICE)( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + IN REDFISH_SERVICE RedfishService + ); + +/** + Unregister Redfish service instance and delete the bootstrap account + when all registered services unregistered. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance. + @param[in] RedfishService Redfish service instance to unregister. + + @retval EFI_SUCCESS This Redfish service instance has been unregistered successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_UNREGISTER_REDFISH_SERVICE)( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + IN REDFISH_SERVICE RedfishService + ); + +struct _EDKII_REDFISH_CREDENTIAL2_PROTOCOL { + UINT64 Revision; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GET_AUTH_INFO GetAuthInfo; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL_STOP_SERVICE StopService; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL_REGISTER_REDFISH_SERVICE RegisterRedfishService; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL_UNREGISTER_REDFISH_SERVICE UnregisterRedfishService; +}; + +extern EFI_GUID gEdkIIRedfishCredential2ProtocolGuid; + +#endif diff --git a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c index 91bffa8067..23201e1dc8 100644 --- a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c +++ b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c @@ -3,6 +3,7 @@ to get the Redfish credential Info and to restrict Redfish access from UEFI side. (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ (C) Copyright 2024 American Megatrends International LLC
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,10 +11,9 @@ #include -EDKII_REDFISH_CREDENTIAL_PROTOCOL mRedfishCredentialProtocol = { - RedfishCredentialGetAuthInfo, - RedfishCredentialStopService -}; +#define REDFISH_VERSION_DEFAULT_STRING L"v1" + +REDFISH_CREDENTIAL_PRIVATE *mCredentialPrivate = NULL; /** Callback function executed when the ExitBootServices event group is signaled. @@ -52,6 +52,15 @@ RedfishCredentialEndOfDxeEventNotify ( gBS->CloseEvent (Event); } +EFI_STATUS +ReleaseCredentialPrivate ( + ); + +EFI_STATUS +IterateThroughBootstrapAccounts ( + IN REDFISH_SERVICE RedfishService + ); + /** Retrieve platform's Redfish authentication information. @@ -93,7 +102,7 @@ RedfishCredentialGetAuthInfo ( } /** - Notify the Redfish service provide to stop provide configuration service to this platform. + Notify the Redfish service provider to stop provide configuration service to this platform. This function should be called when the platfrom is about to leave the safe environment. It will notify the Redfish service provider to abort all logined session, and prohibit @@ -123,6 +132,668 @@ RedfishCredentialStopService ( return LibStopRedfishService (This, ServiceStopType); } +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +EFI_STATUS +EFIAPI +RedfishCredential2GetAuthInfo ( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ) +{ + EFI_STATUS Status; + + if ((AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo ( + &mCredentialPrivate->RedfishCredentialProtocol, + AuthMethod, + UserId, + Password + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to retrieve Redfish credential - %r\n", __func__, Status)); + } + + return Status; +} + +/** + Notifies the Redfish service provider to stop providing configuration service to this platform. + Deletes the bootstrap account on BMC side, so it will not be used by any other driver. + + This function should be called when the platfrom is about to leave the safe environment. + It will delete the bootstrap account sending DELETE request to BMC. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL or given the worng ServiceStopType. + @retval EFI_UNSUPPORTED Not support to stop Redfish service. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishCredential2StopService ( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType + ) +{ + EFI_STATUS Status; + REDFISH_SERVICE_LIST *Instance; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + if ((ServiceStopType == ServiceStopTypeExitBootService) || + (ServiceStopType == ServiceStopTypeNone)) + { + // Check PCD and skip the action if platform library is responsible for deleting account + // on exit boot service event + if (FixedPcdGetBool (PcdRedfishCredentialDeleteAccount)) { + if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) { + Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList); + IterateThroughBootstrapAccounts (Instance->RedfishService); + } + + ReleaseCredentialPrivate (); + } + } + + Status = mCredentialPrivate->RedfishCredentialProtocol.StopService ( + &mCredentialPrivate->RedfishCredentialProtocol, + ServiceStopType + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status)); + } + + return Status; +} + +/** + Function sends DELETE request to BMC for the account defined by the target URI. + + @param[in] RedfishService Pointer to Redfish Service to be used + for sending DELETE request to BMC. + @param[in] TargetUri URI of bootstrap account to send DELETE request to. + +**/ +EFI_STATUS +EFIAPI +DeleteRedfishBootstrapAccount ( + IN REDFISH_SERVICE RedfishService, + IN CHAR16 *TargetUri + ) +{ + EFI_STATUS Status; + REDFISH_RESPONSE RedfishResponse; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic)) { + DEBUG ((DEBUG_ERROR, "%a: Redfish service is not available\n", __func__)); + return EFI_INVALID_PARAMETER; + } + + // + // Remove bootstrap account at /redfish/v1/AccountService/AccountId + // + ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE)); + Status = RedfishHttpDeleteResourceEx ( + RedfishService, + TargetUri, + "{}", + 2, + NULL, + &RedfishResponse + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: can not remove bootstrap account at BMC: %r", __func__, Status)); + DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse); + } else { + DEBUG ( + (REDFISH_CREDENTIAL_DEBUG, "%a: bootstrap account: %a is removed from: %s\nURI - %s", + __func__, mCredentialPrivate->AccountName, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI, TargetUri) + ); + } + + RedfishHttpFreeResponse (&RedfishResponse); + + return Status; +} + +/** + Get the information about specific Account. + Checks the User Name and if name matches delete that account + + + @param[in] RedfishService Pointer to Redfish Service to be used + for sending DELETE request to BMC. + @param[in] AccountUri URI of bootstrap account to verify. + +**/ +BOOLEAN +ProcessRedfishBootstarpAccount ( + IN REDFISH_SERVICE RedfishService, + IN EFI_STRING AccountUri + ) +{ + EDKII_JSON_VALUE JsonUserName; + EDKII_JSON_VALUE JsonValue; + EFI_STATUS Status; + REDFISH_RESPONSE RedfishResponse; + REDFISH_REQUEST RedfishRequest; + BOOLEAN Ret; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return FALSE; + } + + if ((RedfishService == NULL) || IS_EMPTY_STRING (AccountUri) || + (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic)) + { + return FALSE; + } + + ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE)); + ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST)); + Status = RedfishHttpGetResource (RedfishService, AccountUri, &RedfishRequest, &RedfishResponse, FALSE); + if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: can not get account from BMC: %r", __func__, Status)); + DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse); + return FALSE; + } + + Ret = FALSE; + JsonValue = RedfishJsonInPayload (RedfishResponse.Payload); + if (JsonValueIsObject (JsonValue)) { + JsonUserName = JsonObjectGetValue (JsonValueGetObject (JsonValue), "UserName"); + if (JsonValueIsString (JsonUserName) && (JsonValueGetAsciiString (JsonUserName) != NULL)) { + if (AsciiStrCmp (mCredentialPrivate->AccountName, JsonValueGetAsciiString (JsonUserName)) == 0) { + DeleteRedfishBootstrapAccount (RedfishService, AccountUri); + Ret = TRUE; + } + } + } + + RedfishHttpFreeResponse (&RedfishResponse); + RedfishHttpFreeRequest (&RedfishRequest); + + return Ret; +} + +/** + This function returns the string of Redfish service version. + + @param[out] ServiceVersionStr Redfish service string. + + @return EFI_STATUS + +**/ +EFI_STATUS +RedfishGetServiceVersion ( + OUT CHAR16 **ServiceVersionStr + ) +{ + *ServiceVersionStr = (CHAR16 *)PcdGetPtr (PcdDefaultRedfishVersion); + if (*ServiceVersionStr == NULL) { + *ServiceVersionStr = REDFISH_VERSION_DEFAULT_STRING; + } + + return EFI_SUCCESS; +} + +/** + Iterates through all account in the account collection + Get the information about specific Account. + Checks the User Name and if name matches delete that account + + + @param[in] RedfishService Pointer to Redfish Service to be used + for sending DELETE request to BMC. + +**/ +EFI_STATUS +IterateThroughBootstrapAccounts ( + IN REDFISH_SERVICE RedfishService + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonMembers; + EDKII_JSON_VALUE JsonValue; + EDKII_JSON_VALUE OdataId; + CHAR16 TargetUri[REDFISH_URI_LENGTH]; + CHAR16 *RedfishVersion; + REDFISH_RESPONSE RedfishResponse; + REDFISH_REQUEST RedfishRequest; + UINTN MembersCount, Index; + + RedfishVersion = NULL; + Status = EFI_NOT_FOUND; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) || + IS_EMPTY_STRING (mCredentialPrivate->AccountName)) + { + return EFI_INVALID_PARAMETER; + } + + // + // Carving the URI + // + + Status = RedfishGetServiceVersion (&RedfishVersion); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: can not get Redfish version\n", __func__)); + return Status; + } + + UnicodeSPrint ( + TargetUri, + (sizeof (CHAR16) * REDFISH_URI_LENGTH), + L"/redfish/%s/%s", + RedfishVersion, + REDFISH_MANAGER_ACCOUNT_COLLECTION_URI + ); + + DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account collection URI: %s\n", __func__, TargetUri)); + + ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE)); + ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST)); + Status = RedfishHttpGetResource (RedfishService, TargetUri, &RedfishRequest, &RedfishResponse, FALSE); + if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: can not get accounts from BMC: %r\n", __func__, Status)); + DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse); + return Status; + } + + JsonValue = RedfishJsonInPayload (RedfishResponse.Payload); + if (!JsonValueIsObject (JsonValue)) { + Status = EFI_LOAD_ERROR; + goto ON_EXIT; + } + + JsonMembers = JsonObjectGetValue (JsonValueGetObject (JsonValue), "Members"); + if (!JsonValueIsArray (JsonMembers)) { + Status = EFI_LOAD_ERROR; + goto ON_EXIT; + } + + Status = EFI_NOT_FOUND; + + MembersCount = JsonArrayCount (JsonValueGetArray (JsonMembers)); + for (Index = 0; Index < MembersCount; Index++) { + JsonValue = JsonArrayGetValue (JsonValueGetArray (JsonMembers), Index); + if (!JsonValueIsObject (JsonValue)) { + Status = EFI_LOAD_ERROR; + goto ON_EXIT; + } + + OdataId = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.id"); + if (!JsonValueIsString (OdataId) || (JsonValueGetAsciiString (OdataId) == NULL)) { + Status = EFI_LOAD_ERROR; + goto ON_EXIT; + } + + UnicodeSPrint ( + TargetUri, + (sizeof (CHAR16) * REDFISH_URI_LENGTH), + L"%a", + JsonValueGetAsciiString (OdataId) + ); + DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account URI: %s\n", __func__, TargetUri)); + // Verify bootstrap account User Name and delete the account if User Name matches + if (ProcessRedfishBootstarpAccount (RedfishService, TargetUri)) { + Status = EFI_SUCCESS; + break; + } + } + +ON_EXIT: + + RedfishHttpFreeResponse (&RedfishResponse); + RedfishHttpFreeRequest (&RedfishRequest); + + return Status; +} + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id. + For AuthMethodNone, UserId will point to NULL which means authentication + is not required to access the Redfish service. + Callers are responsible for freeing the returned string storage pointed by UserId. + + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_INVALID_PARAMETER AuthMethod or UserId or Password is NULL. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. +**/ +EFI_STATUS +RedfishGetAuthConfig ( + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId + ) +{ + EFI_STATUS Status; + CHAR8 *Password; + + Password = NULL; + + if ((AuthMethod == NULL) || (UserId == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo ( + &mCredentialPrivate->RedfishCredentialProtocol, + AuthMethod, + UserId, + &Password + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to retrieve Redfish credential - %r\n", __func__, Status)); + return Status; + } + + if (Password != NULL) { + ZeroMem (Password, AsciiStrSize (Password)); + FreePool (Password); + } + + return Status; +} + +/** + This function clears Redfish service internal list. + + @retval EFI_SUCCESS Redfish service is deleted from list successfully. + @retval Others Fail to remove the entry + +**/ +EFI_STATUS +ClearRedfishServiceList ( + ) +{ + REDFISH_SERVICE_LIST *Instance; + REDFISH_SERVICE_LIST *NextInstance; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) { + // + // Free memory of REDFISH_SERVICE_LIST instance. + // + Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList); + do { + NextInstance = NULL; + if (!IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &Instance->NextInstance)) { + NextInstance = (REDFISH_SERVICE_LIST *)GetNextNode ( + &mCredentialPrivate->RedfishServiceList, + &Instance->NextInstance + ); + } + + RemoveEntryList (&Instance->NextInstance); + FreePool ((VOID *)Instance); + Instance = NextInstance; + } while (Instance != NULL); + } + + return EFI_SUCCESS; +} + +/** + The function adds a new Redfish service to internal list + + @param[in] RedfishService Pointer to REDFISH_SERVICE to be added to the list. + + @retval EFI_SUCCESS Redfish service is added to list successfully. + @retval EFI_OUT_OF_RESOURCES Out of resources error. +**/ +EFI_STATUS +AddRedfishServiceToList ( + IN REDFISH_SERVICE RedfishService + ) +{ + BOOLEAN ServiceFound; + REDFISH_SERVICE_LIST *RedfishServiceInstance; + + RedfishServiceInstance = NULL; + ServiceFound = FALSE; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) { + RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList); + do { + if (RedfishServiceInstance->RedfishService == RedfishService) { + ServiceFound = TRUE; + break; + } + + if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) { + break; + } + + RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode ( + &mCredentialPrivate->RedfishServiceList, + &RedfishServiceInstance->NextInstance + ); + } while (TRUE); + } + + if (!ServiceFound) { + RedfishServiceInstance = (REDFISH_SERVICE_LIST *)AllocateZeroPool (sizeof (REDFISH_SERVICE_LIST)); + if (RedfishServiceInstance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RedfishServiceInstance->RedfishService = RedfishService; + InsertTailList (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance); + } + + return EFI_SUCCESS; +} + +/** + This function deletes Redfish service from internal list. + + @param[in] RedfishService Pointer to REDFISH_SERVICE to be delete from the list. + + @retval EFI_SUCCESS Redfish service is deleted from list successfully. + @retval Others Fail to remove the entry + +**/ +EFI_STATUS +DeleteRedfishServiceFromList ( + IN REDFISH_SERVICE RedfishService + ) +{ + REDFISH_SERVICE_LIST *RedfishServiceInstance; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) { + RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList); + do { + if (RedfishServiceInstance->RedfishService == RedfishService) { + RemoveEntryList (&RedfishServiceInstance->NextInstance); + FreePool (RedfishServiceInstance); + return EFI_SUCCESS; + } + + if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) { + break; + } + + RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance); + } while (TRUE); + } + + return EFI_NOT_FOUND; +} + +/** + Register Redfish service instance so protocol knows that some module uses bootstrap account. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] RedfishService Redfish service instance to register. + + @retval EFI_SUCCESS This Redfish service instance has been registered successfully. + @retval Others Fail to register Redfish Service + +**/ +EFI_STATUS +EFIAPI +RedfishCredential2RegisterService ( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + IN REDFISH_SERVICE RedfishService + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + if (mCredentialPrivate == NULL) { + DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED)); + return EFI_NOT_STARTED; + } + + // Check if AuthMethod has been initialized yet + if (mCredentialPrivate->AuthMethod == AuthMethodMax) { + Status = RedfishGetAuthConfig ( + &mCredentialPrivate->AuthMethod, + &mCredentialPrivate->AccountName + ); + } + + // Bootstrap account should be deleted only if Basic Authentication is used. + if (!EFI_ERROR (Status) && (mCredentialPrivate->AuthMethod == AuthMethodHttpBasic)) { + Status = AddRedfishServiceToList (RedfishService); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status)); + } + } + + return Status; +} + +/** + Unregister Redfish service instance and delete the bootstrap account + when all registered services unregistered. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] RedfishService Redfish service instance to unregister. + + @retval EFI_SUCCESS This Redfish service instance has been unregistered successfully. + @retval Others Fail to unregister Redfish Service + +**/ +EFI_STATUS +EFIAPI +RedfishCredential2UnregisterService ( + IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This, + IN REDFISH_SERVICE RedfishService + ) +{ + EFI_STATUS Status; + + // Bootstrap account should be deleted only if Basic Authentication is used. + if (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) { + return EFI_SUCCESS; + } + + // Delete Redfish Service from the registered list + Status = DeleteRedfishServiceFromList (RedfishService); + // Check if registered list is empty + if (IsListEmpty (&mCredentialPrivate->RedfishServiceList)) { + // Iterate through all accounts in the account collection and delete the bootstrap account + Status = IterateThroughBootstrapAccounts (RedfishService); + if (!EFI_ERROR (Status)) { + if (mCredentialPrivate->AccountName != NULL) { + ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName)); + FreePool (mCredentialPrivate->AccountName); + mCredentialPrivate->AccountName = NULL; + } + + mCredentialPrivate->AuthMethod = AuthMethodMax; + Status = mCredentialPrivate->RedfishCredentialProtocol.StopService ( + &mCredentialPrivate->RedfishCredentialProtocol, + ServiceStopTypeNone + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status)); + } + } + } + + return Status; +} + /** Main entry for this driver. @@ -140,19 +811,33 @@ RedfishCredentialDxeDriverEntryPoint ( ) { EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_EVENT EndOfDxeEvent; - EFI_EVENT ExitBootServiceEvent; - Handle = NULL; + mCredentialPrivate = (REDFISH_CREDENTIAL_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_CREDENTIAL_PRIVATE)); + if (mCredentialPrivate == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mCredentialPrivate->AuthMethod = AuthMethodMax; + InitializeListHead (&mCredentialPrivate->RedfishServiceList); + + mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo = RedfishCredentialGetAuthInfo; + mCredentialPrivate->RedfishCredentialProtocol.StopService = RedfishCredentialStopService; + + mCredentialPrivate->RedfishCredential2Protocol.Revision = REDFISH_CREDENTIAL_PROTOCOL_REVISION; + mCredentialPrivate->RedfishCredential2Protocol.GetAuthInfo = RedfishCredential2GetAuthInfo; + mCredentialPrivate->RedfishCredential2Protocol.StopService = RedfishCredential2StopService; + mCredentialPrivate->RedfishCredential2Protocol.RegisterRedfishService = RedfishCredential2RegisterService; + mCredentialPrivate->RedfishCredential2Protocol.UnregisterRedfishService = RedfishCredential2UnregisterService; // // Install the RedfishCredentialProtocol onto Handle. // Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, + &mCredentialPrivate->Handle, &gEdkIIRedfishCredentialProtocolGuid, - &mRedfishCredentialProtocol, + &mCredentialPrivate->RedfishCredentialProtocol, + &gEdkIIRedfishCredential2ProtocolGuid, + &mCredentialPrivate->RedfishCredential2Protocol, NULL ); if (EFI_ERROR (Status)) { @@ -169,9 +854,9 @@ RedfishCredentialDxeDriverEntryPoint ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RedfishCredentialEndOfDxeEventNotify, - (VOID *)&mRedfishCredentialProtocol, + (VOID *)&mCredentialPrivate->RedfishCredentialProtocol, &gEfiEndOfDxeEventGroupGuid, - &EndOfDxeEvent + &mCredentialPrivate->EndOfDxeEvent ); if (EFI_ERROR (Status)) { goto ON_ERROR; @@ -185,12 +870,13 @@ RedfishCredentialDxeDriverEntryPoint ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RedfishCredentialExitBootServicesEventNotify, - (VOID *)&mRedfishCredentialProtocol, + (VOID *)&mCredentialPrivate->RedfishCredentialProtocol, &gEfiEventExitBootServicesGuid, - &ExitBootServiceEvent + &mCredentialPrivate->ExitBootServiceEvent ); if (EFI_ERROR (Status)) { - gBS->CloseEvent (EndOfDxeEvent); + gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent); + mCredentialPrivate->EndOfDxeEvent = NULL; goto ON_ERROR; } @@ -199,11 +885,87 @@ RedfishCredentialDxeDriverEntryPoint ( ON_ERROR: gBS->UninstallMultipleProtocolInterfaces ( - Handle, + mCredentialPrivate->Handle, &gEdkIIRedfishCredentialProtocolGuid, - &mRedfishCredentialProtocol, + &mCredentialPrivate->RedfishCredentialProtocol, + &gEdkIIRedfishCredential2ProtocolGuid, + &mCredentialPrivate->RedfishCredential2Protocol, NULL ); + FreePool (mCredentialPrivate); + return Status; } + +/** + Releases all resources allocated by the module. + Uninstall all the protocols installed in the driver entry point. + + @retval EFI_SUCCESS The resources are released. + @retval Others Failed to release the resources. + +**/ +EFI_STATUS +ReleaseCredentialPrivate ( + ) +{ + if (mCredentialPrivate != NULL) { + if (mCredentialPrivate->AccountName != NULL) { + ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName)); + FreePool (mCredentialPrivate->AccountName); + mCredentialPrivate->AccountName = NULL; + } + + ClearRedfishServiceList (mCredentialPrivate); + } + + return EFI_SUCCESS; +} + +/** + This is the unload handle for Redfish Credentials module. + + Uninstall all the protocols installed in the driver entry point. + Clear all allocated resources. + + @param[in] ImageHandle The drivers' driver image. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. + +**/ +EFI_STATUS +EFIAPI +RedfishCredentialDxeDriverUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + if (mCredentialPrivate != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + mCredentialPrivate->Handle, + &gEdkIIRedfishCredentialProtocolGuid, + &mCredentialPrivate->RedfishCredentialProtocol, + &gEdkIIRedfishCredential2ProtocolGuid, + &mCredentialPrivate->RedfishCredential2Protocol, + NULL + ); + + if (mCredentialPrivate->EndOfDxeEvent != NULL) { + gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent); + mCredentialPrivate->EndOfDxeEvent = NULL; + } + + if (mCredentialPrivate->ExitBootServiceEvent != NULL) { + gBS->CloseEvent (mCredentialPrivate->ExitBootServiceEvent); + mCredentialPrivate->ExitBootServiceEvent = NULL; + } + + ReleaseCredentialPrivate (); + + FreePool (mCredentialPrivate); + mCredentialPrivate = NULL; + } + + return EFI_SUCCESS; +} diff --git a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h index dc765d5a1f..4988afab44 100644 --- a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h +++ b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h @@ -2,6 +2,7 @@ Definition of Redfish Credential DXE driver. (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ (C) Copyright 2024 American Megatrends International LLC
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,7 +11,7 @@ #ifndef EDKII_REDFISH_CREDENTIAL_DXE_H_ #define EDKII_REDFISH_CREDENTIAL_DXE_H_ -#include +#include #include #include @@ -18,60 +19,40 @@ #include #include #include +#include +#include +#include +#include +#include -/** - Retrieve platform's Redfish authentication information. - - This functions returns the Redfish authentication method together with the user Id and - password. - - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication - as defined by RFC7235. - - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish - session login as defined by Redfish API specification (DSP0266). - - Callers are responsible for and freeing the returned string storage. - - @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. - @param[out] AuthMethod Type of Redfish authentication method. - @param[out] UserId The pointer to store the returned UserId string. - @param[out] Password The pointer to store the returned Password string. - - @retval EFI_SUCCESS Get the authentication information successfully. - @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. - @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. - @retval EFI_UNSUPPORTED Unsupported authentication method is found. - -**/ -EFI_STATUS -EFIAPI -RedfishCredentialGetAuthInfo ( - IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, - OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, - OUT CHAR8 **UserId, - OUT CHAR8 **Password - ); - -/** - Notify the Redfish service provide to stop provide configuration service to this platform. - - This function should be called when the platfrom is about to leave the safe environment. - It will notify the Redfish service provider to abort all logined session, and prohibit - further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this - function is returned. - - @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. +#define REDFISH_CREDENTIAL_DEBUG DEBUG_VERBOSE +#define REDFISH_MANAGER_ACCOUNT_COLLECTION_URI L"AccountService/Accounts" +#define REDFISH_URI_LENGTH 128 - @retval EFI_SUCCESS Service has been stoped successfully. - @retval EFI_INVALID_PARAMETER This is NULL. - @retval Others Some error happened. +#ifndef IS_EMPTY_STRING +#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0') +#endif -**/ -EFI_STATUS -EFIAPI -RedfishCredentialStopService ( - IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, - IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType - ); +/// +/// Definition of REDFISH_SERVICE_LIST +/// +typedef struct { + LIST_ENTRY NextInstance; + REDFISH_SERVICE RedfishService; +} REDFISH_SERVICE_LIST; + +// +// Definitions of REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE +// +typedef struct { + EFI_HANDLE Handle; + EFI_EVENT EndOfDxeEvent; + EFI_EVENT ExitBootServiceEvent; + EDKII_REDFISH_AUTH_METHOD AuthMethod; + CHAR8 *AccountName; + EDKII_REDFISH_CREDENTIAL_PROTOCOL RedfishCredentialProtocol; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL RedfishCredential2Protocol; + LIST_ENTRY RedfishServiceList; +} REDFISH_CREDENTIAL_PRIVATE; #endif diff --git a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf index 707d9a04d9..c872aa8da3 100644 --- a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf +++ b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf @@ -15,6 +15,7 @@ MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = RedfishCredentialDxeDriverEntryPoint + UNLOAD_IMAGE = RedfishCredentialDxeDriverUnload # # VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 @@ -38,14 +39,22 @@ UefiDriverEntryPoint UefiRuntimeServicesTableLib UefiLib + RedfishHttpLib + RedfishDebugLib + JsonLib [Protocols] gEdkIIRedfishCredentialProtocolGuid ## BY_START + gEdkIIRedfishCredential2ProtocolGuid ## BY_START [Guids] gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event gEfiEventExitBootServicesGuid ## CONSUMES ## Event +[Pcd] + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishCredentialDeleteAccount + gEfiRedfishPkgTokenSpaceGuid.PcdDefaultRedfishVersion + [Depex] TRUE diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h b/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h index 6be610142e..cb956a454b 100644 --- a/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h +++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h @@ -77,14 +77,14 @@ typedef struct { /// Definition of REDFISH_HTTP_CACHE_PRIVATE /// typedef struct { - UINT32 Signature; - EFI_HANDLE ImageHandle; - BOOLEAN CacheDisabled; - EFI_EVENT NotifyEvent; - REDFISH_HTTP_CACHE_LIST CacheList; - EDKII_REDFISH_HTTP_PROTOCOL Protocol; - EDKII_REDFISH_CREDENTIAL_PROTOCOL *CredentialProtocol; - REDFISH_HTTP_RETRY_SETTING RetrySetting; + UINT32 Signature; + EFI_HANDLE ImageHandle; + BOOLEAN CacheDisabled; + EFI_EVENT NotifyEvent; + REDFISH_HTTP_CACHE_LIST CacheList; + EDKII_REDFISH_HTTP_PROTOCOL Protocol; + EDKII_REDFISH_CREDENTIAL2_PROTOCOL *CredentialProtocol; + REDFISH_HTTP_RETRY_SETTING RetrySetting; } REDFISH_HTTP_CACHE_PRIVATE; #define REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS(a) CR (a, REDFISH_HTTP_CACHE_PRIVATE, Protocol, REDFISH_HTTP_DRIVER_SIGNATURE) diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c index 8dcdf55c62..f15b371f5b 100644 --- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c +++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c @@ -313,10 +313,10 @@ RedfishCreateRedfishService ( &Username, &Password ); - if (EFI_ERROR (Status) || IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)) { + if (EFI_ERROR (Status) || ((AuthMethod != AuthMethodNone) && (IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)))) { DEBUG ((DEBUG_ERROR, "%a: cannot get authentication information: %r\n", __func__, Status)); goto ON_RELEASE; - } else { + } else if (AuthMethod != AuthMethodNone) { DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Auth method: 0x%x username: %a password: %a\n", __func__, AuthMethod, Username, Password)); // @@ -371,6 +371,14 @@ RedfishCreateRedfishService ( NewService = CreateRedfishService (Host, AsciiLocation, EncodedAuthString, NULL, RestEx); if (NewService == NULL) { DEBUG ((DEBUG_ERROR, "%a: CreateRedfishService\n", __func__)); + goto ON_RELEASE; + } + + if (Private->CredentialProtocol != NULL) { + Status = Private->CredentialProtocol->RegisterRedfishService (Private->CredentialProtocol, NewService); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status)); + } } ON_RELEASE: @@ -424,17 +432,33 @@ RedfishFreeRedfishService ( IN REDFISH_SERVICE RedfishService ) { - REDFISH_SERVICE_PRIVATE *Service; + EFI_STATUS Status; + REDFISH_SERVICE_PRIVATE *Service; + REDFISH_HTTP_CACHE_PRIVATE *Private; if ((This == NULL) || (RedfishService == NULL)) { return EFI_INVALID_PARAMETER; } + Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This); + Service = (REDFISH_SERVICE_PRIVATE *)RedfishService; if (Service->Signature != REDFISH_HTTP_SERVICE_SIGNATURE) { DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__)); } + if (Private->CredentialProtocol != NULL) { + Status = Private->CredentialProtocol->UnregisterRedfishService (Private->CredentialProtocol, RedfishService); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to unregister Redfish service - %r\n", __func__, Status)); + } else { + if (Service->RestEx != NULL) { + Status = Service->RestEx->Configure (Service->RestEx, NULL); + DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: release RestEx instance: %r\n", __func__, Status)); + } + } + } + return ReleaseRedfishService (Service); } @@ -1245,10 +1269,10 @@ CredentialProtocolInstalled ( } // - // Locate HII database protocol. + // Locate HII credential protocol. // Status = gBS->LocateProtocol ( - &gEdkIIRedfishCredentialProtocolGuid, + &gEdkIIRedfishCredential2ProtocolGuid, NULL, (VOID **)&Private->CredentialProtocol ); @@ -1327,14 +1351,14 @@ RedfishHttpEntryPoint ( // Install protocol notification if credential protocol is installed. // mRedfishHttpCachePrivate->NotifyEvent = EfiCreateProtocolNotifyEvent ( - &gEdkIIRedfishCredentialProtocolGuid, + &gEdkIIRedfishCredential2ProtocolGuid, TPL_CALLBACK, CredentialProtocolInstalled, mRedfishHttpCachePrivate, &Registration ); if (mRedfishHttpCachePrivate->NotifyEvent == NULL) { - DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredentialProtocolGuid\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredential2ProtocolGuid\n", __func__)); ASSERT (FALSE); RedfishHttpDriverUnload (ImageHandle); return Status; diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h index cf6ba9cb47..0c40423655 100644 --- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h +++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include #define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0') diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf index c7dfdffacf..0757960999 100644 --- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf +++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf @@ -56,7 +56,7 @@ [Protocols] gEdkIIRedfishHttpProtocolGuid ## PRODUCED - gEdkIIRedfishCredentialProtocolGuid ## CONSUMES + gEdkIIRedfishCredential2ProtocolGuid ## CONSUMES gEfiRestExProtocolGuid ## CONSUEMS [Pcd] diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec index 54318527fe..f80c6795ae 100644 --- a/RedfishPkg/RedfishPkg.dec +++ b/RedfishPkg/RedfishPkg.dec @@ -90,6 +90,9 @@ ## Include/Protocol/EdkIIRedfishCredential.h gEdkIIRedfishCredentialProtocolGuid = { 0x8804377, 0xaf7a, 0x4496, { 0x8a, 0x7b, 0x17, 0x59, 0x0, 0xe9, 0xab, 0x46 } } + ## Include/Protocol/EdkIIRedfishCredential.h + gEdkIIRedfishCredential2ProtocolGuid = { 0x936b81dc, 0x348c, 0x42e3, { 0x9e, 0x82, 0x2, 0x91, 0x4f, 0xd3, 0x48, 0x86 } } + ## Include/Protocol/Edk2RedfishConfigHandler.h gEdkIIRedfishConfigHandlerProtocolGuid = { 0xbc0fe6bb, 0x2cc9, 0x463e, { 0x90, 0x82, 0xfa, 0x11, 0x76, 0xfc, 0x67, 0xde } } @@ -208,3 +211,7 @@ # # Redfish RedfishPlatformConfigDxe feature Properties gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0|UINT32|0x00001014 + ## This is used to disable a deletion of the bootstrap account. + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishCredentialDeleteAccount|TRUE|BOOLEAN|0x00001015 + ## Default Redfish version string + gEfiRedfishPkgTokenSpaceGuid.PcdDefaultRedfishVersion|L"v1"|VOID*|0x00001016 -- cgit From ab6ad2fbdbaad1eb3a766973d6f587685d784d48 Mon Sep 17 00:00:00 2001 From: Saloni Kasbekar Date: Tue, 23 Jul 2024 13:02:37 -0700 Subject: NetworkPkg/DxeHttpLib: Support HTTP CONNECT message in Tx path. Add HTTP CONNECT message support in HttpGenRequestMessage() Signed-off-by: Saloni Kasbekar --- NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c index 21813463aa..f1da69bbf7 100644 --- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c +++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c @@ -1927,6 +1927,11 @@ HttpGenRequestMessage ( CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength); RequestPtr += StrLength; break; + case HttpMethodConnect: + StrLength = sizeof (HTTP_METHOD_CONNECT) - 1; + CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength); + RequestPtr += StrLength; + break; default: ASSERT (FALSE); Status = EFI_INVALID_PARAMETER; -- cgit From 2bff58935f21749cd282b74869a71f94ea9d40ec Mon Sep 17 00:00:00 2001 From: Dat Mach Date: Mon, 8 Jul 2024 16:50:38 -0700 Subject: MdePkg: Tpm2Acpi.h: Max size for Parameters field Define macro for the max size of the Start Method Specific Paramemeters field. Signed-off-by: Dat Mach --- MdePkg/Include/IndustryStandard/Tpm2Acpi.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/Tpm2Acpi.h b/MdePkg/Include/IndustryStandard/Tpm2Acpi.h index e7d14f9d2e..882e21dfe5 100644 --- a/MdePkg/Include/IndustryStandard/Tpm2Acpi.h +++ b/MdePkg/Include/IndustryStandard/Tpm2Acpi.h @@ -3,6 +3,7 @@ Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
+Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -18,6 +19,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define EFI_TPM2_ACPI_TABLE_REVISION_4 4 #define EFI_TPM2_ACPI_TABLE_REVISION EFI_TPM2_ACPI_TABLE_REVISION_4 +#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4 12 +#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4 + typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; // Flags field is replaced in version 4 and above -- cgit From 75a9afa540822e25e88c664413fcd6075f0ed962 Mon Sep 17 00:00:00 2001 From: Dat Mach Date: Tue, 25 Jun 2024 14:57:53 -0700 Subject: DynamicTablesPkg: ACPI TPM2 generator Generate ACPI TPM2 table using the information obtained from Tpm2InterfaceInfo CM object. Signed-off-by: Dat Mach --- DynamicTablesPkg/DynamicTables.dsc.inc | 3 + DynamicTablesPkg/Include/AcpiTableGenerator.h | 2 + .../Include/ArchCommonNameSpaceObjects.h | 39 ++ .../Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf | 29 ++ .../Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c | 405 +++++++++++++++++++++ DynamicTablesPkg/Readme.md | 1 + 6 files changed, 479 insertions(+) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index 3fdb3e66b2..dc363dc802 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -3,6 +3,7 @@ # # Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -36,6 +37,7 @@ DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf # AML Fixup (Common) DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf @@ -86,6 +88,7 @@ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf # Arm specific NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index f5c6179be0..778a908bcd 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -1,6 +1,7 @@ /** @file Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -99,6 +100,7 @@ typedef enum StdAcpiTableId { EStdAcpiTableIdSsdtCpuTopology, ///< SSDT Cpu Topology EStdAcpiTableIdSsdtPciExpress, ///< SSDT Pci Express Generator EStdAcpiTableIdPcct, ///< PCCT Generator + EStdAcpiTableIdTpm2, ///< TPM2 Generator EStdAcpiTableIdMax } ESTD_ACPI_TABLE_ID; diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h index 6de57dbbf2..4b83e53b4d 100644 --- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h @@ -1,6 +1,7 @@ /** @file Copyright (c) 2024, Arm Limited. All rights reserved.
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -16,6 +17,8 @@ #include #include +#include + /** The EARCH_COMMON_OBJECT_ID enum describes the Object IDs in the Arch Common Namespace */ @@ -46,6 +49,7 @@ typedef enum ArchCommonObjectID { EArchCommonObjPccSubspaceType4Info, ///< 23 - Pcc Subspace Type 4 Info EArchCommonObjPccSubspaceType5Info, ///< 24 - Pcc Subspace Type 5 Info EArchCommonObjPsdInfo, ///< 25 - P-State Dependency (PSD) Info + EArchCommonObjTpm2InterfaceInfo, ///< 26 - TPM Interface Info EArchCommonObjMax } EARCH_COMMON_OBJECT_ID; @@ -652,6 +656,41 @@ typedef struct CmArchCommonPccSubspaceType5Info { */ typedef AML_PSD_INFO CM_ARCH_COMMON_PSD_INFO; +/** A structure that describes TPM interface and access method. + + TCG ACPI Specification 2.0 + + ID: EArchCommonObjTpm2InterfaceInfo +*/ +typedef struct CmArchCommonTpm2InterfaceInfo { + /** Platform Class + 0: Client platform + 1: Server platform + */ + UINT16 PlatformClass; + + /** Physical address of the Control Area */ + UINT64 AddressOfControlArea; + + /** The Start Method selector determines which mechanism the + device driver uses to notify the TPM 2.0 device that a + command is available for processing. + */ + UINT32 StartMethod; + + /** The number of bytes stored in StartMethodParameters[] */ + UINT8 StartMethodParametersSize; + + /** Start method specific parameters */ + UINT8 StartMethodParameters[EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE]; + + /** Log Area Minimum Length */ + UINT32 Laml; + + /** Log Area Start Address */ + UINT64 Lasa; +} CM_ARCH_COMMON_TPM2_INTERFACE_INFO; + #pragma pack() #endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf new file mode 100644 index 0000000000..ee50fc6f70 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf @@ -0,0 +1,29 @@ +## @file +# TPM2 Table Generator +# +# Copyright (c) 2022, ARM Limited. All rights reserved. +# Copyright (c) 2023 - 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = AcpiTpm2Lib + FILE_GUID = 968fa07a-9076-11ed-8041-9bd740d3d45d + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiTpm2LibConstructor + DESTRUCTOR = AcpiTpm2LibDestructor + +[Sources] + Tpm2Generator.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c new file mode 100644 index 0000000000..93dca5e564 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c @@ -0,0 +1,405 @@ +/** @file + TPM2 Table Generator + + Copyright (c) 2022, ARM Limited. All rights reserved. + Copyright (c) 2023 - 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - TCG ACPI Specification Family for TPM 1.2 and 2.0 Version 1.3 Revision 8' + (https://trustedcomputinggroup.org/wp-content/uploads/TCG_ACPIGeneralSpec_v1p3_r8_pub.pdf) + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +#include + +#define START_METHOD_ACPI_PARAM_SIZE_MIN 4 +#define START_METHOD_CRB_WITH_SMC_PARAM_SIZE 12 + +/** + ARM standard TPM2 Generator + + Requirements: + The following Configuration Manager Object(s) are used by this Generator: + - EArchCommonObjTpm2InterfaceInfo +*/ + +/** + This macro expands to a function that retrieves the Processor Hierarchy + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArchCommon, + EArchCommonObjTpm2InterfaceInfo, + CM_ARCH_COMMON_TPM2_INTERFACE_INFO + ); + +/** + Sanity check Start Method Specific Parameters field + + @param [in] TpmInfo Pointer to the CM TPM2 object + + @retval EFI_SUCCESS No failure + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +AcpiTpm2CheckStartMethodParameters ( + CM_ARCH_COMMON_TPM2_INTERFACE_INFO *TpmInfo + ) +{ + ASSERT (TpmInfo != NULL); + + if (sizeof (TpmInfo->StartMethodParameters) < TpmInfo->StartMethodParametersSize) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + // LAML and LASA are either both set or both zeros + if (((TpmInfo->Laml > 0) && (TpmInfo->Lasa == 0)) || + ((TpmInfo->Laml == 0) && (TpmInfo->Lasa != 0))) + { + return EFI_INVALID_PARAMETER; + } + + // Verify StartMethodParametersSize based on StartMethod + switch (TpmInfo->StartMethod) { + case EFI_TPM2_ACPI_TABLE_START_METHOD_ACPI: + // If the Start Method value is 2, then this field is at least four + // bytes in size and the first four bytes must be all zero. + if (TpmInfo->StartMethodParametersSize < START_METHOD_ACPI_PARAM_SIZE_MIN) { + return EFI_INVALID_PARAMETER; + } + + if (((UINT32 *)TpmInfo->StartMethodParameters)[0] != 0) { + return EFI_INVALID_PARAMETER; + } + + break; + + case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_SMC: + // If the Start Method value is 11 then this field is 12 bytes in size + if (TpmInfo->StartMethodParametersSize != START_METHOD_CRB_WITH_SMC_PARAM_SIZE) { + return EFI_INVALID_PARAMETER; + } + + break; + + case EFI_TPM2_ACPI_TABLE_START_METHOD_TIS: + case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE: + case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_ACPI: + break; + + default: + return EFI_INVALID_PARAMETER; + break; + } + + return EFI_SUCCESS; +} + +/** Construct the TPM2 ACPI table. + + Called by the Dynamic Table Manager, this function invokes the + Configuration Manager protocol interface to get the required hardware + information for generating the ACPI table. + + If this function allocates any resources then they must be freed + in the FreeTpm2TableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildTpm2Table ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + UINT32 TableSize; + CM_ARCH_COMMON_TPM2_INTERFACE_INFO *TpmInfo; + EFI_TPM2_ACPI_TABLE *Tpm2; + UINT32 *Laml; + UINT64 *Lasa; + + *Table = NULL; + + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (Table != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: TPM2: Requested table revision = %d is not supported. " + "Supported table revisions: Minimum = %d. Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + Status = GetEArchCommonObjTpm2InterfaceInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &TpmInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to get TPM interface CM Object %r\n", + __func__, + Status + )); + return Status; + } + + // Sanity check Start Method Specific Parameters field + Status = AcpiTpm2CheckStartMethodParameters (TpmInfo); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: TPM2: Unexpected StartMethod %u with parameters size %u\n", + TpmInfo->StartMethod, + TpmInfo->StartMethodParametersSize + )); + return EFI_INVALID_PARAMETER; + } + + // Calculate the size of the TPM2 table + TableSize = sizeof (EFI_TPM2_ACPI_TABLE); + if (TpmInfo->Laml == 0) { + TableSize += TpmInfo->StartMethodParametersSize; + } else { + // If LAML and LASA are present, then StartMethodParameters field would get + // max size regardless of StartMethod value + TableSize += EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4; + TableSize += sizeof (TpmInfo->Laml) + sizeof (TpmInfo->Lasa); + } + + // Allocate the Buffer for TPM2 table + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table == NULL) { + DEBUG (( + DEBUG_ERROR, + "ERROR: TPM2: Failed to allocate memory for TPM2 Table, Size = %d," \ + " Status = %r\n", + TableSize, + Status + )); + return EFI_OUT_OF_RESOURCES; + } + + Tpm2 = (EFI_TPM2_ACPI_TABLE *)*Table; + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + &Tpm2->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: TPM2: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + Tpm2->Flags = TpmInfo->PlatformClass; + Tpm2->AddressOfControlArea = TpmInfo->AddressOfControlArea; + Tpm2->StartMethod = TpmInfo->StartMethod; + + CopyMem ( + Tpm2 + 1, + TpmInfo->StartMethodParameters, + TpmInfo->StartMethodParametersSize + ); + + if (TpmInfo->Laml > 0) { + Laml = (UINT32 *)((UINT8 *)Tpm2 + sizeof (EFI_TPM2_ACPI_TABLE) + + EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4); + Lasa = (UINT64 *)((UINT8 *)Laml + sizeof (TpmInfo->Laml)); + *Laml = TpmInfo->Laml; + *Lasa = TpmInfo->Lasa; + } + + return EFI_SUCCESS; + +error_handler: + + if (*Table != NULL) { + FreePool (*Table); + *Table = NULL; + } + + return Status; +} + +/** Free any resources allocated for constructing the TPM2. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeTpm2TableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: TPM2: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + + return EFI_SUCCESS; +} + +/** The TPM2 Table Generator revision. +*/ +#define TPM2_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the TPM2 Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR Tpm2Generator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdTpm2), + // Generator Description + L"ACPI.STD.TPM2.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_4_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_TPM2_ACPI_TABLE_REVISION_4, + // Minimum supported ACPI Table Revision + EFI_TPM2_ACPI_TABLE_REVISION_4, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + TPM2_GENERATOR_REVISION, + // Build Table function + BuildTpm2Table, + // Free Resource function + FreeTpm2TableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiTpm2LibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&Tpm2Generator); + DEBUG ((DEBUG_INFO, "TPM2: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiTpm2LibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&Tpm2Generator); + DEBUG ((DEBUG_INFO, "TPM2: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index 3b64bc857b..b2230aff46 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -497,6 +497,7 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager | 23 | Pcc Subspace Type 4 Info | | | 24 | Pcc Subspace Type 5 Info | | | 25 | P-State Dependency (PSD) Info | | +| 26 | TPM Interface Info | | | `*` | All other values are reserved. | | #### Object ID's in the X64 Namespace: -- cgit From d24df10cee88c4c011dfe84f7ed66cfb081b8146 Mon Sep 17 00:00:00 2001 From: Dat Mach Date: Tue, 18 Jun 2024 17:50:02 -0700 Subject: DynamicTablesPkg: Add HexDump for CM Object parser Add helper function HexDump for printing hex dump of CM Object fields. Also merge multiple flavors of PrintCharX into one function PrintChars by using the field length. Signed-off-by: Dat Mach --- .../ConfigurationManagerObjectParser.c | 130 ++++++++------------- .../ConfigurationManagerObjectParser.h | 4 +- 2 files changed, 53 insertions(+), 81 deletions(-) diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 96d02821e3..0c66961566 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -3,6 +3,7 @@ Copyright (c) 2021 - 2023, ARM Limited. All rights reserved.
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -17,7 +18,8 @@ VOID EFIAPI PrintString ( CONST CHAR8 *Format, - UINT8 *Ptr + UINT8 *Ptr, + UINT32 Length ); STATIC @@ -25,31 +27,26 @@ VOID EFIAPI PrintStringPtr ( CONST CHAR8 *Format, - UINT8 *Ptr + UINT8 *Ptr, + UINT32 Length ); STATIC VOID EFIAPI -PrintChar4 ( +PrintChars ( CONST CHAR8 *Format, - UINT8 *Ptr + UINT8 *Ptr, + UINT32 Length ); STATIC VOID EFIAPI -PrintChar6 ( +HexDump ( CONST CHAR8 *Format, - UINT8 *Ptr - ); - -STATIC -VOID -EFIAPI -PrintChar8 ( - CONST CHAR8 *Format, - UINT8 *Ptr + UINT8 *Ptr, + UINT32 Length ); /** A parser for EArmObjBootArchInfo. @@ -859,20 +856,20 @@ STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = { /** A parser for EStdObjCfgMgrInfo. */ STATIC CONST CM_OBJ_PARSER StdObjCfgMgrInfoParser[] = { - { "Revision", 4, "0x%x", NULL }, - { "OemId[6]", 6, "%c%c%c%c%c%c", PrintChar6 } + { "Revision", 4, "0x%x", NULL }, + { "OemId[6]", 6, NULL, PrintChars } }; /** A parser for EStdObjAcpiTableList. */ STATIC CONST CM_OBJ_PARSER StdObjAcpiTableInfoParser[] = { - { "AcpiTableSignature", 4, "%c%c%c%c", PrintChar4 }, - { "AcpiTableRevision", 1, "%d", NULL }, - { "TableGeneratorId", sizeof (ACPI_TABLE_GENERATOR_ID), "0x%x", NULL }, - { "AcpiTableData", sizeof (EFI_ACPI_DESCRIPTION_HEADER *), "0x%p", NULL }, - { "OemTableId", 8, "%c%c%c%c%c%c%c%c", PrintChar8 }, - { "OemRevision", 4, "0x%x", NULL }, - { "MinorRevision", 1, "0x%x", NULL }, + { "AcpiTableSignature", 4, NULL, PrintChars }, + { "AcpiTableRevision", 1, "%d", NULL }, + { "TableGeneratorId", sizeof (ACPI_TABLE_GENERATOR_ID), "0x%x", NULL }, + { "AcpiTableData", sizeof (EFI_ACPI_DESCRIPTION_HEADER *), "0x%p", NULL }, + { "OemTableId", 8, NULL, PrintChars }, + { "OemRevision", 4, "0x%x", NULL }, + { "MinorRevision", 1, "0x%x", NULL }, }; /** A parser for EStdObjSmbiosTableList. @@ -897,13 +894,15 @@ STATIC CONST CM_OBJ_PARSER_ARRAY StdNamespaceObjectParser[] = { @param [in] Format Format to print the Ptr. @param [in] Ptr Pointer to the string. + @param [in] Length Length of the field **/ STATIC VOID EFIAPI PrintString ( IN CONST CHAR8 *Format, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { if (Ptr == NULL) { @@ -911,7 +910,7 @@ PrintString ( return; } - DEBUG ((DEBUG_ERROR, "%a", Ptr)); + DEBUG ((DEBUG_INFO, "%a", Ptr)); } /** Print string from pointer. @@ -920,13 +919,15 @@ PrintString ( @param [in] Format Format to print the string. @param [in] Ptr Pointer to the string pointer. + @param [in] Length Length of the field **/ STATIC VOID EFIAPI PrintStringPtr ( IN CONST CHAR8 *Format, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { UINT8 *String; @@ -942,82 +943,51 @@ PrintStringPtr ( String = (UINT8 *)"(NULLPTR)"; } - PrintString (Format, String); + PrintString (Format, String, Length); } -/** Print 4 characters. +/** Print characters. @param [in] Format Format to print the Ptr. @param [in] Ptr Pointer to the characters. + @param [in] Length Length of the field **/ STATIC VOID EFIAPI -PrintChar4 ( +PrintChars ( IN CONST CHAR8 *Format, - IN UINT8 *Ptr + IN UINT8 *Ptr, + IN UINT32 Length ) { - DEBUG (( - DEBUG_ERROR, - (Format != NULL) ? Format : "%c%c%c%c", - Ptr[0], - Ptr[1], - Ptr[2], - Ptr[3] - )); -} - -/** Print 6 characters. + UINT32 Index; - @param [in] Format Format to print the Ptr. - @param [in] Ptr Pointer to the characters. -**/ -STATIC -VOID -EFIAPI -PrintChar6 ( - IN CONST CHAR8 *Format, - IN UINT8 *Ptr - ) -{ - DEBUG (( - DEBUG_ERROR, - (Format != NULL) ? Format : "%c%c%c%c%c%c", - Ptr[0], - Ptr[1], - Ptr[2], - Ptr[3], - Ptr[4], - Ptr[5] - )); + for (Index = 0; Index < Length; Index++) { + DEBUG ((DEBUG_INFO, "%c", Ptr[Index])); + } } -/** Print 8 characters. +/** Dump data in Hex format @param [in] Format Format to print the Ptr. - @param [in] Ptr Pointer to the characters. + @param [in] Ptr Pointer to the string. + @param [in] Length Length of the field **/ STATIC VOID EFIAPI -PrintChar8 ( - IN CONST CHAR8 *Format, - IN UINT8 *Ptr +HexDump ( + IN CONST CHAR8 *Format, + IN UINT8 *Ptr, + IN UINT32 Length ) { - DEBUG (( - DEBUG_ERROR, - (Format != NULL) ? Format : "%c%c%c%c%c%c%c%c", - Ptr[0], - Ptr[1], - Ptr[2], - Ptr[3], - Ptr[4], - Ptr[5], - Ptr[6], - Ptr[7] - )); + UINT32 Index; + + for (Index = 0; Index < Length; Index++) { + DEBUG ((DEBUG_INFO, "0x%02x ", *Ptr++)); + } } /** Print fields of the objects. @@ -1079,7 +1049,7 @@ PrintCmObjDesc ( Parser[Index].NameStr )); if (Parser[Index].PrintFormatter != NULL) { - Parser[Index].PrintFormatter (Parser[Index].Format, Data); + Parser[Index].PrintFormatter (Parser[Index].Format, Data, Parser[Index].Length); } else if (Parser[Index].Format != NULL) { switch (Parser[Index].Length) { case 1: diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h index d996d05a55..3ec82d2fb4 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h @@ -2,6 +2,7 @@ Configuration Manager Object parser. Copyright (c) 2021, ARM Limited. All rights reserved.
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -28,8 +29,9 @@ @param [in] Format Format string for tracing the data as specified by the 'Format' member of ACPI_PARSER. @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the field **/ -typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR8 *Format, UINT8 *Ptr); +typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR8 *Format, UINT8 *Ptr, UINT32 Length); /** The CM_OBJ_PARSER structure describes the fields of an CmObject and -- cgit From b0f43dd3fdec2363e3548ec31eb455dc1c4ac761 Mon Sep 17 00:00:00 2001 From: Dat Mach Date: Tue, 25 Jun 2024 15:07:38 -0700 Subject: DynamicTablesPkg: Add parser for Tpm2 CM object Update the CM Object parser to add support for parsing the CM_ARM_TPM2_INTERFACE_INFO object. Signed-off-by: Dat Mach --- .../TableHelperLib/ConfigurationManagerObjectParser.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c index 0c66961566..eceb91a6d8 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c @@ -665,6 +665,18 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonPsdInfoParser[] = { { "NumProc", 4, "0x%x", NULL }, }; +/** A parser for EArchCommonObjTpm2InterfaceInfo. +*/ +STATIC CONST CM_OBJ_PARSER CmArchCommonTpm2InterfaceInfo[] = { + { "PlatformClass", sizeof (UINT16), "0x%x", NULL }, + { "AddressOfControlArea", sizeof (UINT64), "0x%llx", NULL }, + { "StartMethod", sizeof (UINT32), "0x%x", NULL }, + { "StartMethodParametersSize", sizeof (UINT8), "0x%x", NULL }, + { "StartMethodParameters", EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE, NULL, HexDump }, + { "Laml", sizeof (UINT32), "0x%x", NULL }, + { "Lasa", sizeof (UINT64), "0x%llx", NULL }, +}; + /** A parser for Arch Common namespace objects. */ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { @@ -694,6 +706,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = { CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType4Info, CmArchCommonPccSubspaceType34InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType5Info, CmArchCommonPccSubspaceType5InfoParser), CM_PARSER_ADD_OBJECT (EArchCommonObjPsdInfo, CmArchCommonPsdInfoParser), + CM_PARSER_ADD_OBJECT (EArchCommonObjTpm2InterfaceInfo, CmArchCommonTpm2InterfaceInfo), CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax) }; -- cgit From b158dad150bf02879668f72ce306445250838201 Mon Sep 17 00:00:00 2001 From: Ashraf Ali Date: Sun, 11 Aug 2024 21:31:12 +0530 Subject: EmulatorPkg: VS2022 Support on WinHost. Currently EDK2 is supporting VS2022, with VS2022 EmulatorPkg build is failing, this patch is to add the VS2022 support for WinHost Signed-off-by: Ashraf Ali --- EmulatorPkg/Win/Host/WinHost.inf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EmulatorPkg/Win/Host/WinHost.inf b/EmulatorPkg/Win/Host/WinHost.inf index 4dac6e033e..6bb3d9696c 100644 --- a/EmulatorPkg/Win/Host/WinHost.inf +++ b/EmulatorPkg/Win/Host/WinHost.inf @@ -94,6 +94,7 @@ MSFT:*_VS2015x86_IA32_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%Lib" /LIBPATH:"%VS2015_PREFIX%VC\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib MSFT:*_VS2017_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib MSFT:*_VS2019_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2022_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib MSFT:*_*_IA32_ASM_FLAGS == /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi MSFT:*_*_IA32_ASMLINK_FLAGS == /link /nologo /tiny @@ -101,6 +102,7 @@ MSFT:*_VS2015x86_X64_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%VC\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib MSFT:*_VS2017_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib MSFT:*_VS2019_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2022_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib MSFT:*_*_X64_ASM_FLAGS == /nologo /W3 /WX /c /Cx /Zd /W0 /Zi MSFT:*_*_X64_ASMLINK_FLAGS == /link /nologo -- cgit From 1cc0fae8d9e2681fc6a33e5602ce8368809f9465 Mon Sep 17 00:00:00 2001 From: Mike Maslenkin Date: Sat, 27 Apr 2024 12:14:36 +0300 Subject: MdeModulePkg/RamDiskDxe: fix memory leak on error path. This patch fixes a leak of memory allocated for the RAM disk in cases when an error occurred while reading contents of a file from disk or RamDiskRegister() returned some error condition. Signed-off-by: Mike Maslenkin --- MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c index 60cf3c8c4a..2dac121c47 100644 --- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c +++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c @@ -404,7 +404,8 @@ HiiCreateRamDisk ( ); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - return EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; + goto ErrorExit; } } @@ -431,7 +432,7 @@ HiiCreateRamDisk ( ); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - return Status; + goto ErrorExit; } // @@ -442,6 +443,10 @@ HiiCreateRamDisk ( PrivateData->CreateMethod = RamDiskCreateHii; return EFI_SUCCESS; + +ErrorExit: + gBS->FreePool (StartingAddr); + return Status; } /** -- cgit From f3040bed3cb43ddad2e5d2fd54c6140f23c7d763 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 19 Aug 2024 18:46:51 -0400 Subject: .mergify: Fix pull_request_rules deprecation The following message is visible on mergify runs: "The configuration uses the deprecated merge_method attribute of the queue action in one or more pull_request_rules. It must now be used under the queue_rules configuration." With the following warning: "A brownout is planned on August 26th, 2024. This option will be removed on September 23rd, 2024." This change updates the configuration file to comply with the new format. Signed-off-by: Michael Kubacki --- .mergify/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mergify/config.yml b/.mergify/config.yml index 3471896a34..fd77b1707b 100644 --- a/.mergify/config.yml +++ b/.mergify/config.yml @@ -26,9 +26,10 @@ queue_rules: - name: default - conditions: + queue_conditions: - base~=(^main|^master|^stable/) - label=push + merge_method: rebase pull_request_rules: - name: Automatically merge a PR when all required checks pass and 'push' label is present @@ -37,7 +38,6 @@ pull_request_rules: - label=push actions: queue: - method: rebase name: default - name: Post a comment on a PR that can not be merged due to a merge conflict -- cgit From 0e8af8803489a10d4edc61a94f1c6e03965c16f5 Mon Sep 17 00:00:00 2001 From: Saloni Kasbekar Date: Tue, 6 Aug 2024 14:07:30 -0700 Subject: NetworkPkg: Improve GetBootFile() code flow Introduce state machine to improve the code flow in GetBootFile() to make it more readable. Allows new states to be easily added without adding further nested ifs. Signed-off-by: Saloni Kasbekar --- NetworkPkg/HttpBootDxe/HttpBootImpl.c | 175 ++++++++++++++++++++++------------ NetworkPkg/HttpBootDxe/HttpBootImpl.h | 7 ++ 2 files changed, 122 insertions(+), 60 deletions(-) diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index b4c61925b9..fa27941f80 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -274,6 +274,119 @@ HttpBootDhcp ( return Status; } +/** + Issue calls to HttpBootGetBootFile() based on current Boot File State + @param[in] Private The pointer to the driver's private data. + @param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return + code of EFI_SUCCESS, the amount of data transferred to + Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, + the size of Buffer required to retrieve the requested file. + @param[in] Buffer The memory buffer to transfer the file to. If Buffer is NULL, + then the size of the requested file is returned in + BufferSize. + @param[out] ImageType The image type of the downloaded file. + @retval EFI_SUCCESS The file was loaded. + @retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. + BufferSize has been updated with the size needed to complete + the request. + @retval EFI_ACCESS_DENIED Server authentication failed. + @retval Others Unexpected error happened. +**/ +EFI_STATUS +HttpBootGetBootFileCaller ( + IN HTTP_BOOT_PRIVATE_DATA *Private, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL, + OUT HTTP_BOOT_IMAGE_TYPE *ImageType + ) +{ + HTTP_GET_BOOT_FILE_STATE State; + EFI_STATUS Status; + + if (Private->BootFileSize == 0) { + State = GetBootFileHead; + } else { + State = LoadBootFile; + } + + for ( ; ;) { + switch (State) { + case GetBootFileHead: + // + // Try to use HTTP HEAD method. + // + Status = HttpBootGetBootFile ( + Private, + TRUE, + &Private->BootFileSize, + NULL, + &Private->ImageType + ); + if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) { + if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) { + // + // Try to use HTTP HEAD method again since the Authentication information is provided. + // + State = GetBootFileHead; + } else { + State = GetBootFileGet; + } + } else { + State = LoadBootFile; + } + + break; + + case GetBootFileGet: + // + // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method. + // + ASSERT (Private->BootFileSize == 0); + Status = HttpBootGetBootFile ( + Private, + FALSE, + &Private->BootFileSize, + NULL, + &Private->ImageType + ); + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + State = GetBootFileError; + } else { + State = LoadBootFile; + } + + break; + + case LoadBootFile: + if (*BufferSize < Private->BootFileSize) { + *BufferSize = Private->BootFileSize; + *ImageType = Private->ImageType; + Status = EFI_BUFFER_TOO_SMALL; + return Status; + } + + // + // Load the boot file into Buffer + // + Status = HttpBootGetBootFile ( + Private, + FALSE, + BufferSize, + Buffer, + ImageType + ); + return Status; + + case GetBootFileError: + default: + AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n"); + return Status; + } + } +} + /** Attempt to download the boot file through HTTP message exchange. @@ -345,68 +458,10 @@ HttpBootLoadFile ( } } - if (Private->BootFileSize == 0) { - // - // Discover the information about the bootfile if we haven't. - // - - // - // Try to use HTTP HEAD method. - // - Status = HttpBootGetBootFile ( - Private, - TRUE, - &Private->BootFileSize, - NULL, - &Private->ImageType - ); - if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) { - // - // Try to use HTTP HEAD method again since the Authentication information is provided. - // - Status = HttpBootGetBootFile ( - Private, - TRUE, - &Private->BootFileSize, - NULL, - &Private->ImageType - ); - } else if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) { - // - // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method. - // - ASSERT (Private->BootFileSize == 0); - Status = HttpBootGetBootFile ( - Private, - FALSE, - &Private->BootFileSize, - NULL, - &Private->ImageType - ); - if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { - AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n"); - goto ON_EXIT; - } - } - } - - if (*BufferSize < Private->BootFileSize) { - *BufferSize = Private->BootFileSize; - *ImageType = Private->ImageType; - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - // - // Load the boot file into Buffer + // Load the boot file // - Status = HttpBootGetBootFile ( - Private, - FALSE, - BufferSize, - Buffer, - ImageType - ); + Status = HttpBootGetBootFileCaller (Private, BufferSize, Buffer, ImageType); ON_EXIT: HttpBootUninstallCallback (Private); diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.h b/NetworkPkg/HttpBootDxe/HttpBootImpl.h index 55adc9cb50..33da4fec51 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.h +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.h @@ -11,6 +11,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define HTTP_BOOT_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) +typedef enum { + GetBootFileHead, + GetBootFileGet, + LoadBootFile, + GetBootFileError +} HTTP_GET_BOOT_FILE_STATE; + /** Attempt to complete a DHCPv4 D.O.R.A or DHCPv6 S.R.A.A sequence to retrieve the boot resource information. -- cgit From fadb9dcb9dc734418d4e88296cdc609bb298df41 Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 21 Aug 2024 09:50:14 +0800 Subject: SecurityPkg: Correct Pages for TCG2 communication buffer The value of the Pages for TCG2 communication buffer should be EFI_SIZE_TO_PAGES(sizeof(TCG_NVS)) instead of sizeof(TCG_NVS). Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c index 73121b0a26..0e4dd3e7fd 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c @@ -78,7 +78,7 @@ BuildTcg2AcpiCommunicateBufferHob ( VOID *Buffer; UINTN Pages; - Pages = sizeof (TCG_NVS); + Pages = EFI_SIZE_TO_PAGES (sizeof (TCG_NVS)); Buffer = AllocateRuntimePages (Pages); ASSERT (Buffer != NULL); -- cgit From 5a06afa7dd8ba8e99178fec9525be9e3fd2a4d3a Mon Sep 17 00:00:00 2001 From: Dun Tan Date: Wed, 21 Aug 2024 10:05:34 +0800 Subject: SecurityPkg: Allocate EfiACPIMemoryNVS buffer for TCG2 Allocate EfiACPIMemoryNVS buffer for TCG2 related usage in Tcg2ConfigPeim. The buffer will be used in Tcg2Acpi driver to retrive information from SMM environment. Previously, the buffer used in Tcg2Acpi driver is AcpiNvs type. But I mistakenly thought the Runtime Data type buffer should also work. So I used API AllocateRuntimePages() to allocate buffer in 9a76c7945b7 and consume the buffer in e939ecf6c1. Recently we found that if the buffer type is Runtime Data instead of AcpiNvs, BSOD issue happened after boot into OS. So this commit is to Allocate EfiACPIMemoryNVS buffer for TCG2 usage in SMM to align with the initial code logic. Signed-off-by: Dun Tan --- SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c index 0e4dd3e7fd..92243ec894 100644 --- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c @@ -75,21 +75,25 @@ BuildTcg2AcpiCommunicateBufferHob ( { TCG2_ACPI_COMMUNICATE_BUFFER *Tcg2AcpiCommunicateBufferHob; EFI_STATUS Status; - VOID *Buffer; + EFI_PHYSICAL_ADDRESS Buffer; UINTN Pages; Pages = EFI_SIZE_TO_PAGES (sizeof (TCG_NVS)); - Buffer = AllocateRuntimePages (Pages); - ASSERT (Buffer != NULL); + Status = PeiServicesAllocatePages ( + EfiACPIMemoryNVS, + Pages, + &Buffer + ); + ASSERT_EFI_ERROR (Status); - Status = MmUnblockMemoryRequest ((UINTN)Buffer, Pages); + Status = MmUnblockMemoryRequest (Buffer, Pages); if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) { return Status; } Tcg2AcpiCommunicateBufferHob = BuildGuidHob (&gEdkiiTcg2AcpiCommunicateBufferHobGuid, sizeof (TCG2_ACPI_COMMUNICATE_BUFFER)); ASSERT (Tcg2AcpiCommunicateBufferHob != NULL); - Tcg2AcpiCommunicateBufferHob->Tcg2AcpiCommunicateBuffer = (UINTN)Buffer; + Tcg2AcpiCommunicateBufferHob->Tcg2AcpiCommunicateBuffer = Buffer; Tcg2AcpiCommunicateBufferHob->Pages = Pages; return EFI_SUCCESS; -- cgit From ccda91c28628aa70bca614f1f7b71ad7b5ca61e0 Mon Sep 17 00:00:00 2001 From: "Michael G.A. Holland" Date: Fri, 23 Aug 2024 18:00:16 -0500 Subject: MdePkg: Define BrainpoolP512r1 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4837 Add BrainpoolP512R1 definition to TPM20.h Signed-off-by: Michael G.A. Holland --- MdePkg/Include/IndustryStandard/Tpm20.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/MdePkg/Include/IndustryStandard/Tpm20.h b/MdePkg/Include/IndustryStandard/Tpm20.h index 4440f3769f..9303f16278 100644 --- a/MdePkg/Include/IndustryStandard/Tpm20.h +++ b/MdePkg/Include/IndustryStandard/Tpm20.h @@ -203,15 +203,16 @@ typedef UINT16 TPM_ALG_ID; // Table 8 - TPM_ECC_CURVE Constants typedef UINT16 TPM_ECC_CURVE; -#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000) -#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001) -#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002) -#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003) -#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004) -#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005) -#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010) -#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011) -#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020) +#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000) +#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001) +#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002) +#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003) +#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004) +#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005) +#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010) +#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011) +#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020) +#define TPM_ECC_BP_P512_R1 (TPM_ECC_CURVE)(0x0032) // Table 11 - TPM_CC Constants (Numeric Order) typedef UINT32 TPM_CC; -- cgit From efaf8931bbfa33a81b8792fbf9e2ccc239d53204 Mon Sep 17 00:00:00 2001 From: Min M Xu Date: Tue, 6 Aug 2024 02:01:55 -0400 Subject: OvmfPkg/TdTcg2Dxe: Fix the SeparatorEvent issue in RTMRs According to the TCG EFI platform specification, the firmware must measure the EV_SEPARATOR event into PCRs 0-7. As PCR[1] and PCR[7] map to RTMR[0], and PCRs [2-6] map to RTMR[1], it is necessary to measure one EV_SEPARATOR event into RTMR[0] and another one into RTMR[1]. An issue is found in TdTcg2Dxe that 2 EV_SEPARATOR events are measured to RTMR[0] but no EV_SEPARATOR event is measured to RTMR[1]. This patch fixes the above issue. Cc: Erdem Aktas Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Qinkun Bao Cc: Tom Lendacky Cc: Michael Roth Signed-off-by: Min Xu --- OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c index 0a23bff5a1..6d2de0e838 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c +++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c @@ -2160,11 +2160,17 @@ OnReadyToBoot ( // // 2. Draw a line between pre-boot env and entering post-boot env. - // PCR[7] (is RTMR[0]) is already done. // - Status = MeasureSeparatorEvent (1); + // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel + // TDX Measurement Register is: + // MrIndex 0 <--> MRTD + // MrIndex 1-3 <--> RTMR[0-2] + // RTMR[0] (i.e. MrIndex 1) is already done. So SepartorEvent shall be extended to + // RTMR[1] (i.e. MrIndex 2) as well. + // + Status = MeasureSeparatorEvent (CC_MR_INDEX_2_RTMR1); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n")); + DEBUG ((DEBUG_ERROR, "Separator Event not Measured to RTMR[1]. Error!\n")); } // -- cgit From b2a431868c4ae0ad99def0a504d2fe097e16cd4f Mon Sep 17 00:00:00 2001 From: Oliver Smith-Denny Date: Fri, 23 Aug 2024 14:47:55 -0700 Subject: UefiCpuPkg: CpuPageTableLibTestHost: Disable Random Test Suite Commit 2f499c36db51980ad43fc6b578c7678a1720bd9c commented out the RandomTestCase tests in CpuPageTableLibTestHost, but it left the test suite being registered without any tests. This causes a failure for tools that check to ensure tests are being registered with test suites. This patch comments out the test suite in addition to the tests being added to it. Signed-off-by: Oliver Smith-Denny --- .../UnitTest/CpuPageTableLibUnitTestHost.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c index a610011179..056aabc238 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c @@ -838,7 +838,8 @@ UefiTestMain ( EFI_STATUS Status; UNIT_TEST_FRAMEWORK_HANDLE Framework; UNIT_TEST_SUITE_HANDLE ManualTestCase; - UNIT_TEST_SUITE_HANDLE RandomTestCase; + + // UNIT_TEST_SUITE_HANDLE RandomTestCase; Framework = NULL; @@ -874,12 +875,12 @@ UefiTestMain ( // // Populate the Random Test Cases. // - Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n")); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } + // Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL); + // if (EFI_ERROR (Status)) { + // DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n")); + // Status = EFI_OUT_OF_RESOURCES; + // goto EXIT; + // } // AddTestCase (RandomTestCase, "Random Test for Paging4Level", "Random Test Case1", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level); // AddTestCase (RandomTestCase, "Random Test for Paging4Level1G", "Random Test Case2", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level1GB); -- cgit