Date   

Re: [`edk2-devel][PATCH v2] UefiPayloadPkg: Fix ECC reported issues

Ma, Maurice <maurice.ma@...>
 

Reviewed-by: Maurice Ma <maurice.ma@...>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Guo
Dong
Sent: Friday, October 15, 2021 16:35
To: devel@edk2.groups.io
Cc: Dong, Guo <guo.dong@...>; Ni, Ray <ray.ni@...>; Ma,
Maurice <maurice.ma@...>; You, Benjamin
<benjamin.you@...>
Subject: [edk2-devel] [`edk2-devel][PATCH v2] UefiPayloadPkg: Fix ECC
reported issues

From: Guo Dong <guo.dong@...>

V2: Fix more header files on #ifdef variable

ECC reported some issues on UefiPayloadPkg, this patch fixed most of them
except several files including ElfLib\Elf32.h, coreboot.h, CbParseLib.c, etc.
It also removed unused functions in ResetSystemLib and Hob.c.

Signed-off-by: Guo Dong <guo.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Maurice Ma <maurice.ma@...>
Cc: Benjamin You <benjamin.you@...>
---
UefiPayloadPkg/Include/Coreboot.h | 1 +
UefiPayloadPkg/Include/Guid/AcpiBoardInfoGuid.h | 4 ++--
UefiPayloadPkg/Include/Guid/MemoryMapInfoGuid.h | 4 ++--
UefiPayloadPkg/Include/Guid/SerialPortInfoGuid.h | 4 ++--
UefiPayloadPkg/Include/Guid/SystemTableInfoGuid.h | 4 ++--
UefiPayloadPkg/Include/Library/BlParseLib.h | 8 ++++----
UefiPayloadPkg/Include/Library/DxeHobListLib.h | 4 ++--
UefiPayloadPkg/Include/Library/PlatformSupportLib.h | 4 ++--
UefiPayloadPkg/Library/CbParseLib/CbParseLib.c | 22
+++++++++++-----------
UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.c | 6
++++++
UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c | 28 ++---------
-----------------
UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h | 4 ++--
UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c | 4 ++--
UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c | 15
++++++++++-----
UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c |
4 ++++
UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h |
6 +++---
UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h | 4
++--
UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c | 2 +-
UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c | 16 -------
---------
UefiPayloadPkg/Library/SblParseLib/SblParseLib.c | 2 +-
UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 2 +-
UefiPayloadPkg/UefiPayloadEntry/PrintHob.c | 17
++++++++++++++++-
UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c | 2 ++
UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h | 10 +++++--
---
UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c | 20
+++++++++++++-------
25 files changed, 98 insertions(+), 99 deletions(-)

diff --git a/UefiPayloadPkg/Include/Coreboot.h
b/UefiPayloadPkg/Include/Coreboot.h
index 8a6c300cde..86e14a1a4d 100644
--- a/UefiPayloadPkg/Include/Coreboot.h
+++ b/UefiPayloadPkg/Include/Coreboot.h
@@ -245,5 +245,6 @@ struct cb_cbmem_tab {
(void *)(((UINT8 *) (_rec)) + sizeof(*(_rec)) \ + (sizeof((_rec)->map[0]) *
(_idx))) +typedef struct cb_memory CB_MEMORY; #endif //
_COREBOOT_PEI_H_INCLUDED_diff --git
a/UefiPayloadPkg/Include/Guid/AcpiBoardInfoGuid.h
b/UefiPayloadPkg/Include/Guid/AcpiBoardInfoGuid.h
index 043b748ae4..2ff0677165 100644
--- a/UefiPayloadPkg/Include/Guid/AcpiBoardInfoGuid.h
+++ b/UefiPayloadPkg/Include/Guid/AcpiBoardInfoGuid.h
@@ -6,8 +6,8 @@
**/ -#ifndef __ACPI_BOARD_INFO_GUID_H__-#define
__ACPI_BOARD_INFO_GUID_H__+#ifndef
ACPI_BOARD_INFO_GUID_H_+#define ACPI_BOARD_INFO_GUID_H_ ///
/// Board information GUIDdiff --git
a/UefiPayloadPkg/Include/Guid/MemoryMapInfoGuid.h
b/UefiPayloadPkg/Include/Guid/MemoryMapInfoGuid.h
index 99187e8037..a62002ebbe 100644
--- a/UefiPayloadPkg/Include/Guid/MemoryMapInfoGuid.h
+++ b/UefiPayloadPkg/Include/Guid/MemoryMapInfoGuid.h
@@ -6,8 +6,8 @@
**/ -#ifndef __MEMORY_MAP_INFO_GUID_H__-#define
__MEMORY_MAP_INFO_GUID_H__+#ifndef
MEMORY_MAP_INFO_GUID_H_+#define MEMORY_MAP_INFO_GUID_H_
#include <Library/PcdLib.h> diff --git
a/UefiPayloadPkg/Include/Guid/SerialPortInfoGuid.h
b/UefiPayloadPkg/Include/Guid/SerialPortInfoGuid.h
index a15d5b8671..10197134a3 100644
--- a/UefiPayloadPkg/Include/Guid/SerialPortInfoGuid.h
+++ b/UefiPayloadPkg/Include/Guid/SerialPortInfoGuid.h
@@ -6,8 +6,8 @@
**/ -#ifndef __SERIAL_PORT_INFO_GUID_H__-#define
__SERIAL_PORT_INFO_GUID_H__+#ifndef
SERIAL_PORT_INFO_GUID_H_+#define SERIAL_PORT_INFO_GUID_H_ ///
/// Serial Port Information GUIDdiff --git
a/UefiPayloadPkg/Include/Guid/SystemTableInfoGuid.h
b/UefiPayloadPkg/Include/Guid/SystemTableInfoGuid.h
index 2446820285..e742dd0ca5 100644
--- a/UefiPayloadPkg/Include/Guid/SystemTableInfoGuid.h
+++ b/UefiPayloadPkg/Include/Guid/SystemTableInfoGuid.h
@@ -6,8 +6,8 @@
**/ -#ifndef __SYSTEM_TABLE_INFO_GUID_H__-#define
__SYSTEM_TABLE_INFO_GUID_H__+#ifndef
SYSTEM_TABLE_INFO_GUID_H_+#define SYSTEM_TABLE_INFO_GUID_H_
/// /// System Table Information GUIDdiff --git
a/UefiPayloadPkg/Include/Library/BlParseLib.h
b/UefiPayloadPkg/Include/Library/BlParseLib.h
index 49eac31248..ac61faf980 100644
--- a/UefiPayloadPkg/Include/Library/BlParseLib.h
+++ b/UefiPayloadPkg/Include/Library/BlParseLib.h
@@ -6,6 +6,9 @@
SPDX-License-Identifier: BSD-2-Clause-Patent **/+#ifndef
BOOTLOADER_PARSE_LIB_+#define BOOTLOADER_PARSE_LIB_+ #include
<PiPei.h> #include <Guid/GraphicsInfoHob.h> #include
<Guid/MemoryMapInfoGuid.h>@@ -13,9 +16,6 @@
#include <Guid/SystemTableInfoGuid.h> #include
<Guid/AcpiBoardInfoGuid.h> -#ifndef __BOOTLOADER_PARSE_LIB__-
#define __BOOTLOADER_PARSE_LIB__- #define
GET_BOOTLOADER_PARAMETER() PcdGet64 (PcdBootloaderParameter)
typedef RETURN_STATUS \@@ -73,7 +73,7 @@ ParseSystemTable (
/** Find the serial port information - @param SERIAL_PORT_INFO Pointer
to serial port info structure+ @param SerialPortInfo Pointer to serial port
info structure @retval RETURN_SUCCESS Successfully find the serial port
information. @retval RETURN_NOT_FOUND Failed to find the serial port
information .diff --git a/UefiPayloadPkg/Include/Library/DxeHobListLib.h
b/UefiPayloadPkg/Include/Library/DxeHobListLib.h
index 7e9b23f6d7..139b11e329 100644
--- a/UefiPayloadPkg/Include/Library/DxeHobListLib.h
+++ b/UefiPayloadPkg/Include/Library/DxeHobListLib.h
@@ -15,8 +15,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/ -#ifndef __DXE_HOB_LIST_LIB_H__-#define
__DXE_HOB_LIST_LIB_H__+#ifndef DXE_HOB_LIST_LIB_H_+#define
DXE_HOB_LIST_LIB_H_ /// /// Cache copy of the start of HOB listdiff --git
a/UefiPayloadPkg/Include/Library/PlatformSupportLib.h
b/UefiPayloadPkg/Include/Library/PlatformSupportLib.h
index d9f0b83075..73263722eb 100644
--- a/UefiPayloadPkg/Include/Library/PlatformSupportLib.h
+++ b/UefiPayloadPkg/Include/Library/PlatformSupportLib.h
@@ -8,8 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/ -#ifndef __BOOTLOADER_PLATFORM_SUPPORT_LIB__-#define
__BOOTLOADER_PLATFORM_SUPPORT_LIB__+#ifndef
BOOTLOADER_PLATFORM_SUPPORT_LIB_+#define
BOOTLOADER_PLATFORM_SUPPORT_LIB_ /** Parse platform specific
information from bootloaderdiff --git
a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
index 4be5d66ba5..990508496f 100644
--- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
+++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
@@ -322,7 +322,7 @@ ParseCbMemTable (
) { EFI_STATUS Status;- struct cb_memory *rec;+ CB_MEMORY
*Rec; struct cb_memory_range *Range; UINT64 Start; UINT64
Size;@@ -339,13 +339,13 @@ ParseCbMemTable (
// // Get the coreboot memory table //- rec = (struct cb_memory
*)FindCbTag (CB_TAG_MEMORY);- if (rec == NULL) {+ Rec = (CB_MEMORY
*)FindCbTag (CB_TAG_MEMORY);+ if (Rec == NULL) { return Status; } -
for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) {- Range =
MEM_RANGE_PTR(rec, Index);+ for (Index = 0; Index <
MEM_RANGE_COUNT(Rec); Index++) {+ Range = MEM_RANGE_PTR(Rec,
Index); Start = cb_unpack64(Range->start); Size = cb_unpack64(Range-
size); @@ -380,7 +380,7 @@ ParseMemoryInfo (
IN VOID *Params ) {- struct cb_memory *rec;+ CB_MEMORY
*Rec; struct cb_memory_range *Range; UINTN Index;
MEMROY_MAP_ENTRY MemoryMap;@@ -388,13 +388,13 @@
ParseMemoryInfo (
// // Get the coreboot memory table //- rec = (struct cb_memory
*)FindCbTag (CB_TAG_MEMORY);- if (rec == NULL) {+ Rec = (CB_MEMORY
*)FindCbTag (CB_TAG_MEMORY);+ if (Rec == NULL) { return
RETURN_NOT_FOUND; } - for (Index = 0; Index <
MEM_RANGE_COUNT(rec); Index++) {- Range = MEM_RANGE_PTR(rec,
Index);+ for (Index = 0; Index < MEM_RANGE_COUNT(Rec); Index++) {+
Range = MEM_RANGE_PTR(Rec, Index); MemoryMap.Base =
cb_unpack64(Range->start); MemoryMap.Size = cb_unpack64(Range-
size); MemoryMap.Type = (UINT8)Range->type;@@ -449,7 +449,7 @@
ParseSystemTable (
/** Find the serial port information - @param SERIAL_PORT_INFO Pointer
to serial port info structure+ @param SerialPortInfo Pointer to serial port
info structure @retval RETURN_SUCCESS Successfully find the serial port
information. @retval RETURN_NOT_FOUND Failed to find the serial port
information .diff --git
a/UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.c
b/UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.c
index 92d3e17ef0..6c69f9879e 100644
--- a/UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.c
+++ b/UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.c
@@ -10,6 +10,12 @@
#include <Uefi.h> +/**+ The dummy constructor for DxeHobListLib.++
@retval EFI_SUCCESS++**/ EFI_STATUS EFIAPI
DxeHobListLibNullConstructor (diff --git
a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
index dd25ac2682..61cd11ba03 100644
--- a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
+++ b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
@@ -168,31 +168,6 @@ BuildResourceDescriptorHob (
Hob->ResourceLength = NumberOfBytes; } -VOID-EFIAPI-BuildFvHobs (-
IN EFI_PHYSICAL_ADDRESS PhysicalStart,- IN UINT64
NumberOfBytes,- IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute-
)-{-- EFI_RESOURCE_ATTRIBUTE_TYPE Resource;-- BuildFvHob
(PhysicalStart, NumberOfBytes);-- if (ResourceAttribute == NULL) {-
Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |-
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |-
EFI_RESOURCE_ATTRIBUTE_TESTED |-
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);- } else {- Resource
= *ResourceAttribute;- }-- BuildResourceDescriptorHob
(EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart,
NumberOfBytes);-}- /** Returns the next instance of a HOB type from the
starting HOB. @@ -283,7 +258,8 @@ EFIAPI
GetNextGuidHob ( IN CONST EFI_GUID *Guid, IN CONST VOID
*HobStart- ){+ )+{ EFI_PEI_HOB_POINTERS GuidHob; GuidHob.Raw =
(UINT8 *) HobStart;diff --git
a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h
b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h
index 3eee1fbeac..2848da5ce6 100644
--- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h
+++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -8,8 +8,8 @@
**/ -#ifndef _PCI_HOST_BRIDGE_H-#define
_PCI_HOST_BRIDGE_H+#ifndef PCI_HOST_BRIDGE_H_+#define
PCI_HOST_BRIDGE_H_ #include <UniversalPayload/PciRootBridges.h> diff --
git a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
index a0d7cdc306..0eddebe229 100644
--- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -210,8 +210,8 @@ PciHostBridgeGetRootBridges (
Free the root bridge instances array returned from
PciHostBridgeGetRootBridges(). - @param The root bridge instances array.-
@param The count of the array.+ @param Bridges The root bridge
instances array.+ @param Count The count of the array. **/ VOID
EFIAPIdiff --git
a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
index b0268f0506..eb28d48b3b 100644
--- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
+++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
@@ -205,7 +205,7 @@ PcatPciRootBridgeParseBars (
// // IO Bar //- if (Command & EFI_PCI_COMMAND_IO_SPACE)
{+ if ((Command & EFI_PCI_COMMAND_IO_SPACE) != 0) { Mask =
0xfffffffc; Base = OriginalValue & Mask; Length = ((~(Value & Mask))
& Mask) + 0x04;@@ -227,7 +227,7 @@ PcatPciRootBridgeParseBars (
// // Mem Bar //- if (Command &
EFI_PCI_COMMAND_MEMORY_SPACE) {+ if ((Command &
EFI_PCI_COMMAND_MEMORY_SPACE) != 0) { Mask = 0xfffffff0;
Base = OriginalValue & Mask;@@ -306,9 +306,14 @@ ScanForRootBridges (
UINT64 Base; UINT64 Limit; UINT64 Value;-
PCI_ROOT_BRIDGE_APERTURE Io, Mem, MemAbove4G, PMem,
PMemAbove4G, *MemAperture;- PCI_ROOT_BRIDGE *RootBridges;-
UINTN BarOffsetEnd;+ PCI_ROOT_BRIDGE_APERTURE Io;+
PCI_ROOT_BRIDGE_APERTURE Mem;+ PCI_ROOT_BRIDGE_APERTURE
MemAbove4G;+ PCI_ROOT_BRIDGE_APERTURE PMem;+
PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;+
PCI_ROOT_BRIDGE_APERTURE *MemAperture;+ PCI_ROOT_BRIDGE
*RootBridges;+ UINTN BarOffsetEnd; *NumberOfRootBridges =
0;diff --git
a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
index c4d317fa9e..dd91fcb29d 100644
---
a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
+++
b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.
+++ c
@@ -15,6 +15,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent

UNIVERSAL_PAYLOAD_PLATFORM_BOOT_MANAGER_OVERRIDE_PROTOCO
L *mUniversalPayloadPlatformBootManagerOverrideInstance = NULL;
+/**+ Signal EndOfDxe event and install SMM Ready to lock protocol.++**/
VOID InstallReadyToLock ( VOIDdiff --git
a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.
h
b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.
h
index 2f600c796f..c781610c6c 100644
---
a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.
h
+++
b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.
+++ h
@@ -1,12 +1,12 @@
-/**@file+/** @file Head file for BDS Platform specific code Copyright (c)
2015 - 2016, Intel Corporation. All rights reserved.<BR> SPDX-License-
Identifier: BSD-2-Clause-Patent **/ -#ifndef
_PLATFORM_BOOT_MANAGER_H-#define
_PLATFORM_BOOT_MANAGER_H+#ifndef
PLATFORM_BOOT_MANAGER_H_+#define
PLATFORM_BOOT_MANAGER_H_ #include <PiDxe.h> #include
<Protocol/LoadedImage.h>diff --git
a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h
b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h
index 68bdf5e555..e9d0eb00ee 100644
--- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h
+++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h
@@ -5,8 +5,8 @@ Copyright (c) 2016, Intel Corporation. All rights
reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#ifndef
_PLATFORM_CONSOLE_H-#define _PLATFORM_CONSOLE_H+#ifndef
PLATFORM_CONSOLE_H_+#define PLATFORM_CONSOLE_H_ #include
<PiDxe.h> #include <IndustryStandard/Pci.h>diff --git
a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c
b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c
index d17e660e0f..892a7f01be 100644
--- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c
+++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -1,4 +1,4 @@
-/**@file+/** @file Defined the platform specific device path which will be
filled to ConIn/ConOut variables. diff --git
a/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
b/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
index 2e4b7fe592..b35a4cc1d9 100644
--- a/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
+++ b/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -43,22 +43,6 @@ ResetSystemLibConstructor (
return EFI_SUCCESS; } --VOID-AcpiPmControl (- UINTN SuspendType- )-{-
UINTN PmCtrlReg;-- ASSERT (SuspendType <= 7);-- PmCtrlReg =
(UINTN)mAcpiBoardInfo.PmCtrlRegBase;- IoAndThenOr16 (PmCtrlReg,
(UINT16) ~0x3c00, (UINT16) (SuspendType << 10));- IoOr16 (PmCtrlReg,
BIT13);- CpuDeadLoop ();-}- /** Calling this function causes a system-wide
reset. This sets all circuitry within the system to its initial state. This type of
resetdiff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
index ccdcbfc07d..fc6b1b9a16 100644
--- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
+++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
@@ -141,7 +141,7 @@ ParseSystemTable (
/** Find the serial port information - @param SERIAL_PORT_INFO Pointer
to serial port info structure+ @param[out] SerialPortInfo Pointer to serial
port info structure @retval RETURN_SUCCESS Successfully find the serial
port information. @retval RETURN_NOT_FOUND Failed to find the serial
port information .diff --git
a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
index 0b6cb47cd0..67eed179f0 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
@@ -190,7 +190,7 @@ FvFindFileByTypeGuid (
@param FileHeader A pointer to the file header that contains the set
of sections to be searched.- @param SearchType The
value of the section type to search.+ @param SectionType The value
of the section type to search. @param SectionData A pointer to the
discovered section, if successful. @retval EFI_SUCCESS The section
was found.diff --git a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
index 265d47ca9d..d7f3af1304 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
@@ -196,7 +196,10 @@ PrintResourceDiscriptorHob (
/** Print the information in Acpi Guid Hob.+ @param[in] HobRaw A
pointer to the start of gUniversalPayloadAcpiTableGuid HOB.+ @param[in]
HobLength The size of the HOB data buffer.+ @retval EFI_SUCCESS If
it completed successfully. **/ EFI_STATUS@@ -217,6 +220,8 @@
PrintAcpiGuidHob (
/** Print the information in Serial Guid Hob. @param[in] HobRaw A
pointer to the start of gUniversalPayloadSerialPortInfoGuid HOB.+
@param[in] HobLength The size of the HOB data buffer.+ @retval
EFI_SUCCESS If it completed successfully. **/ EFI_STATUS@@ -240,6
+245,7 @@ PrintSerialGuidHob (
/** Print the information in Smbios Guid Hob. @param[in] HobRaw A
pointer to the start of gUniversalPayloadSmbios3TableGuid HOB.+
@param[in] HobLength The size of the HOB data buffer. @retval
EFI_SUCCESS If it completed successfully. **/ EFI_STATUS@@ -260,6
+266,8 @@ PrintSmbios3GuidHob (
/** Print the information in Smbios Guid Hob. @param[in] HobRaw A
pointer to the start of gUniversalPayloadSmbiosTableGuid HOB.+ @param[in]
HobLength The size of the HOB data buffer.+ @retval EFI_SUCCESS If
it completed successfully. **/ EFI_STATUS@@ -280,6 +288,8 @@
PrintSmbiosTablGuidHob (
/** Print the information in Acpi BoardInfo Guid Hob. @param[in] HobRaw
A pointer to the start of gUefiAcpiBoardInfoGuid HOB.+ @param[in]
HobLength The size of the HOB data buffer.+ @retval EFI_SUCCESS If
it completed successfully. **/ EFI_STATUS@@ -307,6 +317,7 @@
PrintAcpiBoardInfoGuidHob (
/** Print the information in Pci RootBridge Info Guid Hob. @param[in]
HobRaw A pointer to the start of
gUniversalPayloadPciRootBridgeInfoGuid HOB.+ @param[in] HobLength
The size of the HOB data buffer. @retval EFI_SUCCESS If it completed
successfully. **/@@ -362,6 +373,8 @@ PrintPciRootBridgeInfoGuidHob (
/** Print the information in Extra Data Guid Hob. @param[in] HobRaw
A pointer to the start of gUniversalPayloadExtraDataGuid HOB.+ @param[in]
HobLength The size of the HOB data buffer.+ @retval EFI_SUCCESS If
it completed successfully. **/ EFI_STATUS@@ -394,6 +407,8 @@
PrintExtraDataGuidHob (
/** Print the information in MemoryTypeInfoGuidHob. @param[in]
HobRaw A pointer to the start of gEfiMemoryTypeInformationGuid
HOB.+ @param[in] HobLength The size of the HOB data buffer.+ @retval
EFI_SUCCESS If it completed successfully. **/ EFI_STATUS@@ -414,7
+429,7 @@ PrintMemoryTypeInfoGuidHob (
/** Print the information in EdkiiBootManagerMenuFileGuid. @param[in]
HobRaw A pointer to the start of gEdkiiBootManagerMenuFileGuid
HOB.- @param[in] HobLength The size of the data buffer.+ @param[in]
HobLength The size of the HOB data buffer. @retval EFI_SUCCESS If it
completed successfully. **/ EFI_STATUSdiff --git
a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
index 0e6dcf10f9..adc56dc15f 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
@@ -389,6 +389,8 @@ BuildGenericHob (
/** Entry point to the C language phase of UEFI payload. + @param[in]
BootloaderParameter The starting address of bootloader parameter block.+
@retval It will not return if SUCCESS, and return error when passing
bootloader parameter. **/ EFI_STATUSdiff --git
a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
index de51c2fba9..637ed9c20b 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
@@ -1,9 +1,9 @@
/** @file-*-* Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>-
*-* SPDX-License-Identifier: BSD-2-Clause-Patent-*++ Copyright (c) 2021,
Intel Corporation. All rights reserved.<BR>++ SPDX-License-Identifier: BSD-
2-Clause-Patent+ **/ #ifndef __UEFI_PAYLOAD_ENTRY_H__diff --git
a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
index 7e67cf0f04..4d1096b323 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
@@ -114,18 +114,19 @@ AddNewHob (
} /**- Found the Resource Descriptor HOB that contains a range+ Found
the Resource Descriptor HOB that contains a range (Base, Top) + @param[in]
HobList Hob start address @param[in] Base Memory start address-
@param[in] Top Memory Top.+ @param[in] Top Memory end
address. - @return The pointer to the Resource Descriptor HOB.+ @retval
The pointer to the Resource Descriptor HOB. **/
EFI_HOB_RESOURCE_DESCRIPTOR * FindResourceDescriptorByRange (-
VOID *HobList,- EFI_PHYSICAL_ADDRESS Base,-
EFI_PHYSICAL_ADDRESS Top+ IN VOID *HobList,+ IN
EFI_PHYSICAL_ADDRESS Base,+ IN EFI_PHYSICAL_ADDRESS Top )
{ EFI_PEI_HOB_POINTERS Hob;@@ -171,7 +172,7 @@
FindResourceDescriptorByRange (
@param[in] MinimalNeededSize Minimal needed size. @param[in]
ExceptResourceHob Ignore this Resource Descriptor. - @return The
pointer to the Resource Descriptor HOB.+ @retval The pointer to the
Resource Descriptor HOB. **/ EFI_HOB_RESOURCE_DESCRIPTOR *
FindAnotherHighestBelow4GResourceDescriptor (@@ -240,6 +241,9 @@
FindAnotherHighestBelow4GResourceDescriptor (
/** It will build HOBs based on information from bootloaders. + @param[in]
BootloaderParameter The starting memory address of bootloader
parameter block.+ @param[out] DxeFv The pointer to the DXE FV in
memory.+ @retval EFI_SUCCESS If it completed successfully. @retval
Others If it failed to build required HOBs. **/@@ -376,6 +380,8 @@
BuildHobs (
/** Entry point to the C language phase of UEFI payload. + @param[in]
BootloaderParameter The starting address of bootloader parameter block.+
@retval It will not return if SUCCESS, and return error when passing
bootloader parameter. **/ EFI_STATUS--
2.32.0.windows.2



-=-=-=-=-=-=
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#82173): https://edk2.groups.io/g/devel/message/82173
Mute This Topic: https://groups.io/mt/86362335/1773972
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [maurice.ma@...]
-=-=-=-=-=-=


Re: [PATCH v1 3/7] ShellPkg: Update Acpiview PPTT parser to ACPI 6.4

Jeremy Linton
 

Hi,

On 10/18/21 10:10 AM, Chris Jones via groups.io wrote:
Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)
Update the Acpiview PPTT parser to use Acpi64.h. As part of the changes,
remove support for parsing PPTT type 2 ID structure.
Signed-off-by: Chris Jones <christopher.jones@...>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c | 61 ++++----------------
ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 2 +-
2 files changed, 12 insertions(+), 51 deletions(-)
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
index acd2b81bb3258c7322aa10d2c0e0d842d89e358b..bce9edcedde50e53035059e6da57b9449209a674 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
@@ -1,11 +1,11 @@
/** @file
PPTT table parser
- Copyright (c) 2019 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2019 - 2021, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
- - ACPI 6.3 Specification - January 2019
+ - ACPI 6.4 Specification - January 2021
- ARM Architecture Reference Manual ARMv8 (D.a)
**/
@@ -157,8 +157,8 @@ ValidateCacheAttributes (
)
{
// Reference: Advanced Configuration and Power Interface (ACPI) Specification
- // Version 6.2 Errata A, September 2017
- // Table 5-153: Cache Type Structure
+ // Version 6.4, January 2021
+ // Table 5-140: Cache Type Structure
UINT8 Attributes;
Attributes = *(UINT8*)Ptr;
@@ -222,22 +222,6 @@ STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = {
{L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL}
};
-/**
- An ACPI_PARSER array describing the ID Type Structure - Type 2.
-**/
-STATIC CONST ACPI_PARSER IdStructureParser[] = {
- {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
- {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
- {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
-
- {L"VENDOR_ID", 4, 4, NULL, Dump4Chars, NULL, NULL, NULL},
- {L"LEVEL_1_ID", 8, 8, L"0x%x", NULL, NULL, NULL, NULL},
- {L"LEVEL_2_ID", 8, 16, L"0x%x", NULL, NULL, NULL, NULL},
- {L"MAJOR_REV", 2, 24, L"0x%x", NULL, NULL, NULL, NULL},
- {L"MINOR_REV", 2, 26, L"0x%x", NULL, NULL, NULL, NULL},
- {L"SPIN_REV", 2, 28, L"0x%x", NULL, NULL, NULL, NULL},
-};
-
Don't people compile shellpkg for out of tree machines? Are we 100% sure that there aren't any machines in the wild with older PPTT's using this structure?

Although, this is less of a problem than below..

/**
This function parses the Processor Hierarchy Node Structure (Type 0).
@@ -335,29 +319,6 @@ DumpCacheTypeStructure (
);
}
-/**
- This function parses the ID Structure (Type 2).
-
- @param [in] Ptr Pointer to the start of the ID Structure data.
- @param [in] Length Length of the ID Structure.
-**/
-STATIC
-VOID
-DumpIDStructure (
- IN UINT8* Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "ID Structure",
- Ptr,
- Length,
- PARSER_PARAMS (IdStructureParser)
- );
-}
-
/**
This function parses the ACPI PPTT table.
When trace is enabled this function parses the PPTT table and
@@ -366,7 +327,6 @@ DumpIDStructure (
This function parses the following processor topology structures:
- Processor hierarchy node structure (Type 0)
- Cache Type Structure (Type 1)
- - ID structure (Type 2)
This function also performs validation of the ACPI table fields.
@@ -444,22 +404,23 @@ ParseAcpiPptt (
Print (L"0x%x\n", Offset);
switch (*ProcessorTopologyStructureType) {
- case EFI_ACPI_6_2_PPTT_TYPE_PROCESSOR:
+ case EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR:
I suspect this breaks every single other edk2-platforms machine in this tree not using the dynamic table generator. AKA all the hardcoded PPTTs used on synquacer/rpi/etc. I suspect this code path should be able to deal with multiple versions of the spec.


Thanks,

DumpProcessorHierarchyNodeStructure (
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
break;
- case EFI_ACPI_6_2_PPTT_TYPE_CACHE:
+ case EFI_ACPI_6_4_PPTT_TYPE_CACHE:
DumpCacheTypeStructure (
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
break;
- case EFI_ACPI_6_2_PPTT_TYPE_ID:
- DumpIDStructure (
- ProcessorTopologyStructurePtr,
- *ProcessorTopologyStructureLength
+ case EFI_ACPI_6_3_PPTT_TYPE_ID:
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: PPTT Type 2 - Processor ID is deprecated and must not be"
+ L"used.\n"
);
break;
default:
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index d725cad14c5d018e2004eb8e33c845aa9c719429..ab9e6c619d70df4f79d782416037d7bef62c92d5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -62,7 +62,7 @@ ACPI_TABLE_PARSER ParserList[] = {
ParseAcpiMcfg},
{EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
ParseAcpiPcct},
- {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+ {EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
ParseAcpiPptt},
{RSDP_TABLE_INFO, ParseAcpiRsdp},
{EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit},


Re: [PATCH v2 8/8] DynamicTablesPkg: IORT generator updates for Rev E.b spec

PierreGondois
 

Hi Sami,

With the small modification:

Reviewed-by: Pierre Gondois <pierre.gondois@...>

On 6/17/21 10:55, Sami Mujawar via groups.io wrote:
Bugzilla: 3458 - Add support IORT Rev E.b specification updates
(https://bugzilla.tianocore.org/show_bug.cgi?id=3458)

The IO Remapping Table, Platform Design Document, Revision E.b,
Feb 2021 (https://developer.arm.com/documentation/den0049/)
introduces the following updates, collectively including the
updates and errata fixes to Rev E and Rev E.a:
- increments the IORT table revision to 3.
- updates the node definition to add an 'Identifier' field.
- adds definition of node type 6 - Reserved Memory Range node.
- adds definition for Memory Range Descriptors.
- adds flag to indicate PRI support for root complexes.
- adds flag to indicate if the root complex supports forwarding
of PASID information on translated transactions to the SMMU.

Therefore, update the IORT generator to:
- increment IORT table revision count to 3.
- populate Identifier filed if revision is greater than 2.
- add support to populate Reserved Memory Range nodes and
the Memory range descriptors.
- add validation to check that the Identifier field is
unique.

Signed-off-by: Sami Mujawar <sami.mujawar@...>
---

Notes:
v2:
- The macro EFI_ACPI_IO_REMAPPING_TABLE_REVISION was set to [SAMI]
Rev 0 as setting to Rev 3 will break existing platforms.
Therefore, set the max supported IORT generator revision
to 3.

DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c | 661 ++++++++++++++++++--
DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h | 5 +-
2 files changed, 624 insertions(+), 42 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
index 9ccf72594db378878d4e3abbafe98e749d9963da..9b687f0165e6136f2f24749d27dee27edaff1b31 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
@@ -5,8 +5,8 @@
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
- - IO Remapping Table, Platform Design Document,
- Document number: ARM DEN 0049D, Issue D, March 2018
+ - IO Remapping Table, Platform Design Document, Revision E.b, Feb 2021
+ (https://developer.arm.com/documentation/den0049/)

**/
[snip]
+
// Ids for SMMUv3 node
IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuV3Node +
SmmuV3Node->Node.IdReference);
@@ -1417,6 +1616,7 @@ AddSmmuV3Nodes (
@param [in] This Pointer to the table Generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol Interface.
+ @param [in] AcpiTableInfo Pointer to the ACPI table info structure.
@param [in] Iort Pointer to IORT table structure.
@param [in] NodesStartOffset Offset for the start of the PMCG Nodes.
@param [in] NodeList Pointer to an array of PMCG Node Objects.
@@ -1431,6 +1631,7 @@ EFI_STATUS
AddPmcgNodes (
IN CONST ACPI_TABLE_GENERATOR * CONST This,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
IN CONST UINT32 NodesStartOffset,
IN CONST CM_ARM_PMCG_NODE * NodeList,
@@ -1465,12 +1666,18 @@ AddPmcgNodes (
// Populate the node header
PmcgNode->Node.Type = EFI_ACPI_IORT_TYPE_PMCG;
PmcgNode->Node.Length = (UINT16)NodeLength;
- PmcgNode->Node.Revision = 1;
- PmcgNode->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
PmcgNode->Node.NumIdMappings = NodeList->IdMappingCount;
PmcgNode->Node.IdReference = (NodeList->IdMappingCount == 0) ?
0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE);

+ if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV3) {
+ PmcgNode->Node.Revision = 1;
+ PmcgNode->Node.Identifier = EFI_ACPI_RESERVED_DWORD;
+ } else {
+ PmcgNode->Node.Revision = 2;
+ PmcgNode->Node.Identifier = NodeList->Identifier;
+ }
+
// PMCG specific data
PmcgNode->Base = NodeList->BaseAddress;
PmcgNode->OverflowInterruptGsiv = NodeList->OverflowInterrupt;
@@ -1494,8 +1701,19 @@ AddPmcgNodes (
return Status;
}

- if ((NodeList->IdMappingCount > 0) &&
- (NodeList->IdMappingToken != CM_NULL_TOKEN)) {
+ if (NodeList->IdMappingCount > 0) {
+ if (NodeList->IdMappingToken == CM_NULL_TOKEN) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Invalid Id Mapping token,"
+ " Token = 0x%x, Status =%r\n",
+ NodeList->IdMappingToken,
+ Status
+ ));
+ return Status;
+ }
+
As this is not related to the RevE spec update, could it be done in:

[PATCH v2 6/8] DynamicTablesPkg: IORT set reference to interrupt array
if present

This is also done at other places.

// Ids for PMCG node
IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)PmcgNode +
PmcgNode->Node.IdReference);
@@ -1526,6 +1744,273 @@ AddPmcgNodes (
return EFI_SUCCESS;
}
[snip]

Regards,

Pierre


Re: [PATCH v2 7/8] DynamicTablesPkg: Update ArmNameSpaceObjects for IORT Rev E.b

PierreGondois
 

Hi Sami,

With the small modifications:

Reviewed-by: Pierre Gondois <pierre.gondois@...>


On 6/17/21 10:55, Sami Mujawar via groups.io wrote:
Bugzilla: 3458 - Add support IORT Rev E.b specification updates
(https://bugzilla.tianocore.org/show_bug.cgi?id=3458)

The IO Remapping Table, Platform Design Document, Revision E.b,
Feb 2021 (https://developer.arm.com/documentation/den0049/)
introduces the following updates, collectively including the
updates and errata fixes to Rev E and Rev E.a:
- increments the IORT table revision to 3.
- updates the node definition to add an 'Identifier' field.
- adds definition of node type 6 - Reserved Memory Range node.
- adds definition for Memory Range Descriptors.
- adds flag to indicate PRI support for root complexes.
- adds flag to indicate if the root complex supports forwarding
of PASID information on translated transactions to the SMMU.

Therefore, update the Arm namespace objects to:
- add Identifier field to IORT nodes.
- introduce enums to represent RMR nodes and Memory Range
descriptors.
- add definition of node type 6 - Reserved Memory Range node.
- add definition for Memory Range Descriptors.

Signed-off-by: Sami Mujawar <sami.mujawar@...>
---

Notes:
v2:
- No code change since v1. Re-sending with v2 series. [SAMI]

DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 58 ++++++++++++++++++++
1 file changed, 58 insertions(+)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 19dcae13b2191e5f0b03ea85edec1191d2a406bf..98143cb5df127273cdd75452170fa651372b3896 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -58,6 +58,8 @@ typedef enum ArmObjectID {
EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity
EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info
EArmObjCmn600Info, ///< 36 - CMN-600 Info
+ EArmObjRmr, ///< 37 - Reserved Memory Range Node
+ EArmObjMemoryRangeDescriptor, ///< 38 - Memory Range Descriptor
EArmObjMax
} EARM_OBJECT_ID;

@@ -466,6 +468,9 @@ typedef struct CmArmItsGroupNode {
UINT32 ItsIdCount;
/// Reference token for the ITS identifier array
CM_OBJECT_TOKEN ItsIdToken;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
Would it be possible to say in the description that this is part of the
common node header ?

As we cannot modify the order of the fields anymore, I understand this
cannot be upper, but this would help as the order is a bit confusing.

} CM_ARM_ITS_GROUP_NODE;

/** A structure that describes the
@@ -497,6 +502,9 @@ typedef struct CmArmNamedComponentNode {
the entry in the namespace for this object.
*/
CHAR8* ObjectName;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_NAMED_COMPONENT_NODE;

/** A structure that describes the
@@ -525,6 +533,9 @@ typedef struct CmArmRootComplexNode {
UINT32 PciSegmentNumber;
/// Memory address size limit
UINT8 MemoryAddressSize;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_ROOT_COMPLEX_NODE;

/** A structure that describes the
@@ -567,6 +578,9 @@ typedef struct CmArmSmmuV1SmmuV2Node {
UINT32 SMMU_NSgCfgIrpt;
/// SMMU_NSgCfgIrpt interrupt flags
UINT32 SMMU_NSgCfgIrptFlags;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_SMMUV1_SMMUV2_NODE;

/** A structure that describes the
@@ -603,6 +617,9 @@ typedef struct CmArmSmmuV3Node {
UINT32 ProximityDomain;
/// Index into the array of ID mapping
UINT32 DeviceIdMappingIndex;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_SMMUV3_NODE;

/** A structure that describes the
@@ -627,6 +644,9 @@ typedef struct CmArmPmcgNode {

/// Reference token for the IORT node associated with this node
CM_OBJECT_TOKEN ReferenceToken;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_PMCG_NODE;

/** A structure that describes the
@@ -878,6 +898,44 @@ typedef struct CmArmCmn600Info {
CM_ARM_EXTENDED_INTERRUPT DtcInterrupt[4];
} CM_ARM_CMN_600_INFO;

+/** A structure that describes the
+ RMR node for the Platform.
+
+ ID: EArmObjRmr
+*/
+typedef struct CmArmRmrNode {
+ /// An unique token used to identify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// Reserved Memory Range flags.
+ UINT32 Flags;
+
+ /// Memory range descriptor count.
+ UINT32 MemRangeDescCount;
+ /// Reference token for the Memory Range descriptor array
+ CM_OBJECT_TOKEN MemRangeDescToken;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
The 'Identifier' field should be added above the 'Flags' as the
structure is a new and to respect the order of the spec.
+} CM_ARM_RMR_NODE;
+
+/** A structure that describes the
+ Memory Range descriptor.
+
+ ID: EArmObjMemoryRangeDescriptor
+*/
+typedef struct CmArmRmrDescriptor {
+ /// Base address.
+ UINT64 BaseAddress;
+
+ /// Length.
+ UINT64 Length;
The exact names of the fields in the spec are:
-Physical Range offset
-Physical Range length

Would it be possible to add these names in the description ?
+} CM_ARM_MEMORY_RANGE_DESCRIPTOR;
+
#pragma pack()

#endif // ARM_NAMESPACE_OBJECTS_H_


Re: [PATCH v2 7/8] DynamicTablesPkg: Update ArmNameSpaceObjects for IORT Rev E.b

PierreGondois
 

Hi Sami,

With the small modifications:

Reviewed-by: Pierre Gondois <pierre.gondois@...>


On 6/17/21 10:55, Sami Mujawar via groups.io wrote:
Bugzilla: 3458 - Add support IORT Rev E.b specification updates
(https://bugzilla.tianocore.org/show_bug.cgi?id=3458)

The IO Remapping Table, Platform Design Document, Revision E.b,
Feb 2021 (https://developer.arm.com/documentation/den0049/)
introduces the following updates, collectively including the
updates and errata fixes to Rev E and Rev E.a:
- increments the IORT table revision to 3.
- updates the node definition to add an 'Identifier' field.
- adds definition of node type 6 - Reserved Memory Range node.
- adds definition for Memory Range Descriptors.
- adds flag to indicate PRI support for root complexes.
- adds flag to indicate if the root complex supports forwarding
of PASID information on translated transactions to the SMMU.

Therefore, update the Arm namespace objects to:
- add Identifier field to IORT nodes.
- introduce enums to represent RMR nodes and Memory Range
descriptors.
- add definition of node type 6 - Reserved Memory Range node.
- add definition for Memory Range Descriptors.

Signed-off-by: Sami Mujawar <sami.mujawar@...>
---

Notes:
v2:
- No code change since v1. Re-sending with v2 series. [SAMI]

DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 58 ++++++++++++++++++++
1 file changed, 58 insertions(+)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 19dcae13b2191e5f0b03ea85edec1191d2a406bf..98143cb5df127273cdd75452170fa651372b3896 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -58,6 +58,8 @@ typedef enum ArmObjectID {
EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity
EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info
EArmObjCmn600Info, ///< 36 - CMN-600 Info
+ EArmObjRmr, ///< 37 - Reserved Memory Range Node
+ EArmObjMemoryRangeDescriptor, ///< 38 - Memory Range Descriptor
EArmObjMax
} EARM_OBJECT_ID;

@@ -466,6 +468,9 @@ typedef struct CmArmItsGroupNode {
UINT32 ItsIdCount;
/// Reference token for the ITS identifier array
CM_OBJECT_TOKEN ItsIdToken;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
Would it be possible to say in the description that this is part of the
common node header ?

As we cannot modify the order of the fields anymore, I understand this
cannot be upper, but this would help as the order is a bit confusing.

} CM_ARM_ITS_GROUP_NODE;

/** A structure that describes the
@@ -497,6 +502,9 @@ typedef struct CmArmNamedComponentNode {
the entry in the namespace for this object.
*/
CHAR8* ObjectName;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_NAMED_COMPONENT_NODE;

/** A structure that describes the
@@ -525,6 +533,9 @@ typedef struct CmArmRootComplexNode {
UINT32 PciSegmentNumber;
/// Memory address size limit
UINT8 MemoryAddressSize;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_ROOT_COMPLEX_NODE;

/** A structure that describes the
@@ -567,6 +578,9 @@ typedef struct CmArmSmmuV1SmmuV2Node {
UINT32 SMMU_NSgCfgIrpt;
/// SMMU_NSgCfgIrpt interrupt flags
UINT32 SMMU_NSgCfgIrptFlags;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_SMMUV1_SMMUV2_NODE;

/** A structure that describes the
@@ -603,6 +617,9 @@ typedef struct CmArmSmmuV3Node {
UINT32 ProximityDomain;
/// Index into the array of ID mapping
UINT32 DeviceIdMappingIndex;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_SMMUV3_NODE;

/** A structure that describes the
@@ -627,6 +644,9 @@ typedef struct CmArmPmcgNode {

/// Reference token for the IORT node associated with this node
CM_OBJECT_TOKEN ReferenceToken;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
} CM_ARM_PMCG_NODE;

/** A structure that describes the
@@ -878,6 +898,44 @@ typedef struct CmArmCmn600Info {
CM_ARM_EXTENDED_INTERRUPT DtcInterrupt[4];
} CM_ARM_CMN_600_INFO;

+/** A structure that describes the
+ RMR node for the Platform.
+
+ ID: EArmObjRmr
+*/
+typedef struct CmArmRmrNode {
+ /// An unique token used to identify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// Reserved Memory Range flags.
+ UINT32 Flags;
+
+ /// Memory range descriptor count.
+ UINT32 MemRangeDescCount;
+ /// Reference token for the Memory Range descriptor array
+ CM_OBJECT_TOKEN MemRangeDescToken;
+
+ /// Unique identifier for this node.
+ UINT32 Identifier;
The 'Identifier' field should be added above the 'Flags' as the
structure is a new and to respect the order of the spec.
+} CM_ARM_RMR_NODE;
+
+/** A structure that describes the
+ Memory Range descriptor.
+
+ ID: EArmObjMemoryRangeDescriptor
+*/
+typedef struct CmArmRmrDescriptor {
+ /// Base address.
+ UINT64 BaseAddress;
+
+ /// Length.
+ UINT64 Length;
The exact names of the fields in the spec are:
-Physical Range offset
-Physical Range length

Would it be possible to add these names in the description ?
+} CM_ARM_MEMORY_RANGE_DESCRIPTOR;
+
#pragma pack()

#endif // ARM_NAMESPACE_OBJECTS_H_


Re: [PATCH v2 6/8] DynamicTablesPkg: IORT set reference to interrupt array if present

PierreGondois
 

Hi Sami,

With the small modification:

Reviewed-by: Pierre Gondois <pierre.gondois@...>


On 6/17/21 10:55, Sami Mujawar via groups.io wrote:
The IORT generator is populating the reference field for Context and
PMU interrupts even if their count is zero.

Update the IORT generator to set the references only if the interrupt
count is not 0. Also add checks to ensure a valid reference token has
been provided.

Signed-off-by: Sami Mujawar <sami.mujawar@...>
---

Notes:
v2:
- No code change since v1. Re-sending with v2 series. [SAMI]

DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c | 82 +++++++++++++-------
1 file changed, 55 insertions(+), 27 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
index bdf839eab25e2b84b40c50da38f2bf961cdc5f42..9ccf72594db378878d4e3abbafe98e749d9963da 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
@@ -1136,6 +1136,7 @@ AddSmmuV1V2Nodes (
EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * ContextInterruptArray;
EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * PmuInterruptArray;
UINT64 NodeLength;
+ UINT32 Offset;

ASSERT (Iort != NULL);

@@ -1178,47 +1179,74 @@ AddSmmuV1V2Nodes (
SmmuNode->GlobalInterruptArrayRef =
OFFSET_OF (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE, SMMU_NSgIrpt);

+ Offset = sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE);
// Context Interrupt
SmmuNode->NumContextInterrupts = NodeList->ContextInterruptCount;
- SmmuNode->ContextInterruptArrayRef =
- sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE);
- ContextInterruptArray =
- (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode +
- sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE));
+ if (NodeList->ContextInterruptCount != 0) {
+ SmmuNode->ContextInterruptArrayRef = Offset;
+ ContextInterruptArray =
+ (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode + Offset);
+ Offset += (NodeList->ContextInterruptCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT));
+ }

// PMU Interrupt
SmmuNode->NumPmuInterrupts = NodeList->PmuInterruptCount;
- SmmuNode->PmuInterruptArrayRef = SmmuNode->ContextInterruptArrayRef +
- (NodeList->ContextInterruptCount *
- sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT));
- PmuInterruptArray =
- (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode +
- SmmuNode->PmuInterruptArrayRef);
+ if (NodeList->PmuInterruptCount != 0) {
+ SmmuNode->PmuInterruptArrayRef = Offset;
+ PmuInterruptArray =
+ (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode + Offset);
+ }

SmmuNode->SMMU_NSgIrpt = NodeList->SMMU_NSgIrpt;
SmmuNode->SMMU_NSgIrptFlags = NodeList->SMMU_NSgIrptFlags;
SmmuNode->SMMU_NSgCfgIrpt = NodeList->SMMU_NSgCfgIrpt;
SmmuNode->SMMU_NSgCfgIrptFlags = NodeList->SMMU_NSgCfgIrptFlags;

- // Add Context Interrupt Array
- Status = AddSmmuInterruptArray (
- CfgMgrProtocol,
- ContextInterruptArray,
- SmmuNode->NumContextInterrupts,
- NodeList->ContextInterruptToken
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: IORT: Failed to Context Interrupt Array. Status = %r\n",
- Status
- ));
- return Status;
+ if (NodeList->ContextInterruptCount != 0) {
+ if (NodeList->ContextInterruptToken == CM_NULL_TOKEN) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Invalid Context Interrupt token,"
+ " Token = 0x%x, Status =%r\n",
+ NodeList->ContextInterruptToken,
+ Status
+ ));
+ return Status;
+ }
+
+ // Add Context Interrupt Array
+ Status = AddSmmuInterruptArray (
+ CfgMgrProtocol,
+ ContextInterruptArray,
+ SmmuNode->NumContextInterrupts,
+ NodeList->ContextInterruptToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to Context Interrupt Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
}

// Add PMU Interrupt Array
- if ((SmmuNode->NumPmuInterrupts > 0) &&
- (NodeList->PmuInterruptToken != CM_NULL_TOKEN)) {
+ if (SmmuNode->NumPmuInterrupts != 0) {
+ if (NodeList->PmuInterruptToken == CM_NULL_TOKEN) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Invalid PMU Interrupt token,"
+ " Token = 0x%x, Status =%r\n",
+ NodeList->PmuInterruptToken,
+ Status
+ ));
+ return Status;
+ }
+
Some similar modifications are done in the last patch of the serie:

[PATCH v2 8/8] DynamicTablesPkg: IORT generator updates for Rev E.b spec

For instance, the same change is done in the AddPmcgNodes() function.
Would it be possible to group them ?

Status = AddSmmuInterruptArray (
CfgMgrProtocol,
PmuInterruptArray,


[PATCH 2/2] ArmPkg: Add Library/MpInitLib to support EFI_MP_SERVICES_PROTOCOL

Rebecca Cran <rebecca@...>
 

Add support for EFI_MP_SERVICES_PROTOCOL during the DXE phase under
AArch64.

PSCI_CPU_ON is called to power on the core, the supplied procedure is
executed and PSCI_CPU_OFF is called to power off the core.

Minimal setup is done before calling the supplied procedure: for example
the MMU and caches are not enabled.

Signed-off-by: Rebecca Cran <rebecca@...>
---
ArmPkg/ArmPkg.dec | 4 +
ArmPkg/ArmPkg.dsc | 4 +
ArmPkg/Drivers/CpuDxe/AArch64/Arch.c | 22 +
ArmPkg/Drivers/CpuDxe/Arm/Arch.c | 22 +
ArmPkg/Drivers/CpuDxe/CpuDxe.c | 2 +
ArmPkg/Drivers/CpuDxe/CpuDxe.h | 10 +
ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 6 +
ArmPkg/Drivers/CpuDxe/CpuMpInit.c | 604 ++++++++
ArmPkg/Include/Library/MpInitLib.h | 366 +++++
ArmPkg/Library/MpInitLib/AArch64/MpFuncs.S | 61 +
ArmPkg/Library/MpInitLib/DxeMpInitLib.inf | 53 +
ArmPkg/Library/MpInitLib/DxeMpLib.c | 1498 ++++++++++++++++++++
ArmPkg/Library/MpInitLib/InternalMpInitLib.h | 358 +++++
ArmVirtPkg/ArmVirt.dsc.inc | 3 +
14 files changed, 3013 insertions(+)

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 5935663fa9a3..f8bb4af21749 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -74,6 +74,10 @@
#
DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.h

+ ## @libraryclass Provides a MP Services interface.
+ #
+ MpInitLib|Include/Library/MpInitLib.h
+
## @libraryclass Provides an interface to query miscellaneous OEM
# information.
#
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index 8abe3713c829..26fb8bb94c07 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -99,6 +99,9 @@
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf

+[LibraryClasses.AARCH64]
+ MpInitLib|ArmPkg/Library/MpInitLib/DxeMpInitLib.inf
+
[LibraryClasses.ARM, LibraryClasses.AARCH64]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

@@ -163,4 +166,5 @@
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf

[Components.AARCH64, Components.ARM]
+ ArmPkg/Library/MpInitLib/DxeMpInitLib.inf
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Arch.c b/ArmPkg/Drivers/CpuDxe/AArch64/Arch.c
new file mode 100644
index 000000000000..a4b9e9037100
--- /dev/null
+++ b/ArmPkg/Drivers/CpuDxe/AArch64/Arch.c
@@ -0,0 +1,22 @@
+/** @file
+ Architecture specific functions.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <CpuDxe.h>
+
+/** Initializes multi-processor support.
+ *
+**/
+VOID
+ArchInitializeMpSupport (
+ VOID
+ )
+{
+ InitializeMpSupport ();
+}
diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Arch.c b/ArmPkg/Drivers/CpuDxe/Arm/Arch.c
new file mode 100644
index 000000000000..0ded264cd06a
--- /dev/null
+++ b/ArmPkg/Drivers/CpuDxe/Arm/Arch.c
@@ -0,0 +1,22 @@
+/** @file
+ Architecture specific functions.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <CpuDxe.h>
+
+/** Initializes multi-processor support.
+ *
+**/
+VOID
+ArchInitializeMpSupport (
+ VOID
+ )
+{
+ /* Nothing to do - ARM doesn't support EFI_MP_SERVICES_PROTOCOL */
+}
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Drivers/CpuDxe/CpuDxe.c
index 082ef30fb6c4..db8752f5b54f 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.c
@@ -279,5 +279,7 @@ CpuDxeInitialize (
);
ASSERT_EFI_ERROR (Status);

+ ArchInitializeMpSupport ();
+
return Status;
}
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
index 4cf3ab258c24..6e7ceafa4436 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -143,4 +143,14 @@ SetGcdMemorySpaceAttributes (
IN UINT64 Attributes
);

+VOID
+InitializeMpSupport (
+ VOID
+ );
+
+VOID
+ArchInitializeMpSupport (
+ VOID
+ );
+
#endif // CPU_DXE_H_
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
index e5549fc71df7..f4cdb8ab5613 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
@@ -26,10 +26,13 @@
Exception.c

[Sources.ARM]
+ Arm/Arch.c
Arm/Mmu.c

[Sources.AARCH64]
+ AArch64/Arch.c
AArch64/Mmu.c
+ CpuMpInit.c

[Packages]
ArmPkg/ArmPkg.dec
@@ -37,6 +40,9 @@
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec

+[LibraryClasses.AARCH64]
+ MpInitLib
+
[LibraryClasses]
ArmLib
ArmMmuLib
diff --git a/ArmPkg/Drivers/CpuDxe/CpuMpInit.c b/ArmPkg/Drivers/CpuDxe/CpuMpInit.c
new file mode 100644
index 000000000000..5bf4ed12b711
--- /dev/null
+++ b/ArmPkg/Drivers/CpuDxe/CpuMpInit.c
@@ -0,0 +1,604 @@
+/** @file
+ Construct MP Services Protocol.
+
+ The MP Services Protocol provides a generalized way of performing following tasks:
+ - Retrieving information of multi-processor environment and MP-related status of
+ specific processors.
+ - Dispatching user-provided function to APs.
+ - Maintain MP-related processor status.
+
+ The MP Services Protocol must be produced on any system with more than one logical
+ processor.
+
+ The Protocol is available only during boot time.
+
+ MP Services Protocol is hardware-independent. Most of the logic of this protocol
+ is architecturally neutral. It abstracts the multi-processor environment and
+ status of processors, and provides interfaces to retrieve information, maintain,
+ and dispatch.
+
+ MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
+ protocol to retrieve data that are needed for an MP platform and report them to OS.
+ MP Services Protocol may also be used to program and configure processors, such
+ as MTRR synchronization for memory space attributes setting in DXE Services.
+ MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
+ by taking advantage of the processing capabilities of the APs, for example, using
+ APs to help test system memory in parallel with other device initialization.
+ Diagnostics applications may also use this protocol for multi-processor.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MpInitLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ This function is used to retrieve the following information:
+ - The number of logical processors that are present in the system.
+ - The number of enabled logical processors in the system at the instant
+ this call is made.
+
+ Because MP Service Protocol provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
+ course of a boot session.
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
+ is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the
+ EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including
+ the BSP and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled
+ logical processors that exist in the
+ system, including the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetNumberOfProcessors (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ )
+{
+ return MpInitLibGetNumberOfProcessors (
+ This,
+ NumberOfProcessors,
+ NumberOfEnabledProcessors
+ );
+}
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of
+ operation, slot numbers is all considered platform-related information and is
+ not provided by this service.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorNumber The index of the processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information
+ for the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetProcessorInfo (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ )
+{
+ return MpInitLibGetProcessorInfo (
+ This,
+ ProcessorNumber,
+ ProcessorInfoBuffer
+ );
+}
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function
+ specified by Procedure. If any enabled AP is busy, then EFI_NOT_READY is
+ returned immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number.
+ Otherwise, all the enabled APs execute the function specified by Procedure
+ simultaneously.
+
+ If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+ APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in
+ non-blocking mode, and the BSP returns from this service without waiting for
+ APs. If a non-blocking mode is requested after the UEFI Event
+ EFI_EVENT_GROUP_READY_TO_BOOT is signaled, then EFI_UNSUPPORTED must be
+ returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before all APs
+ return from Procedure, then Procedure on the failed APs is terminated.
+ All enabled APs are always available for further calls to
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() to make sure that the nature of the
+ code that is executed on the BSP and the dispatched APs is well controlled.
+ The MP Services Protocol does not guarantee that the Procedure function is
+ MP-safe. Hence, the tasks that can be run in parallel are limited to certain
+ independent tasks and well-controlled exclusive code. EFI services and
+ protocols may not be called by APs unless otherwise specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroseconds expires.
+
+ In non-blocking execution mode, BSP is freed to return to the caller and then
+ proceed to the next task without having to wait for APs. The following
+ sequence needs to occur in a non-blocking execution mode:
+
+ -# The caller that intends to use this MP Services Protocol in non-blocking
+ mode creates WaitEvent by calling the EFI CreateEvent() service. The
+ caller invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter
+ WaitEvent is not NULL, then StartupAllAPs() executes in non-blocking
+ mode. It requests the function specified by Procedure to be started on
+ all the enabled APs, and releases the BSP to continue with other tasks.
+ -# The caller can use the CheckEvent() and WaitForEvent() services to check
+ the state of the WaitEvent created in step 1.
+ -# When the APs complete their task or TimeoutInMicroSecondss expires, the
+ MP Service signals WaitEvent by calling the EFI SignalEvent() function.
+ If FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ It is the caller's responsibility to free the buffer with FreePool()
+ service.
+ -# This invocation of SignalEvent() function informs the caller that invoked
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs
+ completed the specified task or a timeout occurred. The contents of
+ FailedCpuList can be examined to determine which APs did not complete the
+ specified task prior to the timeout.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor
+ handle number. If FALSE, then all the
+ enabled APs execute the function specified
+ by Procedure simultaneously.
+ @param[in] WaitEvent The event created by the caller with
+ CreateEvent() service. If it is NULL,
+ then execute in blocking mode. BSP waits
+ until all APs finish or
+ TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking
+ mode. BSP requests the function specified
+ by Procedure to be started on all the
+ enabled APs, and go on executing
+ immediately. If all return from Procedure,
+ or TimeoutInMicroseconds expires, this
+ event is signaled. The BSP can use the
+ CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds
+ for APs to return from Procedure, either
+ for blocking or non-blocking mode. Zero
+ means infinity. If the timeout expires
+ before all APs return from Procedure, then
+ Procedure on the failed APs is terminated.
+ All enabled APs are available for next
+ function assigned by
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored.
+ Otherwise, if all APs finish successfully,
+ then its content is set to NULL. If not
+ all APs finish before timeout expires,
+ then its content is set to address of the
+ buffer holding handle numbers of the
+ failed APs.
+ The buffer is allocated by MP Service
+ Protocol, and it's the caller's
+ responsibility to free the buffer with
+ FreePool() service.
+ In blocking mode, it is ready for
+ consumption when the call returns. In
+ non-blocking mode, it is ready when
+ WaitEvent is signaled. The list of failed
+ CPU is terminated by END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been
+ dispatched to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StartupAllAPs (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ )
+{
+ return MpInitLibStartupAllAPs (
+ This,
+ Procedure,
+ SingleThread,
+ WaitEvent,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ FailedCpuList
+ );
+}
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
+ is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StartupThisAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ )
+{
+ return MpInitLibStartupThisAP (
+ This,
+ Procedure,
+ ProcessorNumber,
+ WaitEvent,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ Finished
+ );
+}
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be
+ performed by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SwitchBSP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ return MpInitLibSwitchBSP (This, ProcessorNumber, EnableOldBSP);
+}
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system. This service may not be supported
+ after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
+
+ If the enable or disable AP operation cannot be completed prior to the return
+ from this service, then EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+EnableDisableAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ )
+{
+ return MpInitLibEnableDisableAP (This, ProcessorNumber, EnableAP, HealthFlag);
+}
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+WhoAmI (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ return MpInitLibWhoAmI (This, ProcessorNumber);
+}
+
+EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
+ GetNumberOfProcessors,
+ GetProcessorInfo,
+ StartupAllAPs,
+ StartupThisAP,
+ SwitchBSP,
+ EnableDisableAP,
+ WhoAmI
+};
+
+/** Initialize multi-processor support.
+
+**/
+VOID
+InitializeMpSupport (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN MaxCpus;
+ EFI_HOB_GENERIC_HEADER *Hob;
+ VOID *HobData;
+ UINTN HobDataSize;
+ ARM_PROCESSOR_TABLE CpuInfo;
+
+ DEBUG ((DEBUG_INFO, "Starting MP services"));
+
+ Hob = GetFirstGuidHob (&gArmMpCoreInfoGuid);
+ if (Hob != NULL) {
+ HobData = GET_GUID_HOB_DATA (Hob);
+ HobDataSize = GET_GUID_HOB_DATA_SIZE (Hob);
+ CpuInfo.ArmCpus = (ARM_CORE_INFO *)HobData;
+ CpuInfo.NumberOfEntries = HobDataSize / sizeof (ARM_CORE_INFO);
+ MaxCpus = CpuInfo.NumberOfEntries;
+ }
+
+ if (MaxCpus == 1) {
+ DEBUG ((DEBUG_WARN, "Trying to use EFI_MP_SERVICES_PROTOCOL on a UP system"));
+ // We are not MP so nothing to do
+ return;
+ }
+
+ MpInitLibInitialize (MaxCpus, &CpuInfo);
+
+ //
+ // Now install the MP services protocol.
+ //
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiMpServiceProtocolGuid,
+ &mMpServicesTemplate,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+}
diff --git a/ArmPkg/Include/Library/MpInitLib.h b/ArmPkg/Include/Library/MpInitLib.h
new file mode 100644
index 000000000000..a4b80c18a9e8
--- /dev/null
+++ b/ArmPkg/Include/Library/MpInitLib.h
@@ -0,0 +1,366 @@
+/** @file
+
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MP_INITLIB_H_
+#define MP_INITLIB_H_
+
+#include <Protocol/Cpu.h>
+#include <Protocol/MpService.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/ArmMpCoreInfo.h>
+
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ @param[in] This A pointer to the
+ EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including
+ the BSP and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled
+ logical processors that exist in the
+ system, including the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetNumberOfProcessors (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ );
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorIndex The index of the processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information
+ for the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetProcessorInfo (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ );
+
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor
+ handle number. If FALSE, then all the
+ enabled APs execute the function specified
+ by Procedure simultaneously.
+ @param[in] WaitEvent The event created by the caller with
+ CreateEvent() service. If it is NULL,
+ then execute in blocking mode. BSP waits
+ until all APs finish or
+ TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking
+ mode. BSP requests the function specified
+ by Procedure to be started on all the
+ enabled APs, and go on executing
+ immediately. If all return from Procedure,
+ or TimeoutInMicroseconds expires, this
+ event is signaled. The BSP can use the
+ CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds
+ for APs to return from Procedure, either
+ for blocking or non-blocking mode. Zero
+ means infinity. If the timeout expires
+ before all APs return from Procedure, then
+ Procedure on the failed APs is terminated.
+ All enabled APs are available for next
+ function assigned by
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored.
+ Otherwise, if all APs finish successfully,
+ then its content is set to NULL. If not
+ all APs finish before timeout expires,
+ then its content is set to address of the
+ buffer holding handle numbers of the
+ failed APs.
+ The buffer is allocated by MP Service
+ Protocol, and it's the caller's
+ responsibility to free the buffer with
+ FreePool() service.
+ In blocking mode, it is ready for
+ consumption when the call returns. In
+ non-blocking mode, it is ready when
+ WaitEvent is signaled. The list of failed
+ CPU is terminated by END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been
+ dispatched to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibStartupAllAPs (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ );
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibStartupThisAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ );
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be
+ performed by the current BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibSwitchBSP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ );
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibEnableDisableAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ );
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibWhoAmI (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ );
+
+/** Initializes the MP Services system data
+
+ @param NumberOfProcessors The number of processors, both BSP and AP.
+ @param CpuInfo CPU information gathered earlier during boot.
+
+**/
+VOID
+MpInitLibInitialize (
+ IN UINTN NumberOfProcessors,
+ IN ARM_PROCESSOR_TABLE *CpuInfo
+ );
+
+
+
+#endif /* MP_INITLIB_H_ */
diff --git a/ArmPkg/Library/MpInitLib/AArch64/MpFuncs.S b/ArmPkg/Library/MpInitLib/AArch64/MpFuncs.S
new file mode 100644
index 000000000000..287db060e594
--- /dev/null
+++ b/ArmPkg/Library/MpInitLib/AArch64/MpFuncs.S
@@ -0,0 +1,61 @@
+#===============================================================================
+# Copyright (c) 2021 NUVIA Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#===============================================================================
+
+.text
+.align 3
+
+#include <AsmMacroIoLibV8.h>
+#include <IndustryStandard/ArmStdSmc.h>
+
+#include "InternalMpInitLib.h"
+
+GCC_ASM_IMPORT (gApStacksBase)
+GCC_ASM_IMPORT (gProcessorIDs)
+GCC_ASM_IMPORT (ApProcedure)
+GCC_ASM_IMPORT (gApStackSize)
+
+GCC_ASM_EXPORT (ApEntryPoint)
+
+StartupAddr: .8byte ASM_PFX(ApProcedure)
+
+// Entry-point for the AP
+// VOID
+// ApEntryPoint (
+// VOID
+// );
+ASM_PFX(ApEntryPoint):
+ mrs x0, mpidr_el1
+ ldr x1, gProcessorIDs
+ mov x2, 0 // x2 = processor index
+ mov x3, 0 // x3 = address offset
+
+// Find index in gProcessorIDs for current processor
+1:
+ ldr x4, [x1, x3] // x4 = gProcessorIDs + x3
+ cmp x4, 0 // check if we've reached the end of gProcessorIDs
+ beq ProcessorNotFound
+ add x3, x3, 8 // x3 += sizeof (*gProcessorIDs)
+ add x2, x2, 1 // x2++
+ cmp x0, x4 // if mpidr_el1 != *(gProcessorIDs + x3) then loop
+ bne 1b
+ sub x2, x2, 1
+
+// Calculate stack address
+ // x2 contains the index for the current processor
+ ldr x0, gApStacksBase
+ ldr x1, gApStackSize
+ mul x3, x2, x1 // x3 = ProcessorIndex * gApStackSize
+ add x4, x0, x3 // x4 = gApStacksBase + x3
+ add sp, x4, x1 // sp = x4 + gApStackSize
+
+ ldr x0, StartupAddr // ASM_PFX(ApProcedure)
+ blr x0 // doesn't return
+
+ProcessorNotFound:
+// Turn off the processor
+ MOV32 (w0, ARM_SMC_ID_PSCI_CPU_OFF)
+ smc #0
+ b .
diff --git a/ArmPkg/Library/MpInitLib/DxeMpInitLib.inf b/ArmPkg/Library/MpInitLib/DxeMpInitLib.inf
new file mode 100644
index 000000000000..2275b6cca33a
--- /dev/null
+++ b/ArmPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -0,0 +1,53 @@
+#/** @file
+#
+# Component description file for the DxeMpInitLib module.
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = DxeMpInitLib
+ FILE_GUID = c9ca773c-8ae4-4b74-82fd-f7345503294e
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = MpInitLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = AARCH64
+#
+
+[Sources.AARCH64]
+ AArch64/MpFuncs.S
+
+[Sources]
+ DxeMpLib.c
+ InternalMpInitLib.h
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmLib
+ ArmSmcLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiMpServiceProtocolGuid
+
+[Guids]
+ gArmMpCoreInfoGuid
diff --git a/ArmPkg/Library/MpInitLib/DxeMpLib.c b/ArmPkg/Library/MpInitLib/DxeMpLib.c
new file mode 100644
index 000000000000..6053db740624
--- /dev/null
+++ b/ArmPkg/Library/MpInitLib/DxeMpLib.c
@@ -0,0 +1,1498 @@
+/** @file
+ Construct MP Services Protocol.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+ Portions Copyright (c) 2011, Apple Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MpInitLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <IndustryStandard/ArmStdSmc.h>
+
+#include "InternalMpInitLib.h"
+
+#define POLL_INTERVAL_US 50000
+
+STATIC CPU_MP_DATA mCpuMpData;
+STATIC BOOLEAN mNonBlockingModeAllowed;
+UINT64 *gApStacksBase;
+UINT64 *gProcessorIDs;
+CONST UINT64 gApStackSize = AP_STACK_SIZE;
+
+/** C entry-point for the AP.
+ This function gets called from the assembly function ApEntryPoint.
+
+**/
+VOID
+ApProcedure (
+ VOID
+ )
+{
+ ARM_SMC_ARGS Args;
+ EFI_AP_PROCEDURE ApProcedure;
+ VOID *ApParameter;
+ UINTN ProcessorIndex;
+
+ MpInitLibWhoAmI (&mMpServicesTemplate, &ProcessorIndex);
+
+ /* Fetch the user-supplied procedure and parameter to execute */
+ ApProcedure = mCpuMpData.CpuData[ProcessorIndex].Procedure;
+ ApParameter = mCpuMpData.CpuData[ProcessorIndex].Parameter;
+
+ ApProcedure (ApParameter);
+
+ mCpuMpData.CpuData[ProcessorIndex].State = CpuStateFinished;
+
+ /* Since we're finished with this AP, turn it off */
+ Args.Arg0 = ARM_SMC_ID_PSCI_CPU_OFF;
+ ArmCallSmc (&Args);
+
+ /* Should never be reached */
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/** Turns on the specified core using PSCI and executes the user-supplied
+ function that's been configured via a previous call to SetApProcedure.
+
+ @param ProcessorIndex The index of the core to turn on.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_DEVICE_ERROR The processor could not be turned on.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+DispatchCpu (
+ IN UINTN ProcessorIndex
+ )
+{
+ ARM_SMC_ARGS Args;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ mCpuMpData.CpuData[ProcessorIndex].State = CpuStateBusy;
+
+ /* Turn the AP on */
+ if (sizeof (Args.Arg0) == sizeof (UINT32)) {
+ Args.Arg0 = ARM_SMC_ID_PSCI_CPU_ON_AARCH32;
+ } else {
+ Args.Arg0 = ARM_SMC_ID_PSCI_CPU_ON_AARCH64;
+ }
+ Args.Arg1 = gProcessorIDs[ProcessorIndex];
+ Args.Arg2 = (UINTN)ApEntryPoint;
+
+ ArmCallSmc (&Args);
+
+ if (Args.Arg0 != ARM_SMC_PSCI_RET_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "PSCI_CPU_ON call failed: %d", Args.Arg0));
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+/** Returns whether the specified processor is the BSP.
+
+ @param[in] ProcessorIndex The index the processor to check.
+
+ @return TRUE if the processor is the BSP, FALSE otherwise.
+**/
+STATIC
+BOOLEAN
+IsProcessorBSP (
+ UINTN ProcessorIndex
+ )
+{
+ EFI_PROCESSOR_INFORMATION *CpuInfo;
+
+ CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;
+
+ return (CpuInfo->StatusFlag & PROCESSOR_AS_BSP_BIT) != 0;
+}
+
+/** Returns whether the processor executing this function is the BSP.
+
+ @return Whether the current processor is the BSP.
+**/
+STATIC
+BOOLEAN
+IsCurrentProcessorBSP (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN ProcessorIndex;
+
+ Status = MpInitLibWhoAmI (&mMpServicesTemplate, &ProcessorIndex);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return IsProcessorBSP (ProcessorIndex);
+}
+
+/** Get the Application Processors state.
+
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP.
+
+ @return The AP status.
+**/
+CPU_STATE
+GetApState (
+ IN CPU_AP_DATA *CpuData
+ )
+{
+ return CpuData->State;
+}
+
+/** Configures the processor context with the user-supplied procedure and
+ argument.
+
+ @param CpuData The processor context.
+ @param Procedure The user-supplied procedure.
+ @param ProcedureArgument The user-supplied procedure argument.
+
+**/
+STATIC
+VOID
+SetApProcedure (
+ IN CPU_AP_DATA *CpuData,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument
+ )
+{
+ ASSERT (CpuData != NULL);
+ ASSERT (Procedure != NULL);
+
+ CpuData->Parameter = ProcedureArgument;
+ CpuData->Procedure = Procedure;
+}
+
+/** Returns the index of the next processor that is blocked.
+
+ @param[out] NextNumber The index of the next blocked processor.
+
+ @retval EFI_SUCCESS Successfully found the next blocked processor.
+ @retval EFI_NOT_FOUND There are no blocked processors.
+
+**/
+STATIC
+EFI_STATUS
+GetNextBlockedNumber (
+ OUT UINTN *NextNumber
+ )
+{
+ UINTN Index;
+ CPU_STATE State;
+ CPU_AP_DATA *CpuData;
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+ if (IsProcessorBSP (Index)) {
+ // Skip BSP
+ continue;
+ }
+
+ State = CpuData->State;
+
+ if (State == CpuStateBlocked) {
+ *NextNumber = Index;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/** Stalls the BSP for the minimum of POLL_INTERVAL_US and Timeout.
+
+ @param[in] Timeout The time limit in microseconds remaining for
+ APs to return from Procedure.
+
+ @retval StallTime Time of execution stall.
+**/
+STATIC
+UINTN
+CalculateAndStallInterval (
+ IN UINTN Timeout
+ )
+{
+ UINTN StallTime;
+
+ if (Timeout < POLL_INTERVAL_US && Timeout != 0) {
+ StallTime = Timeout;
+ } else {
+ StallTime = POLL_INTERVAL_US;
+ }
+
+ gBS->Stall (StallTime);
+
+ return StallTime;
+}
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ @param[in] This A pointer to the
+ EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including
+ the BSP and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled
+ logical processors that exist in the
+ system, including the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetNumberOfProcessors (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ )
+{
+ if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsCurrentProcessorBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *NumberOfProcessors = mCpuMpData.NumberOfProcessors;
+ *NumberOfEnabledProcessors = mCpuMpData.NumberOfEnabledProcessors;
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorIndex The index of the processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information
+ for the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetProcessorInfo (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ )
+{
+ if (ProcessorInfoBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsCurrentProcessorBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ProcessorIndex &= ~CPU_V2_EXTENDED_TOPOLOGY;
+
+ if (ProcessorIndex >= mCpuMpData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ CopyMem (
+ ProcessorInfoBuffer,
+ &mCpuMpData.CpuData[ProcessorIndex],
+ sizeof (EFI_PROCESSOR_INFORMATION)
+ );
+ return EFI_SUCCESS;
+}
+
+/** Returns whether the specified processor is enabled.
+
+ @param[in] ProcessorIndex The index of the processor to check.
+
+ @return TRUE if the processor is enabled, FALSE otherwise.
+**/
+STATIC
+BOOLEAN
+IsProcessorEnabled (
+ UINTN ProcessorIndex
+ )
+{
+ EFI_PROCESSOR_INFORMATION *CpuInfo;
+
+ CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;
+
+ return (CpuInfo->StatusFlag & PROCESSOR_ENABLED_BIT) != 0;
+}
+
+/** Returns whether all processors are in the idle state.
+
+ @return Whether all the processors are idle.
+
+**/
+STATIC
+BOOLEAN
+CheckAllCpusReady (
+ VOID
+ )
+{
+ UINTN Index;
+ CPU_AP_DATA *CpuData;
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+ if (IsProcessorBSP (Index)) {
+ // Skip BSP
+ continue;
+ }
+
+ if (!IsProcessorEnabled (Index)) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ if (GetApState (CpuData) != CpuStateIdle) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/** Sets up the state for the StartupAllAPs function.
+
+ @param SingleThread Whether the APs will execute sequentially.
+
+**/
+STATIC
+VOID
+StartupAllAPsPrepareState (
+ IN BOOLEAN SingleThread
+ )
+{
+ UINTN Index;
+ CPU_STATE APInitialState;
+ CPU_AP_DATA *CpuData;
+
+ mCpuMpData.FinishCount = 0;
+ mCpuMpData.StartCount = 0;
+ mCpuMpData.SingleThread = SingleThread;
+
+ APInitialState = CpuStateReady;
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+
+ //
+ // Get APs prepared, and put failing APs into FailedCpuList.
+ // If "SingleThread", only 1 AP will put into ready state, other AP will be
+ // put into ready state 1 by 1, until the previous 1 finished its task.
+ // If not "SingleThread", all APs are put into ready state from the
+ // beginning
+ //
+
+ if (IsProcessorBSP (Index)) {
+ // Skip BSP
+ continue;
+ }
+
+ if (!IsProcessorEnabled (Index)) {
+ // Skip Disabled processors
+ if (mCpuMpData.FailedList != NULL) {
+ mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = Index;
+ }
+
+ continue;
+ }
+
+ ASSERT (GetApState (CpuData) == CpuStateIdle);
+ CpuData->State = APInitialState;
+
+ mCpuMpData.StartCount++;
+ if (SingleThread) {
+ APInitialState = CpuStateBlocked;
+ }
+ }
+}
+
+/** Handles execution of StartupAllAPs when a WaitEvent has been specified.
+
+ @param Procedure The user-supplied procedure.
+ @param ProcedureArgument The user-supplied procedure argument.
+ @param WaitEvent The wait event to be signaled when the work is
+ complete or a timeout has occurred.
+ @param TimeoutInMicroseconds The timeout for the work to be completed. Zero
+ indicates an infinite timeout.
+
+ @return EFI_SUCCESS on success.
+**/
+STATIC
+EFI_STATUS
+StartupAllAPsWithWaitEvent (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument,
+ IN EFI_EVENT WaitEvent,
+ IN UINTN TimeoutInMicroseconds
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ CPU_AP_DATA *CpuData;
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+ if (IsProcessorBSP (Index)) {
+ // Skip BSP
+ continue;
+ }
+
+ if (!IsProcessorEnabled (Index)) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ if (GetApState (CpuData) == CpuStateReady) {
+ SetApProcedure (CpuData, Procedure, ProcedureArgument);
+ }
+ }
+
+ //
+ // Save data into private data structure, and create timer to poll AP state
+ // before exiting
+ //
+ mCpuMpData.Procedure = Procedure;
+ mCpuMpData.ProcedureArgument = ProcedureArgument;
+ mCpuMpData.WaitEvent = WaitEvent;
+ mCpuMpData.Timeout = TimeoutInMicroseconds;
+ mCpuMpData.TimeoutActive = (BOOLEAN)(TimeoutInMicroseconds != 0);
+ Status = gBS->SetTimer (
+ mCpuMpData.CheckAllAPsEvent,
+ TimerPeriodic,
+ POLL_INTERVAL_US
+ );
+ return Status;
+}
+
+/** Handles execution of StartupAllAPs when no wait event has been specified.
+
+ @param Procedure The user-supplied procedure.
+ @param ProcedureArgument The user-supplied procedure argument.
+ @param TimeoutInMicroseconds The timeout for the work to be completed. Zero
+ indicates an infinite timeout.
+ @param SingleThread Whether the APs will execute sequentially.
+ @param FailedCpuList User-supplied pointer for list of failed CPUs.
+
+ @return EFI_SUCCESS on success.
+**/
+STATIC
+EFI_STATUS
+StartupAllAPsNoWaitEvent (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument,
+ IN UINTN TimeoutInMicroseconds,
+ IN BOOLEAN SingleThread,
+ IN UINTN **FailedCpuList
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN NextIndex;
+ UINTN Timeout;
+ CPU_AP_DATA *CpuData;
+
+ Timeout = TimeoutInMicroseconds;
+
+ while (TRUE) {
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+ if (IsProcessorBSP (Index)) {
+ // Skip BSP
+ continue;
+ }
+
+ if (!IsProcessorEnabled (Index)) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ switch (GetApState (CpuData)) {
+ case CpuStateReady:
+ SetApProcedure (CpuData, Procedure, ProcedureArgument);
+ Status = DispatchCpu (Index);
+ if (EFI_ERROR (Status)) {
+ CpuData->State = CpuStateIdle;
+ Status = EFI_NOT_READY;
+ goto Done;
+ }
+
+ break;
+
+ case CpuStateFinished:
+ mCpuMpData.FinishCount++;
+ if (SingleThread) {
+ Status = GetNextBlockedNumber (&NextIndex);
+ if (!EFI_ERROR (Status)) {
+ mCpuMpData.CpuData[NextIndex].State = CpuStateReady;
+ }
+ }
+
+ CpuData->State = CpuStateIdle;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (mCpuMpData.FinishCount == mCpuMpData.StartCount) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
+ Status = EFI_TIMEOUT;
+ goto Done;
+ }
+
+ Timeout -= CalculateAndStallInterval (Timeout);
+ }
+
+Done:
+ if (FailedCpuList != NULL) {
+ if (mCpuMpData.FailedListIndex == 0) {
+ FreePool (*FailedCpuList);
+ *FailedCpuList = NULL;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor
+ handle number. If FALSE, then all the
+ enabled APs execute the function specified
+ by Procedure simultaneously.
+ @param[in] WaitEvent The event created by the caller with
+ CreateEvent() service. If it is NULL,
+ then execute in blocking mode. BSP waits
+ until all APs finish or
+ TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking
+ mode. BSP requests the function specified
+ by Procedure to be started on all the
+ enabled APs, and go on executing
+ immediately. If all return from Procedure,
+ or TimeoutInMicroseconds expires, this
+ event is signaled. The BSP can use the
+ CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds
+ for APs to return from Procedure, either
+ for blocking or non-blocking mode. Zero
+ means infinity. If the timeout expires
+ before all APs return from Procedure, then
+ Procedure on the failed APs is terminated.
+ All enabled APs are available for next
+ function assigned by
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored.
+ Otherwise, if all APs finish successfully,
+ then its content is set to NULL. If not
+ all APs finish before timeout expires,
+ then its content is set to address of the
+ buffer holding handle numbers of the
+ failed APs.
+ The buffer is allocated by MP Service
+ Protocol, and it's the caller's
+ responsibility to free the buffer with
+ FreePool() service.
+ In blocking mode, it is ready for
+ consumption when the call returns. In
+ non-blocking mode, it is ready when
+ WaitEvent is signaled. The list of failed
+ CPU is terminated by END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been
+ dispatched to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibStartupAllAPs (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ if (!IsCurrentProcessorBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (mCpuMpData.NumberOfProcessors == 1) {
+ return EFI_NOT_STARTED;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((WaitEvent != NULL) && !mNonBlockingModeAllowed) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (!CheckAllCpusReady ()) {
+ return EFI_NOT_READY;
+ }
+
+ if (FailedCpuList != NULL) {
+ mCpuMpData.FailedList = AllocatePool (
+ (mCpuMpData.NumberOfProcessors + 1) *
+ sizeof (UINTN)
+ );
+ if (mCpuMpData.FailedList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SetMemN (
+ mCpuMpData.FailedList,
+ (mCpuMpData.NumberOfProcessors + 1) *
+ sizeof (UINTN),
+ END_OF_CPU_LIST
+ );
+ mCpuMpData.FailedListIndex = 0;
+ *FailedCpuList = mCpuMpData.FailedList;
+ }
+
+ StartupAllAPsPrepareState (SingleThread);
+
+ if (WaitEvent != NULL) {
+ Status = StartupAllAPsWithWaitEvent (
+ Procedure,
+ ProcedureArgument,
+ WaitEvent,
+ TimeoutInMicroseconds
+ );
+ } else {
+ Status = StartupAllAPsNoWaitEvent (
+ Procedure,
+ ProcedureArgument,
+ TimeoutInMicroseconds,
+ SingleThread,
+ FailedCpuList
+ );
+ }
+
+ return Status;
+}
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibStartupThisAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINTN Timeout;
+ CPU_AP_DATA *CpuData;
+
+ if (!IsCurrentProcessorBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ CpuData = &mCpuMpData.CpuData[ProcessorNumber];
+
+ if (IsProcessorBSP (ProcessorNumber)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsProcessorEnabled (ProcessorNumber)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (GetApState (CpuData) != CpuStateIdle) {
+ return EFI_NOT_READY;
+ }
+
+ if ((WaitEvent != NULL) && !mNonBlockingModeAllowed) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Timeout = TimeoutInMicroseconds;
+
+ mCpuMpData.StartCount = 1;
+ mCpuMpData.FinishCount = 0;
+
+ SetApProcedure (
+ CpuData,
+ Procedure,
+ ProcedureArgument
+ );
+
+ Status = DispatchCpu (ProcessorNumber);
+ if (EFI_ERROR (Status)) {
+ CpuData->State = CpuStateIdle;
+ return EFI_NOT_READY;
+ }
+
+ if (WaitEvent != NULL) {
+ // Non Blocking
+ mCpuMpData.WaitEvent = WaitEvent;
+ gBS->SetTimer (
+ CpuData->CheckThisAPEvent,
+ TimerPeriodic,
+ POLL_INTERVAL_US
+ );
+ return EFI_SUCCESS;
+ }
+
+ // Blocking
+ while (TRUE) {
+ if (GetApState (CpuData) == CpuStateFinished) {
+ CpuData->State = CpuStateIdle;
+ break;
+ }
+
+ if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
+ return EFI_TIMEOUT;
+ }
+
+ Timeout -= CalculateAndStallInterval (Timeout);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be
+ performed by the current BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibSwitchBSP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ UINTN Index;
+ CPU_AP_DATA *CpuData;
+
+ CpuData = &mCpuMpData.CpuData[ProcessorNumber];
+
+ if (!IsCurrentProcessorBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (!IsProcessorEnabled (ProcessorNumber)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsProcessorBSP (ProcessorNumber)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ if (IsProcessorBSP (Index)) {
+ break;
+ }
+ }
+
+ ASSERT (Index != mCpuMpData.NumberOfProcessors);
+
+ if (GetApState (CpuData) != CpuStateIdle) {
+ return EFI_NOT_READY;
+ }
+
+ // Skip for now as we need switch a bunch of stack stuff around and it's
+ // complex. May not be worth it?
+ return EFI_NOT_READY;
+}
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibEnableDisableAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ )
+{
+ UINTN StatusFlag;
+ CPU_AP_DATA *CpuData;
+
+ StatusFlag = mCpuMpData.CpuData[ProcessorNumber].Info.StatusFlag;
+ CpuData = &mCpuMpData.CpuData[ProcessorNumber];
+
+ if (!IsCurrentProcessorBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (IsProcessorBSP (ProcessorNumber)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (GetApState (CpuData) != CpuStateIdle) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EnableAP) {
+ if (!IsProcessorEnabled (ProcessorNumber)) {
+ mCpuMpData.NumberOfEnabledProcessors++;
+ }
+
+ StatusFlag |= PROCESSOR_ENABLED_BIT;
+ } else {
+ if (IsProcessorEnabled (ProcessorNumber)) {
+ mCpuMpData.NumberOfEnabledProcessors--;
+ }
+
+ StatusFlag &= ~PROCESSOR_ENABLED_BIT;
+ }
+
+ if (HealthFlag != NULL) {
+ StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
+ StatusFlag |= (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibWhoAmI (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ UINTN Index;
+ UINT64 ProcessorId;
+ CPU_AP_DATA *CpuData;
+
+ if (ProcessorNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ProcessorId = ArmReadMpidr ();
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+ if (CpuData->Info.ProcessorId == ProcessorId) {
+ break;
+ }
+ }
+
+ *ProcessorNumber = Index;
+ return EFI_SUCCESS;
+}
+
+/** Adds the specified processor the list of failed processors.
+
+ @param ProcessorIndex The processor index to add.
+ @param ApState Processor state.
+
+**/
+STATIC
+VOID
+AddProcessorToFailedList (
+ UINTN ProcessorIndex,
+ CPU_STATE ApState
+ )
+{
+ UINTN Index;
+ BOOLEAN Found;
+
+ Found = FALSE;
+
+ if (ApState == CpuStateIdle) {
+ return;
+ }
+
+ // If we are retrying make sure we don't double count
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ if (mCpuMpData.FailedList[Index] == END_OF_CPU_LIST) {
+ break;
+ }
+
+ if (mCpuMpData.FailedList[ProcessorIndex] == Index) {
+ Found = TRUE;
+ break;
+ }
+ }
+
+ /* If the CPU isn't already in the FailedList, add it */
+ if (!Found) {
+ mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = Index;
+ }
+}
+
+/** Handles the StartupAllAPs case where the timeout has occurred.
+
+**/
+STATIC
+VOID
+ProcessStartupAllAPsTimeout (
+ VOID
+ )
+{
+ CPU_AP_DATA *CpuData;
+ UINTN Index;
+
+ if (mCpuMpData.FailedList == NULL) {
+ return;
+ }
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ CpuData = &mCpuMpData.CpuData[Index];
+ if (IsProcessorBSP (Index)) {
+ // Skip BSP
+ continue;
+ }
+
+ if (!IsProcessorEnabled (Index)) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ AddProcessorToFailedList (Index, GetApState (CpuData));
+ }
+}
+
+/** Updates the status of the APs.
+
+ @param[in] ProcessorIndex The index of the AP to update.
+**/
+STATIC
+VOID
+UpdateApStatus (
+ IN UINTN ProcessorIndex
+ )
+{
+ EFI_STATUS Status;
+ CPU_AP_DATA *CpuData;
+ CPU_AP_DATA *NextCpuData;
+ CPU_STATE State;
+ UINTN NextNumber;
+
+ CpuData = &mCpuMpData.CpuData[ProcessorIndex];
+
+ if (IsProcessorBSP (ProcessorIndex)) {
+ // Skip BSP
+ return;
+ }
+
+ if (!IsProcessorEnabled (ProcessorIndex)) {
+ // Skip Disabled processors
+ return;
+ }
+
+ State = GetApState (CpuData);
+
+ switch (State) {
+ case CpuStateFinished:
+ if (mCpuMpData.SingleThread) {
+ Status = GetNextBlockedNumber (&NextNumber);
+ if (!EFI_ERROR (Status)) {
+ NextCpuData = &mCpuMpData.CpuData[NextNumber];
+
+ NextCpuData->State = CpuStateReady;
+
+ SetApProcedure (
+ NextCpuData,
+ mCpuMpData.Procedure,
+ mCpuMpData.ProcedureArgument
+ );
+ }
+ }
+
+ CpuData->State = CpuStateIdle;
+ mCpuMpData.FinishCount++;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ If a timeout is specified in StartupAllAps(), a timer is set, which invokes
+ this procedure periodically to check whether all APs have finished.
+
+ @param[in] Event The WaitEvent the user supplied.
+ @param[in] Context The event context.
+**/
+STATIC
+VOID
+EFIAPI
+CheckAllAPsStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ if (mCpuMpData.TimeoutActive) {
+ mCpuMpData.Timeout -= CalculateAndStallInterval (mCpuMpData.Timeout);
+ }
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ UpdateApStatus (Index);
+ }
+
+ if (mCpuMpData.TimeoutActive && mCpuMpData.Timeout == 0) {
+ ProcessStartupAllAPsTimeout ();
+
+ // Force terminal exit
+ mCpuMpData.FinishCount = mCpuMpData.StartCount;
+ }
+
+ if (mCpuMpData.FinishCount != mCpuMpData.StartCount) {
+ return;
+ }
+
+ gBS->SetTimer (
+ mCpuMpData.CheckAllAPsEvent,
+ TimerCancel,
+ 0
+ );
+
+ if (mCpuMpData.FailedListIndex == 0) {
+ if (mCpuMpData.FailedList != NULL) {
+ FreePool (mCpuMpData.FailedList);
+ mCpuMpData.FailedList = NULL;
+ }
+ }
+
+ gBS->SignalEvent (mCpuMpData.WaitEvent);
+}
+
+/** Invoked periodically via a timer to check the state of the processor.
+
+ @param Event The event supplied by the timer expiration.
+ @param Context The processor context.
+
+**/
+STATIC
+VOID
+EFIAPI
+CheckThisAPStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ CPU_AP_DATA *CpuData;
+ CPU_STATE State;
+
+ CpuData = Context;
+ CpuData->TimeTaken += POLL_INTERVAL_US;
+
+ State = GetApState (CpuData);
+
+ if (State == CpuStateFinished) {
+ Status = gBS->SetTimer (CpuData->CheckThisAPEvent, TimerCancel, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ if (mCpuMpData.WaitEvent != NULL) {
+ Status = gBS->SignalEvent (mCpuMpData.WaitEvent);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ CpuData->State = CpuStateIdle;
+ }
+
+ if (CpuData->TimeTaken > CpuData->Timeout) {
+ if (mCpuMpData.WaitEvent != NULL) {
+ Status = gBS->SignalEvent (mCpuMpData.WaitEvent);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+}
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects
+ MP related data.
+
+ @param BSP TRUE if the processor is the BSP.
+ @param Mpidr The MPIDR for the specified processor.
+ @param ProcessorIndex The index of the processor.
+
+ @return EFI_SUCCESS if the data for the processor collected and filled in.
+
+**/
+STATIC
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN BSP,
+ IN UINTN Mpidr,
+ IN UINTN ProcessorIndex
+ )
+{
+ EFI_PROCESSOR_INFORMATION *CpuInfo;
+
+ CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;
+
+ /* The MPIDR passed in may be a pseudo-MPIDR that's missing the bit 31 RES1.
+ * Fix it so it's a proper MPIDR.
+ */
+ CpuInfo->ProcessorId = BIT31 | Mpidr;
+ CpuInfo->StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
+
+ if (BSP) {
+ CpuInfo->StatusFlag |= PROCESSOR_AS_BSP_BIT;
+ }
+
+ CpuInfo->Location.Package = GET_CLUSTER_ID (Mpidr);
+ CpuInfo->Location.Core = GET_CORE_ID (Mpidr);
+ CpuInfo->Location.Thread = 0;
+
+ CpuInfo->ExtendedInformation.Location2.Package = 0;
+ CpuInfo->ExtendedInformation.Location2.Module = 0;
+ CpuInfo->ExtendedInformation.Location2.Tile = 0;
+ CpuInfo->ExtendedInformation.Location2.Die = GET_CLUSTER_ID (Mpidr);
+ CpuInfo->ExtendedInformation.Location2.Core = GET_CORE_ID (Mpidr);
+ CpuInfo->ExtendedInformation.Location2.Thread = 0;
+
+ mCpuMpData.CpuData[ProcessorIndex].State = BSP ? CpuStateBusy : CpuStateIdle;
+
+ mCpuMpData.CpuData[ProcessorIndex].Procedure = NULL;
+ mCpuMpData.CpuData[ProcessorIndex].Parameter = NULL;
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes the MP Services system data
+
+ @param NumberOfProcessors The number of processors, both BSP and AP.
+ @param CpuInfo CPU information gathered earlier during boot.
+
+**/
+VOID
+MpInitLibInitialize (
+ IN UINTN NumberOfProcessors,
+ IN ARM_PROCESSOR_TABLE *CpuInfo
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_EVENT ReadyToBootEvent;
+
+ //
+ // Clear the data structure area first.
+ //
+ ZeroMem (&mCpuMpData, sizeof (CPU_MP_DATA));
+ //
+ // First BSP fills and inits all known values, including its own records.
+ //
+ mCpuMpData.NumberOfProcessors = NumberOfProcessors;
+ mCpuMpData.NumberOfEnabledProcessors = NumberOfProcessors;
+
+ mCpuMpData.CpuData = AllocateZeroPool (
+ mCpuMpData.NumberOfProcessors *
+ sizeof (CPU_AP_DATA)
+ );
+ ASSERT (mCpuMpData.CpuData != NULL);
+
+ /* Allocate one extra for the NULL entry at the end */
+ gProcessorIDs = AllocatePool ((mCpuMpData.NumberOfProcessors + 1) * sizeof (UINT64));
+ ASSERT (gProcessorIDs != NULL);
+
+ FillInProcessorInformation (TRUE, CpuInfo->ArmCpus[0].Mpidr, 0);
+ gProcessorIDs[0] = mCpuMpData.CpuData[0].Info.ProcessorId;
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CheckAllAPsStatus,
+ NULL,
+ &mCpuMpData.CheckAllAPsEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ gApStacksBase = AllocatePool (
+ mCpuMpData.NumberOfProcessors *
+ gApStackSize
+ );
+ ASSERT (gApStacksBase != NULL);
+
+ for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
+ if (IsProcessorBSP (Index)) {
+ /* Skip BSP */
+ continue;
+ }
+
+ FillInProcessorInformation (FALSE, CpuInfo->ArmCpus[Index].Mpidr, Index);
+
+ gProcessorIDs[Index] = mCpuMpData.CpuData[Index].Info.ProcessorId;
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CheckThisAPStatus,
+ (VOID *)&mCpuMpData.CpuData[Index],
+ &mCpuMpData.CpuData[Index].CheckThisAPEvent
+ );
+ ASSERT (Status == EFI_SUCCESS);
+ }
+
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_CALLBACK,
+ ReadyToBootSignaled,
+ NULL,
+ &ReadyToBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ gProcessorIDs[Index] = 0;
+}
+
+/**
+ Event notification function called when the EFI_EVENT_GROUP_READY_TO_BOOT is
+ signaled. After this point, non-blocking mode is no longer allowed.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+STATIC
+VOID
+EFIAPI
+ReadyToBootSignaled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ mNonBlockingModeAllowed = FALSE;
+}
+
diff --git a/ArmPkg/Library/MpInitLib/InternalMpInitLib.h b/ArmPkg/Library/MpInitLib/InternalMpInitLib.h
new file mode 100644
index 000000000000..d08bb76246d7
--- /dev/null
+++ b/ArmPkg/Library/MpInitLib/InternalMpInitLib.h
@@ -0,0 +1,358 @@
+/** @file
+
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MP_INTERNAL_INIT_LIB_H_
+#define MP_INTERNAL_INIT_LIB_H_
+
+#include <Protocol/Cpu.h>
+#include <Protocol/MpService.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+
+
+#define AP_STACK_SIZE 0x1000
+
+//
+// Internal Data Structures
+//
+
+//
+// AP state
+//
+// The state transitions for an AP when it process a procedure are:
+// Idle ----> Ready ----> Busy ----> Idle
+// [BSP] [AP] [AP]
+//
+typedef enum {
+ CpuStateIdle,
+ CpuStateReady,
+ CpuStateBlocked,
+ CpuStateBusy,
+ CpuStateFinished,
+ CpuStateDisabled
+} CPU_STATE;
+
+//
+// Define Individual Processor Data block.
+//
+typedef struct {
+ EFI_PROCESSOR_INFORMATION Info;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *Parameter;
+ CPU_STATE State;
+ EFI_EVENT CheckThisAPEvent;
+ UINTN Timeout;
+ UINTN TimeTaken;
+} CPU_AP_DATA;
+
+//
+// Define MP data block which consumes individual processor block.
+//
+typedef struct {
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
+ EFI_EVENT CheckAllAPsEvent;
+ EFI_EVENT WaitEvent;
+ UINTN FinishCount;
+ UINTN StartCount;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *ProcedureArgument;
+ BOOLEAN SingleThread;
+ UINTN StartedNumber;
+ CPU_AP_DATA *CpuData;
+ UINTN Timeout;
+ UINTN *FailedList;
+ UINTN FailedListIndex;
+ BOOLEAN TimeoutActive;
+} CPU_MP_DATA;
+
+EFI_STATUS
+EFIAPI
+CpuMpServicesInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+extern EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate;
+
+/** Secondary core entry point.
+
+**/
+VOID ApEntryPoint (
+ VOID
+ );
+
+/** C entry-point for the AP.
+ This function gets called from the assembly function ApEntryPoint.
+**/
+VOID
+ApProcedure (
+ VOID
+ );
+
+/** Turns on the specified core using PSCI and executes the user-supplied
+ function that's been configured via a previous call to SetApProcedure.
+
+ @param ProcessorIndex The index of the core to turn on.
+
+ @retval EFI_SUCCESS The processor was successfully turned on.
+ @retval EFI_DEVICE_ERROR An error occurred turning the processor on.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+DispatchCpu (
+ IN UINTN ProcessorIndex
+ );
+
+/** Returns whether the specified processor is the BSP.
+
+ @param[in] ProcessorIndex The index the processor to check.
+
+ @return TRUE if the processor is the BSP, FALSE otherwise.
+**/
+STATIC
+BOOLEAN
+IsProcessorBSP (
+ UINTN ProcessorIndex
+ );
+
+/** Returns whether the processor executing this function is the BSP.
+
+ @return Whether the current processor is the BSP.
+**/
+STATIC
+BOOLEAN
+IsCurrentProcessorBSP (
+ VOID
+ );
+
+/** Returns whether the specified processor is enabled.
+
+ @param[in] ProcessorIndex The index of the processor to check.
+
+ @return TRUE if the processor is enabled, FALSE otherwise.
+**/
+STATIC
+BOOLEAN
+IsProcessorEnabled (
+ UINTN ProcessorIndex
+ );
+
+/** Configures the processor context with the user-supplied procedure and
+ argument.
+
+ @param CpuData The processor context.
+ @param Procedure The user-supplied procedure.
+ @param ProcedureArgument The user-supplied procedure argument.
+
+**/
+STATIC
+VOID
+SetApProcedure (
+ IN CPU_AP_DATA *CpuData,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument
+ );
+
+/**
+ Get the Application Processors state.
+
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP
+
+ @return The AP status
+**/
+CPU_STATE
+GetApState (
+ IN CPU_AP_DATA *CpuData
+ );
+
+/** Returns the index of the next processor that is blocked.
+
+ @param[out] NextNumber The index of the next blocked processor.
+
+ @retval EFI_SUCCESS Successfully found the next blocked processor.
+ @retval EFI_NOT_FOUND There are no blocked processors.
+
+**/
+STATIC
+EFI_STATUS
+GetNextBlockedNumber (
+ OUT UINTN *NextNumber
+ );
+
+/** Stalls the BSP for the minimum of gPollInterval and Timeout.
+
+ @param[in] Timeout The time limit in microseconds remaining for
+ APs to return from Procedure.
+
+ @retval StallTime Time of execution stall.
+**/
+STATIC
+UINTN
+CalculateAndStallInterval (
+ IN UINTN Timeout
+ );
+
+/** Returns whether all processors are in the idle state.
+
+ @return Whether all the processors are idle.
+
+**/
+STATIC
+BOOLEAN
+CheckAllCpusReady (
+ VOID
+ );
+
+/** Sets up the state for the StartupAllAPs function.
+
+ @param SingleThread Whether the APs will execute sequentially.
+
+**/
+STATIC
+VOID
+StartupAllAPsPrepareState (
+ IN BOOLEAN SingleThread
+ );
+
+/** Handles execution of StartupAllAPs when a WaitEvent has been specified.
+
+ @param Procedure The user-supplied procedure.
+ @param ProcedureArgument The user-supplied procedure argument.
+ @param WaitEvent The wait event to be signaled when the work is
+ complete or a timeout has occurred.
+ @param TimeoutInMicroseconds The timeout for the work to be completed. Zero
+ indicates an infinite timeout.
+
+ @return EFI_SUCCESS on success.
+**/
+STATIC
+EFI_STATUS
+StartupAllAPsWithWaitEvent (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument,
+ IN EFI_EVENT WaitEvent,
+ IN UINTN TimeoutInMicroseconds
+ );
+
+/** Handles execution of StartupAllAPs when no wait event has been specified.
+
+ @param Procedure The user-supplied procedure.
+ @param ProcedureArgument The user-supplied procedure argument.
+ @param TimeoutInMicroseconds The timeout for the work to be completed. Zero
+ indicates an infinite timeout.
+ @param SingleThread Whether the APs will execute sequentially.
+ @param FailedCpuList User-supplied pointer for list of failed CPUs.
+
+ @return EFI_SUCCESS on success.
+**/
+STATIC
+EFI_STATUS
+StartupAllAPsNoWaitEvent (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument,
+ IN UINTN TimeoutInMicroseconds,
+ IN BOOLEAN SingleThread,
+ IN UINTN **FailedCpuList
+ );
+
+
+/** Adds the specified processor the list of failed processors.
+
+ @param ProcessorIndex The processor index to add.
+ @param ApState Processor state.
+
+**/
+STATIC
+VOID
+AddProcessorToFailedList (
+ UINTN ProcessorIndex,
+ CPU_STATE ApState
+ );
+
+/** Handles the StartupAllAPs case where the timeout has occurred.
+
+**/
+STATIC
+VOID
+ProcessStartupAllAPsTimeout (
+ VOID
+ );
+
+/**
+ If a timeout is specified in StartupAllAps(), a timer is set, which invokes
+ this procedure periodically to check whether all APs have finished.
+
+ @param[in] Event The WaitEvent the user supplied.
+ @param[in] Context The event context.
+**/
+STATIC
+VOID
+EFIAPI
+CheckAllAPsStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/** Invoked periodically via a timer to check the state of the processor.
+
+ @param Event The event supplied by the timer expiration.
+ @param Context The processor context.
+
+**/
+STATIC
+VOID
+EFIAPI
+CheckThisAPStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects
+ MP related data.
+
+ @param BSP TRUE if the processor is the BSP.
+ @param Mpidr The MPIDR for the specified processor.
+ @param ProcessorIndex The index of the processor.
+
+ @return EFI_SUCCESS if the data for the processor collected and filled in.
+
+**/
+STATIC
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN BSP,
+ IN UINTN Mpidr,
+ IN UINTN ProcessorIndex
+ );
+
+/**
+ Event notification function called when the EFI_EVENT_GROUP_READY_TO_BOOT is
+ signaled. After this point, non-blocking mode is no longer allowed.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+STATIC
+VOID
+EFIAPI
+ReadyToBootSignaled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+
+#endif /* MP_INTERNAL_INIT_LIB_H_ */
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 5a1598d90ca7..af6e48fd6cfc 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -261,6 +261,9 @@
[LibraryClasses.ARM]
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf

+[LibraryClasses.AARCH64]
+ MpInitLib|ArmPkg/Library/MpInitLib/DxeMpInitLib.inf
+
[BuildOptions]
RVCT:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG

--
2.31.1


[PATCH 1/2] ArmPkg: Replace CoreId and ClusterId with Mpidr in ARM_CORE_INFO struct

Rebecca Cran <rebecca@...>
 

Remove the ClusterId and CoreId fields in the ARM_CORE_INFO structure in
favor of a new Mpidr field. Update code in
ArmPlatformPkg/PrePeiCore/MainMPCore and ArmPlatformPkg/PrePi/MainMPCore.c
to use the new field and call new macros GET_MPIDR_AFF0 and GET_MPIDR_AFF1
instead.

Signed-off-by: Rebecca Cran <rebecca@...>
---
ArmPkg/Include/Guid/ArmMpCoreInfo.h | 3 +--
ArmPkg/Include/Library/ArmLib.h | 4 ++++
ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c | 8 ++++----
ArmPlatformPkg/PrePeiCore/MainMPCore.c | 2 +-
ArmPlatformPkg/PrePi/MainMPCore.c | 2 +-
5 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/ArmPkg/Include/Guid/ArmMpCoreInfo.h b/ArmPkg/Include/Guid/ArmMpCoreInfo.h
index b810767879ae..04c44650ebf5 100644
--- a/ArmPkg/Include/Guid/ArmMpCoreInfo.h
+++ b/ArmPkg/Include/Guid/ArmMpCoreInfo.h
@@ -14,8 +14,7 @@
#define MPIDR_U_BIT_MASK 0x40000000

typedef struct {
- UINT32 ClusterId;
- UINT32 CoreId;
+ UINT64 Mpidr;

// MP Core Mailbox
EFI_PHYSICAL_ADDRESS MailboxSetAddress;
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 79ea755777a9..d764cc670970 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -107,6 +107,10 @@ typedef enum {
#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 PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK)

/** Reads the CCSIDR register for the specified cache.
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
index 1cd9ec30a977..6630cb68452c 100644
--- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
@@ -15,7 +15,7 @@
ARM_CORE_INFO mArmPlatformNullMpCoreInfoTable[] = {
{
// Cluster 0, Core 0
- 0x0, 0x0,
+ 0x0,

// MP Core MailBox Set/Get/Clear Addresses and Clear Value
(EFI_PHYSICAL_ADDRESS)0,
@@ -25,7 +25,7 @@ ARM_CORE_INFO mArmPlatformNullMpCoreInfoTable[] = {
},
{
// Cluster 0, Core 1
- 0x0, 0x1,
+ 0x1,

// MP Core MailBox Set/Get/Clear Addresses and Clear Value
(EFI_PHYSICAL_ADDRESS)0,
@@ -35,7 +35,7 @@ ARM_CORE_INFO mArmPlatformNullMpCoreInfoTable[] = {
},
{
// Cluster 0, Core 2
- 0x0, 0x2,
+ 0x2,

// MP Core MailBox Set/Get/Clear Addresses and Clear Value
(EFI_PHYSICAL_ADDRESS)0,
@@ -45,7 +45,7 @@ ARM_CORE_INFO mArmPlatformNullMpCoreInfoTable[] = {
},
{
// Cluster 0, Core 3
- 0x0, 0x3,
+ 0x3,

// MP Core MailBox Set/Get/Clear Addresses and Clear Value
(EFI_PHYSICAL_ADDRESS)0,
diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
index 859f1adf2078..5f8a268bf664 100644
--- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c
+++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
@@ -65,7 +65,7 @@ SecondaryMain (

// Find the core in the ArmCoreTable
for (Index = 0; Index < ArmCoreCount; Index++) {
- if ((ArmCoreInfoTable[Index].ClusterId == ClusterId) && (ArmCoreInfoTable[Index].CoreId == CoreId)) {
+ if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) && (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId)) {
break;
}
}
diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c
index 091464df2aa9..6497a1ad27fd 100644
--- a/ArmPlatformPkg/PrePi/MainMPCore.c
+++ b/ArmPlatformPkg/PrePi/MainMPCore.c
@@ -64,7 +64,7 @@ SecondaryMain (

// Find the core in the ArmCoreTable
for (Index = 0; Index < ArmCoreCount; Index++) {
- if ((ArmCoreInfoTable[Index].ClusterId == ClusterId) && (ArmCoreInfoTable[Index].CoreId == CoreId)) {
+ if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) && (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId)) {
break;
}
}
--
2.31.1


[PATCH 0/2] Add EFI_MP_SERVICES_PROTOCOL support for AARCH64

Rebecca Cran <rebecca@...>
 

Patch 1/2 is the start of addressing the issue that the Aff0 field of
the MPIDR is no longer guaranteed to be the core, and should be referred
to in a more generic way: for example it could be the thread, with Aff1
being the core and Aff2 the cluster. Clearly much more work is needed
to fully remove that assumption.

Patch 2/2 implements the EFI_MP_SERVICES_PROTOCOL for DXE in Library/MpInitLib.
CpuDxe initializes the MP support, and as a result gains a dependency on
MpInitLib. ArmVirt.dsc.inc needs updated to add the new library, as will
all AARCH64 platforms.

Cores are powered on and turned off using PSCI.

Note that minimal CPU setup is done: for example the MMU and caches are
left disabled.


Rebecca Cran (2):
ArmPkg: Replace CoreId and ClusterId with Mpidr in ARM_CORE_INFO
struct
ArmPkg: Add Library/MpInitLib to support EFI_MP_SERVICES_PROTOCOL

ArmPkg/ArmPkg.dec | 4 +
ArmPkg/ArmPkg.dsc | 4 +
ArmPkg/Drivers/CpuDxe/AArch64/Arch.c | 22 +
ArmPkg/Drivers/CpuDxe/Arm/Arch.c | 22 +
ArmPkg/Drivers/CpuDxe/CpuDxe.c | 2 +
ArmPkg/Drivers/CpuDxe/CpuDxe.h | 10 +
ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 6 +
ArmPkg/Drivers/CpuDxe/CpuMpInit.c | 604 ++++++++
ArmPkg/Include/Guid/ArmMpCoreInfo.h | 3 +-
ArmPkg/Include/Library/ArmLib.h | 4 +
ArmPkg/Include/Library/MpInitLib.h | 366 +++++
ArmPkg/Library/MpInitLib/AArch64/MpFuncs.S | 61 +
ArmPkg/Library/MpInitLib/DxeMpInitLib.inf | 53 +
ArmPkg/Library/MpInitLib/DxeMpLib.c | 1498 ++++++++++++++++++++
ArmPkg/Library/MpInitLib/InternalMpInitLib.h | 358 +++++
ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c | 8 +-
ArmPlatformPkg/PrePeiCore/MainMPCore.c | 2 +-
ArmPlatformPkg/PrePi/MainMPCore.c | 2 +-
ArmVirtPkg/ArmVirt.dsc.inc | 3 +
19 files changed, 3024 insertions(+), 8 deletions(-)
create mode 100644 ArmPkg/Drivers/CpuDxe/AArch64/Arch.c
create mode 100644 ArmPkg/Drivers/CpuDxe/Arm/Arch.c
create mode 100644 ArmPkg/Drivers/CpuDxe/CpuMpInit.c
create mode 100644 ArmPkg/Include/Library/MpInitLib.h
create mode 100644 ArmPkg/Library/MpInitLib/AArch64/MpFuncs.S
create mode 100644 ArmPkg/Library/MpInitLib/DxeMpInitLib.inf
create mode 100644 ArmPkg/Library/MpInitLib/DxeMpLib.c
create mode 100644 ArmPkg/Library/MpInitLib/InternalMpInitLib.h

--
2.31.1


[PATCH v1 7/7] DynamicTablesPkg: Add CacheId to PPTT generator

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

Update the PPTT generator with the CacheId field as defined in table
5.140 of the ACPI 6.4 specification.

Also add validations to ensure that the cache id generated is unique.

Signed-off-by: Chris Jones <christopher.jones@...>
---
DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 4 +-
DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 102 ++++++++++++++++++--
2 files changed, 96 insertions(+), 10 deletions(-)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 6bc5ab6b2b28424c1afddc26cc89a54b81941aeb..6e27158d720947efb22a350a7e5ffcfdd3005361 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -740,10 +740,12 @@ typedef struct CmArmCacheInfo {
/// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field
/// is 32-bit wide.
UINT32 Associativity;
- /// Cache attributes (ACPI 6.3 - January 2019, PPTT, Table 5-156)
+ /// 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 a reference to another Configuration Manager
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
index 18f093998db57ea4698953ed06a9826df559c1b7..0c22de11c584cfebfcc1600d86290c758a99140a 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
@@ -722,6 +722,35 @@ AddProcHierarchyNodes (
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
+EFI_STATUS
+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.

@@ -734,10 +763,12 @@ AddProcHierarchyNodes (
@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
@@ -745,7 +776,8 @@ 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 NodesStartOffset,
+ IN CONST UINT32 Revision
)
{
EFI_STATUS Status;
@@ -754,6 +786,9 @@ AddCacheTypeStructures (
CM_ARM_CACHE_INFO * CacheInfoNode;
PPTT_NODE_INDEXER * CacheNodeIterator;
UINT32 NodeCount;
+ BOOLEAN CacheIdUnique;
+ UINT32 TotalNodeCount;
+ UINT32 * FoundCacheIds;

ASSERT (
(Generator != NULL) &&
@@ -766,6 +801,13 @@ AddCacheTypeStructures (

CacheNodeIterator = Generator->CacheStructIndexedList;
NodeCount = Generator->CacheStructCount;
+ TotalNodeCount = NodeCount;
+
+ FoundCacheIds = AllocateZeroPool (TotalNodeCount * sizeof (*FoundCacheIds));
+ if (FoundCacheIds == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Failed to allocate resources.\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }

while (NodeCount-- != 0) {
CacheInfoNode = (CM_ARM_CACHE_INFO*)CacheNodeIterator->Object;
@@ -785,6 +827,7 @@ AddCacheTypeStructures (
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
@@ -807,7 +850,7 @@ AddCacheTypeStructures (
CacheInfoNode->Token,
Status
));
- return Status;
+ goto cleanup;
}

// Update Cache Structure with the offset for the next level of cache
@@ -831,7 +874,7 @@ AddCacheTypeStructures (
CacheInfoNode->NumberOfSets,
Status
));
- return Status;
+ goto cleanup;
}

if (CacheInfoNode->NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) {
@@ -858,7 +901,7 @@ AddCacheTypeStructures (
CacheInfoNode->Associativity,
Status
));
- return Status;
+ goto cleanup;
}

// Validate the Associativity field based on the architecture specification
@@ -877,7 +920,7 @@ AddCacheTypeStructures (
CacheInfoNode->Associativity,
Status
));
- return Status;
+ goto cleanup;
}

if (CacheInfoNode->Associativity > PPTT_ARM_CACHE_ASSOCIATIVITY_MAX) {
@@ -918,7 +961,7 @@ AddCacheTypeStructures (
CacheInfoNode->LineSize,
Status
));
- return Status;
+ goto cleanup;
}

if ((CacheInfoNode->LineSize & (CacheInfoNode->LineSize - 1)) != 0) {
@@ -930,18 +973,58 @@ AddCacheTypeStructures (
CacheInfoNode->LineSize,
Status
));
- return 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,
+ TotalNodeCount
+ );
+ 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[NodeCount] = CacheInfoNode->CacheId;
+
+ CacheStruct->CacheId = CacheInfoNode->CacheId;
+ }
+
// Next Cache Type Structure
CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE*)((UINT8*)CacheStruct +
CacheStruct->Length);
CacheNodeIterator++;
} // Cache Type Structure

- return EFI_SUCCESS;
+ Status = EFI_SUCCESS;
+
+cleanup:
+ FreePool (FoundCacheIds);
+
+ return Status;
}

/**
@@ -1200,7 +1283,8 @@ BuildPpttTable (
Generator,
CfgMgrProtocol,
Pptt,
- CacheStructOffset
+ CacheStructOffset,
+ AcpiTableInfo->AcpiTableRevision
);
if (EFI_ERROR (Status)) {
DEBUG ((
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 6/7] DynamicTablesPkg: Update PPTT generator to ACPI 6.4

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

Update the PPTT generator to use Acpi64.h.

Signed-off-by: Chris Jones <christopher.jones@...>
---
DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 44 ++++++++++----------
1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
index 65d1661c0ec47a4d1631c0dcac7bcb16dbc619e0..18f093998db57ea4698953ed06a9826df559c1b7 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
@@ -1,11 +1,11 @@
/** @file
PPTT Table Generator

- Copyright (c) 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2021, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
- - ACPI 6.3 Specification, January 2019
+ - ACPI 6.4 Specification, January 2021

@par Glossary:
- Cm or CM - Configuration Manager
@@ -96,7 +96,7 @@ GetProcHierarchyNodeSize (
ASSERT (Node != NULL);

// <size of Processor Hierarchy Node> + <size of Private Resources array>
- return sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) +
+ return sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR) +
(Node->NoOfPrivateResources * sizeof (UINT32));
}

@@ -116,7 +116,7 @@ GET_SIZE_OF_PPTT_STRUCTS (
*/
GET_SIZE_OF_PPTT_STRUCTS (
CacheTypeStructs,
- sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE),
+ sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE),
CM_ARM_CACHE_INFO
);

@@ -466,12 +466,12 @@ EFI_STATUS
AddProcHierarchyNodes (
IN CONST ACPI_PPTT_GENERATOR * CONST Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
- IN CONST EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt,
+ IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt,
IN CONST UINT32 NodesStartOffset
)
{
EFI_STATUS Status;
- EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR * ProcStruct;
+ EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR * ProcStruct;
UINT32 * PrivateResources;
BOOLEAN IsGicCTokenDuplicated;

@@ -492,7 +492,7 @@ AddProcHierarchyNodes (
(Pptt != NULL)
);

- ProcStruct = (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR*)((UINT8*)Pptt +
+ ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR*)((UINT8*)Pptt +
NodesStartOffset);

ProcNodeIterator = Generator->ProcHierarchyNodeIndexedList;
@@ -536,7 +536,7 @@ AddProcHierarchyNodes (
}

// Populate the node header
- ProcStruct->Type = EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR;
+ 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;
@@ -657,7 +657,7 @@ AddProcHierarchyNodes (

ProcStruct->NumberOfPrivateResources = ProcInfoNode->NoOfPrivateResources;
PrivateResources = (UINT32*)((UINT8*)ProcStruct +
- sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
+ sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR));

if (ProcStruct->NumberOfPrivateResources != 0) {
// Populate the private resources array
@@ -680,7 +680,7 @@ AddProcHierarchyNodes (
}

// Next Processor Hierarchy Node
- ProcStruct = (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR*)((UINT8*)ProcStruct +
+ ProcStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR*)((UINT8*)ProcStruct +
ProcStruct->Length);
ProcNodeIterator++;
} // Processor Hierarchy Node
@@ -744,12 +744,12 @@ EFI_STATUS
AddCacheTypeStructures (
IN CONST ACPI_PPTT_GENERATOR * CONST Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
- IN CONST EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt,
+ IN CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt,
IN CONST UINT32 NodesStartOffset
)
{
EFI_STATUS Status;
- EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE * CacheStruct;
+ EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE * CacheStruct;
PPTT_NODE_INDEXER * PpttNodeFound;
CM_ARM_CACHE_INFO * CacheInfoNode;
PPTT_NODE_INDEXER * CacheNodeIterator;
@@ -761,7 +761,7 @@ AddCacheTypeStructures (
(Pptt != NULL)
);

- CacheStruct = (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE*)((UINT8*)Pptt +
+ CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE*)((UINT8*)Pptt +
NodesStartOffset);

CacheNodeIterator = Generator->CacheStructIndexedList;
@@ -771,13 +771,13 @@ AddCacheTypeStructures (
CacheInfoNode = (CM_ARM_CACHE_INFO*)CacheNodeIterator->Object;

// Populate the node header
- CacheStruct->Type = EFI_ACPI_6_3_PPTT_TYPE_CACHE;
- CacheStruct->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE);
+ 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.3, Section 5.2.29.2)
+ // table." (ACPI 6.4, Section 5.2.29.2)
CacheStruct->Flags.SizePropertyValid = 1;
CacheStruct->Flags.NumberOfSetsValid = 1;
CacheStruct->Flags.AssociativityValid = 1;
@@ -936,7 +936,7 @@ AddCacheTypeStructures (
CacheStruct->LineSize = CacheInfoNode->LineSize;

// Next Cache Type Structure
- CacheStruct = (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE*)((UINT8*)CacheStruct +
+ CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE*)((UINT8*)CacheStruct +
CacheStruct->Length);
CacheNodeIterator++;
} // Cache Type Structure
@@ -994,7 +994,7 @@ BuildPpttTable (
// Pointer to the Node Indexer array
PPTT_NODE_INDEXER * NodeIndexer;

- EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt;
+ EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt;

ASSERT (
(This != NULL) &&
@@ -1081,7 +1081,7 @@ BuildPpttTable (
Generator->NodeIndexer = NodeIndexer;

// Calculate the size of the PPTT table
- TableSize = sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER);
+ 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) {
@@ -1150,7 +1150,7 @@ BuildPpttTable (
goto error_handler;
}

- Pptt = (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER*)*Table;
+ Pptt = (EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER*)*Table;

DEBUG ((
DEBUG_INFO,
@@ -1307,9 +1307,9 @@ ACPI_PPTT_GENERATOR PpttGenerator = {
// Generator Description
L"ACPI.STD.PPTT.GENERATOR",
// ACPI Table Signature
- EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+ EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
// ACPI Table Revision supported by this Generator
- EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
+ 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
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 3/7] ShellPkg: Update Acpiview PPTT parser to ACPI 6.4

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

Update the Acpiview PPTT parser to use Acpi64.h. As part of the changes,
remove support for parsing PPTT type 2 ID structure.

Signed-off-by: Chris Jones <christopher.jones@...>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c | 61 ++++----------------
ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 2 +-
2 files changed, 12 insertions(+), 51 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
index acd2b81bb3258c7322aa10d2c0e0d842d89e358b..bce9edcedde50e53035059e6da57b9449209a674 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
@@ -1,11 +1,11 @@
/** @file
PPTT table parser

- Copyright (c) 2019 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2019 - 2021, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
- - ACPI 6.3 Specification - January 2019
+ - ACPI 6.4 Specification - January 2021
- ARM Architecture Reference Manual ARMv8 (D.a)
**/

@@ -157,8 +157,8 @@ ValidateCacheAttributes (
)
{
// Reference: Advanced Configuration and Power Interface (ACPI) Specification
- // Version 6.2 Errata A, September 2017
- // Table 5-153: Cache Type Structure
+ // Version 6.4, January 2021
+ // Table 5-140: Cache Type Structure
UINT8 Attributes;
Attributes = *(UINT8*)Ptr;

@@ -222,22 +222,6 @@ STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = {
{L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL}
};

-/**
- An ACPI_PARSER array describing the ID Type Structure - Type 2.
-**/
-STATIC CONST ACPI_PARSER IdStructureParser[] = {
- {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
- {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
- {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
-
- {L"VENDOR_ID", 4, 4, NULL, Dump4Chars, NULL, NULL, NULL},
- {L"LEVEL_1_ID", 8, 8, L"0x%x", NULL, NULL, NULL, NULL},
- {L"LEVEL_2_ID", 8, 16, L"0x%x", NULL, NULL, NULL, NULL},
- {L"MAJOR_REV", 2, 24, L"0x%x", NULL, NULL, NULL, NULL},
- {L"MINOR_REV", 2, 26, L"0x%x", NULL, NULL, NULL, NULL},
- {L"SPIN_REV", 2, 28, L"0x%x", NULL, NULL, NULL, NULL},
-};
-
/**
This function parses the Processor Hierarchy Node Structure (Type 0).

@@ -335,29 +319,6 @@ DumpCacheTypeStructure (
);
}

-/**
- This function parses the ID Structure (Type 2).
-
- @param [in] Ptr Pointer to the start of the ID Structure data.
- @param [in] Length Length of the ID Structure.
-**/
-STATIC
-VOID
-DumpIDStructure (
- IN UINT8* Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "ID Structure",
- Ptr,
- Length,
- PARSER_PARAMS (IdStructureParser)
- );
-}
-
/**
This function parses the ACPI PPTT table.
When trace is enabled this function parses the PPTT table and
@@ -366,7 +327,6 @@ DumpIDStructure (
This function parses the following processor topology structures:
- Processor hierarchy node structure (Type 0)
- Cache Type Structure (Type 1)
- - ID structure (Type 2)

This function also performs validation of the ACPI table fields.

@@ -444,22 +404,23 @@ ParseAcpiPptt (
Print (L"0x%x\n", Offset);

switch (*ProcessorTopologyStructureType) {
- case EFI_ACPI_6_2_PPTT_TYPE_PROCESSOR:
+ case EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR:
DumpProcessorHierarchyNodeStructure (
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
break;
- case EFI_ACPI_6_2_PPTT_TYPE_CACHE:
+ case EFI_ACPI_6_4_PPTT_TYPE_CACHE:
DumpCacheTypeStructure (
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
break;
- case EFI_ACPI_6_2_PPTT_TYPE_ID:
- DumpIDStructure (
- ProcessorTopologyStructurePtr,
- *ProcessorTopologyStructureLength
+ case EFI_ACPI_6_3_PPTT_TYPE_ID:
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: PPTT Type 2 - Processor ID is deprecated and must not be"
+ L"used.\n"
);
break;
default:
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index d725cad14c5d018e2004eb8e33c845aa9c719429..ab9e6c619d70df4f79d782416037d7bef62c92d5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -62,7 +62,7 @@ ACPI_TABLE_PARSER ParserList[] = {
ParseAcpiMcfg},
{EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
ParseAcpiPcct},
- {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+ {EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
ParseAcpiPptt},
{RSDP_TABLE_INFO, ParseAcpiRsdp},
{EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit},
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 5/7] DynamicTablesPkg: Remove PPTT ID structure from ACPI 6.4 generator

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

ACPI 6.3A deprecated PPTT ID (type 2) structure which was subsequently
removed in ACPI 6.4. Therefore remove support for generating PPTT ID
structures.

Signed-off-by: Chris Jones <christopher.jones@...>
---
DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 23 +--
DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 155 +-------------------
DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h | 4 -
3 files changed, 3 insertions(+), 179 deletions(-)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index f19c9c70666970bb70b6aa09f064bb10a9a67112..6bc5ab6b2b28424c1afddc26cc89a54b81941aeb 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -50,7 +50,7 @@ typedef enum ArmObjectID {
EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array
EArmObjProcHierarchyInfo, ///< 27 - Processor Hierarchy Info
EArmObjCacheInfo, ///< 28 - Cache Info
- EArmObjProcNodeIdInfo, ///< 29 - Processor Node ID Info
+ EArmObjReserved29, ///< 29 - Reserved
EArmObjCmRef, ///< 30 - CM Object Reference
EArmObjMemoryAffinityInfo, ///< 31 - Memory Affinity Info
EArmObjDeviceHandleAcpi, ///< 32 - Device Handle Acpi
@@ -746,27 +746,6 @@ typedef struct CmArmCacheInfo {
UINT16 LineSize;
} CM_ARM_CACHE_INFO;

-/** A structure that describes the ID Structure (Type 2) in PPTT
-
- ID: EArmObjProcNodeIdInfo
-*/
-typedef struct CmArmProcNodeIdInfo {
- /// A unique token used to identify this object
- CM_OBJECT_TOKEN Token;
- // Vendor ID (as described in ACPI ID registry)
- UINT32 VendorId;
- /// First level unique node ID
- UINT64 Level1Id;
- /// Second level unique node ID
- UINT64 Level2Id;
- /// Major revision of the node
- UINT16 MajorRev;
- /// Minor revision of the node
- UINT16 MinorRev;
- /// Spin revision of the node
- UINT16 SpinRev;
-} CM_ARM_PROC_NODE_ID_INFO;
-
/** A structure that describes a reference to another Configuration Manager
object.

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
index d70fc59e754e7d348965b8c3739822a9f1c4b7e6..65d1661c0ec47a4d1631c0dcac7bcb16dbc619e0 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
@@ -34,7 +34,6 @@
The following Configuration Manager Object(s) are used by this Generator:
- EArmObjProcHierarchyInfo (REQUIRED)
- EArmObjCacheInfo
- - EArmObjProcNodeIdInfo
- EArmObjCmRef
- EArmObjGicCInfo (REQUIRED)
*/
@@ -59,16 +58,6 @@ GET_OBJECT_LIST (
CM_ARM_CACHE_INFO
);

-/**
- This macro expands to a function that retrieves the ID information for
- Processor Hierarchy Nodes from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjProcNodeIdInfo,
- CM_ARM_PROC_NODE_ID_INFO
- );
-
/**
This macro expands to a function that retrieves the cross-CM-object-
reference information from the Configuration Manager.
@@ -131,15 +120,6 @@ GET_SIZE_OF_PPTT_STRUCTS (
CM_ARM_CACHE_INFO
);

-/** This macro expands to a function that retrieves the amount of memory
- required to store the ID Structures (Type 2) and updates the Node Indexer.
-*/
-GET_SIZE_OF_PPTT_STRUCTS (
- IdStructs,
- sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_ID),
- CM_ARM_PROC_NODE_ID_INFO
- );
-
/**
Search the Node Indexer and return the indexed PPTT node with the given
Token.
@@ -372,8 +352,8 @@ AddPrivateResources (
}

// The Node indexer has the Processor hierarchy nodes at the begining
- // followed by the cache structs and Id structs. Therefore we can
- // skip the Processor hierarchy nodes in the node indexer search.
+ // followed by the cache structs. Therefore we can skip the Processor
+ // hierarchy nodes in the node indexer search.
Status = GetPpttNodeReferencedByToken (
Generator->CacheStructIndexedList,
(Generator->ProcTopologyStructCount -
@@ -964,72 +944,6 @@ AddCacheTypeStructures (
return EFI_SUCCESS;
}

-/**
- Update the ID Type Structure (Type 2) information.
-
- This function populates the ID Type Structures with information from
- the Configuration Manager and 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 ID Type Structures.
-
- @retval EFI_SUCCESS Structures updated successfully.
- @retval EFI_INVALID_PARAMETER A parameter is invalid.
- @retval EFI_NOT_FOUND A required object was not found.
-**/
-STATIC
-EFI_STATUS
-AddIdTypeStructures (
- IN CONST ACPI_PPTT_GENERATOR * CONST Generator,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
- IN CONST EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt,
- IN CONST UINT32 NodesStartOffset
- )
-{
- EFI_ACPI_6_3_PPTT_STRUCTURE_ID * IdStruct;
- CM_ARM_PROC_NODE_ID_INFO * ProcIdInfoNode;
- PPTT_NODE_INDEXER * IdStructIterator;
- UINT32 NodeCount;
-
-
- ASSERT (
- (Generator != NULL) &&
- (CfgMgrProtocol != NULL) &&
- (Pptt != NULL)
- );
-
- IdStruct = (EFI_ACPI_6_3_PPTT_STRUCTURE_ID*)((UINT8*)Pptt + NodesStartOffset);
-
- IdStructIterator = Generator->IdStructIndexedList;
- NodeCount = Generator->IdStructCount;
- while (NodeCount-- != 0) {
- ProcIdInfoNode = (CM_ARM_PROC_NODE_ID_INFO*)IdStructIterator->Object;
-
- // Populate the node
- IdStruct->Type = EFI_ACPI_6_3_PPTT_TYPE_ID;
- IdStruct->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_ID);
- IdStruct->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
- IdStruct->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
- IdStruct->VendorId = ProcIdInfoNode->VendorId;
- IdStruct->Level1Id = ProcIdInfoNode->Level1Id;
- IdStruct->Level2Id = ProcIdInfoNode->Level2Id;
- IdStruct->MajorRev = ProcIdInfoNode->MajorRev;
- IdStruct->MinorRev = ProcIdInfoNode->MinorRev;
- IdStruct->SpinRev = ProcIdInfoNode->SpinRev;
-
- // Next ID Type Structure
- IdStruct = (EFI_ACPI_6_3_PPTT_STRUCTURE_ID*)((UINT8*)IdStruct +
- IdStruct->Length);
- IdStructIterator++;
- } // ID Type Structure
-
- return EFI_SUCCESS;
-}
-
/**
Construct the PPTT ACPI table.

@@ -1068,15 +982,12 @@ BuildPpttTable (
UINT32 ProcTopologyStructCount;
UINT32 ProcHierarchyNodeCount;
UINT32 CacheStructCount;
- UINT32 IdStructCount;

UINT32 ProcHierarchyNodeOffset;
UINT32 CacheStructOffset;
- UINT32 IdStructOffset;

CM_ARM_PROC_HIERARCHY_INFO * ProcHierarchyNodeList;
CM_ARM_CACHE_INFO * CacheStructList;
- CM_ARM_PROC_NODE_ID_INFO * IdStructList;

ACPI_PPTT_GENERATOR * Generator;

@@ -1150,27 +1061,6 @@ BuildPpttTable (
ProcTopologyStructCount += CacheStructCount;
Generator->CacheStructCount = CacheStructCount;

- // Get the processor hierarchy node ID info and update the processor topology
- // structure count with ID Structures (Type 2)
- Status = GetEArmObjProcNodeIdInfo (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &IdStructList,
- &IdStructCount
- );
- if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: PPTT: Failed to get processor hierarchy node ID info. " \
- "Status = %r\n",
- Status
- ));
- goto error_handler;
- }
-
- ProcTopologyStructCount += IdStructCount;
- Generator->IdStructCount = IdStructCount;
-
// Allocate Node Indexer array
NodeIndexer = (PPTT_NODE_INDEXER*)AllocateZeroPool (
sizeof (PPTT_NODE_INDEXER) *
@@ -1237,27 +1127,6 @@ BuildPpttTable (
));
}

- // Include the size of ID Type Structures and index them
- if (Generator->IdStructCount != 0) {
- IdStructOffset = TableSize;
- Generator->IdStructIndexedList = NodeIndexer;
- TableSize += GetSizeofIdStructs (
- IdStructOffset,
- IdStructList,
- Generator->IdStructCount,
- &NodeIndexer
- );
- DEBUG ((
- DEBUG_INFO,
- " IdStructCount = %d\n" \
- " IdStructOffset = 0x%x\n" \
- " IdStructIndexedList = 0x%p\n",
- Generator->IdStructCount,
- IdStructOffset,
- Generator->IdStructIndexedList
- ));
- }
-
DEBUG ((
DEBUG_INFO,
"INFO: PPTT:\n" \
@@ -1343,24 +1212,6 @@ BuildPpttTable (
}
}

- // Add ID Type Structures (Type 2) to the generated table
- if (Generator->IdStructCount != 0) {
- Status = AddIdTypeStructures (
- Generator,
- CfgMgrProtocol,
- Pptt,
- IdStructOffset
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: PPTT: Failed to add ID Type Structures. Status = %r\n",
- Status
- ));
- goto error_handler;
- }
- }
-
// Validate CM object cross-references in PPTT
Status = DetectCyclesInTopology (Generator);
if (EFI_ERROR (Status)) {
@@ -1484,8 +1335,6 @@ ACPI_PPTT_GENERATOR PpttGenerator = {
0,
// Count of Cache Structures
0,
- // Count of Id Structures
- 0,
// Pointer to PPTT Node Indexer
NULL
};
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h
index 0a14da502d595e27d87262b1bac681318f1d9ced..59ddd71ac4ef57d748e143afaa6ac0befb4900e0 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h
@@ -171,8 +171,6 @@ typedef struct AcpiPpttGenerator {
UINT32 ProcHierarchyNodeCount;
/// Count of Cache Structures
UINT32 CacheStructCount;
- /// Count of Id Structures
- UINT32 IdStructCount;
/// List of indexed CM objects for PPTT generation
PPTT_NODE_INDEXER * NodeIndexer;
/// Pointer to the start of Processor Hierarchy nodes in
@@ -180,8 +178,6 @@ typedef struct AcpiPpttGenerator {
PPTT_NODE_INDEXER * ProcHierarchyNodeIndexedList;
/// Pointer to the start of Cache Structures in the Node Indexer array
PPTT_NODE_INDEXER * CacheStructIndexedList;
- /// Pointer to the start of Id Structures in the Node Indexer array
- PPTT_NODE_INDEXER * IdStructIndexedList;
} ACPI_PPTT_GENERATOR;

#pragma pack()
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 4/7] ShellPkg: Add Cache ID to PPTT parser

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

Update the Acpiview PPTT parser with the Cache ID field and relevant
validations as defined in tables 5.140 and 5.141 of the ACPI 6.4
specification.

Signed-off-by: Chris Jones <christopher.jones@...>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c | 118 +++++++++++++++++++-
1 file changed, 116 insertions(+), 2 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
index bce9edcedde50e53035059e6da57b9449209a674..a6130eae62c4387d2b6037ecec8db596e4bb6bb1 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
@@ -20,8 +20,82 @@
STATIC CONST UINT8* ProcessorTopologyStructureType;
STATIC CONST UINT8* ProcessorTopologyStructureLength;
STATIC CONST UINT32* NumberOfPrivateResources;
+STATIC CONST EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS* CacheFlags;
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;

+/**
+ Increment the error count and print an error that a required flag is missing.
+
+ @param [in] FlagName Name of the missing flag.
+**/
+STATIC
+VOID
+EFIAPI
+LogCacheFlagError (
+ IN CONST CHAR16* FlagName
+ )
+{
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: On Arm based systems, all cache properties must be"
+ L"provided in the cache type structure."
+ L"Missing '%s' flag.",
+ *FlagName
+ );
+}
+
+/**
+ 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] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateCacheFlags (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+#if defined(MDE_CPU_ARM) || defined(MDE_CPU_AARCH64)
+ if (CacheFlags == NULL) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Cache Structure Flags were not successfully read.");
+ return;
+ }
+
+ if (CacheFlags->SizePropertyValid == EFI_ACPI_6_4_PPTT_CACHE_SIZE_INVALID) {
+ LogCacheFlagError (L"Size Property Valid");
+ }
+ if (CacheFlags->NumberOfSetsValid == EFI_ACPI_6_4_PPTT_NUMBER_OF_SETS_INVALID) {
+ LogCacheFlagError (L"Number Of Sets Valid");
+ }
+ if (CacheFlags->AssociativityValid == EFI_ACPI_6_4_PPTT_ASSOCIATIVITY_INVALID) {
+ LogCacheFlagError (L"Associativity Valid");
+ }
+ if (CacheFlags->AllocationTypeValid == EFI_ACPI_6_4_PPTT_ALLOCATION_TYPE_INVALID) {
+ LogCacheFlagError (L"Allocation Type Valid");
+ }
+ if (CacheFlags->CacheTypeValid == EFI_ACPI_6_4_PPTT_CACHE_TYPE_INVALID) {
+ LogCacheFlagError (L"Cache Type Valid");
+ }
+ if (CacheFlags->WritePolicyValid == EFI_ACPI_6_4_PPTT_WRITE_POLICY_INVALID) {
+ LogCacheFlagError (L"Write Policy Valid");
+ }
+ if (CacheFlags->LineSizeValid == EFI_ACPI_6_4_PPTT_LINE_SIZE_INVALID) {
+ LogCacheFlagError (L"Line Size Valid");
+ }
+ // Cache ID was only introduced in revision 3
+ if (*(AcpiHdrInfo.Revision) >= 3) {
+ if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_INVALID) {
+ LogCacheFlagError (L"Cache Id Valid");
+ }
+ }
+#endif
+}
+
/**
This function validates the Cache Type Structure (Type 1) 'Number of sets'
field.
@@ -141,6 +215,44 @@ ValidateCacheLineSize (
#endif
}

+/**
+ 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] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateCacheId (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ UINT32 CacheId;
+ CacheId = *(UINT32*)Ptr;
+
+ // Cache ID was only introduced in revision 3
+ if (*(AcpiHdrInfo.Revision) < 3) {
+ return;
+ }
+
+ if (CacheFlags == NULL) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Cache Structure Flags were not successfully read.");
+ return;
+ }
+
+ if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_VALID) {
+ if (CacheId == 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: 0 is not a valid Cache ID.");
+ return;
+ }
+ }
+}
+
/**
This function validates the Cache Type Structure (Type 1) Attributes field.

@@ -213,13 +325,15 @@ STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = {
{L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
{L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},

- {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 4, L"0x%x", NULL, (VOID**)&CacheFlags, ValidateCacheFlags,
+ NULL},
{L"Next Level of Cache", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
{L"Size", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
{L"Number of sets", 4, 16, L"%d", NULL, NULL, ValidateCacheNumberOfSets, NULL},
{L"Associativity", 1, 20, L"%d", NULL, NULL, ValidateCacheAssociativity, NULL},
{L"Attributes", 1, 21, L"0x%x", NULL, NULL, ValidateCacheAttributes, NULL},
- {L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL}
+ {L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL},
+ {L"Cache ID", 4, 24, L"%d", NULL, NULL, ValidateCacheId, NULL}
};

/**
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 1/7] MdePkg: Add missing Cache ID (in)valid define

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

Add Cache ID valid/invalid defines to Acpi64.h which were not initially
added when the CacheIdValid field was added to
EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS.

Signed-off-by: Chris Jones <christopher.jones@...>
---
MdePkg/Include/IndustryStandard/Acpi64.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/Acpi64.h b/MdePkg/Include/IndustryStandard/Acpi64.h
index 3a91302f8c0e71d4951d27aac35322073219c836..625504ba77b4000c0a0b540299d2e0e42c768400 100644
--- a/MdePkg/Include/IndustryStandard/Acpi64.h
+++ b/MdePkg/Include/IndustryStandard/Acpi64.h
@@ -2680,6 +2680,8 @@ typedef struct {
#define EFI_ACPI_6_4_PPTT_WRITE_POLICY_VALID 0x1
#define EFI_ACPI_6_4_PPTT_LINE_SIZE_INVALID 0x0
#define EFI_ACPI_6_4_PPTT_LINE_SIZE_VALID 0x1
+#define EFI_ACPI_6_4_PPTT_CACHE_ID_INVALID 0x0
+#define EFI_ACPI_6_4_PPTT_CACHE_ID_VALID 0x1

///
/// Cache Type Structure flags
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 0/7] Support ACPI 6.4 PPTT changes

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

This patch series updates the Acpiview PPTT parser and DynamicTablesPkg
PPTT generator to support ACPI 6.4. This consists of two main changes:
- The addition of the 'Cache ID' field.
- The removal of the PPTT ID (type 2) structure.

In addition add two 'Cache ID' defines and remove the type 2 PPTT
structure from Acpi64.h as these changes were missing when Acpi64.h was
introduced.

The changes can be seen at: https://github.com/chris-jones-arm/edk2/tree/1632_64_acpi_cache_id_v1

Chris Jones (7):
MdePkg: Add missing Cache ID (in)valid define
MdePkg: Remove PPTT ID type structure
ShellPkg: Update Acpiview PPTT parser to ACPI 6.4
ShellPkg: Add Cache ID to PPTT parser
DynamicTablesPkg: Remove PPTT ID structure from ACPI 6.4 generator
DynamicTablesPkg: Update PPTT generator to ACPI 6.4
DynamicTablesPkg: Add CacheId to PPTT generator

.../Include/ArmNameSpaceObjects.h | 27 +-
.../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 297 +++++++-----------
.../Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h | 4 -
MdePkg/Include/IndustryStandard/Acpi64.h | 18 +-
.../Parsers/Pptt/PpttParser.c | 179 ++++++++---
.../UefiShellAcpiViewCommandLib.c | 2 +-
6 files changed, 249 insertions(+), 278 deletions(-)

--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 2/7] MdePkg: Remove PPTT ID type structure

Chris Jones
 

Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

The ACPI 6.3A specification deprecated the PPTT ID type structure (type
2) therefore remove it from Acpi64.h.

Mantis ID: 2072 (https://mantis.uefi.org/mantis/view.php?id=2072)

Signed-off-by: Chris Jones <christopher.jones@...>
---
MdePkg/Include/IndustryStandard/Acpi64.h | 16 ----------------
1 file changed, 16 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/Acpi64.h b/MdePkg/Include/IndustryStandard/Acpi64.h
index 625504ba77b4000c0a0b540299d2e0e42c768400..bc1522722424156f0381e848c2617760f2d31aba 100644
--- a/MdePkg/Include/IndustryStandard/Acpi64.h
+++ b/MdePkg/Include/IndustryStandard/Acpi64.h
@@ -2613,7 +2613,6 @@ typedef struct {
///
#define EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR 0x00
#define EFI_ACPI_6_4_PPTT_TYPE_CACHE 0x01
-#define EFI_ACPI_6_4_PPTT_TYPE_ID 0x02

///
/// PPTT Structure Header
@@ -2737,21 +2736,6 @@ typedef struct {
UINT32 CacheId;
} EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE;

-///
-/// ID structure
-///
-typedef struct {
- UINT8 Type;
- UINT8 Length;
- UINT8 Reserved[2];
- UINT32 VendorId;
- UINT64 Level1Id;
- UINT64 Level2Id;
- UINT16 MajorRev;
- UINT16 MinorRev;
- UINT16 SpinRev;
-} EFI_ACPI_6_4_PPTT_STRUCTURE_ID;
-
///
/// Platform Health Assessment Table (PHAT) Format
///
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


Re: [PATCH 0/2] work area fixes

Yao, Jiewen
 

That is weird. But I am not tool person.

HI Liming/Mike/Sean
Would you please take a look and help us understand what's happening?

Thank you
Yao Jiewen

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Brijesh
Singh via groups.io
Sent: Monday, October 18, 2021 10:45 PM
To: Yao, Jiewen <jiewen.yao@...>; devel@edk2.groups.io
Cc: brijesh.singh@...; James Bottomley <jejb@...>; Xu, Min M
<min.m.xu@...>; Tom Lendacky <thomas.lendacky@...>; Justen,
Jordan L <jordan.l.justen@...>; Ard Biesheuvel
<ardb+tianocore@...>; Erdem Aktas <erdemaktas@...>;
Michael Roth <Michael.Roth@...>; Gerd Hoffmann <kraxel@...>
Subject: Re: [edk2-devel] [PATCH 0/2] work area fixes


On 10/18/21 8:14 AM, Yao, Jiewen wrote:
Hi
This patch failed in PR -
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.c
om%2Ftianocore%2Fedk2%2Fpull%2F2076&amp;data=04%7C01%7Cbrijesh.sing
h%40amd.com%7C20804cf7726f4528ee2608d9923950ba%7C3dd8961fe4884e6
08e11a82d994e183d%7C0%7C0%7C637701597143373879%7CUnknown%7CTW
FpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI
6Mn0%3D%7C1000&amp;sdata=S4RXWkQ5Hs4yr8FvEvKJSYGVPZS7mrBfvjRUKZF
dsZ8%3D&amp;reserved=0

Please take a look.

You are encouraged to try PR before submit next time.
I did ran PR before the submission and it all passed. The error this
link is reports have something to do with the python script used for
running the PR itself. I am not sure what I can do to fix it. Sounds
like a bug in the tool ?




Thank you
Yao Jiewen

-----Original Message-----
From: Yao, Jiewen
Sent: Monday, October 18, 2021 12:53 PM
To: devel@edk2.groups.io; brijesh.singh@...
Cc: James Bottomley <jejb@...>; Xu, Min M
<min.m.xu@...>;
Tom Lendacky <thomas.lendacky@...>; Justen, Jordan L
<jordan.l.justen@...>; Ard Biesheuvel <ardb+tianocore@...>;
Erdem Aktas <erdemaktas@...>; Michael Roth
<Michael.Roth@...>; Gerd Hoffmann <kraxel@...>
Subject: RE: [edk2-devel] [PATCH 0/2] work area fixes

Series: Acked-by: Jiewen Yao <Jiewen.yao@...>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Brijesh
Singh via groups.io
Sent: Friday, October 15, 2021 2:17 AM
To: devel@edk2.groups.io
Cc: James Bottomley <jejb@...>; Xu, Min M
<min.m.xu@...>;
Yao, Jiewen <jiewen.yao@...>; Tom Lendacky
<thomas.lendacky@...>; Justen, Jordan L
<jordan.l.justen@...>;
Ard Biesheuvel <ardb+tianocore@...>; Erdem Aktas
<erdemaktas@...>; Michael Roth <Michael.Roth@...>;
Gerd
Hoffmann <kraxel@...>; Brijesh Singh <brijesh.singh@...>
Subject: [edk2-devel] [PATCH 0/2] work area fixes

We missed updating the AmdSev package and Ia32 buid to use new work
area.

Brijesh Singh (2):
Ovmfpkg: update Ia32 build to use new work area
OvmfPkg/AmdSev: update the fdf to use new workarea PCD

OvmfPkg/AmdSev/AmdSevX64.fdf | 9 ++++++++-
OvmfPkg/OvmfPkgIa32X64.fdf | 3 +++
OvmfPkg/ResetVector/ResetVector.nasmb | 3 ++-
3 files changed, 13 insertions(+), 2 deletions(-)

--
2.25.1







Re: [PATCH 0/2] work area fixes

Brijesh Singh
 

On 10/18/21 8:14 AM, Yao, Jiewen wrote:
Hi
This patch failed in PR - https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2%2Fpull%2F2076&;data=04%7C01%7Cbrijesh.singh%40amd.com%7C20804cf7726f4528ee2608d9923950ba%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637701597143373879%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=S4RXWkQ5Hs4yr8FvEvKJSYGVPZS7mrBfvjRUKZFdsZ8%3D&amp;reserved=0

Please take a look.

You are encouraged to try PR before submit next time.
I did ran PR before the submission and it all passed. The error this
link is reports have something to do with the python script used for
running the PR itself. I am not sure what I can do to fix it. Sounds
like a bug in the tool ?




Thank you
Yao Jiewen

-----Original Message-----
From: Yao, Jiewen
Sent: Monday, October 18, 2021 12:53 PM
To: devel@edk2.groups.io; brijesh.singh@...
Cc: James Bottomley <jejb@...>; Xu, Min M <min.m.xu@...>;
Tom Lendacky <thomas.lendacky@...>; Justen, Jordan L
<jordan.l.justen@...>; Ard Biesheuvel <ardb+tianocore@...>;
Erdem Aktas <erdemaktas@...>; Michael Roth
<Michael.Roth@...>; Gerd Hoffmann <kraxel@...>
Subject: RE: [edk2-devel] [PATCH 0/2] work area fixes

Series: Acked-by: Jiewen Yao <Jiewen.yao@...>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Brijesh
Singh via groups.io
Sent: Friday, October 15, 2021 2:17 AM
To: devel@edk2.groups.io
Cc: James Bottomley <jejb@...>; Xu, Min M
<min.m.xu@...>;
Yao, Jiewen <jiewen.yao@...>; Tom Lendacky
<thomas.lendacky@...>; Justen, Jordan L <jordan.l.justen@...>;
Ard Biesheuvel <ardb+tianocore@...>; Erdem Aktas
<erdemaktas@...>; Michael Roth <Michael.Roth@...>; Gerd
Hoffmann <kraxel@...>; Brijesh Singh <brijesh.singh@...>
Subject: [edk2-devel] [PATCH 0/2] work area fixes

We missed updating the AmdSev package and Ia32 buid to use new work area.

Brijesh Singh (2):
Ovmfpkg: update Ia32 build to use new work area
OvmfPkg/AmdSev: update the fdf to use new workarea PCD

OvmfPkg/AmdSev/AmdSevX64.fdf | 9 ++++++++-
OvmfPkg/OvmfPkgIa32X64.fdf | 3 +++
OvmfPkg/ResetVector/ResetVector.nasmb | 3 ++-
3 files changed, 13 insertions(+), 2 deletions(-)

--
2.25.1





[edk2platforms][PATCH v2 1/1] IntelSiliconPkg: Add IntelDieInfoProtocol

Maciej Czajkowski
 

Added IntelDieInfoProtocol header into IntelSiliconPkg tree.
The purpose is to have generic and unified interface for getting
information about dies installed in the system.
It will be implemented by silicon code.

Change-Id: Iedc414d435c27f37e6f12e7affd046a0a9e7e19d
Cc: Ray Ni <ray.ni@...>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@...>
Signed-off-by: Maciej Czajkowski <maciej.czajkowski@...>
---

Notes:
v2:
- added interface description
- added die specific GUIDs into .dec file

Silicon/Intel/IntelSiliconPkg/Include/Protocol/IntelDieInfoProtocol.h | 117 ++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 9 ++
2 files changed, 126 insertions(+)

diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Protocol/IntelDieInfoProtocol.h b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/IntelDieInfoProtocol.h
new file mode 100644
index 000000000000..954c9ee10c22
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Protocol/IntelDieInfoProtocol.h
@@ -0,0 +1,117 @@
+/** @file
+ IntelDieInfoProtocol definition
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _DIE_INFO_PROTOCOL_H_
+#define _DIE_INFO_PROTOCOL_H_
+
+typedef struct _INTEL_DIE_INFO_PROTOCOL INTEL_DIE_INFO_PROTOCOL;
+typedef INTEL_DIE_INFO_PROTOCOL INTEL_DIE_INFO_PPI;
+
+extern EFI_GUID gIntelDieInfoProtocolGuid;
+extern EFI_GUID gIntelDieInfoPpiGuid;
+
+extern EFI_GUID gIntelDieInfoPchGuid;
+extern EFI_GUID gIntelDieInfoSocGuid;
+extern EFI_GUID gIntelDieInfoIoGuid;
+extern EFI_GUID gIntelDieInfoCpuGuid;
+extern EFI_GUID gIntelDieInfoGfxGuid;
+
+#define INTEL_DIE_INFO_PPI_GUID \
+{ 0xAED8A0A1, 0xFDE6, 0x4CF2, { 0xA3, 0x85, 0x08, 0xF1, 0x25, 0xF2, 0x40, 0x37 }}
+
+#define INTEL_DIE_INFO_PROTOCOL_GUID \
+{ 0xAED8A0A1, 0xFDE6, 0x4CF2, { 0xA3, 0x85, 0x08, 0xF1, 0x25, 0xF2, 0x40, 0x37 }}
+
+#define DIE_INFO_PROTOCOL_REVISION 1
+#define DIE_INFO_PROTOCOL_SIGNATURE SIGNATURE_32 ('I', 'D', 'I', 'P')
+
+#define DIE_INFO_PCH_GUID \
+{ 0x62CB6D68, 0x4771, 0x4569, { 0x81, 0xFA, 0x1E, 0x99, 0x6E, 0xA9, 0x91, 0xC5 }}
+
+#define DIE_INFO_SOC_GUID \
+{ 0x63287105, 0x578E, 0x4799, { 0xBE, 0x55, 0x5D, 0xDA, 0xCA, 0x03, 0x74, 0xD0 }}
+
+#define DIE_INFO_IO_GUID \
+{ 0x23DA4C74, 0x54A0, 0x4E01, { 0x83, 0xB1, 0x8C, 0xA7, 0x43, 0x43, 0x1F, 0xF0 }}
+
+#define DIE_INFO_CPU_GUID \
+{ 0x6E5AF2E3, 0x5D84, 0x48F2, { 0x84, 0x28, 0x99, 0xE4, 0x93, 0x4F, 0x51, 0xE4 }}
+
+#define DIE_INFO_GFX_GUID \
+{ 0x1D3D2599, 0x7A1C, 0x4B1E, { 0x8C, 0xC5, 0x0F, 0x88, 0x27, 0xA0, 0x2E, 0xEC }}
+
+/**
+ Returns pointer to constant string representing die name.
+ Name is specific to die type.
+
+ @param[in] This Pointer to the DieInfoProtocol context structure
+ @retval Pointer to the const string
+**/
+typedef
+CONST CHAR8*
+(EFIAPI *INTEL_DIE_INFO_GET_DIE_NAME_STR) (
+ IN INTEL_DIE_INFO_PROTOCOL *This
+ );
+
+/**
+ Returns pointer to constant string representing stepping of the die.
+
+ @param[in] This Pointer to the DieInfoProtocol context structure
+ @retval Pointer to the const string
+**/
+typedef
+CONST CHAR8*
+(EFIAPI *INTEL_DIE_INFO_GET_STEPPING_STR) (
+ IN INTEL_DIE_INFO_PROTOCOL *This
+ );
+
+/**
+ Returns pointer to constant string representing SKU of the die.
+
+ @param[in] This Pointer to the DieInfoProtocol context structure
+ @retval Pointer to the const string
+**/
+typedef
+CONST CHAR8*
+(EFIAPI *INTEL_DIE_INFO_GET_SKU_STR) (
+ IN INTEL_DIE_INFO_PROTOCOL *This
+ );
+
+/**
+ Protocol/PPI definition.
+ The purpose of this interface is to serve die-specific informations in a unified, generic way.
+ It will be produced by silicon code per die, and can be consumed by any module that needs contained information.
+
+ <b>Revision 1</b>:
+ - Initial version.
+**/
+struct _INTEL_DIE_INFO_PROTOCOL {
+ UINT32 Signature; ///< Protocol signature
+ UINT32 Revision; ///< Current protocol revision
+ /**
+ Type of the die that particular instance is reffering to. See DIE_INFO_*_GUID
+ **/
+ EFI_GUID Type;
+ /**
+ Index of the die in the system.
+ **/
+ UINT32 DieIndex;
+ /**
+ Generation and die specific ID number.
+ **/
+ UINT64 DieId;
+ /**
+ Generation and die specific stepping ID.
+ **/
+ UINT32 SteppingId;
+
+ INTEL_DIE_INFO_GET_DIE_NAME_STR GetNameStr;
+ INTEL_DIE_INFO_GET_STEPPING_STR GetSteppingStr;
+ INTEL_DIE_INFO_GET_SKU_STR GetSkuStr;
+};
+
+#endif // _DIE_INFO_PROTOCOL_H_
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 2461ab8e06e7..fe9b13ba28c7 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -70,12 +70,21 @@ [Guids]
## Include/Guid/MicrocodeShadowInfoHob.h
gEdkiiMicrocodeStorageTypeFlashGuid = { 0x2cba01b3, 0xd391, 0x4598, { 0x8d, 0x89, 0xb7, 0xfc, 0x39, 0x22, 0xfd, 0x71 } }

+ ## Include/Protocol/IntelDieInfoProtocol.h
+ gIntelDieInfoPchGuid = { 0x62CB6D68, 0x4771, 0x4569, { 0x81, 0xFA, 0x1E, 0x99, 0x6E, 0xA9, 0x91, 0xC5 }}
+ gIntelDieInfoSocGuid = { 0x63287105, 0x578E, 0x4799, { 0xBE, 0x55, 0x5D, 0xDA, 0xCA, 0x03, 0x74, 0xD0 }}
+ gIntelDieInfoIoGuid = { 0x23DA4C74, 0x54A0, 0x4E01, { 0x83, 0xB1, 0x8C, 0xA7, 0x43, 0x43, 0x1F, 0xF0 }}
+ gIntelDieInfoCpuGuid = { 0x6E5AF2E3, 0x5D84, 0x48F2, { 0x84, 0x28, 0x99, 0xE4, 0x93, 0x4F, 0x51, 0xE4 }}
+ gIntelDieInfoGfxGuid = { 0x1D3D2599, 0x7A1C, 0x4B1E, { 0x8C, 0xC5, 0x0F, 0x88, 0x27, 0xA0, 0x2E, 0xEC }}
+
[Ppis]
gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
gEdkiiVTdNullRootEntryTableGuid = { 0x3de0593f, 0x6e3e, 0x4542, { 0xa1, 0xcb, 0xcb, 0xb2, 0xdb, 0xeb, 0xd8, 0xff } }
+ gIntelDieInfoPpiGuid = { 0xAED8A0A1, 0xFDE6, 0x4CF2, { 0xA3, 0x85, 0x08, 0xF1, 0x25, 0xF2, 0x40, 0x37 }}

[Protocols]
gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
+ gIntelDieInfoProtocolGuid = { 0xAED8A0A1, 0xFDE6, 0x4CF2, { 0xA3, 0x85, 0x08, 0xF1, 0x25, 0xF2, 0x40, 0x37 }}

## Protocol for device security policy.
# Include/Protocol/PlatformDeviceSecurityPolicy.h
--
2.27.0.windows.1

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.

10061 - 10080 of 92219